spee.ch/index.js
2018-03-19 15:34:32 -07:00

10909 lines
887 KiB
JavaScript

module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 45);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = require("react");
/***/ }),
/* 1 */
/***/ (function(module, exports) {
module.exports = require("react-redux");
/***/ }),
/* 2 */
/***/ (function(module, exports) {
module.exports = require("winston");
/***/ }),
/* 3 */
/***/ (function(module, exports) {
module.exports = require("react-router-dom");
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.selectFile = selectFile;
exports.clearFile = clearFile;
exports.updateMetadata = updateMetadata;
exports.updateClaim = updateClaim;
exports.setPublishInChannel = setPublishInChannel;
exports.updatePublishStatus = updatePublishStatus;
exports.updateError = updateError;
exports.updateSelectedChannel = updateSelectedChannel;
exports.toggleMetadataInputs = toggleMetadataInputs;
exports.onNewThumbnail = onNewThumbnail;
exports.startPublish = startPublish;
var _publish_action_types = __webpack_require__(32);
var actions = _interopRequireWildcard(_publish_action_types);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
// export action creators
function selectFile(file) {
return {
type: actions.FILE_SELECTED,
data: file
};
};
function clearFile() {
return {
type: actions.FILE_CLEAR
};
};
function updateMetadata(name, value) {
return {
type: actions.METADATA_UPDATE,
data: {
name: name,
value: value
}
};
};
function updateClaim(value) {
return {
type: actions.CLAIM_UPDATE,
data: value
};
};
function setPublishInChannel(channel) {
return {
type: actions.SET_PUBLISH_IN_CHANNEL,
channel: channel
};
};
function updatePublishStatus(status, message) {
return {
type: actions.PUBLISH_STATUS_UPDATE,
data: {
status: status,
message: message
}
};
};
function updateError(name, value) {
return {
type: actions.ERROR_UPDATE,
data: {
name: name,
value: value
}
};
};
function updateSelectedChannel(channelName) {
return {
type: actions.SELECTED_CHANNEL_UPDATE,
data: channelName
};
};
function toggleMetadataInputs(showMetadataInputs) {
return {
type: actions.TOGGLE_METADATA_INPUTS,
data: showMetadataInputs
};
};
function onNewThumbnail(file) {
return {
type: actions.THUMBNAIL_NEW,
data: file
};
};
function startPublish(history) {
return {
type: actions.PUBLISH_START,
data: { history: history }
};
}
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
function SiteConfig() {
this.analytics = {
googleId: 'default'
};
this.assetDefaults = {
description: 'An asset published on Spee.ch',
thumbnail: 'https://spee.ch/assets/img/video_thumb_default.png',
title: 'Spee.ch'
};
this.auth = {
sessionKey: 'default'
};
this.details = {
description: 'Open-source, decentralized image and video sharing.',
host: 'default',
port: 3000,
title: 'Spee.ch',
twitter: '@spee_ch'
};
this.publishing = {
additionalClaimAddresses: [],
disabled: false,
disabledMessage: 'Please check back soon.',
primaryClaimAddress: 'default',
thumbnailChannel: 'default',
thumbnailChannelId: 'default',
uploadDirectory: '/home/lbry/Uploads'
};
};
module.exports = new SiteConfig();
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var Sequelize = __webpack_require__(24);
var logger = __webpack_require__(2);
console.log('exporting sequelize models');
var _require = __webpack_require__(66),
database = _require.database,
username = _require.username,
password = _require.password;
var db = {};
// set sequelize options
var sequelize = new Sequelize(database, username, password, {
host: 'localhost',
dialect: 'mysql',
dialectOptions: { decimalNumbers: true }, // fix to ensure DECIMAL will not be stored as a string
logging: false,
pool: {
max: 5,
min: 0,
idle: 10000,
acquire: 10000
}
});
// establish mysql connection
sequelize.authenticate().then(function () {
logger.info('Sequelize has established mysql connection successfully.');
}).catch(function (err) {
logger.error('Sequelize was unable to connect to the database:', err);
});
// manually add each model to the db object
var Certificate = __webpack_require__(67);
var Channel = __webpack_require__(68);
var Claim = __webpack_require__(69);
var File = __webpack_require__(70);
var Request = __webpack_require__(71);
var User = __webpack_require__(72);
db['Certificate'] = sequelize.import('Certificate', Certificate);
db['Channel'] = sequelize.import('Channel', Channel);
db['Claim'] = sequelize.import('Claim', Claim);
db['File'] = sequelize.import('File', File);
db['Request'] = sequelize.import('Request', Request);
db['User'] = sequelize.import('User', User);
// run model.association for each model in the db object that has an association
Object.keys(db).forEach(function (modelName) {
if (db[modelName].associate) {
logger.info('Associating model:', modelName);
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
// add an 'upsert' method to the db object
db.upsert = function (Model, values, condition, tableName) {
return Model.findOne({
where: condition
}).then(function (obj) {
if (obj) {
// update
logger.debug('updating record in db.' + tableName);
return obj.update(values);
} else {
// insert
logger.debug('creating record in db.' + tableName);
return Model.create(values);
}
}).catch(function (error) {
logger.error(tableName + '.upsert error', error);
throw error;
});
};
module.exports = db;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _channel = __webpack_require__(19);
var _publish = __webpack_require__(4);
var _view = __webpack_require__(93);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var channel = _ref.channel,
site = _ref.site;
return {
channelName: channel.loggedInChannel.name,
channelShortId: channel.loggedInChannel.shortId,
channelLongId: channel.loggedInChannel.longId,
siteDescription: site.description
};
};
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
onChannelLogin: function onChannelLogin(name, shortId, longId) {
dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));
dispatch((0, _publish.updateSelectedChannel)(name));
},
onChannelLogout: function onChannelLogout() {
dispatch((0, _channel.updateLoggedInChannel)(null, null, null));
}
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.onHandleShowPageUri = onHandleShowPageUri;
exports.onRequestError = onRequestError;
exports.onNewChannelRequest = onNewChannelRequest;
exports.onNewAssetRequest = onNewAssetRequest;
exports.onRequestUpdate = onRequestUpdate;
exports.addRequestToRequestList = addRequestToRequestList;
exports.addAssetToAssetList = addAssetToAssetList;
exports.addNewChannelToChannelList = addNewChannelToChannelList;
exports.onUpdateChannelClaims = onUpdateChannelClaims;
exports.updateChannelClaims = updateChannelClaims;
exports.fileRequested = fileRequested;
exports.updateFileAvailability = updateFileAvailability;
exports.updateDisplayAssetError = updateDisplayAssetError;
var _show_action_types = __webpack_require__(12);
var actions = _interopRequireWildcard(_show_action_types);
var _show_request_types = __webpack_require__(41);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
// basic request parsing
function onHandleShowPageUri(params) {
return {
type: actions.HANDLE_SHOW_URI,
data: params
};
};
function onRequestError(error) {
return {
type: actions.REQUEST_ERROR,
data: error
};
};
function onNewChannelRequest(channelName, channelId) {
var requestType = _show_request_types.CHANNEL;
var requestId = 'cr#' + channelName + '#' + channelId;
return {
type: actions.CHANNEL_REQUEST_NEW,
data: { requestType: requestType, requestId: requestId, channelName: channelName, channelId: channelId }
};
};
function onNewAssetRequest(name, id, channelName, channelId, extension) {
var requestType = extension ? _show_request_types.ASSET_LITE : _show_request_types.ASSET_DETAILS;
var requestId = 'ar#' + name + '#' + id + '#' + channelName + '#' + channelId;
return {
type: actions.ASSET_REQUEST_NEW,
data: {
requestType: requestType,
requestId: requestId,
name: name,
modifier: {
id: id,
channel: {
name: channelName,
id: channelId
}
}
}
};
};
function onRequestUpdate(requestType, requestId) {
return {
type: actions.REQUEST_UPDATE,
data: {
requestType: requestType,
requestId: requestId
}
};
};
function addRequestToRequestList(id, error, key) {
return {
type: actions.REQUEST_LIST_ADD,
data: { id: id, error: error, key: key }
};
};
// asset actions
function addAssetToAssetList(id, error, name, claimId, shortId, claimData) {
return {
type: actions.ASSET_ADD,
data: { id: id, error: error, name: name, claimId: claimId, shortId: shortId, claimData: claimData }
};
}
// channel actions
function addNewChannelToChannelList(id, name, shortId, longId, claimsData) {
return {
type: actions.CHANNEL_ADD,
data: { id: id, name: name, shortId: shortId, longId: longId, claimsData: claimsData }
};
};
function onUpdateChannelClaims(channelKey, name, longId, page) {
return {
type: actions.CHANNEL_CLAIMS_UPDATE_ASYNC,
data: { channelKey: channelKey, name: name, longId: longId, page: page }
};
};
function updateChannelClaims(channelListId, claimsData) {
return {
type: actions.CHANNEL_CLAIMS_UPDATE_SUCCESS,
data: { channelListId: channelListId, claimsData: claimsData }
};
};
// display a file
function fileRequested(name, claimId) {
return {
type: actions.FILE_REQUESTED,
data: { name: name, claimId: claimId }
};
};
function updateFileAvailability(status) {
return {
type: actions.FILE_AVAILABILITY_UPDATE,
data: status
};
};
function updateDisplayAssetError(error) {
return {
type: actions.DISPLAY_ASSET_ERROR,
data: error
};
};
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(89);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var site = _ref.site;
var defaultDescription = site.defaultDescription,
defaultThumbnail = site.defaultThumbnail,
siteDescription = site.description,
siteHost = site.host,
siteTitle = site.title,
siteTwitter = site.twitter;
return {
defaultDescription: defaultDescription,
defaultThumbnail: defaultThumbnail,
siteDescription: siteDescription,
siteHost: siteHost,
siteTitle: siteTitle,
siteTwitter: siteTwitter
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 10 */
/***/ (function(module, exports) {
module.exports = require("prop-types");
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
exports.default = request;
__webpack_require__(96);
/**
* Parses the JSON returned by a network request
*
* @param {object} response A response from a network request
*
* @return {object} The parsed JSON from the request
*/
function parseJSON(response) {
if (response.status === 204 || response.status === 205) {
return null;
}
return response.json();
}
/**
* Parses the status returned by a network request
*
* @param {object} response A response from a network request
* @param {object} response The parsed JSON from the network request
*
* @return {object | undefined} Returns object with status and statusText, or undefined
*/
function checkStatus(response, jsonResponse) {
if (response.status >= 200 && response.status < 300) {
return jsonResponse;
}
var error = new Error(jsonResponse.message);
error.response = response;
throw error;
}
/**
* Requests a URL, returning a promise
*
* @param {string} url The URL we want to request
* @param {object} [options] The options we want to pass to "fetch"
*
* @return {object} The response data
*/
function request(url, options) {
return fetch(url, options).then(function (response) {
return Promise.all([response, parseJSON(response)]);
}).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
response = _ref2[0],
jsonResponse = _ref2[1];
return checkStatus(response, jsonResponse);
});
}
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
// request actions
var HANDLE_SHOW_URI = exports.HANDLE_SHOW_URI = 'HANDLE_SHOW_URI';
var REQUEST_ERROR = exports.REQUEST_ERROR = 'REQUEST_ERROR';
var REQUEST_UPDATE = exports.REQUEST_UPDATE = 'REQUEST_UPDATE';
var ASSET_REQUEST_NEW = exports.ASSET_REQUEST_NEW = 'ASSET_REQUEST_NEW';
var CHANNEL_REQUEST_NEW = exports.CHANNEL_REQUEST_NEW = 'CHANNEL_REQUEST_NEW';
var REQUEST_LIST_ADD = exports.REQUEST_LIST_ADD = 'REQUEST_LIST_ADD';
// asset actions
var ASSET_ADD = exports.ASSET_ADD = 'ASSET_ADD';
// channel actions
var CHANNEL_ADD = exports.CHANNEL_ADD = 'CHANNEL_ADD';
var CHANNEL_CLAIMS_UPDATE_ASYNC = exports.CHANNEL_CLAIMS_UPDATE_ASYNC = 'CHANNEL_CLAIMS_UPDATE_ASYNC';
var CHANNEL_CLAIMS_UPDATE_SUCCESS = exports.CHANNEL_CLAIMS_UPDATE_SUCCESS = 'CHANNEL_CLAIMS_UPDATE_SUCCESS';
// asset/file display actions
var FILE_REQUESTED = exports.FILE_REQUESTED = 'FILE_REQUESTED';
var FILE_AVAILABILITY_UPDATE = exports.FILE_AVAILABILITY_UPDATE = 'FILE_AVAILABILITY_UPDATE';
var DISPLAY_ASSET_ERROR = exports.DISPLAY_ASSET_ERROR = 'DISPLAY_ASSET_ERROR';
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var selectAsset = exports.selectAsset = function selectAsset(show) {
var request = show.requestList[show.request.id];
var assetKey = request.key;
return show.assetList[assetKey];
};
var selectShowState = exports.selectShowState = function selectShowState(state) {
return state.show;
};
/***/ }),
/* 14 */
/***/ (function(module, exports) {
module.exports = require("react-helmet");
/***/ }),
/* 15 */
/***/ (function(module, exports) {
module.exports = require("redux-saga/effects");
/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var axios = __webpack_require__(63);
var logger = __webpack_require__(2);
var _require = __webpack_require__(64),
_require$api = _require.api,
apiHost = _require$api.apiHost,
apiPort = _require$api.apiPort;
var lbryApiUri = 'http://' + apiHost + ':' + apiPort;
var _require2 = __webpack_require__(17),
chooseGaLbrynetPublishLabel = _require2.chooseGaLbrynetPublishLabel,
sendGATimingEvent = _require2.sendGATimingEvent;
var handleLbrynetResponse = function handleLbrynetResponse(_ref, resolve, reject) {
var data = _ref.data;
logger.debug('lbry api data:', data);
if (data.result) {
// check for an error
if (data.result.error) {
logger.debug('Lbrynet api error:', data.result.error);
reject(new Error(data.result.error));
return;
};
resolve(data.result);
return;
}
// fallback in case it just timed out
reject(JSON.stringify(data));
};
module.exports = {
publishClaim: function publishClaim(publishParams) {
logger.debug('lbryApi >> Publishing claim to "' + publishParams.name + '"');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'publish',
params: publishParams
}).then(function (response) {
sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now());
handleLbrynetResponse(response, resolve, reject);
}).catch(function (error) {
reject(error);
});
});
},
getClaim: function getClaim(uri) {
logger.debug('lbryApi >> Getting Claim for "' + uri + '"');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'get',
params: { uri: uri, timeout: 20 }
}).then(function (response) {
sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());
handleLbrynetResponse(response, resolve, reject);
}).catch(function (error) {
reject(error);
});
});
},
getClaimList: function getClaimList(claimName) {
logger.debug('lbryApi >> Getting claim_list for "' + claimName + '"');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'claim_list',
params: { name: claimName }
}).then(function (response) {
sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now());
handleLbrynetResponse(response, resolve, reject);
}).catch(function (error) {
reject(error);
});
});
},
resolveUri: function resolveUri(uri) {
logger.debug('lbryApi >> Resolving URI for "' + uri + '"');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'resolve',
params: { uri: uri }
}).then(function (_ref2) {
var data = _ref2.data;
sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now());
if (data.result[uri].error) {
// check for errors
reject(data.result[uri].error);
} else {
// if no errors, resolve
resolve(data.result[uri]);
}
}).catch(function (error) {
reject(error);
});
});
},
getDownloadDirectory: function getDownloadDirectory() {
logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'settings_get'
}).then(function (_ref3) {
var data = _ref3.data;
sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now());
if (data.result) {
resolve(data.result.download_directory);
} else {
return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.');
}
}).catch(function (error) {
logger.error('Lbrynet Error:', error);
resolve('/home/lbry/Downloads/');
});
});
},
createChannel: function createChannel(name) {
logger.debug('lbryApi >> Creating channel for ' + name + '...');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'channel_new',
params: {
channel_name: name,
amount: 0.1
}
}).then(function (response) {
sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now());
handleLbrynetResponse(response, resolve, reject);
}).catch(function (error) {
reject(error);
});
});
}
};
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(2);
var ua = __webpack_require__(65);
var _require = __webpack_require__(5),
googleId = _require.analytics.googleId,
title = _require.details.title;
function createServeEventParams(headers, ip, originalUrl) {
return {
eventCategory: 'client requests',
eventAction: 'serve request',
eventLabel: originalUrl,
ipOverride: ip,
userAgentOverride: headers['user-agent']
};
};
function createPublishTimingEventParams(category, variable, label, startTime, endTime) {
var duration = endTime - startTime;
return {
userTimingCategory: category,
userTimingVariableName: variable,
userTimingTime: duration,
userTimingLabel: label
};
};
function sendGoogleAnalyticsEvent(ip, params) {
var visitorId = ip.replace(/\./g, '-');
var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });
visitor.event(params, function (err) {
if (err) {
logger.error('Google Analytics Event Error >>', err);
}
});
};
function sendGoogleAnalyticsTiming(visitorId, params) {
var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });
visitor.timing(params, function (err) {
if (err) {
logger.error('Google Analytics Event Error >>', err);
}
logger.debug('Timing event successfully sent to google analytics');
});
};
module.exports = {
sendGAServeEvent: function sendGAServeEvent(headers, ip, originalUrl) {
var params = createServeEventParams(headers, ip, originalUrl);
sendGoogleAnalyticsEvent(ip, params);
},
sendGATimingEvent: function sendGATimingEvent(category, variable, label, startTime, endTime) {
var params = createPublishTimingEventParams(category, variable, label, startTime, endTime);
sendGoogleAnalyticsTiming(title, params);
},
chooseGaLbrynetPublishLabel: function chooseGaLbrynetPublishLabel(_ref) {
var channelName = _ref.channel_name,
channelId = _ref.channel_id;
return channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM';
}
};
/***/ }),
/* 18 */
/***/ (function(module, exports) {
module.exports = require("redux");
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.updateLoggedInChannel = updateLoggedInChannel;
var _channel_action_types = __webpack_require__(34);
var actions = _interopRequireWildcard(_channel_action_types);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
// export action creators
function updateLoggedInChannel(name, shortId, longId) {
return {
type: actions.CHANNEL_UPDATE,
data: {
name: name,
shortId: shortId,
longId: longId
}
};
};
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(10);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _ActiveStatusBar = __webpack_require__(118);
var _ActiveStatusBar2 = _interopRequireDefault(_ActiveStatusBar);
var _InactiveStatusBar = __webpack_require__(119);
var _InactiveStatusBar2 = _interopRequireDefault(_InactiveStatusBar);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ProgressBar = function (_React$Component) {
_inherits(ProgressBar, _React$Component);
function ProgressBar(props) {
_classCallCheck(this, ProgressBar);
var _this = _possibleConstructorReturn(this, (ProgressBar.__proto__ || Object.getPrototypeOf(ProgressBar)).call(this, props));
_this.state = {
bars: [],
index: 0,
incrementer: 1
};
_this.createBars = _this.createBars.bind(_this);
_this.startProgressBar = _this.startProgressBar.bind(_this);
_this.updateProgressBar = _this.updateProgressBar.bind(_this);
_this.stopProgressBar = _this.stopProgressBar.bind(_this);
return _this;
}
_createClass(ProgressBar, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.createBars();
this.startProgressBar();
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.stopProgressBar();
}
}, {
key: 'createBars',
value: function createBars() {
var bars = [];
for (var i = 0; i <= this.props.size; i++) {
bars.push({ isActive: false });
}
this.setState({ bars: bars });
}
}, {
key: 'startProgressBar',
value: function startProgressBar() {
this.updateInterval = setInterval(this.updateProgressBar.bind(this), 300);
}
}, {
key: 'updateProgressBar',
value: function updateProgressBar() {
var index = this.state.index;
var incrementer = this.state.incrementer;
var bars = this.state.bars;
// flip incrementer if necessary, to stay in bounds
if (index < 0 || index > this.props.size) {
incrementer = incrementer * -1;
index += incrementer;
}
// update the indexed bar
if (incrementer > 0) {
bars[index].isActive = true;
} else {
bars[index].isActive = false;
};
// increment index
index += incrementer;
// update state
this.setState({
bars: bars,
incrementer: incrementer,
index: index
});
}
}, {
key: 'stopProgressBar',
value: function stopProgressBar() {
clearInterval(this.updateInterval);
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
this.state.bars.map(function (bar, index) {
return bar.isActive ? _react2.default.createElement(_ActiveStatusBar2.default, { key: index }) : _react2.default.createElement(_InactiveStatusBar2.default, { key: index });
})
);
}
}]);
return ProgressBar;
}(_react2.default.Component);
;
ProgressBar.propTypes = {
size: _propTypes2.default.number.isRequired
};
exports.default = ProgressBar;
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(10);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _NavBar = __webpack_require__(7);
var _NavBar2 = _interopRequireDefault(_NavBar);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ErrorPage = function (_React$Component) {
_inherits(ErrorPage, _React$Component);
function ErrorPage() {
_classCallCheck(this, ErrorPage);
return _possibleConstructorReturn(this, (ErrorPage.__proto__ || Object.getPrototypeOf(ErrorPage)).apply(this, arguments));
}
_createClass(ErrorPage, [{
key: 'render',
value: function render() {
var error = this.props.error;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(_NavBar2.default, null),
_react2.default.createElement(
'div',
{ className: 'row row--padded' },
_react2.default.createElement(
'p',
null,
error
)
)
);
}
}]);
return ErrorPage;
}(_react2.default.Component);
;
ErrorPage.propTypes = {
error: _propTypes2.default.string.isRequired
};
exports.default = ErrorPage;
/***/ }),
/* 22 */
/***/ (function(module, exports) {
module.exports = require("passport");
/***/ }),
/* 23 */
/***/ (function(module, exports) {
module.exports = require("passport-local");
/***/ }),
/* 24 */
/***/ (function(module, exports) {
module.exports = require("sequelize");
/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = {
returnShortId: function returnShortId(claimsArray, longId) {
var claimIndex = void 0;
var shortId = longId.substring(0, 1); // default short id is the first letter
var shortIdLength = 0;
// find the index of this claim id
claimIndex = claimsArray.findIndex(function (element) {
return element.claimId === longId;
});
if (claimIndex < 0) {
throw new Error('claim id not found in claims list');
}
// get an array of all claims with lower height
var possibleMatches = claimsArray.slice(0, claimIndex);
// remove certificates with the same prefixes until none are left.
while (possibleMatches.length > 0) {
shortIdLength += 1;
shortId = longId.substring(0, shortIdLength);
possibleMatches = possibleMatches.filter(function (element) {
return element.claimId && element.claimId.substring(0, shortIdLength) === shortId;
});
}
return shortId;
}
};
/***/ }),
/* 26 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(2);
var fs = __webpack_require__(79);
var _require = __webpack_require__(5),
details = _require.details,
publishing = _require.publishing;
module.exports = {
parsePublishApiRequestBody: function parsePublishApiRequestBody(_ref) {
var name = _ref.name,
nsfw = _ref.nsfw,
license = _ref.license,
title = _ref.title,
description = _ref.description,
thumbnail = _ref.thumbnail;
// validate name
if (!name) {
throw new Error('no name field found in request');
}
var invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name);
if (invalidNameCharacters) {
throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and "-"');
}
// optional parameters
nsfw = nsfw === 'true';
license = license || null;
title = title || null;
description = description || null;
thumbnail = thumbnail || null;
// return results
return {
name: name,
nsfw: nsfw,
license: license,
title: title,
description: description,
thumbnail: thumbnail
};
},
parsePublishApiRequestFiles: function parsePublishApiRequestFiles(_ref2) {
var file = _ref2.file,
thumbnail = _ref2.thumbnail;
// make sure a file was provided
if (!file) {
throw new Error('no file with key of [file] found in request');
}
if (!file.path) {
throw new Error('no file path found');
}
if (!file.type) {
throw new Error('no file type found');
}
if (!file.size) {
throw new Error('no file type found');
}
// validate the file name
if (/'/.test(file.name)) {
throw new Error('apostrophes are not allowed in the file name');
}
// validate the file
module.exports.validateFileTypeAndSize(file);
// return results
return {
fileName: file.name,
filePath: file.path,
fileType: file.type,
thumbnailFileName: thumbnail ? thumbnail.name : null,
thumbnailFilePath: thumbnail ? thumbnail.path : null,
thumbnailFileType: thumbnail ? thumbnail.type : null
};
},
validateFileTypeAndSize: function validateFileTypeAndSize(file) {
// check file type and size
switch (file.type) {
case 'image/jpeg':
case 'image/jpg':
case 'image/png':
if (file.size > 10000000) {
logger.debug('publish > file validation > .jpeg/.jpg/.png was too big');
throw new Error('Sorry, images are limited to 10 megabytes.');
}
break;
case 'image/gif':
if (file.size > 50000000) {
logger.debug('publish > file validation > .gif was too big');
throw new Error('Sorry, .gifs are limited to 50 megabytes.');
}
break;
case 'video/mp4':
if (file.size > 50000000) {
logger.debug('publish > file validation > .mp4 was too big');
throw new Error('Sorry, videos are limited to 50 megabytes.');
}
break;
default:
logger.debug('publish > file validation > unrecognized file type');
throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');
}
return file;
},
createBasicPublishParams: function createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail) {
logger.debug('Creating Publish Parameters');
// provide defaults for title
if (title === null || title.trim() === '') {
title = name;
}
// provide default for description
if (description === null || description.trim() === '') {
description = '';
}
// provide default for license
if (license === null || license.trim() === '') {
license = ' '; // default to empty string
}
// create the publish params
var publishParams = {
name: name,
file_path: filePath,
bid: 0.01,
metadata: {
description: description,
title: title,
author: details.title,
language: 'en',
license: license,
nsfw: nsfw
},
claim_address: publishing.primaryClaimAddress
};
// add thumbnail to channel if video
if (thumbnail) {
publishParams['metadata']['thumbnail'] = thumbnail;
}
return publishParams;
},
createThumbnailPublishParams: function createThumbnailPublishParams(thumbnailFilePath, claimName, license, nsfw) {
if (!thumbnailFilePath) {
return;
}
logger.debug('Creating Thumbnail Publish Parameters');
// create the publish params
return {
name: claimName + '-thumb',
file_path: thumbnailFilePath,
bid: 0.01,
metadata: {
title: claimName + ' thumbnail',
description: 'a thumbnail for ' + claimName,
author: details.title,
language: 'en',
license: license,
nsfw: nsfw
},
claim_address: publishing.primaryClaimAddress,
channel_name: publishing.thumbnailChannel,
channel_id: publishing.thumbnailChannelId
};
},
deleteTemporaryFile: function deleteTemporaryFile(filePath) {
fs.unlink(filePath, function (err) {
if (err) {
logger.error('error deleting temporary file ' + filePath);
throw err;
}
logger.debug('successfully deleted ' + filePath);
});
},
addGetResultsToFileData: function addGetResultsToFileData(fileInfo, getResult) {
fileInfo.fileName = getResult.file_name;
fileInfo.filePath = getResult.download_path;
return fileInfo;
},
createFileData: function createFileData(_ref3) {
var name = _ref3.name,
claimId = _ref3.claimId,
outpoint = _ref3.outpoint,
height = _ref3.height,
address = _ref3.address,
nsfw = _ref3.nsfw,
contentType = _ref3.contentType;
return {
name: name,
claimId: claimId,
outpoint: outpoint,
height: height,
address: address,
fileName: '',
filePath: '',
fileType: contentType,
nsfw: nsfw
};
}
};
/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var logger = __webpack_require__(2);
module.exports = {
handleErrorResponse: function handleErrorResponse(originalUrl, ip, error, res) {
logger.error('Error on ' + originalUrl, module.exports.useObjectPropertiesIfNoKeys(error));
var _module$exports$retur = module.exports.returnErrorMessageAndStatus(error),
_module$exports$retur2 = _slicedToArray(_module$exports$retur, 2),
status = _module$exports$retur2[0],
message = _module$exports$retur2[1];
res.status(status).json(module.exports.createErrorResponsePayload(status, message));
},
returnErrorMessageAndStatus: function returnErrorMessageAndStatus(error) {
var status = void 0,
message = void 0;
// check for daemon being turned off
if (error.code === 'ECONNREFUSED') {
status = 503;
message = 'Connection refused. The daemon may not be running.';
// fallback for everything else
} else {
status = 400;
if (error.message) {
message = error.message;
} else {
message = error;
};
};
return [status, message];
},
useObjectPropertiesIfNoKeys: function useObjectPropertiesIfNoKeys(err) {
if (Object.keys(err).length === 0) {
var newErrorObject = {};
Object.getOwnPropertyNames(err).forEach(function (key) {
newErrorObject[key] = err[key];
});
return newErrorObject;
}
return err;
},
createErrorResponsePayload: function createErrorResponsePayload(status, message) {
return {
status: status,
success: false,
message: message
};
}
};
/***/ }),
/* 28 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var db = __webpack_require__(6);
var logger = __webpack_require__(2);
var _require = __webpack_require__(81),
returnPaginatedChannelClaims = _require.returnPaginatedChannelClaims;
var NO_CHANNEL = 'NO_CHANNEL';
var NO_CLAIM = 'NO_CLAIM';
var NO_FILE = 'NO_FILE';
module.exports = {
getClaimId: function getClaimId(channelName, channelClaimId, name, claimId) {
if (channelName) {
return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);
} else {
return module.exports.getClaimIdByClaim(name, claimId);
}
},
getClaimIdByClaim: function getClaimIdByClaim(claimName, claimId) {
logger.debug('getClaimIdByClaim(' + claimName + ', ' + claimId + ')');
return new Promise(function (resolve, reject) {
db.Claim.getLongClaimId(claimName, claimId).then(function (longClaimId) {
if (!longClaimId) {
resolve(NO_CLAIM);
}
resolve(longClaimId);
}).catch(function (error) {
reject(error);
});
});
},
getClaimIdByChannel: function getClaimIdByChannel(channelName, channelClaimId, claimName) {
logger.debug('getClaimIdByChannel(' + channelName + ', ' + channelClaimId + ', ' + claimName + ')');
return new Promise(function (resolve, reject) {
db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id
.then(function (longChannelId) {
if (!longChannelId) {
return [null, null];
}
return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id
}).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
longChannelId = _ref2[0],
longClaimId = _ref2[1];
if (!longChannelId) {
return resolve(NO_CHANNEL);
}
if (!longClaimId) {
return resolve(NO_CLAIM);
}
resolve(longClaimId);
}).catch(function (error) {
reject(error);
});
});
},
getChannelData: function getChannelData(channelName, channelClaimId, page) {
return new Promise(function (resolve, reject) {
// 1. get the long channel Id (make sure channel exists)
db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {
if (!longChannelClaimId) {
return [null, null, null];
}
// 2. get the short ID and all claims for that channel
return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);
}).then(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 2),
longChannelClaimId = _ref4[0],
shortChannelClaimId = _ref4[1];
if (!longChannelClaimId) {
return resolve(NO_CHANNEL);
}
// 3. return all the channel information
resolve({
channelName: channelName,
longChannelClaimId: longChannelClaimId,
shortChannelClaimId: shortChannelClaimId
});
}).catch(function (error) {
reject(error);
});
});
},
getChannelClaims: function getChannelClaims(channelName, channelClaimId, page) {
return new Promise(function (resolve, reject) {
// 1. get the long channel Id (make sure channel exists)
db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {
if (!longChannelClaimId) {
return [null, null, null];
}
// 2. get the short ID and all claims for that channel
return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);
}).then(function (_ref5) {
var _ref6 = _slicedToArray(_ref5, 2),
longChannelClaimId = _ref6[0],
channelClaimsArray = _ref6[1];
if (!longChannelClaimId) {
return resolve(NO_CHANNEL);
}
// 3. format the data for the view, including pagination
var paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);
// 4. return all the channel information and contents
resolve(paginatedChannelViewData);
}).catch(function (error) {
reject(error);
});
});
},
getLocalFileRecord: function getLocalFileRecord(claimId, name) {
return db.File.findOne({ where: { claimId: claimId, name: name } }).then(function (file) {
if (!file) {
return NO_FILE;
}
return file.dataValues;
});
}
};
/***/ }),
/* 29 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _server = __webpack_require__(30);
var _redux = __webpack_require__(18);
var _index = __webpack_require__(31);
var _index2 = _interopRequireDefault(_index);
var _reactRedux = __webpack_require__(1);
var _reactRouterDom = __webpack_require__(3);
var _index3 = __webpack_require__(36);
var _index4 = _interopRequireDefault(_index3);
var _app = __webpack_require__(37);
var _app2 = _interopRequireDefault(_app);
var _renderFullPage = __webpack_require__(43);
var _renderFullPage2 = _interopRequireDefault(_renderFullPage);
var _reactHelmet = __webpack_require__(14);
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
module.exports = function (req, res) {
var context = {};
// create a new Redux store instance
var store = (0, _redux.createStore)(_index2.default);
// render component to a string
var html = (0, _server.renderToString)(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(
_reactRouterDom.StaticRouter,
{ location: req.url, context: context },
_react2.default.createElement(
_index4.default,
null,
_react2.default.createElement(_app2.default, null)
)
)
));
// get head tags from helmet
var helmet = _reactHelmet2.default.renderStatic();
// check for a redirect
if (context.url) {
// Somewhere a `<Redirect>` was rendered
return res.redirect(301, context.url);
} else {}
// we're good, send the response
// get the initial state from our Redux store
var preloadedState = store.getState();
// send the rendered page back to the client
res.send((0, _renderFullPage2.default)(helmet, html, preloadedState));
};
/***/ }),
/* 30 */
/***/ (function(module, exports) {
module.exports = require("react-dom/server");
/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _redux = __webpack_require__(18);
var _publish = __webpack_require__(83);
var _publish2 = _interopRequireDefault(_publish);
var _channel = __webpack_require__(84);
var _channel2 = _interopRequireDefault(_channel);
var _show = __webpack_require__(85);
var _show2 = _interopRequireDefault(_show);
var _site = __webpack_require__(86);
var _site2 = _interopRequireDefault(_site);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = (0, _redux.combineReducers)({
channel: _channel2.default,
publish: _publish2.default,
show: _show2.default,
site: _site2.default
});
/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var FILE_SELECTED = exports.FILE_SELECTED = 'FILE_SELECTED';
var FILE_CLEAR = exports.FILE_CLEAR = 'FILE_CLEAR';
var METADATA_UPDATE = exports.METADATA_UPDATE = 'METADATA_UPDATE';
var CLAIM_UPDATE = exports.CLAIM_UPDATE = 'CLAIM_UPDATE';
var SET_PUBLISH_IN_CHANNEL = exports.SET_PUBLISH_IN_CHANNEL = 'SET_PUBLISH_IN_CHANNEL';
var PUBLISH_STATUS_UPDATE = exports.PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE';
var ERROR_UPDATE = exports.ERROR_UPDATE = 'ERROR_UPDATE';
var SELECTED_CHANNEL_UPDATE = exports.SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE';
var TOGGLE_METADATA_INPUTS = exports.TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS';
var THUMBNAIL_NEW = exports.THUMBNAIL_NEW = 'THUMBNAIL_NEW';
var PUBLISH_START = exports.PUBLISH_START = 'PUBLISH_START';
/***/ }),
/* 33 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var LOGIN = exports.LOGIN = 'Existing';
var CREATE = exports.CREATE = 'New';
/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var CHANNEL_UPDATE = exports.CHANNEL_UPDATE = 'CHANNEL_UPDATE';
/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var LOCAL_CHECK = exports.LOCAL_CHECK = 'LOCAL_CHECK';
var UNAVAILABLE = exports.UNAVAILABLE = 'UNAVAILABLE';
var ERROR = exports.ERROR = 'ERROR';
var AVAILABLE = exports.AVAILABLE = 'AVAILABLE';
/***/ }),
/* 36 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactGa = __webpack_require__(87);
var _reactGa2 = _interopRequireDefault(_reactGa);
var _reactRouterDom = __webpack_require__(3);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var _require = __webpack_require__(5),
googleId = _require.analytics.googleId;
_reactGa2.default.initialize(googleId);
var GAListener = function (_React$Component) {
_inherits(GAListener, _React$Component);
function GAListener() {
_classCallCheck(this, GAListener);
return _possibleConstructorReturn(this, (GAListener.__proto__ || Object.getPrototypeOf(GAListener)).apply(this, arguments));
}
_createClass(GAListener, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.sendPageView(this.props.history.location);
this.props.history.listen(this.sendPageView);
}
}, {
key: 'sendPageView',
value: function sendPageView(location) {
_reactGa2.default.set({ page: location.pathname });
_reactGa2.default.pageview(location.pathname);
}
}, {
key: 'render',
value: function render() {
return this.props.children;
}
}]);
return GAListener;
}(_react2.default.Component);
exports.default = (0, _reactRouterDom.withRouter)(GAListener);
/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactRouterDom = __webpack_require__(3);
var _HomePage = __webpack_require__(88);
var _HomePage2 = _interopRequireDefault(_HomePage);
var _AboutPage = __webpack_require__(125);
var _AboutPage2 = _interopRequireDefault(_AboutPage);
var _LoginPage = __webpack_require__(126);
var _LoginPage2 = _interopRequireDefault(_LoginPage);
var _ShowPage = __webpack_require__(128);
var _ShowPage2 = _interopRequireDefault(_ShowPage);
var _FourOhFourPage = __webpack_require__(145);
var _FourOhFourPage2 = _interopRequireDefault(_FourOhFourPage);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// or use the provided local homepage
var App = function App() {
return _react2.default.createElement(
_reactRouterDom.Switch,
null,
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/', component: _HomePage2.default }),
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/about', component: _AboutPage2.default }),
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/login', component: _LoginPage2.default }),
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/:identifier/:claim', component: _ShowPage2.default }),
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/:claim', component: _ShowPage2.default }),
_react2.default.createElement(_reactRouterDom.Route, { component: _FourOhFourPage2.default })
);
};
exports.default = App;
/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _publish = __webpack_require__(4);
var _view = __webpack_require__(99);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var publish = _ref.publish;
return {
file: publish.file,
thumbnail: publish.thumbnail,
fileError: publish.error.file
};
};
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
selectFile: function selectFile(file) {
dispatch((0, _publish.selectFile)(file));
},
setFileError: function setFileError(value) {
dispatch((0, _publish.clearFile)());
dispatch((0, _publish.updateError)('file', value));
}
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 39 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _channel = __webpack_require__(19);
var _view = __webpack_require__(116);
var _view2 = _interopRequireDefault(_view);
var _publish = __webpack_require__(4);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
onChannelLogin: function onChannelLogin(name, shortId, longId) {
dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));
dispatch((0, _publish.updateSelectedChannel)(name));
}
};
};
exports.default = (0, _reactRedux.connect)(null, mapDispatchToProps)(_view2.default);
/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _channel = __webpack_require__(19);
var _view = __webpack_require__(117);
var _view2 = _interopRequireDefault(_view);
var _publish = __webpack_require__(4);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
onChannelLogin: function onChannelLogin(name, shortId, longId) {
dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));
dispatch((0, _publish.updateSelectedChannel)(name));
}
};
};
exports.default = (0, _reactRedux.connect)(null, mapDispatchToProps)(_view2.default);
/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var CHANNEL = exports.CHANNEL = 'CHANNEL';
var ASSET_LITE = exports.ASSET_LITE = 'ASSET_LITE';
var ASSET_DETAILS = exports.ASSET_DETAILS = 'ASSET_DETAILS';
/***/ }),
/* 42 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(132);
var _view2 = _interopRequireDefault(_view);
var _show = __webpack_require__(8);
var _show2 = __webpack_require__(13);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var show = _ref.show;
// select error and status
var error = show.displayAsset.error;
var status = show.displayAsset.status;
// select asset
var asset = (0, _show2.selectAsset)(show);
// return props
return {
error: error,
status: status,
asset: asset
};
};
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
onFileRequest: function onFileRequest(name, claimId) {
dispatch((0, _show.fileRequested)(name, claimId));
}
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 43 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function (helmet, html, preloadedState) {
// take the html and preloadedState and return the full page
return '\n <!DOCTYPE html>\n <html lang="en" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">\n <head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no">\n <meta http-equiv="X-UA-Compatible" content="ie=edge">\n <!--helmet-->\n ' + helmet.title.toString() + '\n ' + helmet.meta.toString() + '\n ' + helmet.link.toString() + '\n <!--style sheets-->\n <link rel="stylesheet" href="/assets/css/reset.css" type="text/css">\n <link rel="stylesheet" href="/assets/css/general.css" type="text/css">\n <link rel="stylesheet" href="/assets/css/mediaQueries.css" type="text/css">\n <!--google font-->\n <link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">\n </head>\n <body id="main-body">\n <div class="row row--tall flex-container--column">\n <div id="react-app" class="row row--tall flex-container--column">' + html + '</div>\n </div>\n <script>\n window.__PRELOADED_STATE__ = ' + JSON.stringify(preloadedState).replace(/</g, '\\<') + '\n </script>\n <script src="/bundle/bundle.js"></script>\n </body>\n </html>\n ';
};
/***/ }),
/* 44 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var selectSiteState = exports.selectSiteState = function selectSiteState(state) {
return state.site;
};
var selectSiteHost = exports.selectSiteHost = function selectSiteHost(state) {
return state.site.host;
};
/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(46);
__webpack_require__(47);
module.exports = __webpack_require__(48);
/***/ }),
/* 46 */
/***/ (function(module, exports) {
module.exports = require("babel-polyfill");
/***/ }),
/* 47 */
/***/ (function(module, exports) {
module.exports = require("whatwg-fetch");
/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// app dependencies
var express = __webpack_require__(49);
var bodyParser = __webpack_require__(50);
var expressHandlebars = __webpack_require__(51);
var Handlebars = __webpack_require__(52);
var helmet = __webpack_require__(53);
var passport = __webpack_require__(22);
var _require = __webpack_require__(54),
serializeSpeechUser = _require.serializeSpeechUser,
deserializeSpeechUser = _require.deserializeSpeechUser;
var cookieSession = __webpack_require__(55);
var http = __webpack_require__(56);
// logging dependencies
var logger = __webpack_require__(2);
// configure logger
__webpack_require__(57)(logger);
__webpack_require__(59)(logger);
var _require2 = __webpack_require__(5),
sessionKey = _require2.auth.sessionKey,
PORT = _require2.details.port;
// create an Express application
var app = express();
// trust the proxy to get ip address for us
app.enable('trust proxy');
// add middleware
app.use(helmet()); // set HTTP headers to protect against well-known web vulnerabilties
app.use(express.static(__dirname + '/public')); // 'express.static' to serve static files from public directory
app.use(bodyParser.json()); // 'body parser' for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded
app.use(function (req, res, next) {
// custom logging middleware to log all incoming http requests
logger.verbose('Request on ' + req.originalUrl + ' from ' + req.ip);
next();
});
// configure passport
passport.serializeUser(serializeSpeechUser);
passport.deserializeUser(deserializeSpeechUser);
var localSignupStrategy = __webpack_require__(62);
var localLoginStrategy = __webpack_require__(74);
passport.use('local-signup', localSignupStrategy);
passport.use('local-login', localLoginStrategy);
// initialize passport
app.use(cookieSession({
name: 'session',
keys: [sessionKey],
maxAge: 24 * 60 * 60 * 1000 // i.e. 24 hours
}));
app.use(passport.initialize());
app.use(passport.session());
// configure handlebars & register it with express app
var hbs = expressHandlebars.create({
defaultLayout: 'embed',
handlebars: Handlebars
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
// set the routes on the app
__webpack_require__(75)(app);
__webpack_require__(76)(app);
__webpack_require__(82)(app);
__webpack_require__(147)(app);
__webpack_require__(158)(app);
// create server
var server = http.Server(app);
// sync sequelize
var db = __webpack_require__(6);
db.sequelize.sync()
// start the server
.then(function () {
server.listen(PORT, function () {
logger.info('Server is listening on PORT ' + PORT);
});
}).catch(function (error) {
logger.error('Startup Error:', error);
});
/***/ }),
/* 49 */
/***/ (function(module, exports) {
module.exports = require("express");
/***/ }),
/* 50 */
/***/ (function(module, exports) {
module.exports = require("body-parser");
/***/ }),
/* 51 */
/***/ (function(module, exports) {
module.exports = require("express-handlebars");
/***/ }),
/* 52 */
/***/ (function(module, exports) {
module.exports = require("handlebars");
/***/ }),
/* 53 */
/***/ (function(module, exports) {
module.exports = require("helmet");
/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(2);
module.exports = {
serializeSpeechUser: function serializeSpeechUser(user, done) {
// returns user data to be serialized into session
logger.debug('serializing user');
done(null, user);
},
deserializeSpeechUser: function deserializeSpeechUser(user, done) {
// deserializes session and populates additional info to req.user
logger.debug('deserializing user');
done(null, user);
}
};
/***/ }),
/* 55 */
/***/ (function(module, exports) {
module.exports = require("cookie-session");
/***/ }),
/* 56 */
/***/ (function(module, exports) {
module.exports = require("http");
/***/ }),
/* 57 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(58),
logLevel = _require.logLevel;
module.exports = function (winston) {
// configure
winston.configure({
transports: [new winston.transports.Console({
level: logLevel,
timestamp: false,
colorize: true,
prettyPrint: true,
handleExceptions: true,
humanReadableUnhandledException: true
})]
});
// test all the log levels
winston.error('Level 0');
winston.warn('Level 1');
winston.info('Level 2');
winston.verbose('Level 3');
winston.debug('Level 4');
winston.silly('Level 5');
};
/***/ }),
/* 58 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var loggerConfig = {
logLevel: 'debug' // options: silly, debug, verbose, info
};
module.exports = loggerConfig;
/***/ }),
/* 59 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var winstonSlackWebHook = __webpack_require__(60).SlackWebHook;
var slackConfig = __webpack_require__(61);
module.exports = function (winston) {
var slackWebHook = slackConfig.slackWebHook,
slackErrorChannel = slackConfig.slackErrorChannel,
slackInfoChannel = slackConfig.slackInfoChannel;
if (slackWebHook) {
// add a transport for errors to slack
if (slackErrorChannel) {
winston.add(winstonSlackWebHook, {
name: 'slack-errors-transport',
level: 'warn',
webhookUrl: slackWebHook,
channel: slackErrorChannel,
username: 'spee.ch',
iconEmoji: ':face_with_head_bandage:'
});
};
if (slackInfoChannel) {
winston.add(winstonSlackWebHook, {
name: 'slack-info-transport',
level: 'info',
webhookUrl: slackWebHook,
channel: slackInfoChannel,
username: 'spee.ch',
iconEmoji: ':nerd_face:'
});
};
// send test message
winston.error('Slack "error" logging is online.');
winston.info('Slack "info" logging is online.');
} else {
winston.warn('Slack logging is not enabled because no slackWebHook config var provided.');
}
};
/***/ }),
/* 60 */
/***/ (function(module, exports) {
module.exports = require("winston-slack-webhook");
/***/ }),
/* 61 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
function SlackConfig() {
this.slackWebHook = 'default';
this.slackErrorChannel = 'default';
this.slackInfoChannel = 'default';
};
module.exports = new SlackConfig();
/***/ }),
/* 62 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var PassportLocalStrategy = __webpack_require__(23).Strategy;
var lbryApi = __webpack_require__(16);
var logger = __webpack_require__(2);
var db = __webpack_require__(6);
module.exports = new PassportLocalStrategy({
usernameField: 'username',
passwordField: 'password'
}, function (username, password, done) {
logger.verbose('new channel signup request. user: ' + username + ' pass: ' + password + ' .');
var userInfo = {};
// server-side validaton of inputs (username, password)
// create the channel and retrieve the metadata
return lbryApi.createChannel('@' + username).then(function (tx) {
// create user record
var userData = {
userName: username,
password: password
};
logger.verbose('userData >', userData);
// create user record
var channelData = {
channelName: '@' + username,
channelClaimId: tx.claim_id
};
logger.verbose('channelData >', channelData);
// create certificate record
var certificateData = {
claimId: tx.claim_id,
name: '@' + username
// address,
};
logger.verbose('certificateData >', certificateData);
// save user and certificate to db
return Promise.all([db.User.create(userData), db.Channel.create(channelData), db.Certificate.create(certificateData)]);
}).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 3),
newUser = _ref2[0],
newChannel = _ref2[1],
newCertificate = _ref2[2];
logger.verbose('user and certificate successfully created');
// store the relevant newUser info to be passed back for req.User
userInfo['id'] = newUser.id;
userInfo['userName'] = newUser.userName;
userInfo['channelName'] = newChannel.channelName;
userInfo['channelClaimId'] = newChannel.channelClaimId;
// associate the instances
return Promise.all([newCertificate.setChannel(newChannel), newChannel.setUser(newUser)]);
}).then(function () {
logger.verbose('user and certificate successfully associated');
return db.Certificate.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName);
}).then(function (shortChannelId) {
userInfo['shortChannelId'] = shortChannelId;
return done(null, userInfo);
}).catch(function (error) {
logger.error('signup error', error);
return done(error);
});
});
/***/ }),
/* 63 */
/***/ (function(module, exports) {
module.exports = require("axios");
/***/ }),
/* 64 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var lbryConfig = {
api: {
apiHost: 'localhost',
apiPort: '5279'
}
};
module.exports = lbryConfig;
/***/ }),
/* 65 */
/***/ (function(module, exports) {
module.exports = require("universal-analytics");
/***/ }),
/* 66 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
function MysqlConfig() {
this.database = 'default';
this.username = 'default';
this.password = 'default';
};
module.exports = new MysqlConfig();
/***/ }),
/* 67 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(2);
var _require = __webpack_require__(25),
returnShortId = _require.returnShortId;
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING,
BOOLEAN = _ref.BOOLEAN,
INTEGER = _ref.INTEGER,
TEXT = _ref.TEXT,
DECIMAL = _ref.DECIMAL;
var Certificate = sequelize.define('Certificate', {
address: {
type: STRING,
default: null
},
amount: {
type: DECIMAL(19, 8),
default: null
},
claimId: {
type: STRING,
default: null
},
claimSequence: {
type: INTEGER,
default: null
},
decodedClaim: {
type: BOOLEAN,
default: null
},
depth: {
type: INTEGER,
default: null
},
effectiveAmount: {
type: DECIMAL(19, 8),
default: null
},
hasSignature: {
type: BOOLEAN,
default: null
},
height: {
type: INTEGER,
default: null
},
hex: {
type: TEXT('long'),
default: null
},
name: {
type: STRING,
default: null
},
nout: {
type: INTEGER,
default: null
},
txid: {
type: STRING,
default: null
},
validAtHeight: {
type: INTEGER,
default: null
},
outpoint: {
type: STRING,
default: null
},
valueVersion: {
type: STRING,
default: null
},
claimType: {
type: STRING,
default: null
},
certificateVersion: {
type: STRING,
default: null
},
keyType: {
type: STRING,
default: null
},
publicKey: {
type: TEXT('long'),
default: null
}
}, {
freezeTableName: true
});
Certificate.associate = function (db) {
Certificate.belongsTo(db.Channel, {
foreignKey: {
allowNull: true
}
});
};
Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {
var _this = this;
logger.debug('getShortChannelIdFromLongChannelId ' + channelName + ':' + longChannelId);
return new Promise(function (resolve, reject) {
_this.findAll({
where: { name: channelName },
order: [['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
throw new Error('No channel(s) found with that channel name');
default:
return resolve(returnShortId(result, longChannelId));
}
}).catch(function (error) {
reject(error);
});
});
};
Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {
var _this2 = this;
logger.debug('getLongChannelIdFromShortChannelId(' + channelName + ', ' + channelClaimId + ')');
return new Promise(function (resolve, reject) {
_this2.findAll({
where: {
name: channelName,
claimId: {
$like: channelClaimId + '%'
}
},
order: [['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
return resolve(null);
default:
// note results must be sorted
return resolve(result[0].claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Certificate.getLongChannelIdFromChannelName = function (channelName) {
var _this3 = this;
logger.debug('getLongChannelIdFromChannelName(' + channelName + ')');
return new Promise(function (resolve, reject) {
_this3.findAll({
where: { name: channelName },
order: [['effectiveAmount', 'DESC'], ['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
return resolve(null);
default:
return resolve(result[0].claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Certificate.validateLongChannelId = function (name, claimId) {
var _this4 = this;
logger.debug('validateLongChannelId(' + name + ', ' + claimId + ')');
return new Promise(function (resolve, reject) {
_this4.findOne({
where: { name: name, claimId: claimId }
}).then(function (result) {
if (!result) {
return resolve(null);
};
resolve(claimId);
}).catch(function (error) {
reject(error);
});
});
};
Certificate.getLongChannelId = function (channelName, channelClaimId) {
logger.debug('getLongChannelId(' + channelName + ', ' + channelClaimId + ')');
if (channelClaimId && channelClaimId.length === 40) {
// if a full channel id is provided
return this.validateLongChannelId(channelName, channelClaimId);
} else if (channelClaimId && channelClaimId.length < 40) {
// if a short channel id is provided
return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);
} else {
return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided
}
};
return Certificate;
};
/***/ }),
/* 68 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING;
var Channel = sequelize.define('Channel', {
channelName: {
type: STRING,
allowNull: false
},
channelClaimId: {
type: STRING,
allowNull: false
}
}, {
freezeTableName: true
});
Channel.associate = function (db) {
Channel.belongsTo(db.User);
Channel.hasOne(db.Certificate);
};
return Channel;
};
/***/ }),
/* 69 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(2);
var _require = __webpack_require__(25),
returnShortId = _require.returnShortId;
var _require2 = __webpack_require__(5),
defaultThumbnail = _require2.assetDefaults.thumbnail,
host = _require2.details.host;
function determineFileExtensionFromContentType(contentType) {
switch (contentType) {
case 'image/jpeg':
case 'image/jpg':
return 'jpeg';
case 'image/png':
return 'png';
case 'image/gif':
return 'gif';
case 'video/mp4':
return 'mp4';
default:
logger.debug('setting unknown file type as file extension jpeg');
return 'jpeg';
}
};
function determineThumbnail(storedThumbnail, defaultThumbnail) {
if (storedThumbnail === '') {
return defaultThumbnail;
}
return storedThumbnail;
};
function prepareClaimData(claim) {
// logger.debug('preparing claim data based on resolved data:', claim);
claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);
claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);
claim['host'] = host;
return claim;
};
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING,
BOOLEAN = _ref.BOOLEAN,
INTEGER = _ref.INTEGER,
TEXT = _ref.TEXT,
DECIMAL = _ref.DECIMAL;
var Claim = sequelize.define('Claim', {
address: {
type: STRING,
default: null
},
amount: {
type: DECIMAL(19, 8),
default: null
},
claimId: {
type: STRING,
default: null
},
claimSequence: {
type: INTEGER,
default: null
},
decodedClaim: {
type: BOOLEAN,
default: null
},
depth: {
type: INTEGER,
default: null
},
effectiveAmount: {
type: DECIMAL(19, 8),
default: null
},
hasSignature: {
type: BOOLEAN,
default: null
},
height: {
type: INTEGER,
default: null
},
hex: {
type: TEXT('long'),
default: null
},
name: {
type: STRING,
default: null
},
nout: {
type: INTEGER,
default: null
},
txid: {
type: STRING,
default: null
},
validAtHeight: {
type: INTEGER,
default: null
},
outpoint: {
type: STRING,
default: null
},
claimType: {
type: STRING,
default: null
},
certificateId: {
type: STRING,
default: null
},
author: {
type: STRING,
default: null
},
description: {
type: TEXT('long'),
default: null
},
language: {
type: STRING,
default: null
},
license: {
type: STRING,
default: null
},
licenseUrl: {
type: STRING,
default: null
},
nsfw: {
type: BOOLEAN,
default: null
},
preview: {
type: STRING,
default: null
},
thumbnail: {
type: STRING,
default: null
},
title: {
type: STRING,
default: null
},
metadataVersion: {
type: STRING,
default: null
},
contentType: {
type: STRING,
default: null
},
source: {
type: STRING,
default: null
},
sourceType: {
type: STRING,
default: null
},
sourceVersion: {
type: STRING,
default: null
},
streamVersion: {
type: STRING,
default: null
},
valueVersion: {
type: STRING,
default: null
},
channelName: {
type: STRING,
allowNull: true,
default: null
}
}, {
freezeTableName: true
});
Claim.associate = function (db) {
Claim.belongsTo(db.File, {
foreignKey: {
allowNull: true
}
});
};
Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {
var _this = this;
logger.debug('Claim.getShortClaimIdFromLongClaimId for ' + claimName + '#' + claimId);
return new Promise(function (resolve, reject) {
_this.findAll({
where: { name: claimName },
order: [['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
throw new Error('No claim(s) found with that claim name');
default:
resolve(returnShortId(result, claimId));
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.getAllChannelClaims = function (channelClaimId) {
var _this2 = this;
logger.debug('Claim.getAllChannelClaims for ' + channelClaimId);
return new Promise(function (resolve, reject) {
_this2.findAll({
where: { certificateId: channelClaimId },
order: [['height', 'ASC']],
raw: true // returns an array of only data, not an array of instances
}).then(function (channelClaimsArray) {
// logger.debug('channelclaimsarray length:', channelClaimsArray.length);
switch (channelClaimsArray.length) {
case 0:
return resolve(null);
default:
channelClaimsArray.forEach(function (claim) {
claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);
claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);
return claim;
});
return resolve(channelClaimsArray);
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) {
var _this3 = this;
logger.debug('finding claim id for claim ' + claimName + ' from channel ' + channelClaimId);
return new Promise(function (resolve, reject) {
_this3.findAll({
where: { name: claimName, certificateId: channelClaimId },
order: [['id', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
return resolve(null);
case 1:
return resolve(result[0].claimId);
default:
logger.error(result.length + ' records found for "' + claimName + '" in channel "' + channelClaimId + '"');
return resolve(result[0].claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {
var _this4 = this;
return new Promise(function (resolve, reject) {
_this4.findAll({
where: {
name: name,
claimId: {
$like: shortId + '%'
} },
order: [['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
return resolve(null);
default:
// note results must be sorted
return resolve(result[0].claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.getTopFreeClaimIdByClaimName = function (name) {
var _this5 = this;
return new Promise(function (resolve, reject) {
_this5.findAll({
where: { name: name },
order: [['effectiveAmount', 'DESC'], ['height', 'ASC']] // note: maybe height and effective amount need to switch?
}).then(function (result) {
logger.debug('length of result', result.length);
switch (result.length) {
case 0:
return resolve(null);
default:
return resolve(result[0].dataValues.claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.validateLongClaimId = function (name, claimId) {
var _this6 = this;
return new Promise(function (resolve, reject) {
_this6.findOne({
where: { name: name, claimId: claimId }
}).then(function (result) {
if (!result) {
return resolve(null);
};
resolve(claimId);
}).catch(function (error) {
reject(error);
});
});
};
Claim.getLongClaimId = function (claimName, claimId) {
logger.debug('getLongClaimId(' + claimName + ', ' + claimId + ')');
if (claimId && claimId.length === 40) {
// if a full claim id is provided
return this.validateLongClaimId(claimName, claimId);
} else if (claimId && claimId.length < 40) {
return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided
} else {
return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided
}
};
Claim.resolveClaim = function (name, claimId) {
var _this7 = this;
logger.debug('Claim.resolveClaim: ' + name + ' ' + claimId);
return new Promise(function (resolve, reject) {
_this7.findAll({
where: { name: name, claimId: claimId }
}).then(function (claimArray) {
switch (claimArray.length) {
case 0:
return resolve(null);
case 1:
return resolve(prepareClaimData(claimArray[0].dataValues));
default:
logger.error('more than one record matches ' + name + '#' + claimId + ' in db.Claim');
return resolve(prepareClaimData(claimArray[0].dataValues));
}
}).catch(function (error) {
reject(error);
});
});
};
return Claim;
};
/***/ }),
/* 70 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING,
BOOLEAN = _ref.BOOLEAN,
INTEGER = _ref.INTEGER;
var File = sequelize.define('File', {
name: {
type: STRING,
allowNull: false
},
claimId: {
type: STRING,
allowNull: false
},
address: {
type: STRING,
allowNull: false
},
outpoint: {
type: STRING,
allowNull: false
},
height: {
type: INTEGER,
allowNull: false,
default: 0
},
fileName: {
type: STRING,
allowNull: false
},
filePath: {
type: STRING,
allowNull: false
},
fileType: {
type: STRING
},
nsfw: {
type: BOOLEAN,
allowNull: false,
defaultValue: false
},
trendingEligible: {
type: BOOLEAN,
allowNull: false,
defaultValue: true
}
}, {
freezeTableName: true
});
File.associate = function (db) {
File.hasMany(db.Request);
File.hasOne(db.Claim);
};
File.getRecentClaims = function () {
return this.findAll({
where: { nsfw: false, trendingEligible: true },
order: [['createdAt', 'DESC']],
limit: 25
});
};
return File;
};
/***/ }),
/* 71 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING,
BOOLEAN = _ref.BOOLEAN,
TEXT = _ref.TEXT;
var Request = sequelize.define('Request', {
action: {
type: STRING,
allowNull: false
},
url: {
type: STRING,
allowNull: false
},
ipAddress: {
type: STRING,
allowNull: true
},
result: {
type: TEXT('long'),
allowNull: true,
default: null
}
}, {
freezeTableName: true
});
Request.associate = function (db) {
Request.belongsTo(db.File, {
foreignKey: {
allowNull: true
}
});
};
return Request;
};
/***/ }),
/* 72 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var bcrypt = __webpack_require__(73);
var logger = __webpack_require__(2);
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING;
var User = sequelize.define('User', {
userName: {
type: STRING,
allowNull: false
},
password: {
type: STRING,
allowNull: false
}
}, {
freezeTableName: true
});
User.associate = function (db) {
User.hasOne(db.Channel);
};
User.prototype.comparePassword = function (password) {
return bcrypt.compare(password, this.password);
};
User.prototype.changePassword = function (newPassword) {
var _this = this;
return new Promise(function (resolve, reject) {
// generate a salt string to use for hashing
bcrypt.genSalt(function (saltError, salt) {
if (saltError) {
logger.error('salt error', saltError);
reject(saltError);
return;
}
// generate a hashed version of the user's password
bcrypt.hash(newPassword, salt, function (hashError, hash) {
// if there is an error with the hash generation return the error
if (hashError) {
logger.error('hash error', hashError);
reject(hashError);
return;
}
// replace the current password with the new hash
_this.update({ password: hash }).then(function () {
resolve();
}).catch(function (error) {
reject(error);
});
});
});
});
};
// pre-save hook method to hash the user's password before the user's info is saved to the db.
User.hook('beforeCreate', function (user, options) {
logger.debug('User.beforeCreate hook...');
return new Promise(function (resolve, reject) {
// generate a salt string to use for hashing
bcrypt.genSalt(function (saltError, salt) {
if (saltError) {
logger.error('salt error', saltError);
reject(saltError);
return;
}
// generate a hashed version of the user's password
bcrypt.hash(user.password, salt, function (hashError, hash) {
// if there is an error with the hash generation return the error
if (hashError) {
logger.error('hash error', hashError);
reject(hashError);
return;
}
// replace the password string with the hash password value
user.password = hash;
resolve();
});
});
});
});
return User;
};
/***/ }),
/* 73 */
/***/ (function(module, exports) {
module.exports = require("bcrypt");
/***/ }),
/* 74 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var PassportLocalStrategy = __webpack_require__(23).Strategy;
var logger = __webpack_require__(2);
var db = __webpack_require__(6);
var returnUserAndChannelInfo = function returnUserAndChannelInfo(userInstance) {
return new Promise(function (resolve, reject) {
var userInfo = {};
userInfo['id'] = userInstance.id;
userInfo['userName'] = userInstance.userName;
userInstance.getChannel().then(function (_ref) {
var channelName = _ref.channelName,
channelClaimId = _ref.channelClaimId;
userInfo['channelName'] = channelName;
userInfo['channelClaimId'] = channelClaimId;
return db.Certificate.getShortChannelIdFromLongChannelId(channelClaimId, channelName);
}).then(function (shortChannelId) {
userInfo['shortChannelId'] = shortChannelId;
resolve(userInfo);
}).catch(function (error) {
reject(error);
});
});
};
module.exports = new PassportLocalStrategy({
usernameField: 'username',
passwordField: 'password'
}, function (username, password, done) {
return db.User.findOne({
where: { userName: username }
}).then(function (user) {
if (!user) {
logger.debug('no user found');
return done(null, false, { message: 'Incorrect username or password' });
}
return user.comparePassword(password).then(function (isMatch) {
if (!isMatch) {
logger.debug('incorrect password');
return done(null, false, { message: 'Incorrect username or password' });
}
logger.debug('Password was a match, returning User');
return returnUserAndChannelInfo(user).then(function (userInfo) {
return done(null, userInfo);
}).catch(function (error) {
return error;
});
}).catch(function (error) {
return error;
});
}).catch(function (error) {
return done(error);
});
});
/***/ }),
/* 75 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(2);
var passport = __webpack_require__(22);
module.exports = function (app) {
// route for sign up
app.post('/signup', passport.authenticate('local-signup'), function (req, res) {
logger.verbose('successful signup for ' + req.user.channelName);
res.status(200).json({
success: true,
channelName: req.user.channelName,
channelClaimId: req.user.channelClaimId,
shortChannelId: req.user.shortChannelId
});
});
// route for log in
app.post('/login', function (req, res, next) {
passport.authenticate('local-login', function (err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.status(400).json({
success: false,
message: info.message
});
}
logger.debug('successful login');
req.logIn(user, function (err) {
if (err) {
return next(err);
}
return res.status(200).json({
success: true,
channelName: req.user.channelName,
channelClaimId: req.user.channelClaimId,
shortChannelId: req.user.shortChannelId
});
});
})(req, res, next);
});
// route to log out
app.get('/logout', function (req, res) {
req.logout();
res.status(200).json({ success: true, message: 'you successfully logged out' });
});
// see if user is authenticated, and return credentials if so
app.get('/user', function (req, res) {
if (req.user) {
res.status(200).json({ success: true, data: req.user });
} else {
res.status(401).json({ success: false, message: 'user is not logged in' });
}
});
};
/***/ }),
/* 76 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var logger = __webpack_require__(2);
var multipart = __webpack_require__(77);
var _require = __webpack_require__(5),
uploadDirectory = _require.publishing.uploadDirectory,
host = _require.details.host;
var multipartMiddleware = multipart({ uploadDir: uploadDirectory });
var db = __webpack_require__(6);
var _require2 = __webpack_require__(78),
claimNameIsAvailable = _require2.claimNameIsAvailable,
checkChannelAvailability = _require2.checkChannelAvailability,
publish = _require2.publish;
var _require3 = __webpack_require__(16),
getClaimList = _require3.getClaimList,
resolveUri = _require3.resolveUri,
getClaim = _require3.getClaim;
var _require4 = __webpack_require__(26),
addGetResultsToFileData = _require4.addGetResultsToFileData,
createBasicPublishParams = _require4.createBasicPublishParams,
createThumbnailPublishParams = _require4.createThumbnailPublishParams,
parsePublishApiRequestBody = _require4.parsePublishApiRequestBody,
parsePublishApiRequestFiles = _require4.parsePublishApiRequestFiles,
createFileData = _require4.createFileData;
var errorHandlers = __webpack_require__(27);
var _require5 = __webpack_require__(17),
sendGATimingEvent = _require5.sendGATimingEvent;
var _require6 = __webpack_require__(80),
authenticateUser = _require6.authenticateUser;
var _require7 = __webpack_require__(28),
getChannelData = _require7.getChannelData,
getChannelClaims = _require7.getChannelClaims,
getClaimId = _require7.getClaimId;
var NO_CHANNEL = 'NO_CHANNEL';
var NO_CLAIM = 'NO_CLAIM';
module.exports = function (app) {
// route to check whether site has published to a channel
app.get('/api/channel/availability/:name', function (_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
name = _ref.params.name;
var gaStartTime = Date.now();
checkChannelAvailability(name).then(function (availableName) {
res.status(200).json(availableName);
sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
// route to get a short channel id from long channel Id
app.get('/api/channel/short-id/:longId/:name', function (_ref2, res) {
var ip = _ref2.ip,
originalUrl = _ref2.originalUrl,
params = _ref2.params;
db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name).then(function (shortId) {
res.status(200).json(shortId);
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
app.get('/api/channel/data/:channelName/:channelClaimId', function (_ref3, res) {
var ip = _ref3.ip,
originalUrl = _ref3.originalUrl,
body = _ref3.body,
params = _ref3.params;
var channelName = params.channelName;
var channelClaimId = params.channelClaimId;
if (channelClaimId === 'none') channelClaimId = null;
getChannelData(channelName, channelClaimId, 0).then(function (data) {
if (data === NO_CHANNEL) {
return res.status(404).json({ success: false, message: 'No matching channel was found' });
}
res.status(200).json({ success: true, data: data });
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
app.get('/api/channel/claims/:channelName/:channelClaimId/:page', function (_ref4, res) {
var ip = _ref4.ip,
originalUrl = _ref4.originalUrl,
body = _ref4.body,
params = _ref4.params;
var channelName = params.channelName;
var channelClaimId = params.channelClaimId;
if (channelClaimId === 'none') channelClaimId = null;
var page = params.page;
getChannelClaims(channelName, channelClaimId, page).then(function (data) {
if (data === NO_CHANNEL) {
return res.status(404).json({ success: false, message: 'No matching channel was found' });
}
res.status(200).json({ success: true, data: data });
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
// route to run a claim_list request on the daemon
app.get('/api/claim/list/:name', function (_ref5, res) {
var ip = _ref5.ip,
originalUrl = _ref5.originalUrl,
params = _ref5.params;
getClaimList(params.name).then(function (claimsList) {
res.status(200).json(claimsList);
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
// route to get an asset
app.get('/api/claim/get/:name/:claimId', function (_ref6, res) {
var ip = _ref6.ip,
originalUrl = _ref6.originalUrl,
params = _ref6.params;
var name = params.name;
var claimId = params.claimId;
// resolve the claim
db.Claim.resolveClaim(name, claimId).then(function (resolveResult) {
// make sure a claim actually exists at that uri
if (!resolveResult) {
throw new Error('No matching uri found in Claim table');
}
var fileData = createFileData(resolveResult);
// get the claim
return Promise.all([fileData, getClaim(name + '#' + claimId)]);
}).then(function (_ref7) {
var _ref8 = _slicedToArray(_ref7, 2),
fileData = _ref8[0],
getResult = _ref8[1];
fileData = addGetResultsToFileData(fileData, getResult);
return Promise.all([db.upsert(db.File, fileData, { name: name, claimId: claimId }, 'File'), getResult]);
}).then(function (_ref9) {
var _ref10 = _slicedToArray(_ref9, 2),
fileRecord = _ref10[0],
_ref10$ = _ref10[1],
message = _ref10$.message,
completed = _ref10$.completed;
res.status(200).json({ success: true, message: message, completed: completed });
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
// route to check whether this site published to a claim
app.get('/api/claim/availability/:name', function (_ref11, res) {
var ip = _ref11.ip,
originalUrl = _ref11.originalUrl,
name = _ref11.params.name;
var gaStartTime = Date.now();
claimNameIsAvailable(name).then(function (result) {
res.status(200).json(result);
sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
// route to run a resolve request on the daemon
app.get('/api/claim/resolve/:name/:claimId', function (_ref12, res) {
var headers = _ref12.headers,
ip = _ref12.ip,
originalUrl = _ref12.originalUrl,
params = _ref12.params;
resolveUri(params.name + '#' + params.claimId).then(function (resolvedUri) {
res.status(200).json(resolvedUri);
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
// route to run a publish request on the daemon
app.post('/api/claim/publish', multipartMiddleware, function (_ref13, res) {
var body = _ref13.body,
files = _ref13.files,
headers = _ref13.headers,
ip = _ref13.ip,
originalUrl = _ref13.originalUrl,
user = _ref13.user;
// define variables
var channelName = void 0,
channelId = void 0,
channelPassword = void 0,
description = void 0,
fileName = void 0,
filePath = void 0,
fileType = void 0,
gaStartTime = void 0,
license = void 0,
name = void 0,
nsfw = void 0,
thumbnail = void 0,
thumbnailFileName = void 0,
thumbnailFilePath = void 0,
thumbnailFileType = void 0,
title = void 0;
// record the start time of the request
gaStartTime = Date.now();
// validate the body and files of the request
try {
var _parsePublishApiReque = parsePublishApiRequestBody(body);
// validateApiPublishRequest(body, files);
name = _parsePublishApiReque.name;
nsfw = _parsePublishApiReque.nsfw;
license = _parsePublishApiReque.license;
title = _parsePublishApiReque.title;
description = _parsePublishApiReque.description;
thumbnail = _parsePublishApiReque.thumbnail;
var _parsePublishApiReque2 = parsePublishApiRequestFiles(files);
fileName = _parsePublishApiReque2.fileName;
filePath = _parsePublishApiReque2.filePath;
fileType = _parsePublishApiReque2.fileType;
thumbnailFileName = _parsePublishApiReque2.thumbnailFileName;
thumbnailFilePath = _parsePublishApiReque2.thumbnailFilePath;
thumbnailFileType = _parsePublishApiReque2.thumbnailFileType;
channelName = body.channelName;
channelId = body.channelId;
channelPassword = body.channelPassword;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
// check channel authorization
Promise.all([authenticateUser(channelName, channelId, channelPassword, user), claimNameIsAvailable(name), createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail), createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw)]).then(function (_ref14) {
var _ref15 = _slicedToArray(_ref14, 4),
_ref15$ = _ref15[0],
channelName = _ref15$.channelName,
channelClaimId = _ref15$.channelClaimId,
validatedClaimName = _ref15[1],
publishParams = _ref15[2],
thumbnailPublishParams = _ref15[3];
// add channel details to the publish params
if (channelName && channelClaimId) {
publishParams['channel_name'] = channelName;
publishParams['channel_id'] = channelClaimId;
}
// publish the thumbnail
if (thumbnailPublishParams) {
publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType);
}
// publish the asset
return publish(publishParams, fileName, fileType);
}).then(function (result) {
res.status(200).json({
success: true,
message: 'publish completed successfully',
data: {
name: name,
claimId: result.claim_id,
url: host + '/' + result.claim_id + '/' + name,
lbryTx: result
}
});
// record the publish end time and send to google analytics
sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
// route to get a short claim id from long claim Id
app.get('/api/claim/short-id/:longId/:name', function (_ref16, res) {
var ip = _ref16.ip,
originalUrl = _ref16.originalUrl,
body = _ref16.body,
params = _ref16.params;
db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name).then(function (shortId) {
res.status(200).json({ success: true, data: shortId });
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
app.post('/api/claim/long-id', function (_ref17, res) {
var ip = _ref17.ip,
originalUrl = _ref17.originalUrl,
body = _ref17.body,
params = _ref17.params;
logger.debug('body:', body);
var channelName = body.channelName;
var channelClaimId = body.channelClaimId;
var claimName = body.claimName;
var claimId = body.claimId;
getClaimId(channelName, channelClaimId, claimName, claimId).then(function (result) {
if (result === NO_CHANNEL) {
return res.status(404).json({ success: false, message: 'No matching channel could be found' });
}
if (result === NO_CLAIM) {
return res.status(404).json({ success: false, message: 'No matching claim id could be found' });
}
res.status(200).json({ success: true, data: result });
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
app.get('/api/claim/data/:claimName/:claimId', function (_ref18, res) {
var ip = _ref18.ip,
originalUrl = _ref18.originalUrl,
body = _ref18.body,
params = _ref18.params;
var claimName = params.claimName;
var claimId = params.claimId;
if (claimId === 'none') claimId = null;
db.Claim.resolveClaim(claimName, claimId).then(function (claimInfo) {
if (!claimInfo) {
return res.status(404).json({ success: false, message: 'No claim could be found' });
}
res.status(200).json({ success: true, data: claimInfo });
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
// route to see if asset is available locally
app.get('/api/file/availability/:name/:claimId', function (_ref19, res) {
var ip = _ref19.ip,
originalUrl = _ref19.originalUrl,
params = _ref19.params;
var name = params.name;
var claimId = params.claimId;
db.File.findOne({ where: { name: name, claimId: claimId } }).then(function (result) {
if (result) {
return res.status(200).json({ success: true, data: true });
}
res.status(200).json({ success: true, data: false });
}).catch(function (error) {
errorHandlers.handleErrorResponse(originalUrl, ip, error, res);
});
});
};
/***/ }),
/* 77 */
/***/ (function(module, exports) {
module.exports = require("connect-multiparty");
/***/ }),
/* 78 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var logger = __webpack_require__(2);
var db = __webpack_require__(6);
var lbryApi = __webpack_require__(16);
var publishHelpers = __webpack_require__(26);
var _require = __webpack_require__(5),
_require$publishing = _require.publishing,
primaryClaimAddress = _require$publishing.primaryClaimAddress,
additionalClaimAddresses = _require$publishing.additionalClaimAddresses;
var Sequelize = __webpack_require__(24);
var Op = Sequelize.Op;
module.exports = {
publish: function publish(publishParams, fileName, fileType) {
return new Promise(function (resolve, reject) {
var publishResults = void 0,
certificateId = void 0,
channelName = void 0;
// publish the file
return lbryApi.publishClaim(publishParams).then(function (tx) {
logger.info('Successfully published ' + publishParams.name + ' ' + fileName, tx);
publishResults = tx;
// get the channel information
if (publishParams.channel_name) {
logger.debug('this claim was published in channel: ' + publishParams.channel_name);
return db.Channel.findOne({ where: { channelName: publishParams.channel_name } });
} else {
logger.debug('this claim was not published in a channel');
return null;
}
}).then(function (channel) {
// set channel information
certificateId = null;
channelName = null;
if (channel) {
certificateId = channel.channelClaimId;
channelName = channel.channelName;
}
logger.debug('certificateId: ' + certificateId);
}).then(function () {
// create the File record
var fileRecord = {
name: publishParams.name,
claimId: publishResults.claim_id,
title: publishParams.metadata.title,
description: publishParams.metadata.description,
address: publishParams.claim_address,
outpoint: publishResults.txid + ':' + publishResults.nout,
height: 0,
fileName: fileName,
filePath: publishParams.file_path,
fileType: fileType,
nsfw: publishParams.metadata.nsfw
};
// create the Claim record
var claimRecord = {
name: publishParams.name,
claimId: publishResults.claim_id,
title: publishParams.metadata.title,
description: publishParams.metadata.description,
address: publishParams.claim_address,
thumbnail: publishParams.metadata.thumbnail,
outpoint: publishResults.txid + ':' + publishResults.nout,
height: 0,
contentType: fileType,
nsfw: publishParams.metadata.nsfw,
amount: publishParams.bid,
certificateId: certificateId,
channelName: channelName
};
// upsert criteria
var upsertCriteria = {
name: publishParams.name,
claimId: publishResults.claim_id
};
// upsert the records
return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]);
}).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
file = _ref2[0],
claim = _ref2[1];
logger.debug('File and Claim records successfully created');
return Promise.all([file.setClaim(claim), claim.setFile(file)]);
}).then(function () {
logger.debug('File and Claim records successfully associated');
resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim;
}).catch(function (error) {
logger.error('PUBLISH ERROR', error);
publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file
reject(error);
});
});
},
claimNameIsAvailable: function claimNameIsAvailable(name) {
var claimAddresses = additionalClaimAddresses || [];
claimAddresses.push(primaryClaimAddress);
// find any records where the name is used
return db.Claim.findAll({
attributes: ['address'],
where: {
name: name,
address: _defineProperty({}, Op.or, claimAddresses)
}
}).then(function (result) {
if (result.length >= 1) {
throw new Error('That claim is already in use');
};
return name;
}).catch(function (error) {
throw error;
});
},
checkChannelAvailability: function checkChannelAvailability(name) {
return db.Channel.findAll({
where: { channelName: name }
}).then(function (result) {
if (result.length >= 1) {
throw new Error('That channel has already been claimed');
}
return name;
}).catch(function (error) {
throw error;
});
}
};
/***/ }),
/* 79 */
/***/ (function(module, exports) {
module.exports = require("fs");
/***/ }),
/* 80 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var db = __webpack_require__(6);
var logger = __webpack_require__(2);
module.exports = {
authenticateUser: function authenticateUser(channelName, channelId, channelPassword, user) {
// case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided
if (!channelName && !channelId) {
return {
channelName: null,
channelClaimId: null
};
}
// case: channelName or channel Id are provided with user token
if (user) {
if (channelName && channelName !== user.channelName) {
throw new Error('the provided channel name does not match user credentials');
}
if (channelId && channelId !== user.channelClaimId) {
throw new Error('the provided channel id does not match user credentials');
}
return {
channelName: user.channelName,
channelClaimId: user.channelClaimId
};
}
// case: channelName or channel Id are provided with password instead of user token
if (!channelPassword) throw new Error('no channel password provided');
return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword);
},
authenticateChannelCredentials: function authenticateChannelCredentials(channelName, channelId, userPassword) {
return new Promise(function (resolve, reject) {
// hoisted variables
var channelData = void 0;
// build the params for finding the channel
var channelFindParams = {};
if (channelName) channelFindParams['channelName'] = channelName;
if (channelId) channelFindParams['channelClaimId'] = channelId;
// find the channel
db.Channel.findOne({
where: channelFindParams
}).then(function (channel) {
if (!channel) {
logger.debug('no channel found');
throw new Error('Authentication failed, you do not have access to that channel');
}
channelData = channel.get();
logger.debug('channel data:', channelData);
return db.User.findOne({
where: { userName: channelData.channelName.substring(1) }
});
}).then(function (user) {
if (!user) {
logger.debug('no user found');
throw new Error('Authentication failed, you do not have access to that channel');
}
return user.comparePassword(userPassword);
}).then(function (isMatch) {
if (!isMatch) {
logger.debug('incorrect password');
throw new Error('Authentication failed, you do not have access to that channel');
}
logger.debug('...password was a match...');
resolve(channelData);
}).catch(function (error) {
reject(error);
});
});
}
};
/***/ }),
/* 81 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var CLAIMS_PER_PAGE = 12;
module.exports = {
returnPaginatedChannelClaims: function returnPaginatedChannelClaims(channelName, longChannelClaimId, claims, page) {
var totalPages = module.exports.determineTotalPages(claims);
var paginationPage = module.exports.getPageFromQuery(page);
var viewData = {
channelName: channelName,
longChannelClaimId: longChannelClaimId,
claims: module.exports.extractPageFromClaims(claims, paginationPage),
previousPage: module.exports.determinePreviousPage(paginationPage),
currentPage: paginationPage,
nextPage: module.exports.determineNextPage(totalPages, paginationPage),
totalPages: totalPages,
totalResults: module.exports.determineTotalClaims(claims)
};
return viewData;
},
getPageFromQuery: function getPageFromQuery(page) {
if (page) {
return parseInt(page);
}
return 1;
},
extractPageFromClaims: function extractPageFromClaims(claims, pageNumber) {
if (!claims) {
return []; // if no claims, return this default
}
// logger.debug('claims is array?', Array.isArray(claims));
// logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));
var claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;
var claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;
var pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);
return pageOfClaims;
},
determineTotalPages: function determineTotalPages(claims) {
if (!claims) {
return 0;
} else {
var totalClaims = claims.length;
if (totalClaims < CLAIMS_PER_PAGE) {
return 1;
}
var fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE);
var remainder = totalClaims % CLAIMS_PER_PAGE;
if (remainder === 0) {
return fullPages;
}
return fullPages + 1;
}
},
determinePreviousPage: function determinePreviousPage(currentPage) {
if (currentPage === 1) {
return null;
}
return currentPage - 1;
},
determineNextPage: function determineNextPage(totalPages, currentPage) {
if (currentPage === totalPages) {
return null;
}
return currentPage + 1;
},
determineTotalClaims: function determineTotalClaims(claims) {
if (!claims) {
return 0;
}
return claims.length;
}
};
/***/ }),
/* 82 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(5),
host = _require.details;
var handlePageRender = __webpack_require__(29);
module.exports = function (app) {
// route for the home page
app.get('/', function (req, res) {
handlePageRender(req, res);
});
// route to display login page
app.get('/login', function (req, res) {
handlePageRender(req, res);
});
// route to show 'about' page
app.get('/about', function (req, res) {
handlePageRender(req, res);
});
// route to display a list of the trending images
app.get('/trending', function (req, res) {
res.status(301).redirect('/popular');
});
app.get('/popular', function (req, res) {
handlePageRender(req, res);
});
// route to display a list of the trending images
app.get('/new', function (req, res) {
handlePageRender(req, res);
});
// route to send embedable video player (for twitter)
app.get('/embed/:claimId/:name', function (_ref, res) {
var params = _ref.params;
var claimId = params.claimId;
var name = params.name;
// get and render the content
res.status(200).render('embed', { layout: 'embed', host: host, claimId: claimId, name: name });
});
};
/***/ }),
/* 83 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function () {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
var action = arguments[1];
switch (action.type) {
case actions.FILE_SELECTED:
return Object.assign({}, initialState, { // note: clears to initial state
file: action.data
});
case actions.FILE_CLEAR:
return initialState;
case actions.METADATA_UPDATE:
return Object.assign({}, state, {
metadata: Object.assign({}, state.metadata, _defineProperty({}, action.data.name, action.data.value))
});
case actions.CLAIM_UPDATE:
return Object.assign({}, state, {
claim: action.data
});
case actions.SET_PUBLISH_IN_CHANNEL:
return Object.assign({}, state, {
publishInChannel: action.channel
});
case actions.PUBLISH_STATUS_UPDATE:
return Object.assign({}, state, {
status: action.data
});
case actions.ERROR_UPDATE:
return Object.assign({}, state, {
error: Object.assign({}, state.error, _defineProperty({}, action.data.name, action.data.value))
});
case actions.SELECTED_CHANNEL_UPDATE:
return Object.assign({}, state, {
selectedChannel: action.data
});
case actions.TOGGLE_METADATA_INPUTS:
return Object.assign({}, state, {
showMetadataInputs: action.data
});
case actions.THUMBNAIL_NEW:
return Object.assign({}, state, {
thumbnail: action.data
});
default:
return state;
}
};
var _publish_action_types = __webpack_require__(32);
var actions = _interopRequireWildcard(_publish_action_types);
var _publish_channel_select_states = __webpack_require__(33);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var _require = __webpack_require__(5),
publishing = _require.publishing;
var initialState = {
disabled: publishing.disabled,
disabledMessage: publishing.disabledMessage,
publishInChannel: false,
selectedChannel: _publish_channel_select_states.LOGIN,
showMetadataInputs: false,
status: {
status: null,
message: null
},
error: {
file: null,
url: null,
channel: null,
publishSubmit: null
},
file: null,
claim: '',
metadata: {
title: '',
description: '',
license: '',
nsfw: false
},
thumbnail: null
};
/***/ }),
/* 84 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function () {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
var action = arguments[1];
switch (action.type) {
case actions.CHANNEL_UPDATE:
return Object.assign({}, state, {
loggedInChannel: action.data
});
default:
return state;
}
};
var _channel_action_types = __webpack_require__(34);
var actions = _interopRequireWildcard(_channel_action_types);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var initialState = {
loggedInChannel: {
name: null,
shortId: null,
longId: null
}
};
/***/ }),
/* 85 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function () {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
var action = arguments[1];
switch (action.type) {
// handle request
case actions.REQUEST_ERROR:
return Object.assign({}, state, {
request: Object.assign({}, state.request, {
error: action.data
})
});
case actions.REQUEST_UPDATE:
return Object.assign({}, state, {
request: Object.assign({}, state.request, {
type: action.data.requestType,
id: action.data.requestId
})
});
// store requests
case actions.REQUEST_LIST_ADD:
return Object.assign({}, state, {
requestList: Object.assign({}, state.requestList, _defineProperty({}, action.data.id, {
error: action.data.error,
key: action.data.key
}))
});
// asset data
case actions.ASSET_ADD:
return Object.assign({}, state, {
assetList: Object.assign({}, state.assetList, _defineProperty({}, action.data.id, {
error: action.data.error,
name: action.data.name,
claimId: action.data.claimId,
shortId: action.data.shortId,
claimData: action.data.claimData
}))
});
// channel data
case actions.CHANNEL_ADD:
return Object.assign({}, state, {
channelList: Object.assign({}, state.channelList, _defineProperty({}, action.data.id, {
name: action.data.name,
longId: action.data.longId,
shortId: action.data.shortId,
claimsData: action.data.claimsData
}))
});
case actions.CHANNEL_CLAIMS_UPDATE_SUCCESS:
return Object.assign({}, state, {
channelList: Object.assign({}, state.channelList, _defineProperty({}, action.data.channelListId, Object.assign({}, state.channelList[action.data.channelListId], {
claimsData: action.data.claimsData
})))
});
// display an asset
case actions.FILE_AVAILABILITY_UPDATE:
return Object.assign({}, state, {
displayAsset: Object.assign({}, state.displayAsset, {
status: action.data
})
});
case actions.DISPLAY_ASSET_ERROR:
return Object.assign({}, state, {
displayAsset: Object.assign({}, state.displayAsset, {
error: action.data,
status: _asset_display_states.ERROR
})
});
default:
return state;
}
};
var _show_action_types = __webpack_require__(12);
var actions = _interopRequireWildcard(_show_action_types);
var _asset_display_states = __webpack_require__(35);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var initialState = {
request: {
error: null,
type: null,
id: null
},
requestList: {},
channelList: {},
assetList: {},
displayAsset: {
error: null,
status: _asset_display_states.LOCAL_CHECK
}
};
/***/ }),
/* 86 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function () {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
var action = arguments[1];
switch (action.type) {
default:
return state;
}
};
var siteConfig = __webpack_require__(5);
var googleAnalyticsId = siteConfig.analytics.googleId,
_siteConfig$assetDefa = siteConfig.assetDefaults,
defaultThumbnail = _siteConfig$assetDefa.thumbnail,
defaultDescription = _siteConfig$assetDefa.description,
_siteConfig$details = siteConfig.details,
description = _siteConfig$details.description,
host = _siteConfig$details.host,
title = _siteConfig$details.title,
twitter = _siteConfig$details.twitter;
var initialState = {
description: description,
googleAnalyticsId: googleAnalyticsId,
host: host,
title: title,
twitter: twitter,
defaultDescription: defaultDescription,
defaultThumbnail: defaultThumbnail
};
/***/ }),
/* 87 */
/***/ (function(module, exports) {
module.exports = require("react-ga");
/***/ }),
/* 88 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _SEO = __webpack_require__(9);
var _SEO2 = _interopRequireDefault(_SEO);
var _NavBar = __webpack_require__(7);
var _NavBar2 = _interopRequireDefault(_NavBar);
var _PublishTool = __webpack_require__(97);
var _PublishTool2 = _interopRequireDefault(_PublishTool);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var HomePage = function (_React$Component) {
_inherits(HomePage, _React$Component);
function HomePage() {
_classCallCheck(this, HomePage);
return _possibleConstructorReturn(this, (HomePage.__proto__ || Object.getPrototypeOf(HomePage)).apply(this, arguments));
}
_createClass(HomePage, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'row row--tall flex-container--column' },
_react2.default.createElement(_SEO2.default, null),
_react2.default.createElement(_NavBar2.default, null),
_react2.default.createElement(
'div',
{ className: 'row row--tall row--padded flex-container--column' },
_react2.default.createElement(_PublishTool2.default, null)
)
);
}
}]);
return HomePage;
}(_react2.default.Component);
;
exports.default = HomePage;
/***/ }),
/* 89 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactHelmet = __webpack_require__(14);
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
var _propTypes = __webpack_require__(10);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _pageTitle = __webpack_require__(90);
var _metaTags = __webpack_require__(91);
var _canonicalLink = __webpack_require__(92);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var SEO = function (_React$Component) {
_inherits(SEO, _React$Component);
function SEO() {
_classCallCheck(this, SEO);
return _possibleConstructorReturn(this, (SEO.__proto__ || Object.getPrototypeOf(SEO)).apply(this, arguments));
}
_createClass(SEO, [{
key: 'render',
value: function render() {
// props from state
var _props = this.props,
defaultDescription = _props.defaultDescription,
defaultThumbnail = _props.defaultThumbnail,
siteDescription = _props.siteDescription,
siteHost = _props.siteHost,
siteTitle = _props.siteTitle,
siteTwitter = _props.siteTwitter;
// props from parent
var _props2 = this.props,
asset = _props2.asset,
channel = _props2.channel,
pageUri = _props2.pageUri;
var pageTitle = this.props.pageTitle;
// create page title, tags, and canonical link
pageTitle = (0, _pageTitle.createPageTitle)(siteTitle, pageTitle);
var metaTags = (0, _metaTags.createMetaTags)(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail);
var canonicalLink = (0, _canonicalLink.createCanonicalLink)(asset, channel, pageUri, siteHost);
// render results
return _react2.default.createElement(_reactHelmet2.default, {
title: pageTitle,
meta: metaTags,
link: [{ rel: 'canonical', href: canonicalLink }]
});
}
}]);
return SEO;
}(_react2.default.Component);
;
SEO.propTypes = {
pageTitle: _propTypes2.default.string,
pageUri: _propTypes2.default.string,
channel: _propTypes2.default.object,
asset: _propTypes2.default.object
};
exports.default = SEO;
/***/ }),
/* 90 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var createPageTitle = exports.createPageTitle = function createPageTitle(siteTitle, pageTitle) {
if (!pageTitle) {
return "" + siteTitle;
}
return siteTitle + " - " + pageTitle;
};
/***/ }),
/* 91 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var determineOgThumbnailContentType = function determineOgThumbnailContentType(thumbnail) {
if (thumbnail) {
var fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));
switch (fileExt) {
case 'jpeg':
case 'jpg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'gif':
return 'image/gif';
case 'mp4':
return 'video/mp4';
default:
return 'image/jpeg';
}
}
return '';
};
var createBasicMetaTags = function createBasicMetaTags(siteHost, siteDescription, siteTitle, siteTwitter) {
return [{ property: 'og:title', content: siteTitle }, { property: 'og:url', content: siteHost }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: siteDescription }, { property: 'twitter:site', content: siteTwitter }, { property: 'twitter:card', content: 'summary' }];
};
var createChannelMetaTags = function createChannelMetaTags(siteTitle, siteHost, siteTwitter, channel) {
var name = channel.name,
longId = channel.longId;
return [{ property: 'og:title', content: name + ' on ' + siteTitle }, { property: 'og:url', content: siteHost + '/' + name + ':' + longId }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: name + ', a channel on ' + siteTitle }, { property: 'twitter:site', content: siteTwitter }, { property: 'twitter:card', content: 'summary' }];
};
var createAssetMetaTags = function createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail) {
var claimData = asset.claimData;
var contentType = claimData.contentType;
var embedUrl = siteHost + '/' + claimData.claimId + '/' + claimData.name;
var showUrl = siteHost + '/' + claimData.claimId + '/' + claimData.name;
var source = siteHost + '/' + claimData.claimId + '/' + claimData.name + '.' + claimData.fileExt;
var ogTitle = claimData.title || claimData.name;
var ogDescription = claimData.description || defaultDescription;
var ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);
var ogThumbnail = claimData.thumbnail || defaultThumbnail;
var metaTags = [{ property: 'og:title', content: ogTitle }, { property: 'og:url', content: showUrl }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: ogDescription }, { property: 'og:image:width', content: 600 }, { property: 'og:image:height', content: 315 }, { property: 'twitter:site', content: siteTwitter }];
if (contentType === 'video/mp4' || contentType === 'video/webm') {
metaTags.push({ property: 'og:video', content: source });
metaTags.push({ property: 'og:video:secure_url', content: source });
metaTags.push({ property: 'og:video:type', content: contentType });
metaTags.push({ property: 'og:image', content: ogThumbnail });
metaTags.push({ property: 'og:image:type', content: ogThumbnailContentType });
metaTags.push({ property: 'og:type', content: 'video' });
metaTags.push({ property: 'twitter:card', content: 'player' });
metaTags.push({ property: 'twitter:player', content: embedUrl });
metaTags.push({ property: 'twitter:player:width', content: 600 });
metaTags.push({ property: 'twitter:text:player_width', content: 600 });
metaTags.push({ property: 'twitter:player:height', content: 337 });
metaTags.push({ property: 'twitter:player:stream', content: source });
metaTags.push({ property: 'twitter:player:stream:content_type', content: contentType });
} else {
metaTags.push({ property: 'og:image', content: source });
metaTags.push({ property: 'og:image:type', content: contentType });
metaTags.push({ property: 'og:type', content: 'article' });
metaTags.push({ property: 'twitter:card', content: 'summary_large_image' });
}
return metaTags;
};
var createMetaTags = exports.createMetaTags = function createMetaTags(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail) {
if (asset) {
return createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail);
};
if (channel) {
return createChannelMetaTags(siteHost, siteTitle, siteTwitter, channel);
};
return createBasicMetaTags(siteDescription, siteHost, siteTitle, siteTwitter);
};
/***/ }),
/* 92 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var createBasicCanonicalLink = function createBasicCanonicalLink(page, siteHost) {
return siteHost + "/" + page;
};
var createAssetCanonicalLink = function createAssetCanonicalLink(asset, siteHost) {
var channelName = void 0,
certificateId = void 0,
name = void 0,
claimId = void 0;
if (asset.claimData) {
var _asset$claimData = asset.claimData;
channelName = _asset$claimData.channelName;
certificateId = _asset$claimData.certificateId;
name = _asset$claimData.name;
claimId = _asset$claimData.claimId;
};
if (channelName) {
return siteHost + "/" + channelName + ":" + certificateId + "/" + name;
};
return siteHost + "/" + claimId + "/" + name;
};
var createChannelCanonicalLink = function createChannelCanonicalLink(channel, siteHost) {
var name = channel.name,
longId = channel.longId;
return siteHost + "/" + name + ":" + longId;
};
var createCanonicalLink = exports.createCanonicalLink = function createCanonicalLink(asset, channel, page, siteHost) {
if (asset) {
return createAssetCanonicalLink(asset, siteHost);
}
if (channel) {
return createChannelCanonicalLink(channel, siteHost);
}
return createBasicCanonicalLink(page, siteHost);
};
/***/ }),
/* 93 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactRouterDom = __webpack_require__(3);
var _Logo = __webpack_require__(94);
var _Logo2 = _interopRequireDefault(_Logo);
var _NavBarChannelOptionsDropdown = __webpack_require__(95);
var _NavBarChannelOptionsDropdown2 = _interopRequireDefault(_NavBarChannelOptionsDropdown);
var _request = __webpack_require__(11);
var _request2 = _interopRequireDefault(_request);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var VIEW = 'VIEW';
var LOGOUT = 'LOGOUT';
var NavBar = function (_React$Component) {
_inherits(NavBar, _React$Component);
function NavBar(props) {
_classCallCheck(this, NavBar);
var _this = _possibleConstructorReturn(this, (NavBar.__proto__ || Object.getPrototypeOf(NavBar)).call(this, props));
_this.checkForLoggedInUser = _this.checkForLoggedInUser.bind(_this);
_this.logoutUser = _this.logoutUser.bind(_this);
_this.handleSelection = _this.handleSelection.bind(_this);
return _this;
}
_createClass(NavBar, [{
key: 'componentDidMount',
value: function componentDidMount() {
// check to see if the user is already logged in
this.checkForLoggedInUser();
}
}, {
key: 'checkForLoggedInUser',
value: function checkForLoggedInUser() {
var _this2 = this;
var params = { credentials: 'include' };
(0, _request2.default)('/user', params).then(function (_ref) {
var data = _ref.data;
_this2.props.onChannelLogin(data.channelName, data.shortChannelId, data.channelClaimId);
}).catch(function (error) {
console.log('/user error:', error.message);
});
}
}, {
key: 'logoutUser',
value: function logoutUser() {
var _this3 = this;
var params = { credentials: 'include' };
(0, _request2.default)('/logout', params).then(function () {
_this3.props.onChannelLogout();
}).catch(function (error) {
console.log('/logout error', error.message);
});
}
}, {
key: 'handleSelection',
value: function handleSelection(event) {
var value = event.target.selectedOptions[0].value;
switch (value) {
case LOGOUT:
this.logoutUser();
break;
case VIEW:
// redirect to channel page
this.props.history.push('/' + this.props.channelName + ':' + this.props.channelLongId);
break;
default:
break;
}
}
}, {
key: 'render',
value: function render() {
var siteDescription = this.props.siteDescription;
return _react2.default.createElement(
'div',
{ className: 'row row--wide nav-bar' },
_react2.default.createElement(
'div',
{ className: 'row row--padded row--short flex-container--row flex-container--space-between-center' },
_react2.default.createElement(_Logo2.default, null),
_react2.default.createElement(
'div',
{ className: 'nav-bar--center' },
_react2.default.createElement(
'span',
{ className: 'nav-bar-tagline' },
siteDescription
)
),
_react2.default.createElement(
'div',
{ className: 'nav-bar--right' },
_react2.default.createElement(
_reactRouterDom.NavLink,
{ className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/', exact: true },
'Publish'
),
_react2.default.createElement(
_reactRouterDom.NavLink,
{ className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/about' },
'About'
),
this.props.channelName ? _react2.default.createElement(_NavBarChannelOptionsDropdown2.default, {
channelName: this.props.channelName,
handleSelection: this.handleSelection,
defaultSelection: this.props.channelName,
VIEW: VIEW,
LOGOUT: LOGOUT
}) : _react2.default.createElement(
_reactRouterDom.NavLink,
{ id: 'nav-bar-login-link', className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/login' },
'Channel'
)
)
)
);
}
}]);
return NavBar;
}(_react2.default.Component);
exports.default = (0, _reactRouterDom.withRouter)(NavBar);
/***/ }),
/* 94 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactRouterDom = __webpack_require__(3);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function Logo() {
return _react2.default.createElement(
'svg',
{ version: '1.1', id: 'Layer_1', x: '0px', y: '0px', height: '24px', viewBox: '0 0 80 31', enableBackground: 'new 0 0 80 31', className: 'nav-bar-logo' },
_react2.default.createElement(
_reactRouterDom.Link,
{ to: '/' },
_react2.default.createElement(
'title',
null,
'Logo'
),
_react2.default.createElement(
'desc',
null,
'Spee.ch logo'
),
_react2.default.createElement(
'g',
{ id: 'About' },
_react2.default.createElement(
'g',
{ id: 'Publish-Form-V2-_x28_filled_x29_', transform: 'translate(-42.000000, -23.000000)' },
_react2.default.createElement(
'g',
{ id: 'Group-17', transform: 'translate(42.000000, 22.000000)' },
_react2.default.createElement(
'text',
{ transform: 'matrix(1 0 0 1 0 20)', fontSize: '25', fontFamily: 'Roboto' },
'Spee<h'
),
_react2.default.createElement(
'g',
{ id: 'Group-16', transform: 'translate(0.000000, 30.000000)' },
_react2.default.createElement('path', { id: 'Line-8', fill: 'none', stroke: '#09F911', strokeWidth: '1', strokeLinecap: 'square', d: 'M0.5,1.5h15' }),
_react2.default.createElement('path', { id: 'Line-8-Copy', fill: 'none', stroke: '#029D74', strokeWidth: '1', strokeLinecap: 'square', d: 'M16.5,1.5h15' }),
_react2.default.createElement('path', { id: 'Line-8-Copy-2', fill: 'none', stroke: '#E35BD8', strokeWidth: '1', strokeLinecap: 'square', d: 'M32.5,1.5h15' }),
_react2.default.createElement('path', { id: 'Line-8-Copy-3', fill: 'none', stroke: '#4156C5', strokeWidth: '1', strokeLinecap: 'square', d: 'M48.5,1.5h15' }),
_react2.default.createElement('path', { id: 'Line-8-Copy-4', fill: 'none', stroke: '#635688', strokeWidth: '1', strokeLinecap: 'square', d: 'M64.5,1.5h15' })
)
)
)
)
)
);
};
exports.default = Logo;
/***/ }),
/* 95 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function NavBarChannelDropdown(_ref) {
var channelName = _ref.channelName,
handleSelection = _ref.handleSelection,
defaultSelection = _ref.defaultSelection,
VIEW = _ref.VIEW,
LOGOUT = _ref.LOGOUT;
return _react2.default.createElement(
'select',
{ type: 'text', id: 'nav-bar-channel-select', className: 'select select--arrow link--nav', onChange: handleSelection, value: defaultSelection },
_react2.default.createElement(
'option',
{ id: 'nav-bar-channel-select-channel-option' },
channelName
),
_react2.default.createElement(
'option',
{ value: VIEW },
'View'
),
_react2.default.createElement(
'option',
{ value: LOGOUT },
'Logout'
)
);
};
exports.default = NavBarChannelDropdown;
/***/ }),
/* 96 */
/***/ (function(module, exports) {
module.exports = require("cross-fetch/polyfill");
/***/ }),
/* 97 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(98);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var publish = _ref.publish;
return {
disabled: publish.disabled,
file: publish.file,
status: publish.status.status
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 98 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _Dropzone = __webpack_require__(38);
var _Dropzone2 = _interopRequireDefault(_Dropzone);
var _PublishDetails = __webpack_require__(102);
var _PublishDetails2 = _interopRequireDefault(_PublishDetails);
var _PublishStatus = __webpack_require__(120);
var _PublishStatus2 = _interopRequireDefault(_PublishStatus);
var _PublishDisabledMessage = __webpack_require__(123);
var _PublishDisabledMessage2 = _interopRequireDefault(_PublishDisabledMessage);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PublishTool = function (_React$Component) {
_inherits(PublishTool, _React$Component);
function PublishTool() {
_classCallCheck(this, PublishTool);
return _possibleConstructorReturn(this, (PublishTool.__proto__ || Object.getPrototypeOf(PublishTool)).apply(this, arguments));
}
_createClass(PublishTool, [{
key: 'render',
value: function render() {
if (this.props.disabled) {
console.log('publish is disabled');
return _react2.default.createElement(_PublishDisabledMessage2.default, null);
} else {
console.log('publish is not disabled');
if (this.props.file) {
if (this.props.status) {
return _react2.default.createElement(_PublishStatus2.default, null);
} else {
return _react2.default.createElement(_PublishDetails2.default, null);
}
}
return _react2.default.createElement(_Dropzone2.default, null);
}
}
}]);
return PublishTool;
}(_react2.default.Component);
;
exports.default = PublishTool;
/***/ }),
/* 99 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _file = __webpack_require__(100);
var _PublishPreview = __webpack_require__(101);
var _PublishPreview2 = _interopRequireDefault(_PublishPreview);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Dropzone = function (_React$Component) {
_inherits(Dropzone, _React$Component);
function Dropzone(props) {
_classCallCheck(this, Dropzone);
var _this = _possibleConstructorReturn(this, (Dropzone.__proto__ || Object.getPrototypeOf(Dropzone)).call(this, props));
_this.state = {
dragOver: false,
mouseOver: false,
dimPreview: false
};
_this.handleDrop = _this.handleDrop.bind(_this);
_this.handleDragOver = _this.handleDragOver.bind(_this);
_this.handleDragEnd = _this.handleDragEnd.bind(_this);
_this.handleDragEnter = _this.handleDragEnter.bind(_this);
_this.handleDragLeave = _this.handleDragLeave.bind(_this);
_this.handleMouseEnter = _this.handleMouseEnter.bind(_this);
_this.handleMouseLeave = _this.handleMouseLeave.bind(_this);
_this.handleClick = _this.handleClick.bind(_this);
_this.handleFileInput = _this.handleFileInput.bind(_this);
_this.chooseFile = _this.chooseFile.bind(_this);
return _this;
}
_createClass(Dropzone, [{
key: 'handleDrop',
value: function handleDrop(event) {
event.preventDefault();
this.setState({ dragOver: false });
// if dropped items aren't files, reject them
var dt = event.dataTransfer;
if (dt.items) {
if (dt.items[0].kind === 'file') {
var droppedFile = dt.items[0].getAsFile();
this.chooseFile(droppedFile);
}
}
}
}, {
key: 'handleDragOver',
value: function handleDragOver(event) {
event.preventDefault();
}
}, {
key: 'handleDragEnd',
value: function handleDragEnd(event) {
var dt = event.dataTransfer;
if (dt.items) {
for (var i = 0; i < dt.items.length; i++) {
dt.items.remove(i);
}
} else {
event.dataTransfer.clearData();
}
}
}, {
key: 'handleDragEnter',
value: function handleDragEnter() {
this.setState({ dragOver: true, dimPreview: true });
}
}, {
key: 'handleDragLeave',
value: function handleDragLeave() {
this.setState({ dragOver: false, dimPreview: false });
}
}, {
key: 'handleMouseEnter',
value: function handleMouseEnter() {
this.setState({ mouseOver: true, dimPreview: true });
}
}, {
key: 'handleMouseLeave',
value: function handleMouseLeave() {
this.setState({ mouseOver: false, dimPreview: false });
}
}, {
key: 'handleClick',
value: function handleClick(event) {
event.preventDefault();
document.getElementById('file_input').click();
}
}, {
key: 'handleFileInput',
value: function handleFileInput(event) {
event.preventDefault();
var fileList = event.target.files;
this.chooseFile(fileList[0]);
}
}, {
key: 'chooseFile',
value: function chooseFile(file) {
if (file) {
try {
(0, _file.validateFile)(file); // validate the file's name, type, and size
} catch (error) {
return this.props.setFileError(error.message);
}
// stage it so it will be ready when the publish button is clicked
this.props.selectFile(file);
}
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'row row--tall flex-container--column' },
_react2.default.createElement(
'form',
null,
_react2.default.createElement('input', { className: 'input-file', type: 'file', id: 'file_input', name: 'file_input', accept: 'video/*,image/*', onChange: this.handleFileInput, encType: 'multipart/form-data' })
),
_react2.default.createElement(
'div',
{ id: 'preview-dropzone', className: 'row row--padded row--tall dropzone' + (this.state.dragOver ? ' dropzone--drag-over' : ''), onDrop: this.handleDrop, onDragOver: this.handleDragOver, onDragEnd: this.handleDragEnd, onDragEnter: this.handleDragEnter, onDragLeave: this.handleDragLeave, onMouseEnter: this.handleMouseEnter, onMouseLeave: this.handleMouseLeave, onClick: this.handleClick },
this.props.file ? _react2.default.createElement(
'div',
null,
_react2.default.createElement(_PublishPreview2.default, {
dimPreview: this.state.dimPreview,
file: this.props.file,
thumbnail: this.props.thumbnail
}),
_react2.default.createElement(
'div',
{ id: 'dropzone-text-holder', className: 'flex-container--column flex-container--center-center' },
this.state.dragOver ? _react2.default.createElement(
'div',
{ id: 'dropzone-dragover' },
_react2.default.createElement(
'p',
{ className: 'blue' },
'Drop it.'
)
) : null,
this.state.mouseOver ? _react2.default.createElement(
'div',
{ id: 'dropzone-instructions' },
_react2.default.createElement(
'p',
{ className: 'info-message-placeholder info-message--failure', id: 'input-error-file-selection' },
this.props.fileError
),
_react2.default.createElement(
'p',
null,
'Drag & drop image or video here to publish'
),
_react2.default.createElement(
'p',
{ className: 'fine-print' },
'OR'
),
_react2.default.createElement(
'p',
{ className: 'blue--underlined' },
'CHOOSE FILE'
)
) : null
)
) : _react2.default.createElement(
'div',
{ id: 'dropzone-text-holder', className: 'flex-container--column flex-container--center-center' },
this.state.dragOver ? _react2.default.createElement(
'div',
{ id: 'dropzone-dragover' },
_react2.default.createElement(
'p',
{ className: 'blue' },
'Drop it.'
)
) : _react2.default.createElement(
'div',
{ id: 'dropzone-instructions' },
_react2.default.createElement(
'p',
{ className: 'info-message-placeholder info-message--failure', id: 'input-error-file-selection' },
this.props.fileError
),
_react2.default.createElement(
'p',
null,
'Drag & drop image or video here to publish'
),
_react2.default.createElement(
'p',
{ className: 'fine-print' },
'OR'
),
_react2.default.createElement(
'p',
{ className: 'blue--underlined' },
'CHOOSE FILE'
)
)
)
)
);
}
}]);
return Dropzone;
}(_react2.default.Component);
;
exports.default = Dropzone;
/***/ }),
/* 100 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = {
validateFile: function validateFile(file) {
if (!file) {
throw new Error('no file provided');
}
if (/'/.test(file.name)) {
throw new Error('apostrophes are not allowed in the file name');
}
// validate size and type
switch (file.type) {
case 'image/jpeg':
case 'image/jpg':
case 'image/png':
if (file.size > 10000000) {
throw new Error('Sorry, images are limited to 10 megabytes.');
}
break;
case 'image/gif':
if (file.size > 50000000) {
throw new Error('Sorry, GIFs are limited to 50 megabytes.');
}
break;
case 'video/mp4':
if (file.size > 50000000) {
throw new Error('Sorry, videos are limited to 50 megabytes.');
}
break;
default:
throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');
}
}
};
/***/ }),
/* 101 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(10);
var _propTypes2 = _interopRequireDefault(_propTypes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PublishPreview = function (_React$Component) {
_inherits(PublishPreview, _React$Component);
function PublishPreview(props) {
_classCallCheck(this, PublishPreview);
var _this = _possibleConstructorReturn(this, (PublishPreview.__proto__ || Object.getPrototypeOf(PublishPreview)).call(this, props));
_this.state = {
imgSource: '',
defaultThumbnail: '/assets/img/video_thumb_default.png'
};
return _this;
}
_createClass(PublishPreview, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.setPreviewImageSource(this.props.file);
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(newProps) {
if (newProps.file !== this.props.file) {
this.setPreviewImageSource(newProps.file);
}
if (newProps.thumbnail !== this.props.thumbnail) {
if (newProps.thumbnail) {
this.setPreviewImageSourceFromFile(newProps.thumbnail);
} else {
this.setState({ imgSource: this.state.defaultThumbnail });
}
}
}
}, {
key: 'setPreviewImageSourceFromFile',
value: function setPreviewImageSourceFromFile(file) {
var _this2 = this;
var previewReader = new FileReader();
previewReader.readAsDataURL(file);
previewReader.onloadend = function () {
_this2.setState({ imgSource: previewReader.result });
};
}
}, {
key: 'setPreviewImageSource',
value: function setPreviewImageSource(file) {
if (file.type !== 'video/mp4') {
this.setPreviewImageSourceFromFile(file);
} else {
if (this.props.thumbnail) {
this.setPreviewImageSourceFromFile(this.props.thumbnail);
}
this.setState({ imgSource: this.state.defaultThumbnail });
}
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement('img', {
id: 'dropzone-preview',
src: this.state.imgSource,
className: this.props.dimPreview ? 'dim' : '',
alt: 'publish preview'
});
}
}]);
return PublishPreview;
}(_react2.default.Component);
;
PublishPreview.propTypes = {
dimPreview: _propTypes2.default.bool.isRequired,
file: _propTypes2.default.object.isRequired,
thumbnail: _propTypes2.default.object
};
exports.default = PublishPreview;
/***/ }),
/* 102 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _publish = __webpack_require__(4);
var _view = __webpack_require__(103);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var channel = _ref.channel,
publish = _ref.publish;
return {
file: publish.file
};
};
var mapDispatchToProps = {
clearFile: _publish.clearFile,
startPublish: _publish.startPublish
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 103 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactRouterDom = __webpack_require__(3);
var _Dropzone = __webpack_require__(38);
var _Dropzone2 = _interopRequireDefault(_Dropzone);
var _PublishTitleInput = __webpack_require__(104);
var _PublishTitleInput2 = _interopRequireDefault(_PublishTitleInput);
var _PublishUrlInput = __webpack_require__(106);
var _PublishUrlInput2 = _interopRequireDefault(_PublishUrlInput);
var _PublishThumbnailInput = __webpack_require__(109);
var _PublishThumbnailInput2 = _interopRequireDefault(_PublishThumbnailInput);
var _PublishMetadataInputs = __webpack_require__(111);
var _PublishMetadataInputs2 = _interopRequireDefault(_PublishMetadataInputs);
var _ChannelSelect = __webpack_require__(114);
var _ChannelSelect2 = _interopRequireDefault(_ChannelSelect);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PublishDetails = function (_React$Component) {
_inherits(PublishDetails, _React$Component);
function PublishDetails(props) {
_classCallCheck(this, PublishDetails);
var _this = _possibleConstructorReturn(this, (PublishDetails.__proto__ || Object.getPrototypeOf(PublishDetails)).call(this, props));
_this.onPublishSubmit = _this.onPublishSubmit.bind(_this);
return _this;
}
_createClass(PublishDetails, [{
key: 'onPublishSubmit',
value: function onPublishSubmit() {
this.props.startPublish(this.props.history);
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'row row--no-bottom' },
_react2.default.createElement(
'div',
{ className: 'column column--10' },
_react2.default.createElement(_PublishTitleInput2.default, null)
),
_react2.default.createElement(
'div',
{ className: 'column column--5 column--sml-10' },
_react2.default.createElement(
'div',
{ className: 'row row--padded' },
_react2.default.createElement(_Dropzone2.default, null)
)
),
_react2.default.createElement(
'div',
{ className: 'column column--5 column--sml-10 align-content-top' },
_react2.default.createElement(
'div',
{ id: 'publish-active-area', className: 'row row--padded' },
_react2.default.createElement(
'div',
{ className: 'row row--padded row--no-top row--wide' },
_react2.default.createElement(_PublishUrlInput2.default, null)
),
_react2.default.createElement(
'div',
{ className: 'row row--padded row--no-top row--wide' },
_react2.default.createElement(_ChannelSelect2.default, null)
),
this.props.file.type === 'video/mp4' && _react2.default.createElement(
'div',
{ className: 'row row--padded row--no-top row--wide ' },
_react2.default.createElement(_PublishThumbnailInput2.default, null)
),
_react2.default.createElement(
'div',
{ className: 'row row--padded row--no-top row--no-bottom row--wide' },
_react2.default.createElement(_PublishMetadataInputs2.default, null)
),
_react2.default.createElement(
'div',
{ className: 'row row--wide align-content-center' },
_react2.default.createElement(
'button',
{ id: 'publish-submit', className: 'button--primary button--large', onClick: this.onPublishSubmit },
'Publish'
)
),
_react2.default.createElement(
'div',
{ className: 'row row--padded row--no-bottom align-content-center' },
_react2.default.createElement(
'button',
{ className: 'button--cancel', onClick: this.props.clearFile },
'Cancel'
)
),
_react2.default.createElement(
'div',
{ className: 'row row--short align-content-center' },
_react2.default.createElement(
'p',
{ className: 'fine-print' },
'By clicking \'Publish\', you affirm that you have the rights to publish this content to the LBRY network, and that you understand the properties of publishing it to a decentralized, user-controlled network. ',
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://lbry.io/learn' },
'Read more.'
)
)
)
)
)
);
}
}]);
return PublishDetails;
}(_react2.default.Component);
;
exports.default = (0, _reactRouterDom.withRouter)(PublishDetails);
/***/ }),
/* 104 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _publish = __webpack_require__(4);
var _view = __webpack_require__(105);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var publish = _ref.publish;
return {
title: publish.metadata.title
};
};
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
onMetadataChange: function onMetadataChange(name, value) {
dispatch((0, _publish.updateMetadata)(name, value));
}
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 105 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PublishTitleInput = function (_React$Component) {
_inherits(PublishTitleInput, _React$Component);
function PublishTitleInput(props) {
_classCallCheck(this, PublishTitleInput);
var _this = _possibleConstructorReturn(this, (PublishTitleInput.__proto__ || Object.getPrototypeOf(PublishTitleInput)).call(this, props));
_this.handleInput = _this.handleInput.bind(_this);
return _this;
}
_createClass(PublishTitleInput, [{
key: 'handleInput',
value: function handleInput(e) {
var name = e.target.name;
var value = e.target.value;
this.props.onMetadataChange(name, value);
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement('input', { type: 'text', id: 'publish-title', className: 'input-text text--large input-text--full-width', name: 'title', placeholder: 'Give your post a title...', onChange: this.handleInput, value: this.props.title });
}
}]);
return PublishTitleInput;
}(_react2.default.Component);
exports.default = PublishTitleInput;
/***/ }),
/* 106 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _publish = __webpack_require__(4);
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(107);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var channel = _ref.channel,
publish = _ref.publish;
return {
loggedInChannelName: channel.loggedInChannel.name,
loggedInChannelShortId: channel.loggedInChannel.shortId,
fileName: publish.file.name,
publishInChannel: publish.publishInChannel,
selectedChannel: publish.selectedChannel,
claim: publish.claim,
urlError: publish.error.url
};
};
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
onClaimChange: function onClaimChange(value) {
dispatch((0, _publish.updateClaim)(value));
dispatch((0, _publish.updateError)('publishSubmit', null));
},
onUrlError: function onUrlError(value) {
dispatch((0, _publish.updateError)('url', value));
}
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 107 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _request = __webpack_require__(11);
var _request2 = _interopRequireDefault(_request);
var _PublishUrlMiddleDisplay = __webpack_require__(108);
var _PublishUrlMiddleDisplay2 = _interopRequireDefault(_PublishUrlMiddleDisplay);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PublishUrlInput = function (_React$Component) {
_inherits(PublishUrlInput, _React$Component);
function PublishUrlInput(props) {
_classCallCheck(this, PublishUrlInput);
var _this = _possibleConstructorReturn(this, (PublishUrlInput.__proto__ || Object.getPrototypeOf(PublishUrlInput)).call(this, props));
_this.handleInput = _this.handleInput.bind(_this);
return _this;
}
_createClass(PublishUrlInput, [{
key: 'componentDidMount',
value: function componentDidMount() {
var _props = this.props,
claim = _props.claim,
fileName = _props.fileName;
if (!claim) {
this.setClaimName(fileName);
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(_ref) {
var claim = _ref.claim,
fileName = _ref.fileName;
// if a new file was chosen, update the claim name
if (fileName !== this.props.fileName) {
return this.setClaimName(fileName);
}
// if the claim has updated, check its availability
if (claim !== this.props.claim) {
this.validateClaim(claim);
}
}
}, {
key: 'handleInput',
value: function handleInput(event) {
var value = event.target.value;
value = this.cleanseInput(value);
// update the state
this.props.onClaimChange(value);
}
}, {
key: 'cleanseInput',
value: function cleanseInput(input) {
input = input.replace(/\s+/g, '-'); // replace spaces with dashes
input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'
return input;
}
}, {
key: 'setClaimName',
value: function setClaimName(fileName) {
var fileNameWithoutEnding = fileName.substring(0, fileName.lastIndexOf('.'));
var cleanClaimName = this.cleanseInput(fileNameWithoutEnding);
this.props.onClaimChange(cleanClaimName);
}
}, {
key: 'validateClaim',
value: function validateClaim(claim) {
var _this2 = this;
if (!claim) {
return this.props.onUrlError('Enter a url above');
}
(0, _request2.default)('/api/claim/availability/' + claim).then(function () {
_this2.props.onUrlError(null);
}).catch(function (error) {
_this2.props.onUrlError(error.message);
});
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
claim = _props2.claim,
loggedInChannelName = _props2.loggedInChannelName,
loggedInChannelShortId = _props2.loggedInChannelShortId,
publishInChannel = _props2.publishInChannel,
selectedChannel = _props2.selectedChannel,
urlError = _props2.urlError;
return _react2.default.createElement(
'div',
{ className: 'column column--10 column--sml-10' },
_react2.default.createElement(
'div',
{ className: 'input-text--primary span--relative' },
_react2.default.createElement(
'span',
{ className: 'url-text--secondary' },
'spee.ch / '
),
_react2.default.createElement(_PublishUrlMiddleDisplay2.default, {
publishInChannel: publishInChannel,
selectedChannel: selectedChannel,
loggedInChannelName: loggedInChannelName,
loggedInChannelShortId: loggedInChannelShortId
}),
_react2.default.createElement('input', { type: 'text', id: 'claim-name-input', className: 'input-text', name: 'claim', placeholder: 'your-url-here', onChange: this.handleInput, value: claim }),
claim && !urlError && _react2.default.createElement(
'span',
{ id: 'input-success-claim-name', className: 'info-message--success span--absolute' },
'\u2713'
),
urlError && _react2.default.createElement(
'span',
{ id: 'input-success-channel-name', className: 'info-message--failure span--absolute' },
'\u2716'
)
),
_react2.default.createElement(
'div',
null,
urlError ? _react2.default.createElement(
'p',
{ id: 'input-error-claim-name', className: 'info-message--failure' },
urlError
) : _react2.default.createElement(
'p',
{ className: 'info-message' },
'Choose a custom url'
)
)
);
}
}]);
return PublishUrlInput;
}(_react2.default.Component);
exports.default = PublishUrlInput;
/***/ }),
/* 108 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(10);
var _propTypes2 = _interopRequireDefault(_propTypes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function UrlMiddle(_ref) {
var publishInChannel = _ref.publishInChannel,
selectedChannel = _ref.selectedChannel,
loggedInChannelName = _ref.loggedInChannelName,
loggedInChannelShortId = _ref.loggedInChannelShortId;
if (publishInChannel) {
if (selectedChannel === loggedInChannelName) {
return _react2.default.createElement(
'span',
{ id: 'url-channel', className: 'url-text--secondary' },
loggedInChannelName,
':',
loggedInChannelShortId,
' /'
);
}
return _react2.default.createElement(
'span',
{ id: 'url-channel-placeholder', className: 'url-text--secondary tooltip' },
'@channel',
_react2.default.createElement(
'span',
{
className: 'tooltip-text' },
'Select a channel below'
),
' /'
);
}
return _react2.default.createElement(
'span',
{ id: 'url-no-channel-placeholder', className: 'url-text--secondary tooltip' },
'xyz',
_react2.default.createElement(
'span',
{ className: 'tooltip-text' },
'This will be a random id'
),
' /'
);
}
UrlMiddle.propTypes = {
publishInChannel: _propTypes2.default.bool.isRequired,
loggedInChannelName: _propTypes2.default.string,
loggedInChannelShortId: _propTypes2.default.string
};
exports.default = UrlMiddle;
/***/ }),
/* 109 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _publish = __webpack_require__(4);
var _view = __webpack_require__(110);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var file = _ref.publish.file;
return {
file: file
};
};
var mapDispatchToProps = {
onNewThumbnail: _publish.onNewThumbnail
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 110 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], { type: mimeString });
}
var PublishThumbnailInput = function (_React$Component) {
_inherits(PublishThumbnailInput, _React$Component);
function PublishThumbnailInput(props) {
_classCallCheck(this, PublishThumbnailInput);
var _this = _possibleConstructorReturn(this, (PublishThumbnailInput.__proto__ || Object.getPrototypeOf(PublishThumbnailInput)).call(this, props));
_this.state = {
videoSource: null,
error: null,
sliderMinRange: 1,
sliderMaxRange: null,
sliderValue: null
};
_this.handleVideoLoadedData = _this.handleVideoLoadedData.bind(_this);
_this.handleSliderChange = _this.handleSliderChange.bind(_this);
_this.createThumbnail = _this.createThumbnail.bind(_this);
return _this;
}
_createClass(PublishThumbnailInput, [{
key: 'componentDidMount',
value: function componentDidMount() {
var file = this.props.file;
this.setVideoSource(file);
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
// if file changes
if (nextProps.file && nextProps.file !== this.props.file) {
var file = nextProps.file;
this.setVideoSource(file);
};
}
}, {
key: 'setVideoSource',
value: function setVideoSource(file) {
var _this2 = this;
var previewReader = new FileReader();
previewReader.readAsDataURL(file);
previewReader.onloadend = function () {
var dataUri = previewReader.result;
var blob = dataURItoBlob(dataUri);
var videoSource = URL.createObjectURL(blob);
_this2.setState({ videoSource: videoSource });
};
}
}, {
key: 'handleVideoLoadedData',
value: function handleVideoLoadedData(event) {
var duration = event.target.duration;
var totalMinutes = Math.floor(duration / 60);
var totalSeconds = Math.floor(duration % 60);
// set the slider
this.setState({
sliderMaxRange: duration * 100,
sliderValue: duration * 100 / 2,
totalMinutes: totalMinutes,
totalSeconds: totalSeconds
});
// update the current time of the video
var video = document.getElementById('video-thumb-player');
video.currentTime = duration / 2;
}
}, {
key: 'handleSliderChange',
value: function handleSliderChange(event) {
var value = parseInt(event.target.value);
// update the slider value
this.setState({
sliderValue: value
});
// update the current time of the video
var video = document.getElementById('video-thumb-player');
video.currentTime = value / 100;
}
}, {
key: 'createThumbnail',
value: function createThumbnail() {
// take a snapshot
var video = document.getElementById('video-thumb-player');
var canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
var dataUrl = canvas.toDataURL();
var blob = dataURItoBlob(dataUrl);
var snapshot = new File([blob], 'thumbnail.png', {
type: 'image/png'
});
// set the thumbnail in redux store
if (snapshot) {
this.props.onNewThumbnail(snapshot);
}
}
}, {
key: 'render',
value: function render() {
var _state = this.state,
error = _state.error,
videoSource = _state.videoSource,
sliderMinRange = _state.sliderMinRange,
sliderMaxRange = _state.sliderMaxRange,
sliderValue = _state.sliderValue,
totalMinutes = _state.totalMinutes,
totalSeconds = _state.totalSeconds;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'label',
{ className: 'label' },
'Thumbnail:'
),
_react2.default.createElement('video', {
id: 'video-thumb-player',
preload: 'metadata',
muted: true,
style: { display: 'none' },
playsInline: true,
onLoadedData: this.handleVideoLoadedData,
src: videoSource,
onSeeked: this.createThumbnail
}),
sliderValue ? _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'div',
{ className: 'flex-container--row flex-container--space-between-center', style: { width: '100%' } },
_react2.default.createElement(
'span',
{ className: 'info-message' },
'0\'00"'
),
_react2.default.createElement(
'span',
{ className: 'info-message' },
totalMinutes,
'\'',
totalSeconds,
'"'
)
),
_react2.default.createElement(
'div',
null,
_react2.default.createElement('input', {
type: 'range',
min: sliderMinRange,
max: sliderMaxRange,
value: sliderValue,
className: 'slider',
onChange: this.handleSliderChange
})
)
) : _react2.default.createElement(
'p',
{ className: 'info-message' },
'loading... '
),
error ? _react2.default.createElement(
'p',
{ className: 'info-message--failure' },
error
) : _react2.default.createElement(
'p',
{ className: 'info-message' },
'Use slider to set thumbnail'
)
);
}
}]);
return PublishThumbnailInput;
}(_react2.default.Component);
exports.default = PublishThumbnailInput;
/***/ }),
/* 111 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _publish = __webpack_require__(4);
var _view = __webpack_require__(112);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var publish = _ref.publish;
return {
showMetadataInputs: publish.showMetadataInputs,
description: publish.metadata.description,
license: publish.metadata.license,
nsfw: publish.metadata.nsfw
};
};
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
onMetadataChange: function onMetadataChange(name, value) {
dispatch((0, _publish.updateMetadata)(name, value));
},
onToggleMetadataInputs: function onToggleMetadataInputs(value) {
dispatch((0, _publish.toggleMetadataInputs)(value));
}
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 112 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _ExpandingTextArea = __webpack_require__(113);
var _ExpandingTextArea2 = _interopRequireDefault(_ExpandingTextArea);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PublishMetadataInputs = function (_React$Component) {
_inherits(PublishMetadataInputs, _React$Component);
function PublishMetadataInputs(props) {
_classCallCheck(this, PublishMetadataInputs);
var _this = _possibleConstructorReturn(this, (PublishMetadataInputs.__proto__ || Object.getPrototypeOf(PublishMetadataInputs)).call(this, props));
_this.toggleShowInputs = _this.toggleShowInputs.bind(_this);
_this.handleInput = _this.handleInput.bind(_this);
_this.handleSelect = _this.handleSelect.bind(_this);
return _this;
}
_createClass(PublishMetadataInputs, [{
key: 'toggleShowInputs',
value: function toggleShowInputs() {
this.props.onToggleMetadataInputs(!this.props.showMetadataInputs);
}
}, {
key: 'handleInput',
value: function handleInput(event) {
var target = event.target;
var value = target.type === 'checkbox' ? target.checked : target.value;
var name = target.name;
this.props.onMetadataChange(name, value);
}
}, {
key: 'handleSelect',
value: function handleSelect(event) {
var name = event.target.name;
var selectedOption = event.target.selectedOptions[0].value;
this.props.onMetadataChange(name, selectedOption);
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ id: 'publish-details', className: 'row row--padded row--no-top row--wide' },
this.props.showMetadataInputs && _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'div',
{ className: 'row row--no-top' },
_react2.default.createElement(
'div',
{ className: 'column column--3 column--med-10 align-content-top' },
_react2.default.createElement(
'label',
{ htmlFor: 'publish-license', className: 'label' },
'Description:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--7 column--sml-10' },
_react2.default.createElement(_ExpandingTextArea2.default, {
id: 'publish-description',
className: 'textarea textarea--primary textarea--full-width',
rows: 1,
maxLength: 2000,
style: { maxHeight: 200 },
name: 'description',
placeholder: 'Optional description',
value: this.props.description,
onChange: this.handleInput })
)
),
_react2.default.createElement(
'div',
{ className: 'row row--no-top' },
_react2.default.createElement(
'div',
{ className: 'column column--3 column--med-10' },
_react2.default.createElement(
'label',
{ htmlFor: 'publish-license', className: 'label' },
'License:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--7 column--sml-10' },
_react2.default.createElement(
'select',
{ type: 'text', name: 'license', id: 'publish-license', className: 'select select--primary', onChange: this.handleSelect },
_react2.default.createElement(
'option',
{ value: ' ' },
'Unspecified'
),
_react2.default.createElement(
'option',
{ value: 'Public Domain' },
'Public Domain'
),
_react2.default.createElement(
'option',
{ value: 'Creative Commons' },
'Creative Commons'
)
)
)
),
_react2.default.createElement(
'div',
{ className: 'row row--no-top' },
_react2.default.createElement(
'div',
{ className: 'column column--3' },
_react2.default.createElement(
'label',
{ htmlFor: 'publish-nsfw', className: 'label' },
'Mature:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--7' },
_react2.default.createElement('input', { className: 'input-checkbox', type: 'checkbox', id: 'publish-nsfw', name: 'nsfw', value: this.props.nsfw, onChange: this.handleInput })
)
)
),
_react2.default.createElement(
'button',
{ className: 'button--secondary', onClick: this.toggleShowInputs },
this.props.showMetadataInputs ? 'less' : 'more'
)
);
}
}]);
return PublishMetadataInputs;
}(_react2.default.Component);
exports.default = PublishMetadataInputs;
/***/ }),
/* 113 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(10);
var _propTypes2 = _interopRequireDefault(_propTypes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ExpandingTextarea = function (_Component) {
_inherits(ExpandingTextarea, _Component);
function ExpandingTextarea(props) {
_classCallCheck(this, ExpandingTextarea);
var _this = _possibleConstructorReturn(this, (ExpandingTextarea.__proto__ || Object.getPrototypeOf(ExpandingTextarea)).call(this, props));
_this._handleChange = _this._handleChange.bind(_this);
return _this;
}
_createClass(ExpandingTextarea, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.adjustTextarea({});
}
}, {
key: '_handleChange',
value: function _handleChange(event) {
var onChange = this.props.onChange;
if (onChange) onChange(event);
this.adjustTextarea(event);
}
}, {
key: 'adjustTextarea',
value: function adjustTextarea(_ref) {
var _ref$target = _ref.target,
target = _ref$target === undefined ? this.el : _ref$target;
target.style.height = 0;
target.style.height = target.scrollHeight + 'px';
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var rest = _objectWithoutProperties(this.props, []);
return _react2.default.createElement('textarea', _extends({}, rest, {
ref: function ref(x) {
return _this2.el = x;
},
onChange: this._handleChange
}));
}
}]);
return ExpandingTextarea;
}(_react.Component);
ExpandingTextarea.propTypes = {
onChange: _propTypes2.default.func
};
exports.default = ExpandingTextarea;
/***/ }),
/* 114 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _publish = __webpack_require__(4);
var _view = __webpack_require__(115);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var channel = _ref.channel,
publish = _ref.publish;
return {
loggedInChannelName: channel.loggedInChannel.name,
publishInChannel: publish.publishInChannel,
selectedChannel: publish.selectedChannel,
channelError: publish.error.channel
};
};
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
return {
onPublishInChannelChange: function onPublishInChannelChange(value) {
dispatch((0, _publish.updateError)('channel', null));
dispatch((0, _publish.setPublishInChannel)(value));
},
onChannelSelect: function onChannelSelect(value) {
dispatch((0, _publish.updateError)('channel', null));
dispatch((0, _publish.updateSelectedChannel)(value));
}
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 115 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _ChannelLoginForm = __webpack_require__(39);
var _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm);
var _ChannelCreateForm = __webpack_require__(40);
var _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm);
var _publish_channel_select_states = __webpack_require__(33);
var states = _interopRequireWildcard(_publish_channel_select_states);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ChannelSelect = function (_React$Component) {
_inherits(ChannelSelect, _React$Component);
function ChannelSelect(props) {
_classCallCheck(this, ChannelSelect);
var _this = _possibleConstructorReturn(this, (ChannelSelect.__proto__ || Object.getPrototypeOf(ChannelSelect)).call(this, props));
_this.toggleAnonymousPublish = _this.toggleAnonymousPublish.bind(_this);
_this.handleSelection = _this.handleSelection.bind(_this);
return _this;
}
_createClass(ChannelSelect, [{
key: 'toggleAnonymousPublish',
value: function toggleAnonymousPublish(event) {
var value = event.target.value;
if (value === 'anonymous') {
this.props.onPublishInChannelChange(false);
} else {
this.props.onPublishInChannelChange(true);
}
}
}, {
key: 'handleSelection',
value: function handleSelection(event) {
var selectedOption = event.target.selectedOptions[0].value;
this.props.onChannelSelect(selectedOption);
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'form',
null,
_react2.default.createElement(
'div',
{ className: 'column column--3 column--med-10' },
_react2.default.createElement('input', { type: 'radio', name: 'anonymous-or-channel', id: 'anonymous-radio', className: 'input-radio', value: 'anonymous', checked: !this.props.publishInChannel, onChange: this.toggleAnonymousPublish }),
_react2.default.createElement(
'label',
{ className: 'label label--pointer', htmlFor: 'anonymous-radio' },
'Anonymous'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--7 column--med-10' },
_react2.default.createElement('input', { type: 'radio', name: 'anonymous-or-channel', id: 'channel-radio', className: 'input-radio', value: 'in a channel', checked: this.props.publishInChannel, onChange: this.toggleAnonymousPublish }),
_react2.default.createElement(
'label',
{ className: 'label label--pointer', htmlFor: 'channel-radio' },
'In a channel'
)
),
this.props.channelError ? _react2.default.createElement(
'p',
{ className: 'info-message--failure' },
this.props.channelError
) : _react2.default.createElement(
'p',
{ className: 'info-message' },
'Publish anonymously or in a channel'
)
),
this.props.publishInChannel && _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'div',
{ className: 'column column--3' },
_react2.default.createElement(
'label',
{ className: 'label', htmlFor: 'channel-name-select' },
'Channel:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--7' },
_react2.default.createElement(
'select',
{ type: 'text', id: 'channel-name-select', className: 'select select--arrow', value: this.props.selectedChannel, onChange: this.handleSelection },
this.props.loggedInChannelName && _react2.default.createElement(
'option',
{ value: this.props.loggedInChannelName, id: 'publish-channel-select-channel-option' },
this.props.loggedInChannelName
),
_react2.default.createElement(
'option',
{ value: states.LOGIN },
'Existing'
),
_react2.default.createElement(
'option',
{ value: states.CREATE },
'New'
)
)
),
this.props.selectedChannel === states.LOGIN && _react2.default.createElement(_ChannelLoginForm2.default, null),
this.props.selectedChannel === states.CREATE && _react2.default.createElement(_ChannelCreateForm2.default, null)
)
);
}
}]);
return ChannelSelect;
}(_react2.default.Component);
exports.default = ChannelSelect;
/***/ }),
/* 116 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _request = __webpack_require__(11);
var _request2 = _interopRequireDefault(_request);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ChannelLoginForm = function (_React$Component) {
_inherits(ChannelLoginForm, _React$Component);
function ChannelLoginForm(props) {
_classCallCheck(this, ChannelLoginForm);
var _this = _possibleConstructorReturn(this, (ChannelLoginForm.__proto__ || Object.getPrototypeOf(ChannelLoginForm)).call(this, props));
_this.state = {
error: null,
name: '',
password: ''
};
_this.handleInput = _this.handleInput.bind(_this);
_this.loginToChannel = _this.loginToChannel.bind(_this);
return _this;
}
_createClass(ChannelLoginForm, [{
key: 'handleInput',
value: function handleInput(event) {
var name = event.target.name;
var value = event.target.value;
this.setState(_defineProperty({}, name, value));
}
}, {
key: 'loginToChannel',
value: function loginToChannel(event) {
var _this2 = this;
event.preventDefault();
var params = {
method: 'POST',
body: JSON.stringify({ username: this.state.name, password: this.state.password }),
headers: new Headers({
'Content-Type': 'application/json'
}),
credentials: 'include'
};
(0, _request2.default)('login', params).then(function (_ref) {
var success = _ref.success,
channelName = _ref.channelName,
shortChannelId = _ref.shortChannelId,
channelClaimId = _ref.channelClaimId,
message = _ref.message;
if (success) {
_this2.props.onChannelLogin(channelName, shortChannelId, channelClaimId);
} else {
_this2.setState({ 'error': message });
};
}).catch(function (error) {
if (error.message) {
_this2.setState({ 'error': error.message });
} else {
_this2.setState({ 'error': error });
}
});
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'form',
{ id: 'channel-login-form' },
_react2.default.createElement(
'div',
{ className: 'row row--wide row--short' },
_react2.default.createElement(
'div',
{ className: 'column column--3 column--sml-10' },
_react2.default.createElement(
'label',
{ className: 'label', htmlFor: 'channel-login-name-input' },
'Name:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--6 column--sml-10' },
_react2.default.createElement(
'div',
{ className: 'input-text--primary flex-container--row flex-container--left-bottom' },
_react2.default.createElement(
'span',
null,
'@'
),
_react2.default.createElement('input', { type: 'text', id: 'channel-login-name-input', className: 'input-text', name: 'name', placeholder: 'Your Channel Name', value: this.state.channelName, onChange: this.handleInput })
)
)
),
_react2.default.createElement(
'div',
{ className: 'row row--wide row--short' },
_react2.default.createElement(
'div',
{ className: 'column column--3 column--sml-10' },
_react2.default.createElement(
'label',
{ className: 'label', htmlFor: 'channel-login-password-input' },
'Password:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--6 column--sml-10' },
_react2.default.createElement(
'div',
{ className: 'input-text--primary' },
_react2.default.createElement('input', { type: 'password', id: 'channel-login-password-input', name: 'password', className: 'input-text', placeholder: '', value: this.state.channelPassword, onChange: this.handleInput })
)
)
),
this.state.error ? _react2.default.createElement(
'p',
{ className: 'info-message--failure' },
this.state.error
) : _react2.default.createElement(
'p',
{ className: 'info-message' },
'Enter the name and password for your channel'
),
_react2.default.createElement(
'div',
{ className: 'row row--wide' },
_react2.default.createElement(
'button',
{ className: 'button--primary', onClick: this.loginToChannel },
'Authenticate'
)
)
);
}
}]);
return ChannelLoginForm;
}(_react2.default.Component);
exports.default = ChannelLoginForm;
/***/ }),
/* 117 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _ProgressBar = __webpack_require__(20);
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
var _request = __webpack_require__(11);
var _request2 = _interopRequireDefault(_request);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ChannelCreateForm = function (_React$Component) {
_inherits(ChannelCreateForm, _React$Component);
function ChannelCreateForm(props) {
_classCallCheck(this, ChannelCreateForm);
var _this = _possibleConstructorReturn(this, (ChannelCreateForm.__proto__ || Object.getPrototypeOf(ChannelCreateForm)).call(this, props));
_this.state = {
error: null,
channel: '',
password: '',
status: null
};
_this.handleChannelInput = _this.handleChannelInput.bind(_this);
_this.handleInput = _this.handleInput.bind(_this);
_this.createChannel = _this.createChannel.bind(_this);
return _this;
}
_createClass(ChannelCreateForm, [{
key: 'cleanseChannelInput',
value: function cleanseChannelInput(input) {
input = input.replace(/\s+/g, '-'); // replace spaces with dashes
input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'
return input;
}
}, {
key: 'handleChannelInput',
value: function handleChannelInput(event) {
var value = event.target.value;
value = this.cleanseChannelInput(value);
this.setState({ channel: value });
if (value) {
this.updateIsChannelAvailable(value);
} else {
this.setState({ error: 'Please enter a channel name' });
}
}
}, {
key: 'handleInput',
value: function handleInput(event) {
var name = event.target.name;
var value = event.target.value;
this.setState(_defineProperty({}, name, value));
}
}, {
key: 'updateIsChannelAvailable',
value: function updateIsChannelAvailable(channel) {
var _this2 = this;
var channelWithAtSymbol = '@' + channel;
(0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol).then(function () {
_this2.setState({ 'error': null });
}).catch(function (error) {
_this2.setState({ 'error': error.message });
});
}
}, {
key: 'checkIsChannelAvailable',
value: function checkIsChannelAvailable(channel) {
var channelWithAtSymbol = '@' + channel;
return (0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol);
}
}, {
key: 'checkIsPasswordProvided',
value: function checkIsPasswordProvided(password) {
return new Promise(function (resolve, reject) {
if (!password || password.length < 1) {
return reject(new Error('Please provide a password'));
}
resolve();
});
}
}, {
key: 'makePublishChannelRequest',
value: function makePublishChannelRequest(username, password) {
var params = {
method: 'POST',
body: JSON.stringify({ username: username, password: password }),
headers: new Headers({
'Content-Type': 'application/json'
}),
credentials: 'include'
};
return new Promise(function (resolve, reject) {
(0, _request2.default)('/signup', params).then(function (result) {
return resolve(result);
}).catch(function (error) {
reject(new Error('Unfortunately, we encountered an error while creating your channel. Please let us know in Discord! ' + error.message));
});
});
}
}, {
key: 'createChannel',
value: function createChannel(event) {
var _this3 = this;
event.preventDefault();
this.checkIsPasswordProvided(this.state.password).then(function () {
return _this3.checkIsChannelAvailable(_this3.state.channel);
}).then(function () {
_this3.setState({ status: 'We are publishing your new channel. Sit tight...' });
return _this3.makePublishChannelRequest(_this3.state.channel, _this3.state.password);
}).then(function (result) {
_this3.setState({ status: null });
_this3.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId);
}).catch(function (error) {
if (error.message) {
_this3.setState({ 'error': error.message, status: null });
} else {
_this3.setState({ 'error': error, status: null });
};
});
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
!this.state.status ? _react2.default.createElement(
'form',
{ id: 'publish-channel-form' },
_react2.default.createElement(
'div',
{ className: 'row row--wide row--short' },
_react2.default.createElement(
'div',
{ className: 'column column--3 column--sml-10' },
_react2.default.createElement(
'label',
{ className: 'label', htmlFor: 'new-channel-name' },
'Name:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--6 column--sml-10' },
_react2.default.createElement(
'div',
{ className: 'input-text--primary flex-container--row flex-container--left-bottom span--relative' },
_react2.default.createElement(
'span',
null,
'@'
),
_react2.default.createElement('input', { type: 'text', name: 'channel', id: 'new-channel-name', className: 'input-text', placeholder: 'exampleChannelName', value: this.state.channel, onChange: this.handleChannelInput }),
this.state.channel && !this.state.error && _react2.default.createElement(
'span',
{ id: 'input-success-channel-name', className: 'info-message--success span--absolute' },
'\u2713'
),
this.state.error && _react2.default.createElement(
'span',
{ id: 'input-success-channel-name', className: 'info-message--failure span--absolute' },
'\u2716'
)
)
)
),
_react2.default.createElement(
'div',
{ className: 'row row--wide row--short' },
_react2.default.createElement(
'div',
{ className: 'column column--3 column--sml-10' },
_react2.default.createElement(
'label',
{ className: 'label', htmlFor: 'new-channel-password' },
'Password:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--6 column--sml-10' },
_react2.default.createElement(
'div',
{ className: 'input-text--primary' },
_react2.default.createElement('input', { type: 'password', name: 'password', id: 'new-channel-password', className: 'input-text', placeholder: '', value: this.state.password, onChange: this.handleInput })
)
)
),
this.state.error ? _react2.default.createElement(
'p',
{ className: 'info-message--failure' },
this.state.error
) : _react2.default.createElement(
'p',
{ className: 'info-message' },
'Choose a name and password for your channel'
),
_react2.default.createElement(
'div',
{ className: 'row row--wide' },
_react2.default.createElement(
'button',
{ className: 'button--primary', onClick: this.createChannel },
'Create Channel'
)
)
) : _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'p',
{ className: 'fine-print' },
this.state.status
),
_react2.default.createElement(_ProgressBar2.default, { size: 12 })
)
);
}
}]);
return ChannelCreateForm;
}(_react2.default.Component);
exports.default = ChannelCreateForm;
/***/ }),
/* 118 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var ActiveStatusBar = function ActiveStatusBar() {
return _react2.default.createElement(
'span',
{ className: 'progress-bar progress-bar--active' },
'| '
);
};
exports.default = ActiveStatusBar;
/***/ }),
/* 119 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var InactiveStatusBar = function InactiveStatusBar() {
return _react2.default.createElement(
'span',
{ className: 'progress-bar progress-bar--inactive' },
'| '
);
};
exports.default = InactiveStatusBar;
/***/ }),
/* 120 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _publish = __webpack_require__(4);
var _view = __webpack_require__(121);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var publish = _ref.publish;
return {
status: publish.status.status,
message: publish.status.message
};
};
var mapDispatchToProps = {
clearFile: _publish.clearFile
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 121 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _ProgressBar = __webpack_require__(20);
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
var _publish_claim_states = __webpack_require__(122);
var publishStates = _interopRequireWildcard(_publish_claim_states);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PublishStatus = function (_React$Component) {
_inherits(PublishStatus, _React$Component);
function PublishStatus() {
_classCallCheck(this, PublishStatus);
return _possibleConstructorReturn(this, (PublishStatus.__proto__ || Object.getPrototypeOf(PublishStatus)).apply(this, arguments));
}
_createClass(PublishStatus, [{
key: 'render',
value: function render() {
var _props = this.props,
status = _props.status,
message = _props.message,
clearFile = _props.clearFile;
return _react2.default.createElement(
'div',
{ className: 'row row--tall flex-container--column flex-container--center-center' },
status === publishStates.LOAD_START && _react2.default.createElement(
'div',
{ className: 'row align-content-center' },
_react2.default.createElement(
'p',
null,
'File is loading to server'
),
_react2.default.createElement(
'p',
{ className: 'blue' },
'0%'
)
),
status === publishStates.LOADING && _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'div',
{ className: 'row align-content-center' },
_react2.default.createElement(
'p',
null,
'File is loading to server'
),
_react2.default.createElement(
'p',
{ className: 'blue' },
message
)
)
),
status === publishStates.PUBLISHING && _react2.default.createElement(
'div',
{ className: 'row align-content-center' },
_react2.default.createElement(
'p',
null,
'Upload complete. Your file is now being published on the blockchain...'
),
_react2.default.createElement(_ProgressBar2.default, { size: 12 }),
_react2.default.createElement(
'p',
null,
'Curious what magic is happening here? ',
_react2.default.createElement(
'a',
{ className: 'link--primary', target: 'blank', href: 'https://lbry.io/faq/what-is-lbry' },
'Learn more.'
)
)
),
status === publishStates.SUCCESS && _react2.default.createElement(
'div',
{ className: 'row align-content-center' },
_react2.default.createElement(
'p',
null,
'Your publish is complete! You are being redirected to it now.'
),
_react2.default.createElement(
'p',
null,
'If you are not automatically redirected, ',
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: message },
'click here.'
)
)
),
status === publishStates.FAILED && _react2.default.createElement(
'div',
{ className: 'row align-content-center' },
_react2.default.createElement(
'p',
null,
'Something went wrong...'
),
_react2.default.createElement(
'p',
null,
_react2.default.createElement(
'strong',
null,
message
)
),
_react2.default.createElement(
'p',
null,
'For help, post the above error text in the #speech channel on the ',
_react2.default.createElement(
'a',
{ className: 'link--primary', href: 'https://discord.gg/YjYbwhS', target: '_blank' },
'lbry discord'
)
),
_react2.default.createElement(
'button',
{ className: 'button--secondary', onClick: clearFile },
'Reset'
)
)
);
}
}]);
return PublishStatus;
}(_react2.default.Component);
;
exports.default = PublishStatus;
/***/ }),
/* 122 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var LOAD_START = exports.LOAD_START = 'LOAD_START';
var LOADING = exports.LOADING = 'LOADING';
var PUBLISHING = exports.PUBLISHING = 'PUBLISHING';
var SUCCESS = exports.SUCCESS = 'SUCCESS';
var FAILED = exports.FAILED = 'FAILED';
/***/ }),
/* 123 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(124);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var publish = _ref.publish;
return {
message: publish.disabledMessage
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 124 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PublishDisabledMessage = function (_React$Component) {
_inherits(PublishDisabledMessage, _React$Component);
function PublishDisabledMessage() {
_classCallCheck(this, PublishDisabledMessage);
return _possibleConstructorReturn(this, (PublishDisabledMessage.__proto__ || Object.getPrototypeOf(PublishDisabledMessage)).apply(this, arguments));
}
_createClass(PublishDisabledMessage, [{
key: 'render',
value: function render() {
var message = this.props.message;
console.log('this.props.message:', message);
return _react2.default.createElement(
'div',
{ className: 'row dropzone--disabled row--tall flex-container--column flex-container--center-center' },
_react2.default.createElement(
'p',
{ className: 'text--disabled' },
'Publishing is currently disabled.'
),
_react2.default.createElement(
'p',
{ className: 'text--disabled' },
message
)
);
}
}]);
return PublishDisabledMessage;
}(_react2.default.Component);
exports.default = PublishDisabledMessage;
/***/ }),
/* 125 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _NavBar = __webpack_require__(7);
var _NavBar2 = _interopRequireDefault(_NavBar);
var _SEO = __webpack_require__(9);
var _SEO2 = _interopRequireDefault(_SEO);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var AboutPage = function (_React$Component) {
_inherits(AboutPage, _React$Component);
function AboutPage() {
_classCallCheck(this, AboutPage);
return _possibleConstructorReturn(this, (AboutPage.__proto__ || Object.getPrototypeOf(AboutPage)).apply(this, arguments));
}
_createClass(AboutPage, [{
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(_SEO2.default, { pageTitle: 'About', pageUri: 'about' }),
_react2.default.createElement(_NavBar2.default, null),
_react2.default.createElement(
'div',
{ className: 'row row--padded' },
_react2.default.createElement(
'div',
{ className: 'column column--5 column--med-10 align-content-top' },
_react2.default.createElement(
'div',
{ className: 'column column--8 column--med-10' },
_react2.default.createElement(
'p',
{ className: 'pull-quote' },
'Spee.ch is an open-source project. Please contribute to the existing site, or fork it and make your own.'
),
_react2.default.createElement(
'p',
null,
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://twitter.com/spee_ch' },
'TWITTER'
)
),
_react2.default.createElement(
'p',
null,
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://github.com/lbryio/spee.ch' },
'GITHUB'
)
),
_react2.default.createElement(
'p',
null,
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://discord.gg/YjYbwhS' },
'DISCORD CHANNEL'
)
),
_react2.default.createElement(
'p',
null,
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://github.com/lbryio/spee.ch/blob/master/README.md' },
'DOCUMENTATION'
)
)
)
),
_react2.default.createElement(
'div',
{ className: 'column column--5 column--med-10 align-content-top' },
_react2.default.createElement(
'div',
{ className: 'column column--8 column--med-10' },
_react2.default.createElement(
'p',
null,
'Spee.ch is a media-hosting site that reads from and publishes content to the ',
_react2.default.createElement(
'a',
{ className: 'link--primary', href: 'https://lbry.io' },
'LBRY'
),
' blockchain.'
),
_react2.default.createElement(
'p',
null,
'Spee.ch is a hosting service, but with the added benefit that it stores your content on a decentralized network of computers -- the ',
_react2.default.createElement(
'a',
{ className: 'link--primary', href: 'https://lbry.io/get' },
'LBRY'
),
' network. This means that your images are stored in multiple locations without a single point of failure.'
),
_react2.default.createElement(
'h3',
null,
'Contribute'
),
_react2.default.createElement(
'p',
null,
'If you have an idea for your own spee.ch-like site on top of LBRY, fork our ',
_react2.default.createElement(
'a',
{ className: 'link--primary', href: 'https://github.com/lbryio/spee.ch' },
'github repo'
),
' and go to town!'
),
_react2.default.createElement(
'p',
null,
'If you want to improve spee.ch, join our ',
_react2.default.createElement(
'a',
{ className: 'link--primary', href: 'https://discord.gg/YjYbwhS' },
'discord channel'
),
' or solve one of our ',
_react2.default.createElement(
'a',
{ className: 'link--primary', href: 'https://github.com/lbryio/spee.ch/issues' },
'github issues'
),
'.'
)
)
)
)
);
}
}]);
return AboutPage;
}(_react2.default.Component);
;
exports.default = AboutPage;
/***/ }),
/* 126 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(127);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var channel = _ref.channel;
return {
loggedInChannelName: channel.loggedInChannel.name
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 127 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactRouterDom = __webpack_require__(3);
var _SEO = __webpack_require__(9);
var _SEO2 = _interopRequireDefault(_SEO);
var _NavBar = __webpack_require__(7);
var _NavBar2 = _interopRequireDefault(_NavBar);
var _ChannelLoginForm = __webpack_require__(39);
var _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm);
var _ChannelCreateForm = __webpack_require__(40);
var _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var LoginPage = function (_React$Component) {
_inherits(LoginPage, _React$Component);
function LoginPage() {
_classCallCheck(this, LoginPage);
return _possibleConstructorReturn(this, (LoginPage.__proto__ || Object.getPrototypeOf(LoginPage)).apply(this, arguments));
}
_createClass(LoginPage, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(newProps) {
// re-route the user to the homepage if the user is logged in
if (newProps.loggedInChannelName !== this.props.loggedInChannelName) {
this.props.history.push('/');
}
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(_SEO2.default, { pageTitle: 'Login', pageUri: 'login' }),
_react2.default.createElement(_NavBar2.default, null),
_react2.default.createElement(
'div',
{ className: 'row row--padded' },
_react2.default.createElement(
'div',
{ className: 'column column--5 column--med-10 align-content-top' },
_react2.default.createElement(
'div',
{ className: 'column column--8 column--med-10' },
_react2.default.createElement(
'p',
null,
'Channels allow you to publish and group content under an identity. You can create a channel for yourself, or share one with like-minded friends. You can create 1 channel, or 100, so whether you\'re ',
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: '/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8' },
'documenting important events'
),
', or making a public repository for ',
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: '/@catGifs' },
'cat gifs'
),
' (password: \'1234\'), try creating a channel for it!'
)
)
),
_react2.default.createElement(
'div',
{ className: 'column column--5 column--med-10 align-content-top' },
_react2.default.createElement(
'div',
{ className: 'column column--8 column--med-10' },
_react2.default.createElement(
'h3',
{ className: 'h3--no-bottom' },
'Log in to an existing channel:'
),
_react2.default.createElement(_ChannelLoginForm2.default, null),
_react2.default.createElement(
'h3',
{ className: 'h3--no-bottom' },
'Create a brand new channel:'
),
_react2.default.createElement(_ChannelCreateForm2.default, null)
)
)
)
);
}
}]);
return LoginPage;
}(_react2.default.Component);
;
exports.default = (0, _reactRouterDom.withRouter)(LoginPage);
/***/ }),
/* 128 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _show = __webpack_require__(8);
var _view = __webpack_require__(129);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var show = _ref.show;
return {
error: show.request.error,
requestType: show.request.type
};
};
var mapDispatchToProps = {
onHandleShowPageUri: _show.onHandleShowPageUri
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 129 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _ErrorPage = __webpack_require__(21);
var _ErrorPage2 = _interopRequireDefault(_ErrorPage);
var _ShowAssetLite = __webpack_require__(130);
var _ShowAssetLite2 = _interopRequireDefault(_ShowAssetLite);
var _ShowAssetDetails = __webpack_require__(133);
var _ShowAssetDetails2 = _interopRequireDefault(_ShowAssetDetails);
var _ShowChannel = __webpack_require__(139);
var _ShowChannel2 = _interopRequireDefault(_ShowChannel);
var _show_request_types = __webpack_require__(41);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ShowPage = function (_React$Component) {
_inherits(ShowPage, _React$Component);
function ShowPage() {
_classCallCheck(this, ShowPage);
return _possibleConstructorReturn(this, (ShowPage.__proto__ || Object.getPrototypeOf(ShowPage)).apply(this, arguments));
}
_createClass(ShowPage, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.props.onHandleShowPageUri(this.props.match.params);
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (nextProps.match.params !== this.props.match.params) {
this.props.onHandleShowPageUri(nextProps.match.params);
}
}
}, {
key: 'render',
value: function render() {
var _props = this.props,
error = _props.error,
requestType = _props.requestType;
if (error) {
return _react2.default.createElement(_ErrorPage2.default, { error: error });
}
switch (requestType) {
case _show_request_types.CHANNEL:
return _react2.default.createElement(_ShowChannel2.default, null);
case _show_request_types.ASSET_LITE:
return _react2.default.createElement(_ShowAssetLite2.default, null);
case _show_request_types.ASSET_DETAILS:
return _react2.default.createElement(_ShowAssetDetails2.default, null);
default:
return _react2.default.createElement(
'p',
null,
'loading...'
);
}
}
}]);
return ShowPage;
}(_react2.default.Component);
;
exports.default = ShowPage;
/***/ }),
/* 130 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(131);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var show = _ref.show;
// select request info
var requestId = show.request.id;
// select asset info
var asset = void 0;
var request = show.requestList[requestId] || null;
var assetList = show.assetList;
if (request && assetList) {
var assetKey = request.key; // note: just store this in the request
asset = assetList[assetKey] || null;
};
// return props
return {
asset: asset
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 131 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _SEO = __webpack_require__(9);
var _SEO2 = _interopRequireDefault(_SEO);
var _reactRouterDom = __webpack_require__(3);
var _AssetDisplay = __webpack_require__(42);
var _AssetDisplay2 = _interopRequireDefault(_AssetDisplay);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ShowLite = function (_React$Component) {
_inherits(ShowLite, _React$Component);
function ShowLite() {
_classCallCheck(this, ShowLite);
return _possibleConstructorReturn(this, (ShowLite.__proto__ || Object.getPrototypeOf(ShowLite)).apply(this, arguments));
}
_createClass(ShowLite, [{
key: 'render',
value: function render() {
var asset = this.props.asset;
if (asset) {
var _asset$claimData = asset.claimData,
name = _asset$claimData.name,
claimId = _asset$claimData.claimId;
return _react2.default.createElement(
'div',
{ className: 'row row--tall flex-container--column flex-container--center-center show-lite-container' },
_react2.default.createElement(_SEO2.default, { pageTitle: name, asset: asset }),
_react2.default.createElement(_AssetDisplay2.default, null),
_react2.default.createElement(
_reactRouterDom.Link,
{ id: 'asset-boilerpate', className: 'link--primary fine-print', to: '/' + claimId + '/' + name },
'hosted via Spee.ch'
)
);
}
return _react2.default.createElement(
'div',
{ className: 'row row--tall row--padded flex-container--column flex-container--center-center' },
_react2.default.createElement(
'p',
null,
'loading asset data...'
)
);
}
}]);
return ShowLite;
}(_react2.default.Component);
;
exports.default = ShowLite;
/***/ }),
/* 132 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _ProgressBar = __webpack_require__(20);
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
var _asset_display_states = __webpack_require__(35);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var AssetDisplay = function (_React$Component) {
_inherits(AssetDisplay, _React$Component);
function AssetDisplay() {
_classCallCheck(this, AssetDisplay);
return _possibleConstructorReturn(this, (AssetDisplay.__proto__ || Object.getPrototypeOf(AssetDisplay)).apply(this, arguments));
}
_createClass(AssetDisplay, [{
key: 'componentDidMount',
value: function componentDidMount() {
var _props$asset$claimDat = this.props.asset.claimData,
name = _props$asset$claimDat.name,
claimId = _props$asset$claimDat.claimId;
this.props.onFileRequest(name, claimId);
}
}, {
key: 'render',
value: function render() {
var _props = this.props,
status = _props.status,
error = _props.error,
_props$asset$claimDat2 = _props.asset.claimData,
name = _props$asset$claimDat2.name,
claimId = _props$asset$claimDat2.claimId,
contentType = _props$asset$claimDat2.contentType,
fileExt = _props$asset$claimDat2.fileExt,
thumbnail = _props$asset$claimDat2.thumbnail;
return _react2.default.createElement(
'div',
{ id: 'asset-display-component' },
status === _asset_display_states.LOCAL_CHECK && _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'p',
null,
'Checking to see if Spee.ch has your asset locally...'
)
),
status === _asset_display_states.UNAVAILABLE && _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'p',
null,
'Sit tight, we\'re searching the LBRY blockchain for your asset!'
),
_react2.default.createElement(_ProgressBar2.default, { size: 12 }),
_react2.default.createElement(
'p',
null,
'Curious what magic is happening here? ',
_react2.default.createElement(
'a',
{ className: 'link--primary', target: 'blank', href: 'https://lbry.io/faq/what-is-lbry' },
'Learn more.'
)
)
),
status === _asset_display_states.ERROR && _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'p',
null,
'Unfortunately, we couldn\'t download your asset from LBRY. You can help us out by sharing the below error message in the ',
_react2.default.createElement(
'a',
{ className: 'link--primary', href: 'https://discord.gg/YjYbwhS', target: '_blank' },
'LBRY discord'
),
'.'
),
_react2.default.createElement(
'i',
null,
_react2.default.createElement(
'p',
{ id: 'error-message' },
error
)
)
),
status === _asset_display_states.AVAILABLE && function () {
switch (contentType) {
case 'image/jpeg':
case 'image/jpg':
case 'image/png':
return _react2.default.createElement('img', {
className: 'asset',
src: '/' + claimId + '/' + name + '.' + fileExt,
alt: name });
case 'image/gif':
return _react2.default.createElement('img', {
className: 'asset',
src: '/' + claimId + '/' + name + '.' + fileExt,
alt: name
});
case 'video/mp4':
return _react2.default.createElement(
'video',
{ className: 'asset video', controls: true, poster: thumbnail },
_react2.default.createElement('source', {
src: '/' + claimId + '/' + name + '.' + fileExt
}),
_react2.default.createElement(
'p',
null,
'Your browser does not support the ',
_react2.default.createElement(
'code',
null,
'video'
),
' element.'
)
);
default:
return _react2.default.createElement(
'p',
null,
'Unsupported file type'
);
}
}()
);
}
}]);
return AssetDisplay;
}(_react2.default.Component);
;
exports.default = AssetDisplay;
/***/ }),
/* 133 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(134);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var show = _ref.show;
// select request info
var requestId = show.request.id;
// select asset info
var asset = void 0;
var request = show.requestList[requestId] || null;
var assetList = show.assetList;
if (request && assetList) {
var assetKey = request.key; // note: just store this in the request
asset = assetList[assetKey] || null;
};
// return props
return {
asset: asset
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 134 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _SEO = __webpack_require__(9);
var _SEO2 = _interopRequireDefault(_SEO);
var _NavBar = __webpack_require__(7);
var _NavBar2 = _interopRequireDefault(_NavBar);
var _ErrorPage = __webpack_require__(21);
var _ErrorPage2 = _interopRequireDefault(_ErrorPage);
var _AssetTitle = __webpack_require__(135);
var _AssetTitle2 = _interopRequireDefault(_AssetTitle);
var _AssetDisplay = __webpack_require__(42);
var _AssetDisplay2 = _interopRequireDefault(_AssetDisplay);
var _AssetInfo = __webpack_require__(137);
var _AssetInfo2 = _interopRequireDefault(_AssetInfo);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ShowAssetDetails = function (_React$Component) {
_inherits(ShowAssetDetails, _React$Component);
function ShowAssetDetails() {
_classCallCheck(this, ShowAssetDetails);
return _possibleConstructorReturn(this, (ShowAssetDetails.__proto__ || Object.getPrototypeOf(ShowAssetDetails)).apply(this, arguments));
}
_createClass(ShowAssetDetails, [{
key: 'render',
value: function render() {
var asset = this.props.asset;
if (asset) {
var name = asset.claimData.name;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(_SEO2.default, { pageTitle: name + ' - details', asset: asset }),
_react2.default.createElement(_NavBar2.default, null),
_react2.default.createElement(
'div',
{ className: 'row row--tall row--padded' },
_react2.default.createElement(
'div',
{ className: 'column column--10' },
_react2.default.createElement(_AssetTitle2.default, null)
),
_react2.default.createElement(
'div',
{ className: 'column column--5 column--sml-10 align-content-top' },
_react2.default.createElement(
'div',
{ className: 'row row--padded show-details-container' },
_react2.default.createElement(_AssetDisplay2.default, null)
)
),
_react2.default.createElement(
'div',
{ className: 'column column--5 column--sml-10 align-content-top' },
_react2.default.createElement(
'div',
{ className: 'row row--padded' },
_react2.default.createElement(_AssetInfo2.default, null)
)
)
)
);
};
return _react2.default.createElement(_ErrorPage2.default, { error: 'loading asset data...' });
}
}]);
return ShowAssetDetails;
}(_react2.default.Component);
;
exports.default = ShowAssetDetails;
/***/ }),
/* 135 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(136);
var _view2 = _interopRequireDefault(_view);
var _show = __webpack_require__(13);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var show = _ref.show;
var _selectAsset = (0, _show.selectAsset)(show),
title = _selectAsset.claimData.title;
return {
title: title
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 136 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var AssetTitle = function AssetTitle(_ref) {
var title = _ref.title;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
'span',
{ className: 'text--large' },
title
)
);
};
exports.default = AssetTitle;
/***/ }),
/* 137 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(138);
var _view2 = _interopRequireDefault(_view);
var _show = __webpack_require__(13);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var show = _ref.show;
// select asset
var asset = (0, _show.selectAsset)(show);
// return props
return {
asset: asset
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 138 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactRouterDom = __webpack_require__(3);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var AssetInfo = function (_React$Component) {
_inherits(AssetInfo, _React$Component);
function AssetInfo(props) {
_classCallCheck(this, AssetInfo);
var _this = _possibleConstructorReturn(this, (AssetInfo.__proto__ || Object.getPrototypeOf(AssetInfo)).call(this, props));
_this.copyToClipboard = _this.copyToClipboard.bind(_this);
return _this;
}
_createClass(AssetInfo, [{
key: 'copyToClipboard',
value: function copyToClipboard(event) {
var elementToCopy = event.target.dataset.elementtocopy;
var element = document.getElementById(elementToCopy);
element.select();
try {
document.execCommand('copy');
} catch (err) {
this.setState({ error: 'Oops, unable to copy' });
}
}
}, {
key: 'render',
value: function render() {
var _props$asset = this.props.asset,
shortId = _props$asset.shortId,
_props$asset$claimDat = _props$asset.claimData,
channelName = _props$asset$claimDat.channelName,
certificateId = _props$asset$claimDat.certificateId,
description = _props$asset$claimDat.description,
name = _props$asset$claimDat.name,
claimId = _props$asset$claimDat.claimId,
fileExt = _props$asset$claimDat.fileExt,
contentType = _props$asset$claimDat.contentType,
thumbnail = _props$asset$claimDat.thumbnail,
host = _props$asset$claimDat.host;
return _react2.default.createElement(
'div',
null,
channelName && _react2.default.createElement(
'div',
{ className: 'row row--padded row--wide row--no-top' },
_react2.default.createElement(
'div',
{ className: 'column column--2 column--med-10' },
_react2.default.createElement(
'span',
{ className: 'text' },
'Channel:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--8 column--med-10' },
_react2.default.createElement(
'span',
{ className: 'text' },
_react2.default.createElement(
_reactRouterDom.Link,
{ to: '/' + channelName + ':' + certificateId },
channelName
)
)
)
),
description && _react2.default.createElement(
'div',
{ className: 'row row--padded row--wide row--no-top' },
_react2.default.createElement(
'span',
{ className: 'text' },
description
)
),
_react2.default.createElement(
'div',
{ id: 'show-share-buttons' },
_react2.default.createElement(
'div',
{ className: 'row row--padded row--wide row--no-top' },
_react2.default.createElement(
'div',
{ className: 'column column--2 column--med-10' },
_react2.default.createElement(
'span',
{ className: 'text' },
'Share:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--8 column--med-10' },
_react2.default.createElement(
'div',
{
className: 'row row--short row--wide flex-container--row flex-container--space-between-bottom flex-container--wrap' },
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://twitter.com/intent/tweet?text=' + host + '/' + shortId + '/' + name },
'twitter'
),
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://www.facebook.com/sharer/sharer.php?u=' + host + '/' + shortId + '/' + name },
'facebook'
),
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'http://tumblr.com/widgets/share/tool?canonicalUrl=' + host + '/' + shortId + '/' + name },
'tumblr'
),
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://www.reddit.com/submit?url=' + host + '/' + shortId + '/' + name + '&title=' + name },
'reddit'
)
)
)
)
),
_react2.default.createElement(
'div',
{ className: 'row row--padded row--wide row--no-top' },
_react2.default.createElement(
'div',
{ id: 'show-short-link' },
_react2.default.createElement(
'div',
{ className: 'column column--2 column--med-10' },
_react2.default.createElement(
'span',
{ className: 'text' },
'Link:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--8 column--med-10' },
_react2.default.createElement(
'div',
{ className: 'row row--short row--wide' },
_react2.default.createElement(
'div',
{ className: 'column column--7' },
_react2.default.createElement(
'div',
{ className: 'input-error', id: 'input-error-copy-short-link', hidden: 'true' },
'error here'
),
_react2.default.createElement('input', { type: 'text', id: 'short-link', className: 'input-disabled input-text--full-width', readOnly: true,
spellCheck: 'false',
value: host + '/' + shortId + '/' + name + '.' + fileExt,
onClick: this.select })
),
_react2.default.createElement('div', { className: 'column column--1' }),
_react2.default.createElement(
'div',
{ className: 'column column--2' },
_react2.default.createElement(
'button',
{ className: 'button--primary button--wide', 'data-elementtocopy': 'short-link',
onClick: this.copyToClipboard },
'copy'
)
)
)
)
),
_react2.default.createElement(
'div',
{ id: 'show-embed-code' },
_react2.default.createElement(
'div',
{ className: 'column column--2 column--med-10' },
_react2.default.createElement(
'span',
{ className: 'text' },
'Embed:'
)
),
_react2.default.createElement(
'div',
{ className: 'column column--8 column--med-10' },
_react2.default.createElement(
'div',
{ className: 'row row--short row--wide' },
_react2.default.createElement(
'div',
{ className: 'column column--7' },
_react2.default.createElement(
'div',
{ className: 'input-error', id: 'input-error-copy-embed-text', hidden: 'true' },
'error here'
),
contentType === 'video/mp4' ? _react2.default.createElement('input', { type: 'text', id: 'embed-text', className: 'input-disabled input-text--full-width', readOnly: true,
onClick: this.select, spellCheck: 'false',
value: '<video width="100%" controls poster="' + thumbnail + '" src="' + host + '/' + claimId + '/' + name + '.' + fileExt + '"/></video>' }) : _react2.default.createElement('input', { type: 'text', id: 'embed-text', className: 'input-disabled input-text--full-width', readOnly: true,
onClick: this.select, spellCheck: 'false',
value: '<img src="' + host + '/' + claimId + '/' + name + '.' + fileExt + '"/>'
})
),
_react2.default.createElement('div', { className: 'column column--1' }),
_react2.default.createElement(
'div',
{ className: 'column column--2' },
_react2.default.createElement(
'button',
{ className: 'button--primary button--wide', 'data-elementtocopy': 'embed-text',
onClick: this.copyToClipboard },
'copy'
)
)
)
)
)
),
_react2.default.createElement(
'div',
{ className: 'flex-container--row flex-container--space-between-bottom' },
_react2.default.createElement(
_reactRouterDom.Link,
{ className: 'link--primary', to: '/' + shortId + '/' + name + '.' + fileExt },
_react2.default.createElement(
'span',
{
className: 'text' },
'Direct Link'
)
),
_react2.default.createElement(
'a',
{ className: 'link--primary', href: host + '/' + claimId + '/' + name + '.' + fileExt, download: name },
'Download'
),
_react2.default.createElement(
'a',
{ className: 'link--primary', target: '_blank', href: 'https://lbry.io/dmca' },
'Report'
)
)
);
}
}]);
return AssetInfo;
}(_react2.default.Component);
;
exports.default = AssetInfo;
/***/ }),
/* 139 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(140);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var show = _ref.show;
// select request info
var requestId = show.request.id;
// select request
var previousRequest = show.requestList[requestId] || null;
// select channel
var channel = void 0;
if (previousRequest) {
var channelKey = previousRequest.key;
channel = show.channelList[channelKey] || null;
}
return {
channel: channel
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 140 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _SEO = __webpack_require__(9);
var _SEO2 = _interopRequireDefault(_SEO);
var _ErrorPage = __webpack_require__(21);
var _ErrorPage2 = _interopRequireDefault(_ErrorPage);
var _NavBar = __webpack_require__(7);
var _NavBar2 = _interopRequireDefault(_NavBar);
var _ChannelClaimsDisplay = __webpack_require__(141);
var _ChannelClaimsDisplay2 = _interopRequireDefault(_ChannelClaimsDisplay);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ShowChannel = function (_React$Component) {
_inherits(ShowChannel, _React$Component);
function ShowChannel() {
_classCallCheck(this, ShowChannel);
return _possibleConstructorReturn(this, (ShowChannel.__proto__ || Object.getPrototypeOf(ShowChannel)).apply(this, arguments));
}
_createClass(ShowChannel, [{
key: 'render',
value: function render() {
var channel = this.props.channel;
if (channel) {
var name = channel.name,
longId = channel.longId,
shortId = channel.shortId;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(_SEO2.default, { pageTitle: name, channel: channel }),
_react2.default.createElement(_NavBar2.default, null),
_react2.default.createElement(
'div',
{ className: 'row row--tall row--padded' },
_react2.default.createElement(
'div',
{ className: 'column column--10' },
_react2.default.createElement(
'h2',
null,
'channel name: ',
name
),
_react2.default.createElement(
'p',
{ className: 'fine-print' },
'full channel id: ',
longId
),
_react2.default.createElement(
'p',
{ className: 'fine-print' },
'short channel id: ',
shortId
)
),
_react2.default.createElement(
'div',
{ className: 'column column--10' },
_react2.default.createElement(_ChannelClaimsDisplay2.default, null)
)
)
);
};
return _react2.default.createElement(_ErrorPage2.default, { error: 'loading channel data...' });
}
}]);
return ShowChannel;
}(_react2.default.Component);
;
exports.default = ShowChannel;
/***/ }),
/* 141 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _show = __webpack_require__(8);
var _view = __webpack_require__(142);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var show = _ref.show;
// select channel key
var request = show.requestList[show.request.id];
var channelKey = request.key;
// select channel claims
var channel = show.channelList[channelKey] || null;
// return props
return {
channelKey: channelKey,
channel: channel
};
};
var mapDispatchToProps = {
onUpdateChannelClaims: _show.onUpdateChannelClaims
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
/***/ }),
/* 142 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _AssetPreview = __webpack_require__(143);
var _AssetPreview2 = _interopRequireDefault(_AssetPreview);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var ChannelClaimsDisplay = function (_React$Component) {
_inherits(ChannelClaimsDisplay, _React$Component);
function ChannelClaimsDisplay(props) {
_classCallCheck(this, ChannelClaimsDisplay);
var _this = _possibleConstructorReturn(this, (ChannelClaimsDisplay.__proto__ || Object.getPrototypeOf(ChannelClaimsDisplay)).call(this, props));
_this.showNextResultsPage = _this.showNextResultsPage.bind(_this);
_this.showPreviousResultsPage = _this.showPreviousResultsPage.bind(_this);
return _this;
}
_createClass(ChannelClaimsDisplay, [{
key: 'showPreviousResultsPage',
value: function showPreviousResultsPage() {
var currentPage = this.props.channel.claimsData.currentPage;
var previousPage = parseInt(currentPage) - 1;
this.showNewPage(previousPage);
}
}, {
key: 'showNextResultsPage',
value: function showNextResultsPage() {
var currentPage = this.props.channel.claimsData.currentPage;
var nextPage = parseInt(currentPage) + 1;
this.showNewPage(nextPage);
}
}, {
key: 'showNewPage',
value: function showNewPage(page) {
var _props = this.props,
channelKey = _props.channelKey,
_props$channel = _props.channel,
name = _props$channel.name,
longId = _props$channel.longId;
this.props.onUpdateChannelClaims(channelKey, name, longId, page);
}
}, {
key: 'render',
value: function render() {
var _props$channel$claims = this.props.channel.claimsData,
claims = _props$channel$claims.claims,
currentPage = _props$channel$claims.currentPage,
totalPages = _props$channel$claims.totalPages;
return _react2.default.createElement(
'div',
{ className: 'row row--tall' },
claims.length > 0 ? _react2.default.createElement(
'div',
null,
claims.map(function (claim, index) {
return _react2.default.createElement(_AssetPreview2.default, {
claimData: claim,
key: claim.name + '-' + index
});
}),
_react2.default.createElement(
'div',
null,
currentPage > 1 && _react2.default.createElement(
'button',
{ className: 'button--secondary', onClick: this.showPreviousResultsPage },
'Previous Page'
),
currentPage < totalPages && _react2.default.createElement(
'button',
{ className: 'button--secondary', onClick: this.showNextResultsPage },
'Next Page'
)
)
) : _react2.default.createElement(
'p',
null,
'There are no claims in this channel'
)
);
}
}]);
return ChannelClaimsDisplay;
}(_react2.default.Component);
;
exports.default = ChannelClaimsDisplay;
/***/ }),
/* 143 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(144);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var defaultThumbnail = _ref.site.defaults.defaultThumbnail;
return {
defaultThumbnail: defaultThumbnail
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 144 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _reactRouterDom = __webpack_require__(3);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var AssetPreview = function AssetPreview(_ref) {
var defaultThumbnail = _ref.defaultThumbnail,
_ref$claimData = _ref.claimData,
name = _ref$claimData.name,
claimId = _ref$claimData.claimId,
fileExt = _ref$claimData.fileExt,
contentType = _ref$claimData.contentType,
thumbnail = _ref$claimData.thumbnail;
var directSourceLink = claimId + '/' + name + '.' + fileExt;
var showUrlLink = '/' + claimId + '/' + name;
return _react2.default.createElement(
'div',
{ className: 'asset-holder' },
_react2.default.createElement(
_reactRouterDom.Link,
{ to: showUrlLink },
function () {
switch (contentType) {
case 'image/jpeg':
case 'image/jpg':
case 'image/png':
case 'image/gif':
return _react2.default.createElement('img', {
className: 'asset-preview',
src: directSourceLink,
alt: name
});
case 'video/mp4':
return _react2.default.createElement('img', {
className: 'asset-preview video',
src: thumbnail || defaultThumbnail,
alt: name
});
default:
return _react2.default.createElement(
'p',
null,
'unsupported file type'
);
}
}()
)
);
};
exports.default = AssetPreview;
/***/ }),
/* 145 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = __webpack_require__(1);
var _view = __webpack_require__(146);
var _view2 = _interopRequireDefault(_view);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mapStateToProps = function mapStateToProps(_ref) {
var _ref$site = _ref.site,
host = _ref$site.host,
title = _ref$site.title;
return {
host: host,
title: title
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
/***/ }),
/* 146 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _NavBar = __webpack_require__(7);
var _NavBar2 = _interopRequireDefault(_NavBar);
var _reactHelmet = __webpack_require__(14);
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var FourOhForPage = function (_React$Component) {
_inherits(FourOhForPage, _React$Component);
function FourOhForPage() {
_classCallCheck(this, FourOhForPage);
return _possibleConstructorReturn(this, (FourOhForPage.__proto__ || Object.getPrototypeOf(FourOhForPage)).apply(this, arguments));
}
_createClass(FourOhForPage, [{
key: 'render',
value: function render() {
var _props = this.props,
title = _props.title,
host = _props.host;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
_reactHelmet2.default,
null,
_react2.default.createElement(
'title',
null,
title,
' - 404'
),
_react2.default.createElement('link', { rel: 'canonical', href: host + '/404' })
),
_react2.default.createElement(_NavBar2.default, null),
_react2.default.createElement(
'div',
{ className: 'row row--padded' },
_react2.default.createElement(
'h2',
null,
'404'
),
_react2.default.createElement(
'p',
null,
'That page does not exist'
)
)
);
}
}]);
return FourOhForPage;
}(_react2.default.Component);
;
exports.default = FourOhForPage;
/***/ }),
/* 147 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _require = __webpack_require__(17),
sendGAServeEvent = _require.sendGAServeEvent;
var _require2 = __webpack_require__(148),
determineResponseType = _require2.determineResponseType,
flipClaimNameAndIdForBackwardsCompatibility = _require2.flipClaimNameAndIdForBackwardsCompatibility,
logRequestData = _require2.logRequestData,
getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;
var lbryUri = __webpack_require__(149);
var handleShowRender = __webpack_require__(150);
var SERVE = 'SERVE';
module.exports = function (app) {
// route to serve a specific asset using the channel or claim id
app.get('/:identifier/:claim', function (req, res) {
var headers = req.headers,
ip = req.ip,
originalUrl = req.originalUrl,
params = req.params;
// decide if this is a show request
var hasFileExtension = void 0;
try {
var _lbryUri$parseModifie = lbryUri.parseModifier(params.claim);
hasFileExtension = _lbryUri$parseModifie.hasFileExtension;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
var responseType = determineResponseType(hasFileExtension, headers);
if (responseType !== SERVE) {
return handleShowRender(req, res);
}
// handle serve request
// send google analytics
sendGAServeEvent(headers, ip, originalUrl);
// parse the claim
var claimName = void 0;
try {
var _lbryUri$parseClaim = lbryUri.parseClaim(params.claim);
claimName = _lbryUri$parseClaim.claimName;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
// parse the identifier
var isChannel = void 0,
channelName = void 0,
channelClaimId = void 0,
claimId = void 0;
try {
var _lbryUri$parseIdentif = lbryUri.parseIdentifier(params.identifier);
isChannel = _lbryUri$parseIdentif.isChannel;
channelName = _lbryUri$parseIdentif.channelName;
channelClaimId = _lbryUri$parseIdentif.channelClaimId;
claimId = _lbryUri$parseIdentif.claimId;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
if (!isChannel) {
var _flipClaimNameAndIdFo = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);
var _flipClaimNameAndIdFo2 = _slicedToArray(_flipClaimNameAndIdFo, 2);
claimId = _flipClaimNameAndIdFo2[0];
claimName = _flipClaimNameAndIdFo2[1];
}
// log the request data for debugging
logRequestData(responseType, claimName, channelName, claimId);
// get the claim Id and then serve the asset
getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);
});
// route to serve the winning asset at a claim or a channel page
app.get('/:claim', function (req, res) {
var headers = req.headers,
ip = req.ip,
originalUrl = req.originalUrl,
params = req.params;
// decide if this is a show request
var hasFileExtension = void 0;
try {
var _lbryUri$parseModifie2 = lbryUri.parseModifier(params.claim);
hasFileExtension = _lbryUri$parseModifie2.hasFileExtension;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
var responseType = determineResponseType(hasFileExtension, headers);
if (responseType !== SERVE) {
return handleShowRender(req, res);
}
// handle serve request
// send google analytics
sendGAServeEvent(headers, ip, originalUrl);
// parse the claim
var claimName = void 0;
try {
var _lbryUri$parseClaim2 = lbryUri.parseClaim(params.claim);
claimName = _lbryUri$parseClaim2.claimName;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
// log the request data for debugging
logRequestData(responseType, claimName, null, null);
// get the claim Id and then serve the asset
getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);
});
};
/***/ }),
/* 148 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(2);
var _require = __webpack_require__(28),
getClaimId = _require.getClaimId,
getLocalFileRecord = _require.getLocalFileRecord;
var _require2 = __webpack_require__(27),
handleErrorResponse = _require2.handleErrorResponse;
var SERVE = 'SERVE';
var SHOW = 'SHOW';
var NO_FILE = 'NO_FILE';
var NO_CHANNEL = 'NO_CHANNEL';
var NO_CLAIM = 'NO_CLAIM';
function clientAcceptsHtml(_ref) {
var accept = _ref.accept;
return accept && accept.match(/text\/html/);
};
function requestIsFromBrowser(headers) {
return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);
};
function clientWantsAsset(_ref2) {
var accept = _ref2.accept,
range = _ref2.range;
var imageIsWanted = accept && accept.match(/image\/.*/) && !accept.match(/text\/html/) && !accept.match(/text\/\*/);
var videoIsWanted = accept && range;
return imageIsWanted || videoIsWanted;
};
function isValidClaimId(claimId) {
return claimId.length === 40 && !/[^A-Za-z0-9]/g.test(claimId);
};
function isValidShortId(claimId) {
return claimId.length === 1; // it should really evaluate the short url itself
};
function isValidShortIdOrClaimId(input) {
return isValidClaimId(input) || isValidShortId(input);
};
function serveAssetToClient(claimId, name, res) {
return getLocalFileRecord(claimId, name).then(function (fileRecord) {
// check that a local record was found
if (fileRecord === NO_FILE) {
return res.status(307).redirect('/api/claim/get/' + name + '/' + claimId);
}
// serve the file
var filePath = fileRecord.filePath,
fileType = fileRecord.fileType;
logger.verbose('serving file: ' + filePath);
var sendFileOptions = {
headers: {
'X-Content-Type-Options': 'nosniff',
'Content-Type': fileType || 'image/jpeg'
}
};
res.status(200).sendFile(filePath, sendFileOptions);
}).catch(function (error) {
throw error;
});
};
module.exports = {
getClaimIdAndServeAsset: function getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res) {
// get the claim Id and then serve the asset
getClaimId(channelName, channelClaimId, claimName, claimId).then(function (fullClaimId) {
if (fullClaimId === NO_CLAIM) {
return res.status(404).json({ success: false, message: 'no claim id could be found' });
} else if (fullClaimId === NO_CHANNEL) {
return res.status(404).json({ success: false, message: 'no channel id could be found' });
}
serveAssetToClient(fullClaimId, claimName, res);
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');
});
},
determineResponseType: function determineResponseType(hasFileExtension, headers) {
var responseType = void 0;
if (hasFileExtension) {
responseType = SERVE; // assume a serve request if file extension is present
if (clientAcceptsHtml(headers)) {
// if the request comes from a browser, change it to a show request
responseType = SHOW;
}
} else {
responseType = SHOW;
if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) {
// this is in case someone embeds a show url
logger.debug('Show request came from browser but wants an image/video. Changing response to serve...');
responseType = SERVE;
}
}
return responseType;
},
flipClaimNameAndIdForBackwardsCompatibility: function flipClaimNameAndIdForBackwardsCompatibility(identifier, name) {
// this is a patch for backwards compatability with '/name/claim_id' url format
if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) {
var tempName = name;
name = identifier;
identifier = tempName;
}
return [identifier, name];
},
logRequestData: function logRequestData(responseType, claimName, channelName, claimId) {
logger.debug('responseType ===', responseType);
logger.debug('claim name === ', claimName);
logger.debug('channel name ===', channelName);
logger.debug('claim id ===', claimId);
}
};
/***/ }),
/* 149 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var logger = __webpack_require__(2);
module.exports = {
REGEXP_INVALID_CLAIM: /[^A-Za-z0-9-]/g,
REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,
REGEXP_ADDRESS: /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,
CHANNEL_CHAR: '@',
parseIdentifier: function parseIdentifier(identifier) {
logger.debug('parsing identifier:', identifier);
var componentsRegex = new RegExp('([^:$#/]*)' + // value (stops at the first separator or end)
'([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
var _componentsRegex$exec = componentsRegex.exec(identifier).map(function (match) {
return match || null;
}),
_componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 4),
proto = _componentsRegex$exec2[0],
value = _componentsRegex$exec2[1],
modifierSeperator = _componentsRegex$exec2[2],
modifier = _componentsRegex$exec2[3];
logger.debug(proto + ', ' + value + ', ' + modifierSeperator + ', ' + modifier);
// Validate and process name
if (!value) {
throw new Error('Check your url. No channel name provided before "' + modifierSeperator + '"');
}
var isChannel = value.startsWith(module.exports.CHANNEL_CHAR);
var channelName = isChannel ? value : null;
var claimId = void 0;
if (isChannel) {
if (!channelName) {
throw new Error('No channel name after @.');
}
var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL);
if (nameBadChars) {
throw new Error('Invalid characters in channel name: ' + nameBadChars.join(', ') + '.');
}
} else {
claimId = value;
}
// Validate and process modifier
var channelClaimId = void 0;
if (modifierSeperator) {
if (!modifier) {
throw new Error('No modifier provided after separator "' + modifierSeperator + '"');
}
if (modifierSeperator === ':') {
channelClaimId = modifier;
} else {
throw new Error('The "' + modifierSeperator + '" modifier is not currently supported');
}
}
return {
isChannel: isChannel,
channelName: channelName,
channelClaimId: channelClaimId,
claimId: claimId
};
},
parseClaim: function parseClaim(claim) {
logger.debug('parsing name:', claim);
var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier)
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
var _componentsRegex$exec3 = componentsRegex.exec(claim).map(function (match) {
return match || null;
}),
_componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4),
proto = _componentsRegex$exec4[0],
claimName = _componentsRegex$exec4[1],
modifierSeperator = _componentsRegex$exec4[2],
modifier = _componentsRegex$exec4[3];
logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier);
// Validate and process name
if (!claimName) {
throw new Error('No claim name provided before .');
}
var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM);
if (nameBadChars) {
throw new Error('Invalid characters in claim name: ' + nameBadChars.join(', ') + '.');
}
// Validate and process modifier
if (modifierSeperator) {
if (!modifier) {
throw new Error('No file extension provided after separator ' + modifierSeperator + '.');
}
if (modifierSeperator !== '.') {
throw new Error('The ' + modifierSeperator + ' modifier is not supported in the claim name');
}
}
// return results
return {
claimName: claimName
};
},
parseModifier: function parseModifier(claim) {
logger.debug('parsing modifier:', claim);
var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier)
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
var _componentsRegex$exec5 = componentsRegex.exec(claim).map(function (match) {
return match || null;
}),
_componentsRegex$exec6 = _slicedToArray(_componentsRegex$exec5, 4),
proto = _componentsRegex$exec6[0],
claimName = _componentsRegex$exec6[1],
modifierSeperator = _componentsRegex$exec6[2],
modifier = _componentsRegex$exec6[3];
logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier);
// Validate and process modifier
var hasFileExtension = false;
if (modifierSeperator) {
hasFileExtension = true;
}
return {
hasFileExtension: hasFileExtension
};
}
};
/***/ }),
/* 150 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _react = __webpack_require__(0);
var _react2 = _interopRequireDefault(_react);
var _server = __webpack_require__(30);
var _redux = __webpack_require__(18);
var _index = __webpack_require__(31);
var _index2 = _interopRequireDefault(_index);
var _reactRedux = __webpack_require__(1);
var _reactRouterDom = __webpack_require__(3);
var _index3 = __webpack_require__(36);
var _index4 = _interopRequireDefault(_index3);
var _app = __webpack_require__(37);
var _app2 = _interopRequireDefault(_app);
var _renderFullPage = __webpack_require__(43);
var _renderFullPage2 = _interopRequireDefault(_renderFullPage);
var _reduxSaga = __webpack_require__(151);
var _reduxSaga2 = _interopRequireDefault(_reduxSaga);
var _effects = __webpack_require__(15);
var _show_uri = __webpack_require__(152);
var _show = __webpack_require__(8);
var _reactHelmet = __webpack_require__(14);
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var returnSagaWithParams = function returnSagaWithParams(saga, params) {
return (/*#__PURE__*/regeneratorRuntime.mark(function _callee() {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return (0, _effects.call)(saga, params);
case 2:
case 'end':
return _context.stop();
}
}
}, _callee, this);
})
);
};
module.exports = function (req, res) {
var context = {};
// create and apply middleware
var sagaMiddleware = (0, _reduxSaga2.default)();
var middleware = (0, _redux.applyMiddleware)(sagaMiddleware);
// create a new Redux store instance
var store = (0, _redux.createStore)(_index2.default, middleware);
// create saga
var action = (0, _show.onHandleShowPageUri)(req.params);
var saga = returnSagaWithParams(_show_uri.handleShowPageUri, action);
// run the saga middleware
sagaMiddleware.run(saga).done.then(function () {
// render component to a string
var html = (0, _server.renderToString)(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(
_reactRouterDom.StaticRouter,
{ location: req.url, context: context },
_react2.default.createElement(
_index4.default,
null,
_react2.default.createElement(_app2.default, null)
)
)
));
// get head tags from helmet
var helmet = _reactHelmet2.default.renderStatic();
// check for a redirect
if (context.url) {
return res.redirect(301, context.url);
}
// get the initial state from our Redux store
var preloadedState = store.getState();
// send the rendered page back to the client
res.send((0, _renderFullPage2.default)(helmet, html, preloadedState));
});
};
/***/ }),
/* 151 */
/***/ (function(module, exports) {
module.exports = require("redux-saga");
/***/ }),
/* 152 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.handleShowPageUri = handleShowPageUri;
exports.watchHandleShowPageUri = watchHandleShowPageUri;
var _effects = __webpack_require__(15);
var _show_action_types = __webpack_require__(12);
var actions = _interopRequireWildcard(_show_action_types);
var _show = __webpack_require__(8);
var _show_asset = __webpack_require__(153);
var _show_channel = __webpack_require__(155);
var _lbryUri = __webpack_require__(157);
var _lbryUri2 = _interopRequireDefault(_lbryUri);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var _marked = /*#__PURE__*/regeneratorRuntime.mark(parseAndUpdateIdentifierAndClaim),
_marked2 = /*#__PURE__*/regeneratorRuntime.mark(parseAndUpdateClaimOnly),
_marked3 = /*#__PURE__*/regeneratorRuntime.mark(handleShowPageUri),
_marked4 = /*#__PURE__*/regeneratorRuntime.mark(watchHandleShowPageUri);
function parseAndUpdateIdentifierAndClaim(modifier, claim) {
var isChannel, channelName, channelClaimId, claimId, claimName, extension, _lbryUri$parseIdentif, _lbryUri$parseClaim;
return regeneratorRuntime.wrap(function parseAndUpdateIdentifierAndClaim$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
// this is a request for an asset
// claim will be an asset claim
// the identifier could be a channel or a claim id
isChannel = void 0, channelName = void 0, channelClaimId = void 0, claimId = void 0, claimName = void 0, extension = void 0;
_context.prev = 1;
_lbryUri$parseIdentif = _lbryUri2.default.parseIdentifier(modifier);
isChannel = _lbryUri$parseIdentif.isChannel;
channelName = _lbryUri$parseIdentif.channelName;
channelClaimId = _lbryUri$parseIdentif.channelClaimId;
claimId = _lbryUri$parseIdentif.claimId;
_lbryUri$parseClaim = _lbryUri2.default.parseClaim(claim);
claimName = _lbryUri$parseClaim.claimName;
extension = _lbryUri$parseClaim.extension;
_context.next = 17;
break;
case 12:
_context.prev = 12;
_context.t0 = _context['catch'](1);
_context.next = 16;
return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));
case 16:
return _context.abrupt('return', _context.sent);
case 17:
if (!isChannel) {
_context.next = 21;
break;
}
_context.next = 20;
return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, null, channelName, channelClaimId, extension));
case 20:
return _context.abrupt('return', _context.sent);
case 21:
;
_context.next = 24;
return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, claimId, null, null, extension));
case 24:
case 'end':
return _context.stop();
}
}
}, _marked, this, [[1, 12]]);
}
function parseAndUpdateClaimOnly(claim) {
var isChannel, channelName, channelClaimId, _lbryUri$parseIdentif2, claimName, extension, _lbryUri$parseClaim2;
return regeneratorRuntime.wrap(function parseAndUpdateClaimOnly$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
// this could be a request for an asset or a channel page
// claim could be an asset claim or a channel claim
isChannel = void 0, channelName = void 0, channelClaimId = void 0;
_context2.prev = 1;
_lbryUri$parseIdentif2 = _lbryUri2.default.parseIdentifier(claim);
isChannel = _lbryUri$parseIdentif2.isChannel;
channelName = _lbryUri$parseIdentif2.channelName;
channelClaimId = _lbryUri$parseIdentif2.channelClaimId;
_context2.next = 13;
break;
case 8:
_context2.prev = 8;
_context2.t0 = _context2['catch'](1);
_context2.next = 12;
return (0, _effects.put)((0, _show.onRequestError)(_context2.t0.message));
case 12:
return _context2.abrupt('return', _context2.sent);
case 13:
if (!isChannel) {
_context2.next = 17;
break;
}
_context2.next = 16;
return (0, _effects.call)(_show_channel.newChannelRequest, (0, _show.onNewChannelRequest)(channelName, channelClaimId));
case 16:
return _context2.abrupt('return', _context2.sent);
case 17:
// if not for a channel, parse the claim request
claimName = void 0, extension = void 0;
_context2.prev = 18;
_lbryUri$parseClaim2 = _lbryUri2.default.parseClaim(claim);
claimName = _lbryUri$parseClaim2.claimName;
extension = _lbryUri$parseClaim2.extension;
_context2.next = 29;
break;
case 24:
_context2.prev = 24;
_context2.t1 = _context2['catch'](18);
_context2.next = 28;
return (0, _effects.put)((0, _show.onRequestError)(_context2.t1.message));
case 28:
return _context2.abrupt('return', _context2.sent);
case 29:
_context2.next = 31;
return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, null, null, null, extension));
case 31:
case 'end':
return _context2.stop();
}
}
}, _marked2, this, [[1, 8], [18, 24]]);
}
function handleShowPageUri(action) {
var _action$data, identifier, claim;
return regeneratorRuntime.wrap(function handleShowPageUri$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_action$data = action.data, identifier = _action$data.identifier, claim = _action$data.claim;
if (!identifier) {
_context3.next = 5;
break;
}
_context3.next = 4;
return (0, _effects.call)(parseAndUpdateIdentifierAndClaim, identifier, claim);
case 4:
return _context3.abrupt('return', _context3.sent);
case 5:
_context3.next = 7;
return (0, _effects.call)(parseAndUpdateClaimOnly, claim);
case 7:
case 'end':
return _context3.stop();
}
}
}, _marked3, this);
};
function watchHandleShowPageUri() {
return regeneratorRuntime.wrap(function watchHandleShowPageUri$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return (0, _effects.takeLatest)(actions.HANDLE_SHOW_URI, handleShowPageUri);
case 2:
case 'end':
return _context4.stop();
}
}
}, _marked4, this);
};
/***/ }),
/* 153 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.newAssetRequest = newAssetRequest;
exports.watchNewAssetRequest = watchNewAssetRequest;
var _effects = __webpack_require__(15);
var _show_action_types = __webpack_require__(12);
var actions = _interopRequireWildcard(_show_action_types);
var _show = __webpack_require__(8);
var _assetApi = __webpack_require__(154);
var _show2 = __webpack_require__(13);
var _site = __webpack_require__(44);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var _marked = /*#__PURE__*/regeneratorRuntime.mark(newAssetRequest),
_marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchNewAssetRequest);
function newAssetRequest(action) {
var _action$data, requestType, requestId, name, modifier, state, host, longId, _ref, assetKey, shortId, _ref2, claimData, _ref3;
return regeneratorRuntime.wrap(function newAssetRequest$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_action$data = action.data, requestType = _action$data.requestType, requestId = _action$data.requestId, name = _action$data.name, modifier = _action$data.modifier;
// put an action to update the request in redux
_context.next = 3;
return (0, _effects.put)((0, _show.onRequestUpdate)(requestType, requestId));
case 3:
_context.next = 5;
return (0, _effects.select)(_show2.selectShowState);
case 5:
state = _context.sent;
_context.next = 8;
return (0, _effects.select)(_site.selectSiteHost);
case 8:
host = _context.sent;
if (!state.requestList[requestId]) {
_context.next = 11;
break;
}
return _context.abrupt('return', null);
case 11:
// get long id && add request to request list
longId = void 0;
_context.prev = 12;
_context.next = 15;
return (0, _effects.call)(_assetApi.getLongClaimId, host, name, modifier);
case 15:
_ref = _context.sent;
longId = _ref.data;
_context.next = 24;
break;
case 19:
_context.prev = 19;
_context.t0 = _context['catch'](12);
_context.next = 23;
return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));
case 23:
return _context.abrupt('return', _context.sent);
case 24:
assetKey = 'a#' + name + '#' + longId;
_context.next = 27;
return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, assetKey));
case 27:
if (!state.assetList[assetKey]) {
_context.next = 29;
break;
}
return _context.abrupt('return', null);
case 29:
// get short Id
shortId = void 0;
_context.prev = 30;
_context.next = 33;
return (0, _effects.call)(_assetApi.getShortId, host, name, longId);
case 33:
_ref2 = _context.sent;
shortId = _ref2.data;
_context.next = 42;
break;
case 37:
_context.prev = 37;
_context.t1 = _context['catch'](30);
_context.next = 41;
return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message));
case 41:
return _context.abrupt('return', _context.sent);
case 42:
// get asset claim data
claimData = void 0;
_context.prev = 43;
_context.next = 46;
return (0, _effects.call)(_assetApi.getClaimData, host, name, longId);
case 46:
_ref3 = _context.sent;
claimData = _ref3.data;
_context.next = 55;
break;
case 50:
_context.prev = 50;
_context.t2 = _context['catch'](43);
_context.next = 54;
return (0, _effects.put)((0, _show.onRequestError)(_context.t2.message));
case 54:
return _context.abrupt('return', _context.sent);
case 55:
_context.next = 57;
return (0, _effects.put)((0, _show.addAssetToAssetList)(assetKey, null, name, longId, shortId, claimData));
case 57:
_context.next = 59;
return (0, _effects.put)((0, _show.onRequestError)(null));
case 59:
case 'end':
return _context.stop();
}
}
}, _marked, this, [[12, 19], [30, 37], [43, 50]]);
};
function watchNewAssetRequest() {
return regeneratorRuntime.wrap(function watchNewAssetRequest$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return (0, _effects.takeLatest)(actions.ASSET_REQUEST_NEW, newAssetRequest);
case 2:
case 'end':
return _context2.stop();
}
}
}, _marked2, this);
};
/***/ }),
/* 154 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getLongClaimId = getLongClaimId;
exports.getShortId = getShortId;
exports.getClaimData = getClaimData;
var _request = __webpack_require__(11);
var _request2 = _interopRequireDefault(_request);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getLongClaimId(host, name, modifier) {
var body = {};
// create request params
if (modifier) {
if (modifier.id) {
body['claimId'] = modifier.id;
} else {
body['channelName'] = modifier.channel.name;
body['channelClaimId'] = modifier.channel.id;
}
}
body['claimName'] = name;
var params = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
};
// create url
var url = host + '/api/claim/long-id';
// return the request promise
return (0, _request2.default)(url, params);
};
function getShortId(host, name, claimId) {
var url = host + '/api/claim/short-id/' + claimId + '/' + name;
return (0, _request2.default)(url);
};
function getClaimData(host, name, claimId) {
var url = host + '/api/claim/data/' + name + '/' + claimId;
return (0, _request2.default)(url);
};
/***/ }),
/* 155 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.newChannelRequest = newChannelRequest;
exports.watchNewChannelRequest = watchNewChannelRequest;
exports.watchUpdateChannelClaims = watchUpdateChannelClaims;
var _effects = __webpack_require__(15);
var _show_action_types = __webpack_require__(12);
var actions = _interopRequireWildcard(_show_action_types);
var _show = __webpack_require__(8);
var _channelApi = __webpack_require__(156);
var _show2 = __webpack_require__(13);
var _site = __webpack_require__(44);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var _marked = /*#__PURE__*/regeneratorRuntime.mark(newChannelRequest),
_marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchNewChannelRequest),
_marked3 = /*#__PURE__*/regeneratorRuntime.mark(getNewClaimsAndUpdateChannel),
_marked4 = /*#__PURE__*/regeneratorRuntime.mark(watchUpdateChannelClaims);
function newChannelRequest(action) {
var _action$data, requestType, requestId, channelName, channelId, state, host, longId, shortId, _ref, _ref$data, channelKey, claimsData, _ref2;
return regeneratorRuntime.wrap(function newChannelRequest$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_action$data = action.data, requestType = _action$data.requestType, requestId = _action$data.requestId, channelName = _action$data.channelName, channelId = _action$data.channelId;
// put an action to update the request in redux
_context.next = 3;
return (0, _effects.put)((0, _show.onRequestUpdate)(requestType, requestId));
case 3:
_context.next = 5;
return (0, _effects.select)(_show2.selectShowState);
case 5:
state = _context.sent;
_context.next = 8;
return (0, _effects.select)(_site.selectSiteHost);
case 8:
host = _context.sent;
if (!state.requestList[requestId]) {
_context.next = 11;
break;
}
return _context.abrupt('return', null);
case 11:
// get channel long id
longId = void 0, shortId = void 0;
_context.prev = 12;
_context.next = 15;
return (0, _effects.call)(_channelApi.getChannelData, host, channelName, channelId);
case 15:
_ref = _context.sent;
_ref$data = _ref.data;
longId = _ref$data.longChannelClaimId;
shortId = _ref$data.shortChannelClaimId;
_context.next = 26;
break;
case 21:
_context.prev = 21;
_context.t0 = _context['catch'](12);
_context.next = 25;
return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));
case 25:
return _context.abrupt('return', _context.sent);
case 26:
// store the request in the channel requests list
channelKey = 'c#' + channelName + '#' + longId;
_context.next = 29;
return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, channelKey));
case 29:
if (!state.channelList[channelKey]) {
_context.next = 31;
break;
}
return _context.abrupt('return', null);
case 31:
// get channel claims data
claimsData = void 0;
_context.prev = 32;
_context.next = 35;
return (0, _effects.call)(_channelApi.getChannelClaims, host, longId, channelName, 1);
case 35:
_ref2 = _context.sent;
claimsData = _ref2.data;
_context.next = 44;
break;
case 39:
_context.prev = 39;
_context.t1 = _context['catch'](32);
_context.next = 43;
return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message));
case 43:
return _context.abrupt('return', _context.sent);
case 44:
_context.next = 46;
return (0, _effects.put)((0, _show.addNewChannelToChannelList)(channelKey, channelName, shortId, longId, claimsData));
case 46:
_context.next = 48;
return (0, _effects.put)((0, _show.onRequestError)(null));
case 48:
case 'end':
return _context.stop();
}
}
}, _marked, this, [[12, 21], [32, 39]]);
}
function watchNewChannelRequest() {
return regeneratorRuntime.wrap(function watchNewChannelRequest$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return (0, _effects.takeLatest)(actions.CHANNEL_REQUEST_NEW, newChannelRequest);
case 2:
case 'end':
return _context2.stop();
}
}
}, _marked2, this);
};
function getNewClaimsAndUpdateChannel(action) {
var _action$data2, channelKey, name, longId, page, host, claimsData, _ref3;
return regeneratorRuntime.wrap(function getNewClaimsAndUpdateChannel$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_action$data2 = action.data, channelKey = _action$data2.channelKey, name = _action$data2.name, longId = _action$data2.longId, page = _action$data2.page;
_context3.next = 3;
return (0, _effects.select)(_site.selectSiteHost);
case 3:
host = _context3.sent;
claimsData = void 0;
_context3.prev = 5;
_context3.next = 8;
return (0, _effects.call)(_channelApi.getChannelClaims, host, longId, name, page);
case 8:
_ref3 = _context3.sent;
claimsData = _ref3.data;
_context3.next = 17;
break;
case 12:
_context3.prev = 12;
_context3.t0 = _context3['catch'](5);
_context3.next = 16;
return (0, _effects.put)((0, _show.onRequestError)(_context3.t0.message));
case 16:
return _context3.abrupt('return', _context3.sent);
case 17:
_context3.next = 19;
return (0, _effects.put)((0, _show.updateChannelClaims)(channelKey, claimsData));
case 19:
case 'end':
return _context3.stop();
}
}
}, _marked3, this, [[5, 12]]);
}
function watchUpdateChannelClaims() {
return regeneratorRuntime.wrap(function watchUpdateChannelClaims$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return (0, _effects.takeLatest)(actions.CHANNEL_CLAIMS_UPDATE_ASYNC, getNewClaimsAndUpdateChannel);
case 2:
case 'end':
return _context4.stop();
}
}
}, _marked4, this);
}
/***/ }),
/* 156 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getChannelData = getChannelData;
exports.getChannelClaims = getChannelClaims;
var _request = __webpack_require__(11);
var _request2 = _interopRequireDefault(_request);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getChannelData(host, id, name) {
if (!id) id = 'none';
var url = host + '/api/channel/data/' + name + '/' + id;
return (0, _request2.default)(url);
};
function getChannelClaims(host, longId, name, page) {
if (!page) page = 1;
var url = host + '/api/channel/claims/' + name + '/' + longId + '/' + page;
return (0, _request2.default)(url);
};
/***/ }),
/* 157 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
module.exports = {
REGEXP_INVALID_CLAIM: /[^A-Za-z0-9-]/g,
REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,
REGEXP_ADDRESS: /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,
CHANNEL_CHAR: '@',
parseIdentifier: function parseIdentifier(identifier) {
var componentsRegex = new RegExp('([^:$#/]*)' + // value (stops at the first separator or end)
'([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
var _componentsRegex$exec = componentsRegex // eslint-disable-line no-unused-vars
.exec(identifier).map(function (match) {
return match || null;
}),
_componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 4),
proto = _componentsRegex$exec2[0],
value = _componentsRegex$exec2[1],
modifierSeperator = _componentsRegex$exec2[2],
modifier = _componentsRegex$exec2[3];
// Validate and process name
if (!value) {
throw new Error('Check your URL. No channel name provided before "' + modifierSeperator + '"');
}
var isChannel = value.startsWith(module.exports.CHANNEL_CHAR);
var channelName = isChannel ? value : null;
var claimId = void 0;
if (isChannel) {
if (!channelName) {
throw new Error('Check your URL. No channel name after "@".');
}
var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL);
if (nameBadChars) {
throw new Error('Check your URL. Invalid characters in channel name: "' + nameBadChars.join(', ') + '".');
}
} else {
claimId = value;
}
// Validate and process modifier
var channelClaimId = void 0;
if (modifierSeperator) {
if (!modifier) {
throw new Error('Check your URL. No modifier provided after separator "' + modifierSeperator + '"');
}
if (modifierSeperator === ':') {
channelClaimId = modifier;
} else {
throw new Error('Check your URL. The "' + modifierSeperator + '" modifier is not currently supported');
}
}
return {
isChannel: isChannel,
channelName: channelName,
channelClaimId: channelClaimId || null,
claimId: claimId || null
};
},
parseClaim: function parseClaim(name) {
var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first extension)
'([:$#.]?)([^/]*)' // extension separator, extension (stops at the first path separator or end)
);
var _componentsRegex$exec3 = componentsRegex // eslint-disable-line no-unused-vars
.exec(name).map(function (match) {
return match || null;
}),
_componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4),
proto = _componentsRegex$exec4[0],
claimName = _componentsRegex$exec4[1],
extensionSeperator = _componentsRegex$exec4[2],
extension = _componentsRegex$exec4[3];
// Validate and process name
if (!claimName) {
throw new Error('Check your URL. No claim name provided before "."');
}
var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM);
if (nameBadChars) {
throw new Error('Check your URL. Invalid characters in claim name: "' + nameBadChars.join(', ') + '".');
}
// Validate and process extension
if (extensionSeperator) {
if (!extension) {
throw new Error('Check your URL. No file extension provided after separator "' + extensionSeperator + '".');
}
if (extensionSeperator !== '.') {
throw new Error('Check your URL. The "' + extensionSeperator + '" separator is not supported in the claim name.');
}
}
return {
claimName: claimName,
extension: extension || null
};
}
};
/***/ }),
/* 158 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var handlePageRender = __webpack_require__(29);
module.exports = function (app) {
// a catch-all route if someone visits a page that does not exist
app.use('*', function (req, res) {
// send response
handlePageRender(req, res);
});
};
/***/ })
/******/ ]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZmRiYmJiMjcwMzQ0OThjZDIwNDciLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3RcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdC1yZWR1eFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcIndpbnN0b25cIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdC1yb3V0ZXItZG9tXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2FjdGlvbnMvcHVibGlzaC5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvc2l0ZUNvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL05hdkJhci9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvYWN0aW9ucy9zaG93LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL1NFTy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJwcm9wLXR5cGVzXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL3JlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcy5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2VsZWN0b3JzL3Nob3cuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3QtaGVsbWV0XCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVkdXgtc2FnYS9lZmZlY3RzXCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvbGJyeUFwaS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9nb29nbGVBbmFseXRpY3MuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVkdXhcIiIsIndlYnBhY2s6Ly8vLi9jbGllbnQvYWN0aW9ucy9jaGFubmVsLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL1Byb2dyZXNzQmFyL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvcGFnZXMvRXJyb3JQYWdlL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJwYXNzcG9ydFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInBhc3Nwb3J0LWxvY2FsXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwic2VxdWVsaXplXCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvc2VxdWVsaXplSGVscGVycy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9wdWJsaXNoSGVscGVycy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9lcnJvckhhbmRsZXJzLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9jb250cm9sbGVycy9zZXJ2ZUNvbnRyb2xsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvaGFuZGxlUGFnZVJlbmRlci5qc3giLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3QtZG9tL3NlcnZlclwiIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29uc3RhbnRzL3B1Ymxpc2hfYWN0aW9uX3R5cGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb25zdGFudHMvcHVibGlzaF9jaGFubmVsX3NlbGVjdF9zdGF0ZXMuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9jaGFubmVsX2FjdGlvbl90eXBlcy5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29uc3RhbnRzL2Fzc2V0X2Rpc3BsYXlfc3RhdGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL0dBTGlzdGVuZXIvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9hcHAuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Ryb3B6b25lL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENyZWF0ZUZvcm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9zaG93X3JlcXVlc3RfdHlwZXMuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQXNzZXREaXNwbGF5L2luZGV4LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL3JlbmRlckZ1bGxQYWdlLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9zZWxlY3RvcnMvc2l0ZS5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJiYWJlbC1wb2x5ZmlsbFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcIndoYXR3Zy1mZXRjaFwiIiwid2VicGFjazovLy8uL3NlcnZlci9zZXJ2ZXIuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZXhwcmVzc1wiIiwid2VicGFjazovLy9leHRlcm5hbCBcImJvZHktcGFyc2VyXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZXhwcmVzcy1oYW5kbGViYXJzXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiaGFuZGxlYmFyc1wiIiwid2VicGFjazovLy9leHRlcm5hbCBcImhlbG1ldFwiIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2F1dGhIZWxwZXJzLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImNvb2tpZS1zZXNzaW9uXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiaHR0cFwiIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2NvbmZpZ3VyZUxvZ2dlci5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvbG9nZ2VyQ29uZmlnLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2NvbmZpZ3VyZVNsYWNrLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcIndpbnN0b24tc2xhY2std2ViaG9va1wiIiwid2VicGFjazovLy8uL2NvbmZpZy9zbGFja0NvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImF4aW9zXCIiLCJ3ZWJwYWNrOi8vLy4vY29uZmlnL2xicnlDb25maWcuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwidW5pdmVyc2FsLWFuYWx5dGljc1wiIiwid2VicGFjazovLy8uL2NvbmZpZy9teXNxbENvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2NlcnRpZmljYXRlLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9tb2RlbHMvY2hhbm5lbC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2NsYWltLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9tb2RlbHMvZmlsZS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL3JlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21vZGVscy91c2VyLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImJjcnlwdFwiIiwid2VicGFjazovLy8uL3NlcnZlci9wYXNzcG9ydC9sb2NhbC1sb2dpbi5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2F1dGgtcm91dGVzLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpLXJvdXRlcy5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJjb25uZWN0LW11bHRpcGFydHlcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvY29udHJvbGxlcnMvcHVibGlzaENvbnRyb2xsZXIuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZnNcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvYXV0aC9hdXRoZW50aWNhdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9jaGFubmVsUGFnaW5hdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL3BhZ2Utcm91dGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9wdWJsaXNoLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9jaGFubmVsLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9zaG93LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9zaXRlLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LWdhXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL0hvbWVQYWdlL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9TRU8vdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL3BhZ2VUaXRsZS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvdXRpbHMvbWV0YVRhZ3MuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL2Nhbm9uaWNhbExpbmsuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvTmF2QmFyL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL0xvZ28vaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL05hdkJhckNoYW5uZWxPcHRpb25zRHJvcGRvd24vaW5kZXguanN4Iiwid2VicGFjazovLy9leHRlcm5hbCBcImNyb3NzLWZldGNoL3BvbHlmaWxsXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFRvb2wvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFRvb2wvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvRHJvcHpvbmUvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL2ZpbGUuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvUHVibGlzaFByZXZpZXcvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEZXRhaWxzL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEZXRhaWxzL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hVcmxJbnB1dC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvUHVibGlzaFVybE1pZGRsZURpc3BsYXkvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaHVtYm5haWxJbnB1dC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaE1ldGFkYXRhSW5wdXRzL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9FeHBhbmRpbmdUZXh0QXJlYS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbFNlbGVjdC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9DaGFubmVsU2VsZWN0L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENyZWF0ZUZvcm0vdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvQWN0aXZlU3RhdHVzQmFyL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9JbmFjdGl2ZVN0YXR1c0Jhci9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFN0YXR1cy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoU3RhdHVzL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb25zdGFudHMvcHVibGlzaF9jbGFpbV9zdGF0ZXMuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaERpc2FibGVkTWVzc2FnZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9wYWdlcy9BYm91dFBhZ2UvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9wYWdlcy9Mb2dpblBhZ2UvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL0xvZ2luUGFnZS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvcGFnZXMvU2hvd1BhZ2UvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL1Nob3dQYWdlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1Nob3dBc3NldExpdGUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0TGl0ZS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9Bc3NldERpc3BsYXkvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Fzc2V0VGl0bGUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQXNzZXRUaXRsZS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9Bc3NldEluZm8vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQXNzZXRJbmZvL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1Nob3dDaGFubmVsL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1Nob3dDaGFubmVsL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL0Fzc2V0UHJldmlldy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9Bc3NldFByZXZpZXcvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2UvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0ZvdXJPaEZvdXJQYWdlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXNzZXQtcm91dGVzLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL3NlcnZlSGVscGVycy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9sYnJ5VXJpLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4Iiwid2VicGFjazovLy9leHRlcm5hbCBcInJlZHV4LXNhZ2FcIiIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2FnYXMvc2hvd191cmkuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3NhZ2FzL3Nob3dfYXNzZXQuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2FwaS9hc3NldEFwaS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2FnYXMvc2hvd19jaGFubmVsLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9hcGkvY2hhbm5lbEFwaS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvdXRpbHMvbGJyeVVyaS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2ZhbGxiYWNrLXJvdXRlcy5qcyJdLCJuYW1lcyI6WyJzZWxlY3RGaWxlIiwiY2xlYXJGaWxlIiwidXBkYXRlTWV0YWRhdGEiLCJ1cGRhdGVDbGFpbSIsInNldFB1Ymxpc2hJbkNoYW5uZWwiLCJ1cGRhdGVQdWJsaXNoU3RhdHVzIiwidXBkYXRlRXJyb3IiLCJ1cGRhdGVTZWxlY3RlZENoYW5uZWwiLCJ0b2dnbGVNZXRhZGF0YUlucHV0cyIsIm9uTmV3VGh1bWJuYWlsIiwic3RhcnRQdWJsaXNoIiwiYWN0aW9ucyIsImZpbGUiLCJ0eXBlIiwiRklMRV9TRUxFQ1RFRCIsImRhdGEiLCJGSUxFX0NMRUFSIiwibmFtZSIsInZhbHVlIiwiTUVUQURBVEFfVVBEQVRFIiwiQ0xBSU1fVVBEQVRFIiwiY2hhbm5lbCIsIlNFVF9QVUJMSVNIX0lOX0NIQU5ORUwiLCJzdGF0dXMiLCJtZXNzYWdlIiwiUFVCTElTSF9TVEFUVVNfVVBEQVRFIiwiRVJST1JfVVBEQVRFIiwiY2hhbm5lbE5hbWUiLCJTRUxFQ1RFRF9DSEFOTkVMX1VQREFURSIsInNob3dNZXRhZGF0YUlucHV0cyIsIlRPR0dMRV9NRVRBREFUQV9JTlBVVFMiLCJUSFVNQk5BSUxfTkVXIiwiaGlzdG9yeSIsIlBVQkxJU0hfU1RBUlQiLCJTaXRlQ29uZmlnIiwiYW5hbHl0aWNzIiwiZ29vZ2xlSWQiLCJhc3NldERlZmF1bHRzIiwiZGVzY3JpcHRpb24iLCJ0aHVtYm5haWwiLCJ0aXRsZSIsImF1dGgiLCJzZXNzaW9uS2V5IiwiZGV0YWlscyIsImhvc3QiLCJwb3J0IiwidHdpdHRlciIsInB1Ymxpc2hpbmciLCJhZGRpdGlvbmFsQ2xhaW1BZGRyZXNzZXMiLCJkaXNhYmxlZCIsImRpc2FibGVkTWVzc2FnZSIsInByaW1hcnlDbGFpbUFkZHJlc3MiLCJ0aHVtYm5haWxDaGFubmVsIiwidGh1bWJuYWlsQ2hhbm5lbElkIiwidXBsb2FkRGlyZWN0b3J5IiwibW9kdWxlIiwiZXhwb3J0cyIsIlNlcXVlbGl6ZSIsInJlcXVpcmUiLCJsb2dnZXIiLCJjb25zb2xlIiwibG9nIiwiZGF0YWJhc2UiLCJ1c2VybmFtZSIsInBhc3N3b3JkIiwiZGIiLCJzZXF1ZWxpemUiLCJkaWFsZWN0IiwiZGlhbGVjdE9wdGlvbnMiLCJkZWNpbWFsTnVtYmVycyIsImxvZ2dpbmciLCJwb29sIiwibWF4IiwibWluIiwiaWRsZSIsImFjcXVpcmUiLCJhdXRoZW50aWNhdGUiLCJ0aGVuIiwiaW5mbyIsImNhdGNoIiwiZXJyb3IiLCJlcnIiLCJDZXJ0aWZpY2F0ZSIsIkNoYW5uZWwiLCJDbGFpbSIsIkZpbGUiLCJSZXF1ZXN0IiwiVXNlciIsImltcG9ydCIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwibW9kZWxOYW1lIiwiYXNzb2NpYXRlIiwidXBzZXJ0IiwiTW9kZWwiLCJ2YWx1ZXMiLCJjb25kaXRpb24iLCJ0YWJsZU5hbWUiLCJmaW5kT25lIiwid2hlcmUiLCJvYmoiLCJkZWJ1ZyIsInVwZGF0ZSIsImNyZWF0ZSIsIm1hcFN0YXRlVG9Qcm9wcyIsInNpdGUiLCJsb2dnZWRJbkNoYW5uZWwiLCJjaGFubmVsU2hvcnRJZCIsInNob3J0SWQiLCJjaGFubmVsTG9uZ0lkIiwibG9uZ0lkIiwic2l0ZURlc2NyaXB0aW9uIiwibWFwRGlzcGF0Y2hUb1Byb3BzIiwib25DaGFubmVsTG9naW4iLCJkaXNwYXRjaCIsIm9uQ2hhbm5lbExvZ291dCIsIm9uSGFuZGxlU2hvd1BhZ2VVcmkiLCJvblJlcXVlc3RFcnJvciIsIm9uTmV3Q2hhbm5lbFJlcXVlc3QiLCJvbk5ld0Fzc2V0UmVxdWVzdCIsIm9uUmVxdWVzdFVwZGF0ZSIsImFkZFJlcXVlc3RUb1JlcXVlc3RMaXN0IiwiYWRkQXNzZXRUb0Fzc2V0TGlzdCIsImFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0Iiwib25VcGRhdGVDaGFubmVsQ2xhaW1zIiwidXBkYXRlQ2hhbm5lbENsYWltcyIsImZpbGVSZXF1ZXN0ZWQiLCJ1cGRhdGVGaWxlQXZhaWxhYmlsaXR5IiwidXBkYXRlRGlzcGxheUFzc2V0RXJyb3IiLCJwYXJhbXMiLCJIQU5ETEVfU0hPV19VUkkiLCJSRVFVRVNUX0VSUk9SIiwiY2hhbm5lbElkIiwicmVxdWVzdFR5cGUiLCJyZXF1ZXN0SWQiLCJDSEFOTkVMX1JFUVVFU1RfTkVXIiwiaWQiLCJleHRlbnNpb24iLCJBU1NFVF9SRVFVRVNUX05FVyIsIm1vZGlmaWVyIiwiUkVRVUVTVF9VUERBVEUiLCJrZXkiLCJSRVFVRVNUX0xJU1RfQUREIiwiY2xhaW1JZCIsImNsYWltRGF0YSIsIkFTU0VUX0FERCIsImNsYWltc0RhdGEiLCJDSEFOTkVMX0FERCIsImNoYW5uZWxLZXkiLCJwYWdlIiwiQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DIiwiY2hhbm5lbExpc3RJZCIsIkNIQU5ORUxfQ0xBSU1TX1VQREFURV9TVUNDRVNTIiwiRklMRV9SRVFVRVNURUQiLCJGSUxFX0FWQUlMQUJJTElUWV9VUERBVEUiLCJESVNQTEFZX0FTU0VUX0VSUk9SIiwiZGVmYXVsdERlc2NyaXB0aW9uIiwiZGVmYXVsdFRodW1ibmFpbCIsInNpdGVIb3N0Iiwic2l0ZVRpdGxlIiwic2l0ZVR3aXR0ZXIiLCJyZXF1ZXN0IiwicGFyc2VKU09OIiwicmVzcG9uc2UiLCJqc29uIiwiY2hlY2tTdGF0dXMiLCJqc29uUmVzcG9uc2UiLCJFcnJvciIsInVybCIsIm9wdGlvbnMiLCJmZXRjaCIsIlByb21pc2UiLCJhbGwiLCJzZWxlY3RBc3NldCIsInNob3ciLCJyZXF1ZXN0TGlzdCIsImFzc2V0S2V5IiwiYXNzZXRMaXN0Iiwic2VsZWN0U2hvd1N0YXRlIiwic3RhdGUiLCJheGlvcyIsImFwaSIsImFwaUhvc3QiLCJhcGlQb3J0IiwibGJyeUFwaVVyaSIsImNob29zZUdhTGJyeW5ldFB1Ymxpc2hMYWJlbCIsInNlbmRHQVRpbWluZ0V2ZW50IiwiaGFuZGxlTGJyeW5ldFJlc3BvbnNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsIkpTT04iLCJzdHJpbmdpZnkiLCJwdWJsaXNoQ2xhaW0iLCJwdWJsaXNoUGFyYW1zIiwiZ2FTdGFydFRpbWUiLCJEYXRlIiwibm93IiwicG9zdCIsIm1ldGhvZCIsImdldENsYWltIiwidXJpIiwidGltZW91dCIsImdldENsYWltTGlzdCIsImNsYWltTmFtZSIsInJlc29sdmVVcmkiLCJnZXREb3dubG9hZERpcmVjdG9yeSIsImRvd25sb2FkX2RpcmVjdG9yeSIsImNyZWF0ZUNoYW5uZWwiLCJjaGFubmVsX25hbWUiLCJhbW91bnQiLCJ1YSIsImNyZWF0ZVNlcnZlRXZlbnRQYXJhbXMiLCJoZWFkZXJzIiwiaXAiLCJvcmlnaW5hbFVybCIsImV2ZW50Q2F0ZWdvcnkiLCJldmVudEFjdGlvbiIsImV2ZW50TGFiZWwiLCJpcE92ZXJyaWRlIiwidXNlckFnZW50T3ZlcnJpZGUiLCJjcmVhdGVQdWJsaXNoVGltaW5nRXZlbnRQYXJhbXMiLCJjYXRlZ29yeSIsInZhcmlhYmxlIiwibGFiZWwiLCJzdGFydFRpbWUiLCJlbmRUaW1lIiwiZHVyYXRpb24iLCJ1c2VyVGltaW5nQ2F0ZWdvcnkiLCJ1c2VyVGltaW5nVmFyaWFibGVOYW1lIiwidXNlclRpbWluZ1RpbWUiLCJ1c2VyVGltaW5nTGFiZWwiLCJzZW5kR29vZ2xlQW5hbHl0aWNzRXZlbnQiLCJ2aXNpdG9ySWQiLCJyZXBsYWNlIiwidmlzaXRvciIsInN0cmljdENpZEZvcm1hdCIsImh0dHBzIiwiZXZlbnQiLCJzZW5kR29vZ2xlQW5hbHl0aWNzVGltaW5nIiwidGltaW5nIiwic2VuZEdBU2VydmVFdmVudCIsImNoYW5uZWxfaWQiLCJ1cGRhdGVMb2dnZWRJbkNoYW5uZWwiLCJDSEFOTkVMX1VQREFURSIsIlByb2dyZXNzQmFyIiwicHJvcHMiLCJiYXJzIiwiaW5kZXgiLCJpbmNyZW1lbnRlciIsImNyZWF0ZUJhcnMiLCJiaW5kIiwic3RhcnRQcm9ncmVzc0JhciIsInVwZGF0ZVByb2dyZXNzQmFyIiwic3RvcFByb2dyZXNzQmFyIiwiaSIsInNpemUiLCJwdXNoIiwiaXNBY3RpdmUiLCJzZXRTdGF0ZSIsInVwZGF0ZUludGVydmFsIiwic2V0SW50ZXJ2YWwiLCJjbGVhckludGVydmFsIiwibWFwIiwiYmFyIiwiQ29tcG9uZW50IiwicHJvcFR5cGVzIiwibnVtYmVyIiwiaXNSZXF1aXJlZCIsIkVycm9yUGFnZSIsInN0cmluZyIsInJldHVyblNob3J0SWQiLCJjbGFpbXNBcnJheSIsImNsYWltSW5kZXgiLCJzdWJzdHJpbmciLCJzaG9ydElkTGVuZ3RoIiwiZmluZEluZGV4IiwiZWxlbWVudCIsInBvc3NpYmxlTWF0Y2hlcyIsInNsaWNlIiwibGVuZ3RoIiwiZmlsdGVyIiwiZnMiLCJwYXJzZVB1Ymxpc2hBcGlSZXF1ZXN0Qm9keSIsIm5zZnciLCJsaWNlbnNlIiwiaW52YWxpZE5hbWVDaGFyYWN0ZXJzIiwiZXhlYyIsInBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyIsInBhdGgiLCJ0ZXN0IiwidmFsaWRhdGVGaWxlVHlwZUFuZFNpemUiLCJmaWxlTmFtZSIsImZpbGVQYXRoIiwiZmlsZVR5cGUiLCJ0aHVtYm5haWxGaWxlTmFtZSIsInRodW1ibmFpbEZpbGVQYXRoIiwidGh1bWJuYWlsRmlsZVR5cGUiLCJjcmVhdGVCYXNpY1B1Ymxpc2hQYXJhbXMiLCJ0cmltIiwiZmlsZV9wYXRoIiwiYmlkIiwibWV0YWRhdGEiLCJhdXRob3IiLCJsYW5ndWFnZSIsImNsYWltX2FkZHJlc3MiLCJjcmVhdGVUaHVtYm5haWxQdWJsaXNoUGFyYW1zIiwiZGVsZXRlVGVtcG9yYXJ5RmlsZSIsInVubGluayIsImFkZEdldFJlc3VsdHNUb0ZpbGVEYXRhIiwiZmlsZUluZm8iLCJnZXRSZXN1bHQiLCJmaWxlX25hbWUiLCJkb3dubG9hZF9wYXRoIiwiY3JlYXRlRmlsZURhdGEiLCJvdXRwb2ludCIsImhlaWdodCIsImFkZHJlc3MiLCJjb250ZW50VHlwZSIsImhhbmRsZUVycm9yUmVzcG9uc2UiLCJyZXMiLCJ1c2VPYmplY3RQcm9wZXJ0aWVzSWZOb0tleXMiLCJyZXR1cm5FcnJvck1lc3NhZ2VBbmRTdGF0dXMiLCJjcmVhdGVFcnJvclJlc3BvbnNlUGF5bG9hZCIsImNvZGUiLCJuZXdFcnJvck9iamVjdCIsImdldE93blByb3BlcnR5TmFtZXMiLCJzdWNjZXNzIiwicmV0dXJuUGFnaW5hdGVkQ2hhbm5lbENsYWltcyIsIk5PX0NIQU5ORUwiLCJOT19DTEFJTSIsIk5PX0ZJTEUiLCJnZXRDbGFpbUlkIiwiY2hhbm5lbENsYWltSWQiLCJnZXRDbGFpbUlkQnlDaGFubmVsIiwiZ2V0Q2xhaW1JZEJ5Q2xhaW0iLCJnZXRMb25nQ2xhaW1JZCIsImxvbmdDbGFpbUlkIiwiZ2V0TG9uZ0NoYW5uZWxJZCIsImxvbmdDaGFubmVsSWQiLCJnZXRDbGFpbUlkQnlMb25nQ2hhbm5lbElkIiwiZ2V0Q2hhbm5lbERhdGEiLCJsb25nQ2hhbm5lbENsYWltSWQiLCJnZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkIiwic2hvcnRDaGFubmVsQ2xhaW1JZCIsImdldENoYW5uZWxDbGFpbXMiLCJnZXRBbGxDaGFubmVsQ2xhaW1zIiwiY2hhbm5lbENsYWltc0FycmF5IiwicGFnaW5hdGVkQ2hhbm5lbFZpZXdEYXRhIiwiZ2V0TG9jYWxGaWxlUmVjb3JkIiwiZGF0YVZhbHVlcyIsInJlcSIsImNvbnRleHQiLCJzdG9yZSIsImh0bWwiLCJoZWxtZXQiLCJyZW5kZXJTdGF0aWMiLCJyZWRpcmVjdCIsInByZWxvYWRlZFN0YXRlIiwiZ2V0U3RhdGUiLCJzZW5kIiwicHVibGlzaCIsIkxPR0lOIiwiQ1JFQVRFIiwiTE9DQUxfQ0hFQ0siLCJVTkFWQUlMQUJMRSIsIkVSUk9SIiwiQVZBSUxBQkxFIiwiaW5pdGlhbGl6ZSIsIkdBTGlzdGVuZXIiLCJzZW5kUGFnZVZpZXciLCJsb2NhdGlvbiIsImxpc3RlbiIsInNldCIsInBhdGhuYW1lIiwicGFnZXZpZXciLCJjaGlsZHJlbiIsIkFwcCIsImZpbGVFcnJvciIsInNldEZpbGVFcnJvciIsIkNIQU5ORUwiLCJBU1NFVF9MSVRFIiwiQVNTRVRfREVUQUlMUyIsImRpc3BsYXlBc3NldCIsImFzc2V0Iiwib25GaWxlUmVxdWVzdCIsInRvU3RyaW5nIiwibWV0YSIsImxpbmsiLCJzZWxlY3RTaXRlU3RhdGUiLCJzZWxlY3RTaXRlSG9zdCIsImV4cHJlc3MiLCJib2R5UGFyc2VyIiwiZXhwcmVzc0hhbmRsZWJhcnMiLCJIYW5kbGViYXJzIiwicGFzc3BvcnQiLCJzZXJpYWxpemVTcGVlY2hVc2VyIiwiZGVzZXJpYWxpemVTcGVlY2hVc2VyIiwiY29va2llU2Vzc2lvbiIsImh0dHAiLCJQT1JUIiwiYXBwIiwiZW5hYmxlIiwidXNlIiwic3RhdGljIiwiX19kaXJuYW1lIiwidXJsZW5jb2RlZCIsImV4dGVuZGVkIiwibmV4dCIsInZlcmJvc2UiLCJzZXJpYWxpemVVc2VyIiwiZGVzZXJpYWxpemVVc2VyIiwibG9jYWxTaWdudXBTdHJhdGVneSIsImxvY2FsTG9naW5TdHJhdGVneSIsIm1heEFnZSIsInNlc3Npb24iLCJoYnMiLCJkZWZhdWx0TGF5b3V0IiwiaGFuZGxlYmFycyIsImVuZ2luZSIsInNlcnZlciIsIlNlcnZlciIsInN5bmMiLCJ1c2VyIiwiZG9uZSIsImxvZ0xldmVsIiwid2luc3RvbiIsImNvbmZpZ3VyZSIsInRyYW5zcG9ydHMiLCJDb25zb2xlIiwibGV2ZWwiLCJ0aW1lc3RhbXAiLCJjb2xvcml6ZSIsInByZXR0eVByaW50IiwiaGFuZGxlRXhjZXB0aW9ucyIsImh1bWFuUmVhZGFibGVVbmhhbmRsZWRFeGNlcHRpb24iLCJ3YXJuIiwic2lsbHkiLCJsb2dnZXJDb25maWciLCJ3aW5zdG9uU2xhY2tXZWJIb29rIiwiU2xhY2tXZWJIb29rIiwic2xhY2tDb25maWciLCJzbGFja1dlYkhvb2siLCJzbGFja0Vycm9yQ2hhbm5lbCIsInNsYWNrSW5mb0NoYW5uZWwiLCJhZGQiLCJ3ZWJob29rVXJsIiwiaWNvbkVtb2ppIiwiU2xhY2tDb25maWciLCJQYXNzcG9ydExvY2FsU3RyYXRlZ3kiLCJTdHJhdGVneSIsImxicnlBcGkiLCJ1c2VybmFtZUZpZWxkIiwicGFzc3dvcmRGaWVsZCIsInVzZXJJbmZvIiwidXNlckRhdGEiLCJ1c2VyTmFtZSIsImNoYW5uZWxEYXRhIiwidHgiLCJjbGFpbV9pZCIsImNlcnRpZmljYXRlRGF0YSIsIm5ld1VzZXIiLCJuZXdDaGFubmVsIiwibmV3Q2VydGlmaWNhdGUiLCJzZXRDaGFubmVsIiwic2V0VXNlciIsInNob3J0Q2hhbm5lbElkIiwibGJyeUNvbmZpZyIsIk15c3FsQ29uZmlnIiwiU1RSSU5HIiwiQk9PTEVBTiIsIklOVEVHRVIiLCJURVhUIiwiREVDSU1BTCIsImRlZmluZSIsImRlZmF1bHQiLCJjbGFpbVNlcXVlbmNlIiwiZGVjb2RlZENsYWltIiwiZGVwdGgiLCJlZmZlY3RpdmVBbW91bnQiLCJoYXNTaWduYXR1cmUiLCJoZXgiLCJub3V0IiwidHhpZCIsInZhbGlkQXRIZWlnaHQiLCJ2YWx1ZVZlcnNpb24iLCJjbGFpbVR5cGUiLCJjZXJ0aWZpY2F0ZVZlcnNpb24iLCJrZXlUeXBlIiwicHVibGljS2V5IiwiZnJlZXplVGFibGVOYW1lIiwiYmVsb25nc1RvIiwiZm9yZWlnbktleSIsImFsbG93TnVsbCIsImZpbmRBbGwiLCJvcmRlciIsImdldExvbmdDaGFubmVsSWRGcm9tU2hvcnRDaGFubmVsSWQiLCIkbGlrZSIsImdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUiLCJ2YWxpZGF0ZUxvbmdDaGFubmVsSWQiLCJoYXNPbmUiLCJkZXRlcm1pbmVGaWxlRXh0ZW5zaW9uRnJvbUNvbnRlbnRUeXBlIiwiZGV0ZXJtaW5lVGh1bWJuYWlsIiwic3RvcmVkVGh1bWJuYWlsIiwicHJlcGFyZUNsYWltRGF0YSIsImNsYWltIiwiY2VydGlmaWNhdGVJZCIsImxpY2Vuc2VVcmwiLCJwcmV2aWV3IiwibWV0YWRhdGFWZXJzaW9uIiwic291cmNlIiwic291cmNlVHlwZSIsInNvdXJjZVZlcnNpb24iLCJzdHJlYW1WZXJzaW9uIiwiZ2V0U2hvcnRDbGFpbUlkRnJvbUxvbmdDbGFpbUlkIiwicmF3IiwiZ2V0TG9uZ0NsYWltSWRGcm9tU2hvcnRDbGFpbUlkIiwiZ2V0VG9wRnJlZUNsYWltSWRCeUNsYWltTmFtZSIsInZhbGlkYXRlTG9uZ0NsYWltSWQiLCJyZXNvbHZlQ2xhaW0iLCJjbGFpbUFycmF5IiwiZGVmYXVsdFZhbHVlIiwidHJlbmRpbmdFbGlnaWJsZSIsImhhc01hbnkiLCJnZXRSZWNlbnRDbGFpbXMiLCJsaW1pdCIsImFjdGlvbiIsImlwQWRkcmVzcyIsImJjcnlwdCIsInByb3RvdHlwZSIsImNvbXBhcmVQYXNzd29yZCIsImNvbXBhcmUiLCJjaGFuZ2VQYXNzd29yZCIsIm5ld1Bhc3N3b3JkIiwiZ2VuU2FsdCIsInNhbHRFcnJvciIsInNhbHQiLCJoYXNoIiwiaGFzaEVycm9yIiwiaG9vayIsInJldHVyblVzZXJBbmRDaGFubmVsSW5mbyIsInVzZXJJbnN0YW5jZSIsImdldENoYW5uZWwiLCJpc01hdGNoIiwibG9nSW4iLCJnZXQiLCJsb2dvdXQiLCJtdWx0aXBhcnQiLCJtdWx0aXBhcnRNaWRkbGV3YXJlIiwidXBsb2FkRGlyIiwiY2xhaW1OYW1lSXNBdmFpbGFibGUiLCJjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkiLCJlcnJvckhhbmRsZXJzIiwiYXV0aGVudGljYXRlVXNlciIsImF2YWlsYWJsZU5hbWUiLCJib2R5IiwiY2xhaW1zTGlzdCIsInJlc29sdmVSZXN1bHQiLCJmaWxlRGF0YSIsImZpbGVSZWNvcmQiLCJjb21wbGV0ZWQiLCJyZXNvbHZlZFVyaSIsImZpbGVzIiwiY2hhbm5lbFBhc3N3b3JkIiwidmFsaWRhdGVkQ2xhaW1OYW1lIiwidGh1bWJuYWlsUHVibGlzaFBhcmFtcyIsImxicnlUeCIsImNsYWltSW5mbyIsInB1Ymxpc2hIZWxwZXJzIiwiT3AiLCJwdWJsaXNoUmVzdWx0cyIsImNsYWltUmVjb3JkIiwidXBzZXJ0Q3JpdGVyaWEiLCJzZXRDbGFpbSIsInNldEZpbGUiLCJjbGFpbUFkZHJlc3NlcyIsImF0dHJpYnV0ZXMiLCJvciIsImF1dGhlbnRpY2F0ZUNoYW5uZWxDcmVkZW50aWFscyIsInVzZXJQYXNzd29yZCIsImNoYW5uZWxGaW5kUGFyYW1zIiwiQ0xBSU1TX1BFUl9QQUdFIiwiY2xhaW1zIiwidG90YWxQYWdlcyIsImRldGVybWluZVRvdGFsUGFnZXMiLCJwYWdpbmF0aW9uUGFnZSIsImdldFBhZ2VGcm9tUXVlcnkiLCJ2aWV3RGF0YSIsImV4dHJhY3RQYWdlRnJvbUNsYWltcyIsInByZXZpb3VzUGFnZSIsImRldGVybWluZVByZXZpb3VzUGFnZSIsImN1cnJlbnRQYWdlIiwibmV4dFBhZ2UiLCJkZXRlcm1pbmVOZXh0UGFnZSIsInRvdGFsUmVzdWx0cyIsImRldGVybWluZVRvdGFsQ2xhaW1zIiwicGFyc2VJbnQiLCJwYWdlTnVtYmVyIiwiY2xhaW1TdGFydEluZGV4IiwiY2xhaW1FbmRJbmRleCIsInBhZ2VPZkNsYWltcyIsInRvdGFsQ2xhaW1zIiwiZnVsbFBhZ2VzIiwiTWF0aCIsImZsb29yIiwicmVtYWluZGVyIiwiaGFuZGxlUGFnZVJlbmRlciIsInJlbmRlciIsImxheW91dCIsImluaXRpYWxTdGF0ZSIsImFzc2lnbiIsInB1Ymxpc2hJbkNoYW5uZWwiLCJzZWxlY3RlZENoYW5uZWwiLCJwdWJsaXNoU3VibWl0IiwiY2hhbm5lbExpc3QiLCJzaXRlQ29uZmlnIiwiZ29vZ2xlQW5hbHl0aWNzSWQiLCJIb21lUGFnZSIsIlNFTyIsInBhZ2VVcmkiLCJwYWdlVGl0bGUiLCJtZXRhVGFncyIsImNhbm9uaWNhbExpbmsiLCJyZWwiLCJocmVmIiwib2JqZWN0IiwiY3JlYXRlUGFnZVRpdGxlIiwiZGV0ZXJtaW5lT2dUaHVtYm5haWxDb250ZW50VHlwZSIsImZpbGVFeHQiLCJsYXN0SW5kZXhPZiIsImNyZWF0ZUJhc2ljTWV0YVRhZ3MiLCJwcm9wZXJ0eSIsImNvbnRlbnQiLCJjcmVhdGVDaGFubmVsTWV0YVRhZ3MiLCJjcmVhdGVBc3NldE1ldGFUYWdzIiwiZW1iZWRVcmwiLCJzaG93VXJsIiwib2dUaXRsZSIsIm9nRGVzY3JpcHRpb24iLCJvZ1RodW1ibmFpbENvbnRlbnRUeXBlIiwib2dUaHVtYm5haWwiLCJjcmVhdGVNZXRhVGFncyIsImNyZWF0ZUJhc2ljQ2Fub25pY2FsTGluayIsImNyZWF0ZUFzc2V0Q2Fub25pY2FsTGluayIsImNyZWF0ZUNoYW5uZWxDYW5vbmljYWxMaW5rIiwiY3JlYXRlQ2Fub25pY2FsTGluayIsIlZJRVciLCJMT0dPVVQiLCJOYXZCYXIiLCJjaGVja0ZvckxvZ2dlZEluVXNlciIsImxvZ291dFVzZXIiLCJoYW5kbGVTZWxlY3Rpb24iLCJjcmVkZW50aWFscyIsInRhcmdldCIsInNlbGVjdGVkT3B0aW9ucyIsIkxvZ28iLCJOYXZCYXJDaGFubmVsRHJvcGRvd24iLCJkZWZhdWx0U2VsZWN0aW9uIiwiUHVibGlzaFRvb2wiLCJEcm9wem9uZSIsImRyYWdPdmVyIiwibW91c2VPdmVyIiwiZGltUHJldmlldyIsImhhbmRsZURyb3AiLCJoYW5kbGVEcmFnT3ZlciIsImhhbmRsZURyYWdFbmQiLCJoYW5kbGVEcmFnRW50ZXIiLCJoYW5kbGVEcmFnTGVhdmUiLCJoYW5kbGVNb3VzZUVudGVyIiwiaGFuZGxlTW91c2VMZWF2ZSIsImhhbmRsZUNsaWNrIiwiaGFuZGxlRmlsZUlucHV0IiwiY2hvb3NlRmlsZSIsInByZXZlbnREZWZhdWx0IiwiZHQiLCJkYXRhVHJhbnNmZXIiLCJpdGVtcyIsImtpbmQiLCJkcm9wcGVkRmlsZSIsImdldEFzRmlsZSIsInJlbW92ZSIsImNsZWFyRGF0YSIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJjbGljayIsImZpbGVMaXN0IiwidmFsaWRhdGVGaWxlIiwiUHVibGlzaFByZXZpZXciLCJpbWdTb3VyY2UiLCJzZXRQcmV2aWV3SW1hZ2VTb3VyY2UiLCJuZXdQcm9wcyIsInNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlIiwicHJldmlld1JlYWRlciIsIkZpbGVSZWFkZXIiLCJyZWFkQXNEYXRhVVJMIiwib25sb2FkZW5kIiwiYm9vbCIsIlB1Ymxpc2hEZXRhaWxzIiwib25QdWJsaXNoU3VibWl0Iiwib25NZXRhZGF0YUNoYW5nZSIsIlB1Ymxpc2hUaXRsZUlucHV0IiwiaGFuZGxlSW5wdXQiLCJlIiwibG9nZ2VkSW5DaGFubmVsTmFtZSIsImxvZ2dlZEluQ2hhbm5lbFNob3J0SWQiLCJ1cmxFcnJvciIsIm9uQ2xhaW1DaGFuZ2UiLCJvblVybEVycm9yIiwiUHVibGlzaFVybElucHV0Iiwic2V0Q2xhaW1OYW1lIiwidmFsaWRhdGVDbGFpbSIsImNsZWFuc2VJbnB1dCIsImlucHV0IiwiZmlsZU5hbWVXaXRob3V0RW5kaW5nIiwiY2xlYW5DbGFpbU5hbWUiLCJVcmxNaWRkbGUiLCJkYXRhVVJJdG9CbG9iIiwiZGF0YVVSSSIsImJ5dGVTdHJpbmciLCJhdG9iIiwic3BsaXQiLCJtaW1lU3RyaW5nIiwiaWEiLCJVaW50OEFycmF5IiwiY2hhckNvZGVBdCIsIkJsb2IiLCJQdWJsaXNoVGh1bWJuYWlsSW5wdXQiLCJ2aWRlb1NvdXJjZSIsInNsaWRlck1pblJhbmdlIiwic2xpZGVyTWF4UmFuZ2UiLCJzbGlkZXJWYWx1ZSIsImhhbmRsZVZpZGVvTG9hZGVkRGF0YSIsImhhbmRsZVNsaWRlckNoYW5nZSIsImNyZWF0ZVRodW1ibmFpbCIsInNldFZpZGVvU291cmNlIiwibmV4dFByb3BzIiwiZGF0YVVyaSIsImJsb2IiLCJVUkwiLCJjcmVhdGVPYmplY3RVUkwiLCJ0b3RhbE1pbnV0ZXMiLCJ0b3RhbFNlY29uZHMiLCJ2aWRlbyIsImN1cnJlbnRUaW1lIiwiY2FudmFzIiwiY3JlYXRlRWxlbWVudCIsIndpZHRoIiwidmlkZW9XaWR0aCIsInZpZGVvSGVpZ2h0IiwiZ2V0Q29udGV4dCIsImRyYXdJbWFnZSIsImRhdGFVcmwiLCJ0b0RhdGFVUkwiLCJzbmFwc2hvdCIsImRpc3BsYXkiLCJvblRvZ2dsZU1ldGFkYXRhSW5wdXRzIiwiUHVibGlzaE1ldGFkYXRhSW5wdXRzIiwidG9nZ2xlU2hvd0lucHV0cyIsImhhbmRsZVNlbGVjdCIsImNoZWNrZWQiLCJzZWxlY3RlZE9wdGlvbiIsIm1heEhlaWdodCIsIkV4cGFuZGluZ1RleHRhcmVhIiwiX2hhbmRsZUNoYW5nZSIsImFkanVzdFRleHRhcmVhIiwib25DaGFuZ2UiLCJlbCIsInN0eWxlIiwic2Nyb2xsSGVpZ2h0IiwicmVzdCIsIngiLCJmdW5jIiwiY2hhbm5lbEVycm9yIiwib25QdWJsaXNoSW5DaGFubmVsQ2hhbmdlIiwib25DaGFubmVsU2VsZWN0Iiwic3RhdGVzIiwiQ2hhbm5lbFNlbGVjdCIsInRvZ2dsZUFub255bW91c1B1Ymxpc2giLCJDaGFubmVsTG9naW5Gb3JtIiwibG9naW5Ub0NoYW5uZWwiLCJIZWFkZXJzIiwiQ2hhbm5lbENyZWF0ZUZvcm0iLCJoYW5kbGVDaGFubmVsSW5wdXQiLCJjbGVhbnNlQ2hhbm5lbElucHV0IiwidXBkYXRlSXNDaGFubmVsQXZhaWxhYmxlIiwiY2hhbm5lbFdpdGhBdFN5bWJvbCIsImNoZWNrSXNQYXNzd29yZFByb3ZpZGVkIiwiY2hlY2tJc0NoYW5uZWxBdmFpbGFibGUiLCJtYWtlUHVibGlzaENoYW5uZWxSZXF1ZXN0IiwiQWN0aXZlU3RhdHVzQmFyIiwiSW5hY3RpdmVTdGF0dXNCYXIiLCJwdWJsaXNoU3RhdGVzIiwiUHVibGlzaFN0YXR1cyIsIkxPQURfU1RBUlQiLCJMT0FESU5HIiwiUFVCTElTSElORyIsIlNVQ0NFU1MiLCJGQUlMRUQiLCJQdWJsaXNoRGlzYWJsZWRNZXNzYWdlIiwiQWJvdXRQYWdlIiwiTG9naW5QYWdlIiwiU2hvd1BhZ2UiLCJtYXRjaCIsIlNob3dMaXRlIiwiQXNzZXREaXNwbGF5IiwiU2hvd0Fzc2V0RGV0YWlscyIsIkFzc2V0VGl0bGUiLCJBc3NldEluZm8iLCJjb3B5VG9DbGlwYm9hcmQiLCJlbGVtZW50VG9Db3B5IiwiZGF0YXNldCIsImVsZW1lbnR0b2NvcHkiLCJzZWxlY3QiLCJleGVjQ29tbWFuZCIsInByZXZpb3VzUmVxdWVzdCIsIlNob3dDaGFubmVsIiwiQ2hhbm5lbENsYWltc0Rpc3BsYXkiLCJzaG93TmV4dFJlc3VsdHNQYWdlIiwic2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UiLCJzaG93TmV3UGFnZSIsImRlZmF1bHRzIiwiQXNzZXRQcmV2aWV3IiwiZGlyZWN0U291cmNlTGluayIsInNob3dVcmxMaW5rIiwiRm91ck9oRm9yUGFnZSIsImRldGVybWluZVJlc3BvbnNlVHlwZSIsImZsaXBDbGFpbU5hbWVBbmRJZEZvckJhY2t3YXJkc0NvbXBhdGliaWxpdHkiLCJsb2dSZXF1ZXN0RGF0YSIsImdldENsYWltSWRBbmRTZXJ2ZUFzc2V0IiwibGJyeVVyaSIsImhhbmRsZVNob3dSZW5kZXIiLCJTRVJWRSIsImhhc0ZpbGVFeHRlbnNpb24iLCJwYXJzZU1vZGlmaWVyIiwicmVzcG9uc2VUeXBlIiwicGFyc2VDbGFpbSIsImlzQ2hhbm5lbCIsInBhcnNlSWRlbnRpZmllciIsImlkZW50aWZpZXIiLCJTSE9XIiwiY2xpZW50QWNjZXB0c0h0bWwiLCJhY2NlcHQiLCJyZXF1ZXN0SXNGcm9tQnJvd3NlciIsImNsaWVudFdhbnRzQXNzZXQiLCJyYW5nZSIsImltYWdlSXNXYW50ZWQiLCJ2aWRlb0lzV2FudGVkIiwiaXNWYWxpZENsYWltSWQiLCJpc1ZhbGlkU2hvcnRJZCIsImlzVmFsaWRTaG9ydElkT3JDbGFpbUlkIiwic2VydmVBc3NldFRvQ2xpZW50Iiwic2VuZEZpbGVPcHRpb25zIiwic2VuZEZpbGUiLCJmdWxsQ2xhaW1JZCIsInRlbXBOYW1lIiwiUkVHRVhQX0lOVkFMSURfQ0xBSU0iLCJSRUdFWFBfSU5WQUxJRF9DSEFOTkVMIiwiUkVHRVhQX0FERFJFU1MiLCJDSEFOTkVMX0NIQVIiLCJjb21wb25lbnRzUmVnZXgiLCJSZWdFeHAiLCJwcm90byIsIm1vZGlmaWVyU2VwZXJhdG9yIiwic3RhcnRzV2l0aCIsIm5hbWVCYWRDaGFycyIsImpvaW4iLCJyZXR1cm5TYWdhV2l0aFBhcmFtcyIsInNhZ2EiLCJzYWdhTWlkZGxld2FyZSIsIm1pZGRsZXdhcmUiLCJydW4iLCJoYW5kbGVTaG93UGFnZVVyaSIsIndhdGNoSGFuZGxlU2hvd1BhZ2VVcmkiLCJwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSIsInBhcnNlQW5kVXBkYXRlQ2xhaW1Pbmx5IiwibmV3QXNzZXRSZXF1ZXN0Iiwid2F0Y2hOZXdBc3NldFJlcXVlc3QiLCJnZXRTaG9ydElkIiwiZ2V0Q2xhaW1EYXRhIiwibmV3Q2hhbm5lbFJlcXVlc3QiLCJ3YXRjaE5ld0NoYW5uZWxSZXF1ZXN0Iiwid2F0Y2hVcGRhdGVDaGFubmVsQ2xhaW1zIiwiZ2V0TmV3Q2xhaW1zQW5kVXBkYXRlQ2hhbm5lbCIsImV4dGVuc2lvblNlcGVyYXRvciJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUNBQTJCLDBCQUEwQixFQUFFO0FBQ3ZELHlDQUFpQyxlQUFlO0FBQ2hEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhEQUFzRCwrREFBK0Q7O0FBRXJIO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7OztBQzdEQSxrQzs7Ozs7O0FDQUEsd0M7Ozs7OztBQ0FBLG9DOzs7Ozs7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QUQsRUFBTS9CLEdBQU4sRUFBYztBQUN6QjtBQUNBOFIscUJBQWlCL1AsR0FBakIsRUFBc0IvQixHQUF0QjtBQUNELEdBSEQ7QUFJRCxDQU5ELEMiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCIvXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gNDUpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHdlYnBhY2svYm9vdHN0cmFwIGZkYmJiYjI3MDM0NDk4Y2QyMDQ3IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3RcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdFwiXG4vLyBtb2R1bGUgaWQgPSAwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LXJlZHV4XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVhY3QtcmVkdXhcIlxuLy8gbW9kdWxlIGlkID0gMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ3aW5zdG9uXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwid2luc3RvblwiXG4vLyBtb2R1bGUgaWQgPSAyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LXJvdXRlci1kb21cIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdC1yb3V0ZXItZG9tXCJcbi8vIG1vZHVsZSBpZCA9IDNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMnO1xuXG4vLyBleHBvcnQgYWN0aW9uIGNyZWF0b3JzXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0RmlsZSAoZmlsZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuRklMRV9TRUxFQ1RFRCxcbiAgICBkYXRhOiBmaWxlLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyRmlsZSAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5GSUxFX0NMRUFSLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZU1ldGFkYXRhIChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuTUVUQURBVEFfVVBEQVRFLFxuICAgIGRhdGE6IHtcbiAgICAgIG5hbWUsXG4gICAgICB2YWx1ZSxcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUNsYWltICh2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0xBSU1fVVBEQVRFLFxuICAgIGRhdGE6IHZhbHVlLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldFB1Ymxpc2hJbkNoYW5uZWwgKGNoYW5uZWwpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlNFVF9QVUJMSVNIX0lOX0NIQU5ORUwsXG4gICAgY2hhbm5lbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVQdWJsaXNoU3RhdHVzIChzdGF0dXMsIG1lc3NhZ2UpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlBVQkxJU0hfU1RBVFVTX1VQREFURSxcbiAgICBkYXRhOiB7XG4gICAgICBzdGF0dXMsXG4gICAgICBtZXNzYWdlLFxuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlRXJyb3IgKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5FUlJPUl9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgbmFtZSxcbiAgICAgIHZhbHVlLFxuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU2VsZWN0ZWRDaGFubmVsIChjaGFubmVsTmFtZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuU0VMRUNURURfQ0hBTk5FTF9VUERBVEUsXG4gICAgZGF0YTogY2hhbm5lbE5hbWUsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdG9nZ2xlTWV0YWRhdGFJbnB1dHMgKHNob3dNZXRhZGF0YUlucHV0cykge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuVE9HR0xFX01FVEFEQVRBX0lOUFVUUyxcbiAgICBkYXRhOiBzaG93TWV0YWRhdGFJbnB1dHMsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gb25OZXdUaHVtYm5haWwgKGZpbGUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlRIVU1CTkFJTF9ORVcsXG4gICAgZGF0YTogZmlsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGFydFB1Ymxpc2ggKGhpc3RvcnkpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlBVQkxJU0hfU1RBUlQsXG4gICAgZGF0YTogeyBoaXN0b3J5IH0sXG4gIH07XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvYWN0aW9ucy9wdWJsaXNoLmpzIiwiZnVuY3Rpb24gU2l0ZUNvbmZpZyAoKSB7XG4gIHRoaXMuYW5hbHl0aWNzID0ge1xuICAgIGdvb2dsZUlkOiAnZGVmYXVsdCcsXG4gIH07XG4gIHRoaXMuYXNzZXREZWZhdWx0cyA9IHtcbiAgICBkZXNjcmlwdGlvbjogJ0FuIGFzc2V0IHB1Ymxpc2hlZCBvbiBTcGVlLmNoJyxcbiAgICB0aHVtYm5haWwgIDogJ2h0dHBzOi8vc3BlZS5jaC9hc3NldHMvaW1nL3ZpZGVvX3RodW1iX2RlZmF1bHQucG5nJyxcbiAgICB0aXRsZSAgICAgIDogJ1NwZWUuY2gnLFxuICB9O1xuICB0aGlzLmF1dGggPSB7XG4gICAgc2Vzc2lvbktleTogJ2RlZmF1bHQnLFxuICB9O1xuICB0aGlzLmRldGFpbHMgPSB7XG4gICAgZGVzY3JpcHRpb246ICdPcGVuLXNvdXJjZSwgZGVjZW50cmFsaXplZCBpbWFnZSBhbmQgdmlkZW8gc2hhcmluZy4nLFxuICAgIGhvc3QgICAgICAgOiAnZGVmYXVsdCcsXG4gICAgcG9ydCAgICAgICA6IDMwMDAsXG4gICAgdGl0bGUgICAgICA6ICdTcGVlLmNoJyxcbiAgICB0d2l0dGVyICAgIDogJ0BzcGVlX2NoJyxcbiAgfTtcbiAgdGhpcy5wdWJsaXNoaW5nID0ge1xuICAgIGFkZGl0aW9uYWxDbGFpbUFkZHJlc3NlczogW10sXG4gICAgZGlzYWJsZWQgICAgICAgICAgICAgICAgOiBmYWxzZSxcbiAgICBkaXNhYmxlZE1lc3NhZ2UgICAgICAgICA6ICdQbGVhc2UgY2hlY2sgYmFjayBzb29uLicsXG4gICAgcHJpbWFyeUNsYWltQWRkcmVzcyAgICAgOiAnZGVmYXVsdCcsXG4gICAgdGh1bWJuYWlsQ2hhbm5lbCAgICAgICAgOiAnZGVmYXVsdCcsXG4gICAgdGh1bWJuYWlsQ2hhbm5lbElkICAgICAgOiAnZGVmYXVsdCcsXG4gICAgdXBsb2FkRGlyZWN0b3J5ICAgICAgICAgOiAnL2hvbWUvbGJyeS9VcGxvYWRzJyxcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNpdGVDb25maWcoKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NvbmZpZy9zaXRlQ29uZmlnLmpzIiwiY29uc3QgU2VxdWVsaXplID0gcmVxdWlyZSgnc2VxdWVsaXplJyk7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbmNvbnNvbGUubG9nKCdleHBvcnRpbmcgc2VxdWVsaXplIG1vZGVscycpO1xuY29uc3QgeyBkYXRhYmFzZSwgdXNlcm5hbWUsIHBhc3N3b3JkIH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvbXlzcWxDb25maWcnKTtcbmNvbnN0IGRiID0ge307XG4vLyBzZXQgc2VxdWVsaXplIG9wdGlvbnNcbmNvbnN0IHNlcXVlbGl6ZSA9IG5ldyBTZXF1ZWxpemUoZGF0YWJhc2UsIHVzZXJuYW1lLCBwYXNzd29yZCwge1xuICBob3N0ICAgICAgICAgIDogJ2xvY2FsaG9zdCcsXG4gIGRpYWxlY3QgICAgICAgOiAnbXlzcWwnLFxuICBkaWFsZWN0T3B0aW9uczoge2RlY2ltYWxOdW1iZXJzOiB0cnVlfSwgLy8gZml4IHRvIGVuc3VyZSBERUNJTUFMIHdpbGwgbm90IGJlIHN0b3JlZCBhcyBhIHN0cmluZ1xuICBsb2dnaW5nICAgICAgIDogZmFsc2UsXG4gIHBvb2wgICAgICAgICAgOiB7XG4gICAgbWF4ICAgIDogNSxcbiAgICBtaW4gICAgOiAwLFxuICAgIGlkbGUgICA6IDEwMDAwLFxuICAgIGFjcXVpcmU6IDEwMDAwLFxuICB9LFxufSk7XG5cbi8vIGVzdGFibGlzaCBteXNxbCBjb25uZWN0aW9uXG5zZXF1ZWxpemVcbiAgLmF1dGhlbnRpY2F0ZSgpXG4gIC50aGVuKCgpID0+IHtcbiAgICBsb2dnZXIuaW5mbygnU2VxdWVsaXplIGhhcyBlc3RhYmxpc2hlZCBteXNxbCBjb25uZWN0aW9uIHN1Y2Nlc3NmdWxseS4nKTtcbiAgfSlcbiAgLmNhdGNoKGVyciA9PiB7XG4gICAgbG9nZ2VyLmVycm9yKCdTZXF1ZWxpemUgd2FzIHVuYWJsZSB0byBjb25uZWN0IHRvIHRoZSBkYXRhYmFzZTonLCBlcnIpO1xuICB9KTtcblxuLy8gbWFudWFsbHkgYWRkIGVhY2ggbW9kZWwgdG8gdGhlIGRiIG9iamVjdFxuY29uc3QgQ2VydGlmaWNhdGUgPSByZXF1aXJlKCcuL2NlcnRpZmljYXRlLmpzJyk7XG5jb25zdCBDaGFubmVsID0gcmVxdWlyZSgnLi9jaGFubmVsLmpzJyk7XG5jb25zdCBDbGFpbSA9IHJlcXVpcmUoJy4vY2xhaW0uanMnKTtcbmNvbnN0IEZpbGUgPSByZXF1aXJlKCcuL2ZpbGUuanMnKTtcbmNvbnN0IFJlcXVlc3QgPSByZXF1aXJlKCcuL3JlcXVlc3QuanMnKTtcbmNvbnN0IFVzZXIgPSByZXF1aXJlKCcuL3VzZXIuanMnKTtcbmRiWydDZXJ0aWZpY2F0ZSddID0gc2VxdWVsaXplLmltcG9ydCgnQ2VydGlmaWNhdGUnLCBDZXJ0aWZpY2F0ZSk7XG5kYlsnQ2hhbm5lbCddID0gc2VxdWVsaXplLmltcG9ydCgnQ2hhbm5lbCcsIENoYW5uZWwpO1xuZGJbJ0NsYWltJ10gPSBzZXF1ZWxpemUuaW1wb3J0KCdDbGFpbScsIENsYWltKTtcbmRiWydGaWxlJ10gPSBzZXF1ZWxpemUuaW1wb3J0KCdGaWxlJywgRmlsZSk7XG5kYlsnUmVxdWVzdCddID0gc2VxdWVsaXplLmltcG9ydCgnUmVxdWVzdCcsIFJlcXVlc3QpO1xuZGJbJ1VzZXInXSA9IHNlcXVlbGl6ZS5pbXBvcnQoJ1VzZXInLCBVc2VyKTtcblxuLy8gcnVuIG1vZGVsLmFzc29jaWF0aW9uIGZvciBlYWNoIG1vZGVsIGluIHRoZSBkYiBvYmplY3QgdGhhdCBoYXMgYW4gYXNzb2NpYXRpb25cbk9iamVjdC5rZXlzKGRiKS5mb3JFYWNoKG1vZGVsTmFtZSA9PiB7XG4gIGlmIChkYlttb2RlbE5hbWVdLmFzc29jaWF0ZSkge1xuICAgIGxvZ2dlci5pbmZvKCdBc3NvY2lhdGluZyBtb2RlbDonLCBtb2RlbE5hbWUpO1xuICAgIGRiW21vZGVsTmFtZV0uYXNzb2NpYXRlKGRiKTtcbiAgfVxufSk7XG5cbmRiLnNlcXVlbGl6ZSA9IHNlcXVlbGl6ZTtcbmRiLlNlcXVlbGl6ZSA9IFNlcXVlbGl6ZTtcblxuLy8gYWRkIGFuICd1cHNlcnQnIG1ldGhvZCB0byB0aGUgZGIgb2JqZWN0XG5kYi51cHNlcnQgPSAoTW9kZWwsIHZhbHVlcywgY29uZGl0aW9uLCB0YWJsZU5hbWUpID0+IHtcbiAgcmV0dXJuIE1vZGVsXG4gICAgLmZpbmRPbmUoe1xuICAgICAgd2hlcmU6IGNvbmRpdGlvbixcbiAgICB9KVxuICAgIC50aGVuKG9iaiA9PiB7XG4gICAgICBpZiAob2JqKSB7ICAvLyB1cGRhdGVcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGB1cGRhdGluZyByZWNvcmQgaW4gZGIuJHt0YWJsZU5hbWV9YCk7XG4gICAgICAgIHJldHVybiBvYmoudXBkYXRlKHZhbHVlcyk7XG4gICAgICB9IGVsc2UgeyAgLy8gaW5zZXJ0XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY3JlYXRpbmcgcmVjb3JkIGluIGRiLiR7dGFibGVOYW1lfWApO1xuICAgICAgICByZXR1cm4gTW9kZWwuY3JlYXRlKHZhbHVlcyk7XG4gICAgICB9XG4gICAgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYCR7dGFibGVOYW1lfS51cHNlcnQgZXJyb3JgLCBlcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZGI7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2luZGV4LmpzIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbCB9IGZyb20gJ2FjdGlvbnMvY2hhbm5lbCc7XG5pbXBvcnQge3VwZGF0ZVNlbGVjdGVkQ2hhbm5lbH0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IGNoYW5uZWwsIHNpdGUgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGNoYW5uZWxOYW1lICAgOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5uYW1lLFxuICAgIGNoYW5uZWxTaG9ydElkOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5zaG9ydElkLFxuICAgIGNoYW5uZWxMb25nSWQgOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5sb25nSWQsXG4gICAgc2l0ZURlc2NyaXB0aW9uOiBzaXRlLmRlc2NyaXB0aW9uLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2hhbm5lbExvZ2luOiAobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVTZWxlY3RlZENoYW5uZWwobmFtZSkpO1xuICAgIH0sXG4gICAgb25DaGFubmVsTG9nb3V0OiAoKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobnVsbCwgbnVsbCwgbnVsbCkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL05hdkJhci9pbmRleC5qcyIsImltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL3Nob3dfYWN0aW9uX3R5cGVzJztcblxuaW1wb3J0IHsgQ0hBTk5FTCwgQVNTRVRfTElURSwgQVNTRVRfREVUQUlMUyB9IGZyb20gJ2NvbnN0YW50cy9zaG93X3JlcXVlc3RfdHlwZXMnO1xuXG4vLyBiYXNpYyByZXF1ZXN0IHBhcnNpbmdcbmV4cG9ydCBmdW5jdGlvbiBvbkhhbmRsZVNob3dQYWdlVXJpIChwYXJhbXMpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkhBTkRMRV9TSE9XX1VSSSxcbiAgICBkYXRhOiBwYXJhbXMsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gb25SZXF1ZXN0RXJyb3IgKGVycm9yKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5SRVFVRVNUX0VSUk9SLFxuICAgIGRhdGE6IGVycm9yLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uTmV3Q2hhbm5lbFJlcXVlc3QgKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQpIHtcbiAgY29uc3QgcmVxdWVzdFR5cGUgPSBDSEFOTkVMO1xuICBjb25zdCByZXF1ZXN0SWQgPSBgY3IjJHtjaGFubmVsTmFtZX0jJHtjaGFubmVsSWR9YDtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkNIQU5ORUxfUkVRVUVTVF9ORVcsXG4gICAgZGF0YTogeyByZXF1ZXN0VHlwZSwgcmVxdWVzdElkLCBjaGFubmVsTmFtZSwgY2hhbm5lbElkIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gb25OZXdBc3NldFJlcXVlc3QgKG5hbWUsIGlkLCBjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBleHRlbnNpb24pIHtcbiAgY29uc3QgcmVxdWVzdFR5cGUgPSBleHRlbnNpb24gPyBBU1NFVF9MSVRFIDogQVNTRVRfREVUQUlMUztcbiAgY29uc3QgcmVxdWVzdElkID0gYGFyIyR7bmFtZX0jJHtpZH0jJHtjaGFubmVsTmFtZX0jJHtjaGFubmVsSWR9YDtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkFTU0VUX1JFUVVFU1RfTkVXLFxuICAgIGRhdGE6IHtcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgcmVxdWVzdElkLFxuICAgICAgbmFtZSxcbiAgICAgIG1vZGlmaWVyOiB7XG4gICAgICAgIGlkLFxuICAgICAgICBjaGFubmVsOiB7XG4gICAgICAgICAgbmFtZTogY2hhbm5lbE5hbWUsXG4gICAgICAgICAgaWQgIDogY2hhbm5lbElkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uUmVxdWVzdFVwZGF0ZSAocmVxdWVzdFR5cGUsIHJlcXVlc3RJZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuUkVRVUVTVF9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgcmVxdWVzdFR5cGUsXG4gICAgICByZXF1ZXN0SWQsXG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdCAoaWQsIGVycm9yLCBrZXkpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlJFUVVFU1RfTElTVF9BREQsXG4gICAgZGF0YTogeyBpZCwgZXJyb3IsIGtleSB9LFxuICB9O1xufTtcblxuLy8gYXNzZXQgYWN0aW9uc1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkQXNzZXRUb0Fzc2V0TGlzdCAoaWQsIGVycm9yLCBuYW1lLCBjbGFpbUlkLCBzaG9ydElkLCBjbGFpbURhdGEpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkFTU0VUX0FERCxcbiAgICBkYXRhOiB7IGlkLCBlcnJvciwgbmFtZSwgY2xhaW1JZCwgc2hvcnRJZCwgY2xhaW1EYXRhIH0sXG4gIH07XG59XG5cbi8vIGNoYW5uZWwgYWN0aW9uc1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkTmV3Q2hhbm5lbFRvQ2hhbm5lbExpc3QgKGlkLCBuYW1lLCBzaG9ydElkLCBsb25nSWQsIGNsYWltc0RhdGEpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkNIQU5ORUxfQURELFxuICAgIGRhdGE6IHsgaWQsIG5hbWUsIHNob3J0SWQsIGxvbmdJZCwgY2xhaW1zRGF0YSB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uVXBkYXRlQ2hhbm5lbENsYWltcyAoY2hhbm5lbEtleSwgbmFtZSwgbG9uZ0lkLCBwYWdlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5DSEFOTkVMX0NMQUlNU19VUERBVEVfQVNZTkMsXG4gICAgZGF0YToge2NoYW5uZWxLZXksIG5hbWUsIGxvbmdJZCwgcGFnZX0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQ2hhbm5lbENsYWltcyAoY2hhbm5lbExpc3RJZCwgY2xhaW1zRGF0YSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MsXG4gICAgZGF0YToge2NoYW5uZWxMaXN0SWQsIGNsYWltc0RhdGF9LFxuICB9O1xufTtcblxuLy8gZGlzcGxheSBhIGZpbGVcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbGVSZXF1ZXN0ZWQgKG5hbWUsIGNsYWltSWQpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkZJTEVfUkVRVUVTVEVELFxuICAgIGRhdGE6IHsgbmFtZSwgY2xhaW1JZCB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUZpbGVBdmFpbGFiaWxpdHkgKHN0YXR1cykge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuRklMRV9BVkFJTEFCSUxJVFlfVVBEQVRFLFxuICAgIGRhdGE6IHN0YXR1cyxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVEaXNwbGF5QXNzZXRFcnJvciAoZXJyb3IpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkRJU1BMQVlfQVNTRVRfRVJST1IsXG4gICAgZGF0YTogZXJyb3IsXG4gIH07XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2FjdGlvbnMvc2hvdy5qcyIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaXRlIH0pID0+IHtcbiAgY29uc3QgeyBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwsIGRlc2NyaXB0aW9uOiBzaXRlRGVzY3JpcHRpb24sIGhvc3Q6IHNpdGVIb3N0LCB0aXRsZTogc2l0ZVRpdGxlLCB0d2l0dGVyOiBzaXRlVHdpdHRlciB9ID0gc2l0ZTtcbiAgcmV0dXJuIHtcbiAgICBkZWZhdWx0RGVzY3JpcHRpb24sXG4gICAgZGVmYXVsdFRodW1ibmFpbCxcbiAgICBzaXRlRGVzY3JpcHRpb24sXG4gICAgc2l0ZUhvc3QsXG4gICAgc2l0ZVRpdGxlLFxuICAgIHNpdGVUd2l0dGVyLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvU0VPL2luZGV4LmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicHJvcC10eXBlc1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInByb3AtdHlwZXNcIlxuLy8gbW9kdWxlIGlkID0gMTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0ICdjcm9zcy1mZXRjaC9wb2x5ZmlsbCc7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBKU09OIHJldHVybmVkIGJ5IGEgbmV0d29yayByZXF1ZXN0XG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSByZXNwb25zZSBBIHJlc3BvbnNlIGZyb20gYSBuZXR3b3JrIHJlcXVlc3RcbiAqXG4gKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgIFRoZSBwYXJzZWQgSlNPTiBmcm9tIHRoZSByZXF1ZXN0XG4gKi9cbmZ1bmN0aW9uIHBhcnNlSlNPTiAocmVzcG9uc2UpIHtcbiAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA0IHx8IHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA1KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbn1cblxuLyoqXG4gKiBQYXJzZXMgdGhlIHN0YXR1cyByZXR1cm5lZCBieSBhIG5ldHdvcmsgcmVxdWVzdFxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gcmVzcG9uc2UgICBBIHJlc3BvbnNlIGZyb20gYSBuZXR3b3JrIHJlcXVlc3RcbiAqIEBwYXJhbSAge29iamVjdH0gcmVzcG9uc2UgICBUaGUgcGFyc2VkIEpTT04gZnJvbSB0aGUgbmV0d29yayByZXF1ZXN0XG4gKlxuICogQHJldHVybiB7b2JqZWN0IHwgdW5kZWZpbmVkfSBSZXR1cm5zIG9iamVjdCB3aXRoIHN0YXR1cyBhbmQgc3RhdHVzVGV4dCwgb3IgdW5kZWZpbmVkXG4gKi9cbmZ1bmN0aW9uIGNoZWNrU3RhdHVzIChyZXNwb25zZSwganNvblJlc3BvbnNlKSB7XG4gIGlmIChyZXNwb25zZS5zdGF0dXMgPj0gMjAwICYmIHJlc3BvbnNlLnN0YXR1cyA8IDMwMCkge1xuICAgIHJldHVybiBqc29uUmVzcG9uc2U7XG4gIH1cbiAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoanNvblJlc3BvbnNlLm1lc3NhZ2UpO1xuICBlcnJvci5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICB0aHJvdyBlcnJvcjtcbn1cblxuLyoqXG4gKiBSZXF1ZXN0cyBhIFVSTCwgcmV0dXJuaW5nIGEgcHJvbWlzZVxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gdXJsICAgICAgIFRoZSBVUkwgd2Ugd2FudCB0byByZXF1ZXN0XG4gKiBAcGFyYW0gIHtvYmplY3R9IFtvcHRpb25zXSBUaGUgb3B0aW9ucyB3ZSB3YW50IHRvIHBhc3MgdG8gXCJmZXRjaFwiXG4gKlxuICogQHJldHVybiB7b2JqZWN0fSAgICAgICAgICAgVGhlIHJlc3BvbnNlIGRhdGFcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZXF1ZXN0ICh1cmwsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGZldGNoKHVybCwgb3B0aW9ucylcbiAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3Jlc3BvbnNlLCBwYXJzZUpTT04ocmVzcG9uc2UpXSk7XG4gICAgfSlcbiAgICAudGhlbigoW3Jlc3BvbnNlLCBqc29uUmVzcG9uc2VdKSA9PiB7XG4gICAgICByZXR1cm4gY2hlY2tTdGF0dXMocmVzcG9uc2UsIGpzb25SZXNwb25zZSk7XG4gICAgfSk7XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvcmVxdWVzdC5qcyIsIi8vIHJlcXVlc3QgYWN0aW9uc1xuZXhwb3J0IGNvbnN0IEhBTkRMRV9TSE9XX1VSSSA9ICdIQU5ETEVfU0hPV19VUkknO1xuZXhwb3J0IGNvbnN0IFJFUVVFU1RfRVJST1IgPSAnUkVRVUVTVF9FUlJPUic7XG5leHBvcnQgY29uc3QgUkVRVUVTVF9VUERBVEUgPSAnUkVRVUVTVF9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IEFTU0VUX1JFUVVFU1RfTkVXID0gJ0FTU0VUX1JFUVVFU1RfTkVXJztcbmV4cG9ydCBjb25zdCBDSEFOTkVMX1JFUVVFU1RfTkVXID0gJ0NIQU5ORUxfUkVRVUVTVF9ORVcnO1xuZXhwb3J0IGNvbnN0IFJFUVVFU1RfTElTVF9BREQgPSAnUkVRVUVTVF9MSVNUX0FERCc7XG5cbi8vIGFzc2V0IGFjdGlvbnNcbmV4cG9ydCBjb25zdCBBU1NFVF9BREQgPSBgQVNTRVRfQUREYDtcblxuLy8gY2hhbm5lbCBhY3Rpb25zXG5leHBvcnQgY29uc3QgQ0hBTk5FTF9BREQgPSAnQ0hBTk5FTF9BREQnO1xuXG5leHBvcnQgY29uc3QgQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DID0gJ0NIQU5ORUxfQ0xBSU1TX1VQREFURV9BU1lOQyc7XG5leHBvcnQgY29uc3QgQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MgPSAnQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MnO1xuXG4vLyBhc3NldC9maWxlIGRpc3BsYXkgYWN0aW9uc1xuZXhwb3J0IGNvbnN0IEZJTEVfUkVRVUVTVEVEID0gJ0ZJTEVfUkVRVUVTVEVEJztcbmV4cG9ydCBjb25zdCBGSUxFX0FWQUlMQUJJTElUWV9VUERBVEUgPSAnRklMRV9BVkFJTEFCSUxJVFlfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBESVNQTEFZX0FTU0VUX0VSUk9SID0gJ0RJU1BMQVlfQVNTRVRfRVJST1InO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcy5qcyIsImV4cG9ydCBjb25zdCBzZWxlY3RBc3NldCA9IChzaG93KSA9PiB7XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3Nob3cucmVxdWVzdC5pZF07XG4gIGNvbnN0IGFzc2V0S2V5ID0gcmVxdWVzdC5rZXk7XG4gIHJldHVybiBzaG93LmFzc2V0TGlzdFthc3NldEtleV07XG59O1xuXG5leHBvcnQgY29uc3Qgc2VsZWN0U2hvd1N0YXRlID0gKHN0YXRlKSA9PiB7XG4gIHJldHVybiBzdGF0ZS5zaG93O1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9zZWxlY3RvcnMvc2hvdy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LWhlbG1ldFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWhlbG1ldFwiXG4vLyBtb2R1bGUgaWQgPSAxNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWR1eC1zYWdhL2VmZmVjdHNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWR1eC1zYWdhL2VmZmVjdHNcIlxuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgYXhpb3MgPSByZXF1aXJlKCdheGlvcycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyBhcGk6IHsgYXBpSG9zdCwgYXBpUG9ydCB9IH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvbGJyeUNvbmZpZy5qcycpO1xuY29uc3QgbGJyeUFwaVVyaSA9ICdodHRwOi8vJyArIGFwaUhvc3QgKyAnOicgKyBhcGlQb3J0O1xuY29uc3QgeyBjaG9vc2VHYUxicnluZXRQdWJsaXNoTGFiZWwsIHNlbmRHQVRpbWluZ0V2ZW50IH0gPSByZXF1aXJlKCcuL2dvb2dsZUFuYWx5dGljcy5qcycpO1xuXG5jb25zdCBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UgPSAoeyBkYXRhIH0sIHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICBsb2dnZXIuZGVidWcoJ2xicnkgYXBpIGRhdGE6JywgZGF0YSk7XG4gIGlmIChkYXRhLnJlc3VsdCkge1xuICAgIC8vIGNoZWNrIGZvciBhbiBlcnJvclxuICAgIGlmIChkYXRhLnJlc3VsdC5lcnJvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdMYnJ5bmV0IGFwaSBlcnJvcjonLCBkYXRhLnJlc3VsdC5lcnJvcik7XG4gICAgICByZWplY3QobmV3IEVycm9yKGRhdGEucmVzdWx0LmVycm9yKSk7XG4gICAgICByZXR1cm47XG4gICAgfTtcbiAgICByZXNvbHZlKGRhdGEucmVzdWx0KTtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gZmFsbGJhY2sgaW4gY2FzZSBpdCBqdXN0IHRpbWVkIG91dFxuICByZWplY3QoSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHB1Ymxpc2hDbGFpbSAocHVibGlzaFBhcmFtcykge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBQdWJsaXNoaW5nIGNsYWltIHRvIFwiJHtwdWJsaXNoUGFyYW1zLm5hbWV9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdwdWJsaXNoJyxcbiAgICAgICAgICBwYXJhbXM6IHB1Ymxpc2hQYXJhbXMsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdwdWJsaXNoJywgY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsKHB1Ymxpc2hQYXJhbXMpLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDbGFpbSAodXJpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBsYnJ5QXBpID4+IEdldHRpbmcgQ2xhaW0gZm9yIFwiJHt1cml9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdnZXQnLFxuICAgICAgICAgIHBhcmFtczogeyB1cmksIHRpbWVvdXQ6IDIwIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdnZXRDbGFpbScsICdHRVQnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDbGFpbUxpc3QgKGNsYWltTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBHZXR0aW5nIGNsYWltX2xpc3QgZm9yIFwiJHtjbGFpbU5hbWV9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdjbGFpbV9saXN0JyxcbiAgICAgICAgICBwYXJhbXM6IHsgbmFtZTogY2xhaW1OYW1lIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdnZXRDbGFpbUxpc3QnLCAnQ0xBSU1fTElTVCcsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgICAgICBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UocmVzcG9uc2UsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIHJlc29sdmVVcmkgKHVyaSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBSZXNvbHZpbmcgVVJJIGZvciBcIiR7dXJpfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAncmVzb2x2ZScsXG4gICAgICAgICAgcGFyYW1zOiB7IHVyaSB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbigoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdyZXNvbHZlVXJpJywgJ1JFU09MVkUnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaWYgKGRhdGEucmVzdWx0W3VyaV0uZXJyb3IpIHsgIC8vIGNoZWNrIGZvciBlcnJvcnNcbiAgICAgICAgICAgIHJlamVjdChkYXRhLnJlc3VsdFt1cmldLmVycm9yKTtcbiAgICAgICAgICB9IGVsc2UgeyAgLy8gaWYgbm8gZXJyb3JzLCByZXNvbHZlXG4gICAgICAgICAgICByZXNvbHZlKGRhdGEucmVzdWx0W3VyaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0RG93bmxvYWREaXJlY3RvcnkgKCkge1xuICAgIGxvZ2dlci5kZWJ1ZygnbGJyeUFwaSA+PiBSZXRyaWV2aW5nIHRoZSBkb3dubG9hZCBkaXJlY3RvcnkgcGF0aCBmcm9tIGxicnkgZGFlbW9uLi4uJyk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnc2V0dGluZ3NfZ2V0JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHsgZGF0YSB9KSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnZ2V0RG93bmxvYWREaXJlY3RvcnknLCAnU0VUVElOR1NfR0VUJywgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGlmIChkYXRhLnJlc3VsdCkge1xuICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnJlc3VsdC5kb3dubG9hZF9kaXJlY3RvcnkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKCdTdWNjZXNzZnVsbHkgY29ubmVjdGVkIHRvIGxicnkgZGFlbW9uLCBidXQgdW5hYmxlIHRvIHJldHJpZXZlIHRoZSBkb3dubG9hZCBkaXJlY3RvcnkuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignTGJyeW5ldCBFcnJvcjonLCBlcnJvcik7XG4gICAgICAgICAgcmVzb2x2ZSgnL2hvbWUvbGJyeS9Eb3dubG9hZHMvJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBjcmVhdGVDaGFubmVsIChuYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBsYnJ5QXBpID4+IENyZWF0aW5nIGNoYW5uZWwgZm9yICR7bmFtZX0uLi5gKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdjaGFubmVsX25ldycsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBjaGFubmVsX25hbWU6IG5hbWUsXG4gICAgICAgICAgICBhbW91bnQgICAgICA6IDAuMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnY3JlYXRlQ2hhbm5lbCcsICdDSEFOTkVMX05FVycsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgICAgICBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UocmVzcG9uc2UsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvbGJyeUFwaS5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHVhID0gcmVxdWlyZSgndW5pdmVyc2FsLWFuYWx5dGljcycpO1xuY29uc3QgeyBhbmFseXRpY3MgOiB7IGdvb2dsZUlkIH0sIGRldGFpbHM6IHsgdGl0bGUgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxuZnVuY3Rpb24gY3JlYXRlU2VydmVFdmVudFBhcmFtcyAoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKSB7XG4gIHJldHVybiB7XG4gICAgZXZlbnRDYXRlZ29yeSAgICA6ICdjbGllbnQgcmVxdWVzdHMnLFxuICAgIGV2ZW50QWN0aW9uICAgICAgOiAnc2VydmUgcmVxdWVzdCcsXG4gICAgZXZlbnRMYWJlbCAgICAgICA6IG9yaWdpbmFsVXJsLFxuICAgIGlwT3ZlcnJpZGUgICAgICAgOiBpcCxcbiAgICB1c2VyQWdlbnRPdmVycmlkZTogaGVhZGVyc1sndXNlci1hZ2VudCddLFxuICB9O1xufTtcblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaFRpbWluZ0V2ZW50UGFyYW1zIChjYXRlZ29yeSwgdmFyaWFibGUsIGxhYmVsLCBzdGFydFRpbWUsIGVuZFRpbWUpIHtcbiAgY29uc3QgZHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lO1xuICByZXR1cm4ge1xuICAgIHVzZXJUaW1pbmdDYXRlZ29yeSAgICA6IGNhdGVnb3J5LFxuICAgIHVzZXJUaW1pbmdWYXJpYWJsZU5hbWU6IHZhcmlhYmxlLFxuICAgIHVzZXJUaW1pbmdUaW1lICAgICAgICA6IGR1cmF0aW9uLFxuICAgIHVzZXJUaW1pbmdMYWJlbCAgICAgICA6IGxhYmVsLFxuICB9O1xufTtcblxuZnVuY3Rpb24gc2VuZEdvb2dsZUFuYWx5dGljc0V2ZW50IChpcCwgcGFyYW1zKSB7XG4gIGNvbnN0IHZpc2l0b3JJZCA9IGlwLnJlcGxhY2UoL1xcLi9nLCAnLScpO1xuICBjb25zdCB2aXNpdG9yID0gdWEoZ29vZ2xlSWQsIHZpc2l0b3JJZCwgeyBzdHJpY3RDaWRGb3JtYXQ6IGZhbHNlLCBodHRwczogdHJ1ZSB9KTtcbiAgdmlzaXRvci5ldmVudChwYXJhbXMsIChlcnIpID0+IHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0dvb2dsZSBBbmFseXRpY3MgRXZlbnQgRXJyb3IgPj4nLCBlcnIpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBzZW5kR29vZ2xlQW5hbHl0aWNzVGltaW5nICh2aXNpdG9ySWQsIHBhcmFtcykge1xuICBjb25zdCB2aXNpdG9yID0gdWEoZ29vZ2xlSWQsIHZpc2l0b3JJZCwgeyBzdHJpY3RDaWRGb3JtYXQ6IGZhbHNlLCBodHRwczogdHJ1ZSB9KTtcbiAgdmlzaXRvci50aW1pbmcocGFyYW1zLCAoZXJyKSA9PiB7XG4gICAgaWYgKGVycikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdHb29nbGUgQW5hbHl0aWNzIEV2ZW50IEVycm9yID4+JywgZXJyKTtcbiAgICB9XG4gICAgbG9nZ2VyLmRlYnVnKGBUaW1pbmcgZXZlbnQgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gZ29vZ2xlIGFuYWx5dGljc2ApO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZW5kR0FTZXJ2ZUV2ZW50IChoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBjcmVhdGVTZXJ2ZUV2ZW50UGFyYW1zKGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCk7XG4gICAgc2VuZEdvb2dsZUFuYWx5dGljc0V2ZW50KGlwLCBwYXJhbXMpO1xuICB9LFxuICBzZW5kR0FUaW1pbmdFdmVudCAoY2F0ZWdvcnksIHZhcmlhYmxlLCBsYWJlbCwgc3RhcnRUaW1lLCBlbmRUaW1lKSB7XG4gICAgY29uc3QgcGFyYW1zID0gY3JlYXRlUHVibGlzaFRpbWluZ0V2ZW50UGFyYW1zKGNhdGVnb3J5LCB2YXJpYWJsZSwgbGFiZWwsIHN0YXJ0VGltZSwgZW5kVGltZSk7XG4gICAgc2VuZEdvb2dsZUFuYWx5dGljc1RpbWluZyh0aXRsZSwgcGFyYW1zKTtcbiAgfSxcbiAgY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsICh7IGNoYW5uZWxfbmFtZTogY2hhbm5lbE5hbWUsIGNoYW5uZWxfaWQ6IGNoYW5uZWxJZCB9KSB7XG4gICAgcmV0dXJuIChjaGFubmVsTmFtZSB8fCBjaGFubmVsSWQgPyAnUFVCTElTSF9JTl9DSEFOTkVMX0NMQUlNJyA6ICdQVUJMSVNIX0FOT05ZTU9VU19DTEFJTScpO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2dvb2dsZUFuYWx5dGljcy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlZHV4XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVkdXhcIlxuLy8gbW9kdWxlIGlkID0gMThcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvY2hhbm5lbF9hY3Rpb25fdHlwZXMnO1xuXG4vLyBleHBvcnQgYWN0aW9uIGNyZWF0b3JzXG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVMb2dnZWRJbkNoYW5uZWwgKG5hbWUsIHNob3J0SWQsIGxvbmdJZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0hBTk5FTF9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgbmFtZSxcbiAgICAgIHNob3J0SWQsXG4gICAgICBsb25nSWQsXG4gICAgfSxcbiAgfTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvYWN0aW9ucy9jaGFubmVsLmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgQWN0aXZlU3RhdHVzQmFyIGZyb20gJ2NvbXBvbmVudHMvQWN0aXZlU3RhdHVzQmFyJztcbmltcG9ydCBJbmFjdGl2ZVN0YXR1c0JhciBmcm9tICdjb21wb25lbnRzL0luYWN0aXZlU3RhdHVzQmFyJztcblxuY2xhc3MgUHJvZ3Jlc3NCYXIgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGJhcnMgICAgICAgOiBbXSxcbiAgICAgIGluZGV4ICAgICAgOiAwLFxuICAgICAgaW5jcmVtZW50ZXI6IDEsXG4gICAgfTtcbiAgICB0aGlzLmNyZWF0ZUJhcnMgPSB0aGlzLmNyZWF0ZUJhcnMuYmluZCh0aGlzKTtcbiAgICB0aGlzLnN0YXJ0UHJvZ3Jlc3NCYXIgPSB0aGlzLnN0YXJ0UHJvZ3Jlc3NCYXIuYmluZCh0aGlzKTtcbiAgICB0aGlzLnVwZGF0ZVByb2dyZXNzQmFyID0gdGhpcy51cGRhdGVQcm9ncmVzc0Jhci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc3RvcFByb2dyZXNzQmFyID0gdGhpcy5zdG9wUHJvZ3Jlc3NCYXIuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgdGhpcy5jcmVhdGVCYXJzKCk7XG4gICAgdGhpcy5zdGFydFByb2dyZXNzQmFyKCk7XG4gIH1cbiAgY29tcG9uZW50V2lsbFVubW91bnQgKCkge1xuICAgIHRoaXMuc3RvcFByb2dyZXNzQmFyKCk7XG4gIH1cbiAgY3JlYXRlQmFycyAoKSB7XG4gICAgY29uc3QgYmFycyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHRoaXMucHJvcHMuc2l6ZTsgaSsrKSB7XG4gICAgICBiYXJzLnB1c2goe2lzQWN0aXZlOiBmYWxzZX0pO1xuICAgIH1cbiAgICB0aGlzLnNldFN0YXRlKHsgYmFycyB9KTtcbiAgfVxuICBzdGFydFByb2dyZXNzQmFyICgpIHtcbiAgICB0aGlzLnVwZGF0ZUludGVydmFsID0gc2V0SW50ZXJ2YWwodGhpcy51cGRhdGVQcm9ncmVzc0Jhci5iaW5kKHRoaXMpLCAzMDApO1xuICB9O1xuICB1cGRhdGVQcm9ncmVzc0JhciAoKSB7XG4gICAgbGV0IGluZGV4ID0gdGhpcy5zdGF0ZS5pbmRleDtcbiAgICBsZXQgaW5jcmVtZW50ZXIgPSB0aGlzLnN0YXRlLmluY3JlbWVudGVyO1xuICAgIGxldCBiYXJzID0gdGhpcy5zdGF0ZS5iYXJzO1xuICAgIC8vIGZsaXAgaW5jcmVtZW50ZXIgaWYgbmVjZXNzYXJ5LCB0byBzdGF5IGluIGJvdW5kc1xuICAgIGlmICgoaW5kZXggPCAwKSB8fCAoaW5kZXggPiB0aGlzLnByb3BzLnNpemUpKSB7XG4gICAgICBpbmNyZW1lbnRlciA9IGluY3JlbWVudGVyICogLTE7XG4gICAgICBpbmRleCArPSBpbmNyZW1lbnRlcjtcbiAgICB9XG4gICAgLy8gdXBkYXRlIHRoZSBpbmRleGVkIGJhclxuICAgIGlmIChpbmNyZW1lbnRlciA+IDApIHtcbiAgICAgIGJhcnNbaW5kZXhdLmlzQWN0aXZlID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgYmFyc1tpbmRleF0uaXNBY3RpdmUgPSBmYWxzZTtcbiAgICB9O1xuICAgIC8vIGluY3JlbWVudCBpbmRleFxuICAgIGluZGV4ICs9IGluY3JlbWVudGVyO1xuICAgIC8vIHVwZGF0ZSBzdGF0ZVxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgYmFycyxcbiAgICAgIGluY3JlbWVudGVyLFxuICAgICAgaW5kZXgsXG4gICAgfSk7XG4gIH07XG4gIHN0b3BQcm9ncmVzc0JhciAoKSB7XG4gICAgY2xlYXJJbnRlcnZhbCh0aGlzLnVwZGF0ZUludGVydmFsKTtcbiAgfTtcbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAge3RoaXMuc3RhdGUuYmFycy5tYXAoKGJhciwgaW5kZXgpID0+IGJhci5pc0FjdGl2ZSA/IDxBY3RpdmVTdGF0dXNCYXIga2V5PXtpbmRleH0gLz4gOiA8SW5hY3RpdmVTdGF0dXNCYXIga2V5PXtpbmRleH0vPil9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5Qcm9ncmVzc0Jhci5wcm9wVHlwZXMgPSB7XG4gIHNpemU6IFByb3BUeXBlcy5udW1iZXIuaXNSZXF1aXJlZCxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFByb2dyZXNzQmFyO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvUHJvZ3Jlc3NCYXIvaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgTmF2QmFyIGZyb20gJ2NvbnRhaW5lcnMvTmF2QmFyJztcblxuY2xhc3MgRXJyb3JQYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGVycm9yIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxwPntlcnJvcn08L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufTtcblxuRXJyb3JQYWdlLnByb3BUeXBlcyA9IHtcbiAgZXJyb3I6IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEVycm9yUGFnZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9wYWdlcy9FcnJvclBhZ2UvaW5kZXguanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicGFzc3BvcnRcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJwYXNzcG9ydFwiXG4vLyBtb2R1bGUgaWQgPSAyMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXNzcG9ydC1sb2NhbFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInBhc3Nwb3J0LWxvY2FsXCJcbi8vIG1vZHVsZSBpZCA9IDIzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInNlcXVlbGl6ZVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInNlcXVlbGl6ZVwiXG4vLyBtb2R1bGUgaWQgPSAyNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmV0dXJuU2hvcnRJZDogZnVuY3Rpb24gKGNsYWltc0FycmF5LCBsb25nSWQpIHtcbiAgICBsZXQgY2xhaW1JbmRleDtcbiAgICBsZXQgc2hvcnRJZCA9IGxvbmdJZC5zdWJzdHJpbmcoMCwgMSk7IC8vIGRlZmF1bHQgc2hvcnQgaWQgaXMgdGhlIGZpcnN0IGxldHRlclxuICAgIGxldCBzaG9ydElkTGVuZ3RoID0gMDtcbiAgICAvLyBmaW5kIHRoZSBpbmRleCBvZiB0aGlzIGNsYWltIGlkXG4gICAgY2xhaW1JbmRleCA9IGNsYWltc0FycmF5LmZpbmRJbmRleChlbGVtZW50ID0+IHtcbiAgICAgIHJldHVybiBlbGVtZW50LmNsYWltSWQgPT09IGxvbmdJZDtcbiAgICB9KTtcbiAgICBpZiAoY2xhaW1JbmRleCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2xhaW0gaWQgbm90IGZvdW5kIGluIGNsYWltcyBsaXN0Jyk7XG4gICAgfVxuICAgIC8vIGdldCBhbiBhcnJheSBvZiBhbGwgY2xhaW1zIHdpdGggbG93ZXIgaGVpZ2h0XG4gICAgbGV0IHBvc3NpYmxlTWF0Y2hlcyA9IGNsYWltc0FycmF5LnNsaWNlKDAsIGNsYWltSW5kZXgpO1xuICAgIC8vIHJlbW92ZSBjZXJ0aWZpY2F0ZXMgd2l0aCB0aGUgc2FtZSBwcmVmaXhlcyB1bnRpbCBub25lIGFyZSBsZWZ0LlxuICAgIHdoaWxlIChwb3NzaWJsZU1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgICAgc2hvcnRJZExlbmd0aCArPSAxO1xuICAgICAgc2hvcnRJZCA9IGxvbmdJZC5zdWJzdHJpbmcoMCwgc2hvcnRJZExlbmd0aCk7XG4gICAgICBwb3NzaWJsZU1hdGNoZXMgPSBwb3NzaWJsZU1hdGNoZXMuZmlsdGVyKGVsZW1lbnQgPT4ge1xuICAgICAgICByZXR1cm4gKGVsZW1lbnQuY2xhaW1JZCAmJiAoZWxlbWVudC5jbGFpbUlkLnN1YnN0cmluZygwLCBzaG9ydElkTGVuZ3RoKSA9PT0gc2hvcnRJZCkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBzaG9ydElkO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL3NlcXVlbGl6ZUhlbHBlcnMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmNvbnN0IHsgZGV0YWlscywgcHVibGlzaGluZyB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5ICh7bmFtZSwgbnNmdywgbGljZW5zZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCB0aHVtYm5haWx9KSB7XG4gICAgLy8gdmFsaWRhdGUgbmFtZVxuICAgIGlmICghbmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBuYW1lIGZpZWxkIGZvdW5kIGluIHJlcXVlc3QnKTtcbiAgICB9XG4gICAgY29uc3QgaW52YWxpZE5hbWVDaGFyYWN0ZXJzID0gL1teQS1aYS16MC05LC1dLy5leGVjKG5hbWUpO1xuICAgIGlmIChpbnZhbGlkTmFtZUNoYXJhY3RlcnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNsYWltIG5hbWUgeW91IHByb3ZpZGVkIGlzIG5vdCBhbGxvd2VkLiAgT25seSB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnMgYXJlIGFsbG93ZWQ6IEEtWiwgYS16LCAwLTksIGFuZCBcIi1cIicpO1xuICAgIH1cbiAgICAvLyBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgbnNmdyA9IChuc2Z3ID09PSAndHJ1ZScpO1xuICAgIGxpY2Vuc2UgPSBsaWNlbnNlIHx8IG51bGw7XG4gICAgdGl0bGUgPSB0aXRsZSB8fCBudWxsO1xuICAgIGRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24gfHwgbnVsbDtcbiAgICB0aHVtYm5haWwgPSB0aHVtYm5haWwgfHwgbnVsbDtcbiAgICAvLyByZXR1cm4gcmVzdWx0c1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lLFxuICAgICAgbnNmdyxcbiAgICAgIGxpY2Vuc2UsXG4gICAgICB0aXRsZSxcbiAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgdGh1bWJuYWlsLFxuICAgIH07XG4gIH0sXG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyAoe2ZpbGUsIHRodW1ibmFpbH0pIHtcbiAgICAvLyBtYWtlIHN1cmUgYSBmaWxlIHdhcyBwcm92aWRlZFxuICAgIGlmICghZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHdpdGgga2V5IG9mIFtmaWxlXSBmb3VuZCBpbiByZXF1ZXN0Jyk7XG4gICAgfVxuICAgIGlmICghZmlsZS5wYXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGZpbGUgcGF0aCBmb3VuZCcpO1xuICAgIH1cbiAgICBpZiAoIWZpbGUudHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHR5cGUgZm91bmQnKTtcbiAgICB9XG4gICAgaWYgKCFmaWxlLnNpemUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gZmlsZSB0eXBlIGZvdW5kJyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHRoZSBmaWxlIG5hbWVcbiAgICBpZiAoLycvLnRlc3QoZmlsZS5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcG9zdHJvcGhlcyBhcmUgbm90IGFsbG93ZWQgaW4gdGhlIGZpbGUgbmFtZScpO1xuICAgIH1cbiAgICAvLyB2YWxpZGF0ZSB0aGUgZmlsZVxuICAgIG1vZHVsZS5leHBvcnRzLnZhbGlkYXRlRmlsZVR5cGVBbmRTaXplKGZpbGUpO1xuICAgIC8vIHJldHVybiByZXN1bHRzXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbGVOYW1lICAgICAgICAgOiBmaWxlLm5hbWUsXG4gICAgICBmaWxlUGF0aCAgICAgICAgIDogZmlsZS5wYXRoLFxuICAgICAgZmlsZVR5cGUgICAgICAgICA6IGZpbGUudHlwZSxcbiAgICAgIHRodW1ibmFpbEZpbGVOYW1lOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLm5hbWUgOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVQYXRoOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnBhdGggOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVUeXBlOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnR5cGUgOiBudWxsKSxcbiAgICB9O1xuICB9LFxuICB2YWxpZGF0ZUZpbGVUeXBlQW5kU2l6ZSAoZmlsZSkge1xuICAgIC8vIGNoZWNrIGZpbGUgdHlwZSBhbmQgc2l6ZVxuICAgIHN3aXRjaCAoZmlsZS50eXBlKSB7XG4gICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICBpZiAoZmlsZS5zaXplID4gMTAwMDAwMDApIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ3B1Ymxpc2ggPiBmaWxlIHZhbGlkYXRpb24gPiAuanBlZy8uanBnLy5wbmcgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCBpbWFnZXMgYXJlIGxpbWl0ZWQgdG8gMTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gLmdpZiB3YXMgdG9vIGJpZycpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU29ycnksIC5naWZzIGFyZSBsaW1pdGVkIHRvIDUwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgIGlmIChmaWxlLnNpemUgPiA1MDAwMDAwMCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygncHVibGlzaCA+IGZpbGUgdmFsaWRhdGlvbiA+IC5tcDQgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCB2aWRlb3MgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gdW5yZWNvZ25pemVkIGZpbGUgdHlwZScpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSAnICsgZmlsZS50eXBlICsgJyBjb250ZW50IHR5cGUgaXMgbm90IHN1cHBvcnRlZC4gIE9ubHksIC5qcGVnLCAucG5nLCAuZ2lmLCBhbmQgLm1wNCBmaWxlcyBhcmUgY3VycmVudGx5IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0sXG4gIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcyAoZmlsZVBhdGgsIG5hbWUsIHRpdGxlLCBkZXNjcmlwdGlvbiwgbGljZW5zZSwgbnNmdywgdGh1bWJuYWlsKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBQdWJsaXNoIFBhcmFtZXRlcnNgKTtcbiAgICAvLyBwcm92aWRlIGRlZmF1bHRzIGZvciB0aXRsZVxuICAgIGlmICh0aXRsZSA9PT0gbnVsbCB8fCB0aXRsZS50cmltKCkgPT09ICcnKSB7XG4gICAgICB0aXRsZSA9IG5hbWU7XG4gICAgfVxuICAgIC8vIHByb3ZpZGUgZGVmYXVsdCBmb3IgZGVzY3JpcHRpb25cbiAgICBpZiAoZGVzY3JpcHRpb24gPT09IG51bGwgfHwgZGVzY3JpcHRpb24udHJpbSgpID09PSAnJykge1xuICAgICAgZGVzY3JpcHRpb24gPSAnJztcbiAgICB9XG4gICAgLy8gcHJvdmlkZSBkZWZhdWx0IGZvciBsaWNlbnNlXG4gICAgaWYgKGxpY2Vuc2UgPT09IG51bGwgfHwgbGljZW5zZS50cmltKCkgPT09ICcnKSB7XG4gICAgICBsaWNlbnNlID0gJyAnOyAgLy8gZGVmYXVsdCB0byBlbXB0eSBzdHJpbmdcbiAgICB9XG4gICAgLy8gY3JlYXRlIHRoZSBwdWJsaXNoIHBhcmFtc1xuICAgIGNvbnN0IHB1Ymxpc2hQYXJhbXMgPSB7XG4gICAgICBuYW1lLFxuICAgICAgZmlsZV9wYXRoOiBmaWxlUGF0aCxcbiAgICAgIGJpZCAgICAgIDogMC4wMSxcbiAgICAgIG1ldGFkYXRhIDoge1xuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGF1dGhvciAgOiBkZXRhaWxzLnRpdGxlLFxuICAgICAgICBsYW5ndWFnZTogJ2VuJyxcbiAgICAgICAgbGljZW5zZSxcbiAgICAgICAgbnNmdyxcbiAgICAgIH0sXG4gICAgICBjbGFpbV9hZGRyZXNzOiBwdWJsaXNoaW5nLnByaW1hcnlDbGFpbUFkZHJlc3MsXG4gICAgfTtcbiAgICAvLyBhZGQgdGh1bWJuYWlsIHRvIGNoYW5uZWwgaWYgdmlkZW9cbiAgICBpZiAodGh1bWJuYWlsKSB7XG4gICAgICBwdWJsaXNoUGFyYW1zWydtZXRhZGF0YSddWyd0aHVtYm5haWwnXSA9IHRodW1ibmFpbDtcbiAgICB9XG4gICAgcmV0dXJuIHB1Ymxpc2hQYXJhbXM7XG4gIH0sXG4gIGNyZWF0ZVRodW1ibmFpbFB1Ymxpc2hQYXJhbXMgKHRodW1ibmFpbEZpbGVQYXRoLCBjbGFpbU5hbWUsIGxpY2Vuc2UsIG5zZncpIHtcbiAgICBpZiAoIXRodW1ibmFpbEZpbGVQYXRoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxvZ2dlci5kZWJ1ZyhgQ3JlYXRpbmcgVGh1bWJuYWlsIFB1Ymxpc2ggUGFyYW1ldGVyc2ApO1xuICAgIC8vIGNyZWF0ZSB0aGUgcHVibGlzaCBwYXJhbXNcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSAgICAgOiBgJHtjbGFpbU5hbWV9LXRodW1iYCxcbiAgICAgIGZpbGVfcGF0aDogdGh1bWJuYWlsRmlsZVBhdGgsXG4gICAgICBiaWQgICAgICA6IDAuMDEsXG4gICAgICBtZXRhZGF0YSA6IHtcbiAgICAgICAgdGl0bGUgICAgICA6IGAke2NsYWltTmFtZX0gdGh1bWJuYWlsYCxcbiAgICAgICAgZGVzY3JpcHRpb246IGBhIHRodW1ibmFpbCBmb3IgJHtjbGFpbU5hbWV9YCxcbiAgICAgICAgYXV0aG9yICAgICA6IGRldGFpbHMudGl0bGUsXG4gICAgICAgIGxhbmd1YWdlICAgOiAnZW4nLFxuICAgICAgICBsaWNlbnNlLFxuICAgICAgICBuc2Z3LFxuICAgICAgfSxcbiAgICAgIGNsYWltX2FkZHJlc3M6IHB1Ymxpc2hpbmcucHJpbWFyeUNsYWltQWRkcmVzcyxcbiAgICAgIGNoYW5uZWxfbmFtZSA6IHB1Ymxpc2hpbmcudGh1bWJuYWlsQ2hhbm5lbCxcbiAgICAgIGNoYW5uZWxfaWQgICA6IHB1Ymxpc2hpbmcudGh1bWJuYWlsQ2hhbm5lbElkLFxuICAgIH07XG4gIH0sXG4gIGRlbGV0ZVRlbXBvcmFyeUZpbGUgKGZpbGVQYXRoKSB7XG4gICAgZnMudW5saW5rKGZpbGVQYXRoLCBlcnIgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYGVycm9yIGRlbGV0aW5nIHRlbXBvcmFyeSBmaWxlICR7ZmlsZVBhdGh9YCk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5kZWJ1Zyhgc3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgJHtmaWxlUGF0aH1gKTtcbiAgICB9KTtcbiAgfSxcbiAgYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEgKGZpbGVJbmZvLCBnZXRSZXN1bHQpIHtcbiAgICBmaWxlSW5mby5maWxlTmFtZSA9IGdldFJlc3VsdC5maWxlX25hbWU7XG4gICAgZmlsZUluZm8uZmlsZVBhdGggPSBnZXRSZXN1bHQuZG93bmxvYWRfcGF0aDtcbiAgICByZXR1cm4gZmlsZUluZm87XG4gIH0sXG4gIGNyZWF0ZUZpbGVEYXRhICh7IG5hbWUsIGNsYWltSWQsIG91dHBvaW50LCBoZWlnaHQsIGFkZHJlc3MsIG5zZncsIGNvbnRlbnRUeXBlIH0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSxcbiAgICAgIGNsYWltSWQsXG4gICAgICBvdXRwb2ludCxcbiAgICAgIGhlaWdodCxcbiAgICAgIGFkZHJlc3MsXG4gICAgICBmaWxlTmFtZTogJycsXG4gICAgICBmaWxlUGF0aDogJycsXG4gICAgICBmaWxlVHlwZTogY29udGVudFR5cGUsXG4gICAgICBuc2Z3LFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBoYW5kbGVFcnJvclJlc3BvbnNlOiBmdW5jdGlvbiAob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKSB7XG4gICAgbG9nZ2VyLmVycm9yKGBFcnJvciBvbiAke29yaWdpbmFsVXJsfWAsIG1vZHVsZS5leHBvcnRzLnVzZU9iamVjdFByb3BlcnRpZXNJZk5vS2V5cyhlcnJvcikpO1xuICAgIGNvbnN0IFtzdGF0dXMsIG1lc3NhZ2VdID0gbW9kdWxlLmV4cG9ydHMucmV0dXJuRXJyb3JNZXNzYWdlQW5kU3RhdHVzKGVycm9yKTtcbiAgICByZXNcbiAgICAgIC5zdGF0dXMoc3RhdHVzKVxuICAgICAgLmpzb24obW9kdWxlLmV4cG9ydHMuY3JlYXRlRXJyb3JSZXNwb25zZVBheWxvYWQoc3RhdHVzLCBtZXNzYWdlKSk7XG4gIH0sXG4gIHJldHVybkVycm9yTWVzc2FnZUFuZFN0YXR1czogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgbGV0IHN0YXR1cywgbWVzc2FnZTtcbiAgICAvLyBjaGVjayBmb3IgZGFlbW9uIGJlaW5nIHR1cm5lZCBvZmZcbiAgICBpZiAoZXJyb3IuY29kZSA9PT0gJ0VDT05OUkVGVVNFRCcpIHtcbiAgICAgIHN0YXR1cyA9IDUwMztcbiAgICAgIG1lc3NhZ2UgPSAnQ29ubmVjdGlvbiByZWZ1c2VkLiAgVGhlIGRhZW1vbiBtYXkgbm90IGJlIHJ1bm5pbmcuJztcbiAgICAgIC8vIGZhbGxiYWNrIGZvciBldmVyeXRoaW5nIGVsc2VcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdHVzID0gNDAwO1xuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZXNzYWdlID0gZXJyb3I7XG4gICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFtzdGF0dXMsIG1lc3NhZ2VdO1xuICB9LFxuICB1c2VPYmplY3RQcm9wZXJ0aWVzSWZOb0tleXM6IGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoT2JqZWN0LmtleXMoZXJyKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGxldCBuZXdFcnJvck9iamVjdCA9IHt9O1xuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZXJyKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgbmV3RXJyb3JPYmplY3Rba2V5XSA9IGVycltrZXldO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3RXJyb3JPYmplY3Q7XG4gICAgfVxuICAgIHJldHVybiBlcnI7XG4gIH0sXG4gIGNyZWF0ZUVycm9yUmVzcG9uc2VQYXlsb2FkIChzdGF0dXMsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzLFxuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBtZXNzYWdlLFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcyIsImNvbnN0IGRiID0gcmVxdWlyZSgnLi4vbW9kZWxzL2luZGV4Jyk7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IHJldHVyblBhZ2luYXRlZENoYW5uZWxDbGFpbXMgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvY2hhbm5lbFBhZ2luYXRpb24uanMnKTtcblxuY29uc3QgTk9fQ0hBTk5FTCA9ICdOT19DSEFOTkVMJztcbmNvbnN0IE5PX0NMQUlNID0gJ05PX0NMQUlNJztcbmNvbnN0IE5PX0ZJTEUgPSAnTk9fRklMRSc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDbGFpbUlkIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIG5hbWUsIGNsYWltSWQpIHtcbiAgICBpZiAoY2hhbm5lbE5hbWUpIHtcbiAgICAgIHJldHVybiBtb2R1bGUuZXhwb3J0cy5nZXRDbGFpbUlkQnlDaGFubmVsKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgbmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBtb2R1bGUuZXhwb3J0cy5nZXRDbGFpbUlkQnlDbGFpbShuYW1lLCBjbGFpbUlkKTtcbiAgICB9XG4gIH0sXG4gIGdldENsYWltSWRCeUNsYWltIChjbGFpbU5hbWUsIGNsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldENsYWltSWRCeUNsYWltKCR7Y2xhaW1OYW1lfSwgJHtjbGFpbUlkfSlgKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZGIuQ2xhaW0uZ2V0TG9uZ0NsYWltSWQoY2xhaW1OYW1lLCBjbGFpbUlkKVxuICAgICAgICAudGhlbihsb25nQ2xhaW1JZCA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmVzb2x2ZShOT19DTEFJTSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUobG9uZ0NsYWltSWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDbGFpbUlkQnlDaGFubmVsIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0Q2xhaW1JZEJ5Q2hhbm5lbCgke2NoYW5uZWxOYW1lfSwgJHtjaGFubmVsQ2xhaW1JZH0sICR7Y2xhaW1OYW1lfSlgKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZGIuQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpIC8vIDEuIGdldCB0aGUgbG9uZyBjaGFubmVsIGlkXG4gICAgICAgIC50aGVuKGxvbmdDaGFubmVsSWQgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxJZCkge1xuICAgICAgICAgICAgcmV0dXJuIFtudWxsLCBudWxsXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtsb25nQ2hhbm5lbElkLCBkYi5DbGFpbS5nZXRDbGFpbUlkQnlMb25nQ2hhbm5lbElkKGxvbmdDaGFubmVsSWQsIGNsYWltTmFtZSldKTsgIC8vIDIuIGdldCB0aGUgbG9uZyBjbGFpbSBpZFxuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2xvbmdDaGFubmVsSWQsIGxvbmdDbGFpbUlkXSkgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxJZCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoTk9fQ0hBTk5FTCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghbG9uZ0NsYWltSWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKE5PX0NMQUlNKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShsb25nQ2xhaW1JZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGdldENoYW5uZWxEYXRhIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIHBhZ2UpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gMS4gZ2V0IHRoZSBsb25nIGNoYW5uZWwgSWQgKG1ha2Ugc3VyZSBjaGFubmVsIGV4aXN0cylcbiAgICAgIGRiLkNlcnRpZmljYXRlLmdldExvbmdDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKVxuICAgICAgICAudGhlbihsb25nQ2hhbm5lbENsYWltSWQgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gW251bGwsIG51bGwsIG51bGxdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyAyLiBnZXQgdGhlIHNob3J0IElEIGFuZCBhbGwgY2xhaW1zIGZvciB0aGF0IGNoYW5uZWxcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2xvbmdDaGFubmVsQ2xhaW1JZCwgZGIuQ2VydGlmaWNhdGUuZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZChsb25nQ2hhbm5lbENsYWltSWQsIGNoYW5uZWxOYW1lKV0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2xvbmdDaGFubmVsQ2xhaW1JZCwgc2hvcnRDaGFubmVsQ2xhaW1JZF0pID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoTk9fQ0hBTk5FTCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIDMuIHJldHVybiBhbGwgdGhlIGNoYW5uZWwgaW5mb3JtYXRpb25cbiAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgIGNoYW5uZWxOYW1lLFxuICAgICAgICAgICAgbG9uZ0NoYW5uZWxDbGFpbUlkLFxuICAgICAgICAgICAgc2hvcnRDaGFubmVsQ2xhaW1JZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2hhbm5lbENsYWltcyAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBwYWdlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIDEuIGdldCB0aGUgbG9uZyBjaGFubmVsIElkIChtYWtlIHN1cmUgY2hhbm5lbCBleGlzdHMpXG4gICAgICBkYi5DZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZClcbiAgICAgICAgLnRoZW4obG9uZ0NoYW5uZWxDbGFpbUlkID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIFtudWxsLCBudWxsLCBudWxsXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gMi4gZ2V0IHRoZSBzaG9ydCBJRCBhbmQgYWxsIGNsYWltcyBmb3IgdGhhdCBjaGFubmVsXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtsb25nQ2hhbm5lbENsYWltSWQsIGRiLkNsYWltLmdldEFsbENoYW5uZWxDbGFpbXMobG9uZ0NoYW5uZWxDbGFpbUlkKV0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2xvbmdDaGFubmVsQ2xhaW1JZCwgY2hhbm5lbENsYWltc0FycmF5XSkgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShOT19DSEFOTkVMKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gMy4gZm9ybWF0IHRoZSBkYXRhIGZvciB0aGUgdmlldywgaW5jbHVkaW5nIHBhZ2luYXRpb25cbiAgICAgICAgICBsZXQgcGFnaW5hdGVkQ2hhbm5lbFZpZXdEYXRhID0gcmV0dXJuUGFnaW5hdGVkQ2hhbm5lbENsYWltcyhjaGFubmVsTmFtZSwgbG9uZ0NoYW5uZWxDbGFpbUlkLCBjaGFubmVsQ2xhaW1zQXJyYXksIHBhZ2UpO1xuICAgICAgICAgIC8vIDQuIHJldHVybiBhbGwgdGhlIGNoYW5uZWwgaW5mb3JtYXRpb24gYW5kIGNvbnRlbnRzXG4gICAgICAgICAgcmVzb2x2ZShwYWdpbmF0ZWRDaGFubmVsVmlld0RhdGEpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRMb2NhbEZpbGVSZWNvcmQgKGNsYWltSWQsIG5hbWUpIHtcbiAgICByZXR1cm4gZGIuRmlsZS5maW5kT25lKHt3aGVyZToge2NsYWltSWQsIG5hbWV9fSlcbiAgICAgIC50aGVuKGZpbGUgPT4ge1xuICAgICAgICBpZiAoIWZpbGUpIHtcbiAgICAgICAgICByZXR1cm4gTk9fRklMRTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsZS5kYXRhVmFsdWVzO1xuICAgICAgfSk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXJUb1N0cmluZyB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IHsgY3JlYXRlU3RvcmUgfSBmcm9tICdyZWR1eCc7XG5pbXBvcnQgUmVkdWNlciBmcm9tICcuLi8uLi9jbGllbnQvcmVkdWNlcnMvaW5kZXgnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBTdGF0aWNSb3V0ZXIgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmltcG9ydCBHQUxpc3RlbmVyIGZyb20gJy4uLy4uL2NsaWVudC9jb21wb25lbnRzL0dBTGlzdGVuZXIvaW5kZXgnO1xuaW1wb3J0IEFwcCBmcm9tICcuLi8uLi9jbGllbnQvYXBwJztcbmltcG9ydCByZW5kZXJGdWxsUGFnZSBmcm9tICcuL3JlbmRlckZ1bGxQYWdlLmpzJztcbmltcG9ydCBIZWxtZXQgZnJvbSAncmVhY3QtaGVsbWV0JztcblxubW9kdWxlLmV4cG9ydHMgPSAocmVxLCByZXMpID0+IHtcbiAgbGV0IGNvbnRleHQgPSB7fTtcblxuICAvLyBjcmVhdGUgYSBuZXcgUmVkdXggc3RvcmUgaW5zdGFuY2VcbiAgY29uc3Qgc3RvcmUgPSBjcmVhdGVTdG9yZShSZWR1Y2VyKTtcblxuICAvLyByZW5kZXIgY29tcG9uZW50IHRvIGEgc3RyaW5nXG4gIGNvbnN0IGh0bWwgPSByZW5kZXJUb1N0cmluZyhcbiAgICA8UHJvdmlkZXIgc3RvcmU9e3N0b3JlfT5cbiAgICAgIDxTdGF0aWNSb3V0ZXIgbG9jYXRpb249e3JlcS51cmx9IGNvbnRleHQ9e2NvbnRleHR9PlxuICAgICAgICA8R0FMaXN0ZW5lcj5cbiAgICAgICAgICA8QXBwIC8+XG4gICAgICAgIDwvR0FMaXN0ZW5lcj5cbiAgICAgIDwvU3RhdGljUm91dGVyPlxuICAgIDwvUHJvdmlkZXI+XG4gICk7XG5cbiAgLy8gZ2V0IGhlYWQgdGFncyBmcm9tIGhlbG1ldFxuICBjb25zdCBoZWxtZXQgPSBIZWxtZXQucmVuZGVyU3RhdGljKCk7XG5cbiAgLy8gY2hlY2sgZm9yIGEgcmVkaXJlY3RcbiAgaWYgKGNvbnRleHQudXJsKSB7XG4gICAgLy8gU29tZXdoZXJlIGEgYDxSZWRpcmVjdD5gIHdhcyByZW5kZXJlZFxuICAgIHJldHVybiByZXMucmVkaXJlY3QoMzAxLCBjb250ZXh0LnVybCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gd2UncmUgZ29vZCwgc2VuZCB0aGUgcmVzcG9uc2VcbiAgfVxuXG4gIC8vIGdldCB0aGUgaW5pdGlhbCBzdGF0ZSBmcm9tIG91ciBSZWR1eCBzdG9yZVxuICBjb25zdCBwcmVsb2FkZWRTdGF0ZSA9IHN0b3JlLmdldFN0YXRlKCk7XG5cbiAgLy8gc2VuZCB0aGUgcmVuZGVyZWQgcGFnZSBiYWNrIHRvIHRoZSBjbGllbnRcbiAgcmVzLnNlbmQocmVuZGVyRnVsbFBhZ2UoaGVsbWV0LCBodG1sLCBwcmVsb2FkZWRTdGF0ZSkpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3QtZG9tL3NlcnZlclwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWRvbS9zZXJ2ZXJcIlxuLy8gbW9kdWxlIGlkID0gMzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHsgY29tYmluZVJlZHVjZXJzIH0gZnJvbSAncmVkdXgnO1xuaW1wb3J0IFB1Ymxpc2hSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3B1Ymxpc2gnO1xuaW1wb3J0IENoYW5uZWxSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL2NoYW5uZWwnO1xuaW1wb3J0IFNob3dSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3Nob3cnO1xuaW1wb3J0IFNpdGVSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3NpdGUnO1xuXG5leHBvcnQgZGVmYXVsdCBjb21iaW5lUmVkdWNlcnMoe1xuICBjaGFubmVsOiBDaGFubmVsUmVkdWNlcixcbiAgcHVibGlzaDogUHVibGlzaFJlZHVjZXIsXG4gIHNob3cgICA6IFNob3dSZWR1Y2VyLFxuICBzaXRlICAgOiBTaXRlUmVkdWNlcixcbn0pO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3JlZHVjZXJzL2luZGV4LmpzIiwiZXhwb3J0IGNvbnN0IEZJTEVfU0VMRUNURUQgPSAnRklMRV9TRUxFQ1RFRCc7XG5leHBvcnQgY29uc3QgRklMRV9DTEVBUiA9ICdGSUxFX0NMRUFSJztcbmV4cG9ydCBjb25zdCBNRVRBREFUQV9VUERBVEUgPSAnTUVUQURBVEFfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBDTEFJTV9VUERBVEUgPSAnQ0xBSU1fVVBEQVRFJztcbmV4cG9ydCBjb25zdCBTRVRfUFVCTElTSF9JTl9DSEFOTkVMID0gJ1NFVF9QVUJMSVNIX0lOX0NIQU5ORUwnO1xuZXhwb3J0IGNvbnN0IFBVQkxJU0hfU1RBVFVTX1VQREFURSA9ICdQVUJMSVNIX1NUQVRVU19VUERBVEUnO1xuZXhwb3J0IGNvbnN0IEVSUk9SX1VQREFURSA9ICdFUlJPUl9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IFNFTEVDVEVEX0NIQU5ORUxfVVBEQVRFID0gJ1NFTEVDVEVEX0NIQU5ORUxfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBUT0dHTEVfTUVUQURBVEFfSU5QVVRTID0gJ1RPR0dMRV9NRVRBREFUQV9JTlBVVFMnO1xuZXhwb3J0IGNvbnN0IFRIVU1CTkFJTF9ORVcgPSAnVEhVTUJOQUlMX05FVyc7XG5leHBvcnQgY29uc3QgUFVCTElTSF9TVEFSVCA9ICdQVUJMSVNIX1NUQVJUJztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMuanMiLCJleHBvcnQgY29uc3QgTE9HSU4gPSAnRXhpc3RpbmcnO1xuZXhwb3J0IGNvbnN0IENSRUFURSA9ICdOZXcnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9wdWJsaXNoX2NoYW5uZWxfc2VsZWN0X3N0YXRlcy5qcyIsImV4cG9ydCBjb25zdCBDSEFOTkVMX1VQREFURSA9ICdDSEFOTkVMX1VQREFURSc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29uc3RhbnRzL2NoYW5uZWxfYWN0aW9uX3R5cGVzLmpzIiwiZXhwb3J0IGNvbnN0IExPQ0FMX0NIRUNLID0gJ0xPQ0FMX0NIRUNLJztcbmV4cG9ydCBjb25zdCBVTkFWQUlMQUJMRSA9ICdVTkFWQUlMQUJMRSc7XG5leHBvcnQgY29uc3QgRVJST1IgPSAnRVJST1InO1xuZXhwb3J0IGNvbnN0IEFWQUlMQUJMRSA9ICdBVkFJTEFCTEUnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9hc3NldF9kaXNwbGF5X3N0YXRlcy5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgR29vZ2xlQW5hbHl0aWNzIGZyb20gJ3JlYWN0LWdhJztcbmltcG9ydCB7IHdpdGhSb3V0ZXIgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmNvbnN0IHsgYW5hbHl0aWNzOiB7IGdvb2dsZUlkIH0gfSA9IHJlcXVpcmUoJy4uLy4uLy4uL2NvbmZpZy9zaXRlQ29uZmlnLmpzJyk7XG5cbkdvb2dsZUFuYWx5dGljcy5pbml0aWFsaXplKGdvb2dsZUlkKTtcblxuY2xhc3MgR0FMaXN0ZW5lciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnNlbmRQYWdlVmlldyh0aGlzLnByb3BzLmhpc3RvcnkubG9jYXRpb24pO1xuICAgIHRoaXMucHJvcHMuaGlzdG9yeS5saXN0ZW4odGhpcy5zZW5kUGFnZVZpZXcpO1xuICB9XG5cbiAgc2VuZFBhZ2VWaWV3IChsb2NhdGlvbikge1xuICAgIEdvb2dsZUFuYWx5dGljcy5zZXQoeyBwYWdlOiBsb2NhdGlvbi5wYXRobmFtZSB9KTtcbiAgICBHb29nbGVBbmFseXRpY3MucGFnZXZpZXcobG9jYXRpb24ucGF0aG5hbWUpO1xuICB9XG5cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5jaGlsZHJlbjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKEdBTGlzdGVuZXIpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvR0FMaXN0ZW5lci9pbmRleC5qc3giLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgUm91dGUsIFN3aXRjaCB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEhvbWVQYWdlIGZyb20gJ3BhZ2VzL0hvbWVQYWdlJzsgLy8gb3IgdXNlIHRoZSBwcm92aWRlZCBsb2NhbCBob21lcGFnZVxuaW1wb3J0IEFib3V0UGFnZSBmcm9tICdwYWdlcy9BYm91dFBhZ2UnO1xuaW1wb3J0IExvZ2luUGFnZSBmcm9tICdwYWdlcy9Mb2dpblBhZ2UnO1xuaW1wb3J0IFNob3dQYWdlIGZyb20gJ3BhZ2VzL1Nob3dQYWdlJztcbmltcG9ydCBGb3VyT2hGb3VyUGFnZSBmcm9tICdjb250YWluZXJzL0ZvdXJPaEZvdXJQYWdlJztcblxuY29uc3QgQXBwID0gKCkgPT4ge1xuICByZXR1cm4gKFxuICAgIDxTd2l0Y2g+XG4gICAgICA8Um91dGUgZXhhY3QgcGF0aD0nLycgY29tcG9uZW50PXtIb21lUGFnZX0gLz5cbiAgICAgIDxSb3V0ZSBleGFjdCBwYXRoPScvYWJvdXQnIGNvbXBvbmVudD17QWJvdXRQYWdlfSAvPlxuICAgICAgPFJvdXRlIGV4YWN0IHBhdGg9Jy9sb2dpbicgY29tcG9uZW50PXtMb2dpblBhZ2V9IC8+XG4gICAgICA8Um91dGUgZXhhY3QgcGF0aD0nLzppZGVudGlmaWVyLzpjbGFpbScgY29tcG9uZW50PXtTaG93UGFnZX0gLz5cbiAgICAgIDxSb3V0ZSBleGFjdCBwYXRoPScvOmNsYWltJyBjb21wb25lbnQ9e1Nob3dQYWdlfSAvPlxuICAgICAgPFJvdXRlIGNvbXBvbmVudD17Rm91ck9oRm91clBhZ2V9IC8+XG4gICAgPC9Td2l0Y2g+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBcHA7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvYXBwLmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBzZWxlY3RGaWxlLCB1cGRhdGVFcnJvciwgY2xlYXJGaWxlIH0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHB1Ymxpc2ggfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGZpbGUgICAgIDogcHVibGlzaC5maWxlLFxuICAgIHRodW1ibmFpbDogcHVibGlzaC50aHVtYm5haWwsXG4gICAgZmlsZUVycm9yOiBwdWJsaXNoLmVycm9yLmZpbGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgc2VsZWN0RmlsZTogKGZpbGUpID0+IHtcbiAgICAgIGRpc3BhdGNoKHNlbGVjdEZpbGUoZmlsZSkpO1xuICAgIH0sXG4gICAgc2V0RmlsZUVycm9yOiAodmFsdWUpID0+IHtcbiAgICAgIGRpc3BhdGNoKGNsZWFyRmlsZSgpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUVycm9yKCdmaWxlJywgdmFsdWUpKTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9Ecm9wem9uZS9pbmRleC5qcyIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyB1cGRhdGVMb2dnZWRJbkNoYW5uZWwgfSBmcm9tICdhY3Rpb25zL2NoYW5uZWwnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcbmltcG9ydCB7dXBkYXRlU2VsZWN0ZWRDaGFubmVsfSBmcm9tICcuLi8uLi9hY3Rpb25zL3B1Ymxpc2gnO1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25DaGFubmVsTG9naW46IChuYW1lLCBzaG9ydElkLCBsb25nSWQpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbChuYW1lLCBzaG9ydElkLCBsb25nSWQpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbChuYW1lKSk7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobnVsbCwgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vaW5kZXguanMiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgdXBkYXRlTG9nZ2VkSW5DaGFubmVsIH0gZnJvbSAnYWN0aW9ucy9jaGFubmVsJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQge3VwZGF0ZVNlbGVjdGVkQ2hhbm5lbH0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2hhbm5lbExvZ2luOiAobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVTZWxlY3RlZENoYW5uZWwobmFtZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG51bGwsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9DaGFubmVsQ3JlYXRlRm9ybS9pbmRleC5qcyIsImV4cG9ydCBjb25zdCBDSEFOTkVMID0gJ0NIQU5ORUwnO1xuZXhwb3J0IGNvbnN0IEFTU0VUX0xJVEUgPSAnQVNTRVRfTElURSc7XG5leHBvcnQgY29uc3QgQVNTRVRfREVUQUlMUyA9ICdBU1NFVF9ERVRBSUxTJztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb25zdGFudHMvc2hvd19yZXF1ZXN0X3R5cGVzLmpzIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQgeyBmaWxlUmVxdWVzdGVkIH0gZnJvbSAnYWN0aW9ucy9zaG93JztcbmltcG9ydCB7IHNlbGVjdEFzc2V0IH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IGVycm9yIGFuZCBzdGF0dXNcbiAgY29uc3QgZXJyb3IgID0gc2hvdy5kaXNwbGF5QXNzZXQuZXJyb3I7XG4gIGNvbnN0IHN0YXR1cyA9IHNob3cuZGlzcGxheUFzc2V0LnN0YXR1cztcbiAgLy8gc2VsZWN0IGFzc2V0XG4gIGNvbnN0IGFzc2V0ID0gc2VsZWN0QXNzZXQoc2hvdyk7XG4gIC8vICByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBlcnJvcixcbiAgICBzdGF0dXMsXG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25GaWxlUmVxdWVzdDogKG5hbWUsIGNsYWltSWQpID0+IHtcbiAgICAgIGRpc3BhdGNoKGZpbGVSZXF1ZXN0ZWQobmFtZSwgY2xhaW1JZCkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0RGlzcGxheS9pbmRleC5qcyIsIm1vZHVsZS5leHBvcnRzID0gKGhlbG1ldCwgaHRtbCwgcHJlbG9hZGVkU3RhdGUpID0+IHtcbiAgLy8gdGFrZSB0aGUgaHRtbCBhbmQgcHJlbG9hZGVkU3RhdGUgYW5kIHJldHVybiB0aGUgZnVsbCBwYWdlXG4gIHJldHVybiBgXG4gICAgPCFET0NUWVBFIGh0bWw+XG4gICAgPGh0bWwgbGFuZz1cImVuXCIgcHJlZml4PVwib2c6IGh0dHA6Ly9vZ3AubWUvbnMjIGZiOiBodHRwOi8vb2dwLm1lL25zL2ZiI1wiPlxuICAgICAgICA8aGVhZD5cbiAgICAgICAgICAgIDxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPlxuICAgICAgICAgICAgPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAsIG1heGltdW0tc2NhbGU9MSwgdXNlci1zY2FsYWJsZT1ub1wiPlxuICAgICAgICAgICAgPG1ldGEgaHR0cC1lcXVpdj1cIlgtVUEtQ29tcGF0aWJsZVwiIGNvbnRlbnQ9XCJpZT1lZGdlXCI+XG4gICAgICAgICAgICA8IS0taGVsbWV0LS0+XG4gICAgICAgICAgICAke2hlbG1ldC50aXRsZS50b1N0cmluZygpfVxuICAgICAgICAgICAgJHtoZWxtZXQubWV0YS50b1N0cmluZygpfVxuICAgICAgICAgICAgJHtoZWxtZXQubGluay50b1N0cmluZygpfVxuICAgICAgICAgICAgPCEtLXN0eWxlIHNoZWV0cy0tPlxuICAgICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvYXNzZXRzL2Nzcy9yZXNldC5jc3NcIiB0eXBlPVwidGV4dC9jc3NcIj5cbiAgICAgICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL2Fzc2V0cy9jc3MvZ2VuZXJhbC5jc3NcIiB0eXBlPVwidGV4dC9jc3NcIj5cbiAgICAgICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL2Fzc2V0cy9jc3MvbWVkaWFRdWVyaWVzLmNzc1wiIHR5cGU9XCJ0ZXh0L2Nzc1wiPlxuICAgICAgICAgICAgPCEtLWdvb2dsZSBmb250LS0+XG4gICAgICAgICAgICA8bGluayBocmVmPVwiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PVJvYm90bzozMDBcIiByZWw9XCJzdHlsZXNoZWV0XCI+XG4gICAgICAgIDwvaGVhZD5cbiAgICAgICAgPGJvZHkgaWQ9XCJtYWluLWJvZHlcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3cgcm93LS10YWxsIGZsZXgtY29udGFpbmVyLS1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGlkPVwicmVhY3QtYXBwXCIgY2xhc3M9XCJyb3cgcm93LS10YWxsIGZsZXgtY29udGFpbmVyLS1jb2x1bW5cIj4ke2h0bWx9PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzY3JpcHQ+XG4gICAgICAgICAgICAgICAgd2luZG93Ll9fUFJFTE9BREVEX1NUQVRFX18gPSAke0pTT04uc3RyaW5naWZ5KHByZWxvYWRlZFN0YXRlKS5yZXBsYWNlKC88L2csICdcXFxcXFx1MDAzYycpfVxuICAgICAgICAgICAgPC9zY3JpcHQ+XG4gICAgICAgICAgICA8c2NyaXB0IHNyYz1cIi9idW5kbGUvYnVuZGxlLmpzXCI+PC9zY3JpcHQ+XG4gICAgICAgIDwvYm9keT5cbiAgICA8L2h0bWw+XG4gIGA7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvcmVuZGVyRnVsbFBhZ2UuanMiLCJleHBvcnQgY29uc3Qgc2VsZWN0U2l0ZVN0YXRlID0gKHN0YXRlKSA9PiB7XG4gIHJldHVybiBzdGF0ZS5zaXRlO1xufTtcblxuZXhwb3J0IGNvbnN0IHNlbGVjdFNpdGVIb3N0ID0gKHN0YXRlKSA9PiB7XG4gIHJldHVybiBzdGF0ZS5zaXRlLmhvc3Q7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NlbGVjdG9ycy9zaXRlLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYmFiZWwtcG9seWZpbGxcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJiYWJlbC1wb2x5ZmlsbFwiXG4vLyBtb2R1bGUgaWQgPSA0NlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ3aGF0d2ctZmV0Y2hcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ3aGF0d2ctZmV0Y2hcIlxuLy8gbW9kdWxlIGlkID0gNDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gYXBwIGRlcGVuZGVuY2llc1xuY29uc3QgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKTtcbmNvbnN0IGJvZHlQYXJzZXIgPSByZXF1aXJlKCdib2R5LXBhcnNlcicpO1xuY29uc3QgZXhwcmVzc0hhbmRsZWJhcnMgPSByZXF1aXJlKCdleHByZXNzLWhhbmRsZWJhcnMnKTtcbmNvbnN0IEhhbmRsZWJhcnMgPSByZXF1aXJlKCdoYW5kbGViYXJzJyk7XG5jb25zdCBoZWxtZXQgPSByZXF1aXJlKCdoZWxtZXQnKTtcbmNvbnN0IHBhc3Nwb3J0ID0gcmVxdWlyZSgncGFzc3BvcnQnKTtcbmNvbnN0IHsgc2VyaWFsaXplU3BlZWNoVXNlciwgZGVzZXJpYWxpemVTcGVlY2hVc2VyIH0gPSByZXF1aXJlKCcuL2hlbHBlcnMvYXV0aEhlbHBlcnMuanMnKTtcbmNvbnN0IGNvb2tpZVNlc3Npb24gPSByZXF1aXJlKCdjb29raWUtc2Vzc2lvbicpO1xuY29uc3QgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcbi8vIGxvZ2dpbmcgZGVwZW5kZW5jaWVzXG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG4vLyBjb25maWd1cmUgbG9nZ2VyXG5yZXF1aXJlKCcuL2hlbHBlcnMvY29uZmlndXJlTG9nZ2VyLmpzJykobG9nZ2VyKTtcbnJlcXVpcmUoJy4vaGVscGVycy9jb25maWd1cmVTbGFjay5qcycpKGxvZ2dlcik7XG5cbmNvbnN0IHthdXRoOiB7IHNlc3Npb25LZXkgfSwgZGV0YWlsczogeyBwb3J0OiBQT1JUIH19ID0gcmVxdWlyZSgnLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxuLy8gY3JlYXRlIGFuIEV4cHJlc3MgYXBwbGljYXRpb25cbmNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcblxuLy8gdHJ1c3QgdGhlIHByb3h5IHRvIGdldCBpcCBhZGRyZXNzIGZvciB1c1xuYXBwLmVuYWJsZSgndHJ1c3QgcHJveHknKTtcblxuLy8gYWRkIG1pZGRsZXdhcmVcbmFwcC51c2UoaGVsbWV0KCkpOyAvLyBzZXQgSFRUUCBoZWFkZXJzIHRvIHByb3RlY3QgYWdhaW5zdCB3ZWxsLWtub3duIHdlYiB2dWxuZXJhYmlsdGllc1xuYXBwLnVzZShleHByZXNzLnN0YXRpYyhgJHtfX2Rpcm5hbWV9L3B1YmxpY2ApKTsgLy8gJ2V4cHJlc3Muc3RhdGljJyB0byBzZXJ2ZSBzdGF0aWMgZmlsZXMgZnJvbSBwdWJsaWMgZGlyZWN0b3J5XG5hcHAudXNlKGJvZHlQYXJzZXIuanNvbigpKTsgLy8gJ2JvZHkgcGFyc2VyJyBmb3IgcGFyc2luZyBhcHBsaWNhdGlvbi9qc29uXG5hcHAudXNlKGJvZHlQYXJzZXIudXJsZW5jb2RlZCh7IGV4dGVuZGVkOiB0cnVlIH0pKTsgLy8gJ2JvZHkgcGFyc2VyJyBmb3IgcGFyc2luZyBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcbmFwcC51c2UoKHJlcSwgcmVzLCBuZXh0KSA9PiB7ICAvLyBjdXN0b20gbG9nZ2luZyBtaWRkbGV3YXJlIHRvIGxvZyBhbGwgaW5jb21pbmcgaHR0cCByZXF1ZXN0c1xuICBsb2dnZXIudmVyYm9zZShgUmVxdWVzdCBvbiAke3JlcS5vcmlnaW5hbFVybH0gZnJvbSAke3JlcS5pcH1gKTtcbiAgbmV4dCgpO1xufSk7XG5cbi8vIGNvbmZpZ3VyZSBwYXNzcG9ydFxucGFzc3BvcnQuc2VyaWFsaXplVXNlcihzZXJpYWxpemVTcGVlY2hVc2VyKTtcbnBhc3Nwb3J0LmRlc2VyaWFsaXplVXNlcihkZXNlcmlhbGl6ZVNwZWVjaFVzZXIpO1xuY29uc3QgbG9jYWxTaWdudXBTdHJhdGVneSA9IHJlcXVpcmUoJy4vcGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzJyk7XG5jb25zdCBsb2NhbExvZ2luU3RyYXRlZ3kgPSByZXF1aXJlKCcuL3Bhc3Nwb3J0L2xvY2FsLWxvZ2luLmpzJyk7XG5wYXNzcG9ydC51c2UoJ2xvY2FsLXNpZ251cCcsIGxvY2FsU2lnbnVwU3RyYXRlZ3kpO1xucGFzc3BvcnQudXNlKCdsb2NhbC1sb2dpbicsIGxvY2FsTG9naW5TdHJhdGVneSk7XG4vLyBpbml0aWFsaXplIHBhc3Nwb3J0XG5hcHAudXNlKGNvb2tpZVNlc3Npb24oe1xuICBuYW1lICA6ICdzZXNzaW9uJyxcbiAga2V5cyAgOiBbc2Vzc2lvbktleV0sXG4gIG1heEFnZTogMjQgKiA2MCAqIDYwICogMTAwMCwgLy8gaS5lLiAyNCBob3Vyc1xufSkpO1xuYXBwLnVzZShwYXNzcG9ydC5pbml0aWFsaXplKCkpO1xuYXBwLnVzZShwYXNzcG9ydC5zZXNzaW9uKCkpO1xuXG4vLyBjb25maWd1cmUgaGFuZGxlYmFycyAmIHJlZ2lzdGVyIGl0IHdpdGggZXhwcmVzcyBhcHBcbmNvbnN0IGhicyA9IGV4cHJlc3NIYW5kbGViYXJzLmNyZWF0ZSh7XG4gIGRlZmF1bHRMYXlvdXQ6ICdlbWJlZCcsXG4gIGhhbmRsZWJhcnMgICA6IEhhbmRsZWJhcnMsXG59KTtcbmFwcC5lbmdpbmUoJ2hhbmRsZWJhcnMnLCBoYnMuZW5naW5lKTtcbmFwcC5zZXQoJ3ZpZXcgZW5naW5lJywgJ2hhbmRsZWJhcnMnKTtcblxuLy8gc2V0IHRoZSByb3V0ZXMgb24gdGhlIGFwcFxucmVxdWlyZSgnLi9yb3V0ZXMvYXV0aC1yb3V0ZXMuanMnKShhcHApO1xucmVxdWlyZSgnLi9yb3V0ZXMvYXBpLXJvdXRlcy5qcycpKGFwcCk7XG5yZXF1aXJlKCcuL3JvdXRlcy9wYWdlLXJvdXRlcy5qcycpKGFwcCk7XG5yZXF1aXJlKCcuL3JvdXRlcy9hc3NldC1yb3V0ZXMuanMnKShhcHApO1xucmVxdWlyZSgnLi9yb3V0ZXMvZmFsbGJhY2stcm91dGVzLmpzJykoYXBwKTtcblxuLy8gY3JlYXRlIHNlcnZlclxuY29uc3Qgc2VydmVyID0gaHR0cC5TZXJ2ZXIoYXBwKTtcblxuLy8gc3luYyBzZXF1ZWxpemVcbmNvbnN0IGRiID0gcmVxdWlyZSgnLi9tb2RlbHMvaW5kZXgnKTtcbmRiLnNlcXVlbGl6ZS5zeW5jKClcbiAgLy8gc3RhcnQgdGhlIHNlcnZlclxuICAudGhlbigoKSA9PiB7XG4gICAgc2VydmVyLmxpc3RlbihQT1JULCAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgU2VydmVyIGlzIGxpc3RlbmluZyBvbiBQT1JUICR7UE9SVH1gKTtcbiAgICB9KTtcbiAgfSlcbiAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgIGxvZ2dlci5lcnJvcihgU3RhcnR1cCBFcnJvcjpgLCBlcnJvcik7XG4gIH0pO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3NlcnZlci5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImV4cHJlc3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJleHByZXNzXCJcbi8vIG1vZHVsZSBpZCA9IDQ5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImJvZHktcGFyc2VyXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiYm9keS1wYXJzZXJcIlxuLy8gbW9kdWxlIGlkID0gNTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXhwcmVzcy1oYW5kbGViYXJzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiZXhwcmVzcy1oYW5kbGViYXJzXCJcbi8vIG1vZHVsZSBpZCA9IDUxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImhhbmRsZWJhcnNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJoYW5kbGViYXJzXCJcbi8vIG1vZHVsZSBpZCA9IDUyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImhlbG1ldFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImhlbG1ldFwiXG4vLyBtb2R1bGUgaWQgPSA1M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXJpYWxpemVTcGVlY2hVc2VyICh1c2VyLCBkb25lKSB7ICAvLyByZXR1cm5zIHVzZXIgZGF0YSB0byBiZSBzZXJpYWxpemVkIGludG8gc2Vzc2lvblxuICAgIGxvZ2dlci5kZWJ1Zygnc2VyaWFsaXppbmcgdXNlcicpO1xuICAgIGRvbmUobnVsbCwgdXNlcik7XG4gIH0sXG4gIGRlc2VyaWFsaXplU3BlZWNoVXNlciAodXNlciwgZG9uZSkgeyAgLy8gZGVzZXJpYWxpemVzIHNlc3Npb24gYW5kIHBvcHVsYXRlcyBhZGRpdGlvbmFsIGluZm8gdG8gcmVxLnVzZXJcbiAgICBsb2dnZXIuZGVidWcoJ2Rlc2VyaWFsaXppbmcgdXNlcicpO1xuICAgIGRvbmUobnVsbCwgdXNlcik7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvYXV0aEhlbHBlcnMuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjb29raWUtc2Vzc2lvblwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImNvb2tpZS1zZXNzaW9uXCJcbi8vIG1vZHVsZSBpZCA9IDU1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImh0dHBcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJodHRwXCJcbi8vIG1vZHVsZSBpZCA9IDU2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IHsgbG9nTGV2ZWwgfSA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9sb2dnZXJDb25maWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAod2luc3RvbikgPT4ge1xuICAvLyBjb25maWd1cmVcbiAgd2luc3Rvbi5jb25maWd1cmUoe1xuICAgIHRyYW5zcG9ydHM6IFtcbiAgICAgIG5ldyAod2luc3Rvbi50cmFuc3BvcnRzLkNvbnNvbGUpKHtcbiAgICAgICAgbGV2ZWwgICAgICAgICAgICAgICAgICAgICAgICAgIDogbG9nTGV2ZWwsXG4gICAgICAgIHRpbWVzdGFtcCAgICAgICAgICAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICBjb2xvcml6ZSAgICAgICAgICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBwcmV0dHlQcmludCAgICAgICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBoYW5kbGVFeGNlcHRpb25zICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBodW1hblJlYWRhYmxlVW5oYW5kbGVkRXhjZXB0aW9uOiB0cnVlLFxuICAgICAgfSksXG4gICAgXSxcbiAgfSk7XG4gIC8vIHRlc3QgYWxsIHRoZSBsb2cgbGV2ZWxzXG4gIHdpbnN0b24uZXJyb3IoJ0xldmVsIDAnKTtcbiAgd2luc3Rvbi53YXJuKCdMZXZlbCAxJyk7XG4gIHdpbnN0b24uaW5mbygnTGV2ZWwgMicpO1xuICB3aW5zdG9uLnZlcmJvc2UoJ0xldmVsIDMnKTtcbiAgd2luc3Rvbi5kZWJ1ZygnTGV2ZWwgNCcpO1xuICB3aW5zdG9uLnNpbGx5KCdMZXZlbCA1Jyk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvY29uZmlndXJlTG9nZ2VyLmpzIiwiY29uc3QgbG9nZ2VyQ29uZmlnID0ge1xuICBsb2dMZXZlbDogJ2RlYnVnJywgIC8vIG9wdGlvbnM6IHNpbGx5LCBkZWJ1ZywgdmVyYm9zZSwgaW5mb1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2dnZXJDb25maWc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvbG9nZ2VyQ29uZmlnLmpzIiwiY29uc3Qgd2luc3RvblNsYWNrV2ViSG9vayA9IHJlcXVpcmUoJ3dpbnN0b24tc2xhY2std2ViaG9vaycpLlNsYWNrV2ViSG9vaztcbmNvbnN0IHNsYWNrQ29uZmlnID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NsYWNrQ29uZmlnLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKHdpbnN0b24pID0+IHtcbiAgY29uc3Qge3NsYWNrV2ViSG9vaywgc2xhY2tFcnJvckNoYW5uZWwsIHNsYWNrSW5mb0NoYW5uZWx9ID0gc2xhY2tDb25maWc7XG4gIGlmIChzbGFja1dlYkhvb2spIHtcbiAgICAvLyBhZGQgYSB0cmFuc3BvcnQgZm9yIGVycm9ycyB0byBzbGFja1xuICAgIGlmIChzbGFja0Vycm9yQ2hhbm5lbCkge1xuICAgICAgd2luc3Rvbi5hZGQod2luc3RvblNsYWNrV2ViSG9vaywge1xuICAgICAgICBuYW1lICAgICAgOiAnc2xhY2stZXJyb3JzLXRyYW5zcG9ydCcsXG4gICAgICAgIGxldmVsICAgICA6ICd3YXJuJyxcbiAgICAgICAgd2ViaG9va1VybDogc2xhY2tXZWJIb29rLFxuICAgICAgICBjaGFubmVsICAgOiBzbGFja0Vycm9yQ2hhbm5lbCxcbiAgICAgICAgdXNlcm5hbWUgIDogJ3NwZWUuY2gnLFxuICAgICAgICBpY29uRW1vamkgOiAnOmZhY2Vfd2l0aF9oZWFkX2JhbmRhZ2U6JyxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgaWYgKHNsYWNrSW5mb0NoYW5uZWwpIHtcbiAgICAgIHdpbnN0b24uYWRkKHdpbnN0b25TbGFja1dlYkhvb2ssIHtcbiAgICAgICAgbmFtZSAgICAgIDogJ3NsYWNrLWluZm8tdHJhbnNwb3J0JyxcbiAgICAgICAgbGV2ZWwgICAgIDogJ2luZm8nLFxuICAgICAgICB3ZWJob29rVXJsOiBzbGFja1dlYkhvb2ssXG4gICAgICAgIGNoYW5uZWwgICA6IHNsYWNrSW5mb0NoYW5uZWwsXG4gICAgICAgIHVzZXJuYW1lICA6ICdzcGVlLmNoJyxcbiAgICAgICAgaWNvbkVtb2ppIDogJzpuZXJkX2ZhY2U6JyxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgLy8gc2VuZCB0ZXN0IG1lc3NhZ2VcbiAgICB3aW5zdG9uLmVycm9yKCdTbGFjayBcImVycm9yXCIgbG9nZ2luZyBpcyBvbmxpbmUuJyk7XG4gICAgd2luc3Rvbi5pbmZvKCdTbGFjayBcImluZm9cIiBsb2dnaW5nIGlzIG9ubGluZS4nKTtcbiAgfSBlbHNlIHtcbiAgICB3aW5zdG9uLndhcm4oJ1NsYWNrIGxvZ2dpbmcgaXMgbm90IGVuYWJsZWQgYmVjYXVzZSBubyBzbGFja1dlYkhvb2sgY29uZmlnIHZhciBwcm92aWRlZC4nKTtcbiAgfVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2NvbmZpZ3VyZVNsYWNrLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwid2luc3Rvbi1zbGFjay13ZWJob29rXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwid2luc3Rvbi1zbGFjay13ZWJob29rXCJcbi8vIG1vZHVsZSBpZCA9IDYwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImZ1bmN0aW9uIFNsYWNrQ29uZmlnICgpIHtcbiAgdGhpcy5zbGFja1dlYkhvb2sgICAgICA9ICdkZWZhdWx0JztcbiAgdGhpcy5zbGFja0Vycm9yQ2hhbm5lbCA9ICdkZWZhdWx0JztcbiAgdGhpcy5zbGFja0luZm9DaGFubmVsICA9ICdkZWZhdWx0Jztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNsYWNrQ29uZmlnKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvc2xhY2tDb25maWcuanMiLCJjb25zdCBQYXNzcG9ydExvY2FsU3RyYXRlZ3kgPSByZXF1aXJlKCdwYXNzcG9ydC1sb2NhbCcpLlN0cmF0ZWd5O1xuY29uc3QgbGJyeUFwaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeUFwaS5qcycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgZGIgPSByZXF1aXJlKCcuLi9tb2RlbHMvaW5kZXgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgUGFzc3BvcnRMb2NhbFN0cmF0ZWd5KFxuICB7XG4gICAgdXNlcm5hbWVGaWVsZDogJ3VzZXJuYW1lJyxcbiAgICBwYXNzd29yZEZpZWxkOiAncGFzc3dvcmQnLFxuICB9LFxuICAodXNlcm5hbWUsIHBhc3N3b3JkLCBkb25lKSA9PiB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoYG5ldyBjaGFubmVsIHNpZ251cCByZXF1ZXN0LiB1c2VyOiAke3VzZXJuYW1lfSBwYXNzOiAke3Bhc3N3b3JkfSAuYCk7XG4gICAgbGV0IHVzZXJJbmZvID0ge307XG4gICAgLy8gc2VydmVyLXNpZGUgdmFsaWRhdG9uIG9mIGlucHV0cyAodXNlcm5hbWUsIHBhc3N3b3JkKVxuXG4gICAgLy8gY3JlYXRlIHRoZSBjaGFubmVsIGFuZCByZXRyaWV2ZSB0aGUgbWV0YWRhdGFcbiAgICByZXR1cm4gbGJyeUFwaS5jcmVhdGVDaGFubmVsKGBAJHt1c2VybmFtZX1gKVxuICAgICAgLnRoZW4odHggPT4ge1xuICAgICAgICAvLyBjcmVhdGUgdXNlciByZWNvcmRcbiAgICAgICAgY29uc3QgdXNlckRhdGEgPSB7XG4gICAgICAgICAgdXNlck5hbWU6IHVzZXJuYW1lLFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXNzd29yZCxcbiAgICAgICAgfTtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ3VzZXJEYXRhID4nLCB1c2VyRGF0YSk7XG4gICAgICAgIC8vIGNyZWF0ZSB1c2VyIHJlY29yZFxuICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IHtcbiAgICAgICAgICBjaGFubmVsTmFtZSAgIDogYEAke3VzZXJuYW1lfWAsXG4gICAgICAgICAgY2hhbm5lbENsYWltSWQ6IHR4LmNsYWltX2lkLFxuICAgICAgICB9O1xuICAgICAgICBsb2dnZXIudmVyYm9zZSgnY2hhbm5lbERhdGEgPicsIGNoYW5uZWxEYXRhKTtcbiAgICAgICAgLy8gY3JlYXRlIGNlcnRpZmljYXRlIHJlY29yZFxuICAgICAgICBjb25zdCBjZXJ0aWZpY2F0ZURhdGEgPSB7XG4gICAgICAgICAgY2xhaW1JZDogdHguY2xhaW1faWQsXG4gICAgICAgICAgbmFtZSAgIDogYEAke3VzZXJuYW1lfWAsXG4gICAgICAgICAgLy8gYWRkcmVzcyxcbiAgICAgICAgfTtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ2NlcnRpZmljYXRlRGF0YSA+JywgY2VydGlmaWNhdGVEYXRhKTtcbiAgICAgICAgLy8gc2F2ZSB1c2VyIGFuZCBjZXJ0aWZpY2F0ZSB0byBkYlxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2RiLlVzZXIuY3JlYXRlKHVzZXJEYXRhKSwgZGIuQ2hhbm5lbC5jcmVhdGUoY2hhbm5lbERhdGEpLCBkYi5DZXJ0aWZpY2F0ZS5jcmVhdGUoY2VydGlmaWNhdGVEYXRhKV0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKChbbmV3VXNlciwgbmV3Q2hhbm5lbCwgbmV3Q2VydGlmaWNhdGVdKSA9PiB7XG4gICAgICAgIGxvZ2dlci52ZXJib3NlKCd1c2VyIGFuZCBjZXJ0aWZpY2F0ZSBzdWNjZXNzZnVsbHkgY3JlYXRlZCcpO1xuICAgICAgICAvLyBzdG9yZSB0aGUgcmVsZXZhbnQgbmV3VXNlciBpbmZvIHRvIGJlIHBhc3NlZCBiYWNrIGZvciByZXEuVXNlclxuICAgICAgICB1c2VySW5mb1snaWQnXSA9IG5ld1VzZXIuaWQ7XG4gICAgICAgIHVzZXJJbmZvWyd1c2VyTmFtZSddID0gbmV3VXNlci51c2VyTmFtZTtcbiAgICAgICAgdXNlckluZm9bJ2NoYW5uZWxOYW1lJ10gPSBuZXdDaGFubmVsLmNoYW5uZWxOYW1lO1xuICAgICAgICB1c2VySW5mb1snY2hhbm5lbENsYWltSWQnXSA9IG5ld0NoYW5uZWwuY2hhbm5lbENsYWltSWQ7XG4gICAgICAgIC8vIGFzc29jaWF0ZSB0aGUgaW5zdGFuY2VzXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbbmV3Q2VydGlmaWNhdGUuc2V0Q2hhbm5lbChuZXdDaGFubmVsKSwgbmV3Q2hhbm5lbC5zZXRVc2VyKG5ld1VzZXIpXSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBsb2dnZXIudmVyYm9zZSgndXNlciBhbmQgY2VydGlmaWNhdGUgc3VjY2Vzc2Z1bGx5IGFzc29jaWF0ZWQnKTtcbiAgICAgICAgcmV0dXJuIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQodXNlckluZm8uY2hhbm5lbENsYWltSWQsIHVzZXJJbmZvLmNoYW5uZWxOYW1lKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihzaG9ydENoYW5uZWxJZCA9PiB7XG4gICAgICAgIHVzZXJJbmZvWydzaG9ydENoYW5uZWxJZCddID0gc2hvcnRDaGFubmVsSWQ7XG4gICAgICAgIHJldHVybiBkb25lKG51bGwsIHVzZXJJbmZvKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ3NpZ251cCBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIGRvbmUoZXJyb3IpO1xuICAgICAgfSk7XG4gIH1cbik7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYXhpb3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJheGlvc1wiXG4vLyBtb2R1bGUgaWQgPSA2M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsYnJ5Q29uZmlnID0ge1xuICBhcGk6IHtcbiAgICBhcGlIb3N0OiAnbG9jYWxob3N0JyxcbiAgICBhcGlQb3J0OiAnNTI3OScsXG4gIH0sXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGxicnlDb25maWc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvbGJyeUNvbmZpZy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInVuaXZlcnNhbC1hbmFseXRpY3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ1bml2ZXJzYWwtYW5hbHl0aWNzXCJcbi8vIG1vZHVsZSBpZCA9IDY1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImZ1bmN0aW9uIE15c3FsQ29uZmlnICgpIHtcbiAgdGhpcy5kYXRhYmFzZSA9ICdkZWZhdWx0JztcbiAgdGhpcy51c2VybmFtZSA9ICdkZWZhdWx0JztcbiAgdGhpcy5wYXNzd29yZCA9ICdkZWZhdWx0Jztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IE15c3FsQ29uZmlnKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvbXlzcWxDb25maWcuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IHJldHVyblNob3J0SWQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvc2VxdWVsaXplSGVscGVycy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HLCBCT09MRUFOLCBJTlRFR0VSLCBURVhULCBERUNJTUFMIH0pID0+IHtcbiAgY29uc3QgQ2VydGlmaWNhdGUgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdDZXJ0aWZpY2F0ZScsXG4gICAge1xuICAgICAgYWRkcmVzczoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgYW1vdW50OiB7XG4gICAgICAgIHR5cGUgICA6IERFQ0lNQUwoMTksIDgpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNsYWltU2VxdWVuY2U6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBkZWNvZGVkQ2xhaW06IHtcbiAgICAgICAgdHlwZSAgIDogQk9PTEVBTixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBkZXB0aDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGVmZmVjdGl2ZUFtb3VudDoge1xuICAgICAgICB0eXBlICAgOiBERUNJTUFMKDE5LCA4KSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoYXNTaWduYXR1cmU6IHtcbiAgICAgICAgdHlwZSAgIDogQk9PTEVBTixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoZXg6IHtcbiAgICAgICAgdHlwZSAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG5hbWU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG5vdXQ6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB0eGlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB2YWxpZEF0SGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgb3V0cG9pbnQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHZhbHVlVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1UeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjZXJ0aWZpY2F0ZVZlcnNpb246IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGtleVR5cGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHB1YmxpY0tleToge1xuICAgICAgICB0eXBlICAgOiBURVhUKCdsb25nJyksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBDZXJ0aWZpY2F0ZS5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2VydGlmaWNhdGUuYmVsb25nc1RvKGRiLkNoYW5uZWwsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkID0gZnVuY3Rpb24gKGxvbmdDaGFubmVsSWQsIGNoYW5uZWxOYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBnZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkICR7Y2hhbm5lbE5hbWV9OiR7bG9uZ0NoYW5uZWxJZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHtuYW1lOiBjaGFubmVsTmFtZX0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2hhbm5lbChzKSBmb3VuZCB3aXRoIHRoYXQgY2hhbm5lbCBuYW1lJyk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXR1cm5TaG9ydElkKHJlc3VsdCwgbG9uZ0NoYW5uZWxJZCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkRnJvbVNob3J0Q2hhbm5lbElkID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZCgke2NoYW5uZWxOYW1lfSwgJHtjaGFubmVsQ2xhaW1JZH0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7XG4gICAgICAgICAgICBuYW1lICAgOiBjaGFubmVsTmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgICAgICAgJGxpa2U6IGAke2NoYW5uZWxDbGFpbUlkfSVgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9yZGVyOiBbWydoZWlnaHQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6IC8vIG5vdGUgcmVzdWx0cyBtdXN0IGJlIHNvcnRlZFxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXN1bHRbMF0uY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENlcnRpZmljYXRlLmdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUgPSBmdW5jdGlvbiAoY2hhbm5lbE5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUoJHtjaGFubmVsTmFtZX0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWU6IGNoYW5uZWxOYW1lIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2VmZmVjdGl2ZUFtb3VudCcsICdERVNDJ10sIFsnaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXN1bHRbMF0uY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENlcnRpZmljYXRlLnZhbGlkYXRlTG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChuYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGB2YWxpZGF0ZUxvbmdDaGFubmVsSWQoJHtuYW1lfSwgJHtjbGFpbUlkfSlgKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5maW5kT25lKHtcbiAgICAgICAgd2hlcmU6IHtuYW1lLCBjbGFpbUlkfSxcbiAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgcmVzb2x2ZShjbGFpbUlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NoYW5uZWxJZCgke2NoYW5uZWxOYW1lfSwgJHtjaGFubmVsQ2xhaW1JZH0pYCk7XG4gICAgaWYgKGNoYW5uZWxDbGFpbUlkICYmIChjaGFubmVsQ2xhaW1JZC5sZW5ndGggPT09IDQwKSkgeyAgLy8gaWYgYSBmdWxsIGNoYW5uZWwgaWQgaXMgcHJvdmlkZWRcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlTG9uZ0NoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbENsYWltSWQgJiYgY2hhbm5lbENsYWltSWQubGVuZ3RoIDwgNDApIHsgIC8vIGlmIGEgc2hvcnQgY2hhbm5lbCBpZCBpcyBwcm92aWRlZFxuICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRMb25nQ2hhbm5lbElkRnJvbUNoYW5uZWxOYW1lKGNoYW5uZWxOYW1lKTsgIC8vIGlmIG5vIGNoYW5uZWwgaWQgcHJvdmlkZWRcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIENlcnRpZmljYXRlO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvY2VydGlmaWNhdGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HIH0pID0+IHtcbiAgY29uc3QgQ2hhbm5lbCA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ0NoYW5uZWwnLFxuICAgIHtcbiAgICAgIGNoYW5uZWxOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGNoYW5uZWxDbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgQ2hhbm5lbC5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2hhbm5lbC5iZWxvbmdzVG8oZGIuVXNlcik7XG4gICAgQ2hhbm5lbC5oYXNPbmUoZGIuQ2VydGlmaWNhdGUpO1xuICB9O1xuXG4gIHJldHVybiBDaGFubmVsO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvY2hhbm5lbC5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHsgcmV0dXJuU2hvcnRJZCB9ID0gcmVxdWlyZSgnLi4vaGVscGVycy9zZXF1ZWxpemVIZWxwZXJzLmpzJyk7XG5jb25zdCB7IGFzc2V0RGVmYXVsdHM6IHsgdGh1bWJuYWlsOiBkZWZhdWx0VGh1bWJuYWlsIH0sIGRldGFpbHM6IHsgaG9zdCB9IH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvc2l0ZUNvbmZpZy5qcycpO1xuXG5mdW5jdGlvbiBkZXRlcm1pbmVGaWxlRXh0ZW5zaW9uRnJvbUNvbnRlbnRUeXBlIChjb250ZW50VHlwZSkge1xuICBzd2l0Y2ggKGNvbnRlbnRUeXBlKSB7XG4gICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgY2FzZSAnaW1hZ2UvanBnJzpcbiAgICAgIHJldHVybiAnanBlZyc7XG4gICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgIHJldHVybiAncG5nJztcbiAgICBjYXNlICdpbWFnZS9naWYnOlxuICAgICAgcmV0dXJuICdnaWYnO1xuICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICByZXR1cm4gJ21wNCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIGxvZ2dlci5kZWJ1Zygnc2V0dGluZyB1bmtub3duIGZpbGUgdHlwZSBhcyBmaWxlIGV4dGVuc2lvbiBqcGVnJyk7XG4gICAgICByZXR1cm4gJ2pwZWcnO1xuICB9XG59O1xuXG5mdW5jdGlvbiBkZXRlcm1pbmVUaHVtYm5haWwgKHN0b3JlZFRodW1ibmFpbCwgZGVmYXVsdFRodW1ibmFpbCkge1xuICBpZiAoc3RvcmVkVGh1bWJuYWlsID09PSAnJykge1xuICAgIHJldHVybiBkZWZhdWx0VGh1bWJuYWlsO1xuICB9XG4gIHJldHVybiBzdG9yZWRUaHVtYm5haWw7XG59O1xuXG5mdW5jdGlvbiBwcmVwYXJlQ2xhaW1EYXRhIChjbGFpbSkge1xuICAvLyBsb2dnZXIuZGVidWcoJ3ByZXBhcmluZyBjbGFpbSBkYXRhIGJhc2VkIG9uIHJlc29sdmVkIGRhdGE6JywgY2xhaW0pO1xuICBjbGFpbVsndGh1bWJuYWlsJ10gPSBkZXRlcm1pbmVUaHVtYm5haWwoY2xhaW0udGh1bWJuYWlsLCBkZWZhdWx0VGh1bWJuYWlsKTtcbiAgY2xhaW1bJ2ZpbGVFeHQnXSA9IGRldGVybWluZUZpbGVFeHRlbnNpb25Gcm9tQ29udGVudFR5cGUoY2xhaW0uY29udGVudFR5cGUpO1xuICBjbGFpbVsnaG9zdCddID0gaG9zdDtcbiAgcmV0dXJuIGNsYWltO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgSU5URUdFUiwgVEVYVCwgREVDSU1BTCB9KSA9PiB7XG4gIGNvbnN0IENsYWltID0gc2VxdWVsaXplLmRlZmluZShcbiAgICAnQ2xhaW0nLFxuICAgIHtcbiAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGFtb3VudDoge1xuICAgICAgICB0eXBlICAgOiBERUNJTUFMKDE5LCA4KSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbVNlcXVlbmNlOiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVjb2RlZENsYWltOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVwdGg6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBlZmZlY3RpdmVBbW91bnQ6IHtcbiAgICAgICAgdHlwZSAgIDogREVDSU1BTCgxOSwgOCksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGFzU2lnbmF0dXJlOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGV4OiB7XG4gICAgICAgIHR5cGUgICA6IFRFWFQoJ2xvbmcnKSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBuYW1lOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBub3V0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdHhpZDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdmFsaWRBdEhlaWdodDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG91dHBvaW50OiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbVR5cGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNlcnRpZmljYXRlSWQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGF1dGhvcjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVzY3JpcHRpb246IHtcbiAgICAgICAgdHlwZSAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGxhbmd1YWdlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBsaWNlbnNlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBsaWNlbnNlVXJsOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBuc2Z3OiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgcHJldmlldzoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdGh1bWJuYWlsOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB0aXRsZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbWV0YWRhdGFWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjb250ZW50VHlwZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc291cmNlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzb3VyY2VUeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzb3VyY2VWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzdHJlYW1WZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB2YWx1ZVZlcnNpb246IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNoYW5uZWxOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICAgIGRlZmF1bHQgIDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIENsYWltLmFzc29jaWF0ZSA9IGRiID0+IHtcbiAgICBDbGFpbS5iZWxvbmdzVG8oZGIuRmlsZSwge1xuICAgICAgZm9yZWlnbktleToge1xuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICB9LFxuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCA9IGZ1bmN0aW9uIChjbGFpbUlkLCBjbGFpbU5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYENsYWltLmdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCBmb3IgJHtjbGFpbU5hbWV9IyR7Y2xhaW1JZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgbmFtZTogY2xhaW1OYW1lIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2xhaW0ocykgZm91bmQgd2l0aCB0aGF0IGNsYWltIG5hbWUnKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJlc29sdmUocmV0dXJuU2hvcnRJZChyZXN1bHQsIGNsYWltSWQpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0QWxsQ2hhbm5lbENsYWltcyA9IGZ1bmN0aW9uIChjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xhaW0uZ2V0QWxsQ2hhbm5lbENsYWltcyBmb3IgJHtjaGFubmVsQ2xhaW1JZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgY2VydGlmaWNhdGVJZDogY2hhbm5lbENsYWltSWQgfSxcbiAgICAgICAgICBvcmRlcjogW1snaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgICByYXcgIDogdHJ1ZSwgIC8vIHJldHVybnMgYW4gYXJyYXkgb2Ygb25seSBkYXRhLCBub3QgYW4gYXJyYXkgb2YgaW5zdGFuY2VzXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNoYW5uZWxDbGFpbXNBcnJheSA9PiB7XG4gICAgICAgICAgLy8gbG9nZ2VyLmRlYnVnKCdjaGFubmVsY2xhaW1zYXJyYXkgbGVuZ3RoOicsIGNoYW5uZWxDbGFpbXNBcnJheS5sZW5ndGgpO1xuICAgICAgICAgIHN3aXRjaCAoY2hhbm5lbENsYWltc0FycmF5Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGNoYW5uZWxDbGFpbXNBcnJheS5mb3JFYWNoKGNsYWltID0+IHtcbiAgICAgICAgICAgICAgICBjbGFpbVsnZmlsZUV4dCddID0gZGV0ZXJtaW5lRmlsZUV4dGVuc2lvbkZyb21Db250ZW50VHlwZShjbGFpbS5jb250ZW50VHlwZSk7XG4gICAgICAgICAgICAgICAgY2xhaW1bJ3RodW1ibmFpbCddID0gZGV0ZXJtaW5lVGh1bWJuYWlsKGNsYWltLnRodW1ibmFpbCwgZGVmYXVsdFRodW1ibmFpbCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNsYWltO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoY2hhbm5lbENsYWltc0FycmF5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0Q2xhaW1JZEJ5TG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBmaW5kaW5nIGNsYWltIGlkIGZvciBjbGFpbSAke2NsYWltTmFtZX0gZnJvbSBjaGFubmVsICR7Y2hhbm5lbENsYWltSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWU6IGNsYWltTmFtZSwgY2VydGlmaWNhdGVJZDogY2hhbm5lbENsYWltSWQgfSxcbiAgICAgICAgICBvcmRlcjogW1snaWQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGAke3Jlc3VsdC5sZW5ndGh9IHJlY29yZHMgZm91bmQgZm9yIFwiJHtjbGFpbU5hbWV9XCIgaW4gY2hhbm5lbCBcIiR7Y2hhbm5lbENsYWltSWR9XCJgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRMb25nQ2xhaW1JZEZyb21TaG9ydENsYWltSWQgPSBmdW5jdGlvbiAobmFtZSwgc2hvcnRJZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZToge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgICAgICAgJGxpa2U6IGAke3Nob3J0SWR9JWAsXG4gICAgICAgICAgICB9fSxcbiAgICAgICAgICBvcmRlcjogW1snaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OiAvLyBub3RlIHJlc3VsdHMgbXVzdCBiZSBzb3J0ZWRcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRUb3BGcmVlQ2xhaW1JZEJ5Q2xhaW1OYW1lID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgbmFtZSB9LFxuICAgICAgICAgIG9yZGVyOiBbWydlZmZlY3RpdmVBbW91bnQnLCAnREVTQyddLCBbJ2hlaWdodCcsICdBU0MnXV0sICAvLyBub3RlOiBtYXliZSBoZWlnaHQgYW5kIGVmZmVjdGl2ZSBhbW91bnQgbmVlZCB0byBzd2l0Y2g/XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdsZW5ndGggb2YgcmVzdWx0JywgcmVzdWx0Lmxlbmd0aCk7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmRhdGFWYWx1ZXMuY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLnZhbGlkYXRlTG9uZ0NsYWltSWQgPSBmdW5jdGlvbiAobmFtZSwgY2xhaW1JZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmZpbmRPbmUoe1xuICAgICAgICB3aGVyZToge25hbWUsIGNsYWltSWR9LFxuICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXNvbHZlKGNsYWltSWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldExvbmdDbGFpbUlkID0gZnVuY3Rpb24gKGNsYWltTmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NsYWltSWQoJHtjbGFpbU5hbWV9LCAke2NsYWltSWR9KWApO1xuICAgIGlmIChjbGFpbUlkICYmIChjbGFpbUlkLmxlbmd0aCA9PT0gNDApKSB7ICAvLyBpZiBhIGZ1bGwgY2xhaW0gaWQgaXMgcHJvdmlkZWRcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlTG9uZ0NsYWltSWQoY2xhaW1OYW1lLCBjbGFpbUlkKTtcbiAgICB9IGVsc2UgaWYgKGNsYWltSWQgJiYgY2xhaW1JZC5sZW5ndGggPCA0MCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9uZ0NsYWltSWRGcm9tU2hvcnRDbGFpbUlkKGNsYWltTmFtZSwgY2xhaW1JZCk7ICAvLyBpZiBhIHNob3J0IGNsYWltIGlkIGlzIHByb3ZpZGVkXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFRvcEZyZWVDbGFpbUlkQnlDbGFpbU5hbWUoY2xhaW1OYW1lKTsgIC8vIGlmIG5vIGNsYWltIGlkIGlzIHByb3ZpZGVkXG4gICAgfVxuICB9O1xuXG4gIENsYWltLnJlc29sdmVDbGFpbSA9IGZ1bmN0aW9uIChuYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbGFpbS5yZXNvbHZlQ2xhaW06ICR7bmFtZX0gJHtjbGFpbUlkfWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZTogeyBuYW1lLCBjbGFpbUlkIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNsYWltQXJyYXkgPT4ge1xuICAgICAgICAgIHN3aXRjaCAoY2xhaW1BcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHByZXBhcmVDbGFpbURhdGEoY2xhaW1BcnJheVswXS5kYXRhVmFsdWVzKSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYG1vcmUgdGhhbiBvbmUgcmVjb3JkIG1hdGNoZXMgJHtuYW1lfSMke2NsYWltSWR9IGluIGRiLkNsYWltYCk7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHByZXBhcmVDbGFpbURhdGEoY2xhaW1BcnJheVswXS5kYXRhVmFsdWVzKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBDbGFpbTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2NsYWltLmpzIiwibW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgSU5URUdFUiB9KSA9PiB7XG4gIGNvbnN0IEZpbGUgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdGaWxlJyxcbiAgICB7XG4gICAgICBuYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgYWRkcmVzczoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBvdXRwb2ludDoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBJTlRFR0VSLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0ICA6IDAsXG4gICAgICB9LFxuICAgICAgZmlsZU5hbWU6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZmlsZVBhdGg6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZmlsZVR5cGU6IHtcbiAgICAgICAgdHlwZTogU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIG5zZnc6IHtcbiAgICAgICAgdHlwZSAgICAgICAgOiBCT09MRUFOLFxuICAgICAgICBhbGxvd051bGwgICA6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIHRyZW5kaW5nRWxpZ2libGU6IHtcbiAgICAgICAgdHlwZSAgICAgICAgOiBCT09MRUFOLFxuICAgICAgICBhbGxvd051bGwgICA6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IHRydWUsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBGaWxlLmFzc29jaWF0ZSA9IGRiID0+IHtcbiAgICBGaWxlLmhhc01hbnkoZGIuUmVxdWVzdCk7XG4gICAgRmlsZS5oYXNPbmUoZGIuQ2xhaW0pO1xuICB9O1xuXG4gIEZpbGUuZ2V0UmVjZW50Q2xhaW1zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmRBbGwoe1xuICAgICAgd2hlcmU6IHsgbnNmdzogZmFsc2UsIHRyZW5kaW5nRWxpZ2libGU6IHRydWUgfSxcbiAgICAgIG9yZGVyOiBbWydjcmVhdGVkQXQnLCAnREVTQyddXSxcbiAgICAgIGxpbWl0OiAyNSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gRmlsZTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2ZpbGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HLCBCT09MRUFOLCBURVhUIH0pID0+IHtcbiAgY29uc3QgUmVxdWVzdCA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ1JlcXVlc3QnLFxuICAgIHtcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICB1cmw6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgaXBBZGRyZXNzOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICB9LFxuICAgICAgcmVzdWx0OiB7XG4gICAgICAgIHR5cGUgICAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICAgIGRlZmF1bHQgIDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIFJlcXVlc3QuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIFJlcXVlc3QuYmVsb25nc1RvKGRiLkZpbGUsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gUmVxdWVzdDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL3JlcXVlc3QuanMiLCIndXNlIHN0cmljdCc7XG5jb25zdCBiY3J5cHQgPSByZXF1aXJlKCdiY3J5cHQnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORyB9KSA9PiB7XG4gIGNvbnN0IFVzZXIgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdVc2VyJyxcbiAgICB7XG4gICAgICB1c2VyTmFtZToge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBwYXNzd29yZDoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIFVzZXIuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIFVzZXIuaGFzT25lKGRiLkNoYW5uZWwpO1xuICB9O1xuXG4gIFVzZXIucHJvdG90eXBlLmNvbXBhcmVQYXNzd29yZCA9IGZ1bmN0aW9uIChwYXNzd29yZCkge1xuICAgIHJldHVybiBiY3J5cHQuY29tcGFyZShwYXNzd29yZCwgdGhpcy5wYXNzd29yZCk7XG4gIH07XG5cbiAgVXNlci5wcm90b3R5cGUuY2hhbmdlUGFzc3dvcmQgPSBmdW5jdGlvbiAobmV3UGFzc3dvcmQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gZ2VuZXJhdGUgYSBzYWx0IHN0cmluZyB0byB1c2UgZm9yIGhhc2hpbmdcbiAgICAgIGJjcnlwdC5nZW5TYWx0KChzYWx0RXJyb3IsIHNhbHQpID0+IHtcbiAgICAgICAgaWYgKHNhbHRFcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignc2FsdCBlcnJvcicsIHNhbHRFcnJvcik7XG4gICAgICAgICAgcmVqZWN0KHNhbHRFcnJvcik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdlbmVyYXRlIGEgaGFzaGVkIHZlcnNpb24gb2YgdGhlIHVzZXIncyBwYXNzd29yZFxuICAgICAgICBiY3J5cHQuaGFzaChuZXdQYXNzd29yZCwgc2FsdCwgKGhhc2hFcnJvciwgaGFzaCkgPT4ge1xuICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIGVycm9yIHdpdGggdGhlIGhhc2ggZ2VuZXJhdGlvbiByZXR1cm4gdGhlIGVycm9yXG4gICAgICAgICAgaWYgKGhhc2hFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdoYXNoIGVycm9yJywgaGFzaEVycm9yKTtcbiAgICAgICAgICAgIHJlamVjdChoYXNoRXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyByZXBsYWNlIHRoZSBjdXJyZW50IHBhc3N3b3JkIHdpdGggdGhlIG5ldyBoYXNoXG4gICAgICAgICAgdGhpc1xuICAgICAgICAgICAgLnVwZGF0ZSh7cGFzc3dvcmQ6IGhhc2h9KVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIHByZS1zYXZlIGhvb2sgbWV0aG9kIHRvIGhhc2ggdGhlIHVzZXIncyBwYXNzd29yZCBiZWZvcmUgdGhlIHVzZXIncyBpbmZvIGlzIHNhdmVkIHRvIHRoZSBkYi5cbiAgVXNlci5ob29rKCdiZWZvcmVDcmVhdGUnLCAodXNlciwgb3B0aW9ucykgPT4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnVXNlci5iZWZvcmVDcmVhdGUgaG9vay4uLicpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBnZW5lcmF0ZSBhIHNhbHQgc3RyaW5nIHRvIHVzZSBmb3IgaGFzaGluZ1xuICAgICAgYmNyeXB0LmdlblNhbHQoKHNhbHRFcnJvciwgc2FsdCkgPT4ge1xuICAgICAgICBpZiAoc2FsdEVycm9yKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdzYWx0IGVycm9yJywgc2FsdEVycm9yKTtcbiAgICAgICAgICByZWplY3Qoc2FsdEVycm9yKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2VuZXJhdGUgYSBoYXNoZWQgdmVyc2lvbiBvZiB0aGUgdXNlcidzIHBhc3N3b3JkXG4gICAgICAgIGJjcnlwdC5oYXNoKHVzZXIucGFzc3dvcmQsIHNhbHQsIChoYXNoRXJyb3IsIGhhc2gpID0+IHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBlcnJvciB3aXRoIHRoZSBoYXNoIGdlbmVyYXRpb24gcmV0dXJuIHRoZSBlcnJvclxuICAgICAgICAgIGlmIChoYXNoRXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignaGFzaCBlcnJvcicsIGhhc2hFcnJvcik7XG4gICAgICAgICAgICByZWplY3QoaGFzaEVycm9yKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gcmVwbGFjZSB0aGUgcGFzc3dvcmQgc3RyaW5nIHdpdGggdGhlIGhhc2ggcGFzc3dvcmQgdmFsdWVcbiAgICAgICAgICB1c2VyLnBhc3N3b3JkID0gaGFzaDtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiBVc2VyO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvdXNlci5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImJjcnlwdFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImJjcnlwdFwiXG4vLyBtb2R1bGUgaWQgPSA3M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBQYXNzcG9ydExvY2FsU3RyYXRlZ3kgPSByZXF1aXJlKCdwYXNzcG9ydC1sb2NhbCcpLlN0cmF0ZWd5O1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgZGIgPSByZXF1aXJlKCcuLi9tb2RlbHMvaW5kZXgnKTtcblxuY29uc3QgcmV0dXJuVXNlckFuZENoYW5uZWxJbmZvID0gKHVzZXJJbnN0YW5jZSkgPT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCB1c2VySW5mbyA9IHt9O1xuICAgIHVzZXJJbmZvWydpZCddID0gdXNlckluc3RhbmNlLmlkO1xuICAgIHVzZXJJbmZvWyd1c2VyTmFtZSddID0gdXNlckluc3RhbmNlLnVzZXJOYW1lO1xuICAgIHVzZXJJbnN0YW5jZVxuICAgICAgLmdldENoYW5uZWwoKVxuICAgICAgLnRoZW4oKHtjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWR9KSA9PiB7XG4gICAgICAgIHVzZXJJbmZvWydjaGFubmVsTmFtZSddID0gY2hhbm5lbE5hbWU7XG4gICAgICAgIHVzZXJJbmZvWydjaGFubmVsQ2xhaW1JZCddID0gY2hhbm5lbENsYWltSWQ7XG4gICAgICAgIHJldHVybiBkYi5DZXJ0aWZpY2F0ZS5nZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkKGNoYW5uZWxDbGFpbUlkLCBjaGFubmVsTmFtZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oc2hvcnRDaGFubmVsSWQgPT4ge1xuICAgICAgICB1c2VySW5mb1snc2hvcnRDaGFubmVsSWQnXSA9IHNob3J0Q2hhbm5lbElkO1xuICAgICAgICByZXNvbHZlKHVzZXJJbmZvKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgUGFzc3BvcnRMb2NhbFN0cmF0ZWd5KFxuICB7XG4gICAgdXNlcm5hbWVGaWVsZDogJ3VzZXJuYW1lJyxcbiAgICBwYXNzd29yZEZpZWxkOiAncGFzc3dvcmQnLFxuICB9LFxuICAodXNlcm5hbWUsIHBhc3N3b3JkLCBkb25lKSA9PiB7XG4gICAgcmV0dXJuIGRiLlVzZXJcbiAgICAgIC5maW5kT25lKHtcbiAgICAgICAgd2hlcmU6IHt1c2VyTmFtZTogdXNlcm5hbWV9LFxuICAgICAgfSlcbiAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ25vIHVzZXIgZm91bmQnKTtcbiAgICAgICAgICByZXR1cm4gZG9uZShudWxsLCBmYWxzZSwge21lc3NhZ2U6ICdJbmNvcnJlY3QgdXNlcm5hbWUgb3IgcGFzc3dvcmQnfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVzZXIuY29tcGFyZVBhc3N3b3JkKHBhc3N3b3JkKVxuICAgICAgICAgIC50aGVuKGlzTWF0Y2ggPT4ge1xuICAgICAgICAgICAgaWYgKCFpc01hdGNoKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnaW5jb3JyZWN0IHBhc3N3b3JkJyk7XG4gICAgICAgICAgICAgIHJldHVybiBkb25lKG51bGwsIGZhbHNlLCB7bWVzc2FnZTogJ0luY29ycmVjdCB1c2VybmFtZSBvciBwYXNzd29yZCd9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnUGFzc3dvcmQgd2FzIGEgbWF0Y2gsIHJldHVybmluZyBVc2VyJyk7XG4gICAgICAgICAgICByZXR1cm4gcmV0dXJuVXNlckFuZENoYW5uZWxJbmZvKHVzZXIpXG4gICAgICAgICAgICAgIC50aGVuKHVzZXJJbmZvID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZG9uZShudWxsLCB1c2VySW5mbyk7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgcmV0dXJuIGRvbmUoZXJyb3IpO1xuICAgICAgfSk7XG4gIH0sXG4pO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3Bhc3Nwb3J0L2xvY2FsLWxvZ2luLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgcGFzc3BvcnQgPSByZXF1aXJlKCdwYXNzcG9ydCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChhcHApID0+IHtcbiAgLy8gcm91dGUgZm9yIHNpZ24gdXBcbiAgYXBwLnBvc3QoJy9zaWdudXAnLCBwYXNzcG9ydC5hdXRoZW50aWNhdGUoJ2xvY2FsLXNpZ251cCcpLCAocmVxLCByZXMpID0+IHtcbiAgICBsb2dnZXIudmVyYm9zZShgc3VjY2Vzc2Z1bCBzaWdudXAgZm9yICR7cmVxLnVzZXIuY2hhbm5lbE5hbWV9YCk7XG4gICAgcmVzLnN0YXR1cygyMDApLmpzb24oe1xuICAgICAgc3VjY2VzcyAgICAgICA6IHRydWUsXG4gICAgICBjaGFubmVsTmFtZSAgIDogcmVxLnVzZXIuY2hhbm5lbE5hbWUsXG4gICAgICBjaGFubmVsQ2xhaW1JZDogcmVxLnVzZXIuY2hhbm5lbENsYWltSWQsXG4gICAgICBzaG9ydENoYW5uZWxJZDogcmVxLnVzZXIuc2hvcnRDaGFubmVsSWQsXG4gICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSBmb3IgbG9nIGluXG4gIGFwcC5wb3N0KCcvbG9naW4nLCAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICBwYXNzcG9ydC5hdXRoZW50aWNhdGUoJ2xvY2FsLWxvZ2luJywgKGVyciwgdXNlciwgaW5mbykgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXR1cm4gbmV4dChlcnIpO1xuICAgICAgfVxuICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgbWVzc2FnZTogaW5mby5tZXNzYWdlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5kZWJ1Zygnc3VjY2Vzc2Z1bCBsb2dpbicpO1xuICAgICAgcmVxLmxvZ0luKHVzZXIsIChlcnIpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiBuZXh0KGVycik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtcbiAgICAgICAgICBzdWNjZXNzICAgICAgIDogdHJ1ZSxcbiAgICAgICAgICBjaGFubmVsTmFtZSAgIDogcmVxLnVzZXIuY2hhbm5lbE5hbWUsXG4gICAgICAgICAgY2hhbm5lbENsYWltSWQ6IHJlcS51c2VyLmNoYW5uZWxDbGFpbUlkLFxuICAgICAgICAgIHNob3J0Q2hhbm5lbElkOiByZXEudXNlci5zaG9ydENoYW5uZWxJZCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KShyZXEsIHJlcywgbmV4dCk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBsb2cgb3V0XG4gIGFwcC5nZXQoJy9sb2dvdXQnLCAocmVxLCByZXMpID0+IHtcbiAgICByZXEubG9nb3V0KCk7XG4gICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIG1lc3NhZ2U6ICd5b3Ugc3VjY2Vzc2Z1bGx5IGxvZ2dlZCBvdXQnfSk7XG4gIH0pO1xuICAvLyBzZWUgaWYgdXNlciBpcyBhdXRoZW50aWNhdGVkLCBhbmQgcmV0dXJuIGNyZWRlbnRpYWxzIGlmIHNvXG4gIGFwcC5nZXQoJy91c2VyJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgaWYgKHJlcS51c2VyKSB7XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogcmVxLnVzZXJ9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzLnN0YXR1cyg0MDEpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAndXNlciBpcyBub3QgbG9nZ2VkIGluJ30pO1xuICAgIH1cbiAgfSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hdXRoLXJvdXRlcy5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IG11bHRpcGFydCA9IHJlcXVpcmUoJ2Nvbm5lY3QtbXVsdGlwYXJ0eScpO1xuY29uc3QgeyBwdWJsaXNoaW5nOiB7IHVwbG9hZERpcmVjdG9yeSB9LCBkZXRhaWxzOiB7IGhvc3QgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcbmNvbnN0IG11bHRpcGFydE1pZGRsZXdhcmUgPSBtdWx0aXBhcnQoe3VwbG9hZERpcjogdXBsb2FkRGlyZWN0b3J5fSk7XG5jb25zdCBkYiA9IHJlcXVpcmUoJy4uL21vZGVscy9pbmRleCcpO1xuY29uc3QgeyBjbGFpbU5hbWVJc0F2YWlsYWJsZSwgY2hlY2tDaGFubmVsQXZhaWxhYmlsaXR5LCBwdWJsaXNoIH0gPSByZXF1aXJlKCcuLi9jb250cm9sbGVycy9wdWJsaXNoQ29udHJvbGxlci5qcycpO1xuY29uc3QgeyBnZXRDbGFpbUxpc3QsIHJlc29sdmVVcmksIGdldENsYWltIH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2xicnlBcGkuanMnKTtcbmNvbnN0IHsgYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEsIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcywgY3JlYXRlVGh1bWJuYWlsUHVibGlzaFBhcmFtcywgcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEJvZHksIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcywgY3JlYXRlRmlsZURhdGEgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMnKTtcbmNvbnN0IGVycm9ySGFuZGxlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcbmNvbnN0IHsgc2VuZEdBVGltaW5nRXZlbnQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzJyk7XG5jb25zdCB7IGF1dGhlbnRpY2F0ZVVzZXIgfSA9IHJlcXVpcmUoJy4uL2F1dGgvYXV0aGVudGljYXRpb24uanMnKTtcbmNvbnN0IHsgZ2V0Q2hhbm5lbERhdGEsIGdldENoYW5uZWxDbGFpbXMsIGdldENsYWltSWQgfSA9IHJlcXVpcmUoJy4uL2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcycpO1xuXG5jb25zdCBOT19DSEFOTkVMID0gJ05PX0NIQU5ORUwnO1xuY29uc3QgTk9fQ0xBSU0gPSAnTk9fQ0xBSU0nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChhcHApID0+IHtcbiAgLy8gcm91dGUgdG8gY2hlY2sgd2hldGhlciBzaXRlIGhhcyBwdWJsaXNoZWQgdG8gYSBjaGFubmVsXG4gIGFwcC5nZXQoJy9hcGkvY2hhbm5lbC9hdmFpbGFiaWxpdHkvOm5hbWUnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtczogeyBuYW1lIH0gfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGNoZWNrQ2hhbm5lbEF2YWlsYWJpbGl0eShuYW1lKVxuICAgICAgLnRoZW4oYXZhaWxhYmxlTmFtZSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKGF2YWlsYWJsZU5hbWUpO1xuICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnZW5kLXRvLWVuZCcsICdjbGFpbSBuYW1lIGF2YWlsYWJpbGl0eScsIG5hbWUsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gZ2V0IGEgc2hvcnQgY2hhbm5lbCBpZCBmcm9tIGxvbmcgY2hhbm5lbCBJZFxuICBhcHAuZ2V0KCcvYXBpL2NoYW5uZWwvc2hvcnQtaWQvOmxvbmdJZC86bmFtZScsICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQocGFyYW1zLmxvbmdJZCwgcGFyYW1zLm5hbWUpXG4gICAgICAudGhlbihzaG9ydElkID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oc2hvcnRJZCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIGFwcC5nZXQoJy9hcGkvY2hhbm5lbC9kYXRhLzpjaGFubmVsTmFtZS86Y2hhbm5lbENsYWltSWQnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IHBhcmFtcy5jaGFubmVsTmFtZTtcbiAgICBsZXQgY2hhbm5lbENsYWltSWQgPSBwYXJhbXMuY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKGNoYW5uZWxDbGFpbUlkID09PSAnbm9uZScpIGNoYW5uZWxDbGFpbUlkID0gbnVsbDtcbiAgICBnZXRDaGFubmVsRGF0YShjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIDApXG4gICAgICAudGhlbihkYXRhID0+IHtcbiAgICAgICAgaWYgKGRhdGEgPT09IE5PX0NIQU5ORUwpIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gbWF0Y2hpbmcgY2hhbm5lbCB3YXMgZm91bmQnfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGF9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgYXBwLmdldCgnL2FwaS9jaGFubmVsL2NsYWltcy86Y2hhbm5lbE5hbWUvOmNoYW5uZWxDbGFpbUlkLzpwYWdlJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgY2hhbm5lbE5hbWUgPSBwYXJhbXMuY2hhbm5lbE5hbWU7XG4gICAgbGV0IGNoYW5uZWxDbGFpbUlkID0gcGFyYW1zLmNoYW5uZWxDbGFpbUlkO1xuICAgIGlmIChjaGFubmVsQ2xhaW1JZCA9PT0gJ25vbmUnKSBjaGFubmVsQ2xhaW1JZCA9IG51bGw7XG4gICAgY29uc3QgcGFnZSA9IHBhcmFtcy5wYWdlO1xuICAgIGdldENoYW5uZWxDbGFpbXMoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBwYWdlKVxuICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgIGlmIChkYXRhID09PSBOT19DSEFOTkVMKSB7XG4gICAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ05vIG1hdGNoaW5nIGNoYW5uZWwgd2FzIGZvdW5kJ30pO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIHJ1biBhIGNsYWltX2xpc3QgcmVxdWVzdCBvbiB0aGUgZGFlbW9uXG4gIGFwcC5nZXQoJy9hcGkvY2xhaW0vbGlzdC86bmFtZScsICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGdldENsYWltTGlzdChwYXJhbXMubmFtZSlcbiAgICAgIC50aGVuKGNsYWltc0xpc3QgPT4ge1xuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbihjbGFpbXNMaXN0KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gZ2V0IGFuIGFzc2V0XG4gIGFwcC5nZXQoJy9hcGkvY2xhaW0vZ2V0LzpuYW1lLzpjbGFpbUlkJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IHBhcmFtcy5uYW1lO1xuICAgIGNvbnN0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcbiAgICAvLyByZXNvbHZlIHRoZSBjbGFpbVxuICAgIGRiLkNsYWltLnJlc29sdmVDbGFpbShuYW1lLCBjbGFpbUlkKVxuICAgICAgLnRoZW4ocmVzb2x2ZVJlc3VsdCA9PiB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSBhIGNsYWltIGFjdHVhbGx5IGV4aXN0cyBhdCB0aGF0IHVyaVxuICAgICAgICBpZiAoIXJlc29sdmVSZXN1bHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIG1hdGNoaW5nIHVyaSBmb3VuZCBpbiBDbGFpbSB0YWJsZScpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBmaWxlRGF0YSA9IGNyZWF0ZUZpbGVEYXRhKHJlc29sdmVSZXN1bHQpO1xuICAgICAgICAvLyBnZXQgdGhlIGNsYWltXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZmlsZURhdGEsIGdldENsYWltKGAke25hbWV9IyR7Y2xhaW1JZH1gKV0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKChbIGZpbGVEYXRhLCBnZXRSZXN1bHQgXSkgPT4ge1xuICAgICAgICBmaWxlRGF0YSA9IGFkZEdldFJlc3VsdHNUb0ZpbGVEYXRhKGZpbGVEYXRhLCBnZXRSZXN1bHQpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2RiLnVwc2VydChkYi5GaWxlLCBmaWxlRGF0YSwge25hbWUsIGNsYWltSWR9LCAnRmlsZScpLCBnZXRSZXN1bHRdKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoWyBmaWxlUmVjb3JkLCB7bWVzc2FnZSwgY29tcGxldGVkfSBdKSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHsgc3VjY2VzczogdHJ1ZSwgbWVzc2FnZSwgY29tcGxldGVkIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBjaGVjayB3aGV0aGVyIHRoaXMgc2l0ZSBwdWJsaXNoZWQgdG8gYSBjbGFpbVxuICBhcHAuZ2V0KCcvYXBpL2NsYWltL2F2YWlsYWJpbGl0eS86bmFtZScsICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zOiB7IG5hbWUgfSB9LCByZXMpID0+IHtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgY2xhaW1OYW1lSXNBdmFpbGFibGUobmFtZSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHJlc3VsdCk7XG4gICAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdlbmQtdG8tZW5kJywgJ2NsYWltIG5hbWUgYXZhaWxhYmlsaXR5JywgbmFtZSwgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBydW4gYSByZXNvbHZlIHJlcXVlc3Qgb24gdGhlIGRhZW1vblxuICBhcHAuZ2V0KCcvYXBpL2NsYWltL3Jlc29sdmUvOm5hbWUvOmNsYWltSWQnLCAoeyBoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICByZXNvbHZlVXJpKGAke3BhcmFtcy5uYW1lfSMke3BhcmFtcy5jbGFpbUlkfWApXG4gICAgICAudGhlbihyZXNvbHZlZFVyaSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHJlc29sdmVkVXJpKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gcnVuIGEgcHVibGlzaCByZXF1ZXN0IG9uIHRoZSBkYWVtb25cbiAgYXBwLnBvc3QoJy9hcGkvY2xhaW0vcHVibGlzaCcsIG11bHRpcGFydE1pZGRsZXdhcmUsICh7IGJvZHksIGZpbGVzLCBoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwsIHVzZXIgfSwgcmVzKSA9PiB7XG4gICAgLy8gZGVmaW5lIHZhcmlhYmxlc1xuICAgIGxldCAgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgY2hhbm5lbFBhc3N3b3JkLCBkZXNjcmlwdGlvbiwgZmlsZU5hbWUsIGZpbGVQYXRoLCBmaWxlVHlwZSwgZ2FTdGFydFRpbWUsIGxpY2Vuc2UsIG5hbWUsIG5zZncsIHRodW1ibmFpbCwgdGh1bWJuYWlsRmlsZU5hbWUsIHRodW1ibmFpbEZpbGVQYXRoLCB0aHVtYm5haWxGaWxlVHlwZSwgdGl0bGU7XG4gICAgLy8gcmVjb3JkIHRoZSBzdGFydCB0aW1lIG9mIHRoZSByZXF1ZXN0XG4gICAgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIC8vIHZhbGlkYXRlIHRoZSBib2R5IGFuZCBmaWxlcyBvZiB0aGUgcmVxdWVzdFxuICAgIHRyeSB7XG4gICAgICAvLyB2YWxpZGF0ZUFwaVB1Ymxpc2hSZXF1ZXN0KGJvZHksIGZpbGVzKTtcbiAgICAgICh7bmFtZSwgbnNmdywgbGljZW5zZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCB0aHVtYm5haWx9ID0gcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEJvZHkoYm9keSkpO1xuICAgICAgKHtmaWxlTmFtZSwgZmlsZVBhdGgsIGZpbGVUeXBlLCB0aHVtYm5haWxGaWxlTmFtZSwgdGh1bWJuYWlsRmlsZVBhdGgsIHRodW1ibmFpbEZpbGVUeXBlfSA9IHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyhmaWxlcykpO1xuICAgICAgKHtjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBjaGFubmVsUGFzc3dvcmR9ID0gYm9keSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgICB9XG4gICAgLy8gY2hlY2sgY2hhbm5lbCBhdXRob3JpemF0aW9uXG4gICAgUHJvbWlzZS5hbGwoW1xuICAgICAgYXV0aGVudGljYXRlVXNlcihjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBjaGFubmVsUGFzc3dvcmQsIHVzZXIpLFxuICAgICAgY2xhaW1OYW1lSXNBdmFpbGFibGUobmFtZSksXG4gICAgICBjcmVhdGVCYXNpY1B1Ymxpc2hQYXJhbXMoZmlsZVBhdGgsIG5hbWUsIHRpdGxlLCBkZXNjcmlwdGlvbiwgbGljZW5zZSwgbnNmdywgdGh1bWJuYWlsKSxcbiAgICAgIGNyZWF0ZVRodW1ibmFpbFB1Ymxpc2hQYXJhbXModGh1bWJuYWlsRmlsZVBhdGgsIG5hbWUsIGxpY2Vuc2UsIG5zZncpLFxuICAgIF0pXG4gICAgICAudGhlbigoW3tjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWR9LCB2YWxpZGF0ZWRDbGFpbU5hbWUsIHB1Ymxpc2hQYXJhbXMsIHRodW1ibmFpbFB1Ymxpc2hQYXJhbXNdKSA9PiB7XG4gICAgICAgIC8vIGFkZCBjaGFubmVsIGRldGFpbHMgdG8gdGhlIHB1Ymxpc2ggcGFyYW1zXG4gICAgICAgIGlmIChjaGFubmVsTmFtZSAmJiBjaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgIHB1Ymxpc2hQYXJhbXNbJ2NoYW5uZWxfbmFtZSddID0gY2hhbm5lbE5hbWU7XG4gICAgICAgICAgcHVibGlzaFBhcmFtc1snY2hhbm5lbF9pZCddID0gY2hhbm5lbENsYWltSWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcHVibGlzaCB0aGUgdGh1bWJuYWlsXG4gICAgICAgIGlmICh0aHVtYm5haWxQdWJsaXNoUGFyYW1zKSB7XG4gICAgICAgICAgcHVibGlzaCh0aHVtYm5haWxQdWJsaXNoUGFyYW1zLCB0aHVtYm5haWxGaWxlTmFtZSwgdGh1bWJuYWlsRmlsZVR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHB1Ymxpc2ggdGhlIGFzc2V0XG4gICAgICAgIHJldHVybiBwdWJsaXNoKHB1Ymxpc2hQYXJhbXMsIGZpbGVOYW1lLCBmaWxlVHlwZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgbWVzc2FnZTogJ3B1Ymxpc2ggY29tcGxldGVkIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgZGF0YSAgIDoge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHJlc3VsdC5jbGFpbV9pZCxcbiAgICAgICAgICAgIHVybCAgICA6IGAke2hvc3R9LyR7cmVzdWx0LmNsYWltX2lkfS8ke25hbWV9YCxcbiAgICAgICAgICAgIGxicnlUeCA6IHJlc3VsdCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gcmVjb3JkIHRoZSBwdWJsaXNoIGVuZCB0aW1lIGFuZCBzZW5kIHRvIGdvb2dsZSBhbmFseXRpY3NcbiAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2VuZC10by1lbmQnLCAncHVibGlzaCcsIGZpbGVUeXBlLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGdldCBhIHNob3J0IGNsYWltIGlkIGZyb20gbG9uZyBjbGFpbSBJZFxuICBhcHAuZ2V0KCcvYXBpL2NsYWltL3Nob3J0LWlkLzpsb25nSWQvOm5hbWUnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBkYi5DbGFpbS5nZXRTaG9ydENsYWltSWRGcm9tTG9uZ0NsYWltSWQocGFyYW1zLmxvbmdJZCwgcGFyYW1zLm5hbWUpXG4gICAgICAudGhlbihzaG9ydElkID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHNob3J0SWR9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgYXBwLnBvc3QoJy9hcGkvY2xhaW0vbG9uZy1pZCcsICh7IGlwLCBvcmlnaW5hbFVybCwgYm9keSwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnYm9keTonLCBib2R5KTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGJvZHkuY2hhbm5lbE5hbWU7XG4gICAgY29uc3QgY2hhbm5lbENsYWltSWQgPSBib2R5LmNoYW5uZWxDbGFpbUlkO1xuICAgIGNvbnN0IGNsYWltTmFtZSA9IGJvZHkuY2xhaW1OYW1lO1xuICAgIGNvbnN0IGNsYWltSWQgPSBib2R5LmNsYWltSWQ7XG4gICAgZ2V0Q2xhaW1JZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSwgY2xhaW1JZClcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQgPT09IE5PX0NIQU5ORUwpIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gbWF0Y2hpbmcgY2hhbm5lbCBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0ID09PSBOT19DTEFJTSkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdObyBtYXRjaGluZyBjbGFpbSBpZCBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfVxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogcmVzdWx0fSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIGFwcC5nZXQoJy9hcGkvY2xhaW0vZGF0YS86Y2xhaW1OYW1lLzpjbGFpbUlkJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgY2xhaW1OYW1lID0gcGFyYW1zLmNsYWltTmFtZTtcbiAgICBsZXQgY2xhaW1JZCA9IHBhcmFtcy5jbGFpbUlkO1xuICAgIGlmIChjbGFpbUlkID09PSAnbm9uZScpIGNsYWltSWQgPSBudWxsO1xuICAgIGRiLkNsYWltLnJlc29sdmVDbGFpbShjbGFpbU5hbWUsIGNsYWltSWQpXG4gICAgICAudGhlbihjbGFpbUluZm8gPT4ge1xuICAgICAgICBpZiAoIWNsYWltSW5mbykge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdObyBjbGFpbSBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfVxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogY2xhaW1JbmZvfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIHNlZSBpZiBhc3NldCBpcyBhdmFpbGFibGUgbG9jYWxseVxuICBhcHAuZ2V0KCcvYXBpL2ZpbGUvYXZhaWxhYmlsaXR5LzpuYW1lLzpjbGFpbUlkJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IHBhcmFtcy5uYW1lO1xuICAgIGNvbnN0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcbiAgICBkYi5GaWxlLmZpbmRPbmUoe3doZXJlOiB7bmFtZSwgY2xhaW1JZH19KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogdHJ1ZX0pO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhOiBmYWxzZX0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpLXJvdXRlcy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNvbm5lY3QtbXVsdGlwYXJ0eVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImNvbm5lY3QtbXVsdGlwYXJ0eVwiXG4vLyBtb2R1bGUgaWQgPSA3N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBkYiA9IHJlcXVpcmUoJy4uL21vZGVscy9pbmRleCcpO1xuY29uc3QgbGJyeUFwaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeUFwaS5qcycpO1xuY29uc3QgcHVibGlzaEhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL3B1Ymxpc2hIZWxwZXJzLmpzJyk7XG5jb25zdCB7IHB1Ymxpc2hpbmc6IHsgcHJpbWFyeUNsYWltQWRkcmVzcywgYWRkaXRpb25hbENsYWltQWRkcmVzc2VzIH0gfSA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9zaXRlQ29uZmlnLmpzJyk7XG5jb25zdCBTZXF1ZWxpemUgPSByZXF1aXJlKCdzZXF1ZWxpemUnKTtcbmNvbnN0IE9wID0gU2VxdWVsaXplLk9wO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcHVibGlzaCAocHVibGlzaFBhcmFtcywgZmlsZU5hbWUsIGZpbGVUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBwdWJsaXNoUmVzdWx0cywgY2VydGlmaWNhdGVJZCwgY2hhbm5lbE5hbWU7XG4gICAgICAvLyBwdWJsaXNoIHRoZSBmaWxlXG4gICAgICByZXR1cm4gbGJyeUFwaS5wdWJsaXNoQ2xhaW0ocHVibGlzaFBhcmFtcylcbiAgICAgICAgLnRoZW4odHggPT4ge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKGBTdWNjZXNzZnVsbHkgcHVibGlzaGVkICR7cHVibGlzaFBhcmFtcy5uYW1lfSAke2ZpbGVOYW1lfWAsIHR4KTtcbiAgICAgICAgICBwdWJsaXNoUmVzdWx0cyA9IHR4O1xuICAgICAgICAgIC8vIGdldCB0aGUgY2hhbm5lbCBpbmZvcm1hdGlvblxuICAgICAgICAgIGlmIChwdWJsaXNoUGFyYW1zLmNoYW5uZWxfbmFtZSkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGB0aGlzIGNsYWltIHdhcyBwdWJsaXNoZWQgaW4gY2hhbm5lbDogJHtwdWJsaXNoUGFyYW1zLmNoYW5uZWxfbmFtZX1gKTtcbiAgICAgICAgICAgIHJldHVybiBkYi5DaGFubmVsLmZpbmRPbmUoe3doZXJlOiB7Y2hhbm5lbE5hbWU6IHB1Ymxpc2hQYXJhbXMuY2hhbm5lbF9uYW1lfX0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ3RoaXMgY2xhaW0gd2FzIG5vdCBwdWJsaXNoZWQgaW4gYSBjaGFubmVsJyk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNoYW5uZWwgPT4ge1xuICAgICAgICAvLyBzZXQgY2hhbm5lbCBpbmZvcm1hdGlvblxuICAgICAgICAgIGNlcnRpZmljYXRlSWQgPSBudWxsO1xuICAgICAgICAgIGNoYW5uZWxOYW1lID0gbnVsbDtcbiAgICAgICAgICBpZiAoY2hhbm5lbCkge1xuICAgICAgICAgICAgY2VydGlmaWNhdGVJZCA9IGNoYW5uZWwuY2hhbm5lbENsYWltSWQ7XG4gICAgICAgICAgICBjaGFubmVsTmFtZSA9IGNoYW5uZWwuY2hhbm5lbE5hbWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgY2VydGlmaWNhdGVJZDogJHtjZXJ0aWZpY2F0ZUlkfWApO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgRmlsZSByZWNvcmRcbiAgICAgICAgICBjb25zdCBmaWxlUmVjb3JkID0ge1xuICAgICAgICAgICAgbmFtZSAgICAgICA6IHB1Ymxpc2hQYXJhbXMubmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQgICAgOiBwdWJsaXNoUmVzdWx0cy5jbGFpbV9pZCxcbiAgICAgICAgICAgIHRpdGxlICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLnRpdGxlLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBhZGRyZXNzICAgIDogcHVibGlzaFBhcmFtcy5jbGFpbV9hZGRyZXNzLFxuICAgICAgICAgICAgb3V0cG9pbnQgICA6IGAke3B1Ymxpc2hSZXN1bHRzLnR4aWR9OiR7cHVibGlzaFJlc3VsdHMubm91dH1gLFxuICAgICAgICAgICAgaGVpZ2h0ICAgICA6IDAsXG4gICAgICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgICAgIGZpbGVQYXRoICAgOiBwdWJsaXNoUGFyYW1zLmZpbGVfcGF0aCxcbiAgICAgICAgICAgIGZpbGVUeXBlLFxuICAgICAgICAgICAgbnNmdyAgICAgICA6IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEubnNmdyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgQ2xhaW0gcmVjb3JkXG4gICAgICAgICAgY29uc3QgY2xhaW1SZWNvcmQgPSB7XG4gICAgICAgICAgICBuYW1lICAgICAgIDogcHVibGlzaFBhcmFtcy5uYW1lLFxuICAgICAgICAgICAgY2xhaW1JZCAgICA6IHB1Ymxpc2hSZXN1bHRzLmNsYWltX2lkLFxuICAgICAgICAgICAgdGl0bGUgICAgICA6IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEudGl0bGUsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICAgICAgICAgIGFkZHJlc3MgICAgOiBwdWJsaXNoUGFyYW1zLmNsYWltX2FkZHJlc3MsXG4gICAgICAgICAgICB0aHVtYm5haWwgIDogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS50aHVtYm5haWwsXG4gICAgICAgICAgICBvdXRwb2ludCAgIDogYCR7cHVibGlzaFJlc3VsdHMudHhpZH06JHtwdWJsaXNoUmVzdWx0cy5ub3V0fWAsXG4gICAgICAgICAgICBoZWlnaHQgICAgIDogMCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmaWxlVHlwZSxcbiAgICAgICAgICAgIG5zZncgICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLm5zZncsXG4gICAgICAgICAgICBhbW91bnQgICAgIDogcHVibGlzaFBhcmFtcy5iaWQsXG4gICAgICAgICAgICBjZXJ0aWZpY2F0ZUlkLFxuICAgICAgICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyB1cHNlcnQgY3JpdGVyaWFcbiAgICAgICAgICBjb25zdCB1cHNlcnRDcml0ZXJpYSA9IHtcbiAgICAgICAgICAgIG5hbWUgICA6IHB1Ymxpc2hQYXJhbXMubmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHB1Ymxpc2hSZXN1bHRzLmNsYWltX2lkLFxuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gdXBzZXJ0IHRoZSByZWNvcmRzXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtkYi51cHNlcnQoZGIuRmlsZSwgZmlsZVJlY29yZCwgdXBzZXJ0Q3JpdGVyaWEsICdGaWxlJyksIGRiLnVwc2VydChkYi5DbGFpbSwgY2xhaW1SZWNvcmQsIHVwc2VydENyaXRlcmlhLCAnQ2xhaW0nKV0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2ZpbGUsIGNsYWltXSkgPT4ge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnRmlsZSBhbmQgQ2xhaW0gcmVjb3JkcyBzdWNjZXNzZnVsbHkgY3JlYXRlZCcpO1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZmlsZS5zZXRDbGFpbShjbGFpbSksIGNsYWltLnNldEZpbGUoZmlsZSldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnRmlsZSBhbmQgQ2xhaW0gcmVjb3JkcyBzdWNjZXNzZnVsbHkgYXNzb2NpYXRlZCcpO1xuICAgICAgICAgIHJlc29sdmUocHVibGlzaFJlc3VsdHMpOyAvLyByZXNvbHZlIHRoZSBwcm9taXNlIHdpdGggdGhlIHJlc3VsdCBmcm9tIGxicnlBcGkucHVibGlzaENsYWltO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignUFVCTElTSCBFUlJPUicsIGVycm9yKTtcbiAgICAgICAgICBwdWJsaXNoSGVscGVycy5kZWxldGVUZW1wb3JhcnlGaWxlKHB1Ymxpc2hQYXJhbXMuZmlsZV9wYXRoKTsgLy8gZGVsZXRlIHRoZSBsb2NhbCBmaWxlXG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGNsYWltTmFtZUlzQXZhaWxhYmxlIChuYW1lKSB7XG4gICAgY29uc3QgY2xhaW1BZGRyZXNzZXMgPSBhZGRpdGlvbmFsQ2xhaW1BZGRyZXNzZXMgfHwgW107XG4gICAgY2xhaW1BZGRyZXNzZXMucHVzaChwcmltYXJ5Q2xhaW1BZGRyZXNzKTtcbiAgICAvLyBmaW5kIGFueSByZWNvcmRzIHdoZXJlIHRoZSBuYW1lIGlzIHVzZWRcbiAgICByZXR1cm4gZGIuQ2xhaW1cbiAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgYXR0cmlidXRlczogWydhZGRyZXNzJ10sXG4gICAgICAgIHdoZXJlICAgICA6IHtcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgICAgIFtPcC5vcl06IGNsYWltQWRkcmVzc2VzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPj0gMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhhdCBjbGFpbSBpcyBhbHJlYWR5IGluIHVzZScpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICB9LFxuICBjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkgKG5hbWUpIHtcbiAgICByZXR1cm4gZGIuQ2hhbm5lbFxuICAgICAgLmZpbmRBbGwoe1xuICAgICAgICB3aGVyZTogeyBjaGFubmVsTmFtZTogbmFtZSB9LFxuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID49IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoYXQgY2hhbm5lbCBoYXMgYWxyZWFkeSBiZWVuIGNsYWltZWQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9jb250cm9sbGVycy9wdWJsaXNoQ29udHJvbGxlci5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImZzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiZnNcIlxuLy8gbW9kdWxlIGlkID0gNzlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgZGIgPSByZXF1aXJlKCcuLi9tb2RlbHMvaW5kZXgnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGF1dGhlbnRpY2F0ZVVzZXIgKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCwgdXNlcikge1xuICAgIC8vIGNhc2U6IG5vIGNoYW5uZWxOYW1lIG9yIGNoYW5uZWwgSWQgYXJlIHByb3ZpZGVkIChhbm9ueW1vdXMpLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdXNlciB0b2tlbiBpcyBwcm92aWRlZFxuICAgIGlmICghY2hhbm5lbE5hbWUgJiYgIWNoYW5uZWxJZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2hhbm5lbE5hbWUgICA6IG51bGwsXG4gICAgICAgIGNoYW5uZWxDbGFpbUlkOiBudWxsLFxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gY2FzZTogY2hhbm5lbE5hbWUgb3IgY2hhbm5lbCBJZCBhcmUgcHJvdmlkZWQgd2l0aCB1c2VyIHRva2VuXG4gICAgaWYgKHVzZXIpIHtcbiAgICAgIGlmIChjaGFubmVsTmFtZSAmJiBjaGFubmVsTmFtZSAhPT0gdXNlci5jaGFubmVsTmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBwcm92aWRlZCBjaGFubmVsIG5hbWUgZG9lcyBub3QgbWF0Y2ggdXNlciBjcmVkZW50aWFscycpO1xuICAgICAgfVxuICAgICAgaWYgKGNoYW5uZWxJZCAmJiBjaGFubmVsSWQgIT09IHVzZXIuY2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgcHJvdmlkZWQgY2hhbm5lbCBpZCBkb2VzIG5vdCBtYXRjaCB1c2VyIGNyZWRlbnRpYWxzJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjaGFubmVsTmFtZSAgIDogdXNlci5jaGFubmVsTmFtZSxcbiAgICAgICAgY2hhbm5lbENsYWltSWQ6IHVzZXIuY2hhbm5lbENsYWltSWQsXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBjYXNlOiBjaGFubmVsTmFtZSBvciBjaGFubmVsIElkIGFyZSBwcm92aWRlZCB3aXRoIHBhc3N3b3JkIGluc3RlYWQgb2YgdXNlciB0b2tlblxuICAgIGlmICghY2hhbm5lbFBhc3N3b3JkKSB0aHJvdyBuZXcgRXJyb3IoJ25vIGNoYW5uZWwgcGFzc3dvcmQgcHJvdmlkZWQnKTtcbiAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuYXV0aGVudGljYXRlQ2hhbm5lbENyZWRlbnRpYWxzKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCk7XG4gIH0sXG4gIGF1dGhlbnRpY2F0ZUNoYW5uZWxDcmVkZW50aWFscyAoY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgdXNlclBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIGhvaXN0ZWQgdmFyaWFibGVzXG4gICAgICBsZXQgY2hhbm5lbERhdGE7XG4gICAgICAvLyBidWlsZCB0aGUgcGFyYW1zIGZvciBmaW5kaW5nIHRoZSBjaGFubmVsXG4gICAgICBsZXQgY2hhbm5lbEZpbmRQYXJhbXMgPSB7fTtcbiAgICAgIGlmIChjaGFubmVsTmFtZSkgY2hhbm5lbEZpbmRQYXJhbXNbJ2NoYW5uZWxOYW1lJ10gPSBjaGFubmVsTmFtZTtcbiAgICAgIGlmIChjaGFubmVsSWQpIGNoYW5uZWxGaW5kUGFyYW1zWydjaGFubmVsQ2xhaW1JZCddID0gY2hhbm5lbElkO1xuICAgICAgLy8gZmluZCB0aGUgY2hhbm5lbFxuICAgICAgZGIuQ2hhbm5lbFxuICAgICAgICAuZmluZE9uZSh7XG4gICAgICAgICAgd2hlcmU6IGNoYW5uZWxGaW5kUGFyYW1zLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihjaGFubmVsID0+IHtcbiAgICAgICAgICBpZiAoIWNoYW5uZWwpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1Zygnbm8gY2hhbm5lbCBmb3VuZCcpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBdXRoZW50aWNhdGlvbiBmYWlsZWQsIHlvdSBkbyBub3QgaGF2ZSBhY2Nlc3MgdG8gdGhhdCBjaGFubmVsJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNoYW5uZWxEYXRhID0gY2hhbm5lbC5nZXQoKTtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ2NoYW5uZWwgZGF0YTonLCBjaGFubmVsRGF0YSk7XG4gICAgICAgICAgcmV0dXJuIGRiLlVzZXIuZmluZE9uZSh7XG4gICAgICAgICAgICB3aGVyZTogeyB1c2VyTmFtZTogY2hhbm5lbERhdGEuY2hhbm5lbE5hbWUuc3Vic3RyaW5nKDEpIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdubyB1c2VyIGZvdW5kJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCwgeW91IGRvIG5vdCBoYXZlIGFjY2VzcyB0byB0aGF0IGNoYW5uZWwnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHVzZXIuY29tcGFyZVBhc3N3b3JkKHVzZXJQYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGlzTWF0Y2ggPT4ge1xuICAgICAgICAgIGlmICghaXNNYXRjaCkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdpbmNvcnJlY3QgcGFzc3dvcmQnKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQXV0aGVudGljYXRpb24gZmFpbGVkLCB5b3UgZG8gbm90IGhhdmUgYWNjZXNzIHRvIHRoYXQgY2hhbm5lbCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsb2dnZXIuZGVidWcoJy4uLnBhc3N3b3JkIHdhcyBhIG1hdGNoLi4uJyk7XG4gICAgICAgICAgcmVzb2x2ZShjaGFubmVsRGF0YSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2F1dGgvYXV0aGVudGljYXRpb24uanMiLCJjb25zdCBDTEFJTVNfUEVSX1BBR0UgPSAxMjtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJldHVyblBhZ2luYXRlZENoYW5uZWxDbGFpbXMgKGNoYW5uZWxOYW1lLCBsb25nQ2hhbm5lbENsYWltSWQsIGNsYWltcywgcGFnZSkge1xuICAgIGNvbnN0IHRvdGFsUGFnZXMgPSBtb2R1bGUuZXhwb3J0cy5kZXRlcm1pbmVUb3RhbFBhZ2VzKGNsYWltcyk7XG4gICAgY29uc3QgcGFnaW5hdGlvblBhZ2UgPSBtb2R1bGUuZXhwb3J0cy5nZXRQYWdlRnJvbVF1ZXJ5KHBhZ2UpO1xuICAgIGNvbnN0IHZpZXdEYXRhID0ge1xuICAgICAgY2hhbm5lbE5hbWUgICAgICAgOiBjaGFubmVsTmFtZSxcbiAgICAgIGxvbmdDaGFubmVsQ2xhaW1JZDogbG9uZ0NoYW5uZWxDbGFpbUlkLFxuICAgICAgY2xhaW1zICAgICAgICAgICAgOiBtb2R1bGUuZXhwb3J0cy5leHRyYWN0UGFnZUZyb21DbGFpbXMoY2xhaW1zLCBwYWdpbmF0aW9uUGFnZSksXG4gICAgICBwcmV2aW91c1BhZ2UgICAgICA6IG1vZHVsZS5leHBvcnRzLmRldGVybWluZVByZXZpb3VzUGFnZShwYWdpbmF0aW9uUGFnZSksXG4gICAgICBjdXJyZW50UGFnZSAgICAgICA6IHBhZ2luYXRpb25QYWdlLFxuICAgICAgbmV4dFBhZ2UgICAgICAgICAgOiBtb2R1bGUuZXhwb3J0cy5kZXRlcm1pbmVOZXh0UGFnZSh0b3RhbFBhZ2VzLCBwYWdpbmF0aW9uUGFnZSksXG4gICAgICB0b3RhbFBhZ2VzICAgICAgICA6IHRvdGFsUGFnZXMsXG4gICAgICB0b3RhbFJlc3VsdHMgICAgICA6IG1vZHVsZS5leHBvcnRzLmRldGVybWluZVRvdGFsQ2xhaW1zKGNsYWltcyksXG4gICAgfTtcbiAgICByZXR1cm4gdmlld0RhdGE7XG4gIH0sXG4gIGdldFBhZ2VGcm9tUXVlcnkgKHBhZ2UpIHtcbiAgICBpZiAocGFnZSkge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHBhZ2UpO1xuICAgIH1cbiAgICByZXR1cm4gMTtcbiAgfSxcbiAgZXh0cmFjdFBhZ2VGcm9tQ2xhaW1zIChjbGFpbXMsIHBhZ2VOdW1iZXIpIHtcbiAgICBpZiAoIWNsYWltcykge1xuICAgICAgcmV0dXJuIFtdOyAgLy8gaWYgbm8gY2xhaW1zLCByZXR1cm4gdGhpcyBkZWZhdWx0XG4gICAgfVxuICAgIC8vIGxvZ2dlci5kZWJ1ZygnY2xhaW1zIGlzIGFycmF5PycsIEFycmF5LmlzQXJyYXkoY2xhaW1zKSk7XG4gICAgLy8gbG9nZ2VyLmRlYnVnKGBwYWdlTnVtYmVyICR7cGFnZU51bWJlcn0gaXMgbnVtYmVyP2AsIE51bWJlci5pc0ludGVnZXIocGFnZU51bWJlcikpO1xuICAgIGNvbnN0IGNsYWltU3RhcnRJbmRleCA9IChwYWdlTnVtYmVyIC0gMSkgKiBDTEFJTVNfUEVSX1BBR0U7XG4gICAgY29uc3QgY2xhaW1FbmRJbmRleCA9IGNsYWltU3RhcnRJbmRleCArIENMQUlNU19QRVJfUEFHRTtcbiAgICBjb25zdCBwYWdlT2ZDbGFpbXMgPSBjbGFpbXMuc2xpY2UoY2xhaW1TdGFydEluZGV4LCBjbGFpbUVuZEluZGV4KTtcbiAgICByZXR1cm4gcGFnZU9mQ2xhaW1zO1xuICB9LFxuICBkZXRlcm1pbmVUb3RhbFBhZ2VzIChjbGFpbXMpIHtcbiAgICBpZiAoIWNsYWltcykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRvdGFsQ2xhaW1zID0gY2xhaW1zLmxlbmd0aDtcbiAgICAgIGlmICh0b3RhbENsYWltcyA8IENMQUlNU19QRVJfUEFHRSkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZ1bGxQYWdlcyA9IE1hdGguZmxvb3IodG90YWxDbGFpbXMgLyBDTEFJTVNfUEVSX1BBR0UpO1xuICAgICAgY29uc3QgcmVtYWluZGVyID0gdG90YWxDbGFpbXMgJSBDTEFJTVNfUEVSX1BBR0U7XG4gICAgICBpZiAocmVtYWluZGVyID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmdWxsUGFnZXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVsbFBhZ2VzICsgMTtcbiAgICB9XG4gIH0sXG4gIGRldGVybWluZVByZXZpb3VzUGFnZSAoY3VycmVudFBhZ2UpIHtcbiAgICBpZiAoY3VycmVudFBhZ2UgPT09IDEpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudFBhZ2UgLSAxO1xuICB9LFxuICBkZXRlcm1pbmVOZXh0UGFnZSAodG90YWxQYWdlcywgY3VycmVudFBhZ2UpIHtcbiAgICBpZiAoY3VycmVudFBhZ2UgPT09IHRvdGFsUGFnZXMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudFBhZ2UgKyAxO1xuICB9LFxuICBkZXRlcm1pbmVUb3RhbENsYWltcyAoY2xhaW1zKSB7XG4gICAgaWYgKCFjbGFpbXMpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gY2xhaW1zLmxlbmd0aDtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvaGVscGVycy9jaGFubmVsUGFnaW5hdGlvbi5qcyIsImNvbnN0IHsgZGV0YWlsczogaG9zdCB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcbmNvbnN0IGhhbmRsZVBhZ2VSZW5kZXIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKGFwcCkgPT4ge1xuICAvLyByb3V0ZSBmb3IgdGhlIGhvbWUgcGFnZVxuICBhcHAuZ2V0KCcvJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgaGFuZGxlUGFnZVJlbmRlcihyZXEsIHJlcyk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBkaXNwbGF5IGxvZ2luIHBhZ2VcbiAgYXBwLmdldCgnL2xvZ2luJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgaGFuZGxlUGFnZVJlbmRlcihyZXEsIHJlcyk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBzaG93ICdhYm91dCcgcGFnZVxuICBhcHAuZ2V0KCcvYWJvdXQnLCAocmVxLCByZXMpID0+IHtcbiAgICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGRpc3BsYXkgYSBsaXN0IG9mIHRoZSB0cmVuZGluZyBpbWFnZXNcbiAgYXBwLmdldCgnL3RyZW5kaW5nJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgcmVzLnN0YXR1cygzMDEpLnJlZGlyZWN0KCcvcG9wdWxhcicpO1xuICB9KTtcbiAgYXBwLmdldCgnL3BvcHVsYXInLCAocmVxLCByZXMpID0+IHtcbiAgICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGRpc3BsYXkgYSBsaXN0IG9mIHRoZSB0cmVuZGluZyBpbWFnZXNcbiAgYXBwLmdldCgnL25ldycsIChyZXEsIHJlcykgPT4ge1xuICAgIGhhbmRsZVBhZ2VSZW5kZXIocmVxLCByZXMpO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gc2VuZCBlbWJlZGFibGUgdmlkZW8gcGxheWVyIChmb3IgdHdpdHRlcilcbiAgYXBwLmdldCgnL2VtYmVkLzpjbGFpbUlkLzpuYW1lJywgKHsgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGNvbnN0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcbiAgICBjb25zdCBuYW1lID0gcGFyYW1zLm5hbWU7XG4gICAgLy8gZ2V0IGFuZCByZW5kZXIgdGhlIGNvbnRlbnRcbiAgICByZXMuc3RhdHVzKDIwMCkucmVuZGVyKCdlbWJlZCcsIHsgbGF5b3V0OiAnZW1iZWQnLCBob3N0LCBjbGFpbUlkLCBuYW1lIH0pO1xuICB9KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL3BhZ2Utcm91dGVzLmpzIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgTE9HSU4gfSBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jaGFubmVsX3NlbGVjdF9zdGF0ZXMnO1xuY29uc3QgeyBwdWJsaXNoaW5nIH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvc2l0ZUNvbmZpZy5qcycpO1xuXG5jb25zdCBpbml0aWFsU3RhdGUgPSB7XG4gIGRpc2FibGVkICAgICAgICAgIDogcHVibGlzaGluZy5kaXNhYmxlZCxcbiAgZGlzYWJsZWRNZXNzYWdlICAgOiBwdWJsaXNoaW5nLmRpc2FibGVkTWVzc2FnZSxcbiAgcHVibGlzaEluQ2hhbm5lbCAgOiBmYWxzZSxcbiAgc2VsZWN0ZWRDaGFubmVsICAgOiBMT0dJTixcbiAgc2hvd01ldGFkYXRhSW5wdXRzOiBmYWxzZSxcbiAgc3RhdHVzICAgICAgICAgICAgOiB7XG4gICAgc3RhdHVzIDogbnVsbCxcbiAgICBtZXNzYWdlOiBudWxsLFxuICB9LFxuICBlcnJvcjoge1xuICAgIGZpbGUgICAgICAgICA6IG51bGwsXG4gICAgdXJsICAgICAgICAgIDogbnVsbCxcbiAgICBjaGFubmVsICAgICAgOiBudWxsLFxuICAgIHB1Ymxpc2hTdWJtaXQ6IG51bGwsXG4gIH0sXG4gIGZpbGUgICAgOiBudWxsLFxuICBjbGFpbSAgIDogJycsXG4gIG1ldGFkYXRhOiB7XG4gICAgdGl0bGUgICAgICA6ICcnLFxuICAgIGRlc2NyaXB0aW9uOiAnJyxcbiAgICBsaWNlbnNlICAgIDogJycsXG4gICAgbnNmdyAgICAgICA6IGZhbHNlLFxuICB9LFxuICB0aHVtYm5haWw6IG51bGwsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUgPSBpbml0aWFsU3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgY2FzZSBhY3Rpb25zLkZJTEVfU0VMRUNURUQ6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgaW5pdGlhbFN0YXRlLCB7ICAvLyBub3RlOiBjbGVhcnMgdG8gaW5pdGlhbCBzdGF0ZVxuICAgICAgICBmaWxlOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5GSUxFX0NMRUFSOlxuICAgICAgcmV0dXJuIGluaXRpYWxTdGF0ZTtcbiAgICBjYXNlIGFjdGlvbnMuTUVUQURBVEFfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIG1ldGFkYXRhOiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5tZXRhZGF0YSwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5uYW1lXTogYWN0aW9uLmRhdGEudmFsdWUsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLkNMQUlNX1VQREFURTpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBjbGFpbTogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuU0VUX1BVQkxJU0hfSU5fQ0hBTk5FTDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBwdWJsaXNoSW5DaGFubmVsOiBhY3Rpb24uY2hhbm5lbCxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5QVUJMSVNIX1NUQVRVU19VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgc3RhdHVzOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5FUlJPUl9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgZXJyb3I6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmVycm9yLCB7XG4gICAgICAgICAgW2FjdGlvbi5kYXRhLm5hbWVdOiBhY3Rpb24uZGF0YS52YWx1ZSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuU0VMRUNURURfQ0hBTk5FTF9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgc2VsZWN0ZWRDaGFubmVsOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5UT0dHTEVfTUVUQURBVEFfSU5QVVRTOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHNob3dNZXRhZGF0YUlucHV0czogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuVEhVTUJOQUlMX05FVzpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICB0aHVtYm5haWw6IGFjdGlvbi5kYXRhLFxuICAgICAgfSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3JlZHVjZXJzL3B1Ymxpc2guanMiLCJpbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9jaGFubmVsX2FjdGlvbl90eXBlcyc7XG5cbmNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgbG9nZ2VkSW5DaGFubmVsOiB7XG4gICAgbmFtZSAgIDogbnVsbCxcbiAgICBzaG9ydElkOiBudWxsLFxuICAgIGxvbmdJZCA6IG51bGwsXG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUgPSBpbml0aWFsU3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgY2FzZSBhY3Rpb25zLkNIQU5ORUxfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGxvZ2dlZEluQ2hhbm5lbDogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcmVkdWNlcnMvY2hhbm5lbC5qcyIsImltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL3Nob3dfYWN0aW9uX3R5cGVzJztcbmltcG9ydCB7IExPQ0FMX0NIRUNLLCBFUlJPUiB9IGZyb20gJ2NvbnN0YW50cy9hc3NldF9kaXNwbGF5X3N0YXRlcyc7XG5cbmNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgcmVxdWVzdDoge1xuICAgIGVycm9yOiBudWxsLFxuICAgIHR5cGUgOiBudWxsLFxuICAgIGlkICAgOiBudWxsLFxuICB9LFxuICByZXF1ZXN0TGlzdCA6IHt9LFxuICBjaGFubmVsTGlzdCA6IHt9LFxuICBhc3NldExpc3QgICA6IHt9LFxuICBkaXNwbGF5QXNzZXQ6IHtcbiAgICBlcnJvciA6IG51bGwsXG4gICAgc3RhdHVzOiBMT0NBTF9DSEVDSyxcbiAgfSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGF0ZSA9IGluaXRpYWxTdGF0ZSwgYWN0aW9uKSB7XG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAvLyBoYW5kbGUgcmVxdWVzdFxuICAgIGNhc2UgYWN0aW9ucy5SRVFVRVNUX0VSUk9SOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHJlcXVlc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlcXVlc3QsIHtcbiAgICAgICAgICBlcnJvcjogYWN0aW9uLmRhdGEsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLlJFUVVFU1RfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHJlcXVlc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlcXVlc3QsIHtcbiAgICAgICAgICB0eXBlOiBhY3Rpb24uZGF0YS5yZXF1ZXN0VHlwZSxcbiAgICAgICAgICBpZCAgOiBhY3Rpb24uZGF0YS5yZXF1ZXN0SWQsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgLy8gc3RvcmUgcmVxdWVzdHNcbiAgICBjYXNlIGFjdGlvbnMuUkVRVUVTVF9MSVNUX0FERDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICByZXF1ZXN0TGlzdDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVxdWVzdExpc3QsIHtcbiAgICAgICAgICBbYWN0aW9uLmRhdGEuaWRdOiB7XG4gICAgICAgICAgICBlcnJvcjogYWN0aW9uLmRhdGEuZXJyb3IsXG4gICAgICAgICAgICBrZXkgIDogYWN0aW9uLmRhdGEua2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgLy8gYXNzZXQgZGF0YVxuICAgIGNhc2UgYWN0aW9ucy5BU1NFVF9BREQ6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgYXNzZXRMaXN0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5hc3NldExpc3QsIHtcbiAgICAgICAgICBbYWN0aW9uLmRhdGEuaWRdOiB7XG4gICAgICAgICAgICBlcnJvciAgICA6IGFjdGlvbi5kYXRhLmVycm9yLFxuICAgICAgICAgICAgbmFtZSAgICAgOiBhY3Rpb24uZGF0YS5uYW1lLFxuICAgICAgICAgICAgY2xhaW1JZCAgOiBhY3Rpb24uZGF0YS5jbGFpbUlkLFxuICAgICAgICAgICAgc2hvcnRJZCAgOiBhY3Rpb24uZGF0YS5zaG9ydElkLFxuICAgICAgICAgICAgY2xhaW1EYXRhOiBhY3Rpb24uZGF0YS5jbGFpbURhdGEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAvLyBjaGFubmVsIGRhdGFcbiAgICBjYXNlIGFjdGlvbnMuQ0hBTk5FTF9BREQ6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgY2hhbm5lbExpc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmNoYW5uZWxMaXN0LCB7XG4gICAgICAgICAgW2FjdGlvbi5kYXRhLmlkXToge1xuICAgICAgICAgICAgbmFtZSAgICAgIDogYWN0aW9uLmRhdGEubmFtZSxcbiAgICAgICAgICAgIGxvbmdJZCAgICA6IGFjdGlvbi5kYXRhLmxvbmdJZCxcbiAgICAgICAgICAgIHNob3J0SWQgICA6IGFjdGlvbi5kYXRhLnNob3J0SWQsXG4gICAgICAgICAgICBjbGFpbXNEYXRhOiBhY3Rpb24uZGF0YS5jbGFpbXNEYXRhLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLkNIQU5ORUxfQ0xBSU1TX1VQREFURV9TVUNDRVNTOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGNoYW5uZWxMaXN0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5jaGFubmVsTGlzdCwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5jaGFubmVsTGlzdElkXTogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuY2hhbm5lbExpc3RbYWN0aW9uLmRhdGEuY2hhbm5lbExpc3RJZF0sIHtcbiAgICAgICAgICAgIGNsYWltc0RhdGE6IGFjdGlvbi5kYXRhLmNsYWltc0RhdGEsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgLy8gZGlzcGxheSBhbiBhc3NldFxuICAgIGNhc2UgYWN0aW9ucy5GSUxFX0FWQUlMQUJJTElUWV9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgZGlzcGxheUFzc2V0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5kaXNwbGF5QXNzZXQsIHtcbiAgICAgICAgICBzdGF0dXM6IGFjdGlvbi5kYXRhLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5ESVNQTEFZX0FTU0VUX0VSUk9SOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGRpc3BsYXlBc3NldDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuZGlzcGxheUFzc2V0LCB7XG4gICAgICAgICAgZXJyb3IgOiBhY3Rpb24uZGF0YSxcbiAgICAgICAgICBzdGF0dXM6IEVSUk9SLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9yZWR1Y2Vycy9zaG93LmpzIiwiY29uc3Qgc2l0ZUNvbmZpZyA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9zaXRlQ29uZmlnLmpzJyk7XG5cbmNvbnN0IHtcbiAgYW5hbHl0aWNzOiB7XG4gICAgZ29vZ2xlSWQ6IGdvb2dsZUFuYWx5dGljc0lkLFxuICB9LFxuICBhc3NldERlZmF1bHRzOiB7XG4gICAgdGh1bWJuYWlsOiBkZWZhdWx0VGh1bWJuYWlsLFxuICAgIGRlc2NyaXB0aW9uOiBkZWZhdWx0RGVzY3JpcHRpb24sXG4gIH0sXG4gIGRldGFpbHM6IHtcbiAgICBkZXNjcmlwdGlvbixcbiAgICBob3N0LFxuICAgIHRpdGxlLFxuICAgIHR3aXR0ZXIsXG4gIH0sXG59ID0gc2l0ZUNvbmZpZztcblxuY29uc3QgaW5pdGlhbFN0YXRlID0ge1xuICBkZXNjcmlwdGlvbixcbiAgZ29vZ2xlQW5hbHl0aWNzSWQsXG4gIGhvc3QsXG4gIHRpdGxlLFxuICB0d2l0dGVyLFxuICBkZWZhdWx0RGVzY3JpcHRpb24sXG4gIGRlZmF1bHRUaHVtYm5haWwsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUgPSBpbml0aWFsU3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3JlZHVjZXJzL3NpdGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdC1nYVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWdhXCJcbi8vIG1vZHVsZSBpZCA9IDg3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IFB1Ymxpc2hUb29sIGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaFRvb2wnO1xuXG5jbGFzcyBIb21lUGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPXsncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uJ30+XG4gICAgICAgIDxTRU8gLz5cbiAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT17J3JvdyByb3ctLXRhbGwgcm93LS1wYWRkZWQgZmxleC1jb250YWluZXItLWNvbHVtbid9PlxuICAgICAgICAgIDxQdWJsaXNoVG9vbCAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEhvbWVQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3BhZ2VzL0hvbWVQYWdlL2luZGV4LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgSGVsbWV0IGZyb20gJ3JlYWN0LWhlbG1ldCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVQYWdlVGl0bGUgfSBmcm9tICd1dGlscy9wYWdlVGl0bGUnO1xuaW1wb3J0IHsgY3JlYXRlTWV0YVRhZ3MgfSBmcm9tICd1dGlscy9tZXRhVGFncyc7XG5pbXBvcnQgeyBjcmVhdGVDYW5vbmljYWxMaW5rIH0gZnJvbSAndXRpbHMvY2Fub25pY2FsTGluayc7XG5cbmNsYXNzIFNFTyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgLy8gcHJvcHMgZnJvbSBzdGF0ZVxuICAgIGNvbnN0IHsgZGVmYXVsdERlc2NyaXB0aW9uLCBkZWZhdWx0VGh1bWJuYWlsLCBzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyIH0gPSB0aGlzLnByb3BzO1xuICAgIC8vIHByb3BzIGZyb20gcGFyZW50XG4gICAgY29uc3QgeyBhc3NldCwgY2hhbm5lbCwgcGFnZVVyaSB9ID0gdGhpcy5wcm9wcztcbiAgICBsZXQgeyBwYWdlVGl0bGUgfSA9IHRoaXMucHJvcHM7XG4gICAgLy8gY3JlYXRlIHBhZ2UgdGl0bGUsIHRhZ3MsIGFuZCBjYW5vbmljYWwgbGlua1xuICAgIHBhZ2VUaXRsZSA9IGNyZWF0ZVBhZ2VUaXRsZShzaXRlVGl0bGUsIHBhZ2VUaXRsZSk7XG4gICAgY29uc3QgbWV0YVRhZ3MgPSBjcmVhdGVNZXRhVGFncyhzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyLCBhc3NldCwgY2hhbm5lbCwgZGVmYXVsdERlc2NyaXB0aW9uLCBkZWZhdWx0VGh1bWJuYWlsKTtcbiAgICBjb25zdCBjYW5vbmljYWxMaW5rID0gY3JlYXRlQ2Fub25pY2FsTGluayhhc3NldCwgY2hhbm5lbCwgcGFnZVVyaSwgc2l0ZUhvc3QpO1xuICAgIC8vIHJlbmRlciByZXN1bHRzXG4gICAgcmV0dXJuIChcbiAgICAgIDxIZWxtZXRcbiAgICAgICAgdGl0bGU9e3BhZ2VUaXRsZX1cbiAgICAgICAgbWV0YT17bWV0YVRhZ3N9XG4gICAgICAgIGxpbms9e1t7cmVsOiAnY2Fub25pY2FsJywgaHJlZjogY2Fub25pY2FsTGlua31dfVxuICAgICAgLz5cbiAgICApO1xuICB9XG59O1xuXG5TRU8ucHJvcFR5cGVzID0ge1xuICBwYWdlVGl0bGU6IFByb3BUeXBlcy5zdHJpbmcsXG4gIHBhZ2VVcmkgIDogUHJvcFR5cGVzLnN0cmluZyxcbiAgY2hhbm5lbCAgOiBQcm9wVHlwZXMub2JqZWN0LFxuICBhc3NldCAgICA6IFByb3BUeXBlcy5vYmplY3QsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBTRU87XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9TRU8vdmlldy5qc3giLCJleHBvcnQgY29uc3QgY3JlYXRlUGFnZVRpdGxlID0gKHNpdGVUaXRsZSwgcGFnZVRpdGxlKSA9PiB7XG4gIGlmICghcGFnZVRpdGxlKSB7XG4gICAgcmV0dXJuIGAke3NpdGVUaXRsZX1gO1xuICB9XG4gIHJldHVybiBgJHtzaXRlVGl0bGV9IC0gJHtwYWdlVGl0bGV9YDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvcGFnZVRpdGxlLmpzIiwiY29uc3QgZGV0ZXJtaW5lT2dUaHVtYm5haWxDb250ZW50VHlwZSA9ICh0aHVtYm5haWwpID0+IHtcbiAgaWYgKHRodW1ibmFpbCkge1xuICAgIGNvbnN0IGZpbGVFeHQgPSB0aHVtYm5haWwuc3Vic3RyaW5nKHRodW1ibmFpbC5sYXN0SW5kZXhPZignLicpKTtcbiAgICBzd2l0Y2ggKGZpbGVFeHQpIHtcbiAgICAgIGNhc2UgJ2pwZWcnOlxuICAgICAgY2FzZSAnanBnJzpcbiAgICAgICAgcmV0dXJuICdpbWFnZS9qcGVnJztcbiAgICAgIGNhc2UgJ3BuZyc6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvcG5nJztcbiAgICAgIGNhc2UgJ2dpZic6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvZ2lmJztcbiAgICAgIGNhc2UgJ21wNCc6XG4gICAgICAgIHJldHVybiAndmlkZW8vbXA0JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvanBlZyc7XG4gICAgfVxuICB9XG4gIHJldHVybiAnJztcbn07XG5cbmNvbnN0IGNyZWF0ZUJhc2ljTWV0YVRhZ3MgPSAoc2l0ZUhvc3QsIHNpdGVEZXNjcmlwdGlvbiwgc2l0ZVRpdGxlLCBzaXRlVHdpdHRlcikgPT4ge1xuICByZXR1cm4gW1xuICAgIHtwcm9wZXJ0eTogJ29nOnRpdGxlJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBzaXRlSG9zdH0sXG4gICAge3Byb3BlcnR5OiAnb2c6c2l0ZV9uYW1lJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzpkZXNjcmlwdGlvbicsIGNvbnRlbnQ6IHNpdGVEZXNjcmlwdGlvbn0sXG4gICAge3Byb3BlcnR5OiAndHdpdHRlcjpzaXRlJywgY29udGVudDogc2l0ZVR3aXR0ZXJ9LFxuICAgIHtwcm9wZXJ0eTogJ3R3aXR0ZXI6Y2FyZCcsIGNvbnRlbnQ6ICdzdW1tYXJ5J30sXG4gIF07XG59O1xuXG5jb25zdCBjcmVhdGVDaGFubmVsTWV0YVRhZ3MgPSAoc2l0ZVRpdGxlLCBzaXRlSG9zdCwgc2l0ZVR3aXR0ZXIsIGNoYW5uZWwpID0+IHtcbiAgY29uc3QgeyBuYW1lLCBsb25nSWQgfSA9IGNoYW5uZWw7XG4gIHJldHVybiBbXG4gICAge3Byb3BlcnR5OiAnb2c6dGl0bGUnLCBjb250ZW50OiBgJHtuYW1lfSBvbiAke3NpdGVUaXRsZX1gfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBgJHtzaXRlSG9zdH0vJHtuYW1lfToke2xvbmdJZH1gfSxcbiAgICB7cHJvcGVydHk6ICdvZzpzaXRlX25hbWUnLCBjb250ZW50OiBzaXRlVGl0bGV9LFxuICAgIHtwcm9wZXJ0eTogJ29nOmRlc2NyaXB0aW9uJywgY29udGVudDogYCR7bmFtZX0sIGEgY2hhbm5lbCBvbiAke3NpdGVUaXRsZX1gfSxcbiAgICB7cHJvcGVydHk6ICd0d2l0dGVyOnNpdGUnLCBjb250ZW50OiBzaXRlVHdpdHRlcn0sXG4gICAge3Byb3BlcnR5OiAndHdpdHRlcjpjYXJkJywgY29udGVudDogJ3N1bW1hcnknfSxcbiAgXTtcbn07XG5cbmNvbnN0IGNyZWF0ZUFzc2V0TWV0YVRhZ3MgPSAoc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpID0+IHtcbiAgY29uc3QgeyBjbGFpbURhdGEgfSA9IGFzc2V0O1xuICBjb25zdCB7IGNvbnRlbnRUeXBlIH0gPSBjbGFpbURhdGE7XG4gIGNvbnN0IGVtYmVkVXJsID0gYCR7c2l0ZUhvc3R9LyR7Y2xhaW1EYXRhLmNsYWltSWR9LyR7Y2xhaW1EYXRhLm5hbWV9YDtcbiAgY29uc3Qgc2hvd1VybCA9IGAke3NpdGVIb3N0fS8ke2NsYWltRGF0YS5jbGFpbUlkfS8ke2NsYWltRGF0YS5uYW1lfWA7XG4gIGNvbnN0IHNvdXJjZSA9IGAke3NpdGVIb3N0fS8ke2NsYWltRGF0YS5jbGFpbUlkfS8ke2NsYWltRGF0YS5uYW1lfS4ke2NsYWltRGF0YS5maWxlRXh0fWA7XG4gIGNvbnN0IG9nVGl0bGUgPSBjbGFpbURhdGEudGl0bGUgfHwgY2xhaW1EYXRhLm5hbWU7XG4gIGNvbnN0IG9nRGVzY3JpcHRpb24gPSBjbGFpbURhdGEuZGVzY3JpcHRpb24gfHwgZGVmYXVsdERlc2NyaXB0aW9uO1xuICBjb25zdCBvZ1RodW1ibmFpbENvbnRlbnRUeXBlID0gZGV0ZXJtaW5lT2dUaHVtYm5haWxDb250ZW50VHlwZShjbGFpbURhdGEudGh1bWJuYWlsKTtcbiAgY29uc3Qgb2dUaHVtYm5haWwgPSBjbGFpbURhdGEudGh1bWJuYWlsIHx8IGRlZmF1bHRUaHVtYm5haWw7XG4gIGNvbnN0IG1ldGFUYWdzID0gW1xuICAgIHtwcm9wZXJ0eTogJ29nOnRpdGxlJywgY29udGVudDogb2dUaXRsZX0sXG4gICAge3Byb3BlcnR5OiAnb2c6dXJsJywgY29udGVudDogc2hvd1VybH0sXG4gICAge3Byb3BlcnR5OiAnb2c6c2l0ZV9uYW1lJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzpkZXNjcmlwdGlvbicsIGNvbnRlbnQ6IG9nRGVzY3JpcHRpb259LFxuICAgIHtwcm9wZXJ0eTogJ29nOmltYWdlOndpZHRoJywgY29udGVudDogNjAwfSxcbiAgICB7cHJvcGVydHk6ICdvZzppbWFnZTpoZWlnaHQnLCBjb250ZW50OiAzMTV9LFxuICAgIHtwcm9wZXJ0eTogJ3R3aXR0ZXI6c2l0ZScsIGNvbnRlbnQ6IHNpdGVUd2l0dGVyfSxcbiAgXTtcbiAgaWYgKGNvbnRlbnRUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50VHlwZSA9PT0gJ3ZpZGVvL3dlYm0nKSB7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzp2aWRlbycsIGNvbnRlbnQ6IHNvdXJjZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dmlkZW86c2VjdXJlX3VybCcsIGNvbnRlbnQ6IHNvdXJjZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dmlkZW86dHlwZScsIGNvbnRlbnQ6IGNvbnRlbnRUeXBlfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzppbWFnZScsIGNvbnRlbnQ6IG9nVGh1bWJuYWlsfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzppbWFnZTp0eXBlJywgY29udGVudDogb2dUaHVtYm5haWxDb250ZW50VHlwZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dHlwZScsIGNvbnRlbnQ6ICd2aWRlbyd9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ3R3aXR0ZXI6Y2FyZCcsIGNvbnRlbnQ6ICdwbGF5ZXInfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcicsIGNvbnRlbnQ6IGVtYmVkVXJsfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcjp3aWR0aCcsIGNvbnRlbnQ6IDYwMH0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjp0ZXh0OnBsYXllcl93aWR0aCcsIGNvbnRlbnQ6IDYwMH0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjpwbGF5ZXI6aGVpZ2h0JywgY29udGVudDogMzM3fSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcjpzdHJlYW0nLCBjb250ZW50OiBzb3VyY2V9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ3R3aXR0ZXI6cGxheWVyOnN0cmVhbTpjb250ZW50X3R5cGUnLCBjb250ZW50OiBjb250ZW50VHlwZX0pO1xuICB9IGVsc2Uge1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6aW1hZ2UnLCBjb250ZW50OiBzb3VyY2V9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ29nOmltYWdlOnR5cGUnLCBjb250ZW50OiBjb250ZW50VHlwZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dHlwZScsIGNvbnRlbnQ6ICdhcnRpY2xlJ30pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjpjYXJkJywgY29udGVudDogJ3N1bW1hcnlfbGFyZ2VfaW1hZ2UnfSk7XG4gIH1cbiAgcmV0dXJuIG1ldGFUYWdzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1ldGFUYWdzID0gKHNpdGVEZXNjcmlwdGlvbiwgc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBjaGFubmVsLCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpID0+IHtcbiAgaWYgKGFzc2V0KSB7XG4gICAgcmV0dXJuIGNyZWF0ZUFzc2V0TWV0YVRhZ3Moc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpO1xuICB9O1xuICBpZiAoY2hhbm5lbCkge1xuICAgIHJldHVybiBjcmVhdGVDaGFubmVsTWV0YVRhZ3Moc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGNoYW5uZWwpO1xuICB9O1xuICByZXR1cm4gY3JlYXRlQmFzaWNNZXRhVGFncyhzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyKTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvbWV0YVRhZ3MuanMiLCJjb25zdCBjcmVhdGVCYXNpY0Nhbm9uaWNhbExpbmsgPSAocGFnZSwgc2l0ZUhvc3QpID0+IHtcbiAgcmV0dXJuIGAke3NpdGVIb3N0fS8ke3BhZ2V9YDtcbn07XG5cbmNvbnN0IGNyZWF0ZUFzc2V0Q2Fub25pY2FsTGluayA9IChhc3NldCwgc2l0ZUhvc3QpID0+IHtcbiAgbGV0IGNoYW5uZWxOYW1lLCBjZXJ0aWZpY2F0ZUlkLCBuYW1lLCBjbGFpbUlkO1xuICBpZiAoYXNzZXQuY2xhaW1EYXRhKSB7XG4gICAgKHsgY2hhbm5lbE5hbWUsIGNlcnRpZmljYXRlSWQsIG5hbWUsIGNsYWltSWQgfSA9IGFzc2V0LmNsYWltRGF0YSk7XG4gIH07XG4gIGlmIChjaGFubmVsTmFtZSkge1xuICAgIHJldHVybiBgJHtzaXRlSG9zdH0vJHtjaGFubmVsTmFtZX06JHtjZXJ0aWZpY2F0ZUlkfS8ke25hbWV9YDtcbiAgfTtcbiAgcmV0dXJuIGAke3NpdGVIb3N0fS8ke2NsYWltSWR9LyR7bmFtZX1gO1xufTtcblxuY29uc3QgY3JlYXRlQ2hhbm5lbENhbm9uaWNhbExpbmsgPSAoY2hhbm5lbCwgc2l0ZUhvc3QpID0+IHtcbiAgY29uc3QgeyBuYW1lLCBsb25nSWQgfSA9IGNoYW5uZWw7XG4gIHJldHVybiBgJHtzaXRlSG9zdH0vJHtuYW1lfToke2xvbmdJZH1gO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUNhbm9uaWNhbExpbmsgPSAoYXNzZXQsIGNoYW5uZWwsIHBhZ2UsIHNpdGVIb3N0KSA9PiB7XG4gIGlmIChhc3NldCkge1xuICAgIHJldHVybiBjcmVhdGVBc3NldENhbm9uaWNhbExpbmsoYXNzZXQsIHNpdGVIb3N0KTtcbiAgfVxuICBpZiAoY2hhbm5lbCkge1xuICAgIHJldHVybiBjcmVhdGVDaGFubmVsQ2Fub25pY2FsTGluayhjaGFubmVsLCBzaXRlSG9zdCk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJhc2ljQ2Fub25pY2FsTGluayhwYWdlLCBzaXRlSG9zdCk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3V0aWxzL2Nhbm9uaWNhbExpbmsuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgTmF2TGluaywgd2l0aFJvdXRlciB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IExvZ28gZnJvbSAnY29tcG9uZW50cy9Mb2dvJztcbmltcG9ydCBOYXZCYXJDaGFubmVsRHJvcGRvd24gZnJvbSAnY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duJztcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5jb25zdCBWSUVXID0gJ1ZJRVcnO1xuY29uc3QgTE9HT1VUID0gJ0xPR09VVCc7XG5cbmNsYXNzIE5hdkJhciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmNoZWNrRm9yTG9nZ2VkSW5Vc2VyID0gdGhpcy5jaGVja0ZvckxvZ2dlZEluVXNlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMubG9nb3V0VXNlciA9IHRoaXMubG9nb3V0VXNlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVTZWxlY3Rpb24uYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgLy8gY2hlY2sgdG8gc2VlIGlmIHRoZSB1c2VyIGlzIGFscmVhZHkgbG9nZ2VkIGluXG4gICAgdGhpcy5jaGVja0ZvckxvZ2dlZEluVXNlcigpO1xuICB9XG4gIGNoZWNrRm9yTG9nZ2VkSW5Vc2VyICgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB7Y3JlZGVudGlhbHM6ICdpbmNsdWRlJ307XG4gICAgcmVxdWVzdCgnL3VzZXInLCBwYXJhbXMpXG4gICAgICAudGhlbigoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihkYXRhLmNoYW5uZWxOYW1lLCBkYXRhLnNob3J0Q2hhbm5lbElkLCBkYXRhLmNoYW5uZWxDbGFpbUlkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnL3VzZXIgZXJyb3I6JywgZXJyb3IubWVzc2FnZSk7XG4gICAgICB9KTtcbiAgfVxuICBsb2dvdXRVc2VyICgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB7Y3JlZGVudGlhbHM6ICdpbmNsdWRlJ307XG4gICAgcmVxdWVzdCgnL2xvZ291dCcsIHBhcmFtcylcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dvdXQoKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnL2xvZ291dCBlcnJvcicsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfSk7XG4gIH1cbiAgaGFuZGxlU2VsZWN0aW9uIChldmVudCkge1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnNlbGVjdGVkT3B0aW9uc1swXS52YWx1ZTtcbiAgICBzd2l0Y2ggKHZhbHVlKSB7XG4gICAgICBjYXNlIExPR09VVDpcbiAgICAgICAgdGhpcy5sb2dvdXRVc2VyKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBWSUVXOlxuICAgICAgICAvLyByZWRpcmVjdCB0byBjaGFubmVsIHBhZ2VcbiAgICAgICAgdGhpcy5wcm9wcy5oaXN0b3J5LnB1c2goYC8ke3RoaXMucHJvcHMuY2hhbm5lbE5hbWV9OiR7dGhpcy5wcm9wcy5jaGFubmVsTG9uZ0lkfWApO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgc2l0ZURlc2NyaXB0aW9uIH0gPSAgdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXdpZGUgbmF2LWJhcic+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1zaG9ydCBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWNlbnRlcic+XG4gICAgICAgICAgPExvZ28gLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbmF2LWJhci0tY2VudGVyJz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0nbmF2LWJhci10YWdsaW5lJz57c2l0ZURlc2NyaXB0aW9ufTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbmF2LWJhci0tcmlnaHQnPlxuICAgICAgICAgICAgPE5hdkxpbmsgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyBhY3RpdmVDbGFzc05hbWU9J2xpbmstLW5hdi1hY3RpdmUnIHRvPScvJyBleGFjdD5QdWJsaXNoPC9OYXZMaW5rPlxuICAgICAgICAgICAgPE5hdkxpbmsgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyAgYWN0aXZlQ2xhc3NOYW1lPSdsaW5rLS1uYXYtYWN0aXZlJyB0bz0nL2Fib3V0Jz5BYm91dDwvTmF2TGluaz5cbiAgICAgICAgICAgIHsgdGhpcy5wcm9wcy5jaGFubmVsTmFtZSA/IChcbiAgICAgICAgICAgICAgPE5hdkJhckNoYW5uZWxEcm9wZG93blxuICAgICAgICAgICAgICAgIGNoYW5uZWxOYW1lPXt0aGlzLnByb3BzLmNoYW5uZWxOYW1lfVxuICAgICAgICAgICAgICAgIGhhbmRsZVNlbGVjdGlvbj17dGhpcy5oYW5kbGVTZWxlY3Rpb259XG4gICAgICAgICAgICAgICAgZGVmYXVsdFNlbGVjdGlvbj17dGhpcy5wcm9wcy5jaGFubmVsTmFtZX1cbiAgICAgICAgICAgICAgICBWSUVXPXtWSUVXfVxuICAgICAgICAgICAgICAgIExPR09VVD17TE9HT1VUfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgPE5hdkxpbmsgaWQ9J25hdi1iYXItbG9naW4tbGluaycgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyBhY3RpdmVDbGFzc05hbWU9J2xpbmstLW5hdi1hY3RpdmUnIHRvPScvbG9naW4nPkNoYW5uZWw8L05hdkxpbms+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aFJvdXRlcihOYXZCYXIpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvTmF2QmFyL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IExpbmsgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcblxuZnVuY3Rpb24gTG9nbyAoKSB7XG4gIHJldHVybiAoXG4gICAgPHN2ZyB2ZXJzaW9uPScxLjEnIGlkPSdMYXllcl8xJyB4PScwcHgnIHk9JzBweCcgaGVpZ2h0PScyNHB4JyB2aWV3Qm94PScwIDAgODAgMzEnIGVuYWJsZUJhY2tncm91bmQ9J25ldyAwIDAgODAgMzEnIGNsYXNzTmFtZT0nbmF2LWJhci1sb2dvJz5cbiAgICAgIDxMaW5rIHRvPScvJz5cbiAgICAgICAgPHRpdGxlPkxvZ288L3RpdGxlPlxuICAgICAgICA8ZGVzYz5TcGVlLmNoIGxvZ288L2Rlc2M+XG4gICAgICAgIDxnIGlkPSdBYm91dCc+XG4gICAgICAgICAgPGcgaWQ9J1B1Ymxpc2gtRm9ybS1WMi1feDI4X2ZpbGxlZF94MjlfJyB0cmFuc2Zvcm09J3RyYW5zbGF0ZSgtNDIuMDAwMDAwLCAtMjMuMDAwMDAwKSc+XG4gICAgICAgICAgICA8ZyBpZD0nR3JvdXAtMTcnIHRyYW5zZm9ybT0ndHJhbnNsYXRlKDQyLjAwMDAwMCwgMjIuMDAwMDAwKSc+XG4gICAgICAgICAgICAgIDx0ZXh0IHRyYW5zZm9ybT0nbWF0cml4KDEgMCAwIDEgMCAyMCknIGZvbnRTaXplPScyNScgZm9udEZhbWlseT0nUm9ib3RvJz5TcGVlJmx0O2g8L3RleHQ+XG4gICAgICAgICAgICAgIDxnIGlkPSdHcm91cC0xNicgdHJhbnNmb3JtPSd0cmFuc2xhdGUoMC4wMDAwMDAsIDMwLjAwMDAwMCknPlxuICAgICAgICAgICAgICAgIDxwYXRoIGlkPSdMaW5lLTgnIGZpbGw9J25vbmUnIHN0cm9rZT0nIzA5RjkxMScgc3Ryb2tlV2lkdGg9JzEnIHN0cm9rZUxpbmVjYXA9J3NxdWFyZScgZD0nTTAuNSwxLjVoMTUnIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggaWQ9J0xpbmUtOC1Db3B5JyBmaWxsPSdub25lJyBzdHJva2U9JyMwMjlENzQnIHN0cm9rZVdpZHRoPScxJyBzdHJva2VMaW5lY2FwPSdzcXVhcmUnIGQ9J00xNi41LDEuNWgxNScgLz5cbiAgICAgICAgICAgICAgICA8cGF0aCBpZD0nTGluZS04LUNvcHktMicgZmlsbD0nbm9uZScgc3Ryb2tlPScjRTM1QkQ4JyBzdHJva2VXaWR0aD0nMScgc3Ryb2tlTGluZWNhcD0nc3F1YXJlJyBkPSdNMzIuNSwxLjVoMTUnIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggaWQ9J0xpbmUtOC1Db3B5LTMnIGZpbGw9J25vbmUnIHN0cm9rZT0nIzQxNTZDNScgc3Ryb2tlV2lkdGg9JzEnIHN0cm9rZUxpbmVjYXA9J3NxdWFyZScgZD0nTTQ4LjUsMS41aDE1JyAvPlxuICAgICAgICAgICAgICAgIDxwYXRoIGlkPSdMaW5lLTgtQ29weS00JyBmaWxsPSdub25lJyBzdHJva2U9JyM2MzU2ODgnIHN0cm9rZVdpZHRoPScxJyBzdHJva2VMaW5lY2FwPSdzcXVhcmUnIGQ9J002NC41LDEuNWgxNScgLz5cbiAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgPC9nPlxuICAgICAgICAgIDwvZz5cbiAgICAgICAgPC9nPlxuICAgICAgPC9MaW5rPlxuICAgIDwvc3ZnPlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgTG9nbztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0xvZ28vaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuZnVuY3Rpb24gTmF2QmFyQ2hhbm5lbERyb3Bkb3duICh7IGNoYW5uZWxOYW1lLCBoYW5kbGVTZWxlY3Rpb24sIGRlZmF1bHRTZWxlY3Rpb24sIFZJRVcsIExPR09VVCB9KSB7XG4gIHJldHVybiAoXG4gICAgPHNlbGVjdCB0eXBlPSd0ZXh0JyBpZD0nbmF2LWJhci1jaGFubmVsLXNlbGVjdCcgY2xhc3NOYW1lPSdzZWxlY3Qgc2VsZWN0LS1hcnJvdyBsaW5rLS1uYXYnIG9uQ2hhbmdlPXtoYW5kbGVTZWxlY3Rpb259IHZhbHVlPXtkZWZhdWx0U2VsZWN0aW9ufT5cbiAgICAgIDxvcHRpb24gaWQ9J25hdi1iYXItY2hhbm5lbC1zZWxlY3QtY2hhbm5lbC1vcHRpb24nPntjaGFubmVsTmFtZX08L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9e1ZJRVd9PlZpZXc8L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9e0xPR09VVH0+TG9nb3V0PC9vcHRpb24+XG4gICAgPC9zZWxlY3Q+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBOYXZCYXJDaGFubmVsRHJvcGRvd247XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duL2luZGV4LmpzeCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNyb3NzLWZldGNoL3BvbHlmaWxsXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiY3Jvc3MtZmV0Y2gvcG9seWZpbGxcIlxuLy8gbW9kdWxlIGlkID0gOTZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBkaXNhYmxlZDogcHVibGlzaC5kaXNhYmxlZCxcbiAgICBmaWxlICAgIDogcHVibGlzaC5maWxlLFxuICAgIHN0YXR1cyAgOiBwdWJsaXNoLnN0YXR1cy5zdGF0dXMsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVG9vbC9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRHJvcHpvbmUgZnJvbSAnY29udGFpbmVycy9Ecm9wem9uZSc7XG5pbXBvcnQgUHVibGlzaERldGFpbHMgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoRGV0YWlscyc7XG5pbXBvcnQgUHVibGlzaFN0YXR1cyBmcm9tICdjb250YWluZXJzL1B1Ymxpc2hTdGF0dXMnO1xuaW1wb3J0IFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlJztcblxuY2xhc3MgUHVibGlzaFRvb2wgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGlmICh0aGlzLnByb3BzLmRpc2FibGVkKSB7XG4gICAgICBjb25zb2xlLmxvZygncHVibGlzaCBpcyBkaXNhYmxlZCcpO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UgLz5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKCdwdWJsaXNoIGlzIG5vdCBkaXNhYmxlZCcpO1xuICAgICAgaWYgKHRoaXMucHJvcHMuZmlsZSkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5zdGF0dXMpIHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPFB1Ymxpc2hTdGF0dXMgLz5cbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiA8UHVibGlzaERldGFpbHMgLz47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiA8RHJvcHpvbmUgLz47XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBQdWJsaXNoVG9vbDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUb29sL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHZhbGlkYXRlRmlsZSB9IGZyb20gJ3V0aWxzL2ZpbGUnO1xuaW1wb3J0IFB1Ymxpc2hQcmV2aWV3IGZyb20gJ2NvbXBvbmVudHMvUHVibGlzaFByZXZpZXcnO1xuXG5jbGFzcyBEcm9wem9uZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgZHJhZ092ZXIgIDogZmFsc2UsXG4gICAgICBtb3VzZU92ZXIgOiBmYWxzZSxcbiAgICAgIGRpbVByZXZpZXc6IGZhbHNlLFxuICAgIH07XG4gICAgdGhpcy5oYW5kbGVEcm9wID0gdGhpcy5oYW5kbGVEcm9wLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVEcmFnT3ZlciA9IHRoaXMuaGFuZGxlRHJhZ092ZXIuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZURyYWdFbmQgPSB0aGlzLmhhbmRsZURyYWdFbmQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZURyYWdFbnRlciA9IHRoaXMuaGFuZGxlRHJhZ0VudGVyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVEcmFnTGVhdmUgPSB0aGlzLmhhbmRsZURyYWdMZWF2ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlTW91c2VFbnRlciA9IHRoaXMuaGFuZGxlTW91c2VFbnRlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlTW91c2VMZWF2ZSA9IHRoaXMuaGFuZGxlTW91c2VMZWF2ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlQ2xpY2sgPSB0aGlzLmhhbmRsZUNsaWNrLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVGaWxlSW5wdXQgPSB0aGlzLmhhbmRsZUZpbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuY2hvb3NlRmlsZSA9IHRoaXMuY2hvb3NlRmlsZS5iaW5kKHRoaXMpO1xuICB9XG4gIGhhbmRsZURyb3AgKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLnNldFN0YXRlKHtkcmFnT3ZlcjogZmFsc2V9KTtcbiAgICAvLyBpZiBkcm9wcGVkIGl0ZW1zIGFyZW4ndCBmaWxlcywgcmVqZWN0IHRoZW1cbiAgICBjb25zdCBkdCA9IGV2ZW50LmRhdGFUcmFuc2ZlcjtcbiAgICBpZiAoZHQuaXRlbXMpIHtcbiAgICAgIGlmIChkdC5pdGVtc1swXS5raW5kID09PSAnZmlsZScpIHtcbiAgICAgICAgY29uc3QgZHJvcHBlZEZpbGUgPSBkdC5pdGVtc1swXS5nZXRBc0ZpbGUoKTtcbiAgICAgICAgdGhpcy5jaG9vc2VGaWxlKGRyb3BwZWRGaWxlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaGFuZGxlRHJhZ092ZXIgKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuICBoYW5kbGVEcmFnRW5kIChldmVudCkge1xuICAgIHZhciBkdCA9IGV2ZW50LmRhdGFUcmFuc2ZlcjtcbiAgICBpZiAoZHQuaXRlbXMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZHQuaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZHQuaXRlbXMucmVtb3ZlKGkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBldmVudC5kYXRhVHJhbnNmZXIuY2xlYXJEYXRhKCk7XG4gICAgfVxuICB9XG4gIGhhbmRsZURyYWdFbnRlciAoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7ZHJhZ092ZXI6IHRydWUsIGRpbVByZXZpZXc6IHRydWV9KTtcbiAgfVxuICBoYW5kbGVEcmFnTGVhdmUgKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe2RyYWdPdmVyOiBmYWxzZSwgZGltUHJldmlldzogZmFsc2V9KTtcbiAgfVxuICBoYW5kbGVNb3VzZUVudGVyICgpIHtcbiAgICB0aGlzLnNldFN0YXRlKHttb3VzZU92ZXI6IHRydWUsIGRpbVByZXZpZXc6IHRydWV9KTtcbiAgfVxuICBoYW5kbGVNb3VzZUxlYXZlICgpIHtcbiAgICB0aGlzLnNldFN0YXRlKHttb3VzZU92ZXI6IGZhbHNlLCBkaW1QcmV2aWV3OiBmYWxzZX0pO1xuICB9XG4gIGhhbmRsZUNsaWNrIChldmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbGVfaW5wdXQnKS5jbGljaygpO1xuICB9XG4gIGhhbmRsZUZpbGVJbnB1dCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IGZpbGVMaXN0ID0gZXZlbnQudGFyZ2V0LmZpbGVzO1xuICAgIHRoaXMuY2hvb3NlRmlsZShmaWxlTGlzdFswXSk7XG4gIH1cbiAgY2hvb3NlRmlsZSAoZmlsZSkge1xuICAgIGlmIChmaWxlKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWxpZGF0ZUZpbGUoZmlsZSk7IC8vIHZhbGlkYXRlIHRoZSBmaWxlJ3MgbmFtZSwgdHlwZSwgYW5kIHNpemVcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BzLnNldEZpbGVFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIC8vIHN0YWdlIGl0IHNvIGl0IHdpbGwgYmUgcmVhZHkgd2hlbiB0aGUgcHVibGlzaCBidXR0b24gaXMgY2xpY2tlZFxuICAgICAgdGhpcy5wcm9wcy5zZWxlY3RGaWxlKGZpbGUpO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uJz5cbiAgICAgICAgPGZvcm0+XG4gICAgICAgICAgPGlucHV0IGNsYXNzTmFtZT0naW5wdXQtZmlsZScgdHlwZT0nZmlsZScgaWQ9J2ZpbGVfaW5wdXQnIG5hbWU9J2ZpbGVfaW5wdXQnIGFjY2VwdD0ndmlkZW8vKixpbWFnZS8qJyBvbkNoYW5nZT17dGhpcy5oYW5kbGVGaWxlSW5wdXR9IGVuY1R5cGU9J211bHRpcGFydC9mb3JtLWRhdGEnIC8+XG4gICAgICAgIDwvZm9ybT5cbiAgICAgICAgPGRpdiBpZD0ncHJldmlldy1kcm9wem9uZScgY2xhc3NOYW1lPXsncm93IHJvdy0tcGFkZGVkIHJvdy0tdGFsbCBkcm9wem9uZScgKyAodGhpcy5zdGF0ZS5kcmFnT3ZlciA/ICcgZHJvcHpvbmUtLWRyYWctb3ZlcicgOiAnJyl9IG9uRHJvcD17dGhpcy5oYW5kbGVEcm9wfSBvbkRyYWdPdmVyPXt0aGlzLmhhbmRsZURyYWdPdmVyfSBvbkRyYWdFbmQ9e3RoaXMuaGFuZGxlRHJhZ0VuZH0gb25EcmFnRW50ZXI9e3RoaXMuaGFuZGxlRHJhZ0VudGVyfSBvbkRyYWdMZWF2ZT17dGhpcy5oYW5kbGVEcmFnTGVhdmV9IG9uTW91c2VFbnRlcj17dGhpcy5oYW5kbGVNb3VzZUVudGVyfSBvbk1vdXNlTGVhdmU9e3RoaXMuaGFuZGxlTW91c2VMZWF2ZX0gb25DbGljaz17dGhpcy5oYW5kbGVDbGlja30+XG4gICAgICAgICAge3RoaXMucHJvcHMuZmlsZSA/IChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxQdWJsaXNoUHJldmlld1xuICAgICAgICAgICAgICAgIGRpbVByZXZpZXc9e3RoaXMuc3RhdGUuZGltUHJldmlld31cbiAgICAgICAgICAgICAgICBmaWxlPXt0aGlzLnByb3BzLmZpbGV9XG4gICAgICAgICAgICAgICAgdGh1bWJuYWlsPXt0aGlzLnByb3BzLnRodW1ibmFpbH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPGRpdiBpZD0nZHJvcHpvbmUtdGV4dC1ob2xkZXInIGNsYXNzTmFtZT17J2ZsZXgtY29udGFpbmVyLS1jb2x1bW4gZmxleC1jb250YWluZXItLWNlbnRlci1jZW50ZXInfT5cbiAgICAgICAgICAgICAgICB7IHRoaXMuc3RhdGUuZHJhZ092ZXIgPyAoXG4gICAgICAgICAgICAgICAgICA8ZGl2IGlkPSdkcm9wem9uZS1kcmFnb3Zlcic+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nYmx1ZSc+RHJvcCBpdC48L3A+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgeyB0aGlzLnN0YXRlLm1vdXNlT3ZlciA/IChcbiAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLWluc3RydWN0aW9ucyc+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLXBsYWNlaG9sZGVyIGluZm8tbWVzc2FnZS0tZmFpbHVyZScgaWQ9J2lucHV0LWVycm9yLWZpbGUtc2VsZWN0aW9uJz57dGhpcy5wcm9wcy5maWxlRXJyb3J9PC9wPlxuICAgICAgICAgICAgICAgICAgICA8cD5EcmFnICYgZHJvcCBpbWFnZSBvciB2aWRlbyBoZXJlIHRvIHB1Ymxpc2g8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+T1I8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nYmx1ZS0tdW5kZXJsaW5lZCc+Q0hPT1NFIEZJTEU8L3A+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLXRleHQtaG9sZGVyJyBjbGFzc05hbWU9eydmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJ30+XG4gICAgICAgICAgICAgIHsgdGhpcy5zdGF0ZS5kcmFnT3ZlciA/IChcbiAgICAgICAgICAgICAgICA8ZGl2IGlkPSdkcm9wem9uZS1kcmFnb3Zlcic+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2JsdWUnPkRyb3AgaXQuPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLWluc3RydWN0aW9ucyc+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS1wbGFjZWhvbGRlciBpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnIGlkPSdpbnB1dC1lcnJvci1maWxlLXNlbGVjdGlvbic+e3RoaXMucHJvcHMuZmlsZUVycm9yfTwvcD5cbiAgICAgICAgICAgICAgICAgIDxwPkRyYWcgJiBkcm9wIGltYWdlIG9yIHZpZGVvIGhlcmUgdG8gcHVibGlzaDwvcD5cbiAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+T1I8L3A+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2JsdWUtLXVuZGVybGluZWQnPkNIT09TRSBGSUxFPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBEcm9wem9uZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Ryb3B6b25lL3ZpZXcuanN4IiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlRmlsZSAoZmlsZSkge1xuICAgIGlmICghZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHByb3ZpZGVkJyk7XG4gICAgfVxuICAgIGlmICgvJy8udGVzdChmaWxlLm5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Fwb3N0cm9waGVzIGFyZSBub3QgYWxsb3dlZCBpbiB0aGUgZmlsZSBuYW1lJyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHNpemUgYW5kIHR5cGVcbiAgICBzd2l0Y2ggKGZpbGUudHlwZSkge1xuICAgICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgICBjYXNlICdpbWFnZS9qcGcnOlxuICAgICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDEwMDAwMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb3JyeSwgaW1hZ2VzIGFyZSBsaW1pdGVkIHRvIDEwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ltYWdlL2dpZic6XG4gICAgICAgIGlmIChmaWxlLnNpemUgPiA1MDAwMDAwMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU29ycnksIEdJRnMgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndmlkZW8vbXA0JzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb3JyeSwgdmlkZW9zIGFyZSBsaW1pdGVkIHRvIDUwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihmaWxlLnR5cGUgKyAnIGlzIG5vdCBhIHN1cHBvcnRlZCBmaWxlIHR5cGUuIE9ubHksIC5qcGVnLCAucG5nLCAuZ2lmLCBhbmQgLm1wNCBmaWxlcyBhcmUgY3VycmVudGx5IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3V0aWxzL2ZpbGUuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcblxuY2xhc3MgUHVibGlzaFByZXZpZXcgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGltZ1NvdXJjZSAgICAgICA6ICcnLFxuICAgICAgZGVmYXVsdFRodW1ibmFpbDogJy9hc3NldHMvaW1nL3ZpZGVvX3RodW1iX2RlZmF1bHQucG5nJyxcbiAgICB9O1xuICB9XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnNldFByZXZpZXdJbWFnZVNvdXJjZSh0aGlzLnByb3BzLmZpbGUpO1xuICB9XG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgKG5ld1Byb3BzKSB7XG4gICAgaWYgKG5ld1Byb3BzLmZpbGUgIT09IHRoaXMucHJvcHMuZmlsZSkge1xuICAgICAgdGhpcy5zZXRQcmV2aWV3SW1hZ2VTb3VyY2UobmV3UHJvcHMuZmlsZSk7XG4gICAgfVxuICAgIGlmIChuZXdQcm9wcy50aHVtYm5haWwgIT09IHRoaXMucHJvcHMudGh1bWJuYWlsKSB7XG4gICAgICBpZiAobmV3UHJvcHMudGh1bWJuYWlsKSB7XG4gICAgICAgIHRoaXMuc2V0UHJldmlld0ltYWdlU291cmNlRnJvbUZpbGUobmV3UHJvcHMudGh1bWJuYWlsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe2ltZ1NvdXJjZTogdGhpcy5zdGF0ZS5kZWZhdWx0VGh1bWJuYWlsfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlIChmaWxlKSB7XG4gICAgY29uc3QgcHJldmlld1JlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcHJldmlld1JlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIHByZXZpZXdSZWFkZXIub25sb2FkZW5kID0gKCkgPT4ge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7aW1nU291cmNlOiBwcmV2aWV3UmVhZGVyLnJlc3VsdH0pO1xuICAgIH07XG4gIH1cbiAgc2V0UHJldmlld0ltYWdlU291cmNlIChmaWxlKSB7XG4gICAgaWYgKGZpbGUudHlwZSAhPT0gJ3ZpZGVvL21wNCcpIHtcbiAgICAgIHRoaXMuc2V0UHJldmlld0ltYWdlU291cmNlRnJvbUZpbGUoZmlsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnByb3BzLnRodW1ibmFpbCkge1xuICAgICAgICB0aGlzLnNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlKHRoaXMucHJvcHMudGh1bWJuYWlsKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoe2ltZ1NvdXJjZTogdGhpcy5zdGF0ZS5kZWZhdWx0VGh1bWJuYWlsfSk7XG4gICAgfVxuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxpbWdcbiAgICAgICAgaWQ9J2Ryb3B6b25lLXByZXZpZXcnXG4gICAgICAgIHNyYz17dGhpcy5zdGF0ZS5pbWdTb3VyY2V9XG4gICAgICAgIGNsYXNzTmFtZT17dGhpcy5wcm9wcy5kaW1QcmV2aWV3ID8gJ2RpbScgOiAnJ31cbiAgICAgICAgYWx0PSdwdWJsaXNoIHByZXZpZXcnXG4gICAgICAvPlxuICAgICk7XG4gIH1cbn07XG5cblB1Ymxpc2hQcmV2aWV3LnByb3BUeXBlcyA9IHtcbiAgZGltUHJldmlldzogUHJvcFR5cGVzLmJvb2wuaXNSZXF1aXJlZCxcbiAgZmlsZSAgICAgIDogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICB0aHVtYm5haWwgOiBQcm9wVHlwZXMub2JqZWN0LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgUHVibGlzaFByZXZpZXc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9QdWJsaXNoUHJldmlldy9pbmRleC5qc3giLCJpbXBvcnQge2Nvbm5lY3R9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7Y2xlYXJGaWxlLCBzdGFydFB1Ymxpc2h9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBjaGFubmVsLCBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBmaWxlOiBwdWJsaXNoLmZpbGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIGNsZWFyRmlsZSxcbiAgc3RhcnRQdWJsaXNoLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGV0YWlscy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgRHJvcHpvbmUgZnJvbSAnY29udGFpbmVycy9Ecm9wem9uZSc7XG5pbXBvcnQgUHVibGlzaFRpdGxlSW5wdXQgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoVGl0bGVJbnB1dCc7XG5pbXBvcnQgUHVibGlzaFVybElucHV0IGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaFVybElucHV0JztcbmltcG9ydCBQdWJsaXNoVGh1bWJuYWlsSW5wdXQgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQnO1xuaW1wb3J0IFB1Ymxpc2hNZXRhZGF0YUlucHV0cyBmcm9tICdjb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cyc7XG5pbXBvcnQgQ2hhbm5lbFNlbGVjdCBmcm9tICdjb250YWluZXJzL0NoYW5uZWxTZWxlY3QnO1xuXG5jbGFzcyBQdWJsaXNoRGV0YWlscyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKVxuICAgIHRoaXMub25QdWJsaXNoU3VibWl0ID0gdGhpcy5vblB1Ymxpc2hTdWJtaXQuYmluZCh0aGlzKTtcbiAgfVxuICBvblB1Ymxpc2hTdWJtaXQgKCkge1xuICAgIHRoaXMucHJvcHMuc3RhcnRQdWJsaXNoKHRoaXMucHJvcHMuaGlzdG9yeSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLW5vLWJvdHRvbSc+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xMCc+XG4gICAgICAgICAgPFB1Ymxpc2hUaXRsZUlucHV0IC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7LyogbGVmdCBjb2x1bW4gKi99XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwJyA+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8RHJvcHpvbmUgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIHsvKiByaWdodCBjb2x1bW4gKi99XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICA8ZGl2IGlkPSdwdWJsaXNoLWFjdGl2ZS1hcmVhJyBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0tbm8tdG9wIHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgIDxQdWJsaXNoVXJsSW5wdXQgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUnPlxuICAgICAgICAgICAgICA8Q2hhbm5lbFNlbGVjdCAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB7ICh0aGlzLnByb3BzLmZpbGUudHlwZSA9PT0gJ3ZpZGVvL21wNCcpICYmIChcbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUgJz5cbiAgICAgICAgICAgICAgICA8UHVibGlzaFRodW1ibmFpbElucHV0IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1uby10b3Agcm93LS1uby1ib3R0b20gcm93LS13aWRlJz5cbiAgICAgICAgICAgICAgPFB1Ymxpc2hNZXRhZGF0YUlucHV0cyAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICAgIDxidXR0b24gaWQ9J3B1Ymxpc2gtc3VibWl0JyBjbGFzc05hbWU9J2J1dHRvbi0tcHJpbWFyeSBidXR0b24tLWxhcmdlJyBvbkNsaWNrPXt0aGlzLm9uUHVibGlzaFN1Ym1pdH0+UHVibGlzaDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0tbm8tYm90dG9tIGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9J2J1dHRvbi0tY2FuY2VsJyBvbkNsaWNrPXt0aGlzLnByb3BzLmNsZWFyRmlsZX0+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1zaG9ydCBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+QnkgY2xpY2tpbmcgJ1B1Ymxpc2gnLCB5b3UgYWZmaXJtIHRoYXQgeW91IGhhdmUgdGhlIHJpZ2h0cyB0byBwdWJsaXNoIHRoaXMgY29udGVudCB0byB0aGUgTEJSWSBuZXR3b3JrLCBhbmQgdGhhdCB5b3UgdW5kZXJzdGFuZCB0aGUgcHJvcGVydGllcyBvZiBwdWJsaXNoaW5nIGl0IHRvIGEgZGVjZW50cmFsaXplZCwgdXNlci1jb250cm9sbGVkIG5ldHdvcmsuIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9sZWFybic+UmVhZCBtb3JlLjwvYT48L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKFB1Ymxpc2hEZXRhaWxzKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEZXRhaWxzL3ZpZXcuanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge3VwZGF0ZU1ldGFkYXRhfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgdGl0bGU6IHB1Ymxpc2gubWV0YWRhdGEudGl0bGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25NZXRhZGF0YUNoYW5nZTogKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVNZXRhZGF0YShuYW1lLCB2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY2xhc3MgUHVibGlzaFRpdGxlSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgfVxuICBoYW5kbGVJbnB1dCAoZSkge1xuICAgIGNvbnN0IG5hbWUgPSBlLnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZS50YXJnZXQudmFsdWU7XG4gICAgdGhpcy5wcm9wcy5vbk1ldGFkYXRhQ2hhbmdlKG5hbWUsIHZhbHVlKTtcbiAgfVxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8aW5wdXQgdHlwZT0ndGV4dCcgaWQ9J3B1Ymxpc2gtdGl0bGUnIGNsYXNzTmFtZT0naW5wdXQtdGV4dCB0ZXh0LS1sYXJnZSBpbnB1dC10ZXh0LS1mdWxsLXdpZHRoJyBuYW1lPSd0aXRsZScgcGxhY2Vob2xkZXI9J0dpdmUgeW91ciBwb3N0IGEgdGl0bGUuLi4nIG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSB2YWx1ZT17dGhpcy5wcm9wcy50aXRsZX0gLz5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hUaXRsZUlucHV0O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFRpdGxlSW5wdXQvdmlldy5qc3giLCJpbXBvcnQge3VwZGF0ZUNsYWltLCB1cGRhdGVFcnJvcn0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgY2hhbm5lbCwgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgbG9nZ2VkSW5DaGFubmVsTmFtZSAgIDogY2hhbm5lbC5sb2dnZWRJbkNoYW5uZWwubmFtZSxcbiAgICBsb2dnZWRJbkNoYW5uZWxTaG9ydElkOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5zaG9ydElkLFxuICAgIGZpbGVOYW1lICAgICAgICAgICAgICA6IHB1Ymxpc2guZmlsZS5uYW1lLFxuICAgIHB1Ymxpc2hJbkNoYW5uZWwgICAgICA6IHB1Ymxpc2gucHVibGlzaEluQ2hhbm5lbCxcbiAgICBzZWxlY3RlZENoYW5uZWwgICAgICAgOiBwdWJsaXNoLnNlbGVjdGVkQ2hhbm5lbCxcbiAgICBjbGFpbSAgICAgICAgICAgICAgICAgOiBwdWJsaXNoLmNsYWltLFxuICAgIHVybEVycm9yICAgICAgICAgICAgICA6IHB1Ymxpc2guZXJyb3IudXJsLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2xhaW1DaGFuZ2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgZGlzcGF0Y2godXBkYXRlQ2xhaW0odmFsdWUpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUVycm9yKCdwdWJsaXNoU3VibWl0JywgbnVsbCkpO1xuICAgIH0sXG4gICAgb25VcmxFcnJvcjogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcigndXJsJywgdmFsdWUpKTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHJlcXVlc3QgZnJvbSAndXRpbHMvcmVxdWVzdCc7XG5pbXBvcnQgVXJsTWlkZGxlIGZyb20gJ2NvbXBvbmVudHMvUHVibGlzaFVybE1pZGRsZURpc3BsYXknO1xuXG5jbGFzcyBQdWJsaXNoVXJsSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBjbGFpbSwgZmlsZU5hbWUgfSA9IHRoaXMucHJvcHM7XG4gICAgaWYgKCFjbGFpbSkge1xuICAgICAgdGhpcy5zZXRDbGFpbU5hbWUoZmlsZU5hbWUpO1xuICAgIH1cbiAgfVxuICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzICh7IGNsYWltLCBmaWxlTmFtZSB9KSB7XG4gICAgLy8gaWYgYSBuZXcgZmlsZSB3YXMgY2hvc2VuLCB1cGRhdGUgdGhlIGNsYWltIG5hbWVcbiAgICBpZiAoZmlsZU5hbWUgIT09IHRoaXMucHJvcHMuZmlsZU5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldENsYWltTmFtZShmaWxlTmFtZSk7XG4gICAgfVxuICAgIC8vIGlmIHRoZSBjbGFpbSBoYXMgdXBkYXRlZCwgY2hlY2sgaXRzIGF2YWlsYWJpbGl0eVxuICAgIGlmIChjbGFpbSAhPT0gdGhpcy5wcm9wcy5jbGFpbSkge1xuICAgICAgdGhpcy52YWxpZGF0ZUNsYWltKGNsYWltKTtcbiAgICB9XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgbGV0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHZhbHVlID0gdGhpcy5jbGVhbnNlSW5wdXQodmFsdWUpO1xuICAgIC8vIHVwZGF0ZSB0aGUgc3RhdGVcbiAgICB0aGlzLnByb3BzLm9uQ2xhaW1DaGFuZ2UodmFsdWUpO1xuICB9XG4gIGNsZWFuc2VJbnB1dCAoaW5wdXQpIHtcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1xccysvZywgJy0nKTsgLy8gcmVwbGFjZSBzcGFjZXMgd2l0aCBkYXNoZXNcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05LV0vZywgJycpOyAgLy8gcmVtb3ZlIGFsbCBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBBLVosIGEteiwgMC05LCBvciAnLSdcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cbiAgc2V0Q2xhaW1OYW1lIChmaWxlTmFtZSkge1xuICAgIGNvbnN0IGZpbGVOYW1lV2l0aG91dEVuZGluZyA9IGZpbGVOYW1lLnN1YnN0cmluZygwLCBmaWxlTmFtZS5sYXN0SW5kZXhPZignLicpKTtcbiAgICBjb25zdCBjbGVhbkNsYWltTmFtZSA9IHRoaXMuY2xlYW5zZUlucHV0KGZpbGVOYW1lV2l0aG91dEVuZGluZyk7XG4gICAgdGhpcy5wcm9wcy5vbkNsYWltQ2hhbmdlKGNsZWFuQ2xhaW1OYW1lKTtcbiAgfVxuICB2YWxpZGF0ZUNsYWltIChjbGFpbSkge1xuICAgIGlmICghY2xhaW0pIHtcbiAgICAgIHJldHVybiB0aGlzLnByb3BzLm9uVXJsRXJyb3IoJ0VudGVyIGEgdXJsIGFib3ZlJyk7XG4gICAgfVxuICAgIHJlcXVlc3QoYC9hcGkvY2xhaW0vYXZhaWxhYmlsaXR5LyR7Y2xhaW19YClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVybEVycm9yKG51bGwpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVybEVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGNsYWltLCBsb2dnZWRJbkNoYW5uZWxOYW1lLCBsb2dnZWRJbkNoYW5uZWxTaG9ydElkLCBwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwsIHVybEVycm9yIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBzcGFuLS1yZWxhdGl2ZSc+XG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd1cmwtdGV4dC0tc2Vjb25kYXJ5Jz5zcGVlLmNoIC8gPC9zcGFuPlxuICAgICAgICAgIDxVcmxNaWRkbGVcbiAgICAgICAgICAgIHB1Ymxpc2hJbkNoYW5uZWw9e3B1Ymxpc2hJbkNoYW5uZWx9XG4gICAgICAgICAgICBzZWxlY3RlZENoYW5uZWw9e3NlbGVjdGVkQ2hhbm5lbH1cbiAgICAgICAgICAgIGxvZ2dlZEluQ2hhbm5lbE5hbWU9e2xvZ2dlZEluQ2hhbm5lbE5hbWV9XG4gICAgICAgICAgICBsb2dnZWRJbkNoYW5uZWxTaG9ydElkPXtsb2dnZWRJbkNoYW5uZWxTaG9ydElkfVxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdjbGFpbS1uYW1lLWlucHV0JyBjbGFzc05hbWU9J2lucHV0LXRleHQnIG5hbWU9J2NsYWltJyBwbGFjZWhvbGRlcj0neW91ci11cmwtaGVyZScgb25DaGFuZ2U9e3RoaXMuaGFuZGxlSW5wdXR9IHZhbHVlPXtjbGFpbX0gLz5cbiAgICAgICAgICB7IChjbGFpbSAmJiAhdXJsRXJyb3IpICYmIDxzcGFuIGlkPSdpbnB1dC1zdWNjZXNzLWNsYWltLW5hbWUnIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1zdWNjZXNzIHNwYW4tLWFic29sdXRlJz57J1xcdTI3MTMnfTwvc3Bhbj4gfVxuICAgICAgICAgIHsgdXJsRXJyb3IgJiYgPHNwYW4gaWQ9J2lucHV0LXN1Y2Nlc3MtY2hhbm5lbC1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSBzcGFuLS1hYnNvbHV0ZSc+eydcXHUyNzE2J308L3NwYW4+IH1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgeyB1cmxFcnJvciA/IChcbiAgICAgICAgICAgIDxwIGlkPSdpbnB1dC1lcnJvci1jbGFpbS1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e3VybEVycm9yfTwvcD5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPkNob29zZSBhIGN1c3RvbSB1cmw8L3A+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hVcmxJbnB1dDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hVcmxJbnB1dC92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5mdW5jdGlvbiBVcmxNaWRkbGUgKHtwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwsIGxvZ2dlZEluQ2hhbm5lbE5hbWUsIGxvZ2dlZEluQ2hhbm5lbFNob3J0SWR9KSB7XG4gIGlmIChwdWJsaXNoSW5DaGFubmVsKSB7XG4gICAgaWYgKHNlbGVjdGVkQ2hhbm5lbCA9PT0gbG9nZ2VkSW5DaGFubmVsTmFtZSkge1xuICAgICAgcmV0dXJuIDxzcGFuIGlkPSd1cmwtY2hhbm5lbCcgY2xhc3NOYW1lPSd1cmwtdGV4dC0tc2Vjb25kYXJ5Jz57bG9nZ2VkSW5DaGFubmVsTmFtZX06e2xvZ2dlZEluQ2hhbm5lbFNob3J0SWR9IC88L3NwYW4+O1xuICAgIH1cbiAgICByZXR1cm4gPHNwYW4gaWQ9J3VybC1jaGFubmVsLXBsYWNlaG9sZGVyJyBjbGFzc05hbWU9J3VybC10ZXh0LS1zZWNvbmRhcnkgdG9vbHRpcCc+QGNoYW5uZWw8c3BhblxuICAgICAgY2xhc3NOYW1lPSd0b29sdGlwLXRleHQnPlNlbGVjdCBhIGNoYW5uZWwgYmVsb3c8L3NwYW4+IC88L3NwYW4+O1xuICB9XG4gIHJldHVybiAoXG4gICAgPHNwYW4gaWQ9J3VybC1uby1jaGFubmVsLXBsYWNlaG9sZGVyJyBjbGFzc05hbWU9J3VybC10ZXh0LS1zZWNvbmRhcnkgdG9vbHRpcCc+eHl6PHNwYW4gY2xhc3NOYW1lPSd0b29sdGlwLXRleHQnPlRoaXMgd2lsbCBiZSBhIHJhbmRvbSBpZDwvc3Bhbj4gLzwvc3Bhbj5cbiAgKTtcbn1cblxuVXJsTWlkZGxlLnByb3BUeXBlcyA9IHtcbiAgcHVibGlzaEluQ2hhbm5lbCAgICAgIDogUHJvcFR5cGVzLmJvb2wuaXNSZXF1aXJlZCxcbiAgbG9nZ2VkSW5DaGFubmVsTmFtZSAgIDogUHJvcFR5cGVzLnN0cmluZyxcbiAgbG9nZ2VkSW5DaGFubmVsU2hvcnRJZDogUHJvcFR5cGVzLnN0cmluZyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFVybE1pZGRsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL1B1Ymxpc2hVcmxNaWRkbGVEaXNwbGF5L2luZGV4LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBvbk5ld1RodW1ibmFpbCB9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoOiB7IGZpbGUgfSB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZmlsZSxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IHtcbiAgb25OZXdUaHVtYm5haWwsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaHVtYm5haWxJbnB1dC9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmZ1bmN0aW9uIGRhdGFVUkl0b0Jsb2IoZGF0YVVSSSkge1xuICAvLyBjb252ZXJ0IGJhc2U2NC9VUkxFbmNvZGVkIGRhdGEgY29tcG9uZW50IHRvIHJhdyBiaW5hcnkgZGF0YSBoZWxkIGluIGEgc3RyaW5nXG4gIGxldCBieXRlU3RyaW5nID0gYXRvYihkYXRhVVJJLnNwbGl0KCcsJylbMV0pO1xuICAvLyBzZXBhcmF0ZSBvdXQgdGhlIG1pbWUgY29tcG9uZW50XG4gIGxldCBtaW1lU3RyaW5nID0gZGF0YVVSSS5zcGxpdCgnLCcpWzBdLnNwbGl0KCc6JylbMV0uc3BsaXQoJzsnKVswXTtcbiAgLy8gd3JpdGUgdGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmcgdG8gYSB0eXBlZCBhcnJheVxuICBsZXQgaWEgPSBuZXcgVWludDhBcnJheShieXRlU3RyaW5nLmxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZVN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgIGlhW2ldID0gYnl0ZVN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICB9XG4gIHJldHVybiBuZXcgQmxvYihbaWFdLCB7dHlwZTogbWltZVN0cmluZ30pO1xufVxuXG5jbGFzcyBQdWJsaXNoVGh1bWJuYWlsSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIHZpZGVvU291cmNlICAgOiBudWxsLFxuICAgICAgZXJyb3IgICAgICAgICA6IG51bGwsXG4gICAgICBzbGlkZXJNaW5SYW5nZTogMSxcbiAgICAgIHNsaWRlck1heFJhbmdlOiBudWxsLFxuICAgICAgc2xpZGVyVmFsdWUgICA6IG51bGwsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZVZpZGVvTG9hZGVkRGF0YSA9IHRoaXMuaGFuZGxlVmlkZW9Mb2FkZWREYXRhLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVTbGlkZXJDaGFuZ2UgPSB0aGlzLmhhbmRsZVNsaWRlckNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuY3JlYXRlVGh1bWJuYWlsID0gdGhpcy5jcmVhdGVUaHVtYm5haWwuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBmaWxlIH0gPSB0aGlzLnByb3BzO1xuICAgIHRoaXMuc2V0VmlkZW9Tb3VyY2UoZmlsZSk7XG4gIH1cbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyAobmV4dFByb3BzKSB7XG4gICAgLy8gaWYgZmlsZSBjaGFuZ2VzXG4gICAgaWYgKG5leHRQcm9wcy5maWxlICYmIG5leHRQcm9wcy5maWxlICE9PSB0aGlzLnByb3BzLmZpbGUpIHtcbiAgICAgIGNvbnN0IHsgZmlsZSB9ID0gbmV4dFByb3BzO1xuICAgICAgdGhpcy5zZXRWaWRlb1NvdXJjZShmaWxlKTtcbiAgICB9O1xuICB9XG4gIHNldFZpZGVvU291cmNlIChmaWxlKSB7XG4gICAgY29uc3QgcHJldmlld1JlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcHJldmlld1JlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIHByZXZpZXdSZWFkZXIub25sb2FkZW5kID0gKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVVyaSA9IHByZXZpZXdSZWFkZXIucmVzdWx0O1xuICAgICAgY29uc3QgYmxvYiA9IGRhdGFVUkl0b0Jsb2IoZGF0YVVyaSk7XG4gICAgICBjb25zdCB2aWRlb1NvdXJjZSA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlkZW9Tb3VyY2UgfSk7XG4gICAgfTtcbiAgfVxuICBoYW5kbGVWaWRlb0xvYWRlZERhdGEgKGV2ZW50KSB7XG4gICAgY29uc3QgZHVyYXRpb24gPSBldmVudC50YXJnZXQuZHVyYXRpb247XG4gICAgY29uc3QgdG90YWxNaW51dGVzID0gTWF0aC5mbG9vcihkdXJhdGlvbiAvIDYwKTtcbiAgICBjb25zdCB0b3RhbFNlY29uZHMgPSBNYXRoLmZsb29yKGR1cmF0aW9uICUgNjApO1xuICAgIC8vIHNldCB0aGUgc2xpZGVyXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzbGlkZXJNYXhSYW5nZTogZHVyYXRpb24gKiAxMDAsXG4gICAgICBzbGlkZXJWYWx1ZSAgIDogZHVyYXRpb24gKiAxMDAgLyAyLFxuICAgICAgdG90YWxNaW51dGVzLFxuICAgICAgdG90YWxTZWNvbmRzLFxuICAgIH0pO1xuICAgIC8vIHVwZGF0ZSB0aGUgY3VycmVudCB0aW1lIG9mIHRoZSB2aWRlb1xuICAgIGxldCB2aWRlbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWRlby10aHVtYi1wbGF5ZXInKTtcbiAgICB2aWRlby5jdXJyZW50VGltZSA9IGR1cmF0aW9uIC8gMjtcbiAgfVxuICBoYW5kbGVTbGlkZXJDaGFuZ2UgKGV2ZW50KSB7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZUludChldmVudC50YXJnZXQudmFsdWUpO1xuICAgIC8vIHVwZGF0ZSB0aGUgc2xpZGVyIHZhbHVlXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzbGlkZXJWYWx1ZTogdmFsdWUsXG4gICAgfSk7XG4gICAgLy8gdXBkYXRlIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIHZpZGVvXG4gICAgbGV0IHZpZGVvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpZGVvLXRodW1iLXBsYXllcicpO1xuICAgIHZpZGVvLmN1cnJlbnRUaW1lID0gdmFsdWUgLyAxMDA7XG4gIH1cbiAgY3JlYXRlVGh1bWJuYWlsICgpIHtcbiAgICAvLyB0YWtlIGEgc25hcHNob3RcbiAgICBsZXQgdmlkZW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlkZW8tdGh1bWItcGxheWVyJyk7XG4gICAgbGV0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IHZpZGVvLnZpZGVvV2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IHZpZGVvLnZpZGVvSGVpZ2h0O1xuICAgIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmRyYXdJbWFnZSh2aWRlbywgMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICBjb25zdCBkYXRhVXJsID0gY2FudmFzLnRvRGF0YVVSTCgpO1xuICAgIGNvbnN0IGJsb2IgPSBkYXRhVVJJdG9CbG9iKGRhdGFVcmwpO1xuICAgIGNvbnN0IHNuYXBzaG90ID0gbmV3IEZpbGUoW2Jsb2JdLCBgdGh1bWJuYWlsLnBuZ2AsIHtcbiAgICAgIHR5cGU6ICdpbWFnZS9wbmcnLFxuICAgIH0pO1xuICAgIC8vIHNldCB0aGUgdGh1bWJuYWlsIGluIHJlZHV4IHN0b3JlXG4gICAgaWYgKHNuYXBzaG90KSB7XG4gICAgICB0aGlzLnByb3BzLm9uTmV3VGh1bWJuYWlsKHNuYXBzaG90KTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGVycm9yLCB2aWRlb1NvdXJjZSwgc2xpZGVyTWluUmFuZ2UsIHNsaWRlck1heFJhbmdlLCBzbGlkZXJWYWx1ZSwgdG90YWxNaW51dGVzLCB0b3RhbFNlY29uZHMgfSA9IHRoaXMuc3RhdGU7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJz5UaHVtYm5haWw6PC9sYWJlbD5cbiAgICAgICAgPHZpZGVvXG4gICAgICAgICAgaWQ9J3ZpZGVvLXRodW1iLXBsYXllcidcbiAgICAgICAgICBwcmVsb2FkPSdtZXRhZGF0YSdcbiAgICAgICAgICBtdXRlZFxuICAgICAgICAgIHN0eWxlPXt7ZGlzcGxheTogJ25vbmUnfX1cbiAgICAgICAgICBwbGF5c0lubGluZVxuICAgICAgICAgIG9uTG9hZGVkRGF0YT17dGhpcy5oYW5kbGVWaWRlb0xvYWRlZERhdGF9XG4gICAgICAgICAgc3JjPXt2aWRlb1NvdXJjZX1cbiAgICAgICAgICBvblNlZWtlZD17dGhpcy5jcmVhdGVUaHVtYm5haWx9XG4gICAgICAgIC8+XG4gICAgICAgIHtcbiAgICAgICAgICBzbGlkZXJWYWx1ZSA/IChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWNlbnRlcicgc3R5bGU9e3t3aWR0aDogJzEwMCUnfX0+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPjAnMDBcIjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+e3RvdGFsTWludXRlc30ne3RvdGFsU2Vjb25kc31cIjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPSdyYW5nZSdcbiAgICAgICAgICAgICAgICAgIG1pbj17c2xpZGVyTWluUmFuZ2V9XG4gICAgICAgICAgICAgICAgICBtYXg9e3NsaWRlck1heFJhbmdlfVxuICAgICAgICAgICAgICAgICAgdmFsdWU9e3NsaWRlclZhbHVlfVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPSdzbGlkZXInXG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5oYW5kbGVTbGlkZXJDaGFuZ2V9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnID5sb2FkaW5nLi4uIDwvcD5cbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgeyBlcnJvciA/IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e2Vycm9yfTwvcD5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+VXNlIHNsaWRlciB0byBzZXQgdGh1bWJuYWlsPC9wPlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQdWJsaXNoVGh1bWJuYWlsSW5wdXQ7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQvdmlldy5qc3giLCJpbXBvcnQge2Nvbm5lY3R9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7dXBkYXRlTWV0YWRhdGEsIHRvZ2dsZU1ldGFkYXRhSW5wdXRzfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgc2hvd01ldGFkYXRhSW5wdXRzOiBwdWJsaXNoLnNob3dNZXRhZGF0YUlucHV0cyxcbiAgICBkZXNjcmlwdGlvbiAgICAgICA6IHB1Ymxpc2gubWV0YWRhdGEuZGVzY3JpcHRpb24sXG4gICAgbGljZW5zZSAgICAgICAgICAgOiBwdWJsaXNoLm1ldGFkYXRhLmxpY2Vuc2UsXG4gICAgbnNmdyAgICAgICAgICAgICAgOiBwdWJsaXNoLm1ldGFkYXRhLm5zZncsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25NZXRhZGF0YUNoYW5nZTogKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVNZXRhZGF0YShuYW1lLCB2YWx1ZSkpO1xuICAgIH0sXG4gICAgb25Ub2dnbGVNZXRhZGF0YUlucHV0czogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh0b2dnbGVNZXRhZGF0YUlucHV0cyh2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRXhwYW5kaW5nVGV4dEFyZWEgZnJvbSAnY29tcG9uZW50cy9FeHBhbmRpbmdUZXh0QXJlYSc7XG5cbmNsYXNzIFB1Ymxpc2hNZXRhZGF0YUlucHV0cyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnRvZ2dsZVNob3dJbnB1dHMgPSB0aGlzLnRvZ2dsZVNob3dJbnB1dHMuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0ID0gdGhpcy5oYW5kbGVTZWxlY3QuYmluZCh0aGlzKTtcbiAgfVxuICB0b2dnbGVTaG93SW5wdXRzICgpIHtcbiAgICB0aGlzLnByb3BzLm9uVG9nZ2xlTWV0YWRhdGFJbnB1dHMoIXRoaXMucHJvcHMuc2hvd01ldGFkYXRhSW5wdXRzKTtcbiAgfVxuICBoYW5kbGVJbnB1dCAoZXZlbnQpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgY29uc3QgdmFsdWUgPSB0YXJnZXQudHlwZSA9PT0gJ2NoZWNrYm94JyA/IHRhcmdldC5jaGVja2VkIDogdGFyZ2V0LnZhbHVlO1xuICAgIGNvbnN0IG5hbWUgPSB0YXJnZXQubmFtZTtcbiAgICB0aGlzLnByb3BzLm9uTWV0YWRhdGFDaGFuZ2UobmFtZSwgdmFsdWUpO1xuICB9XG4gIGhhbmRsZVNlbGVjdCAoZXZlbnQpIHtcbiAgICBjb25zdCBuYW1lID0gZXZlbnQudGFyZ2V0Lm5hbWU7XG4gICAgY29uc3Qgc2VsZWN0ZWRPcHRpb24gPSBldmVudC50YXJnZXQuc2VsZWN0ZWRPcHRpb25zWzBdLnZhbHVlO1xuICAgIHRoaXMucHJvcHMub25NZXRhZGF0YUNoYW5nZShuYW1lLCBzZWxlY3RlZE9wdGlvbik7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBpZD0ncHVibGlzaC1kZXRhaWxzJyBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUnPlxuICAgICAgICB7dGhpcy5wcm9wcy5zaG93TWV0YWRhdGFJbnB1dHMgJiYgKFxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBodG1sRm9yPSdwdWJsaXNoLWxpY2Vuc2UnIGNsYXNzTmFtZT0nbGFiZWwnPkRlc2NyaXB0aW9uOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03IGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgICAgICA8RXhwYW5kaW5nVGV4dEFyZWFcbiAgICAgICAgICAgICAgICAgIGlkPSdwdWJsaXNoLWRlc2NyaXB0aW9uJ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPSd0ZXh0YXJlYSB0ZXh0YXJlYS0tcHJpbWFyeSB0ZXh0YXJlYS0tZnVsbC13aWR0aCdcbiAgICAgICAgICAgICAgICAgIHJvd3M9ezF9XG4gICAgICAgICAgICAgICAgICBtYXhMZW5ndGg9ezIwMDB9XG4gICAgICAgICAgICAgICAgICBzdHlsZT17eyBtYXhIZWlnaHQ6IDIwMCB9fVxuICAgICAgICAgICAgICAgICAgbmFtZT0nZGVzY3JpcHRpb24nXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj0nT3B0aW9uYWwgZGVzY3JpcHRpb24nXG4gICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5wcm9wcy5kZXNjcmlwdGlvbn1cbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBodG1sRm9yPSdwdWJsaXNoLWxpY2Vuc2UnIGNsYXNzTmFtZT0nbGFiZWwnPkxpY2Vuc2U6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxzZWxlY3QgdHlwZT0ndGV4dCcgbmFtZT0nbGljZW5zZScgaWQ9J3B1Ymxpc2gtbGljZW5zZScgY2xhc3NOYW1lPSdzZWxlY3Qgc2VsZWN0LS1wcmltYXJ5JyBvbkNoYW5nZT17dGhpcy5oYW5kbGVTZWxlY3R9PlxuICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0nICc+VW5zcGVjaWZpZWQ8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9J1B1YmxpYyBEb21haW4nPlB1YmxpYyBEb21haW48L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9J0NyZWF0aXZlIENvbW1vbnMnPkNyZWF0aXZlIENvbW1vbnM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLW5vLXRvcCc+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zJz5cbiAgICAgICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj0ncHVibGlzaC1uc2Z3JyBjbGFzc05hbWU9J2xhYmVsJz5NYXR1cmU6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzc05hbWU9J2lucHV0LWNoZWNrYm94JyB0eXBlPSdjaGVja2JveCcgaWQ9J3B1Ymxpc2gtbnNmdycgbmFtZT0nbnNmdycgdmFsdWU9e3RoaXMucHJvcHMubnNmd30gb25DaGFuZ2U9e3RoaXMuaGFuZGxlSW5wdXR9IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICl9XG4gICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXNlY29uZGFyeScgb25DbGljaz17dGhpcy50b2dnbGVTaG93SW5wdXRzfT57dGhpcy5wcm9wcy5zaG93TWV0YWRhdGFJbnB1dHMgPyAnbGVzcycgOiAnbW9yZSd9PC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hNZXRhZGF0YUlucHV0cztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy92aWV3LmpzeCIsImltcG9ydCBSZWFjdCwgeyBDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5jbGFzcyBFeHBhbmRpbmdUZXh0YXJlYSBleHRlbmRzIENvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLl9oYW5kbGVDaGFuZ2UgPSB0aGlzLl9oYW5kbGVDaGFuZ2UuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgdGhpcy5hZGp1c3RUZXh0YXJlYSh7fSk7XG4gIH1cbiAgX2hhbmRsZUNoYW5nZSAoZXZlbnQpIHtcbiAgICBjb25zdCB7IG9uQ2hhbmdlIH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChvbkNoYW5nZSkgb25DaGFuZ2UoZXZlbnQpO1xuICAgIHRoaXMuYWRqdXN0VGV4dGFyZWEoZXZlbnQpO1xuICB9XG4gIGFkanVzdFRleHRhcmVhICh7IHRhcmdldCA9IHRoaXMuZWwgfSkge1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSAwO1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBgJHt0YXJnZXQuc2Nyb2xsSGVpZ2h0fXB4YDtcbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgLi4ucmVzdCB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPHRleHRhcmVhXG4gICAgICAgIHsuLi5yZXN0fVxuICAgICAgICByZWY9e3ggPT4gdGhpcy5lbCA9IHh9XG4gICAgICAgIG9uQ2hhbmdlPXt0aGlzLl9oYW5kbGVDaGFuZ2V9XG4gICAgICAvPlxuICAgICk7XG4gIH1cbn1cblxuRXhwYW5kaW5nVGV4dGFyZWEucHJvcFR5cGVzID0ge1xuICBvbkNoYW5nZTogUHJvcFR5cGVzLmZ1bmMsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBFeHBhbmRpbmdUZXh0YXJlYTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0V4cGFuZGluZ1RleHRBcmVhL2luZGV4LmpzeCIsImltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHtzZXRQdWJsaXNoSW5DaGFubmVsLCB1cGRhdGVTZWxlY3RlZENoYW5uZWwsIHVwZGF0ZUVycm9yfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgY2hhbm5lbCwgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgbG9nZ2VkSW5DaGFubmVsTmFtZTogY2hhbm5lbC5sb2dnZWRJbkNoYW5uZWwubmFtZSxcbiAgICBwdWJsaXNoSW5DaGFubmVsICAgOiBwdWJsaXNoLnB1Ymxpc2hJbkNoYW5uZWwsXG4gICAgc2VsZWN0ZWRDaGFubmVsICAgIDogcHVibGlzaC5zZWxlY3RlZENoYW5uZWwsXG4gICAgY2hhbm5lbEVycm9yICAgICAgIDogcHVibGlzaC5lcnJvci5jaGFubmVsLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uUHVibGlzaEluQ2hhbm5lbENoYW5nZTogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcignY2hhbm5lbCcsIG51bGwpKTtcbiAgICAgIGRpc3BhdGNoKHNldFB1Ymxpc2hJbkNoYW5uZWwodmFsdWUpKTtcbiAgICB9LFxuICAgIG9uQ2hhbm5lbFNlbGVjdDogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcignY2hhbm5lbCcsIG51bGwpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbCh2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxTZWxlY3QvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IENoYW5uZWxMb2dpbkZvcm0gZnJvbSAnY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtJztcbmltcG9ydCBDaGFubmVsQ3JlYXRlRm9ybSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtJztcbmltcG9ydCAqIGFzIHN0YXRlcyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jaGFubmVsX3NlbGVjdF9zdGF0ZXMnO1xuXG5jbGFzcyBDaGFubmVsU2VsZWN0IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IgKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMudG9nZ2xlQW5vbnltb3VzUHVibGlzaCA9IHRoaXMudG9nZ2xlQW5vbnltb3VzUHVibGlzaC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVTZWxlY3Rpb24uYmluZCh0aGlzKTtcbiAgfVxuICB0b2dnbGVBbm9ueW1vdXNQdWJsaXNoIChldmVudCkge1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gJ2Fub255bW91cycpIHtcbiAgICAgIHRoaXMucHJvcHMub25QdWJsaXNoSW5DaGFubmVsQ2hhbmdlKGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wcm9wcy5vblB1Ymxpc2hJbkNoYW5uZWxDaGFuZ2UodHJ1ZSk7XG4gICAgfVxuICB9XG4gIGhhbmRsZVNlbGVjdGlvbiAoZXZlbnQpIHtcbiAgICBjb25zdCBzZWxlY3RlZE9wdGlvbiA9IGV2ZW50LnRhcmdldC5zZWxlY3RlZE9wdGlvbnNbMF0udmFsdWU7XG4gICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxTZWxlY3Qoc2VsZWN0ZWRPcHRpb24pO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxmb3JtPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdyYWRpbycgbmFtZT0nYW5vbnltb3VzLW9yLWNoYW5uZWwnIGlkPSdhbm9ueW1vdXMtcmFkaW8nIGNsYXNzTmFtZT0naW5wdXQtcmFkaW8nIHZhbHVlPSdhbm9ueW1vdXMnIGNoZWNrZWQ9eyF0aGlzLnByb3BzLnB1Ymxpc2hJbkNoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLnRvZ2dsZUFub255bW91c1B1Ymxpc2h9IC8+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCBsYWJlbC0tcG9pbnRlcicgaHRtbEZvcj0nYW5vbnltb3VzLXJhZGlvJz5Bbm9ueW1vdXM8L2xhYmVsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdyYWRpbycgbmFtZT0nYW5vbnltb3VzLW9yLWNoYW5uZWwnIGlkPSdjaGFubmVsLXJhZGlvJyBjbGFzc05hbWU9J2lucHV0LXJhZGlvJyB2YWx1ZT0naW4gYSBjaGFubmVsJyBjaGVja2VkPXt0aGlzLnByb3BzLnB1Ymxpc2hJbkNoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLnRvZ2dsZUFub255bW91c1B1Ymxpc2h9IC8+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCBsYWJlbC0tcG9pbnRlcicgaHRtbEZvcj0nY2hhbm5lbC1yYWRpbyc+SW4gYSBjaGFubmVsPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB7IHRoaXMucHJvcHMuY2hhbm5lbEVycm9yID8gKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnPnt0aGlzLnByb3BzLmNoYW5uZWxFcnJvcn08L3A+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlJz5QdWJsaXNoIGFub255bW91c2x5IG9yIGluIGEgY2hhbm5lbDwvcD5cbiAgICAgICAgICApfVxuICAgICAgICA8L2Zvcm0+XG4gICAgICAgIHsgdGhpcy5wcm9wcy5wdWJsaXNoSW5DaGFubmVsICYmIChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMnPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCcgaHRtbEZvcj0nY2hhbm5lbC1uYW1lLXNlbGVjdCc+Q2hhbm5lbDo8L2xhYmVsPlxuICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICA8c2VsZWN0IHR5cGU9J3RleHQnIGlkPSdjaGFubmVsLW5hbWUtc2VsZWN0JyBjbGFzc05hbWU9J3NlbGVjdCBzZWxlY3QtLWFycm93JyB2YWx1ZT17dGhpcy5wcm9wcy5zZWxlY3RlZENoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZVNlbGVjdGlvbn0+XG4gICAgICAgICAgICAgICAgeyB0aGlzLnByb3BzLmxvZ2dlZEluQ2hhbm5lbE5hbWUgJiYgPG9wdGlvbiB2YWx1ZT17dGhpcy5wcm9wcy5sb2dnZWRJbkNoYW5uZWxOYW1lfSBpZD0ncHVibGlzaC1jaGFubmVsLXNlbGVjdC1jaGFubmVsLW9wdGlvbic+e3RoaXMucHJvcHMubG9nZ2VkSW5DaGFubmVsTmFtZX08L29wdGlvbj4gfVxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9e3N0YXRlcy5MT0dJTn0+RXhpc3Rpbmc8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPXtzdGF0ZXMuQ1JFQVRFfT5OZXc8L29wdGlvbj5cbiAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIHsgKHRoaXMucHJvcHMuc2VsZWN0ZWRDaGFubmVsID09PSBzdGF0ZXMuTE9HSU4pICYmIDxDaGFubmVsTG9naW5Gb3JtIC8+IH1cbiAgICAgICAgICAgIHsgKHRoaXMucHJvcHMuc2VsZWN0ZWRDaGFubmVsID09PSBzdGF0ZXMuQ1JFQVRFKSAmJiA8Q2hhbm5lbENyZWF0ZUZvcm0gLz4gfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsU2VsZWN0O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbFNlbGVjdC92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcblxuY2xhc3MgQ2hhbm5lbExvZ2luRm9ybSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgZXJyb3IgICA6IG51bGwsXG4gICAgICBuYW1lICAgIDogJycsXG4gICAgICBwYXNzd29yZDogJycsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMubG9naW5Ub0NoYW5uZWwgPSB0aGlzLmxvZ2luVG9DaGFubmVsLmJpbmQodGhpcyk7XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgY29uc3QgbmFtZSA9IGV2ZW50LnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1tuYW1lXTogdmFsdWV9KTtcbiAgfVxuICBsb2dpblRvQ2hhbm5lbCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICAgIGJvZHkgICA6IEpTT04uc3RyaW5naWZ5KHt1c2VybmFtZTogdGhpcy5zdGF0ZS5uYW1lLCBwYXNzd29yZDogdGhpcy5zdGF0ZS5wYXNzd29yZH0pLFxuICAgICAgaGVhZGVyczogbmV3IEhlYWRlcnMoe1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgfSksXG4gICAgICBjcmVkZW50aWFsczogJ2luY2x1ZGUnLFxuICAgIH07XG4gICAgcmVxdWVzdCgnbG9naW4nLCBwYXJhbXMpXG4gICAgICAudGhlbigoe3N1Y2Nlc3MsIGNoYW5uZWxOYW1lLCBzaG9ydENoYW5uZWxJZCwgY2hhbm5lbENsYWltSWQsIG1lc3NhZ2V9KSA9PiB7XG4gICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihjaGFubmVsTmFtZSwgc2hvcnRDaGFubmVsSWQsIGNoYW5uZWxDbGFpbUlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBtZXNzYWdlfSk7XG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3J9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGZvcm0gaWQ9J2NoYW5uZWwtbG9naW4tZm9ybSc+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlIHJvdy0tc2hvcnQnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJyBodG1sRm9yPSdjaGFubmVsLWxvZ2luLW5hbWUtaW5wdXQnPk5hbWU6PC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj48ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNiBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1sZWZ0LWJvdHRvbSc+XG4gICAgICAgICAgICAgIDxzcGFuPkA8L3NwYW4+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nY2hhbm5lbC1sb2dpbi1uYW1lLWlucHV0JyBjbGFzc05hbWU9J2lucHV0LXRleHQnIG5hbWU9J25hbWUnIHBsYWNlaG9sZGVyPSdZb3VyIENoYW5uZWwgTmFtZScgdmFsdWU9e3RoaXMuc3RhdGUuY2hhbm5lbE5hbWV9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSByb3ctLXNob3J0Jz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCcgaHRtbEZvcj0nY2hhbm5lbC1sb2dpbi1wYXNzd29yZC1pbnB1dCcgPlBhc3N3b3JkOjwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LXRleHQtLXByaW1hcnknPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ncGFzc3dvcmQnIGlkPSdjaGFubmVsLWxvZ2luLXBhc3N3b3JkLWlucHV0JyBuYW1lPSdwYXNzd29yZCcgY2xhc3NOYW1lPSdpbnB1dC10ZXh0JyBwbGFjZWhvbGRlcj0nJyB2YWx1ZT17dGhpcy5zdGF0ZS5jaGFubmVsUGFzc3dvcmR9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7IHRoaXMuc3RhdGUuZXJyb3IgPyAoXG4gICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnPnt0aGlzLnN0YXRlLmVycm9yfTwvcD5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+RW50ZXIgdGhlIG5hbWUgYW5kIHBhc3N3b3JkIGZvciB5b3VyIGNoYW5uZWw8L3A+XG4gICAgICAgICl9XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlJz5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1wcmltYXJ5JyBvbkNsaWNrPXt0aGlzLmxvZ2luVG9DaGFubmVsfT5BdXRoZW50aWNhdGU8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Zvcm0+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsTG9naW5Gb3JtO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbExvZ2luRm9ybS92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvZ3Jlc3NCYXIgZnJvbSAnY29tcG9uZW50cy9Qcm9ncmVzc0Jhcic7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcblxuY2xhc3MgQ2hhbm5lbENyZWF0ZUZvcm0gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGVycm9yICAgOiBudWxsLFxuICAgICAgY2hhbm5lbCA6ICcnLFxuICAgICAgcGFzc3dvcmQ6ICcnLFxuICAgICAgc3RhdHVzICA6IG51bGwsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZUNoYW5uZWxJbnB1dCA9IHRoaXMuaGFuZGxlQ2hhbm5lbElucHV0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmNyZWF0ZUNoYW5uZWwgPSB0aGlzLmNyZWF0ZUNoYW5uZWwuYmluZCh0aGlzKTtcbiAgfVxuICBjbGVhbnNlQ2hhbm5lbElucHV0IChpbnB1dCkge1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvXFxzKy9nLCAnLScpOyAvLyByZXBsYWNlIHNwYWNlcyB3aXRoIGRhc2hlc1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15BLVphLXowLTktXS9nLCAnJyk7ICAvLyByZW1vdmUgYWxsIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IEEtWiwgYS16LCAwLTksIG9yICctJ1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuICBoYW5kbGVDaGFubmVsSW5wdXQgKGV2ZW50KSB7XG4gICAgbGV0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHZhbHVlID0gdGhpcy5jbGVhbnNlQ2hhbm5lbElucHV0KHZhbHVlKTtcbiAgICB0aGlzLnNldFN0YXRlKHtjaGFubmVsOiB2YWx1ZX0pO1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy51cGRhdGVJc0NoYW5uZWxBdmFpbGFibGUodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtlcnJvcjogJ1BsZWFzZSBlbnRlciBhIGNoYW5uZWwgbmFtZSd9KTtcbiAgICB9XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgY29uc3QgbmFtZSA9IGV2ZW50LnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1tuYW1lXTogdmFsdWV9KTtcbiAgfVxuICB1cGRhdGVJc0NoYW5uZWxBdmFpbGFibGUgKGNoYW5uZWwpIHtcbiAgICBjb25zdCBjaGFubmVsV2l0aEF0U3ltYm9sID0gYEAke2NoYW5uZWx9YDtcbiAgICByZXF1ZXN0KGAvYXBpL2NoYW5uZWwvYXZhaWxhYmlsaXR5LyR7Y2hhbm5lbFdpdGhBdFN5bWJvbH1gKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBudWxsfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgICB9KTtcbiAgfVxuICBjaGVja0lzQ2hhbm5lbEF2YWlsYWJsZSAoY2hhbm5lbCkge1xuICAgIGNvbnN0IGNoYW5uZWxXaXRoQXRTeW1ib2wgPSBgQCR7Y2hhbm5lbH1gO1xuICAgIHJldHVybiByZXF1ZXN0KGAvYXBpL2NoYW5uZWwvYXZhaWxhYmlsaXR5LyR7Y2hhbm5lbFdpdGhBdFN5bWJvbH1gKTtcbiAgfVxuICBjaGVja0lzUGFzc3dvcmRQcm92aWRlZCAocGFzc3dvcmQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaWYgKCFwYXNzd29yZCB8fCBwYXNzd29yZC5sZW5ndGggPCAxKSB7XG4gICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdQbGVhc2UgcHJvdmlkZSBhIHBhc3N3b3JkJykpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9XG4gIG1ha2VQdWJsaXNoQ2hhbm5lbFJlcXVlc3QgKHVzZXJuYW1lLCBwYXNzd29yZCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICAgIGJvZHkgICA6IEpTT04uc3RyaW5naWZ5KHt1c2VybmFtZSwgcGFzc3dvcmR9KSxcbiAgICAgIGhlYWRlcnM6IG5ldyBIZWFkZXJzKHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0pLFxuICAgICAgY3JlZGVudGlhbHM6ICdpbmNsdWRlJyxcbiAgICB9O1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICByZXF1ZXN0KCcvc2lnbnVwJywgcGFyYW1zKVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgVW5mb3J0dW5hdGVseSwgd2UgZW5jb3VudGVyZWQgYW4gZXJyb3Igd2hpbGUgY3JlYXRpbmcgeW91ciBjaGFubmVsLiBQbGVhc2UgbGV0IHVzIGtub3cgaW4gRGlzY29yZCEgJHtlcnJvci5tZXNzYWdlfWApKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgY3JlYXRlQ2hhbm5lbCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuY2hlY2tJc1Bhc3N3b3JkUHJvdmlkZWQodGhpcy5zdGF0ZS5wYXNzd29yZClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tJc0NoYW5uZWxBdmFpbGFibGUodGhpcy5zdGF0ZS5jaGFubmVsKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe3N0YXR1czogJ1dlIGFyZSBwdWJsaXNoaW5nIHlvdXIgbmV3IGNoYW5uZWwuICBTaXQgdGlnaHQuLi4nfSk7XG4gICAgICAgIHJldHVybiB0aGlzLm1ha2VQdWJsaXNoQ2hhbm5lbFJlcXVlc3QodGhpcy5zdGF0ZS5jaGFubmVsLCB0aGlzLnN0YXRlLnBhc3N3b3JkKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtzdGF0dXM6IG51bGx9KTtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihyZXN1bHQuY2hhbm5lbE5hbWUsIHJlc3VsdC5zaG9ydENoYW5uZWxJZCwgcmVzdWx0LmNoYW5uZWxDbGFpbUlkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3IubWVzc2FnZSwgc3RhdHVzOiBudWxsfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3IsIHN0YXR1czogbnVsbH0pO1xuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgeyAhdGhpcy5zdGF0ZS5zdGF0dXMgPyAoXG4gICAgICAgICAgPGZvcm0gaWQ9J3B1Ymxpc2gtY2hhbm5lbC1mb3JtJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlIHJvdy0tc2hvcnQnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzTmFtZT0nbGFiZWwnIGh0bWxGb3I9J25ldy1jaGFubmVsLW5hbWUnPk5hbWU6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdpbnB1dC10ZXh0LS1wcmltYXJ5IGZsZXgtY29udGFpbmVyLS1yb3cgZmxleC1jb250YWluZXItLWxlZnQtYm90dG9tIHNwYW4tLXJlbGF0aXZlJz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPkA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0nY2hhbm5lbCcgaWQ9J25ldy1jaGFubmVsLW5hbWUnIGNsYXNzTmFtZT0naW5wdXQtdGV4dCcgcGxhY2Vob2xkZXI9J2V4YW1wbGVDaGFubmVsTmFtZScgdmFsdWU9e3RoaXMuc3RhdGUuY2hhbm5lbH0gb25DaGFuZ2U9e3RoaXMuaGFuZGxlQ2hhbm5lbElucHV0fSAvPlxuICAgICAgICAgICAgICAgICAgeyAodGhpcy5zdGF0ZS5jaGFubmVsICYmICF0aGlzLnN0YXRlLmVycm9yKSAmJiA8c3BhbiBpZD0naW5wdXQtc3VjY2Vzcy1jaGFubmVsLW5hbWUnIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1zdWNjZXNzIHNwYW4tLWFic29sdXRlJz57J1xcdTI3MTMnfTwvc3Bhbj4gfVxuICAgICAgICAgICAgICAgICAgeyB0aGlzLnN0YXRlLmVycm9yICYmIDxzcGFuIGlkPSdpbnB1dC1zdWNjZXNzLWNoYW5uZWwtbmFtZScgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUgc3Bhbi0tYWJzb2x1dGUnPnsnXFx1MjcxNid9PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSByb3ctLXNob3J0Jz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJyBodG1sRm9yPSduZXctY2hhbm5lbC1wYXNzd29yZCc+UGFzc3dvcmQ6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdpbnB1dC10ZXh0LS1wcmltYXJ5Jz5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdwYXNzd29yZCcgbmFtZT0ncGFzc3dvcmQnIGlkPSduZXctY2hhbm5lbC1wYXNzd29yZCcgY2xhc3NOYW1lPSdpbnB1dC10ZXh0JyAgcGxhY2Vob2xkZXI9JycgdmFsdWU9e3RoaXMuc3RhdGUucGFzc3dvcmR9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAge3RoaXMuc3RhdGUuZXJyb3IgPyAoXG4gICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1mYWlsdXJlJz57dGhpcy5zdGF0ZS5lcnJvcn08L3A+XG4gICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+Q2hvb3NlIGEgbmFtZSBhbmQgcGFzc3dvcmQgZm9yIHlvdXIgY2hhbm5lbDwvcD5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXByaW1hcnknIG9uQ2xpY2s9e3RoaXMuY3JlYXRlQ2hhbm5lbH0+Q3JlYXRlIENoYW5uZWw8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdmaW5lLXByaW50Jz57dGhpcy5zdGF0ZS5zdGF0dXN9PC9wPlxuICAgICAgICAgICAgPFByb2dyZXNzQmFyIHNpemU9ezEyfSAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsQ3JlYXRlRm9ybTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY29uc3QgQWN0aXZlU3RhdHVzQmFyID0gKCkgPT4ge1xuICByZXR1cm4gPHNwYW4gY2xhc3NOYW1lPSdwcm9ncmVzcy1iYXIgcHJvZ3Jlc3MtYmFyLS1hY3RpdmUnPnwgPC9zcGFuPjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFjdGl2ZVN0YXR1c0JhcjtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0FjdGl2ZVN0YXR1c0Jhci9pbmRleC5qc3giLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jb25zdCBJbmFjdGl2ZVN0YXR1c0JhciA9ICgpID0+IHtcbiAgcmV0dXJuIDxzcGFuIGNsYXNzTmFtZT0ncHJvZ3Jlc3MtYmFyIHByb2dyZXNzLWJhci0taW5hY3RpdmUnPnwgPC9zcGFuPjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEluYWN0aXZlU3RhdHVzQmFyO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvSW5hY3RpdmVTdGF0dXNCYXIvaW5kZXguanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge2NsZWFyRmlsZX0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHB1Ymxpc2ggfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIHN0YXR1cyA6IHB1Ymxpc2guc3RhdHVzLnN0YXR1cyxcbiAgICBtZXNzYWdlOiBwdWJsaXNoLnN0YXR1cy5tZXNzYWdlLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0ge1xuICBjbGVhckZpbGUsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hTdGF0dXMvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb2dyZXNzQmFyIGZyb20gJ2NvbXBvbmVudHMvUHJvZ3Jlc3NCYXInO1xuaW1wb3J0ICogYXMgcHVibGlzaFN0YXRlcyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jbGFpbV9zdGF0ZXMnO1xuXG5jbGFzcyBQdWJsaXNoU3RhdHVzIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IHN0YXR1cywgbWVzc2FnZSwgY2xlYXJGaWxlIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJz5cbiAgICAgICAge3N0YXR1cyA9PT0gcHVibGlzaFN0YXRlcy5MT0FEX1NUQVJUICYmXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgYWxpZ24tY29udGVudC1jZW50ZXInPlxuICAgICAgICAgIDxwPkZpbGUgaXMgbG9hZGluZyB0byBzZXJ2ZXI8L3A+XG4gICAgICAgICAgPHAgY2xhc3NOYW1lPSdibHVlJz4wJTwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAge3N0YXR1cyA9PT0gcHVibGlzaFN0YXRlcy5MT0FESU5HICYmXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICA8cD5GaWxlIGlzIGxvYWRpbmcgdG8gc2VydmVyPC9wPlxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdibHVlJz57bWVzc2FnZX08L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHtzdGF0dXMgPT09IHB1Ymxpc2hTdGF0ZXMuUFVCTElTSElORyAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5VcGxvYWQgY29tcGxldGUuICBZb3VyIGZpbGUgaXMgbm93IGJlaW5nIHB1Ymxpc2hlZCBvbiB0aGUgYmxvY2tjaGFpbi4uLjwvcD5cbiAgICAgICAgICA8UHJvZ3Jlc3NCYXIgc2l6ZT17MTJ9IC8+XG4gICAgICAgICAgPHA+Q3VyaW91cyB3aGF0IG1hZ2ljIGlzIGhhcHBlbmluZyBoZXJlPyA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9mYXEvd2hhdC1pcy1sYnJ5Jz5MZWFybiBtb3JlLjwvYT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHtzdGF0dXMgPT09IHB1Ymxpc2hTdGF0ZXMuU1VDQ0VTUyAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5Zb3VyIHB1Ymxpc2ggaXMgY29tcGxldGUhIFlvdSBhcmUgYmVpbmcgcmVkaXJlY3RlZCB0byBpdCBub3cuPC9wPlxuICAgICAgICAgIDxwPklmIHlvdSBhcmUgbm90IGF1dG9tYXRpY2FsbHkgcmVkaXJlY3RlZCwgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj17bWVzc2FnZX0+Y2xpY2sgaGVyZS48L2E+PC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICB7c3RhdHVzID09PSBwdWJsaXNoU3RhdGVzLkZBSUxFRCAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5Tb21ldGhpbmcgd2VudCB3cm9uZy4uLjwvcD5cbiAgICAgICAgICA8cD48c3Ryb25nPnttZXNzYWdlfTwvc3Ryb25nPjwvcD5cbiAgICAgICAgICA8cD5Gb3IgaGVscCwgcG9zdCB0aGUgYWJvdmUgZXJyb3IgdGV4dCBpbiB0aGUgI3NwZWVjaCBjaGFubmVsIG9uIHRoZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZGlzY29yZC5nZy9Zallid2hTJyB0YXJnZXQ9J19ibGFuayc+bGJyeSBkaXNjb3JkPC9hPjwvcD5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1zZWNvbmRhcnknIG9uQ2xpY2s9e2NsZWFyRmlsZX0+UmVzZXQ8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hTdGF0dXM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoU3RhdHVzL3ZpZXcuanN4IiwiZXhwb3J0IGNvbnN0IExPQURfU1RBUlQgPSAnTE9BRF9TVEFSVCc7XG5leHBvcnQgY29uc3QgTE9BRElORyA9ICdMT0FESU5HJztcbmV4cG9ydCBjb25zdCBQVUJMSVNISU5HID0gJ1BVQkxJU0hJTkcnO1xuZXhwb3J0IGNvbnN0IFNVQ0NFU1MgPSAnU1VDQ0VTUyc7XG5leHBvcnQgY29uc3QgRkFJTEVEID0gJ0ZBSUxFRCc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29uc3RhbnRzL3B1Ymxpc2hfY2xhaW1fc3RhdGVzLmpzIiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBtZXNzYWdlOiBwdWJsaXNoLmRpc2FibGVkTWVzc2FnZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jbGFzcyBQdWJsaXNoRGlzYWJsZWRNZXNzYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gdGhpcy5wcm9wcy5tZXNzYWdlO1xuICAgIGNvbnNvbGUubG9nKCd0aGlzLnByb3BzLm1lc3NhZ2U6JywgbWVzc2FnZSk7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgZHJvcHpvbmUtLWRpc2FibGVkIHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJz5cbiAgICAgICAgPHAgY2xhc3NOYW1lPSd0ZXh0LS1kaXNhYmxlZCc+UHVibGlzaGluZyBpcyBjdXJyZW50bHkgZGlzYWJsZWQuPC9wPlxuICAgICAgICA8cCBjbGFzc05hbWU9J3RleHQtLWRpc2FibGVkJz57bWVzc2FnZX08L3A+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2U7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IFNFTyBmcm9tICdjb21wb25lbnRzL1NFTyc7XG5cbmNsYXNzIEFib3V0UGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxTRU8gcGFnZVRpdGxlPXsnQWJvdXQnfSBwYWdlVXJpPXsnYWJvdXQnfSAvPlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdwdWxsLXF1b3RlJz5TcGVlLmNoIGlzIGFuIG9wZW4tc291cmNlIHByb2plY3QuICBQbGVhc2UgY29udHJpYnV0ZSB0byB0aGUgZXhpc3Rpbmcgc2l0ZSwgb3IgZm9yayBpdCBhbmQgbWFrZSB5b3VyIG93bi48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vdHdpdHRlci5jb20vc3BlZV9jaCc+VFdJVFRFUjwvYT48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaCc+R0lUSFVCPC9hPjwvcD5cbiAgICAgICAgICAgICAgPHA+PGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj0naHR0cHM6Ly9kaXNjb3JkLmdnL1lqWWJ3aFMnPkRJU0NPUkQgQ0hBTk5FTDwvYT48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaC9ibG9iL21hc3Rlci9SRUFETUUubWQnPkRPQ1VNRU5UQVRJT048L2E+PC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICA8cD5TcGVlLmNoIGlzIGEgbWVkaWEtaG9zdGluZyBzaXRlIHRoYXQgcmVhZHMgZnJvbSBhbmQgcHVibGlzaGVzIGNvbnRlbnQgdG8gdGhlIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9sYnJ5LmlvJz5MQlJZPC9hPiBibG9ja2NoYWluLjwvcD5cbiAgICAgICAgICAgICAgPHA+U3BlZS5jaCBpcyBhIGhvc3Rpbmcgc2VydmljZSwgYnV0IHdpdGggdGhlIGFkZGVkIGJlbmVmaXQgdGhhdCBpdCBzdG9yZXMgeW91ciBjb250ZW50IG9uIGEgZGVjZW50cmFsaXplZCBuZXR3b3JrIG9mIGNvbXB1dGVycyAtLSB0aGUgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyBocmVmPSdodHRwczovL2xicnkuaW8vZ2V0Jz5MQlJZPC9hPiBuZXR3b3JrLiAgVGhpcyBtZWFucyB0aGF0IHlvdXIgaW1hZ2VzIGFyZSBzdG9yZWQgaW4gbXVsdGlwbGUgbG9jYXRpb25zIHdpdGhvdXQgYSBzaW5nbGUgcG9pbnQgb2YgZmFpbHVyZS48L3A+XG4gICAgICAgICAgICAgIDxoMz5Db250cmlidXRlPC9oMz5cbiAgICAgICAgICAgICAgPHA+SWYgeW91IGhhdmUgYW4gaWRlYSBmb3IgeW91ciBvd24gc3BlZS5jaC1saWtlIHNpdGUgb24gdG9wIG9mIExCUlksIGZvcmsgb3VyIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9naXRodWIuY29tL2xicnlpby9zcGVlLmNoJz5naXRodWIgcmVwbzwvYT4gYW5kIGdvIHRvIHRvd24hPC9wPlxuICAgICAgICAgICAgICA8cD5JZiB5b3Ugd2FudCB0byBpbXByb3ZlIHNwZWUuY2gsIGpvaW4gb3VyIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9kaXNjb3JkLmdnL1lqWWJ3aFMnPmRpc2NvcmQgY2hhbm5lbDwvYT4gb3Igc29sdmUgb25lIG9mIG91ciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaC9pc3N1ZXMnPmdpdGh1YiBpc3N1ZXM8L2E+LjwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFib3V0UGFnZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9wYWdlcy9BYm91dFBhZ2UvaW5kZXguanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBjaGFubmVsIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBsb2dnZWRJbkNoYW5uZWxOYW1lOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5uYW1lLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3BhZ2VzL0xvZ2luUGFnZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IENoYW5uZWxMb2dpbkZvcm0gZnJvbSAnY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtJztcbmltcG9ydCBDaGFubmVsQ3JlYXRlRm9ybSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtJztcblxuY2xhc3MgTG9naW5QYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyAobmV3UHJvcHMpIHtcbiAgICAvLyByZS1yb3V0ZSB0aGUgdXNlciB0byB0aGUgaG9tZXBhZ2UgaWYgdGhlIHVzZXIgaXMgbG9nZ2VkIGluXG4gICAgaWYgKG5ld1Byb3BzLmxvZ2dlZEluQ2hhbm5lbE5hbWUgIT09IHRoaXMucHJvcHMubG9nZ2VkSW5DaGFubmVsTmFtZSkge1xuICAgICAgdGhpcy5wcm9wcy5oaXN0b3J5LnB1c2goYC9gKTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPFNFTyBwYWdlVGl0bGU9eydMb2dpbid9IHBhZ2VVcmk9eydsb2dpbid9IC8+XG4gICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICA8cD5DaGFubmVscyBhbGxvdyB5b3UgdG8gcHVibGlzaCBhbmQgZ3JvdXAgY29udGVudCB1bmRlciBhbiBpZGVudGl0eS4gWW91IGNhbiBjcmVhdGUgYSBjaGFubmVsIGZvciB5b3Vyc2VsZiwgb3Igc2hhcmUgb25lIHdpdGggbGlrZS1taW5kZWQgZnJpZW5kcy4gIFlvdSBjYW4gY3JlYXRlIDEgY2hhbm5lbCwgb3IgMTAwLCBzbyB3aGV0aGVyIHlvdSdyZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPScvQGNhdGFsb25pYTIwMTc6NDNkY2Y0NzE2M2NhYTIxZDg0MDRkOWZlOWIzMGY3OGVmM2UxNDZhOCc+ZG9jdW1lbnRpbmcgaW1wb3J0YW50IGV2ZW50czwvYT4sIG9yIG1ha2luZyBhIHB1YmxpYyByZXBvc2l0b3J5IGZvciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPScvQGNhdEdpZnMnPmNhdCBnaWZzPC9hPiAocGFzc3dvcmQ6ICcxMjM0JyksIHRyeSBjcmVhdGluZyBhIGNoYW5uZWwgZm9yIGl0ITwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZT0naDMtLW5vLWJvdHRvbSc+TG9nIGluIHRvIGFuIGV4aXN0aW5nIGNoYW5uZWw6PC9oMz5cbiAgICAgICAgICAgICAgPENoYW5uZWxMb2dpbkZvcm0gLz5cbiAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZT0naDMtLW5vLWJvdHRvbSc+Q3JlYXRlIGEgYnJhbmQgbmV3IGNoYW5uZWw6PC9oMz5cbiAgICAgICAgICAgICAgPENoYW5uZWxDcmVhdGVGb3JtIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKExvZ2luUGFnZSk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcGFnZXMvTG9naW5QYWdlL3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IG9uSGFuZGxlU2hvd1BhZ2VVcmkgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZXJyb3IgICAgICA6IHNob3cucmVxdWVzdC5lcnJvcixcbiAgICByZXF1ZXN0VHlwZTogc2hvdy5yZXF1ZXN0LnR5cGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIG9uSGFuZGxlU2hvd1BhZ2VVcmksXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9wYWdlcy9TaG93UGFnZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgU2hvd0Fzc2V0TGl0ZSBmcm9tICdjb250YWluZXJzL1Nob3dBc3NldExpdGUnO1xuaW1wb3J0IFNob3dBc3NldERldGFpbHMgZnJvbSAnY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzJztcbmltcG9ydCBTaG93Q2hhbm5lbCBmcm9tICdjb250YWluZXJzL1Nob3dDaGFubmVsJztcblxuaW1wb3J0IHsgQ0hBTk5FTCwgQVNTRVRfTElURSwgQVNTRVRfREVUQUlMUyB9IGZyb20gJ2NvbnN0YW50cy9zaG93X3JlcXVlc3RfdHlwZXMnO1xuXG5jbGFzcyBTaG93UGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnByb3BzLm9uSGFuZGxlU2hvd1BhZ2VVcmkodGhpcy5wcm9wcy5tYXRjaC5wYXJhbXMpO1xuICB9XG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgKG5leHRQcm9wcykge1xuICAgIGlmIChuZXh0UHJvcHMubWF0Y2gucGFyYW1zICE9PSB0aGlzLnByb3BzLm1hdGNoLnBhcmFtcykge1xuICAgICAgdGhpcy5wcm9wcy5vbkhhbmRsZVNob3dQYWdlVXJpKG5leHRQcm9wcy5tYXRjaC5wYXJhbXMpO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgZXJyb3IsIHJlcXVlc3RUeXBlIH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPEVycm9yUGFnZSBlcnJvcj17ZXJyb3J9IC8+XG4gICAgICApO1xuICAgIH1cbiAgICBzd2l0Y2ggKHJlcXVlc3RUeXBlKSB7XG4gICAgICBjYXNlIENIQU5ORUw6XG4gICAgICAgIHJldHVybiA8U2hvd0NoYW5uZWwgLz47XG4gICAgICBjYXNlIEFTU0VUX0xJVEU6XG4gICAgICAgIHJldHVybiA8U2hvd0Fzc2V0TGl0ZSAvPjtcbiAgICAgIGNhc2UgQVNTRVRfREVUQUlMUzpcbiAgICAgICAgcmV0dXJuIDxTaG93QXNzZXREZXRhaWxzIC8+O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIDxwPmxvYWRpbmcuLi48L3A+O1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2hvd1BhZ2U7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcGFnZXMvU2hvd1BhZ2Uvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCByZXF1ZXN0IGluZm9cbiAgY29uc3QgcmVxdWVzdElkID0gc2hvdy5yZXF1ZXN0LmlkO1xuICAvLyBzZWxlY3QgYXNzZXQgaW5mb1xuICBsZXQgYXNzZXQ7XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0gfHwgbnVsbDtcbiAgY29uc3QgYXNzZXRMaXN0ID0gc2hvdy5hc3NldExpc3Q7XG4gIGlmIChyZXF1ZXN0ICYmIGFzc2V0TGlzdCkge1xuICAgIGNvbnN0IGFzc2V0S2V5ID0gcmVxdWVzdC5rZXk7ICAvLyBub3RlOiBqdXN0IHN0b3JlIHRoaXMgaW4gdGhlIHJlcXVlc3RcbiAgICBhc3NldCA9IGFzc2V0TGlzdFthc3NldEtleV0gfHwgbnVsbDtcbiAgfTtcbiAgLy8gcmV0dXJuIHByb3BzXG4gIHJldHVybiB7XG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXRMaXRlL2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBTRU8gZnJvbSAnY29tcG9uZW50cy9TRU8nO1xuaW1wb3J0IHsgTGluayB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEFzc2V0RGlzcGxheSBmcm9tICdjb250YWluZXJzL0Fzc2V0RGlzcGxheSc7XG5cbmNsYXNzIFNob3dMaXRlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGFzc2V0IH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChhc3NldCkge1xuICAgICAgY29uc3QgeyBuYW1lLCBjbGFpbUlkIH0gPSBhc3NldC5jbGFpbURhdGE7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyIHNob3ctbGl0ZS1jb250YWluZXInPlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtuYW1lfSBhc3NldD17YXNzZXR9IC8+XG4gICAgICAgICAgPEFzc2V0RGlzcGxheSAvPlxuICAgICAgICAgIDxMaW5rIGlkPSdhc3NldC1ib2lsZXJwYXRlJyBjbGFzc05hbWU9J2xpbmstLXByaW1hcnkgZmluZS1wcmludCcgdG89e2AvJHtjbGFpbUlkfS8ke25hbWV9YH0+aG9zdGVkXG4gICAgICAgICAgICB2aWEgU3BlZS5jaDwvTGluaz5cbiAgICAgICAgPC9kaXY+XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXRhbGwgcm93LS1wYWRkZWQgZmxleC1jb250YWluZXItLWNvbHVtbiBmbGV4LWNvbnRhaW5lci0tY2VudGVyLWNlbnRlcic+XG4gICAgICAgIDxwPmxvYWRpbmcgYXNzZXQgZGF0YS4uLjwvcD5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNob3dMaXRlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0TGl0ZS92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvZ3Jlc3NCYXIgZnJvbSAnY29tcG9uZW50cy9Qcm9ncmVzc0Jhcic7XG5pbXBvcnQgeyBMT0NBTF9DSEVDSywgVU5BVkFJTEFCTEUsIEVSUk9SLCBBVkFJTEFCTEUgfSBmcm9tICdjb25zdGFudHMvYXNzZXRfZGlzcGxheV9zdGF0ZXMnO1xuXG5jbGFzcyBBc3NldERpc3BsYXkgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBhc3NldDogeyBjbGFpbURhdGE6IHsgbmFtZSwgY2xhaW1JZCB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgdGhpcy5wcm9wcy5vbkZpbGVSZXF1ZXN0KG5hbWUsIGNsYWltSWQpO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBzdGF0dXMsIGVycm9yLCBhc3NldDogeyBjbGFpbURhdGE6IHsgbmFtZSwgY2xhaW1JZCwgY29udGVudFR5cGUsIGZpbGVFeHQsIHRodW1ibmFpbCB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgaWQ9J2Fzc2V0LWRpc3BsYXktY29tcG9uZW50Jz5cbiAgICAgICAgeyhzdGF0dXMgPT09IExPQ0FMX0NIRUNLKSAmJlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxwPkNoZWNraW5nIHRvIHNlZSBpZiBTcGVlLmNoIGhhcyB5b3VyIGFzc2V0IGxvY2FsbHkuLi48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHsoc3RhdHVzID09PSBVTkFWQUlMQUJMRSkgJiZcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8cD5TaXQgdGlnaHQsIHdlJ3JlIHNlYXJjaGluZyB0aGUgTEJSWSBibG9ja2NoYWluIGZvciB5b3VyIGFzc2V0ITwvcD5cbiAgICAgICAgICA8UHJvZ3Jlc3NCYXIgc2l6ZT17MTJ9IC8+XG4gICAgICAgICAgPHA+Q3VyaW91cyB3aGF0IG1hZ2ljIGlzIGhhcHBlbmluZyBoZXJlPyA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9mYXEvd2hhdC1pcy1sYnJ5Jz5MZWFybiBtb3JlLjwvYT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHsoc3RhdHVzID09PSBFUlJPUikgJiZcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8cD5VbmZvcnR1bmF0ZWx5LCB3ZSBjb3VsZG4ndCBkb3dubG9hZCB5b3VyIGFzc2V0IGZyb20gTEJSWS4gIFlvdSBjYW4gaGVscCB1cyBvdXQgYnkgc2hhcmluZyB0aGUgYmVsb3cgZXJyb3IgbWVzc2FnZSBpbiB0aGUgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyBocmVmPSdodHRwczovL2Rpc2NvcmQuZ2cvWWpZYndoUycgdGFyZ2V0PSdfYmxhbmsnPkxCUlkgZGlzY29yZDwvYT4uPC9wPlxuICAgICAgICAgIDxpPjxwIGlkPSdlcnJvci1tZXNzYWdlJz57ZXJyb3J9PC9wPjwvaT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgeyhzdGF0dXMgPT09IEFWQUlMQUJMRSkgJiZcbiAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGNvbnRlbnRUeXBlKSB7XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgICAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0nYXNzZXQnXG4gICAgICAgICAgICAgICAgICBzcmM9e2AvJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfVxuICAgICAgICAgICAgICAgICAgYWx0PXtuYW1lfSAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9J2Fzc2V0J1xuICAgICAgICAgICAgICAgICAgc3JjPXtgLyR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH1cbiAgICAgICAgICAgICAgICAgIGFsdD17bmFtZX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSAndmlkZW8vbXA0JzpcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8dmlkZW8gY2xhc3NOYW1lPSdhc3NldCB2aWRlbycgY29udHJvbHMgcG9zdGVyPXt0aHVtYm5haWx9PlxuICAgICAgICAgICAgICAgICAgPHNvdXJjZVxuICAgICAgICAgICAgICAgICAgICBzcmM9e2AvJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDxwPllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSA8Y29kZT52aWRlbzwvY29kZT4gZWxlbWVudC48L3A+XG4gICAgICAgICAgICAgICAgPC92aWRlbz5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPHA+VW5zdXBwb3J0ZWQgZmlsZSB0eXBlPC9wPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldERpc3BsYXk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9Bc3NldERpc3BsYXkvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCByZXF1ZXN0IGluZm9cbiAgY29uc3QgcmVxdWVzdElkID0gc2hvdy5yZXF1ZXN0LmlkO1xuICAvLyBzZWxlY3QgYXNzZXQgaW5mb1xuICBsZXQgYXNzZXQ7XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0gfHwgbnVsbDtcbiAgY29uc3QgYXNzZXRMaXN0ID0gc2hvdy5hc3NldExpc3Q7XG4gIGlmIChyZXF1ZXN0ICYmIGFzc2V0TGlzdCkge1xuICAgIGNvbnN0IGFzc2V0S2V5ID0gcmVxdWVzdC5rZXk7ICAvLyBub3RlOiBqdXN0IHN0b3JlIHRoaXMgaW4gdGhlIHJlcXVlc3RcbiAgICBhc3NldCA9IGFzc2V0TGlzdFthc3NldEtleV0gfHwgbnVsbDtcbiAgfTtcbiAgLy8gcmV0dXJuIHByb3BzXG4gIHJldHVybiB7XG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzL2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBTRU8gZnJvbSAnY29tcG9uZW50cy9TRU8nO1xuaW1wb3J0IE5hdkJhciBmcm9tICdjb250YWluZXJzL05hdkJhcic7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgQXNzZXRUaXRsZSBmcm9tICdjb250YWluZXJzL0Fzc2V0VGl0bGUnO1xuaW1wb3J0IEFzc2V0RGlzcGxheSBmcm9tICdjb250YWluZXJzL0Fzc2V0RGlzcGxheSc7XG5pbXBvcnQgQXNzZXRJbmZvIGZyb20gJ2NvbnRhaW5lcnMvQXNzZXRJbmZvJztcblxuY2xhc3MgU2hvd0Fzc2V0RGV0YWlscyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBhc3NldCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoYXNzZXQpIHtcbiAgICAgIGNvbnN0IHsgY2xhaW1EYXRhOiB7IG5hbWUgfSB9ID0gYXNzZXQ7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtgJHtuYW1lfSAtIGRldGFpbHNgfSBhc3NldD17YXNzZXR9IC8+XG4gICAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS10YWxsIHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xMCc+XG4gICAgICAgICAgICAgIDxBc3NldFRpdGxlIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCBzaG93LWRldGFpbHMtY29udGFpbmVyJz5cbiAgICAgICAgICAgICAgICA8QXNzZXREaXNwbGF5IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1zbWwtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICAgICAgICA8QXNzZXRJbmZvIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKTtcbiAgICB9O1xuICAgIHJldHVybiAoXG4gICAgICA8RXJyb3JQYWdlIGVycm9yPXsnbG9hZGluZyBhc3NldCBkYXRhLi4uJ30gLz5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTaG93QXNzZXREZXRhaWxzO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscy92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuaW1wb3J0IHsgc2VsZWN0QXNzZXQgfSBmcm9tICdzZWxlY3RvcnMvc2hvdyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHNob3cgfSkgPT4ge1xuICBjb25zdCB7IGNsYWltRGF0YTogeyB0aXRsZSB9IH0gPSBzZWxlY3RBc3NldChzaG93KTtcbiAgcmV0dXJuIHtcbiAgICB0aXRsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0VGl0bGUvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jb25zdCBBc3NldFRpdGxlID0gKHsgdGl0bGUgfSkgPT4ge1xuICByZXR1cm4gKFxuICAgIDxkaXY+XG4gICAgICA8c3BhbiBjbGFzc05hbWU9J3RleHQtLWxhcmdlJz57dGl0bGV9PC9zcGFuPlxuICAgIDwvZGl2PlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgQXNzZXRUaXRsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0VGl0bGUvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcbmltcG9ydCB7IHNlbGVjdEFzc2V0IH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IGFzc2V0XG4gIGNvbnN0IGFzc2V0ID0gc2VsZWN0QXNzZXQoc2hvdyk7XG4gIC8vICByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBhc3NldCxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0SW5mby9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5cbmNsYXNzIEFzc2V0SW5mbyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmNvcHlUb0NsaXBib2FyZCA9IHRoaXMuY29weVRvQ2xpcGJvYXJkLmJpbmQodGhpcyk7XG4gIH1cbiAgY29weVRvQ2xpcGJvYXJkIChldmVudCkge1xuICAgIHZhciBlbGVtZW50VG9Db3B5ID0gZXZlbnQudGFyZ2V0LmRhdGFzZXQuZWxlbWVudHRvY29weTtcbiAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRUb0NvcHkpO1xuICAgIGVsZW1lbnQuc2VsZWN0KCk7XG4gICAgdHJ5IHtcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtlcnJvcjogJ09vcHMsIHVuYWJsZSB0byBjb3B5J30pO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgYXNzZXQ6IHsgc2hvcnRJZCwgY2xhaW1EYXRhIDogeyBjaGFubmVsTmFtZSwgY2VydGlmaWNhdGVJZCwgZGVzY3JpcHRpb24sIG5hbWUsIGNsYWltSWQsIGZpbGVFeHQsIGNvbnRlbnRUeXBlLCB0aHVtYm5haWwsIGhvc3QgfSB9IH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICB7Y2hhbm5lbE5hbWUgJiZcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLXdpZGUgcm93LS1uby10b3AnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+Q2hhbm5lbDo8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd0ZXh0Jz48TGluayB0bz17YC8ke2NoYW5uZWxOYW1lfToke2NlcnRpZmljYXRlSWR9YH0+e2NoYW5uZWxOYW1lfTwvTGluaz48L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAge2Rlc2NyaXB0aW9uICYmXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS13aWRlIHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9J3RleHQnPntkZXNjcmlwdGlvbn08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgPGRpdiBpZD0nc2hvdy1zaGFyZS1idXR0b25zJz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0td2lkZSByb3ctLW5vLXRvcCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMiBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+U2hhcmU6PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tOCBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWJvdHRvbSBmbGV4LWNvbnRhaW5lci0td3JhcCc+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj17YGh0dHBzOi8vdHdpdHRlci5jb20vaW50ZW50L3R3ZWV0P3RleHQ9JHtob3N0fS8ke3Nob3J0SWR9LyR7bmFtZX1gfT50d2l0dGVyPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwczovL3d3dy5mYWNlYm9vay5jb20vc2hhcmVyL3NoYXJlci5waHA/dT0ke2hvc3R9LyR7c2hvcnRJZH0vJHtuYW1lfWB9PmZhY2Vib29rPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwOi8vdHVtYmxyLmNvbS93aWRnZXRzL3NoYXJlL3Rvb2w/Y2Fub25pY2FsVXJsPSR7aG9zdH0vJHtzaG9ydElkfS8ke25hbWV9YH0+dHVtYmxyPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwczovL3d3dy5yZWRkaXQuY29tL3N1Ym1pdD91cmw9JHtob3N0fS8ke3Nob3J0SWR9LyR7bmFtZX0mdGl0bGU9JHtuYW1lfWB9PnJlZGRpdDwvYT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLXdpZGUgcm93LS1uby10b3AnPlxuICAgICAgICAgIDxkaXYgaWQ9J3Nob3ctc2hvcnQtbGluayc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMiBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+TGluazo8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LWVycm9yJyBpZD0naW5wdXQtZXJyb3ItY29weS1zaG9ydC1saW5rJyBoaWRkZW49J3RydWUnPmVycm9yIGhlcmU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nc2hvcnQtbGluaycgY2xhc3NOYW1lPSdpbnB1dC1kaXNhYmxlZCBpbnB1dC10ZXh0LS1mdWxsLXdpZHRoJyByZWFkT25seVxuICAgICAgICAgICAgICAgICAgICBzcGVsbENoZWNrPSdmYWxzZSdcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9e2Ake2hvc3R9LyR7c2hvcnRJZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH1cbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTEnIC8+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTInPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9J2J1dHRvbi0tcHJpbWFyeSBidXR0b24tLXdpZGUnIGRhdGEtZWxlbWVudHRvY29weT0nc2hvcnQtbGluaydcbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5jb3B5VG9DbGlwYm9hcmR9PmNvcHlcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBpZD0nc2hvdy1lbWJlZC1jb2RlJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd0ZXh0Jz5FbWJlZDo8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LWVycm9yJyBpZD0naW5wdXQtZXJyb3ItY29weS1lbWJlZC10ZXh0JyBoaWRkZW49J3RydWUnPmVycm9yIGhlcmU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIHsoY29udGVudFR5cGUgPT09ICd2aWRlby9tcDQnKSA/IChcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdlbWJlZC10ZXh0JyBjbGFzc05hbWU9J2lucHV0LWRpc2FibGVkIGlucHV0LXRleHQtLWZ1bGwtd2lkdGgnIHJlYWRPbmx5XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IHNwZWxsQ2hlY2s9J2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXtgPHZpZGVvIHdpZHRoPVwiMTAwJVwiIGNvbnRyb2xzIHBvc3Rlcj1cIiR7dGh1bWJuYWlsfVwiIHNyYz1cIiR7aG9zdH0vJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1cIi8+PC92aWRlbz5gfSAvPlxuICAgICAgICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdlbWJlZC10ZXh0JyBjbGFzc05hbWU9J2lucHV0LWRpc2FibGVkIGlucHV0LXRleHQtLWZ1bGwtd2lkdGgnIHJlYWRPbmx5XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IHNwZWxsQ2hlY2s9J2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXtgPGltZyBzcmM9XCIke2hvc3R9LyR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9XCIvPmB9XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xJyAvPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yJz5cbiAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXByaW1hcnkgYnV0dG9uLS13aWRlJyBkYXRhLWVsZW1lbnR0b2NvcHk9J2VtYmVkLXRleHQnXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMuY29weVRvQ2xpcGJvYXJkfT5jb3B5XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J2ZsZXgtY29udGFpbmVyLS1yb3cgZmxleC1jb250YWluZXItLXNwYWNlLWJldHdlZW4tYm90dG9tJz5cbiAgICAgICAgICA8TGluayBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRvPXtgLyR7c2hvcnRJZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH0+PHNwYW5cbiAgICAgICAgICAgIGNsYXNzTmFtZT0ndGV4dCc+RGlyZWN0IExpbms8L3NwYW4+PC9MaW5rPlxuICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj17YCR7aG9zdH0vJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfSBkb3dubG9hZD17bmFtZX0+RG93bmxvYWQ8L2E+XG4gICAgICAgICAgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj0naHR0cHM6Ly9sYnJ5LmlvL2RtY2EnPlJlcG9ydDwvYT5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFzc2V0SW5mbztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0SW5mby92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IHJlcXVlc3QgaW5mb1xuICBjb25zdCByZXF1ZXN0SWQgPSBzaG93LnJlcXVlc3QuaWQ7XG4gIC8vIHNlbGVjdCByZXF1ZXN0XG4gIGNvbnN0IHByZXZpb3VzUmVxdWVzdCA9IHNob3cucmVxdWVzdExpc3RbcmVxdWVzdElkXSB8fCBudWxsO1xuICAvLyBzZWxlY3QgY2hhbm5lbFxuICBsZXQgY2hhbm5lbDtcbiAgaWYgKHByZXZpb3VzUmVxdWVzdCkge1xuICAgIGNvbnN0IGNoYW5uZWxLZXkgPSBwcmV2aW91c1JlcXVlc3Qua2V5O1xuICAgIGNoYW5uZWwgPSBzaG93LmNoYW5uZWxMaXN0W2NoYW5uZWxLZXldIHx8IG51bGw7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBjaGFubmVsLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0NoYW5uZWwvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFNFTyBmcm9tICdjb21wb25lbnRzL1NFTyc7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgTmF2QmFyIGZyb20gJ2NvbnRhaW5lcnMvTmF2QmFyJztcbmltcG9ydCBDaGFubmVsQ2xhaW1zRGlzcGxheSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5JztcblxuY2xhc3MgU2hvd0NoYW5uZWwgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgY2hhbm5lbCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoY2hhbm5lbCkge1xuICAgICAgY29uc3QgeyBuYW1lLCBsb25nSWQsIHNob3J0SWQgfSA9IGNoYW5uZWw7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtuYW1lfSBjaGFubmVsPXtjaGFubmVsfSAvPlxuICAgICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAnPlxuICAgICAgICAgICAgICA8aDI+Y2hhbm5lbCBuYW1lOiB7bmFtZX08L2gyPlxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9eydmaW5lLXByaW50J30+ZnVsbCBjaGFubmVsIGlkOiB7bG9uZ0lkfTwvcD5cbiAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPXsnZmluZS1wcmludCd9PnNob3J0IGNoYW5uZWwgaWQ6IHtzaG9ydElkfTwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTEwJz5cbiAgICAgICAgICAgICAgPENoYW5uZWxDbGFpbXNEaXNwbGF5IC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICApO1xuICAgIH07XG4gICAgcmV0dXJuIChcbiAgICAgIDxFcnJvclBhZ2UgZXJyb3I9eydsb2FkaW5nIGNoYW5uZWwgZGF0YS4uLid9IC8+XG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2hvd0NoYW5uZWw7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93Q2hhbm5lbC92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBvblVwZGF0ZUNoYW5uZWxDbGFpbXMgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCBjaGFubmVsIGtleVxuICBjb25zdCByZXF1ZXN0ID0gc2hvdy5yZXF1ZXN0TGlzdFtzaG93LnJlcXVlc3QuaWRdO1xuICBjb25zdCBjaGFubmVsS2V5ID0gcmVxdWVzdC5rZXk7XG4gIC8vIHNlbGVjdCBjaGFubmVsIGNsYWltc1xuICBjb25zdCBjaGFubmVsID0gc2hvdy5jaGFubmVsTGlzdFtjaGFubmVsS2V5XSB8fCBudWxsO1xuICAvLyByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBjaGFubmVsS2V5LFxuICAgIGNoYW5uZWwsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIG9uVXBkYXRlQ2hhbm5lbENsYWltcyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENsYWltc0Rpc3BsYXkvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEFzc2V0UHJldmlldyBmcm9tICdjb21wb25lbnRzL0Fzc2V0UHJldmlldyc7XG5cbmNsYXNzIENoYW5uZWxDbGFpbXNEaXNwbGF5IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IgKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMuc2hvd05leHRSZXN1bHRzUGFnZSA9IHRoaXMuc2hvd05leHRSZXN1bHRzUGFnZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UgPSB0aGlzLnNob3dQcmV2aW91c1Jlc3VsdHNQYWdlLmJpbmQodGhpcyk7XG4gIH1cbiAgc2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UgKCkge1xuICAgIGNvbnN0IHsgY2hhbm5lbDogeyBjbGFpbXNEYXRhOiB7IGN1cnJlbnRQYWdlIH0gfSB9ID0gdGhpcy5wcm9wcztcbiAgICBjb25zdCBwcmV2aW91c1BhZ2UgPSBwYXJzZUludChjdXJyZW50UGFnZSkgLSAxO1xuICAgIHRoaXMuc2hvd05ld1BhZ2UocHJldmlvdXNQYWdlKTtcbiAgfVxuICBzaG93TmV4dFJlc3VsdHNQYWdlICgpIHtcbiAgICBjb25zdCB7IGNoYW5uZWw6IHsgY2xhaW1zRGF0YTogeyBjdXJyZW50UGFnZSB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgbmV4dFBhZ2UgPSBwYXJzZUludChjdXJyZW50UGFnZSkgKyAxO1xuICAgIHRoaXMuc2hvd05ld1BhZ2UobmV4dFBhZ2UpO1xuICB9XG4gIHNob3dOZXdQYWdlIChwYWdlKSB7XG4gICAgY29uc3QgeyBjaGFubmVsS2V5LCBjaGFubmVsOiB7IG5hbWUsIGxvbmdJZCB9IH0gPSB0aGlzLnByb3BzO1xuICAgIHRoaXMucHJvcHMub25VcGRhdGVDaGFubmVsQ2xhaW1zKGNoYW5uZWxLZXksIG5hbWUsIGxvbmdJZCwgcGFnZSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGNoYW5uZWw6IHsgY2xhaW1zRGF0YTogeyBjbGFpbXMsIGN1cnJlbnRQYWdlLCB0b3RhbFBhZ2VzIH0gfSB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXRhbGwnPlxuICAgICAgICB7KGNsYWltcy5sZW5ndGggPiAwKSA/IChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAge2NsYWltcy5tYXAoKGNsYWltLCBpbmRleCkgPT4gPEFzc2V0UHJldmlld1xuICAgICAgICAgICAgICBjbGFpbURhdGE9e2NsYWltfVxuICAgICAgICAgICAgICBrZXk9e2Ake2NsYWltLm5hbWV9LSR7aW5kZXh9YH1cbiAgICAgICAgICAgIC8+KX1cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIHsoY3VycmVudFBhZ2UgPiAxKSAmJlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT17J2J1dHRvbi0tc2Vjb25kYXJ5J30gb25DbGljaz17dGhpcy5zaG93UHJldmlvdXNSZXN1bHRzUGFnZX0+UHJldmlvdXMgUGFnZTwvYnV0dG9uPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHsoY3VycmVudFBhZ2UgPCB0b3RhbFBhZ2VzKSAmJlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT17J2J1dHRvbi0tc2Vjb25kYXJ5J30gb25DbGljaz17dGhpcy5zaG93TmV4dFJlc3VsdHNQYWdlfT5OZXh0IFBhZ2U8L2J1dHRvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICkgOiAoXG4gICAgICAgICAgPHA+VGhlcmUgYXJlIG5vIGNsYWltcyBpbiB0aGlzIGNoYW5uZWw8L3A+XG4gICAgICAgICl9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsQ2xhaW1zRGlzcGxheTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7c2l0ZToge2RlZmF1bHRzOiB7IGRlZmF1bHRUaHVtYm5haWwgfX19KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZGVmYXVsdFRodW1ibmFpbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0Fzc2V0UHJldmlldy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5cbmNvbnN0IEFzc2V0UHJldmlldyA9ICh7IGRlZmF1bHRUaHVtYm5haWwsIGNsYWltRGF0YTogeyBuYW1lLCBjbGFpbUlkLCBmaWxlRXh0LCBjb250ZW50VHlwZSwgdGh1bWJuYWlsIH0gfSkgPT4ge1xuICBjb25zdCBkaXJlY3RTb3VyY2VMaW5rID0gYCR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YDtcbiAgY29uc3Qgc2hvd1VybExpbmsgPSBgLyR7Y2xhaW1JZH0vJHtuYW1lfWA7XG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9J2Fzc2V0LWhvbGRlcic+XG4gICAgICA8TGluayB0bz17c2hvd1VybExpbmt9ID5cbiAgICAgICAgeygoKSA9PiB7XG4gICAgICAgICAgc3dpdGNoIChjb250ZW50VHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9qcGcnOlxuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgICAgICAgIGNhc2UgJ2ltYWdlL2dpZic6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsnYXNzZXQtcHJldmlldyd9XG4gICAgICAgICAgICAgICAgICBzcmM9e2RpcmVjdFNvdXJjZUxpbmt9XG4gICAgICAgICAgICAgICAgICBhbHQ9e25hbWV9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsnYXNzZXQtcHJldmlldyB2aWRlbyd9XG4gICAgICAgICAgICAgICAgICBzcmM9e3RodW1ibmFpbCB8fCBkZWZhdWx0VGh1bWJuYWlsfVxuICAgICAgICAgICAgICAgICAgYWx0PXtuYW1lfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxwPnVuc3VwcG9ydGVkIGZpbGUgdHlwZTwvcD5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCl9XG4gICAgICA8L0xpbms+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldFByZXZpZXc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9Bc3NldFByZXZpZXcvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2l0ZTogeyBob3N0LCB0aXRsZSB9IH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBob3N0LFxuICAgIHRpdGxlLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2UvaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IEhlbG1ldCBmcm9tICdyZWFjdC1oZWxtZXQnO1xuXG5jbGFzcyBGb3VyT2hGb3JQYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7dGl0bGUsIGhvc3R9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPEhlbG1ldD5cbiAgICAgICAgICA8dGl0bGU+e3RpdGxlfSAtIDQwNDwvdGl0bGU+XG4gICAgICAgICAgPGxpbmsgcmVsPSdjYW5vbmljYWwnIGhyZWY9e2Ake2hvc3R9LzQwNGB9IC8+XG4gICAgICAgIDwvSGVsbWV0PlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxoMj40MDQ8L2gyPlxuICAgICAgICAgIDxwPlRoYXQgcGFnZSBkb2VzIG5vdCBleGlzdDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBGb3VyT2hGb3JQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2Uvdmlldy5qc3giLCJjb25zdCB7IHNlbmRHQVNlcnZlRXZlbnQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzJyk7XG5jb25zdCB7IGRldGVybWluZVJlc3BvbnNlVHlwZSwgZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eSwgbG9nUmVxdWVzdERhdGEsIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0IH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL3NlcnZlSGVscGVycy5qcycpO1xuY29uc3QgbGJyeVVyaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeVVyaS5qcycpO1xuY29uc3QgaGFuZGxlU2hvd1JlbmRlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaGFuZGxlU2hvd1JlbmRlci5qc3gnKTtcbmNvbnN0IFNFUlZFID0gJ1NFUlZFJztcblxubW9kdWxlLmV4cG9ydHMgPSAoYXBwKSA9PiB7XG4gIC8vIHJvdXRlIHRvIHNlcnZlIGEgc3BlY2lmaWMgYXNzZXQgdXNpbmcgdGhlIGNoYW5uZWwgb3IgY2xhaW0gaWRcbiAgYXBwLmdldCgnLzppZGVudGlmaWVyLzpjbGFpbScsIChyZXEsIHJlcykgPT4ge1xuICAgIGNvbnN0IHsgaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSA9IHJlcTtcbiAgICAvLyBkZWNpZGUgaWYgdGhpcyBpcyBhIHNob3cgcmVxdWVzdFxuICAgIGxldCBoYXNGaWxlRXh0ZW5zaW9uO1xuICAgIHRyeSB7XG4gICAgICAoeyBoYXNGaWxlRXh0ZW5zaW9uIH0gPSBsYnJ5VXJpLnBhcnNlTW9kaWZpZXIocGFyYW1zLmNsYWltKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgICB9XG4gICAgbGV0IHJlc3BvbnNlVHlwZSA9IGRldGVybWluZVJlc3BvbnNlVHlwZShoYXNGaWxlRXh0ZW5zaW9uLCBoZWFkZXJzKTtcbiAgICBpZiAocmVzcG9uc2VUeXBlICE9PSBTRVJWRSkge1xuICAgICAgcmV0dXJuIGhhbmRsZVNob3dSZW5kZXIocmVxLCByZXMpO1xuICAgIH1cbiAgICAvLyBoYW5kbGUgc2VydmUgcmVxdWVzdFxuICAgIC8vIHNlbmQgZ29vZ2xlIGFuYWx5dGljc1xuICAgIHNlbmRHQVNlcnZlRXZlbnQoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKTtcbiAgICAvLyBwYXJzZSB0aGUgY2xhaW1cbiAgICBsZXQgY2xhaW1OYW1lO1xuICAgIHRyeSB7XG4gICAgICAoeyBjbGFpbU5hbWUgfSA9IGxicnlVcmkucGFyc2VDbGFpbShwYXJhbXMuY2xhaW0pKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZX0pO1xuICAgIH1cbiAgICAvLyBwYXJzZSB0aGUgaWRlbnRpZmllclxuICAgIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1JZDtcbiAgICB0cnkge1xuICAgICAgKHsgaXNDaGFubmVsLCBjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltSWQgfSA9IGxicnlVcmkucGFyc2VJZGVudGlmaWVyKHBhcmFtcy5pZGVudGlmaWVyKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgICB9XG4gICAgaWYgKCFpc0NoYW5uZWwpIHtcbiAgICAgIFtjbGFpbUlkLCBjbGFpbU5hbWVdID0gZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eShjbGFpbUlkLCBjbGFpbU5hbWUpO1xuICAgIH1cbiAgICAvLyBsb2cgdGhlIHJlcXVlc3QgZGF0YSBmb3IgZGVidWdnaW5nXG4gICAgbG9nUmVxdWVzdERhdGEocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIGNoYW5uZWxOYW1lLCBjbGFpbUlkKTtcbiAgICAvLyBnZXQgdGhlIGNsYWltIElkIGFuZCB0aGVuIHNlcnZlIHRoZSBhc3NldFxuICAgIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0KGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lLCBjbGFpbUlkLCBvcmlnaW5hbFVybCwgaXAsIHJlcyk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBzZXJ2ZSB0aGUgd2lubmluZyBhc3NldCBhdCBhIGNsYWltIG9yIGEgY2hhbm5lbCBwYWdlXG4gIGFwcC5nZXQoJy86Y2xhaW0nLCAocmVxLCByZXMpID0+IHtcbiAgICBjb25zdCB7IGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0gPSByZXE7XG4gICAgLy8gZGVjaWRlIGlmIHRoaXMgaXMgYSBzaG93IHJlcXVlc3RcbiAgICBsZXQgaGFzRmlsZUV4dGVuc2lvbjtcbiAgICB0cnkge1xuICAgICAgKHsgaGFzRmlsZUV4dGVuc2lvbiB9ID0gbGJyeVVyaS5wYXJzZU1vZGlmaWVyKHBhcmFtcy5jbGFpbSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgfVxuICAgIGxldCByZXNwb25zZVR5cGUgPSBkZXRlcm1pbmVSZXNwb25zZVR5cGUoaGFzRmlsZUV4dGVuc2lvbiwgaGVhZGVycyk7XG4gICAgaWYgKHJlc3BvbnNlVHlwZSAhPT0gU0VSVkUpIHtcbiAgICAgIHJldHVybiBoYW5kbGVTaG93UmVuZGVyKHJlcSwgcmVzKTtcbiAgICB9XG4gICAgLy8gaGFuZGxlIHNlcnZlIHJlcXVlc3RcbiAgICAvLyBzZW5kIGdvb2dsZSBhbmFseXRpY3NcbiAgICBzZW5kR0FTZXJ2ZUV2ZW50KGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCk7XG4gICAgLy8gcGFyc2UgdGhlIGNsYWltXG4gICAgbGV0IGNsYWltTmFtZTtcbiAgICB0cnkge1xuICAgICAgKHtjbGFpbU5hbWV9ID0gbGJyeVVyaS5wYXJzZUNsYWltKHBhcmFtcy5jbGFpbSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgfVxuICAgIC8vIGxvZyB0aGUgcmVxdWVzdCBkYXRhIGZvciBkZWJ1Z2dpbmdcbiAgICBsb2dSZXF1ZXN0RGF0YShyZXNwb25zZVR5cGUsIGNsYWltTmFtZSwgbnVsbCwgbnVsbCk7XG4gICAgLy8gZ2V0IHRoZSBjbGFpbSBJZCBhbmQgdGhlbiBzZXJ2ZSB0aGUgYXNzZXRcbiAgICBnZXRDbGFpbUlkQW5kU2VydmVBc3NldChudWxsLCBudWxsLCBjbGFpbU5hbWUsIG51bGwsIG9yaWdpbmFsVXJsLCBpcCwgcmVzKTtcbiAgfSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hc3NldC1yb3V0ZXMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IGdldENsYWltSWQsIGdldExvY2FsRmlsZVJlY29yZCB9ID0gcmVxdWlyZSgnLi4vY29udHJvbGxlcnMvc2VydmVDb250cm9sbGVyLmpzJyk7XG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJy4vZXJyb3JIYW5kbGVycy5qcycpO1xuXG5jb25zdCBTRVJWRSA9ICdTRVJWRSc7XG5jb25zdCBTSE9XID0gJ1NIT1cnO1xuY29uc3QgTk9fRklMRSA9ICdOT19GSUxFJztcbmNvbnN0IE5PX0NIQU5ORUwgPSAnTk9fQ0hBTk5FTCc7XG5jb25zdCBOT19DTEFJTSA9ICdOT19DTEFJTSc7XG5cbmZ1bmN0aW9uIGNsaWVudEFjY2VwdHNIdG1sICh7YWNjZXB0fSkge1xuICByZXR1cm4gYWNjZXB0ICYmIGFjY2VwdC5tYXRjaCgvdGV4dFxcL2h0bWwvKTtcbn07XG5cbmZ1bmN0aW9uIHJlcXVlc3RJc0Zyb21Ccm93c2VyIChoZWFkZXJzKSB7XG4gIHJldHVybiBoZWFkZXJzWyd1c2VyLWFnZW50J10gJiYgaGVhZGVyc1sndXNlci1hZ2VudCddLm1hdGNoKC9Nb3ppbGxhLyk7XG59O1xuXG5mdW5jdGlvbiBjbGllbnRXYW50c0Fzc2V0ICh7YWNjZXB0LCByYW5nZX0pIHtcbiAgY29uc3QgaW1hZ2VJc1dhbnRlZCA9IGFjY2VwdCAmJiBhY2NlcHQubWF0Y2goL2ltYWdlXFwvLiovKSAmJiAhYWNjZXB0Lm1hdGNoKC90ZXh0XFwvaHRtbC8pICYmICFhY2NlcHQubWF0Y2goL3RleHRcXC9cXCovKTtcbiAgY29uc3QgdmlkZW9Jc1dhbnRlZCA9IGFjY2VwdCAmJiByYW5nZTtcbiAgcmV0dXJuIGltYWdlSXNXYW50ZWQgfHwgdmlkZW9Jc1dhbnRlZDtcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRDbGFpbUlkIChjbGFpbUlkKSB7XG4gIHJldHVybiAoKGNsYWltSWQubGVuZ3RoID09PSA0MCkgJiYgIS9bXkEtWmEtejAtOV0vZy50ZXN0KGNsYWltSWQpKTtcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRTaG9ydElkIChjbGFpbUlkKSB7XG4gIHJldHVybiBjbGFpbUlkLmxlbmd0aCA9PT0gMTsgIC8vIGl0IHNob3VsZCByZWFsbHkgZXZhbHVhdGUgdGhlIHNob3J0IHVybCBpdHNlbGZcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRTaG9ydElkT3JDbGFpbUlkIChpbnB1dCkge1xuICByZXR1cm4gKGlzVmFsaWRDbGFpbUlkKGlucHV0KSB8fCBpc1ZhbGlkU2hvcnRJZChpbnB1dCkpO1xufTtcblxuZnVuY3Rpb24gc2VydmVBc3NldFRvQ2xpZW50IChjbGFpbUlkLCBuYW1lLCByZXMpIHtcbiAgcmV0dXJuIGdldExvY2FsRmlsZVJlY29yZChjbGFpbUlkLCBuYW1lKVxuICAgIC50aGVuKGZpbGVSZWNvcmQgPT4ge1xuICAgICAgLy8gY2hlY2sgdGhhdCBhIGxvY2FsIHJlY29yZCB3YXMgZm91bmRcbiAgICAgIGlmIChmaWxlUmVjb3JkID09PSBOT19GSUxFKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDMwNykucmVkaXJlY3QoYC9hcGkvY2xhaW0vZ2V0LyR7bmFtZX0vJHtjbGFpbUlkfWApO1xuICAgICAgfVxuICAgICAgLy8gc2VydmUgdGhlIGZpbGVcbiAgICAgIGNvbnN0IHtmaWxlUGF0aCwgZmlsZVR5cGV9ID0gZmlsZVJlY29yZDtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBzZXJ2aW5nIGZpbGU6ICR7ZmlsZVBhdGh9YCk7XG4gICAgICBjb25zdCBzZW5kRmlsZU9wdGlvbnMgPSB7XG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnWC1Db250ZW50LVR5cGUtT3B0aW9ucyc6ICdub3NuaWZmJyxcbiAgICAgICAgICAnQ29udGVudC1UeXBlJyAgICAgICAgICA6IGZpbGVUeXBlIHx8ICdpbWFnZS9qcGVnJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICByZXMuc3RhdHVzKDIwMCkuc2VuZEZpbGUoZmlsZVBhdGgsIHNlbmRGaWxlT3B0aW9ucyk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQgKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lLCBjbGFpbUlkLCBvcmlnaW5hbFVybCwgaXAsIHJlcykge1xuICAgIC8vIGdldCB0aGUgY2xhaW0gSWQgYW5kIHRoZW4gc2VydmUgdGhlIGFzc2V0XG4gICAgZ2V0Q2xhaW1JZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSwgY2xhaW1JZClcbiAgICAgIC50aGVuKGZ1bGxDbGFpbUlkID0+IHtcbiAgICAgICAgaWYgKGZ1bGxDbGFpbUlkID09PSBOT19DTEFJTSkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdubyBjbGFpbSBpZCBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfSBlbHNlIGlmIChmdWxsQ2xhaW1JZCA9PT0gTk9fQ0hBTk5FTCkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdubyBjaGFubmVsIGlkIGNvdWxkIGJlIGZvdW5kJ30pO1xuICAgICAgICB9XG4gICAgICAgIHNlcnZlQXNzZXRUb0NsaWVudChmdWxsQ2xhaW1JZCwgY2xhaW1OYW1lLCByZXMpO1xuICAgICAgICAvLyBwb3N0VG9TdGF0cyhyZXNwb25zZVR5cGUsIG9yaWdpbmFsVXJsLCBpcCwgY2xhaW1OYW1lLCBmdWxsQ2xhaW1JZCwgJ3N1Y2Nlc3MnKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICAgIC8vIHBvc3RUb1N0YXRzKHJlc3BvbnNlVHlwZSwgb3JpZ2luYWxVcmwsIGlwLCBjbGFpbU5hbWUsIGZ1bGxDbGFpbUlkLCAnZmFpbCcpO1xuICAgICAgfSk7XG4gIH0sXG4gIGRldGVybWluZVJlc3BvbnNlVHlwZSAoaGFzRmlsZUV4dGVuc2lvbiwgaGVhZGVycykge1xuICAgIGxldCByZXNwb25zZVR5cGU7XG4gICAgaWYgKGhhc0ZpbGVFeHRlbnNpb24pIHtcbiAgICAgIHJlc3BvbnNlVHlwZSA9IFNFUlZFOyAgLy8gYXNzdW1lIGEgc2VydmUgcmVxdWVzdCBpZiBmaWxlIGV4dGVuc2lvbiBpcyBwcmVzZW50XG4gICAgICBpZiAoY2xpZW50QWNjZXB0c0h0bWwoaGVhZGVycykpIHsgIC8vIGlmIHRoZSByZXF1ZXN0IGNvbWVzIGZyb20gYSBicm93c2VyLCBjaGFuZ2UgaXQgdG8gYSBzaG93IHJlcXVlc3RcbiAgICAgICAgcmVzcG9uc2VUeXBlID0gU0hPVztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzcG9uc2VUeXBlID0gU0hPVztcbiAgICAgIGlmIChjbGllbnRXYW50c0Fzc2V0KGhlYWRlcnMpICYmIHJlcXVlc3RJc0Zyb21Ccm93c2VyKGhlYWRlcnMpKSB7ICAvLyB0aGlzIGlzIGluIGNhc2Ugc29tZW9uZSBlbWJlZHMgYSBzaG93IHVybFxuICAgICAgICBsb2dnZXIuZGVidWcoJ1Nob3cgcmVxdWVzdCBjYW1lIGZyb20gYnJvd3NlciBidXQgd2FudHMgYW4gaW1hZ2UvdmlkZW8uIENoYW5naW5nIHJlc3BvbnNlIHRvIHNlcnZlLi4uJyk7XG4gICAgICAgIHJlc3BvbnNlVHlwZSA9IFNFUlZFO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2VUeXBlO1xuICB9LFxuICBmbGlwQ2xhaW1OYW1lQW5kSWRGb3JCYWNrd2FyZHNDb21wYXRpYmlsaXR5IChpZGVudGlmaWVyLCBuYW1lKSB7XG4gICAgLy8gdGhpcyBpcyBhIHBhdGNoIGZvciBiYWNrd2FyZHMgY29tcGF0YWJpbGl0eSB3aXRoICcvbmFtZS9jbGFpbV9pZCcgdXJsIGZvcm1hdFxuICAgIGlmIChpc1ZhbGlkU2hvcnRJZE9yQ2xhaW1JZChuYW1lKSAmJiAhaXNWYWxpZFNob3J0SWRPckNsYWltSWQoaWRlbnRpZmllcikpIHtcbiAgICAgIGNvbnN0IHRlbXBOYW1lID0gbmFtZTtcbiAgICAgIG5hbWUgPSBpZGVudGlmaWVyO1xuICAgICAgaWRlbnRpZmllciA9IHRlbXBOYW1lO1xuICAgIH1cbiAgICByZXR1cm4gW2lkZW50aWZpZXIsIG5hbWVdO1xuICB9LFxuICBsb2dSZXF1ZXN0RGF0YSAocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIGNoYW5uZWxOYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdyZXNwb25zZVR5cGUgPT09JywgcmVzcG9uc2VUeXBlKTtcbiAgICBsb2dnZXIuZGVidWcoJ2NsYWltIG5hbWUgPT09ICcsIGNsYWltTmFtZSk7XG4gICAgbG9nZ2VyLmRlYnVnKCdjaGFubmVsIG5hbWUgPT09JywgY2hhbm5lbE5hbWUpO1xuICAgIGxvZ2dlci5kZWJ1ZygnY2xhaW0gaWQgPT09JywgY2xhaW1JZCk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvc2VydmVIZWxwZXJzLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgUkVHRVhQX0lOVkFMSURfQ0xBSU0gIDogL1teQS1aYS16MC05LV0vZyxcbiAgUkVHRVhQX0lOVkFMSURfQ0hBTk5FTDogL1teQS1aYS16MC05LUBdL2csXG4gIFJFR0VYUF9BRERSRVNTICAgICAgICA6IC9eYig/PVteME9JbF17MzIsMzN9KVswLTlBLVphLXpdezMyLDMzfSQvLFxuICBDSEFOTkVMX0NIQVIgICAgICAgICAgOiAnQCcsXG4gIHBhcnNlSWRlbnRpZmllciAgICAgICA6IGZ1bmN0aW9uIChpZGVudGlmaWVyKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdwYXJzaW5nIGlkZW50aWZpZXI6JywgaWRlbnRpZmllcik7XG4gICAgY29uc3QgY29tcG9uZW50c1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICAgICcoW146JCMvXSopJyArIC8vIHZhbHVlIChzdG9wcyBhdCB0aGUgZmlyc3Qgc2VwYXJhdG9yIG9yIGVuZClcbiAgICAgICcoWzokI10/KShbXi9dKiknIC8vIG1vZGlmaWVyIHNlcGFyYXRvciwgbW9kaWZpZXIgKHN0b3BzIGF0IHRoZSBmaXJzdCBwYXRoIHNlcGFyYXRvciBvciBlbmQpXG4gICAgKTtcbiAgICBjb25zdCBbcHJvdG8sIHZhbHVlLCBtb2RpZmllclNlcGVyYXRvciwgbW9kaWZpZXJdID0gY29tcG9uZW50c1JlZ2V4XG4gICAgICAuZXhlYyhpZGVudGlmaWVyKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcbiAgICBsb2dnZXIuZGVidWcoYCR7cHJvdG99LCAke3ZhbHVlfSwgJHttb2RpZmllclNlcGVyYXRvcn0sICR7bW9kaWZpZXJ9YCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIHVybC4gIE5vIGNoYW5uZWwgbmFtZSBwcm92aWRlZCBiZWZvcmUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IGlzQ2hhbm5lbCA9IHZhbHVlLnN0YXJ0c1dpdGgobW9kdWxlLmV4cG9ydHMuQ0hBTk5FTF9DSEFSKTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGlzQ2hhbm5lbCA/IHZhbHVlIDogbnVsbDtcbiAgICBsZXQgY2xhaW1JZDtcbiAgICBpZiAoaXNDaGFubmVsKSB7XG4gICAgICBpZiAoIWNoYW5uZWxOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2hhbm5lbCBuYW1lIGFmdGVyIEAuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2hhbm5lbE5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NIQU5ORUwpO1xuICAgICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgY2hhcmFjdGVycyBpbiBjaGFubmVsIG5hbWU6ICR7bmFtZUJhZENoYXJzLmpvaW4oJywgJyl9LmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjbGFpbUlkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gbW9kaWZpZXIgcHJvdmlkZWQgYWZ0ZXIgc2VwYXJhdG9yIFwiJHttb2RpZmllclNlcGVyYXRvcn1cImApO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IgPT09ICc6Jykge1xuICAgICAgICBjaGFubmVsQ2xhaW1JZCA9IG1vZGlmaWVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiIG1vZGlmaWVyIGlzIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkYCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBpc0NoYW5uZWwsXG4gICAgICBjaGFubmVsTmFtZSxcbiAgICAgIGNoYW5uZWxDbGFpbUlkLFxuICAgICAgY2xhaW1JZCxcbiAgICB9O1xuICB9LFxuICBwYXJzZUNsYWltOiBmdW5jdGlvbiAoY2xhaW0pIHtcbiAgICBsb2dnZXIuZGVidWcoJ3BhcnNpbmcgbmFtZTonLCBjbGFpbSk7XG4gICAgY29uc3QgY29tcG9uZW50c1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICAgICcoW146JCMvLl0qKScgKyAvLyBuYW1lIChzdG9wcyBhdCB0aGUgZmlyc3QgbW9kaWZpZXIpXG4gICAgICAnKFs6JCMuXT8pKFteL10qKScgLy8gbW9kaWZpZXIgc2VwYXJhdG9yLCBtb2RpZmllciAoc3RvcHMgYXQgdGhlIGZpcnN0IHBhdGggc2VwYXJhdG9yIG9yIGVuZClcbiAgICApO1xuICAgIGNvbnN0IFtwcm90bywgY2xhaW1OYW1lLCBtb2RpZmllclNlcGVyYXRvciwgbW9kaWZpZXJdID0gY29tcG9uZW50c1JlZ2V4XG4gICAgICAuZXhlYyhjbGFpbSlcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG4gICAgbG9nZ2VyLmRlYnVnKGAke3Byb3RvfSwgJHtjbGFpbU5hbWV9LCAke21vZGlmaWVyU2VwZXJhdG9yfSwgJHttb2RpZmllcn1gKTtcblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG5hbWVcbiAgICBpZiAoIWNsYWltTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjbGFpbSBuYW1lIHByb3ZpZGVkIGJlZm9yZSAuJyk7XG4gICAgfVxuICAgIGNvbnN0IG5hbWVCYWRDaGFycyA9IChjbGFpbU5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NMQUlNKTtcbiAgICBpZiAobmFtZUJhZENoYXJzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgY2hhcmFjdGVycyBpbiBjbGFpbSBuYW1lOiAke25hbWVCYWRDaGFycy5qb2luKCcsICcpfS5gKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IpIHtcbiAgICAgIGlmICghbW9kaWZpZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBmaWxlIGV4dGVuc2lvbiBwcm92aWRlZCBhZnRlciBzZXBhcmF0b3IgJHttb2RpZmllclNlcGVyYXRvcn0uYCk7XG4gICAgICB9XG4gICAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IgIT09ICcuJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSAke21vZGlmaWVyU2VwZXJhdG9yfSBtb2RpZmllciBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjbGFpbSBuYW1lYCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHJldHVybiByZXN1bHRzXG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYWltTmFtZSxcbiAgICB9O1xuICB9LFxuICBwYXJzZU1vZGlmaWVyOiBmdW5jdGlvbiAoY2xhaW0pIHtcbiAgICBsb2dnZXIuZGVidWcoJ3BhcnNpbmcgbW9kaWZpZXI6JywgY2xhaW0pO1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjLy5dKiknICsgLy8gbmFtZSAoc3RvcHMgYXQgdGhlIGZpcnN0IG1vZGlmaWVyKVxuICAgICAgJyhbOiQjLl0/KShbXi9dKiknIC8vIG1vZGlmaWVyIHNlcGFyYXRvciwgbW9kaWZpZXIgKHN0b3BzIGF0IHRoZSBmaXJzdCBwYXRoIHNlcGFyYXRvciBvciBlbmQpXG4gICAgKTtcbiAgICBjb25zdCBbcHJvdG8sIGNsYWltTmFtZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleFxuICAgICAgLmV4ZWMoY2xhaW0pXG4gICAgICAubWFwKG1hdGNoID0+IG1hdGNoIHx8IG51bGwpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgJHtwcm90b30sICR7Y2xhaW1OYW1lfSwgJHttb2RpZmllclNlcGVyYXRvcn0sICR7bW9kaWZpZXJ9YCk7XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgaGFzRmlsZUV4dGVuc2lvbiA9IGZhbHNlO1xuICAgIGlmIChtb2RpZmllclNlcGVyYXRvcikge1xuICAgICAgaGFzRmlsZUV4dGVuc2lvbiA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBoYXNGaWxlRXh0ZW5zaW9uLFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvbGJyeVVyaS5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXJUb1N0cmluZyB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IHsgY3JlYXRlU3RvcmUsIGFwcGx5TWlkZGxld2FyZSB9IGZyb20gJ3JlZHV4JztcbmltcG9ydCBSZWR1Y2VyIGZyb20gJy4uLy4uL2NsaWVudC9yZWR1Y2Vycy9pbmRleCc7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IFN0YXRpY1JvdXRlciB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEdBTGlzdGVuZXIgZnJvbSAnLi4vLi4vY2xpZW50L2NvbXBvbmVudHMvR0FMaXN0ZW5lci9pbmRleCc7XG5pbXBvcnQgQXBwIGZyb20gJy4uLy4uL2NsaWVudC9hcHAnO1xuaW1wb3J0IHJlbmRlckZ1bGxQYWdlIGZyb20gJy4vcmVuZGVyRnVsbFBhZ2UnO1xuaW1wb3J0IGNyZWF0ZVNhZ2FNaWRkbGV3YXJlIGZyb20gJ3JlZHV4LXNhZ2EnO1xuaW1wb3J0IHsgY2FsbCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgeyBoYW5kbGVTaG93UGFnZVVyaSB9IGZyb20gJy4uLy4uL2NsaWVudC9zYWdhcy9zaG93X3VyaSc7XG5pbXBvcnQgeyBvbkhhbmRsZVNob3dQYWdlVXJpIH0gZnJvbSAnLi4vLi4vY2xpZW50L2FjdGlvbnMvc2hvdyc7XG5cbmltcG9ydCBIZWxtZXQgZnJvbSAncmVhY3QtaGVsbWV0JztcblxuY29uc3QgcmV0dXJuU2FnYVdpdGhQYXJhbXMgPSAoc2FnYSwgcGFyYW1zKSA9PiB7XG4gIHJldHVybiBmdW5jdGlvbiAqICgpIHtcbiAgICB5aWVsZCBjYWxsKHNhZ2EsIHBhcmFtcyk7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChyZXEsIHJlcykgPT4ge1xuICBsZXQgY29udGV4dCA9IHt9O1xuXG4gIC8vIGNyZWF0ZSBhbmQgYXBwbHkgbWlkZGxld2FyZVxuICBjb25zdCBzYWdhTWlkZGxld2FyZSA9IGNyZWF0ZVNhZ2FNaWRkbGV3YXJlKCk7XG4gIGNvbnN0IG1pZGRsZXdhcmUgPSBhcHBseU1pZGRsZXdhcmUoc2FnYU1pZGRsZXdhcmUpO1xuXG4gIC8vIGNyZWF0ZSBhIG5ldyBSZWR1eCBzdG9yZSBpbnN0YW5jZVxuICBjb25zdCBzdG9yZSA9IGNyZWF0ZVN0b3JlKFJlZHVjZXIsIG1pZGRsZXdhcmUpO1xuXG4gIC8vIGNyZWF0ZSBzYWdhXG4gIGNvbnN0IGFjdGlvbiA9IG9uSGFuZGxlU2hvd1BhZ2VVcmkocmVxLnBhcmFtcyk7XG4gIGNvbnN0IHNhZ2EgPSByZXR1cm5TYWdhV2l0aFBhcmFtcyhoYW5kbGVTaG93UGFnZVVyaSwgYWN0aW9uKTtcblxuICAvLyBydW4gdGhlIHNhZ2EgbWlkZGxld2FyZVxuICBzYWdhTWlkZGxld2FyZVxuICAgIC5ydW4oc2FnYSlcbiAgICAuZG9uZVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIC8vIHJlbmRlciBjb21wb25lbnQgdG8gYSBzdHJpbmdcbiAgICAgIGNvbnN0IGh0bWwgPSByZW5kZXJUb1N0cmluZyhcbiAgICAgICAgPFByb3ZpZGVyIHN0b3JlPXtzdG9yZX0+XG4gICAgICAgICAgPFN0YXRpY1JvdXRlciBsb2NhdGlvbj17cmVxLnVybH0gY29udGV4dD17Y29udGV4dH0+XG4gICAgICAgICAgICA8R0FMaXN0ZW5lcj5cbiAgICAgICAgICAgICAgPEFwcCAvPlxuICAgICAgICAgICAgPC9HQUxpc3RlbmVyPlxuICAgICAgICAgIDwvU3RhdGljUm91dGVyPlxuICAgICAgICA8L1Byb3ZpZGVyPlxuICAgICAgKTtcblxuICAgICAgLy8gZ2V0IGhlYWQgdGFncyBmcm9tIGhlbG1ldFxuICAgICAgY29uc3QgaGVsbWV0ID0gSGVsbWV0LnJlbmRlclN0YXRpYygpO1xuXG4gICAgICAvLyBjaGVjayBmb3IgYSByZWRpcmVjdFxuICAgICAgaWYgKGNvbnRleHQudXJsKSB7XG4gICAgICAgIHJldHVybiByZXMucmVkaXJlY3QoMzAxLCBjb250ZXh0LnVybCk7XG4gICAgICB9XG5cbiAgICAgIC8vIGdldCB0aGUgaW5pdGlhbCBzdGF0ZSBmcm9tIG91ciBSZWR1eCBzdG9yZVxuICAgICAgY29uc3QgcHJlbG9hZGVkU3RhdGUgPSBzdG9yZS5nZXRTdGF0ZSgpO1xuXG4gICAgICAvLyBzZW5kIHRoZSByZW5kZXJlZCBwYWdlIGJhY2sgdG8gdGhlIGNsaWVudFxuICAgICAgcmVzLnNlbmQocmVuZGVyRnVsbFBhZ2UoaGVsbWV0LCBodG1sLCBwcmVsb2FkZWRTdGF0ZSkpO1xuICAgIH0pO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVkdXgtc2FnYVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlZHV4LXNhZ2FcIlxuLy8gbW9kdWxlIGlkID0gMTUxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImltcG9ydCB7IGNhbGwsIHB1dCwgdGFrZUxhdGVzdCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBvblJlcXVlc3RFcnJvciwgb25OZXdDaGFubmVsUmVxdWVzdCwgb25OZXdBc3NldFJlcXVlc3QgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IHsgbmV3QXNzZXRSZXF1ZXN0IH0gZnJvbSAnc2FnYXMvc2hvd19hc3NldCc7XG5pbXBvcnQgeyBuZXdDaGFubmVsUmVxdWVzdCB9IGZyb20gJ3NhZ2FzL3Nob3dfY2hhbm5lbCc7XG5pbXBvcnQgbGJyeVVyaSBmcm9tICd1dGlscy9sYnJ5VXJpJztcblxuZnVuY3Rpb24gKiBwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSAobW9kaWZpZXIsIGNsYWltKSB7XG4gIC8vIHRoaXMgaXMgYSByZXF1ZXN0IGZvciBhbiBhc3NldFxuICAvLyBjbGFpbSB3aWxsIGJlIGFuIGFzc2V0IGNsYWltXG4gIC8vIHRoZSBpZGVudGlmaWVyIGNvdWxkIGJlIGEgY2hhbm5lbCBvciBhIGNsYWltIGlkXG4gIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1JZCwgY2xhaW1OYW1lLCBleHRlbnNpb247XG4gIHRyeSB7XG4gICAgKHsgaXNDaGFubmVsLCBjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltSWQgfSA9IGxicnlVcmkucGFyc2VJZGVudGlmaWVyKG1vZGlmaWVyKSk7XG4gICAgKHsgY2xhaW1OYW1lLCBleHRlbnNpb24gfSA9IGxicnlVcmkucGFyc2VDbGFpbShjbGFpbSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIHRyaWdnZXIgYW4gbmV3IGFjdGlvbiB0byB1cGRhdGUgdGhlIHN0b3JlXG4gIGlmIChpc0NoYW5uZWwpIHtcbiAgICByZXR1cm4geWllbGQgY2FsbChuZXdBc3NldFJlcXVlc3QsIG9uTmV3QXNzZXRSZXF1ZXN0KGNsYWltTmFtZSwgbnVsbCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBleHRlbnNpb24pKTtcbiAgfTtcbiAgeWllbGQgY2FsbChuZXdBc3NldFJlcXVlc3QsIG9uTmV3QXNzZXRSZXF1ZXN0KGNsYWltTmFtZSwgY2xhaW1JZCwgbnVsbCwgbnVsbCwgZXh0ZW5zaW9uKSk7XG59XG5mdW5jdGlvbiAqIHBhcnNlQW5kVXBkYXRlQ2xhaW1Pbmx5IChjbGFpbSkge1xuICAvLyB0aGlzIGNvdWxkIGJlIGEgcmVxdWVzdCBmb3IgYW4gYXNzZXQgb3IgYSBjaGFubmVsIHBhZ2VcbiAgLy8gY2xhaW0gY291bGQgYmUgYW4gYXNzZXQgY2xhaW0gb3IgYSBjaGFubmVsIGNsYWltXG4gIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZDtcbiAgdHJ5IHtcbiAgICAoeyBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCB9ID0gbGJyeVVyaS5wYXJzZUlkZW50aWZpZXIoY2xhaW0pKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyB0cmlnZ2VyIGFuIG5ldyBhY3Rpb24gdG8gdXBkYXRlIHRoZSBzdG9yZVxuICAvLyByZXR1cm4gZWFybHkgaWYgdGhpcyByZXF1ZXN0IGlzIGZvciBhIGNoYW5uZWxcbiAgaWYgKGlzQ2hhbm5lbCkge1xuICAgIHJldHVybiB5aWVsZCBjYWxsKG5ld0NoYW5uZWxSZXF1ZXN0LCBvbk5ld0NoYW5uZWxSZXF1ZXN0KGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkpO1xuICB9XG4gIC8vIGlmIG5vdCBmb3IgYSBjaGFubmVsLCBwYXJzZSB0aGUgY2xhaW0gcmVxdWVzdFxuICBsZXQgY2xhaW1OYW1lLCBleHRlbnNpb247XG4gIHRyeSB7XG4gICAgKHtjbGFpbU5hbWUsIGV4dGVuc2lvbn0gPSBsYnJ5VXJpLnBhcnNlQ2xhaW0oY2xhaW0pKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICB5aWVsZCBjYWxsKG5ld0Fzc2V0UmVxdWVzdCwgb25OZXdBc3NldFJlcXVlc3QoY2xhaW1OYW1lLCBudWxsLCBudWxsLCBudWxsLCBleHRlbnNpb24pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uICogaGFuZGxlU2hvd1BhZ2VVcmkgKGFjdGlvbikge1xuICBjb25zdCB7IGlkZW50aWZpZXIsIGNsYWltIH0gPSBhY3Rpb24uZGF0YTtcbiAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICByZXR1cm4geWllbGQgY2FsbChwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSwgaWRlbnRpZmllciwgY2xhaW0pO1xuICB9XG4gIHlpZWxkIGNhbGwocGFyc2VBbmRVcGRhdGVDbGFpbU9ubHksIGNsYWltKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoSGFuZGxlU2hvd1BhZ2VVcmkgKCkge1xuICB5aWVsZCB0YWtlTGF0ZXN0KGFjdGlvbnMuSEFORExFX1NIT1dfVVJJLCBoYW5kbGVTaG93UGFnZVVyaSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NhZ2FzL3Nob3dfdXJpLmpzIiwiaW1wb3J0IHsgY2FsbCwgcHV0LCBzZWxlY3QsIHRha2VMYXRlc3QgfSBmcm9tICdyZWR1eC1zYWdhL2VmZmVjdHMnO1xuaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvc2hvd19hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgYWRkUmVxdWVzdFRvUmVxdWVzdExpc3QsIG9uUmVxdWVzdEVycm9yLCBvblJlcXVlc3RVcGRhdGUsIGFkZEFzc2V0VG9Bc3NldExpc3QgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IHsgZ2V0TG9uZ0NsYWltSWQsIGdldFNob3J0SWQsIGdldENsYWltRGF0YSB9IGZyb20gJ2FwaS9hc3NldEFwaSc7XG5pbXBvcnQgeyBzZWxlY3RTaG93U3RhdGUgfSBmcm9tICdzZWxlY3RvcnMvc2hvdyc7XG5pbXBvcnQgeyBzZWxlY3RTaXRlSG9zdCB9IGZyb20gJ3NlbGVjdG9ycy9zaXRlJztcblxuZXhwb3J0IGZ1bmN0aW9uICogbmV3QXNzZXRSZXF1ZXN0IChhY3Rpb24pIHtcbiAgY29uc3QgeyByZXF1ZXN0VHlwZSwgcmVxdWVzdElkLCBuYW1lLCBtb2RpZmllciB9ID0gYWN0aW9uLmRhdGE7XG4gIC8vIHB1dCBhbiBhY3Rpb24gdG8gdXBkYXRlIHRoZSByZXF1ZXN0IGluIHJlZHV4XG4gIHlpZWxkIHB1dChvblJlcXVlc3RVcGRhdGUocmVxdWVzdFR5cGUsIHJlcXVlc3RJZCkpO1xuICAvLyBpcyB0aGlzIGFuIGV4aXN0aW5nIHJlcXVlc3Q/XG4gIC8vIElmIHRoaXMgdXJpIGlzIGluIHRoZSByZXF1ZXN0IGxpc3QsIGl0J3MgYWxyZWFkeSBiZWVuIGZldGNoZWRcbiAgY29uc3Qgc3RhdGUgPSB5aWVsZCBzZWxlY3Qoc2VsZWN0U2hvd1N0YXRlKTtcbiAgY29uc3QgaG9zdCA9IHlpZWxkIHNlbGVjdChzZWxlY3RTaXRlSG9zdCk7XG4gIGlmIChzdGF0ZS5yZXF1ZXN0TGlzdFtyZXF1ZXN0SWRdKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLy8gZ2V0IGxvbmcgaWQgJiYgYWRkIHJlcXVlc3QgdG8gcmVxdWVzdCBsaXN0XG4gIGxldCBsb25nSWQ7XG4gIHRyeSB7XG4gICAgKHtkYXRhOiBsb25nSWR9ID0geWllbGQgY2FsbChnZXRMb25nQ2xhaW1JZCwgaG9zdCwgbmFtZSwgbW9kaWZpZXIpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICBjb25zdCBhc3NldEtleSA9IGBhIyR7bmFtZX0jJHtsb25nSWR9YDtcbiAgeWllbGQgcHV0KGFkZFJlcXVlc3RUb1JlcXVlc3RMaXN0KHJlcXVlc3RJZCwgbnVsbCwgYXNzZXRLZXkpKTtcbiAgLy8gaXMgdGhpcyBhbiBleGlzdGluZyBhc3NldD9cbiAgLy8gSWYgdGhpcyBhc3NldCBpcyBpbiB0aGUgYXNzZXQgbGlzdCwgaXQncyBhbHJlYWR5IGJlZW4gZmV0Y2hlZFxuICBpZiAoc3RhdGUuYXNzZXRMaXN0W2Fzc2V0S2V5XSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIC8vIGdldCBzaG9ydCBJZFxuICBsZXQgc2hvcnRJZDtcbiAgdHJ5IHtcbiAgICAoe2RhdGE6IHNob3J0SWR9ID0geWllbGQgY2FsbChnZXRTaG9ydElkLCBob3N0LCBuYW1lLCBsb25nSWQpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyBnZXQgYXNzZXQgY2xhaW0gZGF0YVxuICBsZXQgY2xhaW1EYXRhO1xuICB0cnkge1xuICAgICh7ZGF0YTogY2xhaW1EYXRhfSA9IHlpZWxkIGNhbGwoZ2V0Q2xhaW1EYXRhLCBob3N0LCBuYW1lLCBsb25nSWQpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyBhZGQgYXNzZXQgdG8gYXNzZXQgbGlzdFxuICB5aWVsZCBwdXQoYWRkQXNzZXRUb0Fzc2V0TGlzdChhc3NldEtleSwgbnVsbCwgbmFtZSwgbG9uZ0lkLCBzaG9ydElkLCBjbGFpbURhdGEpKTtcbiAgLy8gY2xlYXIgYW55IGVycm9ycyBpbiByZXF1ZXN0IGVycm9yXG4gIHlpZWxkIHB1dChvblJlcXVlc3RFcnJvcihudWxsKSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gKiB3YXRjaE5ld0Fzc2V0UmVxdWVzdCAoKSB7XG4gIHlpZWxkIHRha2VMYXRlc3QoYWN0aW9ucy5BU1NFVF9SRVFVRVNUX05FVywgbmV3QXNzZXRSZXF1ZXN0KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvc2FnYXMvc2hvd19hc3NldC5qcyIsImltcG9ydCBSZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9uZ0NsYWltSWQgKGhvc3QsIG5hbWUsIG1vZGlmaWVyKSB7XG4gIGxldCBib2R5ID0ge307XG4gIC8vIGNyZWF0ZSByZXF1ZXN0IHBhcmFtc1xuICBpZiAobW9kaWZpZXIpIHtcbiAgICBpZiAobW9kaWZpZXIuaWQpIHtcbiAgICAgIGJvZHlbJ2NsYWltSWQnXSA9IG1vZGlmaWVyLmlkO1xuICAgIH0gZWxzZSB7XG4gICAgICBib2R5WydjaGFubmVsTmFtZSddID0gbW9kaWZpZXIuY2hhbm5lbC5uYW1lO1xuICAgICAgYm9keVsnY2hhbm5lbENsYWltSWQnXSA9IG1vZGlmaWVyLmNoYW5uZWwuaWQ7XG4gICAgfVxuICB9XG4gIGJvZHlbJ2NsYWltTmFtZSddID0gbmFtZTtcbiAgY29uc3QgcGFyYW1zID0ge1xuICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICBib2R5ICAgOiBKU09OLnN0cmluZ2lmeShib2R5KSxcbiAgfTtcbiAgLy8gY3JlYXRlIHVybFxuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2xhaW0vbG9uZy1pZGA7XG4gIC8vIHJldHVybiB0aGUgcmVxdWVzdCBwcm9taXNlXG4gIHJldHVybiBSZXF1ZXN0KHVybCwgcGFyYW1zKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTaG9ydElkIChob3N0LCBuYW1lLCBjbGFpbUlkKSB7XG4gIGNvbnN0IHVybCA9IGAke2hvc3R9L2FwaS9jbGFpbS9zaG9ydC1pZC8ke2NsYWltSWR9LyR7bmFtZX1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENsYWltRGF0YSAoaG9zdCwgbmFtZSwgY2xhaW1JZCkge1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2xhaW0vZGF0YS8ke25hbWV9LyR7Y2xhaW1JZH1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9hcGkvYXNzZXRBcGkuanMiLCJpbXBvcnQge2NhbGwsIHB1dCwgc2VsZWN0LCB0YWtlTGF0ZXN0fSBmcm9tICdyZWR1eC1zYWdhL2VmZmVjdHMnO1xuaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvc2hvd19hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgYWRkTmV3Q2hhbm5lbFRvQ2hhbm5lbExpc3QsIGFkZFJlcXVlc3RUb1JlcXVlc3RMaXN0LCBvblJlcXVlc3RFcnJvciwgb25SZXF1ZXN0VXBkYXRlLCB1cGRhdGVDaGFubmVsQ2xhaW1zIH0gZnJvbSAnYWN0aW9ucy9zaG93JztcbmltcG9ydCB7IGdldENoYW5uZWxDbGFpbXMsIGdldENoYW5uZWxEYXRhIH0gZnJvbSAnYXBpL2NoYW5uZWxBcGknO1xuaW1wb3J0IHsgc2VsZWN0U2hvd1N0YXRlIH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuaW1wb3J0IHsgc2VsZWN0U2l0ZUhvc3QgfSBmcm9tICdzZWxlY3RvcnMvc2l0ZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiAqIG5ld0NoYW5uZWxSZXF1ZXN0IChhY3Rpb24pIHtcbiAgY29uc3QgeyByZXF1ZXN0VHlwZSwgcmVxdWVzdElkLCBjaGFubmVsTmFtZSwgY2hhbm5lbElkIH0gPSBhY3Rpb24uZGF0YTtcbiAgLy8gcHV0IGFuIGFjdGlvbiB0byB1cGRhdGUgdGhlIHJlcXVlc3QgaW4gcmVkdXhcbiAgeWllbGQgcHV0KG9uUmVxdWVzdFVwZGF0ZShyZXF1ZXN0VHlwZSwgcmVxdWVzdElkKSk7XG4gIC8vIGlzIHRoaXMgYW4gZXhpc3RpbmcgcmVxdWVzdD9cbiAgLy8gSWYgdGhpcyB1cmkgaXMgaW4gdGhlIHJlcXVlc3QgbGlzdCwgaXQncyBhbHJlYWR5IGJlZW4gZmV0Y2hlZFxuICBjb25zdCBzdGF0ZSA9IHlpZWxkIHNlbGVjdChzZWxlY3RTaG93U3RhdGUpO1xuICBjb25zdCBob3N0ID0geWllbGQgc2VsZWN0KHNlbGVjdFNpdGVIb3N0KTtcbiAgaWYgKHN0YXRlLnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBnZXQgY2hhbm5lbCBsb25nIGlkXG4gIGxldCBsb25nSWQsIHNob3J0SWQ7XG4gIHRyeSB7XG4gICAgKHsgZGF0YToge2xvbmdDaGFubmVsQ2xhaW1JZDogbG9uZ0lkLCBzaG9ydENoYW5uZWxDbGFpbUlkOiBzaG9ydElkfSB9ID0geWllbGQgY2FsbChnZXRDaGFubmVsRGF0YSwgaG9zdCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIHN0b3JlIHRoZSByZXF1ZXN0IGluIHRoZSBjaGFubmVsIHJlcXVlc3RzIGxpc3RcbiAgY29uc3QgY2hhbm5lbEtleSA9IGBjIyR7Y2hhbm5lbE5hbWV9IyR7bG9uZ0lkfWA7XG4gIHlpZWxkIHB1dChhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdChyZXF1ZXN0SWQsIG51bGwsIGNoYW5uZWxLZXkpKTtcbiAgLy8gaXMgdGhpcyBhbiBleGlzdGluZyBjaGFubmVsP1xuICAvLyBJZiB0aGlzIGNoYW5uZWwgaXMgaW4gdGhlIGNoYW5uZWwgbGlzdCwgaXQncyBhbHJlYWR5IGJlZW4gZmV0Y2hlZFxuICBpZiAoc3RhdGUuY2hhbm5lbExpc3RbY2hhbm5lbEtleV0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBnZXQgY2hhbm5lbCBjbGFpbXMgZGF0YVxuICBsZXQgY2xhaW1zRGF0YTtcbiAgdHJ5IHtcbiAgICAoeyBkYXRhOiBjbGFpbXNEYXRhIH0gPSB5aWVsZCBjYWxsKGdldENoYW5uZWxDbGFpbXMsIGhvc3QsIGxvbmdJZCwgY2hhbm5lbE5hbWUsIDEpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyBzdG9yZSB0aGUgY2hhbm5lbCBkYXRhIGluIHRoZSBjaGFubmVsIGxpc3RcbiAgeWllbGQgcHV0KGFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0KGNoYW5uZWxLZXksIGNoYW5uZWxOYW1lLCBzaG9ydElkLCBsb25nSWQsIGNsYWltc0RhdGEpKTtcbiAgLy8gY2xlYXIgYW55IHJlcXVlc3QgZXJyb3JzXG4gIHlpZWxkIHB1dChvblJlcXVlc3RFcnJvcihudWxsKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoTmV3Q2hhbm5lbFJlcXVlc3QgKCkge1xuICB5aWVsZCB0YWtlTGF0ZXN0KGFjdGlvbnMuQ0hBTk5FTF9SRVFVRVNUX05FVywgbmV3Q2hhbm5lbFJlcXVlc3QpO1xufTtcblxuZnVuY3Rpb24gKiBnZXROZXdDbGFpbXNBbmRVcGRhdGVDaGFubmVsIChhY3Rpb24pIHtcbiAgY29uc3QgeyBjaGFubmVsS2V5LCBuYW1lLCBsb25nSWQsIHBhZ2UgfSA9IGFjdGlvbi5kYXRhO1xuICBjb25zdCBob3N0ID0geWllbGQgc2VsZWN0KHNlbGVjdFNpdGVIb3N0KTtcbiAgbGV0IGNsYWltc0RhdGE7XG4gIHRyeSB7XG4gICAgKHsgZGF0YTogY2xhaW1zRGF0YSB9ID0geWllbGQgY2FsbChnZXRDaGFubmVsQ2xhaW1zLCBob3N0LCBsb25nSWQsIG5hbWUsIHBhZ2UpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICB5aWVsZCBwdXQodXBkYXRlQ2hhbm5lbENsYWltcyhjaGFubmVsS2V5LCBjbGFpbXNEYXRhKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoVXBkYXRlQ2hhbm5lbENsYWltcyAoKSB7XG4gIHlpZWxkIHRha2VMYXRlc3QoYWN0aW9ucy5DSEFOTkVMX0NMQUlNU19VUERBVEVfQVNZTkMsIGdldE5ld0NsYWltc0FuZFVwZGF0ZUNoYW5uZWwpO1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NhZ2FzL3Nob3dfY2hhbm5lbC5qcyIsImltcG9ydCBSZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2hhbm5lbERhdGEgKGhvc3QsIGlkLCBuYW1lKSB7XG4gIGlmICghaWQpIGlkID0gJ25vbmUnO1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2hhbm5lbC9kYXRhLyR7bmFtZX0vJHtpZH1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYW5uZWxDbGFpbXMgKGhvc3QsIGxvbmdJZCwgbmFtZSwgcGFnZSkge1xuICBpZiAoIXBhZ2UpIHBhZ2UgPSAxO1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2hhbm5lbC9jbGFpbXMvJHtuYW1lfS8ke2xvbmdJZH0vJHtwYWdlfWA7XG4gIHJldHVybiBSZXF1ZXN0KHVybCk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2FwaS9jaGFubmVsQXBpLmpzIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIFJFR0VYUF9JTlZBTElEX0NMQUlNICA6IC9bXkEtWmEtejAtOS1dL2csXG4gIFJFR0VYUF9JTlZBTElEX0NIQU5ORUw6IC9bXkEtWmEtejAtOS1AXS9nLFxuICBSRUdFWFBfQUREUkVTUyAgICAgICAgOiAvXmIoPz1bXjBPSWxdezMyLDMzfSlbMC05QS1aYS16XXszMiwzM30kLyxcbiAgQ0hBTk5FTF9DSEFSICAgICAgICAgIDogJ0AnLFxuICBwYXJzZUlkZW50aWZpZXIgICAgICAgOiBmdW5jdGlvbiAoaWRlbnRpZmllcikge1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjL10qKScgKyAvLyB2YWx1ZSAoc3RvcHMgYXQgdGhlIGZpcnN0IHNlcGFyYXRvciBvciBlbmQpXG4gICAgICAnKFs6JCNdPykoW14vXSopJyAvLyBtb2RpZmllciBzZXBhcmF0b3IsIG1vZGlmaWVyIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCB2YWx1ZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleCAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgLmV4ZWMoaWRlbnRpZmllcilcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIFVSTC4gIE5vIGNoYW5uZWwgbmFtZSBwcm92aWRlZCBiZWZvcmUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IGlzQ2hhbm5lbCA9IHZhbHVlLnN0YXJ0c1dpdGgobW9kdWxlLmV4cG9ydHMuQ0hBTk5FTF9DSEFSKTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGlzQ2hhbm5lbCA/IHZhbHVlIDogbnVsbDtcbiAgICBsZXQgY2xhaW1JZDtcbiAgICBpZiAoaXNDaGFubmVsKSB7XG4gICAgICBpZiAoIWNoYW5uZWxOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2hlY2sgeW91ciBVUkwuICBObyBjaGFubmVsIG5hbWUgYWZ0ZXIgXCJAXCIuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2hhbm5lbE5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NIQU5ORUwpO1xuICAgICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgSW52YWxpZCBjaGFyYWN0ZXJzIGluIGNoYW5uZWwgbmFtZTogXCIke25hbWVCYWRDaGFycy5qb2luKCcsICcpfVwiLmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjbGFpbUlkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciBVUkwuICBObyBtb2RpZmllciBwcm92aWRlZCBhZnRlciBzZXBhcmF0b3IgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RpZmllclNlcGVyYXRvciA9PT0gJzonKSB7XG4gICAgICAgIGNoYW5uZWxDbGFpbUlkID0gbW9kaWZpZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgVGhlIFwiJHttb2RpZmllclNlcGVyYXRvcn1cIiBtb2RpZmllciBpcyBub3QgY3VycmVudGx5IHN1cHBvcnRlZGApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaXNDaGFubmVsLFxuICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICBjaGFubmVsQ2xhaW1JZDogY2hhbm5lbENsYWltSWQgfHwgbnVsbCxcbiAgICAgIGNsYWltSWQgICAgICAgOiBjbGFpbUlkIHx8IG51bGwsXG4gICAgfTtcbiAgfSxcbiAgcGFyc2VDbGFpbTogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBjb25zdCBjb21wb25lbnRzUmVnZXggPSBuZXcgUmVnRXhwKFxuICAgICAgJyhbXjokIy8uXSopJyArIC8vIG5hbWUgKHN0b3BzIGF0IHRoZSBmaXJzdCBleHRlbnNpb24pXG4gICAgICAnKFs6JCMuXT8pKFteL10qKScgLy8gZXh0ZW5zaW9uIHNlcGFyYXRvciwgZXh0ZW5zaW9uIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCBjbGFpbU5hbWUsIGV4dGVuc2lvblNlcGVyYXRvciwgZXh0ZW5zaW9uXSA9IGNvbXBvbmVudHNSZWdleCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICAuZXhlYyhuYW1lKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG5hbWVcbiAgICBpZiAoIWNsYWltTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGVjayB5b3VyIFVSTC4gIE5vIGNsYWltIG5hbWUgcHJvdmlkZWQgYmVmb3JlIFwiLlwiJyk7XG4gICAgfVxuICAgIGNvbnN0IG5hbWVCYWRDaGFycyA9IChjbGFpbU5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NMQUlNKTtcbiAgICBpZiAobmFtZUJhZENoYXJzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgSW52YWxpZCBjaGFyYWN0ZXJzIGluIGNsYWltIG5hbWU6IFwiJHtuYW1lQmFkQ2hhcnMuam9pbignLCAnKX1cIi5gKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgZXh0ZW5zaW9uXG4gICAgaWYgKGV4dGVuc2lvblNlcGVyYXRvcikge1xuICAgICAgaWYgKCFleHRlbnNpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIFVSTC4gIE5vIGZpbGUgZXh0ZW5zaW9uIHByb3ZpZGVkIGFmdGVyIHNlcGFyYXRvciBcIiR7ZXh0ZW5zaW9uU2VwZXJhdG9yfVwiLmApO1xuICAgICAgfVxuICAgICAgaWYgKGV4dGVuc2lvblNlcGVyYXRvciAhPT0gJy4nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciBVUkwuICBUaGUgXCIke2V4dGVuc2lvblNlcGVyYXRvcn1cIiBzZXBhcmF0b3IgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY2xhaW0gbmFtZS5gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYWltTmFtZSxcbiAgICAgIGV4dGVuc2lvbjogZXh0ZW5zaW9uIHx8IG51bGwsXG4gICAgfTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvbGJyeVVyaS5qcyIsImNvbnN0IGhhbmRsZVBhZ2VSZW5kZXIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gYXBwID0+IHtcbiAgLy8gYSBjYXRjaC1hbGwgcm91dGUgaWYgc29tZW9uZSB2aXNpdHMgYSBwYWdlIHRoYXQgZG9lcyBub3QgZXhpc3RcbiAgYXBwLnVzZSgnKicsIChyZXEsIHJlcykgPT4ge1xuICAgIC8vIHNlbmQgcmVzcG9uc2VcbiAgICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbiAgfSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9mYWxsYmFjay1yb3V0ZXMuanMiXSwic291cmNlUm9vdCI6IiJ9