10771 lines
No EOL
882 KiB
JavaScript
10771 lines
No EOL
882 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, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var speechConfig = {
|
|
analytics: {
|
|
googleId: 'UA-60403362-6' // google id for analytics tracking; leave `null` if not applicable
|
|
},
|
|
session: {
|
|
sessionKey: 'nans$#kfjanwe234rydns' // enter a secret key to be used for session encryption
|
|
},
|
|
files: {
|
|
uploadDirectory: '/home/lbry/Uploads' // enter file path to where uploads/publishes should be stored
|
|
},
|
|
site: {
|
|
title: 'dev1.Spee.ch',
|
|
name: 'dev1.Spee.ch',
|
|
host: 'https://dev1.spee.ch',
|
|
description: 'Open-source, decentralized image and video sharing.'
|
|
},
|
|
publish: {
|
|
primaryClaimAddress: 'bDZ2wPwtULUGxT7GXuNLpQhXmdPRUTUkcL',
|
|
additionalClaimAddresses: ['banpwixPosfVDWnGvXqU2af36Qpsd7buGd'],
|
|
thumbnailChannel: '@dev1thumbs', // create a channel to use for thumbnail images
|
|
thumbnailChannelId: 'aeb625ff6f66c3eeeb42885070f4e53876033626' // the channel_id (claim id) for the channel above
|
|
},
|
|
claim: {
|
|
defaultTitle: 'dev1 Spee.ch',
|
|
defaultThumbnail: 'https://spee.ch/assets/img/video_thumb_default.png',
|
|
defaultDescription: 'Open-source, decentralized image and video sharing.'
|
|
}
|
|
};
|
|
|
|
module.exports = speechConfig;
|
|
|
|
/***/ }),
|
|
/* 4 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("react-router-dom");
|
|
|
|
/***/ }),
|
|
/* 5 */
|
|
/***/ (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__(33);
|
|
|
|
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 }
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 6 */
|
|
/***/ (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__(92);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var channel = _ref.channel;
|
|
|
|
return {
|
|
channelName: channel.loggedInChannel.name,
|
|
channelShortId: channel.loggedInChannel.shortId,
|
|
channelLongId: channel.loggedInChannel.longId
|
|
};
|
|
};
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 7 */
|
|
/***/ (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__(42);
|
|
|
|
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
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 8 */
|
|
/***/ (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__(9);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _pageTitle = __webpack_require__(89);
|
|
|
|
var _metaTags = __webpack_require__(90);
|
|
|
|
var _canonicalLink = __webpack_require__(91);
|
|
|
|
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() {
|
|
var _props = this.props,
|
|
pageTitle = _props.pageTitle,
|
|
asset = _props.asset,
|
|
channel = _props.channel,
|
|
pageUri = _props.pageUri;
|
|
|
|
pageTitle = (0, _pageTitle.createPageTitle)(pageTitle);
|
|
var metaTags = (0, _metaTags.createMetaTags)(asset, channel);
|
|
var canonicalLink = (0, _canonicalLink.createCanonicalLink)(asset, channel, pageUri);
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 9 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("prop-types");
|
|
|
|
/***/ }),
|
|
/* 10 */
|
|
/***/ (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__(95);
|
|
|
|
/**
|
|
* 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);
|
|
});
|
|
}
|
|
|
|
/***/ }),
|
|
/* 11 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var Sequelize = __webpack_require__(70);
|
|
var logger = __webpack_require__(2);
|
|
|
|
console.log('exporting sequelize models');
|
|
|
|
var _require = __webpack_require__(23),
|
|
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__(71);
|
|
var Channel = __webpack_require__(72);
|
|
var Claim = __webpack_require__(73);
|
|
var File = __webpack_require__(74);
|
|
var Request = __webpack_require__(75);
|
|
var User = __webpack_require__(76);
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 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__(3),
|
|
googleId = _require.analytics.googleId,
|
|
siteName = _require.site.name;
|
|
|
|
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(siteName, 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__(35);
|
|
|
|
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__(9);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _ActiveStatusBar = __webpack_require__(117);
|
|
|
|
var _ActiveStatusBar2 = _interopRequireDefault(_ActiveStatusBar);
|
|
|
|
var _InactiveStatusBar = __webpack_require__(118);
|
|
|
|
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__(9);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _NavBar = __webpack_require__(6);
|
|
|
|
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, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
function MysqlConfig() {
|
|
var _this = this;
|
|
|
|
this.database = 'default';
|
|
this.username = 'default';
|
|
this.password = 'default';
|
|
this.configure = function (_ref) {
|
|
var database = _ref.database,
|
|
username = _ref.username,
|
|
password = _ref.password;
|
|
|
|
if (database) _this.database = database;
|
|
if (username) _this.username = username;
|
|
if (password) _this.password = password;
|
|
};
|
|
};
|
|
|
|
module.exports = new MysqlConfig();
|
|
|
|
/***/ }),
|
|
/* 24 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
function SlackConfig() {
|
|
var _this = this;
|
|
|
|
this.slackWebHook = 'default';
|
|
this.slackErrorChannel = 'default';
|
|
this.slackInfoChannel = 'default';
|
|
this.configure = function (_ref) {
|
|
var slackWebHook = _ref.slackWebHook,
|
|
slackErrorChannel = _ref.slackErrorChannel,
|
|
slackInfoChannel = _ref.slackInfoChannel;
|
|
|
|
if (slackWebHook) _this.slackWebHook = slackWebHook;
|
|
if (slackErrorChannel) _this.slackErrorChannel = slackErrorChannel;
|
|
if (slackInfoChannel) _this.slackInfoChannel = slackInfoChannel;
|
|
};
|
|
};
|
|
|
|
module.exports = new SlackConfig();
|
|
|
|
/***/ }),
|
|
/* 25 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("passport-local");
|
|
|
|
/***/ }),
|
|
/* 26 */
|
|
/***/ (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;
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 27 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
var fs = __webpack_require__(79);
|
|
|
|
var _require = __webpack_require__(3),
|
|
site = _require.site,
|
|
wallet = _require.wallet,
|
|
publish = _require.publish;
|
|
|
|
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: site.title,
|
|
language: 'en',
|
|
license: license,
|
|
nsfw: nsfw
|
|
},
|
|
claim_address: wallet.lbryClaimAddress
|
|
};
|
|
// 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: site.title,
|
|
language: 'en',
|
|
license: license,
|
|
nsfw: nsfw
|
|
},
|
|
claim_address: wallet.lbryClaimAddress,
|
|
channel_name: publish.thumbnailChannel,
|
|
channel_id: publish.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
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 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 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
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 29 */
|
|
/***/ (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__(11);
|
|
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;
|
|
});
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 30 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _server = __webpack_require__(31);
|
|
|
|
var _redux = __webpack_require__(18);
|
|
|
|
var _reducers = __webpack_require__(32);
|
|
|
|
var _reducers2 = _interopRequireDefault(_reducers);
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _reactRouterDom = __webpack_require__(4);
|
|
|
|
var _GAListener = __webpack_require__(37);
|
|
|
|
var _GAListener2 = _interopRequireDefault(_GAListener);
|
|
|
|
var _app = __webpack_require__(38);
|
|
|
|
var _app2 = _interopRequireDefault(_app);
|
|
|
|
var _renderFullPage = __webpack_require__(44);
|
|
|
|
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)(_reducers2.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(
|
|
_GAListener2.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));
|
|
};
|
|
|
|
/***/ }),
|
|
/* 31 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("react-dom/server");
|
|
|
|
/***/ }),
|
|
/* 32 */
|
|
/***/ (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
|
|
});
|
|
|
|
/***/ }),
|
|
/* 33 */
|
|
/***/ (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';
|
|
|
|
/***/ }),
|
|
/* 34 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var LOGIN = exports.LOGIN = 'Existing';
|
|
var CREATE = exports.CREATE = 'New';
|
|
|
|
/***/ }),
|
|
/* 35 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var CHANNEL_UPDATE = exports.CHANNEL_UPDATE = 'CHANNEL_UPDATE';
|
|
|
|
/***/ }),
|
|
/* 36 */
|
|
/***/ (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';
|
|
|
|
/***/ }),
|
|
/* 37 */
|
|
/***/ (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__(4);
|
|
|
|
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 config = __webpack_require__(3);
|
|
var googleApiKey = config.analytics.googleId;
|
|
|
|
_reactGa2.default.initialize(googleApiKey);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 38 */
|
|
/***/ (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__(4);
|
|
|
|
var _HomePage = __webpack_require__(88);
|
|
|
|
var _HomePage2 = _interopRequireDefault(_HomePage);
|
|
|
|
var _AboutPage = __webpack_require__(122);
|
|
|
|
var _AboutPage2 = _interopRequireDefault(_AboutPage);
|
|
|
|
var _LoginPage = __webpack_require__(123);
|
|
|
|
var _LoginPage2 = _interopRequireDefault(_LoginPage);
|
|
|
|
var _ShowPage = __webpack_require__(125);
|
|
|
|
var _ShowPage2 = _interopRequireDefault(_ShowPage);
|
|
|
|
var _FourOhFourPage = __webpack_require__(141);
|
|
|
|
var _FourOhFourPage2 = _interopRequireDefault(_FourOhFourPage);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 39 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
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 {
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 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__(115);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
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 _reactRedux = __webpack_require__(1);
|
|
|
|
var _channel = __webpack_require__(19);
|
|
|
|
var _view = __webpack_require__(116);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 42 */
|
|
/***/ (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';
|
|
|
|
/***/ }),
|
|
/* 43 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(129);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 44 */
|
|
/***/ (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 ';
|
|
};
|
|
|
|
/***/ }),
|
|
/* 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),
|
|
populateLocalsDotUser = _require.populateLocalsDotUser,
|
|
serializeSpeechUser = _require.serializeSpeechUser,
|
|
deserializeSpeechUser = _require.deserializeSpeechUser;
|
|
|
|
var cookieSession = __webpack_require__(55);
|
|
var http = __webpack_require__(56);
|
|
// logging dependencies
|
|
var logger = __webpack_require__(2);
|
|
|
|
function SpeechServer(_ref) {
|
|
var _this = this;
|
|
|
|
var mysqlConfig = _ref.mysqlConfig,
|
|
siteConfig = _ref.siteConfig,
|
|
slackConfig = _ref.slackConfig;
|
|
|
|
this.PORT = 3000;
|
|
this.speak = function (something) {
|
|
console.log(something);
|
|
};
|
|
this.start = function () {
|
|
_this.configureConfigFiles();
|
|
_this.configureLogging();
|
|
_this.configureApp();
|
|
_this.configureServer();
|
|
_this.startServer();
|
|
};
|
|
this.configureConfigFiles = function () {
|
|
var mysqlAppConfig = __webpack_require__(23);
|
|
mysqlAppConfig.configure(mysqlConfig);
|
|
var slackAppConfig = __webpack_require__(24);
|
|
slackAppConfig.configure(slackConfig);
|
|
// print the config variables
|
|
console.log('configured config files');
|
|
__webpack_require__(57)(mysqlAppConfig);
|
|
__webpack_require__(57)(slackAppConfig);
|
|
};
|
|
this.configureLogging = function () {
|
|
__webpack_require__(58)(logger);
|
|
__webpack_require__(60)(logger);
|
|
};
|
|
this.configureApp = function () {
|
|
var app = express(); // create an Express application
|
|
|
|
// 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__(66);
|
|
passport.use('local-signup', localSignupStrategy);
|
|
passport.use('local-login', localLoginStrategy);
|
|
// initialize passport
|
|
app.use(cookieSession({
|
|
name: 'session',
|
|
keys: [siteConfig.session.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');
|
|
|
|
// middleware to pass user info back to client (for handlebars access), if user is logged in
|
|
app.use(populateLocalsDotUser); // note: I don't think I need this any more?
|
|
|
|
// set the routes on the app
|
|
__webpack_require__(67)(app);
|
|
__webpack_require__(68)(app);
|
|
__webpack_require__(82)(app);
|
|
__webpack_require__(142)(app);
|
|
__webpack_require__(153)(app);
|
|
|
|
_this.app = app;
|
|
};
|
|
this.configureServer = function () {
|
|
_this.server = http.Server(_this.app);
|
|
};
|
|
this.startServer = function () {
|
|
var db = __webpack_require__(11);
|
|
// sync sequelize
|
|
db.sequelize.sync()
|
|
// start the server
|
|
.then(function () {
|
|
_this.server.listen(_this.PORT, function () {
|
|
logger.info('Server is listening on PORT ' + _this.PORT);
|
|
});
|
|
}).catch(function (error) {
|
|
logger.error('Startup Error:', error);
|
|
});
|
|
};
|
|
};
|
|
|
|
module.exports = SpeechServer;
|
|
|
|
/***/ }),
|
|
/* 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 = {
|
|
populateLocalsDotUser: function populateLocalsDotUser(req, res, next) {
|
|
if (req.user) {
|
|
logger.debug('populating res.locals.user');
|
|
res.locals.user = {
|
|
id: req.user.id,
|
|
userName: req.user.userName,
|
|
channelName: req.user.channelName,
|
|
channelClaimId: req.user.channelClaimId,
|
|
shortChannelId: req.user.shortChannelId
|
|
};
|
|
}
|
|
next();
|
|
},
|
|
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 logger = __webpack_require__(2);
|
|
|
|
module.exports = function (config) {
|
|
// get the config file
|
|
for (var configCategoryKey in config) {
|
|
if (config.hasOwnProperty(configCategoryKey)) {
|
|
// get the final variables for each config category
|
|
var configVariables = config[configCategoryKey];
|
|
for (var configVarKey in configVariables) {
|
|
if (configVariables.hasOwnProperty(configVarKey)) {
|
|
// print each variable
|
|
logger.debug('CONFIG CHECK: ' + configCategoryKey + '.' + configVarKey + ' === ' + configVariables[configVarKey]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 58 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(59),
|
|
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');
|
|
};
|
|
|
|
/***/ }),
|
|
/* 59 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var loggerConfig = {
|
|
logLevel: 'debug' // options: silly, debug, verbose, info
|
|
};
|
|
|
|
module.exports = loggerConfig;
|
|
|
|
/***/ }),
|
|
/* 60 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var winstonSlackWebHook = __webpack_require__(61).SlackWebHook;
|
|
var slackConfig = __webpack_require__(24);
|
|
|
|
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.');
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 61 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("winston-slack-webhook");
|
|
|
|
/***/ }),
|
|
/* 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__(25).Strategy;
|
|
var lbryApi = __webpack_require__(16);
|
|
var logger = __webpack_require__(2);
|
|
|
|
module.exports = function (db) {
|
|
return 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";
|
|
|
|
|
|
var PassportLocalStrategy = __webpack_require__(25).Strategy;
|
|
var logger = __webpack_require__(2);
|
|
|
|
module.exports = function (db) {
|
|
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);
|
|
});
|
|
});
|
|
};
|
|
|
|
return 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);
|
|
});
|
|
});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 67 */
|
|
/***/ (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) {
|
|
logger.debug('info:', 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' });
|
|
}
|
|
});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 68 */
|
|
/***/ (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__(69);
|
|
|
|
var _require = __webpack_require__(3),
|
|
files = _require.files,
|
|
site = _require.site;
|
|
|
|
var multipartMiddleware = multipart({ uploadDir: files.uploadDirectory });
|
|
var db = __webpack_require__(11);
|
|
|
|
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__(27),
|
|
addGetResultsToFileData = _require4.addGetResultsToFileData,
|
|
createBasicPublishParams = _require4.createBasicPublishParams,
|
|
createThumbnailPublishParams = _require4.createThumbnailPublishParams,
|
|
parsePublishApiRequestBody = _require4.parsePublishApiRequestBody,
|
|
parsePublishApiRequestFiles = _require4.parsePublishApiRequestFiles,
|
|
createFileData = _require4.createFileData;
|
|
|
|
var errorHandlers = __webpack_require__(28);
|
|
|
|
var _require5 = __webpack_require__(17),
|
|
sendGATimingEvent = _require5.sendGATimingEvent;
|
|
|
|
var _require6 = __webpack_require__(80),
|
|
authenticateUser = _require6.authenticateUser;
|
|
|
|
var _require7 = __webpack_require__(29),
|
|
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,
|
|
params = _ref.params;
|
|
|
|
checkChannelAvailability(params.name).then(function (result) {
|
|
if (result === true) {
|
|
res.status(200).json(true);
|
|
} else {
|
|
res.status(200).json(false);
|
|
}
|
|
}).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,
|
|
params = _ref11.params;
|
|
|
|
claimNameIsAvailable(params.name).then(function (result) {
|
|
res.status(200).json(result);
|
|
}).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;
|
|
|
|
logger.debug('api/claim/publish req.body:', body);
|
|
logger.debug('api/claim/publish req.files:', files);
|
|
// 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: site.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);
|
|
});
|
|
});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 69 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("connect-multiparty");
|
|
|
|
/***/ }),
|
|
/* 70 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("sequelize");
|
|
|
|
/***/ }),
|
|
/* 71 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(26),
|
|
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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 72 */
|
|
/***/ (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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 73 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(26),
|
|
returnShortId = _require.returnShortId;
|
|
|
|
var _require2 = __webpack_require__(3),
|
|
claim = _require2.claim,
|
|
site = _require2.site;
|
|
|
|
var defaultThumbnail = claim.defaultThumbnail;
|
|
|
|
|
|
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'] = site.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) {
|
|
logger.debug('claims found on resolve:', claimArray.length);
|
|
switch (claimArray.length) {
|
|
case 0:
|
|
return resolve(null);
|
|
case 1:
|
|
return resolve(prepareClaimData(claimArray[0].dataValues));
|
|
default:
|
|
logger.error('more than one entry matches that name (' + name + ') and claimID (' + claimId + ')');
|
|
return resolve(prepareClaimData(claimArray[0].dataValues));
|
|
}
|
|
}).catch(function (error) {
|
|
reject(error);
|
|
});
|
|
});
|
|
};
|
|
|
|
return Claim;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 74 */
|
|
/***/ (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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 75 */
|
|
/***/ (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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 76 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var bcrypt = __webpack_require__(77);
|
|
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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 77 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("bcrypt");
|
|
|
|
/***/ }),
|
|
/* 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"); } }; }();
|
|
|
|
var logger = __webpack_require__(2);
|
|
var db = __webpack_require__(11);
|
|
var lbryApi = __webpack_require__(16);
|
|
var publishHelpers = __webpack_require__(27);
|
|
var config = __webpack_require__(3);
|
|
|
|
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) {
|
|
// find any records where the name is used
|
|
return db.File.findAll({ where: { name: name } }).then(function (result) {
|
|
if (result.length >= 1) {
|
|
var claimAddress = config.wallet.lbryClaimAddress;
|
|
// filter out any results that were not published from spee.ch's wallet address
|
|
var filteredResult = result.filter(function (claim) {
|
|
return claim.address === claimAddress;
|
|
});
|
|
// return based on whether any non-spee.ch claims were left
|
|
if (filteredResult.length >= 1) {
|
|
throw new Error('That claim is already in use');
|
|
};
|
|
return name;
|
|
};
|
|
return name;
|
|
});
|
|
},
|
|
checkChannelAvailability: function checkChannelAvailability(name) {
|
|
return new Promise(function (resolve, reject) {
|
|
// find any records where the name is used
|
|
db.Channel.findAll({ where: { channelName: name } }).then(function (result) {
|
|
if (result.length >= 1) {
|
|
return resolve(false);
|
|
}
|
|
resolve(true);
|
|
}).catch(function (error) {
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 79 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("fs");
|
|
|
|
/***/ }),
|
|
/* 80 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var db = __webpack_require__(11);
|
|
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__(3),
|
|
site = _require.site;
|
|
|
|
var handlePageRender = __webpack_require__(30);
|
|
|
|
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;
|
|
var host = site.host;
|
|
// 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__(33);
|
|
|
|
var actions = _interopRequireWildcard(_publish_action_types);
|
|
|
|
var _publish_channel_select_states = __webpack_require__(34);
|
|
|
|
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__(3),
|
|
publish = _require.publish;
|
|
|
|
var initialState = {
|
|
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
|
|
},
|
|
thumbnailChannel: publish.thumbnailChannel,
|
|
thumbnailChannelId: publish.thumbnailChannelId,
|
|
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__(35);
|
|
|
|
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__(36);
|
|
|
|
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 _require = __webpack_require__(3),
|
|
site = _require.site;
|
|
|
|
var initialState = {
|
|
host: site.host
|
|
};
|
|
|
|
/***/ }),
|
|
/* 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__(8);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _NavBar = __webpack_require__(6);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _PublishTool = __webpack_require__(96);
|
|
|
|
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 _require = __webpack_require__(3),
|
|
siteTitle = _require.site.title;
|
|
|
|
var createPageTitle = exports.createPageTitle = function createPageTitle(pageTitle) {
|
|
if (!pageTitle) {
|
|
return '' + siteTitle;
|
|
}
|
|
return siteTitle + ' - ' + pageTitle;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 90 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _require = __webpack_require__(3),
|
|
_require$site = _require.site,
|
|
title = _require$site.title,
|
|
host = _require$site.host,
|
|
description = _require$site.description,
|
|
_require$claim = _require.claim,
|
|
defaultThumbnail = _require$claim.defaultThumbnail,
|
|
defaultDescription = _require$claim.defaultDescription;
|
|
|
|
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() {
|
|
return [{ property: 'og:title', content: title }, { property: 'og:url', content: host }, { property: 'og:site_name', content: title }, { property: 'og:description', content: description }, { property: 'twitter:site', content: '@spee_ch' }, { property: 'twitter:card', content: 'summary' }];
|
|
};
|
|
|
|
var createChannelMetaTags = function createChannelMetaTags(channel) {
|
|
var name = channel.name,
|
|
longId = channel.longId;
|
|
|
|
return [{ property: 'og:title', content: name + ' on ' + title }, { property: 'og:url', content: host + '/' + name + ':' + longId }, { property: 'og:site_name', content: title }, { property: 'og:description', content: name + ', a channel on ' + title }, { property: 'twitter:site', content: '@spee_ch' }, { property: 'twitter:card', content: 'summary' }];
|
|
};
|
|
|
|
var createAssetMetaTags = function createAssetMetaTags(asset) {
|
|
var claimData = asset.claimData;
|
|
var contentType = claimData.contentType;
|
|
|
|
var embedUrl = host + '/' + claimData.claimId + '/' + claimData.name;
|
|
var showUrl = host + '/' + claimData.claimId + '/' + claimData.name;
|
|
var source = host + '/' + 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: title }, { property: 'og:description', content: ogDescription }, { property: 'og:image:width', content: 600 }, { property: 'og:image:height', content: 315 }, { property: 'twitter:site', content: '@spee_ch' }];
|
|
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(asset, channel) {
|
|
if (asset) {
|
|
return createAssetMetaTags(asset);
|
|
};
|
|
if (channel) {
|
|
return createChannelMetaTags(channel);
|
|
};
|
|
return createBasicMetaTags();
|
|
};
|
|
|
|
/***/ }),
|
|
/* 91 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _require = __webpack_require__(3),
|
|
host = _require.site.host;
|
|
|
|
var createBasicCanonicalLink = function createBasicCanonicalLink(page) {
|
|
if (!page) {
|
|
return '' + host;
|
|
};
|
|
return host + '/' + page;
|
|
};
|
|
|
|
var createAssetCanonicalLink = function createAssetCanonicalLink(asset) {
|
|
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 host + '/' + channelName + ':' + certificateId + '/' + name;
|
|
};
|
|
return host + '/' + claimId + '/' + name;
|
|
};
|
|
|
|
var createChannelCanonicalLink = function createChannelCanonicalLink(channel) {
|
|
var name = channel.name,
|
|
longId = channel.longId;
|
|
|
|
return host + '/' + name + ':' + longId;
|
|
};
|
|
|
|
var createCanonicalLink = exports.createCanonicalLink = function createCanonicalLink(asset, channel, page) {
|
|
if (asset) {
|
|
return createAssetCanonicalLink(asset);
|
|
}
|
|
if (channel) {
|
|
return createChannelCanonicalLink(channel);
|
|
}
|
|
if (page) {
|
|
return createBasicCanonicalLink(page);
|
|
}
|
|
return createBasicCanonicalLink();
|
|
};
|
|
|
|
/***/ }),
|
|
/* 92 */
|
|
/***/ (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__(4);
|
|
|
|
var _Logo = __webpack_require__(93);
|
|
|
|
var _Logo2 = _interopRequireDefault(_Logo);
|
|
|
|
var _NavBarChannelOptionsDropdown = __webpack_require__(94);
|
|
|
|
var _NavBarChannelOptionsDropdown2 = _interopRequireDefault(_NavBarChannelOptionsDropdown);
|
|
|
|
var _request = __webpack_require__(10);
|
|
|
|
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() {
|
|
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' },
|
|
'Open-source, decentralized image and video sharing.'
|
|
)
|
|
),
|
|
_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);
|
|
|
|
/***/ }),
|
|
/* 93 */
|
|
/***/ (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__(4);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 94 */
|
|
/***/ (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;
|
|
|
|
/***/ }),
|
|
/* 95 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("cross-fetch/polyfill");
|
|
|
|
/***/ }),
|
|
/* 96 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(97);
|
|
|
|
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,
|
|
status: publish.status.status
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 97 */
|
|
/***/ (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__(39);
|
|
|
|
var _Dropzone2 = _interopRequireDefault(_Dropzone);
|
|
|
|
var _PublishDetails = __webpack_require__(101);
|
|
|
|
var _PublishDetails2 = _interopRequireDefault(_PublishDetails);
|
|
|
|
var _PublishStatus = __webpack_require__(119);
|
|
|
|
var _PublishStatus2 = _interopRequireDefault(_PublishStatus);
|
|
|
|
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.file) {
|
|
if (this.props.status) {
|
|
return _react2.default.createElement(_PublishStatus2.default, null);
|
|
} else {
|
|
return _react2.default.createElement(_PublishDetails2.default, null);
|
|
}
|
|
} else {
|
|
return _react2.default.createElement(_Dropzone2.default, null);
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return PublishTool;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = PublishTool;
|
|
|
|
/***/ }),
|
|
/* 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 _file = __webpack_require__(99);
|
|
|
|
var _Preview = __webpack_require__(100);
|
|
|
|
var _Preview2 = _interopRequireDefault(_Preview);
|
|
|
|
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(_Preview2.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;
|
|
|
|
/***/ }),
|
|
/* 99 */
|
|
/***/ (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.');
|
|
}
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 100 */
|
|
/***/ (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__(9);
|
|
|
|
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 Preview = function (_React$Component) {
|
|
_inherits(Preview, _React$Component);
|
|
|
|
function Preview(props) {
|
|
_classCallCheck(this, Preview);
|
|
|
|
var _this = _possibleConstructorReturn(this, (Preview.__proto__ || Object.getPrototypeOf(Preview)).call(this, props));
|
|
|
|
_this.state = {
|
|
imgSource: '',
|
|
defaultThumbnail: '/assets/img/video_thumb_default.png'
|
|
};
|
|
return _this;
|
|
}
|
|
|
|
_createClass(Preview, [{
|
|
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 Preview;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
Preview.propTypes = {
|
|
dimPreview: _propTypes2.default.bool.isRequired,
|
|
file: _propTypes2.default.object.isRequired,
|
|
thumbnail: _propTypes2.default.object
|
|
};
|
|
|
|
exports.default = Preview;
|
|
|
|
/***/ }),
|
|
/* 101 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
var _view = __webpack_require__(102);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 102 */
|
|
/***/ (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__(4);
|
|
|
|
var _Dropzone = __webpack_require__(39);
|
|
|
|
var _Dropzone2 = _interopRequireDefault(_Dropzone);
|
|
|
|
var _PublishTitleInput = __webpack_require__(103);
|
|
|
|
var _PublishTitleInput2 = _interopRequireDefault(_PublishTitleInput);
|
|
|
|
var _PublishUrlInput = __webpack_require__(105);
|
|
|
|
var _PublishUrlInput2 = _interopRequireDefault(_PublishUrlInput);
|
|
|
|
var _PublishThumbnailInput = __webpack_require__(108);
|
|
|
|
var _PublishThumbnailInput2 = _interopRequireDefault(_PublishThumbnailInput);
|
|
|
|
var _PublishMetadataInputs = __webpack_require__(110);
|
|
|
|
var _PublishMetadataInputs2 = _interopRequireDefault(_PublishMetadataInputs);
|
|
|
|
var _ChannelSelect = __webpack_require__(113);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 103 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
var _view = __webpack_require__(104);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 104 */
|
|
/***/ (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;
|
|
|
|
/***/ }),
|
|
/* 105 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(106);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 106 */
|
|
/***/ (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__(10);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
var _PublishUrlMiddleDisplay = __webpack_require__(107);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 107 */
|
|
/***/ (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__(9);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 108 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
var _view = __webpack_require__(109);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 109 */
|
|
/***/ (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;
|
|
|
|
/***/ }),
|
|
/* 110 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
var _view = __webpack_require__(111);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 111 */
|
|
/***/ (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__(112);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 112 */
|
|
/***/ (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__(9);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 113 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
var _view = __webpack_require__(114);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 114 */
|
|
/***/ (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__(40);
|
|
|
|
var _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm);
|
|
|
|
var _ChannelCreateForm = __webpack_require__(41);
|
|
|
|
var _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm);
|
|
|
|
var _publish_channel_select_states = __webpack_require__(34);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 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 _request = __webpack_require__(10);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 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 _ProgressBar = __webpack_require__(20);
|
|
|
|
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
|
|
|
|
var _request = __webpack_require__(10);
|
|
|
|
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 (isAvailable) {
|
|
if (isAvailable) {
|
|
_this2.setState({ 'error': null });
|
|
} else {
|
|
_this2.setState({ 'error': 'That channel has already been claimed' });
|
|
}
|
|
}).catch(function (error) {
|
|
_this2.setState({ 'error': error.message });
|
|
});
|
|
}
|
|
}, {
|
|
key: 'checkIsChannelAvailable',
|
|
value: function checkIsChannelAvailable(channel) {
|
|
var channelWithAtSymbol = '@' + channel;
|
|
return new Promise(function (resolve, reject) {
|
|
(0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol).then(function (isAvailable) {
|
|
if (!isAvailable) {
|
|
return reject(new Error('That channel has already been claimed'));
|
|
}
|
|
resolve();
|
|
}).catch(function (error) {
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
}, {
|
|
key: 'checkIsPasswordProvided',
|
|
value: function checkIsPasswordProvided() {
|
|
var password = this.state.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().then(function () {
|
|
return _this3.checkIsChannelAvailable(_this3.state.channel, _this3.state.password);
|
|
}).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) {
|
|
_this3.setState({ 'error': error.message, 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;
|
|
|
|
/***/ }),
|
|
/* 117 */
|
|
/***/ (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;
|
|
|
|
/***/ }),
|
|
/* 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 InactiveStatusBar = function InactiveStatusBar() {
|
|
return _react2.default.createElement(
|
|
'span',
|
|
{ className: 'progress-bar progress-bar--inactive' },
|
|
'| '
|
|
);
|
|
};
|
|
|
|
exports.default = InactiveStatusBar;
|
|
|
|
/***/ }),
|
|
/* 119 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(5);
|
|
|
|
var _view = __webpack_require__(120);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 120 */
|
|
/***/ (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__(121);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 121 */
|
|
/***/ (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';
|
|
|
|
/***/ }),
|
|
/* 122 */
|
|
/***/ (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__(6);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _SEO = __webpack_require__(8);
|
|
|
|
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 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;
|
|
|
|
/***/ }),
|
|
/* 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 channel = _ref.channel;
|
|
|
|
return {
|
|
loggedInChannelName: channel.loggedInChannel.name
|
|
};
|
|
};
|
|
|
|
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);
|
|
|
|
var _reactRouterDom = __webpack_require__(4);
|
|
|
|
var _SEO = __webpack_require__(8);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _NavBar = __webpack_require__(6);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _ChannelLoginForm = __webpack_require__(40);
|
|
|
|
var _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm);
|
|
|
|
var _ChannelCreateForm = __webpack_require__(41);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 125 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _view = __webpack_require__(126);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 126 */
|
|
/***/ (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__(127);
|
|
|
|
var _ShowAssetLite2 = _interopRequireDefault(_ShowAssetLite);
|
|
|
|
var _ShowAssetDetails = __webpack_require__(130);
|
|
|
|
var _ShowAssetDetails2 = _interopRequireDefault(_ShowAssetDetails);
|
|
|
|
var _ShowChannel = __webpack_require__(136);
|
|
|
|
var _ShowChannel2 = _interopRequireDefault(_ShowChannel);
|
|
|
|
var _show_request_types = __webpack_require__(42);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 127 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(128);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 128 */
|
|
/***/ (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__(8);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _reactRouterDom = __webpack_require__(4);
|
|
|
|
var _AssetDisplay = __webpack_require__(43);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 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 _ProgressBar = __webpack_require__(20);
|
|
|
|
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
|
|
|
|
var _asset_display_states = __webpack_require__(36);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 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__(8);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _NavBar = __webpack_require__(6);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _ErrorPage = __webpack_require__(21);
|
|
|
|
var _ErrorPage2 = _interopRequireDefault(_ErrorPage);
|
|
|
|
var _AssetTitle = __webpack_require__(132);
|
|
|
|
var _AssetTitle2 = _interopRequireDefault(_AssetTitle);
|
|
|
|
var _AssetDisplay = __webpack_require__(43);
|
|
|
|
var _AssetDisplay2 = _interopRequireDefault(_AssetDisplay);
|
|
|
|
var _AssetInfo = __webpack_require__(134);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 132 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(133);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 133 */
|
|
/***/ (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;
|
|
|
|
/***/ }),
|
|
/* 134 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(135);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 135 */
|
|
/***/ (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__(4);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 136 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(137);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 137 */
|
|
/***/ (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__(8);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _ErrorPage = __webpack_require__(21);
|
|
|
|
var _ErrorPage2 = _interopRequireDefault(_ErrorPage);
|
|
|
|
var _NavBar = __webpack_require__(6);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _ChannelClaimsDisplay = __webpack_require__(138);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 138 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _view = __webpack_require__(139);
|
|
|
|
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);
|
|
|
|
/***/ }),
|
|
/* 139 */
|
|
/***/ (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__(140);
|
|
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 140 */
|
|
/***/ (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__(4);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var _require = __webpack_require__(3),
|
|
defaultThumbnail = _require.claim.defaultThumbnail;
|
|
|
|
var AssetPreview = function AssetPreview(_ref) {
|
|
var _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;
|
|
|
|
/***/ }),
|
|
/* 141 */
|
|
/***/ (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__(6);
|
|
|
|
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 _require = __webpack_require__(3),
|
|
_require$site = _require.site,
|
|
title = _require$site.title,
|
|
host = _require$site.host;
|
|
|
|
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() {
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 142 */
|
|
/***/ (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__(143),
|
|
determineResponseType = _require2.determineResponseType,
|
|
flipClaimNameAndIdForBackwardsCompatibility = _require2.flipClaimNameAndIdForBackwardsCompatibility,
|
|
logRequestData = _require2.logRequestData,
|
|
getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;
|
|
|
|
var lbryUri = __webpack_require__(144);
|
|
var handleShowRender = __webpack_require__(145);
|
|
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);
|
|
});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 143 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(29),
|
|
getClaimId = _require.getClaimId,
|
|
getLocalFileRecord = _require.getLocalFileRecord;
|
|
|
|
var _require2 = __webpack_require__(28),
|
|
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);
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 144 */
|
|
/***/ (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
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 145 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _server = __webpack_require__(31);
|
|
|
|
var _redux = __webpack_require__(18);
|
|
|
|
var _reducers = __webpack_require__(32);
|
|
|
|
var _reducers2 = _interopRequireDefault(_reducers);
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _reactRouterDom = __webpack_require__(4);
|
|
|
|
var _GAListener = __webpack_require__(37);
|
|
|
|
var _GAListener2 = _interopRequireDefault(_GAListener);
|
|
|
|
var _app = __webpack_require__(38);
|
|
|
|
var _app2 = _interopRequireDefault(_app);
|
|
|
|
var _renderFullPage = __webpack_require__(44);
|
|
|
|
var _renderFullPage2 = _interopRequireDefault(_renderFullPage);
|
|
|
|
var _reduxSaga = __webpack_require__(146);
|
|
|
|
var _reduxSaga2 = _interopRequireDefault(_reduxSaga);
|
|
|
|
var _effects = __webpack_require__(15);
|
|
|
|
var _show_uri = __webpack_require__(147);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
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)(_reducers2.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(
|
|
_GAListener2.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));
|
|
});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 146 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("redux-saga");
|
|
|
|
/***/ }),
|
|
/* 147 */
|
|
/***/ (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__(7);
|
|
|
|
var _show_asset = __webpack_require__(148);
|
|
|
|
var _show_channel = __webpack_require__(150);
|
|
|
|
var _lbryUri = __webpack_require__(152);
|
|
|
|
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);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 148 */
|
|
/***/ (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__(7);
|
|
|
|
var _assetApi = __webpack_require__(149);
|
|
|
|
var _show2 = __webpack_require__(13);
|
|
|
|
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, 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;
|
|
|
|
if (!state.requestList[requestId]) {
|
|
_context.next = 8;
|
|
break;
|
|
}
|
|
|
|
return _context.abrupt('return', null);
|
|
|
|
case 8:
|
|
// get long id && add request to request list
|
|
longId = void 0;
|
|
_context.prev = 9;
|
|
_context.next = 12;
|
|
return (0, _effects.call)(_assetApi.getLongClaimId, name, modifier);
|
|
|
|
case 12:
|
|
_ref = _context.sent;
|
|
longId = _ref.data;
|
|
_context.next = 21;
|
|
break;
|
|
|
|
case 16:
|
|
_context.prev = 16;
|
|
_context.t0 = _context['catch'](9);
|
|
_context.next = 20;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));
|
|
|
|
case 20:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 21:
|
|
assetKey = 'a#' + name + '#' + longId;
|
|
_context.next = 24;
|
|
return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, assetKey));
|
|
|
|
case 24:
|
|
if (!state.assetList[assetKey]) {
|
|
_context.next = 26;
|
|
break;
|
|
}
|
|
|
|
return _context.abrupt('return', null);
|
|
|
|
case 26:
|
|
// get short Id
|
|
shortId = void 0;
|
|
_context.prev = 27;
|
|
_context.next = 30;
|
|
return (0, _effects.call)(_assetApi.getShortId, name, longId);
|
|
|
|
case 30:
|
|
_ref2 = _context.sent;
|
|
shortId = _ref2.data;
|
|
_context.next = 39;
|
|
break;
|
|
|
|
case 34:
|
|
_context.prev = 34;
|
|
_context.t1 = _context['catch'](27);
|
|
_context.next = 38;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message));
|
|
|
|
case 38:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 39:
|
|
// get asset claim data
|
|
claimData = void 0;
|
|
_context.prev = 40;
|
|
_context.next = 43;
|
|
return (0, _effects.call)(_assetApi.getClaimData, name, longId);
|
|
|
|
case 43:
|
|
_ref3 = _context.sent;
|
|
claimData = _ref3.data;
|
|
_context.next = 52;
|
|
break;
|
|
|
|
case 47:
|
|
_context.prev = 47;
|
|
_context.t2 = _context['catch'](40);
|
|
_context.next = 51;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t2.message));
|
|
|
|
case 51:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 52:
|
|
_context.next = 54;
|
|
return (0, _effects.put)((0, _show.addAssetToAssetList)(assetKey, null, name, longId, shortId, claimData));
|
|
|
|
case 54:
|
|
_context.next = 56;
|
|
return (0, _effects.put)((0, _show.onRequestError)(null));
|
|
|
|
case 56:
|
|
case 'end':
|
|
return _context.stop();
|
|
}
|
|
}
|
|
}, _marked, this, [[9, 16], [27, 34], [40, 47]]);
|
|
};
|
|
|
|
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);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 149 */
|
|
/***/ (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__(10);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var _require = __webpack_require__(3),
|
|
host = _require.site.host;
|
|
|
|
function getLongClaimId(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(name, claimId) {
|
|
var url = host + '/api/claim/short-id/' + claimId + '/' + name;
|
|
return (0, _request2.default)(url);
|
|
};
|
|
|
|
function getClaimData(name, claimId) {
|
|
var url = host + '/api/claim/data/' + name + '/' + claimId;
|
|
return (0, _request2.default)(url);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 150 */
|
|
/***/ (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__(7);
|
|
|
|
var _channelApi = __webpack_require__(151);
|
|
|
|
var _show2 = __webpack_require__(13);
|
|
|
|
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, 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;
|
|
|
|
if (!state.requestList[requestId]) {
|
|
_context.next = 8;
|
|
break;
|
|
}
|
|
|
|
return _context.abrupt('return', null);
|
|
|
|
case 8:
|
|
// get channel long id
|
|
longId = void 0, shortId = void 0;
|
|
_context.prev = 9;
|
|
_context.next = 12;
|
|
return (0, _effects.call)(_channelApi.getChannelData, channelName, channelId);
|
|
|
|
case 12:
|
|
_ref = _context.sent;
|
|
_ref$data = _ref.data;
|
|
longId = _ref$data.longChannelClaimId;
|
|
shortId = _ref$data.shortChannelClaimId;
|
|
_context.next = 23;
|
|
break;
|
|
|
|
case 18:
|
|
_context.prev = 18;
|
|
_context.t0 = _context['catch'](9);
|
|
_context.next = 22;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));
|
|
|
|
case 22:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 23:
|
|
// store the request in the channel requests list
|
|
channelKey = 'c#' + channelName + '#' + longId;
|
|
_context.next = 26;
|
|
return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, channelKey));
|
|
|
|
case 26:
|
|
if (!state.channelList[channelKey]) {
|
|
_context.next = 28;
|
|
break;
|
|
}
|
|
|
|
return _context.abrupt('return', null);
|
|
|
|
case 28:
|
|
// get channel claims data
|
|
claimsData = void 0;
|
|
_context.prev = 29;
|
|
_context.next = 32;
|
|
return (0, _effects.call)(_channelApi.getChannelClaims, channelName, longId, 1);
|
|
|
|
case 32:
|
|
_ref2 = _context.sent;
|
|
claimsData = _ref2.data;
|
|
_context.next = 41;
|
|
break;
|
|
|
|
case 36:
|
|
_context.prev = 36;
|
|
_context.t1 = _context['catch'](29);
|
|
_context.next = 40;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message));
|
|
|
|
case 40:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 41:
|
|
_context.next = 43;
|
|
return (0, _effects.put)((0, _show.addNewChannelToChannelList)(channelKey, channelName, shortId, longId, claimsData));
|
|
|
|
case 43:
|
|
_context.next = 45;
|
|
return (0, _effects.put)((0, _show.onRequestError)(null));
|
|
|
|
case 45:
|
|
case 'end':
|
|
return _context.stop();
|
|
}
|
|
}
|
|
}, _marked, this, [[9, 18], [29, 36]]);
|
|
}
|
|
|
|
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, 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;
|
|
claimsData = void 0;
|
|
_context3.prev = 2;
|
|
_context3.next = 5;
|
|
return (0, _effects.call)(_channelApi.getChannelClaims, name, longId, page);
|
|
|
|
case 5:
|
|
_ref3 = _context3.sent;
|
|
claimsData = _ref3.data;
|
|
_context3.next = 14;
|
|
break;
|
|
|
|
case 9:
|
|
_context3.prev = 9;
|
|
_context3.t0 = _context3['catch'](2);
|
|
_context3.next = 13;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context3.t0.message));
|
|
|
|
case 13:
|
|
return _context3.abrupt('return', _context3.sent);
|
|
|
|
case 14:
|
|
_context3.next = 16;
|
|
return (0, _effects.put)((0, _show.updateChannelClaims)(channelKey, claimsData));
|
|
|
|
case 16:
|
|
case 'end':
|
|
return _context3.stop();
|
|
}
|
|
}
|
|
}, _marked3, this, [[2, 9]]);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
/***/ }),
|
|
/* 151 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.getChannelData = getChannelData;
|
|
exports.getChannelClaims = getChannelClaims;
|
|
|
|
var _request = __webpack_require__(10);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var _require = __webpack_require__(3),
|
|
host = _require.site.host;
|
|
|
|
function getChannelData(name, id) {
|
|
if (!id) id = 'none';
|
|
var url = host + '/api/channel/data/' + name + '/' + id;
|
|
return (0, _request2.default)(url);
|
|
};
|
|
|
|
function getChannelClaims(name, longId, page) {
|
|
if (!page) page = 1;
|
|
var url = host + '/api/channel/claims/' + name + '/' + longId + '/' + page;
|
|
return (0, _request2.default)(url);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 152 */
|
|
/***/ (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
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 153 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var handlePageRender = __webpack_require__(30);
|
|
|
|
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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgY2NhZjhkNmRhMjVmNjg2NmFhMGQiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3RcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdC1yZWR1eFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcIndpbnN0b25cIiIsIndlYnBhY2s6Ly8vLi9jb25maWcvc3BlZWNoQ29uZmlnLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LXJvdXRlci1kb21cIiIsIndlYnBhY2s6Ly8vLi9yZWFjdC9hY3Rpb25zL3B1Ymxpc2guanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9OYXZCYXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvYWN0aW9ucy9zaG93LmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbXBvbmVudHMvU0VPL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJwcm9wLXR5cGVzXCIiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvdXRpbHMvcmVxdWVzdC5qcyIsIndlYnBhY2s6Ly8vLi9tb2RlbHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29uc3RhbnRzL3Nob3dfYWN0aW9uX3R5cGVzLmpzIiwid2VicGFjazovLy8uL3JlYWN0L3NlbGVjdG9ycy9zaG93LmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LWhlbG1ldFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlZHV4LXNhZ2EvZWZmZWN0c1wiIiwid2VicGFjazovLy8uL2hlbHBlcnMvbGJyeUFwaS5qcyIsIndlYnBhY2s6Ly8vLi9oZWxwZXJzL2dvb2dsZUFuYWx5dGljcy5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWR1eFwiIiwid2VicGFjazovLy8uL3JlYWN0L2FjdGlvbnMvY2hhbm5lbC5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb21wb25lbnRzL1Byb2dyZXNzQmFyL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb21wb25lbnRzL0Vycm9yUGFnZS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicGFzc3BvcnRcIiIsIndlYnBhY2s6Ly8vLi9jb25maWcvbXlzcWxDb25maWcuanMiLCJ3ZWJwYWNrOi8vLy4vY29uZmlnL3NsYWNrQ29uZmlnLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInBhc3Nwb3J0LWxvY2FsXCIiLCJ3ZWJwYWNrOi8vLy4vaGVscGVycy9zZXF1ZWxpemVIZWxwZXJzLmpzIiwid2VicGFjazovLy8uL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMiLCJ3ZWJwYWNrOi8vLy4vaGVscGVycy9lcnJvckhhbmRsZXJzLmpzIiwid2VicGFjazovLy8uL2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcyIsIndlYnBhY2s6Ly8vLi9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4Iiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LWRvbS9zZXJ2ZXJcIiIsIndlYnBhY2s6Ly8vLi9yZWFjdC9yZWR1Y2Vycy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMuanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29uc3RhbnRzL3B1Ymxpc2hfY2hhbm5lbF9zZWxlY3Rfc3RhdGVzLmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbnN0YW50cy9jaGFubmVsX2FjdGlvbl90eXBlcy5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb25zdGFudHMvYXNzZXRfZGlzcGxheV9zdGF0ZXMuanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29tcG9uZW50cy9HQUxpc3RlbmVyL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9hcHAuanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9Ecm9wem9uZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9DaGFubmVsQ3JlYXRlRm9ybS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb25zdGFudHMvc2hvd19yZXF1ZXN0X3R5cGVzLmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvQXNzZXREaXNwbGF5L2luZGV4LmpzIiwid2VicGFjazovLy8uL2hlbHBlcnMvcmVuZGVyRnVsbFBhZ2UuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiYmFiZWwtcG9seWZpbGxcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJ3aGF0d2ctZmV0Y2hcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZXhwcmVzc1wiIiwid2VicGFjazovLy9leHRlcm5hbCBcImJvZHktcGFyc2VyXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZXhwcmVzcy1oYW5kbGViYXJzXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiaGFuZGxlYmFyc1wiIiwid2VicGFjazovLy9leHRlcm5hbCBcImhlbG1ldFwiIiwid2VicGFjazovLy8uL2hlbHBlcnMvYXV0aEhlbHBlcnMuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiY29va2llLXNlc3Npb25cIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJodHRwXCIiLCJ3ZWJwYWNrOi8vLy4vaGVscGVycy9jb25maWdWYXJDaGVjay5qcyIsIndlYnBhY2s6Ly8vLi9oZWxwZXJzL2NvbmZpZ3VyZUxvZ2dlci5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvbG9nZ2VyQ29uZmlnLmpzIiwid2VicGFjazovLy8uL2hlbHBlcnMvY29uZmlndXJlU2xhY2suanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwid2luc3Rvbi1zbGFjay13ZWJob29rXCIiLCJ3ZWJwYWNrOi8vLy4vcGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImF4aW9zXCIiLCJ3ZWJwYWNrOi8vLy4vY29uZmlnL2xicnlDb25maWcuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwidW5pdmVyc2FsLWFuYWx5dGljc1wiIiwid2VicGFjazovLy8uL3Bhc3Nwb3J0L2xvY2FsLWxvZ2luLmpzIiwid2VicGFjazovLy8uL3JvdXRlcy9hdXRoLXJvdXRlcy5qcyIsIndlYnBhY2s6Ly8vLi9yb3V0ZXMvYXBpLXJvdXRlcy5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJjb25uZWN0LW11bHRpcGFydHlcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJzZXF1ZWxpemVcIiIsIndlYnBhY2s6Ly8vLi9tb2RlbHMvY2VydGlmaWNhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vbW9kZWxzL2NoYW5uZWwuanMiLCJ3ZWJwYWNrOi8vLy4vbW9kZWxzL2NsYWltLmpzIiwid2VicGFjazovLy8uL21vZGVscy9maWxlLmpzIiwid2VicGFjazovLy8uL21vZGVscy9yZXF1ZXN0LmpzIiwid2VicGFjazovLy8uL21vZGVscy91c2VyLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImJjcnlwdFwiIiwid2VicGFjazovLy8uL2NvbnRyb2xsZXJzL3B1Ymxpc2hDb250cm9sbGVyLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImZzXCIiLCJ3ZWJwYWNrOi8vLy4vYXV0aC9hdXRoZW50aWNhdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9oZWxwZXJzL2NoYW5uZWxQYWdpbmF0aW9uLmpzIiwid2VicGFjazovLy8uL3JvdXRlcy9wYWdlLXJvdXRlcy5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9yZWR1Y2Vycy9wdWJsaXNoLmpzIiwid2VicGFjazovLy8uL3JlYWN0L3JlZHVjZXJzL2NoYW5uZWwuanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvcmVkdWNlcnMvc2hvdy5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9yZWR1Y2Vycy9zaXRlLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LWdhXCIiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29tcG9uZW50cy9Ib21lUGFnZS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvdXRpbHMvcGFnZVRpdGxlLmpzIiwid2VicGFjazovLy8uL3JlYWN0L3V0aWxzL21ldGFUYWdzLmpzIiwid2VicGFjazovLy8uL3JlYWN0L3V0aWxzL2Nhbm9uaWNhbExpbmsuanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9OYXZCYXIvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29tcG9uZW50cy9Mb2dvL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb21wb25lbnRzL05hdkJhckNoYW5uZWxPcHRpb25zRHJvcGRvd24vaW5kZXguanN4Iiwid2VicGFjazovLy9leHRlcm5hbCBcImNyb3NzLWZldGNoL3BvbHlmaWxsXCIiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoVG9vbC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hUb29sL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvRHJvcHpvbmUvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvdXRpbHMvZmlsZS5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb21wb25lbnRzL1ByZXZpZXcvaW5kZXguanN4Iiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvUHVibGlzaERldGFpbHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoRGV0YWlscy92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L2luZGV4LmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvUHVibGlzaFRpdGxlSW5wdXQvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29tcG9uZW50cy9QdWJsaXNoVXJsTWlkZGxlRGlzcGxheS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoTWV0YWRhdGFJbnB1dHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoTWV0YWRhdGFJbnB1dHMvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29tcG9uZW50cy9FeHBhbmRpbmdUZXh0QXJlYS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9DaGFubmVsU2VsZWN0L2luZGV4LmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvQ2hhbm5lbFNlbGVjdC92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9DaGFubmVsQ3JlYXRlRm9ybS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb21wb25lbnRzL0FjdGl2ZVN0YXR1c0Jhci9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29tcG9uZW50cy9JbmFjdGl2ZVN0YXR1c0Jhci9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoU3RhdHVzL2luZGV4LmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvUHVibGlzaFN0YXR1cy92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb25zdGFudHMvcHVibGlzaF9jbGFpbV9zdGF0ZXMuanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29tcG9uZW50cy9BYm91dFBhZ2UvaW5kZXguanN4Iiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvTG9naW5QYWdlL2luZGV4LmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvTG9naW5QYWdlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvU2hvd1BhZ2UvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9TaG93UGFnZS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL1Nob3dBc3NldExpdGUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9TaG93QXNzZXRMaXRlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvQXNzZXREaXNwbGF5L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL1Nob3dBc3NldERldGFpbHMvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9Bc3NldFRpdGxlL2luZGV4LmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvQXNzZXRUaXRsZS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL0Fzc2V0SW5mby9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL0Fzc2V0SW5mby92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL1Nob3dDaGFubmVsL2luZGV4LmpzIiwid2VicGFjazovLy8uL3JlYWN0L2NvbnRhaW5lcnMvU2hvd0NoYW5uZWwvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvY29udGFpbmVycy9DaGFubmVsQ2xhaW1zRGlzcGxheS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL3JlYWN0L2NvbXBvbmVudHMvQXNzZXRQcmV2aWV3L2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9yZWFjdC9jb21wb25lbnRzL0ZvdXJPaEZvdXJQYWdlL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9yb3V0ZXMvc2VydmUtcm91dGVzLmpzIiwid2VicGFjazovLy8uL2hlbHBlcnMvc2VydmVIZWxwZXJzLmpzIiwid2VicGFjazovLy8uL2hlbHBlcnMvbGJyeVVyaS5qcyIsIndlYnBhY2s6Ly8vLi9oZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4Iiwid2VicGFjazovLy9leHRlcm5hbCBcInJlZHV4LXNhZ2FcIiIsIndlYnBhY2s6Ly8vLi9yZWFjdC9zYWdhcy9zaG93X3VyaS5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9zYWdhcy9zaG93X2Fzc2V0LmpzIiwid2VicGFjazovLy8uL3JlYWN0L2FwaS9hc3NldEFwaS5qcyIsIndlYnBhY2s6Ly8vLi9yZWFjdC9zYWdhcy9zaG93X2NoYW5uZWwuanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvYXBpL2NoYW5uZWxBcGkuanMiLCJ3ZWJwYWNrOi8vLy4vcmVhY3QvdXRpbHMvbGJyeVVyaS5qcyIsIndlYnBhY2s6Ly8vLi9yb3V0ZXMvZmFsbGJhY2stcm91dGVzLmpzIl0sIm5hbWVzIjpbInNwZWVjaENvbmZpZyIsImFuYWx5dGljcyIsImdvb2dsZUlkIiwic2Vzc2lvbiIsInNlc3Npb25LZXkiLCJmaWxlcyIsInVwbG9hZERpcmVjdG9yeSIsInNpdGUiLCJ0aXRsZSIsIm5hbWUiLCJob3N0IiwiZGVzY3JpcHRpb24iLCJwdWJsaXNoIiwicHJpbWFyeUNsYWltQWRkcmVzcyIsImFkZGl0aW9uYWxDbGFpbUFkZHJlc3NlcyIsInRodW1ibmFpbENoYW5uZWwiLCJ0aHVtYm5haWxDaGFubmVsSWQiLCJjbGFpbSIsImRlZmF1bHRUaXRsZSIsImRlZmF1bHRUaHVtYm5haWwiLCJkZWZhdWx0RGVzY3JpcHRpb24iLCJtb2R1bGUiLCJleHBvcnRzIiwic2VsZWN0RmlsZSIsImNsZWFyRmlsZSIsInVwZGF0ZU1ldGFkYXRhIiwidXBkYXRlQ2xhaW0iLCJzZXRQdWJsaXNoSW5DaGFubmVsIiwidXBkYXRlUHVibGlzaFN0YXR1cyIsInVwZGF0ZUVycm9yIiwidXBkYXRlU2VsZWN0ZWRDaGFubmVsIiwidG9nZ2xlTWV0YWRhdGFJbnB1dHMiLCJvbk5ld1RodW1ibmFpbCIsInN0YXJ0UHVibGlzaCIsImFjdGlvbnMiLCJmaWxlIiwidHlwZSIsIkZJTEVfU0VMRUNURUQiLCJkYXRhIiwiRklMRV9DTEVBUiIsInZhbHVlIiwiTUVUQURBVEFfVVBEQVRFIiwiQ0xBSU1fVVBEQVRFIiwiY2hhbm5lbCIsIlNFVF9QVUJMSVNIX0lOX0NIQU5ORUwiLCJzdGF0dXMiLCJtZXNzYWdlIiwiUFVCTElTSF9TVEFUVVNfVVBEQVRFIiwiRVJST1JfVVBEQVRFIiwiY2hhbm5lbE5hbWUiLCJTRUxFQ1RFRF9DSEFOTkVMX1VQREFURSIsInNob3dNZXRhZGF0YUlucHV0cyIsIlRPR0dMRV9NRVRBREFUQV9JTlBVVFMiLCJUSFVNQk5BSUxfTkVXIiwiaGlzdG9yeSIsIlBVQkxJU0hfU1RBUlQiLCJtYXBTdGF0ZVRvUHJvcHMiLCJsb2dnZWRJbkNoYW5uZWwiLCJjaGFubmVsU2hvcnRJZCIsInNob3J0SWQiLCJjaGFubmVsTG9uZ0lkIiwibG9uZ0lkIiwibWFwRGlzcGF0Y2hUb1Byb3BzIiwib25DaGFubmVsTG9naW4iLCJkaXNwYXRjaCIsIm9uQ2hhbm5lbExvZ291dCIsIm9uSGFuZGxlU2hvd1BhZ2VVcmkiLCJvblJlcXVlc3RFcnJvciIsIm9uTmV3Q2hhbm5lbFJlcXVlc3QiLCJvbk5ld0Fzc2V0UmVxdWVzdCIsIm9uUmVxdWVzdFVwZGF0ZSIsImFkZFJlcXVlc3RUb1JlcXVlc3RMaXN0IiwiYWRkQXNzZXRUb0Fzc2V0TGlzdCIsImFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0Iiwib25VcGRhdGVDaGFubmVsQ2xhaW1zIiwidXBkYXRlQ2hhbm5lbENsYWltcyIsImZpbGVSZXF1ZXN0ZWQiLCJ1cGRhdGVGaWxlQXZhaWxhYmlsaXR5IiwidXBkYXRlRGlzcGxheUFzc2V0RXJyb3IiLCJwYXJhbXMiLCJIQU5ETEVfU0hPV19VUkkiLCJlcnJvciIsIlJFUVVFU1RfRVJST1IiLCJjaGFubmVsSWQiLCJyZXF1ZXN0VHlwZSIsInJlcXVlc3RJZCIsIkNIQU5ORUxfUkVRVUVTVF9ORVciLCJpZCIsImV4dGVuc2lvbiIsIkFTU0VUX1JFUVVFU1RfTkVXIiwibW9kaWZpZXIiLCJSRVFVRVNUX1VQREFURSIsImtleSIsIlJFUVVFU1RfTElTVF9BREQiLCJjbGFpbUlkIiwiY2xhaW1EYXRhIiwiQVNTRVRfQUREIiwiY2xhaW1zRGF0YSIsIkNIQU5ORUxfQUREIiwiY2hhbm5lbEtleSIsInBhZ2UiLCJDSEFOTkVMX0NMQUlNU19VUERBVEVfQVNZTkMiLCJjaGFubmVsTGlzdElkIiwiQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MiLCJGSUxFX1JFUVVFU1RFRCIsIkZJTEVfQVZBSUxBQklMSVRZX1VQREFURSIsIkRJU1BMQVlfQVNTRVRfRVJST1IiLCJTRU8iLCJwcm9wcyIsInBhZ2VUaXRsZSIsImFzc2V0IiwicGFnZVVyaSIsIm1ldGFUYWdzIiwiY2Fub25pY2FsTGluayIsInJlbCIsImhyZWYiLCJDb21wb25lbnQiLCJwcm9wVHlwZXMiLCJzdHJpbmciLCJvYmplY3QiLCJyZXF1ZXN0IiwicGFyc2VKU09OIiwicmVzcG9uc2UiLCJqc29uIiwiY2hlY2tTdGF0dXMiLCJqc29uUmVzcG9uc2UiLCJFcnJvciIsInVybCIsIm9wdGlvbnMiLCJmZXRjaCIsInRoZW4iLCJQcm9taXNlIiwiYWxsIiwiU2VxdWVsaXplIiwicmVxdWlyZSIsImxvZ2dlciIsImNvbnNvbGUiLCJsb2ciLCJkYXRhYmFzZSIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJkYiIsInNlcXVlbGl6ZSIsImRpYWxlY3QiLCJkaWFsZWN0T3B0aW9ucyIsImRlY2ltYWxOdW1iZXJzIiwibG9nZ2luZyIsInBvb2wiLCJtYXgiLCJtaW4iLCJpZGxlIiwiYWNxdWlyZSIsImF1dGhlbnRpY2F0ZSIsImluZm8iLCJjYXRjaCIsImVyciIsIkNlcnRpZmljYXRlIiwiQ2hhbm5lbCIsIkNsYWltIiwiRmlsZSIsIlJlcXVlc3QiLCJVc2VyIiwiaW1wb3J0IiwiT2JqZWN0Iiwia2V5cyIsImZvckVhY2giLCJtb2RlbE5hbWUiLCJhc3NvY2lhdGUiLCJ1cHNlcnQiLCJNb2RlbCIsInZhbHVlcyIsImNvbmRpdGlvbiIsInRhYmxlTmFtZSIsImZpbmRPbmUiLCJ3aGVyZSIsIm9iaiIsImRlYnVnIiwidXBkYXRlIiwiY3JlYXRlIiwic2VsZWN0QXNzZXQiLCJzaG93IiwicmVxdWVzdExpc3QiLCJhc3NldEtleSIsImFzc2V0TGlzdCIsInNlbGVjdFNob3dTdGF0ZSIsInN0YXRlIiwiYXhpb3MiLCJhcGkiLCJhcGlIb3N0IiwiYXBpUG9ydCIsImxicnlBcGlVcmkiLCJjaG9vc2VHYUxicnluZXRQdWJsaXNoTGFiZWwiLCJzZW5kR0FUaW1pbmdFdmVudCIsImhhbmRsZUxicnluZXRSZXNwb25zZSIsInJlc29sdmUiLCJyZWplY3QiLCJyZXN1bHQiLCJKU09OIiwic3RyaW5naWZ5IiwicHVibGlzaENsYWltIiwicHVibGlzaFBhcmFtcyIsImdhU3RhcnRUaW1lIiwiRGF0ZSIsIm5vdyIsInBvc3QiLCJtZXRob2QiLCJnZXRDbGFpbSIsInVyaSIsInRpbWVvdXQiLCJnZXRDbGFpbUxpc3QiLCJjbGFpbU5hbWUiLCJyZXNvbHZlVXJpIiwiZ2V0RG93bmxvYWREaXJlY3RvcnkiLCJkb3dubG9hZF9kaXJlY3RvcnkiLCJjcmVhdGVDaGFubmVsIiwiY2hhbm5lbF9uYW1lIiwiYW1vdW50IiwidWEiLCJzaXRlTmFtZSIsImNyZWF0ZVNlcnZlRXZlbnRQYXJhbXMiLCJoZWFkZXJzIiwiaXAiLCJvcmlnaW5hbFVybCIsImV2ZW50Q2F0ZWdvcnkiLCJldmVudEFjdGlvbiIsImV2ZW50TGFiZWwiLCJpcE92ZXJyaWRlIiwidXNlckFnZW50T3ZlcnJpZGUiLCJjcmVhdGVQdWJsaXNoVGltaW5nRXZlbnRQYXJhbXMiLCJjYXRlZ29yeSIsInZhcmlhYmxlIiwibGFiZWwiLCJzdGFydFRpbWUiLCJlbmRUaW1lIiwiZHVyYXRpb24iLCJ1c2VyVGltaW5nQ2F0ZWdvcnkiLCJ1c2VyVGltaW5nVmFyaWFibGVOYW1lIiwidXNlclRpbWluZ1RpbWUiLCJ1c2VyVGltaW5nTGFiZWwiLCJzZW5kR29vZ2xlQW5hbHl0aWNzRXZlbnQiLCJ2aXNpdG9ySWQiLCJyZXBsYWNlIiwidmlzaXRvciIsInN0cmljdENpZEZvcm1hdCIsImh0dHBzIiwiZXZlbnQiLCJzZW5kR29vZ2xlQW5hbHl0aWNzVGltaW5nIiwidGltaW5nIiwic2VuZEdBU2VydmVFdmVudCIsImNoYW5uZWxfaWQiLCJ1cGRhdGVMb2dnZWRJbkNoYW5uZWwiLCJDSEFOTkVMX1VQREFURSIsIlByb2dyZXNzQmFyIiwiYmFycyIsImluZGV4IiwiaW5jcmVtZW50ZXIiLCJjcmVhdGVCYXJzIiwiYmluZCIsInN0YXJ0UHJvZ3Jlc3NCYXIiLCJ1cGRhdGVQcm9ncmVzc0JhciIsInN0b3BQcm9ncmVzc0JhciIsImkiLCJzaXplIiwicHVzaCIsImlzQWN0aXZlIiwic2V0U3RhdGUiLCJ1cGRhdGVJbnRlcnZhbCIsInNldEludGVydmFsIiwiY2xlYXJJbnRlcnZhbCIsIm1hcCIsImJhciIsIm51bWJlciIsImlzUmVxdWlyZWQiLCJFcnJvclBhZ2UiLCJNeXNxbENvbmZpZyIsImNvbmZpZ3VyZSIsIlNsYWNrQ29uZmlnIiwic2xhY2tXZWJIb29rIiwic2xhY2tFcnJvckNoYW5uZWwiLCJzbGFja0luZm9DaGFubmVsIiwicmV0dXJuU2hvcnRJZCIsImNsYWltc0FycmF5IiwiY2xhaW1JbmRleCIsInN1YnN0cmluZyIsInNob3J0SWRMZW5ndGgiLCJmaW5kSW5kZXgiLCJlbGVtZW50IiwicG9zc2libGVNYXRjaGVzIiwic2xpY2UiLCJsZW5ndGgiLCJmaWx0ZXIiLCJmcyIsIndhbGxldCIsInBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5IiwibnNmdyIsImxpY2Vuc2UiLCJ0aHVtYm5haWwiLCJpbnZhbGlkTmFtZUNoYXJhY3RlcnMiLCJleGVjIiwicGFyc2VQdWJsaXNoQXBpUmVxdWVzdEZpbGVzIiwicGF0aCIsInRlc3QiLCJ2YWxpZGF0ZUZpbGVUeXBlQW5kU2l6ZSIsImZpbGVOYW1lIiwiZmlsZVBhdGgiLCJmaWxlVHlwZSIsInRodW1ibmFpbEZpbGVOYW1lIiwidGh1bWJuYWlsRmlsZVBhdGgiLCJ0aHVtYm5haWxGaWxlVHlwZSIsImNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcyIsInRyaW0iLCJmaWxlX3BhdGgiLCJiaWQiLCJtZXRhZGF0YSIsImF1dGhvciIsImxhbmd1YWdlIiwiY2xhaW1fYWRkcmVzcyIsImxicnlDbGFpbUFkZHJlc3MiLCJjcmVhdGVUaHVtYm5haWxQdWJsaXNoUGFyYW1zIiwiZGVsZXRlVGVtcG9yYXJ5RmlsZSIsInVubGluayIsImFkZEdldFJlc3VsdHNUb0ZpbGVEYXRhIiwiZmlsZUluZm8iLCJnZXRSZXN1bHQiLCJmaWxlX25hbWUiLCJkb3dubG9hZF9wYXRoIiwiY3JlYXRlRmlsZURhdGEiLCJvdXRwb2ludCIsImhlaWdodCIsImFkZHJlc3MiLCJjb250ZW50VHlwZSIsImhhbmRsZUVycm9yUmVzcG9uc2UiLCJyZXMiLCJ1c2VPYmplY3RQcm9wZXJ0aWVzSWZOb0tleXMiLCJyZXR1cm5FcnJvck1lc3NhZ2VBbmRTdGF0dXMiLCJjcmVhdGVFcnJvclJlc3BvbnNlUGF5bG9hZCIsImNvZGUiLCJuZXdFcnJvck9iamVjdCIsImdldE93blByb3BlcnR5TmFtZXMiLCJzdWNjZXNzIiwicmV0dXJuUGFnaW5hdGVkQ2hhbm5lbENsYWltcyIsIk5PX0NIQU5ORUwiLCJOT19DTEFJTSIsIk5PX0ZJTEUiLCJnZXRDbGFpbUlkIiwiY2hhbm5lbENsYWltSWQiLCJnZXRDbGFpbUlkQnlDaGFubmVsIiwiZ2V0Q2xhaW1JZEJ5Q2xhaW0iLCJnZXRMb25nQ2xhaW1JZCIsImxvbmdDbGFpbUlkIiwiZ2V0TG9uZ0NoYW5uZWxJZCIsImxvbmdDaGFubmVsSWQiLCJnZXRDbGFpbUlkQnlMb25nQ2hhbm5lbElkIiwiZ2V0Q2hhbm5lbERhdGEiLCJsb25nQ2hhbm5lbENsYWltSWQiLCJnZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkIiwic2hvcnRDaGFubmVsQ2xhaW1JZCIsImdldENoYW5uZWxDbGFpbXMiLCJnZXRBbGxDaGFubmVsQ2xhaW1zIiwiY2hhbm5lbENsYWltc0FycmF5IiwicGFnaW5hdGVkQ2hhbm5lbFZpZXdEYXRhIiwiZ2V0TG9jYWxGaWxlUmVjb3JkIiwiZGF0YVZhbHVlcyIsInJlcSIsImNvbnRleHQiLCJzdG9yZSIsImh0bWwiLCJoZWxtZXQiLCJyZW5kZXJTdGF0aWMiLCJyZWRpcmVjdCIsInByZWxvYWRlZFN0YXRlIiwiZ2V0U3RhdGUiLCJzZW5kIiwiTE9HSU4iLCJDUkVBVEUiLCJMT0NBTF9DSEVDSyIsIlVOQVZBSUxBQkxFIiwiRVJST1IiLCJBVkFJTEFCTEUiLCJjb25maWciLCJnb29nbGVBcGlLZXkiLCJpbml0aWFsaXplIiwiR0FMaXN0ZW5lciIsInNlbmRQYWdlVmlldyIsImxvY2F0aW9uIiwibGlzdGVuIiwic2V0IiwicGF0aG5hbWUiLCJwYWdldmlldyIsImNoaWxkcmVuIiwiQXBwIiwiZmlsZUVycm9yIiwic2V0RmlsZUVycm9yIiwiQ0hBTk5FTCIsIkFTU0VUX0xJVEUiLCJBU1NFVF9ERVRBSUxTIiwiZGlzcGxheUFzc2V0Iiwib25GaWxlUmVxdWVzdCIsInRvU3RyaW5nIiwibWV0YSIsImxpbmsiLCJleHByZXNzIiwiYm9keVBhcnNlciIsImV4cHJlc3NIYW5kbGViYXJzIiwiSGFuZGxlYmFycyIsInBhc3Nwb3J0IiwicG9wdWxhdGVMb2NhbHNEb3RVc2VyIiwic2VyaWFsaXplU3BlZWNoVXNlciIsImRlc2VyaWFsaXplU3BlZWNoVXNlciIsImNvb2tpZVNlc3Npb24iLCJodHRwIiwiU3BlZWNoU2VydmVyIiwibXlzcWxDb25maWciLCJzaXRlQ29uZmlnIiwic2xhY2tDb25maWciLCJQT1JUIiwic3BlYWsiLCJzb21ldGhpbmciLCJzdGFydCIsImNvbmZpZ3VyZUNvbmZpZ0ZpbGVzIiwiY29uZmlndXJlTG9nZ2luZyIsImNvbmZpZ3VyZUFwcCIsImNvbmZpZ3VyZVNlcnZlciIsInN0YXJ0U2VydmVyIiwibXlzcWxBcHBDb25maWciLCJzbGFja0FwcENvbmZpZyIsImFwcCIsImVuYWJsZSIsInVzZSIsInN0YXRpYyIsIl9fZGlybmFtZSIsInVybGVuY29kZWQiLCJleHRlbmRlZCIsIm5leHQiLCJ2ZXJib3NlIiwic2VyaWFsaXplVXNlciIsImRlc2VyaWFsaXplVXNlciIsImxvY2FsU2lnbnVwU3RyYXRlZ3kiLCJsb2NhbExvZ2luU3RyYXRlZ3kiLCJtYXhBZ2UiLCJoYnMiLCJkZWZhdWx0TGF5b3V0IiwiaGFuZGxlYmFycyIsImVuZ2luZSIsInNlcnZlciIsIlNlcnZlciIsInN5bmMiLCJ1c2VyIiwibG9jYWxzIiwidXNlck5hbWUiLCJzaG9ydENoYW5uZWxJZCIsImRvbmUiLCJjb25maWdDYXRlZ29yeUtleSIsImhhc093blByb3BlcnR5IiwiY29uZmlnVmFyaWFibGVzIiwiY29uZmlnVmFyS2V5IiwibG9nTGV2ZWwiLCJ3aW5zdG9uIiwidHJhbnNwb3J0cyIsIkNvbnNvbGUiLCJsZXZlbCIsInRpbWVzdGFtcCIsImNvbG9yaXplIiwicHJldHR5UHJpbnQiLCJoYW5kbGVFeGNlcHRpb25zIiwiaHVtYW5SZWFkYWJsZVVuaGFuZGxlZEV4Y2VwdGlvbiIsIndhcm4iLCJzaWxseSIsImxvZ2dlckNvbmZpZyIsIndpbnN0b25TbGFja1dlYkhvb2siLCJTbGFja1dlYkhvb2siLCJhZGQiLCJ3ZWJob29rVXJsIiwiaWNvbkVtb2ppIiwiUGFzc3BvcnRMb2NhbFN0cmF0ZWd5IiwiU3RyYXRlZ3kiLCJsYnJ5QXBpIiwidXNlcm5hbWVGaWVsZCIsInBhc3N3b3JkRmllbGQiLCJ1c2VySW5mbyIsInVzZXJEYXRhIiwiY2hhbm5lbERhdGEiLCJ0eCIsImNsYWltX2lkIiwiY2VydGlmaWNhdGVEYXRhIiwibmV3VXNlciIsIm5ld0NoYW5uZWwiLCJuZXdDZXJ0aWZpY2F0ZSIsInNldENoYW5uZWwiLCJzZXRVc2VyIiwibGJyeUNvbmZpZyIsInJldHVyblVzZXJBbmRDaGFubmVsSW5mbyIsInVzZXJJbnN0YW5jZSIsImdldENoYW5uZWwiLCJjb21wYXJlUGFzc3dvcmQiLCJpc01hdGNoIiwibG9nSW4iLCJnZXQiLCJsb2dvdXQiLCJtdWx0aXBhcnQiLCJtdWx0aXBhcnRNaWRkbGV3YXJlIiwidXBsb2FkRGlyIiwiY2xhaW1OYW1lSXNBdmFpbGFibGUiLCJjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkiLCJlcnJvckhhbmRsZXJzIiwiYXV0aGVudGljYXRlVXNlciIsImJvZHkiLCJjbGFpbXNMaXN0IiwicmVzb2x2ZUNsYWltIiwicmVzb2x2ZVJlc3VsdCIsImZpbGVEYXRhIiwiZmlsZVJlY29yZCIsImNvbXBsZXRlZCIsInJlc29sdmVkVXJpIiwiY2hhbm5lbFBhc3N3b3JkIiwidmFsaWRhdGVkQ2xhaW1OYW1lIiwidGh1bWJuYWlsUHVibGlzaFBhcmFtcyIsImxicnlUeCIsImdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCIsImNsYWltSW5mbyIsIlNUUklORyIsIkJPT0xFQU4iLCJJTlRFR0VSIiwiVEVYVCIsIkRFQ0lNQUwiLCJkZWZpbmUiLCJkZWZhdWx0IiwiY2xhaW1TZXF1ZW5jZSIsImRlY29kZWRDbGFpbSIsImRlcHRoIiwiZWZmZWN0aXZlQW1vdW50IiwiaGFzU2lnbmF0dXJlIiwiaGV4Iiwibm91dCIsInR4aWQiLCJ2YWxpZEF0SGVpZ2h0IiwidmFsdWVWZXJzaW9uIiwiY2xhaW1UeXBlIiwiY2VydGlmaWNhdGVWZXJzaW9uIiwia2V5VHlwZSIsInB1YmxpY0tleSIsImZyZWV6ZVRhYmxlTmFtZSIsImJlbG9uZ3NUbyIsImZvcmVpZ25LZXkiLCJhbGxvd051bGwiLCJmaW5kQWxsIiwib3JkZXIiLCJnZXRMb25nQ2hhbm5lbElkRnJvbVNob3J0Q2hhbm5lbElkIiwiJGxpa2UiLCJnZXRMb25nQ2hhbm5lbElkRnJvbUNoYW5uZWxOYW1lIiwidmFsaWRhdGVMb25nQ2hhbm5lbElkIiwiaGFzT25lIiwiZGV0ZXJtaW5lRmlsZUV4dGVuc2lvbkZyb21Db250ZW50VHlwZSIsImRldGVybWluZVRodW1ibmFpbCIsInN0b3JlZFRodW1ibmFpbCIsInByZXBhcmVDbGFpbURhdGEiLCJjZXJ0aWZpY2F0ZUlkIiwibGljZW5zZVVybCIsInByZXZpZXciLCJtZXRhZGF0YVZlcnNpb24iLCJzb3VyY2UiLCJzb3VyY2VUeXBlIiwic291cmNlVmVyc2lvbiIsInN0cmVhbVZlcnNpb24iLCJyYXciLCJnZXRMb25nQ2xhaW1JZEZyb21TaG9ydENsYWltSWQiLCJnZXRUb3BGcmVlQ2xhaW1JZEJ5Q2xhaW1OYW1lIiwidmFsaWRhdGVMb25nQ2xhaW1JZCIsImNsYWltQXJyYXkiLCJkZWZhdWx0VmFsdWUiLCJ0cmVuZGluZ0VsaWdpYmxlIiwiaGFzTWFueSIsImdldFJlY2VudENsYWltcyIsImxpbWl0IiwiYWN0aW9uIiwiaXBBZGRyZXNzIiwiYmNyeXB0IiwicHJvdG90eXBlIiwiY29tcGFyZSIsImNoYW5nZVBhc3N3b3JkIiwibmV3UGFzc3dvcmQiLCJnZW5TYWx0Iiwic2FsdEVycm9yIiwic2FsdCIsImhhc2giLCJoYXNoRXJyb3IiLCJob29rIiwicHVibGlzaEhlbHBlcnMiLCJwdWJsaXNoUmVzdWx0cyIsImNsYWltUmVjb3JkIiwidXBzZXJ0Q3JpdGVyaWEiLCJzZXRDbGFpbSIsInNldEZpbGUiLCJjbGFpbUFkZHJlc3MiLCJmaWx0ZXJlZFJlc3VsdCIsImF1dGhlbnRpY2F0ZUNoYW5uZWxDcmVkZW50aWFscyIsInVzZXJQYXNzd29yZCIsImNoYW5uZWxGaW5kUGFyYW1zIiwiQ0xBSU1TX1BFUl9QQUdFIiwiY2xhaW1zIiwidG90YWxQYWdlcyIsImRldGVybWluZVRvdGFsUGFnZXMiLCJwYWdpbmF0aW9uUGFnZSIsImdldFBhZ2VGcm9tUXVlcnkiLCJ2aWV3RGF0YSIsImV4dHJhY3RQYWdlRnJvbUNsYWltcyIsInByZXZpb3VzUGFnZSIsImRldGVybWluZVByZXZpb3VzUGFnZSIsImN1cnJlbnRQYWdlIiwibmV4dFBhZ2UiLCJkZXRlcm1pbmVOZXh0UGFnZSIsInRvdGFsUmVzdWx0cyIsImRldGVybWluZVRvdGFsQ2xhaW1zIiwicGFyc2VJbnQiLCJwYWdlTnVtYmVyIiwiY2xhaW1TdGFydEluZGV4IiwiY2xhaW1FbmRJbmRleCIsInBhZ2VPZkNsYWltcyIsInRvdGFsQ2xhaW1zIiwiZnVsbFBhZ2VzIiwiTWF0aCIsImZsb29yIiwicmVtYWluZGVyIiwiaGFuZGxlUGFnZVJlbmRlciIsInJlbmRlciIsImxheW91dCIsImluaXRpYWxTdGF0ZSIsImFzc2lnbiIsInB1Ymxpc2hJbkNoYW5uZWwiLCJzZWxlY3RlZENoYW5uZWwiLCJwdWJsaXNoU3VibWl0IiwiY2hhbm5lbExpc3QiLCJIb21lUGFnZSIsInNpdGVUaXRsZSIsImNyZWF0ZVBhZ2VUaXRsZSIsImRldGVybWluZU9nVGh1bWJuYWlsQ29udGVudFR5cGUiLCJmaWxlRXh0IiwibGFzdEluZGV4T2YiLCJjcmVhdGVCYXNpY01ldGFUYWdzIiwicHJvcGVydHkiLCJjb250ZW50IiwiY3JlYXRlQ2hhbm5lbE1ldGFUYWdzIiwiY3JlYXRlQXNzZXRNZXRhVGFncyIsImVtYmVkVXJsIiwic2hvd1VybCIsIm9nVGl0bGUiLCJvZ0Rlc2NyaXB0aW9uIiwib2dUaHVtYm5haWxDb250ZW50VHlwZSIsIm9nVGh1bWJuYWlsIiwiY3JlYXRlTWV0YVRhZ3MiLCJjcmVhdGVCYXNpY0Nhbm9uaWNhbExpbmsiLCJjcmVhdGVBc3NldENhbm9uaWNhbExpbmsiLCJjcmVhdGVDaGFubmVsQ2Fub25pY2FsTGluayIsImNyZWF0ZUNhbm9uaWNhbExpbmsiLCJWSUVXIiwiTE9HT1VUIiwiTmF2QmFyIiwiY2hlY2tGb3JMb2dnZWRJblVzZXIiLCJsb2dvdXRVc2VyIiwiaGFuZGxlU2VsZWN0aW9uIiwiY3JlZGVudGlhbHMiLCJ0YXJnZXQiLCJzZWxlY3RlZE9wdGlvbnMiLCJMb2dvIiwiTmF2QmFyQ2hhbm5lbERyb3Bkb3duIiwiZGVmYXVsdFNlbGVjdGlvbiIsIlB1Ymxpc2hUb29sIiwiRHJvcHpvbmUiLCJkcmFnT3ZlciIsIm1vdXNlT3ZlciIsImRpbVByZXZpZXciLCJoYW5kbGVEcm9wIiwiaGFuZGxlRHJhZ092ZXIiLCJoYW5kbGVEcmFnRW5kIiwiaGFuZGxlRHJhZ0VudGVyIiwiaGFuZGxlRHJhZ0xlYXZlIiwiaGFuZGxlTW91c2VFbnRlciIsImhhbmRsZU1vdXNlTGVhdmUiLCJoYW5kbGVDbGljayIsImhhbmRsZUZpbGVJbnB1dCIsImNob29zZUZpbGUiLCJwcmV2ZW50RGVmYXVsdCIsImR0IiwiZGF0YVRyYW5zZmVyIiwiaXRlbXMiLCJraW5kIiwiZHJvcHBlZEZpbGUiLCJnZXRBc0ZpbGUiLCJyZW1vdmUiLCJjbGVhckRhdGEiLCJkb2N1bWVudCIsImdldEVsZW1lbnRCeUlkIiwiY2xpY2siLCJmaWxlTGlzdCIsInZhbGlkYXRlRmlsZSIsIlByZXZpZXciLCJpbWdTb3VyY2UiLCJzZXRQcmV2aWV3SW1hZ2VTb3VyY2UiLCJuZXdQcm9wcyIsInNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlIiwicHJldmlld1JlYWRlciIsIkZpbGVSZWFkZXIiLCJyZWFkQXNEYXRhVVJMIiwib25sb2FkZW5kIiwiYm9vbCIsIlB1Ymxpc2hEZXRhaWxzIiwib25QdWJsaXNoU3VibWl0Iiwib25NZXRhZGF0YUNoYW5nZSIsIlB1Ymxpc2hUaXRsZUlucHV0IiwiaGFuZGxlSW5wdXQiLCJlIiwibG9nZ2VkSW5DaGFubmVsTmFtZSIsImxvZ2dlZEluQ2hhbm5lbFNob3J0SWQiLCJ1cmxFcnJvciIsIm9uQ2xhaW1DaGFuZ2UiLCJvblVybEVycm9yIiwiUHVibGlzaFVybElucHV0Iiwic2V0Q2xhaW1OYW1lIiwidmFsaWRhdGVDbGFpbSIsImNsZWFuc2VJbnB1dCIsImlucHV0IiwiZmlsZU5hbWVXaXRob3V0RW5kaW5nIiwiY2xlYW5DbGFpbU5hbWUiLCJVcmxNaWRkbGUiLCJkYXRhVVJJdG9CbG9iIiwiZGF0YVVSSSIsImJ5dGVTdHJpbmciLCJhdG9iIiwic3BsaXQiLCJtaW1lU3RyaW5nIiwiaWEiLCJVaW50OEFycmF5IiwiY2hhckNvZGVBdCIsIkJsb2IiLCJQdWJsaXNoVGh1bWJuYWlsSW5wdXQiLCJ2aWRlb1NvdXJjZSIsInNsaWRlck1pblJhbmdlIiwic2xpZGVyTWF4UmFuZ2UiLCJzbGlkZXJWYWx1ZSIsImhhbmRsZVZpZGVvTG9hZGVkRGF0YSIsImhhbmRsZVNsaWRlckNoYW5nZSIsImNyZWF0ZVRodW1ibmFpbCIsInNldFZpZGVvU291cmNlIiwibmV4dFByb3BzIiwiZGF0YVVyaSIsImJsb2IiLCJVUkwiLCJjcmVhdGVPYmplY3RVUkwiLCJ0b3RhbE1pbnV0ZXMiLCJ0b3RhbFNlY29uZHMiLCJ2aWRlbyIsImN1cnJlbnRUaW1lIiwiY2FudmFzIiwiY3JlYXRlRWxlbWVudCIsIndpZHRoIiwidmlkZW9XaWR0aCIsInZpZGVvSGVpZ2h0IiwiZ2V0Q29udGV4dCIsImRyYXdJbWFnZSIsImRhdGFVcmwiLCJ0b0RhdGFVUkwiLCJzbmFwc2hvdCIsImRpc3BsYXkiLCJvblRvZ2dsZU1ldGFkYXRhSW5wdXRzIiwiUHVibGlzaE1ldGFkYXRhSW5wdXRzIiwidG9nZ2xlU2hvd0lucHV0cyIsImhhbmRsZVNlbGVjdCIsImNoZWNrZWQiLCJzZWxlY3RlZE9wdGlvbiIsIm1heEhlaWdodCIsIkV4cGFuZGluZ1RleHRhcmVhIiwiX2hhbmRsZUNoYW5nZSIsImFkanVzdFRleHRhcmVhIiwib25DaGFuZ2UiLCJlbCIsInN0eWxlIiwic2Nyb2xsSGVpZ2h0IiwicmVzdCIsIngiLCJmdW5jIiwiY2hhbm5lbEVycm9yIiwib25QdWJsaXNoSW5DaGFubmVsQ2hhbmdlIiwib25DaGFubmVsU2VsZWN0Iiwic3RhdGVzIiwiQ2hhbm5lbFNlbGVjdCIsInRvZ2dsZUFub255bW91c1B1Ymxpc2giLCJDaGFubmVsTG9naW5Gb3JtIiwibG9naW5Ub0NoYW5uZWwiLCJIZWFkZXJzIiwiQ2hhbm5lbENyZWF0ZUZvcm0iLCJoYW5kbGVDaGFubmVsSW5wdXQiLCJjbGVhbnNlQ2hhbm5lbElucHV0IiwidXBkYXRlSXNDaGFubmVsQXZhaWxhYmxlIiwiY2hhbm5lbFdpdGhBdFN5bWJvbCIsImlzQXZhaWxhYmxlIiwiY2hlY2tJc1Bhc3N3b3JkUHJvdmlkZWQiLCJjaGVja0lzQ2hhbm5lbEF2YWlsYWJsZSIsIm1ha2VQdWJsaXNoQ2hhbm5lbFJlcXVlc3QiLCJBY3RpdmVTdGF0dXNCYXIiLCJJbmFjdGl2ZVN0YXR1c0JhciIsInB1Ymxpc2hTdGF0ZXMiLCJQdWJsaXNoU3RhdHVzIiwiTE9BRF9TVEFSVCIsIkxPQURJTkciLCJQVUJMSVNISU5HIiwiU1VDQ0VTUyIsIkZBSUxFRCIsIkFib3V0UGFnZSIsIkxvZ2luUGFnZSIsIlNob3dQYWdlIiwibWF0Y2giLCJTaG93TGl0ZSIsIkFzc2V0RGlzcGxheSIsIlNob3dBc3NldERldGFpbHMiLCJBc3NldFRpdGxlIiwiQXNzZXRJbmZvIiwiY29weVRvQ2xpcGJvYXJkIiwiZWxlbWVudFRvQ29weSIsImRhdGFzZXQiLCJlbGVtZW50dG9jb3B5Iiwic2VsZWN0IiwiZXhlY0NvbW1hbmQiLCJwcmV2aW91c1JlcXVlc3QiLCJTaG93Q2hhbm5lbCIsIkNoYW5uZWxDbGFpbXNEaXNwbGF5Iiwic2hvd05leHRSZXN1bHRzUGFnZSIsInNob3dQcmV2aW91c1Jlc3VsdHNQYWdlIiwic2hvd05ld1BhZ2UiLCJBc3NldFByZXZpZXciLCJkaXJlY3RTb3VyY2VMaW5rIiwic2hvd1VybExpbmsiLCJGb3VyT2hGb3JQYWdlIiwiZGV0ZXJtaW5lUmVzcG9uc2VUeXBlIiwiZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eSIsImxvZ1JlcXVlc3REYXRhIiwiZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQiLCJsYnJ5VXJpIiwiaGFuZGxlU2hvd1JlbmRlciIsIlNFUlZFIiwiaGFzRmlsZUV4dGVuc2lvbiIsInBhcnNlTW9kaWZpZXIiLCJyZXNwb25zZVR5cGUiLCJwYXJzZUNsYWltIiwiaXNDaGFubmVsIiwicGFyc2VJZGVudGlmaWVyIiwiaWRlbnRpZmllciIsIlNIT1ciLCJjbGllbnRBY2NlcHRzSHRtbCIsImFjY2VwdCIsInJlcXVlc3RJc0Zyb21Ccm93c2VyIiwiY2xpZW50V2FudHNBc3NldCIsInJhbmdlIiwiaW1hZ2VJc1dhbnRlZCIsInZpZGVvSXNXYW50ZWQiLCJpc1ZhbGlkQ2xhaW1JZCIsImlzVmFsaWRTaG9ydElkIiwiaXNWYWxpZFNob3J0SWRPckNsYWltSWQiLCJzZXJ2ZUFzc2V0VG9DbGllbnQiLCJzZW5kRmlsZU9wdGlvbnMiLCJzZW5kRmlsZSIsImZ1bGxDbGFpbUlkIiwidGVtcE5hbWUiLCJSRUdFWFBfSU5WQUxJRF9DTEFJTSIsIlJFR0VYUF9JTlZBTElEX0NIQU5ORUwiLCJSRUdFWFBfQUREUkVTUyIsIkNIQU5ORUxfQ0hBUiIsImNvbXBvbmVudHNSZWdleCIsIlJlZ0V4cCIsInByb3RvIiwibW9kaWZpZXJTZXBlcmF0b3IiLCJzdGFydHNXaXRoIiwibmFtZUJhZENoYXJzIiwiam9pbiIsInJldHVyblNhZ2FXaXRoUGFyYW1zIiwic2FnYSIsInNhZ2FNaWRkbGV3YXJlIiwibWlkZGxld2FyZSIsInJ1biIsImhhbmRsZVNob3dQYWdlVXJpIiwid2F0Y2hIYW5kbGVTaG93UGFnZVVyaSIsInBhcnNlQW5kVXBkYXRlSWRlbnRpZmllckFuZENsYWltIiwicGFyc2VBbmRVcGRhdGVDbGFpbU9ubHkiLCJuZXdBc3NldFJlcXVlc3QiLCJ3YXRjaE5ld0Fzc2V0UmVxdWVzdCIsImdldFNob3J0SWQiLCJnZXRDbGFpbURhdGEiLCJuZXdDaGFubmVsUmVxdWVzdCIsIndhdGNoTmV3Q2hhbm5lbFJlcXVlc3QiLCJ3YXRjaFVwZGF0ZUNoYW5uZWxDbGFpbXMiLCJnZXROZXdDbGFpbXNBbmRVcGRhdGVDaGFubmVsIiwiZXh0ZW5zaW9uU2VwZXJhdG9yIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7O0FDN0RBLGtDOzs7Ozs7QUNBQSx3Qzs7Ozs7O0FDQUEsb0M7Ozs7Ozs7OztBQ0FBLElBQU1BLGVBQWU7QUFDbkJDLGFBQVc7QUFDVEMsY0FBVSxlQURELENBQ2tCO0FBRGxCLEdBRFE7QUFJbkJDLFdBQVM7QUFDUEMsZ0JBQVksdUJBREwsQ0FDK0I7QUFEL0IsR0FKVTtBQU9uQkMsU0FBTztBQUNMQyxxQkFBaUIsb0JBRFosQ0FDbUM7QUFEbkMsR0FQWTtBQVVuQkMsUUFBTTtBQUNKQyxXQUFhLGNBRFQ7QUFFSkMsVUFBYSxjQUZUO0FBR0pDLFVBQWEsc0JBSFQ7QUFJSkMsaUJBQWE7QUFKVCxHQVZhO0FBZ0JuQkMsV0FBUztBQUNQQyx5QkFBMEIsb0NBRG5CO0FBRVBDLDhCQUEwQixDQUFDLG9DQUFELENBRm5CO0FBR1BDLHNCQUEwQixhQUhuQixFQUdtQztBQUMxQ0Msd0JBQTBCLDBDQUpuQixDQUlnRTtBQUpoRSxHQWhCVTtBQXNCbkJDLFNBQU87QUFDTEMsa0JBQW9CLGNBRGY7QUFFTEMsc0JBQW9CLG9EQUZmO0FBR0xDLHdCQUFvQjtBQUhmO0FBdEJZLENB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QWtCLElBQWxCLENBQWpFLFFBQU47QUFDRDtBQUNEO0FBQ0EsUUFBSWtCLGtCQUFKLEVBQXdCO0FBQ3RCLFVBQUksQ0FBQ2x5QixTQUFMLEVBQWdCO0FBQ2QsY0FBTSxJQUFJc0MsS0FBSixtRUFBMEU0dkIsa0JBQTFFLFFBQU47QUFDRDtBQUNELFVBQUlBLHVCQUF1QixHQUEzQixFQUFnQztBQUM5QixjQUFNLElBQUk1dkIsS0FBSiw0QkFBbUM0dkIsa0JBQW5DLHFEQUFOO0FBQ0Q7QUFDRjtBQUNELFdBQU87QUFDTHhxQiwwQkFESztBQUVMMUgsaUJBQVdBLGFBQWE7QUFGbkIsS0FBUDtBQUlEO0FBbkZjLENBQWpCLEM7Ozs7Ozs7OztBQ0FBLElBQU11aEIsbUJBQW1CLG1CQUFBemUsQ0FBUSxFQUFSLENBQXpCOztBQUVBakgsT0FBT0MsT0FBUCxHQUFpQixlQUFPO0FBQ3RCO0FBQ0FvWixNQUFJRSxHQUFKLENBQVEsR0FBUixFQUFhLFVBQUNqRSxHQUFELEVBQU0vQixHQUFOLEVBQWM7QUFDekI7QUFDQW1TLHFCQUFpQnBRLEdBQWpCLEVBQXNCL0IsR0FBdEI7QUFDRCxHQUhEO0FBSUQsQ0FORCxDIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7XG4gXHRcdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuIFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcbiBcdFx0XHRcdGdldDogZ2V0dGVyXG4gXHRcdFx0fSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiL1wiO1xuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDQ1KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL2Jvb3RzdHJhcCBjY2FmOGQ2ZGEyNWY2ODY2YWEwZCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVhY3RcIlxuLy8gbW9kdWxlIGlkID0gMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdC1yZWR1eFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LXJlZHV4XCJcbi8vIG1vZHVsZSBpZCA9IDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwid2luc3RvblwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcIndpbnN0b25cIlxuLy8gbW9kdWxlIGlkID0gMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBzcGVlY2hDb25maWcgPSB7XG4gIGFuYWx5dGljczoge1xuICAgIGdvb2dsZUlkOiAnVUEtNjA0MDMzNjItNicsIC8vIGdvb2dsZSBpZCBmb3IgYW5hbHl0aWNzIHRyYWNraW5nOyBsZWF2ZSBgbnVsbGAgaWYgbm90IGFwcGxpY2FibGVcbiAgfSxcbiAgc2Vzc2lvbjoge1xuICAgIHNlc3Npb25LZXk6ICduYW5zJCNrZmphbndlMjM0cnlkbnMnLCAgLy8gZW50ZXIgYSBzZWNyZXQga2V5IHRvIGJlIHVzZWQgZm9yIHNlc3Npb24gZW5jcnlwdGlvblxuICB9LFxuICBmaWxlczoge1xuICAgIHVwbG9hZERpcmVjdG9yeTogJy9ob21lL2xicnkvVXBsb2FkcycsICAvLyBlbnRlciBmaWxlIHBhdGggdG8gd2hlcmUgdXBsb2Fkcy9wdWJsaXNoZXMgc2hvdWxkIGJlIHN0b3JlZFxuICB9LFxuICBzaXRlOiB7XG4gICAgdGl0bGUgICAgICA6ICdkZXYxLlNwZWUuY2gnLFxuICAgIG5hbWUgICAgICAgOiAnZGV2MS5TcGVlLmNoJyxcbiAgICBob3N0ICAgICAgIDogJ2h0dHBzOi8vZGV2MS5zcGVlLmNoJyxcbiAgICBkZXNjcmlwdGlvbjogJ09wZW4tc291cmNlLCBkZWNlbnRyYWxpemVkIGltYWdlIGFuZCB2aWRlbyBzaGFyaW5nLicsXG4gIH0sXG4gIHB1Ymxpc2g6IHtcbiAgICBwcmltYXJ5Q2xhaW1BZGRyZXNzICAgICA6ICdiRFoyd1B3dFVMVUd4VDdHWHVOTHBRaFhtZFBSVVRVa2NMJyxcbiAgICBhZGRpdGlvbmFsQ2xhaW1BZGRyZXNzZXM6IFsnYmFucHdpeFBvc2ZWRFduR3ZYcVUyYWYzNlFwc2Q3YnVHZCddLFxuICAgIHRodW1ibmFpbENoYW5uZWwgICAgICAgIDogJ0BkZXYxdGh1bWJzJywgIC8vIGNyZWF0ZSBhIGNoYW5uZWwgdG8gdXNlIGZvciB0aHVtYm5haWwgaW1hZ2VzXG4gICAgdGh1bWJuYWlsQ2hhbm5lbElkICAgICAgOiAnYWViNjI1ZmY2ZjY2YzNlZWViNDI4ODUwNzBmNGU1Mzg3NjAzMzYyNicsICAvLyB0aGUgY2hhbm5lbF9pZCAoY2xhaW0gaWQpIGZvciB0aGUgY2hhbm5lbCBhYm92ZVxuICB9LFxuICBjbGFpbToge1xuICAgIGRlZmF1bHRUaXRsZSAgICAgIDogJ2RldjEgU3BlZS5jaCcsXG4gICAgZGVmYXVsdFRodW1ibmFpbCAgOiAnaHR0cHM6Ly9zcGVlLmNoL2Fzc2V0cy9pbWcvdmlkZW9fdGh1bWJfZGVmYXVsdC5wbmcnLFxuICAgIGRlZmF1bHREZXNjcmlwdGlvbjogJ09wZW4tc291cmNlLCBkZWNlbnRyYWxpemVkIGltYWdlIGFuZCB2aWRlbyBzaGFyaW5nLicsXG4gIH0sXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNwZWVjaENvbmZpZztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NvbmZpZy9zcGVlY2hDb25maWcuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdC1yb3V0ZXItZG9tXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVhY3Qtcm91dGVyLWRvbVwiXG4vLyBtb2R1bGUgaWQgPSA0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL3B1Ymxpc2hfYWN0aW9uX3R5cGVzJztcblxuLy8gZXhwb3J0IGFjdGlvbiBjcmVhdG9yc1xuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdEZpbGUgKGZpbGUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkZJTEVfU0VMRUNURUQsXG4gICAgZGF0YTogZmlsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhckZpbGUgKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuRklMRV9DTEVBUixcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVNZXRhZGF0YSAobmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLk1FVEFEQVRBX1VQREFURSxcbiAgICBkYXRhOiB7XG4gICAgICBuYW1lLFxuICAgICAgdmFsdWUsXG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVDbGFpbSAodmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkNMQUlNX1VQREFURSxcbiAgICBkYXRhOiB2YWx1ZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRQdWJsaXNoSW5DaGFubmVsIChjaGFubmVsKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5TRVRfUFVCTElTSF9JTl9DSEFOTkVMLFxuICAgIGNoYW5uZWwsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlUHVibGlzaFN0YXR1cyAoc3RhdHVzLCBtZXNzYWdlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5QVUJMSVNIX1NUQVRVU19VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgc3RhdHVzLFxuICAgICAgbWVzc2FnZSxcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUVycm9yIChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuRVJST1JfVVBEQVRFLFxuICAgIGRhdGE6IHtcbiAgICAgIG5hbWUsXG4gICAgICB2YWx1ZSxcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbCAoY2hhbm5lbE5hbWUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlNFTEVDVEVEX0NIQU5ORUxfVVBEQVRFLFxuICAgIGRhdGE6IGNoYW5uZWxOYW1lLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHRvZ2dsZU1ldGFkYXRhSW5wdXRzIChzaG93TWV0YWRhdGFJbnB1dHMpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlRPR0dMRV9NRVRBREFUQV9JTlBVVFMsXG4gICAgZGF0YTogc2hvd01ldGFkYXRhSW5wdXRzLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uTmV3VGh1bWJuYWlsIChmaWxlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5USFVNQk5BSUxfTkVXLFxuICAgIGRhdGE6IGZpbGUsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gc3RhcnRQdWJsaXNoIChoaXN0b3J5KSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5QVUJMSVNIX1NUQVJULFxuICAgIGRhdGE6IHsgaGlzdG9yeSB9LFxuICB9O1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvYWN0aW9ucy9wdWJsaXNoLmpzIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbCB9IGZyb20gJ2FjdGlvbnMvY2hhbm5lbCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuaW1wb3J0IHt1cGRhdGVTZWxlY3RlZENoYW5uZWx9IGZyb20gJy4uLy4uL2FjdGlvbnMvcHVibGlzaCc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IGNoYW5uZWwgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGNoYW5uZWxOYW1lICAgOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5uYW1lLFxuICAgIGNoYW5uZWxTaG9ydElkOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5zaG9ydElkLFxuICAgIGNoYW5uZWxMb25nSWQgOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5sb25nSWQsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25DaGFubmVsTG9naW46IChuYW1lLCBzaG9ydElkLCBsb25nSWQpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbChuYW1lLCBzaG9ydElkLCBsb25nSWQpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbChuYW1lKSk7XG4gICAgfSxcbiAgICBvbkNoYW5uZWxMb2dvdXQ6ICgpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbChudWxsLCBudWxsLCBudWxsKSk7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29udGFpbmVycy9OYXZCYXIvaW5kZXguanMiLCJpbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcyc7XG5cbmltcG9ydCB7IENIQU5ORUwsIEFTU0VUX0xJVEUsIEFTU0VUX0RFVEFJTFMgfSBmcm9tICdjb25zdGFudHMvc2hvd19yZXF1ZXN0X3R5cGVzJztcblxuLy8gYmFzaWMgcmVxdWVzdCBwYXJzaW5nXG5leHBvcnQgZnVuY3Rpb24gb25IYW5kbGVTaG93UGFnZVVyaSAocGFyYW1zKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5IQU5ETEVfU0hPV19VUkksXG4gICAgZGF0YTogcGFyYW1zLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uUmVxdWVzdEVycm9yIChlcnJvcikge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuUkVRVUVTVF9FUlJPUixcbiAgICBkYXRhOiBlcnJvcixcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvbk5ld0NoYW5uZWxSZXF1ZXN0IChjaGFubmVsTmFtZSwgY2hhbm5lbElkKSB7XG4gIGNvbnN0IHJlcXVlc3RUeXBlID0gQ0hBTk5FTDtcbiAgY29uc3QgcmVxdWVzdElkID0gYGNyIyR7Y2hhbm5lbE5hbWV9IyR7Y2hhbm5lbElkfWA7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5DSEFOTkVMX1JFUVVFU1RfTkVXLFxuICAgIGRhdGE6IHsgcmVxdWVzdFR5cGUsIHJlcXVlc3RJZCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uTmV3QXNzZXRSZXF1ZXN0IChuYW1lLCBpZCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgZXh0ZW5zaW9uKSB7XG4gIGNvbnN0IHJlcXVlc3RUeXBlID0gZXh0ZW5zaW9uID8gQVNTRVRfTElURSA6IEFTU0VUX0RFVEFJTFM7XG4gIGNvbnN0IHJlcXVlc3RJZCA9IGBhciMke25hbWV9IyR7aWR9IyR7Y2hhbm5lbE5hbWV9IyR7Y2hhbm5lbElkfWA7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5BU1NFVF9SRVFVRVNUX05FVyxcbiAgICBkYXRhOiB7XG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHJlcXVlc3RJZCxcbiAgICAgIG5hbWUsXG4gICAgICBtb2RpZmllcjoge1xuICAgICAgICBpZCxcbiAgICAgICAgY2hhbm5lbDoge1xuICAgICAgICAgIG5hbWU6IGNoYW5uZWxOYW1lLFxuICAgICAgICAgIGlkICA6IGNoYW5uZWxJZCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvblJlcXVlc3RVcGRhdGUgKHJlcXVlc3RUeXBlLCByZXF1ZXN0SWQpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlJFUVVFU1RfVVBEQVRFLFxuICAgIGRhdGE6IHtcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgcmVxdWVzdElkLFxuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkUmVxdWVzdFRvUmVxdWVzdExpc3QgKGlkLCBlcnJvciwga2V5KSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5SRVFVRVNUX0xJU1RfQURELFxuICAgIGRhdGE6IHsgaWQsIGVycm9yLCBrZXkgfSxcbiAgfTtcbn07XG5cbi8vIGFzc2V0IGFjdGlvbnNcblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEFzc2V0VG9Bc3NldExpc3QgKGlkLCBlcnJvciwgbmFtZSwgY2xhaW1JZCwgc2hvcnRJZCwgY2xhaW1EYXRhKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5BU1NFVF9BREQsXG4gICAgZGF0YTogeyBpZCwgZXJyb3IsIG5hbWUsIGNsYWltSWQsIHNob3J0SWQsIGNsYWltRGF0YSB9LFxuICB9O1xufVxuXG4vLyBjaGFubmVsIGFjdGlvbnNcblxuZXhwb3J0IGZ1bmN0aW9uIGFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0IChpZCwgbmFtZSwgc2hvcnRJZCwgbG9uZ0lkLCBjbGFpbXNEYXRhKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5DSEFOTkVMX0FERCxcbiAgICBkYXRhOiB7IGlkLCBuYW1lLCBzaG9ydElkLCBsb25nSWQsIGNsYWltc0RhdGEgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvblVwZGF0ZUNoYW5uZWxDbGFpbXMgKGNoYW5uZWxLZXksIG5hbWUsIGxvbmdJZCwgcGFnZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DLFxuICAgIGRhdGE6IHtjaGFubmVsS2V5LCBuYW1lLCBsb25nSWQsIHBhZ2V9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUNoYW5uZWxDbGFpbXMgKGNoYW5uZWxMaXN0SWQsIGNsYWltc0RhdGEpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkNIQU5ORUxfQ0xBSU1TX1VQREFURV9TVUNDRVNTLFxuICAgIGRhdGE6IHtjaGFubmVsTGlzdElkLCBjbGFpbXNEYXRhfSxcbiAgfTtcbn07XG5cbi8vIGRpc3BsYXkgYSBmaWxlXG5cbmV4cG9ydCBmdW5jdGlvbiBmaWxlUmVxdWVzdGVkIChuYW1lLCBjbGFpbUlkKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5GSUxFX1JFUVVFU1RFRCxcbiAgICBkYXRhOiB7IG5hbWUsIGNsYWltSWQgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVGaWxlQXZhaWxhYmlsaXR5IChzdGF0dXMpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkZJTEVfQVZBSUxBQklMSVRZX1VQREFURSxcbiAgICBkYXRhOiBzdGF0dXMsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlRGlzcGxheUFzc2V0RXJyb3IgKGVycm9yKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5ESVNQTEFZX0FTU0VUX0VSUk9SLFxuICAgIGRhdGE6IGVycm9yLFxuICB9O1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2FjdGlvbnMvc2hvdy5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgSGVsbWV0IGZyb20gJ3JlYWN0LWhlbG1ldCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVQYWdlVGl0bGUgfSBmcm9tICd1dGlscy9wYWdlVGl0bGUnO1xuaW1wb3J0IHsgY3JlYXRlTWV0YVRhZ3MgfSBmcm9tICd1dGlscy9tZXRhVGFncyc7XG5pbXBvcnQgeyBjcmVhdGVDYW5vbmljYWxMaW5rIH0gZnJvbSAndXRpbHMvY2Fub25pY2FsTGluayc7XG5cbmNsYXNzIFNFTyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgbGV0IHsgcGFnZVRpdGxlLCBhc3NldCwgY2hhbm5lbCwgcGFnZVVyaSB9ID0gdGhpcy5wcm9wcztcbiAgICBwYWdlVGl0bGUgPSBjcmVhdGVQYWdlVGl0bGUocGFnZVRpdGxlKTtcbiAgICBjb25zdCBtZXRhVGFncyA9IGNyZWF0ZU1ldGFUYWdzKGFzc2V0LCBjaGFubmVsKTtcbiAgICBjb25zdCBjYW5vbmljYWxMaW5rID0gY3JlYXRlQ2Fub25pY2FsTGluayhhc3NldCwgY2hhbm5lbCwgcGFnZVVyaSk7XG4gICAgcmV0dXJuIChcbiAgICAgIDxIZWxtZXRcbiAgICAgICAgdGl0bGU9e3BhZ2VUaXRsZX1cbiAgICAgICAgbWV0YT17bWV0YVRhZ3N9XG4gICAgICAgIGxpbms9e1t7cmVsOiAnY2Fub25pY2FsJywgaHJlZjogY2Fub25pY2FsTGlua31dfVxuICAgICAgLz5cbiAgICApO1xuICB9XG59O1xuXG5TRU8ucHJvcFR5cGVzID0ge1xuICBwYWdlVGl0bGU6IFByb3BUeXBlcy5zdHJpbmcsXG4gIHBhZ2VVcmkgIDogUHJvcFR5cGVzLnN0cmluZyxcbiAgY2hhbm5lbCAgOiBQcm9wVHlwZXMub2JqZWN0LFxuICBhc3NldCAgICA6IFByb3BUeXBlcy5vYmplY3QsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBTRU87XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb21wb25lbnRzL1NFTy9pbmRleC5qc3giLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwcm9wLXR5cGVzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicHJvcC10eXBlc1wiXG4vLyBtb2R1bGUgaWQgPSA5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImltcG9ydCAnY3Jvc3MtZmV0Y2gvcG9seWZpbGwnO1xuXG4vKipcbiAqIFBhcnNlcyB0aGUgSlNPTiByZXR1cm5lZCBieSBhIG5ldHdvcmsgcmVxdWVzdFxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gcmVzcG9uc2UgQSByZXNwb25zZSBmcm9tIGEgbmV0d29yayByZXF1ZXN0XG4gKlxuICogQHJldHVybiB7b2JqZWN0fSAgICAgICAgICBUaGUgcGFyc2VkIEpTT04gZnJvbSB0aGUgcmVxdWVzdFxuICovXG5mdW5jdGlvbiBwYXJzZUpTT04gKHJlc3BvbnNlKSB7XG4gIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDIwNCB8fCByZXNwb25zZS5zdGF0dXMgPT09IDIwNSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiByZXNwb25zZS5qc29uKCk7XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBzdGF0dXMgcmV0dXJuZWQgYnkgYSBuZXR3b3JrIHJlcXVlc3RcbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IHJlc3BvbnNlICAgQSByZXNwb25zZSBmcm9tIGEgbmV0d29yayByZXF1ZXN0XG4gKiBAcGFyYW0gIHtvYmplY3R9IHJlc3BvbnNlICAgVGhlIHBhcnNlZCBKU09OIGZyb20gdGhlIG5ldHdvcmsgcmVxdWVzdFxuICpcbiAqIEByZXR1cm4ge29iamVjdCB8IHVuZGVmaW5lZH0gUmV0dXJucyBvYmplY3Qgd2l0aCBzdGF0dXMgYW5kIHN0YXR1c1RleHQsIG9yIHVuZGVmaW5lZFxuICovXG5mdW5jdGlvbiBjaGVja1N0YXR1cyAocmVzcG9uc2UsIGpzb25SZXNwb25zZSkge1xuICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDIwMCAmJiByZXNwb25zZS5zdGF0dXMgPCAzMDApIHtcbiAgICByZXR1cm4ganNvblJlc3BvbnNlO1xuICB9XG4gIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKGpzb25SZXNwb25zZS5tZXNzYWdlKTtcbiAgZXJyb3IucmVzcG9uc2UgPSByZXNwb25zZTtcbiAgdGhyb3cgZXJyb3I7XG59XG5cbi8qKlxuICogUmVxdWVzdHMgYSBVUkwsIHJldHVybmluZyBhIHByb21pc2VcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHVybCAgICAgICBUaGUgVVJMIHdlIHdhbnQgdG8gcmVxdWVzdFxuICogQHBhcmFtICB7b2JqZWN0fSBbb3B0aW9uc10gVGhlIG9wdGlvbnMgd2Ugd2FudCB0byBwYXNzIHRvIFwiZmV0Y2hcIlxuICpcbiAqIEByZXR1cm4ge29iamVjdH0gICAgICAgICAgIFRoZSByZXNwb25zZSBkYXRhXG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVxdWVzdCAodXJsLCBvcHRpb25zKSB7XG4gIHJldHVybiBmZXRjaCh1cmwsIG9wdGlvbnMpXG4gICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtyZXNwb25zZSwgcGFyc2VKU09OKHJlc3BvbnNlKV0pO1xuICAgIH0pXG4gICAgLnRoZW4oKFtyZXNwb25zZSwganNvblJlc3BvbnNlXSkgPT4ge1xuICAgICAgcmV0dXJuIGNoZWNrU3RhdHVzKHJlc3BvbnNlLCBqc29uUmVzcG9uc2UpO1xuICAgIH0pO1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvdXRpbHMvcmVxdWVzdC5qcyIsImNvbnN0IFNlcXVlbGl6ZSA9IHJlcXVpcmUoJ3NlcXVlbGl6ZScpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5jb25zb2xlLmxvZygnZXhwb3J0aW5nIHNlcXVlbGl6ZSBtb2RlbHMnKTtcbmNvbnN0IHsgZGF0YWJhc2UsIHVzZXJuYW1lLCBwYXNzd29yZCB9ID0gcmVxdWlyZSgnLi4vY29uZmlnL215c3FsQ29uZmlnJyk7XG5jb25zdCBkYiA9IHt9O1xuLy8gc2V0IHNlcXVlbGl6ZSBvcHRpb25zXG5jb25zdCBzZXF1ZWxpemUgPSBuZXcgU2VxdWVsaXplKGRhdGFiYXNlLCB1c2VybmFtZSwgcGFzc3dvcmQsIHtcbiAgaG9zdCAgICAgICAgICA6ICdsb2NhbGhvc3QnLFxuICBkaWFsZWN0ICAgICAgIDogJ215c3FsJyxcbiAgZGlhbGVjdE9wdGlvbnM6IHtkZWNpbWFsTnVtYmVyczogdHJ1ZX0sIC8vIGZpeCB0byBlbnN1cmUgREVDSU1BTCB3aWxsIG5vdCBiZSBzdG9yZWQgYXMgYSBzdHJpbmdcbiAgbG9nZ2luZyAgICAgICA6IGZhbHNlLFxuICBwb29sICAgICAgICAgIDoge1xuICAgIG1heCAgICA6IDUsXG4gICAgbWluICAgIDogMCxcbiAgICBpZGxlICAgOiAxMDAwMCxcbiAgICBhY3F1aXJlOiAxMDAwMCxcbiAgfSxcbn0pO1xuXG4vLyBlc3RhYmxpc2ggbXlzcWwgY29ubmVjdGlvblxuc2VxdWVsaXplXG4gIC5hdXRoZW50aWNhdGUoKVxuICAudGhlbigoKSA9PiB7XG4gICAgbG9nZ2VyLmluZm8oJ1NlcXVlbGl6ZSBoYXMgZXN0YWJsaXNoZWQgbXlzcWwgY29ubmVjdGlvbiBzdWNjZXNzZnVsbHkuJyk7XG4gIH0pXG4gIC5jYXRjaChlcnIgPT4ge1xuICAgIGxvZ2dlci5lcnJvcignU2VxdWVsaXplIHdhcyB1bmFibGUgdG8gY29ubmVjdCB0byB0aGUgZGF0YWJhc2U6JywgZXJyKTtcbiAgfSk7XG5cbi8vIG1hbnVhbGx5IGFkZCBlYWNoIG1vZGVsIHRvIHRoZSBkYiBvYmplY3RcbmNvbnN0IENlcnRpZmljYXRlID0gcmVxdWlyZSgnLi9jZXJ0aWZpY2F0ZS5qcycpO1xuY29uc3QgQ2hhbm5lbCA9IHJlcXVpcmUoJy4vY2hhbm5lbC5qcycpO1xuY29uc3QgQ2xhaW0gPSByZXF1aXJlKCcuL2NsYWltLmpzJyk7XG5jb25zdCBGaWxlID0gcmVxdWlyZSgnLi9maWxlLmpzJyk7XG5jb25zdCBSZXF1ZXN0ID0gcmVxdWlyZSgnLi9yZXF1ZXN0LmpzJyk7XG5jb25zdCBVc2VyID0gcmVxdWlyZSgnLi91c2VyLmpzJyk7XG5kYlsnQ2VydGlmaWNhdGUnXSA9IHNlcXVlbGl6ZS5pbXBvcnQoJ0NlcnRpZmljYXRlJywgQ2VydGlmaWNhdGUpO1xuZGJbJ0NoYW5uZWwnXSA9IHNlcXVlbGl6ZS5pbXBvcnQoJ0NoYW5uZWwnLCBDaGFubmVsKTtcbmRiWydDbGFpbSddID0gc2VxdWVsaXplLmltcG9ydCgnQ2xhaW0nLCBDbGFpbSk7XG5kYlsnRmlsZSddID0gc2VxdWVsaXplLmltcG9ydCgnRmlsZScsIEZpbGUpO1xuZGJbJ1JlcXVlc3QnXSA9IHNlcXVlbGl6ZS5pbXBvcnQoJ1JlcXVlc3QnLCBSZXF1ZXN0KTtcbmRiWydVc2VyJ10gPSBzZXF1ZWxpemUuaW1wb3J0KCdVc2VyJywgVXNlcik7XG5cbi8vIHJ1biBtb2RlbC5hc3NvY2lhdGlvbiBmb3IgZWFjaCBtb2RlbCBpbiB0aGUgZGIgb2JqZWN0IHRoYXQgaGFzIGFuIGFzc29jaWF0aW9uXG5PYmplY3Qua2V5cyhkYikuZm9yRWFjaChtb2RlbE5hbWUgPT4ge1xuICBpZiAoZGJbbW9kZWxOYW1lXS5hc3NvY2lhdGUpIHtcbiAgICBsb2dnZXIuaW5mbygnQXNzb2NpYXRpbmcgbW9kZWw6JywgbW9kZWxOYW1lKTtcbiAgICBkYlttb2RlbE5hbWVdLmFzc29jaWF0ZShkYik7XG4gIH1cbn0pO1xuXG5kYi5zZXF1ZWxpemUgPSBzZXF1ZWxpemU7XG5kYi5TZXF1ZWxpemUgPSBTZXF1ZWxpemU7XG5cbi8vIGFkZCBhbiAndXBzZXJ0JyBtZXRob2QgdG8gdGhlIGRiIG9iamVjdFxuZGIudXBzZXJ0ID0gKE1vZGVsLCB2YWx1ZXMsIGNvbmRpdGlvbiwgdGFibGVOYW1lKSA9PiB7XG4gIHJldHVybiBNb2RlbFxuICAgIC5maW5kT25lKHtcbiAgICAgIHdoZXJlOiBjb25kaXRpb24sXG4gICAgfSlcbiAgICAudGhlbihvYmogPT4ge1xuICAgICAgaWYgKG9iaikgeyAgLy8gdXBkYXRlXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgdXBkYXRpbmcgcmVjb3JkIGluIGRiLiR7dGFibGVOYW1lfWApO1xuICAgICAgICByZXR1cm4gb2JqLnVwZGF0ZSh2YWx1ZXMpO1xuICAgICAgfSBlbHNlIHsgIC8vIGluc2VydFxuICAgICAgICBsb2dnZXIuZGVidWcoYGNyZWF0aW5nIHJlY29yZCBpbiBkYi4ke3RhYmxlTmFtZX1gKTtcbiAgICAgICAgcmV0dXJuIE1vZGVsLmNyZWF0ZSh2YWx1ZXMpO1xuICAgICAgfVxuICAgIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGAke3RhYmxlTmFtZX0udXBzZXJ0IGVycm9yYCwgZXJyb3IpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRiO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vbW9kZWxzL2luZGV4LmpzIiwiLy8gcmVxdWVzdCBhY3Rpb25zXG5leHBvcnQgY29uc3QgSEFORExFX1NIT1dfVVJJID0gJ0hBTkRMRV9TSE9XX1VSSSc7XG5leHBvcnQgY29uc3QgUkVRVUVTVF9FUlJPUiA9ICdSRVFVRVNUX0VSUk9SJztcbmV4cG9ydCBjb25zdCBSRVFVRVNUX1VQREFURSA9ICdSRVFVRVNUX1VQREFURSc7XG5leHBvcnQgY29uc3QgQVNTRVRfUkVRVUVTVF9ORVcgPSAnQVNTRVRfUkVRVUVTVF9ORVcnO1xuZXhwb3J0IGNvbnN0IENIQU5ORUxfUkVRVUVTVF9ORVcgPSAnQ0hBTk5FTF9SRVFVRVNUX05FVyc7XG5leHBvcnQgY29uc3QgUkVRVUVTVF9MSVNUX0FERCA9ICdSRVFVRVNUX0xJU1RfQUREJztcblxuLy8gYXNzZXQgYWN0aW9uc1xuZXhwb3J0IGNvbnN0IEFTU0VUX0FERCA9IGBBU1NFVF9BRERgO1xuXG4vLyBjaGFubmVsIGFjdGlvbnNcbmV4cG9ydCBjb25zdCBDSEFOTkVMX0FERCA9ICdDSEFOTkVMX0FERCc7XG5cbmV4cG9ydCBjb25zdCBDSEFOTkVMX0NMQUlNU19VUERBVEVfQVNZTkMgPSAnQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DJztcbmV4cG9ydCBjb25zdCBDSEFOTkVMX0NMQUlNU19VUERBVEVfU1VDQ0VTUyA9ICdDSEFOTkVMX0NMQUlNU19VUERBVEVfU1VDQ0VTUyc7XG5cbi8vIGFzc2V0L2ZpbGUgZGlzcGxheSBhY3Rpb25zXG5leHBvcnQgY29uc3QgRklMRV9SRVFVRVNURUQgPSAnRklMRV9SRVFVRVNURUQnO1xuZXhwb3J0IGNvbnN0IEZJTEVfQVZBSUxBQklMSVRZX1VQREFURSA9ICdGSUxFX0FWQUlMQUJJTElUWV9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IERJU1BMQVlfQVNTRVRfRVJST1IgPSAnRElTUExBWV9BU1NFVF9FUlJPUic7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb25zdGFudHMvc2hvd19hY3Rpb25fdHlwZXMuanMiLCJleHBvcnQgY29uc3Qgc2VsZWN0QXNzZXQgPSAoc2hvdykgPT4ge1xuICBjb25zdCByZXF1ZXN0ID0gc2hvdy5yZXF1ZXN0TGlzdFtzaG93LnJlcXVlc3QuaWRdO1xuICBjb25zdCBhc3NldEtleSA9IHJlcXVlc3Qua2V5O1xuICByZXR1cm4gc2hvdy5hc3NldExpc3RbYXNzZXRLZXldO1xufTtcblxuZXhwb3J0IGNvbnN0IHNlbGVjdFNob3dTdGF0ZSA9IChzdGF0ZSkgPT4ge1xuICByZXR1cm4gc3RhdGUuc2hvdztcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9zZWxlY3RvcnMvc2hvdy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LWhlbG1ldFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWhlbG1ldFwiXG4vLyBtb2R1bGUgaWQgPSAxNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWR1eC1zYWdhL2VmZmVjdHNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWR1eC1zYWdhL2VmZmVjdHNcIlxuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgYXhpb3MgPSByZXF1aXJlKCdheGlvcycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyBhcGk6IHsgYXBpSG9zdCwgYXBpUG9ydCB9IH0gPSByZXF1aXJlKCcuLi9jb25maWcvbGJyeUNvbmZpZy5qcycpO1xuY29uc3QgbGJyeUFwaVVyaSA9ICdodHRwOi8vJyArIGFwaUhvc3QgKyAnOicgKyBhcGlQb3J0O1xuY29uc3QgeyBjaG9vc2VHYUxicnluZXRQdWJsaXNoTGFiZWwsIHNlbmRHQVRpbWluZ0V2ZW50IH0gPSByZXF1aXJlKCcuL2dvb2dsZUFuYWx5dGljcy5qcycpO1xuXG5jb25zdCBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UgPSAoeyBkYXRhIH0sIHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICBsb2dnZXIuZGVidWcoJ2xicnkgYXBpIGRhdGE6JywgZGF0YSk7XG4gIGlmIChkYXRhLnJlc3VsdCkge1xuICAgIC8vIGNoZWNrIGZvciBhbiBlcnJvclxuICAgIGlmIChkYXRhLnJlc3VsdC5lcnJvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdMYnJ5bmV0IGFwaSBlcnJvcjonLCBkYXRhLnJlc3VsdC5lcnJvcik7XG4gICAgICByZWplY3QobmV3IEVycm9yKGRhdGEucmVzdWx0LmVycm9yKSk7XG4gICAgICByZXR1cm47XG4gICAgfTtcbiAgICByZXNvbHZlKGRhdGEucmVzdWx0KTtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gZmFsbGJhY2sgaW4gY2FzZSBpdCBqdXN0IHRpbWVkIG91dFxuICByZWplY3QoSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHB1Ymxpc2hDbGFpbSAocHVibGlzaFBhcmFtcykge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBQdWJsaXNoaW5nIGNsYWltIHRvIFwiJHtwdWJsaXNoUGFyYW1zLm5hbWV9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdwdWJsaXNoJyxcbiAgICAgICAgICBwYXJhbXM6IHB1Ymxpc2hQYXJhbXMsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdwdWJsaXNoJywgY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsKHB1Ymxpc2hQYXJhbXMpLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDbGFpbSAodXJpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBsYnJ5QXBpID4+IEdldHRpbmcgQ2xhaW0gZm9yIFwiJHt1cml9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdnZXQnLFxuICAgICAgICAgIHBhcmFtczogeyB1cmksIHRpbWVvdXQ6IDIwIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdnZXRDbGFpbScsICdHRVQnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDbGFpbUxpc3QgKGNsYWltTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBHZXR0aW5nIGNsYWltX2xpc3QgZm9yIFwiJHtjbGFpbU5hbWV9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdjbGFpbV9saXN0JyxcbiAgICAgICAgICBwYXJhbXM6IHsgbmFtZTogY2xhaW1OYW1lIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdnZXRDbGFpbUxpc3QnLCAnQ0xBSU1fTElTVCcsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgICAgICBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UocmVzcG9uc2UsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIHJlc29sdmVVcmkgKHVyaSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBSZXNvbHZpbmcgVVJJIGZvciBcIiR7dXJpfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAncmVzb2x2ZScsXG4gICAgICAgICAgcGFyYW1zOiB7IHVyaSB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbigoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdyZXNvbHZlVXJpJywgJ1JFU09MVkUnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaWYgKGRhdGEucmVzdWx0W3VyaV0uZXJyb3IpIHsgIC8vIGNoZWNrIGZvciBlcnJvcnNcbiAgICAgICAgICAgIHJlamVjdChkYXRhLnJlc3VsdFt1cmldLmVycm9yKTtcbiAgICAgICAgICB9IGVsc2UgeyAgLy8gaWYgbm8gZXJyb3JzLCByZXNvbHZlXG4gICAgICAgICAgICByZXNvbHZlKGRhdGEucmVzdWx0W3VyaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0RG93bmxvYWREaXJlY3RvcnkgKCkge1xuICAgIGxvZ2dlci5kZWJ1ZygnbGJyeUFwaSA+PiBSZXRyaWV2aW5nIHRoZSBkb3dubG9hZCBkaXJlY3RvcnkgcGF0aCBmcm9tIGxicnkgZGFlbW9uLi4uJyk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnc2V0dGluZ3NfZ2V0JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHsgZGF0YSB9KSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnZ2V0RG93bmxvYWREaXJlY3RvcnknLCAnU0VUVElOR1NfR0VUJywgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGlmIChkYXRhLnJlc3VsdCkge1xuICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnJlc3VsdC5kb3dubG9hZF9kaXJlY3RvcnkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKCdTdWNjZXNzZnVsbHkgY29ubmVjdGVkIHRvIGxicnkgZGFlbW9uLCBidXQgdW5hYmxlIHRvIHJldHJpZXZlIHRoZSBkb3dubG9hZCBkaXJlY3RvcnkuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignTGJyeW5ldCBFcnJvcjonLCBlcnJvcik7XG4gICAgICAgICAgcmVzb2x2ZSgnL2hvbWUvbGJyeS9Eb3dubG9hZHMvJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBjcmVhdGVDaGFubmVsIChuYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBsYnJ5QXBpID4+IENyZWF0aW5nIGNoYW5uZWwgZm9yICR7bmFtZX0uLi5gKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdjaGFubmVsX25ldycsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBjaGFubmVsX25hbWU6IG5hbWUsXG4gICAgICAgICAgICBhbW91bnQgICAgICA6IDAuMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnY3JlYXRlQ2hhbm5lbCcsICdDSEFOTkVMX05FVycsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgICAgICBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UocmVzcG9uc2UsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vaGVscGVycy9sYnJ5QXBpLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgdWEgPSByZXF1aXJlKCd1bml2ZXJzYWwtYW5hbHl0aWNzJyk7XG5jb25zdCB7IGFuYWx5dGljcyA6IHsgZ29vZ2xlSWQgfSwgc2l0ZTogeyBuYW1lOiBzaXRlTmFtZSB9IH0gPSByZXF1aXJlKCcuLi9jb25maWcvc3BlZWNoQ29uZmlnLmpzJyk7XG5cbmZ1bmN0aW9uIGNyZWF0ZVNlcnZlRXZlbnRQYXJhbXMgKGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCkge1xuICByZXR1cm4ge1xuICAgIGV2ZW50Q2F0ZWdvcnkgICAgOiAnY2xpZW50IHJlcXVlc3RzJyxcbiAgICBldmVudEFjdGlvbiAgICAgIDogJ3NlcnZlIHJlcXVlc3QnLFxuICAgIGV2ZW50TGFiZWwgICAgICAgOiBvcmlnaW5hbFVybCxcbiAgICBpcE92ZXJyaWRlICAgICAgIDogaXAsXG4gICAgdXNlckFnZW50T3ZlcnJpZGU6IGhlYWRlcnNbJ3VzZXItYWdlbnQnXSxcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZVB1Ymxpc2hUaW1pbmdFdmVudFBhcmFtcyAoY2F0ZWdvcnksIHZhcmlhYmxlLCBsYWJlbCwgc3RhcnRUaW1lLCBlbmRUaW1lKSB7XG4gIGNvbnN0IGR1cmF0aW9uID0gZW5kVGltZSAtIHN0YXJ0VGltZTtcbiAgcmV0dXJuIHtcbiAgICB1c2VyVGltaW5nQ2F0ZWdvcnkgICAgOiBjYXRlZ29yeSxcbiAgICB1c2VyVGltaW5nVmFyaWFibGVOYW1lOiB2YXJpYWJsZSxcbiAgICB1c2VyVGltaW5nVGltZSAgICAgICAgOiBkdXJhdGlvbixcbiAgICB1c2VyVGltaW5nTGFiZWwgICAgICAgOiBsYWJlbCxcbiAgfTtcbn07XG5cbmZ1bmN0aW9uIHNlbmRHb29nbGVBbmFseXRpY3NFdmVudCAoaXAsIHBhcmFtcykge1xuICBjb25zdCB2aXNpdG9ySWQgPSBpcC5yZXBsYWNlKC9cXC4vZywgJy0nKTtcbiAgY29uc3QgdmlzaXRvciA9IHVhKGdvb2dsZUlkLCB2aXNpdG9ySWQsIHsgc3RyaWN0Q2lkRm9ybWF0OiBmYWxzZSwgaHR0cHM6IHRydWUgfSk7XG4gIHZpc2l0b3IuZXZlbnQocGFyYW1zLCAoZXJyKSA9PiB7XG4gICAgaWYgKGVycikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdHb29nbGUgQW5hbHl0aWNzIEV2ZW50IEVycm9yID4+JywgZXJyKTtcbiAgICB9XG4gIH0pO1xufTtcblxuZnVuY3Rpb24gc2VuZEdvb2dsZUFuYWx5dGljc1RpbWluZyAodmlzaXRvcklkLCBwYXJhbXMpIHtcbiAgY29uc3QgdmlzaXRvciA9IHVhKGdvb2dsZUlkLCB2aXNpdG9ySWQsIHsgc3RyaWN0Q2lkRm9ybWF0OiBmYWxzZSwgaHR0cHM6IHRydWUgfSk7XG4gIHZpc2l0b3IudGltaW5nKHBhcmFtcywgKGVycikgPT4ge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignR29vZ2xlIEFuYWx5dGljcyBFdmVudCBFcnJvciA+PicsIGVycik7XG4gICAgfVxuICAgIGxvZ2dlci5kZWJ1ZyhgVGltaW5nIGV2ZW50IHN1Y2Nlc3NmdWxseSBzZW50IHRvIGdvb2dsZSBhbmFseXRpY3NgKTtcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2VuZEdBU2VydmVFdmVudCAoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKSB7XG4gICAgY29uc3QgcGFyYW1zID0gY3JlYXRlU2VydmVFdmVudFBhcmFtcyhoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwpO1xuICAgIHNlbmRHb29nbGVBbmFseXRpY3NFdmVudChpcCwgcGFyYW1zKTtcbiAgfSxcbiAgc2VuZEdBVGltaW5nRXZlbnQgKGNhdGVnb3J5LCB2YXJpYWJsZSwgbGFiZWwsIHN0YXJ0VGltZSwgZW5kVGltZSkge1xuICAgIGNvbnN0IHBhcmFtcyA9IGNyZWF0ZVB1Ymxpc2hUaW1pbmdFdmVudFBhcmFtcyhjYXRlZ29yeSwgdmFyaWFibGUsIGxhYmVsLCBzdGFydFRpbWUsIGVuZFRpbWUpO1xuICAgIHNlbmRHb29nbGVBbmFseXRpY3NUaW1pbmcoc2l0ZU5hbWUsIHBhcmFtcyk7XG4gIH0sXG4gIGNob29zZUdhTGJyeW5ldFB1Ymxpc2hMYWJlbCAoeyBjaGFubmVsX25hbWU6IGNoYW5uZWxOYW1lLCBjaGFubmVsX2lkOiBjaGFubmVsSWQgfSkge1xuICAgIHJldHVybiAoY2hhbm5lbE5hbWUgfHwgY2hhbm5lbElkID8gJ1BVQkxJU0hfSU5fQ0hBTk5FTF9DTEFJTScgOiAnUFVCTElTSF9BTk9OWU1PVVNfQ0xBSU0nKTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9oZWxwZXJzL2dvb2dsZUFuYWx5dGljcy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlZHV4XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVkdXhcIlxuLy8gbW9kdWxlIGlkID0gMThcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvY2hhbm5lbF9hY3Rpb25fdHlwZXMnO1xuXG4vLyBleHBvcnQgYWN0aW9uIGNyZWF0b3JzXG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVMb2dnZWRJbkNoYW5uZWwgKG5hbWUsIHNob3J0SWQsIGxvbmdJZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0hBTk5FTF9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgbmFtZSxcbiAgICAgIHNob3J0SWQsXG4gICAgICBsb25nSWQsXG4gICAgfSxcbiAgfTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9hY3Rpb25zL2NoYW5uZWwuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBBY3RpdmVTdGF0dXNCYXIgZnJvbSAnY29tcG9uZW50cy9BY3RpdmVTdGF0dXNCYXInO1xuaW1wb3J0IEluYWN0aXZlU3RhdHVzQmFyIGZyb20gJ2NvbXBvbmVudHMvSW5hY3RpdmVTdGF0dXNCYXInO1xuXG5jbGFzcyBQcm9ncmVzc0JhciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgYmFycyAgICAgICA6IFtdLFxuICAgICAgaW5kZXggICAgICA6IDAsXG4gICAgICBpbmNyZW1lbnRlcjogMSxcbiAgICB9O1xuICAgIHRoaXMuY3JlYXRlQmFycyA9IHRoaXMuY3JlYXRlQmFycy5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc3RhcnRQcm9ncmVzc0JhciA9IHRoaXMuc3RhcnRQcm9ncmVzc0Jhci5iaW5kKHRoaXMpO1xuICAgIHRoaXMudXBkYXRlUHJvZ3Jlc3NCYXIgPSB0aGlzLnVwZGF0ZVByb2dyZXNzQmFyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5zdG9wUHJvZ3Jlc3NCYXIgPSB0aGlzLnN0b3BQcm9ncmVzc0Jhci5iaW5kKHRoaXMpO1xuICB9XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLmNyZWF0ZUJhcnMoKTtcbiAgICB0aGlzLnN0YXJ0UHJvZ3Jlc3NCYXIoKTtcbiAgfVxuICBjb21wb25lbnRXaWxsVW5tb3VudCAoKSB7XG4gICAgdGhpcy5zdG9wUHJvZ3Jlc3NCYXIoKTtcbiAgfVxuICBjcmVhdGVCYXJzICgpIHtcbiAgICBjb25zdCBiYXJzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gdGhpcy5wcm9wcy5zaXplOyBpKyspIHtcbiAgICAgIGJhcnMucHVzaCh7aXNBY3RpdmU6IGZhbHNlfSk7XG4gICAgfVxuICAgIHRoaXMuc2V0U3RhdGUoeyBiYXJzIH0pO1xuICB9XG4gIHN0YXJ0UHJvZ3Jlc3NCYXIgKCkge1xuICAgIHRoaXMudXBkYXRlSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCh0aGlzLnVwZGF0ZVByb2dyZXNzQmFyLmJpbmQodGhpcyksIDMwMCk7XG4gIH07XG4gIHVwZGF0ZVByb2dyZXNzQmFyICgpIHtcbiAgICBsZXQgaW5kZXggPSB0aGlzLnN0YXRlLmluZGV4O1xuICAgIGxldCBpbmNyZW1lbnRlciA9IHRoaXMuc3RhdGUuaW5jcmVtZW50ZXI7XG4gICAgbGV0IGJhcnMgPSB0aGlzLnN0YXRlLmJhcnM7XG4gICAgLy8gZmxpcCBpbmNyZW1lbnRlciBpZiBuZWNlc3NhcnksIHRvIHN0YXkgaW4gYm91bmRzXG4gICAgaWYgKChpbmRleCA8IDApIHx8IChpbmRleCA+IHRoaXMucHJvcHMuc2l6ZSkpIHtcbiAgICAgIGluY3JlbWVudGVyID0gaW5jcmVtZW50ZXIgKiAtMTtcbiAgICAgIGluZGV4ICs9IGluY3JlbWVudGVyO1xuICAgIH1cbiAgICAvLyB1cGRhdGUgdGhlIGluZGV4ZWQgYmFyXG4gICAgaWYgKGluY3JlbWVudGVyID4gMCkge1xuICAgICAgYmFyc1tpbmRleF0uaXNBY3RpdmUgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBiYXJzW2luZGV4XS5pc0FjdGl2ZSA9IGZhbHNlO1xuICAgIH07XG4gICAgLy8gaW5jcmVtZW50IGluZGV4XG4gICAgaW5kZXggKz0gaW5jcmVtZW50ZXI7XG4gICAgLy8gdXBkYXRlIHN0YXRlXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBiYXJzLFxuICAgICAgaW5jcmVtZW50ZXIsXG4gICAgICBpbmRleCxcbiAgICB9KTtcbiAgfTtcbiAgc3RvcFByb2dyZXNzQmFyICgpIHtcbiAgICBjbGVhckludGVydmFsKHRoaXMudXBkYXRlSW50ZXJ2YWwpO1xuICB9O1xuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICB7dGhpcy5zdGF0ZS5iYXJzLm1hcCgoYmFyLCBpbmRleCkgPT4gYmFyLmlzQWN0aXZlID8gPEFjdGl2ZVN0YXR1c0JhciBrZXk9e2luZGV4fSAvPiA6IDxJbmFjdGl2ZVN0YXR1c0JhciBrZXk9e2luZGV4fS8+KX1cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cblByb2dyZXNzQmFyLnByb3BUeXBlcyA9IHtcbiAgc2l6ZTogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgUHJvZ3Jlc3NCYXI7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb21wb25lbnRzL1Byb2dyZXNzQmFyL2luZGV4LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IE5hdkJhciBmcm9tICdjb250YWluZXJzL05hdkJhcic7XG5cbmNsYXNzIEVycm9yUGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBlcnJvciB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICA8cD57ZXJyb3J9PC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbkVycm9yUGFnZS5wcm9wVHlwZXMgPSB7XG4gIGVycm9yOiBQcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBFcnJvclBhZ2U7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb21wb25lbnRzL0Vycm9yUGFnZS9pbmRleC5qc3giLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXNzcG9ydFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInBhc3Nwb3J0XCJcbi8vIG1vZHVsZSBpZCA9IDIyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImZ1bmN0aW9uIE15c3FsQ29uZmlnICgpIHtcclxuICB0aGlzLmRhdGFiYXNlID0gJ2RlZmF1bHQnO1xyXG4gIHRoaXMudXNlcm5hbWUgPSAnZGVmYXVsdCc7XHJcbiAgdGhpcy5wYXNzd29yZCA9ICdkZWZhdWx0JztcclxuICB0aGlzLmNvbmZpZ3VyZSA9ICh7ZGF0YWJhc2UsIHVzZXJuYW1lLCBwYXNzd29yZH0pID0+IHtcclxuICAgIGlmIChkYXRhYmFzZSkgdGhpcy5kYXRhYmFzZSA9IGRhdGFiYXNlO1xyXG4gICAgaWYgKHVzZXJuYW1lKSB0aGlzLnVzZXJuYW1lID0gdXNlcm5hbWU7XHJcbiAgICBpZiAocGFzc3dvcmQpIHRoaXMucGFzc3dvcmQgPSBwYXNzd29yZDtcclxuICB9O1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBuZXcgTXlzcWxDb25maWcoKTtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY29uZmlnL215c3FsQ29uZmlnLmpzIiwiZnVuY3Rpb24gU2xhY2tDb25maWcgKCkge1xuICB0aGlzLnNsYWNrV2ViSG9vayAgICAgID0gJ2RlZmF1bHQnO1xuICB0aGlzLnNsYWNrRXJyb3JDaGFubmVsID0gJ2RlZmF1bHQnO1xuICB0aGlzLnNsYWNrSW5mb0NoYW5uZWwgID0gJ2RlZmF1bHQnO1xuICB0aGlzLmNvbmZpZ3VyZSA9ICh7c2xhY2tXZWJIb29rLCBzbGFja0Vycm9yQ2hhbm5lbCwgc2xhY2tJbmZvQ2hhbm5lbH0pID0+IHtcbiAgICBpZiAoc2xhY2tXZWJIb29rKSB0aGlzLnNsYWNrV2ViSG9vayA9IHNsYWNrV2ViSG9vaztcbiAgICBpZiAoc2xhY2tFcnJvckNoYW5uZWwpIHRoaXMuc2xhY2tFcnJvckNoYW5uZWwgPSBzbGFja0Vycm9yQ2hhbm5lbDtcbiAgICBpZiAoc2xhY2tJbmZvQ2hhbm5lbCkgdGhpcy5zbGFja0luZm9DaGFubmVsID0gc2xhY2tJbmZvQ2hhbm5lbDtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNsYWNrQ29uZmlnKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvc2xhY2tDb25maWcuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXNzcG9ydC1sb2NhbFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInBhc3Nwb3J0LWxvY2FsXCJcbi8vIG1vZHVsZSBpZCA9IDI1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0ge1xuICByZXR1cm5TaG9ydElkOiBmdW5jdGlvbiAoY2xhaW1zQXJyYXksIGxvbmdJZCkge1xuICAgIGxldCBjbGFpbUluZGV4O1xuICAgIGxldCBzaG9ydElkID0gbG9uZ0lkLnN1YnN0cmluZygwLCAxKTsgLy8gZGVmYXVsdCBzaG9ydCBpZCBpcyB0aGUgZmlyc3QgbGV0dGVyXG4gICAgbGV0IHNob3J0SWRMZW5ndGggPSAwO1xuICAgIC8vIGZpbmQgdGhlIGluZGV4IG9mIHRoaXMgY2xhaW0gaWRcbiAgICBjbGFpbUluZGV4ID0gY2xhaW1zQXJyYXkuZmluZEluZGV4KGVsZW1lbnQgPT4ge1xuICAgICAgcmV0dXJuIGVsZW1lbnQuY2xhaW1JZCA9PT0gbG9uZ0lkO1xuICAgIH0pO1xuICAgIGlmIChjbGFpbUluZGV4IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjbGFpbSBpZCBub3QgZm91bmQgaW4gY2xhaW1zIGxpc3QnKTtcbiAgICB9XG4gICAgLy8gZ2V0IGFuIGFycmF5IG9mIGFsbCBjbGFpbXMgd2l0aCBsb3dlciBoZWlnaHRcbiAgICBsZXQgcG9zc2libGVNYXRjaGVzID0gY2xhaW1zQXJyYXkuc2xpY2UoMCwgY2xhaW1JbmRleCk7XG4gICAgLy8gcmVtb3ZlIGNlcnRpZmljYXRlcyB3aXRoIHRoZSBzYW1lIHByZWZpeGVzIHVudGlsIG5vbmUgYXJlIGxlZnQuXG4gICAgd2hpbGUgKHBvc3NpYmxlTWF0Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICBzaG9ydElkTGVuZ3RoICs9IDE7XG4gICAgICBzaG9ydElkID0gbG9uZ0lkLnN1YnN0cmluZygwLCBzaG9ydElkTGVuZ3RoKTtcbiAgICAgIHBvc3NpYmxlTWF0Y2hlcyA9IHBvc3NpYmxlTWF0Y2hlcy5maWx0ZXIoZWxlbWVudCA9PiB7XG4gICAgICAgIHJldHVybiAoZWxlbWVudC5jbGFpbUlkICYmIChlbGVtZW50LmNsYWltSWQuc3Vic3RyaW5nKDAsIHNob3J0SWRMZW5ndGgpID09PSBzaG9ydElkKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHNob3J0SWQ7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vaGVscGVycy9zZXF1ZWxpemVIZWxwZXJzLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgZnMgPSByZXF1aXJlKCdmcycpO1xuY29uc3QgeyBzaXRlLCB3YWxsZXQsIHB1Ymxpc2ggfSA9IHJlcXVpcmUoJy4uL2NvbmZpZy9zcGVlY2hDb25maWcuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5ICh7bmFtZSwgbnNmdywgbGljZW5zZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCB0aHVtYm5haWx9KSB7XG4gICAgLy8gdmFsaWRhdGUgbmFtZVxuICAgIGlmICghbmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBuYW1lIGZpZWxkIGZvdW5kIGluIHJlcXVlc3QnKTtcbiAgICB9XG4gICAgY29uc3QgaW52YWxpZE5hbWVDaGFyYWN0ZXJzID0gL1teQS1aYS16MC05LC1dLy5leGVjKG5hbWUpO1xuICAgIGlmIChpbnZhbGlkTmFtZUNoYXJhY3RlcnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNsYWltIG5hbWUgeW91IHByb3ZpZGVkIGlzIG5vdCBhbGxvd2VkLiAgT25seSB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnMgYXJlIGFsbG93ZWQ6IEEtWiwgYS16LCAwLTksIGFuZCBcIi1cIicpO1xuICAgIH1cbiAgICAvLyBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgbnNmdyA9IChuc2Z3ID09PSAndHJ1ZScpO1xuICAgIGxpY2Vuc2UgPSBsaWNlbnNlIHx8IG51bGw7XG4gICAgdGl0bGUgPSB0aXRsZSB8fCBudWxsO1xuICAgIGRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24gfHwgbnVsbDtcbiAgICB0aHVtYm5haWwgPSB0aHVtYm5haWwgfHwgbnVsbDtcbiAgICAvLyByZXR1cm4gcmVzdWx0c1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lLFxuICAgICAgbnNmdyxcbiAgICAgIGxpY2Vuc2UsXG4gICAgICB0aXRsZSxcbiAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgdGh1bWJuYWlsLFxuICAgIH07XG4gIH0sXG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyAoe2ZpbGUsIHRodW1ibmFpbH0pIHtcbiAgICAvLyBtYWtlIHN1cmUgYSBmaWxlIHdhcyBwcm92aWRlZFxuICAgIGlmICghZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHdpdGgga2V5IG9mIFtmaWxlXSBmb3VuZCBpbiByZXF1ZXN0Jyk7XG4gICAgfVxuICAgIGlmICghZmlsZS5wYXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGZpbGUgcGF0aCBmb3VuZCcpO1xuICAgIH1cbiAgICBpZiAoIWZpbGUudHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHR5cGUgZm91bmQnKTtcbiAgICB9XG4gICAgaWYgKCFmaWxlLnNpemUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gZmlsZSB0eXBlIGZvdW5kJyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHRoZSBmaWxlIG5hbWVcbiAgICBpZiAoLycvLnRlc3QoZmlsZS5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcG9zdHJvcGhlcyBhcmUgbm90IGFsbG93ZWQgaW4gdGhlIGZpbGUgbmFtZScpO1xuICAgIH1cbiAgICAvLyB2YWxpZGF0ZSB0aGUgZmlsZVxuICAgIG1vZHVsZS5leHBvcnRzLnZhbGlkYXRlRmlsZVR5cGVBbmRTaXplKGZpbGUpO1xuICAgIC8vIHJldHVybiByZXN1bHRzXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbGVOYW1lICAgICAgICAgOiBmaWxlLm5hbWUsXG4gICAgICBmaWxlUGF0aCAgICAgICAgIDogZmlsZS5wYXRoLFxuICAgICAgZmlsZVR5cGUgICAgICAgICA6IGZpbGUudHlwZSxcbiAgICAgIHRodW1ibmFpbEZpbGVOYW1lOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLm5hbWUgOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVQYXRoOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnBhdGggOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVUeXBlOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnR5cGUgOiBudWxsKSxcbiAgICB9O1xuICB9LFxuICB2YWxpZGF0ZUZpbGVUeXBlQW5kU2l6ZSAoZmlsZSkge1xuICAgIC8vIGNoZWNrIGZpbGUgdHlwZSBhbmQgc2l6ZVxuICAgIHN3aXRjaCAoZmlsZS50eXBlKSB7XG4gICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICBpZiAoZmlsZS5zaXplID4gMTAwMDAwMDApIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ3B1Ymxpc2ggPiBmaWxlIHZhbGlkYXRpb24gPiAuanBlZy8uanBnLy5wbmcgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCBpbWFnZXMgYXJlIGxpbWl0ZWQgdG8gMTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gLmdpZiB3YXMgdG9vIGJpZycpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU29ycnksIC5naWZzIGFyZSBsaW1pdGVkIHRvIDUwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgIGlmIChmaWxlLnNpemUgPiA1MDAwMDAwMCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygncHVibGlzaCA+IGZpbGUgdmFsaWRhdGlvbiA+IC5tcDQgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCB2aWRlb3MgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gdW5yZWNvZ25pemVkIGZpbGUgdHlwZScpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSAnICsgZmlsZS50eXBlICsgJyBjb250ZW50IHR5cGUgaXMgbm90IHN1cHBvcnRlZC4gIE9ubHksIC5qcGVnLCAucG5nLCAuZ2lmLCBhbmQgLm1wNCBmaWxlcyBhcmUgY3VycmVudGx5IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0sXG4gIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcyAoZmlsZVBhdGgsIG5hbWUsIHRpdGxlLCBkZXNjcmlwdGlvbiwgbGljZW5zZSwgbnNmdywgdGh1bWJuYWlsKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBQdWJsaXNoIFBhcmFtZXRlcnNgKTtcbiAgICAvLyBwcm92aWRlIGRlZmF1bHRzIGZvciB0aXRsZVxuICAgIGlmICh0aXRsZSA9PT0gbnVsbCB8fCB0aXRsZS50cmltKCkgPT09ICcnKSB7XG4gICAgICB0aXRsZSA9IG5hbWU7XG4gICAgfVxuICAgIC8vIHByb3ZpZGUgZGVmYXVsdCBmb3IgZGVzY3JpcHRpb25cbiAgICBpZiAoZGVzY3JpcHRpb24gPT09IG51bGwgfHwgZGVzY3JpcHRpb24udHJpbSgpID09PSAnJykge1xuICAgICAgZGVzY3JpcHRpb24gPSAnJztcbiAgICB9XG4gICAgLy8gcHJvdmlkZSBkZWZhdWx0IGZvciBsaWNlbnNlXG4gICAgaWYgKGxpY2Vuc2UgPT09IG51bGwgfHwgbGljZW5zZS50cmltKCkgPT09ICcnKSB7XG4gICAgICBsaWNlbnNlID0gJyAnOyAgLy8gZGVmYXVsdCB0byBlbXB0eSBzdHJpbmdcbiAgICB9XG4gICAgLy8gY3JlYXRlIHRoZSBwdWJsaXNoIHBhcmFtc1xuICAgIGNvbnN0IHB1Ymxpc2hQYXJhbXMgPSB7XG4gICAgICBuYW1lLFxuICAgICAgZmlsZV9wYXRoOiBmaWxlUGF0aCxcbiAgICAgIGJpZCAgICAgIDogMC4wMSxcbiAgICAgIG1ldGFkYXRhIDoge1xuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGF1dGhvciAgOiBzaXRlLnRpdGxlLFxuICAgICAgICBsYW5ndWFnZTogJ2VuJyxcbiAgICAgICAgbGljZW5zZSxcbiAgICAgICAgbnNmdyxcbiAgICAgIH0sXG4gICAgICBjbGFpbV9hZGRyZXNzOiB3YWxsZXQubGJyeUNsYWltQWRkcmVzcyxcbiAgICB9O1xuICAgIC8vIGFkZCB0aHVtYm5haWwgdG8gY2hhbm5lbCBpZiB2aWRlb1xuICAgIGlmICh0aHVtYm5haWwpIHtcbiAgICAgIHB1Ymxpc2hQYXJhbXNbJ21ldGFkYXRhJ11bJ3RodW1ibmFpbCddID0gdGh1bWJuYWlsO1xuICAgIH1cbiAgICByZXR1cm4gcHVibGlzaFBhcmFtcztcbiAgfSxcbiAgY3JlYXRlVGh1bWJuYWlsUHVibGlzaFBhcmFtcyAodGh1bWJuYWlsRmlsZVBhdGgsIGNsYWltTmFtZSwgbGljZW5zZSwgbnNmdykge1xuICAgIGlmICghdGh1bWJuYWlsRmlsZVBhdGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBUaHVtYm5haWwgUHVibGlzaCBQYXJhbWV0ZXJzYCk7XG4gICAgLy8gY3JlYXRlIHRoZSBwdWJsaXNoIHBhcmFtc1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lICAgICA6IGAke2NsYWltTmFtZX0tdGh1bWJgLFxuICAgICAgZmlsZV9wYXRoOiB0aHVtYm5haWxGaWxlUGF0aCxcbiAgICAgIGJpZCAgICAgIDogMC4wMSxcbiAgICAgIG1ldGFkYXRhIDoge1xuICAgICAgICB0aXRsZSAgICAgIDogYCR7Y2xhaW1OYW1lfSB0aHVtYm5haWxgLFxuICAgICAgICBkZXNjcmlwdGlvbjogYGEgdGh1bWJuYWlsIGZvciAke2NsYWltTmFtZX1gLFxuICAgICAgICBhdXRob3IgICAgIDogc2l0ZS50aXRsZSxcbiAgICAgICAgbGFuZ3VhZ2UgICA6ICdlbicsXG4gICAgICAgIGxpY2Vuc2UsXG4gICAgICAgIG5zZncsXG4gICAgICB9LFxuICAgICAgY2xhaW1fYWRkcmVzczogd2FsbGV0LmxicnlDbGFpbUFkZHJlc3MsXG4gICAgICBjaGFubmVsX25hbWUgOiBwdWJsaXNoLnRodW1ibmFpbENoYW5uZWwsXG4gICAgICBjaGFubmVsX2lkICAgOiBwdWJsaXNoLnRodW1ibmFpbENoYW5uZWxJZCxcbiAgICB9O1xuICB9LFxuICBkZWxldGVUZW1wb3JhcnlGaWxlIChmaWxlUGF0aCkge1xuICAgIGZzLnVubGluayhmaWxlUGF0aCwgZXJyID0+IHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBlcnJvciBkZWxldGluZyB0ZW1wb3JhcnkgZmlsZSAke2ZpbGVQYXRofWApO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgICBsb2dnZXIuZGVidWcoYHN1Y2Nlc3NmdWxseSBkZWxldGVkICR7ZmlsZVBhdGh9YCk7XG4gICAgfSk7XG4gIH0sXG4gIGFkZEdldFJlc3VsdHNUb0ZpbGVEYXRhIChmaWxlSW5mbywgZ2V0UmVzdWx0KSB7XG4gICAgZmlsZUluZm8uZmlsZU5hbWUgPSBnZXRSZXN1bHQuZmlsZV9uYW1lO1xuICAgIGZpbGVJbmZvLmZpbGVQYXRoID0gZ2V0UmVzdWx0LmRvd25sb2FkX3BhdGg7XG4gICAgcmV0dXJuIGZpbGVJbmZvO1xuICB9LFxuICBjcmVhdGVGaWxlRGF0YSAoeyBuYW1lLCBjbGFpbUlkLCBvdXRwb2ludCwgaGVpZ2h0LCBhZGRyZXNzLCBuc2Z3LCBjb250ZW50VHlwZSB9KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWUsXG4gICAgICBjbGFpbUlkLFxuICAgICAgb3V0cG9pbnQsXG4gICAgICBoZWlnaHQsXG4gICAgICBhZGRyZXNzLFxuICAgICAgZmlsZU5hbWU6ICcnLFxuICAgICAgZmlsZVBhdGg6ICcnLFxuICAgICAgZmlsZVR5cGU6IGNvbnRlbnRUeXBlLFxuICAgICAgbnNmdyxcbiAgICB9O1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBoYW5kbGVFcnJvclJlc3BvbnNlOiBmdW5jdGlvbiAob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKSB7XG4gICAgbG9nZ2VyLmVycm9yKGBFcnJvciBvbiAke29yaWdpbmFsVXJsfWAsIG1vZHVsZS5leHBvcnRzLnVzZU9iamVjdFByb3BlcnRpZXNJZk5vS2V5cyhlcnJvcikpO1xuICAgIGNvbnN0IFtzdGF0dXMsIG1lc3NhZ2VdID0gbW9kdWxlLmV4cG9ydHMucmV0dXJuRXJyb3JNZXNzYWdlQW5kU3RhdHVzKGVycm9yKTtcbiAgICByZXNcbiAgICAgIC5zdGF0dXMoc3RhdHVzKVxuICAgICAgLmpzb24obW9kdWxlLmV4cG9ydHMuY3JlYXRlRXJyb3JSZXNwb25zZVBheWxvYWQoc3RhdHVzLCBtZXNzYWdlKSk7XG4gIH0sXG4gIHJldHVybkVycm9yTWVzc2FnZUFuZFN0YXR1czogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgbGV0IHN0YXR1cywgbWVzc2FnZTtcbiAgICAvLyBjaGVjayBmb3IgZGFlbW9uIGJlaW5nIHR1cm5lZCBvZmZcbiAgICBpZiAoZXJyb3IuY29kZSA9PT0gJ0VDT05OUkVGVVNFRCcpIHtcbiAgICAgIHN0YXR1cyA9IDUwMztcbiAgICAgIG1lc3NhZ2UgPSAnQ29ubmVjdGlvbiByZWZ1c2VkLiAgVGhlIGRhZW1vbiBtYXkgbm90IGJlIHJ1bm5pbmcuJztcbiAgICAgIC8vIGZhbGxiYWNrIGZvciBldmVyeXRoaW5nIGVsc2VcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdHVzID0gNDAwO1xuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZXNzYWdlID0gZXJyb3I7XG4gICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFtzdGF0dXMsIG1lc3NhZ2VdO1xuICB9LFxuICB1c2VPYmplY3RQcm9wZXJ0aWVzSWZOb0tleXM6IGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoT2JqZWN0LmtleXMoZXJyKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGxldCBuZXdFcnJvck9iamVjdCA9IHt9O1xuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZXJyKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgbmV3RXJyb3JPYmplY3Rba2V5XSA9IGVycltrZXldO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3RXJyb3JPYmplY3Q7XG4gICAgfVxuICAgIHJldHVybiBlcnI7XG4gIH0sXG4gIGNyZWF0ZUVycm9yUmVzcG9uc2VQYXlsb2FkIChzdGF0dXMsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzLFxuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBtZXNzYWdlLFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vaGVscGVycy9lcnJvckhhbmRsZXJzLmpzIiwiY29uc3QgZGIgPSByZXF1aXJlKCcuLi9tb2RlbHMnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHsgcmV0dXJuUGFnaW5hdGVkQ2hhbm5lbENsYWltcyB9ID0gcmVxdWlyZSgnLi4vaGVscGVycy9jaGFubmVsUGFnaW5hdGlvbi5qcycpO1xuXG5jb25zdCBOT19DSEFOTkVMID0gJ05PX0NIQU5ORUwnO1xuY29uc3QgTk9fQ0xBSU0gPSAnTk9fQ0xBSU0nO1xuY29uc3QgTk9fRklMRSA9ICdOT19GSUxFJztcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldENsYWltSWQgKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgbmFtZSwgY2xhaW1JZCkge1xuICAgIGlmIChjaGFubmVsTmFtZSkge1xuICAgICAgcmV0dXJuIG1vZHVsZS5leHBvcnRzLmdldENsYWltSWRCeUNoYW5uZWwoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBuYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1vZHVsZS5leHBvcnRzLmdldENsYWltSWRCeUNsYWltKG5hbWUsIGNsYWltSWQpO1xuICAgIH1cbiAgfSxcbiAgZ2V0Q2xhaW1JZEJ5Q2xhaW0gKGNsYWltTmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0Q2xhaW1JZEJ5Q2xhaW0oJHtjbGFpbU5hbWV9LCAke2NsYWltSWR9KWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBkYi5DbGFpbS5nZXRMb25nQ2xhaW1JZChjbGFpbU5hbWUsIGNsYWltSWQpXG4gICAgICAgIC50aGVuKGxvbmdDbGFpbUlkID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXNvbHZlKE5PX0NMQUlNKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShsb25nQ2xhaW1JZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGdldENsYWltSWRCeUNoYW5uZWwgKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBnZXRDbGFpbUlkQnlDaGFubmVsKCR7Y2hhbm5lbE5hbWV9LCAke2NoYW5uZWxDbGFpbUlkfSwgJHtjbGFpbU5hbWV9KWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBkYi5DZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkgLy8gMS4gZ2V0IHRoZSBsb25nIGNoYW5uZWwgaWRcbiAgICAgICAgLnRoZW4obG9uZ0NoYW5uZWxJZCA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2hhbm5lbElkKSB7XG4gICAgICAgICAgICByZXR1cm4gW251bGwsIG51bGxdO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2xvbmdDaGFubmVsSWQsIGRiLkNsYWltLmdldENsYWltSWRCeUxvbmdDaGFubmVsSWQobG9uZ0NoYW5uZWxJZCwgY2xhaW1OYW1lKV0pOyAgLy8gMi4gZ2V0IHRoZSBsb25nIGNsYWltIGlkXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChbbG9uZ0NoYW5uZWxJZCwgbG9uZ0NsYWltSWRdKSA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2hhbm5lbElkKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShOT19DSEFOTkVMKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFsb25nQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoTk9fQ0xBSU0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKGxvbmdDbGFpbUlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2hhbm5lbERhdGEgKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgcGFnZSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyAxLiBnZXQgdGhlIGxvbmcgY2hhbm5lbCBJZCAobWFrZSBzdXJlIGNoYW5uZWwgZXhpc3RzKVxuICAgICAgZGIuQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpXG4gICAgICAgIC50aGVuKGxvbmdDaGFubmVsQ2xhaW1JZCA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBbbnVsbCwgbnVsbCwgbnVsbF07XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIDIuIGdldCB0aGUgc2hvcnQgSUQgYW5kIGFsbCBjbGFpbXMgZm9yIHRoYXQgY2hhbm5lbFxuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbbG9uZ0NoYW5uZWxDbGFpbUlkLCBkYi5DZXJ0aWZpY2F0ZS5nZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkKGxvbmdDaGFubmVsQ2xhaW1JZCwgY2hhbm5lbE5hbWUpXSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChbbG9uZ0NoYW5uZWxDbGFpbUlkLCBzaG9ydENoYW5uZWxDbGFpbUlkXSkgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShOT19DSEFOTkVMKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gMy4gcmV0dXJuIGFsbCB0aGUgY2hhbm5lbCBpbmZvcm1hdGlvblxuICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICAgICAgICBsb25nQ2hhbm5lbENsYWltSWQsXG4gICAgICAgICAgICBzaG9ydENoYW5uZWxDbGFpbUlkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDaGFubmVsQ2xhaW1zIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIHBhZ2UpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gMS4gZ2V0IHRoZSBsb25nIGNoYW5uZWwgSWQgKG1ha2Ugc3VyZSBjaGFubmVsIGV4aXN0cylcbiAgICAgIGRiLkNlcnRpZmljYXRlLmdldExvbmdDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKVxuICAgICAgICAudGhlbihsb25nQ2hhbm5lbENsYWltSWQgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gW251bGwsIG51bGwsIG51bGxdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyAyLiBnZXQgdGhlIHNob3J0IElEIGFuZCBhbGwgY2xhaW1zIGZvciB0aGF0IGNoYW5uZWxcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2xvbmdDaGFubmVsQ2xhaW1JZCwgZGIuQ2xhaW0uZ2V0QWxsQ2hhbm5lbENsYWltcyhsb25nQ2hhbm5lbENsYWltSWQpXSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChbbG9uZ0NoYW5uZWxDbGFpbUlkLCBjaGFubmVsQ2xhaW1zQXJyYXldKSA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKE5PX0NIQU5ORUwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyAzLiBmb3JtYXQgdGhlIGRhdGEgZm9yIHRoZSB2aWV3LCBpbmNsdWRpbmcgcGFnaW5hdGlvblxuICAgICAgICAgIGxldCBwYWdpbmF0ZWRDaGFubmVsVmlld0RhdGEgPSByZXR1cm5QYWdpbmF0ZWRDaGFubmVsQ2xhaW1zKGNoYW5uZWxOYW1lLCBsb25nQ2hhbm5lbENsYWltSWQsIGNoYW5uZWxDbGFpbXNBcnJheSwgcGFnZSk7XG4gICAgICAgICAgLy8gNC4gcmV0dXJuIGFsbCB0aGUgY2hhbm5lbCBpbmZvcm1hdGlvbiBhbmQgY29udGVudHNcbiAgICAgICAgICByZXNvbHZlKHBhZ2luYXRlZENoYW5uZWxWaWV3RGF0YSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGdldExvY2FsRmlsZVJlY29yZCAoY2xhaW1JZCwgbmFtZSkge1xuICAgIHJldHVybiBkYi5GaWxlLmZpbmRPbmUoe3doZXJlOiB7Y2xhaW1JZCwgbmFtZX19KVxuICAgICAgLnRoZW4oZmlsZSA9PiB7XG4gICAgICAgIGlmICghZmlsZSkge1xuICAgICAgICAgIHJldHVybiBOT19GSUxFO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWxlLmRhdGFWYWx1ZXM7XG4gICAgICB9KTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb250cm9sbGVycy9zZXJ2ZUNvbnRyb2xsZXIuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgcmVuZGVyVG9TdHJpbmcgfSBmcm9tICdyZWFjdC1kb20vc2VydmVyJztcbmltcG9ydCB7IGNyZWF0ZVN0b3JlIH0gZnJvbSAncmVkdXgnO1xuaW1wb3J0IFJlZHVjZXIgZnJvbSAnLi4vcmVhY3QvcmVkdWNlcnMnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBTdGF0aWNSb3V0ZXIgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmltcG9ydCBHQUxpc3RlbmVyIGZyb20gJy4uL3JlYWN0L2NvbXBvbmVudHMvR0FMaXN0ZW5lcic7XG5pbXBvcnQgQXBwIGZyb20gJy4uL3JlYWN0L2FwcCc7XG5pbXBvcnQgcmVuZGVyRnVsbFBhZ2UgZnJvbSAnLi9yZW5kZXJGdWxsUGFnZS5qcyc7XG5pbXBvcnQgSGVsbWV0IGZyb20gJ3JlYWN0LWhlbG1ldCc7XG5cbm1vZHVsZS5leHBvcnRzID0gKHJlcSwgcmVzKSA9PiB7XG4gIGxldCBjb250ZXh0ID0ge307XG5cbiAgLy8gY3JlYXRlIGEgbmV3IFJlZHV4IHN0b3JlIGluc3RhbmNlXG4gIGNvbnN0IHN0b3JlID0gY3JlYXRlU3RvcmUoUmVkdWNlcik7XG5cbiAgLy8gcmVuZGVyIGNvbXBvbmVudCB0byBhIHN0cmluZ1xuICBjb25zdCBodG1sID0gcmVuZGVyVG9TdHJpbmcoXG4gICAgPFByb3ZpZGVyIHN0b3JlPXtzdG9yZX0+XG4gICAgICA8U3RhdGljUm91dGVyIGxvY2F0aW9uPXtyZXEudXJsfSBjb250ZXh0PXtjb250ZXh0fT5cbiAgICAgICAgPEdBTGlzdGVuZXI+XG4gICAgICAgICAgPEFwcCAvPlxuICAgICAgICA8L0dBTGlzdGVuZXI+XG4gICAgICA8L1N0YXRpY1JvdXRlcj5cbiAgICA8L1Byb3ZpZGVyPlxuICApO1xuXG4gIC8vIGdldCBoZWFkIHRhZ3MgZnJvbSBoZWxtZXRcbiAgY29uc3QgaGVsbWV0ID0gSGVsbWV0LnJlbmRlclN0YXRpYygpO1xuXG4gIC8vIGNoZWNrIGZvciBhIHJlZGlyZWN0XG4gIGlmIChjb250ZXh0LnVybCkge1xuICAgIC8vIFNvbWV3aGVyZSBhIGA8UmVkaXJlY3Q+YCB3YXMgcmVuZGVyZWRcbiAgICByZXR1cm4gcmVzLnJlZGlyZWN0KDMwMSwgY29udGV4dC51cmwpO1xuICB9IGVsc2Uge1xuICAgIC8vIHdlJ3JlIGdvb2QsIHNlbmQgdGhlIHJlc3BvbnNlXG4gIH1cblxuICAvLyBnZXQgdGhlIGluaXRpYWwgc3RhdGUgZnJvbSBvdXIgUmVkdXggc3RvcmVcbiAgY29uc3QgcHJlbG9hZGVkU3RhdGUgPSBzdG9yZS5nZXRTdGF0ZSgpO1xuXG4gIC8vIHNlbmQgdGhlIHJlbmRlcmVkIHBhZ2UgYmFjayB0byB0aGUgY2xpZW50XG4gIHJlcy5zZW5kKHJlbmRlckZ1bGxQYWdlKGhlbG1ldCwgaHRtbCwgcHJlbG9hZGVkU3RhdGUpKTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3QtZG9tL3NlcnZlclwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWRvbS9zZXJ2ZXJcIlxuLy8gbW9kdWxlIGlkID0gMzFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHsgY29tYmluZVJlZHVjZXJzIH0gZnJvbSAncmVkdXgnO1xuaW1wb3J0IFB1Ymxpc2hSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3B1Ymxpc2gnO1xuaW1wb3J0IENoYW5uZWxSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL2NoYW5uZWwnO1xuaW1wb3J0IFNob3dSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3Nob3cnO1xuaW1wb3J0IFNpdGVSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3NpdGUnO1xuXG5leHBvcnQgZGVmYXVsdCBjb21iaW5lUmVkdWNlcnMoe1xuICBjaGFubmVsOiBDaGFubmVsUmVkdWNlcixcbiAgcHVibGlzaDogUHVibGlzaFJlZHVjZXIsXG4gIHNob3cgICA6IFNob3dSZWR1Y2VyLFxuICBzaXRlICAgOiBTaXRlUmVkdWNlcixcbn0pO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvcmVkdWNlcnMvaW5kZXguanMiLCJleHBvcnQgY29uc3QgRklMRV9TRUxFQ1RFRCA9ICdGSUxFX1NFTEVDVEVEJztcbmV4cG9ydCBjb25zdCBGSUxFX0NMRUFSID0gJ0ZJTEVfQ0xFQVInO1xuZXhwb3J0IGNvbnN0IE1FVEFEQVRBX1VQREFURSA9ICdNRVRBREFUQV9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IENMQUlNX1VQREFURSA9ICdDTEFJTV9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IFNFVF9QVUJMSVNIX0lOX0NIQU5ORUwgPSAnU0VUX1BVQkxJU0hfSU5fQ0hBTk5FTCc7XG5leHBvcnQgY29uc3QgUFVCTElTSF9TVEFUVVNfVVBEQVRFID0gJ1BVQkxJU0hfU1RBVFVTX1VQREFURSc7XG5leHBvcnQgY29uc3QgRVJST1JfVVBEQVRFID0gJ0VSUk9SX1VQREFURSc7XG5leHBvcnQgY29uc3QgU0VMRUNURURfQ0hBTk5FTF9VUERBVEUgPSAnU0VMRUNURURfQ0hBTk5FTF9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IFRPR0dMRV9NRVRBREFUQV9JTlBVVFMgPSAnVE9HR0xFX01FVEFEQVRBX0lOUFVUUyc7XG5leHBvcnQgY29uc3QgVEhVTUJOQUlMX05FVyA9ICdUSFVNQk5BSUxfTkVXJztcbmV4cG9ydCBjb25zdCBQVUJMSVNIX1NUQVJUID0gJ1BVQkxJU0hfU1RBUlQnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29uc3RhbnRzL3B1Ymxpc2hfYWN0aW9uX3R5cGVzLmpzIiwiZXhwb3J0IGNvbnN0IExPR0lOID0gJ0V4aXN0aW5nJztcbmV4cG9ydCBjb25zdCBDUkVBVEUgPSAnTmV3JztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnN0YW50cy9wdWJsaXNoX2NoYW5uZWxfc2VsZWN0X3N0YXRlcy5qcyIsImV4cG9ydCBjb25zdCBDSEFOTkVMX1VQREFURSA9ICdDSEFOTkVMX1VQREFURSc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb25zdGFudHMvY2hhbm5lbF9hY3Rpb25fdHlwZXMuanMiLCJleHBvcnQgY29uc3QgTE9DQUxfQ0hFQ0sgPSAnTE9DQUxfQ0hFQ0snO1xuZXhwb3J0IGNvbnN0IFVOQVZBSUxBQkxFID0gJ1VOQVZBSUxBQkxFJztcbmV4cG9ydCBjb25zdCBFUlJPUiA9ICdFUlJPUic7XG5leHBvcnQgY29uc3QgQVZBSUxBQkxFID0gJ0FWQUlMQUJMRSc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb25zdGFudHMvYXNzZXRfZGlzcGxheV9zdGF0ZXMuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEdvb2dsZUFuYWx5dGljcyBmcm9tICdyZWFjdC1nYSc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5jb25zdCBjb25maWcgPSByZXF1aXJlKCcuLi8uLi8uLi9jb25maWcvc3BlZWNoQ29uZmlnLmpzJyk7XG5jb25zdCBnb29nbGVBcGlLZXkgPSBjb25maWcuYW5hbHl0aWNzLmdvb2dsZUlkO1xuXG5Hb29nbGVBbmFseXRpY3MuaW5pdGlhbGl6ZShnb29nbGVBcGlLZXkpO1xuXG5jbGFzcyBHQUxpc3RlbmVyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29tcG9uZW50RGlkTW91bnQgKCkge1xuICAgIHRoaXMuc2VuZFBhZ2VWaWV3KHRoaXMucHJvcHMuaGlzdG9yeS5sb2NhdGlvbik7XG4gICAgdGhpcy5wcm9wcy5oaXN0b3J5Lmxpc3Rlbih0aGlzLnNlbmRQYWdlVmlldyk7XG4gIH1cblxuICBzZW5kUGFnZVZpZXcgKGxvY2F0aW9uKSB7XG4gICAgR29vZ2xlQW5hbHl0aWNzLnNldCh7IHBhZ2U6IGxvY2F0aW9uLnBhdGhuYW1lIH0pO1xuICAgIEdvb2dsZUFuYWx5dGljcy5wYWdldmlldyhsb2NhdGlvbi5wYXRobmFtZSk7XG4gIH1cblxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiB0aGlzLnByb3BzLmNoaWxkcmVuO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHdpdGhSb3V0ZXIoR0FMaXN0ZW5lcik7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb21wb25lbnRzL0dBTGlzdGVuZXIvaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IFJvdXRlLCBTd2l0Y2ggfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmltcG9ydCBIb21lUGFnZSBmcm9tICdjb21wb25lbnRzL0hvbWVQYWdlJztcbmltcG9ydCBBYm91dFBhZ2UgZnJvbSAnY29tcG9uZW50cy9BYm91dFBhZ2UnO1xuaW1wb3J0IExvZ2luUGFnZSBmcm9tICdjb250YWluZXJzL0xvZ2luUGFnZSc7XG5pbXBvcnQgU2hvd1BhZ2UgZnJvbSAnY29udGFpbmVycy9TaG93UGFnZSc7XG5pbXBvcnQgRm91ck9oRm91clBhZ2UgZnJvbSAnY29tcG9uZW50cy9Gb3VyT2hGb3VyUGFnZSc7XG5cbmNvbnN0IEFwcCA9ICgpID0+IHtcbiAgcmV0dXJuIChcbiAgICA8U3dpdGNoPlxuICAgICAgPFJvdXRlIGV4YWN0IHBhdGg9Jy8nIGNvbXBvbmVudD17SG9tZVBhZ2V9IC8+XG4gICAgICA8Um91dGUgZXhhY3QgcGF0aD0nL2Fib3V0JyBjb21wb25lbnQ9e0Fib3V0UGFnZX0gLz5cbiAgICAgIDxSb3V0ZSBleGFjdCBwYXRoPScvbG9naW4nIGNvbXBvbmVudD17TG9naW5QYWdlfSAvPlxuICAgICAgPFJvdXRlIGV4YWN0IHBhdGg9Jy86aWRlbnRpZmllci86Y2xhaW0nIGNvbXBvbmVudD17U2hvd1BhZ2V9IC8+XG4gICAgICA8Um91dGUgZXhhY3QgcGF0aD0nLzpjbGFpbScgY29tcG9uZW50PXtTaG93UGFnZX0gLz5cbiAgICAgIDxSb3V0ZSBjb21wb25lbnQ9e0ZvdXJPaEZvdXJQYWdlfSAvPlxuICAgIDwvU3dpdGNoPlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgQXBwO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvYXBwLmpzIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IHNlbGVjdEZpbGUsIHVwZGF0ZUVycm9yLCBjbGVhckZpbGUgfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZmlsZSAgICAgOiBwdWJsaXNoLmZpbGUsXG4gICAgdGh1bWJuYWlsOiBwdWJsaXNoLnRodW1ibmFpbCxcbiAgICBmaWxlRXJyb3I6IHB1Ymxpc2guZXJyb3IuZmlsZSxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IGRpc3BhdGNoID0+IHtcbiAgcmV0dXJuIHtcbiAgICBzZWxlY3RGaWxlOiAoZmlsZSkgPT4ge1xuICAgICAgZGlzcGF0Y2goc2VsZWN0RmlsZShmaWxlKSk7XG4gICAgfSxcbiAgICBzZXRGaWxlRXJyb3I6ICh2YWx1ZSkgPT4ge1xuICAgICAgZGlzcGF0Y2goY2xlYXJGaWxlKCkpO1xuICAgICAgZGlzcGF0Y2godXBkYXRlRXJyb3IoJ2ZpbGUnLCB2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvRHJvcHpvbmUvaW5kZXguanMiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgdXBkYXRlTG9nZ2VkSW5DaGFubmVsIH0gZnJvbSAnYWN0aW9ucy9jaGFubmVsJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQge3VwZGF0ZVNlbGVjdGVkQ2hhbm5lbH0gZnJvbSAnLi4vLi4vYWN0aW9ucy9wdWJsaXNoJztcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2hhbm5lbExvZ2luOiAobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVTZWxlY3RlZENoYW5uZWwobmFtZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG51bGwsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vaW5kZXguanMiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgdXBkYXRlTG9nZ2VkSW5DaGFubmVsIH0gZnJvbSAnYWN0aW9ucy9jaGFubmVsJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQge3VwZGF0ZVNlbGVjdGVkQ2hhbm5lbH0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2hhbm5lbExvZ2luOiAobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVTZWxlY3RlZENoYW5uZWwobmFtZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG51bGwsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtL2luZGV4LmpzIiwiZXhwb3J0IGNvbnN0IENIQU5ORUwgPSAnQ0hBTk5FTCc7XG5leHBvcnQgY29uc3QgQVNTRVRfTElURSA9ICdBU1NFVF9MSVRFJztcbmV4cG9ydCBjb25zdCBBU1NFVF9ERVRBSUxTID0gJ0FTU0VUX0RFVEFJTFMnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29uc3RhbnRzL3Nob3dfcmVxdWVzdF90eXBlcy5qcyIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuaW1wb3J0IHsgZmlsZVJlcXVlc3RlZCB9IGZyb20gJ2FjdGlvbnMvc2hvdyc7XG5pbXBvcnQgeyBzZWxlY3RBc3NldCB9IGZyb20gJ3NlbGVjdG9ycy9zaG93JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCBlcnJvciBhbmQgc3RhdHVzXG4gIGNvbnN0IGVycm9yICA9IHNob3cuZGlzcGxheUFzc2V0LmVycm9yO1xuICBjb25zdCBzdGF0dXMgPSBzaG93LmRpc3BsYXlBc3NldC5zdGF0dXM7XG4gIC8vIHNlbGVjdCBhc3NldFxuICBjb25zdCBhc3NldCA9IHNlbGVjdEFzc2V0KHNob3cpO1xuICAvLyAgcmV0dXJuIHByb3BzXG4gIHJldHVybiB7XG4gICAgZXJyb3IsXG4gICAgc3RhdHVzLFxuICAgIGFzc2V0LFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uRmlsZVJlcXVlc3Q6IChuYW1lLCBjbGFpbUlkKSA9PiB7XG4gICAgICBkaXNwYXRjaChmaWxlUmVxdWVzdGVkKG5hbWUsIGNsYWltSWQpKTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0Fzc2V0RGlzcGxheS9pbmRleC5qcyIsIm1vZHVsZS5leHBvcnRzID0gKGhlbG1ldCwgaHRtbCwgcHJlbG9hZGVkU3RhdGUpID0+IHtcbiAgLy8gdGFrZSB0aGUgaHRtbCBhbmQgcHJlbG9hZGVkU3RhdGUgYW5kIHJldHVybiB0aGUgZnVsbCBwYWdlXG4gIHJldHVybiBgXG4gICAgPCFET0NUWVBFIGh0bWw+XG4gICAgPGh0bWwgbGFuZz1cImVuXCIgcHJlZml4PVwib2c6IGh0dHA6Ly9vZ3AubWUvbnMjIGZiOiBodHRwOi8vb2dwLm1lL25zL2ZiI1wiPlxuICAgICAgICA8aGVhZD5cbiAgICAgICAgICAgIDxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPlxuICAgICAgICAgICAgPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAsIG1heGltdW0tc2NhbGU9MSwgdXNlci1zY2FsYWJsZT1ub1wiPlxuICAgICAgICAgICAgPG1ldGEgaHR0cC1lcXVpdj1cIlgtVUEtQ29tcGF0aWJsZVwiIGNvbnRlbnQ9XCJpZT1lZGdlXCI+XG4gICAgICAgICAgICA8IS0taGVsbWV0LS0+XG4gICAgICAgICAgICAke2hlbG1ldC50aXRsZS50b1N0cmluZygpfVxuICAgICAgICAgICAgJHtoZWxtZXQubWV0YS50b1N0cmluZygpfVxuICAgICAgICAgICAgJHtoZWxtZXQubGluay50b1N0cmluZygpfVxuICAgICAgICAgICAgPCEtLXN0eWxlIHNoZWV0cy0tPlxuICAgICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvYXNzZXRzL2Nzcy9yZXNldC5jc3NcIiB0eXBlPVwidGV4dC9jc3NcIj5cbiAgICAgICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL2Fzc2V0cy9jc3MvZ2VuZXJhbC5jc3NcIiB0eXBlPVwidGV4dC9jc3NcIj5cbiAgICAgICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL2Fzc2V0cy9jc3MvbWVkaWFRdWVyaWVzLmNzc1wiIHR5cGU9XCJ0ZXh0L2Nzc1wiPlxuICAgICAgICAgICAgPCEtLWdvb2dsZSBmb250LS0+XG4gICAgICAgICAgICA8bGluayBocmVmPVwiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PVJvYm90bzozMDBcIiByZWw9XCJzdHlsZXNoZWV0XCI+XG4gICAgICAgIDwvaGVhZD5cbiAgICAgICAgPGJvZHkgaWQ9XCJtYWluLWJvZHlcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3cgcm93LS10YWxsIGZsZXgtY29udGFpbmVyLS1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGlkPVwicmVhY3QtYXBwXCIgY2xhc3M9XCJyb3cgcm93LS10YWxsIGZsZXgtY29udGFpbmVyLS1jb2x1bW5cIj4ke2h0bWx9PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzY3JpcHQ+XG4gICAgICAgICAgICAgICAgd2luZG93Ll9fUFJFTE9BREVEX1NUQVRFX18gPSAke0pTT04uc3RyaW5naWZ5KHByZWxvYWRlZFN0YXRlKS5yZXBsYWNlKC88L2csICdcXFxcXFx1MDAzYycpfVxuICAgICAgICAgICAgPC9zY3JpcHQ+XG4gICAgICAgICAgICA8c2NyaXB0IHNyYz1cIi9idW5kbGUvYnVuZGxlLmpzXCI+PC9zY3JpcHQ+XG4gICAgICAgIDwvYm9keT5cbiAgICA8L2h0bWw+XG4gIGA7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vaGVscGVycy9yZW5kZXJGdWxsUGFnZS5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImJhYmVsLXBvbHlmaWxsXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiYmFiZWwtcG9seWZpbGxcIlxuLy8gbW9kdWxlIGlkID0gNDZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwid2hhdHdnLWZldGNoXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwid2hhdHdnLWZldGNoXCJcbi8vIG1vZHVsZSBpZCA9IDQ3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIGFwcCBkZXBlbmRlbmNpZXNcbmNvbnN0IGV4cHJlc3MgPSByZXF1aXJlKCdleHByZXNzJyk7XG5jb25zdCBib2R5UGFyc2VyID0gcmVxdWlyZSgnYm9keS1wYXJzZXInKTtcbmNvbnN0IGV4cHJlc3NIYW5kbGViYXJzID0gcmVxdWlyZSgnZXhwcmVzcy1oYW5kbGViYXJzJyk7XG5jb25zdCBIYW5kbGViYXJzID0gcmVxdWlyZSgnaGFuZGxlYmFycycpO1xuY29uc3QgaGVsbWV0ID0gcmVxdWlyZSgnaGVsbWV0Jyk7XG5jb25zdCBwYXNzcG9ydCA9IHJlcXVpcmUoJ3Bhc3Nwb3J0Jyk7XG5jb25zdCB7IHBvcHVsYXRlTG9jYWxzRG90VXNlciwgc2VyaWFsaXplU3BlZWNoVXNlciwgZGVzZXJpYWxpemVTcGVlY2hVc2VyIH0gPSByZXF1aXJlKCcuL2hlbHBlcnMvYXV0aEhlbHBlcnMuanMnKTtcbmNvbnN0IGNvb2tpZVNlc3Npb24gPSByZXF1aXJlKCdjb29raWUtc2Vzc2lvbicpO1xuY29uc3QgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcbi8vIGxvZ2dpbmcgZGVwZW5kZW5jaWVzXG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbmZ1bmN0aW9uIFNwZWVjaFNlcnZlciAoeyBteXNxbENvbmZpZywgc2l0ZUNvbmZpZywgc2xhY2tDb25maWcgfSkge1xuICB0aGlzLlBPUlQgPSAzMDAwO1xuICB0aGlzLnNwZWFrID0gKHNvbWV0aGluZykgPT4ge1xuICAgIGNvbnNvbGUubG9nKHNvbWV0aGluZyk7XG4gIH07XG4gIHRoaXMuc3RhcnQgPSAoKSA9PiB7XG4gICAgdGhpcy5jb25maWd1cmVDb25maWdGaWxlcygpO1xuICAgIHRoaXMuY29uZmlndXJlTG9nZ2luZygpO1xuICAgIHRoaXMuY29uZmlndXJlQXBwKCk7XG4gICAgdGhpcy5jb25maWd1cmVTZXJ2ZXIoKTtcbiAgICB0aGlzLnN0YXJ0U2VydmVyKCk7XG4gIH07XG4gIHRoaXMuY29uZmlndXJlQ29uZmlnRmlsZXMgPSAoKSA9PiB7XG4gICAgY29uc3QgbXlzcWxBcHBDb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZy9teXNxbENvbmZpZy5qcycpO1xuICAgIG15c3FsQXBwQ29uZmlnLmNvbmZpZ3VyZShteXNxbENvbmZpZyk7XG4gICAgY29uc3Qgc2xhY2tBcHBDb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZy9zbGFja0NvbmZpZy5qcycpO1xuICAgIHNsYWNrQXBwQ29uZmlnLmNvbmZpZ3VyZShzbGFja0NvbmZpZyk7XG4gICAgLy8gcHJpbnQgdGhlIGNvbmZpZyB2YXJpYWJsZXNcbiAgICBjb25zb2xlLmxvZygnY29uZmlndXJlZCBjb25maWcgZmlsZXMnKTtcbiAgICByZXF1aXJlKCcuL2hlbHBlcnMvY29uZmlnVmFyQ2hlY2suanMnKShteXNxbEFwcENvbmZpZyk7XG4gICAgcmVxdWlyZSgnLi9oZWxwZXJzL2NvbmZpZ1ZhckNoZWNrLmpzJykoc2xhY2tBcHBDb25maWcpO1xuICB9O1xuICB0aGlzLmNvbmZpZ3VyZUxvZ2dpbmcgPSAoKSA9PiB7XG4gICAgcmVxdWlyZSgnLi9oZWxwZXJzL2NvbmZpZ3VyZUxvZ2dlci5qcycpKGxvZ2dlcik7XG4gICAgcmVxdWlyZSgnLi9oZWxwZXJzL2NvbmZpZ3VyZVNsYWNrLmpzJykobG9nZ2VyKTtcbiAgfTtcbiAgdGhpcy5jb25maWd1cmVBcHAgPSAoKSA9PiB7XG4gICAgY29uc3QgYXBwID0gZXhwcmVzcygpOyAvLyBjcmVhdGUgYW4gRXhwcmVzcyBhcHBsaWNhdGlvblxuXG4gICAgLy8gdHJ1c3QgdGhlIHByb3h5IHRvIGdldCBpcCBhZGRyZXNzIGZvciB1c1xuICAgIGFwcC5lbmFibGUoJ3RydXN0IHByb3h5Jyk7XG5cbiAgICAvLyBhZGQgbWlkZGxld2FyZVxuICAgIGFwcC51c2UoaGVsbWV0KCkpOyAvLyBzZXQgSFRUUCBoZWFkZXJzIHRvIHByb3RlY3QgYWdhaW5zdCB3ZWxsLWtub3duIHdlYiB2dWxuZXJhYmlsdGllc1xuICAgIGFwcC51c2UoZXhwcmVzcy5zdGF0aWMoYCR7X19kaXJuYW1lfS9wdWJsaWNgKSk7IC8vICdleHByZXNzLnN0YXRpYycgdG8gc2VydmUgc3RhdGljIGZpbGVzIGZyb20gcHVibGljIGRpcmVjdG9yeVxuICAgIGFwcC51c2UoYm9keVBhcnNlci5qc29uKCkpOyAvLyAnYm9keSBwYXJzZXInIGZvciBwYXJzaW5nIGFwcGxpY2F0aW9uL2pzb25cbiAgICBhcHAudXNlKGJvZHlQYXJzZXIudXJsZW5jb2RlZCh7IGV4dGVuZGVkOiB0cnVlIH0pKTsgLy8gJ2JvZHkgcGFyc2VyJyBmb3IgcGFyc2luZyBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcbiAgICBhcHAudXNlKChyZXEsIHJlcywgbmV4dCkgPT4geyAgLy8gY3VzdG9tIGxvZ2dpbmcgbWlkZGxld2FyZSB0byBsb2cgYWxsIGluY29taW5nIGh0dHAgcmVxdWVzdHNcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBSZXF1ZXN0IG9uICR7cmVxLm9yaWdpbmFsVXJsfSBmcm9tICR7cmVxLmlwfWApO1xuICAgICAgbmV4dCgpO1xuICAgIH0pO1xuXG4gICAgLy8gY29uZmlndXJlIHBhc3Nwb3J0XG4gICAgcGFzc3BvcnQuc2VyaWFsaXplVXNlcihzZXJpYWxpemVTcGVlY2hVc2VyKTtcbiAgICBwYXNzcG9ydC5kZXNlcmlhbGl6ZVVzZXIoZGVzZXJpYWxpemVTcGVlY2hVc2VyKTtcbiAgICBjb25zdCBsb2NhbFNpZ251cFN0cmF0ZWd5ID0gcmVxdWlyZSgnLi9wYXNzcG9ydC9sb2NhbC1zaWdudXAuanMnKTtcbiAgICBjb25zdCBsb2NhbExvZ2luU3RyYXRlZ3kgPSByZXF1aXJlKCcuL3Bhc3Nwb3J0L2xvY2FsLWxvZ2luLmpzJyk7XG4gICAgcGFzc3BvcnQudXNlKCdsb2NhbC1zaWdudXAnLCBsb2NhbFNpZ251cFN0cmF0ZWd5KTtcbiAgICBwYXNzcG9ydC51c2UoJ2xvY2FsLWxvZ2luJywgbG9jYWxMb2dpblN0cmF0ZWd5KTtcbiAgICAvLyBpbml0aWFsaXplIHBhc3Nwb3J0XG4gICAgYXBwLnVzZShjb29raWVTZXNzaW9uKHtcbiAgICAgIG5hbWUgIDogJ3Nlc3Npb24nLFxuICAgICAga2V5cyAgOiBbc2l0ZUNvbmZpZy5zZXNzaW9uLnNlc3Npb25LZXldLFxuICAgICAgbWF4QWdlOiAyNCAqIDYwICogNjAgKiAxMDAwLCAvLyBpLmUuIDI0IGhvdXJzXG4gICAgfSkpO1xuICAgIGFwcC51c2UocGFzc3BvcnQuaW5pdGlhbGl6ZSgpKTtcbiAgICBhcHAudXNlKHBhc3Nwb3J0LnNlc3Npb24oKSk7XG5cbiAgICAvLyBjb25maWd1cmUgaGFuZGxlYmFycyAmIHJlZ2lzdGVyIGl0IHdpdGggZXhwcmVzcyBhcHBcbiAgICBjb25zdCBoYnMgPSBleHByZXNzSGFuZGxlYmFycy5jcmVhdGUoe1xuICAgICAgZGVmYXVsdExheW91dDogJ2VtYmVkJyxcbiAgICAgIGhhbmRsZWJhcnMgICA6IEhhbmRsZWJhcnMsXG4gICAgfSk7XG4gICAgYXBwLmVuZ2luZSgnaGFuZGxlYmFycycsIGhicy5lbmdpbmUpO1xuICAgIGFwcC5zZXQoJ3ZpZXcgZW5naW5lJywgJ2hhbmRsZWJhcnMnKTtcblxuICAgIC8vIG1pZGRsZXdhcmUgdG8gcGFzcyB1c2VyIGluZm8gYmFjayB0byBjbGllbnQgKGZvciBoYW5kbGViYXJzIGFjY2VzcyksIGlmIHVzZXIgaXMgbG9nZ2VkIGluXG4gICAgYXBwLnVzZShwb3B1bGF0ZUxvY2Fsc0RvdFVzZXIpOyAgLy8gbm90ZTogSSBkb24ndCB0aGluayBJIG5lZWQgdGhpcyBhbnkgbW9yZT9cblxuICAgIC8vIHNldCB0aGUgcm91dGVzIG9uIHRoZSBhcHBcbiAgICByZXF1aXJlKCcuL3JvdXRlcy9hdXRoLXJvdXRlcy5qcycpKGFwcCk7XG4gICAgcmVxdWlyZSgnLi9yb3V0ZXMvYXBpLXJvdXRlcy5qcycpKGFwcCk7XG4gICAgcmVxdWlyZSgnLi9yb3V0ZXMvcGFnZS1yb3V0ZXMuanMnKShhcHApO1xuICAgIHJlcXVpcmUoJy4vcm91dGVzL3NlcnZlLXJvdXRlcy5qcycpKGFwcCk7XG4gICAgcmVxdWlyZSgnLi9yb3V0ZXMvZmFsbGJhY2stcm91dGVzLmpzJykoYXBwKTtcblxuICAgIHRoaXMuYXBwID0gYXBwO1xuICB9O1xuICB0aGlzLmNvbmZpZ3VyZVNlcnZlciA9ICgpID0+IHtcbiAgICB0aGlzLnNlcnZlciA9IGh0dHAuU2VydmVyKHRoaXMuYXBwKTtcbiAgfTtcbiAgdGhpcy5zdGFydFNlcnZlciA9ICgpID0+IHtcbiAgICBjb25zdCBkYiA9IHJlcXVpcmUoJy4vbW9kZWxzJyk7XG4gICAgLy8gc3luYyBzZXF1ZWxpemVcbiAgICBkYi5zZXF1ZWxpemUuc3luYygpXG4gICAgICAvLyBzdGFydCB0aGUgc2VydmVyXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc2VydmVyLmxpc3Rlbih0aGlzLlBPUlQsICgpID0+IHtcbiAgICAgICAgICBsb2dnZXIuaW5mbyhgU2VydmVyIGlzIGxpc3RlbmluZyBvbiBQT1JUICR7dGhpcy5QT1JUfWApO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgU3RhcnR1cCBFcnJvcjpgLCBlcnJvcik7XG4gICAgICB9KTtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU3BlZWNoU2VydmVyO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXhwcmVzc1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImV4cHJlc3NcIlxuLy8gbW9kdWxlIGlkID0gNDlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYm9keS1wYXJzZXJcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJib2R5LXBhcnNlclwiXG4vLyBtb2R1bGUgaWQgPSA1MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJleHByZXNzLWhhbmRsZWJhcnNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJleHByZXNzLWhhbmRsZWJhcnNcIlxuLy8gbW9kdWxlIGlkID0gNTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaGFuZGxlYmFyc1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImhhbmRsZWJhcnNcIlxuLy8gbW9kdWxlIGlkID0gNTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaGVsbWV0XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiaGVsbWV0XCJcbi8vIG1vZHVsZSBpZCA9IDUzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHBvcHVsYXRlTG9jYWxzRG90VXNlciAocmVxLCByZXMsIG5leHQpIHtcbiAgICBpZiAocmVxLnVzZXIpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygncG9wdWxhdGluZyByZXMubG9jYWxzLnVzZXInKTtcbiAgICAgIHJlcy5sb2NhbHMudXNlciA9IHtcbiAgICAgICAgaWQgICAgICAgICAgICA6IHJlcS51c2VyLmlkLFxuICAgICAgICB1c2VyTmFtZSAgICAgIDogcmVxLnVzZXIudXNlck5hbWUsXG4gICAgICAgIGNoYW5uZWxOYW1lICAgOiByZXEudXNlci5jaGFubmVsTmFtZSxcbiAgICAgICAgY2hhbm5lbENsYWltSWQ6IHJlcS51c2VyLmNoYW5uZWxDbGFpbUlkLFxuICAgICAgICBzaG9ydENoYW5uZWxJZDogcmVxLnVzZXIuc2hvcnRDaGFubmVsSWQsXG4gICAgICB9O1xuICAgIH1cbiAgICBuZXh0KCk7XG4gIH0sXG4gIHNlcmlhbGl6ZVNwZWVjaFVzZXIgKHVzZXIsIGRvbmUpIHsgIC8vIHJldHVybnMgdXNlciBkYXRhIHRvIGJlIHNlcmlhbGl6ZWQgaW50byBzZXNzaW9uXG4gICAgbG9nZ2VyLmRlYnVnKCdzZXJpYWxpemluZyB1c2VyJyk7XG4gICAgZG9uZShudWxsLCB1c2VyKTtcbiAgfSxcbiAgZGVzZXJpYWxpemVTcGVlY2hVc2VyICh1c2VyLCBkb25lKSB7ICAvLyBkZXNlcmlhbGl6ZXMgc2Vzc2lvbiBhbmQgcG9wdWxhdGVzIGFkZGl0aW9uYWwgaW5mbyB0byByZXEudXNlclxuICAgIGxvZ2dlci5kZWJ1ZygnZGVzZXJpYWxpemluZyB1c2VyJyk7XG4gICAgZG9uZShudWxsLCB1c2VyKTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9oZWxwZXJzL2F1dGhIZWxwZXJzLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiY29va2llLXNlc3Npb25cIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJjb29raWUtc2Vzc2lvblwiXG4vLyBtb2R1bGUgaWQgPSA1NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJodHRwXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiaHR0cFwiXG4vLyBtb2R1bGUgaWQgPSA1NlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKGNvbmZpZykgPT4ge1xuICAvLyBnZXQgdGhlIGNvbmZpZyBmaWxlXG4gIGZvciAobGV0IGNvbmZpZ0NhdGVnb3J5S2V5IGluIGNvbmZpZykge1xuICAgIGlmIChjb25maWcuaGFzT3duUHJvcGVydHkoY29uZmlnQ2F0ZWdvcnlLZXkpKSB7XG4gICAgICAvLyBnZXQgdGhlIGZpbmFsIHZhcmlhYmxlcyBmb3IgZWFjaCBjb25maWcgY2F0ZWdvcnlcbiAgICAgIGNvbnN0IGNvbmZpZ1ZhcmlhYmxlcyA9IGNvbmZpZ1tjb25maWdDYXRlZ29yeUtleV07XG4gICAgICBmb3IgKGxldCBjb25maWdWYXJLZXkgaW4gY29uZmlnVmFyaWFibGVzKSB7XG4gICAgICAgIGlmIChjb25maWdWYXJpYWJsZXMuaGFzT3duUHJvcGVydHkoY29uZmlnVmFyS2V5KSkge1xuICAgICAgICAgIC8vIHByaW50IGVhY2ggdmFyaWFibGVcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYENPTkZJRyBDSEVDSzogJHtjb25maWdDYXRlZ29yeUtleX0uJHtjb25maWdWYXJLZXl9ID09PSAke2NvbmZpZ1ZhcmlhYmxlc1tjb25maWdWYXJLZXldfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vaGVscGVycy9jb25maWdWYXJDaGVjay5qcyIsImNvbnN0IHsgbG9nTGV2ZWwgfSA9IHJlcXVpcmUoJy4uL2NvbmZpZy9sb2dnZXJDb25maWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAod2luc3RvbikgPT4ge1xuICAvLyBjb25maWd1cmVcbiAgd2luc3Rvbi5jb25maWd1cmUoe1xuICAgIHRyYW5zcG9ydHM6IFtcbiAgICAgIG5ldyAod2luc3Rvbi50cmFuc3BvcnRzLkNvbnNvbGUpKHtcbiAgICAgICAgbGV2ZWwgICAgICAgICAgICAgICAgICAgICAgICAgIDogbG9nTGV2ZWwsXG4gICAgICAgIHRpbWVzdGFtcCAgICAgICAgICAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICBjb2xvcml6ZSAgICAgICAgICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBwcmV0dHlQcmludCAgICAgICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBoYW5kbGVFeGNlcHRpb25zICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBodW1hblJlYWRhYmxlVW5oYW5kbGVkRXhjZXB0aW9uOiB0cnVlLFxuICAgICAgfSksXG4gICAgXSxcbiAgfSk7XG4gIC8vIHRlc3QgYWxsIHRoZSBsb2cgbGV2ZWxzXG4gIHdpbnN0b24uZXJyb3IoJ0xldmVsIDAnKTtcbiAgd2luc3Rvbi53YXJuKCdMZXZlbCAxJyk7XG4gIHdpbnN0b24uaW5mbygnTGV2ZWwgMicpO1xuICB3aW5zdG9uLnZlcmJvc2UoJ0xldmVsIDMnKTtcbiAgd2luc3Rvbi5kZWJ1ZygnTGV2ZWwgNCcpO1xuICB3aW5zdG9uLnNpbGx5KCdMZXZlbCA1Jyk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vaGVscGVycy9jb25maWd1cmVMb2dnZXIuanMiLCJjb25zdCBsb2dnZXJDb25maWcgPSB7XG4gIGxvZ0xldmVsOiAnZGVidWcnLCAgLy8gb3B0aW9uczogc2lsbHksIGRlYnVnLCB2ZXJib3NlLCBpbmZvXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGxvZ2dlckNvbmZpZztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NvbmZpZy9sb2dnZXJDb25maWcuanMiLCJjb25zdCB3aW5zdG9uU2xhY2tXZWJIb29rID0gcmVxdWlyZSgnd2luc3Rvbi1zbGFjay13ZWJob29rJykuU2xhY2tXZWJIb29rO1xuY29uc3Qgc2xhY2tDb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcvc2xhY2tDb25maWcuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAod2luc3RvbikgPT4ge1xuICBjb25zdCB7c2xhY2tXZWJIb29rLCBzbGFja0Vycm9yQ2hhbm5lbCwgc2xhY2tJbmZvQ2hhbm5lbH0gPSBzbGFja0NvbmZpZztcbiAgaWYgKHNsYWNrV2ViSG9vaykge1xuICAgIC8vIGFkZCBhIHRyYW5zcG9ydCBmb3IgZXJyb3JzIHRvIHNsYWNrXG4gICAgaWYgKHNsYWNrRXJyb3JDaGFubmVsKSB7XG4gICAgICB3aW5zdG9uLmFkZCh3aW5zdG9uU2xhY2tXZWJIb29rLCB7XG4gICAgICAgIG5hbWUgICAgICA6ICdzbGFjay1lcnJvcnMtdHJhbnNwb3J0JyxcbiAgICAgICAgbGV2ZWwgICAgIDogJ3dhcm4nLFxuICAgICAgICB3ZWJob29rVXJsOiBzbGFja1dlYkhvb2ssXG4gICAgICAgIGNoYW5uZWwgICA6IHNsYWNrRXJyb3JDaGFubmVsLFxuICAgICAgICB1c2VybmFtZSAgOiAnc3BlZS5jaCcsXG4gICAgICAgIGljb25FbW9qaSA6ICc6ZmFjZV93aXRoX2hlYWRfYmFuZGFnZTonLFxuICAgICAgfSk7XG4gICAgfTtcbiAgICBpZiAoc2xhY2tJbmZvQ2hhbm5lbCkge1xuICAgICAgd2luc3Rvbi5hZGQod2luc3RvblNsYWNrV2ViSG9vaywge1xuICAgICAgICBuYW1lICAgICAgOiAnc2xhY2staW5mby10cmFuc3BvcnQnLFxuICAgICAgICBsZXZlbCAgICAgOiAnaW5mbycsXG4gICAgICAgIHdlYmhvb2tVcmw6IHNsYWNrV2ViSG9vayxcbiAgICAgICAgY2hhbm5lbCAgIDogc2xhY2tJbmZvQ2hhbm5lbCxcbiAgICAgICAgdXNlcm5hbWUgIDogJ3NwZWUuY2gnLFxuICAgICAgICBpY29uRW1vamkgOiAnOm5lcmRfZmFjZTonLFxuICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyBzZW5kIHRlc3QgbWVzc2FnZVxuICAgIHdpbnN0b24uZXJyb3IoJ1NsYWNrIFwiZXJyb3JcIiBsb2dnaW5nIGlzIG9ubGluZS4nKTtcbiAgICB3aW5zdG9uLmluZm8oJ1NsYWNrIFwiaW5mb1wiIGxvZ2dpbmcgaXMgb25saW5lLicpO1xuICB9IGVsc2Uge1xuICAgIHdpbnN0b24ud2FybignU2xhY2sgbG9nZ2luZyBpcyBub3QgZW5hYmxlZCBiZWNhdXNlIG5vIHNsYWNrV2ViSG9vayBjb25maWcgdmFyIHByb3ZpZGVkLicpO1xuICB9XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vaGVscGVycy9jb25maWd1cmVTbGFjay5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIndpbnN0b24tc2xhY2std2ViaG9va1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcIndpbnN0b24tc2xhY2std2ViaG9va1wiXG4vLyBtb2R1bGUgaWQgPSA2MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBQYXNzcG9ydExvY2FsU3RyYXRlZ3kgPSByZXF1aXJlKCdwYXNzcG9ydC1sb2NhbCcpLlN0cmF0ZWd5O1xuY29uc3QgbGJyeUFwaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeUFwaS5qcycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChkYikgPT4ge1xuICByZXR1cm4gbmV3IFBhc3Nwb3J0TG9jYWxTdHJhdGVneShcbiAgICB7XG4gICAgICB1c2VybmFtZUZpZWxkOiAndXNlcm5hbWUnLFxuICAgICAgcGFzc3dvcmRGaWVsZDogJ3Bhc3N3b3JkJyxcbiAgICB9LFxuICAgICh1c2VybmFtZSwgcGFzc3dvcmQsIGRvbmUpID0+IHtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBuZXcgY2hhbm5lbCBzaWdudXAgcmVxdWVzdC4gdXNlcjogJHt1c2VybmFtZX0gcGFzczogJHtwYXNzd29yZH0gLmApO1xuICAgICAgbGV0IHVzZXJJbmZvID0ge307XG4gICAgICAvLyBzZXJ2ZXItc2lkZSB2YWxpZGF0b24gb2YgaW5wdXRzICh1c2VybmFtZSwgcGFzc3dvcmQpXG5cbiAgICAgIC8vIGNyZWF0ZSB0aGUgY2hhbm5lbCBhbmQgcmV0cmlldmUgdGhlIG1ldGFkYXRhXG4gICAgICByZXR1cm4gbGJyeUFwaS5jcmVhdGVDaGFubmVsKGBAJHt1c2VybmFtZX1gKVxuICAgICAgICAudGhlbih0eCA9PiB7XG4gICAgICAgICAgLy8gY3JlYXRlIHVzZXIgcmVjb3JkXG4gICAgICAgICAgY29uc3QgdXNlckRhdGEgPSB7XG4gICAgICAgICAgICB1c2VyTmFtZTogdXNlcm5hbWUsXG4gICAgICAgICAgICBwYXNzd29yZDogcGFzc3dvcmQsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBsb2dnZXIudmVyYm9zZSgndXNlckRhdGEgPicsIHVzZXJEYXRhKTtcbiAgICAgICAgICAvLyBjcmVhdGUgdXNlciByZWNvcmRcbiAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IHtcbiAgICAgICAgICAgIGNoYW5uZWxOYW1lICAgOiBgQCR7dXNlcm5hbWV9YCxcbiAgICAgICAgICAgIGNoYW5uZWxDbGFpbUlkOiB0eC5jbGFpbV9pZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGxvZ2dlci52ZXJib3NlKCdjaGFubmVsRGF0YSA+JywgY2hhbm5lbERhdGEpO1xuICAgICAgICAgIC8vIGNyZWF0ZSBjZXJ0aWZpY2F0ZSByZWNvcmRcbiAgICAgICAgICBjb25zdCBjZXJ0aWZpY2F0ZURhdGEgPSB7XG4gICAgICAgICAgICBjbGFpbUlkOiB0eC5jbGFpbV9pZCxcbiAgICAgICAgICAgIG5hbWUgICA6IGBAJHt1c2VybmFtZX1gLFxuICAgICAgICAgICAgLy8gYWRkcmVzcyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGxvZ2dlci52ZXJib3NlKCdjZXJ0aWZpY2F0ZURhdGEgPicsIGNlcnRpZmljYXRlRGF0YSk7XG4gICAgICAgICAgLy8gc2F2ZSB1c2VyIGFuZCBjZXJ0aWZpY2F0ZSB0byBkYlxuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZGIuVXNlci5jcmVhdGUodXNlckRhdGEpLCBkYi5DaGFubmVsLmNyZWF0ZShjaGFubmVsRGF0YSksIGRiLkNlcnRpZmljYXRlLmNyZWF0ZShjZXJ0aWZpY2F0ZURhdGEpXSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChbbmV3VXNlciwgbmV3Q2hhbm5lbCwgbmV3Q2VydGlmaWNhdGVdKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ3VzZXIgYW5kIGNlcnRpZmljYXRlIHN1Y2Nlc3NmdWxseSBjcmVhdGVkJyk7XG4gICAgICAgICAgLy8gc3RvcmUgdGhlIHJlbGV2YW50IG5ld1VzZXIgaW5mbyB0byBiZSBwYXNzZWQgYmFjayBmb3IgcmVxLlVzZXJcbiAgICAgICAgICB1c2VySW5mb1snaWQnXSA9IG5ld1VzZXIuaWQ7XG4gICAgICAgICAgdXNlckluZm9bJ3VzZXJOYW1lJ10gPSBuZXdVc2VyLnVzZXJOYW1lO1xuICAgICAgICAgIHVzZXJJbmZvWydjaGFubmVsTmFtZSddID0gbmV3Q2hhbm5lbC5jaGFubmVsTmFtZTtcbiAgICAgICAgICB1c2VySW5mb1snY2hhbm5lbENsYWltSWQnXSA9IG5ld0NoYW5uZWwuY2hhbm5lbENsYWltSWQ7XG4gICAgICAgICAgLy8gYXNzb2NpYXRlIHRoZSBpbnN0YW5jZXNcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW25ld0NlcnRpZmljYXRlLnNldENoYW5uZWwobmV3Q2hhbm5lbCksIG5ld0NoYW5uZWwuc2V0VXNlcihuZXdVc2VyKV0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ3VzZXIgYW5kIGNlcnRpZmljYXRlIHN1Y2Nlc3NmdWxseSBhc3NvY2lhdGVkJyk7XG4gICAgICAgICAgcmV0dXJuIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQodXNlckluZm8uY2hhbm5lbENsYWltSWQsIHVzZXJJbmZvLmNoYW5uZWxOYW1lKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oc2hvcnRDaGFubmVsSWQgPT4ge1xuICAgICAgICAgIHVzZXJJbmZvWydzaG9ydENoYW5uZWxJZCddID0gc2hvcnRDaGFubmVsSWQ7XG4gICAgICAgICAgcmV0dXJuIGRvbmUobnVsbCwgdXNlckluZm8pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignc2lnbnVwIGVycm9yJywgZXJyb3IpO1xuICAgICAgICAgIHJldHVybiBkb25lKGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICApO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3Bhc3Nwb3J0L2xvY2FsLXNpZ251cC5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImF4aW9zXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiYXhpb3NcIlxuLy8gbW9kdWxlIGlkID0gNjNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgbGJyeUNvbmZpZyA9IHtcbiAgYXBpOiB7XG4gICAgYXBpSG9zdDogJ2xvY2FsaG9zdCcsXG4gICAgYXBpUG9ydDogJzUyNzknLFxuICB9LFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBsYnJ5Q29uZmlnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY29uZmlnL2xicnlDb25maWcuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1bml2ZXJzYWwtYW5hbHl0aWNzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwidW5pdmVyc2FsLWFuYWx5dGljc1wiXG4vLyBtb2R1bGUgaWQgPSA2NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBQYXNzcG9ydExvY2FsU3RyYXRlZ3kgPSByZXF1aXJlKCdwYXNzcG9ydC1sb2NhbCcpLlN0cmF0ZWd5O1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChkYikgPT4ge1xuICBjb25zdCByZXR1cm5Vc2VyQW5kQ2hhbm5lbEluZm8gPSAodXNlckluc3RhbmNlKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCB1c2VySW5mbyA9IHt9O1xuICAgICAgdXNlckluZm9bJ2lkJ10gPSB1c2VySW5zdGFuY2UuaWQ7XG4gICAgICB1c2VySW5mb1sndXNlck5hbWUnXSA9IHVzZXJJbnN0YW5jZS51c2VyTmFtZTtcbiAgICAgIHVzZXJJbnN0YW5jZVxuICAgICAgICAuZ2V0Q2hhbm5lbCgpXG4gICAgICAgIC50aGVuKCh7Y2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkfSkgPT4ge1xuICAgICAgICAgIHVzZXJJbmZvWydjaGFubmVsTmFtZSddID0gY2hhbm5lbE5hbWU7XG4gICAgICAgICAgdXNlckluZm9bJ2NoYW5uZWxDbGFpbUlkJ10gPSBjaGFubmVsQ2xhaW1JZDtcbiAgICAgICAgICByZXR1cm4gZGIuQ2VydGlmaWNhdGUuZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZChjaGFubmVsQ2xhaW1JZCwgY2hhbm5lbE5hbWUpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihzaG9ydENoYW5uZWxJZCA9PiB7XG4gICAgICAgICAgdXNlckluZm9bJ3Nob3J0Q2hhbm5lbElkJ10gPSBzaG9ydENoYW5uZWxJZDtcbiAgICAgICAgICByZXNvbHZlKHVzZXJJbmZvKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gbmV3IFBhc3Nwb3J0TG9jYWxTdHJhdGVneShcbiAgICB7XG4gICAgICB1c2VybmFtZUZpZWxkOiAndXNlcm5hbWUnLFxuICAgICAgcGFzc3dvcmRGaWVsZDogJ3Bhc3N3b3JkJyxcbiAgICB9LFxuICAgICh1c2VybmFtZSwgcGFzc3dvcmQsIGRvbmUpID0+IHtcbiAgICAgIHJldHVybiBkYi5Vc2VyXG4gICAgICAgIC5maW5kT25lKHtcbiAgICAgICAgICB3aGVyZToge3VzZXJOYW1lOiB1c2VybmFtZX0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdubyB1c2VyIGZvdW5kJyk7XG4gICAgICAgICAgICByZXR1cm4gZG9uZShudWxsLCBmYWxzZSwge21lc3NhZ2U6ICdJbmNvcnJlY3QgdXNlcm5hbWUgb3IgcGFzc3dvcmQnfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB1c2VyLmNvbXBhcmVQYXNzd29yZChwYXNzd29yZClcbiAgICAgICAgICAgIC50aGVuKGlzTWF0Y2ggPT4ge1xuICAgICAgICAgICAgICBpZiAoIWlzTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoJ2luY29ycmVjdCBwYXNzd29yZCcpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkb25lKG51bGwsIGZhbHNlLCB7bWVzc2FnZTogJ0luY29ycmVjdCB1c2VybmFtZSBvciBwYXNzd29yZCd9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1Bhc3N3b3JkIHdhcyBhIG1hdGNoLCByZXR1cm5pbmcgVXNlcicpO1xuICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuVXNlckFuZENoYW5uZWxJbmZvKHVzZXIpXG4gICAgICAgICAgICAgICAgLnRoZW4odXNlckluZm8gPT4ge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvbmUobnVsbCwgdXNlckluZm8pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZXR1cm4gZG9uZShlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcGFzc3BvcnQvbG9jYWwtbG9naW4uanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBwYXNzcG9ydCA9IHJlcXVpcmUoJ3Bhc3Nwb3J0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKGFwcCkgPT4ge1xuICAvLyByb3V0ZSBmb3Igc2lnbiB1cFxuICBhcHAucG9zdCgnL3NpZ251cCcsIHBhc3Nwb3J0LmF1dGhlbnRpY2F0ZSgnbG9jYWwtc2lnbnVwJyksIChyZXEsIHJlcykgPT4ge1xuICAgIGxvZ2dlci52ZXJib3NlKGBzdWNjZXNzZnVsIHNpZ251cCBmb3IgJHtyZXEudXNlci5jaGFubmVsTmFtZX1gKTtcbiAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7XG4gICAgICBzdWNjZXNzICAgICAgIDogdHJ1ZSxcbiAgICAgIGNoYW5uZWxOYW1lICAgOiByZXEudXNlci5jaGFubmVsTmFtZSxcbiAgICAgIGNoYW5uZWxDbGFpbUlkOiByZXEudXNlci5jaGFubmVsQ2xhaW1JZCxcbiAgICAgIHNob3J0Q2hhbm5lbElkOiByZXEudXNlci5zaG9ydENoYW5uZWxJZCxcbiAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIGZvciBsb2cgaW5cbiAgYXBwLnBvc3QoJy9sb2dpbicsIChyZXEsIHJlcywgbmV4dCkgPT4ge1xuICAgIHBhc3Nwb3J0LmF1dGhlbnRpY2F0ZSgnbG9jYWwtbG9naW4nLCAoZXJyLCB1c2VyLCBpbmZvKSA9PiB7XG4gICAgICBsb2dnZXIuZGVidWcoJ2luZm86JywgaW5mbyk7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJldHVybiBuZXh0KGVycik7XG4gICAgICB9XG4gICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBtZXNzYWdlOiBpbmZvLm1lc3NhZ2UsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmRlYnVnKCdzdWNjZXNzZnVsIGxvZ2luJyk7XG4gICAgICByZXEubG9nSW4odXNlciwgKGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIG5leHQoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLmpzb24oe1xuICAgICAgICAgIHN1Y2Nlc3MgICAgICAgOiB0cnVlLFxuICAgICAgICAgIGNoYW5uZWxOYW1lICAgOiByZXEudXNlci5jaGFubmVsTmFtZSxcbiAgICAgICAgICBjaGFubmVsQ2xhaW1JZDogcmVxLnVzZXIuY2hhbm5lbENsYWltSWQsXG4gICAgICAgICAgc2hvcnRDaGFubmVsSWQ6IHJlcS51c2VyLnNob3J0Q2hhbm5lbElkLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pKHJlcSwgcmVzLCBuZXh0KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGxvZyBvdXRcbiAgYXBwLmdldCgnL2xvZ291dCcsIChyZXEsIHJlcykgPT4ge1xuICAgIHJlcS5sb2dvdXQoKTtcbiAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgbWVzc2FnZTogJ3lvdSBzdWNjZXNzZnVsbHkgbG9nZ2VkIG91dCd9KTtcbiAgfSk7XG4gIC8vIHNlZSBpZiB1c2VyIGlzIGF1dGhlbnRpY2F0ZWQsIGFuZCByZXR1cm4gY3JlZGVudGlhbHMgaWYgc29cbiAgYXBwLmdldCgnL3VzZXInLCAocmVxLCByZXMpID0+IHtcbiAgICBpZiAocmVxLnVzZXIpIHtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhOiByZXEudXNlcn0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMuc3RhdHVzKDQwMSkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICd1c2VyIGlzIG5vdCBsb2dnZWQgaW4nfSk7XG4gICAgfVxuICB9KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yb3V0ZXMvYXV0aC1yb3V0ZXMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBtdWx0aXBhcnQgPSByZXF1aXJlKCdjb25uZWN0LW11bHRpcGFydHknKTtcbmNvbnN0IHsgZmlsZXMsIHNpdGUgfSA9IHJlcXVpcmUoJy4uL2NvbmZpZy9zcGVlY2hDb25maWcuanMnKTtcbmNvbnN0IG11bHRpcGFydE1pZGRsZXdhcmUgPSBtdWx0aXBhcnQoe3VwbG9hZERpcjogZmlsZXMudXBsb2FkRGlyZWN0b3J5fSk7XG5jb25zdCBkYiA9IHJlcXVpcmUoJy4uL21vZGVscycpO1xuY29uc3QgeyBjbGFpbU5hbWVJc0F2YWlsYWJsZSwgY2hlY2tDaGFubmVsQXZhaWxhYmlsaXR5LCBwdWJsaXNoIH0gPSByZXF1aXJlKCcuLi9jb250cm9sbGVycy9wdWJsaXNoQ29udHJvbGxlci5qcycpO1xuY29uc3QgeyBnZXRDbGFpbUxpc3QsIHJlc29sdmVVcmksIGdldENsYWltIH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2xicnlBcGkuanMnKTtcbmNvbnN0IHsgYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEsIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcywgY3JlYXRlVGh1bWJuYWlsUHVibGlzaFBhcmFtcywgcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEJvZHksIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcywgY3JlYXRlRmlsZURhdGEgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMnKTtcbmNvbnN0IGVycm9ySGFuZGxlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcbmNvbnN0IHsgc2VuZEdBVGltaW5nRXZlbnQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzJyk7XG5jb25zdCB7IGF1dGhlbnRpY2F0ZVVzZXIgfSA9IHJlcXVpcmUoJy4uL2F1dGgvYXV0aGVudGljYXRpb24uanMnKTtcbmNvbnN0IHsgZ2V0Q2hhbm5lbERhdGEsIGdldENoYW5uZWxDbGFpbXMsIGdldENsYWltSWQgfSA9IHJlcXVpcmUoJy4uL2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcycpO1xuXG5jb25zdCBOT19DSEFOTkVMID0gJ05PX0NIQU5ORUwnO1xuY29uc3QgTk9fQ0xBSU0gPSAnTk9fQ0xBSU0nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChhcHApID0+IHtcbiAgLy8gcm91dGUgdG8gY2hlY2sgd2hldGhlciBzaXRlIGhhcyBwdWJsaXNoZWQgdG8gYSBjaGFubmVsXG4gIGFwcC5nZXQoJy9hcGkvY2hhbm5lbC9hdmFpbGFiaWxpdHkvOm5hbWUnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkocGFyYW1zLm5hbWUpXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0ID09PSB0cnVlKSB7XG4gICAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24odHJ1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGdldCBhIHNob3J0IGNoYW5uZWwgaWQgZnJvbSBsb25nIGNoYW5uZWwgSWRcbiAgYXBwLmdldCgnL2FwaS9jaGFubmVsL3Nob3J0LWlkLzpsb25nSWQvOm5hbWUnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBkYi5DZXJ0aWZpY2F0ZS5nZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkKHBhcmFtcy5sb25nSWQsIHBhcmFtcy5uYW1lKVxuICAgICAgLnRoZW4oc2hvcnRJZCA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHNob3J0SWQpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICBhcHAuZ2V0KCcvYXBpL2NoYW5uZWwvZGF0YS86Y2hhbm5lbE5hbWUvOmNoYW5uZWxDbGFpbUlkJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgY2hhbm5lbE5hbWUgPSBwYXJhbXMuY2hhbm5lbE5hbWU7XG4gICAgbGV0IGNoYW5uZWxDbGFpbUlkID0gcGFyYW1zLmNoYW5uZWxDbGFpbUlkO1xuICAgIGlmIChjaGFubmVsQ2xhaW1JZCA9PT0gJ25vbmUnKSBjaGFubmVsQ2xhaW1JZCA9IG51bGw7XG4gICAgZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCAwKVxuICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgIGlmIChkYXRhID09PSBOT19DSEFOTkVMKSB7XG4gICAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ05vIG1hdGNoaW5nIGNoYW5uZWwgd2FzIGZvdW5kJ30pO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIGFwcC5nZXQoJy9hcGkvY2hhbm5lbC9jbGFpbXMvOmNoYW5uZWxOYW1lLzpjaGFubmVsQ2xhaW1JZC86cGFnZScsICh7IGlwLCBvcmlnaW5hbFVybCwgYm9keSwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGNvbnN0IGNoYW5uZWxOYW1lID0gcGFyYW1zLmNoYW5uZWxOYW1lO1xuICAgIGxldCBjaGFubmVsQ2xhaW1JZCA9IHBhcmFtcy5jaGFubmVsQ2xhaW1JZDtcbiAgICBpZiAoY2hhbm5lbENsYWltSWQgPT09ICdub25lJykgY2hhbm5lbENsYWltSWQgPSBudWxsO1xuICAgIGNvbnN0IHBhZ2UgPSBwYXJhbXMucGFnZTtcbiAgICBnZXRDaGFubmVsQ2xhaW1zKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgcGFnZSlcbiAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICBpZiAoZGF0YSA9PT0gTk9fQ0hBTk5FTCkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdObyBtYXRjaGluZyBjaGFubmVsIHdhcyBmb3VuZCd9KTtcbiAgICAgICAgfVxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YX0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBydW4gYSBjbGFpbV9saXN0IHJlcXVlc3Qgb24gdGhlIGRhZW1vblxuICBhcHAuZ2V0KCcvYXBpL2NsYWltL2xpc3QvOm5hbWUnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBnZXRDbGFpbUxpc3QocGFyYW1zLm5hbWUpXG4gICAgICAudGhlbihjbGFpbXNMaXN0ID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oY2xhaW1zTGlzdCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGdldCBhbiBhc3NldFxuICBhcHAuZ2V0KCcvYXBpL2NsYWltL2dldC86bmFtZS86Y2xhaW1JZCcsICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGNvbnN0IG5hbWUgPSBwYXJhbXMubmFtZTtcbiAgICBjb25zdCBjbGFpbUlkID0gcGFyYW1zLmNsYWltSWQ7XG4gICAgLy8gcmVzb2x2ZSB0aGUgY2xhaW1cbiAgICBkYi5DbGFpbS5yZXNvbHZlQ2xhaW0obmFtZSwgY2xhaW1JZClcbiAgICAgIC50aGVuKHJlc29sdmVSZXN1bHQgPT4ge1xuICAgICAgICAvLyBtYWtlIHN1cmUgYSBjbGFpbSBhY3R1YWxseSBleGlzdHMgYXQgdGhhdCB1cmlcbiAgICAgICAgaWYgKCFyZXNvbHZlUmVzdWx0KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBtYXRjaGluZyB1cmkgZm91bmQgaW4gQ2xhaW0gdGFibGUnKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZmlsZURhdGEgPSBjcmVhdGVGaWxlRGF0YShyZXNvbHZlUmVzdWx0KTtcbiAgICAgICAgLy8gZ2V0IHRoZSBjbGFpbVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2ZpbGVEYXRhLCBnZXRDbGFpbShgJHtuYW1lfSMke2NsYWltSWR9YCldKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoWyBmaWxlRGF0YSwgZ2V0UmVzdWx0IF0pID0+IHtcbiAgICAgICAgZmlsZURhdGEgPSBhZGRHZXRSZXN1bHRzVG9GaWxlRGF0YShmaWxlRGF0YSwgZ2V0UmVzdWx0KTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtkYi51cHNlcnQoZGIuRmlsZSwgZmlsZURhdGEsIHtuYW1lLCBjbGFpbUlkfSwgJ0ZpbGUnKSwgZ2V0UmVzdWx0XSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKFsgZmlsZVJlY29yZCwge21lc3NhZ2UsIGNvbXBsZXRlZH0gXSkgPT4ge1xuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7IHN1Y2Nlc3M6IHRydWUsIG1lc3NhZ2UsIGNvbXBsZXRlZCB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gY2hlY2sgd2hldGhlciB0aGlzIHNpdGUgcHVibGlzaGVkIHRvIGEgY2xhaW1cbiAgYXBwLmdldCgnL2FwaS9jbGFpbS9hdmFpbGFiaWxpdHkvOm5hbWUnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBjbGFpbU5hbWVJc0F2YWlsYWJsZShwYXJhbXMubmFtZSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHJlc3VsdCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIHJ1biBhIHJlc29sdmUgcmVxdWVzdCBvbiB0aGUgZGFlbW9uXG4gIGFwcC5nZXQoJy9hcGkvY2xhaW0vcmVzb2x2ZS86bmFtZS86Y2xhaW1JZCcsICh7IGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIHJlc29sdmVVcmkoYCR7cGFyYW1zLm5hbWV9IyR7cGFyYW1zLmNsYWltSWR9YClcbiAgICAgIC50aGVuKHJlc29sdmVkVXJpID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24ocmVzb2x2ZWRVcmkpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBydW4gYSBwdWJsaXNoIHJlcXVlc3Qgb24gdGhlIGRhZW1vblxuICBhcHAucG9zdCgnL2FwaS9jbGFpbS9wdWJsaXNoJywgbXVsdGlwYXJ0TWlkZGxld2FyZSwgKHsgYm9keSwgZmlsZXMsIGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgdXNlciB9LCByZXMpID0+IHtcbiAgICBsb2dnZXIuZGVidWcoJ2FwaS9jbGFpbS9wdWJsaXNoIHJlcS5ib2R5OicsIGJvZHkpO1xuICAgIGxvZ2dlci5kZWJ1ZygnYXBpL2NsYWltL3B1Ymxpc2ggcmVxLmZpbGVzOicsIGZpbGVzKTtcbiAgICAvLyBkZWZpbmUgdmFyaWFibGVzXG4gICAgbGV0ICBjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBjaGFubmVsUGFzc3dvcmQsIGRlc2NyaXB0aW9uLCBmaWxlTmFtZSwgZmlsZVBhdGgsIGZpbGVUeXBlLCBnYVN0YXJ0VGltZSwgbGljZW5zZSwgbmFtZSwgbnNmdywgdGh1bWJuYWlsLCB0aHVtYm5haWxGaWxlTmFtZSwgdGh1bWJuYWlsRmlsZVBhdGgsIHRodW1ibmFpbEZpbGVUeXBlLCB0aXRsZTtcbiAgICAvLyByZWNvcmQgdGhlIHN0YXJ0IHRpbWUgb2YgdGhlIHJlcXVlc3RcbiAgICBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgLy8gdmFsaWRhdGUgdGhlIGJvZHkgYW5kIGZpbGVzIG9mIHRoZSByZXF1ZXN0XG4gICAgdHJ5IHtcbiAgICAgIC8vIHZhbGlkYXRlQXBpUHVibGlzaFJlcXVlc3QoYm9keSwgZmlsZXMpO1xuICAgICAgKHtuYW1lLCBuc2Z3LCBsaWNlbnNlLCB0aXRsZSwgZGVzY3JpcHRpb24sIHRodW1ibmFpbH0gPSBwYXJzZVB1Ymxpc2hBcGlSZXF1ZXN0Qm9keShib2R5KSk7XG4gICAgICAoe2ZpbGVOYW1lLCBmaWxlUGF0aCwgZmlsZVR5cGUsIHRodW1ibmFpbEZpbGVOYW1lLCB0aHVtYm5haWxGaWxlUGF0aCwgdGh1bWJuYWlsRmlsZVR5cGV9ID0gcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEZpbGVzKGZpbGVzKSk7XG4gICAgICAoe2NoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZH0gPSBib2R5KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZX0pO1xuICAgIH1cbiAgICAvLyBjaGVjayBjaGFubmVsIGF1dGhvcml6YXRpb25cbiAgICBQcm9taXNlLmFsbChbXG4gICAgICBhdXRoZW50aWNhdGVVc2VyKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCwgdXNlciksXG4gICAgICBjbGFpbU5hbWVJc0F2YWlsYWJsZShuYW1lKSxcbiAgICAgIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcyhmaWxlUGF0aCwgbmFtZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCBsaWNlbnNlLCBuc2Z3LCB0aHVtYm5haWwpLFxuICAgICAgY3JlYXRlVGh1bWJuYWlsUHVibGlzaFBhcmFtcyh0aHVtYm5haWxGaWxlUGF0aCwgbmFtZSwgbGljZW5zZSwgbnNmdyksXG4gICAgXSlcbiAgICAgIC50aGVuKChbe2NoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZH0sIHZhbGlkYXRlZENsYWltTmFtZSwgcHVibGlzaFBhcmFtcywgdGh1bWJuYWlsUHVibGlzaFBhcmFtc10pID0+IHtcbiAgICAgICAgLy8gYWRkIGNoYW5uZWwgZGV0YWlscyB0byB0aGUgcHVibGlzaCBwYXJhbXNcbiAgICAgICAgaWYgKGNoYW5uZWxOYW1lICYmIGNoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgICAgcHVibGlzaFBhcmFtc1snY2hhbm5lbF9uYW1lJ10gPSBjaGFubmVsTmFtZTtcbiAgICAgICAgICBwdWJsaXNoUGFyYW1zWydjaGFubmVsX2lkJ10gPSBjaGFubmVsQ2xhaW1JZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBwdWJsaXNoIHRoZSB0aHVtYm5haWxcbiAgICAgICAgaWYgKHRodW1ibmFpbFB1Ymxpc2hQYXJhbXMpIHtcbiAgICAgICAgICBwdWJsaXNoKHRodW1ibmFpbFB1Ymxpc2hQYXJhbXMsIHRodW1ibmFpbEZpbGVOYW1lLCB0aHVtYm5haWxGaWxlVHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcHVibGlzaCB0aGUgYXNzZXRcbiAgICAgICAgcmV0dXJuIHB1Ymxpc2gocHVibGlzaFBhcmFtcywgZmlsZU5hbWUsIGZpbGVUeXBlKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBtZXNzYWdlOiAncHVibGlzaCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICBkYXRhICAgOiB7XG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgY2xhaW1JZDogcmVzdWx0LmNsYWltX2lkLFxuICAgICAgICAgICAgdXJsICAgIDogYCR7c2l0ZS5ob3N0fS8ke3Jlc3VsdC5jbGFpbV9pZH0vJHtuYW1lfWAsXG4gICAgICAgICAgICBsYnJ5VHggOiByZXN1bHQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHJlY29yZCB0aGUgcHVibGlzaCBlbmQgdGltZSBhbmQgc2VuZCB0byBnb29nbGUgYW5hbHl0aWNzXG4gICAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdlbmQtdG8tZW5kJywgJ3B1Ymxpc2gnLCBmaWxlVHlwZSwgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBnZXQgYSBzaG9ydCBjbGFpbSBpZCBmcm9tIGxvbmcgY2xhaW0gSWRcbiAgYXBwLmdldCgnL2FwaS9jbGFpbS9zaG9ydC1pZC86bG9uZ0lkLzpuYW1lJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgZGIuQ2xhaW0uZ2V0U2hvcnRDbGFpbUlkRnJvbUxvbmdDbGFpbUlkKHBhcmFtcy5sb25nSWQsIHBhcmFtcy5uYW1lKVxuICAgICAgLnRoZW4oc2hvcnRJZCA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhOiBzaG9ydElkfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIGFwcC5wb3N0KCcvYXBpL2NsYWltL2xvbmctaWQnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBsb2dnZXIuZGVidWcoJ2JvZHk6JywgYm9keSk7XG4gICAgY29uc3QgY2hhbm5lbE5hbWUgPSBib2R5LmNoYW5uZWxOYW1lO1xuICAgIGNvbnN0IGNoYW5uZWxDbGFpbUlkID0gYm9keS5jaGFubmVsQ2xhaW1JZDtcbiAgICBjb25zdCBjbGFpbU5hbWUgPSBib2R5LmNsYWltTmFtZTtcbiAgICBjb25zdCBjbGFpbUlkID0gYm9keS5jbGFpbUlkO1xuICAgIGdldENsYWltSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbU5hbWUsIGNsYWltSWQpXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0ID09PSBOT19DSEFOTkVMKSB7XG4gICAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ05vIG1hdGNoaW5nIGNoYW5uZWwgY291bGQgYmUgZm91bmQnfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gTk9fQ0xBSU0pIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gbWF0Y2hpbmcgY2xhaW0gaWQgY291bGQgYmUgZm91bmQnfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHJlc3VsdH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICBhcHAuZ2V0KCcvYXBpL2NsYWltL2RhdGEvOmNsYWltTmFtZS86Y2xhaW1JZCcsICh7IGlwLCBvcmlnaW5hbFVybCwgYm9keSwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGNvbnN0IGNsYWltTmFtZSA9IHBhcmFtcy5jbGFpbU5hbWU7XG4gICAgbGV0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcbiAgICBpZiAoY2xhaW1JZCA9PT0gJ25vbmUnKSBjbGFpbUlkID0gbnVsbDtcbiAgICBkYi5DbGFpbS5yZXNvbHZlQ2xhaW0oY2xhaW1OYW1lLCBjbGFpbUlkKVxuICAgICAgLnRoZW4oY2xhaW1JbmZvID0+IHtcbiAgICAgICAgaWYgKCFjbGFpbUluZm8pIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gY2xhaW0gY291bGQgYmUgZm91bmQnfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IGNsYWltSW5mb30pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBzZWUgaWYgYXNzZXQgaXMgYXZhaWxhYmxlIGxvY2FsbHlcbiAgYXBwLmdldCgnL2FwaS9maWxlL2F2YWlsYWJpbGl0eS86bmFtZS86Y2xhaW1JZCcsICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGNvbnN0IG5hbWUgPSBwYXJhbXMubmFtZTtcbiAgICBjb25zdCBjbGFpbUlkID0gcGFyYW1zLmNsYWltSWQ7XG4gICAgZGIuRmlsZS5maW5kT25lKHt3aGVyZToge25hbWUsIGNsYWltSWR9fSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHRydWV9KTtcbiAgICAgICAgfVxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogZmFsc2V9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yb3V0ZXMvYXBpLXJvdXRlcy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNvbm5lY3QtbXVsdGlwYXJ0eVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImNvbm5lY3QtbXVsdGlwYXJ0eVwiXG4vLyBtb2R1bGUgaWQgPSA2OVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJzZXF1ZWxpemVcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJzZXF1ZWxpemVcIlxuLy8gbW9kdWxlIGlkID0gNzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyByZXR1cm5TaG9ydElkIH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL3NlcXVlbGl6ZUhlbHBlcnMuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgSU5URUdFUiwgVEVYVCwgREVDSU1BTCB9KSA9PiB7XG4gIGNvbnN0IENlcnRpZmljYXRlID0gc2VxdWVsaXplLmRlZmluZShcbiAgICAnQ2VydGlmaWNhdGUnLFxuICAgIHtcbiAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGFtb3VudDoge1xuICAgICAgICB0eXBlICAgOiBERUNJTUFMKDE5LCA4KSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbVNlcXVlbmNlOiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVjb2RlZENsYWltOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVwdGg6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBlZmZlY3RpdmVBbW91bnQ6IHtcbiAgICAgICAgdHlwZSAgIDogREVDSU1BTCgxOSwgOCksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGFzU2lnbmF0dXJlOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGV4OiB7XG4gICAgICAgIHR5cGUgICA6IFRFWFQoJ2xvbmcnKSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBuYW1lOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBub3V0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdHhpZDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdmFsaWRBdEhlaWdodDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG91dHBvaW50OiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB2YWx1ZVZlcnNpb246IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNsYWltVHlwZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2VydGlmaWNhdGVWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBrZXlUeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBwdWJsaWNLZXk6IHtcbiAgICAgICAgdHlwZSAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgQ2VydGlmaWNhdGUuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIENlcnRpZmljYXRlLmJlbG9uZ3NUbyhkYi5DaGFubmVsLCB7XG4gICAgICBmb3JlaWduS2V5OiB7XG4gICAgICAgIGFsbG93TnVsbDogdHJ1ZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG5cbiAgQ2VydGlmaWNhdGUuZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChsb25nQ2hhbm5lbElkLCBjaGFubmVsTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZCAke2NoYW5uZWxOYW1lfToke2xvbmdDaGFubmVsSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7bmFtZTogY2hhbm5lbE5hbWV9LFxuICAgICAgICAgIG9yZGVyOiBbWydoZWlnaHQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNoYW5uZWwocykgZm91bmQgd2l0aCB0aGF0IGNoYW5uZWwgbmFtZScpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmV0dXJuU2hvcnRJZChyZXN1bHQsIGxvbmdDaGFubmVsSWQpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZCA9IGZ1bmN0aW9uIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDaGFubmVsSWRGcm9tU2hvcnRDaGFubmVsSWQoJHtjaGFubmVsTmFtZX0sICR7Y2hhbm5lbENsYWltSWR9KWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZToge1xuICAgICAgICAgICAgbmFtZSAgIDogY2hhbm5lbE5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkOiB7XG4gICAgICAgICAgICAgICRsaWtlOiBgJHtjaGFubmVsQ2xhaW1JZH0lYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvcmRlcjogW1snaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OiAvLyBub3RlIHJlc3VsdHMgbXVzdCBiZSBzb3J0ZWRcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkRnJvbUNoYW5uZWxOYW1lID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBnZXRMb25nQ2hhbm5lbElkRnJvbUNoYW5uZWxOYW1lKCR7Y2hhbm5lbE5hbWV9KWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZTogeyBuYW1lOiBjaGFubmVsTmFtZSB9LFxuICAgICAgICAgIG9yZGVyOiBbWydlZmZlY3RpdmVBbW91bnQnLCAnREVTQyddLCBbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS52YWxpZGF0ZUxvbmdDaGFubmVsSWQgPSBmdW5jdGlvbiAobmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgdmFsaWRhdGVMb25nQ2hhbm5lbElkKCR7bmFtZX0sICR7Y2xhaW1JZH0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZmluZE9uZSh7XG4gICAgICAgIHdoZXJlOiB7bmFtZSwgY2xhaW1JZH0sXG4gICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc29sdmUoY2xhaW1JZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDaGFubmVsSWQoJHtjaGFubmVsTmFtZX0sICR7Y2hhbm5lbENsYWltSWR9KWApO1xuICAgIGlmIChjaGFubmVsQ2xhaW1JZCAmJiAoY2hhbm5lbENsYWltSWQubGVuZ3RoID09PSA0MCkpIHsgIC8vIGlmIGEgZnVsbCBjaGFubmVsIGlkIGlzIHByb3ZpZGVkXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUxvbmdDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5uZWxDbGFpbUlkICYmIGNoYW5uZWxDbGFpbUlkLmxlbmd0aCA8IDQwKSB7ICAvLyBpZiBhIHNob3J0IGNoYW5uZWwgaWQgaXMgcHJvdmlkZWRcbiAgICAgIHJldHVybiB0aGlzLmdldExvbmdDaGFubmVsSWRGcm9tU2hvcnRDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9uZ0NoYW5uZWxJZEZyb21DaGFubmVsTmFtZShjaGFubmVsTmFtZSk7ICAvLyBpZiBubyBjaGFubmVsIGlkIHByb3ZpZGVkXG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBDZXJ0aWZpY2F0ZTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9tb2RlbHMvY2VydGlmaWNhdGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HIH0pID0+IHtcbiAgY29uc3QgQ2hhbm5lbCA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ0NoYW5uZWwnLFxuICAgIHtcbiAgICAgIGNoYW5uZWxOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGNoYW5uZWxDbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgQ2hhbm5lbC5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2hhbm5lbC5iZWxvbmdzVG8oZGIuVXNlcik7XG4gICAgQ2hhbm5lbC5oYXNPbmUoZGIuQ2VydGlmaWNhdGUpO1xuICB9O1xuXG4gIHJldHVybiBDaGFubmVsO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL21vZGVscy9jaGFubmVsLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyByZXR1cm5TaG9ydElkIH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL3NlcXVlbGl6ZUhlbHBlcnMuanMnKTtcbmNvbnN0IHsgY2xhaW0sIHNpdGUgfSA9IHJlcXVpcmUoJy4uL2NvbmZpZy9zcGVlY2hDb25maWcuanMnKTtcbmNvbnN0IHsgZGVmYXVsdFRodW1ibmFpbCB9ID0gY2xhaW07XG5cbmZ1bmN0aW9uIGRldGVybWluZUZpbGVFeHRlbnNpb25Gcm9tQ29udGVudFR5cGUgKGNvbnRlbnRUeXBlKSB7XG4gIHN3aXRjaCAoY29udGVudFR5cGUpIHtcbiAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICBjYXNlICdpbWFnZS9qcGcnOlxuICAgICAgcmV0dXJuICdqcGVnJztcbiAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgcmV0dXJuICdwbmcnO1xuICAgIGNhc2UgJ2ltYWdlL2dpZic6XG4gICAgICByZXR1cm4gJ2dpZic7XG4gICAgY2FzZSAndmlkZW8vbXA0JzpcbiAgICAgIHJldHVybiAnbXA0JztcbiAgICBkZWZhdWx0OlxuICAgICAgbG9nZ2VyLmRlYnVnKCdzZXR0aW5nIHVua25vd24gZmlsZSB0eXBlIGFzIGZpbGUgZXh0ZW5zaW9uIGpwZWcnKTtcbiAgICAgIHJldHVybiAnanBlZyc7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGRldGVybWluZVRodW1ibmFpbCAoc3RvcmVkVGh1bWJuYWlsLCBkZWZhdWx0VGh1bWJuYWlsKSB7XG4gIGlmIChzdG9yZWRUaHVtYm5haWwgPT09ICcnKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRUaHVtYm5haWw7XG4gIH1cbiAgcmV0dXJuIHN0b3JlZFRodW1ibmFpbDtcbn07XG5cbmZ1bmN0aW9uIHByZXBhcmVDbGFpbURhdGEgKGNsYWltKSB7XG4gIC8vIGxvZ2dlci5kZWJ1ZygncHJlcGFyaW5nIGNsYWltIGRhdGEgYmFzZWQgb24gcmVzb2x2ZWQgZGF0YTonLCBjbGFpbSk7XG4gIGNsYWltWyd0aHVtYm5haWwnXSA9IGRldGVybWluZVRodW1ibmFpbChjbGFpbS50aHVtYm5haWwsIGRlZmF1bHRUaHVtYm5haWwpO1xuICBjbGFpbVsnZmlsZUV4dCddID0gZGV0ZXJtaW5lRmlsZUV4dGVuc2lvbkZyb21Db250ZW50VHlwZShjbGFpbS5jb250ZW50VHlwZSk7XG4gIGNsYWltWydob3N0J10gPSBzaXRlLmhvc3Q7XG4gIHJldHVybiBjbGFpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gKHNlcXVlbGl6ZSwgeyBTVFJJTkcsIEJPT0xFQU4sIElOVEVHRVIsIFRFWFQsIERFQ0lNQUwgfSkgPT4ge1xuICBjb25zdCBDbGFpbSA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ0NsYWltJyxcbiAgICB7XG4gICAgICBhZGRyZXNzOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBhbW91bnQ6IHtcbiAgICAgICAgdHlwZSAgIDogREVDSU1BTCgxOSwgOCksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1JZDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1TZXF1ZW5jZToge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGRlY29kZWRDbGFpbToge1xuICAgICAgICB0eXBlICAgOiBCT09MRUFOLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGRlcHRoOiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZWZmZWN0aXZlQW1vdW50OiB7XG4gICAgICAgIHR5cGUgICA6IERFQ0lNQUwoMTksIDgpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGhhc1NpZ25hdHVyZToge1xuICAgICAgICB0eXBlICAgOiBCT09MRUFOLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGhlaWdodDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGhleDoge1xuICAgICAgICB0eXBlICAgOiBURVhUKCdsb25nJyksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbmFtZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbm91dDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHR4aWQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHZhbGlkQXRIZWlnaHQ6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBvdXRwb2ludDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1UeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjZXJ0aWZpY2F0ZUlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBhdXRob3I6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGRlc2NyaXB0aW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFRFWFQoJ2xvbmcnKSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBsYW5ndWFnZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbGljZW5zZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbGljZW5zZVVybDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbnNmdzoge1xuICAgICAgICB0eXBlICAgOiBCT09MRUFOLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHByZXZpZXc6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHRodW1ibmFpbDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdGl0bGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG1ldGFkYXRhVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY29udGVudFR5cGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHNvdXJjZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc291cmNlVHlwZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc291cmNlVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc3RyZWFtVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdmFsdWVWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjaGFubmVsTmFtZToge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgICBkZWZhdWx0ICA6IG51bGwsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBDbGFpbS5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2xhaW0uYmVsb25nc1RvKGRiLkZpbGUsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRTaG9ydENsYWltSWRGcm9tTG9uZ0NsYWltSWQgPSBmdW5jdGlvbiAoY2xhaW1JZCwgY2xhaW1OYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbGFpbS5nZXRTaG9ydENsYWltSWRGcm9tTG9uZ0NsYWltSWQgZm9yICR7Y2xhaW1OYW1lfSMke2NsYWltSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWU6IGNsYWltTmFtZSB9LFxuICAgICAgICAgIG9yZGVyOiBbWydoZWlnaHQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNsYWltKHMpIGZvdW5kIHdpdGggdGhhdCBjbGFpbSBuYW1lJyk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXNvbHZlKHJldHVyblNob3J0SWQocmVzdWx0LCBjbGFpbUlkKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldEFsbENoYW5uZWxDbGFpbXMgPSBmdW5jdGlvbiAoY2hhbm5lbENsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYENsYWltLmdldEFsbENoYW5uZWxDbGFpbXMgZm9yICR7Y2hhbm5lbENsYWltSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IGNlcnRpZmljYXRlSWQ6IGNoYW5uZWxDbGFpbUlkIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgICAgcmF3ICA6IHRydWUsICAvLyByZXR1cm5zIGFuIGFycmF5IG9mIG9ubHkgZGF0YSwgbm90IGFuIGFycmF5IG9mIGluc3RhbmNlc1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihjaGFubmVsQ2xhaW1zQXJyYXkgPT4ge1xuICAgICAgICAgIC8vIGxvZ2dlci5kZWJ1ZygnY2hhbm5lbGNsYWltc2FycmF5IGxlbmd0aDonLCBjaGFubmVsQ2xhaW1zQXJyYXkubGVuZ3RoKTtcbiAgICAgICAgICBzd2l0Y2ggKGNoYW5uZWxDbGFpbXNBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBjaGFubmVsQ2xhaW1zQXJyYXkuZm9yRWFjaChjbGFpbSA9PiB7XG4gICAgICAgICAgICAgICAgY2xhaW1bJ2ZpbGVFeHQnXSA9IGRldGVybWluZUZpbGVFeHRlbnNpb25Gcm9tQ29udGVudFR5cGUoY2xhaW0uY29udGVudFR5cGUpO1xuICAgICAgICAgICAgICAgIGNsYWltWyd0aHVtYm5haWwnXSA9IGRldGVybWluZVRodW1ibmFpbChjbGFpbS50aHVtYm5haWwsIGRlZmF1bHRUaHVtYm5haWwpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjbGFpbTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGNoYW5uZWxDbGFpbXNBcnJheSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldENsYWltSWRCeUxvbmdDaGFubmVsSWQgPSBmdW5jdGlvbiAoY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZmluZGluZyBjbGFpbSBpZCBmb3IgY2xhaW0gJHtjbGFpbU5hbWV9IGZyb20gY2hhbm5lbCAke2NoYW5uZWxDbGFpbUlkfWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZTogeyBuYW1lOiBjbGFpbU5hbWUsIGNlcnRpZmljYXRlSWQ6IGNoYW5uZWxDbGFpbUlkIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2lkJywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdFswXS5jbGFpbUlkKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgJHtyZXN1bHQubGVuZ3RofSByZWNvcmRzIGZvdW5kIGZvciBcIiR7Y2xhaW1OYW1lfVwiIGluIGNoYW5uZWwgXCIke2NoYW5uZWxDbGFpbUlkfVwiYCk7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdFswXS5jbGFpbUlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0TG9uZ0NsYWltSWRGcm9tU2hvcnRDbGFpbUlkID0gZnVuY3Rpb24gKG5hbWUsIHNob3J0SWQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkOiB7XG4gICAgICAgICAgICAgICRsaWtlOiBgJHtzaG9ydElkfSVgLFxuICAgICAgICAgICAgfX0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgZGVmYXVsdDogLy8gbm90ZSByZXN1bHRzIG11c3QgYmUgc29ydGVkXG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdFswXS5jbGFpbUlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0VG9wRnJlZUNsYWltSWRCeUNsYWltTmFtZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWUgfSxcbiAgICAgICAgICBvcmRlcjogW1snZWZmZWN0aXZlQW1vdW50JywgJ0RFU0MnXSwgWydoZWlnaHQnLCAnQVNDJ11dLCAgLy8gbm90ZTogbWF5YmUgaGVpZ2h0IGFuZCBlZmZlY3RpdmUgYW1vdW50IG5lZWQgdG8gc3dpdGNoP1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnbGVuZ3RoIG9mIHJlc3VsdCcsIHJlc3VsdC5sZW5ndGgpO1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdFswXS5kYXRhVmFsdWVzLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS52YWxpZGF0ZUxvbmdDbGFpbUlkID0gZnVuY3Rpb24gKG5hbWUsIGNsYWltSWQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5maW5kT25lKHtcbiAgICAgICAgd2hlcmU6IHtuYW1lLCBjbGFpbUlkfSxcbiAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgcmVzb2x2ZShjbGFpbUlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRMb25nQ2xhaW1JZCA9IGZ1bmN0aW9uIChjbGFpbU5hbWUsIGNsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDbGFpbUlkKCR7Y2xhaW1OYW1lfSwgJHtjbGFpbUlkfSlgKTtcbiAgICBpZiAoY2xhaW1JZCAmJiAoY2xhaW1JZC5sZW5ndGggPT09IDQwKSkgeyAgLy8gaWYgYSBmdWxsIGNsYWltIGlkIGlzIHByb3ZpZGVkXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUxvbmdDbGFpbUlkKGNsYWltTmFtZSwgY2xhaW1JZCk7XG4gICAgfSBlbHNlIGlmIChjbGFpbUlkICYmIGNsYWltSWQubGVuZ3RoIDwgNDApIHtcbiAgICAgIHJldHVybiB0aGlzLmdldExvbmdDbGFpbUlkRnJvbVNob3J0Q2xhaW1JZChjbGFpbU5hbWUsIGNsYWltSWQpOyAgLy8gaWYgYSBzaG9ydCBjbGFpbSBpZCBpcyBwcm92aWRlZFxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUb3BGcmVlQ2xhaW1JZEJ5Q2xhaW1OYW1lKGNsYWltTmFtZSk7ICAvLyBpZiBubyBjbGFpbSBpZCBpcyBwcm92aWRlZFxuICAgIH1cbiAgfTtcblxuICBDbGFpbS5yZXNvbHZlQ2xhaW0gPSBmdW5jdGlvbiAobmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xhaW0ucmVzb2x2ZUNsYWltOiAke25hbWV9ICR7Y2xhaW1JZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgbmFtZSwgY2xhaW1JZCB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihjbGFpbUFycmF5ID0+IHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ2NsYWltcyBmb3VuZCBvbiByZXNvbHZlOicsIGNsYWltQXJyYXkubGVuZ3RoKTtcbiAgICAgICAgICBzd2l0Y2ggKGNsYWltQXJyYXkubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShwcmVwYXJlQ2xhaW1EYXRhKGNsYWltQXJyYXlbMF0uZGF0YVZhbHVlcykpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBtb3JlIHRoYW4gb25lIGVudHJ5IG1hdGNoZXMgdGhhdCBuYW1lICgke25hbWV9KSBhbmQgY2xhaW1JRCAoJHtjbGFpbUlkfSlgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocHJlcGFyZUNsYWltRGF0YShjbGFpbUFycmF5WzBdLmRhdGFWYWx1ZXMpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIENsYWltO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL21vZGVscy9jbGFpbS5qcyIsIm1vZHVsZS5leHBvcnRzID0gKHNlcXVlbGl6ZSwgeyBTVFJJTkcsIEJPT0xFQU4sIElOVEVHRVIgfSkgPT4ge1xuICBjb25zdCBGaWxlID0gc2VxdWVsaXplLmRlZmluZShcbiAgICAnRmlsZScsXG4gICAge1xuICAgICAgbmFtZToge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBjbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgb3V0cG9pbnQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgaGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICAgIDogSU5URUdFUixcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgICAgZGVmYXVsdCAgOiAwLFxuICAgICAgfSxcbiAgICAgIGZpbGVOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGZpbGVQYXRoOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGZpbGVUeXBlOiB7XG4gICAgICAgIHR5cGU6IFNUUklORyxcbiAgICAgIH0sXG4gICAgICBuc2Z3OiB7XG4gICAgICAgIHR5cGUgICAgICAgIDogQk9PTEVBTixcbiAgICAgICAgYWxsb3dOdWxsICAgOiBmYWxzZSxcbiAgICAgICAgZGVmYXVsdFZhbHVlOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICB0cmVuZGluZ0VsaWdpYmxlOiB7XG4gICAgICAgIHR5cGUgICAgICAgIDogQk9PTEVBTixcbiAgICAgICAgYWxsb3dOdWxsICAgOiBmYWxzZSxcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB0cnVlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgRmlsZS5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgRmlsZS5oYXNNYW55KGRiLlJlcXVlc3QpO1xuICAgIEZpbGUuaGFzT25lKGRiLkNsYWltKTtcbiAgfTtcblxuICBGaWxlLmdldFJlY2VudENsYWltcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5kQWxsKHtcbiAgICAgIHdoZXJlOiB7IG5zZnc6IGZhbHNlLCB0cmVuZGluZ0VsaWdpYmxlOiB0cnVlIH0sXG4gICAgICBvcmRlcjogW1snY3JlYXRlZEF0JywgJ0RFU0MnXV0sXG4gICAgICBsaW1pdDogMjUsXG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIEZpbGU7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vbW9kZWxzL2ZpbGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HLCBCT09MRUFOLCBURVhUIH0pID0+IHtcbiAgY29uc3QgUmVxdWVzdCA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ1JlcXVlc3QnLFxuICAgIHtcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICB1cmw6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgaXBBZGRyZXNzOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICB9LFxuICAgICAgcmVzdWx0OiB7XG4gICAgICAgIHR5cGUgICAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICAgIGRlZmF1bHQgIDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIFJlcXVlc3QuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIFJlcXVlc3QuYmVsb25nc1RvKGRiLkZpbGUsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gUmVxdWVzdDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9tb2RlbHMvcmVxdWVzdC5qcyIsIid1c2Ugc3RyaWN0JztcbmNvbnN0IGJjcnlwdCA9IHJlcXVpcmUoJ2JjcnlwdCcpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HIH0pID0+IHtcbiAgY29uc3QgVXNlciA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ1VzZXInLFxuICAgIHtcbiAgICAgIHVzZXJOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIHBhc3N3b3JkOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgVXNlci5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgVXNlci5oYXNPbmUoZGIuQ2hhbm5lbCk7XG4gIH07XG5cbiAgVXNlci5wcm90b3R5cGUuY29tcGFyZVBhc3N3b3JkID0gZnVuY3Rpb24gKHBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIGJjcnlwdC5jb21wYXJlKHBhc3N3b3JkLCB0aGlzLnBhc3N3b3JkKTtcbiAgfTtcblxuICBVc2VyLnByb3RvdHlwZS5jaGFuZ2VQYXNzd29yZCA9IGZ1bmN0aW9uIChuZXdQYXNzd29yZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBnZW5lcmF0ZSBhIHNhbHQgc3RyaW5nIHRvIHVzZSBmb3IgaGFzaGluZ1xuICAgICAgYmNyeXB0LmdlblNhbHQoKHNhbHRFcnJvciwgc2FsdCkgPT4ge1xuICAgICAgICBpZiAoc2FsdEVycm9yKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdzYWx0IGVycm9yJywgc2FsdEVycm9yKTtcbiAgICAgICAgICByZWplY3Qoc2FsdEVycm9yKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2VuZXJhdGUgYSBoYXNoZWQgdmVyc2lvbiBvZiB0aGUgdXNlcidzIHBhc3N3b3JkXG4gICAgICAgIGJjcnlwdC5oYXNoKG5ld1Bhc3N3b3JkLCBzYWx0LCAoaGFzaEVycm9yLCBoYXNoKSA9PiB7XG4gICAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW4gZXJyb3Igd2l0aCB0aGUgaGFzaCBnZW5lcmF0aW9uIHJldHVybiB0aGUgZXJyb3JcbiAgICAgICAgICBpZiAoaGFzaEVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ2hhc2ggZXJyb3InLCBoYXNoRXJyb3IpO1xuICAgICAgICAgICAgcmVqZWN0KGhhc2hFcnJvcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHJlcGxhY2UgdGhlIGN1cnJlbnQgcGFzc3dvcmQgd2l0aCB0aGUgbmV3IGhhc2hcbiAgICAgICAgICB0aGlzXG4gICAgICAgICAgICAudXBkYXRlKHtwYXNzd29yZDogaGFzaH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8gcHJlLXNhdmUgaG9vayBtZXRob2QgdG8gaGFzaCB0aGUgdXNlcidzIHBhc3N3b3JkIGJlZm9yZSB0aGUgdXNlcidzIGluZm8gaXMgc2F2ZWQgdG8gdGhlIGRiLlxuICBVc2VyLmhvb2soJ2JlZm9yZUNyZWF0ZScsICh1c2VyLCBvcHRpb25zKSA9PiB7XG4gICAgbG9nZ2VyLmRlYnVnKCdVc2VyLmJlZm9yZUNyZWF0ZSBob29rLi4uJyk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIGdlbmVyYXRlIGEgc2FsdCBzdHJpbmcgdG8gdXNlIGZvciBoYXNoaW5nXG4gICAgICBiY3J5cHQuZ2VuU2FsdCgoc2FsdEVycm9yLCBzYWx0KSA9PiB7XG4gICAgICAgIGlmIChzYWx0RXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ3NhbHQgZXJyb3InLCBzYWx0RXJyb3IpO1xuICAgICAgICAgIHJlamVjdChzYWx0RXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBnZW5lcmF0ZSBhIGhhc2hlZCB2ZXJzaW9uIG9mIHRoZSB1c2VyJ3MgcGFzc3dvcmRcbiAgICAgICAgYmNyeXB0Lmhhc2godXNlci5wYXNzd29yZCwgc2FsdCwgKGhhc2hFcnJvciwgaGFzaCkgPT4ge1xuICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIGVycm9yIHdpdGggdGhlIGhhc2ggZ2VuZXJhdGlvbiByZXR1cm4gdGhlIGVycm9yXG4gICAgICAgICAgaWYgKGhhc2hFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdoYXNoIGVycm9yJywgaGFzaEVycm9yKTtcbiAgICAgICAgICAgIHJlamVjdChoYXNoRXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyByZXBsYWNlIHRoZSBwYXNzd29yZCBzdHJpbmcgd2l0aCB0aGUgaGFzaCBwYXNzd29yZCB2YWx1ZVxuICAgICAgICAgIHVzZXIucGFzc3dvcmQgPSBoYXNoO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgcmV0dXJuIFVzZXI7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vbW9kZWxzL3VzZXIuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJiY3J5cHRcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJiY3J5cHRcIlxuLy8gbW9kdWxlIGlkID0gNzdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgZGIgPSByZXF1aXJlKCcuLi9tb2RlbHMnKTtcbmNvbnN0IGxicnlBcGkgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2xicnlBcGkuanMnKTtcbmNvbnN0IHB1Ymxpc2hIZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9wdWJsaXNoSGVscGVycy5qcycpO1xuY29uc3QgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnL3NwZWVjaENvbmZpZy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcHVibGlzaCAocHVibGlzaFBhcmFtcywgZmlsZU5hbWUsIGZpbGVUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBwdWJsaXNoUmVzdWx0cywgY2VydGlmaWNhdGVJZCwgY2hhbm5lbE5hbWU7XG4gICAgICAvLyBwdWJsaXNoIHRoZSBmaWxlXG4gICAgICByZXR1cm4gbGJyeUFwaS5wdWJsaXNoQ2xhaW0ocHVibGlzaFBhcmFtcylcbiAgICAgICAgLnRoZW4odHggPT4ge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKGBTdWNjZXNzZnVsbHkgcHVibGlzaGVkICR7cHVibGlzaFBhcmFtcy5uYW1lfSAke2ZpbGVOYW1lfWAsIHR4KTtcbiAgICAgICAgICBwdWJsaXNoUmVzdWx0cyA9IHR4O1xuICAgICAgICAgIC8vIGdldCB0aGUgY2hhbm5lbCBpbmZvcm1hdGlvblxuICAgICAgICAgIGlmIChwdWJsaXNoUGFyYW1zLmNoYW5uZWxfbmFtZSkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGB0aGlzIGNsYWltIHdhcyBwdWJsaXNoZWQgaW4gY2hhbm5lbDogJHtwdWJsaXNoUGFyYW1zLmNoYW5uZWxfbmFtZX1gKTtcbiAgICAgICAgICAgIHJldHVybiBkYi5DaGFubmVsLmZpbmRPbmUoe3doZXJlOiB7Y2hhbm5lbE5hbWU6IHB1Ymxpc2hQYXJhbXMuY2hhbm5lbF9uYW1lfX0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ3RoaXMgY2xhaW0gd2FzIG5vdCBwdWJsaXNoZWQgaW4gYSBjaGFubmVsJyk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNoYW5uZWwgPT4ge1xuICAgICAgICAvLyBzZXQgY2hhbm5lbCBpbmZvcm1hdGlvblxuICAgICAgICAgIGNlcnRpZmljYXRlSWQgPSBudWxsO1xuICAgICAgICAgIGNoYW5uZWxOYW1lID0gbnVsbDtcbiAgICAgICAgICBpZiAoY2hhbm5lbCkge1xuICAgICAgICAgICAgY2VydGlmaWNhdGVJZCA9IGNoYW5uZWwuY2hhbm5lbENsYWltSWQ7XG4gICAgICAgICAgICBjaGFubmVsTmFtZSA9IGNoYW5uZWwuY2hhbm5lbE5hbWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgY2VydGlmaWNhdGVJZDogJHtjZXJ0aWZpY2F0ZUlkfWApO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgRmlsZSByZWNvcmRcbiAgICAgICAgICBjb25zdCBmaWxlUmVjb3JkID0ge1xuICAgICAgICAgICAgbmFtZSAgICAgICA6IHB1Ymxpc2hQYXJhbXMubmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQgICAgOiBwdWJsaXNoUmVzdWx0cy5jbGFpbV9pZCxcbiAgICAgICAgICAgIHRpdGxlICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLnRpdGxlLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBhZGRyZXNzICAgIDogcHVibGlzaFBhcmFtcy5jbGFpbV9hZGRyZXNzLFxuICAgICAgICAgICAgb3V0cG9pbnQgICA6IGAke3B1Ymxpc2hSZXN1bHRzLnR4aWR9OiR7cHVibGlzaFJlc3VsdHMubm91dH1gLFxuICAgICAgICAgICAgaGVpZ2h0ICAgICA6IDAsXG4gICAgICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgICAgIGZpbGVQYXRoICAgOiBwdWJsaXNoUGFyYW1zLmZpbGVfcGF0aCxcbiAgICAgICAgICAgIGZpbGVUeXBlLFxuICAgICAgICAgICAgbnNmdyAgICAgICA6IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEubnNmdyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgQ2xhaW0gcmVjb3JkXG4gICAgICAgICAgY29uc3QgY2xhaW1SZWNvcmQgPSB7XG4gICAgICAgICAgICBuYW1lICAgICAgIDogcHVibGlzaFBhcmFtcy5uYW1lLFxuICAgICAgICAgICAgY2xhaW1JZCAgICA6IHB1Ymxpc2hSZXN1bHRzLmNsYWltX2lkLFxuICAgICAgICAgICAgdGl0bGUgICAgICA6IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEudGl0bGUsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICAgICAgICAgIGFkZHJlc3MgICAgOiBwdWJsaXNoUGFyYW1zLmNsYWltX2FkZHJlc3MsXG4gICAgICAgICAgICB0aHVtYm5haWwgIDogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS50aHVtYm5haWwsXG4gICAgICAgICAgICBvdXRwb2ludCAgIDogYCR7cHVibGlzaFJlc3VsdHMudHhpZH06JHtwdWJsaXNoUmVzdWx0cy5ub3V0fWAsXG4gICAgICAgICAgICBoZWlnaHQgICAgIDogMCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmaWxlVHlwZSxcbiAgICAgICAgICAgIG5zZncgICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLm5zZncsXG4gICAgICAgICAgICBhbW91bnQgICAgIDogcHVibGlzaFBhcmFtcy5iaWQsXG4gICAgICAgICAgICBjZXJ0aWZpY2F0ZUlkLFxuICAgICAgICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyB1cHNlcnQgY3JpdGVyaWFcbiAgICAgICAgICBjb25zdCB1cHNlcnRDcml0ZXJpYSA9IHtcbiAgICAgICAgICAgIG5hbWUgICA6IHB1Ymxpc2hQYXJhbXMubmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHB1Ymxpc2hSZXN1bHRzLmNsYWltX2lkLFxuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gdXBzZXJ0IHRoZSByZWNvcmRzXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtkYi51cHNlcnQoZGIuRmlsZSwgZmlsZVJlY29yZCwgdXBzZXJ0Q3JpdGVyaWEsICdGaWxlJyksIGRiLnVwc2VydChkYi5DbGFpbSwgY2xhaW1SZWNvcmQsIHVwc2VydENyaXRlcmlhLCAnQ2xhaW0nKV0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2ZpbGUsIGNsYWltXSkgPT4ge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnRmlsZSBhbmQgQ2xhaW0gcmVjb3JkcyBzdWNjZXNzZnVsbHkgY3JlYXRlZCcpO1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZmlsZS5zZXRDbGFpbShjbGFpbSksIGNsYWltLnNldEZpbGUoZmlsZSldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnRmlsZSBhbmQgQ2xhaW0gcmVjb3JkcyBzdWNjZXNzZnVsbHkgYXNzb2NpYXRlZCcpO1xuICAgICAgICAgIHJlc29sdmUocHVibGlzaFJlc3VsdHMpOyAvLyByZXNvbHZlIHRoZSBwcm9taXNlIHdpdGggdGhlIHJlc3VsdCBmcm9tIGxicnlBcGkucHVibGlzaENsYWltO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignUFVCTElTSCBFUlJPUicsIGVycm9yKTtcbiAgICAgICAgICBwdWJsaXNoSGVscGVycy5kZWxldGVUZW1wb3JhcnlGaWxlKHB1Ymxpc2hQYXJhbXMuZmlsZV9wYXRoKTsgLy8gZGVsZXRlIHRoZSBsb2NhbCBmaWxlXG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGNsYWltTmFtZUlzQXZhaWxhYmxlIChuYW1lKSB7XG4gICAgLy8gZmluZCBhbnkgcmVjb3JkcyB3aGVyZSB0aGUgbmFtZSBpcyB1c2VkXG4gICAgcmV0dXJuIGRiLkZpbGUuZmluZEFsbCh7IHdoZXJlOiB7IG5hbWUgfSB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPj0gMSkge1xuICAgICAgICAgIGNvbnN0IGNsYWltQWRkcmVzcyA9IGNvbmZpZy53YWxsZXQubGJyeUNsYWltQWRkcmVzcztcbiAgICAgICAgICAvLyBmaWx0ZXIgb3V0IGFueSByZXN1bHRzIHRoYXQgd2VyZSBub3QgcHVibGlzaGVkIGZyb20gc3BlZS5jaCdzIHdhbGxldCBhZGRyZXNzXG4gICAgICAgICAgY29uc3QgZmlsdGVyZWRSZXN1bHQgPSByZXN1bHQuZmlsdGVyKChjbGFpbSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChjbGFpbS5hZGRyZXNzID09PSBjbGFpbUFkZHJlc3MpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIHJldHVybiBiYXNlZCBvbiB3aGV0aGVyIGFueSBub24tc3BlZS5jaCBjbGFpbXMgd2VyZSBsZWZ0XG4gICAgICAgICAgaWYgKGZpbHRlcmVkUmVzdWx0Lmxlbmd0aCA+PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoYXQgY2xhaW0gaXMgYWxyZWFkeSBpbiB1c2UnKTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJldHVybiBuYW1lO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgIH0pO1xuICB9LFxuICBjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkgKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gZmluZCBhbnkgcmVjb3JkcyB3aGVyZSB0aGUgbmFtZSBpcyB1c2VkXG4gICAgICBkYi5DaGFubmVsLmZpbmRBbGwoeyB3aGVyZTogeyBjaGFubmVsTmFtZTogbmFtZSB9IH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPj0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NvbnRyb2xsZXJzL3B1Ymxpc2hDb250cm9sbGVyLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZnNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJmc1wiXG4vLyBtb2R1bGUgaWQgPSA3OVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBkYiA9IHJlcXVpcmUoJy4uL21vZGVscycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYXV0aGVudGljYXRlVXNlciAoY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgY2hhbm5lbFBhc3N3b3JkLCB1c2VyKSB7XG4gICAgLy8gY2FzZTogbm8gY2hhbm5lbE5hbWUgb3IgY2hhbm5lbCBJZCBhcmUgcHJvdmlkZWQgKGFub255bW91cyksIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB1c2VyIHRva2VuIGlzIHByb3ZpZGVkXG4gICAgaWYgKCFjaGFubmVsTmFtZSAmJiAhY2hhbm5lbElkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjaGFubmVsTmFtZSAgIDogbnVsbCxcbiAgICAgICAgY2hhbm5lbENsYWltSWQ6IG51bGwsXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBjYXNlOiBjaGFubmVsTmFtZSBvciBjaGFubmVsIElkIGFyZSBwcm92aWRlZCB3aXRoIHVzZXIgdG9rZW5cbiAgICBpZiAodXNlcikge1xuICAgICAgaWYgKGNoYW5uZWxOYW1lICYmIGNoYW5uZWxOYW1lICE9PSB1c2VyLmNoYW5uZWxOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHByb3ZpZGVkIGNoYW5uZWwgbmFtZSBkb2VzIG5vdCBtYXRjaCB1c2VyIGNyZWRlbnRpYWxzJyk7XG4gICAgICB9XG4gICAgICBpZiAoY2hhbm5lbElkICYmIGNoYW5uZWxJZCAhPT0gdXNlci5jaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBwcm92aWRlZCBjaGFubmVsIGlkIGRvZXMgbm90IG1hdGNoIHVzZXIgY3JlZGVudGlhbHMnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNoYW5uZWxOYW1lICAgOiB1c2VyLmNoYW5uZWxOYW1lLFxuICAgICAgICBjaGFubmVsQ2xhaW1JZDogdXNlci5jaGFubmVsQ2xhaW1JZCxcbiAgICAgIH07XG4gICAgfVxuICAgIC8vIGNhc2U6IGNoYW5uZWxOYW1lIG9yIGNoYW5uZWwgSWQgYXJlIHByb3ZpZGVkIHdpdGggcGFzc3dvcmQgaW5zdGVhZCBvZiB1c2VyIHRva2VuXG4gICAgaWYgKCFjaGFubmVsUGFzc3dvcmQpIHRocm93IG5ldyBFcnJvcignbm8gY2hhbm5lbCBwYXNzd29yZCBwcm92aWRlZCcpO1xuICAgIHJldHVybiBtb2R1bGUuZXhwb3J0cy5hdXRoZW50aWNhdGVDaGFubmVsQ3JlZGVudGlhbHMoY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgY2hhbm5lbFBhc3N3b3JkKTtcbiAgfSxcbiAgYXV0aGVudGljYXRlQ2hhbm5lbENyZWRlbnRpYWxzIChjaGFubmVsTmFtZSwgY2hhbm5lbElkLCB1c2VyUGFzc3dvcmQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gaG9pc3RlZCB2YXJpYWJsZXNcbiAgICAgIGxldCBjaGFubmVsRGF0YTtcbiAgICAgIC8vIGJ1aWxkIHRoZSBwYXJhbXMgZm9yIGZpbmRpbmcgdGhlIGNoYW5uZWxcbiAgICAgIGxldCBjaGFubmVsRmluZFBhcmFtcyA9IHt9O1xuICAgICAgaWYgKGNoYW5uZWxOYW1lKSBjaGFubmVsRmluZFBhcmFtc1snY2hhbm5lbE5hbWUnXSA9IGNoYW5uZWxOYW1lO1xuICAgICAgaWYgKGNoYW5uZWxJZCkgY2hhbm5lbEZpbmRQYXJhbXNbJ2NoYW5uZWxDbGFpbUlkJ10gPSBjaGFubmVsSWQ7XG4gICAgICAvLyBmaW5kIHRoZSBjaGFubmVsXG4gICAgICBkYi5DaGFubmVsXG4gICAgICAgIC5maW5kT25lKHtcbiAgICAgICAgICB3aGVyZTogY2hhbm5lbEZpbmRQYXJhbXMsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNoYW5uZWwgPT4ge1xuICAgICAgICAgIGlmICghY2hhbm5lbCkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdubyBjaGFubmVsIGZvdW5kJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCwgeW91IGRvIG5vdCBoYXZlIGFjY2VzcyB0byB0aGF0IGNoYW5uZWwnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2hhbm5lbERhdGEgPSBjaGFubmVsLmdldCgpO1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnY2hhbm5lbCBkYXRhOicsIGNoYW5uZWxEYXRhKTtcbiAgICAgICAgICByZXR1cm4gZGIuVXNlci5maW5kT25lKHtcbiAgICAgICAgICAgIHdoZXJlOiB7IHVzZXJOYW1lOiBjaGFubmVsRGF0YS5jaGFubmVsTmFtZS5zdWJzdHJpbmcoMSkgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4odXNlciA9PiB7XG4gICAgICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ25vIHVzZXIgZm91bmQnKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQXV0aGVudGljYXRpb24gZmFpbGVkLCB5b3UgZG8gbm90IGhhdmUgYWNjZXNzIHRvIHRoYXQgY2hhbm5lbCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdXNlci5jb21wYXJlUGFzc3dvcmQodXNlclBhc3N3b3JkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oaXNNYXRjaCA9PiB7XG4gICAgICAgICAgaWYgKCFpc01hdGNoKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ2luY29ycmVjdCBwYXNzd29yZCcpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBdXRoZW50aWNhdGlvbiBmYWlsZWQsIHlvdSBkbyBub3QgaGF2ZSBhY2Nlc3MgdG8gdGhhdCBjaGFubmVsJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnLi4ucGFzc3dvcmQgd2FzIGEgbWF0Y2guLi4nKTtcbiAgICAgICAgICByZXNvbHZlKGNoYW5uZWxEYXRhKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9hdXRoL2F1dGhlbnRpY2F0aW9uLmpzIiwiY29uc3QgQ0xBSU1TX1BFUl9QQUdFID0gMTI7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICByZXR1cm5QYWdpbmF0ZWRDaGFubmVsQ2xhaW1zIChjaGFubmVsTmFtZSwgbG9uZ0NoYW5uZWxDbGFpbUlkLCBjbGFpbXMsIHBhZ2UpIHtcbiAgICBjb25zdCB0b3RhbFBhZ2VzID0gbW9kdWxlLmV4cG9ydHMuZGV0ZXJtaW5lVG90YWxQYWdlcyhjbGFpbXMpO1xuICAgIGNvbnN0IHBhZ2luYXRpb25QYWdlID0gbW9kdWxlLmV4cG9ydHMuZ2V0UGFnZUZyb21RdWVyeShwYWdlKTtcbiAgICBjb25zdCB2aWV3RGF0YSA9IHtcbiAgICAgIGNoYW5uZWxOYW1lICAgICAgIDogY2hhbm5lbE5hbWUsXG4gICAgICBsb25nQ2hhbm5lbENsYWltSWQ6IGxvbmdDaGFubmVsQ2xhaW1JZCxcbiAgICAgIGNsYWltcyAgICAgICAgICAgIDogbW9kdWxlLmV4cG9ydHMuZXh0cmFjdFBhZ2VGcm9tQ2xhaW1zKGNsYWltcywgcGFnaW5hdGlvblBhZ2UpLFxuICAgICAgcHJldmlvdXNQYWdlICAgICAgOiBtb2R1bGUuZXhwb3J0cy5kZXRlcm1pbmVQcmV2aW91c1BhZ2UocGFnaW5hdGlvblBhZ2UpLFxuICAgICAgY3VycmVudFBhZ2UgICAgICAgOiBwYWdpbmF0aW9uUGFnZSxcbiAgICAgIG5leHRQYWdlICAgICAgICAgIDogbW9kdWxlLmV4cG9ydHMuZGV0ZXJtaW5lTmV4dFBhZ2UodG90YWxQYWdlcywgcGFnaW5hdGlvblBhZ2UpLFxuICAgICAgdG90YWxQYWdlcyAgICAgICAgOiB0b3RhbFBhZ2VzLFxuICAgICAgdG90YWxSZXN1bHRzICAgICAgOiBtb2R1bGUuZXhwb3J0cy5kZXRlcm1pbmVUb3RhbENsYWltcyhjbGFpbXMpLFxuICAgIH07XG4gICAgcmV0dXJuIHZpZXdEYXRhO1xuICB9LFxuICBnZXRQYWdlRnJvbVF1ZXJ5IChwYWdlKSB7XG4gICAgaWYgKHBhZ2UpIHtcbiAgICAgIHJldHVybiBwYXJzZUludChwYWdlKTtcbiAgICB9XG4gICAgcmV0dXJuIDE7XG4gIH0sXG4gIGV4dHJhY3RQYWdlRnJvbUNsYWltcyAoY2xhaW1zLCBwYWdlTnVtYmVyKSB7XG4gICAgaWYgKCFjbGFpbXMpIHtcbiAgICAgIHJldHVybiBbXTsgIC8vIGlmIG5vIGNsYWltcywgcmV0dXJuIHRoaXMgZGVmYXVsdFxuICAgIH1cbiAgICAvLyBsb2dnZXIuZGVidWcoJ2NsYWltcyBpcyBhcnJheT8nLCBBcnJheS5pc0FycmF5KGNsYWltcykpO1xuICAgIC8vIGxvZ2dlci5kZWJ1ZyhgcGFnZU51bWJlciAke3BhZ2VOdW1iZXJ9IGlzIG51bWJlcj9gLCBOdW1iZXIuaXNJbnRlZ2VyKHBhZ2VOdW1iZXIpKTtcbiAgICBjb25zdCBjbGFpbVN0YXJ0SW5kZXggPSAocGFnZU51bWJlciAtIDEpICogQ0xBSU1TX1BFUl9QQUdFO1xuICAgIGNvbnN0IGNsYWltRW5kSW5kZXggPSBjbGFpbVN0YXJ0SW5kZXggKyBDTEFJTVNfUEVSX1BBR0U7XG4gICAgY29uc3QgcGFnZU9mQ2xhaW1zID0gY2xhaW1zLnNsaWNlKGNsYWltU3RhcnRJbmRleCwgY2xhaW1FbmRJbmRleCk7XG4gICAgcmV0dXJuIHBhZ2VPZkNsYWltcztcbiAgfSxcbiAgZGV0ZXJtaW5lVG90YWxQYWdlcyAoY2xhaW1zKSB7XG4gICAgaWYgKCFjbGFpbXMpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0b3RhbENsYWltcyA9IGNsYWltcy5sZW5ndGg7XG4gICAgICBpZiAodG90YWxDbGFpbXMgPCBDTEFJTVNfUEVSX1BBR0UpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG4gICAgICBjb25zdCBmdWxsUGFnZXMgPSBNYXRoLmZsb29yKHRvdGFsQ2xhaW1zIC8gQ0xBSU1TX1BFUl9QQUdFKTtcbiAgICAgIGNvbnN0IHJlbWFpbmRlciA9IHRvdGFsQ2xhaW1zICUgQ0xBSU1TX1BFUl9QQUdFO1xuICAgICAgaWYgKHJlbWFpbmRlciA9PT0gMCkge1xuICAgICAgICByZXR1cm4gZnVsbFBhZ2VzO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bGxQYWdlcyArIDE7XG4gICAgfVxuICB9LFxuICBkZXRlcm1pbmVQcmV2aW91c1BhZ2UgKGN1cnJlbnRQYWdlKSB7XG4gICAgaWYgKGN1cnJlbnRQYWdlID09PSAxKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnJlbnRQYWdlIC0gMTtcbiAgfSxcbiAgZGV0ZXJtaW5lTmV4dFBhZ2UgKHRvdGFsUGFnZXMsIGN1cnJlbnRQYWdlKSB7XG4gICAgaWYgKGN1cnJlbnRQYWdlID09PSB0b3RhbFBhZ2VzKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnJlbnRQYWdlICsgMTtcbiAgfSxcbiAgZGV0ZXJtaW5lVG90YWxDbGFpbXMgKGNsYWltcykge1xuICAgIGlmICghY2xhaW1zKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGNsYWltcy5sZW5ndGg7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vaGVscGVycy9jaGFubmVsUGFnaW5hdGlvbi5qcyIsImNvbnN0IHsgc2l0ZSB9ID0gcmVxdWlyZSgnLi4vY29uZmlnL3NwZWVjaENvbmZpZy5qcycpO1xuY29uc3QgaGFuZGxlUGFnZVJlbmRlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaGFuZGxlUGFnZVJlbmRlci5qc3gnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoYXBwKSA9PiB7XG4gIC8vIHJvdXRlIGZvciB0aGUgaG9tZSBwYWdlXG4gIGFwcC5nZXQoJy8nLCAocmVxLCByZXMpID0+IHtcbiAgICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGRpc3BsYXkgbG9naW4gcGFnZVxuICBhcHAuZ2V0KCcvbG9naW4nLCAocmVxLCByZXMpID0+IHtcbiAgICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIHNob3cgJ2Fib3V0JyBwYWdlXG4gIGFwcC5nZXQoJy9hYm91dCcsIChyZXEsIHJlcykgPT4ge1xuICAgIGhhbmRsZVBhZ2VSZW5kZXIocmVxLCByZXMpO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gZGlzcGxheSBhIGxpc3Qgb2YgdGhlIHRyZW5kaW5nIGltYWdlc1xuICBhcHAuZ2V0KCcvdHJlbmRpbmcnLCAocmVxLCByZXMpID0+IHtcbiAgICByZXMuc3RhdHVzKDMwMSkucmVkaXJlY3QoJy9wb3B1bGFyJyk7XG4gIH0pO1xuICBhcHAuZ2V0KCcvcG9wdWxhcicsIChyZXEsIHJlcykgPT4ge1xuICAgIGhhbmRsZVBhZ2VSZW5kZXIocmVxLCByZXMpO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gZGlzcGxheSBhIGxpc3Qgb2YgdGhlIHRyZW5kaW5nIGltYWdlc1xuICBhcHAuZ2V0KCcvbmV3JywgKHJlcSwgcmVzKSA9PiB7XG4gICAgaGFuZGxlUGFnZVJlbmRlcihyZXEsIHJlcyk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBzZW5kIGVtYmVkYWJsZSB2aWRlbyBwbGF5ZXIgKGZvciB0d2l0dGVyKVxuICBhcHAuZ2V0KCcvZW1iZWQvOmNsYWltSWQvOm5hbWUnLCAoeyBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgY2xhaW1JZCA9IHBhcmFtcy5jbGFpbUlkO1xuICAgIGNvbnN0IG5hbWUgPSBwYXJhbXMubmFtZTtcbiAgICBjb25zdCBob3N0ID0gc2l0ZS5ob3N0O1xuICAgIC8vIGdldCBhbmQgcmVuZGVyIHRoZSBjb250ZW50XG4gICAgcmVzLnN0YXR1cygyMDApLnJlbmRlcignZW1iZWQnLCB7IGxheW91dDogJ2VtYmVkJywgaG9zdCwgY2xhaW1JZCwgbmFtZSB9KTtcbiAgfSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcm91dGVzL3BhZ2Utcm91dGVzLmpzIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgTE9HSU4gfSBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jaGFubmVsX3NlbGVjdF9zdGF0ZXMnO1xuY29uc3QgeyBwdWJsaXNoIH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvc3BlZWNoQ29uZmlnLmpzJyk7XG5cbmNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgcHVibGlzaEluQ2hhbm5lbCAgOiBmYWxzZSxcbiAgc2VsZWN0ZWRDaGFubmVsICAgOiBMT0dJTixcbiAgc2hvd01ldGFkYXRhSW5wdXRzOiBmYWxzZSxcbiAgc3RhdHVzICAgICAgICAgICAgOiB7XG4gICAgc3RhdHVzIDogbnVsbCxcbiAgICBtZXNzYWdlOiBudWxsLFxuICB9LFxuICBlcnJvcjoge1xuICAgIGZpbGUgICAgICAgICA6IG51bGwsXG4gICAgdXJsICAgICAgICAgIDogbnVsbCxcbiAgICBjaGFubmVsICAgICAgOiBudWxsLFxuICAgIHB1Ymxpc2hTdWJtaXQ6IG51bGwsXG4gIH0sXG4gIGZpbGUgICAgOiBudWxsLFxuICBjbGFpbSAgIDogJycsXG4gIG1ldGFkYXRhOiB7XG4gICAgdGl0bGUgICAgICA6ICcnLFxuICAgIGRlc2NyaXB0aW9uOiAnJyxcbiAgICBsaWNlbnNlICAgIDogJycsXG4gICAgbnNmdyAgICAgICA6IGZhbHNlLFxuICB9LFxuICB0aHVtYm5haWxDaGFubmVsICA6IHB1Ymxpc2gudGh1bWJuYWlsQ2hhbm5lbCxcbiAgdGh1bWJuYWlsQ2hhbm5lbElkOiBwdWJsaXNoLnRodW1ibmFpbENoYW5uZWxJZCxcbiAgdGh1bWJuYWlsICAgICAgICAgOiBudWxsLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHN0YXRlID0gaW5pdGlhbFN0YXRlLCBhY3Rpb24pIHtcbiAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgIGNhc2UgYWN0aW9ucy5GSUxFX1NFTEVDVEVEOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGluaXRpYWxTdGF0ZSwgeyAgLy8gbm90ZTogY2xlYXJzIHRvIGluaXRpYWwgc3RhdGVcbiAgICAgICAgZmlsZTogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuRklMRV9DTEVBUjpcbiAgICAgIHJldHVybiBpbml0aWFsU3RhdGU7XG4gICAgY2FzZSBhY3Rpb25zLk1FVEFEQVRBX1VQREFURTpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBtZXRhZGF0YTogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUubWV0YWRhdGEsIHtcbiAgICAgICAgICBbYWN0aW9uLmRhdGEubmFtZV06IGFjdGlvbi5kYXRhLnZhbHVlLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5DTEFJTV9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgY2xhaW06IGFjdGlvbi5kYXRhLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLlNFVF9QVUJMSVNIX0lOX0NIQU5ORUw6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgcHVibGlzaEluQ2hhbm5lbDogYWN0aW9uLmNoYW5uZWwsXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuUFVCTElTSF9TVEFUVVNfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHN0YXR1czogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuRVJST1JfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGVycm9yOiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5lcnJvciwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5uYW1lXTogYWN0aW9uLmRhdGEudmFsdWUsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLlNFTEVDVEVEX0NIQU5ORUxfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHNlbGVjdGVkQ2hhbm5lbDogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuVE9HR0xFX01FVEFEQVRBX0lOUFVUUzpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBzaG93TWV0YWRhdGFJbnB1dHM6IGFjdGlvbi5kYXRhLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLlRIVU1CTkFJTF9ORVc6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgdGh1bWJuYWlsOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L3JlZHVjZXJzL3B1Ymxpc2guanMiLCJpbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9jaGFubmVsX2FjdGlvbl90eXBlcyc7XG5cbmNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgbG9nZ2VkSW5DaGFubmVsOiB7XG4gICAgbmFtZSAgIDogbnVsbCxcbiAgICBzaG9ydElkOiBudWxsLFxuICAgIGxvbmdJZCA6IG51bGwsXG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUgPSBpbml0aWFsU3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgY2FzZSBhY3Rpb25zLkNIQU5ORUxfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGxvZ2dlZEluQ2hhbm5lbDogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9yZWR1Y2Vycy9jaGFubmVsLmpzIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvc2hvd19hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgTE9DQUxfQ0hFQ0ssIEVSUk9SIH0gZnJvbSAnY29uc3RhbnRzL2Fzc2V0X2Rpc3BsYXlfc3RhdGVzJztcblxuY29uc3QgaW5pdGlhbFN0YXRlID0ge1xuICByZXF1ZXN0OiB7XG4gICAgZXJyb3I6IG51bGwsXG4gICAgdHlwZSA6IG51bGwsXG4gICAgaWQgICA6IG51bGwsXG4gIH0sXG4gIHJlcXVlc3RMaXN0IDoge30sXG4gIGNoYW5uZWxMaXN0IDoge30sXG4gIGFzc2V0TGlzdCAgIDoge30sXG4gIGRpc3BsYXlBc3NldDoge1xuICAgIGVycm9yIDogbnVsbCxcbiAgICBzdGF0dXM6IExPQ0FMX0NIRUNLLFxuICB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHN0YXRlID0gaW5pdGlhbFN0YXRlLCBhY3Rpb24pIHtcbiAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgIC8vIGhhbmRsZSByZXF1ZXN0XG4gICAgY2FzZSBhY3Rpb25zLlJFUVVFU1RfRVJST1I6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgcmVxdWVzdDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVxdWVzdCwge1xuICAgICAgICAgIGVycm9yOiBhY3Rpb24uZGF0YSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuUkVRVUVTVF9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgcmVxdWVzdDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVxdWVzdCwge1xuICAgICAgICAgIHR5cGU6IGFjdGlvbi5kYXRhLnJlcXVlc3RUeXBlLFxuICAgICAgICAgIGlkICA6IGFjdGlvbi5kYXRhLnJlcXVlc3RJZCxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAvLyBzdG9yZSByZXF1ZXN0c1xuICAgIGNhc2UgYWN0aW9ucy5SRVFVRVNUX0xJU1RfQUREOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHJlcXVlc3RMaXN0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5yZXF1ZXN0TGlzdCwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5pZF06IHtcbiAgICAgICAgICAgIGVycm9yOiBhY3Rpb24uZGF0YS5lcnJvcixcbiAgICAgICAgICAgIGtleSAgOiBhY3Rpb24uZGF0YS5rZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAvLyBhc3NldCBkYXRhXG4gICAgY2FzZSBhY3Rpb25zLkFTU0VUX0FERDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBhc3NldExpc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmFzc2V0TGlzdCwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5pZF06IHtcbiAgICAgICAgICAgIGVycm9yICAgIDogYWN0aW9uLmRhdGEuZXJyb3IsXG4gICAgICAgICAgICBuYW1lICAgICA6IGFjdGlvbi5kYXRhLm5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkICA6IGFjdGlvbi5kYXRhLmNsYWltSWQsXG4gICAgICAgICAgICBzaG9ydElkICA6IGFjdGlvbi5kYXRhLnNob3J0SWQsXG4gICAgICAgICAgICBjbGFpbURhdGE6IGFjdGlvbi5kYXRhLmNsYWltRGF0YSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIC8vIGNoYW5uZWwgZGF0YVxuICAgIGNhc2UgYWN0aW9ucy5DSEFOTkVMX0FERDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBjaGFubmVsTGlzdDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuY2hhbm5lbExpc3QsIHtcbiAgICAgICAgICBbYWN0aW9uLmRhdGEuaWRdOiB7XG4gICAgICAgICAgICBuYW1lICAgICAgOiBhY3Rpb24uZGF0YS5uYW1lLFxuICAgICAgICAgICAgbG9uZ0lkICAgIDogYWN0aW9uLmRhdGEubG9uZ0lkLFxuICAgICAgICAgICAgc2hvcnRJZCAgIDogYWN0aW9uLmRhdGEuc2hvcnRJZCxcbiAgICAgICAgICAgIGNsYWltc0RhdGE6IGFjdGlvbi5kYXRhLmNsYWltc0RhdGEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1M6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgY2hhbm5lbExpc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmNoYW5uZWxMaXN0LCB7XG4gICAgICAgICAgW2FjdGlvbi5kYXRhLmNoYW5uZWxMaXN0SWRdOiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5jaGFubmVsTGlzdFthY3Rpb24uZGF0YS5jaGFubmVsTGlzdElkXSwge1xuICAgICAgICAgICAgY2xhaW1zRGF0YTogYWN0aW9uLmRhdGEuY2xhaW1zRGF0YSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAvLyBkaXNwbGF5IGFuIGFzc2V0XG4gICAgY2FzZSBhY3Rpb25zLkZJTEVfQVZBSUxBQklMSVRZX1VQREFURTpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBkaXNwbGF5QXNzZXQ6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmRpc3BsYXlBc3NldCwge1xuICAgICAgICAgIHN0YXR1czogYWN0aW9uLmRhdGEsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLkRJU1BMQVlfQVNTRVRfRVJST1I6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgZGlzcGxheUFzc2V0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5kaXNwbGF5QXNzZXQsIHtcbiAgICAgICAgICBlcnJvciA6IGFjdGlvbi5kYXRhLFxuICAgICAgICAgIHN0YXR1czogRVJST1IsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvcmVkdWNlcnMvc2hvdy5qcyIsImNvbnN0IHsgc2l0ZSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NwZWVjaENvbmZpZy5qcycpO1xuXG5jb25zdCBpbml0aWFsU3RhdGUgPSB7XG4gIGhvc3Q6IHNpdGUuaG9zdCxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGF0ZSA9IGluaXRpYWxTdGF0ZSwgYWN0aW9uKSB7XG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9yZWR1Y2Vycy9zaXRlLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3QtZ2FcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdC1nYVwiXG4vLyBtb2R1bGUgaWQgPSA4N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFNFTyBmcm9tICdjb21wb25lbnRzL1NFTyc7XG5pbXBvcnQgTmF2QmFyIGZyb20gJ2NvbnRhaW5lcnMvTmF2QmFyJztcbmltcG9ydCBQdWJsaXNoVG9vbCBmcm9tICdjb250YWluZXJzL1B1Ymxpc2hUb29sJztcblxuY2xhc3MgSG9tZVBhZ2UgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT17J3JvdyByb3ctLXRhbGwgZmxleC1jb250YWluZXItLWNvbHVtbid9PlxuICAgICAgICA8U0VPIC8+XG4gICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9eydyb3cgcm93LS10YWxsIHJvdy0tcGFkZGVkIGZsZXgtY29udGFpbmVyLS1jb2x1bW4nfT5cbiAgICAgICAgICA8UHVibGlzaFRvb2wgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBIb21lUGFnZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbXBvbmVudHMvSG9tZVBhZ2UvaW5kZXguanN4IiwiY29uc3QgeyBzaXRlOiB7IHRpdGxlOiBzaXRlVGl0bGUgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NwZWVjaENvbmZpZy5qcycpO1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFnZVRpdGxlID0gKHBhZ2VUaXRsZSkgPT4ge1xuICBpZiAoIXBhZ2VUaXRsZSkge1xuICAgIHJldHVybiBgJHtzaXRlVGl0bGV9YDtcbiAgfVxuICByZXR1cm4gYCR7c2l0ZVRpdGxlfSAtICR7cGFnZVRpdGxlfWA7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvdXRpbHMvcGFnZVRpdGxlLmpzIiwiY29uc3QgeyBzaXRlOiB7IHRpdGxlLCBob3N0LCBkZXNjcmlwdGlvbiB9LCBjbGFpbTogeyBkZWZhdWx0VGh1bWJuYWlsLCBkZWZhdWx0RGVzY3JpcHRpb24gfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NwZWVjaENvbmZpZy5qcycpO1xuXG5jb25zdCBkZXRlcm1pbmVPZ1RodW1ibmFpbENvbnRlbnRUeXBlID0gKHRodW1ibmFpbCkgPT4ge1xuICBpZiAodGh1bWJuYWlsKSB7XG4gICAgY29uc3QgZmlsZUV4dCA9IHRodW1ibmFpbC5zdWJzdHJpbmcodGh1bWJuYWlsLmxhc3RJbmRleE9mKCcuJykpO1xuICAgIHN3aXRjaCAoZmlsZUV4dCkge1xuICAgICAgY2FzZSAnanBlZyc6XG4gICAgICBjYXNlICdqcGcnOlxuICAgICAgICByZXR1cm4gJ2ltYWdlL2pwZWcnO1xuICAgICAgY2FzZSAncG5nJzpcbiAgICAgICAgcmV0dXJuICdpbWFnZS9wbmcnO1xuICAgICAgY2FzZSAnZ2lmJzpcbiAgICAgICAgcmV0dXJuICdpbWFnZS9naWYnO1xuICAgICAgY2FzZSAnbXA0JzpcbiAgICAgICAgcmV0dXJuICd2aWRlby9tcDQnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICdpbWFnZS9qcGVnJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuICcnO1xufTtcblxuY29uc3QgY3JlYXRlQmFzaWNNZXRhVGFncyA9ICgpID0+IHtcbiAgcmV0dXJuIFtcbiAgICB7cHJvcGVydHk6ICdvZzp0aXRsZScsIGNvbnRlbnQ6IHRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBob3N0fSxcbiAgICB7cHJvcGVydHk6ICdvZzpzaXRlX25hbWUnLCBjb250ZW50OiB0aXRsZX0sXG4gICAge3Byb3BlcnR5OiAnb2c6ZGVzY3JpcHRpb24nLCBjb250ZW50OiBkZXNjcmlwdGlvbn0sXG4gICAge3Byb3BlcnR5OiAndHdpdHRlcjpzaXRlJywgY29udGVudDogJ0BzcGVlX2NoJ30sXG4gICAge3Byb3BlcnR5OiAndHdpdHRlcjpjYXJkJywgY29udGVudDogJ3N1bW1hcnknfSxcbiAgXTtcbn07XG5cbmNvbnN0IGNyZWF0ZUNoYW5uZWxNZXRhVGFncyA9IChjaGFubmVsKSA9PiB7XG4gIGNvbnN0IHsgbmFtZSwgbG9uZ0lkIH0gPSBjaGFubmVsO1xuICByZXR1cm4gW1xuICAgIHtwcm9wZXJ0eTogJ29nOnRpdGxlJywgY29udGVudDogYCR7bmFtZX0gb24gJHt0aXRsZX1gfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBgJHtob3N0fS8ke25hbWV9OiR7bG9uZ0lkfWB9LFxuICAgIHtwcm9wZXJ0eTogJ29nOnNpdGVfbmFtZScsIGNvbnRlbnQ6IHRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzpkZXNjcmlwdGlvbicsIGNvbnRlbnQ6IGAke25hbWV9LCBhIGNoYW5uZWwgb24gJHt0aXRsZX1gfSxcbiAgICB7cHJvcGVydHk6ICd0d2l0dGVyOnNpdGUnLCBjb250ZW50OiAnQHNwZWVfY2gnfSxcbiAgICB7cHJvcGVydHk6ICd0d2l0dGVyOmNhcmQnLCBjb250ZW50OiAnc3VtbWFyeSd9LFxuICBdO1xufTtcblxuY29uc3QgY3JlYXRlQXNzZXRNZXRhVGFncyA9IChhc3NldCkgPT4ge1xuICBjb25zdCB7IGNsYWltRGF0YSB9ID0gYXNzZXQ7XG4gIGNvbnN0IHsgY29udGVudFR5cGUgfSA9IGNsYWltRGF0YTtcbiAgY29uc3QgZW1iZWRVcmwgPSBgJHtob3N0fS8ke2NsYWltRGF0YS5jbGFpbUlkfS8ke2NsYWltRGF0YS5uYW1lfWA7XG4gIGNvbnN0IHNob3dVcmwgPSBgJHtob3N0fS8ke2NsYWltRGF0YS5jbGFpbUlkfS8ke2NsYWltRGF0YS5uYW1lfWA7XG4gIGNvbnN0IHNvdXJjZSA9IGAke2hvc3R9LyR7Y2xhaW1EYXRhLmNsYWltSWR9LyR7Y2xhaW1EYXRhLm5hbWV9LiR7Y2xhaW1EYXRhLmZpbGVFeHR9YDtcbiAgY29uc3Qgb2dUaXRsZSA9IGNsYWltRGF0YS50aXRsZSB8fCBjbGFpbURhdGEubmFtZTtcbiAgY29uc3Qgb2dEZXNjcmlwdGlvbiA9IGNsYWltRGF0YS5kZXNjcmlwdGlvbiB8fCBkZWZhdWx0RGVzY3JpcHRpb247XG4gIGNvbnN0IG9nVGh1bWJuYWlsQ29udGVudFR5cGUgPSBkZXRlcm1pbmVPZ1RodW1ibmFpbENvbnRlbnRUeXBlKGNsYWltRGF0YS50aHVtYm5haWwpO1xuICBjb25zdCBvZ1RodW1ibmFpbCA9IGNsYWltRGF0YS50aHVtYm5haWwgfHwgZGVmYXVsdFRodW1ibmFpbDtcbiAgY29uc3QgbWV0YVRhZ3MgPSBbXG4gICAge3Byb3BlcnR5OiAnb2c6dGl0bGUnLCBjb250ZW50OiBvZ1RpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBzaG93VXJsfSxcbiAgICB7cHJvcGVydHk6ICdvZzpzaXRlX25hbWUnLCBjb250ZW50OiB0aXRsZX0sXG4gICAge3Byb3BlcnR5OiAnb2c6ZGVzY3JpcHRpb24nLCBjb250ZW50OiBvZ0Rlc2NyaXB0aW9ufSxcbiAgICB7cHJvcGVydHk6ICdvZzppbWFnZTp3aWR0aCcsIGNvbnRlbnQ6IDYwMH0sXG4gICAge3Byb3BlcnR5OiAnb2c6aW1hZ2U6aGVpZ2h0JywgY29udGVudDogMzE1fSxcbiAgICB7cHJvcGVydHk6ICd0d2l0dGVyOnNpdGUnLCBjb250ZW50OiAnQHNwZWVfY2gnfSxcbiAgXTtcbiAgaWYgKGNvbnRlbnRUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50VHlwZSA9PT0gJ3ZpZGVvL3dlYm0nKSB7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzp2aWRlbycsIGNvbnRlbnQ6IHNvdXJjZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dmlkZW86c2VjdXJlX3VybCcsIGNvbnRlbnQ6IHNvdXJjZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dmlkZW86dHlwZScsIGNvbnRlbnQ6IGNvbnRlbnRUeXBlfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzppbWFnZScsIGNvbnRlbnQ6IG9nVGh1bWJuYWlsfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzppbWFnZTp0eXBlJywgY29udGVudDogb2dUaHVtYm5haWxDb250ZW50VHlwZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dHlwZScsIGNvbnRlbnQ6ICd2aWRlbyd9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ3R3aXR0ZXI6Y2FyZCcsIGNvbnRlbnQ6ICdwbGF5ZXInfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcicsIGNvbnRlbnQ6IGVtYmVkVXJsfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcjp3aWR0aCcsIGNvbnRlbnQ6IDYwMH0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjp0ZXh0OnBsYXllcl93aWR0aCcsIGNvbnRlbnQ6IDYwMH0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjpwbGF5ZXI6aGVpZ2h0JywgY29udGVudDogMzM3fSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcjpzdHJlYW0nLCBjb250ZW50OiBzb3VyY2V9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ3R3aXR0ZXI6cGxheWVyOnN0cmVhbTpjb250ZW50X3R5cGUnLCBjb250ZW50OiBjb250ZW50VHlwZX0pO1xuICB9IGVsc2Uge1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6aW1hZ2UnLCBjb250ZW50OiBzb3VyY2V9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ29nOmltYWdlOnR5cGUnLCBjb250ZW50OiBjb250ZW50VHlwZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dHlwZScsIGNvbnRlbnQ6ICdhcnRpY2xlJ30pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjpjYXJkJywgY29udGVudDogJ3N1bW1hcnlfbGFyZ2VfaW1hZ2UnfSk7XG4gIH1cbiAgcmV0dXJuIG1ldGFUYWdzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1ldGFUYWdzID0gKGFzc2V0LCBjaGFubmVsKSA9PiB7XG4gIGlmIChhc3NldCkge1xuICAgIHJldHVybiBjcmVhdGVBc3NldE1ldGFUYWdzKGFzc2V0KTtcbiAgfTtcbiAgaWYgKGNoYW5uZWwpIHtcbiAgICByZXR1cm4gY3JlYXRlQ2hhbm5lbE1ldGFUYWdzKGNoYW5uZWwpO1xuICB9O1xuICByZXR1cm4gY3JlYXRlQmFzaWNNZXRhVGFncygpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L3V0aWxzL21ldGFUYWdzLmpzIiwiY29uc3QgeyBzaXRlOiB7IGhvc3QgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NwZWVjaENvbmZpZy5qcycpO1xuXG5jb25zdCBjcmVhdGVCYXNpY0Nhbm9uaWNhbExpbmsgPSAocGFnZSkgPT4ge1xuICBpZiAoIXBhZ2UpIHtcbiAgICByZXR1cm4gYCR7aG9zdH1gO1xuICB9O1xuICByZXR1cm4gYCR7aG9zdH0vJHtwYWdlfWA7XG59O1xuXG5jb25zdCBjcmVhdGVBc3NldENhbm9uaWNhbExpbmsgPSAoYXNzZXQpID0+IHtcbiAgbGV0IGNoYW5uZWxOYW1lLCBjZXJ0aWZpY2F0ZUlkLCBuYW1lLCBjbGFpbUlkO1xuICBpZiAoYXNzZXQuY2xhaW1EYXRhKSB7XG4gICAgKHsgY2hhbm5lbE5hbWUsIGNlcnRpZmljYXRlSWQsIG5hbWUsIGNsYWltSWQgfSA9IGFzc2V0LmNsYWltRGF0YSk7XG4gIH07XG4gIGlmIChjaGFubmVsTmFtZSkge1xuICAgIHJldHVybiBgJHtob3N0fS8ke2NoYW5uZWxOYW1lfToke2NlcnRpZmljYXRlSWR9LyR7bmFtZX1gO1xuICB9O1xuICByZXR1cm4gYCR7aG9zdH0vJHtjbGFpbUlkfS8ke25hbWV9YDtcbn07XG5cbmNvbnN0IGNyZWF0ZUNoYW5uZWxDYW5vbmljYWxMaW5rID0gKGNoYW5uZWwpID0+IHtcbiAgY29uc3QgeyBuYW1lLCBsb25nSWQgfSA9IGNoYW5uZWw7XG4gIHJldHVybiBgJHtob3N0fS8ke25hbWV9OiR7bG9uZ0lkfWA7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlQ2Fub25pY2FsTGluayA9IChhc3NldCwgY2hhbm5lbCwgcGFnZSkgPT4ge1xuICBpZiAoYXNzZXQpIHtcbiAgICByZXR1cm4gY3JlYXRlQXNzZXRDYW5vbmljYWxMaW5rKGFzc2V0KTtcbiAgfVxuICBpZiAoY2hhbm5lbCkge1xuICAgIHJldHVybiBjcmVhdGVDaGFubmVsQ2Fub25pY2FsTGluayhjaGFubmVsKTtcbiAgfVxuICBpZiAocGFnZSkge1xuICAgIHJldHVybiBjcmVhdGVCYXNpY0Nhbm9uaWNhbExpbmsocGFnZSk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJhc2ljQ2Fub25pY2FsTGluaygpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L3V0aWxzL2Nhbm9uaWNhbExpbmsuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgTmF2TGluaywgd2l0aFJvdXRlciB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IExvZ28gZnJvbSAnY29tcG9uZW50cy9Mb2dvJztcbmltcG9ydCBOYXZCYXJDaGFubmVsRHJvcGRvd24gZnJvbSAnY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duJztcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5jb25zdCBWSUVXID0gJ1ZJRVcnO1xuY29uc3QgTE9HT1VUID0gJ0xPR09VVCc7XG5cbmNsYXNzIE5hdkJhciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmNoZWNrRm9yTG9nZ2VkSW5Vc2VyID0gdGhpcy5jaGVja0ZvckxvZ2dlZEluVXNlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMubG9nb3V0VXNlciA9IHRoaXMubG9nb3V0VXNlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVTZWxlY3Rpb24uYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgLy8gY2hlY2sgdG8gc2VlIGlmIHRoZSB1c2VyIGlzIGFscmVhZHkgbG9nZ2VkIGluXG4gICAgdGhpcy5jaGVja0ZvckxvZ2dlZEluVXNlcigpO1xuICB9XG4gIGNoZWNrRm9yTG9nZ2VkSW5Vc2VyICgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB7Y3JlZGVudGlhbHM6ICdpbmNsdWRlJ307XG4gICAgcmVxdWVzdCgnL3VzZXInLCBwYXJhbXMpXG4gICAgICAudGhlbigoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihkYXRhLmNoYW5uZWxOYW1lLCBkYXRhLnNob3J0Q2hhbm5lbElkLCBkYXRhLmNoYW5uZWxDbGFpbUlkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnL3VzZXIgZXJyb3I6JywgZXJyb3IubWVzc2FnZSk7XG4gICAgICB9KTtcbiAgfVxuICBsb2dvdXRVc2VyICgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB7Y3JlZGVudGlhbHM6ICdpbmNsdWRlJ307XG4gICAgcmVxdWVzdCgnL2xvZ291dCcsIHBhcmFtcylcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dvdXQoKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnL2xvZ291dCBlcnJvcicsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfSk7XG4gIH1cbiAgaGFuZGxlU2VsZWN0aW9uIChldmVudCkge1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnNlbGVjdGVkT3B0aW9uc1swXS52YWx1ZTtcbiAgICBzd2l0Y2ggKHZhbHVlKSB7XG4gICAgICBjYXNlIExPR09VVDpcbiAgICAgICAgdGhpcy5sb2dvdXRVc2VyKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBWSUVXOlxuICAgICAgICAvLyByZWRpcmVjdCB0byBjaGFubmVsIHBhZ2VcbiAgICAgICAgdGhpcy5wcm9wcy5oaXN0b3J5LnB1c2goYC8ke3RoaXMucHJvcHMuY2hhbm5lbE5hbWV9OiR7dGhpcy5wcm9wcy5jaGFubmVsTG9uZ0lkfWApO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSBuYXYtYmFyJz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLXNob3J0IGZsZXgtY29udGFpbmVyLS1yb3cgZmxleC1jb250YWluZXItLXNwYWNlLWJldHdlZW4tY2VudGVyJz5cbiAgICAgICAgICA8TG9nbyAvPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSduYXYtYmFyLS1jZW50ZXInPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSduYXYtYmFyLXRhZ2xpbmUnPk9wZW4tc291cmNlLCBkZWNlbnRyYWxpemVkIGltYWdlIGFuZCB2aWRlbyBzaGFyaW5nLjwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbmF2LWJhci0tcmlnaHQnPlxuICAgICAgICAgICAgPE5hdkxpbmsgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyBhY3RpdmVDbGFzc05hbWU9J2xpbmstLW5hdi1hY3RpdmUnIHRvPScvJyBleGFjdD5QdWJsaXNoPC9OYXZMaW5rPlxuICAgICAgICAgICAgPE5hdkxpbmsgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyAgYWN0aXZlQ2xhc3NOYW1lPSdsaW5rLS1uYXYtYWN0aXZlJyB0bz0nL2Fib3V0Jz5BYm91dDwvTmF2TGluaz5cbiAgICAgICAgICAgIHsgdGhpcy5wcm9wcy5jaGFubmVsTmFtZSA/IChcbiAgICAgICAgICAgICAgPE5hdkJhckNoYW5uZWxEcm9wZG93blxuICAgICAgICAgICAgICAgIGNoYW5uZWxOYW1lPXt0aGlzLnByb3BzLmNoYW5uZWxOYW1lfVxuICAgICAgICAgICAgICAgIGhhbmRsZVNlbGVjdGlvbj17dGhpcy5oYW5kbGVTZWxlY3Rpb259XG4gICAgICAgICAgICAgICAgZGVmYXVsdFNlbGVjdGlvbj17dGhpcy5wcm9wcy5jaGFubmVsTmFtZX1cbiAgICAgICAgICAgICAgICBWSUVXPXtWSUVXfVxuICAgICAgICAgICAgICAgIExPR09VVD17TE9HT1VUfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgPE5hdkxpbmsgaWQ9J25hdi1iYXItbG9naW4tbGluaycgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyBhY3RpdmVDbGFzc05hbWU9J2xpbmstLW5hdi1hY3RpdmUnIHRvPScvbG9naW4nPkNoYW5uZWw8L05hdkxpbms+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aFJvdXRlcihOYXZCYXIpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29udGFpbmVycy9OYXZCYXIvdmlldy5qc3giLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgTGluayB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuXG5mdW5jdGlvbiBMb2dvICgpIHtcbiAgcmV0dXJuIChcbiAgICA8c3ZnIHZlcnNpb249JzEuMScgaWQ9J0xheWVyXzEnIHg9JzBweCcgeT0nMHB4JyBoZWlnaHQ9JzI0cHgnIHZpZXdCb3g9JzAgMCA4MCAzMScgZW5hYmxlQmFja2dyb3VuZD0nbmV3IDAgMCA4MCAzMScgY2xhc3NOYW1lPSduYXYtYmFyLWxvZ28nPlxuICAgICAgPExpbmsgdG89Jy8nPlxuICAgICAgICA8dGl0bGU+TG9nbzwvdGl0bGU+XG4gICAgICAgIDxkZXNjPlNwZWUuY2ggbG9nbzwvZGVzYz5cbiAgICAgICAgPGcgaWQ9J0Fib3V0Jz5cbiAgICAgICAgICA8ZyBpZD0nUHVibGlzaC1Gb3JtLVYyLV94MjhfZmlsbGVkX3gyOV8nIHRyYW5zZm9ybT0ndHJhbnNsYXRlKC00Mi4wMDAwMDAsIC0yMy4wMDAwMDApJz5cbiAgICAgICAgICAgIDxnIGlkPSdHcm91cC0xNycgdHJhbnNmb3JtPSd0cmFuc2xhdGUoNDIuMDAwMDAwLCAyMi4wMDAwMDApJz5cbiAgICAgICAgICAgICAgPHRleHQgdHJhbnNmb3JtPSdtYXRyaXgoMSAwIDAgMSAwIDIwKScgZm9udFNpemU9JzI1JyBmb250RmFtaWx5PSdSb2JvdG8nPlNwZWUmbHQ7aDwvdGV4dD5cbiAgICAgICAgICAgICAgPGcgaWQ9J0dyb3VwLTE2JyB0cmFuc2Zvcm09J3RyYW5zbGF0ZSgwLjAwMDAwMCwgMzAuMDAwMDAwKSc+XG4gICAgICAgICAgICAgICAgPHBhdGggaWQ9J0xpbmUtOCcgZmlsbD0nbm9uZScgc3Ryb2tlPScjMDlGOTExJyBzdHJva2VXaWR0aD0nMScgc3Ryb2tlTGluZWNhcD0nc3F1YXJlJyBkPSdNMC41LDEuNWgxNScgLz5cbiAgICAgICAgICAgICAgICA8cGF0aCBpZD0nTGluZS04LUNvcHknIGZpbGw9J25vbmUnIHN0cm9rZT0nIzAyOUQ3NCcgc3Ryb2tlV2lkdGg9JzEnIHN0cm9rZUxpbmVjYXA9J3NxdWFyZScgZD0nTTE2LjUsMS41aDE1JyAvPlxuICAgICAgICAgICAgICAgIDxwYXRoIGlkPSdMaW5lLTgtQ29weS0yJyBmaWxsPSdub25lJyBzdHJva2U9JyNFMzVCRDgnIHN0cm9rZVdpZHRoPScxJyBzdHJva2VMaW5lY2FwPSdzcXVhcmUnIGQ9J00zMi41LDEuNWgxNScgLz5cbiAgICAgICAgICAgICAgICA8cGF0aCBpZD0nTGluZS04LUNvcHktMycgZmlsbD0nbm9uZScgc3Ryb2tlPScjNDE1NkM1JyBzdHJva2VXaWR0aD0nMScgc3Ryb2tlTGluZWNhcD0nc3F1YXJlJyBkPSdNNDguNSwxLjVoMTUnIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggaWQ9J0xpbmUtOC1Db3B5LTQnIGZpbGw9J25vbmUnIHN0cm9rZT0nIzYzNTY4OCcgc3Ryb2tlV2lkdGg9JzEnIHN0cm9rZUxpbmVjYXA9J3NxdWFyZScgZD0nTTY0LjUsMS41aDE1JyAvPlxuICAgICAgICAgICAgICA8L2c+XG4gICAgICAgICAgICA8L2c+XG4gICAgICAgICAgPC9nPlxuICAgICAgICA8L2c+XG4gICAgICA8L0xpbms+XG4gICAgPC9zdmc+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBMb2dvO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29tcG9uZW50cy9Mb2dvL2luZGV4LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmZ1bmN0aW9uIE5hdkJhckNoYW5uZWxEcm9wZG93biAoeyBjaGFubmVsTmFtZSwgaGFuZGxlU2VsZWN0aW9uLCBkZWZhdWx0U2VsZWN0aW9uLCBWSUVXLCBMT0dPVVQgfSkge1xuICByZXR1cm4gKFxuICAgIDxzZWxlY3QgdHlwZT0ndGV4dCcgaWQ9J25hdi1iYXItY2hhbm5lbC1zZWxlY3QnIGNsYXNzTmFtZT0nc2VsZWN0IHNlbGVjdC0tYXJyb3cgbGluay0tbmF2JyBvbkNoYW5nZT17aGFuZGxlU2VsZWN0aW9ufSB2YWx1ZT17ZGVmYXVsdFNlbGVjdGlvbn0+XG4gICAgICA8b3B0aW9uIGlkPSduYXYtYmFyLWNoYW5uZWwtc2VsZWN0LWNoYW5uZWwtb3B0aW9uJz57Y2hhbm5lbE5hbWV9PC9vcHRpb24+XG4gICAgICA8b3B0aW9uIHZhbHVlPXtWSUVXfT5WaWV3PC9vcHRpb24+XG4gICAgICA8b3B0aW9uIHZhbHVlPXtMT0dPVVR9PkxvZ291dDwvb3B0aW9uPlxuICAgIDwvc2VsZWN0PlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgTmF2QmFyQ2hhbm5lbERyb3Bkb3duO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duL2luZGV4LmpzeCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNyb3NzLWZldGNoL3BvbHlmaWxsXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiY3Jvc3MtZmV0Y2gvcG9seWZpbGxcIlxuLy8gbW9kdWxlIGlkID0gOTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBmaWxlICA6IHB1Ymxpc2guZmlsZSxcbiAgICBzdGF0dXM6IHB1Ymxpc2guc3RhdHVzLnN0YXR1cyxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvUHVibGlzaFRvb2wvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IERyb3B6b25lIGZyb20gJ2NvbnRhaW5lcnMvRHJvcHpvbmUnO1xuaW1wb3J0IFB1Ymxpc2hEZXRhaWxzIGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaERldGFpbHMnO1xuaW1wb3J0IFB1Ymxpc2hTdGF0dXMgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoU3RhdHVzJztcblxuY2xhc3MgUHVibGlzaFRvb2wgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGlmICh0aGlzLnByb3BzLmZpbGUpIHtcbiAgICAgIGlmICh0aGlzLnByb3BzLnN0YXR1cykge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxQdWJsaXNoU3RhdHVzIC8+XG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gPFB1Ymxpc2hEZXRhaWxzIC8+O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gPERyb3B6b25lIC8+O1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgUHVibGlzaFRvb2w7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hUb29sL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHZhbGlkYXRlRmlsZSB9IGZyb20gJ3V0aWxzL2ZpbGUnO1xuaW1wb3J0IFByZXZpZXcgZnJvbSAnY29tcG9uZW50cy9QcmV2aWV3JztcblxuY2xhc3MgRHJvcHpvbmUgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGRyYWdPdmVyICA6IGZhbHNlLFxuICAgICAgbW91c2VPdmVyIDogZmFsc2UsXG4gICAgICBkaW1QcmV2aWV3OiBmYWxzZSxcbiAgICB9O1xuICAgIHRoaXMuaGFuZGxlRHJvcCA9IHRoaXMuaGFuZGxlRHJvcC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlRHJhZ092ZXIgPSB0aGlzLmhhbmRsZURyYWdPdmVyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVEcmFnRW5kID0gdGhpcy5oYW5kbGVEcmFnRW5kLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVEcmFnRW50ZXIgPSB0aGlzLmhhbmRsZURyYWdFbnRlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlRHJhZ0xlYXZlID0gdGhpcy5oYW5kbGVEcmFnTGVhdmUuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZU1vdXNlRW50ZXIgPSB0aGlzLmhhbmRsZU1vdXNlRW50ZXIuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZU1vdXNlTGVhdmUgPSB0aGlzLmhhbmRsZU1vdXNlTGVhdmUuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZUNsaWNrID0gdGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlRmlsZUlucHV0ID0gdGhpcy5oYW5kbGVGaWxlSW5wdXQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmNob29zZUZpbGUgPSB0aGlzLmNob29zZUZpbGUuYmluZCh0aGlzKTtcbiAgfVxuICBoYW5kbGVEcm9wIChldmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7ZHJhZ092ZXI6IGZhbHNlfSk7XG4gICAgLy8gaWYgZHJvcHBlZCBpdGVtcyBhcmVuJ3QgZmlsZXMsIHJlamVjdCB0aGVtXG4gICAgY29uc3QgZHQgPSBldmVudC5kYXRhVHJhbnNmZXI7XG4gICAgaWYgKGR0Lml0ZW1zKSB7XG4gICAgICBpZiAoZHQuaXRlbXNbMF0ua2luZCA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgIGNvbnN0IGRyb3BwZWRGaWxlID0gZHQuaXRlbXNbMF0uZ2V0QXNGaWxlKCk7XG4gICAgICAgIHRoaXMuY2hvb3NlRmlsZShkcm9wcGVkRmlsZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGhhbmRsZURyYWdPdmVyIChldmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbiAgaGFuZGxlRHJhZ0VuZCAoZXZlbnQpIHtcbiAgICB2YXIgZHQgPSBldmVudC5kYXRhVHJhbnNmZXI7XG4gICAgaWYgKGR0Lml0ZW1zKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGR0Lml0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGR0Lml0ZW1zLnJlbW92ZShpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyLmNsZWFyRGF0YSgpO1xuICAgIH1cbiAgfVxuICBoYW5kbGVEcmFnRW50ZXIgKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe2RyYWdPdmVyOiB0cnVlLCBkaW1QcmV2aWV3OiB0cnVlfSk7XG4gIH1cbiAgaGFuZGxlRHJhZ0xlYXZlICgpIHtcbiAgICB0aGlzLnNldFN0YXRlKHtkcmFnT3ZlcjogZmFsc2UsIGRpbVByZXZpZXc6IGZhbHNlfSk7XG4gIH1cbiAgaGFuZGxlTW91c2VFbnRlciAoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7bW91c2VPdmVyOiB0cnVlLCBkaW1QcmV2aWV3OiB0cnVlfSk7XG4gIH1cbiAgaGFuZGxlTW91c2VMZWF2ZSAoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7bW91c2VPdmVyOiBmYWxzZSwgZGltUHJldmlldzogZmFsc2V9KTtcbiAgfVxuICBoYW5kbGVDbGljayAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmaWxlX2lucHV0JykuY2xpY2soKTtcbiAgfVxuICBoYW5kbGVGaWxlSW5wdXQgKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBmaWxlTGlzdCA9IGV2ZW50LnRhcmdldC5maWxlcztcbiAgICB0aGlzLmNob29zZUZpbGUoZmlsZUxpc3RbMF0pO1xuICB9XG4gIGNob29zZUZpbGUgKGZpbGUpIHtcbiAgICBpZiAoZmlsZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsaWRhdGVGaWxlKGZpbGUpOyAvLyB2YWxpZGF0ZSB0aGUgZmlsZSdzIG5hbWUsIHR5cGUsIGFuZCBzaXplXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5zZXRGaWxlRXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICB9XG4gICAgICAvLyBzdGFnZSBpdCBzbyBpdCB3aWxsIGJlIHJlYWR5IHdoZW4gdGhlIHB1Ymxpc2ggYnV0dG9uIGlzIGNsaWNrZWRcbiAgICAgIHRoaXMucHJvcHMuc2VsZWN0RmlsZShmaWxlKTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXRhbGwgZmxleC1jb250YWluZXItLWNvbHVtbic+XG4gICAgICAgIDxmb3JtPlxuICAgICAgICAgIDxpbnB1dCBjbGFzc05hbWU9J2lucHV0LWZpbGUnIHR5cGU9J2ZpbGUnIGlkPSdmaWxlX2lucHV0JyBuYW1lPSdmaWxlX2lucHV0JyBhY2NlcHQ9J3ZpZGVvLyosaW1hZ2UvKicgb25DaGFuZ2U9e3RoaXMuaGFuZGxlRmlsZUlucHV0fSBlbmNUeXBlPSdtdWx0aXBhcnQvZm9ybS1kYXRhJyAvPlxuICAgICAgICA8L2Zvcm0+XG4gICAgICAgIDxkaXYgaWQ9J3ByZXZpZXctZHJvcHpvbmUnIGNsYXNzTmFtZT17J3JvdyByb3ctLXBhZGRlZCByb3ctLXRhbGwgZHJvcHpvbmUnICsgKHRoaXMuc3RhdGUuZHJhZ092ZXIgPyAnIGRyb3B6b25lLS1kcmFnLW92ZXInIDogJycpfSBvbkRyb3A9e3RoaXMuaGFuZGxlRHJvcH0gb25EcmFnT3Zlcj17dGhpcy5oYW5kbGVEcmFnT3Zlcn0gb25EcmFnRW5kPXt0aGlzLmhhbmRsZURyYWdFbmR9IG9uRHJhZ0VudGVyPXt0aGlzLmhhbmRsZURyYWdFbnRlcn0gb25EcmFnTGVhdmU9e3RoaXMuaGFuZGxlRHJhZ0xlYXZlfSBvbk1vdXNlRW50ZXI9e3RoaXMuaGFuZGxlTW91c2VFbnRlcn0gb25Nb3VzZUxlYXZlPXt0aGlzLmhhbmRsZU1vdXNlTGVhdmV9IG9uQ2xpY2s9e3RoaXMuaGFuZGxlQ2xpY2t9PlxuICAgICAgICAgIHt0aGlzLnByb3BzLmZpbGUgPyAoXG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8UHJldmlld1xuICAgICAgICAgICAgICAgIGRpbVByZXZpZXc9e3RoaXMuc3RhdGUuZGltUHJldmlld31cbiAgICAgICAgICAgICAgICBmaWxlPXt0aGlzLnByb3BzLmZpbGV9XG4gICAgICAgICAgICAgICAgdGh1bWJuYWlsPXt0aGlzLnByb3BzLnRodW1ibmFpbH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPGRpdiBpZD0nZHJvcHpvbmUtdGV4dC1ob2xkZXInIGNsYXNzTmFtZT17J2ZsZXgtY29udGFpbmVyLS1jb2x1bW4gZmxleC1jb250YWluZXItLWNlbnRlci1jZW50ZXInfT5cbiAgICAgICAgICAgICAgICB7IHRoaXMuc3RhdGUuZHJhZ092ZXIgPyAoXG4gICAgICAgICAgICAgICAgICA8ZGl2IGlkPSdkcm9wem9uZS1kcmFnb3Zlcic+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nYmx1ZSc+RHJvcCBpdC48L3A+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgeyB0aGlzLnN0YXRlLm1vdXNlT3ZlciA/IChcbiAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLWluc3RydWN0aW9ucyc+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLXBsYWNlaG9sZGVyIGluZm8tbWVzc2FnZS0tZmFpbHVyZScgaWQ9J2lucHV0LWVycm9yLWZpbGUtc2VsZWN0aW9uJz57dGhpcy5wcm9wcy5maWxlRXJyb3J9PC9wPlxuICAgICAgICAgICAgICAgICAgICA8cD5EcmFnICYgZHJvcCBpbWFnZSBvciB2aWRlbyBoZXJlIHRvIHB1Ymxpc2g8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+T1I8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nYmx1ZS0tdW5kZXJsaW5lZCc+Q0hPT1NFIEZJTEU8L3A+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLXRleHQtaG9sZGVyJyBjbGFzc05hbWU9eydmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJ30+XG4gICAgICAgICAgICAgIHsgdGhpcy5zdGF0ZS5kcmFnT3ZlciA/IChcbiAgICAgICAgICAgICAgICA8ZGl2IGlkPSdkcm9wem9uZS1kcmFnb3Zlcic+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2JsdWUnPkRyb3AgaXQuPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLWluc3RydWN0aW9ucyc+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS1wbGFjZWhvbGRlciBpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnIGlkPSdpbnB1dC1lcnJvci1maWxlLXNlbGVjdGlvbic+e3RoaXMucHJvcHMuZmlsZUVycm9yfTwvcD5cbiAgICAgICAgICAgICAgICAgIDxwPkRyYWcgJiBkcm9wIGltYWdlIG9yIHZpZGVvIGhlcmUgdG8gcHVibGlzaDwvcD5cbiAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+T1I8L3A+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2JsdWUtLXVuZGVybGluZWQnPkNIT09TRSBGSUxFPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBEcm9wem9uZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvRHJvcHpvbmUvdmlldy5qc3giLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVGaWxlIChmaWxlKSB7XG4gICAgaWYgKCFmaWxlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGZpbGUgcHJvdmlkZWQnKTtcbiAgICB9XG4gICAgaWYgKC8nLy50ZXN0KGZpbGUubmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYXBvc3Ryb3BoZXMgYXJlIG5vdCBhbGxvd2VkIGluIHRoZSBmaWxlIG5hbWUnKTtcbiAgICB9XG4gICAgLy8gdmFsaWRhdGUgc2l6ZSBhbmQgdHlwZVxuICAgIHN3aXRjaCAoZmlsZS50eXBlKSB7XG4gICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICBpZiAoZmlsZS5zaXplID4gMTAwMDAwMDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCBpbWFnZXMgYXJlIGxpbWl0ZWQgdG8gMTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb3JyeSwgR0lGcyBhcmUgbGltaXRlZCB0byA1MCBtZWdhYnl0ZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd2aWRlby9tcDQnOlxuICAgICAgICBpZiAoZmlsZS5zaXplID4gNTAwMDAwMDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCB2aWRlb3MgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZpbGUudHlwZSArICcgaXMgbm90IGEgc3VwcG9ydGVkIGZpbGUgdHlwZS4gT25seSwgLmpwZWcsIC5wbmcsIC5naWYsIGFuZCAubXA0IGZpbGVzIGFyZSBjdXJyZW50bHkgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC91dGlscy9maWxlLmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5cbmNsYXNzIFByZXZpZXcgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGltZ1NvdXJjZSAgICAgICA6ICcnLFxuICAgICAgZGVmYXVsdFRodW1ibmFpbDogJy9hc3NldHMvaW1nL3ZpZGVvX3RodW1iX2RlZmF1bHQucG5nJyxcbiAgICB9O1xuICB9XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnNldFByZXZpZXdJbWFnZVNvdXJjZSh0aGlzLnByb3BzLmZpbGUpO1xuICB9XG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgKG5ld1Byb3BzKSB7XG4gICAgaWYgKG5ld1Byb3BzLmZpbGUgIT09IHRoaXMucHJvcHMuZmlsZSkge1xuICAgICAgdGhpcy5zZXRQcmV2aWV3SW1hZ2VTb3VyY2UobmV3UHJvcHMuZmlsZSk7XG4gICAgfVxuICAgIGlmIChuZXdQcm9wcy50aHVtYm5haWwgIT09IHRoaXMucHJvcHMudGh1bWJuYWlsKSB7XG4gICAgICBpZiAobmV3UHJvcHMudGh1bWJuYWlsKSB7XG4gICAgICAgIHRoaXMuc2V0UHJldmlld0ltYWdlU291cmNlRnJvbUZpbGUobmV3UHJvcHMudGh1bWJuYWlsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe2ltZ1NvdXJjZTogdGhpcy5zdGF0ZS5kZWZhdWx0VGh1bWJuYWlsfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlIChmaWxlKSB7XG4gICAgY29uc3QgcHJldmlld1JlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcHJldmlld1JlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIHByZXZpZXdSZWFkZXIub25sb2FkZW5kID0gKCkgPT4ge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7aW1nU291cmNlOiBwcmV2aWV3UmVhZGVyLnJlc3VsdH0pO1xuICAgIH07XG4gIH1cbiAgc2V0UHJldmlld0ltYWdlU291cmNlIChmaWxlKSB7XG4gICAgaWYgKGZpbGUudHlwZSAhPT0gJ3ZpZGVvL21wNCcpIHtcbiAgICAgIHRoaXMuc2V0UHJldmlld0ltYWdlU291cmNlRnJvbUZpbGUoZmlsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnByb3BzLnRodW1ibmFpbCkge1xuICAgICAgICB0aGlzLnNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlKHRoaXMucHJvcHMudGh1bWJuYWlsKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoe2ltZ1NvdXJjZTogdGhpcy5zdGF0ZS5kZWZhdWx0VGh1bWJuYWlsfSk7XG4gICAgfVxuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxpbWdcbiAgICAgICAgaWQ9J2Ryb3B6b25lLXByZXZpZXcnXG4gICAgICAgIHNyYz17dGhpcy5zdGF0ZS5pbWdTb3VyY2V9XG4gICAgICAgIGNsYXNzTmFtZT17dGhpcy5wcm9wcy5kaW1QcmV2aWV3ID8gJ2RpbScgOiAnJ31cbiAgICAgICAgYWx0PSdwdWJsaXNoIHByZXZpZXcnXG4gICAgICAvPlxuICAgICk7XG4gIH1cbn07XG5cblByZXZpZXcucHJvcFR5cGVzID0ge1xuICBkaW1QcmV2aWV3OiBQcm9wVHlwZXMuYm9vbC5pc1JlcXVpcmVkLFxuICBmaWxlICAgICAgOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gIHRodW1ibmFpbCA6IFByb3BUeXBlcy5vYmplY3QsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBQcmV2aWV3O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29tcG9uZW50cy9QcmV2aWV3L2luZGV4LmpzeCIsImltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHtjbGVhckZpbGUsIHN0YXJ0UHVibGlzaH0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IGNoYW5uZWwsIHB1Ymxpc2ggfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGZpbGU6IHB1Ymxpc2guZmlsZSxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IHtcbiAgY2xlYXJGaWxlLFxuICBzdGFydFB1Ymxpc2gsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvUHVibGlzaERldGFpbHMvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgd2l0aFJvdXRlciB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IERyb3B6b25lIGZyb20gJ2NvbnRhaW5lcnMvRHJvcHpvbmUnO1xuaW1wb3J0IFB1Ymxpc2hUaXRsZUlucHV0IGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaFRpdGxlSW5wdXQnO1xuaW1wb3J0IFB1Ymxpc2hVcmxJbnB1dCBmcm9tICdjb250YWluZXJzL1B1Ymxpc2hVcmxJbnB1dCc7XG5pbXBvcnQgUHVibGlzaFRodW1ibmFpbElucHV0IGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaFRodW1ibmFpbElucHV0JztcbmltcG9ydCBQdWJsaXNoTWV0YWRhdGFJbnB1dHMgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoTWV0YWRhdGFJbnB1dHMnO1xuaW1wb3J0IENoYW5uZWxTZWxlY3QgZnJvbSAnY29udGFpbmVycy9DaGFubmVsU2VsZWN0JztcblxuY2xhc3MgUHVibGlzaERldGFpbHMgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcylcbiAgICB0aGlzLm9uUHVibGlzaFN1Ym1pdCA9IHRoaXMub25QdWJsaXNoU3VibWl0LmJpbmQodGhpcyk7XG4gIH1cbiAgb25QdWJsaXNoU3VibWl0ICgpIHtcbiAgICB0aGlzLnByb3BzLnN0YXJ0UHVibGlzaCh0aGlzLnByb3BzLmhpc3RvcnkpO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1uby1ib3R0b20nPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAnPlxuICAgICAgICAgIDxQdWJsaXNoVGl0bGVJbnB1dCAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgey8qIGxlZnQgY29sdW1uICovfVxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNSBjb2x1bW4tLXNtbC0xMCcgPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgICAgPERyb3B6b25lIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7LyogcmlnaHQgY29sdW1uICovfVxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNSBjb2x1bW4tLXNtbC0xMCBhbGlnbi1jb250ZW50LXRvcCc+XG4gICAgICAgICAgPGRpdiBpZD0ncHVibGlzaC1hY3RpdmUtYXJlYScgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUnPlxuICAgICAgICAgICAgICA8UHVibGlzaFVybElucHV0IC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1uby10b3Agcm93LS13aWRlJz5cbiAgICAgICAgICAgICAgPENoYW5uZWxTZWxlY3QgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgeyAodGhpcy5wcm9wcy5maWxlLnR5cGUgPT09ICd2aWRlby9tcDQnKSAmJiAoXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1uby10b3Agcm93LS13aWRlICc+XG4gICAgICAgICAgICAgICAgPFB1Ymxpc2hUaHVtYm5haWxJbnB1dCAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0tbm8tdG9wIHJvdy0tbm8tYm90dG9tIHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgIDxQdWJsaXNoTWV0YWRhdGFJbnB1dHMgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXdpZGUgYWxpZ24tY29udGVudC1jZW50ZXInPlxuICAgICAgICAgICAgICA8YnV0dG9uIGlkPSdwdWJsaXNoLXN1Ym1pdCcgY2xhc3NOYW1lPSdidXR0b24tLXByaW1hcnkgYnV0dG9uLS1sYXJnZScgb25DbGljaz17dGhpcy5vblB1Ymxpc2hTdWJtaXR9PlB1Ymxpc2g8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLWJvdHRvbSBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLWNhbmNlbCcgb25DbGljaz17dGhpcy5wcm9wcy5jbGVhckZpbGV9PkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tc2hvcnQgYWxpZ24tY29udGVudC1jZW50ZXInPlxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2ZpbmUtcHJpbnQnPkJ5IGNsaWNraW5nICdQdWJsaXNoJywgeW91IGFmZmlybSB0aGF0IHlvdSBoYXZlIHRoZSByaWdodHMgdG8gcHVibGlzaCB0aGlzIGNvbnRlbnQgdG8gdGhlIExCUlkgbmV0d29yaywgYW5kIHRoYXQgeW91IHVuZGVyc3RhbmQgdGhlIHByb3BlcnRpZXMgb2YgcHVibGlzaGluZyBpdCB0byBhIGRlY2VudHJhbGl6ZWQsIHVzZXItY29udHJvbGxlZCBuZXR3b3JrLiA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPSdodHRwczovL2xicnkuaW8vbGVhcm4nPlJlYWQgbW9yZS48L2E+PC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgd2l0aFJvdXRlcihQdWJsaXNoRGV0YWlscyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hEZXRhaWxzL3ZpZXcuanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge3VwZGF0ZU1ldGFkYXRhfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgdGl0bGU6IHB1Ymxpc2gubWV0YWRhdGEudGl0bGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25NZXRhZGF0YUNoYW5nZTogKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVNZXRhZGF0YShuYW1lLCB2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvUHVibGlzaFRpdGxlSW5wdXQvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jbGFzcyBQdWJsaXNoVGl0bGVJbnB1dCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICB9XG4gIGhhbmRsZUlucHV0IChlKSB7XG4gICAgY29uc3QgbmFtZSA9IGUudGFyZ2V0Lm5hbWU7XG4gICAgY29uc3QgdmFsdWUgPSBlLnRhcmdldC52YWx1ZTtcbiAgICB0aGlzLnByb3BzLm9uTWV0YWRhdGFDaGFuZ2UobmFtZSwgdmFsdWUpO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0ncHVibGlzaC10aXRsZScgY2xhc3NOYW1lPSdpbnB1dC10ZXh0IHRleHQtLWxhcmdlIGlucHV0LXRleHQtLWZ1bGwtd2lkdGgnIG5hbWU9J3RpdGxlJyBwbGFjZWhvbGRlcj0nR2l2ZSB5b3VyIHBvc3QgYSB0aXRsZS4uLicgb25DaGFuZ2U9e3RoaXMuaGFuZGxlSW5wdXR9IHZhbHVlPXt0aGlzLnByb3BzLnRpdGxlfSAvPlxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVibGlzaFRpdGxlSW5wdXQ7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L3ZpZXcuanN4IiwiaW1wb3J0IHt1cGRhdGVDbGFpbSwgdXBkYXRlRXJyb3J9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQge2Nvbm5lY3R9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IGNoYW5uZWwsIHB1Ymxpc2ggfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGxvZ2dlZEluQ2hhbm5lbE5hbWUgICA6IGNoYW5uZWwubG9nZ2VkSW5DaGFubmVsLm5hbWUsXG4gICAgbG9nZ2VkSW5DaGFubmVsU2hvcnRJZDogY2hhbm5lbC5sb2dnZWRJbkNoYW5uZWwuc2hvcnRJZCxcbiAgICBmaWxlTmFtZSAgICAgICAgICAgICAgOiBwdWJsaXNoLmZpbGUubmFtZSxcbiAgICBwdWJsaXNoSW5DaGFubmVsICAgICAgOiBwdWJsaXNoLnB1Ymxpc2hJbkNoYW5uZWwsXG4gICAgc2VsZWN0ZWRDaGFubmVsICAgICAgIDogcHVibGlzaC5zZWxlY3RlZENoYW5uZWwsXG4gICAgY2xhaW0gICAgICAgICAgICAgICAgIDogcHVibGlzaC5jbGFpbSxcbiAgICB1cmxFcnJvciAgICAgICAgICAgICAgOiBwdWJsaXNoLmVycm9yLnVybCxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IGRpc3BhdGNoID0+IHtcbiAgcmV0dXJuIHtcbiAgICBvbkNsYWltQ2hhbmdlOiAodmFsdWUpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUNsYWltKHZhbHVlKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcigncHVibGlzaFN1Ym1pdCcsIG51bGwpKTtcbiAgICB9LFxuICAgIG9uVXJsRXJyb3I6ICh2YWx1ZSkgPT4ge1xuICAgICAgZGlzcGF0Y2godXBkYXRlRXJyb3IoJ3VybCcsIHZhbHVlKSk7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHJlcXVlc3QgZnJvbSAndXRpbHMvcmVxdWVzdCc7XG5pbXBvcnQgVXJsTWlkZGxlIGZyb20gJ2NvbXBvbmVudHMvUHVibGlzaFVybE1pZGRsZURpc3BsYXknO1xuXG5jbGFzcyBQdWJsaXNoVXJsSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBjbGFpbSwgZmlsZU5hbWUgfSA9IHRoaXMucHJvcHM7XG4gICAgaWYgKCFjbGFpbSkge1xuICAgICAgdGhpcy5zZXRDbGFpbU5hbWUoZmlsZU5hbWUpO1xuICAgIH1cbiAgfVxuICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzICh7IGNsYWltLCBmaWxlTmFtZSB9KSB7XG4gICAgLy8gaWYgYSBuZXcgZmlsZSB3YXMgY2hvc2VuLCB1cGRhdGUgdGhlIGNsYWltIG5hbWVcbiAgICBpZiAoZmlsZU5hbWUgIT09IHRoaXMucHJvcHMuZmlsZU5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldENsYWltTmFtZShmaWxlTmFtZSk7XG4gICAgfVxuICAgIC8vIGlmIHRoZSBjbGFpbSBoYXMgdXBkYXRlZCwgY2hlY2sgaXRzIGF2YWlsYWJpbGl0eVxuICAgIGlmIChjbGFpbSAhPT0gdGhpcy5wcm9wcy5jbGFpbSkge1xuICAgICAgdGhpcy52YWxpZGF0ZUNsYWltKGNsYWltKTtcbiAgICB9XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgbGV0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHZhbHVlID0gdGhpcy5jbGVhbnNlSW5wdXQodmFsdWUpO1xuICAgIC8vIHVwZGF0ZSB0aGUgc3RhdGVcbiAgICB0aGlzLnByb3BzLm9uQ2xhaW1DaGFuZ2UodmFsdWUpO1xuICB9XG4gIGNsZWFuc2VJbnB1dCAoaW5wdXQpIHtcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1xccysvZywgJy0nKTsgLy8gcmVwbGFjZSBzcGFjZXMgd2l0aCBkYXNoZXNcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05LV0vZywgJycpOyAgLy8gcmVtb3ZlIGFsbCBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBBLVosIGEteiwgMC05LCBvciAnLSdcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cbiAgc2V0Q2xhaW1OYW1lIChmaWxlTmFtZSkge1xuICAgIGNvbnN0IGZpbGVOYW1lV2l0aG91dEVuZGluZyA9IGZpbGVOYW1lLnN1YnN0cmluZygwLCBmaWxlTmFtZS5sYXN0SW5kZXhPZignLicpKTtcbiAgICBjb25zdCBjbGVhbkNsYWltTmFtZSA9IHRoaXMuY2xlYW5zZUlucHV0KGZpbGVOYW1lV2l0aG91dEVuZGluZyk7XG4gICAgdGhpcy5wcm9wcy5vbkNsYWltQ2hhbmdlKGNsZWFuQ2xhaW1OYW1lKTtcbiAgfVxuICB2YWxpZGF0ZUNsYWltIChjbGFpbSkge1xuICAgIGlmICghY2xhaW0pIHtcbiAgICAgIHJldHVybiB0aGlzLnByb3BzLm9uVXJsRXJyb3IoJ0VudGVyIGEgdXJsIGFib3ZlJyk7XG4gICAgfVxuICAgIHJlcXVlc3QoYC9hcGkvY2xhaW0vYXZhaWxhYmlsaXR5LyR7Y2xhaW19YClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVybEVycm9yKG51bGwpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVybEVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGNsYWltLCBsb2dnZWRJbkNoYW5uZWxOYW1lLCBsb2dnZWRJbkNoYW5uZWxTaG9ydElkLCBwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwsIHVybEVycm9yIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBzcGFuLS1yZWxhdGl2ZSc+XG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd1cmwtdGV4dC0tc2Vjb25kYXJ5Jz5zcGVlLmNoIC8gPC9zcGFuPlxuICAgICAgICAgIDxVcmxNaWRkbGVcbiAgICAgICAgICAgIHB1Ymxpc2hJbkNoYW5uZWw9e3B1Ymxpc2hJbkNoYW5uZWx9XG4gICAgICAgICAgICBzZWxlY3RlZENoYW5uZWw9e3NlbGVjdGVkQ2hhbm5lbH1cbiAgICAgICAgICAgIGxvZ2dlZEluQ2hhbm5lbE5hbWU9e2xvZ2dlZEluQ2hhbm5lbE5hbWV9XG4gICAgICAgICAgICBsb2dnZWRJbkNoYW5uZWxTaG9ydElkPXtsb2dnZWRJbkNoYW5uZWxTaG9ydElkfVxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdjbGFpbS1uYW1lLWlucHV0JyBjbGFzc05hbWU9J2lucHV0LXRleHQnIG5hbWU9J2NsYWltJyBwbGFjZWhvbGRlcj0neW91ci11cmwtaGVyZScgb25DaGFuZ2U9e3RoaXMuaGFuZGxlSW5wdXR9IHZhbHVlPXtjbGFpbX0gLz5cbiAgICAgICAgICB7IChjbGFpbSAmJiAhdXJsRXJyb3IpICYmIDxzcGFuIGlkPSdpbnB1dC1zdWNjZXNzLWNsYWltLW5hbWUnIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1zdWNjZXNzIHNwYW4tLWFic29sdXRlJz57J1xcdTI3MTMnfTwvc3Bhbj4gfVxuICAgICAgICAgIHsgdXJsRXJyb3IgJiYgPHNwYW4gaWQ9J2lucHV0LXN1Y2Nlc3MtY2hhbm5lbC1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSBzcGFuLS1hYnNvbHV0ZSc+eydcXHUyNzE2J308L3NwYW4+IH1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgeyB1cmxFcnJvciA/IChcbiAgICAgICAgICAgIDxwIGlkPSdpbnB1dC1lcnJvci1jbGFpbS1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e3VybEVycm9yfTwvcD5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPkNob29zZSBhIGN1c3RvbSB1cmw8L3A+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hVcmxJbnB1dDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvUHVibGlzaFVybElucHV0L3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5cbmZ1bmN0aW9uIFVybE1pZGRsZSAoe3B1Ymxpc2hJbkNoYW5uZWwsIHNlbGVjdGVkQ2hhbm5lbCwgbG9nZ2VkSW5DaGFubmVsTmFtZSwgbG9nZ2VkSW5DaGFubmVsU2hvcnRJZH0pIHtcbiAgaWYgKHB1Ymxpc2hJbkNoYW5uZWwpIHtcbiAgICBpZiAoc2VsZWN0ZWRDaGFubmVsID09PSBsb2dnZWRJbkNoYW5uZWxOYW1lKSB7XG4gICAgICByZXR1cm4gPHNwYW4gaWQ9J3VybC1jaGFubmVsJyBjbGFzc05hbWU9J3VybC10ZXh0LS1zZWNvbmRhcnknPntsb2dnZWRJbkNoYW5uZWxOYW1lfTp7bG9nZ2VkSW5DaGFubmVsU2hvcnRJZH0gLzwvc3Bhbj47XG4gICAgfVxuICAgIHJldHVybiA8c3BhbiBpZD0ndXJsLWNoYW5uZWwtcGxhY2Vob2xkZXInIGNsYXNzTmFtZT0ndXJsLXRleHQtLXNlY29uZGFyeSB0b29sdGlwJz5AY2hhbm5lbDxzcGFuXG4gICAgICBjbGFzc05hbWU9J3Rvb2x0aXAtdGV4dCc+U2VsZWN0IGEgY2hhbm5lbCBiZWxvdzwvc3Bhbj4gLzwvc3Bhbj47XG4gIH1cbiAgcmV0dXJuIChcbiAgICA8c3BhbiBpZD0ndXJsLW5vLWNoYW5uZWwtcGxhY2Vob2xkZXInIGNsYXNzTmFtZT0ndXJsLXRleHQtLXNlY29uZGFyeSB0b29sdGlwJz54eXo8c3BhbiBjbGFzc05hbWU9J3Rvb2x0aXAtdGV4dCc+VGhpcyB3aWxsIGJlIGEgcmFuZG9tIGlkPC9zcGFuPiAvPC9zcGFuPlxuICApO1xufVxuXG5VcmxNaWRkbGUucHJvcFR5cGVzID0ge1xuICBwdWJsaXNoSW5DaGFubmVsICAgICAgOiBQcm9wVHlwZXMuYm9vbC5pc1JlcXVpcmVkLFxuICBsb2dnZWRJbkNoYW5uZWxOYW1lICAgOiBQcm9wVHlwZXMuc3RyaW5nLFxuICBsb2dnZWRJbkNoYW5uZWxTaG9ydElkOiBQcm9wVHlwZXMuc3RyaW5nLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgVXJsTWlkZGxlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29tcG9uZW50cy9QdWJsaXNoVXJsTWlkZGxlRGlzcGxheS9pbmRleC5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgb25OZXdUaHVtYm5haWwgfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaDogeyBmaWxlIH0gfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGZpbGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIG9uTmV3VGh1bWJuYWlsLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hUaHVtYm5haWxJbnB1dC9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmZ1bmN0aW9uIGRhdGFVUkl0b0Jsb2IoZGF0YVVSSSkge1xuICAvLyBjb252ZXJ0IGJhc2U2NC9VUkxFbmNvZGVkIGRhdGEgY29tcG9uZW50IHRvIHJhdyBiaW5hcnkgZGF0YSBoZWxkIGluIGEgc3RyaW5nXG4gIGxldCBieXRlU3RyaW5nID0gYXRvYihkYXRhVVJJLnNwbGl0KCcsJylbMV0pO1xuICAvLyBzZXBhcmF0ZSBvdXQgdGhlIG1pbWUgY29tcG9uZW50XG4gIGxldCBtaW1lU3RyaW5nID0gZGF0YVVSSS5zcGxpdCgnLCcpWzBdLnNwbGl0KCc6JylbMV0uc3BsaXQoJzsnKVswXTtcbiAgLy8gd3JpdGUgdGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmcgdG8gYSB0eXBlZCBhcnJheVxuICBsZXQgaWEgPSBuZXcgVWludDhBcnJheShieXRlU3RyaW5nLmxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZVN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgIGlhW2ldID0gYnl0ZVN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICB9XG4gIHJldHVybiBuZXcgQmxvYihbaWFdLCB7dHlwZTogbWltZVN0cmluZ30pO1xufVxuXG5jbGFzcyBQdWJsaXNoVGh1bWJuYWlsSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIHZpZGVvU291cmNlICAgOiBudWxsLFxuICAgICAgZXJyb3IgICAgICAgICA6IG51bGwsXG4gICAgICBzbGlkZXJNaW5SYW5nZTogMSxcbiAgICAgIHNsaWRlck1heFJhbmdlOiBudWxsLFxuICAgICAgc2xpZGVyVmFsdWUgICA6IG51bGwsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZVZpZGVvTG9hZGVkRGF0YSA9IHRoaXMuaGFuZGxlVmlkZW9Mb2FkZWREYXRhLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVTbGlkZXJDaGFuZ2UgPSB0aGlzLmhhbmRsZVNsaWRlckNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuY3JlYXRlVGh1bWJuYWlsID0gdGhpcy5jcmVhdGVUaHVtYm5haWwuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBmaWxlIH0gPSB0aGlzLnByb3BzO1xuICAgIHRoaXMuc2V0VmlkZW9Tb3VyY2UoZmlsZSk7XG4gIH1cbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyAobmV4dFByb3BzKSB7XG4gICAgLy8gaWYgZmlsZSBjaGFuZ2VzXG4gICAgaWYgKG5leHRQcm9wcy5maWxlICYmIG5leHRQcm9wcy5maWxlICE9PSB0aGlzLnByb3BzLmZpbGUpIHtcbiAgICAgIGNvbnN0IHsgZmlsZSB9ID0gbmV4dFByb3BzO1xuICAgICAgdGhpcy5zZXRWaWRlb1NvdXJjZShmaWxlKTtcbiAgICB9O1xuICB9XG4gIHNldFZpZGVvU291cmNlIChmaWxlKSB7XG4gICAgY29uc3QgcHJldmlld1JlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcHJldmlld1JlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIHByZXZpZXdSZWFkZXIub25sb2FkZW5kID0gKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVVyaSA9IHByZXZpZXdSZWFkZXIucmVzdWx0O1xuICAgICAgY29uc3QgYmxvYiA9IGRhdGFVUkl0b0Jsb2IoZGF0YVVyaSk7XG4gICAgICBjb25zdCB2aWRlb1NvdXJjZSA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlkZW9Tb3VyY2UgfSk7XG4gICAgfTtcbiAgfVxuICBoYW5kbGVWaWRlb0xvYWRlZERhdGEgKGV2ZW50KSB7XG4gICAgY29uc3QgZHVyYXRpb24gPSBldmVudC50YXJnZXQuZHVyYXRpb247XG4gICAgY29uc3QgdG90YWxNaW51dGVzID0gTWF0aC5mbG9vcihkdXJhdGlvbiAvIDYwKTtcbiAgICBjb25zdCB0b3RhbFNlY29uZHMgPSBNYXRoLmZsb29yKGR1cmF0aW9uICUgNjApO1xuICAgIC8vIHNldCB0aGUgc2xpZGVyXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzbGlkZXJNYXhSYW5nZTogZHVyYXRpb24gKiAxMDAsXG4gICAgICBzbGlkZXJWYWx1ZSAgIDogZHVyYXRpb24gKiAxMDAgLyAyLFxuICAgICAgdG90YWxNaW51dGVzLFxuICAgICAgdG90YWxTZWNvbmRzLFxuICAgIH0pO1xuICAgIC8vIHVwZGF0ZSB0aGUgY3VycmVudCB0aW1lIG9mIHRoZSB2aWRlb1xuICAgIGxldCB2aWRlbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWRlby10aHVtYi1wbGF5ZXInKTtcbiAgICB2aWRlby5jdXJyZW50VGltZSA9IGR1cmF0aW9uIC8gMjtcbiAgfVxuICBoYW5kbGVTbGlkZXJDaGFuZ2UgKGV2ZW50KSB7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZUludChldmVudC50YXJnZXQudmFsdWUpO1xuICAgIC8vIHVwZGF0ZSB0aGUgc2xpZGVyIHZhbHVlXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzbGlkZXJWYWx1ZTogdmFsdWUsXG4gICAgfSk7XG4gICAgLy8gdXBkYXRlIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIHZpZGVvXG4gICAgbGV0IHZpZGVvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpZGVvLXRodW1iLXBsYXllcicpO1xuICAgIHZpZGVvLmN1cnJlbnRUaW1lID0gdmFsdWUgLyAxMDA7XG4gIH1cbiAgY3JlYXRlVGh1bWJuYWlsICgpIHtcbiAgICAvLyB0YWtlIGEgc25hcHNob3RcbiAgICBsZXQgdmlkZW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlkZW8tdGh1bWItcGxheWVyJyk7XG4gICAgbGV0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IHZpZGVvLnZpZGVvV2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IHZpZGVvLnZpZGVvSGVpZ2h0O1xuICAgIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmRyYXdJbWFnZSh2aWRlbywgMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICBjb25zdCBkYXRhVXJsID0gY2FudmFzLnRvRGF0YVVSTCgpO1xuICAgIGNvbnN0IGJsb2IgPSBkYXRhVVJJdG9CbG9iKGRhdGFVcmwpO1xuICAgIGNvbnN0IHNuYXBzaG90ID0gbmV3IEZpbGUoW2Jsb2JdLCBgdGh1bWJuYWlsLnBuZ2AsIHtcbiAgICAgIHR5cGU6ICdpbWFnZS9wbmcnLFxuICAgIH0pO1xuICAgIC8vIHNldCB0aGUgdGh1bWJuYWlsIGluIHJlZHV4IHN0b3JlXG4gICAgaWYgKHNuYXBzaG90KSB7XG4gICAgICB0aGlzLnByb3BzLm9uTmV3VGh1bWJuYWlsKHNuYXBzaG90KTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGVycm9yLCB2aWRlb1NvdXJjZSwgc2xpZGVyTWluUmFuZ2UsIHNsaWRlck1heFJhbmdlLCBzbGlkZXJWYWx1ZSwgdG90YWxNaW51dGVzLCB0b3RhbFNlY29uZHMgfSA9IHRoaXMuc3RhdGU7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJz5UaHVtYm5haWw6PC9sYWJlbD5cbiAgICAgICAgPHZpZGVvXG4gICAgICAgICAgaWQ9J3ZpZGVvLXRodW1iLXBsYXllcidcbiAgICAgICAgICBwcmVsb2FkPSdtZXRhZGF0YSdcbiAgICAgICAgICBtdXRlZFxuICAgICAgICAgIHN0eWxlPXt7ZGlzcGxheTogJ25vbmUnfX1cbiAgICAgICAgICBwbGF5c0lubGluZVxuICAgICAgICAgIG9uTG9hZGVkRGF0YT17dGhpcy5oYW5kbGVWaWRlb0xvYWRlZERhdGF9XG4gICAgICAgICAgc3JjPXt2aWRlb1NvdXJjZX1cbiAgICAgICAgICBvblNlZWtlZD17dGhpcy5jcmVhdGVUaHVtYm5haWx9XG4gICAgICAgIC8+XG4gICAgICAgIHtcbiAgICAgICAgICBzbGlkZXJWYWx1ZSA/IChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWNlbnRlcicgc3R5bGU9e3t3aWR0aDogJzEwMCUnfX0+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPjAnMDBcIjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+e3RvdGFsTWludXRlc30ne3RvdGFsU2Vjb25kc31cIjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPSdyYW5nZSdcbiAgICAgICAgICAgICAgICAgIG1pbj17c2xpZGVyTWluUmFuZ2V9XG4gICAgICAgICAgICAgICAgICBtYXg9e3NsaWRlck1heFJhbmdlfVxuICAgICAgICAgICAgICAgICAgdmFsdWU9e3NsaWRlclZhbHVlfVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPSdzbGlkZXInXG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5oYW5kbGVTbGlkZXJDaGFuZ2V9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnID5sb2FkaW5nLi4uIDwvcD5cbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgeyBlcnJvciA/IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e2Vycm9yfTwvcD5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+VXNlIHNsaWRlciB0byBzZXQgdGh1bWJuYWlsPC9wPlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQdWJsaXNoVGh1bWJuYWlsSW5wdXQ7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hUaHVtYm5haWxJbnB1dC92aWV3LmpzeCIsImltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHt1cGRhdGVNZXRhZGF0YSwgdG9nZ2xlTWV0YWRhdGFJbnB1dHN9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBzaG93TWV0YWRhdGFJbnB1dHM6IHB1Ymxpc2guc2hvd01ldGFkYXRhSW5wdXRzLFxuICAgIGRlc2NyaXB0aW9uICAgICAgIDogcHVibGlzaC5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICBsaWNlbnNlICAgICAgICAgICA6IHB1Ymxpc2gubWV0YWRhdGEubGljZW5zZSxcbiAgICBuc2Z3ICAgICAgICAgICAgICA6IHB1Ymxpc2gubWV0YWRhdGEubnNmdyxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IGRpc3BhdGNoID0+IHtcbiAgcmV0dXJuIHtcbiAgICBvbk1ldGFkYXRhQ2hhbmdlOiAobmFtZSwgdmFsdWUpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZU1ldGFkYXRhKG5hbWUsIHZhbHVlKSk7XG4gICAgfSxcbiAgICBvblRvZ2dsZU1ldGFkYXRhSW5wdXRzOiAodmFsdWUpID0+IHtcbiAgICAgIGRpc3BhdGNoKHRvZ2dsZU1ldGFkYXRhSW5wdXRzKHZhbHVlKSk7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29udGFpbmVycy9QdWJsaXNoTWV0YWRhdGFJbnB1dHMvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEV4cGFuZGluZ1RleHRBcmVhIGZyb20gJ2NvbXBvbmVudHMvRXhwYW5kaW5nVGV4dEFyZWEnO1xuXG5jbGFzcyBQdWJsaXNoTWV0YWRhdGFJbnB1dHMgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy50b2dnbGVTaG93SW5wdXRzID0gdGhpcy50b2dnbGVTaG93SW5wdXRzLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZVNlbGVjdCA9IHRoaXMuaGFuZGxlU2VsZWN0LmJpbmQodGhpcyk7XG4gIH1cbiAgdG9nZ2xlU2hvd0lucHV0cyAoKSB7XG4gICAgdGhpcy5wcm9wcy5vblRvZ2dsZU1ldGFkYXRhSW5wdXRzKCF0aGlzLnByb3BzLnNob3dNZXRhZGF0YUlucHV0cyk7XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuICAgIGNvbnN0IHZhbHVlID0gdGFyZ2V0LnR5cGUgPT09ICdjaGVja2JveCcgPyB0YXJnZXQuY2hlY2tlZCA6IHRhcmdldC52YWx1ZTtcbiAgICBjb25zdCBuYW1lID0gdGFyZ2V0Lm5hbWU7XG4gICAgdGhpcy5wcm9wcy5vbk1ldGFkYXRhQ2hhbmdlKG5hbWUsIHZhbHVlKTtcbiAgfVxuICBoYW5kbGVTZWxlY3QgKGV2ZW50KSB7XG4gICAgY29uc3QgbmFtZSA9IGV2ZW50LnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHNlbGVjdGVkT3B0aW9uID0gZXZlbnQudGFyZ2V0LnNlbGVjdGVkT3B0aW9uc1swXS52YWx1ZTtcbiAgICB0aGlzLnByb3BzLm9uTWV0YWRhdGFDaGFuZ2UobmFtZSwgc2VsZWN0ZWRPcHRpb24pO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgaWQ9J3B1Ymxpc2gtZGV0YWlscycgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1uby10b3Agcm93LS13aWRlJz5cbiAgICAgICAge3RoaXMucHJvcHMuc2hvd01ldGFkYXRhSW5wdXRzICYmIChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLW5vLXRvcCc+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj0ncHVibGlzaC1saWNlbnNlJyBjbGFzc05hbWU9J2xhYmVsJz5EZXNjcmlwdGlvbjo8L2xhYmVsPlxuICAgICAgICAgICAgICA8L2Rpdj48ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNyBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICAgICAgPEV4cGFuZGluZ1RleHRBcmVhXG4gICAgICAgICAgICAgICAgICBpZD0ncHVibGlzaC1kZXNjcmlwdGlvbidcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0ndGV4dGFyZWEgdGV4dGFyZWEtLXByaW1hcnkgdGV4dGFyZWEtLWZ1bGwtd2lkdGgnXG4gICAgICAgICAgICAgICAgICByb3dzPXsxfVxuICAgICAgICAgICAgICAgICAgbWF4TGVuZ3RoPXsyMDAwfVxuICAgICAgICAgICAgICAgICAgc3R5bGU9e3sgbWF4SGVpZ2h0OiAyMDAgfX1cbiAgICAgICAgICAgICAgICAgIG5hbWU9J2Rlc2NyaXB0aW9uJ1xuICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9J09wdGlvbmFsIGRlc2NyaXB0aW9uJ1xuICAgICAgICAgICAgICAgICAgdmFsdWU9e3RoaXMucHJvcHMuZGVzY3JpcHRpb259XG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5oYW5kbGVJbnB1dH0gLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLW5vLXRvcCc+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj0ncHVibGlzaC1saWNlbnNlJyBjbGFzc05hbWU9J2xhYmVsJz5MaWNlbnNlOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03IGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgICAgICA8c2VsZWN0IHR5cGU9J3RleHQnIG5hbWU9J2xpY2Vuc2UnIGlkPSdwdWJsaXNoLWxpY2Vuc2UnIGNsYXNzTmFtZT0nc2VsZWN0IHNlbGVjdC0tcHJpbWFyeScgb25DaGFuZ2U9e3RoaXMuaGFuZGxlU2VsZWN0fT5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9JyAnPlVuc3BlY2lmaWVkPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSdQdWJsaWMgRG9tYWluJz5QdWJsaWMgRG9tYWluPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSdDcmVhdGl2ZSBDb21tb25zJz5DcmVhdGl2ZSBDb21tb25zPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1uby10b3AnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyc+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGh0bWxGb3I9J3B1Ymxpc2gtbnNmdycgY2xhc3NOYW1lPSdsYWJlbCc+TWF0dXJlOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03Jz5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3NOYW1lPSdpbnB1dC1jaGVja2JveCcgdHlwZT0nY2hlY2tib3gnIGlkPSdwdWJsaXNoLW5zZncnIG5hbWU9J25zZncnIHZhbHVlPXt0aGlzLnByb3BzLm5zZnd9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1zZWNvbmRhcnknIG9uQ2xpY2s9e3RoaXMudG9nZ2xlU2hvd0lucHV0c30+e3RoaXMucHJvcHMuc2hvd01ldGFkYXRhSW5wdXRzID8gJ2xlc3MnIDogJ21vcmUnfTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQdWJsaXNoTWV0YWRhdGFJbnB1dHM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy92aWV3LmpzeCIsImltcG9ydCBSZWFjdCwgeyBDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5jbGFzcyBFeHBhbmRpbmdUZXh0YXJlYSBleHRlbmRzIENvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLl9oYW5kbGVDaGFuZ2UgPSB0aGlzLl9oYW5kbGVDaGFuZ2UuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgdGhpcy5hZGp1c3RUZXh0YXJlYSh7fSk7XG4gIH1cbiAgX2hhbmRsZUNoYW5nZSAoZXZlbnQpIHtcbiAgICBjb25zdCB7IG9uQ2hhbmdlIH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChvbkNoYW5nZSkgb25DaGFuZ2UoZXZlbnQpO1xuICAgIHRoaXMuYWRqdXN0VGV4dGFyZWEoZXZlbnQpO1xuICB9XG4gIGFkanVzdFRleHRhcmVhICh7IHRhcmdldCA9IHRoaXMuZWwgfSkge1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSAwO1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBgJHt0YXJnZXQuc2Nyb2xsSGVpZ2h0fXB4YDtcbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgLi4ucmVzdCB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPHRleHRhcmVhXG4gICAgICAgIHsuLi5yZXN0fVxuICAgICAgICByZWY9e3ggPT4gdGhpcy5lbCA9IHh9XG4gICAgICAgIG9uQ2hhbmdlPXt0aGlzLl9oYW5kbGVDaGFuZ2V9XG4gICAgICAvPlxuICAgICk7XG4gIH1cbn1cblxuRXhwYW5kaW5nVGV4dGFyZWEucHJvcFR5cGVzID0ge1xuICBvbkNoYW5nZTogUHJvcFR5cGVzLmZ1bmMsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBFeHBhbmRpbmdUZXh0YXJlYTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbXBvbmVudHMvRXhwYW5kaW5nVGV4dEFyZWEvaW5kZXguanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge3NldFB1Ymxpc2hJbkNoYW5uZWwsIHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbCwgdXBkYXRlRXJyb3J9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBjaGFubmVsLCBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBsb2dnZWRJbkNoYW5uZWxOYW1lOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5uYW1lLFxuICAgIHB1Ymxpc2hJbkNoYW5uZWwgICA6IHB1Ymxpc2gucHVibGlzaEluQ2hhbm5lbCxcbiAgICBzZWxlY3RlZENoYW5uZWwgICAgOiBwdWJsaXNoLnNlbGVjdGVkQ2hhbm5lbCxcbiAgICBjaGFubmVsRXJyb3IgICAgICAgOiBwdWJsaXNoLmVycm9yLmNoYW5uZWwsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25QdWJsaXNoSW5DaGFubmVsQ2hhbmdlOiAodmFsdWUpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUVycm9yKCdjaGFubmVsJywgbnVsbCkpO1xuICAgICAgZGlzcGF0Y2goc2V0UHVibGlzaEluQ2hhbm5lbCh2YWx1ZSkpO1xuICAgIH0sXG4gICAgb25DaGFubmVsU2VsZWN0OiAodmFsdWUpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUVycm9yKCdjaGFubmVsJywgbnVsbCkpO1xuICAgICAgZGlzcGF0Y2godXBkYXRlU2VsZWN0ZWRDaGFubmVsKHZhbHVlKSk7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29udGFpbmVycy9DaGFubmVsU2VsZWN0L2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBDaGFubmVsTG9naW5Gb3JtIGZyb20gJ2NvbnRhaW5lcnMvQ2hhbm5lbExvZ2luRm9ybSc7XG5pbXBvcnQgQ2hhbm5lbENyZWF0ZUZvcm0gZnJvbSAnY29udGFpbmVycy9DaGFubmVsQ3JlYXRlRm9ybSc7XG5pbXBvcnQgKiBhcyBzdGF0ZXMgZnJvbSAnY29uc3RhbnRzL3B1Ymxpc2hfY2hhbm5lbF9zZWxlY3Rfc3RhdGVzJztcblxuY2xhc3MgQ2hhbm5lbFNlbGVjdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnRvZ2dsZUFub255bW91c1B1Ymxpc2ggPSB0aGlzLnRvZ2dsZUFub255bW91c1B1Ymxpc2guYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZVNlbGVjdGlvbiA9IHRoaXMuaGFuZGxlU2VsZWN0aW9uLmJpbmQodGhpcyk7XG4gIH1cbiAgdG9nZ2xlQW5vbnltb3VzUHVibGlzaCAoZXZlbnQpIHtcbiAgICBjb25zdCB2YWx1ZSA9IGV2ZW50LnRhcmdldC52YWx1ZTtcbiAgICBpZiAodmFsdWUgPT09ICdhbm9ueW1vdXMnKSB7XG4gICAgICB0aGlzLnByb3BzLm9uUHVibGlzaEluQ2hhbm5lbENoYW5nZShmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJvcHMub25QdWJsaXNoSW5DaGFubmVsQ2hhbmdlKHRydWUpO1xuICAgIH1cbiAgfVxuICBoYW5kbGVTZWxlY3Rpb24gKGV2ZW50KSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRPcHRpb24gPSBldmVudC50YXJnZXQuc2VsZWN0ZWRPcHRpb25zWzBdLnZhbHVlO1xuICAgIHRoaXMucHJvcHMub25DaGFubmVsU2VsZWN0KHNlbGVjdGVkT3B0aW9uKTtcbiAgfVxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICA8Zm9ybT5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT0ncmFkaW8nIG5hbWU9J2Fub255bW91cy1vci1jaGFubmVsJyBpZD0nYW5vbnltb3VzLXJhZGlvJyBjbGFzc05hbWU9J2lucHV0LXJhZGlvJyB2YWx1ZT0nYW5vbnltb3VzJyBjaGVja2VkPXshdGhpcy5wcm9wcy5wdWJsaXNoSW5DaGFubmVsfSBvbkNoYW5nZT17dGhpcy50b2dnbGVBbm9ueW1vdXNQdWJsaXNofSAvPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzTmFtZT0nbGFiZWwgbGFiZWwtLXBvaW50ZXInIGh0bWxGb3I9J2Fub255bW91cy1yYWRpbyc+QW5vbnltb3VzPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNyBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT0ncmFkaW8nIG5hbWU9J2Fub255bW91cy1vci1jaGFubmVsJyBpZD0nY2hhbm5lbC1yYWRpbycgY2xhc3NOYW1lPSdpbnB1dC1yYWRpbycgdmFsdWU9J2luIGEgY2hhbm5lbCcgY2hlY2tlZD17dGhpcy5wcm9wcy5wdWJsaXNoSW5DaGFubmVsfSBvbkNoYW5nZT17dGhpcy50b2dnbGVBbm9ueW1vdXNQdWJsaXNofSAvPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzTmFtZT0nbGFiZWwgbGFiZWwtLXBvaW50ZXInIGh0bWxGb3I9J2NoYW5uZWwtcmFkaW8nPkluIGEgY2hhbm5lbDwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgeyB0aGlzLnByb3BzLmNoYW5uZWxFcnJvciA/IChcbiAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1mYWlsdXJlJz57dGhpcy5wcm9wcy5jaGFubmVsRXJyb3J9PC9wPlxuICAgICAgICAgICkgOiAoXG4gICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+UHVibGlzaCBhbm9ueW1vdXNseSBvciBpbiBhIGNoYW5uZWw8L3A+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9mb3JtPlxuICAgICAgICB7IHRoaXMucHJvcHMucHVibGlzaEluQ2hhbm5lbCAmJiAoXG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zJz5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzTmFtZT0nbGFiZWwnIGh0bWxGb3I9J2NoYW5uZWwtbmFtZS1zZWxlY3QnPkNoYW5uZWw6PC9sYWJlbD5cbiAgICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03Jz5cbiAgICAgICAgICAgICAgPHNlbGVjdCB0eXBlPSd0ZXh0JyBpZD0nY2hhbm5lbC1uYW1lLXNlbGVjdCcgY2xhc3NOYW1lPSdzZWxlY3Qgc2VsZWN0LS1hcnJvdycgdmFsdWU9e3RoaXMucHJvcHMuc2VsZWN0ZWRDaGFubmVsfSBvbkNoYW5nZT17dGhpcy5oYW5kbGVTZWxlY3Rpb259PlxuICAgICAgICAgICAgICAgIHsgdGhpcy5wcm9wcy5sb2dnZWRJbkNoYW5uZWxOYW1lICYmIDxvcHRpb24gdmFsdWU9e3RoaXMucHJvcHMubG9nZ2VkSW5DaGFubmVsTmFtZX0gaWQ9J3B1Ymxpc2gtY2hhbm5lbC1zZWxlY3QtY2hhbm5lbC1vcHRpb24nPnt0aGlzLnByb3BzLmxvZ2dlZEluQ2hhbm5lbE5hbWV9PC9vcHRpb24+IH1cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPXtzdGF0ZXMuTE9HSU59PkV4aXN0aW5nPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT17c3RhdGVzLkNSRUFURX0+TmV3PC9vcHRpb24+XG4gICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB7ICh0aGlzLnByb3BzLnNlbGVjdGVkQ2hhbm5lbCA9PT0gc3RhdGVzLkxPR0lOKSAmJiA8Q2hhbm5lbExvZ2luRm9ybSAvPiB9XG4gICAgICAgICAgICB7ICh0aGlzLnByb3BzLnNlbGVjdGVkQ2hhbm5lbCA9PT0gc3RhdGVzLkNSRUFURSkgJiYgPENoYW5uZWxDcmVhdGVGb3JtIC8+IH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKX1cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2hhbm5lbFNlbGVjdDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvQ2hhbm5lbFNlbGVjdC92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcblxuY2xhc3MgQ2hhbm5lbExvZ2luRm9ybSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgZXJyb3IgICA6IG51bGwsXG4gICAgICBuYW1lICAgIDogJycsXG4gICAgICBwYXNzd29yZDogJycsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMubG9naW5Ub0NoYW5uZWwgPSB0aGlzLmxvZ2luVG9DaGFubmVsLmJpbmQodGhpcyk7XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgY29uc3QgbmFtZSA9IGV2ZW50LnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1tuYW1lXTogdmFsdWV9KTtcbiAgfVxuICBsb2dpblRvQ2hhbm5lbCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICAgIGJvZHkgICA6IEpTT04uc3RyaW5naWZ5KHt1c2VybmFtZTogdGhpcy5zdGF0ZS5uYW1lLCBwYXNzd29yZDogdGhpcy5zdGF0ZS5wYXNzd29yZH0pLFxuICAgICAgaGVhZGVyczogbmV3IEhlYWRlcnMoe1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgfSksXG4gICAgICBjcmVkZW50aWFsczogJ2luY2x1ZGUnLFxuICAgIH07XG4gICAgcmVxdWVzdCgnbG9naW4nLCBwYXJhbXMpXG4gICAgICAudGhlbigoe3N1Y2Nlc3MsIGNoYW5uZWxOYW1lLCBzaG9ydENoYW5uZWxJZCwgY2hhbm5lbENsYWltSWQsIG1lc3NhZ2V9KSA9PiB7XG4gICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihjaGFubmVsTmFtZSwgc2hvcnRDaGFubmVsSWQsIGNoYW5uZWxDbGFpbUlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBtZXNzYWdlfSk7XG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3J9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGZvcm0gaWQ9J2NoYW5uZWwtbG9naW4tZm9ybSc+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlIHJvdy0tc2hvcnQnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJyBodG1sRm9yPSdjaGFubmVsLWxvZ2luLW5hbWUtaW5wdXQnPk5hbWU6PC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj48ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNiBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1sZWZ0LWJvdHRvbSc+XG4gICAgICAgICAgICAgIDxzcGFuPkA8L3NwYW4+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nY2hhbm5lbC1sb2dpbi1uYW1lLWlucHV0JyBjbGFzc05hbWU9J2lucHV0LXRleHQnIG5hbWU9J25hbWUnIHBsYWNlaG9sZGVyPSdZb3VyIENoYW5uZWwgTmFtZScgdmFsdWU9e3RoaXMuc3RhdGUuY2hhbm5lbE5hbWV9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSByb3ctLXNob3J0Jz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCcgaHRtbEZvcj0nY2hhbm5lbC1sb2dpbi1wYXNzd29yZC1pbnB1dCcgPlBhc3N3b3JkOjwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LXRleHQtLXByaW1hcnknPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ncGFzc3dvcmQnIGlkPSdjaGFubmVsLWxvZ2luLXBhc3N3b3JkLWlucHV0JyBuYW1lPSdwYXNzd29yZCcgY2xhc3NOYW1lPSdpbnB1dC10ZXh0JyBwbGFjZWhvbGRlcj0nJyB2YWx1ZT17dGhpcy5zdGF0ZS5jaGFubmVsUGFzc3dvcmR9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7IHRoaXMuc3RhdGUuZXJyb3IgPyAoXG4gICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnPnt0aGlzLnN0YXRlLmVycm9yfTwvcD5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+RW50ZXIgdGhlIG5hbWUgYW5kIHBhc3N3b3JkIGZvciB5b3VyIGNoYW5uZWw8L3A+XG4gICAgICAgICl9XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlJz5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1wcmltYXJ5JyBvbkNsaWNrPXt0aGlzLmxvZ2luVG9DaGFubmVsfT5BdXRoZW50aWNhdGU8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Zvcm0+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsTG9naW5Gb3JtO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9ncmVzc0JhciBmcm9tICdjb21wb25lbnRzL1Byb2dyZXNzQmFyJztcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5jbGFzcyBDaGFubmVsQ3JlYXRlRm9ybSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgZXJyb3IgICA6IG51bGwsXG4gICAgICBjaGFubmVsIDogJycsXG4gICAgICBwYXNzd29yZDogJycsXG4gICAgICBzdGF0dXMgIDogbnVsbCxcbiAgICB9O1xuICAgIHRoaXMuaGFuZGxlQ2hhbm5lbElucHV0ID0gdGhpcy5oYW5kbGVDaGFubmVsSW5wdXQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuY3JlYXRlQ2hhbm5lbCA9IHRoaXMuY3JlYXRlQ2hhbm5lbC5iaW5kKHRoaXMpO1xuICB9XG4gIGNsZWFuc2VDaGFubmVsSW5wdXQgKGlucHV0KSB7XG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9cXHMrL2csICctJyk7IC8vIHJlcGxhY2Ugc3BhY2VzIHdpdGggZGFzaGVzXG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9bXkEtWmEtejAtOS1dL2csICcnKTsgIC8vIHJlbW92ZSBhbGwgY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgQS1aLCBhLXosIDAtOSwgb3IgJy0nXG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG4gIGhhbmRsZUNoYW5uZWxJbnB1dCAoZXZlbnQpIHtcbiAgICBsZXQgdmFsdWUgPSBldmVudC50YXJnZXQudmFsdWU7XG4gICAgdmFsdWUgPSB0aGlzLmNsZWFuc2VDaGFubmVsSW5wdXQodmFsdWUpO1xuICAgIHRoaXMuc2V0U3RhdGUoe2NoYW5uZWw6IHZhbHVlfSk7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUlzQ2hhbm5lbEF2YWlsYWJsZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe2Vycm9yOiAnUGxlYXNlIGVudGVyIGEgY2hhbm5lbCBuYW1lJ30pO1xuICAgIH1cbiAgfVxuICBoYW5kbGVJbnB1dCAoZXZlbnQpIHtcbiAgICBjb25zdCBuYW1lID0gZXZlbnQudGFyZ2V0Lm5hbWU7XG4gICAgY29uc3QgdmFsdWUgPSBldmVudC50YXJnZXQudmFsdWU7XG4gICAgdGhpcy5zZXRTdGF0ZSh7W25hbWVdOiB2YWx1ZX0pO1xuICB9XG4gIHVwZGF0ZUlzQ2hhbm5lbEF2YWlsYWJsZSAoY2hhbm5lbCkge1xuICAgIGNvbnN0IGNoYW5uZWxXaXRoQXRTeW1ib2wgPSBgQCR7Y2hhbm5lbH1gO1xuICAgIHJlcXVlc3QoYC9hcGkvY2hhbm5lbC9hdmFpbGFiaWxpdHkvJHtjaGFubmVsV2l0aEF0U3ltYm9sfWApXG4gICAgICAudGhlbihpc0F2YWlsYWJsZSA9PiB7XG4gICAgICAgIGlmIChpc0F2YWlsYWJsZSkge1xuICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeydlcnJvcic6IG51bGx9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiAnVGhhdCBjaGFubmVsIGhhcyBhbHJlYWR5IGJlZW4gY2xhaW1lZCd9KTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3IubWVzc2FnZX0pO1xuICAgICAgfSk7XG4gIH1cbiAgY2hlY2tJc0NoYW5uZWxBdmFpbGFibGUgKGNoYW5uZWwpIHtcbiAgICBjb25zdCBjaGFubmVsV2l0aEF0U3ltYm9sID0gYEAke2NoYW5uZWx9YDtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgcmVxdWVzdChgL2FwaS9jaGFubmVsL2F2YWlsYWJpbGl0eS8ke2NoYW5uZWxXaXRoQXRTeW1ib2x9YClcbiAgICAgICAgLnRoZW4oaXNBdmFpbGFibGUgPT4ge1xuICAgICAgICAgIGlmICghaXNBdmFpbGFibGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdUaGF0IGNoYW5uZWwgaGFzIGFscmVhZHkgYmVlbiBjbGFpbWVkJykpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICBjaGVja0lzUGFzc3dvcmRQcm92aWRlZCAoKSB7XG4gICAgY29uc3QgcGFzc3dvcmQgPSB0aGlzLnN0YXRlLnBhc3N3b3JkO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAoIXBhc3N3b3JkIHx8IHBhc3N3b3JkLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgcGFzc3dvcmQnKSk7XG4gICAgICB9XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH1cbiAgbWFrZVB1Ymxpc2hDaGFubmVsUmVxdWVzdCAodXNlcm5hbWUsIHBhc3N3b3JkKSB7XG4gICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgbWV0aG9kIDogJ1BPU1QnLFxuICAgICAgYm9keSAgIDogSlNPTi5zdHJpbmdpZnkoe3VzZXJuYW1lLCBwYXNzd29yZH0pLFxuICAgICAgaGVhZGVyczogbmV3IEhlYWRlcnMoe1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgfSksXG4gICAgICBjcmVkZW50aWFsczogJ2luY2x1ZGUnLFxuICAgIH07XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHJlcXVlc3QoJy9zaWdudXAnLCBwYXJhbXMpXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBVbmZvcnR1bmF0ZWx5LCB3ZSBlbmNvdW50ZXJlZCBhbiBlcnJvciB3aGlsZSBjcmVhdGluZyB5b3VyIGNoYW5uZWwuIFBsZWFzZSBsZXQgdXMga25vdyBpbiBEaXNjb3JkISAke2Vycm9yLm1lc3NhZ2V9YCkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICBjcmVhdGVDaGFubmVsIChldmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5jaGVja0lzUGFzc3dvcmRQcm92aWRlZCgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoZWNrSXNDaGFubmVsQXZhaWxhYmxlKHRoaXMuc3RhdGUuY2hhbm5lbCwgdGhpcy5zdGF0ZS5wYXNzd29yZCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtzdGF0dXM6ICdXZSBhcmUgcHVibGlzaGluZyB5b3VyIG5ldyBjaGFubmVsLiAgU2l0IHRpZ2h0Li4uJ30pO1xuICAgICAgICByZXR1cm4gdGhpcy5tYWtlUHVibGlzaENoYW5uZWxSZXF1ZXN0KHRoaXMuc3RhdGUuY2hhbm5lbCwgdGhpcy5zdGF0ZS5wYXNzd29yZCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7c3RhdHVzOiBudWxsfSk7XG4gICAgICAgIHRoaXMucHJvcHMub25DaGFubmVsTG9naW4ocmVzdWx0LmNoYW5uZWxOYW1lLCByZXN1bHQuc2hvcnRDaGFubmVsSWQsIHJlc3VsdC5jaGFubmVsQ2xhaW1JZCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBlcnJvci5tZXNzYWdlLCBzdGF0dXM6IG51bGx9KTtcbiAgICAgIH0pO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIHsgIXRoaXMuc3RhdGUuc3RhdHVzID8gKFxuICAgICAgICAgIDxmb3JtIGlkPSdwdWJsaXNoLWNoYW5uZWwtZm9ybSc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSByb3ctLXNob3J0Jz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJyBodG1sRm9yPSduZXctY2hhbm5lbC1uYW1lJz5OYW1lOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS02IGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1sZWZ0LWJvdHRvbSBzcGFuLS1yZWxhdGl2ZSc+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5APC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIG5hbWU9J2NoYW5uZWwnIGlkPSduZXctY2hhbm5lbC1uYW1lJyBjbGFzc05hbWU9J2lucHV0LXRleHQnIHBsYWNlaG9sZGVyPSdleGFtcGxlQ2hhbm5lbE5hbWUnIHZhbHVlPXt0aGlzLnN0YXRlLmNoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUNoYW5uZWxJbnB1dH0gLz5cbiAgICAgICAgICAgICAgICAgIHsgKHRoaXMuc3RhdGUuY2hhbm5lbCAmJiAhdGhpcy5zdGF0ZS5lcnJvcikgJiYgPHNwYW4gaWQ9J2lucHV0LXN1Y2Nlc3MtY2hhbm5lbC1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tc3VjY2VzcyBzcGFuLS1hYnNvbHV0ZSc+eydcXHUyNzEzJ308L3NwYW4+IH1cbiAgICAgICAgICAgICAgICAgIHsgdGhpcy5zdGF0ZS5lcnJvciAmJiA8c3BhbiBpZD0naW5wdXQtc3VjY2Vzcy1jaGFubmVsLW5hbWUnIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1mYWlsdXJlIHNwYW4tLWFic29sdXRlJz57J1xcdTI3MTYnfTwvc3Bhbj4gfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXdpZGUgcm93LS1zaG9ydCc+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCcgaHRtbEZvcj0nbmV3LWNoYW5uZWwtcGFzc3dvcmQnPlBhc3N3b3JkOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS02IGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSc+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ncGFzc3dvcmQnIG5hbWU9J3Bhc3N3b3JkJyBpZD0nbmV3LWNoYW5uZWwtcGFzc3dvcmQnIGNsYXNzTmFtZT0naW5wdXQtdGV4dCcgIHBsYWNlaG9sZGVyPScnIHZhbHVlPXt0aGlzLnN0YXRlLnBhc3N3b3JkfSBvbkNoYW5nZT17dGhpcy5oYW5kbGVJbnB1dH0gLz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIHt0aGlzLnN0YXRlLmVycm9yID8gKFxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e3RoaXMuc3RhdGUuZXJyb3J9PC9wPlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPkNob29zZSBhIG5hbWUgYW5kIHBhc3N3b3JkIGZvciB5b3VyIGNoYW5uZWw8L3A+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXdpZGUnPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1wcmltYXJ5JyBvbkNsaWNrPXt0aGlzLmNyZWF0ZUNoYW5uZWx9PkNyZWF0ZSBDaGFubmVsPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICkgOiAoXG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+e3RoaXMuc3RhdGUuc3RhdHVzfTwvcD5cbiAgICAgICAgICAgIDxQcm9ncmVzc0JhciBzaXplPXsxMn0gLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKX1cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2hhbm5lbENyZWF0ZUZvcm07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY29uc3QgQWN0aXZlU3RhdHVzQmFyID0gKCkgPT4ge1xuICByZXR1cm4gPHNwYW4gY2xhc3NOYW1lPSdwcm9ncmVzcy1iYXIgcHJvZ3Jlc3MtYmFyLS1hY3RpdmUnPnwgPC9zcGFuPjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFjdGl2ZVN0YXR1c0JhcjtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbXBvbmVudHMvQWN0aXZlU3RhdHVzQmFyL2luZGV4LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmNvbnN0IEluYWN0aXZlU3RhdHVzQmFyID0gKCkgPT4ge1xuICByZXR1cm4gPHNwYW4gY2xhc3NOYW1lPSdwcm9ncmVzcy1iYXIgcHJvZ3Jlc3MtYmFyLS1pbmFjdGl2ZSc+fCA8L3NwYW4+O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgSW5hY3RpdmVTdGF0dXNCYXI7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb21wb25lbnRzL0luYWN0aXZlU3RhdHVzQmFyL2luZGV4LmpzeCIsImltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHtjbGVhckZpbGV9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBzdGF0dXMgOiBwdWJsaXNoLnN0YXR1cy5zdGF0dXMsXG4gICAgbWVzc2FnZTogcHVibGlzaC5zdGF0dXMubWVzc2FnZSxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IHtcbiAgY2xlYXJGaWxlLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hTdGF0dXMvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb2dyZXNzQmFyIGZyb20gJ2NvbXBvbmVudHMvUHJvZ3Jlc3NCYXInO1xuaW1wb3J0ICogYXMgcHVibGlzaFN0YXRlcyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jbGFpbV9zdGF0ZXMnO1xuXG5jbGFzcyBQdWJsaXNoU3RhdHVzIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IHN0YXR1cywgbWVzc2FnZSwgY2xlYXJGaWxlIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJz5cbiAgICAgICAge3N0YXR1cyA9PT0gcHVibGlzaFN0YXRlcy5MT0FEX1NUQVJUICYmXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgYWxpZ24tY29udGVudC1jZW50ZXInPlxuICAgICAgICAgIDxwPkZpbGUgaXMgbG9hZGluZyB0byBzZXJ2ZXI8L3A+XG4gICAgICAgICAgPHAgY2xhc3NOYW1lPSdibHVlJz4wJTwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAge3N0YXR1cyA9PT0gcHVibGlzaFN0YXRlcy5MT0FESU5HICYmXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICA8cD5GaWxlIGlzIGxvYWRpbmcgdG8gc2VydmVyPC9wPlxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdibHVlJz57bWVzc2FnZX08L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHtzdGF0dXMgPT09IHB1Ymxpc2hTdGF0ZXMuUFVCTElTSElORyAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5VcGxvYWQgY29tcGxldGUuICBZb3VyIGZpbGUgaXMgbm93IGJlaW5nIHB1Ymxpc2hlZCBvbiB0aGUgYmxvY2tjaGFpbi4uLjwvcD5cbiAgICAgICAgICA8UHJvZ3Jlc3NCYXIgc2l6ZT17MTJ9IC8+XG4gICAgICAgICAgPHA+Q3VyaW91cyB3aGF0IG1hZ2ljIGlzIGhhcHBlbmluZyBoZXJlPyA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9mYXEvd2hhdC1pcy1sYnJ5Jz5MZWFybiBtb3JlLjwvYT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHtzdGF0dXMgPT09IHB1Ymxpc2hTdGF0ZXMuU1VDQ0VTUyAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5Zb3VyIHB1Ymxpc2ggaXMgY29tcGxldGUhIFlvdSBhcmUgYmVpbmcgcmVkaXJlY3RlZCB0byBpdCBub3cuPC9wPlxuICAgICAgICAgIDxwPklmIHlvdSBhcmUgbm90IGF1dG9tYXRpY2FsbHkgcmVkaXJlY3RlZCwgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj17bWVzc2FnZX0+Y2xpY2sgaGVyZS48L2E+PC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICB7c3RhdHVzID09PSBwdWJsaXNoU3RhdGVzLkZBSUxFRCAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5Tb21ldGhpbmcgd2VudCB3cm9uZy4uLjwvcD5cbiAgICAgICAgICA8cD48c3Ryb25nPnttZXNzYWdlfTwvc3Ryb25nPjwvcD5cbiAgICAgICAgICA8cD5Gb3IgaGVscCwgcG9zdCB0aGUgYWJvdmUgZXJyb3IgdGV4dCBpbiB0aGUgI3NwZWVjaCBjaGFubmVsIG9uIHRoZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZGlzY29yZC5nZy9Zallid2hTJyB0YXJnZXQ9J19ibGFuayc+bGJyeSBkaXNjb3JkPC9hPjwvcD5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1zZWNvbmRhcnknIG9uQ2xpY2s9e2NsZWFyRmlsZX0+UmVzZXQ8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hTdGF0dXM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1B1Ymxpc2hTdGF0dXMvdmlldy5qc3giLCJleHBvcnQgY29uc3QgTE9BRF9TVEFSVCA9ICdMT0FEX1NUQVJUJztcbmV4cG9ydCBjb25zdCBMT0FESU5HID0gJ0xPQURJTkcnO1xuZXhwb3J0IGNvbnN0IFBVQkxJU0hJTkcgPSAnUFVCTElTSElORyc7XG5leHBvcnQgY29uc3QgU1VDQ0VTUyA9ICdTVUNDRVNTJztcbmV4cG9ydCBjb25zdCBGQUlMRUQgPSAnRkFJTEVEJztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnN0YW50cy9wdWJsaXNoX2NsYWltX3N0YXRlcy5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgTmF2QmFyIGZyb20gJ2NvbnRhaW5lcnMvTmF2QmFyJztcbmltcG9ydCBTRU8gZnJvbSAnY29tcG9uZW50cy9TRU8nO1xuXG5jbGFzcyBBYm91dFBhZ2UgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICA8U0VPIHBhZ2VUaXRsZT17J0Fib3V0J30gcGFnZVVyaT17J2Fib3V0J30gLz5cbiAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNSBjb2x1bW4tLW1lZC0xMCBhbGlnbi1jb250ZW50LXRvcCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tOCBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0ncHVsbC1xdW90ZSc+U3BlZS5jaCBpcyBhbiBvcGVuLXNvdXJjZSBwcm9qZWN0LiAgUGxlYXNlIGNvbnRyaWJ1dGUgdG8gdGhlIGV4aXN0aW5nIHNpdGUsIG9yIGZvcmsgaXQgYW5kIG1ha2UgeW91ciBvd24uPC9wPlxuICAgICAgICAgICAgICA8cD48YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPSdodHRwczovL3R3aXR0ZXIuY29tL3NwZWVfY2gnPlRXSVRURVI8L2E+PC9wPlxuICAgICAgICAgICAgICA8cD48YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPSdodHRwczovL2dpdGh1Yi5jb20vbGJyeWlvL3NwZWUuY2gnPkdJVEhVQjwvYT48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vZGlzY29yZC5nZy9Zallid2hTJz5ESVNDT1JEIENIQU5ORUw8L2E+PC9wPlxuICAgICAgICAgICAgICA8cD48YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPSdodHRwczovL2dpdGh1Yi5jb20vbGJyeWlvL3NwZWUuY2gvYmxvYi9tYXN0ZXIvUkVBRE1FLm1kJz5ET0NVTUVOVEFUSU9OPC9hPjwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPHA+U3BlZS5jaCBpcyBhIG1lZGlhLWhvc3Rpbmcgc2l0ZSB0aGF0IHJlYWRzIGZyb20gYW5kIHB1Ymxpc2hlcyBjb250ZW50IHRvIHRoZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vbGJyeS5pbyc+TEJSWTwvYT4gYmxvY2tjaGFpbi48L3A+XG4gICAgICAgICAgICAgIDxwPlNwZWUuY2ggaXMgYSBob3N0aW5nIHNlcnZpY2UsIGJ1dCB3aXRoIHRoZSBhZGRlZCBiZW5lZml0IHRoYXQgaXQgc3RvcmVzIHlvdXIgY29udGVudCBvbiBhIGRlY2VudHJhbGl6ZWQgbmV0d29yayBvZiBjb21wdXRlcnMgLS0gdGhlIExCUlkgbmV0d29yay4gIFRoaXMgbWVhbnMgdGhhdCB5b3VyIGltYWdlcyBhcmUgc3RvcmVkIGluIG11bHRpcGxlIGxvY2F0aW9ucyB3aXRob3V0IGEgc2luZ2xlIHBvaW50IG9mIGZhaWx1cmUuPC9wPlxuICAgICAgICAgICAgICA8aDM+Q29udHJpYnV0ZTwvaDM+XG4gICAgICAgICAgICAgIDxwPklmIHlvdSBoYXZlIGFuIGlkZWEgZm9yIHlvdXIgb3duIHNwZWUuY2gtbGlrZSBzaXRlIG9uIHRvcCBvZiBMQlJZLCBmb3JrIG91ciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaCc+Z2l0aHViIHJlcG88L2E+IGFuZCBnbyB0byB0b3duITwvcD5cbiAgICAgICAgICAgICAgPHA+SWYgeW91IHdhbnQgdG8gaW1wcm92ZSBzcGVlLmNoLCBqb2luIG91ciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZGlzY29yZC5nZy9Zallid2hTJz5kaXNjb3JkIGNoYW5uZWw8L2E+IG9yIHNvbHZlIG9uZSBvZiBvdXIgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyBocmVmPSdodHRwczovL2dpdGh1Yi5jb20vbGJyeWlvL3NwZWUuY2gvaXNzdWVzJz5naXRodWIgaXNzdWVzPC9hPi48L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBYm91dFBhZ2U7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb21wb25lbnRzL0Fib3V0UGFnZS9pbmRleC5qc3giLCJpbXBvcnQge2Nvbm5lY3R9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IGNoYW5uZWwgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGxvZ2dlZEluQ2hhbm5lbE5hbWU6IGNoYW5uZWwubG9nZ2VkSW5DaGFubmVsLm5hbWUsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0xvZ2luUGFnZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IENoYW5uZWxMb2dpbkZvcm0gZnJvbSAnY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtJztcbmltcG9ydCBDaGFubmVsQ3JlYXRlRm9ybSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtJztcblxuY2xhc3MgTG9naW5QYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyAobmV3UHJvcHMpIHtcbiAgICAvLyByZS1yb3V0ZSB0aGUgdXNlciB0byB0aGUgaG9tZXBhZ2UgaWYgdGhlIHVzZXIgaXMgbG9nZ2VkIGluXG4gICAgaWYgKG5ld1Byb3BzLmxvZ2dlZEluQ2hhbm5lbE5hbWUgIT09IHRoaXMucHJvcHMubG9nZ2VkSW5DaGFubmVsTmFtZSkge1xuICAgICAgdGhpcy5wcm9wcy5oaXN0b3J5LnB1c2goYC9gKTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPFNFTyBwYWdlVGl0bGU9eydMb2dpbid9IHBhZ2VVcmk9eydsb2dpbid9IC8+XG4gICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICA8cD5DaGFubmVscyBhbGxvdyB5b3UgdG8gcHVibGlzaCBhbmQgZ3JvdXAgY29udGVudCB1bmRlciBhbiBpZGVudGl0eS4gWW91IGNhbiBjcmVhdGUgYSBjaGFubmVsIGZvciB5b3Vyc2VsZiwgb3Igc2hhcmUgb25lIHdpdGggbGlrZS1taW5kZWQgZnJpZW5kcy4gIFlvdSBjYW4gY3JlYXRlIDEgY2hhbm5lbCwgb3IgMTAwLCBzbyB3aGV0aGVyIHlvdSdyZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPScvQGNhdGFsb25pYTIwMTc6NDNkY2Y0NzE2M2NhYTIxZDg0MDRkOWZlOWIzMGY3OGVmM2UxNDZhOCc+ZG9jdW1lbnRpbmcgaW1wb3J0YW50IGV2ZW50czwvYT4sIG9yIG1ha2luZyBhIHB1YmxpYyByZXBvc2l0b3J5IGZvciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPScvQGNhdEdpZnMnPmNhdCBnaWZzPC9hPiAocGFzc3dvcmQ6ICcxMjM0JyksIHRyeSBjcmVhdGluZyBhIGNoYW5uZWwgZm9yIGl0ITwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZT0naDMtLW5vLWJvdHRvbSc+TG9nIGluIHRvIGFuIGV4aXN0aW5nIGNoYW5uZWw6PC9oMz5cbiAgICAgICAgICAgICAgPENoYW5uZWxMb2dpbkZvcm0gLz5cbiAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZT0naDMtLW5vLWJvdHRvbSc+Q3JlYXRlIGEgYnJhbmQgbmV3IGNoYW5uZWw6PC9oMz5cbiAgICAgICAgICAgICAgPENoYW5uZWxDcmVhdGVGb3JtIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKExvZ2luUGFnZSk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0xvZ2luUGFnZS92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBvbkhhbmRsZVNob3dQYWdlVXJpIH0gZnJvbSAnYWN0aW9ucy9zaG93JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHNob3cgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGVycm9yICAgICAgOiBzaG93LnJlcXVlc3QuZXJyb3IsXG4gICAgcmVxdWVzdFR5cGU6IHNob3cucmVxdWVzdC50eXBlLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0ge1xuICBvbkhhbmRsZVNob3dQYWdlVXJpLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1Nob3dQYWdlL2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBFcnJvclBhZ2UgZnJvbSAnY29tcG9uZW50cy9FcnJvclBhZ2UnO1xuaW1wb3J0IFNob3dBc3NldExpdGUgZnJvbSAnY29udGFpbmVycy9TaG93QXNzZXRMaXRlJztcbmltcG9ydCBTaG93QXNzZXREZXRhaWxzIGZyb20gJ2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscyc7XG5pbXBvcnQgU2hvd0NoYW5uZWwgZnJvbSAnY29udGFpbmVycy9TaG93Q2hhbm5lbCc7XG5cbmltcG9ydCB7IENIQU5ORUwsIEFTU0VUX0xJVEUsIEFTU0VUX0RFVEFJTFMgfSBmcm9tICdjb25zdGFudHMvc2hvd19yZXF1ZXN0X3R5cGVzJztcblxuY2xhc3MgU2hvd1BhZ2UgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgdGhpcy5wcm9wcy5vbkhhbmRsZVNob3dQYWdlVXJpKHRoaXMucHJvcHMubWF0Y2gucGFyYW1zKTtcbiAgfVxuICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIChuZXh0UHJvcHMpIHtcbiAgICBpZiAobmV4dFByb3BzLm1hdGNoLnBhcmFtcyAhPT0gdGhpcy5wcm9wcy5tYXRjaC5wYXJhbXMpIHtcbiAgICAgIHRoaXMucHJvcHMub25IYW5kbGVTaG93UGFnZVVyaShuZXh0UHJvcHMubWF0Y2gucGFyYW1zKTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGVycm9yLCByZXF1ZXN0VHlwZSB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxFcnJvclBhZ2UgZXJyb3I9e2Vycm9yfSAvPlxuICAgICAgKTtcbiAgICB9XG4gICAgc3dpdGNoIChyZXF1ZXN0VHlwZSkge1xuICAgICAgY2FzZSBDSEFOTkVMOlxuICAgICAgICByZXR1cm4gPFNob3dDaGFubmVsIC8+O1xuICAgICAgY2FzZSBBU1NFVF9MSVRFOlxuICAgICAgICByZXR1cm4gPFNob3dBc3NldExpdGUgLz47XG4gICAgICBjYXNlIEFTU0VUX0RFVEFJTFM6XG4gICAgICAgIHJldHVybiA8U2hvd0Fzc2V0RGV0YWlscyAvPjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiA8cD5sb2FkaW5nLi4uPC9wPjtcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNob3dQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29udGFpbmVycy9TaG93UGFnZS92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IHJlcXVlc3QgaW5mb1xuICBjb25zdCByZXF1ZXN0SWQgPSBzaG93LnJlcXVlc3QuaWQ7XG4gIC8vIHNlbGVjdCBhc3NldCBpbmZvXG4gIGxldCBhc3NldDtcbiAgY29uc3QgcmVxdWVzdCA9IHNob3cucmVxdWVzdExpc3RbcmVxdWVzdElkXSB8fCBudWxsO1xuICBjb25zdCBhc3NldExpc3QgPSBzaG93LmFzc2V0TGlzdDtcbiAgaWYgKHJlcXVlc3QgJiYgYXNzZXRMaXN0KSB7XG4gICAgY29uc3QgYXNzZXRLZXkgPSByZXF1ZXN0LmtleTsgIC8vIG5vdGU6IGp1c3Qgc3RvcmUgdGhpcyBpbiB0aGUgcmVxdWVzdFxuICAgIGFzc2V0ID0gYXNzZXRMaXN0W2Fzc2V0S2V5XSB8fCBudWxsO1xuICB9O1xuICAvLyByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBhc3NldCxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvU2hvd0Fzc2V0TGl0ZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCB7IExpbmsgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmltcG9ydCBBc3NldERpc3BsYXkgZnJvbSAnY29udGFpbmVycy9Bc3NldERpc3BsYXknO1xuXG5jbGFzcyBTaG93TGl0ZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBhc3NldCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoYXNzZXQpIHtcbiAgICAgIGNvbnN0IHsgbmFtZSwgY2xhaW1JZCB9ID0gYXNzZXQuY2xhaW1EYXRhO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXRhbGwgZmxleC1jb250YWluZXItLWNvbHVtbiBmbGV4LWNvbnRhaW5lci0tY2VudGVyLWNlbnRlciBzaG93LWxpdGUtY29udGFpbmVyJz5cbiAgICAgICAgICA8U0VPIHBhZ2VUaXRsZT17bmFtZX0gYXNzZXQ9e2Fzc2V0fSAvPlxuICAgICAgICAgIDxBc3NldERpc3BsYXkgLz5cbiAgICAgICAgICA8TGluayBpZD0nYXNzZXQtYm9pbGVycGF0ZScgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5IGZpbmUtcHJpbnQnIHRvPXtgLyR7Y2xhaW1JZH0vJHtuYW1lfWB9Pmhvc3RlZFxuICAgICAgICAgICAgdmlhIFNwZWUuY2g8L0xpbms+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS10YWxsIHJvdy0tcGFkZGVkIGZsZXgtY29udGFpbmVyLS1jb2x1bW4gZmxleC1jb250YWluZXItLWNlbnRlci1jZW50ZXInPlxuICAgICAgICA8cD5sb2FkaW5nIGFzc2V0IGRhdGEuLi48L3A+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTaG93TGl0ZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvU2hvd0Fzc2V0TGl0ZS92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvZ3Jlc3NCYXIgZnJvbSAnY29tcG9uZW50cy9Qcm9ncmVzc0Jhcic7XG5pbXBvcnQgeyBMT0NBTF9DSEVDSywgVU5BVkFJTEFCTEUsIEVSUk9SLCBBVkFJTEFCTEUgfSBmcm9tICdjb25zdGFudHMvYXNzZXRfZGlzcGxheV9zdGF0ZXMnO1xuXG5jbGFzcyBBc3NldERpc3BsYXkgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBhc3NldDogeyBjbGFpbURhdGE6IHsgbmFtZSwgY2xhaW1JZCB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgdGhpcy5wcm9wcy5vbkZpbGVSZXF1ZXN0KG5hbWUsIGNsYWltSWQpO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBzdGF0dXMsIGVycm9yLCBhc3NldDogeyBjbGFpbURhdGE6IHsgbmFtZSwgY2xhaW1JZCwgY29udGVudFR5cGUsIGZpbGVFeHQsIHRodW1ibmFpbCB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgaWQ9J2Fzc2V0LWRpc3BsYXktY29tcG9uZW50Jz5cbiAgICAgICAgeyhzdGF0dXMgPT09IExPQ0FMX0NIRUNLKSAmJlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxwPkNoZWNraW5nIHRvIHNlZSBpZiBTcGVlLmNoIGhhcyB5b3VyIGFzc2V0IGxvY2FsbHkuLi48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHsoc3RhdHVzID09PSBVTkFWQUlMQUJMRSkgJiZcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8cD5TaXQgdGlnaHQsIHdlJ3JlIHNlYXJjaGluZyB0aGUgTEJSWSBibG9ja2NoYWluIGZvciB5b3VyIGFzc2V0ITwvcD5cbiAgICAgICAgICA8UHJvZ3Jlc3NCYXIgc2l6ZT17MTJ9IC8+XG4gICAgICAgICAgPHA+Q3VyaW91cyB3aGF0IG1hZ2ljIGlzIGhhcHBlbmluZyBoZXJlPyA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9mYXEvd2hhdC1pcy1sYnJ5Jz5MZWFybiBtb3JlLjwvYT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHsoc3RhdHVzID09PSBFUlJPUikgJiZcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8cD5VbmZvcnR1bmF0ZWx5LCB3ZSBjb3VsZG4ndCBkb3dubG9hZCB5b3VyIGFzc2V0IGZyb20gTEJSWS4gIFlvdSBjYW4gaGVscCB1cyBvdXQgYnkgc2hhcmluZyB0aGUgYmVsb3cgZXJyb3IgbWVzc2FnZSBpbiB0aGUgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyBocmVmPSdodHRwczovL2Rpc2NvcmQuZ2cvWWpZYndoUycgdGFyZ2V0PSdfYmxhbmsnPkxCUlkgZGlzY29yZDwvYT4uPC9wPlxuICAgICAgICAgIDxpPjxwIGlkPSdlcnJvci1tZXNzYWdlJz57ZXJyb3J9PC9wPjwvaT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgeyhzdGF0dXMgPT09IEFWQUlMQUJMRSkgJiZcbiAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGNvbnRlbnRUeXBlKSB7XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgICAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0nYXNzZXQnXG4gICAgICAgICAgICAgICAgICBzcmM9e2AvJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfVxuICAgICAgICAgICAgICAgICAgYWx0PXtuYW1lfSAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9J2Fzc2V0J1xuICAgICAgICAgICAgICAgICAgc3JjPXtgLyR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH1cbiAgICAgICAgICAgICAgICAgIGFsdD17bmFtZX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSAndmlkZW8vbXA0JzpcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8dmlkZW8gY2xhc3NOYW1lPSdhc3NldCB2aWRlbycgY29udHJvbHMgcG9zdGVyPXt0aHVtYm5haWx9PlxuICAgICAgICAgICAgICAgICAgPHNvdXJjZVxuICAgICAgICAgICAgICAgICAgICBzcmM9e2AvJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDxwPllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSA8Y29kZT52aWRlbzwvY29kZT4gZWxlbWVudC48L3A+XG4gICAgICAgICAgICAgICAgPC92aWRlbz5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPHA+VW5zdXBwb3J0ZWQgZmlsZSB0eXBlPC9wPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldERpc3BsYXk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0Fzc2V0RGlzcGxheS92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IHJlcXVlc3QgaW5mb1xuICBjb25zdCByZXF1ZXN0SWQgPSBzaG93LnJlcXVlc3QuaWQ7XG4gIC8vIHNlbGVjdCBhc3NldCBpbmZvXG4gIGxldCBhc3NldDtcbiAgY29uc3QgcmVxdWVzdCA9IHNob3cucmVxdWVzdExpc3RbcmVxdWVzdElkXSB8fCBudWxsO1xuICBjb25zdCBhc3NldExpc3QgPSBzaG93LmFzc2V0TGlzdDtcbiAgaWYgKHJlcXVlc3QgJiYgYXNzZXRMaXN0KSB7XG4gICAgY29uc3QgYXNzZXRLZXkgPSByZXF1ZXN0LmtleTsgIC8vIG5vdGU6IGp1c3Qgc3RvcmUgdGhpcyBpbiB0aGUgcmVxdWVzdFxuICAgIGFzc2V0ID0gYXNzZXRMaXN0W2Fzc2V0S2V5XSB8fCBudWxsO1xuICB9O1xuICAvLyByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBhc3NldCxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IEVycm9yUGFnZSBmcm9tICdjb21wb25lbnRzL0Vycm9yUGFnZSc7XG5pbXBvcnQgQXNzZXRUaXRsZSBmcm9tICdjb250YWluZXJzL0Fzc2V0VGl0bGUnO1xuaW1wb3J0IEFzc2V0RGlzcGxheSBmcm9tICdjb250YWluZXJzL0Fzc2V0RGlzcGxheSc7XG5pbXBvcnQgQXNzZXRJbmZvIGZyb20gJ2NvbnRhaW5lcnMvQXNzZXRJbmZvJztcblxuY2xhc3MgU2hvd0Fzc2V0RGV0YWlscyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBhc3NldCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoYXNzZXQpIHtcbiAgICAgIGNvbnN0IHsgY2xhaW1EYXRhOiB7IG5hbWUgfSB9ID0gYXNzZXQ7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtgJHtuYW1lfSAtIGRldGFpbHNgfSBhc3NldD17YXNzZXR9IC8+XG4gICAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS10YWxsIHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xMCc+XG4gICAgICAgICAgICAgIDxBc3NldFRpdGxlIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCBzaG93LWRldGFpbHMtY29udGFpbmVyJz5cbiAgICAgICAgICAgICAgICA8QXNzZXREaXNwbGF5IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1zbWwtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICAgICAgICA8QXNzZXRJbmZvIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICk7XG4gICAgfTtcbiAgICByZXR1cm4gKFxuICAgICAgPEVycm9yUGFnZSBlcnJvcj17J2xvYWRpbmcgYXNzZXQgZGF0YS4uLid9IC8+XG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2hvd0Fzc2V0RGV0YWlscztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscy92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuaW1wb3J0IHsgc2VsZWN0QXNzZXQgfSBmcm9tICdzZWxlY3RvcnMvc2hvdyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHNob3cgfSkgPT4ge1xuICBjb25zdCB7IGNsYWltRGF0YTogeyB0aXRsZSB9IH0gPSBzZWxlY3RBc3NldChzaG93KTtcbiAgcmV0dXJuIHtcbiAgICB0aXRsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvQXNzZXRUaXRsZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmNvbnN0IEFzc2V0VGl0bGUgPSAoeyB0aXRsZSB9KSA9PiB7XG4gIHJldHVybiAoXG4gICAgPGRpdj5cbiAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dC0tbGFyZ2UnPnt0aXRsZX08L3NwYW4+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldFRpdGxlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29udGFpbmVycy9Bc3NldFRpdGxlL3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQgeyBzZWxlY3RBc3NldCB9IGZyb20gJ3NlbGVjdG9ycy9zaG93JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCBhc3NldFxuICBjb25zdCBhc3NldCA9IHNlbGVjdEFzc2V0KHNob3cpO1xuICAvLyAgcmV0dXJuIHByb3BzXG4gIHJldHVybiB7XG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0Fzc2V0SW5mby9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5cbmNsYXNzIEFzc2V0SW5mbyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmNvcHlUb0NsaXBib2FyZCA9IHRoaXMuY29weVRvQ2xpcGJvYXJkLmJpbmQodGhpcyk7XG4gIH1cbiAgY29weVRvQ2xpcGJvYXJkIChldmVudCkge1xuICAgIHZhciBlbGVtZW50VG9Db3B5ID0gZXZlbnQudGFyZ2V0LmRhdGFzZXQuZWxlbWVudHRvY29weTtcbiAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRUb0NvcHkpO1xuICAgIGVsZW1lbnQuc2VsZWN0KCk7XG4gICAgdHJ5IHtcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtlcnJvcjogJ09vcHMsIHVuYWJsZSB0byBjb3B5J30pO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgYXNzZXQ6IHsgc2hvcnRJZCwgY2xhaW1EYXRhIDogeyBjaGFubmVsTmFtZSwgY2VydGlmaWNhdGVJZCwgZGVzY3JpcHRpb24sIG5hbWUsIGNsYWltSWQsIGZpbGVFeHQsIGNvbnRlbnRUeXBlLCB0aHVtYm5haWwsIGhvc3QgfSB9IH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICB7Y2hhbm5lbE5hbWUgJiZcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLXdpZGUgcm93LS1uby10b3AnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+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+XG5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFzc2V0SW5mbztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2NvbnRhaW5lcnMvQXNzZXRJbmZvL3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHNob3cgfSkgPT4ge1xuICAvLyBzZWxlY3QgcmVxdWVzdCBpbmZvXG4gIGNvbnN0IHJlcXVlc3RJZCA9IHNob3cucmVxdWVzdC5pZDtcbiAgLy8gc2VsZWN0IHJlcXVlc3RcbiAgY29uc3QgcHJldmlvdXNSZXF1ZXN0ID0gc2hvdy5yZXF1ZXN0TGlzdFtyZXF1ZXN0SWRdIHx8IG51bGw7XG4gIC8vIHNlbGVjdCBjaGFubmVsXG4gIGxldCBjaGFubmVsO1xuICBpZiAocHJldmlvdXNSZXF1ZXN0KSB7XG4gICAgY29uc3QgY2hhbm5lbEtleSA9IHByZXZpb3VzUmVxdWVzdC5rZXk7XG4gICAgY2hhbm5lbCA9IHNob3cuY2hhbm5lbExpc3RbY2hhbm5lbEtleV0gfHwgbnVsbDtcbiAgfVxuICByZXR1cm4ge1xuICAgIGNoYW5uZWwsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1Nob3dDaGFubmVsL2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBTRU8gZnJvbSAnY29tcG9uZW50cy9TRU8nO1xuaW1wb3J0IEVycm9yUGFnZSBmcm9tICdjb21wb25lbnRzL0Vycm9yUGFnZSc7XG5pbXBvcnQgTmF2QmFyIGZyb20gJ2NvbnRhaW5lcnMvTmF2QmFyJztcbmltcG9ydCBDaGFubmVsQ2xhaW1zRGlzcGxheSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5JztcblxuY2xhc3MgU2hvd0NoYW5uZWwgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgY2hhbm5lbCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoY2hhbm5lbCkge1xuICAgICAgY29uc3QgeyBuYW1lLCBsb25nSWQsIHNob3J0SWQgfSA9IGNoYW5uZWw7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtuYW1lfSBjaGFubmVsPXtjaGFubmVsfSAvPlxuICAgICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAnPlxuICAgICAgICAgICAgICA8aDI+Y2hhbm5lbCBuYW1lOiB7bmFtZX08L2gyPlxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9eydmaW5lLXByaW50J30+ZnVsbCBjaGFubmVsIGlkOiB7bG9uZ0lkfTwvcD5cbiAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPXsnZmluZS1wcmludCd9PnNob3J0IGNoYW5uZWwgaWQ6IHtzaG9ydElkfTwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTEwJz5cbiAgICAgICAgICAgICAgPENoYW5uZWxDbGFpbXNEaXNwbGF5IC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICApO1xuICAgIH07XG4gICAgcmV0dXJuIChcbiAgICAgIDxFcnJvclBhZ2UgZXJyb3I9eydsb2FkaW5nIGNoYW5uZWwgZGF0YS4uLid9IC8+XG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2hvd0NoYW5uZWw7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL1Nob3dDaGFubmVsL3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IG9uVXBkYXRlQ2hhbm5lbENsYWltcyB9IGZyb20gJ2FjdGlvbnMvc2hvdyc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IGNoYW5uZWwga2V5XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3Nob3cucmVxdWVzdC5pZF07XG4gIGNvbnN0IGNoYW5uZWxLZXkgPSByZXF1ZXN0LmtleTtcbiAgLy8gc2VsZWN0IGNoYW5uZWwgY2xhaW1zXG4gIGNvbnN0IGNoYW5uZWwgPSBzaG93LmNoYW5uZWxMaXN0W2NoYW5uZWxLZXldIHx8IG51bGw7XG4gIC8vIHJldHVybiBwcm9wc1xuICByZXR1cm4ge1xuICAgIGNoYW5uZWxLZXksXG4gICAgY2hhbm5lbCxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IHtcbiAgb25VcGRhdGVDaGFubmVsQ2xhaW1zLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBBc3NldFByZXZpZXcgZnJvbSAnY29tcG9uZW50cy9Bc3NldFByZXZpZXcnO1xuXG5jbGFzcyBDaGFubmVsQ2xhaW1zRGlzcGxheSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnNob3dOZXh0UmVzdWx0c1BhZ2UgPSB0aGlzLnNob3dOZXh0UmVzdWx0c1BhZ2UuYmluZCh0aGlzKTtcbiAgICB0aGlzLnNob3dQcmV2aW91c1Jlc3VsdHNQYWdlID0gdGhpcy5zaG93UHJldmlvdXNSZXN1bHRzUGFnZS5iaW5kKHRoaXMpO1xuICB9XG4gIHNob3dQcmV2aW91c1Jlc3VsdHNQYWdlICgpIHtcbiAgICBjb25zdCB7IGNoYW5uZWw6IHsgY2xhaW1zRGF0YTogeyBjdXJyZW50UGFnZSB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgcHJldmlvdXNQYWdlID0gcGFyc2VJbnQoY3VycmVudFBhZ2UpIC0gMTtcbiAgICB0aGlzLnNob3dOZXdQYWdlKHByZXZpb3VzUGFnZSk7XG4gIH1cbiAgc2hvd05leHRSZXN1bHRzUGFnZSAoKSB7XG4gICAgY29uc3QgeyBjaGFubmVsOiB7IGNsYWltc0RhdGE6IHsgY3VycmVudFBhZ2UgfSB9IH0gPSB0aGlzLnByb3BzO1xuICAgIGNvbnN0IG5leHRQYWdlID0gcGFyc2VJbnQoY3VycmVudFBhZ2UpICsgMTtcbiAgICB0aGlzLnNob3dOZXdQYWdlKG5leHRQYWdlKTtcbiAgfVxuICBzaG93TmV3UGFnZSAocGFnZSkge1xuICAgIGNvbnN0IHsgY2hhbm5lbEtleSwgY2hhbm5lbDogeyBuYW1lLCBsb25nSWQgfSB9ID0gdGhpcy5wcm9wcztcbiAgICB0aGlzLnByb3BzLm9uVXBkYXRlQ2hhbm5lbENsYWltcyhjaGFubmVsS2V5LCBuYW1lLCBsb25nSWQsIHBhZ2UpO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBjaGFubmVsOiB7IGNsYWltc0RhdGE6IHsgY2xhaW1zLCBjdXJyZW50UGFnZSwgdG90YWxQYWdlcyB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS10YWxsJz5cbiAgICAgICAgeyhjbGFpbXMubGVuZ3RoID4gMCkgPyAoXG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIHtjbGFpbXMubWFwKChjbGFpbSwgaW5kZXgpID0+IDxBc3NldFByZXZpZXdcbiAgICAgICAgICAgICAgY2xhaW1EYXRhPXtjbGFpbX1cbiAgICAgICAgICAgICAga2V5PXtgJHtjbGFpbS5uYW1lfS0ke2luZGV4fWB9XG4gICAgICAgICAgICAvPil9XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICB7KGN1cnJlbnRQYWdlID4gMSkgJiZcbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9eydidXR0b24tLXNlY29uZGFyeSd9IG9uQ2xpY2s9e3RoaXMuc2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2V9PlByZXZpb3VzIFBhZ2U8L2J1dHRvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB7KGN1cnJlbnRQYWdlIDwgdG90YWxQYWdlcykgJiZcbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9eydidXR0b24tLXNlY29uZGFyeSd9IG9uQ2xpY2s9e3RoaXMuc2hvd05leHRSZXN1bHRzUGFnZX0+TmV4dCBQYWdlPC9idXR0b24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApIDogKFxuICAgICAgICAgIDxwPlRoZXJlIGFyZSBubyBjbGFpbXMgaW4gdGhpcyBjaGFubmVsPC9wPlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgQ2hhbm5lbENsYWltc0Rpc3BsYXk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IExpbmsgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmNvbnN0IHsgY2xhaW06IHsgZGVmYXVsdFRodW1ibmFpbCB9IH0gPSByZXF1aXJlKCcuLi8uLi8uLi9jb25maWcvc3BlZWNoQ29uZmlnLmpzJyk7XG5cbmNvbnN0IEFzc2V0UHJldmlldyA9ICh7IGNsYWltRGF0YTogeyBuYW1lLCBjbGFpbUlkLCBmaWxlRXh0LCBjb250ZW50VHlwZSwgdGh1bWJuYWlsIH0gfSkgPT4ge1xuICBjb25zdCBkaXJlY3RTb3VyY2VMaW5rID0gYCR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YDtcbiAgY29uc3Qgc2hvd1VybExpbmsgPSBgLyR7Y2xhaW1JZH0vJHtuYW1lfWA7XG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9J2Fzc2V0LWhvbGRlcic+XG4gICAgICA8TGluayB0bz17c2hvd1VybExpbmt9ID5cbiAgICAgICAgeygoKSA9PiB7XG4gICAgICAgICAgc3dpdGNoIChjb250ZW50VHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9qcGcnOlxuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgICAgICAgIGNhc2UgJ2ltYWdlL2dpZic6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsnYXNzZXQtcHJldmlldyd9XG4gICAgICAgICAgICAgICAgICBzcmM9e2RpcmVjdFNvdXJjZUxpbmt9XG4gICAgICAgICAgICAgICAgICBhbHQ9e25hbWV9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsnYXNzZXQtcHJldmlldyB2aWRlbyd9XG4gICAgICAgICAgICAgICAgICBzcmM9e3RodW1ibmFpbCB8fCBkZWZhdWx0VGh1bWJuYWlsfVxuICAgICAgICAgICAgICAgICAgYWx0PXtuYW1lfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxwPnVuc3VwcG9ydGVkIGZpbGUgdHlwZTwvcD5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCl9XG4gICAgICA8L0xpbms+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldFByZXZpZXc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9jb21wb25lbnRzL0Fzc2V0UHJldmlldy9pbmRleC5qc3giLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IE5hdkJhciBmcm9tICdjb250YWluZXJzL05hdkJhcic7XG5pbXBvcnQgSGVsbWV0IGZyb20gJ3JlYWN0LWhlbG1ldCc7XG5jb25zdCB7IHNpdGU6IHsgdGl0bGUsIGhvc3QgfSB9ID0gcmVxdWlyZSgnLi4vLi4vLi4vY29uZmlnL3NwZWVjaENvbmZpZy5qcycpO1xuXG5jbGFzcyBGb3VyT2hGb3JQYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPEhlbG1ldD5cbiAgICAgICAgICA8dGl0bGU+e3RpdGxlfSAtIDQwNDwvdGl0bGU+XG4gICAgICAgICAgPGxpbmsgcmVsPSdjYW5vbmljYWwnIGhyZWY9e2Ake2hvc3R9LzQwNGB9IC8+XG4gICAgICAgIDwvSGVsbWV0PlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxoMj40MDQ8L2gyPlxuICAgICAgICAgIDxwPlRoYXQgcGFnZSBkb2VzIG5vdCBleGlzdDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBGb3VyT2hGb3JQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3QvY29tcG9uZW50cy9Gb3VyT2hGb3VyUGFnZS9pbmRleC5qc3giLCJjb25zdCB7IHNlbmRHQVNlcnZlRXZlbnQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzJyk7XG5jb25zdCB7IGRldGVybWluZVJlc3BvbnNlVHlwZSwgZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eSwgbG9nUmVxdWVzdERhdGEsIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0IH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL3NlcnZlSGVscGVycy5qcycpO1xuY29uc3QgbGJyeVVyaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeVVyaS5qcycpO1xuY29uc3QgaGFuZGxlU2hvd1JlbmRlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaGFuZGxlU2hvd1JlbmRlci5qc3gnKTtcbmNvbnN0IFNFUlZFID0gJ1NFUlZFJztcblxubW9kdWxlLmV4cG9ydHMgPSAoYXBwKSA9PiB7XG4gIC8vIHJvdXRlIHRvIHNlcnZlIGEgc3BlY2lmaWMgYXNzZXQgdXNpbmcgdGhlIGNoYW5uZWwgb3IgY2xhaW0gaWRcbiAgYXBwLmdldCgnLzppZGVudGlmaWVyLzpjbGFpbScsIChyZXEsIHJlcykgPT4ge1xuICAgIGNvbnN0IHsgaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSA9IHJlcTtcbiAgICAvLyBkZWNpZGUgaWYgdGhpcyBpcyBhIHNob3cgcmVxdWVzdFxuICAgIGxldCBoYXNGaWxlRXh0ZW5zaW9uO1xuICAgIHRyeSB7XG4gICAgICAoeyBoYXNGaWxlRXh0ZW5zaW9uIH0gPSBsYnJ5VXJpLnBhcnNlTW9kaWZpZXIocGFyYW1zLmNsYWltKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgICB9XG4gICAgbGV0IHJlc3BvbnNlVHlwZSA9IGRldGVybWluZVJlc3BvbnNlVHlwZShoYXNGaWxlRXh0ZW5zaW9uLCBoZWFkZXJzKTtcbiAgICBpZiAocmVzcG9uc2VUeXBlICE9PSBTRVJWRSkge1xuICAgICAgcmV0dXJuIGhhbmRsZVNob3dSZW5kZXIocmVxLCByZXMpO1xuICAgIH1cbiAgICAvLyBoYW5kbGUgc2VydmUgcmVxdWVzdFxuICAgIC8vIHNlbmQgZ29vZ2xlIGFuYWx5dGljc1xuICAgIHNlbmRHQVNlcnZlRXZlbnQoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKTtcbiAgICAvLyBwYXJzZSB0aGUgY2xhaW1cbiAgICBsZXQgY2xhaW1OYW1lO1xuICAgIHRyeSB7XG4gICAgICAoeyBjbGFpbU5hbWUgfSA9IGxicnlVcmkucGFyc2VDbGFpbShwYXJhbXMuY2xhaW0pKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZX0pO1xuICAgIH1cbiAgICAvLyBwYXJzZSB0aGUgaWRlbnRpZmllclxuICAgIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1JZDtcbiAgICB0cnkge1xuICAgICAgKHsgaXNDaGFubmVsLCBjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltSWQgfSA9IGxicnlVcmkucGFyc2VJZGVudGlmaWVyKHBhcmFtcy5pZGVudGlmaWVyKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgICB9XG4gICAgaWYgKCFpc0NoYW5uZWwpIHtcbiAgICAgIFtjbGFpbUlkLCBjbGFpbU5hbWVdID0gZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eShjbGFpbUlkLCBjbGFpbU5hbWUpO1xuICAgIH1cbiAgICAvLyBsb2cgdGhlIHJlcXVlc3QgZGF0YSBmb3IgZGVidWdnaW5nXG4gICAgbG9nUmVxdWVzdERhdGEocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIGNoYW5uZWxOYW1lLCBjbGFpbUlkKTtcbiAgICAvLyBnZXQgdGhlIGNsYWltIElkIGFuZCB0aGVuIHNlcnZlIHRoZSBhc3NldFxuICAgIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0KGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lLCBjbGFpbUlkLCBvcmlnaW5hbFVybCwgaXAsIHJlcyk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBzZXJ2ZSB0aGUgd2lubmluZyBhc3NldCBhdCBhIGNsYWltIG9yIGEgY2hhbm5lbCBwYWdlXG4gIGFwcC5nZXQoJy86Y2xhaW0nLCAocmVxLCByZXMpID0+IHtcbiAgICBjb25zdCB7IGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0gPSByZXE7XG4gICAgLy8gZGVjaWRlIGlmIHRoaXMgaXMgYSBzaG93IHJlcXVlc3RcbiAgICBsZXQgaGFzRmlsZUV4dGVuc2lvbjtcbiAgICB0cnkge1xuICAgICAgKHsgaGFzRmlsZUV4dGVuc2lvbiB9ID0gbGJyeVVyaS5wYXJzZU1vZGlmaWVyKHBhcmFtcy5jbGFpbSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgfVxuICAgIGxldCByZXNwb25zZVR5cGUgPSBkZXRlcm1pbmVSZXNwb25zZVR5cGUoaGFzRmlsZUV4dGVuc2lvbiwgaGVhZGVycyk7XG4gICAgaWYgKHJlc3BvbnNlVHlwZSAhPT0gU0VSVkUpIHtcbiAgICAgIHJldHVybiBoYW5kbGVTaG93UmVuZGVyKHJlcSwgcmVzKTtcbiAgICB9XG4gICAgLy8gaGFuZGxlIHNlcnZlIHJlcXVlc3RcbiAgICAvLyBzZW5kIGdvb2dsZSBhbmFseXRpY3NcbiAgICBzZW5kR0FTZXJ2ZUV2ZW50KGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCk7XG4gICAgLy8gcGFyc2UgdGhlIGNsYWltXG4gICAgbGV0IGNsYWltTmFtZTtcbiAgICB0cnkge1xuICAgICAgKHtjbGFpbU5hbWV9ID0gbGJyeVVyaS5wYXJzZUNsYWltKHBhcmFtcy5jbGFpbSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgfVxuICAgIC8vIGxvZyB0aGUgcmVxdWVzdCBkYXRhIGZvciBkZWJ1Z2dpbmdcbiAgICBsb2dSZXF1ZXN0RGF0YShyZXNwb25zZVR5cGUsIGNsYWltTmFtZSwgbnVsbCwgbnVsbCk7XG4gICAgLy8gZ2V0IHRoZSBjbGFpbSBJZCBhbmQgdGhlbiBzZXJ2ZSB0aGUgYXNzZXRcbiAgICBnZXRDbGFpbUlkQW5kU2VydmVBc3NldChudWxsLCBudWxsLCBjbGFpbU5hbWUsIG51bGwsIG9yaWdpbmFsVXJsLCBpcCwgcmVzKTtcbiAgfSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcm91dGVzL3NlcnZlLXJvdXRlcy5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHsgZ2V0Q2xhaW1JZCwgZ2V0TG9jYWxGaWxlUmVjb3JkIH0gPSByZXF1aXJlKCcuLi9jb250cm9sbGVycy9zZXJ2ZUNvbnRyb2xsZXIuanMnKTtcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnLi4vaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XG5cbmNvbnN0IFNFUlZFID0gJ1NFUlZFJztcbmNvbnN0IFNIT1cgPSAnU0hPVyc7XG5jb25zdCBOT19GSUxFID0gJ05PX0ZJTEUnO1xuY29uc3QgTk9fQ0hBTk5FTCA9ICdOT19DSEFOTkVMJztcbmNvbnN0IE5PX0NMQUlNID0gJ05PX0NMQUlNJztcblxuZnVuY3Rpb24gY2xpZW50QWNjZXB0c0h0bWwgKHthY2NlcHR9KSB7XG4gIHJldHVybiBhY2NlcHQgJiYgYWNjZXB0Lm1hdGNoKC90ZXh0XFwvaHRtbC8pO1xufTtcblxuZnVuY3Rpb24gcmVxdWVzdElzRnJvbUJyb3dzZXIgKGhlYWRlcnMpIHtcbiAgcmV0dXJuIGhlYWRlcnNbJ3VzZXItYWdlbnQnXSAmJiBoZWFkZXJzWyd1c2VyLWFnZW50J10ubWF0Y2goL01vemlsbGEvKTtcbn07XG5cbmZ1bmN0aW9uIGNsaWVudFdhbnRzQXNzZXQgKHthY2NlcHQsIHJhbmdlfSkge1xuICBjb25zdCBpbWFnZUlzV2FudGVkID0gYWNjZXB0ICYmIGFjY2VwdC5tYXRjaCgvaW1hZ2VcXC8uKi8pICYmICFhY2NlcHQubWF0Y2goL3RleHRcXC9odG1sLykgJiYgIWFjY2VwdC5tYXRjaCgvdGV4dFxcL1xcKi8pO1xuICBjb25zdCB2aWRlb0lzV2FudGVkID0gYWNjZXB0ICYmIHJhbmdlO1xuICByZXR1cm4gaW1hZ2VJc1dhbnRlZCB8fCB2aWRlb0lzV2FudGVkO1xufTtcblxuZnVuY3Rpb24gaXNWYWxpZENsYWltSWQgKGNsYWltSWQpIHtcbiAgcmV0dXJuICgoY2xhaW1JZC5sZW5ndGggPT09IDQwKSAmJiAhL1teQS1aYS16MC05XS9nLnRlc3QoY2xhaW1JZCkpO1xufTtcblxuZnVuY3Rpb24gaXNWYWxpZFNob3J0SWQgKGNsYWltSWQpIHtcbiAgcmV0dXJuIGNsYWltSWQubGVuZ3RoID09PSAxOyAgLy8gaXQgc2hvdWxkIHJlYWxseSBldmFsdWF0ZSB0aGUgc2hvcnQgdXJsIGl0c2VsZlxufTtcblxuZnVuY3Rpb24gaXNWYWxpZFNob3J0SWRPckNsYWltSWQgKGlucHV0KSB7XG4gIHJldHVybiAoaXNWYWxpZENsYWltSWQoaW5wdXQpIHx8IGlzVmFsaWRTaG9ydElkKGlucHV0KSk7XG59O1xuXG5mdW5jdGlvbiBzZXJ2ZUFzc2V0VG9DbGllbnQgKGNsYWltSWQsIG5hbWUsIHJlcykge1xuICByZXR1cm4gZ2V0TG9jYWxGaWxlUmVjb3JkKGNsYWltSWQsIG5hbWUpXG4gICAgLnRoZW4oZmlsZVJlY29yZCA9PiB7XG4gICAgICAvLyBjaGVjayB0aGF0IGEgbG9jYWwgcmVjb3JkIHdhcyBmb3VuZFxuICAgICAgaWYgKGZpbGVSZWNvcmQgPT09IE5PX0ZJTEUpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMzA3KS5yZWRpcmVjdChgL2FwaS9jbGFpbS9nZXQvJHtuYW1lfS8ke2NsYWltSWR9YCk7XG4gICAgICB9XG4gICAgICAvLyBzZXJ2ZSB0aGUgZmlsZVxuICAgICAgY29uc3Qge2ZpbGVQYXRoLCBmaWxlVHlwZX0gPSBmaWxlUmVjb3JkO1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoYHNlcnZpbmcgZmlsZTogJHtmaWxlUGF0aH1gKTtcbiAgICAgIGNvbnN0IHNlbmRGaWxlT3B0aW9ucyA9IHtcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICdYLUNvbnRlbnQtVHlwZS1PcHRpb25zJzogJ25vc25pZmYnLFxuICAgICAgICAgICdDb250ZW50LVR5cGUnICAgICAgICAgIDogZmlsZVR5cGUgfHwgJ2ltYWdlL2pwZWcnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKS5zZW5kRmlsZShmaWxlUGF0aCwgc2VuZEZpbGVPcHRpb25zKTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDbGFpbUlkQW5kU2VydmVBc3NldCAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbU5hbWUsIGNsYWltSWQsIG9yaWdpbmFsVXJsLCBpcCwgcmVzKSB7XG4gICAgLy8gZ2V0IHRoZSBjbGFpbSBJZCBhbmQgdGhlbiBzZXJ2ZSB0aGUgYXNzZXRcbiAgICBnZXRDbGFpbUlkKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lLCBjbGFpbUlkKVxuICAgICAgLnRoZW4oZnVsbENsYWltSWQgPT4ge1xuICAgICAgICBpZiAoZnVsbENsYWltSWQgPT09IE5PX0NMQUlNKSB7XG4gICAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ25vIGNsYWltIGlkIGNvdWxkIGJlIGZvdW5kJ30pO1xuICAgICAgICB9IGVsc2UgaWYgKGZ1bGxDbGFpbUlkID09PSBOT19DSEFOTkVMKSB7XG4gICAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ25vIGNoYW5uZWwgaWQgY291bGQgYmUgZm91bmQnfSk7XG4gICAgICAgIH1cbiAgICAgICAgc2VydmVBc3NldFRvQ2xpZW50KGZ1bGxDbGFpbUlkLCBjbGFpbU5hbWUsIHJlcyk7XG4gICAgICAgIC8vIHBvc3RUb1N0YXRzKHJlc3BvbnNlVHlwZSwgb3JpZ2luYWxVcmwsIGlwLCBjbGFpbU5hbWUsIGZ1bGxDbGFpbUlkLCAnc3VjY2VzcycpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgICAgLy8gcG9zdFRvU3RhdHMocmVzcG9uc2VUeXBlLCBvcmlnaW5hbFVybCwgaXAsIGNsYWltTmFtZSwgZnVsbENsYWltSWQsICdmYWlsJyk7XG4gICAgICB9KTtcbiAgfSxcbiAgZGV0ZXJtaW5lUmVzcG9uc2VUeXBlIChoYXNGaWxlRXh0ZW5zaW9uLCBoZWFkZXJzKSB7XG4gICAgbGV0IHJlc3BvbnNlVHlwZTtcbiAgICBpZiAoaGFzRmlsZUV4dGVuc2lvbikge1xuICAgICAgcmVzcG9uc2VUeXBlID0gU0VSVkU7ICAvLyBhc3N1bWUgYSBzZXJ2ZSByZXF1ZXN0IGlmIGZpbGUgZXh0ZW5zaW9uIGlzIHByZXNlbnRcbiAgICAgIGlmIChjbGllbnRBY2NlcHRzSHRtbChoZWFkZXJzKSkgeyAgLy8gaWYgdGhlIHJlcXVlc3QgY29tZXMgZnJvbSBhIGJyb3dzZXIsIGNoYW5nZSBpdCB0byBhIHNob3cgcmVxdWVzdFxuICAgICAgICByZXNwb25zZVR5cGUgPSBTSE9XO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXNwb25zZVR5cGUgPSBTSE9XO1xuICAgICAgaWYgKGNsaWVudFdhbnRzQXNzZXQoaGVhZGVycykgJiYgcmVxdWVzdElzRnJvbUJyb3dzZXIoaGVhZGVycykpIHsgIC8vIHRoaXMgaXMgaW4gY2FzZSBzb21lb25lIGVtYmVkcyBhIHNob3cgdXJsXG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnU2hvdyByZXF1ZXN0IGNhbWUgZnJvbSBicm93c2VyIGJ1dCB3YW50cyBhbiBpbWFnZS92aWRlby4gQ2hhbmdpbmcgcmVzcG9uc2UgdG8gc2VydmUuLi4nKTtcbiAgICAgICAgcmVzcG9uc2VUeXBlID0gU0VSVkU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNwb25zZVR5cGU7XG4gIH0sXG4gIGZsaXBDbGFpbU5hbWVBbmRJZEZvckJhY2t3YXJkc0NvbXBhdGliaWxpdHkgKGlkZW50aWZpZXIsIG5hbWUpIHtcbiAgICAvLyB0aGlzIGlzIGEgcGF0Y2ggZm9yIGJhY2t3YXJkcyBjb21wYXRhYmlsaXR5IHdpdGggJy9uYW1lL2NsYWltX2lkJyB1cmwgZm9ybWF0XG4gICAgaWYgKGlzVmFsaWRTaG9ydElkT3JDbGFpbUlkKG5hbWUpICYmICFpc1ZhbGlkU2hvcnRJZE9yQ2xhaW1JZChpZGVudGlmaWVyKSkge1xuICAgICAgY29uc3QgdGVtcE5hbWUgPSBuYW1lO1xuICAgICAgbmFtZSA9IGlkZW50aWZpZXI7XG4gICAgICBpZGVudGlmaWVyID0gdGVtcE5hbWU7XG4gICAgfVxuICAgIHJldHVybiBbaWRlbnRpZmllciwgbmFtZV07XG4gIH0sXG4gIGxvZ1JlcXVlc3REYXRhIChyZXNwb25zZVR5cGUsIGNsYWltTmFtZSwgY2hhbm5lbE5hbWUsIGNsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoJ3Jlc3BvbnNlVHlwZSA9PT0nLCByZXNwb25zZVR5cGUpO1xuICAgIGxvZ2dlci5kZWJ1ZygnY2xhaW0gbmFtZSA9PT0gJywgY2xhaW1OYW1lKTtcbiAgICBsb2dnZXIuZGVidWcoJ2NoYW5uZWwgbmFtZSA9PT0nLCBjaGFubmVsTmFtZSk7XG4gICAgbG9nZ2VyLmRlYnVnKCdjbGFpbSBpZCA9PT0nLCBjbGFpbUlkKTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9oZWxwZXJzL3NlcnZlSGVscGVycy5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFJFR0VYUF9JTlZBTElEX0NMQUlNICA6IC9bXkEtWmEtejAtOS1dL2csXG4gIFJFR0VYUF9JTlZBTElEX0NIQU5ORUw6IC9bXkEtWmEtejAtOS1AXS9nLFxuICBSRUdFWFBfQUREUkVTUyAgICAgICAgOiAvXmIoPz1bXjBPSWxdezMyLDMzfSlbMC05QS1aYS16XXszMiwzM30kLyxcbiAgQ0hBTk5FTF9DSEFSICAgICAgICAgIDogJ0AnLFxuICBwYXJzZUlkZW50aWZpZXIgICAgICAgOiBmdW5jdGlvbiAoaWRlbnRpZmllcikge1xuICAgIGxvZ2dlci5kZWJ1ZygncGFyc2luZyBpZGVudGlmaWVyOicsIGlkZW50aWZpZXIpO1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjL10qKScgKyAvLyB2YWx1ZSAoc3RvcHMgYXQgdGhlIGZpcnN0IHNlcGFyYXRvciBvciBlbmQpXG4gICAgICAnKFs6JCNdPykoW14vXSopJyAvLyBtb2RpZmllciBzZXBhcmF0b3IsIG1vZGlmaWVyIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCB2YWx1ZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleFxuICAgICAgLmV4ZWMoaWRlbnRpZmllcilcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG4gICAgbG9nZ2VyLmRlYnVnKGAke3Byb3RvfSwgJHt2YWx1ZX0sICR7bW9kaWZpZXJTZXBlcmF0b3J9LCAke21vZGlmaWVyfWApO1xuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbmFtZVxuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciB1cmwuICBObyBjaGFubmVsIG5hbWUgcHJvdmlkZWQgYmVmb3JlIFwiJHttb2RpZmllclNlcGVyYXRvcn1cImApO1xuICAgIH1cbiAgICBjb25zdCBpc0NoYW5uZWwgPSB2YWx1ZS5zdGFydHNXaXRoKG1vZHVsZS5leHBvcnRzLkNIQU5ORUxfQ0hBUik7XG4gICAgY29uc3QgY2hhbm5lbE5hbWUgPSBpc0NoYW5uZWwgPyB2YWx1ZSA6IG51bGw7XG4gICAgbGV0IGNsYWltSWQ7XG4gICAgaWYgKGlzQ2hhbm5lbCkge1xuICAgICAgaWYgKCFjaGFubmVsTmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNoYW5uZWwgbmFtZSBhZnRlciBALicpO1xuICAgICAgfVxuICAgICAgY29uc3QgbmFtZUJhZENoYXJzID0gKGNoYW5uZWxOYW1lKS5tYXRjaChtb2R1bGUuZXhwb3J0cy5SRUdFWFBfSU5WQUxJRF9DSEFOTkVMKTtcbiAgICAgIGlmIChuYW1lQmFkQ2hhcnMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGNoYXJhY3RlcnMgaW4gY2hhbm5lbCBuYW1lOiAke25hbWVCYWRDaGFycy5qb2luKCcsICcpfS5gKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY2xhaW1JZCA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG1vZGlmaWVyXG4gICAgbGV0IGNoYW5uZWxDbGFpbUlkO1xuICAgIGlmIChtb2RpZmllclNlcGVyYXRvcikge1xuICAgICAgaWYgKCFtb2RpZmllcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIG1vZGlmaWVyIHByb3ZpZGVkIGFmdGVyIHNlcGFyYXRvciBcIiR7bW9kaWZpZXJTZXBlcmF0b3J9XCJgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yID09PSAnOicpIHtcbiAgICAgICAgY2hhbm5lbENsYWltSWQgPSBtb2RpZmllcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIFwiJHttb2RpZmllclNlcGVyYXRvcn1cIiBtb2RpZmllciBpcyBub3QgY3VycmVudGx5IHN1cHBvcnRlZGApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaXNDaGFubmVsLFxuICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICBjaGFubmVsQ2xhaW1JZCxcbiAgICAgIGNsYWltSWQsXG4gICAgfTtcbiAgfSxcbiAgcGFyc2VDbGFpbTogZnVuY3Rpb24gKGNsYWltKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdwYXJzaW5nIG5hbWU6JywgY2xhaW0pO1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjLy5dKiknICsgLy8gbmFtZSAoc3RvcHMgYXQgdGhlIGZpcnN0IG1vZGlmaWVyKVxuICAgICAgJyhbOiQjLl0/KShbXi9dKiknIC8vIG1vZGlmaWVyIHNlcGFyYXRvciwgbW9kaWZpZXIgKHN0b3BzIGF0IHRoZSBmaXJzdCBwYXRoIHNlcGFyYXRvciBvciBlbmQpXG4gICAgKTtcbiAgICBjb25zdCBbcHJvdG8sIGNsYWltTmFtZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleFxuICAgICAgLmV4ZWMoY2xhaW0pXG4gICAgICAubWFwKG1hdGNoID0+IG1hdGNoIHx8IG51bGwpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgJHtwcm90b30sICR7Y2xhaW1OYW1lfSwgJHttb2RpZmllclNlcGVyYXRvcn0sICR7bW9kaWZpZXJ9YCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCFjbGFpbU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2xhaW0gbmFtZSBwcm92aWRlZCBiZWZvcmUgLicpO1xuICAgIH1cbiAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2xhaW1OYW1lKS5tYXRjaChtb2R1bGUuZXhwb3J0cy5SRUdFWFBfSU5WQUxJRF9DTEFJTSk7XG4gICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGNoYXJhY3RlcnMgaW4gY2xhaW0gbmFtZTogJHtuYW1lQmFkQ2hhcnMuam9pbignLCAnKX0uYCk7XG4gICAgfVxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG1vZGlmaWVyXG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gZmlsZSBleHRlbnNpb24gcHJvdmlkZWQgYWZ0ZXIgc2VwYXJhdG9yICR7bW9kaWZpZXJTZXBlcmF0b3J9LmApO1xuICAgICAgfVxuICAgICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yICE9PSAnLicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgJHttb2RpZmllclNlcGVyYXRvcn0gbW9kaWZpZXIgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY2xhaW0gbmFtZWApO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyByZXR1cm4gcmVzdWx0c1xuICAgIHJldHVybiB7XG4gICAgICBjbGFpbU5hbWUsXG4gICAgfTtcbiAgfSxcbiAgcGFyc2VNb2RpZmllcjogZnVuY3Rpb24gKGNsYWltKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdwYXJzaW5nIG1vZGlmaWVyOicsIGNsYWltKTtcbiAgICBjb25zdCBjb21wb25lbnRzUmVnZXggPSBuZXcgUmVnRXhwKFxuICAgICAgJyhbXjokIy8uXSopJyArIC8vIG5hbWUgKHN0b3BzIGF0IHRoZSBmaXJzdCBtb2RpZmllcilcbiAgICAgICcoWzokIy5dPykoW14vXSopJyAvLyBtb2RpZmllciBzZXBhcmF0b3IsIG1vZGlmaWVyIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCBjbGFpbU5hbWUsIG1vZGlmaWVyU2VwZXJhdG9yLCBtb2RpZmllcl0gPSBjb21wb25lbnRzUmVnZXhcbiAgICAgIC5leGVjKGNsYWltKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcbiAgICBsb2dnZXIuZGVidWcoYCR7cHJvdG99LCAke2NsYWltTmFtZX0sICR7bW9kaWZpZXJTZXBlcmF0b3J9LCAke21vZGlmaWVyfWApO1xuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG1vZGlmaWVyXG4gICAgbGV0IGhhc0ZpbGVFeHRlbnNpb24gPSBmYWxzZTtcbiAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IpIHtcbiAgICAgIGhhc0ZpbGVFeHRlbnNpb24gPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaGFzRmlsZUV4dGVuc2lvbixcbiAgICB9O1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2hlbHBlcnMvbGJyeVVyaS5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXJUb1N0cmluZyB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IHsgY3JlYXRlU3RvcmUsIGFwcGx5TWlkZGxld2FyZSB9IGZyb20gJ3JlZHV4JztcbmltcG9ydCBSZWR1Y2VyIGZyb20gJy4uL3JlYWN0L3JlZHVjZXJzJztcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgU3RhdGljUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgR0FMaXN0ZW5lciBmcm9tICcuLi9yZWFjdC9jb21wb25lbnRzL0dBTGlzdGVuZXInO1xuaW1wb3J0IEFwcCBmcm9tICcuLi9yZWFjdC9hcHAnO1xuaW1wb3J0IHJlbmRlckZ1bGxQYWdlIGZyb20gJy4vcmVuZGVyRnVsbFBhZ2UnO1xuaW1wb3J0IGNyZWF0ZVNhZ2FNaWRkbGV3YXJlIGZyb20gJ3JlZHV4LXNhZ2EnO1xuaW1wb3J0IHsgY2FsbCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgeyBoYW5kbGVTaG93UGFnZVVyaSB9IGZyb20gJy4uL3JlYWN0L3NhZ2FzL3Nob3dfdXJpJztcbmltcG9ydCB7IG9uSGFuZGxlU2hvd1BhZ2VVcmkgfSBmcm9tICcuLi9yZWFjdC9hY3Rpb25zL3Nob3cnO1xuXG5pbXBvcnQgSGVsbWV0IGZyb20gJ3JlYWN0LWhlbG1ldCc7XG5cbmNvbnN0IHJldHVyblNhZ2FXaXRoUGFyYW1zID0gKHNhZ2EsIHBhcmFtcykgPT4ge1xuICByZXR1cm4gZnVuY3Rpb24gKiAoKSB7XG4gICAgeWllbGQgY2FsbChzYWdhLCBwYXJhbXMpO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSAocmVxLCByZXMpID0+IHtcbiAgbGV0IGNvbnRleHQgPSB7fTtcblxuICAvLyBjcmVhdGUgYW5kIGFwcGx5IG1pZGRsZXdhcmVcbiAgY29uc3Qgc2FnYU1pZGRsZXdhcmUgPSBjcmVhdGVTYWdhTWlkZGxld2FyZSgpO1xuICBjb25zdCBtaWRkbGV3YXJlID0gYXBwbHlNaWRkbGV3YXJlKHNhZ2FNaWRkbGV3YXJlKTtcblxuICAvLyBjcmVhdGUgYSBuZXcgUmVkdXggc3RvcmUgaW5zdGFuY2VcbiAgY29uc3Qgc3RvcmUgPSBjcmVhdGVTdG9yZShSZWR1Y2VyLCBtaWRkbGV3YXJlKTtcblxuICAvLyBjcmVhdGUgc2FnYVxuICBjb25zdCBhY3Rpb24gPSBvbkhhbmRsZVNob3dQYWdlVXJpKHJlcS5wYXJhbXMpO1xuICBjb25zdCBzYWdhID0gcmV0dXJuU2FnYVdpdGhQYXJhbXMoaGFuZGxlU2hvd1BhZ2VVcmksIGFjdGlvbik7XG5cbiAgLy8gcnVuIHRoZSBzYWdhIG1pZGRsZXdhcmVcbiAgc2FnYU1pZGRsZXdhcmVcbiAgICAucnVuKHNhZ2EpXG4gICAgLmRvbmVcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICAvLyByZW5kZXIgY29tcG9uZW50IHRvIGEgc3RyaW5nXG4gICAgICBjb25zdCBodG1sID0gcmVuZGVyVG9TdHJpbmcoXG4gICAgICAgIDxQcm92aWRlciBzdG9yZT17c3RvcmV9PlxuICAgICAgICAgIDxTdGF0aWNSb3V0ZXIgbG9jYXRpb249e3JlcS51cmx9IGNvbnRleHQ9e2NvbnRleHR9PlxuICAgICAgICAgICAgPEdBTGlzdGVuZXI+XG4gICAgICAgICAgICAgIDxBcHAgLz5cbiAgICAgICAgICAgIDwvR0FMaXN0ZW5lcj5cbiAgICAgICAgICA8L1N0YXRpY1JvdXRlcj5cbiAgICAgICAgPC9Qcm92aWRlcj5cbiAgICAgICk7XG5cbiAgICAgIC8vIGdldCBoZWFkIHRhZ3MgZnJvbSBoZWxtZXRcbiAgICAgIGNvbnN0IGhlbG1ldCA9IEhlbG1ldC5yZW5kZXJTdGF0aWMoKTtcblxuICAgICAgLy8gY2hlY2sgZm9yIGEgcmVkaXJlY3RcbiAgICAgIGlmIChjb250ZXh0LnVybCkge1xuICAgICAgICByZXR1cm4gcmVzLnJlZGlyZWN0KDMwMSwgY29udGV4dC51cmwpO1xuICAgICAgfVxuXG4gICAgICAvLyBnZXQgdGhlIGluaXRpYWwgc3RhdGUgZnJvbSBvdXIgUmVkdXggc3RvcmVcbiAgICAgIGNvbnN0IHByZWxvYWRlZFN0YXRlID0gc3RvcmUuZ2V0U3RhdGUoKTtcblxuICAgICAgLy8gc2VuZCB0aGUgcmVuZGVyZWQgcGFnZSBiYWNrIHRvIHRoZSBjbGllbnRcbiAgICAgIHJlcy5zZW5kKHJlbmRlckZ1bGxQYWdlKGhlbG1ldCwgaHRtbCwgcHJlbG9hZGVkU3RhdGUpKTtcbiAgICB9KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9oZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVkdXgtc2FnYVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlZHV4LXNhZ2FcIlxuLy8gbW9kdWxlIGlkID0gMTQ2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImltcG9ydCB7IGNhbGwsIHB1dCwgdGFrZUxhdGVzdCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBvblJlcXVlc3RFcnJvciwgb25OZXdDaGFubmVsUmVxdWVzdCwgb25OZXdBc3NldFJlcXVlc3QgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IHsgbmV3QXNzZXRSZXF1ZXN0IH0gZnJvbSAnc2FnYXMvc2hvd19hc3NldCc7XG5pbXBvcnQgeyBuZXdDaGFubmVsUmVxdWVzdCB9IGZyb20gJ3NhZ2FzL3Nob3dfY2hhbm5lbCc7XG5pbXBvcnQgbGJyeVVyaSBmcm9tICd1dGlscy9sYnJ5VXJpJztcblxuZnVuY3Rpb24gKiBwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSAobW9kaWZpZXIsIGNsYWltKSB7XG4gIC8vIHRoaXMgaXMgYSByZXF1ZXN0IGZvciBhbiBhc3NldFxuICAvLyBjbGFpbSB3aWxsIGJlIGFuIGFzc2V0IGNsYWltXG4gIC8vIHRoZSBpZGVudGlmaWVyIGNvdWxkIGJlIGEgY2hhbm5lbCBvciBhIGNsYWltIGlkXG4gIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1JZCwgY2xhaW1OYW1lLCBleHRlbnNpb247XG4gIHRyeSB7XG4gICAgKHsgaXNDaGFubmVsLCBjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltSWQgfSA9IGxicnlVcmkucGFyc2VJZGVudGlmaWVyKG1vZGlmaWVyKSk7XG4gICAgKHsgY2xhaW1OYW1lLCBleHRlbnNpb24gfSA9IGxicnlVcmkucGFyc2VDbGFpbShjbGFpbSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIHRyaWdnZXIgYW4gbmV3IGFjdGlvbiB0byB1cGRhdGUgdGhlIHN0b3JlXG4gIGlmIChpc0NoYW5uZWwpIHtcbiAgICByZXR1cm4geWllbGQgY2FsbChuZXdBc3NldFJlcXVlc3QsIG9uTmV3QXNzZXRSZXF1ZXN0KGNsYWltTmFtZSwgbnVsbCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBleHRlbnNpb24pKTtcbiAgfTtcbiAgeWllbGQgY2FsbChuZXdBc3NldFJlcXVlc3QsIG9uTmV3QXNzZXRSZXF1ZXN0KGNsYWltTmFtZSwgY2xhaW1JZCwgbnVsbCwgbnVsbCwgZXh0ZW5zaW9uKSk7XG59XG5mdW5jdGlvbiAqIHBhcnNlQW5kVXBkYXRlQ2xhaW1Pbmx5IChjbGFpbSkge1xuICAvLyB0aGlzIGNvdWxkIGJlIGEgcmVxdWVzdCBmb3IgYW4gYXNzZXQgb3IgYSBjaGFubmVsIHBhZ2VcbiAgLy8gY2xhaW0gY291bGQgYmUgYW4gYXNzZXQgY2xhaW0gb3IgYSBjaGFubmVsIGNsYWltXG4gIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZDtcbiAgdHJ5IHtcbiAgICAoeyBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCB9ID0gbGJyeVVyaS5wYXJzZUlkZW50aWZpZXIoY2xhaW0pKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyB0cmlnZ2VyIGFuIG5ldyBhY3Rpb24gdG8gdXBkYXRlIHRoZSBzdG9yZVxuICAvLyByZXR1cm4gZWFybHkgaWYgdGhpcyByZXF1ZXN0IGlzIGZvciBhIGNoYW5uZWxcbiAgaWYgKGlzQ2hhbm5lbCkge1xuICAgIHJldHVybiB5aWVsZCBjYWxsKG5ld0NoYW5uZWxSZXF1ZXN0LCBvbk5ld0NoYW5uZWxSZXF1ZXN0KGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkpO1xuICB9XG4gIC8vIGlmIG5vdCBmb3IgYSBjaGFubmVsLCBwYXJzZSB0aGUgY2xhaW0gcmVxdWVzdFxuICBsZXQgY2xhaW1OYW1lLCBleHRlbnNpb247XG4gIHRyeSB7XG4gICAgKHtjbGFpbU5hbWUsIGV4dGVuc2lvbn0gPSBsYnJ5VXJpLnBhcnNlQ2xhaW0oY2xhaW0pKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICB5aWVsZCBjYWxsKG5ld0Fzc2V0UmVxdWVzdCwgb25OZXdBc3NldFJlcXVlc3QoY2xhaW1OYW1lLCBudWxsLCBudWxsLCBudWxsLCBleHRlbnNpb24pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uICogaGFuZGxlU2hvd1BhZ2VVcmkgKGFjdGlvbikge1xuICBjb25zdCB7IGlkZW50aWZpZXIsIGNsYWltIH0gPSBhY3Rpb24uZGF0YTtcbiAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICByZXR1cm4geWllbGQgY2FsbChwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSwgaWRlbnRpZmllciwgY2xhaW0pO1xuICB9XG4gIHlpZWxkIGNhbGwocGFyc2VBbmRVcGRhdGVDbGFpbU9ubHksIGNsYWltKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoSGFuZGxlU2hvd1BhZ2VVcmkgKCkge1xuICB5aWVsZCB0YWtlTGF0ZXN0KGFjdGlvbnMuSEFORExFX1NIT1dfVVJJLCBoYW5kbGVTaG93UGFnZVVyaSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vcmVhY3Qvc2FnYXMvc2hvd191cmkuanMiLCJpbXBvcnQgeyBjYWxsLCBwdXQsIHNlbGVjdCwgdGFrZUxhdGVzdCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdCwgb25SZXF1ZXN0RXJyb3IsIG9uUmVxdWVzdFVwZGF0ZSwgYWRkQXNzZXRUb0Fzc2V0TGlzdCB9IGZyb20gJ2FjdGlvbnMvc2hvdyc7XG5pbXBvcnQgeyBnZXRMb25nQ2xhaW1JZCwgZ2V0U2hvcnRJZCwgZ2V0Q2xhaW1EYXRhIH0gZnJvbSAnYXBpL2Fzc2V0QXBpJztcbmltcG9ydCB7IHNlbGVjdFNob3dTdGF0ZSB9IGZyb20gJ3NlbGVjdG9ycy9zaG93JztcblxuZXhwb3J0IGZ1bmN0aW9uICogbmV3QXNzZXRSZXF1ZXN0IChhY3Rpb24pIHtcbiAgY29uc3QgeyByZXF1ZXN0VHlwZSwgcmVxdWVzdElkLCBuYW1lLCBtb2RpZmllciB9ID0gYWN0aW9uLmRhdGE7XG4gIC8vIHB1dCBhbiBhY3Rpb24gdG8gdXBkYXRlIHRoZSByZXF1ZXN0IGluIHJlZHV4XG4gIHlpZWxkIHB1dChvblJlcXVlc3RVcGRhdGUocmVxdWVzdFR5cGUsIHJlcXVlc3RJZCkpO1xuICAvLyBpcyB0aGlzIGFuIGV4aXN0aW5nIHJlcXVlc3Q/XG4gIC8vIElmIHRoaXMgdXJpIGlzIGluIHRoZSByZXF1ZXN0IGxpc3QsIGl0J3MgYWxyZWFkeSBiZWVuIGZldGNoZWRcbiAgY29uc3Qgc3RhdGUgPSB5aWVsZCBzZWxlY3Qoc2VsZWN0U2hvd1N0YXRlKTtcbiAgaWYgKHN0YXRlLnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBnZXQgbG9uZyBpZCAmJiBhZGQgcmVxdWVzdCB0byByZXF1ZXN0IGxpc3RcbiAgbGV0IGxvbmdJZDtcbiAgdHJ5IHtcbiAgICAoe2RhdGE6IGxvbmdJZH0gPSB5aWVsZCBjYWxsKGdldExvbmdDbGFpbUlkLCBuYW1lLCBtb2RpZmllcikpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIGNvbnN0IGFzc2V0S2V5ID0gYGEjJHtuYW1lfSMke2xvbmdJZH1gO1xuICB5aWVsZCBwdXQoYWRkUmVxdWVzdFRvUmVxdWVzdExpc3QocmVxdWVzdElkLCBudWxsLCBhc3NldEtleSkpO1xuICAvLyBpcyB0aGlzIGFuIGV4aXN0aW5nIGFzc2V0P1xuICAvLyBJZiB0aGlzIGFzc2V0IGlzIGluIHRoZSBhc3NldCBsaXN0LCBpdCdzIGFscmVhZHkgYmVlbiBmZXRjaGVkXG4gIGlmIChzdGF0ZS5hc3NldExpc3RbYXNzZXRLZXldKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLy8gZ2V0IHNob3J0IElkXG4gIGxldCBzaG9ydElkO1xuICB0cnkge1xuICAgICh7ZGF0YTogc2hvcnRJZH0gPSB5aWVsZCBjYWxsKGdldFNob3J0SWQsIG5hbWUsIGxvbmdJZCkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIGdldCBhc3NldCBjbGFpbSBkYXRhXG4gIGxldCBjbGFpbURhdGE7XG4gIHRyeSB7XG4gICAgKHtkYXRhOiBjbGFpbURhdGF9ID0geWllbGQgY2FsbChnZXRDbGFpbURhdGEsIG5hbWUsIGxvbmdJZCkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIGFkZCBhc3NldCB0byBhc3NldCBsaXN0XG4gIHlpZWxkIHB1dChhZGRBc3NldFRvQXNzZXRMaXN0KGFzc2V0S2V5LCBudWxsLCBuYW1lLCBsb25nSWQsIHNob3J0SWQsIGNsYWltRGF0YSkpO1xuICAvLyBjbGVhciBhbnkgZXJyb3JzIGluIHJlcXVlc3QgZXJyb3JcbiAgeWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKG51bGwpKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoTmV3QXNzZXRSZXF1ZXN0ICgpIHtcbiAgeWllbGQgdGFrZUxhdGVzdChhY3Rpb25zLkFTU0VUX1JFUVVFU1RfTkVXLCBuZXdBc3NldFJlcXVlc3QpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L3NhZ2FzL3Nob3dfYXNzZXQuanMiLCJpbXBvcnQgUmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcbmNvbnN0IHsgc2l0ZTogeyBob3N0IH0gfSA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9zcGVlY2hDb25maWcuanMnKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldExvbmdDbGFpbUlkIChuYW1lLCBtb2RpZmllcikge1xuICBsZXQgYm9keSA9IHt9O1xuICAvLyBjcmVhdGUgcmVxdWVzdCBwYXJhbXNcbiAgaWYgKG1vZGlmaWVyKSB7XG4gICAgaWYgKG1vZGlmaWVyLmlkKSB7XG4gICAgICBib2R5WydjbGFpbUlkJ10gPSBtb2RpZmllci5pZDtcbiAgICB9IGVsc2Uge1xuICAgICAgYm9keVsnY2hhbm5lbE5hbWUnXSA9IG1vZGlmaWVyLmNoYW5uZWwubmFtZTtcbiAgICAgIGJvZHlbJ2NoYW5uZWxDbGFpbUlkJ10gPSBtb2RpZmllci5jaGFubmVsLmlkO1xuICAgIH1cbiAgfVxuICBib2R5WydjbGFpbU5hbWUnXSA9IG5hbWU7XG4gIGNvbnN0IHBhcmFtcyA9IHtcbiAgICBtZXRob2QgOiAnUE9TVCcsXG4gICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgYm9keSAgIDogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gIH07XG4gIC8vIGNyZWF0ZSB1cmxcbiAgY29uc3QgdXJsID0gYCR7aG9zdH0vYXBpL2NsYWltL2xvbmctaWRgO1xuICAvLyByZXR1cm4gdGhlIHJlcXVlc3QgcHJvbWlzZVxuICByZXR1cm4gUmVxdWVzdCh1cmwsIHBhcmFtcyk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2hvcnRJZCAobmFtZSwgY2xhaW1JZCkge1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2xhaW0vc2hvcnQtaWQvJHtjbGFpbUlkfS8ke25hbWV9YDtcbiAgcmV0dXJuIFJlcXVlc3QodXJsKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGFpbURhdGEgKG5hbWUsIGNsYWltSWQpIHtcbiAgY29uc3QgdXJsID0gYCR7aG9zdH0vYXBpL2NsYWltL2RhdGEvJHtuYW1lfS8ke2NsYWltSWR9YDtcbiAgcmV0dXJuIFJlcXVlc3QodXJsKTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9hcGkvYXNzZXRBcGkuanMiLCJpbXBvcnQge2NhbGwsIHB1dCwgc2VsZWN0LCB0YWtlTGF0ZXN0fSBmcm9tICdyZWR1eC1zYWdhL2VmZmVjdHMnO1xuaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvc2hvd19hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgYWRkTmV3Q2hhbm5lbFRvQ2hhbm5lbExpc3QsIGFkZFJlcXVlc3RUb1JlcXVlc3RMaXN0LCBvblJlcXVlc3RFcnJvciwgb25SZXF1ZXN0VXBkYXRlLCB1cGRhdGVDaGFubmVsQ2xhaW1zIH0gZnJvbSAnYWN0aW9ucy9zaG93JztcbmltcG9ydCB7IGdldENoYW5uZWxDbGFpbXMsIGdldENoYW5uZWxEYXRhIH0gZnJvbSAnYXBpL2NoYW5uZWxBcGknO1xuaW1wb3J0IHsgc2VsZWN0U2hvd1N0YXRlIH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuXG5leHBvcnQgZnVuY3Rpb24gKiBuZXdDaGFubmVsUmVxdWVzdCAoYWN0aW9uKSB7XG4gIGNvbnN0IHsgcmVxdWVzdFR5cGUsIHJlcXVlc3RJZCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCB9ID0gYWN0aW9uLmRhdGE7XG4gIC8vIHB1dCBhbiBhY3Rpb24gdG8gdXBkYXRlIHRoZSByZXF1ZXN0IGluIHJlZHV4XG4gIHlpZWxkIHB1dChvblJlcXVlc3RVcGRhdGUocmVxdWVzdFR5cGUsIHJlcXVlc3RJZCkpO1xuICAvLyBpcyB0aGlzIGFuIGV4aXN0aW5nIHJlcXVlc3Q/XG4gIC8vIElmIHRoaXMgdXJpIGlzIGluIHRoZSByZXF1ZXN0IGxpc3QsIGl0J3MgYWxyZWFkeSBiZWVuIGZldGNoZWRcbiAgY29uc3Qgc3RhdGUgPSB5aWVsZCBzZWxlY3Qoc2VsZWN0U2hvd1N0YXRlKTtcbiAgaWYgKHN0YXRlLnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBnZXQgY2hhbm5lbCBsb25nIGlkXG4gIGxldCBsb25nSWQsIHNob3J0SWQ7XG4gIHRyeSB7XG4gICAgKHsgZGF0YToge2xvbmdDaGFubmVsQ2xhaW1JZDogbG9uZ0lkLCBzaG9ydENoYW5uZWxDbGFpbUlkOiBzaG9ydElkfSB9ID0geWllbGQgY2FsbChnZXRDaGFubmVsRGF0YSwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIHN0b3JlIHRoZSByZXF1ZXN0IGluIHRoZSBjaGFubmVsIHJlcXVlc3RzIGxpc3RcbiAgY29uc3QgY2hhbm5lbEtleSA9IGBjIyR7Y2hhbm5lbE5hbWV9IyR7bG9uZ0lkfWA7XG4gIHlpZWxkIHB1dChhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdChyZXF1ZXN0SWQsIG51bGwsIGNoYW5uZWxLZXkpKTtcbiAgLy8gaXMgdGhpcyBhbiBleGlzdGluZyBjaGFubmVsP1xuICAvLyBJZiB0aGlzIGNoYW5uZWwgaXMgaW4gdGhlIGNoYW5uZWwgbGlzdCwgaXQncyBhbHJlYWR5IGJlZW4gZmV0Y2hlZFxuICBpZiAoc3RhdGUuY2hhbm5lbExpc3RbY2hhbm5lbEtleV0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBnZXQgY2hhbm5lbCBjbGFpbXMgZGF0YVxuICBsZXQgY2xhaW1zRGF0YTtcbiAgdHJ5IHtcbiAgICAoeyBkYXRhOiBjbGFpbXNEYXRhIH0gPSB5aWVsZCBjYWxsKGdldENoYW5uZWxDbGFpbXMsIGNoYW5uZWxOYW1lLCBsb25nSWQsIDEpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyBzdG9yZSB0aGUgY2hhbm5lbCBkYXRhIGluIHRoZSBjaGFubmVsIGxpc3RcbiAgeWllbGQgcHV0KGFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0KGNoYW5uZWxLZXksIGNoYW5uZWxOYW1lLCBzaG9ydElkLCBsb25nSWQsIGNsYWltc0RhdGEpKTtcbiAgLy8gY2xlYXIgYW55IHJlcXVlc3QgZXJyb3JzXG4gIHlpZWxkIHB1dChvblJlcXVlc3RFcnJvcihudWxsKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoTmV3Q2hhbm5lbFJlcXVlc3QgKCkge1xuICB5aWVsZCB0YWtlTGF0ZXN0KGFjdGlvbnMuQ0hBTk5FTF9SRVFVRVNUX05FVywgbmV3Q2hhbm5lbFJlcXVlc3QpO1xufTtcblxuZnVuY3Rpb24gKiBnZXROZXdDbGFpbXNBbmRVcGRhdGVDaGFubmVsIChhY3Rpb24pIHtcbiAgY29uc3QgeyBjaGFubmVsS2V5LCBuYW1lLCBsb25nSWQsIHBhZ2UgfSA9IGFjdGlvbi5kYXRhO1xuICBsZXQgY2xhaW1zRGF0YTtcbiAgdHJ5IHtcbiAgICAoeyBkYXRhOiBjbGFpbXNEYXRhIH0gPSB5aWVsZCBjYWxsKGdldENoYW5uZWxDbGFpbXMsIG5hbWUsIGxvbmdJZCwgcGFnZSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIHlpZWxkIHB1dCh1cGRhdGVDaGFubmVsQ2xhaW1zKGNoYW5uZWxLZXksIGNsYWltc0RhdGEpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uICogd2F0Y2hVcGRhdGVDaGFubmVsQ2xhaW1zICgpIHtcbiAgeWllbGQgdGFrZUxhdGVzdChhY3Rpb25zLkNIQU5ORUxfQ0xBSU1TX1VQREFURV9BU1lOQywgZ2V0TmV3Q2xhaW1zQW5kVXBkYXRlQ2hhbm5lbCk7XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC9zYWdhcy9zaG93X2NoYW5uZWwuanMiLCJpbXBvcnQgUmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcbmNvbnN0IHsgc2l0ZTogeyBob3N0IH0gfSA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9zcGVlY2hDb25maWcuanMnKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYW5uZWxEYXRhIChuYW1lLCBpZCkge1xuICBpZiAoIWlkKSBpZCA9ICdub25lJztcbiAgY29uc3QgdXJsID0gYCR7aG9zdH0vYXBpL2NoYW5uZWwvZGF0YS8ke25hbWV9LyR7aWR9YDtcbiAgcmV0dXJuIFJlcXVlc3QodXJsKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGFubmVsQ2xhaW1zIChuYW1lLCBsb25nSWQsIHBhZ2UpIHtcbiAgaWYgKCFwYWdlKSBwYWdlID0gMTtcbiAgY29uc3QgdXJsID0gYCR7aG9zdH0vYXBpL2NoYW5uZWwvY2xhaW1zLyR7bmFtZX0vJHtsb25nSWR9LyR7cGFnZX1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3JlYWN0L2FwaS9jaGFubmVsQXBpLmpzIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIFJFR0VYUF9JTlZBTElEX0NMQUlNICA6IC9bXkEtWmEtejAtOS1dL2csXG4gIFJFR0VYUF9JTlZBTElEX0NIQU5ORUw6IC9bXkEtWmEtejAtOS1AXS9nLFxuICBSRUdFWFBfQUREUkVTUyAgICAgICAgOiAvXmIoPz1bXjBPSWxdezMyLDMzfSlbMC05QS1aYS16XXszMiwzM30kLyxcbiAgQ0hBTk5FTF9DSEFSICAgICAgICAgIDogJ0AnLFxuICBwYXJzZUlkZW50aWZpZXIgICAgICAgOiBmdW5jdGlvbiAoaWRlbnRpZmllcikge1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjL10qKScgKyAvLyB2YWx1ZSAoc3RvcHMgYXQgdGhlIGZpcnN0IHNlcGFyYXRvciBvciBlbmQpXG4gICAgICAnKFs6JCNdPykoW14vXSopJyAvLyBtb2RpZmllciBzZXBhcmF0b3IsIG1vZGlmaWVyIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCB2YWx1ZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleCAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgLmV4ZWMoaWRlbnRpZmllcilcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIFVSTC4gIE5vIGNoYW5uZWwgbmFtZSBwcm92aWRlZCBiZWZvcmUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IGlzQ2hhbm5lbCA9IHZhbHVlLnN0YXJ0c1dpdGgobW9kdWxlLmV4cG9ydHMuQ0hBTk5FTF9DSEFSKTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGlzQ2hhbm5lbCA/IHZhbHVlIDogbnVsbDtcbiAgICBsZXQgY2xhaW1JZDtcbiAgICBpZiAoaXNDaGFubmVsKSB7XG4gICAgICBpZiAoIWNoYW5uZWxOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2hlY2sgeW91ciBVUkwuICBObyBjaGFubmVsIG5hbWUgYWZ0ZXIgXCJAXCIuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2hhbm5lbE5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NIQU5ORUwpO1xuICAgICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgSW52YWxpZCBjaGFyYWN0ZXJzIGluIGNoYW5uZWwgbmFtZTogXCIke25hbWVCYWRDaGFycy5qb2luKCcsICcpfVwiLmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjbGFpbUlkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciBVUkwuICBObyBtb2RpZmllciBwcm92aWRlZCBhZnRlciBzZXBhcmF0b3IgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RpZmllclNlcGVyYXRvciA9PT0gJzonKSB7XG4gICAgICAgIGNoYW5uZWxDbGFpbUlkID0gbW9kaWZpZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgVGhlIFwiJHttb2RpZmllclNlcGVyYXRvcn1cIiBtb2RpZmllciBpcyBub3QgY3VycmVudGx5IHN1cHBvcnRlZGApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaXNDaGFubmVsLFxuICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICBjaGFubmVsQ2xhaW1JZDogY2hhbm5lbENsYWltSWQgfHwgbnVsbCxcbiAgICAgIGNsYWltSWQgICAgICAgOiBjbGFpbUlkIHx8IG51bGwsXG4gICAgfTtcbiAgfSxcbiAgcGFyc2VDbGFpbTogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBjb25zdCBjb21wb25lbnRzUmVnZXggPSBuZXcgUmVnRXhwKFxuICAgICAgJyhbXjokIy8uXSopJyArIC8vIG5hbWUgKHN0b3BzIGF0IHRoZSBmaXJzdCBleHRlbnNpb24pXG4gICAgICAnKFs6JCMuXT8pKFteL10qKScgLy8gZXh0ZW5zaW9uIHNlcGFyYXRvciwgZXh0ZW5zaW9uIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCBjbGFpbU5hbWUsIGV4dGVuc2lvblNlcGVyYXRvciwgZXh0ZW5zaW9uXSA9IGNvbXBvbmVudHNSZWdleCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICAuZXhlYyhuYW1lKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG5hbWVcbiAgICBpZiAoIWNsYWltTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGVjayB5b3VyIFVSTC4gIE5vIGNsYWltIG5hbWUgcHJvdmlkZWQgYmVmb3JlIFwiLlwiJyk7XG4gICAgfVxuICAgIGNvbnN0IG5hbWVCYWRDaGFycyA9IChjbGFpbU5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NMQUlNKTtcbiAgICBpZiAobmFtZUJhZENoYXJzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgSW52YWxpZCBjaGFyYWN0ZXJzIGluIGNsYWltIG5hbWU6IFwiJHtuYW1lQmFkQ2hhcnMuam9pbignLCAnKX1cIi5gKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgZXh0ZW5zaW9uXG4gICAgaWYgKGV4dGVuc2lvblNlcGVyYXRvcikge1xuICAgICAgaWYgKCFleHRlbnNpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIFVSTC4gIE5vIGZpbGUgZXh0ZW5zaW9uIHByb3ZpZGVkIGFmdGVyIHNlcGFyYXRvciBcIiR7ZXh0ZW5zaW9uU2VwZXJhdG9yfVwiLmApO1xuICAgICAgfVxuICAgICAgaWYgKGV4dGVuc2lvblNlcGVyYXRvciAhPT0gJy4nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciBVUkwuICBUaGUgXCIke2V4dGVuc2lvblNlcGVyYXRvcn1cIiBzZXBhcmF0b3IgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY2xhaW0gbmFtZS5gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYWltTmFtZSxcbiAgICAgIGV4dGVuc2lvbjogZXh0ZW5zaW9uIHx8IG51bGwsXG4gICAgfTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yZWFjdC91dGlscy9sYnJ5VXJpLmpzIiwiY29uc3QgaGFuZGxlUGFnZVJlbmRlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaGFuZGxlUGFnZVJlbmRlci5qc3gnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBhcHAgPT4ge1xuICAvLyBhIGNhdGNoLWFsbCByb3V0ZSBpZiBzb21lb25lIHZpc2l0cyBhIHBhZ2UgdGhhdCBkb2VzIG5vdCBleGlzdFxuICBhcHAudXNlKCcqJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgLy8gc2VuZCByZXNwb25zZVxuICAgIGhhbmRsZVBhZ2VSZW5kZXIocmVxLCByZXMpO1xuICB9KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9yb3V0ZXMvZmFsbGJhY2stcm91dGVzLmpzIl0sInNvdXJjZVJvb3QiOiIifQ==
|