diff --git a/.eslintignore b/.eslintignore index 07d60219..8254ff89 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ node_modules/ -public/ +public/bundle +index.js test diff --git a/.gitignore b/.gitignore index 2d5233ca..7bc3a273 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,12 @@ -node_modules -.idea -config/sequelizeCliConfig.js -config/speechConfig.js -public/bundle -server.js -webpack.config.js +node_modules/ +.idea/ +config/lbryConfig.js +config/loggerConfig.js +config/mysqlConfig.js +config/siteConfig.js +devConfig/slackConfig.js +devConfig/sequelizeCliConfig.js +devConfig/testingConfig.js + +public/bundle/ +index.js diff --git a/.sequelizerc b/.sequelizerc index f2daa0b6..757fef10 100644 --- a/.sequelizerc +++ b/.sequelizerc @@ -1,5 +1,5 @@ const path = require('path'); module.exports = { - 'config': path.resolve('config', 'sequelizeCliConfig.js'), -} \ No newline at end of file + 'config': path.resolve('devConfig', 'sequelizeCliConfig.js'), +} diff --git a/README.md b/README.md index f32e93d7..0898be0c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Spee.ch Spee.ch is a web app that reads and publishes images and videos to and from the [LBRY](https://lbry.io/) blockchain. -## How to run this repository locally +##Installation * start mysql * install mysql * create a database called `lbry` @@ -12,10 +12,13 @@ Spee.ch is a web app that reads and publishes images and videos to and from the * start spee.ch * clone this repo * run `npm install` - * create your `speechConfig.js` file - * copy `speechConfig.js.example` and name it `speechConfig.js` + * create your own config files in `/config` + * copy `example.js.example` and name it `example.js` * replace the `null` values in the config file with the appropriate values for your environment - * build the app by running `npm run build-prod` + * create your own config files in `/devConfig` + * copy `example.js.example` and name it `example.js` + * note: you must create these files, but the default values are sufficient if you do not want to update them. + * build the app by running `npm run build` * to start the server, run `npm run start` * visit [localhost:3000](http://localhost:3000) * start spee.ch-sync (optional, recommended) @@ -45,8 +48,8 @@ Spee.ch is a web app that reads and publishes images and videos to and from the * /api/claim/publish * example: `curl -F 'name=MyPictureName' -F 'file=@/path/to/myPicture.jpeg' https://spee.ch/api/claim/publish` * Parameters: - * `name` - * `file` (must be type .mp4, .jpeg, .jpg, .gif, or .png) + * `name` (required) + * `file` (required) (must be type .mp4, .jpeg, .jpg, .gif, or .png) * `nsfw` (optional) * `license` (optional) * `title` (optional) diff --git a/react/actions/channel.js b/client/actions/channel.js similarity index 100% rename from react/actions/channel.js rename to client/actions/channel.js diff --git a/react/actions/publish.js b/client/actions/publish.js similarity index 100% rename from react/actions/publish.js rename to client/actions/publish.js diff --git a/react/actions/show.js b/client/actions/show.js similarity index 100% rename from react/actions/show.js rename to client/actions/show.js diff --git a/react/api/assetApi.js b/client/api/assetApi.js similarity index 78% rename from react/api/assetApi.js rename to client/api/assetApi.js index 7ea0012a..b6389612 100644 --- a/react/api/assetApi.js +++ b/client/api/assetApi.js @@ -1,7 +1,6 @@ import Request from 'utils/request'; -const { site: { host } } = require('../../config/speechConfig.js'); -export function getLongClaimId (name, modifier) { +export function getLongClaimId (host, name, modifier) { let body = {}; // create request params if (modifier) { @@ -24,12 +23,12 @@ export function getLongClaimId (name, modifier) { return Request(url, params); }; -export function getShortId (name, claimId) { +export function getShortId (host, name, claimId) { const url = `${host}/api/claim/short-id/${claimId}/${name}`; return Request(url); }; -export function getClaimData (name, claimId) { +export function getClaimData (host, name, claimId) { const url = `${host}/api/claim/data/${name}/${claimId}`; return Request(url); }; diff --git a/react/api/channelApi.js b/client/api/channelApi.js similarity index 61% rename from react/api/channelApi.js rename to client/api/channelApi.js index e582c7fe..cf5738fc 100644 --- a/react/api/channelApi.js +++ b/client/api/channelApi.js @@ -1,13 +1,12 @@ import Request from 'utils/request'; -const { site: { host } } = require('../../config/speechConfig.js'); -export function getChannelData (name, id) { +export function getChannelData (host, id, name) { if (!id) id = 'none'; const url = `${host}/api/channel/data/${name}/${id}`; return Request(url); }; -export function getChannelClaims (name, longId, page) { +export function getChannelClaims (host, longId, name, page) { if (!page) page = 1; const url = `${host}/api/channel/claims/${name}/${longId}/${page}`; return Request(url); diff --git a/react/api/fileApi.js b/client/api/fileApi.js similarity index 55% rename from react/api/fileApi.js rename to client/api/fileApi.js index 64ff1ad9..62c71b78 100644 --- a/react/api/fileApi.js +++ b/client/api/fileApi.js @@ -1,12 +1,11 @@ import Request from 'utils/request'; -const { site: { host } } = require('../../config/speechConfig.js'); -export function checkFileAvailability (name, claimId) { +export function checkFileAvailability (claimId, host, name) { const url = `${host}/api/file/availability/${name}/${claimId}`; return Request(url); } -export function triggerClaimGet (name, claimId) { +export function triggerClaimGet (claimId, host, name) { const url = `${host}/api/claim/get/${name}/${claimId}`; return Request(url); } diff --git a/react/app.js b/client/app.jsx similarity index 66% rename from react/app.js rename to client/app.jsx index 8c8e00ff..8d78b17a 100644 --- a/react/app.js +++ b/client/app.jsx @@ -1,10 +1,10 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; -import HomePage from 'components/HomePage'; -import AboutPage from 'components/AboutPage'; -import LoginPage from 'containers/LoginPage'; -import ShowPage from 'containers/ShowPage'; -import FourOhFourPage from 'components/FourOhFourPage'; +import HomePage from 'pages/HomePage'; // or use the provided local homepage +import AboutPage from 'pages/AboutPage'; +import LoginPage from 'pages/LoginPage'; +import ShowPage from 'pages/ShowPage'; +import FourOhFourPage from 'containers/FourOhFourPage'; const App = () => { return ( diff --git a/react/channels/publish.js b/client/channels/publish.js similarity index 100% rename from react/channels/publish.js rename to client/channels/publish.js diff --git a/react/client.js b/client/client.js similarity index 100% rename from react/client.js rename to client/client.js diff --git a/react/components/ActiveStatusBar/index.jsx b/client/components/ActiveStatusBar/index.jsx similarity index 100% rename from react/components/ActiveStatusBar/index.jsx rename to client/components/ActiveStatusBar/index.jsx diff --git a/client/components/AssetPreview/index.js b/client/components/AssetPreview/index.js new file mode 100644 index 00000000..e431b9bd --- /dev/null +++ b/client/components/AssetPreview/index.js @@ -0,0 +1,10 @@ +import { connect } from 'react-redux'; +import View from './view'; + +const mapStateToProps = ({site: {defaults: { defaultThumbnail }}}) => { + return { + defaultThumbnail, + }; +}; + +export default connect(mapStateToProps, null)(View); diff --git a/react/components/AssetPreview/index.jsx b/client/components/AssetPreview/view.jsx similarity index 85% rename from react/components/AssetPreview/index.jsx rename to client/components/AssetPreview/view.jsx index 4963056e..d98a1f4c 100644 --- a/react/components/AssetPreview/index.jsx +++ b/client/components/AssetPreview/view.jsx @@ -1,8 +1,7 @@ import React from 'react'; import { Link } from 'react-router-dom'; -const { claim: { defaultThumbnail } } = require('../../../config/speechConfig.js'); -const AssetPreview = ({ claimData: { name, claimId, fileExt, contentType, thumbnail } }) => { +const AssetPreview = ({ defaultThumbnail, claimData: { name, claimId, fileExt, contentType, thumbnail } }) => { const directSourceLink = `${claimId}/${name}.${fileExt}`; const showUrlLink = `/${claimId}/${name}`; return ( diff --git a/react/components/ExpandingTextArea/index.jsx b/client/components/ExpandingTextArea/index.jsx similarity index 100% rename from react/components/ExpandingTextArea/index.jsx rename to client/components/ExpandingTextArea/index.jsx diff --git a/react/components/GAListener/index.jsx b/client/components/GAListener/index.jsx similarity index 77% rename from react/components/GAListener/index.jsx rename to client/components/GAListener/index.jsx index f388e2a0..5f5fffd5 100644 --- a/react/components/GAListener/index.jsx +++ b/client/components/GAListener/index.jsx @@ -1,10 +1,9 @@ import React from 'react'; import GoogleAnalytics from 'react-ga'; import { withRouter } from 'react-router-dom'; -const config = require('../../../config/speechConfig.js'); -const googleApiKey = config.analytics.googleId; +const { analytics: { googleId } } = require('../../../config/siteConfig.js'); -GoogleAnalytics.initialize(googleApiKey); +GoogleAnalytics.initialize(googleId); class GAListener extends React.Component { componentDidMount () { diff --git a/react/components/InactiveStatusBar/index.jsx b/client/components/InactiveStatusBar/index.jsx similarity index 100% rename from react/components/InactiveStatusBar/index.jsx rename to client/components/InactiveStatusBar/index.jsx diff --git a/react/components/Logo/index.jsx b/client/components/Logo/index.jsx similarity index 100% rename from react/components/Logo/index.jsx rename to client/components/Logo/index.jsx diff --git a/react/components/NavBarChannelOptionsDropdown/index.jsx b/client/components/NavBarChannelOptionsDropdown/index.jsx similarity index 100% rename from react/components/NavBarChannelOptionsDropdown/index.jsx rename to client/components/NavBarChannelOptionsDropdown/index.jsx diff --git a/react/components/ProgressBar/index.jsx b/client/components/ProgressBar/index.jsx similarity index 100% rename from react/components/ProgressBar/index.jsx rename to client/components/ProgressBar/index.jsx diff --git a/react/components/Preview/index.jsx b/client/components/PublishPreview/index.jsx similarity index 93% rename from react/components/Preview/index.jsx rename to client/components/PublishPreview/index.jsx index e8c3b2f7..3699ba4e 100644 --- a/react/components/Preview/index.jsx +++ b/client/components/PublishPreview/index.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -class Preview extends React.Component { +class PublishPreview extends React.Component { constructor (props) { super(props); this.state = { @@ -53,10 +53,10 @@ class Preview extends React.Component { } }; -Preview.propTypes = { +PublishPreview.propTypes = { dimPreview: PropTypes.bool.isRequired, file : PropTypes.object.isRequired, thumbnail : PropTypes.object, }; -export default Preview; +export default PublishPreview; diff --git a/react/components/PublishUrlMiddleDisplay/index.jsx b/client/components/PublishUrlMiddleDisplay/index.jsx similarity index 100% rename from react/components/PublishUrlMiddleDisplay/index.jsx rename to client/components/PublishUrlMiddleDisplay/index.jsx diff --git a/client/components/SEO/index.js b/client/components/SEO/index.js new file mode 100644 index 00000000..8a004ff6 --- /dev/null +++ b/client/components/SEO/index.js @@ -0,0 +1,16 @@ +import { connect } from 'react-redux'; +import View from './view'; + +const mapStateToProps = ({ site }) => { + const { defaultDescription, defaultThumbnail, description: siteDescription, host: siteHost, title: siteTitle, twitter: siteTwitter } = site; + return { + defaultDescription, + defaultThumbnail, + siteDescription, + siteHost, + siteTitle, + siteTwitter, + }; +}; + +export default connect(mapStateToProps, null)(View); diff --git a/react/components/SEO/index.jsx b/client/components/SEO/view.jsx similarity index 56% rename from react/components/SEO/index.jsx rename to client/components/SEO/view.jsx index 555777d6..7d476367 100644 --- a/react/components/SEO/index.jsx +++ b/client/components/SEO/view.jsx @@ -8,10 +8,16 @@ import { createCanonicalLink } from 'utils/canonicalLink'; class SEO extends React.Component { render () { - let { pageTitle, asset, channel, pageUri } = this.props; - pageTitle = createPageTitle(pageTitle); - const metaTags = createMetaTags(asset, channel); - const canonicalLink = createCanonicalLink(asset, channel, pageUri); + // props from state + const { defaultDescription, defaultThumbnail, siteDescription, siteHost, siteTitle, siteTwitter } = this.props; + // props from parent + const { asset, channel, pageUri } = this.props; + let { pageTitle } = this.props; + // create page title, tags, and canonical link + pageTitle = createPageTitle(siteTitle, pageTitle); + const metaTags = createMetaTags(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail); + const canonicalLink = createCanonicalLink(asset, channel, pageUri, siteHost); + // render results return ( {this.props.file ? (
- { + return { + host, + title, + }; +}; + +export default connect(mapStateToProps, null)(View); diff --git a/react/components/FourOhFourPage/index.jsx b/client/containers/FourOhFourPage/view.jsx similarity index 86% rename from react/components/FourOhFourPage/index.jsx rename to client/containers/FourOhFourPage/view.jsx index 0c2a3c12..71898ea2 100644 --- a/react/components/FourOhFourPage/index.jsx +++ b/client/containers/FourOhFourPage/view.jsx @@ -1,10 +1,10 @@ import React from 'react'; import NavBar from 'containers/NavBar'; import Helmet from 'react-helmet'; -const { site: { title, host } } = require('../../../config/speechConfig.js'); class FourOhForPage extends React.Component { render () { + const {title, host} = this.props; return (
diff --git a/react/containers/NavBar/index.js b/client/containers/NavBar/index.js similarity index 82% rename from react/containers/NavBar/index.js rename to client/containers/NavBar/index.js index 80689d97..b53eba49 100644 --- a/react/containers/NavBar/index.js +++ b/client/containers/NavBar/index.js @@ -1,13 +1,14 @@ import { connect } from 'react-redux'; import { updateLoggedInChannel } from 'actions/channel'; +import {updateSelectedChannel} from 'actions/publish'; import View from './view'; -import {updateSelectedChannel} from '../../actions/publish'; -const mapStateToProps = ({ channel }) => { +const mapStateToProps = ({ channel, site }) => { return { channelName : channel.loggedInChannel.name, channelShortId: channel.loggedInChannel.shortId, channelLongId : channel.loggedInChannel.longId, + siteDescription: site.description, }; }; diff --git a/react/containers/NavBar/view.jsx b/client/containers/NavBar/view.jsx similarity index 95% rename from react/containers/NavBar/view.jsx rename to client/containers/NavBar/view.jsx index f7339019..816e461c 100644 --- a/react/containers/NavBar/view.jsx +++ b/client/containers/NavBar/view.jsx @@ -53,12 +53,13 @@ class NavBar extends React.Component { } } render () { + const { siteDescription } = this.props; return (
- Open-source, decentralized image and video sharing. + {siteDescription}
Publish diff --git a/react/containers/PublishDetails/index.js b/client/containers/PublishDetails/index.js similarity index 100% rename from react/containers/PublishDetails/index.js rename to client/containers/PublishDetails/index.js diff --git a/react/containers/PublishDetails/view.jsx b/client/containers/PublishDetails/view.jsx similarity index 100% rename from react/containers/PublishDetails/view.jsx rename to client/containers/PublishDetails/view.jsx diff --git a/client/containers/PublishDisabledMessage/index.js b/client/containers/PublishDisabledMessage/index.js new file mode 100644 index 00000000..76cab861 --- /dev/null +++ b/client/containers/PublishDisabledMessage/index.js @@ -0,0 +1,10 @@ +import {connect} from 'react-redux'; +import View from './view'; + +const mapStateToProps = ({ publish }) => { + return { + message: publish.disabledMessage, + }; +}; + +export default connect(mapStateToProps, null)(View); diff --git a/client/containers/PublishDisabledMessage/view.jsx b/client/containers/PublishDisabledMessage/view.jsx new file mode 100644 index 00000000..af03f370 --- /dev/null +++ b/client/containers/PublishDisabledMessage/view.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +class PublishDisabledMessage extends React.Component { + render () { + const message = this.props.message; + console.log('this.props.message:', message); + return ( +
+

Publishing is currently disabled.

+

{message}

+
+ ); + } +} + +export default PublishDisabledMessage; diff --git a/react/containers/PublishMetadataInputs/index.js b/client/containers/PublishMetadataInputs/index.js similarity index 100% rename from react/containers/PublishMetadataInputs/index.js rename to client/containers/PublishMetadataInputs/index.js diff --git a/react/containers/PublishMetadataInputs/view.jsx b/client/containers/PublishMetadataInputs/view.jsx similarity index 100% rename from react/containers/PublishMetadataInputs/view.jsx rename to client/containers/PublishMetadataInputs/view.jsx diff --git a/react/containers/PublishStatus/index.js b/client/containers/PublishStatus/index.js similarity index 100% rename from react/containers/PublishStatus/index.js rename to client/containers/PublishStatus/index.js diff --git a/react/containers/PublishStatus/view.jsx b/client/containers/PublishStatus/view.jsx similarity index 100% rename from react/containers/PublishStatus/view.jsx rename to client/containers/PublishStatus/view.jsx diff --git a/react/containers/PublishThumbnailInput/index.js b/client/containers/PublishThumbnailInput/index.js similarity index 100% rename from react/containers/PublishThumbnailInput/index.js rename to client/containers/PublishThumbnailInput/index.js diff --git a/react/containers/PublishThumbnailInput/view.jsx b/client/containers/PublishThumbnailInput/view.jsx similarity index 100% rename from react/containers/PublishThumbnailInput/view.jsx rename to client/containers/PublishThumbnailInput/view.jsx diff --git a/react/containers/PublishTitleInput/index.js b/client/containers/PublishTitleInput/index.js similarity index 100% rename from react/containers/PublishTitleInput/index.js rename to client/containers/PublishTitleInput/index.js diff --git a/react/containers/PublishTitleInput/view.jsx b/client/containers/PublishTitleInput/view.jsx similarity index 100% rename from react/containers/PublishTitleInput/view.jsx rename to client/containers/PublishTitleInput/view.jsx diff --git a/react/containers/PublishTool/index.js b/client/containers/PublishTool/index.js similarity index 100% rename from react/containers/PublishTool/index.js rename to client/containers/PublishTool/index.js diff --git a/client/containers/PublishTool/view.jsx b/client/containers/PublishTool/view.jsx new file mode 100644 index 00000000..add1dcf6 --- /dev/null +++ b/client/containers/PublishTool/view.jsx @@ -0,0 +1,30 @@ +import React from 'react'; +import Dropzone from 'containers/Dropzone'; +import PublishDetails from 'containers/PublishDetails'; +import PublishStatus from 'containers/PublishStatus'; +import PublishDisabledMessage from 'containers/PublishDisabledMessage'; + +class PublishTool extends React.Component { + render () { + if (this.props.disabled) { + console.log('publish is disabled'); + return ( + + ); + } else { + console.log('publish is not disabled'); + if (this.props.file) { + if (this.props.status) { + return ( + + ); + } else { + return ; + } + } + return ; + } + } +}; + +export default PublishTool; diff --git a/react/containers/PublishUrlInput/index.js b/client/containers/PublishUrlInput/index.js similarity index 100% rename from react/containers/PublishUrlInput/index.js rename to client/containers/PublishUrlInput/index.js diff --git a/react/containers/PublishUrlInput/view.jsx b/client/containers/PublishUrlInput/view.jsx similarity index 100% rename from react/containers/PublishUrlInput/view.jsx rename to client/containers/PublishUrlInput/view.jsx diff --git a/react/containers/ShowAssetDetails/index.js b/client/containers/ShowAssetDetails/index.js similarity index 100% rename from react/containers/ShowAssetDetails/index.js rename to client/containers/ShowAssetDetails/index.js diff --git a/react/containers/ShowAssetDetails/view.jsx b/client/containers/ShowAssetDetails/view.jsx similarity index 96% rename from react/containers/ShowAssetDetails/view.jsx rename to client/containers/ShowAssetDetails/view.jsx index 8fd3ae53..dc90b300 100644 --- a/react/containers/ShowAssetDetails/view.jsx +++ b/client/containers/ShowAssetDetails/view.jsx @@ -1,7 +1,7 @@ import React from 'react'; import SEO from 'components/SEO'; import NavBar from 'containers/NavBar'; -import ErrorPage from 'components/ErrorPage'; +import ErrorPage from 'pages/ErrorPage'; import AssetTitle from 'containers/AssetTitle'; import AssetDisplay from 'containers/AssetDisplay'; import AssetInfo from 'containers/AssetInfo'; diff --git a/react/containers/ShowAssetLite/index.js b/client/containers/ShowAssetLite/index.js similarity index 100% rename from react/containers/ShowAssetLite/index.js rename to client/containers/ShowAssetLite/index.js diff --git a/react/containers/ShowAssetLite/view.jsx b/client/containers/ShowAssetLite/view.jsx similarity index 100% rename from react/containers/ShowAssetLite/view.jsx rename to client/containers/ShowAssetLite/view.jsx diff --git a/react/containers/ShowChannel/index.js b/client/containers/ShowChannel/index.js similarity index 100% rename from react/containers/ShowChannel/index.js rename to client/containers/ShowChannel/index.js diff --git a/react/containers/ShowChannel/view.jsx b/client/containers/ShowChannel/view.jsx similarity index 95% rename from react/containers/ShowChannel/view.jsx rename to client/containers/ShowChannel/view.jsx index 842a6953..d4399382 100644 --- a/react/containers/ShowChannel/view.jsx +++ b/client/containers/ShowChannel/view.jsx @@ -1,6 +1,6 @@ import React from 'react'; import SEO from 'components/SEO'; -import ErrorPage from 'components/ErrorPage'; +import ErrorPage from 'pages/ErrorPage'; import NavBar from 'containers/NavBar'; import ChannelClaimsDisplay from 'containers/ChannelClaimsDisplay'; diff --git a/react/components/AboutPage/index.jsx b/client/pages/AboutPage/index.jsx similarity index 100% rename from react/components/AboutPage/index.jsx rename to client/pages/AboutPage/index.jsx diff --git a/react/components/ErrorPage/index.jsx b/client/pages/ErrorPage/index.jsx similarity index 100% rename from react/components/ErrorPage/index.jsx rename to client/pages/ErrorPage/index.jsx diff --git a/react/components/HomePage/index.jsx b/client/pages/HomePage/index.jsx similarity index 100% rename from react/components/HomePage/index.jsx rename to client/pages/HomePage/index.jsx diff --git a/react/containers/LoginPage/index.js b/client/pages/LoginPage/index.js similarity index 100% rename from react/containers/LoginPage/index.js rename to client/pages/LoginPage/index.js diff --git a/react/containers/LoginPage/view.jsx b/client/pages/LoginPage/view.jsx similarity index 100% rename from react/containers/LoginPage/view.jsx rename to client/pages/LoginPage/view.jsx diff --git a/react/containers/ShowPage/index.js b/client/pages/ShowPage/index.js similarity index 100% rename from react/containers/ShowPage/index.js rename to client/pages/ShowPage/index.js diff --git a/react/containers/ShowPage/view.jsx b/client/pages/ShowPage/view.jsx similarity index 95% rename from react/containers/ShowPage/view.jsx rename to client/pages/ShowPage/view.jsx index 8e579c02..ee210445 100644 --- a/react/containers/ShowPage/view.jsx +++ b/client/pages/ShowPage/view.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import ErrorPage from 'components/ErrorPage'; +import ErrorPage from 'pages/ErrorPage'; import ShowAssetLite from 'containers/ShowAssetLite'; import ShowAssetDetails from 'containers/ShowAssetDetails'; import ShowChannel from 'containers/ShowChannel'; diff --git a/react/reducers/channel.js b/client/reducers/channel.js similarity index 100% rename from react/reducers/channel.js rename to client/reducers/channel.js diff --git a/react/reducers/index.js b/client/reducers/index.js similarity index 100% rename from react/reducers/index.js rename to client/reducers/index.js diff --git a/react/reducers/publish.js b/client/reducers/publish.js similarity index 89% rename from react/reducers/publish.js rename to client/reducers/publish.js index b1bffad5..fbb7023b 100644 --- a/react/reducers/publish.js +++ b/client/reducers/publish.js @@ -1,9 +1,10 @@ import * as actions from 'constants/publish_action_types'; import { LOGIN } from 'constants/publish_channel_select_states'; -const { publish } = require('../../config/speechConfig.js'); +const { publishing } = require('../../config/siteConfig.js'); const initialState = { - disabled : publish.disabled, + disabled : publishing.disabled, + disabledMessage : publishing.disabledMessage, publishInChannel : false, selectedChannel : LOGIN, showMetadataInputs: false, @@ -25,9 +26,7 @@ const initialState = { license : '', nsfw : false, }, - thumbnailChannel : publish.thumbnailChannel, - thumbnailChannelId: publish.thumbnailChannelId, - thumbnail : null, + thumbnail: null, }; export default function (state = initialState, action) { diff --git a/react/reducers/show.js b/client/reducers/show.js similarity index 100% rename from react/reducers/show.js rename to client/reducers/show.js diff --git a/client/reducers/site.js b/client/reducers/site.js new file mode 100644 index 00000000..5533df72 --- /dev/null +++ b/client/reducers/site.js @@ -0,0 +1,34 @@ +const siteConfig = require('../../config/siteConfig.js'); + +const { + analytics: { + googleId: googleAnalyticsId, + }, + assetDefaults: { + thumbnail: defaultThumbnail, + description: defaultDescription, + }, + details: { + description, + host, + title, + twitter, + }, +} = siteConfig; + +const initialState = { + description, + googleAnalyticsId, + host, + title, + twitter, + defaultDescription, + defaultThumbnail, +}; + +export default function (state = initialState, action) { + switch (action.type) { + default: + return state; + } +} diff --git a/react/sagas/file.js b/client/sagas/file.js similarity index 76% rename from react/sagas/file.js rename to client/sagas/file.js index c1e71ae4..fe096473 100644 --- a/react/sagas/file.js +++ b/client/sagas/file.js @@ -1,16 +1,18 @@ -import { call, put, takeLatest } from 'redux-saga/effects'; +import {call, put, select, takeLatest} from 'redux-saga/effects'; import * as actions from 'constants/show_action_types'; import { updateFileAvailability, updateDisplayAssetError } from 'actions/show'; import { UNAVAILABLE, AVAILABLE } from 'constants/asset_display_states'; import { checkFileAvailability, triggerClaimGet } from 'api/fileApi'; +import { selectSiteHost } from 'selectors/site'; function * retrieveFile (action) { const name = action.data.name; const claimId = action.data.claimId; + const host = yield select(selectSiteHost); // see if the file is available let isAvailable; try { - ({ data: isAvailable } = yield call(checkFileAvailability, name, claimId)); + ({ data: isAvailable } = yield call(checkFileAvailability, claimId, host, name)); } catch (error) { return yield put(updateDisplayAssetError(error.message)); }; @@ -21,7 +23,7 @@ function * retrieveFile (action) { yield put(updateFileAvailability(UNAVAILABLE)); // initiate get request for the file try { - yield call(triggerClaimGet, name, claimId); + yield call(triggerClaimGet, claimId, host, name); } catch (error) { return yield put(updateDisplayAssetError(error.message)); }; diff --git a/react/sagas/index.js b/client/sagas/index.js similarity index 100% rename from react/sagas/index.js rename to client/sagas/index.js diff --git a/react/sagas/publish.js b/client/sagas/publish.js similarity index 100% rename from react/sagas/publish.js rename to client/sagas/publish.js diff --git a/react/sagas/show_asset.js b/client/sagas/show_asset.js similarity index 84% rename from react/sagas/show_asset.js rename to client/sagas/show_asset.js index 331959d1..dd4fb7ce 100644 --- a/react/sagas/show_asset.js +++ b/client/sagas/show_asset.js @@ -3,6 +3,7 @@ import * as actions from 'constants/show_action_types'; import { addRequestToRequestList, onRequestError, onRequestUpdate, addAssetToAssetList } from 'actions/show'; import { getLongClaimId, getShortId, getClaimData } from 'api/assetApi'; import { selectShowState } from 'selectors/show'; +import { selectSiteHost } from 'selectors/site'; export function * newAssetRequest (action) { const { requestType, requestId, name, modifier } = action.data; @@ -11,13 +12,14 @@ export function * newAssetRequest (action) { // is this an existing request? // If this uri is in the request list, it's already been fetched const state = yield select(selectShowState); + const host = yield select(selectSiteHost); if (state.requestList[requestId]) { return null; } // get long id && add request to request list let longId; try { - ({data: longId} = yield call(getLongClaimId, name, modifier)); + ({data: longId} = yield call(getLongClaimId, host, name, modifier)); } catch (error) { return yield put(onRequestError(error.message)); } @@ -31,14 +33,14 @@ export function * newAssetRequest (action) { // get short Id let shortId; try { - ({data: shortId} = yield call(getShortId, name, longId)); + ({data: shortId} = yield call(getShortId, host, name, longId)); } catch (error) { return yield put(onRequestError(error.message)); } // get asset claim data let claimData; try { - ({data: claimData} = yield call(getClaimData, name, longId)); + ({data: claimData} = yield call(getClaimData, host, name, longId)); } catch (error) { return yield put(onRequestError(error.message)); } diff --git a/react/sagas/show_channel.js b/client/sagas/show_channel.js similarity index 85% rename from react/sagas/show_channel.js rename to client/sagas/show_channel.js index a2cb20a2..1e4428a2 100644 --- a/react/sagas/show_channel.js +++ b/client/sagas/show_channel.js @@ -3,6 +3,7 @@ import * as actions from 'constants/show_action_types'; import { addNewChannelToChannelList, addRequestToRequestList, onRequestError, onRequestUpdate, updateChannelClaims } from 'actions/show'; import { getChannelClaims, getChannelData } from 'api/channelApi'; import { selectShowState } from 'selectors/show'; +import { selectSiteHost } from 'selectors/site'; export function * newChannelRequest (action) { const { requestType, requestId, channelName, channelId } = action.data; @@ -11,13 +12,14 @@ export function * newChannelRequest (action) { // is this an existing request? // If this uri is in the request list, it's already been fetched const state = yield select(selectShowState); + const host = yield select(selectSiteHost); if (state.requestList[requestId]) { return null; } // get channel long id let longId, shortId; try { - ({ data: {longChannelClaimId: longId, shortChannelClaimId: shortId} } = yield call(getChannelData, channelName, channelId)); + ({ data: {longChannelClaimId: longId, shortChannelClaimId: shortId} } = yield call(getChannelData, host, channelName, channelId)); } catch (error) { return yield put(onRequestError(error.message)); } @@ -32,7 +34,7 @@ export function * newChannelRequest (action) { // get channel claims data let claimsData; try { - ({ data: claimsData } = yield call(getChannelClaims, channelName, longId, 1)); + ({ data: claimsData } = yield call(getChannelClaims, host, longId, channelName, 1)); } catch (error) { return yield put(onRequestError(error.message)); } @@ -48,9 +50,10 @@ export function * watchNewChannelRequest () { function * getNewClaimsAndUpdateChannel (action) { const { channelKey, name, longId, page } = action.data; + const host = yield select(selectSiteHost); let claimsData; try { - ({ data: claimsData } = yield call(getChannelClaims, name, longId, page)); + ({ data: claimsData } = yield call(getChannelClaims, host, longId, name, page)); } catch (error) { return yield put(onRequestError(error.message)); } diff --git a/react/sagas/show_uri.js b/client/sagas/show_uri.js similarity index 100% rename from react/sagas/show_uri.js rename to client/sagas/show_uri.js diff --git a/react/selectors/channel.js b/client/selectors/channel.js similarity index 100% rename from react/selectors/channel.js rename to client/selectors/channel.js diff --git a/react/selectors/publish.js b/client/selectors/publish.js similarity index 100% rename from react/selectors/publish.js rename to client/selectors/publish.js diff --git a/react/selectors/show.js b/client/selectors/show.js similarity index 100% rename from react/selectors/show.js rename to client/selectors/show.js diff --git a/client/selectors/site.js b/client/selectors/site.js new file mode 100644 index 00000000..e89eb8f9 --- /dev/null +++ b/client/selectors/site.js @@ -0,0 +1,7 @@ +export const selectSiteState = (state) => { + return state.site; +}; + +export const selectSiteHost = (state) => { + return state.site.host; +}; diff --git a/client/utils/canonicalLink.js b/client/utils/canonicalLink.js new file mode 100644 index 00000000..3866b16f --- /dev/null +++ b/client/utils/canonicalLink.js @@ -0,0 +1,29 @@ +const createBasicCanonicalLink = (page, siteHost) => { + return `${siteHost}/${page}`; +}; + +const createAssetCanonicalLink = (asset, siteHost) => { + let channelName, certificateId, name, claimId; + if (asset.claimData) { + ({ channelName, certificateId, name, claimId } = asset.claimData); + }; + if (channelName) { + return `${siteHost}/${channelName}:${certificateId}/${name}`; + }; + return `${siteHost}/${claimId}/${name}`; +}; + +const createChannelCanonicalLink = (channel, siteHost) => { + const { name, longId } = channel; + return `${siteHost}/${name}:${longId}`; +}; + +export const createCanonicalLink = (asset, channel, page, siteHost) => { + if (asset) { + return createAssetCanonicalLink(asset, siteHost); + } + if (channel) { + return createChannelCanonicalLink(channel, siteHost); + } + return createBasicCanonicalLink(page, siteHost); +}; diff --git a/react/utils/file.js b/client/utils/file.js similarity index 100% rename from react/utils/file.js rename to client/utils/file.js diff --git a/react/utils/lbryUri.js b/client/utils/lbryUri.js similarity index 100% rename from react/utils/lbryUri.js rename to client/utils/lbryUri.js diff --git a/react/utils/metaTags.js b/client/utils/metaTags.js similarity index 63% rename from react/utils/metaTags.js rename to client/utils/metaTags.js index ec9237d1..215b8253 100644 --- a/react/utils/metaTags.js +++ b/client/utils/metaTags.js @@ -1,5 +1,3 @@ -const { site: { title, host, description }, claim: { defaultThumbnail, defaultDescription } } = require('../../config/speechConfig.js'); - const determineOgThumbnailContentType = (thumbnail) => { if (thumbnail) { const fileExt = thumbnail.substring(thumbnail.lastIndexOf('.')); @@ -20,35 +18,35 @@ const determineOgThumbnailContentType = (thumbnail) => { return ''; }; -const createBasicMetaTags = () => { +const createBasicMetaTags = (siteHost, siteDescription, siteTitle, siteTwitter) => { 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: 'og:title', content: siteTitle}, + {property: 'og:url', content: siteHost}, + {property: 'og:site_name', content: siteTitle}, + {property: 'og:description', content: siteDescription}, + {property: 'twitter:site', content: siteTwitter}, {property: 'twitter:card', content: 'summary'}, ]; }; -const createChannelMetaTags = (channel) => { +const createChannelMetaTags = (siteTitle, siteHost, siteTwitter, channel) => { const { name, longId } = channel; 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: 'og:title', content: `${name} on ${siteTitle}`}, + {property: 'og:url', content: `${siteHost}/${name}:${longId}`}, + {property: 'og:site_name', content: siteTitle}, + {property: 'og:description', content: `${name}, a channel on ${siteTitle}`}, + {property: 'twitter:site', content: siteTwitter}, {property: 'twitter:card', content: 'summary'}, ]; }; -const createAssetMetaTags = (asset) => { +const createAssetMetaTags = (siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail) => { const { claimData } = asset; const { contentType } = claimData; - const embedUrl = `${host}/${claimData.claimId}/${claimData.name}`; - const showUrl = `${host}/${claimData.claimId}/${claimData.name}`; - const source = `${host}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`; + const embedUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`; + const showUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`; + const source = `${siteHost}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`; const ogTitle = claimData.title || claimData.name; const ogDescription = claimData.description || defaultDescription; const ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail); @@ -56,11 +54,11 @@ const createAssetMetaTags = (asset) => { const metaTags = [ {property: 'og:title', content: ogTitle}, {property: 'og:url', content: showUrl}, - {property: 'og:site_name', content: title}, + {property: 'og:site_name', content: siteTitle}, {property: 'og:description', content: ogDescription}, {property: 'og:image:width', content: 600}, {property: 'og:image:height', content: 315}, - {property: 'twitter:site', content: '@spee_ch'}, + {property: 'twitter:site', content: siteTwitter}, ]; if (contentType === 'video/mp4' || contentType === 'video/webm') { metaTags.push({property: 'og:video', content: source}); @@ -85,12 +83,12 @@ const createAssetMetaTags = (asset) => { return metaTags; }; -export const createMetaTags = (asset, channel) => { +export const createMetaTags = (siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail) => { if (asset) { - return createAssetMetaTags(asset); + return createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail); }; if (channel) { - return createChannelMetaTags(channel); + return createChannelMetaTags(siteHost, siteTitle, siteTwitter, channel); }; - return createBasicMetaTags(); + return createBasicMetaTags(siteDescription, siteHost, siteTitle, siteTwitter); }; diff --git a/client/utils/pageTitle.js b/client/utils/pageTitle.js new file mode 100644 index 00000000..2b577c0b --- /dev/null +++ b/client/utils/pageTitle.js @@ -0,0 +1,6 @@ +export const createPageTitle = (siteTitle, pageTitle) => { + if (!pageTitle) { + return `${siteTitle}`; + } + return `${siteTitle} - ${pageTitle}`; +}; diff --git a/react/utils/publish.js b/client/utils/publish.js similarity index 100% rename from react/utils/publish.js rename to client/utils/publish.js diff --git a/react/utils/request.js b/client/utils/request.js similarity index 100% rename from react/utils/request.js rename to client/utils/request.js diff --git a/react/utils/validate.js b/client/utils/validate.js similarity index 100% rename from react/utils/validate.js rename to client/utils/validate.js diff --git a/config/mysqlConfig.js.example b/config/mysqlConfig.js.example new file mode 100644 index 00000000..58f2b2ae --- /dev/null +++ b/config/mysqlConfig.js.example @@ -0,0 +1,5 @@ +module.exports = { + database: 'default', + username: 'default', + password: 'default', +}; diff --git a/config/siteConfig.js.example b/config/siteConfig.js.example new file mode 100644 index 00000000..de2fe86d --- /dev/null +++ b/config/siteConfig.js.example @@ -0,0 +1,29 @@ +module.exports = { + analytics: { + googleId: 'default', + }, + assetDefaults: { + description: 'An asset published on Spee.ch', + thumbnail : 'https://spee.ch/assets/img/video_thumb_default.png', + title : 'Spee.ch', + }, + auth: { + sessionKey: 'default', + }, + details: { + description: 'Open-source, decentralized image and video sharing.', + host : 'default', + port : 3000, + title : 'Spee.ch', + twitter : '@spee_ch', + }, + publishing: { + additionalClaimAddresses: [], + disabled : false, + disabledMessage : 'Please check back soon.', + primaryClaimAddress : 'default', + thumbnailChannel : 'default', + thumbnailChannelId : 'default', + uploadDirectory : '/home/lbry/Uploads', + }, +}; diff --git a/config/speechConfig.js.example b/config/speechConfig.js.example deleted file mode 100644 index e1d5538f..00000000 --- a/config/speechConfig.js.example +++ /dev/null @@ -1,49 +0,0 @@ -module.exports = { - analytics: { - googleId: null, // google id for analytics tracking; leave `null` if not applicable - }, - sql: { - database: 'lbry', - username: null, // username for mysql - password: null, // password for mysql - }, - logging: { - logLevel : 'debug', // options: silly, debug, verbose, info - slackWebHook : null, // enter a webhook if you wish to push logs to slack; otherwise leave as `null` - slackErrorChannel: null, // enter a slack channel (#example) for errors to be sent to; otherwise leave null - slackInfoChannel : null, // enter a slack channel (#info) for info level logs to be sent to otherwise leave null - }, - session: { - sessionKey: null, // enter a secret key to be used for session encryption - }, - files: { - uploadDirectory: null, // enter file path to where uploads/publishes should be stored - }, - site: { - title : 'Spee.ch', - name : 'Spee.ch', - host : 'https://spee.ch', - description: 'Open-source, decentralized image and video sharing.', - }, - publish: { - additionalClaimAddresses: [], // // optional: add previously used claim addresses - disabled : false, - primaryClaimAddress : null, // choose any address from your lbry wallet - thumbnailChannel : '@channelName', // create a channel to use for thumbnail images - thumbnailChannelId : 'xyz123...', // the channel_id (claim id) for the channel above - }, - claim: { - defaultTitle : 'Spee.ch', - defaultThumbnail : 'https://spee.ch/assets/img/video_thumb_default.png', - defaultDescription: 'Open-source, decentralized image and video sharing.', - }, - testing: { - testChannel : '@testpublishchannel', // a channel to make test publishes in - testChannelId : 'xyz123...', // the claim id for the test channel - testChannelPassword: 'password', // password for the test channel - }, - api: { - apiHost: 'localhost', - apiPort: '5279', - }, -}; diff --git a/constants/index.js b/constants/index.js deleted file mode 100644 index ee36baf0..00000000 --- a/constants/index.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - PUBLISH_ANONYMOUS_CLAIM : 'PUBLISH_ANONYMOUS_CLAIM', - PUBLISH_IN_CHANNEL_CLAIM: 'PUBLISH_IN_CHANNEL_CLAIM', -}; diff --git a/controllers/statsController.js b/controllers/statsController.js deleted file mode 100644 index 75ddfb9c..00000000 --- a/controllers/statsController.js +++ /dev/null @@ -1,41 +0,0 @@ -const logger = require('winston'); -const db = require('../models'); - -module.exports = { - getTrendingClaims (startDate) { - logger.debug('retrieving trending'); - return new Promise((resolve, reject) => { - // get the raw requests data - db.getTrendingFiles(startDate) - .then(fileArray => { - let claimsPromiseArray = []; - if (fileArray) { - fileArray.forEach(file => { - claimsPromiseArray.push(db.Claim.resolveClaim(file.name, file.claimId)); - }); - return Promise.all(claimsPromiseArray); - } - }) - .then(claimsArray => { - resolve(claimsArray); - }) - .catch(error => { - reject(error); - }); - }); - }, - getRecentClaims () { - logger.debug('retrieving most recent claims'); - return new Promise((resolve, reject) => { - // get the raw requests data - db.File.getRecentClaims() - .then(results => { - resolve(results); - }) - .catch(error => { - logger.error('sequelize error', error); - reject(error); - }); - }); - }, -}; diff --git a/devConfig/lbryConfig.js b/devConfig/lbryConfig.js new file mode 100644 index 00000000..dd954fcc --- /dev/null +++ b/devConfig/lbryConfig.js @@ -0,0 +1,6 @@ +module.exports = { + api: { + apiHost: 'localhost', + apiPort: '5279', + }, +}; diff --git a/devConfig/lbryConfig.js.example b/devConfig/lbryConfig.js.example new file mode 100644 index 00000000..dd954fcc --- /dev/null +++ b/devConfig/lbryConfig.js.example @@ -0,0 +1,6 @@ +module.exports = { + api: { + apiHost: 'localhost', + apiPort: '5279', + }, +}; diff --git a/devConfig/loggerConfig.js b/devConfig/loggerConfig.js new file mode 100644 index 00000000..bbbbbbcf --- /dev/null +++ b/devConfig/loggerConfig.js @@ -0,0 +1,3 @@ +module.exports = { + logLevel: 'debug', // options: silly, debug, verbose, info +}; diff --git a/devConfig/loggerConfig.js.example b/devConfig/loggerConfig.js.example new file mode 100644 index 00000000..bbbbbbcf --- /dev/null +++ b/devConfig/loggerConfig.js.example @@ -0,0 +1,3 @@ +module.exports = { + logLevel: 'debug', // options: silly, debug, verbose, info +}; diff --git a/config/sequelizeCliConfig.js.example b/devConfig/sequelizeCliConfig.js.example similarity index 100% rename from config/sequelizeCliConfig.js.example rename to devConfig/sequelizeCliConfig.js.example diff --git a/devConfig/slackConfig.js.example b/devConfig/slackConfig.js.example new file mode 100644 index 00000000..9f4b8f21 --- /dev/null +++ b/devConfig/slackConfig.js.example @@ -0,0 +1,5 @@ +module.exports = { + slackWebHook : null, + slackErrorChannel: null, + slackInfoChannel : null, +}; diff --git a/devConfig/testingConfig.js.example b/devConfig/testingConfig.js.example new file mode 100644 index 00000000..4837fc20 --- /dev/null +++ b/devConfig/testingConfig.js.example @@ -0,0 +1,5 @@ +module.exports = { + testChannel : null, // a channel to make test publishes in + testChannelId : null, // the claim id for the test channel + testChannelPassword: null, // password for the test channel +}; diff --git a/helpers/authHelpers.js b/helpers/authHelpers.js deleted file mode 100644 index e9bf0210..00000000 --- a/helpers/authHelpers.js +++ /dev/null @@ -1,26 +0,0 @@ -// const db = require('../models'); // require our models for syncing -const logger = require('winston'); - -module.exports = { - 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 (user, done) { // returns user data to be serialized into session - logger.debug('serializing user'); - done(null, user); - }, - deserializeSpeechUser (user, done) { // deserializes session and populates additional info to req.user - logger.debug('deserializing user'); - done(null, user); - }, -}; diff --git a/index.js b/index.js index 9303e671..3c88b473 100644 --- a/index.js +++ b/index.js @@ -1,84 +1,10909 @@ -// load dependencies -const express = require('express'); -const bodyParser = require('body-parser'); -const expressHandlebars = require('express-handlebars'); -const Handlebars = require('handlebars'); -const { populateLocalsDotUser, serializeSpeechUser, deserializeSpeechUser } = require('./helpers/authHelpers.js'); -const config = require('./config/speechConfig.js'); -const logger = require('winston'); -const helmet = require('helmet'); -const PORT = 3000; // set port -const app = express(); // create an Express application -const db = require('./models'); // require our models for syncing -const passport = require('passport'); -const cookieSession = require('cookie-session'); +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) { -// configure logging -const logLevel = config.logging.logLevel; -require('./config/loggerConfig.js')(logger, logLevel); -require('./config/slackConfig.js')(logger); +module.exports = require("react"); -// check for global config variables -require('./helpers/configVarCheck.js')(); +/***/ }), +/* 1 */ +/***/ (function(module, exports) { + +module.exports = require("react-redux"); + +/***/ }), +/* 2 */ +/***/ (function(module, exports) { + +module.exports = require("winston"); + +/***/ }), +/* 3 */ +/***/ (function(module, exports) { + +module.exports = require("react-router-dom"); + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.selectFile = selectFile; +exports.clearFile = clearFile; +exports.updateMetadata = updateMetadata; +exports.updateClaim = updateClaim; +exports.setPublishInChannel = setPublishInChannel; +exports.updatePublishStatus = updatePublishStatus; +exports.updateError = updateError; +exports.updateSelectedChannel = updateSelectedChannel; +exports.toggleMetadataInputs = toggleMetadataInputs; +exports.onNewThumbnail = onNewThumbnail; +exports.startPublish = startPublish; + +var _publish_action_types = __webpack_require__(32); + +var actions = _interopRequireWildcard(_publish_action_types); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +// export action creators +function selectFile(file) { + return { + type: actions.FILE_SELECTED, + data: file + }; +}; + +function clearFile() { + return { + type: actions.FILE_CLEAR + }; +}; + +function updateMetadata(name, value) { + return { + type: actions.METADATA_UPDATE, + data: { + name: name, + value: value + } + }; +}; + +function updateClaim(value) { + return { + type: actions.CLAIM_UPDATE, + data: value + }; +}; + +function setPublishInChannel(channel) { + return { + type: actions.SET_PUBLISH_IN_CHANNEL, + channel: channel + }; +}; + +function updatePublishStatus(status, message) { + return { + type: actions.PUBLISH_STATUS_UPDATE, + data: { + status: status, + message: message + } + }; +}; + +function updateError(name, value) { + return { + type: actions.ERROR_UPDATE, + data: { + name: name, + value: value + } + }; +}; + +function updateSelectedChannel(channelName) { + return { + type: actions.SELECTED_CHANNEL_UPDATE, + data: channelName + }; +}; + +function toggleMetadataInputs(showMetadataInputs) { + return { + type: actions.TOGGLE_METADATA_INPUTS, + data: showMetadataInputs + }; +}; + +function onNewThumbnail(file) { + return { + type: actions.THUMBNAIL_NEW, + data: file + }; +}; + +function startPublish(history) { + return { + type: actions.PUBLISH_START, + data: { history: history } + }; +} + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function SiteConfig() { + this.analytics = { + googleId: 'default' + }; + this.assetDefaults = { + description: 'An asset published on Spee.ch', + thumbnail: 'https://spee.ch/assets/img/video_thumb_default.png', + title: 'Spee.ch' + }; + this.auth = { + sessionKey: 'default' + }; + this.details = { + description: 'Open-source, decentralized image and video sharing.', + host: 'default', + port: 3000, + title: 'Spee.ch', + twitter: '@spee_ch' + }; + this.publishing = { + additionalClaimAddresses: [], + disabled: false, + disabledMessage: 'Please check back soon.', + primaryClaimAddress: 'default', + thumbnailChannel: 'default', + thumbnailChannelId: 'default', + uploadDirectory: '/home/lbry/Uploads' + }; +}; + +module.exports = new SiteConfig(); + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var Sequelize = __webpack_require__(24); +var logger = __webpack_require__(2); + +console.log('exporting sequelize models'); + +var _require = __webpack_require__(66), + database = _require.database, + username = _require.username, + password = _require.password; + +var db = {}; +// set sequelize options +var sequelize = new Sequelize(database, username, password, { + host: 'localhost', + dialect: 'mysql', + dialectOptions: { decimalNumbers: true }, // fix to ensure DECIMAL will not be stored as a string + logging: false, + pool: { + max: 5, + min: 0, + idle: 10000, + acquire: 10000 + } +}); + +// establish mysql connection +sequelize.authenticate().then(function () { + logger.info('Sequelize has established mysql connection successfully.'); +}).catch(function (err) { + logger.error('Sequelize was unable to connect to the database:', err); +}); + +// manually add each model to the db object +var Certificate = __webpack_require__(67); +var Channel = __webpack_require__(68); +var Claim = __webpack_require__(69); +var File = __webpack_require__(70); +var Request = __webpack_require__(71); +var User = __webpack_require__(72); +db['Certificate'] = sequelize.import('Certificate', Certificate); +db['Channel'] = sequelize.import('Channel', Channel); +db['Claim'] = sequelize.import('Claim', Claim); +db['File'] = sequelize.import('File', File); +db['Request'] = sequelize.import('Request', Request); +db['User'] = sequelize.import('User', User); + +// run model.association for each model in the db object that has an association +Object.keys(db).forEach(function (modelName) { + if (db[modelName].associate) { + logger.info('Associating model:', modelName); + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +// add an 'upsert' method to the db object +db.upsert = function (Model, values, condition, tableName) { + return Model.findOne({ + where: condition + }).then(function (obj) { + if (obj) { + // update + logger.debug('updating record in db.' + tableName); + return obj.update(values); + } else { + // insert + logger.debug('creating record in db.' + tableName); + return Model.create(values); + } + }).catch(function (error) { + logger.error(tableName + '.upsert error', error); + throw error; + }); +}; + +module.exports = db; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _channel = __webpack_require__(19); + +var _publish = __webpack_require__(4); + +var _view = __webpack_require__(93); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var channel = _ref.channel, + site = _ref.site; + + return { + channelName: channel.loggedInChannel.name, + channelShortId: channel.loggedInChannel.shortId, + channelLongId: channel.loggedInChannel.longId, + siteDescription: site.description + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + onChannelLogin: function onChannelLogin(name, shortId, longId) { + dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId)); + dispatch((0, _publish.updateSelectedChannel)(name)); + }, + onChannelLogout: function onChannelLogout() { + dispatch((0, _channel.updateLoggedInChannel)(null, null, null)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.onHandleShowPageUri = onHandleShowPageUri; +exports.onRequestError = onRequestError; +exports.onNewChannelRequest = onNewChannelRequest; +exports.onNewAssetRequest = onNewAssetRequest; +exports.onRequestUpdate = onRequestUpdate; +exports.addRequestToRequestList = addRequestToRequestList; +exports.addAssetToAssetList = addAssetToAssetList; +exports.addNewChannelToChannelList = addNewChannelToChannelList; +exports.onUpdateChannelClaims = onUpdateChannelClaims; +exports.updateChannelClaims = updateChannelClaims; +exports.fileRequested = fileRequested; +exports.updateFileAvailability = updateFileAvailability; +exports.updateDisplayAssetError = updateDisplayAssetError; + +var _show_action_types = __webpack_require__(12); + +var actions = _interopRequireWildcard(_show_action_types); + +var _show_request_types = __webpack_require__(41); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +// basic request parsing +function onHandleShowPageUri(params) { + return { + type: actions.HANDLE_SHOW_URI, + data: params + }; +}; + +function onRequestError(error) { + return { + type: actions.REQUEST_ERROR, + data: error + }; +}; + +function onNewChannelRequest(channelName, channelId) { + var requestType = _show_request_types.CHANNEL; + var requestId = 'cr#' + channelName + '#' + channelId; + return { + type: actions.CHANNEL_REQUEST_NEW, + data: { requestType: requestType, requestId: requestId, channelName: channelName, channelId: channelId } + }; +}; + +function onNewAssetRequest(name, id, channelName, channelId, extension) { + var requestType = extension ? _show_request_types.ASSET_LITE : _show_request_types.ASSET_DETAILS; + var requestId = 'ar#' + name + '#' + id + '#' + channelName + '#' + channelId; + return { + type: actions.ASSET_REQUEST_NEW, + data: { + requestType: requestType, + requestId: requestId, + name: name, + modifier: { + id: id, + channel: { + name: channelName, + id: channelId + } + } + } + }; +}; + +function onRequestUpdate(requestType, requestId) { + return { + type: actions.REQUEST_UPDATE, + data: { + requestType: requestType, + requestId: requestId + } + }; +}; + +function addRequestToRequestList(id, error, key) { + return { + type: actions.REQUEST_LIST_ADD, + data: { id: id, error: error, key: key } + }; +}; + +// asset actions + +function addAssetToAssetList(id, error, name, claimId, shortId, claimData) { + return { + type: actions.ASSET_ADD, + data: { id: id, error: error, name: name, claimId: claimId, shortId: shortId, claimData: claimData } + }; +} + +// channel actions + +function addNewChannelToChannelList(id, name, shortId, longId, claimsData) { + return { + type: actions.CHANNEL_ADD, + data: { id: id, name: name, shortId: shortId, longId: longId, claimsData: claimsData } + }; +}; + +function onUpdateChannelClaims(channelKey, name, longId, page) { + return { + type: actions.CHANNEL_CLAIMS_UPDATE_ASYNC, + data: { channelKey: channelKey, name: name, longId: longId, page: page } + }; +}; + +function updateChannelClaims(channelListId, claimsData) { + return { + type: actions.CHANNEL_CLAIMS_UPDATE_SUCCESS, + data: { channelListId: channelListId, claimsData: claimsData } + }; +}; + +// display a file + +function fileRequested(name, claimId) { + return { + type: actions.FILE_REQUESTED, + data: { name: name, claimId: claimId } + }; +}; + +function updateFileAvailability(status) { + return { + type: actions.FILE_AVAILABILITY_UPDATE, + data: status + }; +}; + +function updateDisplayAssetError(error) { + return { + type: actions.DISPLAY_ASSET_ERROR, + data: error + }; +}; + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(89); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var site = _ref.site; + var defaultDescription = site.defaultDescription, + defaultThumbnail = site.defaultThumbnail, + siteDescription = site.description, + siteHost = site.host, + siteTitle = site.title, + siteTwitter = site.twitter; + + return { + defaultDescription: defaultDescription, + defaultThumbnail: defaultThumbnail, + siteDescription: siteDescription, + siteHost: siteHost, + siteTitle: siteTitle, + siteTwitter: siteTwitter + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 10 */ +/***/ (function(module, exports) { + +module.exports = require("prop-types"); + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +exports.default = request; + +__webpack_require__(96); + +/** + * Parses the JSON returned by a network request + * + * @param {object} response A response from a network request + * + * @return {object} The parsed JSON from the request + */ +function parseJSON(response) { + if (response.status === 204 || response.status === 205) { + return null; + } + return response.json(); +} + +/** + * Parses the status returned by a network request + * + * @param {object} response A response from a network request + * @param {object} response The parsed JSON from the network request + * + * @return {object | undefined} Returns object with status and statusText, or undefined + */ +function checkStatus(response, jsonResponse) { + if (response.status >= 200 && response.status < 300) { + return jsonResponse; + } + var error = new Error(jsonResponse.message); + error.response = response; + throw error; +} + +/** + * Requests a URL, returning a promise + * + * @param {string} url The URL we want to request + * @param {object} [options] The options we want to pass to "fetch" + * + * @return {object} The response data + */ + +function request(url, options) { + return fetch(url, options).then(function (response) { + return Promise.all([response, parseJSON(response)]); + }).then(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + response = _ref2[0], + jsonResponse = _ref2[1]; + + return checkStatus(response, jsonResponse); + }); +} + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +// request actions +var HANDLE_SHOW_URI = exports.HANDLE_SHOW_URI = 'HANDLE_SHOW_URI'; +var REQUEST_ERROR = exports.REQUEST_ERROR = 'REQUEST_ERROR'; +var REQUEST_UPDATE = exports.REQUEST_UPDATE = 'REQUEST_UPDATE'; +var ASSET_REQUEST_NEW = exports.ASSET_REQUEST_NEW = 'ASSET_REQUEST_NEW'; +var CHANNEL_REQUEST_NEW = exports.CHANNEL_REQUEST_NEW = 'CHANNEL_REQUEST_NEW'; +var REQUEST_LIST_ADD = exports.REQUEST_LIST_ADD = 'REQUEST_LIST_ADD'; + +// asset actions +var ASSET_ADD = exports.ASSET_ADD = 'ASSET_ADD'; + +// channel actions +var CHANNEL_ADD = exports.CHANNEL_ADD = 'CHANNEL_ADD'; + +var CHANNEL_CLAIMS_UPDATE_ASYNC = exports.CHANNEL_CLAIMS_UPDATE_ASYNC = 'CHANNEL_CLAIMS_UPDATE_ASYNC'; +var CHANNEL_CLAIMS_UPDATE_SUCCESS = exports.CHANNEL_CLAIMS_UPDATE_SUCCESS = 'CHANNEL_CLAIMS_UPDATE_SUCCESS'; + +// asset/file display actions +var FILE_REQUESTED = exports.FILE_REQUESTED = 'FILE_REQUESTED'; +var FILE_AVAILABILITY_UPDATE = exports.FILE_AVAILABILITY_UPDATE = 'FILE_AVAILABILITY_UPDATE'; +var DISPLAY_ASSET_ERROR = exports.DISPLAY_ASSET_ERROR = 'DISPLAY_ASSET_ERROR'; + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var selectAsset = exports.selectAsset = function selectAsset(show) { + var request = show.requestList[show.request.id]; + var assetKey = request.key; + return show.assetList[assetKey]; +}; + +var selectShowState = exports.selectShowState = function selectShowState(state) { + return state.show; +}; + +/***/ }), +/* 14 */ +/***/ (function(module, exports) { + +module.exports = require("react-helmet"); + +/***/ }), +/* 15 */ +/***/ (function(module, exports) { + +module.exports = require("redux-saga/effects"); + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var axios = __webpack_require__(63); +var logger = __webpack_require__(2); + +var _require = __webpack_require__(64), + _require$api = _require.api, + apiHost = _require$api.apiHost, + apiPort = _require$api.apiPort; + +var lbryApiUri = 'http://' + apiHost + ':' + apiPort; + +var _require2 = __webpack_require__(17), + chooseGaLbrynetPublishLabel = _require2.chooseGaLbrynetPublishLabel, + sendGATimingEvent = _require2.sendGATimingEvent; + +var handleLbrynetResponse = function handleLbrynetResponse(_ref, resolve, reject) { + var data = _ref.data; + + logger.debug('lbry api data:', data); + if (data.result) { + // check for an error + if (data.result.error) { + logger.debug('Lbrynet api error:', data.result.error); + reject(new Error(data.result.error)); + return; + }; + resolve(data.result); + return; + } + // fallback in case it just timed out + reject(JSON.stringify(data)); +}; + +module.exports = { + publishClaim: function publishClaim(publishParams) { + logger.debug('lbryApi >> Publishing claim to "' + publishParams.name + '"'); + var gaStartTime = Date.now(); + return new Promise(function (resolve, reject) { + axios.post(lbryApiUri, { + method: 'publish', + params: publishParams + }).then(function (response) { + sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now()); + handleLbrynetResponse(response, resolve, reject); + }).catch(function (error) { + reject(error); + }); + }); + }, + getClaim: function getClaim(uri) { + logger.debug('lbryApi >> Getting Claim for "' + uri + '"'); + var gaStartTime = Date.now(); + return new Promise(function (resolve, reject) { + axios.post(lbryApiUri, { + method: 'get', + params: { uri: uri, timeout: 20 } + }).then(function (response) { + sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now()); + handleLbrynetResponse(response, resolve, reject); + }).catch(function (error) { + reject(error); + }); + }); + }, + getClaimList: function getClaimList(claimName) { + logger.debug('lbryApi >> Getting claim_list for "' + claimName + '"'); + var gaStartTime = Date.now(); + return new Promise(function (resolve, reject) { + axios.post(lbryApiUri, { + method: 'claim_list', + params: { name: claimName } + }).then(function (response) { + sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now()); + handleLbrynetResponse(response, resolve, reject); + }).catch(function (error) { + reject(error); + }); + }); + }, + resolveUri: function resolveUri(uri) { + logger.debug('lbryApi >> Resolving URI for "' + uri + '"'); + var gaStartTime = Date.now(); + return new Promise(function (resolve, reject) { + axios.post(lbryApiUri, { + method: 'resolve', + params: { uri: uri } + }).then(function (_ref2) { + var data = _ref2.data; + + sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now()); + if (data.result[uri].error) { + // check for errors + reject(data.result[uri].error); + } else { + // if no errors, resolve + resolve(data.result[uri]); + } + }).catch(function (error) { + reject(error); + }); + }); + }, + getDownloadDirectory: function getDownloadDirectory() { + logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...'); + var gaStartTime = Date.now(); + return new Promise(function (resolve, reject) { + axios.post(lbryApiUri, { + method: 'settings_get' + }).then(function (_ref3) { + var data = _ref3.data; + + sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now()); + if (data.result) { + resolve(data.result.download_directory); + } else { + return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.'); + } + }).catch(function (error) { + logger.error('Lbrynet Error:', error); + resolve('/home/lbry/Downloads/'); + }); + }); + }, + createChannel: function createChannel(name) { + logger.debug('lbryApi >> Creating channel for ' + name + '...'); + var gaStartTime = Date.now(); + return new Promise(function (resolve, reject) { + axios.post(lbryApiUri, { + method: 'channel_new', + params: { + channel_name: name, + amount: 0.1 + } + }).then(function (response) { + sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now()); + handleLbrynetResponse(response, resolve, reject); + }).catch(function (error) { + reject(error); + }); + }); + } +}; + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var logger = __webpack_require__(2); +var ua = __webpack_require__(65); + +var _require = __webpack_require__(5), + googleId = _require.analytics.googleId, + title = _require.details.title; + +function createServeEventParams(headers, ip, originalUrl) { + return { + eventCategory: 'client requests', + eventAction: 'serve request', + eventLabel: originalUrl, + ipOverride: ip, + userAgentOverride: headers['user-agent'] + }; +}; + +function createPublishTimingEventParams(category, variable, label, startTime, endTime) { + var duration = endTime - startTime; + return { + userTimingCategory: category, + userTimingVariableName: variable, + userTimingTime: duration, + userTimingLabel: label + }; +}; + +function sendGoogleAnalyticsEvent(ip, params) { + var visitorId = ip.replace(/\./g, '-'); + var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true }); + visitor.event(params, function (err) { + if (err) { + logger.error('Google Analytics Event Error >>', err); + } + }); +}; + +function sendGoogleAnalyticsTiming(visitorId, params) { + var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true }); + visitor.timing(params, function (err) { + if (err) { + logger.error('Google Analytics Event Error >>', err); + } + logger.debug('Timing event successfully sent to google analytics'); + }); +}; + +module.exports = { + sendGAServeEvent: function sendGAServeEvent(headers, ip, originalUrl) { + var params = createServeEventParams(headers, ip, originalUrl); + sendGoogleAnalyticsEvent(ip, params); + }, + sendGATimingEvent: function sendGATimingEvent(category, variable, label, startTime, endTime) { + var params = createPublishTimingEventParams(category, variable, label, startTime, endTime); + sendGoogleAnalyticsTiming(title, params); + }, + chooseGaLbrynetPublishLabel: function chooseGaLbrynetPublishLabel(_ref) { + var channelName = _ref.channel_name, + channelId = _ref.channel_id; + + return channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM'; + } +}; + +/***/ }), +/* 18 */ +/***/ (function(module, exports) { + +module.exports = require("redux"); + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.updateLoggedInChannel = updateLoggedInChannel; + +var _channel_action_types = __webpack_require__(34); + +var actions = _interopRequireWildcard(_channel_action_types); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +// export action creators + +function updateLoggedInChannel(name, shortId, longId) { + return { + type: actions.CHANNEL_UPDATE, + data: { + name: name, + shortId: shortId, + longId: longId + } + }; +}; + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = __webpack_require__(10); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _ActiveStatusBar = __webpack_require__(118); + +var _ActiveStatusBar2 = _interopRequireDefault(_ActiveStatusBar); + +var _InactiveStatusBar = __webpack_require__(119); + +var _InactiveStatusBar2 = _interopRequireDefault(_InactiveStatusBar); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ProgressBar = function (_React$Component) { + _inherits(ProgressBar, _React$Component); + + function ProgressBar(props) { + _classCallCheck(this, ProgressBar); + + var _this = _possibleConstructorReturn(this, (ProgressBar.__proto__ || Object.getPrototypeOf(ProgressBar)).call(this, props)); + + _this.state = { + bars: [], + index: 0, + incrementer: 1 + }; + _this.createBars = _this.createBars.bind(_this); + _this.startProgressBar = _this.startProgressBar.bind(_this); + _this.updateProgressBar = _this.updateProgressBar.bind(_this); + _this.stopProgressBar = _this.stopProgressBar.bind(_this); + return _this; + } + + _createClass(ProgressBar, [{ + key: 'componentDidMount', + value: function componentDidMount() { + this.createBars(); + this.startProgressBar(); + } + }, { + key: 'componentWillUnmount', + value: function componentWillUnmount() { + this.stopProgressBar(); + } + }, { + key: 'createBars', + value: function createBars() { + var bars = []; + for (var i = 0; i <= this.props.size; i++) { + bars.push({ isActive: false }); + } + this.setState({ bars: bars }); + } + }, { + key: 'startProgressBar', + value: function startProgressBar() { + this.updateInterval = setInterval(this.updateProgressBar.bind(this), 300); + } + }, { + key: 'updateProgressBar', + value: function updateProgressBar() { + var index = this.state.index; + var incrementer = this.state.incrementer; + var bars = this.state.bars; + // flip incrementer if necessary, to stay in bounds + if (index < 0 || index > this.props.size) { + incrementer = incrementer * -1; + index += incrementer; + } + // update the indexed bar + if (incrementer > 0) { + bars[index].isActive = true; + } else { + bars[index].isActive = false; + }; + // increment index + index += incrementer; + // update state + this.setState({ + bars: bars, + incrementer: incrementer, + index: index + }); + } + }, { + key: 'stopProgressBar', + value: function stopProgressBar() { + clearInterval(this.updateInterval); + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + null, + this.state.bars.map(function (bar, index) { + return bar.isActive ? _react2.default.createElement(_ActiveStatusBar2.default, { key: index }) : _react2.default.createElement(_InactiveStatusBar2.default, { key: index }); + }) + ); + } + }]); + + return ProgressBar; +}(_react2.default.Component); + +; + +ProgressBar.propTypes = { + size: _propTypes2.default.number.isRequired +}; + +exports.default = ProgressBar; + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = __webpack_require__(10); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _NavBar = __webpack_require__(7); + +var _NavBar2 = _interopRequireDefault(_NavBar); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ErrorPage = function (_React$Component) { + _inherits(ErrorPage, _React$Component); + + function ErrorPage() { + _classCallCheck(this, ErrorPage); + + return _possibleConstructorReturn(this, (ErrorPage.__proto__ || Object.getPrototypeOf(ErrorPage)).apply(this, arguments)); + } + + _createClass(ErrorPage, [{ + key: 'render', + value: function render() { + var error = this.props.error; + + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement(_NavBar2.default, null), + _react2.default.createElement( + 'div', + { className: 'row row--padded' }, + _react2.default.createElement( + 'p', + null, + error + ) + ) + ); + } + }]); + + return ErrorPage; +}(_react2.default.Component); + +; + +ErrorPage.propTypes = { + error: _propTypes2.default.string.isRequired +}; + +exports.default = ErrorPage; + +/***/ }), +/* 22 */ +/***/ (function(module, exports) { + +module.exports = require("passport"); + +/***/ }), +/* 23 */ +/***/ (function(module, exports) { + +module.exports = require("passport-local"); + +/***/ }), +/* 24 */ +/***/ (function(module, exports) { + +module.exports = require("sequelize"); + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = { + returnShortId: function returnShortId(claimsArray, longId) { + var claimIndex = void 0; + var shortId = longId.substring(0, 1); // default short id is the first letter + var shortIdLength = 0; + // find the index of this claim id + claimIndex = claimsArray.findIndex(function (element) { + return element.claimId === longId; + }); + if (claimIndex < 0) { + throw new Error('claim id not found in claims list'); + } + // get an array of all claims with lower height + var possibleMatches = claimsArray.slice(0, claimIndex); + // remove certificates with the same prefixes until none are left. + while (possibleMatches.length > 0) { + shortIdLength += 1; + shortId = longId.substring(0, shortIdLength); + possibleMatches = possibleMatches.filter(function (element) { + return element.claimId && element.claimId.substring(0, shortIdLength) === shortId; + }); + } + return shortId; + } +}; + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var logger = __webpack_require__(2); +var fs = __webpack_require__(79); + +var _require = __webpack_require__(5), + details = _require.details, + publishing = _require.publishing; + +module.exports = { + parsePublishApiRequestBody: function parsePublishApiRequestBody(_ref) { + var name = _ref.name, + nsfw = _ref.nsfw, + license = _ref.license, + title = _ref.title, + description = _ref.description, + thumbnail = _ref.thumbnail; + + // validate name + if (!name) { + throw new Error('no name field found in request'); + } + var invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name); + if (invalidNameCharacters) { + throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and "-"'); + } + // optional parameters + nsfw = nsfw === 'true'; + license = license || null; + title = title || null; + description = description || null; + thumbnail = thumbnail || null; + // return results + return { + name: name, + nsfw: nsfw, + license: license, + title: title, + description: description, + thumbnail: thumbnail + }; + }, + parsePublishApiRequestFiles: function parsePublishApiRequestFiles(_ref2) { + var file = _ref2.file, + thumbnail = _ref2.thumbnail; + + // make sure a file was provided + if (!file) { + throw new Error('no file with key of [file] found in request'); + } + if (!file.path) { + throw new Error('no file path found'); + } + if (!file.type) { + throw new Error('no file type found'); + } + if (!file.size) { + throw new Error('no file type found'); + } + // validate the file name + if (/'/.test(file.name)) { + throw new Error('apostrophes are not allowed in the file name'); + } + // validate the file + module.exports.validateFileTypeAndSize(file); + // return results + return { + fileName: file.name, + filePath: file.path, + fileType: file.type, + thumbnailFileName: thumbnail ? thumbnail.name : null, + thumbnailFilePath: thumbnail ? thumbnail.path : null, + thumbnailFileType: thumbnail ? thumbnail.type : null + }; + }, + validateFileTypeAndSize: function validateFileTypeAndSize(file) { + // check file type and size + switch (file.type) { + case 'image/jpeg': + case 'image/jpg': + case 'image/png': + if (file.size > 10000000) { + logger.debug('publish > file validation > .jpeg/.jpg/.png was too big'); + throw new Error('Sorry, images are limited to 10 megabytes.'); + } + break; + case 'image/gif': + if (file.size > 50000000) { + logger.debug('publish > file validation > .gif was too big'); + throw new Error('Sorry, .gifs are limited to 50 megabytes.'); + } + break; + case 'video/mp4': + if (file.size > 50000000) { + logger.debug('publish > file validation > .mp4 was too big'); + throw new Error('Sorry, videos are limited to 50 megabytes.'); + } + break; + default: + logger.debug('publish > file validation > unrecognized file type'); + throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.'); + } + return file; + }, + createBasicPublishParams: function createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail) { + logger.debug('Creating Publish Parameters'); + // provide defaults for title + if (title === null || title.trim() === '') { + title = name; + } + // provide default for description + if (description === null || description.trim() === '') { + description = ''; + } + // provide default for license + if (license === null || license.trim() === '') { + license = ' '; // default to empty string + } + // create the publish params + var publishParams = { + name: name, + file_path: filePath, + bid: 0.01, + metadata: { + description: description, + title: title, + author: details.title, + language: 'en', + license: license, + nsfw: nsfw + }, + claim_address: publishing.primaryClaimAddress + }; + // add thumbnail to channel if video + if (thumbnail) { + publishParams['metadata']['thumbnail'] = thumbnail; + } + return publishParams; + }, + createThumbnailPublishParams: function createThumbnailPublishParams(thumbnailFilePath, claimName, license, nsfw) { + if (!thumbnailFilePath) { + return; + } + logger.debug('Creating Thumbnail Publish Parameters'); + // create the publish params + return { + name: claimName + '-thumb', + file_path: thumbnailFilePath, + bid: 0.01, + metadata: { + title: claimName + ' thumbnail', + description: 'a thumbnail for ' + claimName, + author: details.title, + language: 'en', + license: license, + nsfw: nsfw + }, + claim_address: publishing.primaryClaimAddress, + channel_name: publishing.thumbnailChannel, + channel_id: publishing.thumbnailChannelId + }; + }, + deleteTemporaryFile: function deleteTemporaryFile(filePath) { + fs.unlink(filePath, function (err) { + if (err) { + logger.error('error deleting temporary file ' + filePath); + throw err; + } + logger.debug('successfully deleted ' + filePath); + }); + }, + addGetResultsToFileData: function addGetResultsToFileData(fileInfo, getResult) { + fileInfo.fileName = getResult.file_name; + fileInfo.filePath = getResult.download_path; + return fileInfo; + }, + createFileData: function createFileData(_ref3) { + var name = _ref3.name, + claimId = _ref3.claimId, + outpoint = _ref3.outpoint, + height = _ref3.height, + address = _ref3.address, + nsfw = _ref3.nsfw, + contentType = _ref3.contentType; + + return { + name: name, + claimId: claimId, + outpoint: outpoint, + height: height, + address: address, + fileName: '', + filePath: '', + fileType: contentType, + nsfw: nsfw + }; + } +}; + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var logger = __webpack_require__(2); + +module.exports = { + handleErrorResponse: function handleErrorResponse(originalUrl, ip, error, res) { + logger.error('Error on ' + originalUrl, module.exports.useObjectPropertiesIfNoKeys(error)); + + var _module$exports$retur = module.exports.returnErrorMessageAndStatus(error), + _module$exports$retur2 = _slicedToArray(_module$exports$retur, 2), + status = _module$exports$retur2[0], + message = _module$exports$retur2[1]; + + res.status(status).json(module.exports.createErrorResponsePayload(status, message)); + }, + returnErrorMessageAndStatus: function returnErrorMessageAndStatus(error) { + var status = void 0, + message = void 0; + // check for daemon being turned off + if (error.code === 'ECONNREFUSED') { + status = 503; + message = 'Connection refused. The daemon may not be running.'; + // fallback for everything else + } else { + status = 400; + if (error.message) { + message = error.message; + } else { + message = error; + }; + }; + return [status, message]; + }, + useObjectPropertiesIfNoKeys: function useObjectPropertiesIfNoKeys(err) { + if (Object.keys(err).length === 0) { + var newErrorObject = {}; + Object.getOwnPropertyNames(err).forEach(function (key) { + newErrorObject[key] = err[key]; + }); + return newErrorObject; + } + return err; + }, + createErrorResponsePayload: function createErrorResponsePayload(status, message) { + return { + status: status, + success: false, + message: message + }; + } +}; + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var db = __webpack_require__(6); +var logger = __webpack_require__(2); + +var _require = __webpack_require__(81), + returnPaginatedChannelClaims = _require.returnPaginatedChannelClaims; + +var NO_CHANNEL = 'NO_CHANNEL'; +var NO_CLAIM = 'NO_CLAIM'; +var NO_FILE = 'NO_FILE'; + +module.exports = { + getClaimId: function getClaimId(channelName, channelClaimId, name, claimId) { + if (channelName) { + return module.exports.getClaimIdByChannel(channelName, channelClaimId, name); + } else { + return module.exports.getClaimIdByClaim(name, claimId); + } + }, + getClaimIdByClaim: function getClaimIdByClaim(claimName, claimId) { + logger.debug('getClaimIdByClaim(' + claimName + ', ' + claimId + ')'); + return new Promise(function (resolve, reject) { + db.Claim.getLongClaimId(claimName, claimId).then(function (longClaimId) { + if (!longClaimId) { + resolve(NO_CLAIM); + } + resolve(longClaimId); + }).catch(function (error) { + reject(error); + }); + }); + }, + getClaimIdByChannel: function getClaimIdByChannel(channelName, channelClaimId, claimName) { + logger.debug('getClaimIdByChannel(' + channelName + ', ' + channelClaimId + ', ' + claimName + ')'); + return new Promise(function (resolve, reject) { + db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id + .then(function (longChannelId) { + if (!longChannelId) { + return [null, null]; + } + return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id + }).then(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + longChannelId = _ref2[0], + longClaimId = _ref2[1]; + + if (!longChannelId) { + return resolve(NO_CHANNEL); + } + if (!longClaimId) { + return resolve(NO_CLAIM); + } + resolve(longClaimId); + }).catch(function (error) { + reject(error); + }); + }); + }, + getChannelData: function getChannelData(channelName, channelClaimId, page) { + return new Promise(function (resolve, reject) { + // 1. get the long channel Id (make sure channel exists) + db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) { + if (!longChannelClaimId) { + return [null, null, null]; + } + // 2. get the short ID and all claims for that channel + return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]); + }).then(function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + longChannelClaimId = _ref4[0], + shortChannelClaimId = _ref4[1]; + + if (!longChannelClaimId) { + return resolve(NO_CHANNEL); + } + // 3. return all the channel information + resolve({ + channelName: channelName, + longChannelClaimId: longChannelClaimId, + shortChannelClaimId: shortChannelClaimId + }); + }).catch(function (error) { + reject(error); + }); + }); + }, + getChannelClaims: function getChannelClaims(channelName, channelClaimId, page) { + return new Promise(function (resolve, reject) { + // 1. get the long channel Id (make sure channel exists) + db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) { + if (!longChannelClaimId) { + return [null, null, null]; + } + // 2. get the short ID and all claims for that channel + return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]); + }).then(function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + longChannelClaimId = _ref6[0], + channelClaimsArray = _ref6[1]; + + if (!longChannelClaimId) { + return resolve(NO_CHANNEL); + } + // 3. format the data for the view, including pagination + var paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page); + // 4. return all the channel information and contents + resolve(paginatedChannelViewData); + }).catch(function (error) { + reject(error); + }); + }); + }, + getLocalFileRecord: function getLocalFileRecord(claimId, name) { + return db.File.findOne({ where: { claimId: claimId, name: name } }).then(function (file) { + if (!file) { + return NO_FILE; + } + return file.dataValues; + }); + } +}; + +/***/ }), +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _server = __webpack_require__(30); + +var _redux = __webpack_require__(18); + +var _index = __webpack_require__(31); + +var _index2 = _interopRequireDefault(_index); + +var _reactRedux = __webpack_require__(1); + +var _reactRouterDom = __webpack_require__(3); + +var _index3 = __webpack_require__(36); + +var _index4 = _interopRequireDefault(_index3); + +var _app = __webpack_require__(37); + +var _app2 = _interopRequireDefault(_app); + +var _renderFullPage = __webpack_require__(43); + +var _renderFullPage2 = _interopRequireDefault(_renderFullPage); + +var _reactHelmet = __webpack_require__(14); + +var _reactHelmet2 = _interopRequireDefault(_reactHelmet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +module.exports = function (req, res) { + var context = {}; + + // create a new Redux store instance + var store = (0, _redux.createStore)(_index2.default); + + // render component to a string + var html = (0, _server.renderToString)(_react2.default.createElement( + _reactRedux.Provider, + { store: store }, + _react2.default.createElement( + _reactRouterDom.StaticRouter, + { location: req.url, context: context }, + _react2.default.createElement( + _index4.default, + null, + _react2.default.createElement(_app2.default, null) + ) + ) + )); + + // get head tags from helmet + var helmet = _reactHelmet2.default.renderStatic(); + + // check for a redirect + if (context.url) { + // Somewhere a `` was rendered + return res.redirect(301, context.url); + } else {} + // we're good, send the response + + + // get the initial state from our Redux store + var preloadedState = store.getState(); + + // send the rendered page back to the client + res.send((0, _renderFullPage2.default)(helmet, html, preloadedState)); +}; + +/***/ }), +/* 30 */ +/***/ (function(module, exports) { + +module.exports = require("react-dom/server"); + +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _redux = __webpack_require__(18); + +var _publish = __webpack_require__(83); + +var _publish2 = _interopRequireDefault(_publish); + +var _channel = __webpack_require__(84); + +var _channel2 = _interopRequireDefault(_channel); + +var _show = __webpack_require__(85); + +var _show2 = _interopRequireDefault(_show); + +var _site = __webpack_require__(86); + +var _site2 = _interopRequireDefault(_site); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = (0, _redux.combineReducers)({ + channel: _channel2.default, + publish: _publish2.default, + show: _show2.default, + site: _site2.default +}); + +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var FILE_SELECTED = exports.FILE_SELECTED = 'FILE_SELECTED'; +var FILE_CLEAR = exports.FILE_CLEAR = 'FILE_CLEAR'; +var METADATA_UPDATE = exports.METADATA_UPDATE = 'METADATA_UPDATE'; +var CLAIM_UPDATE = exports.CLAIM_UPDATE = 'CLAIM_UPDATE'; +var SET_PUBLISH_IN_CHANNEL = exports.SET_PUBLISH_IN_CHANNEL = 'SET_PUBLISH_IN_CHANNEL'; +var PUBLISH_STATUS_UPDATE = exports.PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE'; +var ERROR_UPDATE = exports.ERROR_UPDATE = 'ERROR_UPDATE'; +var SELECTED_CHANNEL_UPDATE = exports.SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE'; +var TOGGLE_METADATA_INPUTS = exports.TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS'; +var THUMBNAIL_NEW = exports.THUMBNAIL_NEW = 'THUMBNAIL_NEW'; +var PUBLISH_START = exports.PUBLISH_START = 'PUBLISH_START'; + +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var LOGIN = exports.LOGIN = 'Existing'; +var CREATE = exports.CREATE = 'New'; + +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var CHANNEL_UPDATE = exports.CHANNEL_UPDATE = 'CHANNEL_UPDATE'; + +/***/ }), +/* 35 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var LOCAL_CHECK = exports.LOCAL_CHECK = 'LOCAL_CHECK'; +var UNAVAILABLE = exports.UNAVAILABLE = 'UNAVAILABLE'; +var ERROR = exports.ERROR = 'ERROR'; +var AVAILABLE = exports.AVAILABLE = 'AVAILABLE'; + +/***/ }), +/* 36 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactGa = __webpack_require__(87); + +var _reactGa2 = _interopRequireDefault(_reactGa); + +var _reactRouterDom = __webpack_require__(3); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _require = __webpack_require__(5), + googleId = _require.analytics.googleId; + +_reactGa2.default.initialize(googleId); + +var GAListener = function (_React$Component) { + _inherits(GAListener, _React$Component); + + function GAListener() { + _classCallCheck(this, GAListener); + + return _possibleConstructorReturn(this, (GAListener.__proto__ || Object.getPrototypeOf(GAListener)).apply(this, arguments)); + } + + _createClass(GAListener, [{ + key: 'componentDidMount', + value: function componentDidMount() { + this.sendPageView(this.props.history.location); + this.props.history.listen(this.sendPageView); + } + }, { + key: 'sendPageView', + value: function sendPageView(location) { + _reactGa2.default.set({ page: location.pathname }); + _reactGa2.default.pageview(location.pathname); + } + }, { + key: 'render', + value: function render() { + return this.props.children; + } + }]); + + return GAListener; +}(_react2.default.Component); + +exports.default = (0, _reactRouterDom.withRouter)(GAListener); + +/***/ }), +/* 37 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactRouterDom = __webpack_require__(3); + +var _HomePage = __webpack_require__(88); + +var _HomePage2 = _interopRequireDefault(_HomePage); + +var _AboutPage = __webpack_require__(125); + +var _AboutPage2 = _interopRequireDefault(_AboutPage); + +var _LoginPage = __webpack_require__(126); + +var _LoginPage2 = _interopRequireDefault(_LoginPage); + +var _ShowPage = __webpack_require__(128); + +var _ShowPage2 = _interopRequireDefault(_ShowPage); + +var _FourOhFourPage = __webpack_require__(145); + +var _FourOhFourPage2 = _interopRequireDefault(_FourOhFourPage); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// or use the provided local homepage +var App = function App() { + return _react2.default.createElement( + _reactRouterDom.Switch, + null, + _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/', component: _HomePage2.default }), + _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/about', component: _AboutPage2.default }), + _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/login', component: _LoginPage2.default }), + _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/:identifier/:claim', component: _ShowPage2.default }), + _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/:claim', component: _ShowPage2.default }), + _react2.default.createElement(_reactRouterDom.Route, { component: _FourOhFourPage2.default }) + ); +}; + +exports.default = App; + +/***/ }), +/* 38 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _publish = __webpack_require__(4); + +var _view = __webpack_require__(99); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var publish = _ref.publish; + + return { + file: publish.file, + thumbnail: publish.thumbnail, + fileError: publish.error.file + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + selectFile: function selectFile(file) { + dispatch((0, _publish.selectFile)(file)); + }, + setFileError: function setFileError(value) { + dispatch((0, _publish.clearFile)()); + dispatch((0, _publish.updateError)('file', value)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _channel = __webpack_require__(19); + +var _view = __webpack_require__(116); + +var _view2 = _interopRequireDefault(_view); + +var _publish = __webpack_require__(4); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + onChannelLogin: function onChannelLogin(name, shortId, longId) { + dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId)); + dispatch((0, _publish.updateSelectedChannel)(name)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(null, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _channel = __webpack_require__(19); + +var _view = __webpack_require__(117); + +var _view2 = _interopRequireDefault(_view); + +var _publish = __webpack_require__(4); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + onChannelLogin: function onChannelLogin(name, shortId, longId) { + dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId)); + dispatch((0, _publish.updateSelectedChannel)(name)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(null, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 41 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var CHANNEL = exports.CHANNEL = 'CHANNEL'; +var ASSET_LITE = exports.ASSET_LITE = 'ASSET_LITE'; +var ASSET_DETAILS = exports.ASSET_DETAILS = 'ASSET_DETAILS'; + +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(132); + +var _view2 = _interopRequireDefault(_view); + +var _show = __webpack_require__(8); + +var _show2 = __webpack_require__(13); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var show = _ref.show; + + // select error and status + var error = show.displayAsset.error; + var status = show.displayAsset.status; + // select asset + var asset = (0, _show2.selectAsset)(show); + // return props + return { + error: error, + status: status, + asset: asset + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + onFileRequest: function onFileRequest(name, claimId) { + dispatch((0, _show.fileRequested)(name, claimId)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 43 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function (helmet, html, preloadedState) { + // take the html and preloadedState and return the full page + return '\n \n \n \n \n \n \n \n ' + helmet.title.toString() + '\n ' + helmet.meta.toString() + '\n ' + helmet.link.toString() + '\n \n \n \n \n \n \n \n \n
\n
' + html + '
\n
\n \n \n \n \n '; +}; + +/***/ }), +/* 44 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var selectSiteState = exports.selectSiteState = function selectSiteState(state) { + return state.site; +}; + +var selectSiteHost = exports.selectSiteHost = function selectSiteHost(state) { + return state.site.host; +}; + +/***/ }), +/* 45 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(46); +__webpack_require__(47); +module.exports = __webpack_require__(48); + + +/***/ }), +/* 46 */ +/***/ (function(module, exports) { + +module.exports = require("babel-polyfill"); + +/***/ }), +/* 47 */ +/***/ (function(module, exports) { + +module.exports = require("whatwg-fetch"); + +/***/ }), +/* 48 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// app dependencies +var express = __webpack_require__(49); +var bodyParser = __webpack_require__(50); +var expressHandlebars = __webpack_require__(51); +var Handlebars = __webpack_require__(52); +var helmet = __webpack_require__(53); +var passport = __webpack_require__(22); + +var _require = __webpack_require__(54), + serializeSpeechUser = _require.serializeSpeechUser, + deserializeSpeechUser = _require.deserializeSpeechUser; + +var cookieSession = __webpack_require__(55); +var http = __webpack_require__(56); +// logging dependencies +var logger = __webpack_require__(2); +// configure logger +__webpack_require__(57)(logger); +__webpack_require__(59)(logger); + +var _require2 = __webpack_require__(5), + sessionKey = _require2.auth.sessionKey, + PORT = _require2.details.port; + +// create an Express application + + +var app = express(); // trust the proxy to get ip address for us app.enable('trust proxy'); // add middleware app.use(helmet()); // set HTTP headers to protect against well-known web vulnerabilties -app.use(express.static(`${__dirname}/public`)); // 'express.static' to serve static files from public directory +app.use(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((req, res, next) => { // custom logging middleware to log all incoming http requests - logger.verbose(`Request on ${req.originalUrl} from ${req.ip}`); +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); -const localSignupStrategy = require('./passport/local-signup.js'); -const localLoginStrategy = require('./passport/local-login.js'); +var localSignupStrategy = __webpack_require__(62); +var localLoginStrategy = __webpack_require__(74); passport.use('local-signup', localSignupStrategy); passport.use('local-login', localLoginStrategy); // initialize passport app.use(cookieSession({ - name : 'session', - keys : [config.session.sessionKey], - maxAge: 24 * 60 * 60 * 1000, // 24 hours + name: 'session', + keys: [sessionKey], + maxAge: 24 * 60 * 60 * 1000 // i.e. 24 hours })); app.use(passport.initialize()); app.use(passport.session()); // configure handlebars & register it with express app -const hbs = expressHandlebars.create({ - defaultLayout: 'embed', // sets the default layout - handlebars : Handlebars, // includes basic handlebars for access to that library +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); +// set the routes on the app +__webpack_require__(75)(app); +__webpack_require__(76)(app); +__webpack_require__(82)(app); +__webpack_require__(147)(app); +__webpack_require__(158)(app); +// create server +var server = http.Server(app); + +// sync sequelize +var db = __webpack_require__(6); +db.sequelize.sync() // start the server -db.sequelize - .sync() // sync sequelize - .then(() => { // require routes - require('./routes/auth-routes.js')(app); - require('./routes/api-routes.js')(app); - require('./routes/page-routes.js')(app); - require('./routes/serve-routes.js')(app); - require('./routes/fallback-routes.js')(app); - const http = require('http'); - return http.Server(app); - }) - .then(server => { // start the server - server.listen(PORT, () => { - logger.info('Trusting proxy?', app.get('trust proxy')); - logger.info(`Server is listening on PORT ${PORT}`); - }); - }) - .catch((error) => { - logger.error(`Startup Error >> ${error.message}`, error); +.then(function () { + server.listen(PORT, function () { + logger.info('Server is listening on PORT ' + PORT); }); +}).catch(function (error) { + logger.error('Startup Error:', error); +}); + +/***/ }), +/* 49 */ +/***/ (function(module, exports) { + +module.exports = require("express"); + +/***/ }), +/* 50 */ +/***/ (function(module, exports) { + +module.exports = require("body-parser"); + +/***/ }), +/* 51 */ +/***/ (function(module, exports) { + +module.exports = require("express-handlebars"); + +/***/ }), +/* 52 */ +/***/ (function(module, exports) { + +module.exports = require("handlebars"); + +/***/ }), +/* 53 */ +/***/ (function(module, exports) { + +module.exports = require("helmet"); + +/***/ }), +/* 54 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var logger = __webpack_require__(2); + +module.exports = { + serializeSpeechUser: function serializeSpeechUser(user, done) { + // returns user data to be serialized into session + logger.debug('serializing user'); + done(null, user); + }, + deserializeSpeechUser: function deserializeSpeechUser(user, done) { + // deserializes session and populates additional info to req.user + logger.debug('deserializing user'); + done(null, user); + } +}; + +/***/ }), +/* 55 */ +/***/ (function(module, exports) { + +module.exports = require("cookie-session"); + +/***/ }), +/* 56 */ +/***/ (function(module, exports) { + +module.exports = require("http"); + +/***/ }), +/* 57 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _require = __webpack_require__(58), + logLevel = _require.logLevel; + +module.exports = function (winston) { + // configure + winston.configure({ + transports: [new winston.transports.Console({ + level: logLevel, + timestamp: false, + colorize: true, + prettyPrint: true, + handleExceptions: true, + humanReadableUnhandledException: true + })] + }); + // test all the log levels + winston.error('Level 0'); + winston.warn('Level 1'); + winston.info('Level 2'); + winston.verbose('Level 3'); + winston.debug('Level 4'); + winston.silly('Level 5'); +}; + +/***/ }), +/* 58 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var loggerConfig = { + logLevel: 'debug' // options: silly, debug, verbose, info +}; + +module.exports = loggerConfig; + +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var winstonSlackWebHook = __webpack_require__(60).SlackWebHook; +var slackConfig = __webpack_require__(61); + +module.exports = function (winston) { + var slackWebHook = slackConfig.slackWebHook, + slackErrorChannel = slackConfig.slackErrorChannel, + slackInfoChannel = slackConfig.slackInfoChannel; + + if (slackWebHook) { + // add a transport for errors to slack + if (slackErrorChannel) { + winston.add(winstonSlackWebHook, { + name: 'slack-errors-transport', + level: 'warn', + webhookUrl: slackWebHook, + channel: slackErrorChannel, + username: 'spee.ch', + iconEmoji: ':face_with_head_bandage:' + }); + }; + if (slackInfoChannel) { + winston.add(winstonSlackWebHook, { + name: 'slack-info-transport', + level: 'info', + webhookUrl: slackWebHook, + channel: slackInfoChannel, + username: 'spee.ch', + iconEmoji: ':nerd_face:' + }); + }; + // send test message + winston.error('Slack "error" logging is online.'); + winston.info('Slack "info" logging is online.'); + } else { + winston.warn('Slack logging is not enabled because no slackWebHook config var provided.'); + } +}; + +/***/ }), +/* 60 */ +/***/ (function(module, exports) { + +module.exports = require("winston-slack-webhook"); + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function SlackConfig() { + this.slackWebHook = 'default'; + this.slackErrorChannel = 'default'; + this.slackInfoChannel = 'default'; +}; + +module.exports = new SlackConfig(); + +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var PassportLocalStrategy = __webpack_require__(23).Strategy; +var lbryApi = __webpack_require__(16); +var logger = __webpack_require__(2); +var db = __webpack_require__(6); + +module.exports = new PassportLocalStrategy({ + usernameField: 'username', + passwordField: 'password' +}, function (username, password, done) { + logger.verbose('new channel signup request. user: ' + username + ' pass: ' + password + ' .'); + var userInfo = {}; + // server-side validaton of inputs (username, password) + + // create the channel and retrieve the metadata + return lbryApi.createChannel('@' + username).then(function (tx) { + // create user record + var userData = { + userName: username, + password: password + }; + logger.verbose('userData >', userData); + // create user record + var channelData = { + channelName: '@' + username, + channelClaimId: tx.claim_id + }; + logger.verbose('channelData >', channelData); + // create certificate record + var certificateData = { + claimId: tx.claim_id, + name: '@' + username + // address, + }; + logger.verbose('certificateData >', certificateData); + // save user and certificate to db + return Promise.all([db.User.create(userData), db.Channel.create(channelData), db.Certificate.create(certificateData)]); + }).then(function (_ref) { + var _ref2 = _slicedToArray(_ref, 3), + newUser = _ref2[0], + newChannel = _ref2[1], + newCertificate = _ref2[2]; + + logger.verbose('user and certificate successfully created'); + // store the relevant newUser info to be passed back for req.User + userInfo['id'] = newUser.id; + userInfo['userName'] = newUser.userName; + userInfo['channelName'] = newChannel.channelName; + userInfo['channelClaimId'] = newChannel.channelClaimId; + // associate the instances + return Promise.all([newCertificate.setChannel(newChannel), newChannel.setUser(newUser)]); + }).then(function () { + logger.verbose('user and certificate successfully associated'); + return db.Certificate.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName); + }).then(function (shortChannelId) { + userInfo['shortChannelId'] = shortChannelId; + return done(null, userInfo); + }).catch(function (error) { + logger.error('signup error', error); + return done(error); + }); +}); + +/***/ }), +/* 63 */ +/***/ (function(module, exports) { + +module.exports = require("axios"); + +/***/ }), +/* 64 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var lbryConfig = { + api: { + apiHost: 'localhost', + apiPort: '5279' + } +}; + +module.exports = lbryConfig; + +/***/ }), +/* 65 */ +/***/ (function(module, exports) { + +module.exports = require("universal-analytics"); + +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function MysqlConfig() { + this.database = 'default'; + this.username = 'default'; + this.password = 'default'; +}; + +module.exports = new MysqlConfig(); + +/***/ }), +/* 67 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var logger = __webpack_require__(2); + +var _require = __webpack_require__(25), + returnShortId = _require.returnShortId; + +module.exports = function (sequelize, _ref) { + var STRING = _ref.STRING, + BOOLEAN = _ref.BOOLEAN, + INTEGER = _ref.INTEGER, + TEXT = _ref.TEXT, + DECIMAL = _ref.DECIMAL; + + var Certificate = sequelize.define('Certificate', { + address: { + type: STRING, + default: null + }, + amount: { + type: DECIMAL(19, 8), + default: null + }, + claimId: { + type: STRING, + default: null + }, + claimSequence: { + type: INTEGER, + default: null + }, + decodedClaim: { + type: BOOLEAN, + default: null + }, + depth: { + type: INTEGER, + default: null + }, + effectiveAmount: { + type: DECIMAL(19, 8), + default: null + }, + hasSignature: { + type: BOOLEAN, + default: null + }, + height: { + type: INTEGER, + default: null + }, + hex: { + type: TEXT('long'), + default: null + }, + name: { + type: STRING, + default: null + }, + nout: { + type: INTEGER, + default: null + }, + txid: { + type: STRING, + default: null + }, + validAtHeight: { + type: INTEGER, + default: null + }, + outpoint: { + type: STRING, + default: null + }, + valueVersion: { + type: STRING, + default: null + }, + claimType: { + type: STRING, + default: null + }, + certificateVersion: { + type: STRING, + default: null + }, + keyType: { + type: STRING, + default: null + }, + publicKey: { + type: TEXT('long'), + default: null + } + }, { + freezeTableName: true + }); + + Certificate.associate = function (db) { + Certificate.belongsTo(db.Channel, { + foreignKey: { + allowNull: true + } + }); + }; + + Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) { + var _this = this; + + logger.debug('getShortChannelIdFromLongChannelId ' + channelName + ':' + longChannelId); + return new Promise(function (resolve, reject) { + _this.findAll({ + where: { name: channelName }, + order: [['height', 'ASC']] + }).then(function (result) { + switch (result.length) { + case 0: + throw new Error('No channel(s) found with that channel name'); + default: + return resolve(returnShortId(result, longChannelId)); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) { + var _this2 = this; + + logger.debug('getLongChannelIdFromShortChannelId(' + channelName + ', ' + channelClaimId + ')'); + return new Promise(function (resolve, reject) { + _this2.findAll({ + where: { + name: channelName, + claimId: { + $like: channelClaimId + '%' + } + }, + order: [['height', 'ASC']] + }).then(function (result) { + switch (result.length) { + case 0: + return resolve(null); + default: + // note results must be sorted + return resolve(result[0].claimId); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + Certificate.getLongChannelIdFromChannelName = function (channelName) { + var _this3 = this; + + logger.debug('getLongChannelIdFromChannelName(' + channelName + ')'); + return new Promise(function (resolve, reject) { + _this3.findAll({ + where: { name: channelName }, + order: [['effectiveAmount', 'DESC'], ['height', 'ASC']] + }).then(function (result) { + switch (result.length) { + case 0: + return resolve(null); + default: + return resolve(result[0].claimId); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + Certificate.validateLongChannelId = function (name, claimId) { + var _this4 = this; + + logger.debug('validateLongChannelId(' + name + ', ' + claimId + ')'); + return new Promise(function (resolve, reject) { + _this4.findOne({ + where: { name: name, claimId: claimId } + }).then(function (result) { + if (!result) { + return resolve(null); + }; + resolve(claimId); + }).catch(function (error) { + reject(error); + }); + }); + }; + + Certificate.getLongChannelId = function (channelName, channelClaimId) { + logger.debug('getLongChannelId(' + channelName + ', ' + channelClaimId + ')'); + if (channelClaimId && channelClaimId.length === 40) { + // if a full channel id is provided + return this.validateLongChannelId(channelName, channelClaimId); + } else if (channelClaimId && channelClaimId.length < 40) { + // if a short channel id is provided + return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId); + } else { + return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided + } + }; + + return Certificate; +}; + +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function (sequelize, _ref) { + var STRING = _ref.STRING; + + var Channel = sequelize.define('Channel', { + channelName: { + type: STRING, + allowNull: false + }, + channelClaimId: { + type: STRING, + allowNull: false + } + }, { + freezeTableName: true + }); + + Channel.associate = function (db) { + Channel.belongsTo(db.User); + Channel.hasOne(db.Certificate); + }; + + return Channel; +}; + +/***/ }), +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var logger = __webpack_require__(2); + +var _require = __webpack_require__(25), + returnShortId = _require.returnShortId; + +var _require2 = __webpack_require__(5), + defaultThumbnail = _require2.assetDefaults.thumbnail, + host = _require2.details.host; + +function determineFileExtensionFromContentType(contentType) { + switch (contentType) { + case 'image/jpeg': + case 'image/jpg': + return 'jpeg'; + case 'image/png': + return 'png'; + case 'image/gif': + return 'gif'; + case 'video/mp4': + return 'mp4'; + default: + logger.debug('setting unknown file type as file extension jpeg'); + return 'jpeg'; + } +}; + +function determineThumbnail(storedThumbnail, defaultThumbnail) { + if (storedThumbnail === '') { + return defaultThumbnail; + } + return storedThumbnail; +}; + +function prepareClaimData(claim) { + // logger.debug('preparing claim data based on resolved data:', claim); + claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail); + claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType); + claim['host'] = host; + return claim; +}; + +module.exports = function (sequelize, _ref) { + var STRING = _ref.STRING, + BOOLEAN = _ref.BOOLEAN, + INTEGER = _ref.INTEGER, + TEXT = _ref.TEXT, + DECIMAL = _ref.DECIMAL; + + var Claim = sequelize.define('Claim', { + address: { + type: STRING, + default: null + }, + amount: { + type: DECIMAL(19, 8), + default: null + }, + claimId: { + type: STRING, + default: null + }, + claimSequence: { + type: INTEGER, + default: null + }, + decodedClaim: { + type: BOOLEAN, + default: null + }, + depth: { + type: INTEGER, + default: null + }, + effectiveAmount: { + type: DECIMAL(19, 8), + default: null + }, + hasSignature: { + type: BOOLEAN, + default: null + }, + height: { + type: INTEGER, + default: null + }, + hex: { + type: TEXT('long'), + default: null + }, + name: { + type: STRING, + default: null + }, + nout: { + type: INTEGER, + default: null + }, + txid: { + type: STRING, + default: null + }, + validAtHeight: { + type: INTEGER, + default: null + }, + outpoint: { + type: STRING, + default: null + }, + claimType: { + type: STRING, + default: null + }, + certificateId: { + type: STRING, + default: null + }, + author: { + type: STRING, + default: null + }, + description: { + type: TEXT('long'), + default: null + }, + language: { + type: STRING, + default: null + }, + license: { + type: STRING, + default: null + }, + licenseUrl: { + type: STRING, + default: null + }, + nsfw: { + type: BOOLEAN, + default: null + }, + preview: { + type: STRING, + default: null + }, + thumbnail: { + type: STRING, + default: null + }, + title: { + type: STRING, + default: null + }, + metadataVersion: { + type: STRING, + default: null + }, + contentType: { + type: STRING, + default: null + }, + source: { + type: STRING, + default: null + }, + sourceType: { + type: STRING, + default: null + }, + sourceVersion: { + type: STRING, + default: null + }, + streamVersion: { + type: STRING, + default: null + }, + valueVersion: { + type: STRING, + default: null + }, + channelName: { + type: STRING, + allowNull: true, + default: null + } + }, { + freezeTableName: true + }); + + Claim.associate = function (db) { + Claim.belongsTo(db.File, { + foreignKey: { + allowNull: true + } + }); + }; + + Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) { + var _this = this; + + logger.debug('Claim.getShortClaimIdFromLongClaimId for ' + claimName + '#' + claimId); + return new Promise(function (resolve, reject) { + _this.findAll({ + where: { name: claimName }, + order: [['height', 'ASC']] + }).then(function (result) { + switch (result.length) { + case 0: + throw new Error('No claim(s) found with that claim name'); + default: + resolve(returnShortId(result, claimId)); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + Claim.getAllChannelClaims = function (channelClaimId) { + var _this2 = this; + + logger.debug('Claim.getAllChannelClaims for ' + channelClaimId); + return new Promise(function (resolve, reject) { + _this2.findAll({ + where: { certificateId: channelClaimId }, + order: [['height', 'ASC']], + raw: true // returns an array of only data, not an array of instances + }).then(function (channelClaimsArray) { + // logger.debug('channelclaimsarray length:', channelClaimsArray.length); + switch (channelClaimsArray.length) { + case 0: + return resolve(null); + default: + channelClaimsArray.forEach(function (claim) { + claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType); + claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail); + return claim; + }); + return resolve(channelClaimsArray); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) { + var _this3 = this; + + logger.debug('finding claim id for claim ' + claimName + ' from channel ' + channelClaimId); + return new Promise(function (resolve, reject) { + _this3.findAll({ + where: { name: claimName, certificateId: channelClaimId }, + order: [['id', 'ASC']] + }).then(function (result) { + switch (result.length) { + case 0: + return resolve(null); + case 1: + return resolve(result[0].claimId); + default: + logger.error(result.length + ' records found for "' + claimName + '" in channel "' + channelClaimId + '"'); + return resolve(result[0].claimId); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + Claim.getLongClaimIdFromShortClaimId = function (name, shortId) { + var _this4 = this; + + return new Promise(function (resolve, reject) { + _this4.findAll({ + where: { + name: name, + claimId: { + $like: shortId + '%' + } }, + order: [['height', 'ASC']] + }).then(function (result) { + switch (result.length) { + case 0: + return resolve(null); + default: + // note results must be sorted + return resolve(result[0].claimId); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + Claim.getTopFreeClaimIdByClaimName = function (name) { + var _this5 = this; + + return new Promise(function (resolve, reject) { + _this5.findAll({ + where: { name: name }, + order: [['effectiveAmount', 'DESC'], ['height', 'ASC']] // note: maybe height and effective amount need to switch? + }).then(function (result) { + logger.debug('length of result', result.length); + switch (result.length) { + case 0: + return resolve(null); + default: + return resolve(result[0].dataValues.claimId); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + Claim.validateLongClaimId = function (name, claimId) { + var _this6 = this; + + return new Promise(function (resolve, reject) { + _this6.findOne({ + where: { name: name, claimId: claimId } + }).then(function (result) { + if (!result) { + return resolve(null); + }; + resolve(claimId); + }).catch(function (error) { + reject(error); + }); + }); + }; + + Claim.getLongClaimId = function (claimName, claimId) { + logger.debug('getLongClaimId(' + claimName + ', ' + claimId + ')'); + if (claimId && claimId.length === 40) { + // if a full claim id is provided + return this.validateLongClaimId(claimName, claimId); + } else if (claimId && claimId.length < 40) { + return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided + } else { + return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided + } + }; + + Claim.resolveClaim = function (name, claimId) { + var _this7 = this; + + logger.debug('Claim.resolveClaim: ' + name + ' ' + claimId); + return new Promise(function (resolve, reject) { + _this7.findAll({ + where: { name: name, claimId: claimId } + }).then(function (claimArray) { + switch (claimArray.length) { + case 0: + return resolve(null); + case 1: + return resolve(prepareClaimData(claimArray[0].dataValues)); + default: + logger.error('more than one record matches ' + name + '#' + claimId + ' in db.Claim'); + return resolve(prepareClaimData(claimArray[0].dataValues)); + } + }).catch(function (error) { + reject(error); + }); + }); + }; + + return Claim; +}; + +/***/ }), +/* 70 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function (sequelize, _ref) { + var STRING = _ref.STRING, + BOOLEAN = _ref.BOOLEAN, + INTEGER = _ref.INTEGER; + + var File = sequelize.define('File', { + name: { + type: STRING, + allowNull: false + }, + claimId: { + type: STRING, + allowNull: false + }, + address: { + type: STRING, + allowNull: false + }, + outpoint: { + type: STRING, + allowNull: false + }, + height: { + type: INTEGER, + allowNull: false, + default: 0 + }, + fileName: { + type: STRING, + allowNull: false + }, + filePath: { + type: STRING, + allowNull: false + }, + fileType: { + type: STRING + }, + nsfw: { + type: BOOLEAN, + allowNull: false, + defaultValue: false + }, + trendingEligible: { + type: BOOLEAN, + allowNull: false, + defaultValue: true + } + }, { + freezeTableName: true + }); + + File.associate = function (db) { + File.hasMany(db.Request); + File.hasOne(db.Claim); + }; + + File.getRecentClaims = function () { + return this.findAll({ + where: { nsfw: false, trendingEligible: true }, + order: [['createdAt', 'DESC']], + limit: 25 + }); + }; + + return File; +}; + +/***/ }), +/* 71 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function (sequelize, _ref) { + var STRING = _ref.STRING, + BOOLEAN = _ref.BOOLEAN, + TEXT = _ref.TEXT; + + var Request = sequelize.define('Request', { + action: { + type: STRING, + allowNull: false + }, + url: { + type: STRING, + allowNull: false + }, + ipAddress: { + type: STRING, + allowNull: true + }, + result: { + type: TEXT('long'), + allowNull: true, + default: null + } + }, { + freezeTableName: true + }); + + Request.associate = function (db) { + Request.belongsTo(db.File, { + foreignKey: { + allowNull: true + } + }); + }; + + return Request; +}; + +/***/ }), +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var bcrypt = __webpack_require__(73); +var logger = __webpack_require__(2); + +module.exports = function (sequelize, _ref) { + var STRING = _ref.STRING; + + var User = sequelize.define('User', { + userName: { + type: STRING, + allowNull: false + }, + password: { + type: STRING, + allowNull: false + } + }, { + freezeTableName: true + }); + + User.associate = function (db) { + User.hasOne(db.Channel); + }; + + User.prototype.comparePassword = function (password) { + return bcrypt.compare(password, this.password); + }; + + User.prototype.changePassword = function (newPassword) { + var _this = this; + + return new Promise(function (resolve, reject) { + // generate a salt string to use for hashing + bcrypt.genSalt(function (saltError, salt) { + if (saltError) { + logger.error('salt error', saltError); + reject(saltError); + return; + } + // generate a hashed version of the user's password + bcrypt.hash(newPassword, salt, function (hashError, hash) { + // if there is an error with the hash generation return the error + if (hashError) { + logger.error('hash error', hashError); + reject(hashError); + return; + } + // replace the current password with the new hash + _this.update({ password: hash }).then(function () { + resolve(); + }).catch(function (error) { + reject(error); + }); + }); + }); + }); + }; + + // pre-save hook method to hash the user's password before the user's info is saved to the db. + User.hook('beforeCreate', function (user, options) { + logger.debug('User.beforeCreate hook...'); + return new Promise(function (resolve, reject) { + // generate a salt string to use for hashing + bcrypt.genSalt(function (saltError, salt) { + if (saltError) { + logger.error('salt error', saltError); + reject(saltError); + return; + } + // generate a hashed version of the user's password + bcrypt.hash(user.password, salt, function (hashError, hash) { + // if there is an error with the hash generation return the error + if (hashError) { + logger.error('hash error', hashError); + reject(hashError); + return; + } + // replace the password string with the hash password value + user.password = hash; + resolve(); + }); + }); + }); + }); + + return User; +}; + +/***/ }), +/* 73 */ +/***/ (function(module, exports) { + +module.exports = require("bcrypt"); + +/***/ }), +/* 74 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var PassportLocalStrategy = __webpack_require__(23).Strategy; +var logger = __webpack_require__(2); +var db = __webpack_require__(6); + +var returnUserAndChannelInfo = function returnUserAndChannelInfo(userInstance) { + return new Promise(function (resolve, reject) { + var userInfo = {}; + userInfo['id'] = userInstance.id; + userInfo['userName'] = userInstance.userName; + userInstance.getChannel().then(function (_ref) { + var channelName = _ref.channelName, + channelClaimId = _ref.channelClaimId; + + userInfo['channelName'] = channelName; + userInfo['channelClaimId'] = channelClaimId; + return db.Certificate.getShortChannelIdFromLongChannelId(channelClaimId, channelName); + }).then(function (shortChannelId) { + userInfo['shortChannelId'] = shortChannelId; + resolve(userInfo); + }).catch(function (error) { + reject(error); + }); + }); +}; + +module.exports = new PassportLocalStrategy({ + usernameField: 'username', + passwordField: 'password' +}, function (username, password, done) { + return db.User.findOne({ + where: { userName: username } + }).then(function (user) { + if (!user) { + logger.debug('no user found'); + return done(null, false, { message: 'Incorrect username or password' }); + } + return user.comparePassword(password).then(function (isMatch) { + if (!isMatch) { + logger.debug('incorrect password'); + return done(null, false, { message: 'Incorrect username or password' }); + } + logger.debug('Password was a match, returning User'); + return returnUserAndChannelInfo(user).then(function (userInfo) { + return done(null, userInfo); + }).catch(function (error) { + return error; + }); + }).catch(function (error) { + return error; + }); + }).catch(function (error) { + return done(error); + }); +}); + +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var logger = __webpack_require__(2); +var passport = __webpack_require__(22); + +module.exports = function (app) { + // route for sign up + app.post('/signup', passport.authenticate('local-signup'), function (req, res) { + logger.verbose('successful signup for ' + req.user.channelName); + res.status(200).json({ + success: true, + channelName: req.user.channelName, + channelClaimId: req.user.channelClaimId, + shortChannelId: req.user.shortChannelId + }); + }); + // route for log in + app.post('/login', function (req, res, next) { + passport.authenticate('local-login', function (err, user, info) { + if (err) { + return next(err); + } + if (!user) { + return res.status(400).json({ + success: false, + message: info.message + }); + } + logger.debug('successful login'); + req.logIn(user, function (err) { + if (err) { + return next(err); + } + return res.status(200).json({ + success: true, + channelName: req.user.channelName, + channelClaimId: req.user.channelClaimId, + shortChannelId: req.user.shortChannelId + }); + }); + })(req, res, next); + }); + // route to log out + app.get('/logout', function (req, res) { + req.logout(); + res.status(200).json({ success: true, message: 'you successfully logged out' }); + }); + // see if user is authenticated, and return credentials if so + app.get('/user', function (req, res) { + if (req.user) { + res.status(200).json({ success: true, data: req.user }); + } else { + res.status(401).json({ success: false, message: 'user is not logged in' }); + } + }); +}; + +/***/ }), +/* 76 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var logger = __webpack_require__(2); +var multipart = __webpack_require__(77); + +var _require = __webpack_require__(5), + uploadDirectory = _require.publishing.uploadDirectory, + host = _require.details.host; + +var multipartMiddleware = multipart({ uploadDir: uploadDirectory }); +var db = __webpack_require__(6); + +var _require2 = __webpack_require__(78), + claimNameIsAvailable = _require2.claimNameIsAvailable, + checkChannelAvailability = _require2.checkChannelAvailability, + publish = _require2.publish; + +var _require3 = __webpack_require__(16), + getClaimList = _require3.getClaimList, + resolveUri = _require3.resolveUri, + getClaim = _require3.getClaim; + +var _require4 = __webpack_require__(26), + addGetResultsToFileData = _require4.addGetResultsToFileData, + createBasicPublishParams = _require4.createBasicPublishParams, + createThumbnailPublishParams = _require4.createThumbnailPublishParams, + parsePublishApiRequestBody = _require4.parsePublishApiRequestBody, + parsePublishApiRequestFiles = _require4.parsePublishApiRequestFiles, + createFileData = _require4.createFileData; + +var errorHandlers = __webpack_require__(27); + +var _require5 = __webpack_require__(17), + sendGATimingEvent = _require5.sendGATimingEvent; + +var _require6 = __webpack_require__(80), + authenticateUser = _require6.authenticateUser; + +var _require7 = __webpack_require__(28), + getChannelData = _require7.getChannelData, + getChannelClaims = _require7.getChannelClaims, + getClaimId = _require7.getClaimId; + +var NO_CHANNEL = 'NO_CHANNEL'; +var NO_CLAIM = 'NO_CLAIM'; + +module.exports = function (app) { + // route to check whether site has published to a channel + app.get('/api/channel/availability/:name', function (_ref, res) { + var ip = _ref.ip, + originalUrl = _ref.originalUrl, + name = _ref.params.name; + + var gaStartTime = Date.now(); + checkChannelAvailability(name).then(function (availableName) { + res.status(200).json(availableName); + sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now()); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + // route to get a short channel id from long channel Id + app.get('/api/channel/short-id/:longId/:name', function (_ref2, res) { + var ip = _ref2.ip, + originalUrl = _ref2.originalUrl, + params = _ref2.params; + + db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name).then(function (shortId) { + res.status(200).json(shortId); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + app.get('/api/channel/data/:channelName/:channelClaimId', function (_ref3, res) { + var ip = _ref3.ip, + originalUrl = _ref3.originalUrl, + body = _ref3.body, + params = _ref3.params; + + var channelName = params.channelName; + var channelClaimId = params.channelClaimId; + if (channelClaimId === 'none') channelClaimId = null; + getChannelData(channelName, channelClaimId, 0).then(function (data) { + if (data === NO_CHANNEL) { + return res.status(404).json({ success: false, message: 'No matching channel was found' }); + } + res.status(200).json({ success: true, data: data }); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + app.get('/api/channel/claims/:channelName/:channelClaimId/:page', function (_ref4, res) { + var ip = _ref4.ip, + originalUrl = _ref4.originalUrl, + body = _ref4.body, + params = _ref4.params; + + var channelName = params.channelName; + var channelClaimId = params.channelClaimId; + if (channelClaimId === 'none') channelClaimId = null; + var page = params.page; + getChannelClaims(channelName, channelClaimId, page).then(function (data) { + if (data === NO_CHANNEL) { + return res.status(404).json({ success: false, message: 'No matching channel was found' }); + } + res.status(200).json({ success: true, data: data }); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + // route to run a claim_list request on the daemon + app.get('/api/claim/list/:name', function (_ref5, res) { + var ip = _ref5.ip, + originalUrl = _ref5.originalUrl, + params = _ref5.params; + + getClaimList(params.name).then(function (claimsList) { + res.status(200).json(claimsList); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + // route to get an asset + app.get('/api/claim/get/:name/:claimId', function (_ref6, res) { + var ip = _ref6.ip, + originalUrl = _ref6.originalUrl, + params = _ref6.params; + + var name = params.name; + var claimId = params.claimId; + // resolve the claim + db.Claim.resolveClaim(name, claimId).then(function (resolveResult) { + // make sure a claim actually exists at that uri + if (!resolveResult) { + throw new Error('No matching uri found in Claim table'); + } + var fileData = createFileData(resolveResult); + // get the claim + return Promise.all([fileData, getClaim(name + '#' + claimId)]); + }).then(function (_ref7) { + var _ref8 = _slicedToArray(_ref7, 2), + fileData = _ref8[0], + getResult = _ref8[1]; + + fileData = addGetResultsToFileData(fileData, getResult); + return Promise.all([db.upsert(db.File, fileData, { name: name, claimId: claimId }, 'File'), getResult]); + }).then(function (_ref9) { + var _ref10 = _slicedToArray(_ref9, 2), + fileRecord = _ref10[0], + _ref10$ = _ref10[1], + message = _ref10$.message, + completed = _ref10$.completed; + + res.status(200).json({ success: true, message: message, completed: completed }); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + // route to check whether this site published to a claim + app.get('/api/claim/availability/:name', function (_ref11, res) { + var ip = _ref11.ip, + originalUrl = _ref11.originalUrl, + name = _ref11.params.name; + + var gaStartTime = Date.now(); + claimNameIsAvailable(name).then(function (result) { + res.status(200).json(result); + sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now()); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + // route to run a resolve request on the daemon + app.get('/api/claim/resolve/:name/:claimId', function (_ref12, res) { + var headers = _ref12.headers, + ip = _ref12.ip, + originalUrl = _ref12.originalUrl, + params = _ref12.params; + + resolveUri(params.name + '#' + params.claimId).then(function (resolvedUri) { + res.status(200).json(resolvedUri); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + // route to run a publish request on the daemon + app.post('/api/claim/publish', multipartMiddleware, function (_ref13, res) { + var body = _ref13.body, + files = _ref13.files, + headers = _ref13.headers, + ip = _ref13.ip, + originalUrl = _ref13.originalUrl, + user = _ref13.user; + + // define variables + var channelName = void 0, + channelId = void 0, + channelPassword = void 0, + description = void 0, + fileName = void 0, + filePath = void 0, + fileType = void 0, + gaStartTime = void 0, + license = void 0, + name = void 0, + nsfw = void 0, + thumbnail = void 0, + thumbnailFileName = void 0, + thumbnailFilePath = void 0, + thumbnailFileType = void 0, + title = void 0; + // record the start time of the request + gaStartTime = Date.now(); + // validate the body and files of the request + try { + var _parsePublishApiReque = parsePublishApiRequestBody(body); + // validateApiPublishRequest(body, files); + + + name = _parsePublishApiReque.name; + nsfw = _parsePublishApiReque.nsfw; + license = _parsePublishApiReque.license; + title = _parsePublishApiReque.title; + description = _parsePublishApiReque.description; + thumbnail = _parsePublishApiReque.thumbnail; + + var _parsePublishApiReque2 = parsePublishApiRequestFiles(files); + + fileName = _parsePublishApiReque2.fileName; + filePath = _parsePublishApiReque2.filePath; + fileType = _parsePublishApiReque2.fileType; + thumbnailFileName = _parsePublishApiReque2.thumbnailFileName; + thumbnailFilePath = _parsePublishApiReque2.thumbnailFilePath; + thumbnailFileType = _parsePublishApiReque2.thumbnailFileType; + channelName = body.channelName; + channelId = body.channelId; + channelPassword = body.channelPassword; + } catch (error) { + return res.status(400).json({ success: false, message: error.message }); + } + // check channel authorization + Promise.all([authenticateUser(channelName, channelId, channelPassword, user), claimNameIsAvailable(name), createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail), createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw)]).then(function (_ref14) { + var _ref15 = _slicedToArray(_ref14, 4), + _ref15$ = _ref15[0], + channelName = _ref15$.channelName, + channelClaimId = _ref15$.channelClaimId, + validatedClaimName = _ref15[1], + publishParams = _ref15[2], + thumbnailPublishParams = _ref15[3]; + + // add channel details to the publish params + if (channelName && channelClaimId) { + publishParams['channel_name'] = channelName; + publishParams['channel_id'] = channelClaimId; + } + // publish the thumbnail + if (thumbnailPublishParams) { + publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType); + } + // publish the asset + return publish(publishParams, fileName, fileType); + }).then(function (result) { + res.status(200).json({ + success: true, + message: 'publish completed successfully', + data: { + name: name, + claimId: result.claim_id, + url: host + '/' + result.claim_id + '/' + name, + lbryTx: result + } + }); + // record the publish end time and send to google analytics + sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now()); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + // route to get a short claim id from long claim Id + app.get('/api/claim/short-id/:longId/:name', function (_ref16, res) { + var ip = _ref16.ip, + originalUrl = _ref16.originalUrl, + body = _ref16.body, + params = _ref16.params; + + db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name).then(function (shortId) { + res.status(200).json({ success: true, data: shortId }); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + app.post('/api/claim/long-id', function (_ref17, res) { + var ip = _ref17.ip, + originalUrl = _ref17.originalUrl, + body = _ref17.body, + params = _ref17.params; + + logger.debug('body:', body); + var channelName = body.channelName; + var channelClaimId = body.channelClaimId; + var claimName = body.claimName; + var claimId = body.claimId; + getClaimId(channelName, channelClaimId, claimName, claimId).then(function (result) { + if (result === NO_CHANNEL) { + return res.status(404).json({ success: false, message: 'No matching channel could be found' }); + } + if (result === NO_CLAIM) { + return res.status(404).json({ success: false, message: 'No matching claim id could be found' }); + } + res.status(200).json({ success: true, data: result }); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + app.get('/api/claim/data/:claimName/:claimId', function (_ref18, res) { + var ip = _ref18.ip, + originalUrl = _ref18.originalUrl, + body = _ref18.body, + params = _ref18.params; + + var claimName = params.claimName; + var claimId = params.claimId; + if (claimId === 'none') claimId = null; + db.Claim.resolveClaim(claimName, claimId).then(function (claimInfo) { + if (!claimInfo) { + return res.status(404).json({ success: false, message: 'No claim could be found' }); + } + res.status(200).json({ success: true, data: claimInfo }); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); + // route to see if asset is available locally + app.get('/api/file/availability/:name/:claimId', function (_ref19, res) { + var ip = _ref19.ip, + originalUrl = _ref19.originalUrl, + params = _ref19.params; + + var name = params.name; + var claimId = params.claimId; + db.File.findOne({ where: { name: name, claimId: claimId } }).then(function (result) { + if (result) { + return res.status(200).json({ success: true, data: true }); + } + res.status(200).json({ success: true, data: false }); + }).catch(function (error) { + errorHandlers.handleErrorResponse(originalUrl, ip, error, res); + }); + }); +}; + +/***/ }), +/* 77 */ +/***/ (function(module, exports) { + +module.exports = require("connect-multiparty"); + +/***/ }), +/* 78 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var logger = __webpack_require__(2); +var db = __webpack_require__(6); +var lbryApi = __webpack_require__(16); +var publishHelpers = __webpack_require__(26); + +var _require = __webpack_require__(5), + _require$publishing = _require.publishing, + primaryClaimAddress = _require$publishing.primaryClaimAddress, + additionalClaimAddresses = _require$publishing.additionalClaimAddresses; + +var Sequelize = __webpack_require__(24); +var Op = Sequelize.Op; + +module.exports = { + publish: function publish(publishParams, fileName, fileType) { + return new Promise(function (resolve, reject) { + var publishResults = void 0, + certificateId = void 0, + channelName = void 0; + // publish the file + return lbryApi.publishClaim(publishParams).then(function (tx) { + logger.info('Successfully published ' + publishParams.name + ' ' + fileName, tx); + publishResults = tx; + // get the channel information + if (publishParams.channel_name) { + logger.debug('this claim was published in channel: ' + publishParams.channel_name); + return db.Channel.findOne({ where: { channelName: publishParams.channel_name } }); + } else { + logger.debug('this claim was not published in a channel'); + return null; + } + }).then(function (channel) { + // set channel information + certificateId = null; + channelName = null; + if (channel) { + certificateId = channel.channelClaimId; + channelName = channel.channelName; + } + logger.debug('certificateId: ' + certificateId); + }).then(function () { + // create the File record + var fileRecord = { + name: publishParams.name, + claimId: publishResults.claim_id, + title: publishParams.metadata.title, + description: publishParams.metadata.description, + address: publishParams.claim_address, + outpoint: publishResults.txid + ':' + publishResults.nout, + height: 0, + fileName: fileName, + filePath: publishParams.file_path, + fileType: fileType, + nsfw: publishParams.metadata.nsfw + }; + // create the Claim record + var claimRecord = { + name: publishParams.name, + claimId: publishResults.claim_id, + title: publishParams.metadata.title, + description: publishParams.metadata.description, + address: publishParams.claim_address, + thumbnail: publishParams.metadata.thumbnail, + outpoint: publishResults.txid + ':' + publishResults.nout, + height: 0, + contentType: fileType, + nsfw: publishParams.metadata.nsfw, + amount: publishParams.bid, + certificateId: certificateId, + channelName: channelName + }; + // upsert criteria + var upsertCriteria = { + name: publishParams.name, + claimId: publishResults.claim_id + }; + // upsert the records + return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]); + }).then(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + file = _ref2[0], + claim = _ref2[1]; + + logger.debug('File and Claim records successfully created'); + return Promise.all([file.setClaim(claim), claim.setFile(file)]); + }).then(function () { + logger.debug('File and Claim records successfully associated'); + resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim; + }).catch(function (error) { + logger.error('PUBLISH ERROR', error); + publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file + reject(error); + }); + }); + }, + claimNameIsAvailable: function claimNameIsAvailable(name) { + var claimAddresses = additionalClaimAddresses || []; + claimAddresses.push(primaryClaimAddress); + // find any records where the name is used + return db.Claim.findAll({ + attributes: ['address'], + where: { + name: name, + address: _defineProperty({}, Op.or, claimAddresses) + } + }).then(function (result) { + if (result.length >= 1) { + throw new Error('That claim is already in use'); + }; + return name; + }).catch(function (error) { + throw error; + }); + }, + checkChannelAvailability: function checkChannelAvailability(name) { + return db.Channel.findAll({ + where: { channelName: name } + }).then(function (result) { + if (result.length >= 1) { + throw new Error('That channel has already been claimed'); + } + return name; + }).catch(function (error) { + throw error; + }); + } +}; + +/***/ }), +/* 79 */ +/***/ (function(module, exports) { + +module.exports = require("fs"); + +/***/ }), +/* 80 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var db = __webpack_require__(6); +var logger = __webpack_require__(2); + +module.exports = { + authenticateUser: function authenticateUser(channelName, channelId, channelPassword, user) { + // case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided + if (!channelName && !channelId) { + return { + channelName: null, + channelClaimId: null + }; + } + // case: channelName or channel Id are provided with user token + if (user) { + if (channelName && channelName !== user.channelName) { + throw new Error('the provided channel name does not match user credentials'); + } + if (channelId && channelId !== user.channelClaimId) { + throw new Error('the provided channel id does not match user credentials'); + } + return { + channelName: user.channelName, + channelClaimId: user.channelClaimId + }; + } + // case: channelName or channel Id are provided with password instead of user token + if (!channelPassword) throw new Error('no channel password provided'); + return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword); + }, + authenticateChannelCredentials: function authenticateChannelCredentials(channelName, channelId, userPassword) { + return new Promise(function (resolve, reject) { + // hoisted variables + var channelData = void 0; + // build the params for finding the channel + var channelFindParams = {}; + if (channelName) channelFindParams['channelName'] = channelName; + if (channelId) channelFindParams['channelClaimId'] = channelId; + // find the channel + db.Channel.findOne({ + where: channelFindParams + }).then(function (channel) { + if (!channel) { + logger.debug('no channel found'); + throw new Error('Authentication failed, you do not have access to that channel'); + } + channelData = channel.get(); + logger.debug('channel data:', channelData); + return db.User.findOne({ + where: { userName: channelData.channelName.substring(1) } + }); + }).then(function (user) { + if (!user) { + logger.debug('no user found'); + throw new Error('Authentication failed, you do not have access to that channel'); + } + return user.comparePassword(userPassword); + }).then(function (isMatch) { + if (!isMatch) { + logger.debug('incorrect password'); + throw new Error('Authentication failed, you do not have access to that channel'); + } + logger.debug('...password was a match...'); + resolve(channelData); + }).catch(function (error) { + reject(error); + }); + }); + } +}; + +/***/ }), +/* 81 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var CLAIMS_PER_PAGE = 12; + +module.exports = { + returnPaginatedChannelClaims: function returnPaginatedChannelClaims(channelName, longChannelClaimId, claims, page) { + var totalPages = module.exports.determineTotalPages(claims); + var paginationPage = module.exports.getPageFromQuery(page); + var viewData = { + channelName: channelName, + longChannelClaimId: longChannelClaimId, + claims: module.exports.extractPageFromClaims(claims, paginationPage), + previousPage: module.exports.determinePreviousPage(paginationPage), + currentPage: paginationPage, + nextPage: module.exports.determineNextPage(totalPages, paginationPage), + totalPages: totalPages, + totalResults: module.exports.determineTotalClaims(claims) + }; + return viewData; + }, + getPageFromQuery: function getPageFromQuery(page) { + if (page) { + return parseInt(page); + } + return 1; + }, + extractPageFromClaims: function extractPageFromClaims(claims, pageNumber) { + if (!claims) { + return []; // if no claims, return this default + } + // logger.debug('claims is array?', Array.isArray(claims)); + // logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber)); + var claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE; + var claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE; + var pageOfClaims = claims.slice(claimStartIndex, claimEndIndex); + return pageOfClaims; + }, + determineTotalPages: function determineTotalPages(claims) { + if (!claims) { + return 0; + } else { + var totalClaims = claims.length; + if (totalClaims < CLAIMS_PER_PAGE) { + return 1; + } + var fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE); + var remainder = totalClaims % CLAIMS_PER_PAGE; + if (remainder === 0) { + return fullPages; + } + return fullPages + 1; + } + }, + determinePreviousPage: function determinePreviousPage(currentPage) { + if (currentPage === 1) { + return null; + } + return currentPage - 1; + }, + determineNextPage: function determineNextPage(totalPages, currentPage) { + if (currentPage === totalPages) { + return null; + } + return currentPage + 1; + }, + determineTotalClaims: function determineTotalClaims(claims) { + if (!claims) { + return 0; + } + return claims.length; + } +}; + +/***/ }), +/* 82 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _require = __webpack_require__(5), + host = _require.details; + +var handlePageRender = __webpack_require__(29); + +module.exports = function (app) { + // route for the home page + app.get('/', function (req, res) { + handlePageRender(req, res); + }); + // route to display login page + app.get('/login', function (req, res) { + handlePageRender(req, res); + }); + // route to show 'about' page + app.get('/about', function (req, res) { + handlePageRender(req, res); + }); + // route to display a list of the trending images + app.get('/trending', function (req, res) { + res.status(301).redirect('/popular'); + }); + app.get('/popular', function (req, res) { + handlePageRender(req, res); + }); + // route to display a list of the trending images + app.get('/new', function (req, res) { + handlePageRender(req, res); + }); + // route to send embedable video player (for twitter) + app.get('/embed/:claimId/:name', function (_ref, res) { + var params = _ref.params; + + var claimId = params.claimId; + var name = params.name; + // get and render the content + res.status(200).render('embed', { layout: 'embed', host: host, claimId: claimId, name: name }); + }); +}; + +/***/ }), +/* 83 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function () { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + var action = arguments[1]; + + switch (action.type) { + case actions.FILE_SELECTED: + return Object.assign({}, initialState, { // note: clears to initial state + file: action.data + }); + case actions.FILE_CLEAR: + return initialState; + case actions.METADATA_UPDATE: + return Object.assign({}, state, { + metadata: Object.assign({}, state.metadata, _defineProperty({}, action.data.name, action.data.value)) + }); + case actions.CLAIM_UPDATE: + return Object.assign({}, state, { + claim: action.data + }); + case actions.SET_PUBLISH_IN_CHANNEL: + return Object.assign({}, state, { + publishInChannel: action.channel + }); + case actions.PUBLISH_STATUS_UPDATE: + return Object.assign({}, state, { + status: action.data + }); + case actions.ERROR_UPDATE: + return Object.assign({}, state, { + error: Object.assign({}, state.error, _defineProperty({}, action.data.name, action.data.value)) + }); + case actions.SELECTED_CHANNEL_UPDATE: + return Object.assign({}, state, { + selectedChannel: action.data + }); + case actions.TOGGLE_METADATA_INPUTS: + return Object.assign({}, state, { + showMetadataInputs: action.data + }); + case actions.THUMBNAIL_NEW: + return Object.assign({}, state, { + thumbnail: action.data + }); + default: + return state; + } +}; + +var _publish_action_types = __webpack_require__(32); + +var actions = _interopRequireWildcard(_publish_action_types); + +var _publish_channel_select_states = __webpack_require__(33); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var _require = __webpack_require__(5), + publishing = _require.publishing; + +var initialState = { + disabled: publishing.disabled, + disabledMessage: publishing.disabledMessage, + publishInChannel: false, + selectedChannel: _publish_channel_select_states.LOGIN, + showMetadataInputs: false, + status: { + status: null, + message: null + }, + error: { + file: null, + url: null, + channel: null, + publishSubmit: null + }, + file: null, + claim: '', + metadata: { + title: '', + description: '', + license: '', + nsfw: false + }, + thumbnail: null +}; + +/***/ }), +/* 84 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function () { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + var action = arguments[1]; + + switch (action.type) { + case actions.CHANNEL_UPDATE: + return Object.assign({}, state, { + loggedInChannel: action.data + }); + default: + return state; + } +}; + +var _channel_action_types = __webpack_require__(34); + +var actions = _interopRequireWildcard(_channel_action_types); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var initialState = { + loggedInChannel: { + name: null, + shortId: null, + longId: null + } +}; + +/***/ }), +/* 85 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function () { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + var action = arguments[1]; + + switch (action.type) { + // handle request + case actions.REQUEST_ERROR: + return Object.assign({}, state, { + request: Object.assign({}, state.request, { + error: action.data + }) + }); + case actions.REQUEST_UPDATE: + return Object.assign({}, state, { + request: Object.assign({}, state.request, { + type: action.data.requestType, + id: action.data.requestId + }) + }); + // store requests + case actions.REQUEST_LIST_ADD: + return Object.assign({}, state, { + requestList: Object.assign({}, state.requestList, _defineProperty({}, action.data.id, { + error: action.data.error, + key: action.data.key + })) + }); + // asset data + case actions.ASSET_ADD: + return Object.assign({}, state, { + assetList: Object.assign({}, state.assetList, _defineProperty({}, action.data.id, { + error: action.data.error, + name: action.data.name, + claimId: action.data.claimId, + shortId: action.data.shortId, + claimData: action.data.claimData + })) + }); + // channel data + case actions.CHANNEL_ADD: + return Object.assign({}, state, { + channelList: Object.assign({}, state.channelList, _defineProperty({}, action.data.id, { + name: action.data.name, + longId: action.data.longId, + shortId: action.data.shortId, + claimsData: action.data.claimsData + })) + }); + case actions.CHANNEL_CLAIMS_UPDATE_SUCCESS: + return Object.assign({}, state, { + channelList: Object.assign({}, state.channelList, _defineProperty({}, action.data.channelListId, Object.assign({}, state.channelList[action.data.channelListId], { + claimsData: action.data.claimsData + }))) + }); + // display an asset + case actions.FILE_AVAILABILITY_UPDATE: + return Object.assign({}, state, { + displayAsset: Object.assign({}, state.displayAsset, { + status: action.data + }) + }); + case actions.DISPLAY_ASSET_ERROR: + return Object.assign({}, state, { + displayAsset: Object.assign({}, state.displayAsset, { + error: action.data, + status: _asset_display_states.ERROR + }) + }); + default: + return state; + } +}; + +var _show_action_types = __webpack_require__(12); + +var actions = _interopRequireWildcard(_show_action_types); + +var _asset_display_states = __webpack_require__(35); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var initialState = { + request: { + error: null, + type: null, + id: null + }, + requestList: {}, + channelList: {}, + assetList: {}, + displayAsset: { + error: null, + status: _asset_display_states.LOCAL_CHECK + } +}; + +/***/ }), +/* 86 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function () { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; + var action = arguments[1]; + + switch (action.type) { + default: + return state; + } +}; + +var siteConfig = __webpack_require__(5); + +var googleAnalyticsId = siteConfig.analytics.googleId, + _siteConfig$assetDefa = siteConfig.assetDefaults, + defaultThumbnail = _siteConfig$assetDefa.thumbnail, + defaultDescription = _siteConfig$assetDefa.description, + _siteConfig$details = siteConfig.details, + description = _siteConfig$details.description, + host = _siteConfig$details.host, + title = _siteConfig$details.title, + twitter = _siteConfig$details.twitter; + + +var initialState = { + description: description, + googleAnalyticsId: googleAnalyticsId, + host: host, + title: title, + twitter: twitter, + defaultDescription: defaultDescription, + defaultThumbnail: defaultThumbnail +}; + +/***/ }), +/* 87 */ +/***/ (function(module, exports) { + +module.exports = require("react-ga"); + +/***/ }), +/* 88 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _SEO = __webpack_require__(9); + +var _SEO2 = _interopRequireDefault(_SEO); + +var _NavBar = __webpack_require__(7); + +var _NavBar2 = _interopRequireDefault(_NavBar); + +var _PublishTool = __webpack_require__(97); + +var _PublishTool2 = _interopRequireDefault(_PublishTool); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var HomePage = function (_React$Component) { + _inherits(HomePage, _React$Component); + + function HomePage() { + _classCallCheck(this, HomePage); + + return _possibleConstructorReturn(this, (HomePage.__proto__ || Object.getPrototypeOf(HomePage)).apply(this, arguments)); + } + + _createClass(HomePage, [{ + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + { className: 'row row--tall flex-container--column' }, + _react2.default.createElement(_SEO2.default, null), + _react2.default.createElement(_NavBar2.default, null), + _react2.default.createElement( + 'div', + { className: 'row row--tall row--padded flex-container--column' }, + _react2.default.createElement(_PublishTool2.default, null) + ) + ); + } + }]); + + return HomePage; +}(_react2.default.Component); + +; + +exports.default = HomePage; + +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactHelmet = __webpack_require__(14); + +var _reactHelmet2 = _interopRequireDefault(_reactHelmet); + +var _propTypes = __webpack_require__(10); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +var _pageTitle = __webpack_require__(90); + +var _metaTags = __webpack_require__(91); + +var _canonicalLink = __webpack_require__(92); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var SEO = function (_React$Component) { + _inherits(SEO, _React$Component); + + function SEO() { + _classCallCheck(this, SEO); + + return _possibleConstructorReturn(this, (SEO.__proto__ || Object.getPrototypeOf(SEO)).apply(this, arguments)); + } + + _createClass(SEO, [{ + key: 'render', + value: function render() { + // props from state + var _props = this.props, + defaultDescription = _props.defaultDescription, + defaultThumbnail = _props.defaultThumbnail, + siteDescription = _props.siteDescription, + siteHost = _props.siteHost, + siteTitle = _props.siteTitle, + siteTwitter = _props.siteTwitter; + // props from parent + + var _props2 = this.props, + asset = _props2.asset, + channel = _props2.channel, + pageUri = _props2.pageUri; + var pageTitle = this.props.pageTitle; + // create page title, tags, and canonical link + + pageTitle = (0, _pageTitle.createPageTitle)(siteTitle, pageTitle); + var metaTags = (0, _metaTags.createMetaTags)(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail); + var canonicalLink = (0, _canonicalLink.createCanonicalLink)(asset, channel, pageUri, siteHost); + // render results + return _react2.default.createElement(_reactHelmet2.default, { + title: pageTitle, + meta: metaTags, + link: [{ rel: 'canonical', href: canonicalLink }] + }); + } + }]); + + return SEO; +}(_react2.default.Component); + +; + +SEO.propTypes = { + pageTitle: _propTypes2.default.string, + pageUri: _propTypes2.default.string, + channel: _propTypes2.default.object, + asset: _propTypes2.default.object +}; + +exports.default = SEO; + +/***/ }), +/* 90 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var createPageTitle = exports.createPageTitle = function createPageTitle(siteTitle, pageTitle) { + if (!pageTitle) { + return "" + siteTitle; + } + return siteTitle + " - " + pageTitle; +}; + +/***/ }), +/* 91 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var determineOgThumbnailContentType = function determineOgThumbnailContentType(thumbnail) { + if (thumbnail) { + var fileExt = thumbnail.substring(thumbnail.lastIndexOf('.')); + switch (fileExt) { + case 'jpeg': + case 'jpg': + return 'image/jpeg'; + case 'png': + return 'image/png'; + case 'gif': + return 'image/gif'; + case 'mp4': + return 'video/mp4'; + default: + return 'image/jpeg'; + } + } + return ''; +}; + +var createBasicMetaTags = function createBasicMetaTags(siteHost, siteDescription, siteTitle, siteTwitter) { + return [{ property: 'og:title', content: siteTitle }, { property: 'og:url', content: siteHost }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: siteDescription }, { property: 'twitter:site', content: siteTwitter }, { property: 'twitter:card', content: 'summary' }]; +}; + +var createChannelMetaTags = function createChannelMetaTags(siteTitle, siteHost, siteTwitter, channel) { + var name = channel.name, + longId = channel.longId; + + return [{ property: 'og:title', content: name + ' on ' + siteTitle }, { property: 'og:url', content: siteHost + '/' + name + ':' + longId }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: name + ', a channel on ' + siteTitle }, { property: 'twitter:site', content: siteTwitter }, { property: 'twitter:card', content: 'summary' }]; +}; + +var createAssetMetaTags = function createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail) { + var claimData = asset.claimData; + var contentType = claimData.contentType; + + var embedUrl = siteHost + '/' + claimData.claimId + '/' + claimData.name; + var showUrl = siteHost + '/' + claimData.claimId + '/' + claimData.name; + var source = siteHost + '/' + claimData.claimId + '/' + claimData.name + '.' + claimData.fileExt; + var ogTitle = claimData.title || claimData.name; + var ogDescription = claimData.description || defaultDescription; + var ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail); + var ogThumbnail = claimData.thumbnail || defaultThumbnail; + var metaTags = [{ property: 'og:title', content: ogTitle }, { property: 'og:url', content: showUrl }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: ogDescription }, { property: 'og:image:width', content: 600 }, { property: 'og:image:height', content: 315 }, { property: 'twitter:site', content: siteTwitter }]; + if (contentType === 'video/mp4' || contentType === 'video/webm') { + metaTags.push({ property: 'og:video', content: source }); + metaTags.push({ property: 'og:video:secure_url', content: source }); + metaTags.push({ property: 'og:video:type', content: contentType }); + metaTags.push({ property: 'og:image', content: ogThumbnail }); + metaTags.push({ property: 'og:image:type', content: ogThumbnailContentType }); + metaTags.push({ property: 'og:type', content: 'video' }); + metaTags.push({ property: 'twitter:card', content: 'player' }); + metaTags.push({ property: 'twitter:player', content: embedUrl }); + metaTags.push({ property: 'twitter:player:width', content: 600 }); + metaTags.push({ property: 'twitter:text:player_width', content: 600 }); + metaTags.push({ property: 'twitter:player:height', content: 337 }); + metaTags.push({ property: 'twitter:player:stream', content: source }); + metaTags.push({ property: 'twitter:player:stream:content_type', content: contentType }); + } else { + metaTags.push({ property: 'og:image', content: source }); + metaTags.push({ property: 'og:image:type', content: contentType }); + metaTags.push({ property: 'og:type', content: 'article' }); + metaTags.push({ property: 'twitter:card', content: 'summary_large_image' }); + } + return metaTags; +}; + +var createMetaTags = exports.createMetaTags = function createMetaTags(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail) { + if (asset) { + return createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail); + }; + if (channel) { + return createChannelMetaTags(siteHost, siteTitle, siteTwitter, channel); + }; + return createBasicMetaTags(siteDescription, siteHost, siteTitle, siteTwitter); +}; + +/***/ }), +/* 92 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var createBasicCanonicalLink = function createBasicCanonicalLink(page, siteHost) { + return siteHost + "/" + page; +}; + +var createAssetCanonicalLink = function createAssetCanonicalLink(asset, siteHost) { + var channelName = void 0, + certificateId = void 0, + name = void 0, + claimId = void 0; + if (asset.claimData) { + var _asset$claimData = asset.claimData; + channelName = _asset$claimData.channelName; + certificateId = _asset$claimData.certificateId; + name = _asset$claimData.name; + claimId = _asset$claimData.claimId; + }; + if (channelName) { + return siteHost + "/" + channelName + ":" + certificateId + "/" + name; + }; + return siteHost + "/" + claimId + "/" + name; +}; + +var createChannelCanonicalLink = function createChannelCanonicalLink(channel, siteHost) { + var name = channel.name, + longId = channel.longId; + + return siteHost + "/" + name + ":" + longId; +}; + +var createCanonicalLink = exports.createCanonicalLink = function createCanonicalLink(asset, channel, page, siteHost) { + if (asset) { + return createAssetCanonicalLink(asset, siteHost); + } + if (channel) { + return createChannelCanonicalLink(channel, siteHost); + } + return createBasicCanonicalLink(page, siteHost); +}; + +/***/ }), +/* 93 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactRouterDom = __webpack_require__(3); + +var _Logo = __webpack_require__(94); + +var _Logo2 = _interopRequireDefault(_Logo); + +var _NavBarChannelOptionsDropdown = __webpack_require__(95); + +var _NavBarChannelOptionsDropdown2 = _interopRequireDefault(_NavBarChannelOptionsDropdown); + +var _request = __webpack_require__(11); + +var _request2 = _interopRequireDefault(_request); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var VIEW = 'VIEW'; +var LOGOUT = 'LOGOUT'; + +var NavBar = function (_React$Component) { + _inherits(NavBar, _React$Component); + + function NavBar(props) { + _classCallCheck(this, NavBar); + + var _this = _possibleConstructorReturn(this, (NavBar.__proto__ || Object.getPrototypeOf(NavBar)).call(this, props)); + + _this.checkForLoggedInUser = _this.checkForLoggedInUser.bind(_this); + _this.logoutUser = _this.logoutUser.bind(_this); + _this.handleSelection = _this.handleSelection.bind(_this); + return _this; + } + + _createClass(NavBar, [{ + key: 'componentDidMount', + value: function componentDidMount() { + // check to see if the user is already logged in + this.checkForLoggedInUser(); + } + }, { + key: 'checkForLoggedInUser', + value: function checkForLoggedInUser() { + var _this2 = this; + + var params = { credentials: 'include' }; + (0, _request2.default)('/user', params).then(function (_ref) { + var data = _ref.data; + + _this2.props.onChannelLogin(data.channelName, data.shortChannelId, data.channelClaimId); + }).catch(function (error) { + console.log('/user error:', error.message); + }); + } + }, { + key: 'logoutUser', + value: function logoutUser() { + var _this3 = this; + + var params = { credentials: 'include' }; + (0, _request2.default)('/logout', params).then(function () { + _this3.props.onChannelLogout(); + }).catch(function (error) { + console.log('/logout error', error.message); + }); + } + }, { + key: 'handleSelection', + value: function handleSelection(event) { + var value = event.target.selectedOptions[0].value; + switch (value) { + case LOGOUT: + this.logoutUser(); + break; + case VIEW: + // redirect to channel page + this.props.history.push('/' + this.props.channelName + ':' + this.props.channelLongId); + break; + default: + break; + } + } + }, { + key: 'render', + value: function render() { + var siteDescription = this.props.siteDescription; + + return _react2.default.createElement( + 'div', + { className: 'row row--wide nav-bar' }, + _react2.default.createElement( + 'div', + { className: 'row row--padded row--short flex-container--row flex-container--space-between-center' }, + _react2.default.createElement(_Logo2.default, null), + _react2.default.createElement( + 'div', + { className: 'nav-bar--center' }, + _react2.default.createElement( + 'span', + { className: 'nav-bar-tagline' }, + siteDescription + ) + ), + _react2.default.createElement( + 'div', + { className: 'nav-bar--right' }, + _react2.default.createElement( + _reactRouterDom.NavLink, + { className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/', exact: true }, + 'Publish' + ), + _react2.default.createElement( + _reactRouterDom.NavLink, + { className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/about' }, + 'About' + ), + this.props.channelName ? _react2.default.createElement(_NavBarChannelOptionsDropdown2.default, { + channelName: this.props.channelName, + handleSelection: this.handleSelection, + defaultSelection: this.props.channelName, + VIEW: VIEW, + LOGOUT: LOGOUT + }) : _react2.default.createElement( + _reactRouterDom.NavLink, + { id: 'nav-bar-login-link', className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/login' }, + 'Channel' + ) + ) + ) + ); + } + }]); + + return NavBar; +}(_react2.default.Component); + +exports.default = (0, _reactRouterDom.withRouter)(NavBar); + +/***/ }), +/* 94 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactRouterDom = __webpack_require__(3); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function Logo() { + return _react2.default.createElement( + 'svg', + { version: '1.1', id: 'Layer_1', x: '0px', y: '0px', height: '24px', viewBox: '0 0 80 31', enableBackground: 'new 0 0 80 31', className: 'nav-bar-logo' }, + _react2.default.createElement( + _reactRouterDom.Link, + { to: '/' }, + _react2.default.createElement( + 'title', + null, + 'Logo' + ), + _react2.default.createElement( + 'desc', + null, + 'Spee.ch logo' + ), + _react2.default.createElement( + 'g', + { id: 'About' }, + _react2.default.createElement( + 'g', + { id: 'Publish-Form-V2-_x28_filled_x29_', transform: 'translate(-42.000000, -23.000000)' }, + _react2.default.createElement( + 'g', + { id: 'Group-17', transform: 'translate(42.000000, 22.000000)' }, + _react2.default.createElement( + 'text', + { transform: 'matrix(1 0 0 1 0 20)', fontSize: '25', fontFamily: 'Roboto' }, + 'Spee 10000000) { + throw new Error('Sorry, images are limited to 10 megabytes.'); + } + break; + case 'image/gif': + if (file.size > 50000000) { + throw new Error('Sorry, GIFs are limited to 50 megabytes.'); + } + break; + case 'video/mp4': + if (file.size > 50000000) { + throw new Error('Sorry, videos are limited to 50 megabytes.'); + } + break; + default: + throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.'); + } + } +}; + +/***/ }), +/* 101 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = __webpack_require__(10); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var PublishPreview = function (_React$Component) { + _inherits(PublishPreview, _React$Component); + + function PublishPreview(props) { + _classCallCheck(this, PublishPreview); + + var _this = _possibleConstructorReturn(this, (PublishPreview.__proto__ || Object.getPrototypeOf(PublishPreview)).call(this, props)); + + _this.state = { + imgSource: '', + defaultThumbnail: '/assets/img/video_thumb_default.png' + }; + return _this; + } + + _createClass(PublishPreview, [{ + key: 'componentDidMount', + value: function componentDidMount() { + this.setPreviewImageSource(this.props.file); + } + }, { + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(newProps) { + if (newProps.file !== this.props.file) { + this.setPreviewImageSource(newProps.file); + } + if (newProps.thumbnail !== this.props.thumbnail) { + if (newProps.thumbnail) { + this.setPreviewImageSourceFromFile(newProps.thumbnail); + } else { + this.setState({ imgSource: this.state.defaultThumbnail }); + } + } + } + }, { + key: 'setPreviewImageSourceFromFile', + value: function setPreviewImageSourceFromFile(file) { + var _this2 = this; + + var previewReader = new FileReader(); + previewReader.readAsDataURL(file); + previewReader.onloadend = function () { + _this2.setState({ imgSource: previewReader.result }); + }; + } + }, { + key: 'setPreviewImageSource', + value: function setPreviewImageSource(file) { + if (file.type !== 'video/mp4') { + this.setPreviewImageSourceFromFile(file); + } else { + if (this.props.thumbnail) { + this.setPreviewImageSourceFromFile(this.props.thumbnail); + } + this.setState({ imgSource: this.state.defaultThumbnail }); + } + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement('img', { + id: 'dropzone-preview', + src: this.state.imgSource, + className: this.props.dimPreview ? 'dim' : '', + alt: 'publish preview' + }); + } + }]); + + return PublishPreview; +}(_react2.default.Component); + +; + +PublishPreview.propTypes = { + dimPreview: _propTypes2.default.bool.isRequired, + file: _propTypes2.default.object.isRequired, + thumbnail: _propTypes2.default.object +}; + +exports.default = PublishPreview; + +/***/ }), +/* 102 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _publish = __webpack_require__(4); + +var _view = __webpack_require__(103); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var channel = _ref.channel, + publish = _ref.publish; + + return { + file: publish.file + }; +}; + +var mapDispatchToProps = { + clearFile: _publish.clearFile, + startPublish: _publish.startPublish +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 103 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactRouterDom = __webpack_require__(3); + +var _Dropzone = __webpack_require__(38); + +var _Dropzone2 = _interopRequireDefault(_Dropzone); + +var _PublishTitleInput = __webpack_require__(104); + +var _PublishTitleInput2 = _interopRequireDefault(_PublishTitleInput); + +var _PublishUrlInput = __webpack_require__(106); + +var _PublishUrlInput2 = _interopRequireDefault(_PublishUrlInput); + +var _PublishThumbnailInput = __webpack_require__(109); + +var _PublishThumbnailInput2 = _interopRequireDefault(_PublishThumbnailInput); + +var _PublishMetadataInputs = __webpack_require__(111); + +var _PublishMetadataInputs2 = _interopRequireDefault(_PublishMetadataInputs); + +var _ChannelSelect = __webpack_require__(114); + +var _ChannelSelect2 = _interopRequireDefault(_ChannelSelect); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var PublishDetails = function (_React$Component) { + _inherits(PublishDetails, _React$Component); + + function PublishDetails(props) { + _classCallCheck(this, PublishDetails); + + var _this = _possibleConstructorReturn(this, (PublishDetails.__proto__ || Object.getPrototypeOf(PublishDetails)).call(this, props)); + + _this.onPublishSubmit = _this.onPublishSubmit.bind(_this); + return _this; + } + + _createClass(PublishDetails, [{ + key: 'onPublishSubmit', + value: function onPublishSubmit() { + this.props.startPublish(this.props.history); + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + { className: 'row row--no-bottom' }, + _react2.default.createElement( + 'div', + { className: 'column column--10' }, + _react2.default.createElement(_PublishTitleInput2.default, null) + ), + _react2.default.createElement( + 'div', + { className: 'column column--5 column--sml-10' }, + _react2.default.createElement( + 'div', + { className: 'row row--padded' }, + _react2.default.createElement(_Dropzone2.default, null) + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--5 column--sml-10 align-content-top' }, + _react2.default.createElement( + 'div', + { id: 'publish-active-area', className: 'row row--padded' }, + _react2.default.createElement( + 'div', + { className: 'row row--padded row--no-top row--wide' }, + _react2.default.createElement(_PublishUrlInput2.default, null) + ), + _react2.default.createElement( + 'div', + { className: 'row row--padded row--no-top row--wide' }, + _react2.default.createElement(_ChannelSelect2.default, null) + ), + this.props.file.type === 'video/mp4' && _react2.default.createElement( + 'div', + { className: 'row row--padded row--no-top row--wide ' }, + _react2.default.createElement(_PublishThumbnailInput2.default, null) + ), + _react2.default.createElement( + 'div', + { className: 'row row--padded row--no-top row--no-bottom row--wide' }, + _react2.default.createElement(_PublishMetadataInputs2.default, null) + ), + _react2.default.createElement( + 'div', + { className: 'row row--wide align-content-center' }, + _react2.default.createElement( + 'button', + { id: 'publish-submit', className: 'button--primary button--large', onClick: this.onPublishSubmit }, + 'Publish' + ) + ), + _react2.default.createElement( + 'div', + { className: 'row row--padded row--no-bottom align-content-center' }, + _react2.default.createElement( + 'button', + { className: 'button--cancel', onClick: this.props.clearFile }, + 'Cancel' + ) + ), + _react2.default.createElement( + 'div', + { className: 'row row--short align-content-center' }, + _react2.default.createElement( + 'p', + { className: 'fine-print' }, + 'By clicking \'Publish\', you affirm that you have the rights to publish this content to the LBRY network, and that you understand the properties of publishing it to a decentralized, user-controlled network. ', + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://lbry.io/learn' }, + 'Read more.' + ) + ) + ) + ) + ) + ); + } + }]); + + return PublishDetails; +}(_react2.default.Component); + +; + +exports.default = (0, _reactRouterDom.withRouter)(PublishDetails); + +/***/ }), +/* 104 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _publish = __webpack_require__(4); + +var _view = __webpack_require__(105); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var publish = _ref.publish; + + return { + title: publish.metadata.title + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + onMetadataChange: function onMetadataChange(name, value) { + dispatch((0, _publish.updateMetadata)(name, value)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var PublishTitleInput = function (_React$Component) { + _inherits(PublishTitleInput, _React$Component); + + function PublishTitleInput(props) { + _classCallCheck(this, PublishTitleInput); + + var _this = _possibleConstructorReturn(this, (PublishTitleInput.__proto__ || Object.getPrototypeOf(PublishTitleInput)).call(this, props)); + + _this.handleInput = _this.handleInput.bind(_this); + return _this; + } + + _createClass(PublishTitleInput, [{ + key: 'handleInput', + value: function handleInput(e) { + var name = e.target.name; + var value = e.target.value; + this.props.onMetadataChange(name, value); + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement('input', { type: 'text', id: 'publish-title', className: 'input-text text--large input-text--full-width', name: 'title', placeholder: 'Give your post a title...', onChange: this.handleInput, value: this.props.title }); + } + }]); + + return PublishTitleInput; +}(_react2.default.Component); + +exports.default = PublishTitleInput; + +/***/ }), +/* 106 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _publish = __webpack_require__(4); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(107); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var channel = _ref.channel, + publish = _ref.publish; + + return { + loggedInChannelName: channel.loggedInChannel.name, + loggedInChannelShortId: channel.loggedInChannel.shortId, + fileName: publish.file.name, + publishInChannel: publish.publishInChannel, + selectedChannel: publish.selectedChannel, + claim: publish.claim, + urlError: publish.error.url + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + onClaimChange: function onClaimChange(value) { + dispatch((0, _publish.updateClaim)(value)); + dispatch((0, _publish.updateError)('publishSubmit', null)); + }, + onUrlError: function onUrlError(value) { + dispatch((0, _publish.updateError)('url', value)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 107 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _request = __webpack_require__(11); + +var _request2 = _interopRequireDefault(_request); + +var _PublishUrlMiddleDisplay = __webpack_require__(108); + +var _PublishUrlMiddleDisplay2 = _interopRequireDefault(_PublishUrlMiddleDisplay); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var PublishUrlInput = function (_React$Component) { + _inherits(PublishUrlInput, _React$Component); + + function PublishUrlInput(props) { + _classCallCheck(this, PublishUrlInput); + + var _this = _possibleConstructorReturn(this, (PublishUrlInput.__proto__ || Object.getPrototypeOf(PublishUrlInput)).call(this, props)); + + _this.handleInput = _this.handleInput.bind(_this); + return _this; + } + + _createClass(PublishUrlInput, [{ + key: 'componentDidMount', + value: function componentDidMount() { + var _props = this.props, + claim = _props.claim, + fileName = _props.fileName; + + if (!claim) { + this.setClaimName(fileName); + } + } + }, { + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(_ref) { + var claim = _ref.claim, + fileName = _ref.fileName; + + // if a new file was chosen, update the claim name + if (fileName !== this.props.fileName) { + return this.setClaimName(fileName); + } + // if the claim has updated, check its availability + if (claim !== this.props.claim) { + this.validateClaim(claim); + } + } + }, { + key: 'handleInput', + value: function handleInput(event) { + var value = event.target.value; + value = this.cleanseInput(value); + // update the state + this.props.onClaimChange(value); + } + }, { + key: 'cleanseInput', + value: function cleanseInput(input) { + input = input.replace(/\s+/g, '-'); // replace spaces with dashes + input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-' + return input; + } + }, { + key: 'setClaimName', + value: function setClaimName(fileName) { + var fileNameWithoutEnding = fileName.substring(0, fileName.lastIndexOf('.')); + var cleanClaimName = this.cleanseInput(fileNameWithoutEnding); + this.props.onClaimChange(cleanClaimName); + } + }, { + key: 'validateClaim', + value: function validateClaim(claim) { + var _this2 = this; + + if (!claim) { + return this.props.onUrlError('Enter a url above'); + } + (0, _request2.default)('/api/claim/availability/' + claim).then(function () { + _this2.props.onUrlError(null); + }).catch(function (error) { + _this2.props.onUrlError(error.message); + }); + } + }, { + key: 'render', + value: function render() { + var _props2 = this.props, + claim = _props2.claim, + loggedInChannelName = _props2.loggedInChannelName, + loggedInChannelShortId = _props2.loggedInChannelShortId, + publishInChannel = _props2.publishInChannel, + selectedChannel = _props2.selectedChannel, + urlError = _props2.urlError; + + return _react2.default.createElement( + 'div', + { className: 'column column--10 column--sml-10' }, + _react2.default.createElement( + 'div', + { className: 'input-text--primary span--relative' }, + _react2.default.createElement( + 'span', + { className: 'url-text--secondary' }, + 'spee.ch / ' + ), + _react2.default.createElement(_PublishUrlMiddleDisplay2.default, { + publishInChannel: publishInChannel, + selectedChannel: selectedChannel, + loggedInChannelName: loggedInChannelName, + loggedInChannelShortId: loggedInChannelShortId + }), + _react2.default.createElement('input', { type: 'text', id: 'claim-name-input', className: 'input-text', name: 'claim', placeholder: 'your-url-here', onChange: this.handleInput, value: claim }), + claim && !urlError && _react2.default.createElement( + 'span', + { id: 'input-success-claim-name', className: 'info-message--success span--absolute' }, + '\u2713' + ), + urlError && _react2.default.createElement( + 'span', + { id: 'input-success-channel-name', className: 'info-message--failure span--absolute' }, + '\u2716' + ) + ), + _react2.default.createElement( + 'div', + null, + urlError ? _react2.default.createElement( + 'p', + { id: 'input-error-claim-name', className: 'info-message--failure' }, + urlError + ) : _react2.default.createElement( + 'p', + { className: 'info-message' }, + 'Choose a custom url' + ) + ) + ); + } + }]); + + return PublishUrlInput; +}(_react2.default.Component); + +exports.default = PublishUrlInput; + +/***/ }), +/* 108 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = __webpack_require__(10); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function UrlMiddle(_ref) { + var publishInChannel = _ref.publishInChannel, + selectedChannel = _ref.selectedChannel, + loggedInChannelName = _ref.loggedInChannelName, + loggedInChannelShortId = _ref.loggedInChannelShortId; + + if (publishInChannel) { + if (selectedChannel === loggedInChannelName) { + return _react2.default.createElement( + 'span', + { id: 'url-channel', className: 'url-text--secondary' }, + loggedInChannelName, + ':', + loggedInChannelShortId, + ' /' + ); + } + return _react2.default.createElement( + 'span', + { id: 'url-channel-placeholder', className: 'url-text--secondary tooltip' }, + '@channel', + _react2.default.createElement( + 'span', + { + className: 'tooltip-text' }, + 'Select a channel below' + ), + ' /' + ); + } + return _react2.default.createElement( + 'span', + { id: 'url-no-channel-placeholder', className: 'url-text--secondary tooltip' }, + 'xyz', + _react2.default.createElement( + 'span', + { className: 'tooltip-text' }, + 'This will be a random id' + ), + ' /' + ); +} + +UrlMiddle.propTypes = { + publishInChannel: _propTypes2.default.bool.isRequired, + loggedInChannelName: _propTypes2.default.string, + loggedInChannelShortId: _propTypes2.default.string +}; + +exports.default = UrlMiddle; + +/***/ }), +/* 109 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _publish = __webpack_require__(4); + +var _view = __webpack_require__(110); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var file = _ref.publish.file; + + return { + file: file + }; +}; + +var mapDispatchToProps = { + onNewThumbnail: _publish.onNewThumbnail +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 110 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +function dataURItoBlob(dataURI) { + // convert base64/URLEncoded data component to raw binary data held in a string + var byteString = atob(dataURI.split(',')[1]); + // separate out the mime component + var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; + // write the bytes of the string to a typed array + var ia = new Uint8Array(byteString.length); + for (var i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i); + } + return new Blob([ia], { type: mimeString }); +} + +var PublishThumbnailInput = function (_React$Component) { + _inherits(PublishThumbnailInput, _React$Component); + + function PublishThumbnailInput(props) { + _classCallCheck(this, PublishThumbnailInput); + + var _this = _possibleConstructorReturn(this, (PublishThumbnailInput.__proto__ || Object.getPrototypeOf(PublishThumbnailInput)).call(this, props)); + + _this.state = { + videoSource: null, + error: null, + sliderMinRange: 1, + sliderMaxRange: null, + sliderValue: null + }; + _this.handleVideoLoadedData = _this.handleVideoLoadedData.bind(_this); + _this.handleSliderChange = _this.handleSliderChange.bind(_this); + _this.createThumbnail = _this.createThumbnail.bind(_this); + return _this; + } + + _createClass(PublishThumbnailInput, [{ + key: 'componentDidMount', + value: function componentDidMount() { + var file = this.props.file; + + this.setVideoSource(file); + } + }, { + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + // if file changes + if (nextProps.file && nextProps.file !== this.props.file) { + var file = nextProps.file; + + this.setVideoSource(file); + }; + } + }, { + key: 'setVideoSource', + value: function setVideoSource(file) { + var _this2 = this; + + var previewReader = new FileReader(); + previewReader.readAsDataURL(file); + previewReader.onloadend = function () { + var dataUri = previewReader.result; + var blob = dataURItoBlob(dataUri); + var videoSource = URL.createObjectURL(blob); + _this2.setState({ videoSource: videoSource }); + }; + } + }, { + key: 'handleVideoLoadedData', + value: function handleVideoLoadedData(event) { + var duration = event.target.duration; + var totalMinutes = Math.floor(duration / 60); + var totalSeconds = Math.floor(duration % 60); + // set the slider + this.setState({ + sliderMaxRange: duration * 100, + sliderValue: duration * 100 / 2, + totalMinutes: totalMinutes, + totalSeconds: totalSeconds + }); + // update the current time of the video + var video = document.getElementById('video-thumb-player'); + video.currentTime = duration / 2; + } + }, { + key: 'handleSliderChange', + value: function handleSliderChange(event) { + var value = parseInt(event.target.value); + // update the slider value + this.setState({ + sliderValue: value + }); + // update the current time of the video + var video = document.getElementById('video-thumb-player'); + video.currentTime = value / 100; + } + }, { + key: 'createThumbnail', + value: function createThumbnail() { + // take a snapshot + var video = document.getElementById('video-thumb-player'); + var canvas = document.createElement('canvas'); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); + var dataUrl = canvas.toDataURL(); + var blob = dataURItoBlob(dataUrl); + var snapshot = new File([blob], 'thumbnail.png', { + type: 'image/png' + }); + // set the thumbnail in redux store + if (snapshot) { + this.props.onNewThumbnail(snapshot); + } + } + }, { + key: 'render', + value: function render() { + var _state = this.state, + error = _state.error, + videoSource = _state.videoSource, + sliderMinRange = _state.sliderMinRange, + sliderMaxRange = _state.sliderMaxRange, + sliderValue = _state.sliderValue, + totalMinutes = _state.totalMinutes, + totalSeconds = _state.totalSeconds; + + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'label', + { className: 'label' }, + 'Thumbnail:' + ), + _react2.default.createElement('video', { + id: 'video-thumb-player', + preload: 'metadata', + muted: true, + style: { display: 'none' }, + playsInline: true, + onLoadedData: this.handleVideoLoadedData, + src: videoSource, + onSeeked: this.createThumbnail + }), + sliderValue ? _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'div', + { className: 'flex-container--row flex-container--space-between-center', style: { width: '100%' } }, + _react2.default.createElement( + 'span', + { className: 'info-message' }, + '0\'00"' + ), + _react2.default.createElement( + 'span', + { className: 'info-message' }, + totalMinutes, + '\'', + totalSeconds, + '"' + ) + ), + _react2.default.createElement( + 'div', + null, + _react2.default.createElement('input', { + type: 'range', + min: sliderMinRange, + max: sliderMaxRange, + value: sliderValue, + className: 'slider', + onChange: this.handleSliderChange + }) + ) + ) : _react2.default.createElement( + 'p', + { className: 'info-message' }, + 'loading... ' + ), + error ? _react2.default.createElement( + 'p', + { className: 'info-message--failure' }, + error + ) : _react2.default.createElement( + 'p', + { className: 'info-message' }, + 'Use slider to set thumbnail' + ) + ); + } + }]); + + return PublishThumbnailInput; +}(_react2.default.Component); + +exports.default = PublishThumbnailInput; + +/***/ }), +/* 111 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _publish = __webpack_require__(4); + +var _view = __webpack_require__(112); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var publish = _ref.publish; + + return { + showMetadataInputs: publish.showMetadataInputs, + description: publish.metadata.description, + license: publish.metadata.license, + nsfw: publish.metadata.nsfw + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + onMetadataChange: function onMetadataChange(name, value) { + dispatch((0, _publish.updateMetadata)(name, value)); + }, + onToggleMetadataInputs: function onToggleMetadataInputs(value) { + dispatch((0, _publish.toggleMetadataInputs)(value)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 112 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _ExpandingTextArea = __webpack_require__(113); + +var _ExpandingTextArea2 = _interopRequireDefault(_ExpandingTextArea); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var PublishMetadataInputs = function (_React$Component) { + _inherits(PublishMetadataInputs, _React$Component); + + function PublishMetadataInputs(props) { + _classCallCheck(this, PublishMetadataInputs); + + var _this = _possibleConstructorReturn(this, (PublishMetadataInputs.__proto__ || Object.getPrototypeOf(PublishMetadataInputs)).call(this, props)); + + _this.toggleShowInputs = _this.toggleShowInputs.bind(_this); + _this.handleInput = _this.handleInput.bind(_this); + _this.handleSelect = _this.handleSelect.bind(_this); + return _this; + } + + _createClass(PublishMetadataInputs, [{ + key: 'toggleShowInputs', + value: function toggleShowInputs() { + this.props.onToggleMetadataInputs(!this.props.showMetadataInputs); + } + }, { + key: 'handleInput', + value: function handleInput(event) { + var target = event.target; + var value = target.type === 'checkbox' ? target.checked : target.value; + var name = target.name; + this.props.onMetadataChange(name, value); + } + }, { + key: 'handleSelect', + value: function handleSelect(event) { + var name = event.target.name; + var selectedOption = event.target.selectedOptions[0].value; + this.props.onMetadataChange(name, selectedOption); + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + { id: 'publish-details', className: 'row row--padded row--no-top row--wide' }, + this.props.showMetadataInputs && _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'div', + { className: 'row row--no-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--3 column--med-10 align-content-top' }, + _react2.default.createElement( + 'label', + { htmlFor: 'publish-license', className: 'label' }, + 'Description:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--7 column--sml-10' }, + _react2.default.createElement(_ExpandingTextArea2.default, { + id: 'publish-description', + className: 'textarea textarea--primary textarea--full-width', + rows: 1, + maxLength: 2000, + style: { maxHeight: 200 }, + name: 'description', + placeholder: 'Optional description', + value: this.props.description, + onChange: this.handleInput }) + ) + ), + _react2.default.createElement( + 'div', + { className: 'row row--no-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--3 column--med-10' }, + _react2.default.createElement( + 'label', + { htmlFor: 'publish-license', className: 'label' }, + 'License:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--7 column--sml-10' }, + _react2.default.createElement( + 'select', + { type: 'text', name: 'license', id: 'publish-license', className: 'select select--primary', onChange: this.handleSelect }, + _react2.default.createElement( + 'option', + { value: ' ' }, + 'Unspecified' + ), + _react2.default.createElement( + 'option', + { value: 'Public Domain' }, + 'Public Domain' + ), + _react2.default.createElement( + 'option', + { value: 'Creative Commons' }, + 'Creative Commons' + ) + ) + ) + ), + _react2.default.createElement( + 'div', + { className: 'row row--no-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--3' }, + _react2.default.createElement( + 'label', + { htmlFor: 'publish-nsfw', className: 'label' }, + 'Mature:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--7' }, + _react2.default.createElement('input', { className: 'input-checkbox', type: 'checkbox', id: 'publish-nsfw', name: 'nsfw', value: this.props.nsfw, onChange: this.handleInput }) + ) + ) + ), + _react2.default.createElement( + 'button', + { className: 'button--secondary', onClick: this.toggleShowInputs }, + this.props.showMetadataInputs ? 'less' : 'more' + ) + ); + } + }]); + + return PublishMetadataInputs; +}(_react2.default.Component); + +exports.default = PublishMetadataInputs; + +/***/ }), +/* 113 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _propTypes = __webpack_require__(10); + +var _propTypes2 = _interopRequireDefault(_propTypes); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ExpandingTextarea = function (_Component) { + _inherits(ExpandingTextarea, _Component); + + function ExpandingTextarea(props) { + _classCallCheck(this, ExpandingTextarea); + + var _this = _possibleConstructorReturn(this, (ExpandingTextarea.__proto__ || Object.getPrototypeOf(ExpandingTextarea)).call(this, props)); + + _this._handleChange = _this._handleChange.bind(_this); + return _this; + } + + _createClass(ExpandingTextarea, [{ + key: 'componentDidMount', + value: function componentDidMount() { + this.adjustTextarea({}); + } + }, { + key: '_handleChange', + value: function _handleChange(event) { + var onChange = this.props.onChange; + + if (onChange) onChange(event); + this.adjustTextarea(event); + } + }, { + key: 'adjustTextarea', + value: function adjustTextarea(_ref) { + var _ref$target = _ref.target, + target = _ref$target === undefined ? this.el : _ref$target; + + target.style.height = 0; + target.style.height = target.scrollHeight + 'px'; + } + }, { + key: 'render', + value: function render() { + var _this2 = this; + + var rest = _objectWithoutProperties(this.props, []); + + return _react2.default.createElement('textarea', _extends({}, rest, { + ref: function ref(x) { + return _this2.el = x; + }, + onChange: this._handleChange + })); + } + }]); + + return ExpandingTextarea; +}(_react.Component); + +ExpandingTextarea.propTypes = { + onChange: _propTypes2.default.func +}; + +exports.default = ExpandingTextarea; + +/***/ }), +/* 114 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _publish = __webpack_require__(4); + +var _view = __webpack_require__(115); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var channel = _ref.channel, + publish = _ref.publish; + + return { + loggedInChannelName: channel.loggedInChannel.name, + publishInChannel: publish.publishInChannel, + selectedChannel: publish.selectedChannel, + channelError: publish.error.channel + }; +}; + +var mapDispatchToProps = function mapDispatchToProps(dispatch) { + return { + onPublishInChannelChange: function onPublishInChannelChange(value) { + dispatch((0, _publish.updateError)('channel', null)); + dispatch((0, _publish.setPublishInChannel)(value)); + }, + onChannelSelect: function onChannelSelect(value) { + dispatch((0, _publish.updateError)('channel', null)); + dispatch((0, _publish.updateSelectedChannel)(value)); + } + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 115 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _ChannelLoginForm = __webpack_require__(39); + +var _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm); + +var _ChannelCreateForm = __webpack_require__(40); + +var _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm); + +var _publish_channel_select_states = __webpack_require__(33); + +var states = _interopRequireWildcard(_publish_channel_select_states); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ChannelSelect = function (_React$Component) { + _inherits(ChannelSelect, _React$Component); + + function ChannelSelect(props) { + _classCallCheck(this, ChannelSelect); + + var _this = _possibleConstructorReturn(this, (ChannelSelect.__proto__ || Object.getPrototypeOf(ChannelSelect)).call(this, props)); + + _this.toggleAnonymousPublish = _this.toggleAnonymousPublish.bind(_this); + _this.handleSelection = _this.handleSelection.bind(_this); + return _this; + } + + _createClass(ChannelSelect, [{ + key: 'toggleAnonymousPublish', + value: function toggleAnonymousPublish(event) { + var value = event.target.value; + if (value === 'anonymous') { + this.props.onPublishInChannelChange(false); + } else { + this.props.onPublishInChannelChange(true); + } + } + }, { + key: 'handleSelection', + value: function handleSelection(event) { + var selectedOption = event.target.selectedOptions[0].value; + this.props.onChannelSelect(selectedOption); + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'form', + null, + _react2.default.createElement( + 'div', + { className: 'column column--3 column--med-10' }, + _react2.default.createElement('input', { type: 'radio', name: 'anonymous-or-channel', id: 'anonymous-radio', className: 'input-radio', value: 'anonymous', checked: !this.props.publishInChannel, onChange: this.toggleAnonymousPublish }), + _react2.default.createElement( + 'label', + { className: 'label label--pointer', htmlFor: 'anonymous-radio' }, + 'Anonymous' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--7 column--med-10' }, + _react2.default.createElement('input', { type: 'radio', name: 'anonymous-or-channel', id: 'channel-radio', className: 'input-radio', value: 'in a channel', checked: this.props.publishInChannel, onChange: this.toggleAnonymousPublish }), + _react2.default.createElement( + 'label', + { className: 'label label--pointer', htmlFor: 'channel-radio' }, + 'In a channel' + ) + ), + this.props.channelError ? _react2.default.createElement( + 'p', + { className: 'info-message--failure' }, + this.props.channelError + ) : _react2.default.createElement( + 'p', + { className: 'info-message' }, + 'Publish anonymously or in a channel' + ) + ), + this.props.publishInChannel && _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'div', + { className: 'column column--3' }, + _react2.default.createElement( + 'label', + { className: 'label', htmlFor: 'channel-name-select' }, + 'Channel:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--7' }, + _react2.default.createElement( + 'select', + { type: 'text', id: 'channel-name-select', className: 'select select--arrow', value: this.props.selectedChannel, onChange: this.handleSelection }, + this.props.loggedInChannelName && _react2.default.createElement( + 'option', + { value: this.props.loggedInChannelName, id: 'publish-channel-select-channel-option' }, + this.props.loggedInChannelName + ), + _react2.default.createElement( + 'option', + { value: states.LOGIN }, + 'Existing' + ), + _react2.default.createElement( + 'option', + { value: states.CREATE }, + 'New' + ) + ) + ), + this.props.selectedChannel === states.LOGIN && _react2.default.createElement(_ChannelLoginForm2.default, null), + this.props.selectedChannel === states.CREATE && _react2.default.createElement(_ChannelCreateForm2.default, null) + ) + ); + } + }]); + + return ChannelSelect; +}(_react2.default.Component); + +exports.default = ChannelSelect; + +/***/ }), +/* 116 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _request = __webpack_require__(11); + +var _request2 = _interopRequireDefault(_request); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ChannelLoginForm = function (_React$Component) { + _inherits(ChannelLoginForm, _React$Component); + + function ChannelLoginForm(props) { + _classCallCheck(this, ChannelLoginForm); + + var _this = _possibleConstructorReturn(this, (ChannelLoginForm.__proto__ || Object.getPrototypeOf(ChannelLoginForm)).call(this, props)); + + _this.state = { + error: null, + name: '', + password: '' + }; + _this.handleInput = _this.handleInput.bind(_this); + _this.loginToChannel = _this.loginToChannel.bind(_this); + return _this; + } + + _createClass(ChannelLoginForm, [{ + key: 'handleInput', + value: function handleInput(event) { + var name = event.target.name; + var value = event.target.value; + this.setState(_defineProperty({}, name, value)); + } + }, { + key: 'loginToChannel', + value: function loginToChannel(event) { + var _this2 = this; + + event.preventDefault(); + var params = { + method: 'POST', + body: JSON.stringify({ username: this.state.name, password: this.state.password }), + headers: new Headers({ + 'Content-Type': 'application/json' + }), + credentials: 'include' + }; + (0, _request2.default)('login', params).then(function (_ref) { + var success = _ref.success, + channelName = _ref.channelName, + shortChannelId = _ref.shortChannelId, + channelClaimId = _ref.channelClaimId, + message = _ref.message; + + if (success) { + _this2.props.onChannelLogin(channelName, shortChannelId, channelClaimId); + } else { + _this2.setState({ 'error': message }); + }; + }).catch(function (error) { + if (error.message) { + _this2.setState({ 'error': error.message }); + } else { + _this2.setState({ 'error': error }); + } + }); + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement( + 'form', + { id: 'channel-login-form' }, + _react2.default.createElement( + 'div', + { className: 'row row--wide row--short' }, + _react2.default.createElement( + 'div', + { className: 'column column--3 column--sml-10' }, + _react2.default.createElement( + 'label', + { className: 'label', htmlFor: 'channel-login-name-input' }, + 'Name:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--6 column--sml-10' }, + _react2.default.createElement( + 'div', + { className: 'input-text--primary flex-container--row flex-container--left-bottom' }, + _react2.default.createElement( + 'span', + null, + '@' + ), + _react2.default.createElement('input', { type: 'text', id: 'channel-login-name-input', className: 'input-text', name: 'name', placeholder: 'Your Channel Name', value: this.state.channelName, onChange: this.handleInput }) + ) + ) + ), + _react2.default.createElement( + 'div', + { className: 'row row--wide row--short' }, + _react2.default.createElement( + 'div', + { className: 'column column--3 column--sml-10' }, + _react2.default.createElement( + 'label', + { className: 'label', htmlFor: 'channel-login-password-input' }, + 'Password:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--6 column--sml-10' }, + _react2.default.createElement( + 'div', + { className: 'input-text--primary' }, + _react2.default.createElement('input', { type: 'password', id: 'channel-login-password-input', name: 'password', className: 'input-text', placeholder: '', value: this.state.channelPassword, onChange: this.handleInput }) + ) + ) + ), + this.state.error ? _react2.default.createElement( + 'p', + { className: 'info-message--failure' }, + this.state.error + ) : _react2.default.createElement( + 'p', + { className: 'info-message' }, + 'Enter the name and password for your channel' + ), + _react2.default.createElement( + 'div', + { className: 'row row--wide' }, + _react2.default.createElement( + 'button', + { className: 'button--primary', onClick: this.loginToChannel }, + 'Authenticate' + ) + ) + ); + } + }]); + + return ChannelLoginForm; +}(_react2.default.Component); + +exports.default = ChannelLoginForm; + +/***/ }), +/* 117 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _ProgressBar = __webpack_require__(20); + +var _ProgressBar2 = _interopRequireDefault(_ProgressBar); + +var _request = __webpack_require__(11); + +var _request2 = _interopRequireDefault(_request); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ChannelCreateForm = function (_React$Component) { + _inherits(ChannelCreateForm, _React$Component); + + function ChannelCreateForm(props) { + _classCallCheck(this, ChannelCreateForm); + + var _this = _possibleConstructorReturn(this, (ChannelCreateForm.__proto__ || Object.getPrototypeOf(ChannelCreateForm)).call(this, props)); + + _this.state = { + error: null, + channel: '', + password: '', + status: null + }; + _this.handleChannelInput = _this.handleChannelInput.bind(_this); + _this.handleInput = _this.handleInput.bind(_this); + _this.createChannel = _this.createChannel.bind(_this); + return _this; + } + + _createClass(ChannelCreateForm, [{ + key: 'cleanseChannelInput', + value: function cleanseChannelInput(input) { + input = input.replace(/\s+/g, '-'); // replace spaces with dashes + input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-' + return input; + } + }, { + key: 'handleChannelInput', + value: function handleChannelInput(event) { + var value = event.target.value; + value = this.cleanseChannelInput(value); + this.setState({ channel: value }); + if (value) { + this.updateIsChannelAvailable(value); + } else { + this.setState({ error: 'Please enter a channel name' }); + } + } + }, { + key: 'handleInput', + value: function handleInput(event) { + var name = event.target.name; + var value = event.target.value; + this.setState(_defineProperty({}, name, value)); + } + }, { + key: 'updateIsChannelAvailable', + value: function updateIsChannelAvailable(channel) { + var _this2 = this; + + var channelWithAtSymbol = '@' + channel; + (0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol).then(function () { + _this2.setState({ 'error': null }); + }).catch(function (error) { + _this2.setState({ 'error': error.message }); + }); + } + }, { + key: 'checkIsChannelAvailable', + value: function checkIsChannelAvailable(channel) { + var channelWithAtSymbol = '@' + channel; + return (0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol); + } + }, { + key: 'checkIsPasswordProvided', + value: function checkIsPasswordProvided(password) { + return new Promise(function (resolve, reject) { + if (!password || password.length < 1) { + return reject(new Error('Please provide a password')); + } + resolve(); + }); + } + }, { + key: 'makePublishChannelRequest', + value: function makePublishChannelRequest(username, password) { + var params = { + method: 'POST', + body: JSON.stringify({ username: username, password: password }), + headers: new Headers({ + 'Content-Type': 'application/json' + }), + credentials: 'include' + }; + return new Promise(function (resolve, reject) { + (0, _request2.default)('/signup', params).then(function (result) { + return resolve(result); + }).catch(function (error) { + reject(new Error('Unfortunately, we encountered an error while creating your channel. Please let us know in Discord! ' + error.message)); + }); + }); + } + }, { + key: 'createChannel', + value: function createChannel(event) { + var _this3 = this; + + event.preventDefault(); + this.checkIsPasswordProvided(this.state.password).then(function () { + return _this3.checkIsChannelAvailable(_this3.state.channel); + }).then(function () { + _this3.setState({ status: 'We are publishing your new channel. Sit tight...' }); + return _this3.makePublishChannelRequest(_this3.state.channel, _this3.state.password); + }).then(function (result) { + _this3.setState({ status: null }); + _this3.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId); + }).catch(function (error) { + if (error.message) { + _this3.setState({ 'error': error.message, status: null }); + } else { + _this3.setState({ 'error': error, status: null }); + }; + }); + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + null, + !this.state.status ? _react2.default.createElement( + 'form', + { id: 'publish-channel-form' }, + _react2.default.createElement( + 'div', + { className: 'row row--wide row--short' }, + _react2.default.createElement( + 'div', + { className: 'column column--3 column--sml-10' }, + _react2.default.createElement( + 'label', + { className: 'label', htmlFor: 'new-channel-name' }, + 'Name:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--6 column--sml-10' }, + _react2.default.createElement( + 'div', + { className: 'input-text--primary flex-container--row flex-container--left-bottom span--relative' }, + _react2.default.createElement( + 'span', + null, + '@' + ), + _react2.default.createElement('input', { type: 'text', name: 'channel', id: 'new-channel-name', className: 'input-text', placeholder: 'exampleChannelName', value: this.state.channel, onChange: this.handleChannelInput }), + this.state.channel && !this.state.error && _react2.default.createElement( + 'span', + { id: 'input-success-channel-name', className: 'info-message--success span--absolute' }, + '\u2713' + ), + this.state.error && _react2.default.createElement( + 'span', + { id: 'input-success-channel-name', className: 'info-message--failure span--absolute' }, + '\u2716' + ) + ) + ) + ), + _react2.default.createElement( + 'div', + { className: 'row row--wide row--short' }, + _react2.default.createElement( + 'div', + { className: 'column column--3 column--sml-10' }, + _react2.default.createElement( + 'label', + { className: 'label', htmlFor: 'new-channel-password' }, + 'Password:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--6 column--sml-10' }, + _react2.default.createElement( + 'div', + { className: 'input-text--primary' }, + _react2.default.createElement('input', { type: 'password', name: 'password', id: 'new-channel-password', className: 'input-text', placeholder: '', value: this.state.password, onChange: this.handleInput }) + ) + ) + ), + this.state.error ? _react2.default.createElement( + 'p', + { className: 'info-message--failure' }, + this.state.error + ) : _react2.default.createElement( + 'p', + { className: 'info-message' }, + 'Choose a name and password for your channel' + ), + _react2.default.createElement( + 'div', + { className: 'row row--wide' }, + _react2.default.createElement( + 'button', + { className: 'button--primary', onClick: this.createChannel }, + 'Create Channel' + ) + ) + ) : _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'p', + { className: 'fine-print' }, + this.state.status + ), + _react2.default.createElement(_ProgressBar2.default, { size: 12 }) + ) + ); + } + }]); + + return ChannelCreateForm; +}(_react2.default.Component); + +exports.default = ChannelCreateForm; + +/***/ }), +/* 118 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var ActiveStatusBar = function ActiveStatusBar() { + return _react2.default.createElement( + 'span', + { className: 'progress-bar progress-bar--active' }, + '| ' + ); +}; + +exports.default = ActiveStatusBar; + +/***/ }), +/* 119 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var InactiveStatusBar = function InactiveStatusBar() { + return _react2.default.createElement( + 'span', + { className: 'progress-bar progress-bar--inactive' }, + '| ' + ); +}; + +exports.default = InactiveStatusBar; + +/***/ }), +/* 120 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _publish = __webpack_require__(4); + +var _view = __webpack_require__(121); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var publish = _ref.publish; + + return { + status: publish.status.status, + message: publish.status.message + }; +}; + +var mapDispatchToProps = { + clearFile: _publish.clearFile +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 121 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _ProgressBar = __webpack_require__(20); + +var _ProgressBar2 = _interopRequireDefault(_ProgressBar); + +var _publish_claim_states = __webpack_require__(122); + +var publishStates = _interopRequireWildcard(_publish_claim_states); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var PublishStatus = function (_React$Component) { + _inherits(PublishStatus, _React$Component); + + function PublishStatus() { + _classCallCheck(this, PublishStatus); + + return _possibleConstructorReturn(this, (PublishStatus.__proto__ || Object.getPrototypeOf(PublishStatus)).apply(this, arguments)); + } + + _createClass(PublishStatus, [{ + key: 'render', + value: function render() { + var _props = this.props, + status = _props.status, + message = _props.message, + clearFile = _props.clearFile; + + return _react2.default.createElement( + 'div', + { className: 'row row--tall flex-container--column flex-container--center-center' }, + status === publishStates.LOAD_START && _react2.default.createElement( + 'div', + { className: 'row align-content-center' }, + _react2.default.createElement( + 'p', + null, + 'File is loading to server' + ), + _react2.default.createElement( + 'p', + { className: 'blue' }, + '0%' + ) + ), + status === publishStates.LOADING && _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'div', + { className: 'row align-content-center' }, + _react2.default.createElement( + 'p', + null, + 'File is loading to server' + ), + _react2.default.createElement( + 'p', + { className: 'blue' }, + message + ) + ) + ), + status === publishStates.PUBLISHING && _react2.default.createElement( + 'div', + { className: 'row align-content-center' }, + _react2.default.createElement( + 'p', + null, + 'Upload complete. Your file is now being published on the blockchain...' + ), + _react2.default.createElement(_ProgressBar2.default, { size: 12 }), + _react2.default.createElement( + 'p', + null, + 'Curious what magic is happening here? ', + _react2.default.createElement( + 'a', + { className: 'link--primary', target: 'blank', href: 'https://lbry.io/faq/what-is-lbry' }, + 'Learn more.' + ) + ) + ), + status === publishStates.SUCCESS && _react2.default.createElement( + 'div', + { className: 'row align-content-center' }, + _react2.default.createElement( + 'p', + null, + 'Your publish is complete! You are being redirected to it now.' + ), + _react2.default.createElement( + 'p', + null, + 'If you are not automatically redirected, ', + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: message }, + 'click here.' + ) + ) + ), + status === publishStates.FAILED && _react2.default.createElement( + 'div', + { className: 'row align-content-center' }, + _react2.default.createElement( + 'p', + null, + 'Something went wrong...' + ), + _react2.default.createElement( + 'p', + null, + _react2.default.createElement( + 'strong', + null, + message + ) + ), + _react2.default.createElement( + 'p', + null, + 'For help, post the above error text in the #speech channel on the ', + _react2.default.createElement( + 'a', + { className: 'link--primary', href: 'https://discord.gg/YjYbwhS', target: '_blank' }, + 'lbry discord' + ) + ), + _react2.default.createElement( + 'button', + { className: 'button--secondary', onClick: clearFile }, + 'Reset' + ) + ) + ); + } + }]); + + return PublishStatus; +}(_react2.default.Component); + +; + +exports.default = PublishStatus; + +/***/ }), +/* 122 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var LOAD_START = exports.LOAD_START = 'LOAD_START'; +var LOADING = exports.LOADING = 'LOADING'; +var PUBLISHING = exports.PUBLISHING = 'PUBLISHING'; +var SUCCESS = exports.SUCCESS = 'SUCCESS'; +var FAILED = exports.FAILED = 'FAILED'; + +/***/ }), +/* 123 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(124); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var publish = _ref.publish; + + return { + message: publish.disabledMessage + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 124 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var PublishDisabledMessage = function (_React$Component) { + _inherits(PublishDisabledMessage, _React$Component); + + function PublishDisabledMessage() { + _classCallCheck(this, PublishDisabledMessage); + + return _possibleConstructorReturn(this, (PublishDisabledMessage.__proto__ || Object.getPrototypeOf(PublishDisabledMessage)).apply(this, arguments)); + } + + _createClass(PublishDisabledMessage, [{ + key: 'render', + value: function render() { + var message = this.props.message; + console.log('this.props.message:', message); + return _react2.default.createElement( + 'div', + { className: 'row dropzone--disabled row--tall flex-container--column flex-container--center-center' }, + _react2.default.createElement( + 'p', + { className: 'text--disabled' }, + 'Publishing is currently disabled.' + ), + _react2.default.createElement( + 'p', + { className: 'text--disabled' }, + message + ) + ); + } + }]); + + return PublishDisabledMessage; +}(_react2.default.Component); + +exports.default = PublishDisabledMessage; + +/***/ }), +/* 125 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _NavBar = __webpack_require__(7); + +var _NavBar2 = _interopRequireDefault(_NavBar); + +var _SEO = __webpack_require__(9); + +var _SEO2 = _interopRequireDefault(_SEO); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var AboutPage = function (_React$Component) { + _inherits(AboutPage, _React$Component); + + function AboutPage() { + _classCallCheck(this, AboutPage); + + return _possibleConstructorReturn(this, (AboutPage.__proto__ || Object.getPrototypeOf(AboutPage)).apply(this, arguments)); + } + + _createClass(AboutPage, [{ + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement(_SEO2.default, { pageTitle: 'About', pageUri: 'about' }), + _react2.default.createElement(_NavBar2.default, null), + _react2.default.createElement( + 'div', + { className: 'row row--padded' }, + _react2.default.createElement( + 'div', + { className: 'column column--5 column--med-10 align-content-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--8 column--med-10' }, + _react2.default.createElement( + 'p', + { className: 'pull-quote' }, + 'Spee.ch is an open-source project. Please contribute to the existing site, or fork it and make your own.' + ), + _react2.default.createElement( + 'p', + null, + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://twitter.com/spee_ch' }, + 'TWITTER' + ) + ), + _react2.default.createElement( + 'p', + null, + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://github.com/lbryio/spee.ch' }, + 'GITHUB' + ) + ), + _react2.default.createElement( + 'p', + null, + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://discord.gg/YjYbwhS' }, + 'DISCORD CHANNEL' + ) + ), + _react2.default.createElement( + 'p', + null, + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://github.com/lbryio/spee.ch/blob/master/README.md' }, + 'DOCUMENTATION' + ) + ) + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--5 column--med-10 align-content-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--8 column--med-10' }, + _react2.default.createElement( + 'p', + null, + 'Spee.ch is a media-hosting site that reads from and publishes content to the ', + _react2.default.createElement( + 'a', + { className: 'link--primary', href: 'https://lbry.io' }, + 'LBRY' + ), + ' blockchain.' + ), + _react2.default.createElement( + 'p', + null, + 'Spee.ch is a hosting service, but with the added benefit that it stores your content on a decentralized network of computers -- the ', + _react2.default.createElement( + 'a', + { className: 'link--primary', href: 'https://lbry.io/get' }, + 'LBRY' + ), + ' network. This means that your images are stored in multiple locations without a single point of failure.' + ), + _react2.default.createElement( + 'h3', + null, + 'Contribute' + ), + _react2.default.createElement( + 'p', + null, + 'If you have an idea for your own spee.ch-like site on top of LBRY, fork our ', + _react2.default.createElement( + 'a', + { className: 'link--primary', href: 'https://github.com/lbryio/spee.ch' }, + 'github repo' + ), + ' and go to town!' + ), + _react2.default.createElement( + 'p', + null, + 'If you want to improve spee.ch, join our ', + _react2.default.createElement( + 'a', + { className: 'link--primary', href: 'https://discord.gg/YjYbwhS' }, + 'discord channel' + ), + ' or solve one of our ', + _react2.default.createElement( + 'a', + { className: 'link--primary', href: 'https://github.com/lbryio/spee.ch/issues' }, + 'github issues' + ), + '.' + ) + ) + ) + ) + ); + } + }]); + + return AboutPage; +}(_react2.default.Component); + +; + +exports.default = AboutPage; + +/***/ }), +/* 126 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(127); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var channel = _ref.channel; + + return { + loggedInChannelName: channel.loggedInChannel.name + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 127 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactRouterDom = __webpack_require__(3); + +var _SEO = __webpack_require__(9); + +var _SEO2 = _interopRequireDefault(_SEO); + +var _NavBar = __webpack_require__(7); + +var _NavBar2 = _interopRequireDefault(_NavBar); + +var _ChannelLoginForm = __webpack_require__(39); + +var _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm); + +var _ChannelCreateForm = __webpack_require__(40); + +var _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var LoginPage = function (_React$Component) { + _inherits(LoginPage, _React$Component); + + function LoginPage() { + _classCallCheck(this, LoginPage); + + return _possibleConstructorReturn(this, (LoginPage.__proto__ || Object.getPrototypeOf(LoginPage)).apply(this, arguments)); + } + + _createClass(LoginPage, [{ + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(newProps) { + // re-route the user to the homepage if the user is logged in + if (newProps.loggedInChannelName !== this.props.loggedInChannelName) { + this.props.history.push('/'); + } + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement(_SEO2.default, { pageTitle: 'Login', pageUri: 'login' }), + _react2.default.createElement(_NavBar2.default, null), + _react2.default.createElement( + 'div', + { className: 'row row--padded' }, + _react2.default.createElement( + 'div', + { className: 'column column--5 column--med-10 align-content-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--8 column--med-10' }, + _react2.default.createElement( + 'p', + null, + 'Channels allow you to publish and group content under an identity. You can create a channel for yourself, or share one with like-minded friends. You can create 1 channel, or 100, so whether you\'re ', + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: '/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8' }, + 'documenting important events' + ), + ', or making a public repository for ', + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: '/@catGifs' }, + 'cat gifs' + ), + ' (password: \'1234\'), try creating a channel for it!' + ) + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--5 column--med-10 align-content-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--8 column--med-10' }, + _react2.default.createElement( + 'h3', + { className: 'h3--no-bottom' }, + 'Log in to an existing channel:' + ), + _react2.default.createElement(_ChannelLoginForm2.default, null), + _react2.default.createElement( + 'h3', + { className: 'h3--no-bottom' }, + 'Create a brand new channel:' + ), + _react2.default.createElement(_ChannelCreateForm2.default, null) + ) + ) + ) + ); + } + }]); + + return LoginPage; +}(_react2.default.Component); + +; + +exports.default = (0, _reactRouterDom.withRouter)(LoginPage); + +/***/ }), +/* 128 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _show = __webpack_require__(8); + +var _view = __webpack_require__(129); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var show = _ref.show; + + return { + error: show.request.error, + requestType: show.request.type + }; +}; + +var mapDispatchToProps = { + onHandleShowPageUri: _show.onHandleShowPageUri +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 129 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _ErrorPage = __webpack_require__(21); + +var _ErrorPage2 = _interopRequireDefault(_ErrorPage); + +var _ShowAssetLite = __webpack_require__(130); + +var _ShowAssetLite2 = _interopRequireDefault(_ShowAssetLite); + +var _ShowAssetDetails = __webpack_require__(133); + +var _ShowAssetDetails2 = _interopRequireDefault(_ShowAssetDetails); + +var _ShowChannel = __webpack_require__(139); + +var _ShowChannel2 = _interopRequireDefault(_ShowChannel); + +var _show_request_types = __webpack_require__(41); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ShowPage = function (_React$Component) { + _inherits(ShowPage, _React$Component); + + function ShowPage() { + _classCallCheck(this, ShowPage); + + return _possibleConstructorReturn(this, (ShowPage.__proto__ || Object.getPrototypeOf(ShowPage)).apply(this, arguments)); + } + + _createClass(ShowPage, [{ + key: 'componentDidMount', + value: function componentDidMount() { + this.props.onHandleShowPageUri(this.props.match.params); + } + }, { + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + if (nextProps.match.params !== this.props.match.params) { + this.props.onHandleShowPageUri(nextProps.match.params); + } + } + }, { + key: 'render', + value: function render() { + var _props = this.props, + error = _props.error, + requestType = _props.requestType; + + if (error) { + return _react2.default.createElement(_ErrorPage2.default, { error: error }); + } + switch (requestType) { + case _show_request_types.CHANNEL: + return _react2.default.createElement(_ShowChannel2.default, null); + case _show_request_types.ASSET_LITE: + return _react2.default.createElement(_ShowAssetLite2.default, null); + case _show_request_types.ASSET_DETAILS: + return _react2.default.createElement(_ShowAssetDetails2.default, null); + default: + return _react2.default.createElement( + 'p', + null, + 'loading...' + ); + } + } + }]); + + return ShowPage; +}(_react2.default.Component); + +; + +exports.default = ShowPage; + +/***/ }), +/* 130 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(131); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var show = _ref.show; + + // select request info + var requestId = show.request.id; + // select asset info + var asset = void 0; + var request = show.requestList[requestId] || null; + var assetList = show.assetList; + if (request && assetList) { + var assetKey = request.key; // note: just store this in the request + asset = assetList[assetKey] || null; + }; + // return props + return { + asset: asset + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 131 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _SEO = __webpack_require__(9); + +var _SEO2 = _interopRequireDefault(_SEO); + +var _reactRouterDom = __webpack_require__(3); + +var _AssetDisplay = __webpack_require__(42); + +var _AssetDisplay2 = _interopRequireDefault(_AssetDisplay); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ShowLite = function (_React$Component) { + _inherits(ShowLite, _React$Component); + + function ShowLite() { + _classCallCheck(this, ShowLite); + + return _possibleConstructorReturn(this, (ShowLite.__proto__ || Object.getPrototypeOf(ShowLite)).apply(this, arguments)); + } + + _createClass(ShowLite, [{ + key: 'render', + value: function render() { + var asset = this.props.asset; + + if (asset) { + var _asset$claimData = asset.claimData, + name = _asset$claimData.name, + claimId = _asset$claimData.claimId; + + return _react2.default.createElement( + 'div', + { className: 'row row--tall flex-container--column flex-container--center-center show-lite-container' }, + _react2.default.createElement(_SEO2.default, { pageTitle: name, asset: asset }), + _react2.default.createElement(_AssetDisplay2.default, null), + _react2.default.createElement( + _reactRouterDom.Link, + { id: 'asset-boilerpate', className: 'link--primary fine-print', to: '/' + claimId + '/' + name }, + 'hosted via Spee.ch' + ) + ); + } + return _react2.default.createElement( + 'div', + { className: 'row row--tall row--padded flex-container--column flex-container--center-center' }, + _react2.default.createElement( + 'p', + null, + 'loading asset data...' + ) + ); + } + }]); + + return ShowLite; +}(_react2.default.Component); + +; + +exports.default = ShowLite; + +/***/ }), +/* 132 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _ProgressBar = __webpack_require__(20); + +var _ProgressBar2 = _interopRequireDefault(_ProgressBar); + +var _asset_display_states = __webpack_require__(35); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var AssetDisplay = function (_React$Component) { + _inherits(AssetDisplay, _React$Component); + + function AssetDisplay() { + _classCallCheck(this, AssetDisplay); + + return _possibleConstructorReturn(this, (AssetDisplay.__proto__ || Object.getPrototypeOf(AssetDisplay)).apply(this, arguments)); + } + + _createClass(AssetDisplay, [{ + key: 'componentDidMount', + value: function componentDidMount() { + var _props$asset$claimDat = this.props.asset.claimData, + name = _props$asset$claimDat.name, + claimId = _props$asset$claimDat.claimId; + + this.props.onFileRequest(name, claimId); + } + }, { + key: 'render', + value: function render() { + var _props = this.props, + status = _props.status, + error = _props.error, + _props$asset$claimDat2 = _props.asset.claimData, + name = _props$asset$claimDat2.name, + claimId = _props$asset$claimDat2.claimId, + contentType = _props$asset$claimDat2.contentType, + fileExt = _props$asset$claimDat2.fileExt, + thumbnail = _props$asset$claimDat2.thumbnail; + + return _react2.default.createElement( + 'div', + { id: 'asset-display-component' }, + status === _asset_display_states.LOCAL_CHECK && _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'p', + null, + 'Checking to see if Spee.ch has your asset locally...' + ) + ), + status === _asset_display_states.UNAVAILABLE && _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'p', + null, + 'Sit tight, we\'re searching the LBRY blockchain for your asset!' + ), + _react2.default.createElement(_ProgressBar2.default, { size: 12 }), + _react2.default.createElement( + 'p', + null, + 'Curious what magic is happening here? ', + _react2.default.createElement( + 'a', + { className: 'link--primary', target: 'blank', href: 'https://lbry.io/faq/what-is-lbry' }, + 'Learn more.' + ) + ) + ), + status === _asset_display_states.ERROR && _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'p', + null, + 'Unfortunately, we couldn\'t download your asset from LBRY. You can help us out by sharing the below error message in the ', + _react2.default.createElement( + 'a', + { className: 'link--primary', href: 'https://discord.gg/YjYbwhS', target: '_blank' }, + 'LBRY discord' + ), + '.' + ), + _react2.default.createElement( + 'i', + null, + _react2.default.createElement( + 'p', + { id: 'error-message' }, + error + ) + ) + ), + status === _asset_display_states.AVAILABLE && function () { + switch (contentType) { + case 'image/jpeg': + case 'image/jpg': + case 'image/png': + return _react2.default.createElement('img', { + className: 'asset', + src: '/' + claimId + '/' + name + '.' + fileExt, + alt: name }); + case 'image/gif': + return _react2.default.createElement('img', { + className: 'asset', + src: '/' + claimId + '/' + name + '.' + fileExt, + alt: name + }); + case 'video/mp4': + return _react2.default.createElement( + 'video', + { className: 'asset video', controls: true, poster: thumbnail }, + _react2.default.createElement('source', { + src: '/' + claimId + '/' + name + '.' + fileExt + }), + _react2.default.createElement( + 'p', + null, + 'Your browser does not support the ', + _react2.default.createElement( + 'code', + null, + 'video' + ), + ' element.' + ) + ); + default: + return _react2.default.createElement( + 'p', + null, + 'Unsupported file type' + ); + } + }() + ); + } + }]); + + return AssetDisplay; +}(_react2.default.Component); + +; + +exports.default = AssetDisplay; + +/***/ }), +/* 133 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(134); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var show = _ref.show; + + // select request info + var requestId = show.request.id; + // select asset info + var asset = void 0; + var request = show.requestList[requestId] || null; + var assetList = show.assetList; + if (request && assetList) { + var assetKey = request.key; // note: just store this in the request + asset = assetList[assetKey] || null; + }; + // return props + return { + asset: asset + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 134 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _SEO = __webpack_require__(9); + +var _SEO2 = _interopRequireDefault(_SEO); + +var _NavBar = __webpack_require__(7); + +var _NavBar2 = _interopRequireDefault(_NavBar); + +var _ErrorPage = __webpack_require__(21); + +var _ErrorPage2 = _interopRequireDefault(_ErrorPage); + +var _AssetTitle = __webpack_require__(135); + +var _AssetTitle2 = _interopRequireDefault(_AssetTitle); + +var _AssetDisplay = __webpack_require__(42); + +var _AssetDisplay2 = _interopRequireDefault(_AssetDisplay); + +var _AssetInfo = __webpack_require__(137); + +var _AssetInfo2 = _interopRequireDefault(_AssetInfo); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ShowAssetDetails = function (_React$Component) { + _inherits(ShowAssetDetails, _React$Component); + + function ShowAssetDetails() { + _classCallCheck(this, ShowAssetDetails); + + return _possibleConstructorReturn(this, (ShowAssetDetails.__proto__ || Object.getPrototypeOf(ShowAssetDetails)).apply(this, arguments)); + } + + _createClass(ShowAssetDetails, [{ + key: 'render', + value: function render() { + var asset = this.props.asset; + + if (asset) { + var name = asset.claimData.name; + + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement(_SEO2.default, { pageTitle: name + ' - details', asset: asset }), + _react2.default.createElement(_NavBar2.default, null), + _react2.default.createElement( + 'div', + { className: 'row row--tall row--padded' }, + _react2.default.createElement( + 'div', + { className: 'column column--10' }, + _react2.default.createElement(_AssetTitle2.default, null) + ), + _react2.default.createElement( + 'div', + { className: 'column column--5 column--sml-10 align-content-top' }, + _react2.default.createElement( + 'div', + { className: 'row row--padded show-details-container' }, + _react2.default.createElement(_AssetDisplay2.default, null) + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--5 column--sml-10 align-content-top' }, + _react2.default.createElement( + 'div', + { className: 'row row--padded' }, + _react2.default.createElement(_AssetInfo2.default, null) + ) + ) + ) + ); + }; + return _react2.default.createElement(_ErrorPage2.default, { error: 'loading asset data...' }); + } + }]); + + return ShowAssetDetails; +}(_react2.default.Component); + +; + +exports.default = ShowAssetDetails; + +/***/ }), +/* 135 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(136); + +var _view2 = _interopRequireDefault(_view); + +var _show = __webpack_require__(13); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var show = _ref.show; + + var _selectAsset = (0, _show.selectAsset)(show), + title = _selectAsset.claimData.title; + + return { + title: title + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 136 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var AssetTitle = function AssetTitle(_ref) { + var title = _ref.title; + + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'span', + { className: 'text--large' }, + title + ) + ); +}; + +exports.default = AssetTitle; + +/***/ }), +/* 137 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(138); + +var _view2 = _interopRequireDefault(_view); + +var _show = __webpack_require__(13); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var show = _ref.show; + + // select asset + var asset = (0, _show.selectAsset)(show); + // return props + return { + asset: asset + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 138 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactRouterDom = __webpack_require__(3); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var AssetInfo = function (_React$Component) { + _inherits(AssetInfo, _React$Component); + + function AssetInfo(props) { + _classCallCheck(this, AssetInfo); + + var _this = _possibleConstructorReturn(this, (AssetInfo.__proto__ || Object.getPrototypeOf(AssetInfo)).call(this, props)); + + _this.copyToClipboard = _this.copyToClipboard.bind(_this); + return _this; + } + + _createClass(AssetInfo, [{ + key: 'copyToClipboard', + value: function copyToClipboard(event) { + var elementToCopy = event.target.dataset.elementtocopy; + var element = document.getElementById(elementToCopy); + element.select(); + try { + document.execCommand('copy'); + } catch (err) { + this.setState({ error: 'Oops, unable to copy' }); + } + } + }, { + key: 'render', + value: function render() { + var _props$asset = this.props.asset, + shortId = _props$asset.shortId, + _props$asset$claimDat = _props$asset.claimData, + channelName = _props$asset$claimDat.channelName, + certificateId = _props$asset$claimDat.certificateId, + description = _props$asset$claimDat.description, + name = _props$asset$claimDat.name, + claimId = _props$asset$claimDat.claimId, + fileExt = _props$asset$claimDat.fileExt, + contentType = _props$asset$claimDat.contentType, + thumbnail = _props$asset$claimDat.thumbnail, + host = _props$asset$claimDat.host; + + return _react2.default.createElement( + 'div', + null, + channelName && _react2.default.createElement( + 'div', + { className: 'row row--padded row--wide row--no-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--2 column--med-10' }, + _react2.default.createElement( + 'span', + { className: 'text' }, + 'Channel:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--8 column--med-10' }, + _react2.default.createElement( + 'span', + { className: 'text' }, + _react2.default.createElement( + _reactRouterDom.Link, + { to: '/' + channelName + ':' + certificateId }, + channelName + ) + ) + ) + ), + description && _react2.default.createElement( + 'div', + { className: 'row row--padded row--wide row--no-top' }, + _react2.default.createElement( + 'span', + { className: 'text' }, + description + ) + ), + _react2.default.createElement( + 'div', + { id: 'show-share-buttons' }, + _react2.default.createElement( + 'div', + { className: 'row row--padded row--wide row--no-top' }, + _react2.default.createElement( + 'div', + { className: 'column column--2 column--med-10' }, + _react2.default.createElement( + 'span', + { className: 'text' }, + 'Share:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--8 column--med-10' }, + _react2.default.createElement( + 'div', + { + className: 'row row--short row--wide flex-container--row flex-container--space-between-bottom flex-container--wrap' }, + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://twitter.com/intent/tweet?text=' + host + '/' + shortId + '/' + name }, + 'twitter' + ), + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://www.facebook.com/sharer/sharer.php?u=' + host + '/' + shortId + '/' + name }, + 'facebook' + ), + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'http://tumblr.com/widgets/share/tool?canonicalUrl=' + host + '/' + shortId + '/' + name }, + 'tumblr' + ), + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://www.reddit.com/submit?url=' + host + '/' + shortId + '/' + name + '&title=' + name }, + 'reddit' + ) + ) + ) + ) + ), + _react2.default.createElement( + 'div', + { className: 'row row--padded row--wide row--no-top' }, + _react2.default.createElement( + 'div', + { id: 'show-short-link' }, + _react2.default.createElement( + 'div', + { className: 'column column--2 column--med-10' }, + _react2.default.createElement( + 'span', + { className: 'text' }, + 'Link:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--8 column--med-10' }, + _react2.default.createElement( + 'div', + { className: 'row row--short row--wide' }, + _react2.default.createElement( + 'div', + { className: 'column column--7' }, + _react2.default.createElement( + 'div', + { className: 'input-error', id: 'input-error-copy-short-link', hidden: 'true' }, + 'error here' + ), + _react2.default.createElement('input', { type: 'text', id: 'short-link', className: 'input-disabled input-text--full-width', readOnly: true, + spellCheck: 'false', + value: host + '/' + shortId + '/' + name + '.' + fileExt, + onClick: this.select }) + ), + _react2.default.createElement('div', { className: 'column column--1' }), + _react2.default.createElement( + 'div', + { className: 'column column--2' }, + _react2.default.createElement( + 'button', + { className: 'button--primary button--wide', 'data-elementtocopy': 'short-link', + onClick: this.copyToClipboard }, + 'copy' + ) + ) + ) + ) + ), + _react2.default.createElement( + 'div', + { id: 'show-embed-code' }, + _react2.default.createElement( + 'div', + { className: 'column column--2 column--med-10' }, + _react2.default.createElement( + 'span', + { className: 'text' }, + 'Embed:' + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--8 column--med-10' }, + _react2.default.createElement( + 'div', + { className: 'row row--short row--wide' }, + _react2.default.createElement( + 'div', + { className: 'column column--7' }, + _react2.default.createElement( + 'div', + { className: 'input-error', id: 'input-error-copy-embed-text', hidden: 'true' }, + 'error here' + ), + contentType === 'video/mp4' ? _react2.default.createElement('input', { type: 'text', id: 'embed-text', className: 'input-disabled input-text--full-width', readOnly: true, + onClick: this.select, spellCheck: 'false', + value: '' }) : _react2.default.createElement('input', { type: 'text', id: 'embed-text', className: 'input-disabled input-text--full-width', readOnly: true, + onClick: this.select, spellCheck: 'false', + value: '' + }) + ), + _react2.default.createElement('div', { className: 'column column--1' }), + _react2.default.createElement( + 'div', + { className: 'column column--2' }, + _react2.default.createElement( + 'button', + { className: 'button--primary button--wide', 'data-elementtocopy': 'embed-text', + onClick: this.copyToClipboard }, + 'copy' + ) + ) + ) + ) + ) + ), + _react2.default.createElement( + 'div', + { className: 'flex-container--row flex-container--space-between-bottom' }, + _react2.default.createElement( + _reactRouterDom.Link, + { className: 'link--primary', to: '/' + shortId + '/' + name + '.' + fileExt }, + _react2.default.createElement( + 'span', + { + className: 'text' }, + 'Direct Link' + ) + ), + _react2.default.createElement( + 'a', + { className: 'link--primary', href: host + '/' + claimId + '/' + name + '.' + fileExt, download: name }, + 'Download' + ), + _react2.default.createElement( + 'a', + { className: 'link--primary', target: '_blank', href: 'https://lbry.io/dmca' }, + 'Report' + ) + ) + ); + } + }]); + + return AssetInfo; +}(_react2.default.Component); + +; + +exports.default = AssetInfo; + +/***/ }), +/* 139 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(140); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var show = _ref.show; + + // select request info + var requestId = show.request.id; + // select request + var previousRequest = show.requestList[requestId] || null; + // select channel + var channel = void 0; + if (previousRequest) { + var channelKey = previousRequest.key; + channel = show.channelList[channelKey] || null; + } + return { + channel: channel + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 140 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _SEO = __webpack_require__(9); + +var _SEO2 = _interopRequireDefault(_SEO); + +var _ErrorPage = __webpack_require__(21); + +var _ErrorPage2 = _interopRequireDefault(_ErrorPage); + +var _NavBar = __webpack_require__(7); + +var _NavBar2 = _interopRequireDefault(_NavBar); + +var _ChannelClaimsDisplay = __webpack_require__(141); + +var _ChannelClaimsDisplay2 = _interopRequireDefault(_ChannelClaimsDisplay); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ShowChannel = function (_React$Component) { + _inherits(ShowChannel, _React$Component); + + function ShowChannel() { + _classCallCheck(this, ShowChannel); + + return _possibleConstructorReturn(this, (ShowChannel.__proto__ || Object.getPrototypeOf(ShowChannel)).apply(this, arguments)); + } + + _createClass(ShowChannel, [{ + key: 'render', + value: function render() { + var channel = this.props.channel; + + if (channel) { + var name = channel.name, + longId = channel.longId, + shortId = channel.shortId; + + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement(_SEO2.default, { pageTitle: name, channel: channel }), + _react2.default.createElement(_NavBar2.default, null), + _react2.default.createElement( + 'div', + { className: 'row row--tall row--padded' }, + _react2.default.createElement( + 'div', + { className: 'column column--10' }, + _react2.default.createElement( + 'h2', + null, + 'channel name: ', + name + ), + _react2.default.createElement( + 'p', + { className: 'fine-print' }, + 'full channel id: ', + longId + ), + _react2.default.createElement( + 'p', + { className: 'fine-print' }, + 'short channel id: ', + shortId + ) + ), + _react2.default.createElement( + 'div', + { className: 'column column--10' }, + _react2.default.createElement(_ChannelClaimsDisplay2.default, null) + ) + ) + ); + }; + return _react2.default.createElement(_ErrorPage2.default, { error: 'loading channel data...' }); + } + }]); + + return ShowChannel; +}(_react2.default.Component); + +; + +exports.default = ShowChannel; + +/***/ }), +/* 141 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _show = __webpack_require__(8); + +var _view = __webpack_require__(142); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var show = _ref.show; + + // select channel key + var request = show.requestList[show.request.id]; + var channelKey = request.key; + // select channel claims + var channel = show.channelList[channelKey] || null; + // return props + return { + channelKey: channelKey, + channel: channel + }; +}; + +var mapDispatchToProps = { + onUpdateChannelClaims: _show.onUpdateChannelClaims +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default); + +/***/ }), +/* 142 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _AssetPreview = __webpack_require__(143); + +var _AssetPreview2 = _interopRequireDefault(_AssetPreview); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var ChannelClaimsDisplay = function (_React$Component) { + _inherits(ChannelClaimsDisplay, _React$Component); + + function ChannelClaimsDisplay(props) { + _classCallCheck(this, ChannelClaimsDisplay); + + var _this = _possibleConstructorReturn(this, (ChannelClaimsDisplay.__proto__ || Object.getPrototypeOf(ChannelClaimsDisplay)).call(this, props)); + + _this.showNextResultsPage = _this.showNextResultsPage.bind(_this); + _this.showPreviousResultsPage = _this.showPreviousResultsPage.bind(_this); + return _this; + } + + _createClass(ChannelClaimsDisplay, [{ + key: 'showPreviousResultsPage', + value: function showPreviousResultsPage() { + var currentPage = this.props.channel.claimsData.currentPage; + + var previousPage = parseInt(currentPage) - 1; + this.showNewPage(previousPage); + } + }, { + key: 'showNextResultsPage', + value: function showNextResultsPage() { + var currentPage = this.props.channel.claimsData.currentPage; + + var nextPage = parseInt(currentPage) + 1; + this.showNewPage(nextPage); + } + }, { + key: 'showNewPage', + value: function showNewPage(page) { + var _props = this.props, + channelKey = _props.channelKey, + _props$channel = _props.channel, + name = _props$channel.name, + longId = _props$channel.longId; + + this.props.onUpdateChannelClaims(channelKey, name, longId, page); + } + }, { + key: 'render', + value: function render() { + var _props$channel$claims = this.props.channel.claimsData, + claims = _props$channel$claims.claims, + currentPage = _props$channel$claims.currentPage, + totalPages = _props$channel$claims.totalPages; + + return _react2.default.createElement( + 'div', + { className: 'row row--tall' }, + claims.length > 0 ? _react2.default.createElement( + 'div', + null, + claims.map(function (claim, index) { + return _react2.default.createElement(_AssetPreview2.default, { + claimData: claim, + key: claim.name + '-' + index + }); + }), + _react2.default.createElement( + 'div', + null, + currentPage > 1 && _react2.default.createElement( + 'button', + { className: 'button--secondary', onClick: this.showPreviousResultsPage }, + 'Previous Page' + ), + currentPage < totalPages && _react2.default.createElement( + 'button', + { className: 'button--secondary', onClick: this.showNextResultsPage }, + 'Next Page' + ) + ) + ) : _react2.default.createElement( + 'p', + null, + 'There are no claims in this channel' + ) + ); + } + }]); + + return ChannelClaimsDisplay; +}(_react2.default.Component); + +; + +exports.default = ChannelClaimsDisplay; + +/***/ }), +/* 143 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(144); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var defaultThumbnail = _ref.site.defaults.defaultThumbnail; + + return { + defaultThumbnail: defaultThumbnail + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 144 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _reactRouterDom = __webpack_require__(3); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var AssetPreview = function AssetPreview(_ref) { + var defaultThumbnail = _ref.defaultThumbnail, + _ref$claimData = _ref.claimData, + name = _ref$claimData.name, + claimId = _ref$claimData.claimId, + fileExt = _ref$claimData.fileExt, + contentType = _ref$claimData.contentType, + thumbnail = _ref$claimData.thumbnail; + + var directSourceLink = claimId + '/' + name + '.' + fileExt; + var showUrlLink = '/' + claimId + '/' + name; + return _react2.default.createElement( + 'div', + { className: 'asset-holder' }, + _react2.default.createElement( + _reactRouterDom.Link, + { to: showUrlLink }, + function () { + switch (contentType) { + case 'image/jpeg': + case 'image/jpg': + case 'image/png': + case 'image/gif': + return _react2.default.createElement('img', { + className: 'asset-preview', + src: directSourceLink, + alt: name + }); + case 'video/mp4': + return _react2.default.createElement('img', { + className: 'asset-preview video', + src: thumbnail || defaultThumbnail, + alt: name + }); + default: + return _react2.default.createElement( + 'p', + null, + 'unsupported file type' + ); + } + }() + ) + ); +}; + +exports.default = AssetPreview; + +/***/ }), +/* 145 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactRedux = __webpack_require__(1); + +var _view = __webpack_require__(146); + +var _view2 = _interopRequireDefault(_view); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var mapStateToProps = function mapStateToProps(_ref) { + var _ref$site = _ref.site, + host = _ref$site.host, + title = _ref$site.title; + + return { + host: host, + title: title + }; +}; + +exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default); + +/***/ }), +/* 146 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _NavBar = __webpack_require__(7); + +var _NavBar2 = _interopRequireDefault(_NavBar); + +var _reactHelmet = __webpack_require__(14); + +var _reactHelmet2 = _interopRequireDefault(_reactHelmet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var FourOhForPage = function (_React$Component) { + _inherits(FourOhForPage, _React$Component); + + function FourOhForPage() { + _classCallCheck(this, FourOhForPage); + + return _possibleConstructorReturn(this, (FourOhForPage.__proto__ || Object.getPrototypeOf(FourOhForPage)).apply(this, arguments)); + } + + _createClass(FourOhForPage, [{ + key: 'render', + value: function render() { + var _props = this.props, + title = _props.title, + host = _props.host; + + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + _reactHelmet2.default, + null, + _react2.default.createElement( + 'title', + null, + title, + ' - 404' + ), + _react2.default.createElement('link', { rel: 'canonical', href: host + '/404' }) + ), + _react2.default.createElement(_NavBar2.default, null), + _react2.default.createElement( + 'div', + { className: 'row row--padded' }, + _react2.default.createElement( + 'h2', + null, + '404' + ), + _react2.default.createElement( + 'p', + null, + 'That page does not exist' + ) + ) + ); + } + }]); + + return FourOhForPage; +}(_react2.default.Component); + +; + +exports.default = FourOhForPage; + +/***/ }), +/* 147 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _require = __webpack_require__(17), + sendGAServeEvent = _require.sendGAServeEvent; + +var _require2 = __webpack_require__(148), + determineResponseType = _require2.determineResponseType, + flipClaimNameAndIdForBackwardsCompatibility = _require2.flipClaimNameAndIdForBackwardsCompatibility, + logRequestData = _require2.logRequestData, + getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset; + +var lbryUri = __webpack_require__(149); +var handleShowRender = __webpack_require__(150); +var SERVE = 'SERVE'; + +module.exports = function (app) { + // route to serve a specific asset using the channel or claim id + app.get('/:identifier/:claim', function (req, res) { + var headers = req.headers, + ip = req.ip, + originalUrl = req.originalUrl, + params = req.params; + // decide if this is a show request + + var hasFileExtension = void 0; + try { + var _lbryUri$parseModifie = lbryUri.parseModifier(params.claim); + + hasFileExtension = _lbryUri$parseModifie.hasFileExtension; + } catch (error) { + return res.status(400).json({ success: false, message: error.message }); + } + var responseType = determineResponseType(hasFileExtension, headers); + if (responseType !== SERVE) { + return handleShowRender(req, res); + } + // handle serve request + // send google analytics + sendGAServeEvent(headers, ip, originalUrl); + // parse the claim + var claimName = void 0; + try { + var _lbryUri$parseClaim = lbryUri.parseClaim(params.claim); + + claimName = _lbryUri$parseClaim.claimName; + } catch (error) { + return res.status(400).json({ success: false, message: error.message }); + } + // parse the identifier + var isChannel = void 0, + channelName = void 0, + channelClaimId = void 0, + claimId = void 0; + try { + var _lbryUri$parseIdentif = lbryUri.parseIdentifier(params.identifier); + + isChannel = _lbryUri$parseIdentif.isChannel; + channelName = _lbryUri$parseIdentif.channelName; + channelClaimId = _lbryUri$parseIdentif.channelClaimId; + claimId = _lbryUri$parseIdentif.claimId; + } catch (error) { + return res.status(400).json({ success: false, message: error.message }); + } + if (!isChannel) { + var _flipClaimNameAndIdFo = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName); + + var _flipClaimNameAndIdFo2 = _slicedToArray(_flipClaimNameAndIdFo, 2); + + claimId = _flipClaimNameAndIdFo2[0]; + claimName = _flipClaimNameAndIdFo2[1]; + } + // log the request data for debugging + logRequestData(responseType, claimName, channelName, claimId); + // get the claim Id and then serve the asset + getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res); + }); + // route to serve the winning asset at a claim or a channel page + app.get('/:claim', function (req, res) { + var headers = req.headers, + ip = req.ip, + originalUrl = req.originalUrl, + params = req.params; + // decide if this is a show request + + var hasFileExtension = void 0; + try { + var _lbryUri$parseModifie2 = lbryUri.parseModifier(params.claim); + + hasFileExtension = _lbryUri$parseModifie2.hasFileExtension; + } catch (error) { + return res.status(400).json({ success: false, message: error.message }); + } + var responseType = determineResponseType(hasFileExtension, headers); + if (responseType !== SERVE) { + return handleShowRender(req, res); + } + // handle serve request + // send google analytics + sendGAServeEvent(headers, ip, originalUrl); + // parse the claim + var claimName = void 0; + try { + var _lbryUri$parseClaim2 = lbryUri.parseClaim(params.claim); + + claimName = _lbryUri$parseClaim2.claimName; + } catch (error) { + return res.status(400).json({ success: false, message: error.message }); + } + // log the request data for debugging + logRequestData(responseType, claimName, null, null); + // get the claim Id and then serve the asset + getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res); + }); +}; + +/***/ }), +/* 148 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var logger = __webpack_require__(2); + +var _require = __webpack_require__(28), + getClaimId = _require.getClaimId, + getLocalFileRecord = _require.getLocalFileRecord; + +var _require2 = __webpack_require__(27), + handleErrorResponse = _require2.handleErrorResponse; + +var SERVE = 'SERVE'; +var SHOW = 'SHOW'; +var NO_FILE = 'NO_FILE'; +var NO_CHANNEL = 'NO_CHANNEL'; +var NO_CLAIM = 'NO_CLAIM'; + +function clientAcceptsHtml(_ref) { + var accept = _ref.accept; + + return accept && accept.match(/text\/html/); +}; + +function requestIsFromBrowser(headers) { + return headers['user-agent'] && headers['user-agent'].match(/Mozilla/); +}; + +function clientWantsAsset(_ref2) { + var accept = _ref2.accept, + range = _ref2.range; + + var imageIsWanted = accept && accept.match(/image\/.*/) && !accept.match(/text\/html/) && !accept.match(/text\/\*/); + var videoIsWanted = accept && range; + return imageIsWanted || videoIsWanted; +}; + +function isValidClaimId(claimId) { + return claimId.length === 40 && !/[^A-Za-z0-9]/g.test(claimId); +}; + +function isValidShortId(claimId) { + return claimId.length === 1; // it should really evaluate the short url itself +}; + +function isValidShortIdOrClaimId(input) { + return isValidClaimId(input) || isValidShortId(input); +}; + +function serveAssetToClient(claimId, name, res) { + return getLocalFileRecord(claimId, name).then(function (fileRecord) { + // check that a local record was found + if (fileRecord === NO_FILE) { + return res.status(307).redirect('/api/claim/get/' + name + '/' + claimId); + } + // serve the file + var filePath = fileRecord.filePath, + fileType = fileRecord.fileType; + + logger.verbose('serving file: ' + filePath); + var sendFileOptions = { + headers: { + 'X-Content-Type-Options': 'nosniff', + 'Content-Type': fileType || 'image/jpeg' + } + }; + res.status(200).sendFile(filePath, sendFileOptions); + }).catch(function (error) { + throw error; + }); +}; + +module.exports = { + getClaimIdAndServeAsset: function getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res) { + // get the claim Id and then serve the asset + getClaimId(channelName, channelClaimId, claimName, claimId).then(function (fullClaimId) { + if (fullClaimId === NO_CLAIM) { + return res.status(404).json({ success: false, message: 'no claim id could be found' }); + } else if (fullClaimId === NO_CHANNEL) { + return res.status(404).json({ success: false, message: 'no channel id could be found' }); + } + serveAssetToClient(fullClaimId, claimName, res); + // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success'); + }).catch(function (error) { + handleErrorResponse(originalUrl, ip, error, res); + // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail'); + }); + }, + determineResponseType: function determineResponseType(hasFileExtension, headers) { + var responseType = void 0; + if (hasFileExtension) { + responseType = SERVE; // assume a serve request if file extension is present + if (clientAcceptsHtml(headers)) { + // if the request comes from a browser, change it to a show request + responseType = SHOW; + } + } else { + responseType = SHOW; + if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) { + // this is in case someone embeds a show url + logger.debug('Show request came from browser but wants an image/video. Changing response to serve...'); + responseType = SERVE; + } + } + return responseType; + }, + flipClaimNameAndIdForBackwardsCompatibility: function flipClaimNameAndIdForBackwardsCompatibility(identifier, name) { + // this is a patch for backwards compatability with '/name/claim_id' url format + if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) { + var tempName = name; + name = identifier; + identifier = tempName; + } + return [identifier, name]; + }, + logRequestData: function logRequestData(responseType, claimName, channelName, claimId) { + logger.debug('responseType ===', responseType); + logger.debug('claim name === ', claimName); + logger.debug('channel name ===', channelName); + logger.debug('claim id ===', claimId); + } +}; + +/***/ }), +/* 149 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var logger = __webpack_require__(2); + +module.exports = { + REGEXP_INVALID_CLAIM: /[^A-Za-z0-9-]/g, + REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g, + REGEXP_ADDRESS: /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/, + CHANNEL_CHAR: '@', + parseIdentifier: function parseIdentifier(identifier) { + logger.debug('parsing identifier:', identifier); + var componentsRegex = new RegExp('([^:$#/]*)' + // value (stops at the first separator or end) + '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end) + ); + + var _componentsRegex$exec = componentsRegex.exec(identifier).map(function (match) { + return match || null; + }), + _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 4), + proto = _componentsRegex$exec2[0], + value = _componentsRegex$exec2[1], + modifierSeperator = _componentsRegex$exec2[2], + modifier = _componentsRegex$exec2[3]; + + logger.debug(proto + ', ' + value + ', ' + modifierSeperator + ', ' + modifier); + + // Validate and process name + if (!value) { + throw new Error('Check your url. No channel name provided before "' + modifierSeperator + '"'); + } + var isChannel = value.startsWith(module.exports.CHANNEL_CHAR); + var channelName = isChannel ? value : null; + var claimId = void 0; + if (isChannel) { + if (!channelName) { + throw new Error('No channel name after @.'); + } + var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL); + if (nameBadChars) { + throw new Error('Invalid characters in channel name: ' + nameBadChars.join(', ') + '.'); + } + } else { + claimId = value; + } + + // Validate and process modifier + var channelClaimId = void 0; + if (modifierSeperator) { + if (!modifier) { + throw new Error('No modifier provided after separator "' + modifierSeperator + '"'); + } + + if (modifierSeperator === ':') { + channelClaimId = modifier; + } else { + throw new Error('The "' + modifierSeperator + '" modifier is not currently supported'); + } + } + return { + isChannel: isChannel, + channelName: channelName, + channelClaimId: channelClaimId, + claimId: claimId + }; + }, + parseClaim: function parseClaim(claim) { + logger.debug('parsing name:', claim); + var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier) + '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end) + ); + + var _componentsRegex$exec3 = componentsRegex.exec(claim).map(function (match) { + return match || null; + }), + _componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4), + proto = _componentsRegex$exec4[0], + claimName = _componentsRegex$exec4[1], + modifierSeperator = _componentsRegex$exec4[2], + modifier = _componentsRegex$exec4[3]; + + logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier); + + // Validate and process name + if (!claimName) { + throw new Error('No claim name provided before .'); + } + var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM); + if (nameBadChars) { + throw new Error('Invalid characters in claim name: ' + nameBadChars.join(', ') + '.'); + } + // Validate and process modifier + if (modifierSeperator) { + if (!modifier) { + throw new Error('No file extension provided after separator ' + modifierSeperator + '.'); + } + if (modifierSeperator !== '.') { + throw new Error('The ' + modifierSeperator + ' modifier is not supported in the claim name'); + } + } + // return results + return { + claimName: claimName + }; + }, + parseModifier: function parseModifier(claim) { + logger.debug('parsing modifier:', claim); + var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier) + '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end) + ); + + var _componentsRegex$exec5 = componentsRegex.exec(claim).map(function (match) { + return match || null; + }), + _componentsRegex$exec6 = _slicedToArray(_componentsRegex$exec5, 4), + proto = _componentsRegex$exec6[0], + claimName = _componentsRegex$exec6[1], + modifierSeperator = _componentsRegex$exec6[2], + modifier = _componentsRegex$exec6[3]; + + logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier); + // Validate and process modifier + var hasFileExtension = false; + if (modifierSeperator) { + hasFileExtension = true; + } + return { + hasFileExtension: hasFileExtension + }; + } +}; + +/***/ }), +/* 150 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +var _server = __webpack_require__(30); + +var _redux = __webpack_require__(18); + +var _index = __webpack_require__(31); + +var _index2 = _interopRequireDefault(_index); + +var _reactRedux = __webpack_require__(1); + +var _reactRouterDom = __webpack_require__(3); + +var _index3 = __webpack_require__(36); + +var _index4 = _interopRequireDefault(_index3); + +var _app = __webpack_require__(37); + +var _app2 = _interopRequireDefault(_app); + +var _renderFullPage = __webpack_require__(43); + +var _renderFullPage2 = _interopRequireDefault(_renderFullPage); + +var _reduxSaga = __webpack_require__(151); + +var _reduxSaga2 = _interopRequireDefault(_reduxSaga); + +var _effects = __webpack_require__(15); + +var _show_uri = __webpack_require__(152); + +var _show = __webpack_require__(8); + +var _reactHelmet = __webpack_require__(14); + +var _reactHelmet2 = _interopRequireDefault(_reactHelmet); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var returnSagaWithParams = function returnSagaWithParams(saga, params) { + return (/*#__PURE__*/regeneratorRuntime.mark(function _callee() { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return (0, _effects.call)(saga, params); + + case 2: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + }) + ); +}; + +module.exports = function (req, res) { + var context = {}; + + // create and apply middleware + var sagaMiddleware = (0, _reduxSaga2.default)(); + var middleware = (0, _redux.applyMiddleware)(sagaMiddleware); + + // create a new Redux store instance + var store = (0, _redux.createStore)(_index2.default, middleware); + + // create saga + var action = (0, _show.onHandleShowPageUri)(req.params); + var saga = returnSagaWithParams(_show_uri.handleShowPageUri, action); + + // run the saga middleware + sagaMiddleware.run(saga).done.then(function () { + // render component to a string + var html = (0, _server.renderToString)(_react2.default.createElement( + _reactRedux.Provider, + { store: store }, + _react2.default.createElement( + _reactRouterDom.StaticRouter, + { location: req.url, context: context }, + _react2.default.createElement( + _index4.default, + null, + _react2.default.createElement(_app2.default, null) + ) + ) + )); + + // get head tags from helmet + var helmet = _reactHelmet2.default.renderStatic(); + + // check for a redirect + if (context.url) { + return res.redirect(301, context.url); + } + + // get the initial state from our Redux store + var preloadedState = store.getState(); + + // send the rendered page back to the client + res.send((0, _renderFullPage2.default)(helmet, html, preloadedState)); + }); +}; + +/***/ }), +/* 151 */ +/***/ (function(module, exports) { + +module.exports = require("redux-saga"); + +/***/ }), +/* 152 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.handleShowPageUri = handleShowPageUri; +exports.watchHandleShowPageUri = watchHandleShowPageUri; + +var _effects = __webpack_require__(15); + +var _show_action_types = __webpack_require__(12); + +var actions = _interopRequireWildcard(_show_action_types); + +var _show = __webpack_require__(8); + +var _show_asset = __webpack_require__(153); + +var _show_channel = __webpack_require__(155); + +var _lbryUri = __webpack_require__(157); + +var _lbryUri2 = _interopRequireDefault(_lbryUri); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var _marked = /*#__PURE__*/regeneratorRuntime.mark(parseAndUpdateIdentifierAndClaim), + _marked2 = /*#__PURE__*/regeneratorRuntime.mark(parseAndUpdateClaimOnly), + _marked3 = /*#__PURE__*/regeneratorRuntime.mark(handleShowPageUri), + _marked4 = /*#__PURE__*/regeneratorRuntime.mark(watchHandleShowPageUri); + +function parseAndUpdateIdentifierAndClaim(modifier, claim) { + var isChannel, channelName, channelClaimId, claimId, claimName, extension, _lbryUri$parseIdentif, _lbryUri$parseClaim; + + return regeneratorRuntime.wrap(function parseAndUpdateIdentifierAndClaim$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + // this is a request for an asset + // claim will be an asset claim + // the identifier could be a channel or a claim id + isChannel = void 0, channelName = void 0, channelClaimId = void 0, claimId = void 0, claimName = void 0, extension = void 0; + _context.prev = 1; + _lbryUri$parseIdentif = _lbryUri2.default.parseIdentifier(modifier); + isChannel = _lbryUri$parseIdentif.isChannel; + channelName = _lbryUri$parseIdentif.channelName; + channelClaimId = _lbryUri$parseIdentif.channelClaimId; + claimId = _lbryUri$parseIdentif.claimId; + _lbryUri$parseClaim = _lbryUri2.default.parseClaim(claim); + claimName = _lbryUri$parseClaim.claimName; + extension = _lbryUri$parseClaim.extension; + _context.next = 17; + break; + + case 12: + _context.prev = 12; + _context.t0 = _context['catch'](1); + _context.next = 16; + return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message)); + + case 16: + return _context.abrupt('return', _context.sent); + + case 17: + if (!isChannel) { + _context.next = 21; + break; + } + + _context.next = 20; + return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, null, channelName, channelClaimId, extension)); + + case 20: + return _context.abrupt('return', _context.sent); + + case 21: + ; + _context.next = 24; + return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, claimId, null, null, extension)); + + case 24: + case 'end': + return _context.stop(); + } + } + }, _marked, this, [[1, 12]]); +} +function parseAndUpdateClaimOnly(claim) { + var isChannel, channelName, channelClaimId, _lbryUri$parseIdentif2, claimName, extension, _lbryUri$parseClaim2; + + return regeneratorRuntime.wrap(function parseAndUpdateClaimOnly$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + // this could be a request for an asset or a channel page + // claim could be an asset claim or a channel claim + isChannel = void 0, channelName = void 0, channelClaimId = void 0; + _context2.prev = 1; + _lbryUri$parseIdentif2 = _lbryUri2.default.parseIdentifier(claim); + isChannel = _lbryUri$parseIdentif2.isChannel; + channelName = _lbryUri$parseIdentif2.channelName; + channelClaimId = _lbryUri$parseIdentif2.channelClaimId; + _context2.next = 13; + break; + + case 8: + _context2.prev = 8; + _context2.t0 = _context2['catch'](1); + _context2.next = 12; + return (0, _effects.put)((0, _show.onRequestError)(_context2.t0.message)); + + case 12: + return _context2.abrupt('return', _context2.sent); + + case 13: + if (!isChannel) { + _context2.next = 17; + break; + } + + _context2.next = 16; + return (0, _effects.call)(_show_channel.newChannelRequest, (0, _show.onNewChannelRequest)(channelName, channelClaimId)); + + case 16: + return _context2.abrupt('return', _context2.sent); + + case 17: + // if not for a channel, parse the claim request + claimName = void 0, extension = void 0; + _context2.prev = 18; + _lbryUri$parseClaim2 = _lbryUri2.default.parseClaim(claim); + claimName = _lbryUri$parseClaim2.claimName; + extension = _lbryUri$parseClaim2.extension; + _context2.next = 29; + break; + + case 24: + _context2.prev = 24; + _context2.t1 = _context2['catch'](18); + _context2.next = 28; + return (0, _effects.put)((0, _show.onRequestError)(_context2.t1.message)); + + case 28: + return _context2.abrupt('return', _context2.sent); + + case 29: + _context2.next = 31; + return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, null, null, null, extension)); + + case 31: + case 'end': + return _context2.stop(); + } + } + }, _marked2, this, [[1, 8], [18, 24]]); +} + +function handleShowPageUri(action) { + var _action$data, identifier, claim; + + return regeneratorRuntime.wrap(function handleShowPageUri$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _action$data = action.data, identifier = _action$data.identifier, claim = _action$data.claim; + + if (!identifier) { + _context3.next = 5; + break; + } + + _context3.next = 4; + return (0, _effects.call)(parseAndUpdateIdentifierAndClaim, identifier, claim); + + case 4: + return _context3.abrupt('return', _context3.sent); + + case 5: + _context3.next = 7; + return (0, _effects.call)(parseAndUpdateClaimOnly, claim); + + case 7: + case 'end': + return _context3.stop(); + } + } + }, _marked3, this); +}; + +function watchHandleShowPageUri() { + return regeneratorRuntime.wrap(function watchHandleShowPageUri$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return (0, _effects.takeLatest)(actions.HANDLE_SHOW_URI, handleShowPageUri); + + case 2: + case 'end': + return _context4.stop(); + } + } + }, _marked4, this); +}; + +/***/ }), +/* 153 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.newAssetRequest = newAssetRequest; +exports.watchNewAssetRequest = watchNewAssetRequest; + +var _effects = __webpack_require__(15); + +var _show_action_types = __webpack_require__(12); + +var actions = _interopRequireWildcard(_show_action_types); + +var _show = __webpack_require__(8); + +var _assetApi = __webpack_require__(154); + +var _show2 = __webpack_require__(13); + +var _site = __webpack_require__(44); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var _marked = /*#__PURE__*/regeneratorRuntime.mark(newAssetRequest), + _marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchNewAssetRequest); + +function newAssetRequest(action) { + var _action$data, requestType, requestId, name, modifier, state, host, longId, _ref, assetKey, shortId, _ref2, claimData, _ref3; + + return regeneratorRuntime.wrap(function newAssetRequest$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _action$data = action.data, requestType = _action$data.requestType, requestId = _action$data.requestId, name = _action$data.name, modifier = _action$data.modifier; + // put an action to update the request in redux + + _context.next = 3; + return (0, _effects.put)((0, _show.onRequestUpdate)(requestType, requestId)); + + case 3: + _context.next = 5; + return (0, _effects.select)(_show2.selectShowState); + + case 5: + state = _context.sent; + _context.next = 8; + return (0, _effects.select)(_site.selectSiteHost); + + case 8: + host = _context.sent; + + if (!state.requestList[requestId]) { + _context.next = 11; + break; + } + + return _context.abrupt('return', null); + + case 11: + // get long id && add request to request list + longId = void 0; + _context.prev = 12; + _context.next = 15; + return (0, _effects.call)(_assetApi.getLongClaimId, host, name, modifier); + + case 15: + _ref = _context.sent; + longId = _ref.data; + _context.next = 24; + break; + + case 19: + _context.prev = 19; + _context.t0 = _context['catch'](12); + _context.next = 23; + return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message)); + + case 23: + return _context.abrupt('return', _context.sent); + + case 24: + assetKey = 'a#' + name + '#' + longId; + _context.next = 27; + return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, assetKey)); + + case 27: + if (!state.assetList[assetKey]) { + _context.next = 29; + break; + } + + return _context.abrupt('return', null); + + case 29: + // get short Id + shortId = void 0; + _context.prev = 30; + _context.next = 33; + return (0, _effects.call)(_assetApi.getShortId, host, name, longId); + + case 33: + _ref2 = _context.sent; + shortId = _ref2.data; + _context.next = 42; + break; + + case 37: + _context.prev = 37; + _context.t1 = _context['catch'](30); + _context.next = 41; + return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message)); + + case 41: + return _context.abrupt('return', _context.sent); + + case 42: + // get asset claim data + claimData = void 0; + _context.prev = 43; + _context.next = 46; + return (0, _effects.call)(_assetApi.getClaimData, host, name, longId); + + case 46: + _ref3 = _context.sent; + claimData = _ref3.data; + _context.next = 55; + break; + + case 50: + _context.prev = 50; + _context.t2 = _context['catch'](43); + _context.next = 54; + return (0, _effects.put)((0, _show.onRequestError)(_context.t2.message)); + + case 54: + return _context.abrupt('return', _context.sent); + + case 55: + _context.next = 57; + return (0, _effects.put)((0, _show.addAssetToAssetList)(assetKey, null, name, longId, shortId, claimData)); + + case 57: + _context.next = 59; + return (0, _effects.put)((0, _show.onRequestError)(null)); + + case 59: + case 'end': + return _context.stop(); + } + } + }, _marked, this, [[12, 19], [30, 37], [43, 50]]); +}; + +function watchNewAssetRequest() { + return regeneratorRuntime.wrap(function watchNewAssetRequest$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return (0, _effects.takeLatest)(actions.ASSET_REQUEST_NEW, newAssetRequest); + + case 2: + case 'end': + return _context2.stop(); + } + } + }, _marked2, this); +}; + +/***/ }), +/* 154 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getLongClaimId = getLongClaimId; +exports.getShortId = getShortId; +exports.getClaimData = getClaimData; + +var _request = __webpack_require__(11); + +var _request2 = _interopRequireDefault(_request); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function getLongClaimId(host, name, modifier) { + var body = {}; + // create request params + if (modifier) { + if (modifier.id) { + body['claimId'] = modifier.id; + } else { + body['channelName'] = modifier.channel.name; + body['channelClaimId'] = modifier.channel.id; + } + } + body['claimName'] = name; + var params = { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }; + // create url + var url = host + '/api/claim/long-id'; + // return the request promise + return (0, _request2.default)(url, params); +}; + +function getShortId(host, name, claimId) { + var url = host + '/api/claim/short-id/' + claimId + '/' + name; + return (0, _request2.default)(url); +}; + +function getClaimData(host, name, claimId) { + var url = host + '/api/claim/data/' + name + '/' + claimId; + return (0, _request2.default)(url); +}; + +/***/ }), +/* 155 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.newChannelRequest = newChannelRequest; +exports.watchNewChannelRequest = watchNewChannelRequest; +exports.watchUpdateChannelClaims = watchUpdateChannelClaims; + +var _effects = __webpack_require__(15); + +var _show_action_types = __webpack_require__(12); + +var actions = _interopRequireWildcard(_show_action_types); + +var _show = __webpack_require__(8); + +var _channelApi = __webpack_require__(156); + +var _show2 = __webpack_require__(13); + +var _site = __webpack_require__(44); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var _marked = /*#__PURE__*/regeneratorRuntime.mark(newChannelRequest), + _marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchNewChannelRequest), + _marked3 = /*#__PURE__*/regeneratorRuntime.mark(getNewClaimsAndUpdateChannel), + _marked4 = /*#__PURE__*/regeneratorRuntime.mark(watchUpdateChannelClaims); + +function newChannelRequest(action) { + var _action$data, requestType, requestId, channelName, channelId, state, host, longId, shortId, _ref, _ref$data, channelKey, claimsData, _ref2; + + return regeneratorRuntime.wrap(function newChannelRequest$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _action$data = action.data, requestType = _action$data.requestType, requestId = _action$data.requestId, channelName = _action$data.channelName, channelId = _action$data.channelId; + // put an action to update the request in redux + + _context.next = 3; + return (0, _effects.put)((0, _show.onRequestUpdate)(requestType, requestId)); + + case 3: + _context.next = 5; + return (0, _effects.select)(_show2.selectShowState); + + case 5: + state = _context.sent; + _context.next = 8; + return (0, _effects.select)(_site.selectSiteHost); + + case 8: + host = _context.sent; + + if (!state.requestList[requestId]) { + _context.next = 11; + break; + } + + return _context.abrupt('return', null); + + case 11: + // get channel long id + longId = void 0, shortId = void 0; + _context.prev = 12; + _context.next = 15; + return (0, _effects.call)(_channelApi.getChannelData, host, channelName, channelId); + + case 15: + _ref = _context.sent; + _ref$data = _ref.data; + longId = _ref$data.longChannelClaimId; + shortId = _ref$data.shortChannelClaimId; + _context.next = 26; + break; + + case 21: + _context.prev = 21; + _context.t0 = _context['catch'](12); + _context.next = 25; + return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message)); + + case 25: + return _context.abrupt('return', _context.sent); + + case 26: + // store the request in the channel requests list + channelKey = 'c#' + channelName + '#' + longId; + _context.next = 29; + return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, channelKey)); + + case 29: + if (!state.channelList[channelKey]) { + _context.next = 31; + break; + } + + return _context.abrupt('return', null); + + case 31: + // get channel claims data + claimsData = void 0; + _context.prev = 32; + _context.next = 35; + return (0, _effects.call)(_channelApi.getChannelClaims, host, longId, channelName, 1); + + case 35: + _ref2 = _context.sent; + claimsData = _ref2.data; + _context.next = 44; + break; + + case 39: + _context.prev = 39; + _context.t1 = _context['catch'](32); + _context.next = 43; + return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message)); + + case 43: + return _context.abrupt('return', _context.sent); + + case 44: + _context.next = 46; + return (0, _effects.put)((0, _show.addNewChannelToChannelList)(channelKey, channelName, shortId, longId, claimsData)); + + case 46: + _context.next = 48; + return (0, _effects.put)((0, _show.onRequestError)(null)); + + case 48: + case 'end': + return _context.stop(); + } + } + }, _marked, this, [[12, 21], [32, 39]]); +} + +function watchNewChannelRequest() { + return regeneratorRuntime.wrap(function watchNewChannelRequest$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return (0, _effects.takeLatest)(actions.CHANNEL_REQUEST_NEW, newChannelRequest); + + case 2: + case 'end': + return _context2.stop(); + } + } + }, _marked2, this); +}; + +function getNewClaimsAndUpdateChannel(action) { + var _action$data2, channelKey, name, longId, page, host, claimsData, _ref3; + + return regeneratorRuntime.wrap(function getNewClaimsAndUpdateChannel$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _action$data2 = action.data, channelKey = _action$data2.channelKey, name = _action$data2.name, longId = _action$data2.longId, page = _action$data2.page; + _context3.next = 3; + return (0, _effects.select)(_site.selectSiteHost); + + case 3: + host = _context3.sent; + claimsData = void 0; + _context3.prev = 5; + _context3.next = 8; + return (0, _effects.call)(_channelApi.getChannelClaims, host, longId, name, page); + + case 8: + _ref3 = _context3.sent; + claimsData = _ref3.data; + _context3.next = 17; + break; + + case 12: + _context3.prev = 12; + _context3.t0 = _context3['catch'](5); + _context3.next = 16; + return (0, _effects.put)((0, _show.onRequestError)(_context3.t0.message)); + + case 16: + return _context3.abrupt('return', _context3.sent); + + case 17: + _context3.next = 19; + return (0, _effects.put)((0, _show.updateChannelClaims)(channelKey, claimsData)); + + case 19: + case 'end': + return _context3.stop(); + } + } + }, _marked3, this, [[5, 12]]); +} + +function watchUpdateChannelClaims() { + return regeneratorRuntime.wrap(function watchUpdateChannelClaims$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return (0, _effects.takeLatest)(actions.CHANNEL_CLAIMS_UPDATE_ASYNC, getNewClaimsAndUpdateChannel); + + case 2: + case 'end': + return _context4.stop(); + } + } + }, _marked4, this); +} + +/***/ }), +/* 156 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getChannelData = getChannelData; +exports.getChannelClaims = getChannelClaims; + +var _request = __webpack_require__(11); + +var _request2 = _interopRequireDefault(_request); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function getChannelData(host, id, name) { + if (!id) id = 'none'; + var url = host + '/api/channel/data/' + name + '/' + id; + return (0, _request2.default)(url); +}; + +function getChannelClaims(host, longId, name, page) { + if (!page) page = 1; + var url = host + '/api/channel/claims/' + name + '/' + longId + '/' + page; + return (0, _request2.default)(url); +}; + +/***/ }), +/* 157 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +module.exports = { + REGEXP_INVALID_CLAIM: /[^A-Za-z0-9-]/g, + REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g, + REGEXP_ADDRESS: /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/, + CHANNEL_CHAR: '@', + parseIdentifier: function parseIdentifier(identifier) { + var componentsRegex = new RegExp('([^:$#/]*)' + // value (stops at the first separator or end) + '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end) + ); + + var _componentsRegex$exec = componentsRegex // eslint-disable-line no-unused-vars + .exec(identifier).map(function (match) { + return match || null; + }), + _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 4), + proto = _componentsRegex$exec2[0], + value = _componentsRegex$exec2[1], + modifierSeperator = _componentsRegex$exec2[2], + modifier = _componentsRegex$exec2[3]; + + // Validate and process name + + + if (!value) { + throw new Error('Check your URL. No channel name provided before "' + modifierSeperator + '"'); + } + var isChannel = value.startsWith(module.exports.CHANNEL_CHAR); + var channelName = isChannel ? value : null; + var claimId = void 0; + if (isChannel) { + if (!channelName) { + throw new Error('Check your URL. No channel name after "@".'); + } + var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL); + if (nameBadChars) { + throw new Error('Check your URL. Invalid characters in channel name: "' + nameBadChars.join(', ') + '".'); + } + } else { + claimId = value; + } + + // Validate and process modifier + var channelClaimId = void 0; + if (modifierSeperator) { + if (!modifier) { + throw new Error('Check your URL. No modifier provided after separator "' + modifierSeperator + '"'); + } + + if (modifierSeperator === ':') { + channelClaimId = modifier; + } else { + throw new Error('Check your URL. The "' + modifierSeperator + '" modifier is not currently supported'); + } + } + return { + isChannel: isChannel, + channelName: channelName, + channelClaimId: channelClaimId || null, + claimId: claimId || null + }; + }, + parseClaim: function parseClaim(name) { + var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first extension) + '([:$#.]?)([^/]*)' // extension separator, extension (stops at the first path separator or end) + ); + + var _componentsRegex$exec3 = componentsRegex // eslint-disable-line no-unused-vars + .exec(name).map(function (match) { + return match || null; + }), + _componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4), + proto = _componentsRegex$exec4[0], + claimName = _componentsRegex$exec4[1], + extensionSeperator = _componentsRegex$exec4[2], + extension = _componentsRegex$exec4[3]; + + // Validate and process name + + + if (!claimName) { + throw new Error('Check your URL. No claim name provided before "."'); + } + var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM); + if (nameBadChars) { + throw new Error('Check your URL. Invalid characters in claim name: "' + nameBadChars.join(', ') + '".'); + } + // Validate and process extension + if (extensionSeperator) { + if (!extension) { + throw new Error('Check your URL. No file extension provided after separator "' + extensionSeperator + '".'); + } + if (extensionSeperator !== '.') { + throw new Error('Check your URL. The "' + extensionSeperator + '" separator is not supported in the claim name.'); + } + } + return { + claimName: claimName, + extension: extension || null + }; + } +}; + +/***/ }), +/* 158 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var handlePageRender = __webpack_require__(29); + +module.exports = function (app) { + // a catch-all route if someone visits a page that does not exist + app.use('*', function (req, res) { + // send response + handlePageRender(req, res); + }); +}; + +/***/ }) +/******/ ]); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZmRiYmJiMjcwMzQ0OThjZDIwNDciLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3RcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdC1yZWR1eFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcIndpbnN0b25cIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdC1yb3V0ZXItZG9tXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2FjdGlvbnMvcHVibGlzaC5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvc2l0ZUNvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL05hdkJhci9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvYWN0aW9ucy9zaG93LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL1NFTy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJwcm9wLXR5cGVzXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL3JlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcy5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2VsZWN0b3JzL3Nob3cuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3QtaGVsbWV0XCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVkdXgtc2FnYS9lZmZlY3RzXCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvbGJyeUFwaS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9nb29nbGVBbmFseXRpY3MuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVkdXhcIiIsIndlYnBhY2s6Ly8vLi9jbGllbnQvYWN0aW9ucy9jaGFubmVsLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL1Byb2dyZXNzQmFyL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvcGFnZXMvRXJyb3JQYWdlL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJwYXNzcG9ydFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInBhc3Nwb3J0LWxvY2FsXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwic2VxdWVsaXplXCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvc2VxdWVsaXplSGVscGVycy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9wdWJsaXNoSGVscGVycy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9lcnJvckhhbmRsZXJzLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9jb250cm9sbGVycy9zZXJ2ZUNvbnRyb2xsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvaGFuZGxlUGFnZVJlbmRlci5qc3giLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3QtZG9tL3NlcnZlclwiIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29uc3RhbnRzL3B1Ymxpc2hfYWN0aW9uX3R5cGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb25zdGFudHMvcHVibGlzaF9jaGFubmVsX3NlbGVjdF9zdGF0ZXMuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9jaGFubmVsX2FjdGlvbl90eXBlcy5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29uc3RhbnRzL2Fzc2V0X2Rpc3BsYXlfc3RhdGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL0dBTGlzdGVuZXIvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9hcHAuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Ryb3B6b25lL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENyZWF0ZUZvcm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9zaG93X3JlcXVlc3RfdHlwZXMuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQXNzZXREaXNwbGF5L2luZGV4LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL3JlbmRlckZ1bGxQYWdlLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9zZWxlY3RvcnMvc2l0ZS5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJiYWJlbC1wb2x5ZmlsbFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcIndoYXR3Zy1mZXRjaFwiIiwid2VicGFjazovLy8uL3NlcnZlci9zZXJ2ZXIuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZXhwcmVzc1wiIiwid2VicGFjazovLy9leHRlcm5hbCBcImJvZHktcGFyc2VyXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZXhwcmVzcy1oYW5kbGViYXJzXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiaGFuZGxlYmFyc1wiIiwid2VicGFjazovLy9leHRlcm5hbCBcImhlbG1ldFwiIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2F1dGhIZWxwZXJzLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImNvb2tpZS1zZXNzaW9uXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiaHR0cFwiIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2NvbmZpZ3VyZUxvZ2dlci5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvbG9nZ2VyQ29uZmlnLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2NvbmZpZ3VyZVNsYWNrLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcIndpbnN0b24tc2xhY2std2ViaG9va1wiIiwid2VicGFjazovLy8uL2NvbmZpZy9zbGFja0NvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImF4aW9zXCIiLCJ3ZWJwYWNrOi8vLy4vY29uZmlnL2xicnlDb25maWcuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwidW5pdmVyc2FsLWFuYWx5dGljc1wiIiwid2VicGFjazovLy8uL2NvbmZpZy9teXNxbENvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2NlcnRpZmljYXRlLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9tb2RlbHMvY2hhbm5lbC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2NsYWltLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9tb2RlbHMvZmlsZS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL3JlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21vZGVscy91c2VyLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImJjcnlwdFwiIiwid2VicGFjazovLy8uL3NlcnZlci9wYXNzcG9ydC9sb2NhbC1sb2dpbi5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2F1dGgtcm91dGVzLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpLXJvdXRlcy5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJjb25uZWN0LW11bHRpcGFydHlcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvY29udHJvbGxlcnMvcHVibGlzaENvbnRyb2xsZXIuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZnNcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvYXV0aC9hdXRoZW50aWNhdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9jaGFubmVsUGFnaW5hdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL3BhZ2Utcm91dGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9wdWJsaXNoLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9jaGFubmVsLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9zaG93LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9yZWR1Y2Vycy9zaXRlLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LWdhXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL0hvbWVQYWdlL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9TRU8vdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL3BhZ2VUaXRsZS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvdXRpbHMvbWV0YVRhZ3MuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL2Nhbm9uaWNhbExpbmsuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvTmF2QmFyL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL0xvZ28vaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL05hdkJhckNoYW5uZWxPcHRpb25zRHJvcGRvd24vaW5kZXguanN4Iiwid2VicGFjazovLy9leHRlcm5hbCBcImNyb3NzLWZldGNoL3BvbHlmaWxsXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFRvb2wvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFRvb2wvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvRHJvcHpvbmUvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL2ZpbGUuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvUHVibGlzaFByZXZpZXcvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEZXRhaWxzL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEZXRhaWxzL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hVcmxJbnB1dC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvUHVibGlzaFVybE1pZGRsZURpc3BsYXkvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaHVtYm5haWxJbnB1dC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaE1ldGFkYXRhSW5wdXRzL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9FeHBhbmRpbmdUZXh0QXJlYS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbFNlbGVjdC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9DaGFubmVsU2VsZWN0L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENyZWF0ZUZvcm0vdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvQWN0aXZlU3RhdHVzQmFyL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9JbmFjdGl2ZVN0YXR1c0Jhci9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFN0YXR1cy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoU3RhdHVzL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb25zdGFudHMvcHVibGlzaF9jbGFpbV9zdGF0ZXMuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaERpc2FibGVkTWVzc2FnZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9wYWdlcy9BYm91dFBhZ2UvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9wYWdlcy9Mb2dpblBhZ2UvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL0xvZ2luUGFnZS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvcGFnZXMvU2hvd1BhZ2UvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL1Nob3dQYWdlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1Nob3dBc3NldExpdGUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0TGl0ZS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9Bc3NldERpc3BsYXkvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Fzc2V0VGl0bGUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQXNzZXRUaXRsZS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9Bc3NldEluZm8vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQXNzZXRJbmZvL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1Nob3dDaGFubmVsL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1Nob3dDaGFubmVsL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL0Fzc2V0UHJldmlldy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9Bc3NldFByZXZpZXcvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2UvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0ZvdXJPaEZvdXJQYWdlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXNzZXQtcm91dGVzLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL3NlcnZlSGVscGVycy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9sYnJ5VXJpLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4Iiwid2VicGFjazovLy9leHRlcm5hbCBcInJlZHV4LXNhZ2FcIiIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2FnYXMvc2hvd191cmkuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3NhZ2FzL3Nob3dfYXNzZXQuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2FwaS9hc3NldEFwaS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2FnYXMvc2hvd19jaGFubmVsLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9hcGkvY2hhbm5lbEFwaS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvdXRpbHMvbGJyeVVyaS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2ZhbGxiYWNrLXJvdXRlcy5qcyJdLCJuYW1lcyI6WyJzZWxlY3RGaWxlIiwiY2xlYXJGaWxlIiwidXBkYXRlTWV0YWRhdGEiLCJ1cGRhdGVDbGFpbSIsInNldFB1Ymxpc2hJbkNoYW5uZWwiLCJ1cGRhdGVQdWJsaXNoU3RhdHVzIiwidXBkYXRlRXJyb3IiLCJ1cGRhdGVTZWxlY3RlZENoYW5uZWwiLCJ0b2dnbGVNZXRhZGF0YUlucHV0cyIsIm9uTmV3VGh1bWJuYWlsIiwic3RhcnRQdWJsaXNoIiwiYWN0aW9ucyIsImZpbGUiLCJ0eXBlIiwiRklMRV9TRUxFQ1RFRCIsImRhdGEiLCJGSUxFX0NMRUFSIiwibmFtZSIsInZhbHVlIiwiTUVUQURBVEFfVVBEQVRFIiwiQ0xBSU1fVVBEQVRFIiwiY2hhbm5lbCIsIlNFVF9QVUJMSVNIX0lOX0NIQU5ORUwiLCJzdGF0dXMiLCJtZXNzYWdlIiwiUFVCTElTSF9TVEFUVVNfVVBEQVRFIiwiRVJST1JfVVBEQVRFIiwiY2hhbm5lbE5hbWUiLCJTRUxFQ1RFRF9DSEFOTkVMX1VQREFURSIsInNob3dNZXRhZGF0YUlucHV0cyIsIlRPR0dMRV9NRVRBREFUQV9JTlBVVFMiLCJUSFVNQk5BSUxfTkVXIiwiaGlzdG9yeSIsIlBVQkxJU0hfU1RBUlQiLCJTaXRlQ29uZmlnIiwiYW5hbHl0aWNzIiwiZ29vZ2xlSWQiLCJhc3NldERlZmF1bHRzIiwiZGVzY3JpcHRpb24iLCJ0aHVtYm5haWwiLCJ0aXRsZSIsImF1dGgiLCJzZXNzaW9uS2V5IiwiZGV0YWlscyIsImhvc3QiLCJwb3J0IiwidHdpdHRlciIsInB1Ymxpc2hpbmciLCJhZGRpdGlvbmFsQ2xhaW1BZGRyZXNzZXMiLCJkaXNhYmxlZCIsImRpc2FibGVkTWVzc2FnZSIsInByaW1hcnlDbGFpbUFkZHJlc3MiLCJ0aHVtYm5haWxDaGFubmVsIiwidGh1bWJuYWlsQ2hhbm5lbElkIiwidXBsb2FkRGlyZWN0b3J5IiwibW9kdWxlIiwiZXhwb3J0cyIsIlNlcXVlbGl6ZSIsInJlcXVpcmUiLCJsb2dnZXIiLCJjb25zb2xlIiwibG9nIiwiZGF0YWJhc2UiLCJ1c2VybmFtZSIsInBhc3N3b3JkIiwiZGIiLCJzZXF1ZWxpemUiLCJkaWFsZWN0IiwiZGlhbGVjdE9wdGlvbnMiLCJkZWNpbWFsTnVtYmVycyIsImxvZ2dpbmciLCJwb29sIiwibWF4IiwibWluIiwiaWRsZSIsImFjcXVpcmUiLCJhdXRoZW50aWNhdGUiLCJ0aGVuIiwiaW5mbyIsImNhdGNoIiwiZXJyb3IiLCJlcnIiLCJDZXJ0aWZpY2F0ZSIsIkNoYW5uZWwiLCJDbGFpbSIsIkZpbGUiLCJSZXF1ZXN0IiwiVXNlciIsImltcG9ydCIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwibW9kZWxOYW1lIiwiYXNzb2NpYXRlIiwidXBzZXJ0IiwiTW9kZWwiLCJ2YWx1ZXMiLCJjb25kaXRpb24iLCJ0YWJsZU5hbWUiLCJmaW5kT25lIiwid2hlcmUiLCJvYmoiLCJkZWJ1ZyIsInVwZGF0ZSIsImNyZWF0ZSIsIm1hcFN0YXRlVG9Qcm9wcyIsInNpdGUiLCJsb2dnZWRJbkNoYW5uZWwiLCJjaGFubmVsU2hvcnRJZCIsInNob3J0SWQiLCJjaGFubmVsTG9uZ0lkIiwibG9uZ0lkIiwic2l0ZURlc2NyaXB0aW9uIiwibWFwRGlzcGF0Y2hUb1Byb3BzIiwib25DaGFubmVsTG9naW4iLCJkaXNwYXRjaCIsIm9uQ2hhbm5lbExvZ291dCIsIm9uSGFuZGxlU2hvd1BhZ2VVcmkiLCJvblJlcXVlc3RFcnJvciIsIm9uTmV3Q2hhbm5lbFJlcXVlc3QiLCJvbk5ld0Fzc2V0UmVxdWVzdCIsIm9uUmVxdWVzdFVwZGF0ZSIsImFkZFJlcXVlc3RUb1JlcXVlc3RMaXN0IiwiYWRkQXNzZXRUb0Fzc2V0TGlzdCIsImFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0Iiwib25VcGRhdGVDaGFubmVsQ2xhaW1zIiwidXBkYXRlQ2hhbm5lbENsYWltcyIsImZpbGVSZXF1ZXN0ZWQiLCJ1cGRhdGVGaWxlQXZhaWxhYmlsaXR5IiwidXBkYXRlRGlzcGxheUFzc2V0RXJyb3IiLCJwYXJhbXMiLCJIQU5ETEVfU0hPV19VUkkiLCJSRVFVRVNUX0VSUk9SIiwiY2hhbm5lbElkIiwicmVxdWVzdFR5cGUiLCJyZXF1ZXN0SWQiLCJDSEFOTkVMX1JFUVVFU1RfTkVXIiwiaWQiLCJleHRlbnNpb24iLCJBU1NFVF9SRVFVRVNUX05FVyIsIm1vZGlmaWVyIiwiUkVRVUVTVF9VUERBVEUiLCJrZXkiLCJSRVFVRVNUX0xJU1RfQUREIiwiY2xhaW1JZCIsImNsYWltRGF0YSIsIkFTU0VUX0FERCIsImNsYWltc0RhdGEiLCJDSEFOTkVMX0FERCIsImNoYW5uZWxLZXkiLCJwYWdlIiwiQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DIiwiY2hhbm5lbExpc3RJZCIsIkNIQU5ORUxfQ0xBSU1TX1VQREFURV9TVUNDRVNTIiwiRklMRV9SRVFVRVNURUQiLCJGSUxFX0FWQUlMQUJJTElUWV9VUERBVEUiLCJESVNQTEFZX0FTU0VUX0VSUk9SIiwiZGVmYXVsdERlc2NyaXB0aW9uIiwiZGVmYXVsdFRodW1ibmFpbCIsInNpdGVIb3N0Iiwic2l0ZVRpdGxlIiwic2l0ZVR3aXR0ZXIiLCJyZXF1ZXN0IiwicGFyc2VKU09OIiwicmVzcG9uc2UiLCJqc29uIiwiY2hlY2tTdGF0dXMiLCJqc29uUmVzcG9uc2UiLCJFcnJvciIsInVybCIsIm9wdGlvbnMiLCJmZXRjaCIsIlByb21pc2UiLCJhbGwiLCJzZWxlY3RBc3NldCIsInNob3ciLCJyZXF1ZXN0TGlzdCIsImFzc2V0S2V5IiwiYXNzZXRMaXN0Iiwic2VsZWN0U2hvd1N0YXRlIiwic3RhdGUiLCJheGlvcyIsImFwaSIsImFwaUhvc3QiLCJhcGlQb3J0IiwibGJyeUFwaVVyaSIsImNob29zZUdhTGJyeW5ldFB1Ymxpc2hMYWJlbCIsInNlbmRHQVRpbWluZ0V2ZW50IiwiaGFuZGxlTGJyeW5ldFJlc3BvbnNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsIkpTT04iLCJzdHJpbmdpZnkiLCJwdWJsaXNoQ2xhaW0iLCJwdWJsaXNoUGFyYW1zIiwiZ2FTdGFydFRpbWUiLCJEYXRlIiwibm93IiwicG9zdCIsIm1ldGhvZCIsImdldENsYWltIiwidXJpIiwidGltZW91dCIsImdldENsYWltTGlzdCIsImNsYWltTmFtZSIsInJlc29sdmVVcmkiLCJnZXREb3dubG9hZERpcmVjdG9yeSIsImRvd25sb2FkX2RpcmVjdG9yeSIsImNyZWF0ZUNoYW5uZWwiLCJjaGFubmVsX25hbWUiLCJhbW91bnQiLCJ1YSIsImNyZWF0ZVNlcnZlRXZlbnRQYXJhbXMiLCJoZWFkZXJzIiwiaXAiLCJvcmlnaW5hbFVybCIsImV2ZW50Q2F0ZWdvcnkiLCJldmVudEFjdGlvbiIsImV2ZW50TGFiZWwiLCJpcE92ZXJyaWRlIiwidXNlckFnZW50T3ZlcnJpZGUiLCJjcmVhdGVQdWJsaXNoVGltaW5nRXZlbnRQYXJhbXMiLCJjYXRlZ29yeSIsInZhcmlhYmxlIiwibGFiZWwiLCJzdGFydFRpbWUiLCJlbmRUaW1lIiwiZHVyYXRpb24iLCJ1c2VyVGltaW5nQ2F0ZWdvcnkiLCJ1c2VyVGltaW5nVmFyaWFibGVOYW1lIiwidXNlclRpbWluZ1RpbWUiLCJ1c2VyVGltaW5nTGFiZWwiLCJzZW5kR29vZ2xlQW5hbHl0aWNzRXZlbnQiLCJ2aXNpdG9ySWQiLCJyZXBsYWNlIiwidmlzaXRvciIsInN0cmljdENpZEZvcm1hdCIsImh0dHBzIiwiZXZlbnQiLCJzZW5kR29vZ2xlQW5hbHl0aWNzVGltaW5nIiwidGltaW5nIiwic2VuZEdBU2VydmVFdmVudCIsImNoYW5uZWxfaWQiLCJ1cGRhdGVMb2dnZWRJbkNoYW5uZWwiLCJDSEFOTkVMX1VQREFURSIsIlByb2dyZXNzQmFyIiwicHJvcHMiLCJiYXJzIiwiaW5kZXgiLCJpbmNyZW1lbnRlciIsImNyZWF0ZUJhcnMiLCJiaW5kIiwic3RhcnRQcm9ncmVzc0JhciIsInVwZGF0ZVByb2dyZXNzQmFyIiwic3RvcFByb2dyZXNzQmFyIiwiaSIsInNpemUiLCJwdXNoIiwiaXNBY3RpdmUiLCJzZXRTdGF0ZSIsInVwZGF0ZUludGVydmFsIiwic2V0SW50ZXJ2YWwiLCJjbGVhckludGVydmFsIiwibWFwIiwiYmFyIiwiQ29tcG9uZW50IiwicHJvcFR5cGVzIiwibnVtYmVyIiwiaXNSZXF1aXJlZCIsIkVycm9yUGFnZSIsInN0cmluZyIsInJldHVyblNob3J0SWQiLCJjbGFpbXNBcnJheSIsImNsYWltSW5kZXgiLCJzdWJzdHJpbmciLCJzaG9ydElkTGVuZ3RoIiwiZmluZEluZGV4IiwiZWxlbWVudCIsInBvc3NpYmxlTWF0Y2hlcyIsInNsaWNlIiwibGVuZ3RoIiwiZmlsdGVyIiwiZnMiLCJwYXJzZVB1Ymxpc2hBcGlSZXF1ZXN0Qm9keSIsIm5zZnciLCJsaWNlbnNlIiwiaW52YWxpZE5hbWVDaGFyYWN0ZXJzIiwiZXhlYyIsInBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyIsInBhdGgiLCJ0ZXN0IiwidmFsaWRhdGVGaWxlVHlwZUFuZFNpemUiLCJmaWxlTmFtZSIsImZpbGVQYXRoIiwiZmlsZVR5cGUiLCJ0aHVtYm5haWxGaWxlTmFtZSIsInRodW1ibmFpbEZpbGVQYXRoIiwidGh1bWJuYWlsRmlsZVR5cGUiLCJjcmVhdGVCYXNpY1B1Ymxpc2hQYXJhbXMiLCJ0cmltIiwiZmlsZV9wYXRoIiwiYmlkIiwibWV0YWRhdGEiLCJhdXRob3IiLCJsYW5ndWFnZSIsImNsYWltX2FkZHJlc3MiLCJjcmVhdGVUaHVtYm5haWxQdWJsaXNoUGFyYW1zIiwiZGVsZXRlVGVtcG9yYXJ5RmlsZSIsInVubGluayIsImFkZEdldFJlc3VsdHNUb0ZpbGVEYXRhIiwiZmlsZUluZm8iLCJnZXRSZXN1bHQiLCJmaWxlX25hbWUiLCJkb3dubG9hZF9wYXRoIiwiY3JlYXRlRmlsZURhdGEiLCJvdXRwb2ludCIsImhlaWdodCIsImFkZHJlc3MiLCJjb250ZW50VHlwZSIsImhhbmRsZUVycm9yUmVzcG9uc2UiLCJyZXMiLCJ1c2VPYmplY3RQcm9wZXJ0aWVzSWZOb0tleXMiLCJyZXR1cm5FcnJvck1lc3NhZ2VBbmRTdGF0dXMiLCJjcmVhdGVFcnJvclJlc3BvbnNlUGF5bG9hZCIsImNvZGUiLCJuZXdFcnJvck9iamVjdCIsImdldE93blByb3BlcnR5TmFtZXMiLCJzdWNjZXNzIiwicmV0dXJuUGFnaW5hdGVkQ2hhbm5lbENsYWltcyIsIk5PX0NIQU5ORUwiLCJOT19DTEFJTSIsIk5PX0ZJTEUiLCJnZXRDbGFpbUlkIiwiY2hhbm5lbENsYWltSWQiLCJnZXRDbGFpbUlkQnlDaGFubmVsIiwiZ2V0Q2xhaW1JZEJ5Q2xhaW0iLCJnZXRMb25nQ2xhaW1JZCIsImxvbmdDbGFpbUlkIiwiZ2V0TG9uZ0NoYW5uZWxJZCIsImxvbmdDaGFubmVsSWQiLCJnZXRDbGFpbUlkQnlMb25nQ2hhbm5lbElkIiwiZ2V0Q2hhbm5lbERhdGEiLCJsb25nQ2hhbm5lbENsYWltSWQiLCJnZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkIiwic2hvcnRDaGFubmVsQ2xhaW1JZCIsImdldENoYW5uZWxDbGFpbXMiLCJnZXRBbGxDaGFubmVsQ2xhaW1zIiwiY2hhbm5lbENsYWltc0FycmF5IiwicGFnaW5hdGVkQ2hhbm5lbFZpZXdEYXRhIiwiZ2V0TG9jYWxGaWxlUmVjb3JkIiwiZGF0YVZhbHVlcyIsInJlcSIsImNvbnRleHQiLCJzdG9yZSIsImh0bWwiLCJoZWxtZXQiLCJyZW5kZXJTdGF0aWMiLCJyZWRpcmVjdCIsInByZWxvYWRlZFN0YXRlIiwiZ2V0U3RhdGUiLCJzZW5kIiwicHVibGlzaCIsIkxPR0lOIiwiQ1JFQVRFIiwiTE9DQUxfQ0hFQ0siLCJVTkFWQUlMQUJMRSIsIkVSUk9SIiwiQVZBSUxBQkxFIiwiaW5pdGlhbGl6ZSIsIkdBTGlzdGVuZXIiLCJzZW5kUGFnZVZpZXciLCJsb2NhdGlvbiIsImxpc3RlbiIsInNldCIsInBhdGhuYW1lIiwicGFnZXZpZXciLCJjaGlsZHJlbiIsIkFwcCIsImZpbGVFcnJvciIsInNldEZpbGVFcnJvciIsIkNIQU5ORUwiLCJBU1NFVF9MSVRFIiwiQVNTRVRfREVUQUlMUyIsImRpc3BsYXlBc3NldCIsImFzc2V0Iiwib25GaWxlUmVxdWVzdCIsInRvU3RyaW5nIiwibWV0YSIsImxpbmsiLCJzZWxlY3RTaXRlU3RhdGUiLCJzZWxlY3RTaXRlSG9zdCIsImV4cHJlc3MiLCJib2R5UGFyc2VyIiwiZXhwcmVzc0hhbmRsZWJhcnMiLCJIYW5kbGViYXJzIiwicGFzc3BvcnQiLCJzZXJpYWxpemVTcGVlY2hVc2VyIiwiZGVzZXJpYWxpemVTcGVlY2hVc2VyIiwiY29va2llU2Vzc2lvbiIsImh0dHAiLCJQT1JUIiwiYXBwIiwiZW5hYmxlIiwidXNlIiwic3RhdGljIiwiX19kaXJuYW1lIiwidXJsZW5jb2RlZCIsImV4dGVuZGVkIiwibmV4dCIsInZlcmJvc2UiLCJzZXJpYWxpemVVc2VyIiwiZGVzZXJpYWxpemVVc2VyIiwibG9jYWxTaWdudXBTdHJhdGVneSIsImxvY2FsTG9naW5TdHJhdGVneSIsIm1heEFnZSIsInNlc3Npb24iLCJoYnMiLCJkZWZhdWx0TGF5b3V0IiwiaGFuZGxlYmFycyIsImVuZ2luZSIsInNlcnZlciIsIlNlcnZlciIsInN5bmMiLCJ1c2VyIiwiZG9uZSIsImxvZ0xldmVsIiwid2luc3RvbiIsImNvbmZpZ3VyZSIsInRyYW5zcG9ydHMiLCJDb25zb2xlIiwibGV2ZWwiLCJ0aW1lc3RhbXAiLCJjb2xvcml6ZSIsInByZXR0eVByaW50IiwiaGFuZGxlRXhjZXB0aW9ucyIsImh1bWFuUmVhZGFibGVVbmhhbmRsZWRFeGNlcHRpb24iLCJ3YXJuIiwic2lsbHkiLCJsb2dnZXJDb25maWciLCJ3aW5zdG9uU2xhY2tXZWJIb29rIiwiU2xhY2tXZWJIb29rIiwic2xhY2tDb25maWciLCJzbGFja1dlYkhvb2siLCJzbGFja0Vycm9yQ2hhbm5lbCIsInNsYWNrSW5mb0NoYW5uZWwiLCJhZGQiLCJ3ZWJob29rVXJsIiwiaWNvbkVtb2ppIiwiU2xhY2tDb25maWciLCJQYXNzcG9ydExvY2FsU3RyYXRlZ3kiLCJTdHJhdGVneSIsImxicnlBcGkiLCJ1c2VybmFtZUZpZWxkIiwicGFzc3dvcmRGaWVsZCIsInVzZXJJbmZvIiwidXNlckRhdGEiLCJ1c2VyTmFtZSIsImNoYW5uZWxEYXRhIiwidHgiLCJjbGFpbV9pZCIsImNlcnRpZmljYXRlRGF0YSIsIm5ld1VzZXIiLCJuZXdDaGFubmVsIiwibmV3Q2VydGlmaWNhdGUiLCJzZXRDaGFubmVsIiwic2V0VXNlciIsInNob3J0Q2hhbm5lbElkIiwibGJyeUNvbmZpZyIsIk15c3FsQ29uZmlnIiwiU1RSSU5HIiwiQk9PTEVBTiIsIklOVEVHRVIiLCJURVhUIiwiREVDSU1BTCIsImRlZmluZSIsImRlZmF1bHQiLCJjbGFpbVNlcXVlbmNlIiwiZGVjb2RlZENsYWltIiwiZGVwdGgiLCJlZmZlY3RpdmVBbW91bnQiLCJoYXNTaWduYXR1cmUiLCJoZXgiLCJub3V0IiwidHhpZCIsInZhbGlkQXRIZWlnaHQiLCJ2YWx1ZVZlcnNpb24iLCJjbGFpbVR5cGUiLCJjZXJ0aWZpY2F0ZVZlcnNpb24iLCJrZXlUeXBlIiwicHVibGljS2V5IiwiZnJlZXplVGFibGVOYW1lIiwiYmVsb25nc1RvIiwiZm9yZWlnbktleSIsImFsbG93TnVsbCIsImZpbmRBbGwiLCJvcmRlciIsImdldExvbmdDaGFubmVsSWRGcm9tU2hvcnRDaGFubmVsSWQiLCIkbGlrZSIsImdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUiLCJ2YWxpZGF0ZUxvbmdDaGFubmVsSWQiLCJoYXNPbmUiLCJkZXRlcm1pbmVGaWxlRXh0ZW5zaW9uRnJvbUNvbnRlbnRUeXBlIiwiZGV0ZXJtaW5lVGh1bWJuYWlsIiwic3RvcmVkVGh1bWJuYWlsIiwicHJlcGFyZUNsYWltRGF0YSIsImNsYWltIiwiY2VydGlmaWNhdGVJZCIsImxpY2Vuc2VVcmwiLCJwcmV2aWV3IiwibWV0YWRhdGFWZXJzaW9uIiwic291cmNlIiwic291cmNlVHlwZSIsInNvdXJjZVZlcnNpb24iLCJzdHJlYW1WZXJzaW9uIiwiZ2V0U2hvcnRDbGFpbUlkRnJvbUxvbmdDbGFpbUlkIiwicmF3IiwiZ2V0TG9uZ0NsYWltSWRGcm9tU2hvcnRDbGFpbUlkIiwiZ2V0VG9wRnJlZUNsYWltSWRCeUNsYWltTmFtZSIsInZhbGlkYXRlTG9uZ0NsYWltSWQiLCJyZXNvbHZlQ2xhaW0iLCJjbGFpbUFycmF5IiwiZGVmYXVsdFZhbHVlIiwidHJlbmRpbmdFbGlnaWJsZSIsImhhc01hbnkiLCJnZXRSZWNlbnRDbGFpbXMiLCJsaW1pdCIsImFjdGlvbiIsImlwQWRkcmVzcyIsImJjcnlwdCIsInByb3RvdHlwZSIsImNvbXBhcmVQYXNzd29yZCIsImNvbXBhcmUiLCJjaGFuZ2VQYXNzd29yZCIsIm5ld1Bhc3N3b3JkIiwiZ2VuU2FsdCIsInNhbHRFcnJvciIsInNhbHQiLCJoYXNoIiwiaGFzaEVycm9yIiwiaG9vayIsInJldHVyblVzZXJBbmRDaGFubmVsSW5mbyIsInVzZXJJbnN0YW5jZSIsImdldENoYW5uZWwiLCJpc01hdGNoIiwibG9nSW4iLCJnZXQiLCJsb2dvdXQiLCJtdWx0aXBhcnQiLCJtdWx0aXBhcnRNaWRkbGV3YXJlIiwidXBsb2FkRGlyIiwiY2xhaW1OYW1lSXNBdmFpbGFibGUiLCJjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkiLCJlcnJvckhhbmRsZXJzIiwiYXV0aGVudGljYXRlVXNlciIsImF2YWlsYWJsZU5hbWUiLCJib2R5IiwiY2xhaW1zTGlzdCIsInJlc29sdmVSZXN1bHQiLCJmaWxlRGF0YSIsImZpbGVSZWNvcmQiLCJjb21wbGV0ZWQiLCJyZXNvbHZlZFVyaSIsImZpbGVzIiwiY2hhbm5lbFBhc3N3b3JkIiwidmFsaWRhdGVkQ2xhaW1OYW1lIiwidGh1bWJuYWlsUHVibGlzaFBhcmFtcyIsImxicnlUeCIsImNsYWltSW5mbyIsInB1Ymxpc2hIZWxwZXJzIiwiT3AiLCJwdWJsaXNoUmVzdWx0cyIsImNsYWltUmVjb3JkIiwidXBzZXJ0Q3JpdGVyaWEiLCJzZXRDbGFpbSIsInNldEZpbGUiLCJjbGFpbUFkZHJlc3NlcyIsImF0dHJpYnV0ZXMiLCJvciIsImF1dGhlbnRpY2F0ZUNoYW5uZWxDcmVkZW50aWFscyIsInVzZXJQYXNzd29yZCIsImNoYW5uZWxGaW5kUGFyYW1zIiwiQ0xBSU1TX1BFUl9QQUdFIiwiY2xhaW1zIiwidG90YWxQYWdlcyIsImRldGVybWluZVRvdGFsUGFnZXMiLCJwYWdpbmF0aW9uUGFnZSIsImdldFBhZ2VGcm9tUXVlcnkiLCJ2aWV3RGF0YSIsImV4dHJhY3RQYWdlRnJvbUNsYWltcyIsInByZXZpb3VzUGFnZSIsImRldGVybWluZVByZXZpb3VzUGFnZSIsImN1cnJlbnRQYWdlIiwibmV4dFBhZ2UiLCJkZXRlcm1pbmVOZXh0UGFnZSIsInRvdGFsUmVzdWx0cyIsImRldGVybWluZVRvdGFsQ2xhaW1zIiwicGFyc2VJbnQiLCJwYWdlTnVtYmVyIiwiY2xhaW1TdGFydEluZGV4IiwiY2xhaW1FbmRJbmRleCIsInBhZ2VPZkNsYWltcyIsInRvdGFsQ2xhaW1zIiwiZnVsbFBhZ2VzIiwiTWF0aCIsImZsb29yIiwicmVtYWluZGVyIiwiaGFuZGxlUGFnZVJlbmRlciIsInJlbmRlciIsImxheW91dCIsImluaXRpYWxTdGF0ZSIsImFzc2lnbiIsInB1Ymxpc2hJbkNoYW5uZWwiLCJzZWxlY3RlZENoYW5uZWwiLCJwdWJsaXNoU3VibWl0IiwiY2hhbm5lbExpc3QiLCJzaXRlQ29uZmlnIiwiZ29vZ2xlQW5hbHl0aWNzSWQiLCJIb21lUGFnZSIsIlNFTyIsInBhZ2VVcmkiLCJwYWdlVGl0bGUiLCJtZXRhVGFncyIsImNhbm9uaWNhbExpbmsiLCJyZWwiLCJocmVmIiwib2JqZWN0IiwiY3JlYXRlUGFnZVRpdGxlIiwiZGV0ZXJtaW5lT2dUaHVtYm5haWxDb250ZW50VHlwZSIsImZpbGVFeHQiLCJsYXN0SW5kZXhPZiIsImNyZWF0ZUJhc2ljTWV0YVRhZ3MiLCJwcm9wZXJ0eSIsImNvbnRlbnQiLCJjcmVhdGVDaGFubmVsTWV0YVRhZ3MiLCJjcmVhdGVBc3NldE1ldGFUYWdzIiwiZW1iZWRVcmwiLCJzaG93VXJsIiwib2dUaXRsZSIsIm9nRGVzY3JpcHRpb24iLCJvZ1RodW1ibmFpbENvbnRlbnRUeXBlIiwib2dUaHVtYm5haWwiLCJjcmVhdGVNZXRhVGFncyIsImNyZWF0ZUJhc2ljQ2Fub25pY2FsTGluayIsImNyZWF0ZUFzc2V0Q2Fub25pY2FsTGluayIsImNyZWF0ZUNoYW5uZWxDYW5vbmljYWxMaW5rIiwiY3JlYXRlQ2Fub25pY2FsTGluayIsIlZJRVciLCJMT0dPVVQiLCJOYXZCYXIiLCJjaGVja0ZvckxvZ2dlZEluVXNlciIsImxvZ291dFVzZXIiLCJoYW5kbGVTZWxlY3Rpb24iLCJjcmVkZW50aWFscyIsInRhcmdldCIsInNlbGVjdGVkT3B0aW9ucyIsIkxvZ28iLCJOYXZCYXJDaGFubmVsRHJvcGRvd24iLCJkZWZhdWx0U2VsZWN0aW9uIiwiUHVibGlzaFRvb2wiLCJEcm9wem9uZSIsImRyYWdPdmVyIiwibW91c2VPdmVyIiwiZGltUHJldmlldyIsImhhbmRsZURyb3AiLCJoYW5kbGVEcmFnT3ZlciIsImhhbmRsZURyYWdFbmQiLCJoYW5kbGVEcmFnRW50ZXIiLCJoYW5kbGVEcmFnTGVhdmUiLCJoYW5kbGVNb3VzZUVudGVyIiwiaGFuZGxlTW91c2VMZWF2ZSIsImhhbmRsZUNsaWNrIiwiaGFuZGxlRmlsZUlucHV0IiwiY2hvb3NlRmlsZSIsInByZXZlbnREZWZhdWx0IiwiZHQiLCJkYXRhVHJhbnNmZXIiLCJpdGVtcyIsImtpbmQiLCJkcm9wcGVkRmlsZSIsImdldEFzRmlsZSIsInJlbW92ZSIsImNsZWFyRGF0YSIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJjbGljayIsImZpbGVMaXN0IiwidmFsaWRhdGVGaWxlIiwiUHVibGlzaFByZXZpZXciLCJpbWdTb3VyY2UiLCJzZXRQcmV2aWV3SW1hZ2VTb3VyY2UiLCJuZXdQcm9wcyIsInNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlIiwicHJldmlld1JlYWRlciIsIkZpbGVSZWFkZXIiLCJyZWFkQXNEYXRhVVJMIiwib25sb2FkZW5kIiwiYm9vbCIsIlB1Ymxpc2hEZXRhaWxzIiwib25QdWJsaXNoU3VibWl0Iiwib25NZXRhZGF0YUNoYW5nZSIsIlB1Ymxpc2hUaXRsZUlucHV0IiwiaGFuZGxlSW5wdXQiLCJlIiwibG9nZ2VkSW5DaGFubmVsTmFtZSIsImxvZ2dlZEluQ2hhbm5lbFNob3J0SWQiLCJ1cmxFcnJvciIsIm9uQ2xhaW1DaGFuZ2UiLCJvblVybEVycm9yIiwiUHVibGlzaFVybElucHV0Iiwic2V0Q2xhaW1OYW1lIiwidmFsaWRhdGVDbGFpbSIsImNsZWFuc2VJbnB1dCIsImlucHV0IiwiZmlsZU5hbWVXaXRob3V0RW5kaW5nIiwiY2xlYW5DbGFpbU5hbWUiLCJVcmxNaWRkbGUiLCJkYXRhVVJJdG9CbG9iIiwiZGF0YVVSSSIsImJ5dGVTdHJpbmciLCJhdG9iIiwic3BsaXQiLCJtaW1lU3RyaW5nIiwiaWEiLCJVaW50OEFycmF5IiwiY2hhckNvZGVBdCIsIkJsb2IiLCJQdWJsaXNoVGh1bWJuYWlsSW5wdXQiLCJ2aWRlb1NvdXJjZSIsInNsaWRlck1pblJhbmdlIiwic2xpZGVyTWF4UmFuZ2UiLCJzbGlkZXJWYWx1ZSIsImhhbmRsZVZpZGVvTG9hZGVkRGF0YSIsImhhbmRsZVNsaWRlckNoYW5nZSIsImNyZWF0ZVRodW1ibmFpbCIsInNldFZpZGVvU291cmNlIiwibmV4dFByb3BzIiwiZGF0YVVyaSIsImJsb2IiLCJVUkwiLCJjcmVhdGVPYmplY3RVUkwiLCJ0b3RhbE1pbnV0ZXMiLCJ0b3RhbFNlY29uZHMiLCJ2aWRlbyIsImN1cnJlbnRUaW1lIiwiY2FudmFzIiwiY3JlYXRlRWxlbWVudCIsIndpZHRoIiwidmlkZW9XaWR0aCIsInZpZGVvSGVpZ2h0IiwiZ2V0Q29udGV4dCIsImRyYXdJbWFnZSIsImRhdGFVcmwiLCJ0b0RhdGFVUkwiLCJzbmFwc2hvdCIsImRpc3BsYXkiLCJvblRvZ2dsZU1ldGFkYXRhSW5wdXRzIiwiUHVibGlzaE1ldGFkYXRhSW5wdXRzIiwidG9nZ2xlU2hvd0lucHV0cyIsImhhbmRsZVNlbGVjdCIsImNoZWNrZWQiLCJzZWxlY3RlZE9wdGlvbiIsIm1heEhlaWdodCIsIkV4cGFuZGluZ1RleHRhcmVhIiwiX2hhbmRsZUNoYW5nZSIsImFkanVzdFRleHRhcmVhIiwib25DaGFuZ2UiLCJlbCIsInN0eWxlIiwic2Nyb2xsSGVpZ2h0IiwicmVzdCIsIngiLCJmdW5jIiwiY2hhbm5lbEVycm9yIiwib25QdWJsaXNoSW5DaGFubmVsQ2hhbmdlIiwib25DaGFubmVsU2VsZWN0Iiwic3RhdGVzIiwiQ2hhbm5lbFNlbGVjdCIsInRvZ2dsZUFub255bW91c1B1Ymxpc2giLCJDaGFubmVsTG9naW5Gb3JtIiwibG9naW5Ub0NoYW5uZWwiLCJIZWFkZXJzIiwiQ2hhbm5lbENyZWF0ZUZvcm0iLCJoYW5kbGVDaGFubmVsSW5wdXQiLCJjbGVhbnNlQ2hhbm5lbElucHV0IiwidXBkYXRlSXNDaGFubmVsQXZhaWxhYmxlIiwiY2hhbm5lbFdpdGhBdFN5bWJvbCIsImNoZWNrSXNQYXNzd29yZFByb3ZpZGVkIiwiY2hlY2tJc0NoYW5uZWxBdmFpbGFibGUiLCJtYWtlUHVibGlzaENoYW5uZWxSZXF1ZXN0IiwiQWN0aXZlU3RhdHVzQmFyIiwiSW5hY3RpdmVTdGF0dXNCYXIiLCJwdWJsaXNoU3RhdGVzIiwiUHVibGlzaFN0YXR1cyIsIkxPQURfU1RBUlQiLCJMT0FESU5HIiwiUFVCTElTSElORyIsIlNVQ0NFU1MiLCJGQUlMRUQiLCJQdWJsaXNoRGlzYWJsZWRNZXNzYWdlIiwiQWJvdXRQYWdlIiwiTG9naW5QYWdlIiwiU2hvd1BhZ2UiLCJtYXRjaCIsIlNob3dMaXRlIiwiQXNzZXREaXNwbGF5IiwiU2hvd0Fzc2V0RGV0YWlscyIsIkFzc2V0VGl0bGUiLCJBc3NldEluZm8iLCJjb3B5VG9DbGlwYm9hcmQiLCJlbGVtZW50VG9Db3B5IiwiZGF0YXNldCIsImVsZW1lbnR0b2NvcHkiLCJzZWxlY3QiLCJleGVjQ29tbWFuZCIsInByZXZpb3VzUmVxdWVzdCIsIlNob3dDaGFubmVsIiwiQ2hhbm5lbENsYWltc0Rpc3BsYXkiLCJzaG93TmV4dFJlc3VsdHNQYWdlIiwic2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UiLCJzaG93TmV3UGFnZSIsImRlZmF1bHRzIiwiQXNzZXRQcmV2aWV3IiwiZGlyZWN0U291cmNlTGluayIsInNob3dVcmxMaW5rIiwiRm91ck9oRm9yUGFnZSIsImRldGVybWluZVJlc3BvbnNlVHlwZSIsImZsaXBDbGFpbU5hbWVBbmRJZEZvckJhY2t3YXJkc0NvbXBhdGliaWxpdHkiLCJsb2dSZXF1ZXN0RGF0YSIsImdldENsYWltSWRBbmRTZXJ2ZUFzc2V0IiwibGJyeVVyaSIsImhhbmRsZVNob3dSZW5kZXIiLCJTRVJWRSIsImhhc0ZpbGVFeHRlbnNpb24iLCJwYXJzZU1vZGlmaWVyIiwicmVzcG9uc2VUeXBlIiwicGFyc2VDbGFpbSIsImlzQ2hhbm5lbCIsInBhcnNlSWRlbnRpZmllciIsImlkZW50aWZpZXIiLCJTSE9XIiwiY2xpZW50QWNjZXB0c0h0bWwiLCJhY2NlcHQiLCJyZXF1ZXN0SXNGcm9tQnJvd3NlciIsImNsaWVudFdhbnRzQXNzZXQiLCJyYW5nZSIsImltYWdlSXNXYW50ZWQiLCJ2aWRlb0lzV2FudGVkIiwiaXNWYWxpZENsYWltSWQiLCJpc1ZhbGlkU2hvcnRJZCIsImlzVmFsaWRTaG9ydElkT3JDbGFpbUlkIiwic2VydmVBc3NldFRvQ2xpZW50Iiwic2VuZEZpbGVPcHRpb25zIiwic2VuZEZpbGUiLCJmdWxsQ2xhaW1JZCIsInRlbXBOYW1lIiwiUkVHRVhQX0lOVkFMSURfQ0xBSU0iLCJSRUdFWFBfSU5WQUxJRF9DSEFOTkVMIiwiUkVHRVhQX0FERFJFU1MiLCJDSEFOTkVMX0NIQVIiLCJjb21wb25lbnRzUmVnZXgiLCJSZWdFeHAiLCJwcm90byIsIm1vZGlmaWVyU2VwZXJhdG9yIiwic3RhcnRzV2l0aCIsIm5hbWVCYWRDaGFycyIsImpvaW4iLCJyZXR1cm5TYWdhV2l0aFBhcmFtcyIsInNhZ2EiLCJzYWdhTWlkZGxld2FyZSIsIm1pZGRsZXdhcmUiLCJydW4iLCJoYW5kbGVTaG93UGFnZVVyaSIsIndhdGNoSGFuZGxlU2hvd1BhZ2VVcmkiLCJwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSIsInBhcnNlQW5kVXBkYXRlQ2xhaW1Pbmx5IiwibmV3QXNzZXRSZXF1ZXN0Iiwid2F0Y2hOZXdBc3NldFJlcXVlc3QiLCJnZXRTaG9ydElkIiwiZ2V0Q2xhaW1EYXRhIiwibmV3Q2hhbm5lbFJlcXVlc3QiLCJ3YXRjaE5ld0NoYW5uZWxSZXF1ZXN0Iiwid2F0Y2hVcGRhdGVDaGFubmVsQ2xhaW1zIiwiZ2V0TmV3Q2xhaW1zQW5kVXBkYXRlQ2hhbm5lbCIsImV4dGVuc2lvblNlcGVyYXRvciJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUNBQTJCLDBCQUEwQixFQUFFO0FBQ3ZELHlDQUFpQyxlQUFlO0FBQ2hEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhEQUFzRCwrREFBK0Q7O0FBRXJIO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7OztBQzdEQSxrQzs7Ozs7O0FDQUEsd0M7Ozs7OztBQ0FBLG9DOzs7Ozs7QUNBQSw2Qzs7Ozs7Ozs7Ozs7O1FDR2dCQSxVLEdBQUFBLFU7UUFPQUMsUyxHQUFBQSxTO1FBTUFDLGMsR0FBQUEsYztRQVVBQyxXLEdBQUFBLFc7UUFPQUMsbUIsR0FBQUEsbUI7UUFPQUMsbUIsR0FBQUEsbUI7UUFVQUMsVyxHQUFBQSxXO1FBVUFDLHFCLEdBQUFBLHFCO1FBT0FDLG9CLEdBQUFBLG9CO1FBT0FDLGMsR0FBQUEsYztRQU9BQyxZLEdBQUFBLFk7O0FBakZoQjs7SUFBWUMsTzs7OztBQUVaO0FBQ08sU0FBU1gsVUFBVCxDQUFxQlksSUFBckIsRUFBMkI7QUFDaEMsU0FBTztBQUNMQyxVQUFNRixRQUFRRyxhQURUO0FBRUxDLFVBQU1IO0FBRkQsR0FBUDtBQUlEOztBQUVNLFNBQVNYLFNBQVQsR0FBc0I7QUFDM0IsU0FBTztBQUNMWSxVQUFNRixRQUFRSztBQURULEdBQVA7QUFHRDs7QUFFTSxTQUFTZCxjQUFULENBQXlCZSxJQUF6QixFQUErQkMsS0FBL0IsRUFBc0M7QUFDM0MsU0FBTztBQUNMTCxVQUFNRixRQUFRUSxlQURUO0FBRUxKLFVBQU07QUFDSkUsZ0JBREk7QUFFSkM7QUFGSTtBQUZELEdBQVA7QUFPRDs7QUFFTSxTQUFTZixXQUFULENBQXNCZSxLQUF0QixFQUE2QjtBQUNsQyxTQUFPO0FBQ0xMLFVBQU1GLFFBQVFTLFlBRFQ7QUFFTEwsVUFBTUc7QUFGRCxHQUFQO0FBSUQ7O0FBRU0sU0FBU2QsbUJBQVQsQ0FBOEJpQixPQUE5QixFQUF1QztBQUM1QyxTQUFPO0FBQ0xSLFVBQU1GLFFBQVFXLHNCQURUO0FBRUxEO0FBRkssR0FBUDtBQUlEOztBQUVNLFNBQVNoQixtQkFBVCxDQUE4QmtCLE1BQTlCLEVBQXNDQyxPQUF0QyxFQUErQztBQUNwRCxTQUFPO0FBQ0xYLFVBQU1GLFFBQVFjLHFCQURUO0FBRUxWLFVBQU07QUFDSlEsb0JBREk7QUFFSkM7QUFGSTtBQUZELEdBQVA7QUFPRDs7QUFFTSxTQUFTbEIsV0FBVCxDQUFzQlcsSUFBdEIsRUFBNEJDLEtBQTVCLEVBQW1DO0FBQ3hDLFNBQU87QUFDTEwsVUFBTUYsUUFBUWUsWUFEVDtBQUVMWCxVQUFNO0FBQ0pFLGdCQURJO0FBRUpDO0FBRkk7QUFGRCxHQUFQO0FBT0Q7O0FBRU0sU0FBU1gscUJBQVQsQ0FBZ0NvQixXQUFoQyxFQUE2QztBQUNsRCxTQUFPO0FBQ0xkLFVBQU1GLFFBQVFpQix1QkFEVDtBQUVMYixVQUFNWTtBQUZELEdBQVA7QUFJRDs7QUFFTSxTQUFTbkIsb0JBQVQsQ0FBK0JxQixrQkFBL0IsRUFBbUQ7QUFDeEQsU0FBTztBQUNMaEIsVUFBTUYsUUFBUW1CLHNCQURUO0FBRUxmLFVBQU1jO0FBRkQsR0FBUDtBQUlEOztBQUVNLFNBQVNwQixjQUFULENBQXlCRyxJQUF6QixFQUErQjtBQUNwQyxTQUFPO0FBQ0xDLFVBQU1GLFFBQVFvQixhQURUO0FBRUxoQixVQUFNSDtBQUZELEdBQVA7QUFJRDs7QUFFTSxTQUFTRixZQUFULENBQXVCc0IsT0FBdkIsRUFBZ0M7QUFDckMsU0FBTztBQUNMbkIsVUFBTUYsUUFBUXNCLGFBRFQ7QUFFTGxCLFVBQU0sRUFBRWlCLGdCQUFGO0FBRkQsR0FBUDtBQUlELEM7Ozs7Ozs7OztBQ3RGRCxTQUFTRSxVQUFULEdBQXVCO0FBQ3JCLE9BQUtDLFNBQUwsR0FBaUI7QUFDZkMsY0FBVTtBQURLLEdBQWpCO0FBR0EsT0FBS0MsYUFBTCxHQUFxQjtBQUNuQkMsaUJBQWEsK0JBRE07QUFFbkJDLGVBQWEsb0RBRk07QUFHbkJDLFdBQWE7QUFITSxHQUFyQjtBQUtBLE9BQUtDLElBQUwsR0FBWTtBQUNWQyxnQkFBWTtBQURGLEdBQVo7QUFHQSxPQUFLQyxPQUFMLEdBQWU7QUFDYkwsaUJBQWEscURBREE7QUFFYk0sVUFBYSxTQUZBO0FBR2JDLFVBQWEsSUFIQTtBQUliTCxXQUFhLFNBSkE7QUFLYk0sYUFBYTtBQUxBLEdBQWY7QUFPQSxPQUFLQyxVQUFMLEdBQWtCO0FBQ2hCQyw4QkFBMEIsRUFEVjtBQUVoQkMsY0FBMEIsS0FGVjtBQUdoQkMscUJBQTBCLHlCQUhWO0FBSWhCQyx5QkFBMEIsU0FKVjtBQUtoQkMsc0JBQTBCLFNBTFY7QUFNaEJDLHdCQUEwQixTQU5WO0FBT2hCQyxxQkFBMEI7QUFQVixHQUFsQjtBQVNEOztBQUVEQyxPQUFPQyxPQUFQLEdBQWlCLElBQUl0QixVQUFKLEVBQWpCLEM7Ozs7Ozs7OztBQzlCQSxJQUFNdUIsWUFBWSxtQkFBQUMsQ0FBUSxFQUFSLENBQWxCO0FBQ0EsSUFBTUMsU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7O0FBRUFFLFFBQVFDLEdBQVIsQ0FBWSw0QkFBWjs7ZUFDeUMsbUJBQUFILENBQVEsRUFBUixDO0lBQWpDSSxRLFlBQUFBLFE7SUFBVUMsUSxZQUFBQSxRO0lBQVVDLFEsWUFBQUEsUTs7QUFDNUIsSUFBTUMsS0FBSyxFQUFYO0FBQ0E7QUFDQSxJQUFNQyxZQUFZLElBQUlULFNBQUosQ0FBY0ssUUFBZCxFQUF3QkMsUUFBeEIsRUFBa0NDLFFBQWxDLEVBQTRDO0FBQzVEcEIsUUFBZ0IsV0FENEM7QUFFNUR1QixXQUFnQixPQUY0QztBQUc1REMsa0JBQWdCLEVBQUNDLGdCQUFnQixJQUFqQixFQUg0QyxFQUdwQjtBQUN4Q0MsV0FBZ0IsS0FKNEM7QUFLNURDLFFBQWdCO0FBQ2RDLFNBQVMsQ0FESztBQUVkQyxTQUFTLENBRks7QUFHZEMsVUFBUyxLQUhLO0FBSWRDLGFBQVM7QUFKSztBQUw0QyxDQUE1QyxDQUFsQjs7QUFhQTtBQUNBVCxVQUNHVSxZQURILEdBRUdDLElBRkgsQ0FFUSxZQUFNO0FBQ1ZsQixTQUFPbUIsSUFBUCxDQUFZLDBEQUFaO0FBQ0QsQ0FKSCxFQUtHQyxLQUxILENBS1MsZUFBTztBQUNacEIsU0FBT3FCLEtBQVAsQ0FBYSxrREFBYixFQUFpRUMsR0FBakU7QUFDRCxDQVBIOztBQVNBO0FBQ0EsSUFBTUMsY0FBYyxtQkFBQXhCLENBQVEsRUFBUixDQUFwQjtBQUNBLElBQU15QixVQUFVLG1CQUFBekIsQ0FBUSxFQUFSLENBQWhCO0FBQ0EsSUFBTTBCLFFBQVEsbUJBQUExQixDQUFRLEVBQVIsQ0FBZDtBQUNBLElBQU0yQixPQUFPLG1CQUFBM0IsQ0FBUSxFQUFSLENBQWI7QUFDQSxJQUFNNEIsVUFBVSxtQkFBQTVCLENBQVEsRUFBUixDQUFoQjtBQUNBLElBQU02QixPQUFPLG1CQUFBN0IsQ0FBUSxFQUFSLENBQWI7QUFDQU8sR0FBRyxhQUFILElBQW9CQyxVQUFVc0IsTUFBVixDQUFpQixhQUFqQixFQUFnQ04sV0FBaEMsQ0FBcEI7QUFDQWpCLEdBQUcsU0FBSCxJQUFnQkMsVUFBVXNCLE1BQVYsQ0FBaUIsU0FBakIsRUFBNEJMLE9BQTVCLENBQWhCO0FBQ0FsQixHQUFHLE9BQUgsSUFBY0MsVUFBVXNCLE1BQVYsQ0FBaUIsT0FBakIsRUFBMEJKLEtBQTFCLENBQWQ7QUFDQW5CLEdBQUcsTUFBSCxJQUFhQyxVQUFVc0IsTUFBVixDQUFpQixNQUFqQixFQUF5QkgsSUFBekIsQ0FBYjtBQUNBcEIsR0FBRyxTQUFILElBQWdCQyxVQUFVc0IsTUFBVixDQUFpQixTQUFqQixFQUE0QkYsT0FBNUIsQ0FBaEI7QUFDQXJCLEdBQUcsTUFBSCxJQUFhQyxVQUFVc0IsTUFBVixDQUFpQixNQUFqQixFQUF5QkQsSUFBekIsQ0FBYjs7QUFFQTtBQUNBRSxPQUFPQyxJQUFQLENBQVl6QixFQUFaLEVBQWdCMEIsT0FBaEIsQ0FBd0IscUJBQWE7QUFDbkMsTUFBSTFCLEdBQUcyQixTQUFILEVBQWNDLFNBQWxCLEVBQTZCO0FBQzNCbEMsV0FBT21CLElBQVAsQ0FBWSxvQkFBWixFQUFrQ2MsU0FBbEM7QUFDQTNCLE9BQUcyQixTQUFILEVBQWNDLFNBQWQsQ0FBd0I1QixFQUF4QjtBQUNEO0FBQ0YsQ0FMRDs7QUFPQUEsR0FBR0MsU0FBSCxHQUFlQSxTQUFmO0FBQ0FELEdBQUdSLFNBQUgsR0FBZUEsU0FBZjs7QUFFQTtBQUNBUSxHQUFHNkIsTUFBSCxHQUFZLFVBQUNDLEtBQUQsRUFBUUMsTUFBUixFQUFnQkMsU0FBaEIsRUFBMkJDLFNBQTNCLEVBQXlDO0FBQ25ELFNBQU9ILE1BQ0pJLE9BREksQ0FDSTtBQUNQQyxXQUFPSDtBQURBLEdBREosRUFJSnBCLElBSkksQ0FJQyxlQUFPO0FBQ1gsUUFBSXdCLEdBQUosRUFBUztBQUFHO0FBQ1YxQyxhQUFPMkMsS0FBUCw0QkFBc0NKLFNBQXRDO0FBQ0EsYUFBT0csSUFBSUUsTUFBSixDQUFXUCxNQUFYLENBQVA7QUFDRCxLQUhELE1BR087QUFBRztBQUNSckMsYUFBTzJDLEtBQVAsNEJBQXNDSixTQUF0QztBQUNBLGFBQU9ILE1BQU1TLE1BQU4sQ0FBYVIsTUFBYixDQUFQO0FBQ0Q7QUFDRixHQVpJLEVBYUpqQixLQWJJLENBYUUsVUFBVUMsS0FBVixFQUFpQjtBQUN0QnJCLFdBQU9xQixLQUFQLENBQWdCa0IsU0FBaEIsb0JBQTBDbEIsS0FBMUM7QUFDQSxVQUFNQSxLQUFOO0FBQ0QsR0FoQkksQ0FBUDtBQWlCRCxDQWxCRDs7QUFvQkF6QixPQUFPQyxPQUFQLEdBQWlCUyxFQUFqQixDOzs7Ozs7Ozs7Ozs7O0FDNUVBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7QUFFQSxJQUFNd0Msa0JBQWtCLFNBQWxCQSxlQUFrQixPQUF1QjtBQUFBLE1BQXBCcEYsT0FBb0IsUUFBcEJBLE9BQW9CO0FBQUEsTUFBWHFGLElBQVcsUUFBWEEsSUFBVzs7QUFDN0MsU0FBTztBQUNML0UsaUJBQWdCTixRQUFRc0YsZUFBUixDQUF3QjFGLElBRG5DO0FBRUwyRixvQkFBZ0J2RixRQUFRc0YsZUFBUixDQUF3QkUsT0FGbkM7QUFHTEMsbUJBQWdCekYsUUFBUXNGLGVBQVIsQ0FBd0JJLE1BSG5DO0FBSUxDLHFCQUFpQk4sS0FBS3BFO0FBSmpCLEdBQVA7QUFNRCxDQVBEOztBQVNBLElBQU0yRSxxQkFBcUIsU0FBckJBLGtCQUFxQixXQUFZO0FBQ3JDLFNBQU87QUFDTEMsb0JBQWdCLHdCQUFDakcsSUFBRCxFQUFPNEYsT0FBUCxFQUFnQkUsTUFBaEIsRUFBMkI7QUFDekNJLGVBQVMsb0NBQXNCbEcsSUFBdEIsRUFBNEI0RixPQUE1QixFQUFxQ0UsTUFBckMsQ0FBVDtBQUNBSSxlQUFTLG9DQUFzQmxHLElBQXRCLENBQVQ7QUFDRCxLQUpJO0FBS0xtRyxxQkFBaUIsMkJBQU07QUFDckJELGVBQVMsb0NBQXNCLElBQXRCLEVBQTRCLElBQTVCLEVBQWtDLElBQWxDLENBQVQ7QUFDRDtBQVBJLEdBQVA7QUFTRCxDQVZEOztrQkFZZSx5QkFBUVYsZUFBUixFQUF5QlEsa0JBQXpCLGlCOzs7Ozs7Ozs7Ozs7UUNyQkNJLG1CLEdBQUFBLG1CO1FBT0FDLGMsR0FBQUEsYztRQU9BQyxtQixHQUFBQSxtQjtRQVNBQyxpQixHQUFBQSxpQjtRQW9CQUMsZSxHQUFBQSxlO1FBVUFDLHVCLEdBQUFBLHVCO1FBU0FDLG1CLEdBQUFBLG1CO1FBU0FDLDBCLEdBQUFBLDBCO1FBT0FDLHFCLEdBQUFBLHFCO1FBT0FDLG1CLEdBQUFBLG1CO1FBU0FDLGEsR0FBQUEsYTtRQU9BQyxzQixHQUFBQSxzQjtRQU9BQyx1QixHQUFBQSx1Qjs7QUFqSGhCOztJQUFZdEgsTzs7QUFFWjs7OztBQUVBO0FBQ08sU0FBUzBHLG1CQUFULENBQThCYSxNQUE5QixFQUFzQztBQUMzQyxTQUFPO0FBQ0xySCxVQUFNRixRQUFRd0gsZUFEVDtBQUVMcEgsVUFBTW1IO0FBRkQsR0FBUDtBQUlEOztBQUVNLFNBQVNaLGNBQVQsQ0FBeUJ0QyxLQUF6QixFQUFnQztBQUNyQyxTQUFPO0FBQ0xuRSxVQUFNRixRQUFReUgsYUFEVDtBQUVMckgsVUFBTWlFO0FBRkQsR0FBUDtBQUlEOztBQUVNLFNBQVN1QyxtQkFBVCxDQUE4QjVGLFdBQTlCLEVBQTJDMEcsU0FBM0MsRUFBc0Q7QUFDM0QsTUFBTUMseUNBQU47QUFDQSxNQUFNQyxvQkFBa0I1RyxXQUFsQixTQUFpQzBHLFNBQXZDO0FBQ0EsU0FBTztBQUNMeEgsVUFBTUYsUUFBUTZILG1CQURUO0FBRUx6SCxVQUFNLEVBQUV1SCx3QkFBRixFQUFlQyxvQkFBZixFQUEwQjVHLHdCQUExQixFQUF1QzBHLG9CQUF2QztBQUZELEdBQVA7QUFJRDs7QUFFTSxTQUFTYixpQkFBVCxDQUE0QnZHLElBQTVCLEVBQWtDd0gsRUFBbEMsRUFBc0M5RyxXQUF0QyxFQUFtRDBHLFNBQW5ELEVBQThESyxTQUE5RCxFQUF5RTtBQUM5RSxNQUFNSixjQUFjSSw4RUFBcEI7QUFDQSxNQUFNSCxvQkFBa0J0SCxJQUFsQixTQUEwQndILEVBQTFCLFNBQWdDOUcsV0FBaEMsU0FBK0MwRyxTQUFyRDtBQUNBLFNBQU87QUFDTHhILFVBQU1GLFFBQVFnSSxpQkFEVDtBQUVMNUgsVUFBTTtBQUNKdUgsOEJBREk7QUFFSkMsMEJBRkk7QUFHSnRILGdCQUhJO0FBSUoySCxnQkFBVTtBQUNSSCxjQURRO0FBRVJwSCxpQkFBUztBQUNQSixnQkFBTVUsV0FEQztBQUVQOEcsY0FBTUo7QUFGQztBQUZEO0FBSk47QUFGRCxHQUFQO0FBZUQ7O0FBRU0sU0FBU1osZUFBVCxDQUEwQmEsV0FBMUIsRUFBdUNDLFNBQXZDLEVBQWtEO0FBQ3ZELFNBQU87QUFDTDFILFVBQU1GLFFBQVFrSSxjQURUO0FBRUw5SCxVQUFNO0FBQ0p1SCw4QkFESTtBQUVKQztBQUZJO0FBRkQsR0FBUDtBQU9EOztBQUVNLFNBQVNiLHVCQUFULENBQWtDZSxFQUFsQyxFQUFzQ3pELEtBQXRDLEVBQTZDOEQsR0FBN0MsRUFBa0Q7QUFDdkQsU0FBTztBQUNMakksVUFBTUYsUUFBUW9JLGdCQURUO0FBRUxoSSxVQUFNLEVBQUUwSCxNQUFGLEVBQU16RCxZQUFOLEVBQWE4RCxRQUFiO0FBRkQsR0FBUDtBQUlEOztBQUVEOztBQUVPLFNBQVNuQixtQkFBVCxDQUE4QmMsRUFBOUIsRUFBa0N6RCxLQUFsQyxFQUF5Qy9ELElBQXpDLEVBQStDK0gsT0FBL0MsRUFBd0RuQyxPQUF4RCxFQUFpRW9DLFNBQWpFLEVBQTRFO0FBQ2pGLFNBQU87QUFDTHBJLFVBQU1GLFFBQVF1SSxTQURUO0FBRUxuSSxVQUFNLEVBQUUwSCxNQUFGLEVBQU16RCxZQUFOLEVBQWEvRCxVQUFiLEVBQW1CK0gsZ0JBQW5CLEVBQTRCbkMsZ0JBQTVCLEVBQXFDb0Msb0JBQXJDO0FBRkQsR0FBUDtBQUlEOztBQUVEOztBQUVPLFNBQVNyQiwwQkFBVCxDQUFxQ2EsRUFBckMsRUFBeUN4SCxJQUF6QyxFQUErQzRGLE9BQS9DLEVBQXdERSxNQUF4RCxFQUFnRW9DLFVBQWhFLEVBQTRFO0FBQ2pGLFNBQU87QUFDTHRJLFVBQU1GLFFBQVF5SSxXQURUO0FBRUxySSxVQUFNLEVBQUUwSCxNQUFGLEVBQU14SCxVQUFOLEVBQVk0RixnQkFBWixFQUFxQkUsY0FBckIsRUFBNkJvQyxzQkFBN0I7QUFGRCxHQUFQO0FBSUQ7O0FBRU0sU0FBU3RCLHFCQUFULENBQWdDd0IsVUFBaEMsRUFBNENwSSxJQUE1QyxFQUFrRDhGLE1BQWxELEVBQTBEdUMsSUFBMUQsRUFBZ0U7QUFDckUsU0FBTztBQUNMekksVUFBTUYsUUFBUTRJLDJCQURUO0FBRUx4SSxVQUFNLEVBQUNzSSxzQkFBRCxFQUFhcEksVUFBYixFQUFtQjhGLGNBQW5CLEVBQTJCdUMsVUFBM0I7QUFGRCxHQUFQO0FBSUQ7O0FBRU0sU0FBU3hCLG1CQUFULENBQThCMEIsYUFBOUIsRUFBNkNMLFVBQTdDLEVBQXlEO0FBQzlELFNBQU87QUFDTHRJLFVBQU1GLFFBQVE4SSw2QkFEVDtBQUVMMUksVUFBTSxFQUFDeUksNEJBQUQsRUFBZ0JMLHNCQUFoQjtBQUZELEdBQVA7QUFJRDs7QUFFRDs7QUFFTyxTQUFTcEIsYUFBVCxDQUF3QjlHLElBQXhCLEVBQThCK0gsT0FBOUIsRUFBdUM7QUFDNUMsU0FBTztBQUNMbkksVUFBTUYsUUFBUStJLGNBRFQ7QUFFTDNJLFVBQU0sRUFBRUUsVUFBRixFQUFRK0gsZ0JBQVI7QUFGRCxHQUFQO0FBSUQ7O0FBRU0sU0FBU2hCLHNCQUFULENBQWlDekcsTUFBakMsRUFBeUM7QUFDOUMsU0FBTztBQUNMVixVQUFNRixRQUFRZ0osd0JBRFQ7QUFFTDVJLFVBQU1RO0FBRkQsR0FBUDtBQUlEOztBQUVNLFNBQVMwRyx1QkFBVCxDQUFrQ2pELEtBQWxDLEVBQXlDO0FBQzlDLFNBQU87QUFDTG5FLFVBQU1GLFFBQVFpSixtQkFEVDtBQUVMN0ksVUFBTWlFO0FBRkQsR0FBUDtBQUlELEU7Ozs7Ozs7Ozs7Ozs7QUN0SEQ7O0FBQ0E7Ozs7OztBQUVBLElBQU15QixrQkFBa0IsU0FBbEJBLGVBQWtCLE9BQWM7QUFBQSxNQUFYQyxJQUFXLFFBQVhBLElBQVc7QUFBQSxNQUM1Qm1ELGtCQUQ0QixHQUNtR25ELElBRG5HLENBQzVCbUQsa0JBRDRCO0FBQUEsTUFDUkMsZ0JBRFEsR0FDbUdwRCxJQURuRyxDQUNSb0QsZ0JBRFE7QUFBQSxNQUN1QjlDLGVBRHZCLEdBQ21HTixJQURuRyxDQUNVcEUsV0FEVjtBQUFBLE1BQzhDeUgsUUFEOUMsR0FDbUdyRCxJQURuRyxDQUN3QzlELElBRHhDO0FBQUEsTUFDK0RvSCxTQUQvRCxHQUNtR3RELElBRG5HLENBQ3dEbEUsS0FEeEQ7QUFBQSxNQUNtRnlILFdBRG5GLEdBQ21HdkQsSUFEbkcsQ0FDMEU1RCxPQUQxRTs7QUFFcEMsU0FBTztBQUNMK0csMENBREs7QUFFTEMsc0NBRks7QUFHTDlDLG9DQUhLO0FBSUwrQyxzQkFKSztBQUtMQyx3QkFMSztBQU1MQztBQU5LLEdBQVA7QUFRRCxDQVZEOztrQkFZZSx5QkFBUXhELGVBQVIsRUFBeUIsSUFBekIsaUI7Ozs7OztBQ2ZmLHVDOzs7Ozs7Ozs7Ozs7Ozs7a0JDMEN3QnlELE87O0FBMUN4Qjs7QUFFQTs7Ozs7OztBQU9BLFNBQVNDLFNBQVQsQ0FBb0JDLFFBQXBCLEVBQThCO0FBQzVCLE1BQUlBLFNBQVM3SSxNQUFULEtBQW9CLEdBQXBCLElBQTJCNkksU0FBUzdJLE1BQVQsS0FBb0IsR0FBbkQsRUFBd0Q7QUFDdEQsV0FBTyxJQUFQO0FBQ0Q7QUFDRCxTQUFPNkksU0FBU0MsSUFBVCxFQUFQO0FBQ0Q7O0FBRUQ7Ozs7Ozs7O0FBUUEsU0FBU0MsV0FBVCxDQUFzQkYsUUFBdEIsRUFBZ0NHLFlBQWhDLEVBQThDO0FBQzVDLE1BQUlILFNBQVM3SSxNQUFULElBQW1CLEdBQW5CLElBQTBCNkksU0FBUzdJLE1BQVQsR0FBa0IsR0FBaEQsRUFBcUQ7QUFDbkQsV0FBT2dKLFlBQVA7QUFDRDtBQUNELE1BQU12RixRQUFRLElBQUl3RixLQUFKLENBQVVELGFBQWEvSSxPQUF2QixDQUFkO0FBQ0F3RCxRQUFNb0YsUUFBTixHQUFpQkEsUUFBakI7QUFDQSxRQUFNcEYsS0FBTjtBQUNEOztBQUVEOzs7Ozs7Ozs7QUFTZSxTQUFTa0YsT0FBVCxDQUFrQk8sR0FBbEIsRUFBdUJDLE9BQXZCLEVBQWdDO0FBQzdDLFNBQU9DLE1BQU1GLEdBQU4sRUFBV0MsT0FBWCxFQUNKN0YsSUFESSxDQUNDLG9CQUFZO0FBQ2hCLFdBQU8rRixRQUFRQyxHQUFSLENBQVksQ0FBQ1QsUUFBRCxFQUFXRCxVQUFVQyxRQUFWLENBQVgsQ0FBWixDQUFQO0FBQ0QsR0FISSxFQUlKdkYsSUFKSSxDQUlDLGdCQUE4QjtBQUFBO0FBQUEsUUFBNUJ1RixRQUE0QjtBQUFBLFFBQWxCRyxZQUFrQjs7QUFDbEMsV0FBT0QsWUFBWUYsUUFBWixFQUFzQkcsWUFBdEIsQ0FBUDtBQUNELEdBTkksQ0FBUDtBQU9ELEM7Ozs7Ozs7Ozs7OztBQ2xERDtBQUNPLElBQU1wQyw0Q0FBa0IsaUJBQXhCO0FBQ0EsSUFBTUMsd0NBQWdCLGVBQXRCO0FBQ0EsSUFBTVMsMENBQWlCLGdCQUF2QjtBQUNBLElBQU1GLGdEQUFvQixtQkFBMUI7QUFDQSxJQUFNSCxvREFBc0IscUJBQTVCO0FBQ0EsSUFBTU8sOENBQW1CLGtCQUF6Qjs7QUFFUDtBQUNPLElBQU1HLDJDQUFOOztBQUVQO0FBQ08sSUFBTUUsb0NBQWMsYUFBcEI7O0FBRUEsSUFBTUcsb0VBQThCLDZCQUFwQztBQUNBLElBQU1FLHdFQUFnQywrQkFBdEM7O0FBRVA7QUFDTyxJQUFNQywwQ0FBaUIsZ0JBQXZCO0FBQ0EsSUFBTUMsOERBQTJCLDBCQUFqQztBQUNBLElBQU1DLG9EQUFzQixxQkFBNUIsQzs7Ozs7Ozs7Ozs7O0FDcEJBLElBQU1rQixvQ0FBYyxTQUFkQSxXQUFjLENBQUNDLElBQUQsRUFBVTtBQUNuQyxNQUFNYixVQUFVYSxLQUFLQyxXQUFMLENBQWlCRCxLQUFLYixPQUFMLENBQWF6QixFQUE5QixDQUFoQjtBQUNBLE1BQU13QyxXQUFXZixRQUFRcEIsR0FBekI7QUFDQSxTQUFPaUMsS0FBS0csU0FBTCxDQUFlRCxRQUFmLENBQVA7QUFDRCxDQUpNOztBQU1BLElBQU1FLDRDQUFrQixTQUFsQkEsZUFBa0IsQ0FBQ0MsS0FBRCxFQUFXO0FBQ3hDLFNBQU9BLE1BQU1MLElBQWI7QUFDRCxDQUZNLEM7Ozs7OztBQ05QLHlDOzs7Ozs7QUNBQSwrQzs7Ozs7Ozs7O0FDQUEsSUFBTU0sUUFBUSxtQkFBQTNILENBQVEsRUFBUixDQUFkO0FBQ0EsSUFBTUMsU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7O2VBQ3NDLG1CQUFBQSxDQUFRLEVBQVIsQzs0QkFBOUI0SCxHO0lBQU9DLE8sZ0JBQUFBLE87SUFBU0MsTyxnQkFBQUEsTzs7QUFDeEIsSUFBTUMsYUFBYSxZQUFZRixPQUFaLEdBQXNCLEdBQXRCLEdBQTRCQyxPQUEvQzs7Z0JBQzJELG1CQUFBOUgsQ0FBUSxFQUFSLEM7SUFBbkRnSSwyQixhQUFBQSwyQjtJQUE2QkMsaUIsYUFBQUEsaUI7O0FBRXJDLElBQU1DLHdCQUF3QixTQUF4QkEscUJBQXdCLE9BQVdDLE9BQVgsRUFBb0JDLE1BQXBCLEVBQStCO0FBQUEsTUFBNUIvSyxJQUE0QixRQUE1QkEsSUFBNEI7O0FBQzNENEMsU0FBTzJDLEtBQVAsQ0FBYSxnQkFBYixFQUErQnZGLElBQS9CO0FBQ0EsTUFBSUEsS0FBS2dMLE1BQVQsRUFBaUI7QUFDZjtBQUNBLFFBQUloTCxLQUFLZ0wsTUFBTCxDQUFZL0csS0FBaEIsRUFBdUI7QUFDckJyQixhQUFPMkMsS0FBUCxDQUFhLG9CQUFiLEVBQW1DdkYsS0FBS2dMLE1BQUwsQ0FBWS9HLEtBQS9DO0FBQ0E4RyxhQUFPLElBQUl0QixLQUFKLENBQVV6SixLQUFLZ0wsTUFBTCxDQUFZL0csS0FBdEIsQ0FBUDtBQUNBO0FBQ0Q7QUFDRDZHLFlBQVE5SyxLQUFLZ0wsTUFBYjtBQUNBO0FBQ0Q7QUFDRDtBQUNBRCxTQUFPRSxLQUFLQyxTQUFMLENBQWVsTCxJQUFmLENBQVA7QUFDRCxDQWREOztBQWdCQXdDLE9BQU9DLE9BQVAsR0FBaUI7QUFDZjBJLGNBRGUsd0JBQ0RDLGFBREMsRUFDYztBQUMzQnhJLFdBQU8yQyxLQUFQLHNDQUFnRDZGLGNBQWNsTCxJQUE5RDtBQUNBLFFBQU1tTCxjQUFjQyxLQUFLQyxHQUFMLEVBQXBCO0FBQ0EsV0FBTyxJQUFJMUIsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdENULFlBQ0drQixJQURILENBQ1FkLFVBRFIsRUFDb0I7QUFDaEJlLGdCQUFRLFNBRFE7QUFFaEJ0RSxnQkFBUWlFO0FBRlEsT0FEcEIsRUFLR3RILElBTEgsQ0FLUSxvQkFBWTtBQUNoQjhHLDBCQUFrQixTQUFsQixFQUE2QixTQUE3QixFQUF3Q0QsNEJBQTRCUyxhQUE1QixDQUF4QyxFQUFvRkMsV0FBcEYsRUFBaUdDLEtBQUtDLEdBQUwsRUFBakc7QUFDQVYsOEJBQXNCeEIsUUFBdEIsRUFBZ0N5QixPQUFoQyxFQUF5Q0MsTUFBekM7QUFDRCxPQVJILEVBU0cvRyxLQVRILENBU1MsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FYSDtBQVlELEtBYk0sQ0FBUDtBQWNELEdBbEJjO0FBbUJmeUgsVUFuQmUsb0JBbUJMQyxHQW5CSyxFQW1CQTtBQUNiL0ksV0FBTzJDLEtBQVAsb0NBQThDb0csR0FBOUM7QUFDQSxRQUFNTixjQUFjQyxLQUFLQyxHQUFMLEVBQXBCO0FBQ0EsV0FBTyxJQUFJMUIsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdENULFlBQ0drQixJQURILENBQ1FkLFVBRFIsRUFDb0I7QUFDaEJlLGdCQUFRLEtBRFE7QUFFaEJ0RSxnQkFBUSxFQUFFd0UsUUFBRixFQUFPQyxTQUFTLEVBQWhCO0FBRlEsT0FEcEIsRUFLRzlILElBTEgsQ0FLUSxvQkFBWTtBQUNoQjhHLDBCQUFrQixTQUFsQixFQUE2QixVQUE3QixFQUF5QyxLQUF6QyxFQUFnRFMsV0FBaEQsRUFBNkRDLEtBQUtDLEdBQUwsRUFBN0Q7QUFDQVYsOEJBQXNCeEIsUUFBdEIsRUFBZ0N5QixPQUFoQyxFQUF5Q0MsTUFBekM7QUFDRCxPQVJILEVBU0cvRyxLQVRILENBU1MsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FYSDtBQVlELEtBYk0sQ0FBUDtBQWNELEdBcENjO0FBcUNmNEgsY0FyQ2Usd0JBcUNEQyxTQXJDQyxFQXFDVTtBQUN2QmxKLFdBQU8yQyxLQUFQLHlDQUFtRHVHLFNBQW5EO0FBQ0EsUUFBTVQsY0FBY0MsS0FBS0MsR0FBTCxFQUFwQjtBQUNBLFdBQU8sSUFBSTFCLE9BQUosQ0FBWSxVQUFDaUIsT0FBRCxFQUFVQyxNQUFWLEVBQXFCO0FBQ3RDVCxZQUNHa0IsSUFESCxDQUNRZCxVQURSLEVBQ29CO0FBQ2hCZSxnQkFBUSxZQURRO0FBRWhCdEUsZ0JBQVEsRUFBRWpILE1BQU00TCxTQUFSO0FBRlEsT0FEcEIsRUFLR2hJLElBTEgsQ0FLUSxvQkFBWTtBQUNoQjhHLDBCQUFrQixTQUFsQixFQUE2QixjQUE3QixFQUE2QyxZQUE3QyxFQUEyRFMsV0FBM0QsRUFBd0VDLEtBQUtDLEdBQUwsRUFBeEU7QUFDQVYsOEJBQXNCeEIsUUFBdEIsRUFBZ0N5QixPQUFoQyxFQUF5Q0MsTUFBekM7QUFDRCxPQVJILEVBU0cvRyxLQVRILENBU1MsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FYSDtBQVlELEtBYk0sQ0FBUDtBQWNELEdBdERjO0FBdURmOEgsWUF2RGUsc0JBdURISixHQXZERyxFQXVERTtBQUNmL0ksV0FBTzJDLEtBQVAsb0NBQThDb0csR0FBOUM7QUFDQSxRQUFNTixjQUFjQyxLQUFLQyxHQUFMLEVBQXBCO0FBQ0EsV0FBTyxJQUFJMUIsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdENULFlBQ0drQixJQURILENBQ1FkLFVBRFIsRUFDb0I7QUFDaEJlLGdCQUFRLFNBRFE7QUFFaEJ0RSxnQkFBUSxFQUFFd0UsUUFBRjtBQUZRLE9BRHBCLEVBS0c3SCxJQUxILENBS1EsaUJBQWM7QUFBQSxZQUFYOUQsSUFBVyxTQUFYQSxJQUFXOztBQUNsQjRLLDBCQUFrQixTQUFsQixFQUE2QixZQUE3QixFQUEyQyxTQUEzQyxFQUFzRFMsV0FBdEQsRUFBbUVDLEtBQUtDLEdBQUwsRUFBbkU7QUFDQSxZQUFJdkwsS0FBS2dMLE1BQUwsQ0FBWVcsR0FBWixFQUFpQjFILEtBQXJCLEVBQTRCO0FBQUc7QUFDN0I4RyxpQkFBTy9LLEtBQUtnTCxNQUFMLENBQVlXLEdBQVosRUFBaUIxSCxLQUF4QjtBQUNELFNBRkQsTUFFTztBQUFHO0FBQ1I2RyxrQkFBUTlLLEtBQUtnTCxNQUFMLENBQVlXLEdBQVosQ0FBUjtBQUNEO0FBQ0YsT0FaSCxFQWFHM0gsS0FiSCxDQWFTLGlCQUFTO0FBQ2QrRyxlQUFPOUcsS0FBUDtBQUNELE9BZkg7QUFnQkQsS0FqQk0sQ0FBUDtBQWtCRCxHQTVFYztBQTZFZitILHNCQTdFZSxrQ0E2RVM7QUFDdEJwSixXQUFPMkMsS0FBUCxDQUFhLHVFQUFiO0FBQ0EsUUFBTThGLGNBQWNDLEtBQUtDLEdBQUwsRUFBcEI7QUFDQSxXQUFPLElBQUkxQixPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0Q1QsWUFDR2tCLElBREgsQ0FDUWQsVUFEUixFQUNvQjtBQUNoQmUsZ0JBQVE7QUFEUSxPQURwQixFQUlHM0gsSUFKSCxDQUlRLGlCQUFjO0FBQUEsWUFBWDlELElBQVcsU0FBWEEsSUFBVzs7QUFDbEI0SywwQkFBa0IsU0FBbEIsRUFBNkIsc0JBQTdCLEVBQXFELGNBQXJELEVBQXFFUyxXQUFyRSxFQUFrRkMsS0FBS0MsR0FBTCxFQUFsRjtBQUNBLFlBQUl2TCxLQUFLZ0wsTUFBVCxFQUFpQjtBQUNmRixrQkFBUTlLLEtBQUtnTCxNQUFMLENBQVlpQixrQkFBcEI7QUFDRCxTQUZELE1BRU87QUFDTCxpQkFBTyxJQUFJeEMsS0FBSixDQUFVLHVGQUFWLENBQVA7QUFDRDtBQUNGLE9BWEgsRUFZR3pGLEtBWkgsQ0FZUyxpQkFBUztBQUNkcEIsZUFBT3FCLEtBQVAsQ0FBYSxnQkFBYixFQUErQkEsS0FBL0I7QUFDQTZHLGdCQUFRLHVCQUFSO0FBQ0QsT0FmSDtBQWdCRCxLQWpCTSxDQUFQO0FBa0JELEdBbEdjO0FBbUdmb0IsZUFuR2UseUJBbUdBaE0sSUFuR0EsRUFtR007QUFDbkIwQyxXQUFPMkMsS0FBUCxzQ0FBZ0RyRixJQUFoRDtBQUNBLFFBQU1tTCxjQUFjQyxLQUFLQyxHQUFMLEVBQXBCO0FBQ0EsV0FBTyxJQUFJMUIsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdENULFlBQ0drQixJQURILENBQ1FkLFVBRFIsRUFDb0I7QUFDaEJlLGdCQUFRLGFBRFE7QUFFaEJ0RSxnQkFBUTtBQUNOZ0Ysd0JBQWNqTSxJQURSO0FBRU5rTSxrQkFBYztBQUZSO0FBRlEsT0FEcEIsRUFRR3RJLElBUkgsQ0FRUSxvQkFBWTtBQUNoQjhHLDBCQUFrQixTQUFsQixFQUE2QixlQUE3QixFQUE4QyxhQUE5QyxFQUE2RFMsV0FBN0QsRUFBMEVDLEtBQUtDLEdBQUwsRUFBMUU7QUFDQVYsOEJBQXNCeEIsUUFBdEIsRUFBZ0N5QixPQUFoQyxFQUF5Q0MsTUFBekM7QUFDRCxPQVhILEVBWUcvRyxLQVpILENBWVMsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FkSDtBQWVELEtBaEJNLENBQVA7QUFpQkQ7QUF2SGMsQ0FBakIsQzs7Ozs7Ozs7O0FDdEJBLElBQU1yQixTQUFTLG1CQUFBRCxDQUFRLENBQVIsQ0FBZjtBQUNBLElBQU0wSixLQUFLLG1CQUFBMUosQ0FBUSxFQUFSLENBQVg7O2VBQ3lELG1CQUFBQSxDQUFRLENBQVIsQztJQUFuQ3RCLFEsWUFBZEQsUyxDQUFjQyxRO0lBQXVCSSxLLFlBQVhHLE8sQ0FBV0gsSzs7QUFFN0MsU0FBUzZLLHNCQUFULENBQWlDQyxPQUFqQyxFQUEwQ0MsRUFBMUMsRUFBOENDLFdBQTlDLEVBQTJEO0FBQ3pELFNBQU87QUFDTEMsbUJBQW1CLGlCQURkO0FBRUxDLGlCQUFtQixlQUZkO0FBR0xDLGdCQUFtQkgsV0FIZDtBQUlMSSxnQkFBbUJMLEVBSmQ7QUFLTE0sdUJBQW1CUCxRQUFRLFlBQVI7QUFMZCxHQUFQO0FBT0Q7O0FBRUQsU0FBU1EsOEJBQVQsQ0FBeUNDLFFBQXpDLEVBQW1EQyxRQUFuRCxFQUE2REMsS0FBN0QsRUFBb0VDLFNBQXBFLEVBQStFQyxPQUEvRSxFQUF3RjtBQUN0RixNQUFNQyxXQUFXRCxVQUFVRCxTQUEzQjtBQUNBLFNBQU87QUFDTEcsd0JBQXdCTixRQURuQjtBQUVMTyw0QkFBd0JOLFFBRm5CO0FBR0xPLG9CQUF3QkgsUUFIbkI7QUFJTEkscUJBQXdCUDtBQUpuQixHQUFQO0FBTUQ7O0FBRUQsU0FBU1Esd0JBQVQsQ0FBbUNsQixFQUFuQyxFQUF1Q3JGLE1BQXZDLEVBQStDO0FBQzdDLE1BQU13RyxZQUFZbkIsR0FBR29CLE9BQUgsQ0FBVyxLQUFYLEVBQWtCLEdBQWxCLENBQWxCO0FBQ0EsTUFBTUMsVUFBVXhCLEdBQUdoTCxRQUFILEVBQWFzTSxTQUFiLEVBQXdCLEVBQUVHLGlCQUFpQixLQUFuQixFQUEwQkMsT0FBTyxJQUFqQyxFQUF4QixDQUFoQjtBQUNBRixVQUFRRyxLQUFSLENBQWM3RyxNQUFkLEVBQXNCLFVBQUNqRCxHQUFELEVBQVM7QUFDN0IsUUFBSUEsR0FBSixFQUFTO0FBQ1B0QixhQUFPcUIsS0FBUCxDQUFhLGlDQUFiLEVBQWdEQyxHQUFoRDtBQUNEO0FBQ0YsR0FKRDtBQUtEOztBQUVELFNBQVMrSix5QkFBVCxDQUFvQ04sU0FBcEMsRUFBK0N4RyxNQUEvQyxFQUF1RDtBQUNyRCxNQUFNMEcsVUFBVXhCLEdBQUdoTCxRQUFILEVBQWFzTSxTQUFiLEVBQXdCLEVBQUVHLGlCQUFpQixLQUFuQixFQUEwQkMsT0FBTyxJQUFqQyxFQUF4QixDQUFoQjtBQUNBRixVQUFRSyxNQUFSLENBQWUvRyxNQUFmLEVBQXVCLFVBQUNqRCxHQUFELEVBQVM7QUFDOUIsUUFBSUEsR0FBSixFQUFTO0FBQ1B0QixhQUFPcUIsS0FBUCxDQUFhLGlDQUFiLEVBQWdEQyxHQUFoRDtBQUNEO0FBQ0R0QixXQUFPMkMsS0FBUDtBQUNELEdBTEQ7QUFNRDs7QUFFRC9DLE9BQU9DLE9BQVAsR0FBaUI7QUFDZjBMLGtCQURlLDRCQUNHNUIsT0FESCxFQUNZQyxFQURaLEVBQ2dCQyxXQURoQixFQUM2QjtBQUMxQyxRQUFNdEYsU0FBU21GLHVCQUF1QkMsT0FBdkIsRUFBZ0NDLEVBQWhDLEVBQW9DQyxXQUFwQyxDQUFmO0FBQ0FpQiw2QkFBeUJsQixFQUF6QixFQUE2QnJGLE1BQTdCO0FBQ0QsR0FKYztBQUtmeUQsbUJBTGUsNkJBS0lvQyxRQUxKLEVBS2NDLFFBTGQsRUFLd0JDLEtBTHhCLEVBSytCQyxTQUwvQixFQUswQ0MsT0FMMUMsRUFLbUQ7QUFDaEUsUUFBTWpHLFNBQVM0RiwrQkFBK0JDLFFBQS9CLEVBQXlDQyxRQUF6QyxFQUFtREMsS0FBbkQsRUFBMERDLFNBQTFELEVBQXFFQyxPQUFyRSxDQUFmO0FBQ0FhLDhCQUEwQnhNLEtBQTFCLEVBQWlDMEYsTUFBakM7QUFDRCxHQVJjO0FBU2Z3RCw2QkFUZSw2Q0FTb0U7QUFBQSxRQUF0Qy9KLFdBQXNDLFFBQXBEdUwsWUFBb0Q7QUFBQSxRQUFiN0UsU0FBYSxRQUF6QjhHLFVBQXlCOztBQUNqRixXQUFReE4sZUFBZTBHLFNBQWYsR0FBMkIsMEJBQTNCLEdBQXdELHlCQUFoRTtBQUNEO0FBWGMsQ0FBakIsQzs7Ozs7O0FDNUNBLGtDOzs7Ozs7Ozs7Ozs7UUNJZ0IrRyxxQixHQUFBQSxxQjs7QUFKaEI7O0lBQVl6TyxPOzs7O0FBRVo7O0FBRU8sU0FBU3lPLHFCQUFULENBQWdDbk8sSUFBaEMsRUFBc0M0RixPQUF0QyxFQUErQ0UsTUFBL0MsRUFBdUQ7QUFDNUQsU0FBTztBQUNMbEcsVUFBTUYsUUFBUTBPLGNBRFQ7QUFFTHRPLFVBQU07QUFDSkUsZ0JBREk7QUFFSjRGLHNCQUZJO0FBR0pFO0FBSEk7QUFGRCxHQUFQO0FBUUQsRTs7Ozs7Ozs7Ozs7Ozs7O0FDYkQ7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7Ozs7Ozs7OztJQUVNdUksVzs7O0FBQ0osdUJBQWFDLEtBQWIsRUFBb0I7QUFBQTs7QUFBQSwwSEFDWkEsS0FEWTs7QUFFbEIsVUFBS25FLEtBQUwsR0FBYTtBQUNYb0UsWUFBYSxFQURGO0FBRVhDLGFBQWEsQ0FGRjtBQUdYQyxtQkFBYTtBQUhGLEtBQWI7QUFLQSxVQUFLQyxVQUFMLEdBQWtCLE1BQUtBLFVBQUwsQ0FBZ0JDLElBQWhCLE9BQWxCO0FBQ0EsVUFBS0MsZ0JBQUwsR0FBd0IsTUFBS0EsZ0JBQUwsQ0FBc0JELElBQXRCLE9BQXhCO0FBQ0EsVUFBS0UsaUJBQUwsR0FBeUIsTUFBS0EsaUJBQUwsQ0FBdUJGLElBQXZCLE9BQXpCO0FBQ0EsVUFBS0csZUFBTCxHQUF1QixNQUFLQSxlQUFMLENBQXFCSCxJQUFyQixPQUF2QjtBQVZrQjtBQVduQjs7Ozt3Q0FDb0I7QUFDbkIsV0FBS0QsVUFBTDtBQUNBLFdBQUtFLGdCQUFMO0FBQ0Q7OzsyQ0FDdUI7QUFDdEIsV0FBS0UsZUFBTDtBQUNEOzs7aUNBQ2E7QUFDWixVQUFNUCxPQUFPLEVBQWI7QUFDQSxXQUFLLElBQUlRLElBQUksQ0FBYixFQUFnQkEsS0FBSyxLQUFLVCxLQUFMLENBQVdVLElBQWhDLEVBQXNDRCxHQUF0QyxFQUEyQztBQUN6Q1IsYUFBS1UsSUFBTCxDQUFVLEVBQUNDLFVBQVUsS0FBWCxFQUFWO0FBQ0Q7QUFDRCxXQUFLQyxRQUFMLENBQWMsRUFBRVosVUFBRixFQUFkO0FBQ0Q7Ozt1Q0FDbUI7QUFDbEIsV0FBS2EsY0FBTCxHQUFzQkMsWUFBWSxLQUFLUixpQkFBTCxDQUF1QkYsSUFBdkIsQ0FBNEIsSUFBNUIsQ0FBWixFQUErQyxHQUEvQyxDQUF0QjtBQUNEOzs7d0NBQ29CO0FBQ25CLFVBQUlILFFBQVEsS0FBS3JFLEtBQUwsQ0FBV3FFLEtBQXZCO0FBQ0EsVUFBSUMsY0FBYyxLQUFLdEUsS0FBTCxDQUFXc0UsV0FBN0I7QUFDQSxVQUFJRixPQUFPLEtBQUtwRSxLQUFMLENBQVdvRSxJQUF0QjtBQUNBO0FBQ0EsVUFBS0MsUUFBUSxDQUFULElBQWdCQSxRQUFRLEtBQUtGLEtBQUwsQ0FBV1UsSUFBdkMsRUFBOEM7QUFDNUNQLHNCQUFjQSxjQUFjLENBQUMsQ0FBN0I7QUFDQUQsaUJBQVNDLFdBQVQ7QUFDRDtBQUNEO0FBQ0EsVUFBSUEsY0FBYyxDQUFsQixFQUFxQjtBQUNuQkYsYUFBS0MsS0FBTCxFQUFZVSxRQUFaLEdBQXVCLElBQXZCO0FBQ0QsT0FGRCxNQUVPO0FBQ0xYLGFBQUtDLEtBQUwsRUFBWVUsUUFBWixHQUF1QixLQUF2QjtBQUNEO0FBQ0Q7QUFDQVYsZUFBU0MsV0FBVDtBQUNBO0FBQ0EsV0FBS1UsUUFBTCxDQUFjO0FBQ1paLGtCQURZO0FBRVpFLGdDQUZZO0FBR1pEO0FBSFksT0FBZDtBQUtEOzs7c0NBQ2tCO0FBQ2pCYyxvQkFBYyxLQUFLRixjQUFuQjtBQUNEOzs7NkJBQ1M7QUFDUixhQUNFO0FBQUE7QUFBQTtBQUNHLGFBQUtqRixLQUFMLENBQVdvRSxJQUFYLENBQWdCZ0IsR0FBaEIsQ0FBb0IsVUFBQ0MsR0FBRCxFQUFNaEIsS0FBTjtBQUFBLGlCQUFnQmdCLElBQUlOLFFBQUosR0FBZSwyREFBaUIsS0FBS1YsS0FBdEIsR0FBZixHQUFpRCw2REFBbUIsS0FBS0EsS0FBeEIsR0FBakU7QUFBQSxTQUFwQjtBQURILE9BREY7QUFLRDs7OztFQS9EdUIsZ0JBQU1pQixTOztBQWdFL0I7O0FBRURwQixZQUFZcUIsU0FBWixHQUF3QjtBQUN0QlYsUUFBTSxvQkFBVVcsTUFBVixDQUFpQkM7QUFERCxDQUF4Qjs7a0JBSWV2QixXOzs7Ozs7Ozs7Ozs7Ozs7QUMzRWY7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7Ozs7Ozs7SUFFTXdCLFM7Ozs7Ozs7Ozs7OzZCQUNNO0FBQUEsVUFDQTlMLEtBREEsR0FDVSxLQUFLdUssS0FEZixDQUNBdkssS0FEQTs7QUFFUixhQUNFO0FBQUE7QUFBQTtBQUNFLDZEQURGO0FBRUU7QUFBQTtBQUFBLFlBQUssV0FBVSxpQkFBZjtBQUNFO0FBQUE7QUFBQTtBQUFJQTtBQUFKO0FBREY7QUFGRixPQURGO0FBUUQ7Ozs7RUFYcUIsZ0JBQU0wTCxTOztBQVk3Qjs7QUFFREksVUFBVUgsU0FBVixHQUFzQjtBQUNwQjNMLFNBQU8sb0JBQVUrTCxNQUFWLENBQWlCRjtBQURKLENBQXRCOztrQkFJZUMsUzs7Ozs7O0FDdEJmLHFDOzs7Ozs7QUNBQSwyQzs7Ozs7O0FDQUEsc0M7Ozs7Ozs7OztBQ0FBdk4sT0FBT0MsT0FBUCxHQUFpQjtBQUNmd04saUJBQWUsdUJBQVVDLFdBQVYsRUFBdUJsSyxNQUF2QixFQUErQjtBQUM1QyxRQUFJbUssbUJBQUo7QUFDQSxRQUFJckssVUFBVUUsT0FBT29LLFNBQVAsQ0FBaUIsQ0FBakIsRUFBb0IsQ0FBcEIsQ0FBZCxDQUY0QyxDQUVOO0FBQ3RDLFFBQUlDLGdCQUFnQixDQUFwQjtBQUNBO0FBQ0FGLGlCQUFhRCxZQUFZSSxTQUFaLENBQXNCLG1CQUFXO0FBQzVDLGFBQU9DLFFBQVF0SSxPQUFSLEtBQW9CakMsTUFBM0I7QUFDRCxLQUZZLENBQWI7QUFHQSxRQUFJbUssYUFBYSxDQUFqQixFQUFvQjtBQUNsQixZQUFNLElBQUkxRyxLQUFKLENBQVUsbUNBQVYsQ0FBTjtBQUNEO0FBQ0Q7QUFDQSxRQUFJK0csa0JBQWtCTixZQUFZTyxLQUFaLENBQWtCLENBQWxCLEVBQXFCTixVQUFyQixDQUF0QjtBQUNBO0FBQ0EsV0FBT0ssZ0JBQWdCRSxNQUFoQixHQUF5QixDQUFoQyxFQUFtQztBQUNqQ0wsdUJBQWlCLENBQWpCO0FBQ0F2SyxnQkFBVUUsT0FBT29LLFNBQVAsQ0FBaUIsQ0FBakIsRUFBb0JDLGFBQXBCLENBQVY7QUFDQUcsd0JBQWtCQSxnQkFBZ0JHLE1BQWhCLENBQXVCLG1CQUFXO0FBQ2xELGVBQVFKLFFBQVF0SSxPQUFSLElBQW9Cc0ksUUFBUXRJLE9BQVIsQ0FBZ0JtSSxTQUFoQixDQUEwQixDQUExQixFQUE2QkMsYUFBN0IsTUFBZ0R2SyxPQUE1RTtBQUNELE9BRmlCLENBQWxCO0FBR0Q7QUFDRCxXQUFPQSxPQUFQO0FBQ0Q7QUF2QmMsQ0FBakIsQzs7Ozs7Ozs7O0FDQUEsSUFBTWxELFNBQVMsbUJBQUFELENBQVEsQ0FBUixDQUFmO0FBQ0EsSUFBTWlPLEtBQUssbUJBQUFqTyxDQUFRLEVBQVIsQ0FBWDs7ZUFFZ0MsbUJBQUFBLENBQVEsQ0FBUixDO0lBQXhCZixPLFlBQUFBLE87SUFBU0ksVSxZQUFBQSxVOztBQUVqQlEsT0FBT0MsT0FBUCxHQUFpQjtBQUNmb08sNEJBRGUsNENBQ21FO0FBQUEsUUFBckQzUSxJQUFxRCxRQUFyREEsSUFBcUQ7QUFBQSxRQUEvQzRRLElBQStDLFFBQS9DQSxJQUErQztBQUFBLFFBQXpDQyxPQUF5QyxRQUF6Q0EsT0FBeUM7QUFBQSxRQUFoQ3RQLEtBQWdDLFFBQWhDQSxLQUFnQztBQUFBLFFBQXpCRixXQUF5QixRQUF6QkEsV0FBeUI7QUFBQSxRQUFaQyxTQUFZLFFBQVpBLFNBQVk7O0FBQ2hGO0FBQ0EsUUFBSSxDQUFDdEIsSUFBTCxFQUFXO0FBQ1QsWUFBTSxJQUFJdUosS0FBSixDQUFVLGdDQUFWLENBQU47QUFDRDtBQUNELFFBQU11SCx3QkFBd0IsaUJBQWlCQyxJQUFqQixDQUFzQi9RLElBQXRCLENBQTlCO0FBQ0EsUUFBSThRLHFCQUFKLEVBQTJCO0FBQ3pCLFlBQU0sSUFBSXZILEtBQUosQ0FBVSxnSEFBVixDQUFOO0FBQ0Q7QUFDRDtBQUNBcUgsV0FBUUEsU0FBUyxNQUFqQjtBQUNBQyxjQUFVQSxXQUFXLElBQXJCO0FBQ0F0UCxZQUFRQSxTQUFTLElBQWpCO0FBQ0FGLGtCQUFjQSxlQUFlLElBQTdCO0FBQ0FDLGdCQUFZQSxhQUFhLElBQXpCO0FBQ0E7QUFDQSxXQUFPO0FBQ0x0QixnQkFESztBQUVMNFEsZ0JBRks7QUFHTEMsc0JBSEs7QUFJTHRQLGtCQUpLO0FBS0xGLDhCQUxLO0FBTUxDO0FBTkssS0FBUDtBQVFELEdBekJjO0FBMEJmMFAsNkJBMUJlLDhDQTBCaUM7QUFBQSxRQUFsQnJSLElBQWtCLFNBQWxCQSxJQUFrQjtBQUFBLFFBQVoyQixTQUFZLFNBQVpBLFNBQVk7O0FBQzlDO0FBQ0EsUUFBSSxDQUFDM0IsSUFBTCxFQUFXO0FBQ1QsWUFBTSxJQUFJNEosS0FBSixDQUFVLDZDQUFWLENBQU47QUFDRDtBQUNELFFBQUksQ0FBQzVKLEtBQUtzUixJQUFWLEVBQWdCO0FBQ2QsWUFBTSxJQUFJMUgsS0FBSixDQUFVLG9CQUFWLENBQU47QUFDRDtBQUNELFFBQUksQ0FBQzVKLEtBQUtDLElBQVYsRUFBZ0I7QUFDZCxZQUFNLElBQUkySixLQUFKLENBQVUsb0JBQVYsQ0FBTjtBQUNEO0FBQ0QsUUFBSSxDQUFDNUosS0FBS3FQLElBQVYsRUFBZ0I7QUFDZCxZQUFNLElBQUl6RixLQUFKLENBQVUsb0JBQVYsQ0FBTjtBQUNEO0FBQ0Q7QUFDQSxRQUFJLElBQUkySCxJQUFKLENBQVN2UixLQUFLSyxJQUFkLENBQUosRUFBeUI7QUFDdkIsWUFBTSxJQUFJdUosS0FBSixDQUFVLDhDQUFWLENBQU47QUFDRDtBQUNEO0FBQ0FqSCxXQUFPQyxPQUFQLENBQWU0Tyx1QkFBZixDQUF1Q3hSLElBQXZDO0FBQ0E7QUFDQSxXQUFPO0FBQ0x5UixnQkFBbUJ6UixLQUFLSyxJQURuQjtBQUVMcVIsZ0JBQW1CMVIsS0FBS3NSLElBRm5CO0FBR0xLLGdCQUFtQjNSLEtBQUtDLElBSG5CO0FBSUwyUix5QkFBb0JqUSxZQUFZQSxVQUFVdEIsSUFBdEIsR0FBNkIsSUFKNUM7QUFLTHdSLHlCQUFvQmxRLFlBQVlBLFVBQVUyUCxJQUF0QixHQUE2QixJQUw1QztBQU1MUSx5QkFBb0JuUSxZQUFZQSxVQUFVMUIsSUFBdEIsR0FBNkI7QUFONUMsS0FBUDtBQVFELEdBdkRjO0FBd0RmdVIseUJBeERlLG1DQXdEVXhSLElBeERWLEVBd0RnQjtBQUM3QjtBQUNBLFlBQVFBLEtBQUtDLElBQWI7QUFDRSxXQUFLLFlBQUw7QUFDQSxXQUFLLFdBQUw7QUFDQSxXQUFLLFdBQUw7QUFDRSxZQUFJRCxLQUFLcVAsSUFBTCxHQUFZLFFBQWhCLEVBQTBCO0FBQ3hCdE0saUJBQU8yQyxLQUFQLENBQWEseURBQWI7QUFDQSxnQkFBTSxJQUFJa0UsS0FBSixDQUFVLDRDQUFWLENBQU47QUFDRDtBQUNEO0FBQ0YsV0FBSyxXQUFMO0FBQ0UsWUFBSTVKLEtBQUtxUCxJQUFMLEdBQVksUUFBaEIsRUFBMEI7QUFDeEJ0TSxpQkFBTzJDLEtBQVAsQ0FBYSw4Q0FBYjtBQUNBLGdCQUFNLElBQUlrRSxLQUFKLENBQVUsMkNBQVYsQ0FBTjtBQUNEO0FBQ0Q7QUFDRixXQUFLLFdBQUw7QUFDRSxZQUFJNUosS0FBS3FQLElBQUwsR0FBWSxRQUFoQixFQUEwQjtBQUN4QnRNLGlCQUFPMkMsS0FBUCxDQUFhLDhDQUFiO0FBQ0EsZ0JBQU0sSUFBSWtFLEtBQUosQ0FBVSw0Q0FBVixDQUFOO0FBQ0Q7QUFDRDtBQUNGO0FBQ0U3RyxlQUFPMkMsS0FBUCxDQUFhLG9EQUFiO0FBQ0EsY0FBTSxJQUFJa0UsS0FBSixDQUFVLFNBQVM1SixLQUFLQyxJQUFkLEdBQXFCLG1HQUEvQixDQUFOO0FBdkJKO0FBeUJBLFdBQU9ELElBQVA7QUFDRCxHQXBGYztBQXFGZitSLDBCQXJGZSxvQ0FxRldMLFFBckZYLEVBcUZxQnJSLElBckZyQixFQXFGMkJ1QixLQXJGM0IsRUFxRmtDRixXQXJGbEMsRUFxRitDd1AsT0FyRi9DLEVBcUZ3REQsSUFyRnhELEVBcUY4RHRQLFNBckY5RCxFQXFGeUU7QUFDdEZvQixXQUFPMkMsS0FBUDtBQUNBO0FBQ0EsUUFBSTlELFVBQVUsSUFBVixJQUFrQkEsTUFBTW9RLElBQU4sT0FBaUIsRUFBdkMsRUFBMkM7QUFDekNwUSxjQUFRdkIsSUFBUjtBQUNEO0FBQ0Q7QUFDQSxRQUFJcUIsZ0JBQWdCLElBQWhCLElBQXdCQSxZQUFZc1EsSUFBWixPQUF1QixFQUFuRCxFQUF1RDtBQUNyRHRRLG9CQUFjLEVBQWQ7QUFDRDtBQUNEO0FBQ0EsUUFBSXdQLFlBQVksSUFBWixJQUFvQkEsUUFBUWMsSUFBUixPQUFtQixFQUEzQyxFQUErQztBQUM3Q2QsZ0JBQVUsR0FBVixDQUQ2QyxDQUM3QjtBQUNqQjtBQUNEO0FBQ0EsUUFBTTNGLGdCQUFnQjtBQUNwQmxMLGdCQURvQjtBQUVwQjRSLGlCQUFXUCxRQUZTO0FBR3BCUSxXQUFXLElBSFM7QUFJcEJDLGdCQUFXO0FBQ1R6USxnQ0FEUztBQUVURSxvQkFGUztBQUdUd1EsZ0JBQVVyUSxRQUFRSCxLQUhUO0FBSVR5USxrQkFBVSxJQUpEO0FBS1RuQix3QkFMUztBQU1URDtBQU5TLE9BSlM7QUFZcEJxQixxQkFBZW5RLFdBQVdJO0FBWk4sS0FBdEI7QUFjQTtBQUNBLFFBQUlaLFNBQUosRUFBZTtBQUNiNEosb0JBQWMsVUFBZCxFQUEwQixXQUExQixJQUF5QzVKLFNBQXpDO0FBQ0Q7QUFDRCxXQUFPNEosYUFBUDtBQUNELEdBdkhjO0FBd0hmZ0gsOEJBeEhlLHdDQXdIZVYsaUJBeEhmLEVBd0hrQzVGLFNBeEhsQyxFQXdINkNpRixPQXhIN0MsRUF3SHNERCxJQXhIdEQsRUF3SDREO0FBQ3pFLFFBQUksQ0FBQ1ksaUJBQUwsRUFBd0I7QUFDdEI7QUFDRDtBQUNEOU8sV0FBTzJDLEtBQVA7QUFDQTtBQUNBLFdBQU87QUFDTHJGLFlBQWM0TCxTQUFkLFdBREs7QUFFTGdHLGlCQUFXSixpQkFGTjtBQUdMSyxXQUFXLElBSE47QUFJTEMsZ0JBQVc7QUFDVHZRLGVBQWdCcUssU0FBaEIsZUFEUztBQUVUdkssMENBQWdDdUssU0FGdkI7QUFHVG1HLGdCQUFhclEsUUFBUUgsS0FIWjtBQUlUeVEsa0JBQWEsSUFKSjtBQUtUbkIsd0JBTFM7QUFNVEQ7QUFOUyxPQUpOO0FBWUxxQixxQkFBZW5RLFdBQVdJLG1CQVpyQjtBQWFMK0osb0JBQWVuSyxXQUFXSyxnQkFickI7QUFjTCtMLGtCQUFlcE0sV0FBV007QUFkckIsS0FBUDtBQWdCRCxHQTlJYztBQStJZitQLHFCQS9JZSwrQkErSU1kLFFBL0lOLEVBK0lnQjtBQUM3QlgsT0FBRzBCLE1BQUgsQ0FBVWYsUUFBVixFQUFvQixlQUFPO0FBQ3pCLFVBQUlyTixHQUFKLEVBQVM7QUFDUHRCLGVBQU9xQixLQUFQLG9DQUE4Q3NOLFFBQTlDO0FBQ0EsY0FBTXJOLEdBQU47QUFDRDtBQUNEdEIsYUFBTzJDLEtBQVAsMkJBQXFDZ00sUUFBckM7QUFDRCxLQU5EO0FBT0QsR0F2SmM7QUF3SmZnQix5QkF4SmUsbUNBd0pVQyxRQXhKVixFQXdKb0JDLFNBeEpwQixFQXdKK0I7QUFDNUNELGFBQVNsQixRQUFULEdBQW9CbUIsVUFBVUMsU0FBOUI7QUFDQUYsYUFBU2pCLFFBQVQsR0FBb0JrQixVQUFVRSxhQUE5QjtBQUNBLFdBQU9ILFFBQVA7QUFDRCxHQTVKYztBQTZKZkksZ0JBN0plLGlDQTZKa0U7QUFBQSxRQUEvRDFTLElBQStELFNBQS9EQSxJQUErRDtBQUFBLFFBQXpEK0gsT0FBeUQsU0FBekRBLE9BQXlEO0FBQUEsUUFBaEQ0SyxRQUFnRCxTQUFoREEsUUFBZ0Q7QUFBQSxRQUF0Q0MsTUFBc0MsU0FBdENBLE1BQXNDO0FBQUEsUUFBOUJDLE9BQThCLFNBQTlCQSxPQUE4QjtBQUFBLFFBQXJCakMsSUFBcUIsU0FBckJBLElBQXFCO0FBQUEsUUFBZmtDLFdBQWUsU0FBZkEsV0FBZTs7QUFDL0UsV0FBTztBQUNMOVMsZ0JBREs7QUFFTCtILHNCQUZLO0FBR0w0Syx3QkFISztBQUlMQyxvQkFKSztBQUtMQyxzQkFMSztBQU1MekIsZ0JBQVUsRUFOTDtBQU9MQyxnQkFBVSxFQVBMO0FBUUxDLGdCQUFVd0IsV0FSTDtBQVNMbEM7QUFUSyxLQUFQO0FBV0Q7QUF6S2MsQ0FBakIsQzs7Ozs7Ozs7Ozs7QUNMQSxJQUFNbE8sU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7O0FBRUFILE9BQU9DLE9BQVAsR0FBaUI7QUFDZndRLHVCQUFxQiw2QkFBVXhHLFdBQVYsRUFBdUJELEVBQXZCLEVBQTJCdkksS0FBM0IsRUFBa0NpUCxHQUFsQyxFQUF1QztBQUMxRHRRLFdBQU9xQixLQUFQLGVBQXlCd0ksV0FBekIsRUFBd0NqSyxPQUFPQyxPQUFQLENBQWUwUSwyQkFBZixDQUEyQ2xQLEtBQTNDLENBQXhDOztBQUQwRCxnQ0FFaEN6QixPQUFPQyxPQUFQLENBQWUyUSwyQkFBZixDQUEyQ25QLEtBQTNDLENBRmdDO0FBQUE7QUFBQSxRQUVuRHpELE1BRm1EO0FBQUEsUUFFM0NDLE9BRjJDOztBQUcxRHlTLFFBQ0cxUyxNQURILENBQ1VBLE1BRFYsRUFFRzhJLElBRkgsQ0FFUTlHLE9BQU9DLE9BQVAsQ0FBZTRRLDBCQUFmLENBQTBDN1MsTUFBMUMsRUFBa0RDLE9BQWxELENBRlI7QUFHRCxHQVBjO0FBUWYyUywrQkFBNkIscUNBQVVuUCxLQUFWLEVBQWlCO0FBQzVDLFFBQUl6RCxlQUFKO0FBQUEsUUFBWUMsZ0JBQVo7QUFDQTtBQUNBLFFBQUl3RCxNQUFNcVAsSUFBTixLQUFlLGNBQW5CLEVBQW1DO0FBQ2pDOVMsZUFBUyxHQUFUO0FBQ0FDLGdCQUFVLHFEQUFWO0FBQ0E7QUFDRCxLQUpELE1BSU87QUFDTEQsZUFBUyxHQUFUO0FBQ0EsVUFBSXlELE1BQU14RCxPQUFWLEVBQW1CO0FBQ2pCQSxrQkFBVXdELE1BQU14RCxPQUFoQjtBQUNELE9BRkQsTUFFTztBQUNMQSxrQkFBVXdELEtBQVY7QUFDRDtBQUNGO0FBQ0QsV0FBTyxDQUFDekQsTUFBRCxFQUFTQyxPQUFULENBQVA7QUFDRCxHQXhCYztBQXlCZjBTLCtCQUE2QixxQ0FBVWpQLEdBQVYsRUFBZTtBQUMxQyxRQUFJUSxPQUFPQyxJQUFQLENBQVlULEdBQVosRUFBaUJ3TSxNQUFqQixLQUE0QixDQUFoQyxFQUFtQztBQUNqQyxVQUFJNkMsaUJBQWlCLEVBQXJCO0FBQ0E3TyxhQUFPOE8sbUJBQVAsQ0FBMkJ0UCxHQUEzQixFQUFnQ1UsT0FBaEMsQ0FBd0MsVUFBQ21ELEdBQUQsRUFBUztBQUMvQ3dMLHVCQUFleEwsR0FBZixJQUFzQjdELElBQUk2RCxHQUFKLENBQXRCO0FBQ0QsT0FGRDtBQUdBLGFBQU93TCxjQUFQO0FBQ0Q7QUFDRCxXQUFPclAsR0FBUDtBQUNELEdBbENjO0FBbUNmbVAsNEJBbkNlLHNDQW1DYTdTLE1BbkNiLEVBbUNxQkMsT0FuQ3JCLEVBbUM4QjtBQUMzQyxXQUFPO0FBQ0xELG9CQURLO0FBRUxpVCxlQUFTLEtBRko7QUFHTGhUO0FBSEssS0FBUDtBQUtEO0FBekNjLENBQWpCLEM7Ozs7Ozs7Ozs7O0FDRkEsSUFBTXlDLEtBQUssbUJBQUFQLENBQVEsQ0FBUixDQUFYO0FBQ0EsSUFBTUMsU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7O2VBQ3lDLG1CQUFBQSxDQUFRLEVBQVIsQztJQUFqQytRLDRCLFlBQUFBLDRCOztBQUVSLElBQU1DLGFBQWEsWUFBbkI7QUFDQSxJQUFNQyxXQUFXLFVBQWpCO0FBQ0EsSUFBTUMsVUFBVSxTQUFoQjs7QUFFQXJSLE9BQU9DLE9BQVAsR0FBaUI7QUFDZnFSLFlBRGUsc0JBQ0hsVCxXQURHLEVBQ1VtVCxjQURWLEVBQzBCN1QsSUFEMUIsRUFDZ0MrSCxPQURoQyxFQUN5QztBQUN0RCxRQUFJckgsV0FBSixFQUFpQjtBQUNmLGFBQU80QixPQUFPQyxPQUFQLENBQWV1UixtQkFBZixDQUFtQ3BULFdBQW5DLEVBQWdEbVQsY0FBaEQsRUFBZ0U3VCxJQUFoRSxDQUFQO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsYUFBT3NDLE9BQU9DLE9BQVAsQ0FBZXdSLGlCQUFmLENBQWlDL1QsSUFBakMsRUFBdUMrSCxPQUF2QyxDQUFQO0FBQ0Q7QUFDRixHQVBjO0FBUWZnTSxtQkFSZSw2QkFRSW5JLFNBUkosRUFRZTdELE9BUmYsRUFRd0I7QUFDckNyRixXQUFPMkMsS0FBUCx3QkFBa0N1RyxTQUFsQyxVQUFnRDdELE9BQWhEO0FBQ0EsV0FBTyxJQUFJNEIsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdEM3SCxTQUFHbUIsS0FBSCxDQUFTNlAsY0FBVCxDQUF3QnBJLFNBQXhCLEVBQW1DN0QsT0FBbkMsRUFDR25FLElBREgsQ0FDUSx1QkFBZTtBQUNuQixZQUFJLENBQUNxUSxXQUFMLEVBQWtCO0FBQ2hCckosa0JBQVE4SSxRQUFSO0FBQ0Q7QUFDRDlJLGdCQUFRcUosV0FBUjtBQUNELE9BTkgsRUFPR25RLEtBUEgsQ0FPUyxpQkFBUztBQUNkK0csZUFBTzlHLEtBQVA7QUFDRCxPQVRIO0FBVUQsS0FYTSxDQUFQO0FBWUQsR0F0QmM7QUF1QmYrUCxxQkF2QmUsK0JBdUJNcFQsV0F2Qk4sRUF1Qm1CbVQsY0F2Qm5CLEVBdUJtQ2pJLFNBdkJuQyxFQXVCOEM7QUFDM0RsSixXQUFPMkMsS0FBUCwwQkFBb0MzRSxXQUFwQyxVQUFvRG1ULGNBQXBELFVBQXVFakksU0FBdkU7QUFDQSxXQUFPLElBQUlqQyxPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QzdILFNBQUdpQixXQUFILENBQWVpUSxnQkFBZixDQUFnQ3hULFdBQWhDLEVBQTZDbVQsY0FBN0MsRUFBNkQ7QUFBN0QsT0FDR2pRLElBREgsQ0FDUSx5QkFBaUI7QUFDckIsWUFBSSxDQUFDdVEsYUFBTCxFQUFvQjtBQUNsQixpQkFBTyxDQUFDLElBQUQsRUFBTyxJQUFQLENBQVA7QUFDRDtBQUNELGVBQU94SyxRQUFRQyxHQUFSLENBQVksQ0FBQ3VLLGFBQUQsRUFBZ0JuUixHQUFHbUIsS0FBSCxDQUFTaVEseUJBQVQsQ0FBbUNELGFBQW5DLEVBQWtEdkksU0FBbEQsQ0FBaEIsQ0FBWixDQUFQLENBSnFCLENBSStFO0FBQ3JHLE9BTkgsRUFPR2hJLElBUEgsQ0FPUSxnQkFBa0M7QUFBQTtBQUFBLFlBQWhDdVEsYUFBZ0M7QUFBQSxZQUFqQkYsV0FBaUI7O0FBQ3RDLFlBQUksQ0FBQ0UsYUFBTCxFQUFvQjtBQUNsQixpQkFBT3ZKLFFBQVE2SSxVQUFSLENBQVA7QUFDRDtBQUNELFlBQUksQ0FBQ1EsV0FBTCxFQUFrQjtBQUNoQixpQkFBT3JKLFFBQVE4SSxRQUFSLENBQVA7QUFDRDtBQUNEOUksZ0JBQVFxSixXQUFSO0FBQ0QsT0FmSCxFQWdCR25RLEtBaEJILENBZ0JTLGlCQUFTO0FBQ2QrRyxlQUFPOUcsS0FBUDtBQUNELE9BbEJIO0FBbUJELEtBcEJNLENBQVA7QUFxQkQsR0E5Q2M7QUErQ2ZzUSxnQkEvQ2UsMEJBK0NDM1QsV0EvQ0QsRUErQ2NtVCxjQS9DZCxFQStDOEJ4TCxJQS9DOUIsRUErQ29DO0FBQ2pELFdBQU8sSUFBSXNCLE9BQUosQ0FBWSxVQUFDaUIsT0FBRCxFQUFVQyxNQUFWLEVBQXFCO0FBQ3RDO0FBQ0E3SCxTQUFHaUIsV0FBSCxDQUFlaVEsZ0JBQWYsQ0FBZ0N4VCxXQUFoQyxFQUE2Q21ULGNBQTdDLEVBQ0dqUSxJQURILENBQ1EsOEJBQXNCO0FBQzFCLFlBQUksQ0FBQzBRLGtCQUFMLEVBQXlCO0FBQ3ZCLGlCQUFPLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLENBQVA7QUFDRDtBQUNEO0FBQ0EsZUFBTzNLLFFBQVFDLEdBQVIsQ0FBWSxDQUFDMEssa0JBQUQsRUFBcUJ0UixHQUFHaUIsV0FBSCxDQUFlc1Esa0NBQWYsQ0FBa0RELGtCQUFsRCxFQUFzRTVULFdBQXRFLENBQXJCLENBQVosQ0FBUDtBQUNELE9BUEgsRUFRR2tELElBUkgsQ0FRUSxpQkFBK0M7QUFBQTtBQUFBLFlBQTdDMFEsa0JBQTZDO0FBQUEsWUFBekJFLG1CQUF5Qjs7QUFDbkQsWUFBSSxDQUFDRixrQkFBTCxFQUF5QjtBQUN2QixpQkFBTzFKLFFBQVE2SSxVQUFSLENBQVA7QUFDRDtBQUNEO0FBQ0E3SSxnQkFBUTtBQUNObEssa0NBRE07QUFFTjRULGdEQUZNO0FBR05FO0FBSE0sU0FBUjtBQUtELE9BbEJILEVBbUJHMVEsS0FuQkgsQ0FtQlMsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FyQkg7QUFzQkQsS0F4Qk0sQ0FBUDtBQXlCRCxHQXpFYztBQTBFZjBRLGtCQTFFZSw0QkEwRUcvVCxXQTFFSCxFQTBFZ0JtVCxjQTFFaEIsRUEwRWdDeEwsSUExRWhDLEVBMEVzQztBQUNuRCxXQUFPLElBQUlzQixPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QztBQUNBN0gsU0FBR2lCLFdBQUgsQ0FBZWlRLGdCQUFmLENBQWdDeFQsV0FBaEMsRUFBNkNtVCxjQUE3QyxFQUNHalEsSUFESCxDQUNRLDhCQUFzQjtBQUMxQixZQUFJLENBQUMwUSxrQkFBTCxFQUF5QjtBQUN2QixpQkFBTyxDQUFDLElBQUQsRUFBTyxJQUFQLEVBQWEsSUFBYixDQUFQO0FBQ0Q7QUFDRDtBQUNBLGVBQU8zSyxRQUFRQyxHQUFSLENBQVksQ0FBQzBLLGtCQUFELEVBQXFCdFIsR0FBR21CLEtBQUgsQ0FBU3VRLG1CQUFULENBQTZCSixrQkFBN0IsQ0FBckIsQ0FBWixDQUFQO0FBQ0QsT0FQSCxFQVFHMVEsSUFSSCxDQVFRLGlCQUE4QztBQUFBO0FBQUEsWUFBNUMwUSxrQkFBNEM7QUFBQSxZQUF4Qkssa0JBQXdCOztBQUNsRCxZQUFJLENBQUNMLGtCQUFMLEVBQXlCO0FBQ3ZCLGlCQUFPMUosUUFBUTZJLFVBQVIsQ0FBUDtBQUNEO0FBQ0Q7QUFDQSxZQUFJbUIsMkJBQTJCcEIsNkJBQTZCOVMsV0FBN0IsRUFBMEM0VCxrQkFBMUMsRUFBOERLLGtCQUE5RCxFQUFrRnRNLElBQWxGLENBQS9CO0FBQ0E7QUFDQXVDLGdCQUFRZ0ssd0JBQVI7QUFDRCxPQWhCSCxFQWlCRzlRLEtBakJILENBaUJTLGlCQUFTO0FBQ2QrRyxlQUFPOUcsS0FBUDtBQUNELE9BbkJIO0FBb0JELEtBdEJNLENBQVA7QUF1QkQsR0FsR2M7QUFtR2Y4USxvQkFuR2UsOEJBbUdLOU0sT0FuR0wsRUFtR2MvSCxJQW5HZCxFQW1Hb0I7QUFDakMsV0FBT2dELEdBQUdvQixJQUFILENBQVFjLE9BQVIsQ0FBZ0IsRUFBQ0MsT0FBTyxFQUFDNEMsZ0JBQUQsRUFBVS9ILFVBQVYsRUFBUixFQUFoQixFQUNKNEQsSUFESSxDQUNDLGdCQUFRO0FBQ1osVUFBSSxDQUFDakUsSUFBTCxFQUFXO0FBQ1QsZUFBT2dVLE9BQVA7QUFDRDtBQUNELGFBQU9oVSxLQUFLbVYsVUFBWjtBQUNELEtBTkksQ0FBUDtBQU9EO0FBM0djLENBQWpCLEM7Ozs7Ozs7OztBQ1JBOzs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBRUF4UyxPQUFPQyxPQUFQLEdBQWlCLFVBQUN3UyxHQUFELEVBQU0vQixHQUFOLEVBQWM7QUFDN0IsTUFBSWdDLFVBQVUsRUFBZDs7QUFFQTtBQUNBLE1BQU1DLFFBQVEsd0NBQWQ7O0FBRUE7QUFDQSxNQUFNQyxPQUFPLDRCQUNYO0FBQUE7QUFBQSxNQUFVLE9BQU9ELEtBQWpCO0FBQ0U7QUFBQTtBQUFBLFFBQWMsVUFBVUYsSUFBSXZMLEdBQTVCLEVBQWlDLFNBQVN3TCxPQUExQztBQUNFO0FBQUE7QUFBQTtBQUNFO0FBREY7QUFERjtBQURGLEdBRFcsQ0FBYjs7QUFVQTtBQUNBLE1BQU1HLFNBQVMsc0JBQU9DLFlBQVAsRUFBZjs7QUFFQTtBQUNBLE1BQUlKLFFBQVF4TCxHQUFaLEVBQWlCO0FBQ2Y7QUFDQSxXQUFPd0osSUFBSXFDLFFBQUosQ0FBYSxHQUFiLEVBQWtCTCxRQUFReEwsR0FBMUIsQ0FBUDtBQUNELEdBSEQsTUFHTyxDQUVOO0FBREM7OztBQUdGO0FBQ0EsTUFBTThMLGlCQUFpQkwsTUFBTU0sUUFBTixFQUF2Qjs7QUFFQTtBQUNBdkMsTUFBSXdDLElBQUosQ0FBUyw4QkFBZUwsTUFBZixFQUF1QkQsSUFBdkIsRUFBNkJJLGNBQTdCLENBQVQ7QUFDRCxDQWpDRCxDOzs7Ozs7QUNYQSw2Qzs7Ozs7Ozs7Ozs7OztBQ0FBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7a0JBRWUsNEJBQWdCO0FBQzdCbFYsNEJBRDZCO0FBRTdCcVYsNEJBRjZCO0FBRzdCM0wsc0JBSDZCO0FBSTdCckU7QUFKNkIsQ0FBaEIsQzs7Ozs7Ozs7Ozs7O0FDTlIsSUFBTTVGLHdDQUFnQixlQUF0QjtBQUNBLElBQU1FLGtDQUFhLFlBQW5CO0FBQ0EsSUFBTUcsNENBQWtCLGlCQUF4QjtBQUNBLElBQU1DLHNDQUFlLGNBQXJCO0FBQ0EsSUFBTUUsMERBQXlCLHdCQUEvQjtBQUNBLElBQU1HLHdEQUF3Qix1QkFBOUI7QUFDQSxJQUFNQyxzQ0FBZSxjQUFyQjtBQUNBLElBQU1FLDREQUEwQix5QkFBaEM7QUFDQSxJQUFNRSwwREFBeUIsd0JBQS9CO0FBQ0EsSUFBTUMsd0NBQWdCLGVBQXRCO0FBQ0EsSUFBTUUsd0NBQWdCLGVBQXRCLEM7Ozs7Ozs7Ozs7OztBQ1ZBLElBQU0wVSx3QkFBUSxVQUFkO0FBQ0EsSUFBTUMsMEJBQVMsS0FBZixDOzs7Ozs7Ozs7Ozs7QUNEQSxJQUFNdkgsMENBQWlCLGdCQUF2QixDOzs7Ozs7Ozs7Ozs7QUNBQSxJQUFNd0gsb0NBQWMsYUFBcEI7QUFDQSxJQUFNQyxvQ0FBYyxhQUFwQjtBQUNBLElBQU1DLHdCQUFRLE9BQWQ7QUFDQSxJQUFNQyxnQ0FBWSxXQUFsQixDOzs7Ozs7Ozs7Ozs7Ozs7QUNIUDs7OztBQUNBOzs7O0FBQ0E7Ozs7Ozs7Ozs7ZUFDb0MsbUJBQUF0VCxDQUFRLENBQVIsQztJQUFmdEIsUSxZQUFiRCxTLENBQWFDLFE7O0FBRXJCLGtCQUFnQjZVLFVBQWhCLENBQTJCN1UsUUFBM0I7O0lBRU04VSxVOzs7Ozs7Ozs7Ozt3Q0FDaUI7QUFDbkIsV0FBS0MsWUFBTCxDQUFrQixLQUFLNUgsS0FBTCxDQUFXdk4sT0FBWCxDQUFtQm9WLFFBQXJDO0FBQ0EsV0FBSzdILEtBQUwsQ0FBV3ZOLE9BQVgsQ0FBbUJxVixNQUFuQixDQUEwQixLQUFLRixZQUEvQjtBQUNEOzs7aUNBRWFDLFEsRUFBVTtBQUN0Qix3QkFBZ0JFLEdBQWhCLENBQW9CLEVBQUVoTyxNQUFNOE4sU0FBU0csUUFBakIsRUFBcEI7QUFDQSx3QkFBZ0JDLFFBQWhCLENBQXlCSixTQUFTRyxRQUFsQztBQUNEOzs7NkJBRVM7QUFDUixhQUFPLEtBQUtoSSxLQUFMLENBQVdrSSxRQUFsQjtBQUNEOzs7O0VBYnNCLGdCQUFNL0csUzs7a0JBZ0JoQixnQ0FBV3dHLFVBQVgsQzs7Ozs7Ozs7Ozs7OztBQ3ZCZjs7OztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7OztBQUp1QztBQU12QyxJQUFNUSxNQUFNLFNBQU5BLEdBQU0sR0FBTTtBQUNoQixTQUNFO0FBQUE7QUFBQTtBQUNFLDJEQUFPLFdBQVAsRUFBYSxNQUFLLEdBQWxCLEVBQXNCLDZCQUF0QixHQURGO0FBRUUsMkRBQU8sV0FBUCxFQUFhLE1BQUssUUFBbEIsRUFBMkIsOEJBQTNCLEdBRkY7QUFHRSwyREFBTyxXQUFQLEVBQWEsTUFBSyxRQUFsQixFQUEyQiw4QkFBM0IsR0FIRjtBQUlFLDJEQUFPLFdBQVAsRUFBYSxNQUFLLHFCQUFsQixFQUF3Qyw2QkFBeEMsR0FKRjtBQUtFLDJEQUFPLFdBQVAsRUFBYSxNQUFLLFNBQWxCLEVBQTRCLDZCQUE1QixHQUxGO0FBTUUsMkRBQU8sbUNBQVA7QUFORixHQURGO0FBVUQsQ0FYRDs7a0JBYWVBLEc7Ozs7Ozs7Ozs7Ozs7QUNyQmY7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLElBQU1qUixrQkFBa0IsU0FBbEJBLGVBQWtCLE9BQWlCO0FBQUEsTUFBZGlRLE9BQWMsUUFBZEEsT0FBYzs7QUFDdkMsU0FBTztBQUNMOVYsVUFBVzhWLFFBQVE5VixJQURkO0FBRUwyQixlQUFXbVUsUUFBUW5VLFNBRmQ7QUFHTG9WLGVBQVdqQixRQUFRMVIsS0FBUixDQUFjcEU7QUFIcEIsR0FBUDtBQUtELENBTkQ7O0FBUUEsSUFBTXFHLHFCQUFxQixTQUFyQkEsa0JBQXFCLFdBQVk7QUFDckMsU0FBTztBQUNMakgsZ0JBQVksb0JBQUNZLElBQUQsRUFBVTtBQUNwQnVHLGVBQVMseUJBQVd2RyxJQUFYLENBQVQ7QUFDRCxLQUhJO0FBSUxnWCxrQkFBYyxzQkFBQzFXLEtBQUQsRUFBVztBQUN2QmlHLGVBQVMseUJBQVQ7QUFDQUEsZUFBUywwQkFBWSxNQUFaLEVBQW9CakcsS0FBcEIsQ0FBVDtBQUNEO0FBUEksR0FBUDtBQVNELENBVkQ7O2tCQVllLHlCQUFRdUYsZUFBUixFQUF5QlEsa0JBQXpCLGlCOzs7Ozs7Ozs7Ozs7O0FDeEJmOztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFFQSxJQUFNQSxxQkFBcUIsU0FBckJBLGtCQUFxQixXQUFZO0FBQ3JDLFNBQU87QUFDTEMsb0JBQWdCLHdCQUFDakcsSUFBRCxFQUFPNEYsT0FBUCxFQUFnQkUsTUFBaEIsRUFBMkI7QUFDekNJLGVBQVMsb0NBQXNCbEcsSUFBdEIsRUFBNEI0RixPQUE1QixFQUFxQ0UsTUFBckMsQ0FBVDtBQUNBSSxlQUFTLG9DQUFzQmxHLElBQXRCLENBQVQ7QUFDRDtBQUpJLEdBQVA7QUFNRCxDQVBEOztrQkFTZSx5QkFBUSxJQUFSLEVBQWNnRyxrQkFBZCxpQjs7Ozs7Ozs7Ozs7OztBQ2RmOztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFFQSxJQUFNQSxxQkFBcUIsU0FBckJBLGtCQUFxQixXQUFZO0FBQ3JDLFNBQU87QUFDTEMsb0JBQWdCLHdCQUFDakcsSUFBRCxFQUFPNEYsT0FBUCxFQUFnQkUsTUFBaEIsRUFBMkI7QUFDekNJLGVBQVMsb0NBQXNCbEcsSUFBdEIsRUFBNEI0RixPQUE1QixFQUFxQ0UsTUFBckMsQ0FBVDtBQUNBSSxlQUFTLG9DQUFzQmxHLElBQXRCLENBQVQ7QUFDRDtBQUpJLEdBQVA7QUFNRCxDQVBEOztrQkFTZSx5QkFBUSxJQUFSLEVBQWNnRyxrQkFBZCxpQjs7Ozs7Ozs7Ozs7O0FDZFIsSUFBTTRRLDRCQUFVLFNBQWhCO0FBQ0EsSUFBTUMsa0NBQWEsWUFBbkI7QUFDQSxJQUFNQyx3Q0FBZ0IsZUFBdEIsQzs7Ozs7Ozs7Ozs7OztBQ0ZQOztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxJQUFNdFIsa0JBQWtCLFNBQWxCQSxlQUFrQixPQUFjO0FBQUEsTUFBWHNFLElBQVcsUUFBWEEsSUFBVzs7QUFDcEM7QUFDQSxNQUFNL0YsUUFBUytGLEtBQUtpTixZQUFMLENBQWtCaFQsS0FBakM7QUFDQSxNQUFNekQsU0FBU3dKLEtBQUtpTixZQUFMLENBQWtCelcsTUFBakM7QUFDQTtBQUNBLE1BQU0wVyxRQUFRLHdCQUFZbE4sSUFBWixDQUFkO0FBQ0E7QUFDQSxTQUFPO0FBQ0wvRixnQkFESztBQUVMekQsa0JBRks7QUFHTDBXO0FBSEssR0FBUDtBQUtELENBWkQ7O0FBY0EsSUFBTWhSLHFCQUFxQixTQUFyQkEsa0JBQXFCLFdBQVk7QUFDckMsU0FBTztBQUNMaVIsbUJBQWUsdUJBQUNqWCxJQUFELEVBQU8rSCxPQUFQLEVBQW1CO0FBQ2hDN0IsZUFBUyx5QkFBY2xHLElBQWQsRUFBb0IrSCxPQUFwQixDQUFUO0FBQ0Q7QUFISSxHQUFQO0FBS0QsQ0FORDs7a0JBUWUseUJBQVF2QyxlQUFSLEVBQXlCUSxrQkFBekIsaUI7Ozs7Ozs7OztBQzNCZjFELE9BQU9DLE9BQVAsR0FBaUIsVUFBQzRTLE1BQUQsRUFBU0QsSUFBVCxFQUFlSSxjQUFmLEVBQWtDO0FBQ2pEO0FBQ0EsMFlBUVlILE9BQU81VCxLQUFQLENBQWEyVixRQUFiLEVBUlosc0JBU1kvQixPQUFPZ0MsSUFBUCxDQUFZRCxRQUFaLEVBVFosc0JBVVkvQixPQUFPaUMsSUFBUCxDQUFZRixRQUFaLEVBVlosMG1CQW9CaUZoQyxJQXBCakYsdUdBdUI2Q25LLEtBQUtDLFNBQUwsQ0FBZXNLLGNBQWYsRUFBK0I1SCxPQUEvQixDQUF1QyxJQUF2QyxFQUE2QyxLQUE3QyxDQXZCN0M7QUE2QkQsQ0EvQkQsQzs7Ozs7Ozs7Ozs7O0FDQU8sSUFBTTJKLDRDQUFrQixTQUFsQkEsZUFBa0IsQ0FBQ2xOLEtBQUQsRUFBVztBQUN4QyxTQUFPQSxNQUFNMUUsSUFBYjtBQUNELENBRk07O0FBSUEsSUFBTTZSLDBDQUFpQixTQUFqQkEsY0FBaUIsQ0FBQ25OLEtBQUQsRUFBVztBQUN2QyxTQUFPQSxNQUFNMUUsSUFBTixDQUFXOUQsSUFBbEI7QUFDRCxDQUZNLEM7Ozs7Ozs7Ozs7Ozs7OztBQ0pQLDJDOzs7Ozs7QUNBQSx5Qzs7Ozs7Ozs7O0FDQUE7QUFDQSxJQUFNNFYsVUFBVSxtQkFBQTlVLENBQVEsRUFBUixDQUFoQjtBQUNBLElBQU0rVSxhQUFhLG1CQUFBL1UsQ0FBUSxFQUFSLENBQW5CO0FBQ0EsSUFBTWdWLG9CQUFvQixtQkFBQWhWLENBQVEsRUFBUixDQUExQjtBQUNBLElBQU1pVixhQUFhLG1CQUFBalYsQ0FBUSxFQUFSLENBQW5CO0FBQ0EsSUFBTTBTLFNBQVMsbUJBQUExUyxDQUFRLEVBQVIsQ0FBZjtBQUNBLElBQU1rVixXQUFXLG1CQUFBbFYsQ0FBUSxFQUFSLENBQWpCOztlQUN1RCxtQkFBQUEsQ0FBUSxFQUFSLEM7SUFBL0NtVixtQixZQUFBQSxtQjtJQUFxQkMscUIsWUFBQUEscUI7O0FBQzdCLElBQU1DLGdCQUFnQixtQkFBQXJWLENBQVEsRUFBUixDQUF0QjtBQUNBLElBQU1zVixPQUFPLG1CQUFBdFYsQ0FBUSxFQUFSLENBQWI7QUFDQTtBQUNBLElBQU1DLFNBQVMsbUJBQUFELENBQVEsQ0FBUixDQUFmO0FBQ0E7QUFDQSxtQkFBQUEsQ0FBUSxFQUFSLEVBQXdDQyxNQUF4QztBQUNBLG1CQUFBRCxDQUFRLEVBQVIsRUFBdUNDLE1BQXZDOztnQkFFd0QsbUJBQUFELENBQVEsQ0FBUixDO0lBQXpDaEIsVSxhQUFSRCxJLENBQVFDLFU7SUFBK0J1VyxJLGFBQWpCdFcsTyxDQUFXRSxJOztBQUV4Qzs7O0FBQ0EsSUFBTXFXLE1BQU1WLFNBQVo7O0FBRUE7QUFDQVUsSUFBSUMsTUFBSixDQUFXLGFBQVg7O0FBRUE7QUFDQUQsSUFBSUUsR0FBSixDQUFRaEQsUUFBUixFLENBQW1CO0FBQ25COEMsSUFBSUUsR0FBSixDQUFRWixRQUFRYSxNQUFSLENBQWtCQyxTQUFsQixhQUFSLEUsQ0FBZ0Q7QUFDaERKLElBQUlFLEdBQUosQ0FBUVgsV0FBV3BPLElBQVgsRUFBUixFLENBQTRCO0FBQzVCNk8sSUFBSUUsR0FBSixDQUFRWCxXQUFXYyxVQUFYLENBQXNCLEVBQUVDLFVBQVUsSUFBWixFQUF0QixDQUFSLEUsQ0FBb0Q7QUFDcEROLElBQUlFLEdBQUosQ0FBUSxVQUFDcEQsR0FBRCxFQUFNL0IsR0FBTixFQUFXd0YsSUFBWCxFQUFvQjtBQUFHO0FBQzdCOVYsU0FBTytWLE9BQVAsaUJBQTZCMUQsSUFBSXhJLFdBQWpDLGNBQXFEd0ksSUFBSXpJLEVBQXpEO0FBQ0FrTTtBQUNELENBSEQ7O0FBS0E7QUFDQWIsU0FBU2UsYUFBVCxDQUF1QmQsbUJBQXZCO0FBQ0FELFNBQVNnQixlQUFULENBQXlCZCxxQkFBekI7QUFDQSxJQUFNZSxzQkFBc0IsbUJBQUFuVyxDQUFRLEVBQVIsQ0FBNUI7QUFDQSxJQUFNb1cscUJBQXFCLG1CQUFBcFcsQ0FBUSxFQUFSLENBQTNCO0FBQ0FrVixTQUFTUSxHQUFULENBQWEsY0FBYixFQUE2QlMsbUJBQTdCO0FBQ0FqQixTQUFTUSxHQUFULENBQWEsYUFBYixFQUE0QlUsa0JBQTVCO0FBQ0E7QUFDQVosSUFBSUUsR0FBSixDQUFRTCxjQUFjO0FBQ3BCOVgsUUFBUSxTQURZO0FBRXBCeUUsUUFBUSxDQUFDaEQsVUFBRCxDQUZZO0FBR3BCcVgsVUFBUSxLQUFLLEVBQUwsR0FBVSxFQUFWLEdBQWUsSUFISCxDQUdTO0FBSFQsQ0FBZCxDQUFSO0FBS0FiLElBQUlFLEdBQUosQ0FBUVIsU0FBUzNCLFVBQVQsRUFBUjtBQUNBaUMsSUFBSUUsR0FBSixDQUFRUixTQUFTb0IsT0FBVCxFQUFSOztBQUVBO0FBQ0EsSUFBTUMsTUFBTXZCLGtCQUFrQmxTLE1BQWxCLENBQXlCO0FBQ25DMFQsaUJBQWUsT0FEb0I7QUFFbkNDLGNBQWV4QjtBQUZvQixDQUF6QixDQUFaO0FBSUFPLElBQUlrQixNQUFKLENBQVcsWUFBWCxFQUF5QkgsSUFBSUcsTUFBN0I7QUFDQWxCLElBQUk1QixHQUFKLENBQVEsYUFBUixFQUF1QixZQUF2Qjs7QUFFQTtBQUNBLG1CQUFBNVQsQ0FBUSxFQUFSLEVBQW1Dd1YsR0FBbkM7QUFDQSxtQkFBQXhWLENBQVEsRUFBUixFQUFrQ3dWLEdBQWxDO0FBQ0EsbUJBQUF4VixDQUFRLEVBQVIsRUFBbUN3VixHQUFuQztBQUNBLG1CQUFBeFYsQ0FBUSxHQUFSLEVBQW9Dd1YsR0FBcEM7QUFDQSxtQkFBQXhWLENBQVEsR0FBUixFQUF1Q3dWLEdBQXZDOztBQUVBO0FBQ0EsSUFBTW1CLFNBQVNyQixLQUFLc0IsTUFBTCxDQUFZcEIsR0FBWixDQUFmOztBQUVBO0FBQ0EsSUFBTWpWLEtBQUssbUJBQUFQLENBQVEsQ0FBUixDQUFYO0FBQ0FPLEdBQUdDLFNBQUgsQ0FBYXFXLElBQWI7QUFDRTtBQURGLENBRUcxVixJQUZILENBRVEsWUFBTTtBQUNWd1YsU0FBT2hELE1BQVAsQ0FBYzRCLElBQWQsRUFBb0IsWUFBTTtBQUN4QnRWLFdBQU9tQixJQUFQLGtDQUEyQ21VLElBQTNDO0FBQ0QsR0FGRDtBQUdELENBTkgsRUFPR2xVLEtBUEgsQ0FPUyxVQUFDQyxLQUFELEVBQVc7QUFDaEJyQixTQUFPcUIsS0FBUCxtQkFBK0JBLEtBQS9CO0FBQ0QsQ0FUSCxFOzs7Ozs7QUN0RUEsb0M7Ozs7OztBQ0FBLHdDOzs7Ozs7QUNBQSwrQzs7Ozs7O0FDQUEsdUM7Ozs7OztBQ0FBLG1DOzs7Ozs7Ozs7QUNBQSxJQUFNckIsU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7O0FBRUFILE9BQU9DLE9BQVAsR0FBaUI7QUFDZnFWLHFCQURlLCtCQUNNMkIsSUFETixFQUNZQyxJQURaLEVBQ2tCO0FBQUc7QUFDbEM5VyxXQUFPMkMsS0FBUCxDQUFhLGtCQUFiO0FBQ0FtVSxTQUFLLElBQUwsRUFBV0QsSUFBWDtBQUNELEdBSmM7QUFLZjFCLHVCQUxlLGlDQUtRMEIsSUFMUixFQUtjQyxJQUxkLEVBS29CO0FBQUc7QUFDcEM5VyxXQUFPMkMsS0FBUCxDQUFhLG9CQUFiO0FBQ0FtVSxTQUFLLElBQUwsRUFBV0QsSUFBWDtBQUNEO0FBUmMsQ0FBakIsQzs7Ozs7O0FDRkEsMkM7Ozs7OztBQ0FBLGlDOzs7Ozs7Ozs7ZUNBcUIsbUJBQUE5VyxDQUFRLEVBQVIsQztJQUFiZ1gsUSxZQUFBQSxROztBQUVSblgsT0FBT0MsT0FBUCxHQUFpQixVQUFDbVgsT0FBRCxFQUFhO0FBQzVCO0FBQ0FBLFVBQVFDLFNBQVIsQ0FBa0I7QUFDaEJDLGdCQUFZLENBQ1YsSUFBS0YsUUFBUUUsVUFBUixDQUFtQkMsT0FBeEIsQ0FBaUM7QUFDL0JDLGFBQWlDTCxRQURGO0FBRS9CTSxpQkFBaUMsS0FGRjtBQUcvQkMsZ0JBQWlDLElBSEY7QUFJL0JDLG1CQUFpQyxJQUpGO0FBSy9CQyx3QkFBaUMsSUFMRjtBQU0vQkMsdUNBQWlDO0FBTkYsS0FBakMsQ0FEVTtBQURJLEdBQWxCO0FBWUE7QUFDQVQsVUFBUTNWLEtBQVIsQ0FBYyxTQUFkO0FBQ0EyVixVQUFRVSxJQUFSLENBQWEsU0FBYjtBQUNBVixVQUFRN1YsSUFBUixDQUFhLFNBQWI7QUFDQTZWLFVBQVFqQixPQUFSLENBQWdCLFNBQWhCO0FBQ0FpQixVQUFRclUsS0FBUixDQUFjLFNBQWQ7QUFDQXFVLFVBQVFXLEtBQVIsQ0FBYyxTQUFkO0FBQ0QsQ0FyQkQsQzs7Ozs7Ozs7O0FDRkEsSUFBTUMsZUFBZTtBQUNuQmIsWUFBVSxPQURTLENBQ0M7QUFERCxDQUFyQjs7QUFJQW5YLE9BQU9DLE9BQVAsR0FBaUIrWCxZQUFqQixDOzs7Ozs7Ozs7QUNKQSxJQUFNQyxzQkFBc0IsbUJBQUE5WCxDQUFRLEVBQVIsRUFBaUMrWCxZQUE3RDtBQUNBLElBQU1DLGNBQWMsbUJBQUFoWSxDQUFRLEVBQVIsQ0FBcEI7O0FBRUFILE9BQU9DLE9BQVAsR0FBaUIsVUFBQ21YLE9BQUQsRUFBYTtBQUFBLE1BQ3JCZ0IsWUFEcUIsR0FDZ0NELFdBRGhDLENBQ3JCQyxZQURxQjtBQUFBLE1BQ1BDLGlCQURPLEdBQ2dDRixXQURoQyxDQUNQRSxpQkFETztBQUFBLE1BQ1lDLGdCQURaLEdBQ2dDSCxXQURoQyxDQUNZRyxnQkFEWjs7QUFFNUIsTUFBSUYsWUFBSixFQUFrQjtBQUNoQjtBQUNBLFFBQUlDLGlCQUFKLEVBQXVCO0FBQ3JCakIsY0FBUW1CLEdBQVIsQ0FBWU4sbUJBQVosRUFBaUM7QUFDL0J2YSxjQUFZLHdCQURtQjtBQUUvQjhaLGVBQVksTUFGbUI7QUFHL0JnQixvQkFBWUosWUFIbUI7QUFJL0J0YSxpQkFBWXVhLGlCQUptQjtBQUsvQjdYLGtCQUFZLFNBTG1CO0FBTS9CaVksbUJBQVk7QUFObUIsT0FBakM7QUFRRDtBQUNELFFBQUlILGdCQUFKLEVBQXNCO0FBQ3BCbEIsY0FBUW1CLEdBQVIsQ0FBWU4sbUJBQVosRUFBaUM7QUFDL0J2YSxjQUFZLHNCQURtQjtBQUUvQjhaLGVBQVksTUFGbUI7QUFHL0JnQixvQkFBWUosWUFIbUI7QUFJL0J0YSxpQkFBWXdhLGdCQUptQjtBQUsvQjlYLGtCQUFZLFNBTG1CO0FBTS9CaVksbUJBQVk7QUFObUIsT0FBakM7QUFRRDtBQUNEO0FBQ0FyQixZQUFRM1YsS0FBUixDQUFjLGtDQUFkO0FBQ0EyVixZQUFRN1YsSUFBUixDQUFhLGlDQUFiO0FBQ0QsR0F6QkQsTUF5Qk87QUFDTDZWLFlBQVFVLElBQVIsQ0FBYSwyRUFBYjtBQUNEO0FBQ0YsQ0E5QkQsQzs7Ozs7O0FDSEEsa0Q7Ozs7Ozs7OztBQ0FBLFNBQVNZLFdBQVQsR0FBd0I7QUFDdEIsT0FBS04sWUFBTCxHQUF5QixTQUF6QjtBQUNBLE9BQUtDLGlCQUFMLEdBQXlCLFNBQXpCO0FBQ0EsT0FBS0MsZ0JBQUwsR0FBeUIsU0FBekI7QUFDRDs7QUFFRHRZLE9BQU9DLE9BQVAsR0FBaUIsSUFBSXlZLFdBQUosRUFBakIsQzs7Ozs7Ozs7Ozs7QUNOQSxJQUFNQyx3QkFBd0IsbUJBQUF4WSxDQUFRLEVBQVIsRUFBMEJ5WSxRQUF4RDtBQUNBLElBQU1DLFVBQVUsbUJBQUExWSxDQUFRLEVBQVIsQ0FBaEI7QUFDQSxJQUFNQyxTQUFTLG1CQUFBRCxDQUFRLENBQVIsQ0FBZjtBQUNBLElBQU1PLEtBQUssbUJBQUFQLENBQVEsQ0FBUixDQUFYOztBQUVBSCxPQUFPQyxPQUFQLEdBQWlCLElBQUkwWSxxQkFBSixDQUNmO0FBQ0VHLGlCQUFlLFVBRGpCO0FBRUVDLGlCQUFlO0FBRmpCLENBRGUsRUFLZixVQUFDdlksUUFBRCxFQUFXQyxRQUFYLEVBQXFCeVcsSUFBckIsRUFBOEI7QUFDNUI5VyxTQUFPK1YsT0FBUCx3Q0FBb0QzVixRQUFwRCxlQUFzRUMsUUFBdEU7QUFDQSxNQUFJdVksV0FBVyxFQUFmO0FBQ0E7O0FBRUE7QUFDQSxTQUFPSCxRQUFRblAsYUFBUixPQUEwQmxKLFFBQTFCLEVBQ0pjLElBREksQ0FDQyxjQUFNO0FBQ1Y7QUFDQSxRQUFNMlgsV0FBVztBQUNmQyxnQkFBVTFZLFFBREs7QUFFZkMsZ0JBQVVBO0FBRkssS0FBakI7QUFJQUwsV0FBTytWLE9BQVAsQ0FBZSxZQUFmLEVBQTZCOEMsUUFBN0I7QUFDQTtBQUNBLFFBQU1FLGNBQWM7QUFDbEIvYSx5QkFBb0JvQyxRQURGO0FBRWxCK1Esc0JBQWdCNkgsR0FBR0M7QUFGRCxLQUFwQjtBQUlBalosV0FBTytWLE9BQVAsQ0FBZSxlQUFmLEVBQWdDZ0QsV0FBaEM7QUFDQTtBQUNBLFFBQU1HLGtCQUFrQjtBQUN0QjdULGVBQVMyVCxHQUFHQyxRQURVO0FBRXRCM2Isa0JBQWE4QztBQUNiO0FBSHNCLEtBQXhCO0FBS0FKLFdBQU8rVixPQUFQLENBQWUsbUJBQWYsRUFBb0NtRCxlQUFwQztBQUNBO0FBQ0EsV0FBT2pTLFFBQVFDLEdBQVIsQ0FBWSxDQUFDNUcsR0FBR3NCLElBQUgsQ0FBUWlCLE1BQVIsQ0FBZWdXLFFBQWYsQ0FBRCxFQUEyQnZZLEdBQUdrQixPQUFILENBQVdxQixNQUFYLENBQWtCa1csV0FBbEIsQ0FBM0IsRUFBMkR6WSxHQUFHaUIsV0FBSCxDQUFlc0IsTUFBZixDQUFzQnFXLGVBQXRCLENBQTNELENBQVosQ0FBUDtBQUNELEdBdkJJLEVBd0JKaFksSUF4QkksQ0F3QkMsZ0JBQTJDO0FBQUE7QUFBQSxRQUF6Q2lZLE9BQXlDO0FBQUEsUUFBaENDLFVBQWdDO0FBQUEsUUFBcEJDLGNBQW9COztBQUMvQ3JaLFdBQU8rVixPQUFQLENBQWUsMkNBQWY7QUFDQTtBQUNBNkMsYUFBUyxJQUFULElBQWlCTyxRQUFRclUsRUFBekI7QUFDQThULGFBQVMsVUFBVCxJQUF1Qk8sUUFBUUwsUUFBL0I7QUFDQUYsYUFBUyxhQUFULElBQTBCUSxXQUFXcGIsV0FBckM7QUFDQTRhLGFBQVMsZ0JBQVQsSUFBNkJRLFdBQVdqSSxjQUF4QztBQUNBO0FBQ0EsV0FBT2xLLFFBQVFDLEdBQVIsQ0FBWSxDQUFDbVMsZUFBZUMsVUFBZixDQUEwQkYsVUFBMUIsQ0FBRCxFQUF3Q0EsV0FBV0csT0FBWCxDQUFtQkosT0FBbkIsQ0FBeEMsQ0FBWixDQUFQO0FBQ0QsR0FqQ0ksRUFrQ0pqWSxJQWxDSSxDQWtDQyxZQUFNO0FBQ1ZsQixXQUFPK1YsT0FBUCxDQUFlLDhDQUFmO0FBQ0EsV0FBT3pWLEdBQUdpQixXQUFILENBQWVzUSxrQ0FBZixDQUFrRCtHLFNBQVN6SCxjQUEzRCxFQUEyRXlILFNBQVM1YSxXQUFwRixDQUFQO0FBQ0QsR0FyQ0ksRUFzQ0prRCxJQXRDSSxDQXNDQywwQkFBa0I7QUFDdEIwWCxhQUFTLGdCQUFULElBQTZCWSxjQUE3QjtBQUNBLFdBQU8xQyxLQUFLLElBQUwsRUFBVzhCLFFBQVgsQ0FBUDtBQUNELEdBekNJLEVBMENKeFgsS0ExQ0ksQ0EwQ0UsaUJBQVM7QUFDZHBCLFdBQU9xQixLQUFQLENBQWEsY0FBYixFQUE2QkEsS0FBN0I7QUFDQSxXQUFPeVYsS0FBS3pWLEtBQUwsQ0FBUDtBQUNELEdBN0NJLENBQVA7QUE4Q0QsQ0F6RGMsQ0FBakIsQzs7Ozs7O0FDTEEsa0M7Ozs7Ozs7OztBQ0FBLElBQU1vWSxhQUFhO0FBQ2pCOVIsT0FBSztBQUNIQyxhQUFTLFdBRE47QUFFSEMsYUFBUztBQUZOO0FBRFksQ0FBbkI7O0FBT0FqSSxPQUFPQyxPQUFQLEdBQWlCNFosVUFBakIsQzs7Ozs7O0FDUEEsZ0Q7Ozs7Ozs7OztBQ0FBLFNBQVNDLFdBQVQsR0FBd0I7QUFDdEIsT0FBS3ZaLFFBQUwsR0FBZ0IsU0FBaEI7QUFDQSxPQUFLQyxRQUFMLEdBQWdCLFNBQWhCO0FBQ0EsT0FBS0MsUUFBTCxHQUFnQixTQUFoQjtBQUNEOztBQUVEVCxPQUFPQyxPQUFQLEdBQWlCLElBQUk2WixXQUFKLEVBQWpCLEM7Ozs7Ozs7OztBQ05BLElBQU0xWixTQUFTLG1CQUFBRCxDQUFRLENBQVIsQ0FBZjs7ZUFDMEIsbUJBQUFBLENBQVEsRUFBUixDO0lBQWxCc04sYSxZQUFBQSxhOztBQUVSek4sT0FBT0MsT0FBUCxHQUFpQixVQUFDVSxTQUFELFFBQTREO0FBQUEsTUFBOUNvWixNQUE4QyxRQUE5Q0EsTUFBOEM7QUFBQSxNQUF0Q0MsT0FBc0MsUUFBdENBLE9BQXNDO0FBQUEsTUFBN0JDLE9BQTZCLFFBQTdCQSxPQUE2QjtBQUFBLE1BQXBCQyxJQUFvQixRQUFwQkEsSUFBb0I7QUFBQSxNQUFkQyxPQUFjLFFBQWRBLE9BQWM7O0FBQzNFLE1BQU14WSxjQUFjaEIsVUFBVXlaLE1BQVYsQ0FDbEIsYUFEa0IsRUFFbEI7QUFDRTdKLGFBQVM7QUFDUGpULFlBQVN5YyxNQURGO0FBRVBNLGVBQVM7QUFGRixLQURYO0FBS0V6USxZQUFRO0FBQ050TSxZQUFTNmMsUUFBUSxFQUFSLEVBQVksQ0FBWixDQURIO0FBRU5FLGVBQVM7QUFGSCxLQUxWO0FBU0U1VSxhQUFTO0FBQ1BuSSxZQUFTeWMsTUFERjtBQUVQTSxlQUFTO0FBRkYsS0FUWDtBQWFFQyxtQkFBZTtBQUNiaGQsWUFBUzJjLE9BREk7QUFFYkksZUFBUztBQUZJLEtBYmpCO0FBaUJFRSxrQkFBYztBQUNaamQsWUFBUzBjLE9BREc7QUFFWkssZUFBUztBQUZHLEtBakJoQjtBQXFCRUcsV0FBTztBQUNMbGQsWUFBUzJjLE9BREo7QUFFTEksZUFBUztBQUZKLEtBckJUO0FBeUJFSSxxQkFBaUI7QUFDZm5kLFlBQVM2YyxRQUFRLEVBQVIsRUFBWSxDQUFaLENBRE07QUFFZkUsZUFBUztBQUZNLEtBekJuQjtBQTZCRUssa0JBQWM7QUFDWnBkLFlBQVMwYyxPQURHO0FBRVpLLGVBQVM7QUFGRyxLQTdCaEI7QUFpQ0UvSixZQUFRO0FBQ05oVCxZQUFTMmMsT0FESDtBQUVOSSxlQUFTO0FBRkgsS0FqQ1Y7QUFxQ0VNLFNBQUs7QUFDSHJkLFlBQVM0YyxLQUFLLE1BQUwsQ0FETjtBQUVIRyxlQUFTO0FBRk4sS0FyQ1A7QUF5Q0UzYyxVQUFNO0FBQ0pKLFlBQVN5YyxNQURMO0FBRUpNLGVBQVM7QUFGTCxLQXpDUjtBQTZDRU8sVUFBTTtBQUNKdGQsWUFBUzJjLE9BREw7QUFFSkksZUFBUztBQUZMLEtBN0NSO0FBaURFUSxVQUFNO0FBQ0p2ZCxZQUFTeWMsTUFETDtBQUVKTSxlQUFTO0FBRkwsS0FqRFI7QUFxREVTLG1CQUFlO0FBQ2J4ZCxZQUFTMmMsT0FESTtBQUViSSxlQUFTO0FBRkksS0FyRGpCO0FBeURFaEssY0FBVTtBQUNSL1MsWUFBU3ljLE1BREQ7QUFFUk0sZUFBUztBQUZELEtBekRaO0FBNkRFVSxrQkFBYztBQUNaemQsWUFBU3ljLE1BREc7QUFFWk0sZUFBUztBQUZHLEtBN0RoQjtBQWlFRVcsZUFBVztBQUNUMWQsWUFBU3ljLE1BREE7QUFFVE0sZUFBUztBQUZBLEtBakViO0FBcUVFWSx3QkFBb0I7QUFDbEIzZCxZQUFTeWMsTUFEUztBQUVsQk0sZUFBUztBQUZTLEtBckV0QjtBQXlFRWEsYUFBUztBQUNQNWQsWUFBU3ljLE1BREY7QUFFUE0sZUFBUztBQUZGLEtBekVYO0FBNkVFYyxlQUFXO0FBQ1Q3ZCxZQUFTNGMsS0FBSyxNQUFMLENBREE7QUFFVEcsZUFBUztBQUZBO0FBN0ViLEdBRmtCLEVBb0ZsQjtBQUNFZSxxQkFBaUI7QUFEbkIsR0FwRmtCLENBQXBCOztBQXlGQXpaLGNBQVlXLFNBQVosR0FBd0IsY0FBTTtBQUM1QlgsZ0JBQVkwWixTQUFaLENBQXNCM2EsR0FBR2tCLE9BQXpCLEVBQWtDO0FBQ2hDMFosa0JBQVk7QUFDVkMsbUJBQVc7QUFERDtBQURvQixLQUFsQztBQUtELEdBTkQ7O0FBUUE1WixjQUFZc1Esa0NBQVosR0FBaUQsVUFBVUosYUFBVixFQUF5QnpULFdBQXpCLEVBQXNDO0FBQUE7O0FBQ3JGZ0MsV0FBTzJDLEtBQVAseUNBQW1EM0UsV0FBbkQsU0FBa0V5VCxhQUFsRTtBQUNBLFdBQU8sSUFBSXhLLE9BQUosQ0FBWSxVQUFDaUIsT0FBRCxFQUFVQyxNQUFWLEVBQXFCO0FBQ3RDLFlBQ0dpVCxPQURILENBQ1c7QUFDUDNZLGVBQU8sRUFBQ25GLE1BQU1VLFdBQVAsRUFEQTtBQUVQcWQsZUFBTyxDQUFDLENBQUMsUUFBRCxFQUFXLEtBQVgsQ0FBRDtBQUZBLE9BRFgsRUFLR25hLElBTEgsQ0FLUSxrQkFBVTtBQUNkLGdCQUFRa0gsT0FBTzBGLE1BQWY7QUFDRSxlQUFLLENBQUw7QUFDRSxrQkFBTSxJQUFJakgsS0FBSixDQUFVLDRDQUFWLENBQU47QUFDRjtBQUNFLG1CQUFPcUIsUUFBUW1GLGNBQWNqRixNQUFkLEVBQXNCcUosYUFBdEIsQ0FBUixDQUFQO0FBSko7QUFNRCxPQVpILEVBYUdyUSxLQWJILENBYVMsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FmSDtBQWdCRCxLQWpCTSxDQUFQO0FBa0JELEdBcEJEOztBQXNCQUUsY0FBWStaLGtDQUFaLEdBQWlELFVBQVV0ZCxXQUFWLEVBQXVCbVQsY0FBdkIsRUFBdUM7QUFBQTs7QUFDdEZuUixXQUFPMkMsS0FBUCx5Q0FBbUQzRSxXQUFuRCxVQUFtRW1ULGNBQW5FO0FBQ0EsV0FBTyxJQUFJbEssT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdEMsYUFDR2lULE9BREgsQ0FDVztBQUNQM1ksZUFBTztBQUNMbkYsZ0JBQVNVLFdBREo7QUFFTHFILG1CQUFTO0FBQ1BrVyxtQkFBVXBLLGNBQVY7QUFETztBQUZKLFNBREE7QUFPUGtLLGVBQU8sQ0FBQyxDQUFDLFFBQUQsRUFBVyxLQUFYLENBQUQ7QUFQQSxPQURYLEVBVUduYSxJQVZILENBVVEsa0JBQVU7QUFDZCxnQkFBUWtILE9BQU8wRixNQUFmO0FBQ0UsZUFBSyxDQUFMO0FBQ0UsbUJBQU81RixRQUFRLElBQVIsQ0FBUDtBQUNGO0FBQVM7QUFDUCxtQkFBT0EsUUFBUUUsT0FBTyxDQUFQLEVBQVUvQyxPQUFsQixDQUFQO0FBSko7QUFNRCxPQWpCSCxFQWtCR2pFLEtBbEJILENBa0JTLGlCQUFTO0FBQ2QrRyxlQUFPOUcsS0FBUDtBQUNELE9BcEJIO0FBcUJELEtBdEJNLENBQVA7QUF1QkQsR0F6QkQ7O0FBMkJBRSxjQUFZaWEsK0JBQVosR0FBOEMsVUFBVXhkLFdBQVYsRUFBdUI7QUFBQTs7QUFDbkVnQyxXQUFPMkMsS0FBUCxzQ0FBZ0QzRSxXQUFoRDtBQUNBLFdBQU8sSUFBSWlKLE9BQUosQ0FBWSxVQUFDaUIsT0FBRCxFQUFVQyxNQUFWLEVBQXFCO0FBQ3RDLGFBQ0dpVCxPQURILENBQ1c7QUFDUDNZLGVBQU8sRUFBRW5GLE1BQU1VLFdBQVIsRUFEQTtBQUVQcWQsZUFBTyxDQUFDLENBQUMsaUJBQUQsRUFBb0IsTUFBcEIsQ0FBRCxFQUE4QixDQUFDLFFBQUQsRUFBVyxLQUFYLENBQTlCO0FBRkEsT0FEWCxFQUtHbmEsSUFMSCxDQUtRLGtCQUFVO0FBQ2QsZ0JBQVFrSCxPQUFPMEYsTUFBZjtBQUNFLGVBQUssQ0FBTDtBQUNFLG1CQUFPNUYsUUFBUSxJQUFSLENBQVA7QUFDRjtBQUNFLG1CQUFPQSxRQUFRRSxPQUFPLENBQVAsRUFBVS9DLE9BQWxCLENBQVA7QUFKSjtBQU1ELE9BWkgsRUFhR2pFLEtBYkgsQ0FhUyxpQkFBUztBQUNkK0csZUFBTzlHLEtBQVA7QUFDRCxPQWZIO0FBZ0JELEtBakJNLENBQVA7QUFrQkQsR0FwQkQ7O0FBc0JBRSxjQUFZa2EscUJBQVosR0FBb0MsVUFBVW5lLElBQVYsRUFBZ0IrSCxPQUFoQixFQUF5QjtBQUFBOztBQUMzRHJGLFdBQU8yQyxLQUFQLDRCQUFzQ3JGLElBQXRDLFVBQStDK0gsT0FBL0M7QUFDQSxXQUFPLElBQUk0QixPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QyxhQUFLM0YsT0FBTCxDQUFhO0FBQ1hDLGVBQU8sRUFBQ25GLFVBQUQsRUFBTytILGdCQUFQO0FBREksT0FBYixFQUdHbkUsSUFISCxDQUdRLGtCQUFVO0FBQ2QsWUFBSSxDQUFDa0gsTUFBTCxFQUFhO0FBQ1gsaUJBQU9GLFFBQVEsSUFBUixDQUFQO0FBQ0Q7QUFDREEsZ0JBQVE3QyxPQUFSO0FBQ0QsT0FSSCxFQVNHakUsS0FUSCxDQVNTLGlCQUFTO0FBQ2QrRyxlQUFPOUcsS0FBUDtBQUNELE9BWEg7QUFZRCxLQWJNLENBQVA7QUFjRCxHQWhCRDs7QUFrQkFFLGNBQVlpUSxnQkFBWixHQUErQixVQUFVeFQsV0FBVixFQUF1Qm1ULGNBQXZCLEVBQXVDO0FBQ3BFblIsV0FBTzJDLEtBQVAsdUJBQWlDM0UsV0FBakMsVUFBaURtVCxjQUFqRDtBQUNBLFFBQUlBLGtCQUFtQkEsZUFBZXJELE1BQWYsS0FBMEIsRUFBakQsRUFBc0Q7QUFBRztBQUN2RCxhQUFPLEtBQUsyTixxQkFBTCxDQUEyQnpkLFdBQTNCLEVBQXdDbVQsY0FBeEMsQ0FBUDtBQUNELEtBRkQsTUFFTyxJQUFJQSxrQkFBa0JBLGVBQWVyRCxNQUFmLEdBQXdCLEVBQTlDLEVBQWtEO0FBQUc7QUFDMUQsYUFBTyxLQUFLd04sa0NBQUwsQ0FBd0N0ZCxXQUF4QyxFQUFxRG1ULGNBQXJELENBQVA7QUFDRCxLQUZNLE1BRUE7QUFDTCxhQUFPLEtBQUtxSywrQkFBTCxDQUFxQ3hkLFdBQXJDLENBQVAsQ0FESyxDQUNzRDtBQUM1RDtBQUNGLEdBVEQ7O0FBV0EsU0FBT3VELFdBQVA7QUFDRCxDQXZNRCxDOzs7Ozs7Ozs7QUNIQTNCLE9BQU9DLE9BQVAsR0FBaUIsVUFBQ1UsU0FBRCxRQUEyQjtBQUFBLE1BQWJvWixNQUFhLFFBQWJBLE1BQWE7O0FBQzFDLE1BQU1uWSxVQUFVakIsVUFBVXlaLE1BQVYsQ0FDZCxTQURjLEVBRWQ7QUFDRWhjLGlCQUFhO0FBQ1hkLFlBQVd5YyxNQURBO0FBRVh3QixpQkFBVztBQUZBLEtBRGY7QUFLRWhLLG9CQUFnQjtBQUNkalUsWUFBV3ljLE1BREc7QUFFZHdCLGlCQUFXO0FBRkc7QUFMbEIsR0FGYyxFQVlkO0FBQ0VILHFCQUFpQjtBQURuQixHQVpjLENBQWhCOztBQWlCQXhaLFVBQVFVLFNBQVIsR0FBb0IsY0FBTTtBQUN4QlYsWUFBUXlaLFNBQVIsQ0FBa0IzYSxHQUFHc0IsSUFBckI7QUFDQUosWUFBUWthLE1BQVIsQ0FBZXBiLEdBQUdpQixXQUFsQjtBQUNELEdBSEQ7O0FBS0EsU0FBT0MsT0FBUDtBQUNELENBeEJELEM7Ozs7Ozs7OztBQ0FBLElBQU14QixTQUFTLG1CQUFBRCxDQUFRLENBQVIsQ0FBZjs7ZUFDMEIsbUJBQUFBLENBQVEsRUFBUixDO0lBQWxCc04sYSxZQUFBQSxhOztnQkFDc0UsbUJBQUF0TixDQUFRLENBQVIsQztJQUExQ29HLGdCLGFBQTVCekgsYSxDQUFpQkUsUztJQUEwQ0ssSSxhQUFYRCxPLENBQVdDLEk7O0FBRW5FLFNBQVMwYyxxQ0FBVCxDQUFnRHZMLFdBQWhELEVBQTZEO0FBQzNELFVBQVFBLFdBQVI7QUFDRSxTQUFLLFlBQUw7QUFDQSxTQUFLLFdBQUw7QUFDRSxhQUFPLE1BQVA7QUFDRixTQUFLLFdBQUw7QUFDRSxhQUFPLEtBQVA7QUFDRixTQUFLLFdBQUw7QUFDRSxhQUFPLEtBQVA7QUFDRixTQUFLLFdBQUw7QUFDRSxhQUFPLEtBQVA7QUFDRjtBQUNFcFEsYUFBTzJDLEtBQVAsQ0FBYSxrREFBYjtBQUNBLGFBQU8sTUFBUDtBQVpKO0FBY0Q7O0FBRUQsU0FBU2laLGtCQUFULENBQTZCQyxlQUE3QixFQUE4QzFWLGdCQUE5QyxFQUFnRTtBQUM5RCxNQUFJMFYsb0JBQW9CLEVBQXhCLEVBQTRCO0FBQzFCLFdBQU8xVixnQkFBUDtBQUNEO0FBQ0QsU0FBTzBWLGVBQVA7QUFDRDs7QUFFRCxTQUFTQyxnQkFBVCxDQUEyQkMsS0FBM0IsRUFBa0M7QUFDaEM7QUFDQUEsUUFBTSxXQUFOLElBQXFCSCxtQkFBbUJHLE1BQU1uZCxTQUF6QixFQUFvQ3VILGdCQUFwQyxDQUFyQjtBQUNBNFYsUUFBTSxTQUFOLElBQW1CSixzQ0FBc0NJLE1BQU0zTCxXQUE1QyxDQUFuQjtBQUNBMkwsUUFBTSxNQUFOLElBQWdCOWMsSUFBaEI7QUFDQSxTQUFPOGMsS0FBUDtBQUNEOztBQUVEbmMsT0FBT0MsT0FBUCxHQUFpQixVQUFDVSxTQUFELFFBQTREO0FBQUEsTUFBOUNvWixNQUE4QyxRQUE5Q0EsTUFBOEM7QUFBQSxNQUF0Q0MsT0FBc0MsUUFBdENBLE9BQXNDO0FBQUEsTUFBN0JDLE9BQTZCLFFBQTdCQSxPQUE2QjtBQUFBLE1BQXBCQyxJQUFvQixRQUFwQkEsSUFBb0I7QUFBQSxNQUFkQyxPQUFjLFFBQWRBLE9BQWM7O0FBQzNFLE1BQU10WSxRQUFRbEIsVUFBVXlaLE1BQVYsQ0FDWixPQURZLEVBRVo7QUFDRTdKLGFBQVM7QUFDUGpULFlBQVN5YyxNQURGO0FBRVBNLGVBQVM7QUFGRixLQURYO0FBS0V6USxZQUFRO0FBQ050TSxZQUFTNmMsUUFBUSxFQUFSLEVBQVksQ0FBWixDQURIO0FBRU5FLGVBQVM7QUFGSCxLQUxWO0FBU0U1VSxhQUFTO0FBQ1BuSSxZQUFTeWMsTUFERjtBQUVQTSxlQUFTO0FBRkYsS0FUWDtBQWFFQyxtQkFBZTtBQUNiaGQsWUFBUzJjLE9BREk7QUFFYkksZUFBUztBQUZJLEtBYmpCO0FBaUJFRSxrQkFBYztBQUNaamQsWUFBUzBjLE9BREc7QUFFWkssZUFBUztBQUZHLEtBakJoQjtBQXFCRUcsV0FBTztBQUNMbGQsWUFBUzJjLE9BREo7QUFFTEksZUFBUztBQUZKLEtBckJUO0FBeUJFSSxxQkFBaUI7QUFDZm5kLFlBQVM2YyxRQUFRLEVBQVIsRUFBWSxDQUFaLENBRE07QUFFZkUsZUFBUztBQUZNLEtBekJuQjtBQTZCRUssa0JBQWM7QUFDWnBkLFlBQVMwYyxPQURHO0FBRVpLLGVBQVM7QUFGRyxLQTdCaEI7QUFpQ0UvSixZQUFRO0FBQ05oVCxZQUFTMmMsT0FESDtBQUVOSSxlQUFTO0FBRkgsS0FqQ1Y7QUFxQ0VNLFNBQUs7QUFDSHJkLFlBQVM0YyxLQUFLLE1BQUwsQ0FETjtBQUVIRyxlQUFTO0FBRk4sS0FyQ1A7QUF5Q0UzYyxVQUFNO0FBQ0pKLFlBQVN5YyxNQURMO0FBRUpNLGVBQVM7QUFGTCxLQXpDUjtBQTZDRU8sVUFBTTtBQUNKdGQsWUFBUzJjLE9BREw7QUFFSkksZUFBUztBQUZMLEtBN0NSO0FBaURFUSxVQUFNO0FBQ0p2ZCxZQUFTeWMsTUFETDtBQUVKTSxlQUFTO0FBRkwsS0FqRFI7QUFxREVTLG1CQUFlO0FBQ2J4ZCxZQUFTMmMsT0FESTtBQUViSSxlQUFTO0FBRkksS0FyRGpCO0FBeURFaEssY0FBVTtBQUNSL1MsWUFBU3ljLE1BREQ7QUFFUk0sZUFBUztBQUZELEtBekRaO0FBNkRFVyxlQUFXO0FBQ1QxZCxZQUFTeWMsTUFEQTtBQUVUTSxlQUFTO0FBRkEsS0E3RGI7QUFpRUUrQixtQkFBZTtBQUNiOWUsWUFBU3ljLE1BREk7QUFFYk0sZUFBUztBQUZJLEtBakVqQjtBQXFFRTVLLFlBQVE7QUFDTm5TLFlBQVN5YyxNQURIO0FBRU5NLGVBQVM7QUFGSCxLQXJFVjtBQXlFRXRiLGlCQUFhO0FBQ1h6QixZQUFTNGMsS0FBSyxNQUFMLENBREU7QUFFWEcsZUFBUztBQUZFLEtBekVmO0FBNkVFM0ssY0FBVTtBQUNScFMsWUFBU3ljLE1BREQ7QUFFUk0sZUFBUztBQUZELEtBN0VaO0FBaUZFOUwsYUFBUztBQUNQalIsWUFBU3ljLE1BREY7QUFFUE0sZUFBUztBQUZGLEtBakZYO0FBcUZFZ0MsZ0JBQVk7QUFDVi9lLFlBQVN5YyxNQURDO0FBRVZNLGVBQVM7QUFGQyxLQXJGZDtBQXlGRS9MLFVBQU07QUFDSmhSLFlBQVMwYyxPQURMO0FBRUpLLGVBQVM7QUFGTCxLQXpGUjtBQTZGRWlDLGFBQVM7QUFDUGhmLFlBQVN5YyxNQURGO0FBRVBNLGVBQVM7QUFGRixLQTdGWDtBQWlHRXJiLGVBQVc7QUFDVDFCLFlBQVN5YyxNQURBO0FBRVRNLGVBQVM7QUFGQSxLQWpHYjtBQXFHRXBiLFdBQU87QUFDTDNCLFlBQVN5YyxNQURKO0FBRUxNLGVBQVM7QUFGSixLQXJHVDtBQXlHRWtDLHFCQUFpQjtBQUNmamYsWUFBU3ljLE1BRE07QUFFZk0sZUFBUztBQUZNLEtBekduQjtBQTZHRTdKLGlCQUFhO0FBQ1hsVCxZQUFTeWMsTUFERTtBQUVYTSxlQUFTO0FBRkUsS0E3R2Y7QUFpSEVtQyxZQUFRO0FBQ05sZixZQUFTeWMsTUFESDtBQUVOTSxlQUFTO0FBRkgsS0FqSFY7QUFxSEVvQyxnQkFBWTtBQUNWbmYsWUFBU3ljLE1BREM7QUFFVk0sZUFBUztBQUZDLEtBckhkO0FBeUhFcUMsbUJBQWU7QUFDYnBmLFlBQVN5YyxNQURJO0FBRWJNLGVBQVM7QUFGSSxLQXpIakI7QUE2SEVzQyxtQkFBZTtBQUNicmYsWUFBU3ljLE1BREk7QUFFYk0sZUFBUztBQUZJLEtBN0hqQjtBQWlJRVUsa0JBQWM7QUFDWnpkLFlBQVN5YyxNQURHO0FBRVpNLGVBQVM7QUFGRyxLQWpJaEI7QUFxSUVqYyxpQkFBYTtBQUNYZCxZQUFXeWMsTUFEQTtBQUVYd0IsaUJBQVcsSUFGQTtBQUdYbEIsZUFBVztBQUhBO0FBcklmLEdBRlksRUE2SVo7QUFDRWUscUJBQWlCO0FBRG5CLEdBN0lZLENBQWQ7O0FBa0pBdlosUUFBTVMsU0FBTixHQUFrQixjQUFNO0FBQ3RCVCxVQUFNd1osU0FBTixDQUFnQjNhLEdBQUdvQixJQUFuQixFQUF5QjtBQUN2QndaLGtCQUFZO0FBQ1ZDLG1CQUFXO0FBREQ7QUFEVyxLQUF6QjtBQUtELEdBTkQ7O0FBUUExWixRQUFNK2EsOEJBQU4sR0FBdUMsVUFBVW5YLE9BQVYsRUFBbUI2RCxTQUFuQixFQUE4QjtBQUFBOztBQUNuRWxKLFdBQU8yQyxLQUFQLCtDQUF5RHVHLFNBQXpELFNBQXNFN0QsT0FBdEU7QUFDQSxXQUFPLElBQUk0QixPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QyxZQUNHaVQsT0FESCxDQUNXO0FBQ1AzWSxlQUFPLEVBQUVuRixNQUFNNEwsU0FBUixFQURBO0FBRVBtUyxlQUFPLENBQUMsQ0FBQyxRQUFELEVBQVcsS0FBWCxDQUFEO0FBRkEsT0FEWCxFQUtHbmEsSUFMSCxDQUtRLGtCQUFVO0FBQ2QsZ0JBQVFrSCxPQUFPMEYsTUFBZjtBQUNFLGVBQUssQ0FBTDtBQUNFLGtCQUFNLElBQUlqSCxLQUFKLENBQVUsd0NBQVYsQ0FBTjtBQUNGO0FBQ0VxQixvQkFBUW1GLGNBQWNqRixNQUFkLEVBQXNCL0MsT0FBdEIsQ0FBUjtBQUpKO0FBTUQsT0FaSCxFQWFHakUsS0FiSCxDQWFTLGlCQUFTO0FBQ2QrRyxlQUFPOUcsS0FBUDtBQUNELE9BZkg7QUFnQkQsS0FqQk0sQ0FBUDtBQWtCRCxHQXBCRDs7QUFzQkFJLFFBQU11USxtQkFBTixHQUE0QixVQUFVYixjQUFWLEVBQTBCO0FBQUE7O0FBQ3BEblIsV0FBTzJDLEtBQVAsb0NBQThDd08sY0FBOUM7QUFDQSxXQUFPLElBQUlsSyxPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QyxhQUNHaVQsT0FESCxDQUNXO0FBQ1AzWSxlQUFPLEVBQUV1WixlQUFlN0ssY0FBakIsRUFEQTtBQUVQa0ssZUFBTyxDQUFDLENBQUMsUUFBRCxFQUFXLEtBQVgsQ0FBRCxDQUZBO0FBR1BvQixhQUFPLElBSEEsQ0FHTztBQUhQLE9BRFgsRUFNR3ZiLElBTkgsQ0FNUSw4QkFBc0I7QUFDMUI7QUFDQSxnQkFBUStRLG1CQUFtQm5FLE1BQTNCO0FBQ0UsZUFBSyxDQUFMO0FBQ0UsbUJBQU81RixRQUFRLElBQVIsQ0FBUDtBQUNGO0FBQ0UrSiwrQkFBbUJqUSxPQUFuQixDQUEyQixpQkFBUztBQUNsQytaLG9CQUFNLFNBQU4sSUFBbUJKLHNDQUFzQ0ksTUFBTTNMLFdBQTVDLENBQW5CO0FBQ0EyTCxvQkFBTSxXQUFOLElBQXFCSCxtQkFBbUJHLE1BQU1uZCxTQUF6QixFQUFvQ3VILGdCQUFwQyxDQUFyQjtBQUNBLHFCQUFPNFYsS0FBUDtBQUNELGFBSkQ7QUFLQSxtQkFBTzdULFFBQVErSixrQkFBUixDQUFQO0FBVEo7QUFXRCxPQW5CSCxFQW9CRzdRLEtBcEJILENBb0JTLGlCQUFTO0FBQ2QrRyxlQUFPOUcsS0FBUDtBQUNELE9BdEJIO0FBdUJELEtBeEJNLENBQVA7QUF5QkQsR0EzQkQ7O0FBNkJBSSxRQUFNaVEseUJBQU4sR0FBa0MsVUFBVVAsY0FBVixFQUEwQmpJLFNBQTFCLEVBQXFDO0FBQUE7O0FBQ3JFbEosV0FBTzJDLEtBQVAsaUNBQTJDdUcsU0FBM0Msc0JBQXFFaUksY0FBckU7QUFDQSxXQUFPLElBQUlsSyxPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QyxhQUNHaVQsT0FESCxDQUNXO0FBQ1AzWSxlQUFPLEVBQUVuRixNQUFNNEwsU0FBUixFQUFtQjhTLGVBQWU3SyxjQUFsQyxFQURBO0FBRVBrSyxlQUFPLENBQUMsQ0FBQyxJQUFELEVBQU8sS0FBUCxDQUFEO0FBRkEsT0FEWCxFQUtHbmEsSUFMSCxDQUtRLGtCQUFVO0FBQ2QsZ0JBQVFrSCxPQUFPMEYsTUFBZjtBQUNFLGVBQUssQ0FBTDtBQUNFLG1CQUFPNUYsUUFBUSxJQUFSLENBQVA7QUFDRixlQUFLLENBQUw7QUFDRSxtQkFBT0EsUUFBUUUsT0FBTyxDQUFQLEVBQVUvQyxPQUFsQixDQUFQO0FBQ0Y7QUFDRXJGLG1CQUFPcUIsS0FBUCxDQUFnQitHLE9BQU8wRixNQUF2Qiw0QkFBb0Q1RSxTQUFwRCxzQkFBOEVpSSxjQUE5RTtBQUNBLG1CQUFPakosUUFBUUUsT0FBTyxDQUFQLEVBQVUvQyxPQUFsQixDQUFQO0FBUEo7QUFTRCxPQWZILEVBZ0JHakUsS0FoQkgsQ0FnQlMsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FsQkg7QUFtQkQsS0FwQk0sQ0FBUDtBQXFCRCxHQXZCRDs7QUF5QkFJLFFBQU1pYiw4QkFBTixHQUF1QyxVQUFVcGYsSUFBVixFQUFnQjRGLE9BQWhCLEVBQXlCO0FBQUE7O0FBQzlELFdBQU8sSUFBSStELE9BQUosQ0FBWSxVQUFDaUIsT0FBRCxFQUFVQyxNQUFWLEVBQXFCO0FBQ3RDLGFBQ0dpVCxPQURILENBQ1c7QUFDUDNZLGVBQU87QUFDTG5GLG9CQURLO0FBRUwrSCxtQkFBUztBQUNQa1csbUJBQVVyWSxPQUFWO0FBRE8sV0FGSixFQURBO0FBTVBtWSxlQUFPLENBQUMsQ0FBQyxRQUFELEVBQVcsS0FBWCxDQUFEO0FBTkEsT0FEWCxFQVNHbmEsSUFUSCxDQVNRLGtCQUFVO0FBQ2QsZ0JBQVFrSCxPQUFPMEYsTUFBZjtBQUNFLGVBQUssQ0FBTDtBQUNFLG1CQUFPNUYsUUFBUSxJQUFSLENBQVA7QUFDRjtBQUFTO0FBQ1AsbUJBQU9BLFFBQVFFLE9BQU8sQ0FBUCxFQUFVL0MsT0FBbEIsQ0FBUDtBQUpKO0FBTUQsT0FoQkgsRUFpQkdqRSxLQWpCSCxDQWlCUyxpQkFBUztBQUNkK0csZUFBTzlHLEtBQVA7QUFDRCxPQW5CSDtBQW9CRCxLQXJCTSxDQUFQO0FBc0JELEdBdkJEOztBQXlCQUksUUFBTWtiLDRCQUFOLEdBQXFDLFVBQVVyZixJQUFWLEVBQWdCO0FBQUE7O0FBQ25ELFdBQU8sSUFBSTJKLE9BQUosQ0FBWSxVQUFDaUIsT0FBRCxFQUFVQyxNQUFWLEVBQXFCO0FBQ3RDLGFBQ0dpVCxPQURILENBQ1c7QUFDUDNZLGVBQU8sRUFBRW5GLFVBQUYsRUFEQTtBQUVQK2QsZUFBTyxDQUFDLENBQUMsaUJBQUQsRUFBb0IsTUFBcEIsQ0FBRCxFQUE4QixDQUFDLFFBQUQsRUFBVyxLQUFYLENBQTlCLENBRkEsQ0FFbUQ7QUFGbkQsT0FEWCxFQUtHbmEsSUFMSCxDQUtRLGtCQUFVO0FBQ2RsQixlQUFPMkMsS0FBUCxDQUFhLGtCQUFiLEVBQWlDeUYsT0FBTzBGLE1BQXhDO0FBQ0EsZ0JBQVExRixPQUFPMEYsTUFBZjtBQUNFLGVBQUssQ0FBTDtBQUNFLG1CQUFPNUYsUUFBUSxJQUFSLENBQVA7QUFDRjtBQUNFLG1CQUFPQSxRQUFRRSxPQUFPLENBQVAsRUFBVWdLLFVBQVYsQ0FBcUIvTSxPQUE3QixDQUFQO0FBSko7QUFNRCxPQWJILEVBY0dqRSxLQWRILENBY1MsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FoQkg7QUFpQkQsS0FsQk0sQ0FBUDtBQW1CRCxHQXBCRDs7QUFzQkFJLFFBQU1tYixtQkFBTixHQUE0QixVQUFVdGYsSUFBVixFQUFnQitILE9BQWhCLEVBQXlCO0FBQUE7O0FBQ25ELFdBQU8sSUFBSTRCLE9BQUosQ0FBWSxVQUFDaUIsT0FBRCxFQUFVQyxNQUFWLEVBQXFCO0FBQ3RDLGFBQUszRixPQUFMLENBQWE7QUFDWEMsZUFBTyxFQUFDbkYsVUFBRCxFQUFPK0gsZ0JBQVA7QUFESSxPQUFiLEVBR0duRSxJQUhILENBR1Esa0JBQVU7QUFDZCxZQUFJLENBQUNrSCxNQUFMLEVBQWE7QUFDWCxpQkFBT0YsUUFBUSxJQUFSLENBQVA7QUFDRDtBQUNEQSxnQkFBUTdDLE9BQVI7QUFDRCxPQVJILEVBU0dqRSxLQVRILENBU1MsaUJBQVM7QUFDZCtHLGVBQU85RyxLQUFQO0FBQ0QsT0FYSDtBQVlELEtBYk0sQ0FBUDtBQWNELEdBZkQ7O0FBaUJBSSxRQUFNNlAsY0FBTixHQUF1QixVQUFVcEksU0FBVixFQUFxQjdELE9BQXJCLEVBQThCO0FBQ25EckYsV0FBTzJDLEtBQVAscUJBQStCdUcsU0FBL0IsVUFBNkM3RCxPQUE3QztBQUNBLFFBQUlBLFdBQVlBLFFBQVF5SSxNQUFSLEtBQW1CLEVBQW5DLEVBQXdDO0FBQUc7QUFDekMsYUFBTyxLQUFLOE8sbUJBQUwsQ0FBeUIxVCxTQUF6QixFQUFvQzdELE9BQXBDLENBQVA7QUFDRCxLQUZELE1BRU8sSUFBSUEsV0FBV0EsUUFBUXlJLE1BQVIsR0FBaUIsRUFBaEMsRUFBb0M7QUFDekMsYUFBTyxLQUFLNE8sOEJBQUwsQ0FBb0N4VCxTQUFwQyxFQUErQzdELE9BQS9DLENBQVAsQ0FEeUMsQ0FDd0I7QUFDbEUsS0FGTSxNQUVBO0FBQ0wsYUFBTyxLQUFLc1gsNEJBQUwsQ0FBa0N6VCxTQUFsQyxDQUFQLENBREssQ0FDaUQ7QUFDdkQ7QUFDRixHQVREOztBQVdBekgsUUFBTW9iLFlBQU4sR0FBcUIsVUFBVXZmLElBQVYsRUFBZ0IrSCxPQUFoQixFQUF5QjtBQUFBOztBQUM1Q3JGLFdBQU8yQyxLQUFQLDBCQUFvQ3JGLElBQXBDLFNBQTRDK0gsT0FBNUM7QUFDQSxXQUFPLElBQUk0QixPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QyxhQUNHaVQsT0FESCxDQUNXO0FBQ1AzWSxlQUFPLEVBQUVuRixVQUFGLEVBQVErSCxnQkFBUjtBQURBLE9BRFgsRUFJR25FLElBSkgsQ0FJUSxzQkFBYztBQUNsQixnQkFBUTRiLFdBQVdoUCxNQUFuQjtBQUNFLGVBQUssQ0FBTDtBQUNFLG1CQUFPNUYsUUFBUSxJQUFSLENBQVA7QUFDRixlQUFLLENBQUw7QUFDRSxtQkFBT0EsUUFBUTRULGlCQUFpQmdCLFdBQVcsQ0FBWCxFQUFjMUssVUFBL0IsQ0FBUixDQUFQO0FBQ0Y7QUFDRXBTLG1CQUFPcUIsS0FBUCxtQ0FBNkMvRCxJQUE3QyxTQUFxRCtILE9BQXJEO0FBQ0EsbUJBQU82QyxRQUFRNFQsaUJBQWlCZ0IsV0FBVyxDQUFYLEVBQWMxSyxVQUEvQixDQUFSLENBQVA7QUFQSjtBQVNELE9BZEgsRUFlR2hSLEtBZkgsQ0FlUyxpQkFBUztBQUNkK0csZUFBTzlHLEtBQVA7QUFDRCxPQWpCSDtBQWtCRCxLQW5CTSxDQUFQO0FBb0JELEdBdEJEOztBQXdCQSxTQUFPSSxLQUFQO0FBQ0QsQ0EzVUQsQzs7Ozs7Ozs7O0FDcENBN0IsT0FBT0MsT0FBUCxHQUFpQixVQUFDVSxTQUFELFFBQTZDO0FBQUEsTUFBL0JvWixNQUErQixRQUEvQkEsTUFBK0I7QUFBQSxNQUF2QkMsT0FBdUIsUUFBdkJBLE9BQXVCO0FBQUEsTUFBZEMsT0FBYyxRQUFkQSxPQUFjOztBQUM1RCxNQUFNblksT0FBT25CLFVBQVV5WixNQUFWLENBQ1gsTUFEVyxFQUVYO0FBQ0UxYyxVQUFNO0FBQ0pKLFlBQVd5YyxNQURQO0FBRUp3QixpQkFBVztBQUZQLEtBRFI7QUFLRTlWLGFBQVM7QUFDUG5JLFlBQVd5YyxNQURKO0FBRVB3QixpQkFBVztBQUZKLEtBTFg7QUFTRWhMLGFBQVM7QUFDUGpULFlBQVd5YyxNQURKO0FBRVB3QixpQkFBVztBQUZKLEtBVFg7QUFhRWxMLGNBQVU7QUFDUi9TLFlBQVd5YyxNQURIO0FBRVJ3QixpQkFBVztBQUZILEtBYlo7QUFpQkVqTCxZQUFRO0FBQ05oVCxZQUFXMmMsT0FETDtBQUVOc0IsaUJBQVcsS0FGTDtBQUdObEIsZUFBVztBQUhMLEtBakJWO0FBc0JFdkwsY0FBVTtBQUNSeFIsWUFBV3ljLE1BREg7QUFFUndCLGlCQUFXO0FBRkgsS0F0Qlo7QUEwQkV4TSxjQUFVO0FBQ1J6UixZQUFXeWMsTUFESDtBQUVSd0IsaUJBQVc7QUFGSCxLQTFCWjtBQThCRXZNLGNBQVU7QUFDUjFSLFlBQU15YztBQURFLEtBOUJaO0FBaUNFekwsVUFBTTtBQUNKaFIsWUFBYzBjLE9BRFY7QUFFSnVCLGlCQUFjLEtBRlY7QUFHSjRCLG9CQUFjO0FBSFYsS0FqQ1I7QUFzQ0VDLHNCQUFrQjtBQUNoQjlmLFlBQWMwYyxPQURFO0FBRWhCdUIsaUJBQWMsS0FGRTtBQUdoQjRCLG9CQUFjO0FBSEU7QUF0Q3BCLEdBRlcsRUE4Q1g7QUFDRS9CLHFCQUFpQjtBQURuQixHQTlDVyxDQUFiOztBQW1EQXRaLE9BQUtRLFNBQUwsR0FBaUIsY0FBTTtBQUNyQlIsU0FBS3ViLE9BQUwsQ0FBYTNjLEdBQUdxQixPQUFoQjtBQUNBRCxTQUFLZ2EsTUFBTCxDQUFZcGIsR0FBR21CLEtBQWY7QUFDRCxHQUhEOztBQUtBQyxPQUFLd2IsZUFBTCxHQUF1QixZQUFZO0FBQ2pDLFdBQU8sS0FBSzlCLE9BQUwsQ0FBYTtBQUNsQjNZLGFBQU8sRUFBRXlMLE1BQU0sS0FBUixFQUFlOE8sa0JBQWtCLElBQWpDLEVBRFc7QUFFbEIzQixhQUFPLENBQUMsQ0FBQyxXQUFELEVBQWMsTUFBZCxDQUFELENBRlc7QUFHbEI4QixhQUFPO0FBSFcsS0FBYixDQUFQO0FBS0QsR0FORDs7QUFRQSxTQUFPemIsSUFBUDtBQUNELENBbEVELEM7Ozs7Ozs7OztBQ0FBOUIsT0FBT0MsT0FBUCxHQUFpQixVQUFDVSxTQUFELFFBQTBDO0FBQUEsTUFBNUJvWixNQUE0QixRQUE1QkEsTUFBNEI7QUFBQSxNQUFwQkMsT0FBb0IsUUFBcEJBLE9BQW9CO0FBQUEsTUFBWEUsSUFBVyxRQUFYQSxJQUFXOztBQUN6RCxNQUFNblksVUFBVXBCLFVBQVV5WixNQUFWLENBQ2QsU0FEYyxFQUVkO0FBQ0VvRCxZQUFRO0FBQ05sZ0IsWUFBV3ljLE1BREw7QUFFTndCLGlCQUFXO0FBRkwsS0FEVjtBQUtFclUsU0FBSztBQUNINUosWUFBV3ljLE1BRFI7QUFFSHdCLGlCQUFXO0FBRlIsS0FMUDtBQVNFa0MsZUFBVztBQUNUbmdCLFlBQVd5YyxNQURGO0FBRVR3QixpQkFBVztBQUZGLEtBVGI7QUFhRS9TLFlBQVE7QUFDTmxMLFlBQVc0YyxLQUFLLE1BQUwsQ0FETDtBQUVOcUIsaUJBQVcsSUFGTDtBQUdObEIsZUFBVztBQUhMO0FBYlYsR0FGYyxFQXFCZDtBQUNFZSxxQkFBaUI7QUFEbkIsR0FyQmMsQ0FBaEI7O0FBMEJBclosVUFBUU8sU0FBUixHQUFvQixjQUFNO0FBQ3hCUCxZQUFRc1osU0FBUixDQUFrQjNhLEdBQUdvQixJQUFyQixFQUEyQjtBQUN6QndaLGtCQUFZO0FBQ1ZDLG1CQUFXO0FBREQ7QUFEYSxLQUEzQjtBQUtELEdBTkQ7O0FBUUEsU0FBT3haLE9BQVA7QUFDRCxDQXBDRCxDOzs7Ozs7O0FDQUE7O0FBQ0EsSUFBTTJiLFNBQVMsbUJBQUF2ZCxDQUFRLEVBQVIsQ0FBZjtBQUNBLElBQU1DLFNBQVMsbUJBQUFELENBQVEsQ0FBUixDQUFmOztBQUVBSCxPQUFPQyxPQUFQLEdBQWlCLFVBQUNVLFNBQUQsUUFBMkI7QUFBQSxNQUFib1osTUFBYSxRQUFiQSxNQUFhOztBQUMxQyxNQUFNL1gsT0FBT3JCLFVBQVV5WixNQUFWLENBQ1gsTUFEVyxFQUVYO0FBQ0VsQixjQUFVO0FBQ1I1YixZQUFXeWMsTUFESDtBQUVSd0IsaUJBQVc7QUFGSCxLQURaO0FBS0U5YSxjQUFVO0FBQ1JuRCxZQUFXeWMsTUFESDtBQUVSd0IsaUJBQVc7QUFGSDtBQUxaLEdBRlcsRUFZWDtBQUNFSCxxQkFBaUI7QUFEbkIsR0FaVyxDQUFiOztBQWlCQXBaLE9BQUtNLFNBQUwsR0FBaUIsY0FBTTtBQUNyQk4sU0FBSzhaLE1BQUwsQ0FBWXBiLEdBQUdrQixPQUFmO0FBQ0QsR0FGRDs7QUFJQUksT0FBSzJiLFNBQUwsQ0FBZUMsZUFBZixHQUFpQyxVQUFVbmQsUUFBVixFQUFvQjtBQUNuRCxXQUFPaWQsT0FBT0csT0FBUCxDQUFlcGQsUUFBZixFQUF5QixLQUFLQSxRQUE5QixDQUFQO0FBQ0QsR0FGRDs7QUFJQXVCLE9BQUsyYixTQUFMLENBQWVHLGNBQWYsR0FBZ0MsVUFBVUMsV0FBVixFQUF1QjtBQUFBOztBQUNyRCxXQUFPLElBQUkxVyxPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QztBQUNBbVYsYUFBT00sT0FBUCxDQUFlLFVBQUNDLFNBQUQsRUFBWUMsSUFBWixFQUFxQjtBQUNsQyxZQUFJRCxTQUFKLEVBQWU7QUFDYjdkLGlCQUFPcUIsS0FBUCxDQUFhLFlBQWIsRUFBMkJ3YyxTQUEzQjtBQUNBMVYsaUJBQU8wVixTQUFQO0FBQ0E7QUFDRDtBQUNEO0FBQ0FQLGVBQU9TLElBQVAsQ0FBWUosV0FBWixFQUF5QkcsSUFBekIsRUFBK0IsVUFBQ0UsU0FBRCxFQUFZRCxJQUFaLEVBQXFCO0FBQ2xEO0FBQ0EsY0FBSUMsU0FBSixFQUFlO0FBQ2JoZSxtQkFBT3FCLEtBQVAsQ0FBYSxZQUFiLEVBQTJCMmMsU0FBM0I7QUFDQTdWLG1CQUFPNlYsU0FBUDtBQUNBO0FBQ0Q7QUFDRDtBQUNBLGdCQUNHcGIsTUFESCxDQUNVLEVBQUN2QyxVQUFVMGQsSUFBWCxFQURWLEVBRUc3YyxJQUZILENBRVEsWUFBTTtBQUNWZ0g7QUFDRCxXQUpILEVBS0c5RyxLQUxILENBS1MsaUJBQVM7QUFDZCtHLG1CQUFPOUcsS0FBUDtBQUNELFdBUEg7QUFRRCxTQWhCRDtBQWlCRCxPQXhCRDtBQXlCRCxLQTNCTSxDQUFQO0FBNEJELEdBN0JEOztBQStCQTtBQUNBTyxPQUFLcWMsSUFBTCxDQUFVLGNBQVYsRUFBMEIsVUFBQ3BILElBQUQsRUFBTzlQLE9BQVAsRUFBbUI7QUFDM0MvRyxXQUFPMkMsS0FBUCxDQUFhLDJCQUFiO0FBQ0EsV0FBTyxJQUFJc0UsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdEM7QUFDQW1WLGFBQU9NLE9BQVAsQ0FBZSxVQUFDQyxTQUFELEVBQVlDLElBQVosRUFBcUI7QUFDbEMsWUFBSUQsU0FBSixFQUFlO0FBQ2I3ZCxpQkFBT3FCLEtBQVAsQ0FBYSxZQUFiLEVBQTJCd2MsU0FBM0I7QUFDQTFWLGlCQUFPMFYsU0FBUDtBQUNBO0FBQ0Q7QUFDRDtBQUNBUCxlQUFPUyxJQUFQLENBQVlsSCxLQUFLeFcsUUFBakIsRUFBMkJ5ZCxJQUEzQixFQUFpQyxVQUFDRSxTQUFELEVBQVlELElBQVosRUFBcUI7QUFDcEQ7QUFDQSxjQUFJQyxTQUFKLEVBQWU7QUFDYmhlLG1CQUFPcUIsS0FBUCxDQUFhLFlBQWIsRUFBMkIyYyxTQUEzQjtBQUNBN1YsbUJBQU82VixTQUFQO0FBQ0E7QUFDRDtBQUNEO0FBQ0FuSCxlQUFLeFcsUUFBTCxHQUFnQjBkLElBQWhCO0FBQ0E3VjtBQUNELFNBVkQ7QUFXRCxPQWxCRDtBQW1CRCxLQXJCTSxDQUFQO0FBc0JELEdBeEJEOztBQTBCQSxTQUFPdEcsSUFBUDtBQUNELENBckZELEM7Ozs7OztBQ0pBLG1DOzs7Ozs7Ozs7QUNBQSxJQUFNMlcsd0JBQXdCLG1CQUFBeFksQ0FBUSxFQUFSLEVBQTBCeVksUUFBeEQ7QUFDQSxJQUFNeFksU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7QUFDQSxJQUFNTyxLQUFLLG1CQUFBUCxDQUFRLENBQVIsQ0FBWDs7QUFFQSxJQUFNbWUsMkJBQTJCLFNBQTNCQSx3QkFBMkIsQ0FBQ0MsWUFBRCxFQUFrQjtBQUNqRCxTQUFPLElBQUlsWCxPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QyxRQUFJeVEsV0FBVyxFQUFmO0FBQ0FBLGFBQVMsSUFBVCxJQUFpQnVGLGFBQWFyWixFQUE5QjtBQUNBOFQsYUFBUyxVQUFULElBQXVCdUYsYUFBYXJGLFFBQXBDO0FBQ0FxRixpQkFDR0MsVUFESCxHQUVHbGQsSUFGSCxDQUVRLGdCQUFtQztBQUFBLFVBQWpDbEQsV0FBaUMsUUFBakNBLFdBQWlDO0FBQUEsVUFBcEJtVCxjQUFvQixRQUFwQkEsY0FBb0I7O0FBQ3ZDeUgsZUFBUyxhQUFULElBQTBCNWEsV0FBMUI7QUFDQTRhLGVBQVMsZ0JBQVQsSUFBNkJ6SCxjQUE3QjtBQUNBLGFBQU83USxHQUFHaUIsV0FBSCxDQUFlc1Esa0NBQWYsQ0FBa0RWLGNBQWxELEVBQWtFblQsV0FBbEUsQ0FBUDtBQUNELEtBTkgsRUFPR2tELElBUEgsQ0FPUSwwQkFBa0I7QUFDdEIwWCxlQUFTLGdCQUFULElBQTZCWSxjQUE3QjtBQUNBdFIsY0FBUTBRLFFBQVI7QUFDRCxLQVZILEVBV0d4WCxLQVhILENBV1MsaUJBQVM7QUFDZCtHLGFBQU85RyxLQUFQO0FBQ0QsS0FiSDtBQWNELEdBbEJNLENBQVA7QUFtQkQsQ0FwQkQ7O0FBc0JBekIsT0FBT0MsT0FBUCxHQUFpQixJQUFJMFkscUJBQUosQ0FDZjtBQUNFRyxpQkFBZSxVQURqQjtBQUVFQyxpQkFBZTtBQUZqQixDQURlLEVBS2YsVUFBQ3ZZLFFBQUQsRUFBV0MsUUFBWCxFQUFxQnlXLElBQXJCLEVBQThCO0FBQzVCLFNBQU94VyxHQUFHc0IsSUFBSCxDQUNKWSxPQURJLENBQ0k7QUFDUEMsV0FBTyxFQUFDcVcsVUFBVTFZLFFBQVg7QUFEQSxHQURKLEVBSUpjLElBSkksQ0FJQyxnQkFBUTtBQUNaLFFBQUksQ0FBQzJWLElBQUwsRUFBVztBQUNUN1csYUFBTzJDLEtBQVAsQ0FBYSxlQUFiO0FBQ0EsYUFBT21VLEtBQUssSUFBTCxFQUFXLEtBQVgsRUFBa0IsRUFBQ2paLFNBQVMsZ0NBQVYsRUFBbEIsQ0FBUDtBQUNEO0FBQ0QsV0FBT2daLEtBQUsyRyxlQUFMLENBQXFCbmQsUUFBckIsRUFDSmEsSUFESSxDQUNDLG1CQUFXO0FBQ2YsVUFBSSxDQUFDbWQsT0FBTCxFQUFjO0FBQ1pyZSxlQUFPMkMsS0FBUCxDQUFhLG9CQUFiO0FBQ0EsZUFBT21VLEtBQUssSUFBTCxFQUFXLEtBQVgsRUFBa0IsRUFBQ2paLFNBQVMsZ0NBQVYsRUFBbEIsQ0FBUDtBQUNEO0FBQ0RtQyxhQUFPMkMsS0FBUCxDQUFhLHNDQUFiO0FBQ0EsYUFBT3ViLHlCQUF5QnJILElBQXpCLEVBQ0ozVixJQURJLENBQ0Msb0JBQVk7QUFDaEIsZUFBTzRWLEtBQUssSUFBTCxFQUFXOEIsUUFBWCxDQUFQO0FBQ0QsT0FISSxFQUlKeFgsS0FKSSxDQUlFLGlCQUFTO0FBQ2QsZUFBT0MsS0FBUDtBQUNELE9BTkksQ0FBUDtBQU9ELEtBZEksRUFlSkQsS0FmSSxDQWVFLGlCQUFTO0FBQ2QsYUFBT0MsS0FBUDtBQUNELEtBakJJLENBQVA7QUFrQkQsR0EzQkksRUE0QkpELEtBNUJJLENBNEJFLGlCQUFTO0FBQ2QsV0FBTzBWLEtBQUt6VixLQUFMLENBQVA7QUFDRCxHQTlCSSxDQUFQO0FBK0JELENBckNjLENBQWpCLEM7Ozs7Ozs7OztBQzFCQSxJQUFNckIsU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7QUFDQSxJQUFNa1YsV0FBVyxtQkFBQWxWLENBQVEsRUFBUixDQUFqQjs7QUFFQUgsT0FBT0MsT0FBUCxHQUFpQixVQUFDMFYsR0FBRCxFQUFTO0FBQ3hCO0FBQ0FBLE1BQUkzTSxJQUFKLENBQVMsU0FBVCxFQUFvQnFNLFNBQVNoVSxZQUFULENBQXNCLGNBQXRCLENBQXBCLEVBQTJELFVBQUNvUixHQUFELEVBQU0vQixHQUFOLEVBQWM7QUFDdkV0USxXQUFPK1YsT0FBUCw0QkFBd0MxRCxJQUFJd0UsSUFBSixDQUFTN1ksV0FBakQ7QUFDQXNTLFFBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCO0FBQ25CbUssZUFBZ0IsSUFERztBQUVuQjdTLG1CQUFnQnFVLElBQUl3RSxJQUFKLENBQVM3WSxXQUZOO0FBR25CbVQsc0JBQWdCa0IsSUFBSXdFLElBQUosQ0FBUzFGLGNBSE47QUFJbkJxSSxzQkFBZ0JuSCxJQUFJd0UsSUFBSixDQUFTMkM7QUFKTixLQUFyQjtBQU1ELEdBUkQ7QUFTQTtBQUNBakUsTUFBSTNNLElBQUosQ0FBUyxRQUFULEVBQW1CLFVBQUN5SixHQUFELEVBQU0vQixHQUFOLEVBQVd3RixJQUFYLEVBQW9CO0FBQ3JDYixhQUFTaFUsWUFBVCxDQUFzQixhQUF0QixFQUFxQyxVQUFDSyxHQUFELEVBQU11VixJQUFOLEVBQVkxVixJQUFaLEVBQXFCO0FBQ3hELFVBQUlHLEdBQUosRUFBUztBQUNQLGVBQU93VSxLQUFLeFUsR0FBTCxDQUFQO0FBQ0Q7QUFDRCxVQUFJLENBQUN1VixJQUFMLEVBQVc7QUFDVCxlQUFPdkcsSUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUI7QUFDMUJtSyxtQkFBUyxLQURpQjtBQUUxQmhULG1CQUFTc0QsS0FBS3REO0FBRlksU0FBckIsQ0FBUDtBQUlEO0FBQ0RtQyxhQUFPMkMsS0FBUCxDQUFhLGtCQUFiO0FBQ0EwUCxVQUFJaU0sS0FBSixDQUFVekgsSUFBVixFQUFnQixVQUFDdlYsR0FBRCxFQUFTO0FBQ3ZCLFlBQUlBLEdBQUosRUFBUztBQUNQLGlCQUFPd1UsS0FBS3hVLEdBQUwsQ0FBUDtBQUNEO0FBQ0QsZUFBT2dQLElBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCO0FBQzFCbUssbUJBQWdCLElBRFU7QUFFMUI3Uyx1QkFBZ0JxVSxJQUFJd0UsSUFBSixDQUFTN1ksV0FGQztBQUcxQm1ULDBCQUFnQmtCLElBQUl3RSxJQUFKLENBQVMxRixjQUhDO0FBSTFCcUksMEJBQWdCbkgsSUFBSXdFLElBQUosQ0FBUzJDO0FBSkMsU0FBckIsQ0FBUDtBQU1ELE9BVkQ7QUFXRCxLQXRCRCxFQXNCR25ILEdBdEJILEVBc0JRL0IsR0F0QlIsRUFzQmF3RixJQXRCYjtBQXVCRCxHQXhCRDtBQXlCQTtBQUNBUCxNQUFJZ0osR0FBSixDQUFRLFNBQVIsRUFBbUIsVUFBQ2xNLEdBQUQsRUFBTS9CLEdBQU4sRUFBYztBQUMvQitCLFFBQUltTSxNQUFKO0FBQ0FsTyxRQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxJQUFWLEVBQWdCaFQsU0FBUyw2QkFBekIsRUFBckI7QUFDRCxHQUhEO0FBSUE7QUFDQTBYLE1BQUlnSixHQUFKLENBQVEsT0FBUixFQUFpQixVQUFDbE0sR0FBRCxFQUFNL0IsR0FBTixFQUFjO0FBQzdCLFFBQUkrQixJQUFJd0UsSUFBUixFQUFjO0FBQ1p2RyxVQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxJQUFWLEVBQWdCelQsTUFBTWlWLElBQUl3RSxJQUExQixFQUFyQjtBQUNELEtBRkQsTUFFTztBQUNMdkcsVUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIsRUFBQ21LLFNBQVMsS0FBVixFQUFpQmhULFNBQVMsdUJBQTFCLEVBQXJCO0FBQ0Q7QUFDRixHQU5EO0FBT0QsQ0FsREQsQzs7Ozs7Ozs7Ozs7QUNIQSxJQUFNbUMsU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7QUFDQSxJQUFNMGUsWUFBWSxtQkFBQTFlLENBQVEsRUFBUixDQUFsQjs7ZUFDK0QsbUJBQUFBLENBQVEsQ0FBUixDO0lBQXpDSixlLFlBQWRQLFUsQ0FBY08sZTtJQUE4QlYsSSxZQUFYRCxPLENBQVdDLEk7O0FBQ3BELElBQU15ZixzQkFBc0JELFVBQVUsRUFBQ0UsV0FBV2hmLGVBQVosRUFBVixDQUE1QjtBQUNBLElBQU1XLEtBQUssbUJBQUFQLENBQVEsQ0FBUixDQUFYOztnQkFDb0UsbUJBQUFBLENBQVEsRUFBUixDO0lBQTVENmUsb0IsYUFBQUEsb0I7SUFBc0JDLHdCLGFBQUFBLHdCO0lBQTBCOUwsTyxhQUFBQSxPOztnQkFDVCxtQkFBQWhULENBQVEsRUFBUixDO0lBQXZDa0osWSxhQUFBQSxZO0lBQWNFLFUsYUFBQUEsVTtJQUFZTCxRLGFBQUFBLFE7O2dCQUNtSSxtQkFBQS9JLENBQVEsRUFBUixDO0lBQTdKNFAsdUIsYUFBQUEsdUI7SUFBeUJYLHdCLGFBQUFBLHdCO0lBQTBCUSw0QixhQUFBQSw0QjtJQUE4QnZCLDBCLGFBQUFBLDBCO0lBQTRCSywyQixhQUFBQSwyQjtJQUE2QjBCLGMsYUFBQUEsYzs7QUFDbEosSUFBTThPLGdCQUFnQixtQkFBQS9lLENBQVEsRUFBUixDQUF0Qjs7Z0JBQzhCLG1CQUFBQSxDQUFRLEVBQVIsQztJQUF0QmlJLGlCLGFBQUFBLGlCOztnQkFDcUIsbUJBQUFqSSxDQUFRLEVBQVIsQztJQUFyQmdmLGdCLGFBQUFBLGdCOztnQkFDaUQsbUJBQUFoZixDQUFRLEVBQVIsQztJQUFqRDRSLGMsYUFBQUEsYztJQUFnQkksZ0IsYUFBQUEsZ0I7SUFBa0JiLFUsYUFBQUEsVTs7QUFFMUMsSUFBTUgsYUFBYSxZQUFuQjtBQUNBLElBQU1DLFdBQVcsVUFBakI7O0FBRUFwUixPQUFPQyxPQUFQLEdBQWlCLFVBQUMwVixHQUFELEVBQVM7QUFDeEI7QUFDQUEsTUFBSWdKLEdBQUosQ0FBUSxpQ0FBUixFQUEyQyxnQkFBd0NqTyxHQUF4QyxFQUFnRDtBQUFBLFFBQTdDMUcsRUFBNkMsUUFBN0NBLEVBQTZDO0FBQUEsUUFBekNDLFdBQXlDLFFBQXpDQSxXQUF5QztBQUFBLFFBQWxCdk0sSUFBa0IsUUFBNUJpSCxNQUE0QixDQUFsQmpILElBQWtCOztBQUN6RixRQUFNbUwsY0FBY0MsS0FBS0MsR0FBTCxFQUFwQjtBQUNBa1csNkJBQXlCdmhCLElBQXpCLEVBQ0c0RCxJQURILENBQ1EseUJBQWlCO0FBQ3JCb1AsVUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUJzWSxhQUFyQjtBQUNBaFgsd0JBQWtCLFlBQWxCLEVBQWdDLHlCQUFoQyxFQUEyRDFLLElBQTNELEVBQWlFbUwsV0FBakUsRUFBOEVDLEtBQUtDLEdBQUwsRUFBOUU7QUFDRCxLQUpILEVBS0d2SCxLQUxILENBS1MsaUJBQVM7QUFDZDBkLG9CQUFjek8sbUJBQWQsQ0FBa0N4RyxXQUFsQyxFQUErQ0QsRUFBL0MsRUFBbUR2SSxLQUFuRCxFQUEwRGlQLEdBQTFEO0FBQ0QsS0FQSDtBQVFELEdBVkQ7QUFXQTtBQUNBaUYsTUFBSWdKLEdBQUosQ0FBUSxxQ0FBUixFQUErQyxpQkFBOEJqTyxHQUE5QixFQUFzQztBQUFBLFFBQW5DMUcsRUFBbUMsU0FBbkNBLEVBQW1DO0FBQUEsUUFBL0JDLFdBQStCLFNBQS9CQSxXQUErQjtBQUFBLFFBQWxCdEYsTUFBa0IsU0FBbEJBLE1BQWtCOztBQUNuRmpFLE9BQUdpQixXQUFILENBQWVzUSxrQ0FBZixDQUFrRHROLE9BQU9uQixNQUF6RCxFQUFpRW1CLE9BQU9qSCxJQUF4RSxFQUNHNEQsSUFESCxDQUNRLG1CQUFXO0FBQ2ZvUCxVQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQnhELE9BQXJCO0FBQ0QsS0FISCxFQUlHOUIsS0FKSCxDQUlTLGlCQUFTO0FBQ2QwZCxvQkFBY3pPLG1CQUFkLENBQWtDeEcsV0FBbEMsRUFBK0NELEVBQS9DLEVBQW1EdkksS0FBbkQsRUFBMERpUCxHQUExRDtBQUNELEtBTkg7QUFPRCxHQVJEO0FBU0FpRixNQUFJZ0osR0FBSixDQUFRLGdEQUFSLEVBQTBELGlCQUFvQ2pPLEdBQXBDLEVBQTRDO0FBQUEsUUFBekMxRyxFQUF5QyxTQUF6Q0EsRUFBeUM7QUFBQSxRQUFyQ0MsV0FBcUMsU0FBckNBLFdBQXFDO0FBQUEsUUFBeEJvVixJQUF3QixTQUF4QkEsSUFBd0I7QUFBQSxRQUFsQjFhLE1BQWtCLFNBQWxCQSxNQUFrQjs7QUFDcEcsUUFBTXZHLGNBQWN1RyxPQUFPdkcsV0FBM0I7QUFDQSxRQUFJbVQsaUJBQWlCNU0sT0FBTzRNLGNBQTVCO0FBQ0EsUUFBSUEsbUJBQW1CLE1BQXZCLEVBQStCQSxpQkFBaUIsSUFBakI7QUFDL0JRLG1CQUFlM1QsV0FBZixFQUE0Qm1ULGNBQTVCLEVBQTRDLENBQTVDLEVBQ0dqUSxJQURILENBQ1EsZ0JBQVE7QUFDWixVQUFJOUQsU0FBUzJULFVBQWIsRUFBeUI7QUFDdkIsZUFBT1QsSUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIsRUFBQ21LLFNBQVMsS0FBVixFQUFpQmhULFNBQVMsK0JBQTFCLEVBQXJCLENBQVA7QUFDRDtBQUNEeVMsVUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIsRUFBQ21LLFNBQVMsSUFBVixFQUFnQnpULFVBQWhCLEVBQXJCO0FBQ0QsS0FOSCxFQU9HZ0UsS0FQSCxDQU9TLGlCQUFTO0FBQ2QwZCxvQkFBY3pPLG1CQUFkLENBQWtDeEcsV0FBbEMsRUFBK0NELEVBQS9DLEVBQW1EdkksS0FBbkQsRUFBMERpUCxHQUExRDtBQUNELEtBVEg7QUFVRCxHQWREO0FBZUFpRixNQUFJZ0osR0FBSixDQUFRLHdEQUFSLEVBQWtFLGlCQUFvQ2pPLEdBQXBDLEVBQTRDO0FBQUEsUUFBekMxRyxFQUF5QyxTQUF6Q0EsRUFBeUM7QUFBQSxRQUFyQ0MsV0FBcUMsU0FBckNBLFdBQXFDO0FBQUEsUUFBeEJvVixJQUF3QixTQUF4QkEsSUFBd0I7QUFBQSxRQUFsQjFhLE1BQWtCLFNBQWxCQSxNQUFrQjs7QUFDNUcsUUFBTXZHLGNBQWN1RyxPQUFPdkcsV0FBM0I7QUFDQSxRQUFJbVQsaUJBQWlCNU0sT0FBTzRNLGNBQTVCO0FBQ0EsUUFBSUEsbUJBQW1CLE1BQXZCLEVBQStCQSxpQkFBaUIsSUFBakI7QUFDL0IsUUFBTXhMLE9BQU9wQixPQUFPb0IsSUFBcEI7QUFDQW9NLHFCQUFpQi9ULFdBQWpCLEVBQThCbVQsY0FBOUIsRUFBOEN4TCxJQUE5QyxFQUNHekUsSUFESCxDQUNRLGdCQUFRO0FBQ1osVUFBSTlELFNBQVMyVCxVQUFiLEVBQXlCO0FBQ3ZCLGVBQU9ULElBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCLEVBQUNtSyxTQUFTLEtBQVYsRUFBaUJoVCxTQUFTLCtCQUExQixFQUFyQixDQUFQO0FBQ0Q7QUFDRHlTLFVBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCLEVBQUNtSyxTQUFTLElBQVYsRUFBZ0J6VCxVQUFoQixFQUFyQjtBQUNELEtBTkgsRUFPR2dFLEtBUEgsQ0FPUyxpQkFBUztBQUNkMGQsb0JBQWN6TyxtQkFBZCxDQUFrQ3hHLFdBQWxDLEVBQStDRCxFQUEvQyxFQUFtRHZJLEtBQW5ELEVBQTBEaVAsR0FBMUQ7QUFDRCxLQVRIO0FBVUQsR0FmRDtBQWdCQTtBQUNBaUYsTUFBSWdKLEdBQUosQ0FBUSx1QkFBUixFQUFpQyxpQkFBOEJqTyxHQUE5QixFQUFzQztBQUFBLFFBQW5DMUcsRUFBbUMsU0FBbkNBLEVBQW1DO0FBQUEsUUFBL0JDLFdBQStCLFNBQS9CQSxXQUErQjtBQUFBLFFBQWxCdEYsTUFBa0IsU0FBbEJBLE1BQWtCOztBQUNyRTBFLGlCQUFhMUUsT0FBT2pILElBQXBCLEVBQ0c0RCxJQURILENBQ1Esc0JBQWM7QUFDbEJvUCxVQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQndZLFVBQXJCO0FBQ0QsS0FISCxFQUlHOWQsS0FKSCxDQUlTLGlCQUFTO0FBQ2QwZCxvQkFBY3pPLG1CQUFkLENBQWtDeEcsV0FBbEMsRUFBK0NELEVBQS9DLEVBQW1EdkksS0FBbkQsRUFBMERpUCxHQUExRDtBQUNELEtBTkg7QUFPRCxHQVJEO0FBU0E7QUFDQWlGLE1BQUlnSixHQUFKLENBQVEsK0JBQVIsRUFBeUMsaUJBQThCak8sR0FBOUIsRUFBc0M7QUFBQSxRQUFuQzFHLEVBQW1DLFNBQW5DQSxFQUFtQztBQUFBLFFBQS9CQyxXQUErQixTQUEvQkEsV0FBK0I7QUFBQSxRQUFsQnRGLE1BQWtCLFNBQWxCQSxNQUFrQjs7QUFDN0UsUUFBTWpILE9BQU9pSCxPQUFPakgsSUFBcEI7QUFDQSxRQUFNK0gsVUFBVWQsT0FBT2MsT0FBdkI7QUFDQTtBQUNBL0UsT0FBR21CLEtBQUgsQ0FBU29iLFlBQVQsQ0FBc0J2ZixJQUF0QixFQUE0QitILE9BQTVCLEVBQ0duRSxJQURILENBQ1EseUJBQWlCO0FBQ3JCO0FBQ0EsVUFBSSxDQUFDaWUsYUFBTCxFQUFvQjtBQUNsQixjQUFNLElBQUl0WSxLQUFKLENBQVUsc0NBQVYsQ0FBTjtBQUNEO0FBQ0QsVUFBSXVZLFdBQVdwUCxlQUFlbVAsYUFBZixDQUFmO0FBQ0E7QUFDQSxhQUFPbFksUUFBUUMsR0FBUixDQUFZLENBQUNrWSxRQUFELEVBQVd0VyxTQUFZeEwsSUFBWixTQUFvQitILE9BQXBCLENBQVgsQ0FBWixDQUFQO0FBQ0QsS0FUSCxFQVVHbkUsSUFWSCxDQVVRLGlCQUE2QjtBQUFBO0FBQUEsVUFBMUJrZSxRQUEwQjtBQUFBLFVBQWhCdlAsU0FBZ0I7O0FBQ2pDdVAsaUJBQVd6UCx3QkFBd0J5UCxRQUF4QixFQUFrQ3ZQLFNBQWxDLENBQVg7QUFDQSxhQUFPNUksUUFBUUMsR0FBUixDQUFZLENBQUM1RyxHQUFHNkIsTUFBSCxDQUFVN0IsR0FBR29CLElBQWIsRUFBbUIwZCxRQUFuQixFQUE2QixFQUFDOWhCLFVBQUQsRUFBTytILGdCQUFQLEVBQTdCLEVBQThDLE1BQTlDLENBQUQsRUFBd0R3SyxTQUF4RCxDQUFaLENBQVA7QUFDRCxLQWJILEVBY0czTyxJQWRILENBY1EsaUJBQTBDO0FBQUE7QUFBQSxVQUF2Q21lLFVBQXVDO0FBQUE7QUFBQSxVQUExQnhoQixPQUEwQixXQUExQkEsT0FBMEI7QUFBQSxVQUFqQnloQixTQUFpQixXQUFqQkEsU0FBaUI7O0FBQzlDaFAsVUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIsRUFBRW1LLFNBQVMsSUFBWCxFQUFpQmhULGdCQUFqQixFQUEwQnloQixvQkFBMUIsRUFBckI7QUFDRCxLQWhCSCxFQWlCR2xlLEtBakJILENBaUJTLGlCQUFTO0FBQ2QwZCxvQkFBY3pPLG1CQUFkLENBQWtDeEcsV0FBbEMsRUFBK0NELEVBQS9DLEVBQW1EdkksS0FBbkQsRUFBMERpUCxHQUExRDtBQUNELEtBbkJIO0FBb0JELEdBeEJEO0FBeUJBO0FBQ0FpRixNQUFJZ0osR0FBSixDQUFRLCtCQUFSLEVBQXlDLGtCQUF3Q2pPLEdBQXhDLEVBQWdEO0FBQUEsUUFBN0MxRyxFQUE2QyxVQUE3Q0EsRUFBNkM7QUFBQSxRQUF6Q0MsV0FBeUMsVUFBekNBLFdBQXlDO0FBQUEsUUFBbEJ2TSxJQUFrQixVQUE1QmlILE1BQTRCLENBQWxCakgsSUFBa0I7O0FBQ3ZGLFFBQU1tTCxjQUFjQyxLQUFLQyxHQUFMLEVBQXBCO0FBQ0FpVyx5QkFBcUJ0aEIsSUFBckIsRUFDRzRELElBREgsQ0FDUSxrQkFBVTtBQUNkb1AsVUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIwQixNQUFyQjtBQUNBSix3QkFBa0IsWUFBbEIsRUFBZ0MseUJBQWhDLEVBQTJEMUssSUFBM0QsRUFBaUVtTCxXQUFqRSxFQUE4RUMsS0FBS0MsR0FBTCxFQUE5RTtBQUNELEtBSkgsRUFLR3ZILEtBTEgsQ0FLUyxpQkFBUztBQUNkMGQsb0JBQWN6TyxtQkFBZCxDQUFrQ3hHLFdBQWxDLEVBQStDRCxFQUEvQyxFQUFtRHZJLEtBQW5ELEVBQTBEaVAsR0FBMUQ7QUFDRCxLQVBIO0FBUUQsR0FWRDtBQVdBO0FBQ0FpRixNQUFJZ0osR0FBSixDQUFRLG1DQUFSLEVBQTZDLGtCQUF1Q2pPLEdBQXZDLEVBQStDO0FBQUEsUUFBNUMzRyxPQUE0QyxVQUE1Q0EsT0FBNEM7QUFBQSxRQUFuQ0MsRUFBbUMsVUFBbkNBLEVBQW1DO0FBQUEsUUFBL0JDLFdBQStCLFVBQS9CQSxXQUErQjtBQUFBLFFBQWxCdEYsTUFBa0IsVUFBbEJBLE1BQWtCOztBQUMxRjRFLGVBQWM1RSxPQUFPakgsSUFBckIsU0FBNkJpSCxPQUFPYyxPQUFwQyxFQUNHbkUsSUFESCxDQUNRLHVCQUFlO0FBQ25Cb1AsVUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUI2WSxXQUFyQjtBQUNELEtBSEgsRUFJR25lLEtBSkgsQ0FJUyxpQkFBUztBQUNkMGQsb0JBQWN6TyxtQkFBZCxDQUFrQ3hHLFdBQWxDLEVBQStDRCxFQUEvQyxFQUFtRHZJLEtBQW5ELEVBQTBEaVAsR0FBMUQ7QUFDRCxLQU5IO0FBT0QsR0FSRDtBQVNBO0FBQ0FpRixNQUFJM00sSUFBSixDQUFTLG9CQUFULEVBQStCOFYsbUJBQS9CLEVBQW9ELGtCQUFrRHBPLEdBQWxELEVBQTBEO0FBQUEsUUFBdkQyTyxJQUF1RCxVQUF2REEsSUFBdUQ7QUFBQSxRQUFqRE8sS0FBaUQsVUFBakRBLEtBQWlEO0FBQUEsUUFBMUM3VixPQUEwQyxVQUExQ0EsT0FBMEM7QUFBQSxRQUFqQ0MsRUFBaUMsVUFBakNBLEVBQWlDO0FBQUEsUUFBN0JDLFdBQTZCLFVBQTdCQSxXQUE2QjtBQUFBLFFBQWhCZ04sSUFBZ0IsVUFBaEJBLElBQWdCOztBQUM1RztBQUNBLFFBQUs3WSxvQkFBTDtBQUFBLFFBQWtCMEcsa0JBQWxCO0FBQUEsUUFBNkIrYSx3QkFBN0I7QUFBQSxRQUE4QzlnQixvQkFBOUM7QUFBQSxRQUEyRCtQLGlCQUEzRDtBQUFBLFFBQXFFQyxpQkFBckU7QUFBQSxRQUErRUMsaUJBQS9FO0FBQUEsUUFBeUZuRyxvQkFBekY7QUFBQSxRQUFzRzBGLGdCQUF0RztBQUFBLFFBQStHN1EsYUFBL0c7QUFBQSxRQUFxSDRRLGFBQXJIO0FBQUEsUUFBMkh0UCxrQkFBM0g7QUFBQSxRQUFzSWlRLDBCQUF0STtBQUFBLFFBQXlKQywwQkFBeko7QUFBQSxRQUE0S0MsMEJBQTVLO0FBQUEsUUFBK0xsUSxjQUEvTDtBQUNBO0FBQ0E0SixrQkFBY0MsS0FBS0MsR0FBTCxFQUFkO0FBQ0E7QUFDQSxRQUFJO0FBQUEsa0NBRXNEc0YsMkJBQTJCZ1IsSUFBM0IsQ0FGdEQ7QUFDRjs7O0FBQ0UzaEIsVUFGQSx5QkFFQUEsSUFGQTtBQUVNNFEsVUFGTix5QkFFTUEsSUFGTjtBQUVZQyxhQUZaLHlCQUVZQSxPQUZaO0FBRXFCdFAsV0FGckIseUJBRXFCQSxLQUZyQjtBQUU0QkYsaUJBRjVCLHlCQUU0QkEsV0FGNUI7QUFFeUNDLGVBRnpDLHlCQUV5Q0EsU0FGekM7O0FBQUEsbUNBR3lGMFAsNEJBQTRCa1IsS0FBNUIsQ0FIekY7O0FBR0E5USxjQUhBLDBCQUdBQSxRQUhBO0FBR1VDLGNBSFYsMEJBR1VBLFFBSFY7QUFHb0JDLGNBSHBCLDBCQUdvQkEsUUFIcEI7QUFHOEJDLHVCQUg5QiwwQkFHOEJBLGlCQUg5QjtBQUdpREMsdUJBSGpELDBCQUdpREEsaUJBSGpEO0FBR29FQyx1QkFIcEUsMEJBR29FQSxpQkFIcEU7QUFJQS9RLGlCQUpBLEdBSTJDaWhCLElBSjNDLENBSUFqaEIsV0FKQTtBQUlhMEcsZUFKYixHQUkyQ3VhLElBSjNDLENBSWF2YSxTQUpiO0FBSXdCK2EscUJBSnhCLEdBSTJDUixJQUozQyxDQUl3QlEsZUFKeEI7QUFLSCxLQUxELENBS0UsT0FBT3BlLEtBQVAsRUFBYztBQUNkLGFBQU9pUCxJQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxLQUFWLEVBQWlCaFQsU0FBU3dELE1BQU14RCxPQUFoQyxFQUFyQixDQUFQO0FBQ0Q7QUFDRDtBQUNBb0osWUFBUUMsR0FBUixDQUFZLENBQ1Y2WCxpQkFBaUIvZ0IsV0FBakIsRUFBOEIwRyxTQUE5QixFQUF5QythLGVBQXpDLEVBQTBENUksSUFBMUQsQ0FEVSxFQUVWK0gscUJBQXFCdGhCLElBQXJCLENBRlUsRUFHVjBSLHlCQUF5QkwsUUFBekIsRUFBbUNyUixJQUFuQyxFQUF5Q3VCLEtBQXpDLEVBQWdERixXQUFoRCxFQUE2RHdQLE9BQTdELEVBQXNFRCxJQUF0RSxFQUE0RXRQLFNBQTVFLENBSFUsRUFJVjRRLDZCQUE2QlYsaUJBQTdCLEVBQWdEeFIsSUFBaEQsRUFBc0Q2USxPQUF0RCxFQUErREQsSUFBL0QsQ0FKVSxDQUFaLEVBTUdoTixJQU5ILENBTVEsa0JBQWdHO0FBQUE7QUFBQTtBQUFBLFVBQTdGbEQsV0FBNkYsV0FBN0ZBLFdBQTZGO0FBQUEsVUFBaEZtVCxjQUFnRixXQUFoRkEsY0FBZ0Y7QUFBQSxVQUEvRHVPLGtCQUErRDtBQUFBLFVBQTNDbFgsYUFBMkM7QUFBQSxVQUE1Qm1YLHNCQUE0Qjs7QUFDcEc7QUFDQSxVQUFJM2hCLGVBQWVtVCxjQUFuQixFQUFtQztBQUNqQzNJLHNCQUFjLGNBQWQsSUFBZ0N4SyxXQUFoQztBQUNBd0ssc0JBQWMsWUFBZCxJQUE4QjJJLGNBQTlCO0FBQ0Q7QUFDRDtBQUNBLFVBQUl3TyxzQkFBSixFQUE0QjtBQUMxQjVNLGdCQUFRNE0sc0JBQVIsRUFBZ0M5USxpQkFBaEMsRUFBbURFLGlCQUFuRDtBQUNEO0FBQ0Q7QUFDQSxhQUFPZ0UsUUFBUXZLLGFBQVIsRUFBdUJrRyxRQUF2QixFQUFpQ0UsUUFBakMsQ0FBUDtBQUNELEtBbEJILEVBbUJHMU4sSUFuQkgsQ0FtQlEsa0JBQVU7QUFDZG9QLFVBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCO0FBQ25CbUssaUJBQVMsSUFEVTtBQUVuQmhULGlCQUFTLGdDQUZVO0FBR25CVCxjQUFTO0FBQ1BFLG9CQURPO0FBRVArSCxtQkFBUytDLE9BQU82USxRQUZUO0FBR1BuUyxlQUFZN0gsSUFBWixTQUFvQm1KLE9BQU82USxRQUEzQixTQUF1QzNiLElBSGhDO0FBSVBzaUIsa0JBQVN4WDtBQUpGO0FBSFUsT0FBckI7QUFVQTtBQUNBSix3QkFBa0IsWUFBbEIsRUFBZ0MsU0FBaEMsRUFBMkM0RyxRQUEzQyxFQUFxRG5HLFdBQXJELEVBQWtFQyxLQUFLQyxHQUFMLEVBQWxFO0FBQ0QsS0FoQ0gsRUFpQ0d2SCxLQWpDSCxDQWlDUyxpQkFBUztBQUNkMGQsb0JBQWN6TyxtQkFBZCxDQUFrQ3hHLFdBQWxDLEVBQStDRCxFQUEvQyxFQUFtRHZJLEtBQW5ELEVBQTBEaVAsR0FBMUQ7QUFDRCxLQW5DSDtBQW9DRCxHQW5ERDtBQW9EQTtBQUNBaUYsTUFBSWdKLEdBQUosQ0FBUSxtQ0FBUixFQUE2QyxrQkFBb0NqTyxHQUFwQyxFQUE0QztBQUFBLFFBQXpDMUcsRUFBeUMsVUFBekNBLEVBQXlDO0FBQUEsUUFBckNDLFdBQXFDLFVBQXJDQSxXQUFxQztBQUFBLFFBQXhCb1YsSUFBd0IsVUFBeEJBLElBQXdCO0FBQUEsUUFBbEIxYSxNQUFrQixVQUFsQkEsTUFBa0I7O0FBQ3ZGakUsT0FBR21CLEtBQUgsQ0FBUythLDhCQUFULENBQXdDalksT0FBT25CLE1BQS9DLEVBQXVEbUIsT0FBT2pILElBQTlELEVBQ0c0RCxJQURILENBQ1EsbUJBQVc7QUFDZm9QLFVBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCLEVBQUNtSyxTQUFTLElBQVYsRUFBZ0J6VCxNQUFNOEYsT0FBdEIsRUFBckI7QUFDRCxLQUhILEVBSUc5QixLQUpILENBSVMsaUJBQVM7QUFDZDBkLG9CQUFjek8sbUJBQWQsQ0FBa0N4RyxXQUFsQyxFQUErQ0QsRUFBL0MsRUFBbUR2SSxLQUFuRCxFQUEwRGlQLEdBQTFEO0FBQ0QsS0FOSDtBQU9ELEdBUkQ7QUFTQWlGLE1BQUkzTSxJQUFKLENBQVMsb0JBQVQsRUFBK0Isa0JBQW9DMEgsR0FBcEMsRUFBNEM7QUFBQSxRQUF6QzFHLEVBQXlDLFVBQXpDQSxFQUF5QztBQUFBLFFBQXJDQyxXQUFxQyxVQUFyQ0EsV0FBcUM7QUFBQSxRQUF4Qm9WLElBQXdCLFVBQXhCQSxJQUF3QjtBQUFBLFFBQWxCMWEsTUFBa0IsVUFBbEJBLE1BQWtCOztBQUN6RXZFLFdBQU8yQyxLQUFQLENBQWEsT0FBYixFQUFzQnNjLElBQXRCO0FBQ0EsUUFBTWpoQixjQUFjaWhCLEtBQUtqaEIsV0FBekI7QUFDQSxRQUFNbVQsaUJBQWlCOE4sS0FBSzlOLGNBQTVCO0FBQ0EsUUFBTWpJLFlBQVkrVixLQUFLL1YsU0FBdkI7QUFDQSxRQUFNN0QsVUFBVTRaLEtBQUs1WixPQUFyQjtBQUNBNkwsZUFBV2xULFdBQVgsRUFBd0JtVCxjQUF4QixFQUF3Q2pJLFNBQXhDLEVBQW1EN0QsT0FBbkQsRUFDR25FLElBREgsQ0FDUSxrQkFBVTtBQUNkLFVBQUlrSCxXQUFXMkksVUFBZixFQUEyQjtBQUN6QixlQUFPVCxJQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxLQUFWLEVBQWlCaFQsU0FBUyxvQ0FBMUIsRUFBckIsQ0FBUDtBQUNEO0FBQ0QsVUFBSXVLLFdBQVc0SSxRQUFmLEVBQXlCO0FBQ3ZCLGVBQU9WLElBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCLEVBQUNtSyxTQUFTLEtBQVYsRUFBaUJoVCxTQUFTLHFDQUExQixFQUFyQixDQUFQO0FBQ0Q7QUFDRHlTLFVBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCLEVBQUNtSyxTQUFTLElBQVYsRUFBZ0J6VCxNQUFNZ0wsTUFBdEIsRUFBckI7QUFDRCxLQVRILEVBVUdoSCxLQVZILENBVVMsaUJBQVM7QUFDZDBkLG9CQUFjek8sbUJBQWQsQ0FBa0N4RyxXQUFsQyxFQUErQ0QsRUFBL0MsRUFBbUR2SSxLQUFuRCxFQUEwRGlQLEdBQTFEO0FBQ0QsS0FaSDtBQWFELEdBbkJEO0FBb0JBaUYsTUFBSWdKLEdBQUosQ0FBUSxxQ0FBUixFQUErQyxrQkFBb0NqTyxHQUFwQyxFQUE0QztBQUFBLFFBQXpDMUcsRUFBeUMsVUFBekNBLEVBQXlDO0FBQUEsUUFBckNDLFdBQXFDLFVBQXJDQSxXQUFxQztBQUFBLFFBQXhCb1YsSUFBd0IsVUFBeEJBLElBQXdCO0FBQUEsUUFBbEIxYSxNQUFrQixVQUFsQkEsTUFBa0I7O0FBQ3pGLFFBQU0yRSxZQUFZM0UsT0FBTzJFLFNBQXpCO0FBQ0EsUUFBSTdELFVBQVVkLE9BQU9jLE9BQXJCO0FBQ0EsUUFBSUEsWUFBWSxNQUFoQixFQUF3QkEsVUFBVSxJQUFWO0FBQ3hCL0UsT0FBR21CLEtBQUgsQ0FBU29iLFlBQVQsQ0FBc0IzVCxTQUF0QixFQUFpQzdELE9BQWpDLEVBQ0duRSxJQURILENBQ1EscUJBQWE7QUFDakIsVUFBSSxDQUFDMmUsU0FBTCxFQUFnQjtBQUNkLGVBQU92UCxJQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxLQUFWLEVBQWlCaFQsU0FBUyx5QkFBMUIsRUFBckIsQ0FBUDtBQUNEO0FBQ0R5UyxVQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxJQUFWLEVBQWdCelQsTUFBTXlpQixTQUF0QixFQUFyQjtBQUNELEtBTkgsRUFPR3plLEtBUEgsQ0FPUyxpQkFBUztBQUNkMGQsb0JBQWN6TyxtQkFBZCxDQUFrQ3hHLFdBQWxDLEVBQStDRCxFQUEvQyxFQUFtRHZJLEtBQW5ELEVBQTBEaVAsR0FBMUQ7QUFDRCxLQVRIO0FBVUQsR0FkRDtBQWVBO0FBQ0FpRixNQUFJZ0osR0FBSixDQUFRLHVDQUFSLEVBQWlELGtCQUE4QmpPLEdBQTlCLEVBQXNDO0FBQUEsUUFBbkMxRyxFQUFtQyxVQUFuQ0EsRUFBbUM7QUFBQSxRQUEvQkMsV0FBK0IsVUFBL0JBLFdBQStCO0FBQUEsUUFBbEJ0RixNQUFrQixVQUFsQkEsTUFBa0I7O0FBQ3JGLFFBQU1qSCxPQUFPaUgsT0FBT2pILElBQXBCO0FBQ0EsUUFBTStILFVBQVVkLE9BQU9jLE9BQXZCO0FBQ0EvRSxPQUFHb0IsSUFBSCxDQUFRYyxPQUFSLENBQWdCLEVBQUNDLE9BQU8sRUFBQ25GLFVBQUQsRUFBTytILGdCQUFQLEVBQVIsRUFBaEIsRUFDR25FLElBREgsQ0FDUSxrQkFBVTtBQUNkLFVBQUlrSCxNQUFKLEVBQVk7QUFDVixlQUFPa0ksSUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIsRUFBQ21LLFNBQVMsSUFBVixFQUFnQnpULE1BQU0sSUFBdEIsRUFBckIsQ0FBUDtBQUNEO0FBQ0RrVCxVQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxJQUFWLEVBQWdCelQsTUFBTSxLQUF0QixFQUFyQjtBQUNELEtBTkgsRUFPR2dFLEtBUEgsQ0FPUyxpQkFBUztBQUNkMGQsb0JBQWN6TyxtQkFBZCxDQUFrQ3hHLFdBQWxDLEVBQStDRCxFQUEvQyxFQUFtRHZJLEtBQW5ELEVBQTBEaVAsR0FBMUQ7QUFDRCxLQVRIO0FBVUQsR0FiRDtBQWNELENBak9ELEM7Ozs7OztBQ2hCQSwrQzs7Ozs7Ozs7Ozs7OztBQ0FBLElBQU10USxTQUFTLG1CQUFBRCxDQUFRLENBQVIsQ0FBZjtBQUNBLElBQU1PLEtBQUssbUJBQUFQLENBQVEsQ0FBUixDQUFYO0FBQ0EsSUFBTTBZLFVBQVUsbUJBQUExWSxDQUFRLEVBQVIsQ0FBaEI7QUFDQSxJQUFNK2YsaUJBQWlCLG1CQUFBL2YsQ0FBUSxFQUFSLENBQXZCOztlQUMwRSxtQkFBQUEsQ0FBUSxDQUFSLEM7bUNBQWxFWCxVO0lBQWNJLG1CLHVCQUFBQSxtQjtJQUFxQkgsd0IsdUJBQUFBLHdCOztBQUMzQyxJQUFNUyxZQUFZLG1CQUFBQyxDQUFRLEVBQVIsQ0FBbEI7QUFDQSxJQUFNZ2dCLEtBQUtqZ0IsVUFBVWlnQixFQUFyQjs7QUFFQW5nQixPQUFPQyxPQUFQLEdBQWlCO0FBQ2ZrVCxTQURlLG1CQUNOdkssYUFETSxFQUNTa0csUUFEVCxFQUNtQkUsUUFEbkIsRUFDNkI7QUFDMUMsV0FBTyxJQUFJM0gsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdEMsVUFBSTZYLHVCQUFKO0FBQUEsVUFBb0JoRSxzQkFBcEI7QUFBQSxVQUFtQ2hlLG9CQUFuQztBQUNBO0FBQ0EsYUFBT3lhLFFBQVFsUSxZQUFSLENBQXFCQyxhQUFyQixFQUNKdEgsSUFESSxDQUNDLGNBQU07QUFDVmxCLGVBQU9tQixJQUFQLDZCQUFzQ3FILGNBQWNsTCxJQUFwRCxTQUE0RG9SLFFBQTVELEVBQXdFc0ssRUFBeEU7QUFDQWdILHlCQUFpQmhILEVBQWpCO0FBQ0E7QUFDQSxZQUFJeFEsY0FBY2UsWUFBbEIsRUFBZ0M7QUFDOUJ2SixpQkFBTzJDLEtBQVAsMkNBQXFENkYsY0FBY2UsWUFBbkU7QUFDQSxpQkFBT2pKLEdBQUdrQixPQUFILENBQVdnQixPQUFYLENBQW1CLEVBQUNDLE9BQU8sRUFBQ3pFLGFBQWF3SyxjQUFjZSxZQUE1QixFQUFSLEVBQW5CLENBQVA7QUFDRCxTQUhELE1BR087QUFDTHZKLGlCQUFPMkMsS0FBUCxDQUFhLDJDQUFiO0FBQ0EsaUJBQU8sSUFBUDtBQUNEO0FBQ0YsT0FaSSxFQWFKekIsSUFiSSxDQWFDLG1CQUFXO0FBQ2pCO0FBQ0U4YSx3QkFBZ0IsSUFBaEI7QUFDQWhlLHNCQUFjLElBQWQ7QUFDQSxZQUFJTixPQUFKLEVBQWE7QUFDWHNlLDBCQUFnQnRlLFFBQVF5VCxjQUF4QjtBQUNBblQsd0JBQWNOLFFBQVFNLFdBQXRCO0FBQ0Q7QUFDRGdDLGVBQU8yQyxLQUFQLHFCQUErQnFaLGFBQS9CO0FBQ0QsT0F0QkksRUF1Qko5YSxJQXZCSSxDQXVCQyxZQUFNO0FBQ1o7QUFDRSxZQUFNbWUsYUFBYTtBQUNqQi9oQixnQkFBYWtMLGNBQWNsTCxJQURWO0FBRWpCK0gsbUJBQWEyYSxlQUFlL0csUUFGWDtBQUdqQnBhLGlCQUFhMkosY0FBYzRHLFFBQWQsQ0FBdUJ2USxLQUhuQjtBQUlqQkYsdUJBQWE2SixjQUFjNEcsUUFBZCxDQUF1QnpRLFdBSm5CO0FBS2pCd1IsbUJBQWEzSCxjQUFjK0csYUFMVjtBQU1qQlUsb0JBQWdCK1AsZUFBZXZGLElBQS9CLFNBQXVDdUYsZUFBZXhGLElBTnJDO0FBT2pCdEssa0JBQWEsQ0FQSTtBQVFqQnhCLDRCQVJpQjtBQVNqQkMsb0JBQWFuRyxjQUFjMEcsU0FUVjtBQVVqQk4sNEJBVmlCO0FBV2pCVixnQkFBYTFGLGNBQWM0RyxRQUFkLENBQXVCbEI7QUFYbkIsU0FBbkI7QUFhQTtBQUNBLFlBQU0rUixjQUFjO0FBQ2xCM2lCLGdCQUFha0wsY0FBY2xMLElBRFQ7QUFFbEIrSCxtQkFBYTJhLGVBQWUvRyxRQUZWO0FBR2xCcGEsaUJBQWEySixjQUFjNEcsUUFBZCxDQUF1QnZRLEtBSGxCO0FBSWxCRix1QkFBYTZKLGNBQWM0RyxRQUFkLENBQXVCelEsV0FKbEI7QUFLbEJ3UixtQkFBYTNILGNBQWMrRyxhQUxUO0FBTWxCM1EscUJBQWE0SixjQUFjNEcsUUFBZCxDQUF1QnhRLFNBTmxCO0FBT2xCcVIsb0JBQWdCK1AsZUFBZXZGLElBQS9CLFNBQXVDdUYsZUFBZXhGLElBUHBDO0FBUWxCdEssa0JBQWEsQ0FSSztBQVNsQkUsdUJBQWF4QixRQVRLO0FBVWxCVixnQkFBYTFGLGNBQWM0RyxRQUFkLENBQXVCbEIsSUFWbEI7QUFXbEIxRSxrQkFBYWhCLGNBQWMyRyxHQVhUO0FBWWxCNk0sc0NBWmtCO0FBYWxCaGU7QUFia0IsU0FBcEI7QUFlQTtBQUNBLFlBQU1raUIsaUJBQWlCO0FBQ3JCNWlCLGdCQUFTa0wsY0FBY2xMLElBREY7QUFFckIrSCxtQkFBUzJhLGVBQWUvRztBQUZILFNBQXZCO0FBSUE7QUFDQSxlQUFPaFMsUUFBUUMsR0FBUixDQUFZLENBQUM1RyxHQUFHNkIsTUFBSCxDQUFVN0IsR0FBR29CLElBQWIsRUFBbUIyZCxVQUFuQixFQUErQmEsY0FBL0IsRUFBK0MsTUFBL0MsQ0FBRCxFQUF5RDVmLEdBQUc2QixNQUFILENBQVU3QixHQUFHbUIsS0FBYixFQUFvQndlLFdBQXBCLEVBQWlDQyxjQUFqQyxFQUFpRCxPQUFqRCxDQUF6RCxDQUFaLENBQVA7QUFDRCxPQTdESSxFQThESmhmLElBOURJLENBOERDLGdCQUFtQjtBQUFBO0FBQUEsWUFBakJqRSxJQUFpQjtBQUFBLFlBQVg4ZSxLQUFXOztBQUN2Qi9iLGVBQU8yQyxLQUFQLENBQWEsNkNBQWI7QUFDQSxlQUFPc0UsUUFBUUMsR0FBUixDQUFZLENBQUNqSyxLQUFLa2pCLFFBQUwsQ0FBY3BFLEtBQWQsQ0FBRCxFQUF1QkEsTUFBTXFFLE9BQU4sQ0FBY25qQixJQUFkLENBQXZCLENBQVosQ0FBUDtBQUNELE9BakVJLEVBa0VKaUUsSUFsRUksQ0FrRUMsWUFBTTtBQUNWbEIsZUFBTzJDLEtBQVAsQ0FBYSxnREFBYjtBQUNBdUYsZ0JBQVE4WCxjQUFSLEVBRlUsQ0FFZTtBQUMxQixPQXJFSSxFQXNFSjVlLEtBdEVJLENBc0VFLGlCQUFTO0FBQ2RwQixlQUFPcUIsS0FBUCxDQUFhLGVBQWIsRUFBOEJBLEtBQTlCO0FBQ0F5ZSx1QkFBZXJRLG1CQUFmLENBQW1DakgsY0FBYzBHLFNBQWpELEVBRmMsQ0FFK0M7QUFDN0QvRyxlQUFPOUcsS0FBUDtBQUNELE9BMUVJLENBQVA7QUEyRUQsS0E5RU0sQ0FBUDtBQStFRCxHQWpGYztBQWtGZnVkLHNCQWxGZSxnQ0FrRk90aEIsSUFsRlAsRUFrRmE7QUFDMUIsUUFBTStpQixpQkFBaUJoaEIsNEJBQTRCLEVBQW5EO0FBQ0FnaEIsbUJBQWU5VCxJQUFmLENBQW9CL00sbUJBQXBCO0FBQ0E7QUFDQSxXQUFPYyxHQUFHbUIsS0FBSCxDQUNKMlosT0FESSxDQUNJO0FBQ1BrRixrQkFBWSxDQUFDLFNBQUQsQ0FETDtBQUVQN2QsYUFBWTtBQUNWbkYsa0JBRFU7QUFFVjZTLHFDQUNHNFAsR0FBR1EsRUFETixFQUNXRixjQURYO0FBRlU7QUFGTCxLQURKLEVBVUpuZixJQVZJLENBVUMsa0JBQVU7QUFDZCxVQUFJa0gsT0FBTzBGLE1BQVAsSUFBaUIsQ0FBckIsRUFBd0I7QUFDdEIsY0FBTSxJQUFJakgsS0FBSixDQUFVLDhCQUFWLENBQU47QUFDRDtBQUNELGFBQU92SixJQUFQO0FBQ0QsS0FmSSxFQWdCSjhELEtBaEJJLENBZ0JFLGlCQUFTO0FBQ2QsWUFBTUMsS0FBTjtBQUNELEtBbEJJLENBQVA7QUFtQkQsR0F6R2M7QUEwR2Z3ZCwwQkExR2Usb0NBMEdXdmhCLElBMUdYLEVBMEdpQjtBQUM5QixXQUFPZ0QsR0FBR2tCLE9BQUgsQ0FDSjRaLE9BREksQ0FDSTtBQUNQM1ksYUFBTyxFQUFFekUsYUFBYVYsSUFBZjtBQURBLEtBREosRUFJSjRELElBSkksQ0FJQyxrQkFBVTtBQUNkLFVBQUlrSCxPQUFPMEYsTUFBUCxJQUFpQixDQUFyQixFQUF3QjtBQUN0QixjQUFNLElBQUlqSCxLQUFKLENBQVUsdUNBQVYsQ0FBTjtBQUNEO0FBQ0QsYUFBT3ZKLElBQVA7QUFDRCxLQVRJLEVBVUo4RCxLQVZJLENBVUUsaUJBQVM7QUFDZCxZQUFNQyxLQUFOO0FBQ0QsS0FaSSxDQUFQO0FBYUQ7QUF4SGMsQ0FBakIsQzs7Ozs7O0FDUkEsK0I7Ozs7Ozs7OztBQ0FBLElBQU1mLEtBQUssbUJBQUFQLENBQVEsQ0FBUixDQUFYO0FBQ0EsSUFBTUMsU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7O0FBRUFILE9BQU9DLE9BQVAsR0FBaUI7QUFDZmtmLGtCQURlLDRCQUNHL2dCLFdBREgsRUFDZ0IwRyxTQURoQixFQUMyQithLGVBRDNCLEVBQzRDNUksSUFENUMsRUFDa0Q7QUFDL0Q7QUFDQSxRQUFJLENBQUM3WSxXQUFELElBQWdCLENBQUMwRyxTQUFyQixFQUFnQztBQUM5QixhQUFPO0FBQ0wxRyxxQkFBZ0IsSUFEWDtBQUVMbVQsd0JBQWdCO0FBRlgsT0FBUDtBQUlEO0FBQ0Q7QUFDQSxRQUFJMEYsSUFBSixFQUFVO0FBQ1IsVUFBSTdZLGVBQWVBLGdCQUFnQjZZLEtBQUs3WSxXQUF4QyxFQUFxRDtBQUNuRCxjQUFNLElBQUk2SSxLQUFKLENBQVUsMkRBQVYsQ0FBTjtBQUNEO0FBQ0QsVUFBSW5DLGFBQWFBLGNBQWNtUyxLQUFLMUYsY0FBcEMsRUFBb0Q7QUFDbEQsY0FBTSxJQUFJdEssS0FBSixDQUFVLHlEQUFWLENBQU47QUFDRDtBQUNELGFBQU87QUFDTDdJLHFCQUFnQjZZLEtBQUs3WSxXQURoQjtBQUVMbVQsd0JBQWdCMEYsS0FBSzFGO0FBRmhCLE9BQVA7QUFJRDtBQUNEO0FBQ0EsUUFBSSxDQUFDc08sZUFBTCxFQUFzQixNQUFNLElBQUk1WSxLQUFKLENBQVUsOEJBQVYsQ0FBTjtBQUN0QixXQUFPakgsT0FBT0MsT0FBUCxDQUFlMmdCLDhCQUFmLENBQThDeGlCLFdBQTlDLEVBQTJEMEcsU0FBM0QsRUFBc0UrYSxlQUF0RSxDQUFQO0FBQ0QsR0F6QmM7QUEwQmZlLGdDQTFCZSwwQ0EwQmlCeGlCLFdBMUJqQixFQTBCOEIwRyxTQTFCOUIsRUEwQnlDK2IsWUExQnpDLEVBMEJ1RDtBQUNwRSxXQUFPLElBQUl4WixPQUFKLENBQVksVUFBQ2lCLE9BQUQsRUFBVUMsTUFBVixFQUFxQjtBQUN0QztBQUNBLFVBQUk0USxvQkFBSjtBQUNBO0FBQ0EsVUFBSTJILG9CQUFvQixFQUF4QjtBQUNBLFVBQUkxaUIsV0FBSixFQUFpQjBpQixrQkFBa0IsYUFBbEIsSUFBbUMxaUIsV0FBbkM7QUFDakIsVUFBSTBHLFNBQUosRUFBZWdjLGtCQUFrQixnQkFBbEIsSUFBc0NoYyxTQUF0QztBQUNmO0FBQ0FwRSxTQUFHa0IsT0FBSCxDQUNHZ0IsT0FESCxDQUNXO0FBQ1BDLGVBQU9pZTtBQURBLE9BRFgsRUFJR3hmLElBSkgsQ0FJUSxtQkFBVztBQUNmLFlBQUksQ0FBQ3hELE9BQUwsRUFBYztBQUNac0MsaUJBQU8yQyxLQUFQLENBQWEsa0JBQWI7QUFDQSxnQkFBTSxJQUFJa0UsS0FBSixDQUFVLCtEQUFWLENBQU47QUFDRDtBQUNEa1Msc0JBQWNyYixRQUFRNmdCLEdBQVIsRUFBZDtBQUNBdmUsZUFBTzJDLEtBQVAsQ0FBYSxlQUFiLEVBQThCb1csV0FBOUI7QUFDQSxlQUFPelksR0FBR3NCLElBQUgsQ0FBUVksT0FBUixDQUFnQjtBQUNyQkMsaUJBQU8sRUFBRXFXLFVBQVVDLFlBQVkvYSxXQUFaLENBQXdCd1AsU0FBeEIsQ0FBa0MsQ0FBbEMsQ0FBWjtBQURjLFNBQWhCLENBQVA7QUFHRCxPQWRILEVBZUd0TSxJQWZILENBZVEsZ0JBQVE7QUFDWixZQUFJLENBQUMyVixJQUFMLEVBQVc7QUFDVDdXLGlCQUFPMkMsS0FBUCxDQUFhLGVBQWI7QUFDQSxnQkFBTSxJQUFJa0UsS0FBSixDQUFVLCtEQUFWLENBQU47QUFDRDtBQUNELGVBQU9nUSxLQUFLMkcsZUFBTCxDQUFxQmlELFlBQXJCLENBQVA7QUFDRCxPQXJCSCxFQXNCR3ZmLElBdEJILENBc0JRLG1CQUFXO0FBQ2YsWUFBSSxDQUFDbWQsT0FBTCxFQUFjO0FBQ1pyZSxpQkFBTzJDLEtBQVAsQ0FBYSxvQkFBYjtBQUNBLGdCQUFNLElBQUlrRSxLQUFKLENBQVUsK0RBQVYsQ0FBTjtBQUNEO0FBQ0Q3RyxlQUFPMkMsS0FBUCxDQUFhLDRCQUFiO0FBQ0F1RixnQkFBUTZRLFdBQVI7QUFDRCxPQTdCSCxFQThCRzNYLEtBOUJILENBOEJTLGlCQUFTO0FBQ2QrRyxlQUFPOUcsS0FBUDtBQUNELE9BaENIO0FBaUNELEtBekNNLENBQVA7QUEwQ0Q7QUFyRWMsQ0FBakIsQzs7Ozs7Ozs7O0FDSEEsSUFBTXNmLGtCQUFrQixFQUF4Qjs7QUFFQS9nQixPQUFPQyxPQUFQLEdBQWlCO0FBQ2ZpUiw4QkFEZSx3Q0FDZTlTLFdBRGYsRUFDNEI0VCxrQkFENUIsRUFDZ0RnUCxNQURoRCxFQUN3RGpiLElBRHhELEVBQzhEO0FBQzNFLFFBQU1rYixhQUFhamhCLE9BQU9DLE9BQVAsQ0FBZWloQixtQkFBZixDQUFtQ0YsTUFBbkMsQ0FBbkI7QUFDQSxRQUFNRyxpQkFBaUJuaEIsT0FBT0MsT0FBUCxDQUFlbWhCLGdCQUFmLENBQWdDcmIsSUFBaEMsQ0FBdkI7QUFDQSxRQUFNc2IsV0FBVztBQUNmampCLG1CQUFvQkEsV0FETDtBQUVmNFQsMEJBQW9CQSxrQkFGTDtBQUdmZ1AsY0FBb0JoaEIsT0FBT0MsT0FBUCxDQUFlcWhCLHFCQUFmLENBQXFDTixNQUFyQyxFQUE2Q0csY0FBN0MsQ0FITDtBQUlmSSxvQkFBb0J2aEIsT0FBT0MsT0FBUCxDQUFldWhCLHFCQUFmLENBQXFDTCxjQUFyQyxDQUpMO0FBS2ZNLG1CQUFvQk4sY0FMTDtBQU1mTyxnQkFBb0IxaEIsT0FBT0MsT0FBUCxDQUFlMGhCLGlCQUFmLENBQWlDVixVQUFqQyxFQUE2Q0UsY0FBN0MsQ0FOTDtBQU9mRixrQkFBb0JBLFVBUEw7QUFRZlcsb0JBQW9CNWhCLE9BQU9DLE9BQVAsQ0FBZTRoQixvQkFBZixDQUFvQ2IsTUFBcEM7QUFSTCxLQUFqQjtBQVVBLFdBQU9LLFFBQVA7QUFDRCxHQWZjO0FBZ0JmRCxrQkFoQmUsNEJBZ0JHcmIsSUFoQkgsRUFnQlM7QUFDdEIsUUFBSUEsSUFBSixFQUFVO0FBQ1IsYUFBTytiLFNBQVMvYixJQUFULENBQVA7QUFDRDtBQUNELFdBQU8sQ0FBUDtBQUNELEdBckJjO0FBc0JmdWIsdUJBdEJlLGlDQXNCUU4sTUF0QlIsRUFzQmdCZSxVQXRCaEIsRUFzQjRCO0FBQ3pDLFFBQUksQ0FBQ2YsTUFBTCxFQUFhO0FBQ1gsYUFBTyxFQUFQLENBRFcsQ0FDQztBQUNiO0FBQ0Q7QUFDQTtBQUNBLFFBQU1nQixrQkFBa0IsQ0FBQ0QsYUFBYSxDQUFkLElBQW1CaEIsZUFBM0M7QUFDQSxRQUFNa0IsZ0JBQWdCRCxrQkFBa0JqQixlQUF4QztBQUNBLFFBQU1tQixlQUFlbEIsT0FBTy9TLEtBQVAsQ0FBYStULGVBQWIsRUFBOEJDLGFBQTlCLENBQXJCO0FBQ0EsV0FBT0MsWUFBUDtBQUNELEdBaENjO0FBaUNmaEIscUJBakNlLCtCQWlDTUYsTUFqQ04sRUFpQ2M7QUFDM0IsUUFBSSxDQUFDQSxNQUFMLEVBQWE7QUFDWCxhQUFPLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxVQUFNbUIsY0FBY25CLE9BQU85UyxNQUEzQjtBQUNBLFVBQUlpVSxjQUFjcEIsZUFBbEIsRUFBbUM7QUFDakMsZUFBTyxDQUFQO0FBQ0Q7QUFDRCxVQUFNcUIsWUFBWUMsS0FBS0MsS0FBTCxDQUFXSCxjQUFjcEIsZUFBekIsQ0FBbEI7QUFDQSxVQUFNd0IsWUFBWUosY0FBY3BCLGVBQWhDO0FBQ0EsVUFBSXdCLGNBQWMsQ0FBbEIsRUFBcUI7QUFDbkIsZUFBT0gsU0FBUDtBQUNEO0FBQ0QsYUFBT0EsWUFBWSxDQUFuQjtBQUNEO0FBQ0YsR0FoRGM7QUFpRGZaLHVCQWpEZSxpQ0FpRFFDLFdBakRSLEVBaURxQjtBQUNsQyxRQUFJQSxnQkFBZ0IsQ0FBcEIsRUFBdUI7QUFDckIsYUFBTyxJQUFQO0FBQ0Q7QUFDRCxXQUFPQSxjQUFjLENBQXJCO0FBQ0QsR0F0RGM7QUF1RGZFLG1CQXZEZSw2QkF1RElWLFVBdkRKLEVBdURnQlEsV0F2RGhCLEVBdUQ2QjtBQUMxQyxRQUFJQSxnQkFBZ0JSLFVBQXBCLEVBQWdDO0FBQzlCLGFBQU8sSUFBUDtBQUNEO0FBQ0QsV0FBT1EsY0FBYyxDQUFyQjtBQUNELEdBNURjO0FBNkRmSSxzQkE3RGUsZ0NBNkRPYixNQTdEUCxFQTZEZTtBQUM1QixRQUFJLENBQUNBLE1BQUwsRUFBYTtBQUNYLGFBQU8sQ0FBUDtBQUNEO0FBQ0QsV0FBT0EsT0FBTzlTLE1BQWQ7QUFDRDtBQWxFYyxDQUFqQixDOzs7Ozs7Ozs7ZUNGMEIsbUJBQUEvTixDQUFRLENBQVIsQztJQUFUZCxJLFlBQVRELE87O0FBQ1IsSUFBTW9qQixtQkFBbUIsbUJBQUFyaUIsQ0FBUSxFQUFSLENBQXpCOztBQUVBSCxPQUFPQyxPQUFQLEdBQWlCLFVBQUMwVixHQUFELEVBQVM7QUFDeEI7QUFDQUEsTUFBSWdKLEdBQUosQ0FBUSxHQUFSLEVBQWEsVUFBQ2xNLEdBQUQsRUFBTS9CLEdBQU4sRUFBYztBQUN6QjhSLHFCQUFpQi9QLEdBQWpCLEVBQXNCL0IsR0FBdEI7QUFDRCxHQUZEO0FBR0E7QUFDQWlGLE1BQUlnSixHQUFKLENBQVEsUUFBUixFQUFrQixVQUFDbE0sR0FBRCxFQUFNL0IsR0FBTixFQUFjO0FBQzlCOFIscUJBQWlCL1AsR0FBakIsRUFBc0IvQixHQUF0QjtBQUNELEdBRkQ7QUFHQTtBQUNBaUYsTUFBSWdKLEdBQUosQ0FBUSxRQUFSLEVBQWtCLFVBQUNsTSxHQUFELEVBQU0vQixHQUFOLEVBQWM7QUFDOUI4UixxQkFBaUIvUCxHQUFqQixFQUFzQi9CLEdBQXRCO0FBQ0QsR0FGRDtBQUdBO0FBQ0FpRixNQUFJZ0osR0FBSixDQUFRLFdBQVIsRUFBcUIsVUFBQ2xNLEdBQUQsRUFBTS9CLEdBQU4sRUFBYztBQUNqQ0EsUUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCK1UsUUFBaEIsQ0FBeUIsVUFBekI7QUFDRCxHQUZEO0FBR0E0QyxNQUFJZ0osR0FBSixDQUFRLFVBQVIsRUFBb0IsVUFBQ2xNLEdBQUQsRUFBTS9CLEdBQU4sRUFBYztBQUNoQzhSLHFCQUFpQi9QLEdBQWpCLEVBQXNCL0IsR0FBdEI7QUFDRCxHQUZEO0FBR0E7QUFDQWlGLE1BQUlnSixHQUFKLENBQVEsTUFBUixFQUFnQixVQUFDbE0sR0FBRCxFQUFNL0IsR0FBTixFQUFjO0FBQzVCOFIscUJBQWlCL1AsR0FBakIsRUFBc0IvQixHQUF0QjtBQUNELEdBRkQ7QUFHQTtBQUNBaUYsTUFBSWdKLEdBQUosQ0FBUSx1QkFBUixFQUFpQyxnQkFBYWpPLEdBQWIsRUFBcUI7QUFBQSxRQUFsQi9MLE1BQWtCLFFBQWxCQSxNQUFrQjs7QUFDcEQsUUFBTWMsVUFBVWQsT0FBT2MsT0FBdkI7QUFDQSxRQUFNL0gsT0FBT2lILE9BQU9qSCxJQUFwQjtBQUNBO0FBQ0FnVCxRQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0J5a0IsTUFBaEIsQ0FBdUIsT0FBdkIsRUFBZ0MsRUFBRUMsUUFBUSxPQUFWLEVBQW1CcmpCLFVBQW5CLEVBQXlCb0csZ0JBQXpCLEVBQWtDL0gsVUFBbEMsRUFBaEM7QUFDRCxHQUxEO0FBTUQsQ0EvQkQsQzs7Ozs7Ozs7Ozs7OztrQkM0QmUsWUFBd0M7QUFBQSxNQUE5Qm1LLEtBQThCLHVFQUF0QjhhLFlBQXNCO0FBQUEsTUFBUm5GLE1BQVE7O0FBQ3JELFVBQVFBLE9BQU9sZ0IsSUFBZjtBQUNFLFNBQUtGLFFBQVFHLGFBQWI7QUFDRSxhQUFPMkUsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQkQsWUFBbEIsRUFBZ0MsRUFBRztBQUN4Q3RsQixjQUFNbWdCLE9BQU9oZ0I7QUFEd0IsT0FBaEMsQ0FBUDtBQUdGLFNBQUtKLFFBQVFLLFVBQWI7QUFDRSxhQUFPa2xCLFlBQVA7QUFDRixTQUFLdmxCLFFBQVFRLGVBQWI7QUFDRSxhQUFPc0UsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLEtBQWxCLEVBQXlCO0FBQzlCMkgsa0JBQVV0TixPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsTUFBTTJILFFBQXhCLHNCQUNQZ08sT0FBT2hnQixJQUFQLENBQVlFLElBREwsRUFDWThmLE9BQU9oZ0IsSUFBUCxDQUFZRyxLQUR4QjtBQURvQixPQUF6QixDQUFQO0FBS0YsU0FBS1AsUUFBUVMsWUFBYjtBQUNFLGFBQU9xRSxPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsS0FBbEIsRUFBeUI7QUFDOUJzVSxlQUFPcUIsT0FBT2hnQjtBQURnQixPQUF6QixDQUFQO0FBR0YsU0FBS0osUUFBUVcsc0JBQWI7QUFDRSxhQUFPbUUsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLEtBQWxCLEVBQXlCO0FBQzlCZ2IsMEJBQWtCckYsT0FBTzFmO0FBREssT0FBekIsQ0FBUDtBQUdGLFNBQUtWLFFBQVFjLHFCQUFiO0FBQ0UsYUFBT2dFLE9BQU8wZ0IsTUFBUCxDQUFjLEVBQWQsRUFBa0IvYSxLQUFsQixFQUF5QjtBQUM5QjdKLGdCQUFRd2YsT0FBT2hnQjtBQURlLE9BQXpCLENBQVA7QUFHRixTQUFLSixRQUFRZSxZQUFiO0FBQ0UsYUFBTytELE9BQU8wZ0IsTUFBUCxDQUFjLEVBQWQsRUFBa0IvYSxLQUFsQixFQUF5QjtBQUM5QnBHLGVBQU9TLE9BQU8wZ0IsTUFBUCxDQUFjLEVBQWQsRUFBa0IvYSxNQUFNcEcsS0FBeEIsc0JBQ0orYixPQUFPaGdCLElBQVAsQ0FBWUUsSUFEUixFQUNlOGYsT0FBT2hnQixJQUFQLENBQVlHLEtBRDNCO0FBRHVCLE9BQXpCLENBQVA7QUFLRixTQUFLUCxRQUFRaUIsdUJBQWI7QUFDRSxhQUFPNkQsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLEtBQWxCLEVBQXlCO0FBQzlCaWIseUJBQWlCdEYsT0FBT2hnQjtBQURNLE9BQXpCLENBQVA7QUFHRixTQUFLSixRQUFRbUIsc0JBQWI7QUFDRSxhQUFPMkQsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLEtBQWxCLEVBQXlCO0FBQzlCdkosNEJBQW9Ca2YsT0FBT2hnQjtBQURHLE9BQXpCLENBQVA7QUFHRixTQUFLSixRQUFRb0IsYUFBYjtBQUNFLGFBQU8wRCxPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsS0FBbEIsRUFBeUI7QUFDOUI3SSxtQkFBV3dlLE9BQU9oZ0I7QUFEWSxPQUF6QixDQUFQO0FBR0Y7QUFDRSxhQUFPcUssS0FBUDtBQTVDSjtBQThDRCxDOztBQTlFRDs7SUFBWXpLLE87O0FBQ1o7Ozs7OztlQUN1QixtQkFBQStDLENBQVEsQ0FBUixDO0lBQWZYLFUsWUFBQUEsVTs7QUFFUixJQUFNbWpCLGVBQWU7QUFDbkJqakIsWUFBb0JGLFdBQVdFLFFBRFo7QUFFbkJDLG1CQUFvQkgsV0FBV0csZUFGWjtBQUduQmtqQixvQkFBb0IsS0FIRDtBQUluQkMsdURBSm1CO0FBS25CeGtCLHNCQUFvQixLQUxEO0FBTW5CTixVQUFvQjtBQUNsQkEsWUFBUyxJQURTO0FBRWxCQyxhQUFTO0FBRlMsR0FORDtBQVVuQndELFNBQU87QUFDTHBFLFVBQWUsSUFEVjtBQUVMNkosU0FBZSxJQUZWO0FBR0xwSixhQUFlLElBSFY7QUFJTGlsQixtQkFBZTtBQUpWLEdBVlk7QUFnQm5CMWxCLFFBQVUsSUFoQlM7QUFpQm5COGUsU0FBVSxFQWpCUztBQWtCbkIzTSxZQUFVO0FBQ1J2USxXQUFhLEVBREw7QUFFUkYsaUJBQWEsRUFGTDtBQUdSd1AsYUFBYSxFQUhMO0FBSVJELFVBQWE7QUFKTCxHQWxCUztBQXdCbkJ0UCxhQUFXO0FBeEJRLENBQXJCLEM7Ozs7Ozs7Ozs7Ozs7a0JDTWUsWUFBd0M7QUFBQSxNQUE5QjZJLEtBQThCLHVFQUF0QjhhLFlBQXNCO0FBQUEsTUFBUm5GLE1BQVE7O0FBQ3JELFVBQVFBLE9BQU9sZ0IsSUFBZjtBQUNFLFNBQUtGLFFBQVEwTyxjQUFiO0FBQ0UsYUFBTzVKLE9BQU8wZ0IsTUFBUCxDQUFjLEVBQWQsRUFBa0IvYSxLQUFsQixFQUF5QjtBQUM5QnpFLHlCQUFpQm9hLE9BQU9oZ0I7QUFETSxPQUF6QixDQUFQO0FBR0Y7QUFDRSxhQUFPcUssS0FBUDtBQU5KO0FBUUQsQzs7QUFuQkQ7O0lBQVl6SyxPOzs7O0FBRVosSUFBTXVsQixlQUFlO0FBQ25CdmYsbUJBQWlCO0FBQ2YxRixVQUFTLElBRE07QUFFZjRGLGFBQVMsSUFGTTtBQUdmRSxZQUFTO0FBSE07QUFERSxDQUFyQixDOzs7Ozs7Ozs7Ozs7O2tCQ2dCZSxZQUF3QztBQUFBLE1BQTlCcUUsS0FBOEIsdUVBQXRCOGEsWUFBc0I7QUFBQSxNQUFSbkYsTUFBUTs7QUFDckQsVUFBUUEsT0FBT2xnQixJQUFmO0FBQ0U7QUFDQSxTQUFLRixRQUFReUgsYUFBYjtBQUNFLGFBQU8zQyxPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsS0FBbEIsRUFBeUI7QUFDOUJsQixpQkFBU3pFLE9BQU8wZ0IsTUFBUCxDQUFjLEVBQWQsRUFBa0IvYSxNQUFNbEIsT0FBeEIsRUFBaUM7QUFDeENsRixpQkFBTytiLE9BQU9oZ0I7QUFEMEIsU0FBakM7QUFEcUIsT0FBekIsQ0FBUDtBQUtGLFNBQUtKLFFBQVFrSSxjQUFiO0FBQ0UsYUFBT3BELE9BQU8wZ0IsTUFBUCxDQUFjLEVBQWQsRUFBa0IvYSxLQUFsQixFQUF5QjtBQUM5QmxCLGlCQUFTekUsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLE1BQU1sQixPQUF4QixFQUFpQztBQUN4Q3JKLGdCQUFNa2dCLE9BQU9oZ0IsSUFBUCxDQUFZdUgsV0FEc0I7QUFFeENHLGNBQU1zWSxPQUFPaGdCLElBQVAsQ0FBWXdIO0FBRnNCLFNBQWpDO0FBRHFCLE9BQXpCLENBQVA7QUFNRjtBQUNBLFNBQUs1SCxRQUFRb0ksZ0JBQWI7QUFDRSxhQUFPdEQsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLEtBQWxCLEVBQXlCO0FBQzlCSixxQkFBYXZGLE9BQU8wZ0IsTUFBUCxDQUFjLEVBQWQsRUFBa0IvYSxNQUFNSixXQUF4QixzQkFDVitWLE9BQU9oZ0IsSUFBUCxDQUFZMEgsRUFERixFQUNPO0FBQ2hCekQsaUJBQU8rYixPQUFPaGdCLElBQVAsQ0FBWWlFLEtBREg7QUFFaEI4RCxlQUFPaVksT0FBT2hnQixJQUFQLENBQVkrSDtBQUZILFNBRFA7QUFEaUIsT0FBekIsQ0FBUDtBQVFGO0FBQ0EsU0FBS25JLFFBQVF1SSxTQUFiO0FBQ0UsYUFBT3pELE9BQU8wZ0IsTUFBUCxDQUFjLEVBQWQsRUFBa0IvYSxLQUFsQixFQUF5QjtBQUM5QkYsbUJBQVd6RixPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsTUFBTUYsU0FBeEIsc0JBQ1I2VixPQUFPaGdCLElBQVAsQ0FBWTBILEVBREosRUFDUztBQUNoQnpELGlCQUFXK2IsT0FBT2hnQixJQUFQLENBQVlpRSxLQURQO0FBRWhCL0QsZ0JBQVc4ZixPQUFPaGdCLElBQVAsQ0FBWUUsSUFGUDtBQUdoQitILG1CQUFXK1gsT0FBT2hnQixJQUFQLENBQVlpSSxPQUhQO0FBSWhCbkMsbUJBQVdrYSxPQUFPaGdCLElBQVAsQ0FBWThGLE9BSlA7QUFLaEJvQyxxQkFBVzhYLE9BQU9oZ0IsSUFBUCxDQUFZa0k7QUFMUCxTQURUO0FBRG1CLE9BQXpCLENBQVA7QUFXRjtBQUNBLFNBQUt0SSxRQUFReUksV0FBYjtBQUNFLGFBQU8zRCxPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsS0FBbEIsRUFBeUI7QUFDOUJtYixxQkFBYTlnQixPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsTUFBTW1iLFdBQXhCLHNCQUNWeEYsT0FBT2hnQixJQUFQLENBQVkwSCxFQURGLEVBQ087QUFDaEJ4SCxnQkFBWThmLE9BQU9oZ0IsSUFBUCxDQUFZRSxJQURSO0FBRWhCOEYsa0JBQVlnYSxPQUFPaGdCLElBQVAsQ0FBWWdHLE1BRlI7QUFHaEJGLG1CQUFZa2EsT0FBT2hnQixJQUFQLENBQVk4RixPQUhSO0FBSWhCc0Msc0JBQVk0WCxPQUFPaGdCLElBQVAsQ0FBWW9JO0FBSlIsU0FEUDtBQURpQixPQUF6QixDQUFQO0FBVUYsU0FBS3hJLFFBQVE4SSw2QkFBYjtBQUNFLGFBQU9oRSxPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsS0FBbEIsRUFBeUI7QUFDOUJtYixxQkFBYTlnQixPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsTUFBTW1iLFdBQXhCLHNCQUNWeEYsT0FBT2hnQixJQUFQLENBQVl5SSxhQURGLEVBQ2tCL0QsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLE1BQU1tYixXQUFOLENBQWtCeEYsT0FBT2hnQixJQUFQLENBQVl5SSxhQUE5QixDQUFsQixFQUFnRTtBQUMzRkwsc0JBQVk0WCxPQUFPaGdCLElBQVAsQ0FBWW9JO0FBRG1FLFNBQWhFLENBRGxCO0FBRGlCLE9BQXpCLENBQVA7QUFPRjtBQUNBLFNBQUt4SSxRQUFRZ0osd0JBQWI7QUFDRSxhQUFPbEUsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLEtBQWxCLEVBQXlCO0FBQzlCNE0sc0JBQWN2UyxPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsTUFBTTRNLFlBQXhCLEVBQXNDO0FBQ2xEelcsa0JBQVF3ZixPQUFPaGdCO0FBRG1DLFNBQXRDO0FBRGdCLE9BQXpCLENBQVA7QUFLRixTQUFLSixRQUFRaUosbUJBQWI7QUFDRSxhQUFPbkUsT0FBTzBnQixNQUFQLENBQWMsRUFBZCxFQUFrQi9hLEtBQWxCLEVBQXlCO0FBQzlCNE0sc0JBQWN2UyxPQUFPMGdCLE1BQVAsQ0FBYyxFQUFkLEVBQWtCL2EsTUFBTTRNLFlBQXhCLEVBQXNDO0FBQ2xEaFQsaUJBQVErYixPQUFPaGdCLElBRG1DO0FBRWxEUTtBQUZrRCxTQUF0QztBQURnQixPQUF6QixDQUFQO0FBTUY7QUFDRSxhQUFPNkosS0FBUDtBQXpFSjtBQTJFRCxDOztBQTlGRDs7SUFBWXpLLE87O0FBQ1o7Ozs7OztBQUVBLElBQU11bEIsZUFBZTtBQUNuQmhjLFdBQVM7QUFDUGxGLFdBQU8sSUFEQTtBQUVQbkUsVUFBTyxJQUZBO0FBR1A0SCxRQUFPO0FBSEEsR0FEVTtBQU1uQnVDLGVBQWMsRUFOSztBQU9uQnViLGVBQWMsRUFQSztBQVFuQnJiLGFBQWMsRUFSSztBQVNuQjhNLGdCQUFjO0FBQ1poVCxXQUFRLElBREk7QUFFWnpEO0FBRlk7QUFUSyxDQUFyQixDOzs7Ozs7Ozs7Ozs7O2tCQ3lCZSxZQUF3QztBQUFBLE1BQTlCNkosS0FBOEIsdUVBQXRCOGEsWUFBc0I7QUFBQSxNQUFSbkYsTUFBUTs7QUFDckQsVUFBUUEsT0FBT2xnQixJQUFmO0FBQ0U7QUFDRSxhQUFPdUssS0FBUDtBQUZKO0FBSUQsQzs7QUFqQ0QsSUFBTW9iLGFBQWEsbUJBQUE5aUIsQ0FBUSxDQUFSLENBQW5COztJQUljK2lCLGlCLEdBWVZELFUsQ0FiRnJrQixTLENBQ0VDLFE7NEJBWUFva0IsVSxDQVZGbmtCLGE7SUFDYXlILGdCLHlCQUFYdkgsUztJQUNhc0gsa0IseUJBQWJ2SCxXOzBCQVFBa2tCLFUsQ0FORjdqQixPO0lBQ0VMLFcsdUJBQUFBLFc7SUFDQU0sSSx1QkFBQUEsSTtJQUNBSixLLHVCQUFBQSxLO0lBQ0FNLE8sdUJBQUFBLE87OztBQUlKLElBQU1vakIsZUFBZTtBQUNuQjVqQiwwQkFEbUI7QUFFbkJta0Isc0NBRm1CO0FBR25CN2pCLFlBSG1CO0FBSW5CSixjQUptQjtBQUtuQk0sa0JBTG1CO0FBTW5CK0csd0NBTm1CO0FBT25CQztBQVBtQixDQUFyQixDOzs7Ozs7QUNsQkEscUM7Ozs7Ozs7Ozs7Ozs7OztBQ0FBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7Ozs7Ozs7SUFFTTRjLFE7Ozs7Ozs7Ozs7OzZCQUNNO0FBQ1IsYUFDRTtBQUFBO0FBQUEsVUFBSyxXQUFXLHNDQUFoQjtBQUNFLDBEQURGO0FBRUUsNkRBRkY7QUFHRTtBQUFBO0FBQUEsWUFBSyxXQUFXLGtEQUFoQjtBQUNFO0FBREY7QUFIRixPQURGO0FBU0Q7Ozs7RUFYb0IsZ0JBQU1oVyxTOztBQVk1Qjs7a0JBRWNnVyxROzs7Ozs7Ozs7Ozs7Ozs7QUNuQmY7Ozs7QUFDQTs7OztBQUNBOzs7O0FBRUE7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7SUFFTUMsRzs7Ozs7Ozs7Ozs7NkJBQ007QUFDUjtBQURRLG1CQUU0RixLQUFLcFgsS0FGakc7QUFBQSxVQUVBMUYsa0JBRkEsVUFFQUEsa0JBRkE7QUFBQSxVQUVvQkMsZ0JBRnBCLFVBRW9CQSxnQkFGcEI7QUFBQSxVQUVzQzlDLGVBRnRDLFVBRXNDQSxlQUZ0QztBQUFBLFVBRXVEK0MsUUFGdkQsVUFFdURBLFFBRnZEO0FBQUEsVUFFaUVDLFNBRmpFLFVBRWlFQSxTQUZqRTtBQUFBLFVBRTRFQyxXQUY1RSxVQUU0RUEsV0FGNUU7QUFHUjs7QUFIUSxvQkFJNEIsS0FBS3NGLEtBSmpDO0FBQUEsVUFJQTBJLEtBSkEsV0FJQUEsS0FKQTtBQUFBLFVBSU81VyxPQUpQLFdBSU9BLE9BSlA7QUFBQSxVQUlnQnVsQixPQUpoQixXQUlnQkEsT0FKaEI7QUFBQSxVQUtGQyxTQUxFLEdBS1ksS0FBS3RYLEtBTGpCLENBS0ZzWCxTQUxFO0FBTVI7O0FBQ0FBLGtCQUFZLGdDQUFnQjdjLFNBQWhCLEVBQTJCNmMsU0FBM0IsQ0FBWjtBQUNBLFVBQU1DLFdBQVcsOEJBQWU5ZixlQUFmLEVBQWdDK0MsUUFBaEMsRUFBMENDLFNBQTFDLEVBQXFEQyxXQUFyRCxFQUFrRWdPLEtBQWxFLEVBQXlFNVcsT0FBekUsRUFBa0Z3SSxrQkFBbEYsRUFBc0dDLGdCQUF0RyxDQUFqQjtBQUNBLFVBQU1pZCxnQkFBZ0Isd0NBQW9COU8sS0FBcEIsRUFBMkI1VyxPQUEzQixFQUFvQ3VsQixPQUFwQyxFQUE2QzdjLFFBQTdDLENBQXRCO0FBQ0E7QUFDQSxhQUNFO0FBQ0UsZUFBTzhjLFNBRFQ7QUFFRSxjQUFNQyxRQUZSO0FBR0UsY0FBTSxDQUFDLEVBQUNFLEtBQUssV0FBTixFQUFtQkMsTUFBTUYsYUFBekIsRUFBRDtBQUhSLFFBREY7QUFPRDs7OztFQW5CZSxnQkFBTXJXLFM7O0FBb0J2Qjs7QUFFRGlXLElBQUloVyxTQUFKLEdBQWdCO0FBQ2RrVyxhQUFXLG9CQUFVOVYsTUFEUDtBQUVkNlYsV0FBVyxvQkFBVTdWLE1BRlA7QUFHZDFQLFdBQVcsb0JBQVU2bEIsTUFIUDtBQUlkalAsU0FBVyxvQkFBVWlQO0FBSlAsQ0FBaEI7O2tCQU9lUCxHOzs7Ozs7Ozs7Ozs7QUNyQ1IsSUFBTVEsNENBQWtCLFNBQWxCQSxlQUFrQixDQUFDbmQsU0FBRCxFQUFZNmMsU0FBWixFQUEwQjtBQUN2RCxNQUFJLENBQUNBLFNBQUwsRUFBZ0I7QUFDZCxnQkFBVTdjLFNBQVY7QUFDRDtBQUNELFNBQVVBLFNBQVYsV0FBeUI2YyxTQUF6QjtBQUNELENBTE0sQzs7Ozs7Ozs7Ozs7O0FDQVAsSUFBTU8sa0NBQWtDLFNBQWxDQSwrQkFBa0MsQ0FBQzdrQixTQUFELEVBQWU7QUFDckQsTUFBSUEsU0FBSixFQUFlO0FBQ2IsUUFBTThrQixVQUFVOWtCLFVBQVU0TyxTQUFWLENBQW9CNU8sVUFBVStrQixXQUFWLENBQXNCLEdBQXRCLENBQXBCLENBQWhCO0FBQ0EsWUFBUUQsT0FBUjtBQUNFLFdBQUssTUFBTDtBQUNBLFdBQUssS0FBTDtBQUNFLGVBQU8sWUFBUDtBQUNGLFdBQUssS0FBTDtBQUNFLGVBQU8sV0FBUDtBQUNGLFdBQUssS0FBTDtBQUNFLGVBQU8sV0FBUDtBQUNGLFdBQUssS0FBTDtBQUNFLGVBQU8sV0FBUDtBQUNGO0FBQ0UsZUFBTyxZQUFQO0FBWEo7QUFhRDtBQUNELFNBQU8sRUFBUDtBQUNELENBbEJEOztBQW9CQSxJQUFNRSxzQkFBc0IsU0FBdEJBLG1CQUFzQixDQUFDeGQsUUFBRCxFQUFXL0MsZUFBWCxFQUE0QmdELFNBQTVCLEVBQXVDQyxXQUF2QyxFQUF1RDtBQUNqRixTQUFPLENBQ0wsRUFBQ3VkLFVBQVUsVUFBWCxFQUF1QkMsU0FBU3pkLFNBQWhDLEVBREssRUFFTCxFQUFDd2QsVUFBVSxRQUFYLEVBQXFCQyxTQUFTMWQsUUFBOUIsRUFGSyxFQUdMLEVBQUN5ZCxVQUFVLGNBQVgsRUFBMkJDLFNBQVN6ZCxTQUFwQyxFQUhLLEVBSUwsRUFBQ3dkLFVBQVUsZ0JBQVgsRUFBNkJDLFNBQVN6Z0IsZUFBdEMsRUFKSyxFQUtMLEVBQUN3Z0IsVUFBVSxjQUFYLEVBQTJCQyxTQUFTeGQsV0FBcEMsRUFMSyxFQU1MLEVBQUN1ZCxVQUFVLGNBQVgsRUFBMkJDLFNBQVMsU0FBcEMsRUFOSyxDQUFQO0FBUUQsQ0FURDs7QUFXQSxJQUFNQyx3QkFBd0IsU0FBeEJBLHFCQUF3QixDQUFDMWQsU0FBRCxFQUFZRCxRQUFaLEVBQXNCRSxXQUF0QixFQUFtQzVJLE9BQW5DLEVBQStDO0FBQUEsTUFDbkVKLElBRG1FLEdBQ2xESSxPQURrRCxDQUNuRUosSUFEbUU7QUFBQSxNQUM3RDhGLE1BRDZELEdBQ2xEMUYsT0FEa0QsQ0FDN0QwRixNQUQ2RDs7QUFFM0UsU0FBTyxDQUNMLEVBQUN5Z0IsVUFBVSxVQUFYLEVBQXVCQyxTQUFZeG1CLElBQVosWUFBdUIrSSxTQUE5QyxFQURLLEVBRUwsRUFBQ3dkLFVBQVUsUUFBWCxFQUFxQkMsU0FBWTFkLFFBQVosU0FBd0I5SSxJQUF4QixTQUFnQzhGLE1BQXJELEVBRkssRUFHTCxFQUFDeWdCLFVBQVUsY0FBWCxFQUEyQkMsU0FBU3pkLFNBQXBDLEVBSEssRUFJTCxFQUFDd2QsVUFBVSxnQkFBWCxFQUE2QkMsU0FBWXhtQixJQUFaLHVCQUFrQytJLFNBQS9ELEVBSkssRUFLTCxFQUFDd2QsVUFBVSxjQUFYLEVBQTJCQyxTQUFTeGQsV0FBcEMsRUFMSyxFQU1MLEVBQUN1ZCxVQUFVLGNBQVgsRUFBMkJDLFNBQVMsU0FBcEMsRUFOSyxDQUFQO0FBUUQsQ0FWRDs7QUFZQSxJQUFNRSxzQkFBc0IsU0FBdEJBLG1CQUFzQixDQUFDNWQsUUFBRCxFQUFXQyxTQUFYLEVBQXNCQyxXQUF0QixFQUFtQ2dPLEtBQW5DLEVBQTBDcE8sa0JBQTFDLEVBQThEQyxnQkFBOUQsRUFBbUY7QUFBQSxNQUNyR2IsU0FEcUcsR0FDdkZnUCxLQUR1RixDQUNyR2hQLFNBRHFHO0FBQUEsTUFFckc4SyxXQUZxRyxHQUVyRjlLLFNBRnFGLENBRXJHOEssV0FGcUc7O0FBRzdHLE1BQU02VCxXQUFjN2QsUUFBZCxTQUEwQmQsVUFBVUQsT0FBcEMsU0FBK0NDLFVBQVVoSSxJQUEvRDtBQUNBLE1BQU00bUIsVUFBYTlkLFFBQWIsU0FBeUJkLFVBQVVELE9BQW5DLFNBQThDQyxVQUFVaEksSUFBOUQ7QUFDQSxNQUFNOGUsU0FBWWhXLFFBQVosU0FBd0JkLFVBQVVELE9BQWxDLFNBQTZDQyxVQUFVaEksSUFBdkQsU0FBK0RnSSxVQUFVb2UsT0FBL0U7QUFDQSxNQUFNUyxVQUFVN2UsVUFBVXpHLEtBQVYsSUFBbUJ5RyxVQUFVaEksSUFBN0M7QUFDQSxNQUFNOG1CLGdCQUFnQjllLFVBQVUzRyxXQUFWLElBQXlCdUgsa0JBQS9DO0FBQ0EsTUFBTW1lLHlCQUF5QlosZ0NBQWdDbmUsVUFBVTFHLFNBQTFDLENBQS9CO0FBQ0EsTUFBTTBsQixjQUFjaGYsVUFBVTFHLFNBQVYsSUFBdUJ1SCxnQkFBM0M7QUFDQSxNQUFNZ2QsV0FBVyxDQUNmLEVBQUNVLFVBQVUsVUFBWCxFQUF1QkMsU0FBU0ssT0FBaEMsRUFEZSxFQUVmLEVBQUNOLFVBQVUsUUFBWCxFQUFxQkMsU0FBU0ksT0FBOUIsRUFGZSxFQUdmLEVBQUNMLFVBQVUsY0FBWCxFQUEyQkMsU0FBU3pkLFNBQXBDLEVBSGUsRUFJZixFQUFDd2QsVUFBVSxnQkFBWCxFQUE2QkMsU0FBU00sYUFBdEMsRUFKZSxFQUtmLEVBQUNQLFVBQVUsZ0JBQVgsRUFBNkJDLFNBQVMsR0FBdEMsRUFMZSxFQU1mLEVBQUNELFVBQVUsaUJBQVgsRUFBOEJDLFNBQVMsR0FBdkMsRUFOZSxFQU9mLEVBQUNELFVBQVUsY0FBWCxFQUEyQkMsU0FBU3hkLFdBQXBDLEVBUGUsQ0FBakI7QUFTQSxNQUFJOEosZ0JBQWdCLFdBQWhCLElBQStCQSxnQkFBZ0IsWUFBbkQsRUFBaUU7QUFDL0QrUyxhQUFTNVcsSUFBVCxDQUFjLEVBQUNzWCxVQUFVLFVBQVgsRUFBdUJDLFNBQVMxSCxNQUFoQyxFQUFkO0FBQ0ErRyxhQUFTNVcsSUFBVCxDQUFjLEVBQUNzWCxVQUFVLHFCQUFYLEVBQWtDQyxTQUFTMUgsTUFBM0MsRUFBZDtBQUNBK0csYUFBUzVXLElBQVQsQ0FBYyxFQUFDc1gsVUFBVSxlQUFYLEVBQTRCQyxTQUFTMVQsV0FBckMsRUFBZDtBQUNBK1MsYUFBUzVXLElBQVQsQ0FBYyxFQUFDc1gsVUFBVSxVQUFYLEVBQXVCQyxTQUFTUSxXQUFoQyxFQUFkO0FBQ0FuQixhQUFTNVcsSUFBVCxDQUFjLEVBQUNzWCxVQUFVLGVBQVgsRUFBNEJDLFNBQVNPLHNCQUFyQyxFQUFkO0FBQ0FsQixhQUFTNVcsSUFBVCxDQUFjLEVBQUNzWCxVQUFVLFNBQVgsRUFBc0JDLFNBQVMsT0FBL0IsRUFBZDtBQUNBWCxhQUFTNVcsSUFBVCxDQUFjLEVBQUNzWCxVQUFVLGNBQVgsRUFBMkJDLFNBQVMsUUFBcEMsRUFBZDtBQUNBWCxhQUFTNVcsSUFBVCxDQUFjLEVBQUNzWCxVQUFVLGdCQUFYLEVBQTZCQyxTQUFTRyxRQUF0QyxFQUFkO0FBQ0FkLGFBQVM1VyxJQUFULENBQWMsRUFBQ3NYLFVBQVUsc0JBQVgsRUFBbUNDLFNBQVMsR0FBNUMsRUFBZDtBQUNBWCxhQUFTNVcsSUFBVCxDQUFjLEVBQUNzWCxVQUFVLDJCQUFYLEVBQXdDQyxTQUFTLEdBQWpELEVBQWQ7QUFDQVgsYUFBUzVXLElBQVQsQ0FBYyxFQUFDc1gsVUFBVSx1QkFBWCxFQUFvQ0MsU0FBUyxHQUE3QyxFQUFkO0FBQ0FYLGFBQVM1VyxJQUFULENBQWMsRUFBQ3NYLFVBQVUsdUJBQVgsRUFBb0NDLFNBQVMxSCxNQUE3QyxFQUFkO0FBQ0ErRyxhQUFTNVcsSUFBVCxDQUFjLEVBQUNzWCxVQUFVLG9DQUFYLEVBQWlEQyxTQUFTMVQsV0FBMUQsRUFBZDtBQUNELEdBZEQsTUFjTztBQUNMK1MsYUFBUzVXLElBQVQsQ0FBYyxFQUFDc1gsVUFBVSxVQUFYLEVBQXVCQyxTQUFTMUgsTUFBaEMsRUFBZDtBQUNBK0csYUFBUzVXLElBQVQsQ0FBYyxFQUFDc1gsVUFBVSxlQUFYLEVBQTRCQyxTQUFTMVQsV0FBckMsRUFBZDtBQUNBK1MsYUFBUzVXLElBQVQsQ0FBYyxFQUFDc1gsVUFBVSxTQUFYLEVBQXNCQyxTQUFTLFNBQS9CLEVBQWQ7QUFDQVgsYUFBUzVXLElBQVQsQ0FBYyxFQUFDc1gsVUFBVSxjQUFYLEVBQTJCQyxTQUFTLHFCQUFwQyxFQUFkO0FBQ0Q7QUFDRCxTQUFPWCxRQUFQO0FBQ0QsQ0F4Q0Q7O0FBMENPLElBQU1vQiwwQ0FBaUIsU0FBakJBLGNBQWlCLENBQUNsaEIsZUFBRCxFQUFrQitDLFFBQWxCLEVBQTRCQyxTQUE1QixFQUF1Q0MsV0FBdkMsRUFBb0RnTyxLQUFwRCxFQUEyRDVXLE9BQTNELEVBQW9Fd0ksa0JBQXBFLEVBQXdGQyxnQkFBeEYsRUFBNkc7QUFDekksTUFBSW1PLEtBQUosRUFBVztBQUNULFdBQU8wUCxvQkFBb0I1ZCxRQUFwQixFQUE4QkMsU0FBOUIsRUFBeUNDLFdBQXpDLEVBQXNEZ08sS0FBdEQsRUFBNkRwTyxrQkFBN0QsRUFBaUZDLGdCQUFqRixDQUFQO0FBQ0Q7QUFDRCxNQUFJekksT0FBSixFQUFhO0FBQ1gsV0FBT3FtQixzQkFBc0IzZCxRQUF0QixFQUFnQ0MsU0FBaEMsRUFBMkNDLFdBQTNDLEVBQXdENUksT0FBeEQsQ0FBUDtBQUNEO0FBQ0QsU0FBT2ttQixvQkFBb0J2Z0IsZUFBcEIsRUFBcUMrQyxRQUFyQyxFQUErQ0MsU0FBL0MsRUFBMERDLFdBQTFELENBQVA7QUFDRCxDQVJNLEM7Ozs7Ozs7Ozs7OztBQ3JGUCxJQUFNa2UsMkJBQTJCLFNBQTNCQSx3QkFBMkIsQ0FBQzdlLElBQUQsRUFBT1MsUUFBUCxFQUFvQjtBQUNuRCxTQUFVQSxRQUFWLFNBQXNCVCxJQUF0QjtBQUNELENBRkQ7O0FBSUEsSUFBTThlLDJCQUEyQixTQUEzQkEsd0JBQTJCLENBQUNuUSxLQUFELEVBQVFsTyxRQUFSLEVBQXFCO0FBQ3BELE1BQUlwSSxvQkFBSjtBQUFBLE1BQWlCZ2Usc0JBQWpCO0FBQUEsTUFBZ0MxZSxhQUFoQztBQUFBLE1BQXNDK0gsZ0JBQXRDO0FBQ0EsTUFBSWlQLE1BQU1oUCxTQUFWLEVBQXFCO0FBQUEsMkJBQzhCZ1AsTUFBTWhQLFNBRHBDO0FBQ2hCdEgsZUFEZ0Isb0JBQ2hCQSxXQURnQjtBQUNIZ2UsaUJBREcsb0JBQ0hBLGFBREc7QUFDWTFlLFFBRFosb0JBQ1lBLElBRFo7QUFDa0IrSCxXQURsQixvQkFDa0JBLE9BRGxCO0FBRXBCO0FBQ0QsTUFBSXJILFdBQUosRUFBaUI7QUFDZixXQUFVb0ksUUFBVixTQUFzQnBJLFdBQXRCLFNBQXFDZ2UsYUFBckMsU0FBc0QxZSxJQUF0RDtBQUNEO0FBQ0QsU0FBVThJLFFBQVYsU0FBc0JmLE9BQXRCLFNBQWlDL0gsSUFBakM7QUFDRCxDQVREOztBQVdBLElBQU1vbkIsNkJBQTZCLFNBQTdCQSwwQkFBNkIsQ0FBQ2huQixPQUFELEVBQVUwSSxRQUFWLEVBQXVCO0FBQUEsTUFDaEQ5SSxJQURnRCxHQUMvQkksT0FEK0IsQ0FDaERKLElBRGdEO0FBQUEsTUFDMUM4RixNQUQwQyxHQUMvQjFGLE9BRCtCLENBQzFDMEYsTUFEMEM7O0FBRXhELFNBQVVnRCxRQUFWLFNBQXNCOUksSUFBdEIsU0FBOEI4RixNQUE5QjtBQUNELENBSEQ7O0FBS08sSUFBTXVoQixvREFBc0IsU0FBdEJBLG1CQUFzQixDQUFDclEsS0FBRCxFQUFRNVcsT0FBUixFQUFpQmlJLElBQWpCLEVBQXVCUyxRQUF2QixFQUFvQztBQUNyRSxNQUFJa08sS0FBSixFQUFXO0FBQ1QsV0FBT21RLHlCQUF5Qm5RLEtBQXpCLEVBQWdDbE8sUUFBaEMsQ0FBUDtBQUNEO0FBQ0QsTUFBSTFJLE9BQUosRUFBYTtBQUNYLFdBQU9nbkIsMkJBQTJCaG5CLE9BQTNCLEVBQW9DMEksUUFBcEMsQ0FBUDtBQUNEO0FBQ0QsU0FBT29lLHlCQUF5QjdlLElBQXpCLEVBQStCUyxRQUEvQixDQUFQO0FBQ0QsQ0FSTSxDOzs7Ozs7Ozs7Ozs7Ozs7QUNwQlA7Ozs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7Ozs7Ozs7OztBQUVBLElBQU13ZSxPQUFPLE1BQWI7QUFDQSxJQUFNQyxTQUFTLFFBQWY7O0lBRU1DLE07OztBQUNKLGtCQUFhbFosS0FBYixFQUFvQjtBQUFBOztBQUFBLGdIQUNaQSxLQURZOztBQUVsQixVQUFLbVosb0JBQUwsR0FBNEIsTUFBS0Esb0JBQUwsQ0FBMEI5WSxJQUExQixPQUE1QjtBQUNBLFVBQUsrWSxVQUFMLEdBQWtCLE1BQUtBLFVBQUwsQ0FBZ0IvWSxJQUFoQixPQUFsQjtBQUNBLFVBQUtnWixlQUFMLEdBQXVCLE1BQUtBLGVBQUwsQ0FBcUJoWixJQUFyQixPQUF2QjtBQUprQjtBQUtuQjs7Ozt3Q0FDb0I7QUFDbkI7QUFDQSxXQUFLOFksb0JBQUw7QUFDRDs7OzJDQUN1QjtBQUFBOztBQUN0QixVQUFNeGdCLFNBQVMsRUFBQzJnQixhQUFhLFNBQWQsRUFBZjtBQUNBLDZCQUFRLE9BQVIsRUFBaUIzZ0IsTUFBakIsRUFDR3JELElBREgsQ0FDUSxnQkFBYztBQUFBLFlBQVg5RCxJQUFXLFFBQVhBLElBQVc7O0FBQ2xCLGVBQUt3TyxLQUFMLENBQVdySSxjQUFYLENBQTBCbkcsS0FBS1ksV0FBL0IsRUFBNENaLEtBQUtvYyxjQUFqRCxFQUFpRXBjLEtBQUsrVCxjQUF0RTtBQUNELE9BSEgsRUFJRy9QLEtBSkgsQ0FJUyxpQkFBUztBQUNkbkIsZ0JBQVFDLEdBQVIsQ0FBWSxjQUFaLEVBQTRCbUIsTUFBTXhELE9BQWxDO0FBQ0QsT0FOSDtBQU9EOzs7aUNBQ2E7QUFBQTs7QUFDWixVQUFNMEcsU0FBUyxFQUFDMmdCLGFBQWEsU0FBZCxFQUFmO0FBQ0EsNkJBQVEsU0FBUixFQUFtQjNnQixNQUFuQixFQUNHckQsSUFESCxDQUNRLFlBQU07QUFDVixlQUFLMEssS0FBTCxDQUFXbkksZUFBWDtBQUNELE9BSEgsRUFJR3JDLEtBSkgsQ0FJUyxpQkFBUztBQUNkbkIsZ0JBQVFDLEdBQVIsQ0FBWSxlQUFaLEVBQTZCbUIsTUFBTXhELE9BQW5DO0FBQ0QsT0FOSDtBQU9EOzs7b0NBQ2dCdU4sSyxFQUFPO0FBQ3RCLFVBQU03TixRQUFRNk4sTUFBTStaLE1BQU4sQ0FBYUMsZUFBYixDQUE2QixDQUE3QixFQUFnQzduQixLQUE5QztBQUNBLGNBQVFBLEtBQVI7QUFDRSxhQUFLc25CLE1BQUw7QUFDRSxlQUFLRyxVQUFMO0FBQ0E7QUFDRixhQUFLSixJQUFMO0FBQ0U7QUFDQSxlQUFLaFosS0FBTCxDQUFXdk4sT0FBWCxDQUFtQmtPLElBQW5CLE9BQTRCLEtBQUtYLEtBQUwsQ0FBVzVOLFdBQXZDLFNBQXNELEtBQUs0TixLQUFMLENBQVd6SSxhQUFqRTtBQUNBO0FBQ0Y7QUFDRTtBQVRKO0FBV0Q7Ozs2QkFDUztBQUFBLFVBQ0FFLGVBREEsR0FDcUIsS0FBS3VJLEtBRDFCLENBQ0F2SSxlQURBOztBQUVSLGFBQ0U7QUFBQTtBQUFBLFVBQUssV0FBVSx1QkFBZjtBQUNFO0FBQUE7QUFBQSxZQUFLLFdBQVUscUZBQWY7QUFDRSw2REFERjtBQUVFO0FBQUE7QUFBQSxjQUFLLFdBQVUsaUJBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQU0sV0FBVSxpQkFBaEI7QUFBbUNBO0FBQW5DO0FBREYsV0FGRjtBQUtFO0FBQUE7QUFBQSxjQUFLLFdBQVUsZ0JBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQVMsV0FBVSx3QkFBbkIsRUFBNEMsaUJBQWdCLGtCQUE1RCxFQUErRSxJQUFHLEdBQWxGLEVBQXNGLFdBQXRGO0FBQUE7QUFBQSxhQURGO0FBRUU7QUFBQTtBQUFBLGdCQUFTLFdBQVUsd0JBQW5CLEVBQTZDLGlCQUFnQixrQkFBN0QsRUFBZ0YsSUFBRyxRQUFuRjtBQUFBO0FBQUEsYUFGRjtBQUdJLGlCQUFLdUksS0FBTCxDQUFXNU4sV0FBWCxHQUNBO0FBQ0UsMkJBQWEsS0FBSzROLEtBQUwsQ0FBVzVOLFdBRDFCO0FBRUUsK0JBQWlCLEtBQUtpbkIsZUFGeEI7QUFHRSxnQ0FBa0IsS0FBS3JaLEtBQUwsQ0FBVzVOLFdBSC9CO0FBSUUsb0JBQU00bUIsSUFKUjtBQUtFLHNCQUFRQztBQUxWLGNBREEsR0FTQTtBQUFBO0FBQUEsZ0JBQVMsSUFBRyxvQkFBWixFQUFpQyxXQUFVLHdCQUEzQyxFQUFvRSxpQkFBZ0Isa0JBQXBGLEVBQXVHLElBQUcsUUFBMUc7QUFBQTtBQUFBO0FBWko7QUFMRjtBQURGLE9BREY7QUF5QkQ7Ozs7RUF4RWtCLGdCQUFNOVgsUzs7a0JBMkVaLGdDQUFXK1gsTUFBWCxDOzs7Ozs7Ozs7Ozs7O0FDcEZmOzs7O0FBQ0E7Ozs7QUFFQSxTQUFTTyxJQUFULEdBQWlCO0FBQ2YsU0FDRTtBQUFBO0FBQUEsTUFBSyxTQUFRLEtBQWIsRUFBbUIsSUFBRyxTQUF0QixFQUFnQyxHQUFFLEtBQWxDLEVBQXdDLEdBQUUsS0FBMUMsRUFBZ0QsUUFBTyxNQUF2RCxFQUE4RCxTQUFRLFdBQXRFLEVBQWtGLGtCQUFpQixlQUFuRyxFQUFtSCxXQUFVLGNBQTdIO0FBQ0U7QUFBQTtBQUFBLFFBQU0sSUFBRyxHQUFUO0FBQ0U7QUFBQTtBQUFBO0FBQUE7QUFBQSxPQURGO0FBRUU7QUFBQTtBQUFBO0FBQUE7QUFBQSxPQUZGO0FBR0U7QUFBQTtBQUFBLFVBQUcsSUFBRyxPQUFOO0FBQ0U7QUFBQTtBQUFBLFlBQUcsSUFBRyxrQ0FBTixFQUF5QyxXQUFVLG1DQUFuRDtBQUNFO0FBQUE7QUFBQSxjQUFHLElBQUcsVUFBTixFQUFpQixXQUFVLGlDQUEzQjtBQUNFO0FBQUE7QUFBQSxnQkFBTSxXQUFVLHNCQUFoQixFQUF1QyxVQUFTLElBQWhELEVBQXFELFlBQVcsUUFBaEU7QUFBQTtBQUFBLGFBREY7QUFFRTtBQUFBO0FBQUEsZ0JBQUcsSUFBRyxVQUFOLEVBQWlCLFdBQVUsZ0NBQTNCO0FBQ0Usc0RBQU0sSUFBRyxRQUFULEVBQWtCLE1BQUssTUFBdkIsRUFBOEIsUUFBTyxTQUFyQyxFQUErQyxhQUFZLEdBQTNELEVBQStELGVBQWMsUUFBN0UsRUFBc0YsR0FBRSxhQUF4RixHQURGO0FBRUUsc0RBQU0sSUFBRyxhQUFULEVBQXVCLE1BQUssTUFBNUIsRUFBbUMsUUFBTyxTQUExQyxFQUFvRCxhQUFZLEdBQWhFLEVBQW9FLGVBQWMsUUFBbEYsRUFBMkYsR0FBRSxjQUE3RixHQUZGO0FBR0Usc0RBQU0sSUFBRyxlQUFULEVBQXlCLE1BQUssTUFBOUIsRUFBcUMsUUFBTyxTQUE1QyxFQUFzRCxhQUFZLEdBQWxFLEVBQXNFLGVBQWMsUUFBcEYsRUFBNkYsR0FBRSxjQUEvRixHQUhGO0FBSUUsc0RBQU0sSUFBRyxlQUFULEVBQXlCLE1BQUssTUFBOUIsRUFBcUMsUUFBTyxTQUE1QyxFQUFzRCxhQUFZLEdBQWxFLEVBQXNFLGVBQWMsUUFBcEYsRUFBNkYsR0FBRSxjQUEvRixHQUpGO0FBS0Usc0RBQU0sSUFBRyxlQUFULEVBQXlCLE1BQUssTUFBOUIsRUFBcUMsUUFBTyxTQUE1QyxFQUFzRCxhQUFZLEdBQWxFLEVBQXNFLGVBQWMsUUFBcEYsRUFBNkYsR0FBRSxjQUEvRjtBQUxGO0FBRkY7QUFERjtBQURGO0FBSEY7QUFERixHQURGO0FBc0JEOztrQkFFY0EsSTs7Ozs7Ozs7Ozs7OztBQzVCZjs7Ozs7O0FBRUEsU0FBU0MscUJBQVQsT0FBa0c7QUFBQSxNQUFoRXRuQixXQUFnRSxRQUFoRUEsV0FBZ0U7QUFBQSxNQUFuRGluQixlQUFtRCxRQUFuREEsZUFBbUQ7QUFBQSxNQUFsQ00sZ0JBQWtDLFFBQWxDQSxnQkFBa0M7QUFBQSxNQUFoQlgsSUFBZ0IsUUFBaEJBLElBQWdCO0FBQUEsTUFBVkMsTUFBVSxRQUFWQSxNQUFVOztBQUNoRyxTQUNFO0FBQUE7QUFBQSxNQUFRLE1BQUssTUFBYixFQUFvQixJQUFHLHdCQUF2QixFQUFnRCxXQUFVLGdDQUExRCxFQUEyRixVQUFVSSxlQUFyRyxFQUFzSCxPQUFPTSxnQkFBN0g7QUFDRTtBQUFBO0FBQUEsUUFBUSxJQUFHLHVDQUFYO0FBQW9Edm5CO0FBQXBELEtBREY7QUFFRTtBQUFBO0FBQUEsUUFBUSxPQUFPNG1CLElBQWY7QUFBQTtBQUFBLEtBRkY7QUFHRTtBQUFBO0FBQUEsUUFBUSxPQUFPQyxNQUFmO0FBQUE7QUFBQTtBQUhGLEdBREY7QUFPRDs7a0JBRWNTLHFCOzs7Ozs7QUNaZixpRDs7Ozs7Ozs7Ozs7OztBQ0FBOztBQUNBOzs7Ozs7QUFFQSxJQUFNeGlCLGtCQUFrQixTQUFsQkEsZUFBa0IsT0FBaUI7QUFBQSxNQUFkaVEsT0FBYyxRQUFkQSxPQUFjOztBQUN2QyxTQUFPO0FBQ0x6VCxjQUFVeVQsUUFBUXpULFFBRGI7QUFFTHJDLFVBQVU4VixRQUFROVYsSUFGYjtBQUdMVyxZQUFVbVYsUUFBUW5WLE1BQVIsQ0FBZUE7QUFIcEIsR0FBUDtBQUtELENBTkQ7O2tCQVFlLHlCQUFRa0YsZUFBUixFQUF5QixJQUF6QixpQjs7Ozs7Ozs7Ozs7Ozs7O0FDWGY7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7Ozs7O0lBRU0waUIsVzs7Ozs7Ozs7Ozs7NkJBQ007QUFDUixVQUFJLEtBQUs1WixLQUFMLENBQVd0TSxRQUFmLEVBQXlCO0FBQ3ZCVyxnQkFBUUMsR0FBUixDQUFZLHFCQUFaO0FBQ0EsZUFDRSxxRUFERjtBQUdELE9BTEQsTUFLTztBQUNMRCxnQkFBUUMsR0FBUixDQUFZLHlCQUFaO0FBQ0EsWUFBSSxLQUFLMEwsS0FBTCxDQUFXM08sSUFBZixFQUFxQjtBQUNuQixjQUFJLEtBQUsyTyxLQUFMLENBQVdoTyxNQUFmLEVBQXVCO0FBQ3JCLG1CQUNFLDREQURGO0FBR0QsV0FKRCxNQUlPO0FBQ0wsbUJBQU8sNkRBQVA7QUFDRDtBQUNGO0FBQ0QsZUFBTyx1REFBUDtBQUNEO0FBQ0Y7Ozs7RUFwQnVCLGdCQUFNbVAsUzs7QUFxQi9COztrQkFFY3lZLFc7Ozs7Ozs7Ozs7Ozs7OztBQzdCZjs7OztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7SUFFTUMsUTs7O0FBQ0osb0JBQWE3WixLQUFiLEVBQW9CO0FBQUE7O0FBQUEsb0hBQ1pBLEtBRFk7O0FBRWxCLFVBQUtuRSxLQUFMLEdBQWE7QUFDWGllLGdCQUFZLEtBREQ7QUFFWEMsaUJBQVksS0FGRDtBQUdYQyxrQkFBWTtBQUhELEtBQWI7QUFLQSxVQUFLQyxVQUFMLEdBQWtCLE1BQUtBLFVBQUwsQ0FBZ0I1WixJQUFoQixPQUFsQjtBQUNBLFVBQUs2WixjQUFMLEdBQXNCLE1BQUtBLGNBQUwsQ0FBb0I3WixJQUFwQixPQUF0QjtBQUNBLFVBQUs4WixhQUFMLEdBQXFCLE1BQUtBLGFBQUwsQ0FBbUI5WixJQUFuQixPQUFyQjtBQUNBLFVBQUsrWixlQUFMLEdBQXVCLE1BQUtBLGVBQUwsQ0FBcUIvWixJQUFyQixPQUF2QjtBQUNBLFVBQUtnYSxlQUFMLEdBQXVCLE1BQUtBLGVBQUwsQ0FBcUJoYSxJQUFyQixPQUF2QjtBQUNBLFVBQUtpYSxnQkFBTCxHQUF3QixNQUFLQSxnQkFBTCxDQUFzQmphLElBQXRCLE9BQXhCO0FBQ0EsVUFBS2thLGdCQUFMLEdBQXdCLE1BQUtBLGdCQUFMLENBQXNCbGEsSUFBdEIsT0FBeEI7QUFDQSxVQUFLbWEsV0FBTCxHQUFtQixNQUFLQSxXQUFMLENBQWlCbmEsSUFBakIsT0FBbkI7QUFDQSxVQUFLb2EsZUFBTCxHQUF1QixNQUFLQSxlQUFMLENBQXFCcGEsSUFBckIsT0FBdkI7QUFDQSxVQUFLcWEsVUFBTCxHQUFrQixNQUFLQSxVQUFMLENBQWdCcmEsSUFBaEIsT0FBbEI7QUFoQmtCO0FBaUJuQjs7OzsrQkFDV2IsSyxFQUFPO0FBQ2pCQSxZQUFNbWIsY0FBTjtBQUNBLFdBQUs5WixRQUFMLENBQWMsRUFBQ2laLFVBQVUsS0FBWCxFQUFkO0FBQ0E7QUFDQSxVQUFNYyxLQUFLcGIsTUFBTXFiLFlBQWpCO0FBQ0EsVUFBSUQsR0FBR0UsS0FBUCxFQUFjO0FBQ1osWUFBSUYsR0FBR0UsS0FBSCxDQUFTLENBQVQsRUFBWUMsSUFBWixLQUFxQixNQUF6QixFQUFpQztBQUMvQixjQUFNQyxjQUFjSixHQUFHRSxLQUFILENBQVMsQ0FBVCxFQUFZRyxTQUFaLEVBQXBCO0FBQ0EsZUFBS1AsVUFBTCxDQUFnQk0sV0FBaEI7QUFDRDtBQUNGO0FBQ0Y7OzttQ0FDZXhiLEssRUFBTztBQUNyQkEsWUFBTW1iLGNBQU47QUFDRDs7O2tDQUNjbmIsSyxFQUFPO0FBQ3BCLFVBQUlvYixLQUFLcGIsTUFBTXFiLFlBQWY7QUFDQSxVQUFJRCxHQUFHRSxLQUFQLEVBQWM7QUFDWixhQUFLLElBQUlyYSxJQUFJLENBQWIsRUFBZ0JBLElBQUltYSxHQUFHRSxLQUFILENBQVM1WSxNQUE3QixFQUFxQ3pCLEdBQXJDLEVBQTBDO0FBQ3hDbWEsYUFBR0UsS0FBSCxDQUFTSSxNQUFULENBQWdCemEsQ0FBaEI7QUFDRDtBQUNGLE9BSkQsTUFJTztBQUNMakIsY0FBTXFiLFlBQU4sQ0FBbUJNLFNBQW5CO0FBQ0Q7QUFDRjs7O3NDQUNrQjtBQUNqQixXQUFLdGEsUUFBTCxDQUFjLEVBQUNpWixVQUFVLElBQVgsRUFBaUJFLFlBQVksSUFBN0IsRUFBZDtBQUNEOzs7c0NBQ2tCO0FBQ2pCLFdBQUtuWixRQUFMLENBQWMsRUFBQ2laLFVBQVUsS0FBWCxFQUFrQkUsWUFBWSxLQUE5QixFQUFkO0FBQ0Q7Ozt1Q0FDbUI7QUFDbEIsV0FBS25aLFFBQUwsQ0FBYyxFQUFDa1osV0FBVyxJQUFaLEVBQWtCQyxZQUFZLElBQTlCLEVBQWQ7QUFDRDs7O3VDQUNtQjtBQUNsQixXQUFLblosUUFBTCxDQUFjLEVBQUNrWixXQUFXLEtBQVosRUFBbUJDLFlBQVksS0FBL0IsRUFBZDtBQUNEOzs7Z0NBQ1l4YSxLLEVBQU87QUFDbEJBLFlBQU1tYixjQUFOO0FBQ0FTLGVBQVNDLGNBQVQsQ0FBd0IsWUFBeEIsRUFBc0NDLEtBQXRDO0FBQ0Q7OztvQ0FDZ0I5YixLLEVBQU87QUFDdEJBLFlBQU1tYixjQUFOO0FBQ0EsVUFBTVksV0FBVy9iLE1BQU0rWixNQUFOLENBQWEzRixLQUE5QjtBQUNBLFdBQUs4RyxVQUFMLENBQWdCYSxTQUFTLENBQVQsQ0FBaEI7QUFDRDs7OytCQUNXbHFCLEksRUFBTTtBQUNoQixVQUFJQSxJQUFKLEVBQVU7QUFDUixZQUFJO0FBQ0Ysa0NBQWFBLElBQWIsRUFERSxDQUNrQjtBQUNyQixTQUZELENBRUUsT0FBT29FLEtBQVAsRUFBYztBQUNkLGlCQUFPLEtBQUt1SyxLQUFMLENBQVdxSSxZQUFYLENBQXdCNVMsTUFBTXhELE9BQTlCLENBQVA7QUFDRDtBQUNEO0FBQ0EsYUFBSytOLEtBQUwsQ0FBV3ZQLFVBQVgsQ0FBc0JZLElBQXRCO0FBQ0Q7QUFDRjs7OzZCQUNTO0FBQ1IsYUFDRTtBQUFBO0FBQUEsVUFBSyxXQUFVLHNDQUFmO0FBQ0U7QUFBQTtBQUFBO0FBQ0UsbURBQU8sV0FBVSxZQUFqQixFQUE4QixNQUFLLE1BQW5DLEVBQTBDLElBQUcsWUFBN0MsRUFBMEQsTUFBSyxZQUEvRCxFQUE0RSxRQUFPLGlCQUFuRixFQUFxRyxVQUFVLEtBQUtvcEIsZUFBcEgsRUFBcUksU0FBUSxxQkFBN0k7QUFERixTQURGO0FBSUU7QUFBQTtBQUFBLFlBQUssSUFBRyxrQkFBUixFQUEyQixXQUFXLHdDQUF3QyxLQUFLNWUsS0FBTCxDQUFXaWUsUUFBWCxHQUFzQixzQkFBdEIsR0FBK0MsRUFBdkYsQ0FBdEMsRUFBa0ksUUFBUSxLQUFLRyxVQUEvSSxFQUEySixZQUFZLEtBQUtDLGNBQTVLLEVBQTRMLFdBQVcsS0FBS0MsYUFBNU0sRUFBMk4sYUFBYSxLQUFLQyxlQUE3TyxFQUE4UCxhQUFhLEtBQUtDLGVBQWhSLEVBQWlTLGNBQWMsS0FBS0MsZ0JBQXBULEVBQXNVLGNBQWMsS0FBS0MsZ0JBQXpWLEVBQTJXLFNBQVMsS0FBS0MsV0FBelg7QUFDRyxlQUFLeGEsS0FBTCxDQUFXM08sSUFBWCxHQUNDO0FBQUE7QUFBQTtBQUNFO0FBQ0UsMEJBQVksS0FBS3dLLEtBQUwsQ0FBV21lLFVBRHpCO0FBRUUsb0JBQU0sS0FBS2hhLEtBQUwsQ0FBVzNPLElBRm5CO0FBR0UseUJBQVcsS0FBSzJPLEtBQUwsQ0FBV2hOO0FBSHhCLGNBREY7QUFNRTtBQUFBO0FBQUEsZ0JBQUssSUFBRyxzQkFBUixFQUErQixXQUFXLHNEQUExQztBQUNJLG1CQUFLNkksS0FBTCxDQUFXaWUsUUFBWCxHQUNBO0FBQUE7QUFBQSxrQkFBSyxJQUFHLG1CQUFSO0FBQ0U7QUFBQTtBQUFBLG9CQUFHLFdBQVUsTUFBYjtBQUFBO0FBQUE7QUFERixlQURBLEdBS0EsSUFOSjtBQVFJLG1CQUFLamUsS0FBTCxDQUFXa2UsU0FBWCxHQUNBO0FBQUE7QUFBQSxrQkFBSyxJQUFHLHVCQUFSO0FBQ0U7QUFBQTtBQUFBLG9CQUFHLFdBQVUsZ0RBQWIsRUFBOEQsSUFBRyw0QkFBakU7QUFBK0YsdUJBQUsvWixLQUFMLENBQVdvSTtBQUExRyxpQkFERjtBQUVFO0FBQUE7QUFBQTtBQUFBO0FBQUEsaUJBRkY7QUFHRTtBQUFBO0FBQUEsb0JBQUcsV0FBVSxZQUFiO0FBQUE7QUFBQSxpQkFIRjtBQUlFO0FBQUE7QUFBQSxvQkFBRyxXQUFVLGtCQUFiO0FBQUE7QUFBQTtBQUpGLGVBREEsR0FRQTtBQWhCSjtBQU5GLFdBREQsR0E0QkM7QUFBQTtBQUFBLGNBQUssSUFBRyxzQkFBUixFQUErQixXQUFXLHNEQUExQztBQUNJLGlCQUFLdk0sS0FBTCxDQUFXaWUsUUFBWCxHQUNBO0FBQUE7QUFBQSxnQkFBSyxJQUFHLG1CQUFSO0FBQ0U7QUFBQTtBQUFBLGtCQUFHLFdBQVUsTUFBYjtBQUFBO0FBQUE7QUFERixhQURBLEdBS0E7QUFBQTtBQUFBLGdCQUFLLElBQUcsdUJBQVI7QUFDRTtBQUFBO0FBQUEsa0JBQUcsV0FBVSxnREFBYixFQUE4RCxJQUFHLDRCQUFqRTtBQUErRixxQkFBSzlaLEtBQUwsQ0FBV29JO0FBQTFHLGVBREY7QUFFRTtBQUFBO0FBQUE7QUFBQTtBQUFBLGVBRkY7QUFHRTtBQUFBO0FBQUEsa0JBQUcsV0FBVSxZQUFiO0FBQUE7QUFBQSxlQUhGO0FBSUU7QUFBQTtBQUFBLGtCQUFHLFdBQVUsa0JBQWI7QUFBQTtBQUFBO0FBSkY7QUFOSjtBQTdCSjtBQUpGLE9BREY7QUFvREQ7Ozs7RUFqSW9CLGdCQUFNakgsUzs7QUFrSTVCOztrQkFFYzBZLFE7Ozs7Ozs7OztBQ3hJZjdsQixPQUFPQyxPQUFQLEdBQWlCO0FBQ2Z1bkIsY0FEZSx3QkFDRG5xQixJQURDLEVBQ0s7QUFDbEIsUUFBSSxDQUFDQSxJQUFMLEVBQVc7QUFDVCxZQUFNLElBQUk0SixLQUFKLENBQVUsa0JBQVYsQ0FBTjtBQUNEO0FBQ0QsUUFBSSxJQUFJMkgsSUFBSixDQUFTdlIsS0FBS0ssSUFBZCxDQUFKLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSXVKLEtBQUosQ0FBVSw4Q0FBVixDQUFOO0FBQ0Q7QUFDRDtBQUNBLFlBQVE1SixLQUFLQyxJQUFiO0FBQ0UsV0FBSyxZQUFMO0FBQ0EsV0FBSyxXQUFMO0FBQ0EsV0FBSyxXQUFMO0FBQ0UsWUFBSUQsS0FBS3FQLElBQUwsR0FBWSxRQUFoQixFQUEwQjtBQUN4QixnQkFBTSxJQUFJekYsS0FBSixDQUFVLDRDQUFWLENBQU47QUFDRDtBQUNEO0FBQ0YsV0FBSyxXQUFMO0FBQ0UsWUFBSTVKLEtBQUtxUCxJQUFMLEdBQVksUUFBaEIsRUFBMEI7QUFDeEIsZ0JBQU0sSUFBSXpGLEtBQUosQ0FBVSwwQ0FBVixDQUFOO0FBQ0Q7QUFDRDtBQUNGLFdBQUssV0FBTDtBQUNFLFlBQUk1SixLQUFLcVAsSUFBTCxHQUFZLFFBQWhCLEVBQTBCO0FBQ3hCLGdCQUFNLElBQUl6RixLQUFKLENBQVUsNENBQVYsQ0FBTjtBQUNEO0FBQ0Q7QUFDRjtBQUNFLGNBQU0sSUFBSUEsS0FBSixDQUFVNUosS0FBS0MsSUFBTCxHQUFZLGlHQUF0QixDQUFOO0FBbkJKO0FBcUJEO0FBOUJjLENBQWpCLEM7Ozs7Ozs7Ozs7Ozs7OztBQ0FBOzs7O0FBQ0E7Ozs7Ozs7Ozs7OztJQUVNbXFCLGM7OztBQUNKLDBCQUFhemIsS0FBYixFQUFvQjtBQUFBOztBQUFBLGdJQUNaQSxLQURZOztBQUVsQixVQUFLbkUsS0FBTCxHQUFhO0FBQ1g2ZixpQkFBa0IsRUFEUDtBQUVYbmhCLHdCQUFrQjtBQUZQLEtBQWI7QUFGa0I7QUFNbkI7Ozs7d0NBQ29CO0FBQ25CLFdBQUtvaEIscUJBQUwsQ0FBMkIsS0FBSzNiLEtBQUwsQ0FBVzNPLElBQXRDO0FBQ0Q7Ozs4Q0FDMEJ1cUIsUSxFQUFVO0FBQ25DLFVBQUlBLFNBQVN2cUIsSUFBVCxLQUFrQixLQUFLMk8sS0FBTCxDQUFXM08sSUFBakMsRUFBdUM7QUFDckMsYUFBS3NxQixxQkFBTCxDQUEyQkMsU0FBU3ZxQixJQUFwQztBQUNEO0FBQ0QsVUFBSXVxQixTQUFTNW9CLFNBQVQsS0FBdUIsS0FBS2dOLEtBQUwsQ0FBV2hOLFNBQXRDLEVBQWlEO0FBQy9DLFlBQUk0b0IsU0FBUzVvQixTQUFiLEVBQXdCO0FBQ3RCLGVBQUs2b0IsNkJBQUwsQ0FBbUNELFNBQVM1b0IsU0FBNUM7QUFDRCxTQUZELE1BRU87QUFDTCxlQUFLNk4sUUFBTCxDQUFjLEVBQUM2YSxXQUFXLEtBQUs3ZixLQUFMLENBQVd0QixnQkFBdkIsRUFBZDtBQUNEO0FBQ0Y7QUFDRjs7O2tEQUM4QmxKLEksRUFBTTtBQUFBOztBQUNuQyxVQUFNeXFCLGdCQUFnQixJQUFJQyxVQUFKLEVBQXRCO0FBQ0FELG9CQUFjRSxhQUFkLENBQTRCM3FCLElBQTVCO0FBQ0F5cUIsb0JBQWNHLFNBQWQsR0FBMEIsWUFBTTtBQUM5QixlQUFLcGIsUUFBTCxDQUFjLEVBQUM2YSxXQUFXSSxjQUFjdGYsTUFBMUIsRUFBZDtBQUNELE9BRkQ7QUFHRDs7OzBDQUNzQm5MLEksRUFBTTtBQUMzQixVQUFJQSxLQUFLQyxJQUFMLEtBQWMsV0FBbEIsRUFBK0I7QUFDN0IsYUFBS3VxQiw2QkFBTCxDQUFtQ3hxQixJQUFuQztBQUNELE9BRkQsTUFFTztBQUNMLFlBQUksS0FBSzJPLEtBQUwsQ0FBV2hOLFNBQWYsRUFBMEI7QUFDeEIsZUFBSzZvQiw2QkFBTCxDQUFtQyxLQUFLN2IsS0FBTCxDQUFXaE4sU0FBOUM7QUFDRDtBQUNELGFBQUs2TixRQUFMLENBQWMsRUFBQzZhLFdBQVcsS0FBSzdmLEtBQUwsQ0FBV3RCLGdCQUF2QixFQUFkO0FBQ0Q7QUFDRjs7OzZCQUNTO0FBQ1IsYUFDRTtBQUNFLFlBQUcsa0JBREw7QUFFRSxhQUFLLEtBQUtzQixLQUFMLENBQVc2ZixTQUZsQjtBQUdFLG1CQUFXLEtBQUsxYixLQUFMLENBQVdnYSxVQUFYLEdBQXdCLEtBQXhCLEdBQWdDLEVBSDdDO0FBSUUsYUFBSTtBQUpOLFFBREY7QUFRRDs7OztFQWpEMEIsZ0JBQU03WSxTOztBQWtEbEM7O0FBRURzYSxlQUFlcmEsU0FBZixHQUEyQjtBQUN6QjRZLGNBQVksb0JBQVVrQyxJQUFWLENBQWU1YSxVQURGO0FBRXpCalEsUUFBWSxvQkFBVXNtQixNQUFWLENBQWlCclcsVUFGSjtBQUd6QnRPLGFBQVksb0JBQVUya0I7QUFIRyxDQUEzQjs7a0JBTWU4RCxjOzs7Ozs7Ozs7Ozs7O0FDN0RmOztBQUNBOztBQUNBOzs7Ozs7QUFFQSxJQUFNdmtCLGtCQUFrQixTQUFsQkEsZUFBa0IsT0FBMEI7QUFBQSxNQUF2QnBGLE9BQXVCLFFBQXZCQSxPQUF1QjtBQUFBLE1BQWRxVixPQUFjLFFBQWRBLE9BQWM7O0FBQ2hELFNBQU87QUFDTDlWLFVBQU04VixRQUFROVY7QUFEVCxHQUFQO0FBR0QsQ0FKRDs7QUFNQSxJQUFNcUcscUJBQXFCO0FBQ3pCaEgsK0JBRHlCO0FBRXpCUztBQUZ5QixDQUEzQjs7a0JBS2UseUJBQVErRixlQUFSLEVBQXlCUSxrQkFBekIsaUI7Ozs7Ozs7Ozs7Ozs7OztBQ2ZmOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7Ozs7Ozs7SUFFTXlrQixjOzs7QUFDSiwwQkFBYW5jLEtBQWIsRUFBb0I7QUFBQTs7QUFBQSxnSUFDWkEsS0FEWTs7QUFFbEIsVUFBS29jLGVBQUwsR0FBdUIsTUFBS0EsZUFBTCxDQUFxQi9iLElBQXJCLE9BQXZCO0FBRmtCO0FBR25COzs7O3NDQUNrQjtBQUNqQixXQUFLTCxLQUFMLENBQVc3TyxZQUFYLENBQXdCLEtBQUs2TyxLQUFMLENBQVd2TixPQUFuQztBQUNEOzs7NkJBQ1M7QUFDUixhQUNFO0FBQUE7QUFBQSxVQUFLLFdBQVUsb0JBQWY7QUFDRTtBQUFBO0FBQUEsWUFBSyxXQUFVLG1CQUFmO0FBQ0U7QUFERixTQURGO0FBS0U7QUFBQTtBQUFBLFlBQUssV0FBVSxpQ0FBZjtBQUNFO0FBQUE7QUFBQSxjQUFLLFdBQVUsaUJBQWY7QUFDRTtBQURGO0FBREYsU0FMRjtBQVdFO0FBQUE7QUFBQSxZQUFLLFdBQVUsbURBQWY7QUFDRTtBQUFBO0FBQUEsY0FBSyxJQUFHLHFCQUFSLEVBQThCLFdBQVUsaUJBQXhDO0FBQ0U7QUFBQTtBQUFBLGdCQUFLLFdBQVUsdUNBQWY7QUFDRTtBQURGLGFBREY7QUFJRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSx1Q0FBZjtBQUNFO0FBREYsYUFKRjtBQU9LLGlCQUFLdU4sS0FBTCxDQUFXM08sSUFBWCxDQUFnQkMsSUFBaEIsS0FBeUIsV0FBMUIsSUFDQTtBQUFBO0FBQUEsZ0JBQUssV0FBVSx3Q0FBZjtBQUNFO0FBREYsYUFSSjtBQVlFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLHNEQUFmO0FBQ0U7QUFERixhQVpGO0FBZUU7QUFBQTtBQUFBLGdCQUFLLFdBQVUsb0NBQWY7QUFDRTtBQUFBO0FBQUEsa0JBQVEsSUFBRyxnQkFBWCxFQUE0QixXQUFVLCtCQUF0QyxFQUFzRSxTQUFTLEtBQUs4cUIsZUFBcEY7QUFBQTtBQUFBO0FBREYsYUFmRjtBQWtCRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxxREFBZjtBQUNFO0FBQUE7QUFBQSxrQkFBUSxXQUFVLGdCQUFsQixFQUFtQyxTQUFTLEtBQUtwYyxLQUFMLENBQVd0UCxTQUF2RDtBQUFBO0FBQUE7QUFERixhQWxCRjtBQXFCRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxxQ0FBZjtBQUNFO0FBQUE7QUFBQSxrQkFBRyxXQUFVLFlBQWI7QUFBQTtBQUF1TztBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLFFBQU8sUUFBcEMsRUFBNkMsTUFBSyx1QkFBbEQ7QUFBQTtBQUFBO0FBQXZPO0FBREY7QUFyQkY7QUFERjtBQVhGLE9BREY7QUF5Q0Q7Ozs7RUFsRDBCLGdCQUFNeVEsUzs7QUFtRGxDOztrQkFFYyxnQ0FBV2diLGNBQVgsQzs7Ozs7Ozs7Ozs7OztBQzlEZjs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsSUFBTWpsQixrQkFBa0IsU0FBbEJBLGVBQWtCLE9BQWlCO0FBQUEsTUFBZGlRLE9BQWMsUUFBZEEsT0FBYzs7QUFDdkMsU0FBTztBQUNMbFUsV0FBT2tVLFFBQVEzRCxRQUFSLENBQWlCdlE7QUFEbkIsR0FBUDtBQUdELENBSkQ7O0FBTUEsSUFBTXlFLHFCQUFxQixTQUFyQkEsa0JBQXFCLFdBQVk7QUFDckMsU0FBTztBQUNMMmtCLHNCQUFrQiwwQkFBQzNxQixJQUFELEVBQU9DLEtBQVAsRUFBaUI7QUFDakNpRyxlQUFTLDZCQUFlbEcsSUFBZixFQUFxQkMsS0FBckIsQ0FBVDtBQUNEO0FBSEksR0FBUDtBQUtELENBTkQ7O2tCQVFlLHlCQUFRdUYsZUFBUixFQUF5QlEsa0JBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNsQmY7Ozs7Ozs7Ozs7OztJQUVNNGtCLGlCOzs7QUFDSiw2QkFBYXRjLEtBQWIsRUFBb0I7QUFBQTs7QUFBQSxzSUFDWkEsS0FEWTs7QUFFbEIsVUFBS3VjLFdBQUwsR0FBbUIsTUFBS0EsV0FBTCxDQUFpQmxjLElBQWpCLE9BQW5CO0FBRmtCO0FBR25COzs7O2dDQUNZbWMsQyxFQUFHO0FBQ2QsVUFBTTlxQixPQUFPOHFCLEVBQUVqRCxNQUFGLENBQVM3bkIsSUFBdEI7QUFDQSxVQUFNQyxRQUFRNnFCLEVBQUVqRCxNQUFGLENBQVM1bkIsS0FBdkI7QUFDQSxXQUFLcU8sS0FBTCxDQUFXcWMsZ0JBQVgsQ0FBNEIzcUIsSUFBNUIsRUFBa0NDLEtBQWxDO0FBQ0Q7Ozs2QkFDUztBQUNSLGFBQ0UseUNBQU8sTUFBSyxNQUFaLEVBQW1CLElBQUcsZUFBdEIsRUFBc0MsV0FBVSwrQ0FBaEQsRUFBZ0csTUFBSyxPQUFyRyxFQUE2RyxhQUFZLDJCQUF6SCxFQUFxSixVQUFVLEtBQUs0cUIsV0FBcEssRUFBaUwsT0FBTyxLQUFLdmMsS0FBTCxDQUFXL00sS0FBbk0sR0FERjtBQUdEOzs7O0VBZDZCLGdCQUFNa08sUzs7a0JBaUJ2Qm1iLGlCOzs7Ozs7Ozs7Ozs7O0FDbkJmOztBQUNBOztBQUNBOzs7Ozs7QUFFQSxJQUFNcGxCLGtCQUFrQixTQUFsQkEsZUFBa0IsT0FBMEI7QUFBQSxNQUF2QnBGLE9BQXVCLFFBQXZCQSxPQUF1QjtBQUFBLE1BQWRxVixPQUFjLFFBQWRBLE9BQWM7O0FBQ2hELFNBQU87QUFDTHNWLHlCQUF3QjNxQixRQUFRc0YsZUFBUixDQUF3QjFGLElBRDNDO0FBRUxnckIsNEJBQXdCNXFCLFFBQVFzRixlQUFSLENBQXdCRSxPQUYzQztBQUdMd0wsY0FBd0JxRSxRQUFROVYsSUFBUixDQUFhSyxJQUhoQztBQUlMbWxCLHNCQUF3QjFQLFFBQVEwUCxnQkFKM0I7QUFLTEMscUJBQXdCM1AsUUFBUTJQLGVBTDNCO0FBTUwzRyxXQUF3QmhKLFFBQVFnSixLQU4zQjtBQU9Md00sY0FBd0J4VixRQUFRMVIsS0FBUixDQUFjeUY7QUFQakMsR0FBUDtBQVNELENBVkQ7O0FBWUEsSUFBTXhELHFCQUFxQixTQUFyQkEsa0JBQXFCLFdBQVk7QUFDckMsU0FBTztBQUNMa2xCLG1CQUFlLHVCQUFDanJCLEtBQUQsRUFBVztBQUN4QmlHLGVBQVMsMEJBQVlqRyxLQUFaLENBQVQ7QUFDQWlHLGVBQVMsMEJBQVksZUFBWixFQUE2QixJQUE3QixDQUFUO0FBQ0QsS0FKSTtBQUtMaWxCLGdCQUFZLG9CQUFDbHJCLEtBQUQsRUFBVztBQUNyQmlHLGVBQVMsMEJBQVksS0FBWixFQUFtQmpHLEtBQW5CLENBQVQ7QUFDRDtBQVBJLEdBQVA7QUFTRCxDQVZEOztrQkFZZSx5QkFBUXVGLGVBQVIsRUFBeUJRLGtCQUF6QixpQjs7Ozs7Ozs7Ozs7Ozs7O0FDNUJmOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7Ozs7O0lBRU1vbEIsZTs7O0FBQ0osMkJBQWE5YyxLQUFiLEVBQW9CO0FBQUE7O0FBQUEsa0lBQ1pBLEtBRFk7O0FBRWxCLFVBQUt1YyxXQUFMLEdBQW1CLE1BQUtBLFdBQUwsQ0FBaUJsYyxJQUFqQixPQUFuQjtBQUZrQjtBQUduQjs7Ozt3Q0FDb0I7QUFBQSxtQkFDUyxLQUFLTCxLQURkO0FBQUEsVUFDWG1RLEtBRFcsVUFDWEEsS0FEVztBQUFBLFVBQ0pyTixRQURJLFVBQ0pBLFFBREk7O0FBRW5CLFVBQUksQ0FBQ3FOLEtBQUwsRUFBWTtBQUNWLGFBQUs0TSxZQUFMLENBQWtCamEsUUFBbEI7QUFDRDtBQUNGOzs7b0RBQytDO0FBQUEsVUFBbkJxTixLQUFtQixRQUFuQkEsS0FBbUI7QUFBQSxVQUFack4sUUFBWSxRQUFaQSxRQUFZOztBQUM5QztBQUNBLFVBQUlBLGFBQWEsS0FBSzlDLEtBQUwsQ0FBVzhDLFFBQTVCLEVBQXNDO0FBQ3BDLGVBQU8sS0FBS2lhLFlBQUwsQ0FBa0JqYSxRQUFsQixDQUFQO0FBQ0Q7QUFDRDtBQUNBLFVBQUlxTixVQUFVLEtBQUtuUSxLQUFMLENBQVdtUSxLQUF6QixFQUFnQztBQUM5QixhQUFLNk0sYUFBTCxDQUFtQjdNLEtBQW5CO0FBQ0Q7QUFDRjs7O2dDQUNZM1EsSyxFQUFPO0FBQ2xCLFVBQUk3TixRQUFRNk4sTUFBTStaLE1BQU4sQ0FBYTVuQixLQUF6QjtBQUNBQSxjQUFRLEtBQUtzckIsWUFBTCxDQUFrQnRyQixLQUFsQixDQUFSO0FBQ0E7QUFDQSxXQUFLcU8sS0FBTCxDQUFXNGMsYUFBWCxDQUF5QmpyQixLQUF6QjtBQUNEOzs7aUNBQ2F1ckIsSyxFQUFPO0FBQ25CQSxjQUFRQSxNQUFNOWQsT0FBTixDQUFjLE1BQWQsRUFBc0IsR0FBdEIsQ0FBUixDQURtQixDQUNpQjtBQUNwQzhkLGNBQVFBLE1BQU05ZCxPQUFOLENBQWMsZ0JBQWQsRUFBZ0MsRUFBaEMsQ0FBUixDQUZtQixDQUUyQjtBQUM5QyxhQUFPOGQsS0FBUDtBQUNEOzs7aUNBQ2FwYSxRLEVBQVU7QUFDdEIsVUFBTXFhLHdCQUF3QnJhLFNBQVNsQixTQUFULENBQW1CLENBQW5CLEVBQXNCa0IsU0FBU2lWLFdBQVQsQ0FBcUIsR0FBckIsQ0FBdEIsQ0FBOUI7QUFDQSxVQUFNcUYsaUJBQWlCLEtBQUtILFlBQUwsQ0FBa0JFLHFCQUFsQixDQUF2QjtBQUNBLFdBQUtuZCxLQUFMLENBQVc0YyxhQUFYLENBQXlCUSxjQUF6QjtBQUNEOzs7a0NBQ2NqTixLLEVBQU87QUFBQTs7QUFDcEIsVUFBSSxDQUFDQSxLQUFMLEVBQVk7QUFDVixlQUFPLEtBQUtuUSxLQUFMLENBQVc2YyxVQUFYLENBQXNCLG1CQUF0QixDQUFQO0FBQ0Q7QUFDRCwwREFBbUMxTSxLQUFuQyxFQUNHN2EsSUFESCxDQUNRLFlBQU07QUFDVixlQUFLMEssS0FBTCxDQUFXNmMsVUFBWCxDQUFzQixJQUF0QjtBQUNELE9BSEgsRUFJR3JuQixLQUpILENBSVMsVUFBQ0MsS0FBRCxFQUFXO0FBQ2hCLGVBQUt1SyxLQUFMLENBQVc2YyxVQUFYLENBQXNCcG5CLE1BQU14RCxPQUE1QjtBQUNELE9BTkg7QUFPRDs7OzZCQUNTO0FBQUEsb0JBQ29HLEtBQUsrTixLQUR6RztBQUFBLFVBQ0FtUSxLQURBLFdBQ0FBLEtBREE7QUFBQSxVQUNPc00sbUJBRFAsV0FDT0EsbUJBRFA7QUFBQSxVQUM0QkMsc0JBRDVCLFdBQzRCQSxzQkFENUI7QUFBQSxVQUNvRDdGLGdCQURwRCxXQUNvREEsZ0JBRHBEO0FBQUEsVUFDc0VDLGVBRHRFLFdBQ3NFQSxlQUR0RTtBQUFBLFVBQ3VGNkYsUUFEdkYsV0FDdUZBLFFBRHZGOztBQUVSLGFBQ0U7QUFBQTtBQUFBLFVBQUssV0FBVSxrQ0FBZjtBQUNFO0FBQUE7QUFBQSxZQUFLLFdBQVUsb0NBQWY7QUFDRTtBQUFBO0FBQUEsY0FBTSxXQUFVLHFCQUFoQjtBQUFBO0FBQUEsV0FERjtBQUVFO0FBQ0UsOEJBQWtCOUYsZ0JBRHBCO0FBRUUsNkJBQWlCQyxlQUZuQjtBQUdFLGlDQUFxQjJGLG1CQUh2QjtBQUlFLG9DQUF3QkM7QUFKMUIsWUFGRjtBQVFFLG1EQUFPLE1BQUssTUFBWixFQUFtQixJQUFHLGtCQUF0QixFQUF5QyxXQUFVLFlBQW5ELEVBQWdFLE1BQUssT0FBckUsRUFBNkUsYUFBWSxlQUF6RixFQUF5RyxVQUFVLEtBQUtILFdBQXhILEVBQXFJLE9BQU9wTSxLQUE1SSxHQVJGO0FBU0tBLG1CQUFTLENBQUN3TSxRQUFYLElBQXdCO0FBQUE7QUFBQSxjQUFNLElBQUcsMEJBQVQsRUFBb0MsV0FBVSxzQ0FBOUM7QUFBc0Y7QUFBdEYsV0FUNUI7QUFVSUEsc0JBQVk7QUFBQTtBQUFBLGNBQU0sSUFBRyw0QkFBVCxFQUFzQyxXQUFVLHNDQUFoRDtBQUF3RjtBQUF4RjtBQVZoQixTQURGO0FBYUU7QUFBQTtBQUFBO0FBQ0lBLHFCQUNBO0FBQUE7QUFBQSxjQUFHLElBQUcsd0JBQU4sRUFBK0IsV0FBVSx1QkFBekM7QUFBa0VBO0FBQWxFLFdBREEsR0FHQTtBQUFBO0FBQUEsY0FBRyxXQUFVLGNBQWI7QUFBQTtBQUFBO0FBSko7QUFiRixPQURGO0FBdUJEOzs7O0VBMUUyQixnQkFBTXhiLFM7O2tCQTZFckIyYixlOzs7Ozs7Ozs7Ozs7O0FDakZmOzs7O0FBQ0E7Ozs7OztBQUVBLFNBQVNPLFNBQVQsT0FBc0c7QUFBQSxNQUFqRnhHLGdCQUFpRixRQUFqRkEsZ0JBQWlGO0FBQUEsTUFBL0RDLGVBQStELFFBQS9EQSxlQUErRDtBQUFBLE1BQTlDMkYsbUJBQThDLFFBQTlDQSxtQkFBOEM7QUFBQSxNQUF6QkMsc0JBQXlCLFFBQXpCQSxzQkFBeUI7O0FBQ3BHLE1BQUk3RixnQkFBSixFQUFzQjtBQUNwQixRQUFJQyxvQkFBb0IyRixtQkFBeEIsRUFBNkM7QUFDM0MsYUFBTztBQUFBO0FBQUEsVUFBTSxJQUFHLGFBQVQsRUFBdUIsV0FBVSxxQkFBakM7QUFBd0RBLDJCQUF4RDtBQUFBO0FBQThFQyw4QkFBOUU7QUFBQTtBQUFBLE9BQVA7QUFDRDtBQUNELFdBQU87QUFBQTtBQUFBLFFBQU0sSUFBRyx5QkFBVCxFQUFtQyxXQUFVLDZCQUE3QztBQUFBO0FBQW1GO0FBQUE7QUFBQTtBQUN4RixxQkFBVSxjQUQ4RTtBQUFBO0FBQUEsT0FBbkY7QUFBQTtBQUFBLEtBQVA7QUFFRDtBQUNELFNBQ0U7QUFBQTtBQUFBLE1BQU0sSUFBRyw0QkFBVCxFQUFzQyxXQUFVLDZCQUFoRDtBQUFBO0FBQWlGO0FBQUE7QUFBQSxRQUFNLFdBQVUsY0FBaEI7QUFBQTtBQUFBLEtBQWpGO0FBQUE7QUFBQSxHQURGO0FBR0Q7O0FBRURXLFVBQVVqYyxTQUFWLEdBQXNCO0FBQ3BCeVYsb0JBQXdCLG9CQUFVcUYsSUFBVixDQUFlNWEsVUFEbkI7QUFFcEJtYix1QkFBd0Isb0JBQVVqYixNQUZkO0FBR3BCa2IsMEJBQXdCLG9CQUFVbGI7QUFIZCxDQUF0Qjs7a0JBTWU2YixTOzs7Ozs7Ozs7Ozs7O0FDdEJmOztBQUNBOztBQUNBOzs7Ozs7QUFFQSxJQUFNbm1CLGtCQUFrQixTQUFsQkEsZUFBa0IsT0FBMkI7QUFBQSxNQUFiN0YsSUFBYSxRQUF4QjhWLE9BQXdCLENBQWI5VixJQUFhOztBQUNqRCxTQUFPO0FBQ0xBO0FBREssR0FBUDtBQUdELENBSkQ7O0FBTUEsSUFBTXFHLHFCQUFxQjtBQUN6QnhHO0FBRHlCLENBQTNCOztrQkFJZSx5QkFBUWdHLGVBQVIsRUFBeUJRLGtCQUF6QixpQjs7Ozs7Ozs7Ozs7Ozs7O0FDZGY7Ozs7Ozs7Ozs7OztBQUVBLFNBQVM0bEIsYUFBVCxDQUF1QkMsT0FBdkIsRUFBZ0M7QUFDOUI7QUFDQSxNQUFJQyxhQUFhQyxLQUFLRixRQUFRRyxLQUFSLENBQWMsR0FBZCxFQUFtQixDQUFuQixDQUFMLENBQWpCO0FBQ0E7QUFDQSxNQUFJQyxhQUFhSixRQUFRRyxLQUFSLENBQWMsR0FBZCxFQUFtQixDQUFuQixFQUFzQkEsS0FBdEIsQ0FBNEIsR0FBNUIsRUFBaUMsQ0FBakMsRUFBb0NBLEtBQXBDLENBQTBDLEdBQTFDLEVBQStDLENBQS9DLENBQWpCO0FBQ0E7QUFDQSxNQUFJRSxLQUFLLElBQUlDLFVBQUosQ0FBZUwsV0FBV3RiLE1BQTFCLENBQVQ7QUFDQSxPQUFLLElBQUl6QixJQUFJLENBQWIsRUFBZ0JBLElBQUkrYyxXQUFXdGIsTUFBL0IsRUFBdUN6QixHQUF2QyxFQUE0QztBQUMxQ21kLE9BQUduZCxDQUFILElBQVErYyxXQUFXTSxVQUFYLENBQXNCcmQsQ0FBdEIsQ0FBUjtBQUNEO0FBQ0QsU0FBTyxJQUFJc2QsSUFBSixDQUFTLENBQUNILEVBQUQsQ0FBVCxFQUFlLEVBQUN0c0IsTUFBTXFzQixVQUFQLEVBQWYsQ0FBUDtBQUNEOztJQUVLSyxxQjs7O0FBQ0osaUNBQWFoZSxLQUFiLEVBQW9CO0FBQUE7O0FBQUEsOElBQ1pBLEtBRFk7O0FBRWxCLFVBQUtuRSxLQUFMLEdBQWE7QUFDWG9pQixtQkFBZ0IsSUFETDtBQUVYeG9CLGFBQWdCLElBRkw7QUFHWHlvQixzQkFBZ0IsQ0FITDtBQUlYQyxzQkFBZ0IsSUFKTDtBQUtYQyxtQkFBZ0I7QUFMTCxLQUFiO0FBT0EsVUFBS0MscUJBQUwsR0FBNkIsTUFBS0EscUJBQUwsQ0FBMkJoZSxJQUEzQixPQUE3QjtBQUNBLFVBQUtpZSxrQkFBTCxHQUEwQixNQUFLQSxrQkFBTCxDQUF3QmplLElBQXhCLE9BQTFCO0FBQ0EsVUFBS2tlLGVBQUwsR0FBdUIsTUFBS0EsZUFBTCxDQUFxQmxlLElBQXJCLE9BQXZCO0FBWGtCO0FBWW5COzs7O3dDQUNvQjtBQUFBLFVBQ1hoUCxJQURXLEdBQ0YsS0FBSzJPLEtBREgsQ0FDWDNPLElBRFc7O0FBRW5CLFdBQUttdEIsY0FBTCxDQUFvQm50QixJQUFwQjtBQUNEOzs7OENBQzBCb3RCLFMsRUFBVztBQUNwQztBQUNBLFVBQUlBLFVBQVVwdEIsSUFBVixJQUFrQm90QixVQUFVcHRCLElBQVYsS0FBbUIsS0FBSzJPLEtBQUwsQ0FBVzNPLElBQXBELEVBQTBEO0FBQUEsWUFDaERBLElBRGdELEdBQ3ZDb3RCLFNBRHVDLENBQ2hEcHRCLElBRGdEOztBQUV4RCxhQUFLbXRCLGNBQUwsQ0FBb0JudEIsSUFBcEI7QUFDRDtBQUNGOzs7bUNBQ2VBLEksRUFBTTtBQUFBOztBQUNwQixVQUFNeXFCLGdCQUFnQixJQUFJQyxVQUFKLEVBQXRCO0FBQ0FELG9CQUFjRSxhQUFkLENBQTRCM3FCLElBQTVCO0FBQ0F5cUIsb0JBQWNHLFNBQWQsR0FBMEIsWUFBTTtBQUM5QixZQUFNeUMsVUFBVTVDLGNBQWN0ZixNQUE5QjtBQUNBLFlBQU1taUIsT0FBT3JCLGNBQWNvQixPQUFkLENBQWI7QUFDQSxZQUFNVCxjQUFjVyxJQUFJQyxlQUFKLENBQW9CRixJQUFwQixDQUFwQjtBQUNBLGVBQUs5ZCxRQUFMLENBQWMsRUFBRW9kLHdCQUFGLEVBQWQ7QUFDRCxPQUxEO0FBTUQ7OzswQ0FDc0J6ZSxLLEVBQU87QUFDNUIsVUFBTVgsV0FBV1csTUFBTStaLE1BQU4sQ0FBYTFhLFFBQTlCO0FBQ0EsVUFBTWlnQixlQUFlekksS0FBS0MsS0FBTCxDQUFXelgsV0FBVyxFQUF0QixDQUFyQjtBQUNBLFVBQU1rZ0IsZUFBZTFJLEtBQUtDLEtBQUwsQ0FBV3pYLFdBQVcsRUFBdEIsQ0FBckI7QUFDQTtBQUNBLFdBQUtnQyxRQUFMLENBQWM7QUFDWnNkLHdCQUFnQnRmLFdBQVcsR0FEZjtBQUVadWYscUJBQWdCdmYsV0FBVyxHQUFYLEdBQWlCLENBRnJCO0FBR1ppZ0Isa0NBSFk7QUFJWkM7QUFKWSxPQUFkO0FBTUE7QUFDQSxVQUFJQyxRQUFRNUQsU0FBU0MsY0FBVCxDQUF3QixvQkFBeEIsQ0FBWjtBQUNBMkQsWUFBTUMsV0FBTixHQUFvQnBnQixXQUFXLENBQS9CO0FBQ0Q7Ozt1Q0FDbUJXLEssRUFBTztBQUN6QixVQUFNN04sUUFBUW1rQixTQUFTdFcsTUFBTStaLE1BQU4sQ0FBYTVuQixLQUF0QixDQUFkO0FBQ0E7QUFDQSxXQUFLa1AsUUFBTCxDQUFjO0FBQ1p1ZCxxQkFBYXpzQjtBQURELE9BQWQ7QUFHQTtBQUNBLFVBQUlxdEIsUUFBUTVELFNBQVNDLGNBQVQsQ0FBd0Isb0JBQXhCLENBQVo7QUFDQTJELFlBQU1DLFdBQU4sR0FBb0J0dEIsUUFBUSxHQUE1QjtBQUNEOzs7c0NBQ2tCO0FBQ2pCO0FBQ0EsVUFBSXF0QixRQUFRNUQsU0FBU0MsY0FBVCxDQUF3QixvQkFBeEIsQ0FBWjtBQUNBLFVBQUk2RCxTQUFTOUQsU0FBUytELGFBQVQsQ0FBdUIsUUFBdkIsQ0FBYjtBQUNBRCxhQUFPRSxLQUFQLEdBQWVKLE1BQU1LLFVBQXJCO0FBQ0FILGFBQU81YSxNQUFQLEdBQWdCMGEsTUFBTU0sV0FBdEI7QUFDQUosYUFBT0ssVUFBUCxDQUFrQixJQUFsQixFQUF3QkMsU0FBeEIsQ0FBa0NSLEtBQWxDLEVBQXlDLENBQXpDLEVBQTRDLENBQTVDLEVBQStDRSxPQUFPRSxLQUF0RCxFQUE2REYsT0FBTzVhLE1BQXBFO0FBQ0EsVUFBTW1iLFVBQVVQLE9BQU9RLFNBQVAsRUFBaEI7QUFDQSxVQUFNZixPQUFPckIsY0FBY21DLE9BQWQsQ0FBYjtBQUNBLFVBQU1FLFdBQVcsSUFBSTdwQixJQUFKLENBQVMsQ0FBQzZvQixJQUFELENBQVQsbUJBQWtDO0FBQ2pEcnRCLGNBQU07QUFEMkMsT0FBbEMsQ0FBakI7QUFHQTtBQUNBLFVBQUlxdUIsUUFBSixFQUFjO0FBQ1osYUFBSzNmLEtBQUwsQ0FBVzlPLGNBQVgsQ0FBMEJ5dUIsUUFBMUI7QUFDRDtBQUNGOzs7NkJBQ1M7QUFBQSxtQkFDZ0csS0FBSzlqQixLQURyRztBQUFBLFVBQ0FwRyxLQURBLFVBQ0FBLEtBREE7QUFBQSxVQUNPd29CLFdBRFAsVUFDT0EsV0FEUDtBQUFBLFVBQ29CQyxjQURwQixVQUNvQkEsY0FEcEI7QUFBQSxVQUNvQ0MsY0FEcEMsVUFDb0NBLGNBRHBDO0FBQUEsVUFDb0RDLFdBRHBELFVBQ29EQSxXQURwRDtBQUFBLFVBQ2lFVSxZQURqRSxVQUNpRUEsWUFEakU7QUFBQSxVQUMrRUMsWUFEL0UsVUFDK0VBLFlBRC9FOztBQUVSLGFBQ0U7QUFBQTtBQUFBO0FBQ0U7QUFBQTtBQUFBLFlBQU8sV0FBVSxPQUFqQjtBQUFBO0FBQUEsU0FERjtBQUVFO0FBQ0UsY0FBRyxvQkFETDtBQUVFLG1CQUFRLFVBRlY7QUFHRSxxQkFIRjtBQUlFLGlCQUFPLEVBQUNhLFNBQVMsTUFBVixFQUpUO0FBS0UsMkJBTEY7QUFNRSx3QkFBYyxLQUFLdkIscUJBTnJCO0FBT0UsZUFBS0osV0FQUDtBQVFFLG9CQUFVLEtBQUtNO0FBUmpCLFVBRkY7QUFhSUgsc0JBQ0U7QUFBQTtBQUFBO0FBQ0U7QUFBQTtBQUFBLGNBQUssV0FBVSwwREFBZixFQUEwRSxPQUFPLEVBQUNnQixPQUFPLE1BQVIsRUFBakY7QUFDRTtBQUFBO0FBQUEsZ0JBQU0sV0FBVSxjQUFoQjtBQUFBO0FBQUEsYUFERjtBQUVFO0FBQUE7QUFBQSxnQkFBTSxXQUFVLGNBQWhCO0FBQWdDTiwwQkFBaEM7QUFBQTtBQUErQ0MsMEJBQS9DO0FBQUE7QUFBQTtBQUZGLFdBREY7QUFLRTtBQUFBO0FBQUE7QUFDRTtBQUNFLG9CQUFLLE9BRFA7QUFFRSxtQkFBS2IsY0FGUDtBQUdFLG1CQUFLQyxjQUhQO0FBSUUscUJBQU9DLFdBSlQ7QUFLRSx5QkFBVSxRQUxaO0FBTUUsd0JBQVUsS0FBS0U7QUFOakI7QUFERjtBQUxGLFNBREYsR0FrQkU7QUFBQTtBQUFBLFlBQUcsV0FBVSxjQUFiO0FBQUE7QUFBQSxTQS9CTjtBQWtDSTdvQixnQkFDQTtBQUFBO0FBQUEsWUFBRyxXQUFVLHVCQUFiO0FBQXNDQTtBQUF0QyxTQURBLEdBR0E7QUFBQTtBQUFBLFlBQUcsV0FBVSxjQUFiO0FBQUE7QUFBQTtBQXJDSixPQURGO0FBMENEOzs7O0VBekhpQyxnQkFBTTBMLFM7O2tCQTRIM0I2YyxxQjs7Ozs7Ozs7Ozs7OztBQzNJZjs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsSUFBTTltQixrQkFBa0IsU0FBbEJBLGVBQWtCLE9BQWlCO0FBQUEsTUFBZGlRLE9BQWMsUUFBZEEsT0FBYzs7QUFDdkMsU0FBTztBQUNMN1Usd0JBQW9CNlUsUUFBUTdVLGtCQUR2QjtBQUVMUyxpQkFBb0JvVSxRQUFRM0QsUUFBUixDQUFpQnpRLFdBRmhDO0FBR0x3UCxhQUFvQjRFLFFBQVEzRCxRQUFSLENBQWlCakIsT0FIaEM7QUFJTEQsVUFBb0I2RSxRQUFRM0QsUUFBUixDQUFpQmxCO0FBSmhDLEdBQVA7QUFNRCxDQVBEOztBQVNBLElBQU01SyxxQkFBcUIsU0FBckJBLGtCQUFxQixXQUFZO0FBQ3JDLFNBQU87QUFDTDJrQixzQkFBa0IsMEJBQUMzcUIsSUFBRCxFQUFPQyxLQUFQLEVBQWlCO0FBQ2pDaUcsZUFBUyw2QkFBZWxHLElBQWYsRUFBcUJDLEtBQXJCLENBQVQ7QUFDRCxLQUhJO0FBSUxrdUIsNEJBQXdCLGdDQUFDbHVCLEtBQUQsRUFBVztBQUNqQ2lHLGVBQVMsbUNBQXFCakcsS0FBckIsQ0FBVDtBQUNEO0FBTkksR0FBUDtBQVFELENBVEQ7O2tCQVdlLHlCQUFRdUYsZUFBUixFQUF5QlEsa0JBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUN4QmY7Ozs7QUFDQTs7Ozs7Ozs7Ozs7O0lBRU1vb0IscUI7OztBQUNKLGlDQUFhOWYsS0FBYixFQUFvQjtBQUFBOztBQUFBLDhJQUNaQSxLQURZOztBQUVsQixVQUFLK2YsZ0JBQUwsR0FBd0IsTUFBS0EsZ0JBQUwsQ0FBc0IxZixJQUF0QixPQUF4QjtBQUNBLFVBQUtrYyxXQUFMLEdBQW1CLE1BQUtBLFdBQUwsQ0FBaUJsYyxJQUFqQixPQUFuQjtBQUNBLFVBQUsyZixZQUFMLEdBQW9CLE1BQUtBLFlBQUwsQ0FBa0IzZixJQUFsQixPQUFwQjtBQUprQjtBQUtuQjs7Ozt1Q0FDbUI7QUFDbEIsV0FBS0wsS0FBTCxDQUFXNmYsc0JBQVgsQ0FBa0MsQ0FBQyxLQUFLN2YsS0FBTCxDQUFXMU4sa0JBQTlDO0FBQ0Q7OztnQ0FDWWtOLEssRUFBTztBQUNsQixVQUFNK1osU0FBUy9aLE1BQU0rWixNQUFyQjtBQUNBLFVBQU01bkIsUUFBUTRuQixPQUFPam9CLElBQVAsS0FBZ0IsVUFBaEIsR0FBNkJpb0IsT0FBTzBHLE9BQXBDLEdBQThDMUcsT0FBTzVuQixLQUFuRTtBQUNBLFVBQU1ELE9BQU82bkIsT0FBTzduQixJQUFwQjtBQUNBLFdBQUtzTyxLQUFMLENBQVdxYyxnQkFBWCxDQUE0QjNxQixJQUE1QixFQUFrQ0MsS0FBbEM7QUFDRDs7O2lDQUNhNk4sSyxFQUFPO0FBQ25CLFVBQU05TixPQUFPOE4sTUFBTStaLE1BQU4sQ0FBYTduQixJQUExQjtBQUNBLFVBQU13dUIsaUJBQWlCMWdCLE1BQU0rWixNQUFOLENBQWFDLGVBQWIsQ0FBNkIsQ0FBN0IsRUFBZ0M3bkIsS0FBdkQ7QUFDQSxXQUFLcU8sS0FBTCxDQUFXcWMsZ0JBQVgsQ0FBNEIzcUIsSUFBNUIsRUFBa0N3dUIsY0FBbEM7QUFDRDs7OzZCQUNTO0FBQ1IsYUFDRTtBQUFBO0FBQUEsVUFBSyxJQUFHLGlCQUFSLEVBQTBCLFdBQVUsdUNBQXBDO0FBQ0csYUFBS2xnQixLQUFMLENBQVcxTixrQkFBWCxJQUNDO0FBQUE7QUFBQTtBQUNFO0FBQUE7QUFBQSxjQUFLLFdBQVUsaUJBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxtREFBZjtBQUNFO0FBQUE7QUFBQSxrQkFBTyxTQUFRLGlCQUFmLEVBQWlDLFdBQVUsT0FBM0M7QUFBQTtBQUFBO0FBREYsYUFERjtBQUdRO0FBQUE7QUFBQSxnQkFBSyxXQUFVLGlDQUFmO0FBQ0o7QUFDRSxvQkFBRyxxQkFETDtBQUVFLDJCQUFVLGlEQUZaO0FBR0Usc0JBQU0sQ0FIUjtBQUlFLDJCQUFXLElBSmI7QUFLRSx1QkFBTyxFQUFFNnRCLFdBQVcsR0FBYixFQUxUO0FBTUUsc0JBQUssYUFOUDtBQU9FLDZCQUFZLHNCQVBkO0FBUUUsdUJBQU8sS0FBS25nQixLQUFMLENBQVdqTixXQVJwQjtBQVNFLDBCQUFVLEtBQUt3cEIsV0FUakI7QUFESTtBQUhSLFdBREY7QUFrQkU7QUFBQTtBQUFBLGNBQUssV0FBVSxpQkFBZjtBQUNFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLGlDQUFmO0FBQ0U7QUFBQTtBQUFBLGtCQUFPLFNBQVEsaUJBQWYsRUFBaUMsV0FBVSxPQUEzQztBQUFBO0FBQUE7QUFERixhQURGO0FBR1E7QUFBQTtBQUFBLGdCQUFLLFdBQVUsaUNBQWY7QUFDSjtBQUFBO0FBQUEsa0JBQVEsTUFBSyxNQUFiLEVBQW9CLE1BQUssU0FBekIsRUFBbUMsSUFBRyxpQkFBdEMsRUFBd0QsV0FBVSx3QkFBbEUsRUFBMkYsVUFBVSxLQUFLeUQsWUFBMUc7QUFDRTtBQUFBO0FBQUEsb0JBQVEsT0FBTSxHQUFkO0FBQUE7QUFBQSxpQkFERjtBQUVFO0FBQUE7QUFBQSxvQkFBUSxPQUFNLGVBQWQ7QUFBQTtBQUFBLGlCQUZGO0FBR0U7QUFBQTtBQUFBLG9CQUFRLE9BQU0sa0JBQWQ7QUFBQTtBQUFBO0FBSEY7QUFESTtBQUhSLFdBbEJGO0FBOEJFO0FBQUE7QUFBQSxjQUFLLFdBQVUsaUJBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxrQkFBZjtBQUNFO0FBQUE7QUFBQSxrQkFBTyxTQUFRLGNBQWYsRUFBOEIsV0FBVSxPQUF4QztBQUFBO0FBQUE7QUFERixhQURGO0FBR1E7QUFBQTtBQUFBLGdCQUFLLFdBQVUsa0JBQWY7QUFDSix1REFBTyxXQUFVLGdCQUFqQixFQUFrQyxNQUFLLFVBQXZDLEVBQWtELElBQUcsY0FBckQsRUFBb0UsTUFBSyxNQUF6RSxFQUFnRixPQUFPLEtBQUtoZ0IsS0FBTCxDQUFXc0MsSUFBbEcsRUFBd0csVUFBVSxLQUFLaWEsV0FBdkg7QUFESTtBQUhSO0FBOUJGLFNBRko7QUF5Q0U7QUFBQTtBQUFBLFlBQVEsV0FBVSxtQkFBbEIsRUFBc0MsU0FBUyxLQUFLd0QsZ0JBQXBEO0FBQXVFLGVBQUsvZixLQUFMLENBQVcxTixrQkFBWCxHQUFnQyxNQUFoQyxHQUF5QztBQUFoSDtBQXpDRixPQURGO0FBNkNEOzs7O0VBbkVpQyxnQkFBTTZPLFM7O2tCQXNFM0IyZSxxQjs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN6RWY7Ozs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7SUFFTU0saUI7OztBQUNKLDZCQUFhcGdCLEtBQWIsRUFBb0I7QUFBQTs7QUFBQSxzSUFDWkEsS0FEWTs7QUFFbEIsVUFBS3FnQixhQUFMLEdBQXFCLE1BQUtBLGFBQUwsQ0FBbUJoZ0IsSUFBbkIsT0FBckI7QUFGa0I7QUFHbkI7Ozs7d0NBQ29CO0FBQ25CLFdBQUtpZ0IsY0FBTCxDQUFvQixFQUFwQjtBQUNEOzs7a0NBQ2M5Z0IsSyxFQUFPO0FBQUEsVUFDWitnQixRQURZLEdBQ0MsS0FBS3ZnQixLQUROLENBQ1p1Z0IsUUFEWTs7QUFFcEIsVUFBSUEsUUFBSixFQUFjQSxTQUFTL2dCLEtBQVQ7QUFDZCxXQUFLOGdCLGNBQUwsQ0FBb0I5Z0IsS0FBcEI7QUFDRDs7O3lDQUNxQztBQUFBLDZCQUFwQitaLE1BQW9CO0FBQUEsVUFBcEJBLE1BQW9CLCtCQUFYLEtBQUtpSCxFQUFNOztBQUNwQ2pILGFBQU9rSCxLQUFQLENBQWFuYyxNQUFiLEdBQXNCLENBQXRCO0FBQ0FpVixhQUFPa0gsS0FBUCxDQUFhbmMsTUFBYixHQUF5QmlWLE9BQU9tSCxZQUFoQztBQUNEOzs7NkJBQ1M7QUFBQTs7QUFBQSxVQUNHQyxJQURILDRCQUNZLEtBQUszZ0IsS0FEakI7O0FBRVIsYUFDRSx1REFDTTJnQixJQUROO0FBRUUsYUFBSztBQUFBLGlCQUFLLE9BQUtILEVBQUwsR0FBVUksQ0FBZjtBQUFBLFNBRlA7QUFHRSxrQkFBVSxLQUFLUDtBQUhqQixTQURGO0FBT0Q7Ozs7OztBQUdIRCxrQkFBa0JoZixTQUFsQixHQUE4QjtBQUM1Qm1mLFlBQVUsb0JBQVVNO0FBRFEsQ0FBOUI7O2tCQUllVCxpQjs7Ozs7Ozs7Ozs7OztBQ3BDZjs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsSUFBTWxwQixrQkFBa0IsU0FBbEJBLGVBQWtCLE9BQTBCO0FBQUEsTUFBdkJwRixPQUF1QixRQUF2QkEsT0FBdUI7QUFBQSxNQUFkcVYsT0FBYyxRQUFkQSxPQUFjOztBQUNoRCxTQUFPO0FBQ0xzVix5QkFBcUIzcUIsUUFBUXNGLGVBQVIsQ0FBd0IxRixJQUR4QztBQUVMbWxCLHNCQUFxQjFQLFFBQVEwUCxnQkFGeEI7QUFHTEMscUJBQXFCM1AsUUFBUTJQLGVBSHhCO0FBSUxnSyxrQkFBcUIzWixRQUFRMVIsS0FBUixDQUFjM0Q7QUFKOUIsR0FBUDtBQU1ELENBUEQ7O0FBU0EsSUFBTTRGLHFCQUFxQixTQUFyQkEsa0JBQXFCLFdBQVk7QUFDckMsU0FBTztBQUNMcXBCLDhCQUEwQixrQ0FBQ3B2QixLQUFELEVBQVc7QUFDbkNpRyxlQUFTLDBCQUFZLFNBQVosRUFBdUIsSUFBdkIsQ0FBVDtBQUNBQSxlQUFTLGtDQUFvQmpHLEtBQXBCLENBQVQ7QUFDRCxLQUpJO0FBS0xxdkIscUJBQWlCLHlCQUFDcnZCLEtBQUQsRUFBVztBQUMxQmlHLGVBQVMsMEJBQVksU0FBWixFQUF1QixJQUF2QixDQUFUO0FBQ0FBLGVBQVMsb0NBQXNCakcsS0FBdEIsQ0FBVDtBQUNEO0FBUkksR0FBUDtBQVVELENBWEQ7O2tCQWFlLHlCQUFRdUYsZUFBUixFQUF5QlEsa0JBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUMxQmY7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0lBQVl1cEIsTTs7Ozs7Ozs7Ozs7O0lBRU5DLGE7OztBQUNKLHlCQUFhbGhCLEtBQWIsRUFBb0I7QUFBQTs7QUFBQSw4SEFDWkEsS0FEWTs7QUFFbEIsVUFBS21oQixzQkFBTCxHQUE4QixNQUFLQSxzQkFBTCxDQUE0QjlnQixJQUE1QixPQUE5QjtBQUNBLFVBQUtnWixlQUFMLEdBQXVCLE1BQUtBLGVBQUwsQ0FBcUJoWixJQUFyQixPQUF2QjtBQUhrQjtBQUluQjs7OzsyQ0FDdUJiLEssRUFBTztBQUM3QixVQUFNN04sUUFBUTZOLE1BQU0rWixNQUFOLENBQWE1bkIsS0FBM0I7QUFDQSxVQUFJQSxVQUFVLFdBQWQsRUFBMkI7QUFDekIsYUFBS3FPLEtBQUwsQ0FBVytnQix3QkFBWCxDQUFvQyxLQUFwQztBQUNELE9BRkQsTUFFTztBQUNMLGFBQUsvZ0IsS0FBTCxDQUFXK2dCLHdCQUFYLENBQW9DLElBQXBDO0FBQ0Q7QUFDRjs7O29DQUNnQnZoQixLLEVBQU87QUFDdEIsVUFBTTBnQixpQkFBaUIxZ0IsTUFBTStaLE1BQU4sQ0FBYUMsZUFBYixDQUE2QixDQUE3QixFQUFnQzduQixLQUF2RDtBQUNBLFdBQUtxTyxLQUFMLENBQVdnaEIsZUFBWCxDQUEyQmQsY0FBM0I7QUFDRDs7OzZCQUNTO0FBQ1IsYUFDRTtBQUFBO0FBQUE7QUFDRTtBQUFBO0FBQUE7QUFDRTtBQUFBO0FBQUEsY0FBSyxXQUFVLGlDQUFmO0FBQ0UscURBQU8sTUFBSyxPQUFaLEVBQW9CLE1BQUssc0JBQXpCLEVBQWdELElBQUcsaUJBQW5ELEVBQXFFLFdBQVUsYUFBL0UsRUFBNkYsT0FBTSxXQUFuRyxFQUErRyxTQUFTLENBQUMsS0FBS2xnQixLQUFMLENBQVc2VyxnQkFBcEksRUFBc0osVUFBVSxLQUFLc0ssc0JBQXJLLEdBREY7QUFFRTtBQUFBO0FBQUEsZ0JBQU8sV0FBVSxzQkFBakIsRUFBd0MsU0FBUSxpQkFBaEQ7QUFBQTtBQUFBO0FBRkYsV0FERjtBQUtFO0FBQUE7QUFBQSxjQUFLLFdBQVUsaUNBQWY7QUFDRSxxREFBTyxNQUFLLE9BQVosRUFBb0IsTUFBSyxzQkFBekIsRUFBZ0QsSUFBRyxlQUFuRCxFQUFtRSxXQUFVLGFBQTdFLEVBQTJGLE9BQU0sY0FBakcsRUFBZ0gsU0FBUyxLQUFLbmhCLEtBQUwsQ0FBVzZXLGdCQUFwSSxFQUFzSixVQUFVLEtBQUtzSyxzQkFBckssR0FERjtBQUVFO0FBQUE7QUFBQSxnQkFBTyxXQUFVLHNCQUFqQixFQUF3QyxTQUFRLGVBQWhEO0FBQUE7QUFBQTtBQUZGLFdBTEY7QUFTSSxlQUFLbmhCLEtBQUwsQ0FBVzhnQixZQUFYLEdBQ0E7QUFBQTtBQUFBLGNBQUcsV0FBVSx1QkFBYjtBQUFzQyxpQkFBSzlnQixLQUFMLENBQVc4Z0I7QUFBakQsV0FEQSxHQUdBO0FBQUE7QUFBQSxjQUFHLFdBQVUsY0FBYjtBQUFBO0FBQUE7QUFaSixTQURGO0FBZ0JJLGFBQUs5Z0IsS0FBTCxDQUFXNlcsZ0JBQVgsSUFDQTtBQUFBO0FBQUE7QUFDRTtBQUFBO0FBQUEsY0FBSyxXQUFVLGtCQUFmO0FBQ0U7QUFBQTtBQUFBLGdCQUFPLFdBQVUsT0FBakIsRUFBeUIsU0FBUSxxQkFBakM7QUFBQTtBQUFBO0FBREYsV0FERjtBQUdRO0FBQUE7QUFBQSxjQUFLLFdBQVUsa0JBQWY7QUFDSjtBQUFBO0FBQUEsZ0JBQVEsTUFBSyxNQUFiLEVBQW9CLElBQUcscUJBQXZCLEVBQTZDLFdBQVUsc0JBQXZELEVBQThFLE9BQU8sS0FBSzdXLEtBQUwsQ0FBVzhXLGVBQWhHLEVBQWlILFVBQVUsS0FBS3VDLGVBQWhJO0FBQ0ksbUJBQUtyWixLQUFMLENBQVd5YyxtQkFBWCxJQUFrQztBQUFBO0FBQUEsa0JBQVEsT0FBTyxLQUFLemMsS0FBTCxDQUFXeWMsbUJBQTFCLEVBQStDLElBQUcsdUNBQWxEO0FBQTJGLHFCQUFLemMsS0FBTCxDQUFXeWM7QUFBdEcsZUFEdEM7QUFFRTtBQUFBO0FBQUEsa0JBQVEsT0FBT3dFLE9BQU83WixLQUF0QjtBQUFBO0FBQUEsZUFGRjtBQUdFO0FBQUE7QUFBQSxrQkFBUSxPQUFPNlosT0FBTzVaLE1BQXRCO0FBQUE7QUFBQTtBQUhGO0FBREksV0FIUjtBQVVLLGVBQUtySCxLQUFMLENBQVc4VyxlQUFYLEtBQStCbUssT0FBTzdaLEtBQXZDLElBQWlELCtEQVZyRDtBQVdLLGVBQUtwSCxLQUFMLENBQVc4VyxlQUFYLEtBQStCbUssT0FBTzVaLE1BQXZDLElBQWtEO0FBWHREO0FBakJKLE9BREY7QUFrQ0Q7Ozs7RUFyRHlCLGdCQUFNbEcsUzs7a0JBd0RuQitmLGE7Ozs7Ozs7Ozs7Ozs7OztBQzdEZjs7OztBQUNBOzs7Ozs7Ozs7Ozs7OztJQUVNRSxnQjs7O0FBQ0osNEJBQWFwaEIsS0FBYixFQUFvQjtBQUFBOztBQUFBLG9JQUNaQSxLQURZOztBQUVsQixVQUFLbkUsS0FBTCxHQUFhO0FBQ1hwRyxhQUFVLElBREM7QUFFWC9ELFlBQVUsRUFGQztBQUdYK0MsZ0JBQVU7QUFIQyxLQUFiO0FBS0EsVUFBSzhuQixXQUFMLEdBQW1CLE1BQUtBLFdBQUwsQ0FBaUJsYyxJQUFqQixPQUFuQjtBQUNBLFVBQUtnaEIsY0FBTCxHQUFzQixNQUFLQSxjQUFMLENBQW9CaGhCLElBQXBCLE9BQXRCO0FBUmtCO0FBU25COzs7O2dDQUNZYixLLEVBQU87QUFDbEIsVUFBTTlOLE9BQU84TixNQUFNK1osTUFBTixDQUFhN25CLElBQTFCO0FBQ0EsVUFBTUMsUUFBUTZOLE1BQU0rWixNQUFOLENBQWE1bkIsS0FBM0I7QUFDQSxXQUFLa1AsUUFBTCxxQkFBZ0JuUCxJQUFoQixFQUF1QkMsS0FBdkI7QUFDRDs7O21DQUNlNk4sSyxFQUFPO0FBQUE7O0FBQ3JCQSxZQUFNbWIsY0FBTjtBQUNBLFVBQU1oaUIsU0FBUztBQUNic0UsZ0JBQVMsTUFESTtBQUVib1csY0FBUzVXLEtBQUtDLFNBQUwsQ0FBZSxFQUFDbEksVUFBVSxLQUFLcUgsS0FBTCxDQUFXbkssSUFBdEIsRUFBNEIrQyxVQUFVLEtBQUtvSCxLQUFMLENBQVdwSCxRQUFqRCxFQUFmLENBRkk7QUFHYnNKLGlCQUFTLElBQUl1akIsT0FBSixDQUFZO0FBQ25CLDBCQUFnQjtBQURHLFNBQVosQ0FISTtBQU1iaEkscUJBQWE7QUFOQSxPQUFmO0FBUUEsNkJBQVEsT0FBUixFQUFpQjNnQixNQUFqQixFQUNHckQsSUFESCxDQUNRLGdCQUFxRTtBQUFBLFlBQW5FMlAsT0FBbUUsUUFBbkVBLE9BQW1FO0FBQUEsWUFBMUQ3UyxXQUEwRCxRQUExREEsV0FBMEQ7QUFBQSxZQUE3Q3diLGNBQTZDLFFBQTdDQSxjQUE2QztBQUFBLFlBQTdCckksY0FBNkIsUUFBN0JBLGNBQTZCO0FBQUEsWUFBYnRULE9BQWEsUUFBYkEsT0FBYTs7QUFDekUsWUFBSWdULE9BQUosRUFBYTtBQUNYLGlCQUFLakYsS0FBTCxDQUFXckksY0FBWCxDQUEwQnZGLFdBQTFCLEVBQXVDd2IsY0FBdkMsRUFBdURySSxjQUF2RDtBQUNELFNBRkQsTUFFTztBQUNMLGlCQUFLMUUsUUFBTCxDQUFjLEVBQUMsU0FBUzVPLE9BQVYsRUFBZDtBQUNEO0FBQ0YsT0FQSCxFQVFHdUQsS0FSSCxDQVFTLGlCQUFTO0FBQ2QsWUFBSUMsTUFBTXhELE9BQVYsRUFBbUI7QUFDakIsaUJBQUs0TyxRQUFMLENBQWMsRUFBQyxTQUFTcEwsTUFBTXhELE9BQWhCLEVBQWQ7QUFDRCxTQUZELE1BRU87QUFDTCxpQkFBSzRPLFFBQUwsQ0FBYyxFQUFDLFNBQVNwTCxLQUFWLEVBQWQ7QUFDRDtBQUNGLE9BZEg7QUFlRDs7OzZCQUNTO0FBQ1IsYUFDRTtBQUFBO0FBQUEsVUFBTSxJQUFHLG9CQUFUO0FBQ0U7QUFBQTtBQUFBLFlBQUssV0FBVSwwQkFBZjtBQUNFO0FBQUE7QUFBQSxjQUFLLFdBQVUsaUNBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQU8sV0FBVSxPQUFqQixFQUF5QixTQUFRLDBCQUFqQztBQUFBO0FBQUE7QUFERixXQURGO0FBR1E7QUFBQTtBQUFBLGNBQUssV0FBVSxpQ0FBZjtBQUNKO0FBQUE7QUFBQSxnQkFBSyxXQUFVLHFFQUFmO0FBQ0U7QUFBQTtBQUFBO0FBQUE7QUFBQSxlQURGO0FBRUUsdURBQU8sTUFBSyxNQUFaLEVBQW1CLElBQUcsMEJBQXRCLEVBQWlELFdBQVUsWUFBM0QsRUFBd0UsTUFBSyxNQUE3RSxFQUFvRixhQUFZLG1CQUFoRyxFQUFvSCxPQUFPLEtBQUtvRyxLQUFMLENBQVd6SixXQUF0SSxFQUFtSixVQUFVLEtBQUttcUIsV0FBbEs7QUFGRjtBQURJO0FBSFIsU0FERjtBQVdFO0FBQUE7QUFBQSxZQUFLLFdBQVUsMEJBQWY7QUFDRTtBQUFBO0FBQUEsY0FBSyxXQUFVLGlDQUFmO0FBQ0U7QUFBQTtBQUFBLGdCQUFPLFdBQVUsT0FBakIsRUFBeUIsU0FBUSw4QkFBakM7QUFBQTtBQUFBO0FBREYsV0FERjtBQUdRO0FBQUE7QUFBQSxjQUFLLFdBQVUsaUNBQWY7QUFDSjtBQUFBO0FBQUEsZ0JBQUssV0FBVSxxQkFBZjtBQUNFLHVEQUFPLE1BQUssVUFBWixFQUF1QixJQUFHLDhCQUExQixFQUF5RCxNQUFLLFVBQTlELEVBQXlFLFdBQVUsWUFBbkYsRUFBZ0csYUFBWSxFQUE1RyxFQUErRyxPQUFPLEtBQUsxZ0IsS0FBTCxDQUFXZ1ksZUFBakksRUFBa0osVUFBVSxLQUFLMEksV0FBaks7QUFERjtBQURJO0FBSFIsU0FYRjtBQW9CSSxhQUFLMWdCLEtBQUwsQ0FBV3BHLEtBQVgsR0FDQTtBQUFBO0FBQUEsWUFBRyxXQUFVLHVCQUFiO0FBQXNDLGVBQUtvRyxLQUFMLENBQVdwRztBQUFqRCxTQURBLEdBR0E7QUFBQTtBQUFBLFlBQUcsV0FBVSxjQUFiO0FBQUE7QUFBQSxTQXZCSjtBQXlCRTtBQUFBO0FBQUEsWUFBSyxXQUFVLGVBQWY7QUFDRTtBQUFBO0FBQUEsY0FBUSxXQUFVLGlCQUFsQixFQUFvQyxTQUFTLEtBQUs0ckIsY0FBbEQ7QUFBQTtBQUFBO0FBREY7QUF6QkYsT0FERjtBQStCRDs7OztFQTFFNEIsZ0JBQU1sZ0IsUzs7a0JBNkV0QmlnQixnQjs7Ozs7Ozs7Ozs7Ozs7O0FDaEZmOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7SUFFTUcsaUI7OztBQUNKLDZCQUFhdmhCLEtBQWIsRUFBb0I7QUFBQTs7QUFBQSxzSUFDWkEsS0FEWTs7QUFFbEIsVUFBS25FLEtBQUwsR0FBYTtBQUNYcEcsYUFBVSxJQURDO0FBRVgzRCxlQUFVLEVBRkM7QUFHWDJDLGdCQUFVLEVBSEM7QUFJWHpDLGNBQVU7QUFKQyxLQUFiO0FBTUEsVUFBS3d2QixrQkFBTCxHQUEwQixNQUFLQSxrQkFBTCxDQUF3Qm5oQixJQUF4QixPQUExQjtBQUNBLFVBQUtrYyxXQUFMLEdBQW1CLE1BQUtBLFdBQUwsQ0FBaUJsYyxJQUFqQixPQUFuQjtBQUNBLFVBQUszQyxhQUFMLEdBQXFCLE1BQUtBLGFBQUwsQ0FBbUIyQyxJQUFuQixPQUFyQjtBQVZrQjtBQVduQjs7Ozt3Q0FDb0I2YyxLLEVBQU87QUFDMUJBLGNBQVFBLE1BQU05ZCxPQUFOLENBQWMsTUFBZCxFQUFzQixHQUF0QixDQUFSLENBRDBCLENBQ1U7QUFDcEM4ZCxjQUFRQSxNQUFNOWQsT0FBTixDQUFjLGdCQUFkLEVBQWdDLEVBQWhDLENBQVIsQ0FGMEIsQ0FFb0I7QUFDOUMsYUFBTzhkLEtBQVA7QUFDRDs7O3VDQUNtQjFkLEssRUFBTztBQUN6QixVQUFJN04sUUFBUTZOLE1BQU0rWixNQUFOLENBQWE1bkIsS0FBekI7QUFDQUEsY0FBUSxLQUFLOHZCLG1CQUFMLENBQXlCOXZCLEtBQXpCLENBQVI7QUFDQSxXQUFLa1AsUUFBTCxDQUFjLEVBQUMvTyxTQUFTSCxLQUFWLEVBQWQ7QUFDQSxVQUFJQSxLQUFKLEVBQVc7QUFDVCxhQUFLK3ZCLHdCQUFMLENBQThCL3ZCLEtBQTlCO0FBQ0QsT0FGRCxNQUVPO0FBQ0wsYUFBS2tQLFFBQUwsQ0FBYyxFQUFDcEwsT0FBTyw2QkFBUixFQUFkO0FBQ0Q7QUFDRjs7O2dDQUNZK0osSyxFQUFPO0FBQ2xCLFVBQU05TixPQUFPOE4sTUFBTStaLE1BQU4sQ0FBYTduQixJQUExQjtBQUNBLFVBQU1DLFFBQVE2TixNQUFNK1osTUFBTixDQUFhNW5CLEtBQTNCO0FBQ0EsV0FBS2tQLFFBQUwscUJBQWdCblAsSUFBaEIsRUFBdUJDLEtBQXZCO0FBQ0Q7Ozs2Q0FDeUJHLE8sRUFBUztBQUFBOztBQUNqQyxVQUFNNnZCLDRCQUEwQjd2QixPQUFoQztBQUNBLDREQUFxQzZ2QixtQkFBckMsRUFDR3JzQixJQURILENBQ1EsWUFBTTtBQUNWLGVBQUt1TCxRQUFMLENBQWMsRUFBQyxTQUFTLElBQVYsRUFBZDtBQUNELE9BSEgsRUFJR3JMLEtBSkgsQ0FJUyxVQUFDQyxLQUFELEVBQVc7QUFDaEIsZUFBS29MLFFBQUwsQ0FBYyxFQUFDLFNBQVNwTCxNQUFNeEQsT0FBaEIsRUFBZDtBQUNELE9BTkg7QUFPRDs7OzRDQUN3QkgsTyxFQUFTO0FBQ2hDLFVBQU02dkIsNEJBQTBCN3ZCLE9BQWhDO0FBQ0EsYUFBTyxzREFBcUM2dkIsbUJBQXJDLENBQVA7QUFDRDs7OzRDQUN3Qmx0QixRLEVBQVU7QUFDakMsYUFBTyxJQUFJNEcsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdEMsWUFBSSxDQUFDOUgsUUFBRCxJQUFhQSxTQUFTeU4sTUFBVCxHQUFrQixDQUFuQyxFQUFzQztBQUNwQyxpQkFBTzNGLE9BQU8sSUFBSXRCLEtBQUosQ0FBVSwyQkFBVixDQUFQLENBQVA7QUFDRDtBQUNEcUI7QUFDRCxPQUxNLENBQVA7QUFNRDs7OzhDQUMwQjlILFEsRUFBVUMsUSxFQUFVO0FBQzdDLFVBQU1rRSxTQUFTO0FBQ2JzRSxnQkFBUyxNQURJO0FBRWJvVyxjQUFTNVcsS0FBS0MsU0FBTCxDQUFlLEVBQUNsSSxrQkFBRCxFQUFXQyxrQkFBWCxFQUFmLENBRkk7QUFHYnNKLGlCQUFTLElBQUl1akIsT0FBSixDQUFZO0FBQ25CLDBCQUFnQjtBQURHLFNBQVosQ0FISTtBQU1iaEkscUJBQWE7QUFOQSxPQUFmO0FBUUEsYUFBTyxJQUFJamUsT0FBSixDQUFZLFVBQUNpQixPQUFELEVBQVVDLE1BQVYsRUFBcUI7QUFDdEMsK0JBQVEsU0FBUixFQUFtQjVELE1BQW5CLEVBQ0dyRCxJQURILENBQ1Esa0JBQVU7QUFDZCxpQkFBT2dILFFBQVFFLE1BQVIsQ0FBUDtBQUNELFNBSEgsRUFJR2hILEtBSkgsQ0FJUyxpQkFBUztBQUNkK0csaUJBQU8sSUFBSXRCLEtBQUoseUdBQWdIeEYsTUFBTXhELE9BQXRILENBQVA7QUFDRCxTQU5IO0FBT0QsT0FSTSxDQUFQO0FBU0Q7OztrQ0FDY3VOLEssRUFBTztBQUFBOztBQUNwQkEsWUFBTW1iLGNBQU47QUFDQSxXQUFLaUgsdUJBQUwsQ0FBNkIsS0FBSy9sQixLQUFMLENBQVdwSCxRQUF4QyxFQUNHYSxJQURILENBQ1EsWUFBTTtBQUNWLGVBQU8sT0FBS3VzQix1QkFBTCxDQUE2QixPQUFLaG1CLEtBQUwsQ0FBVy9KLE9BQXhDLENBQVA7QUFDRCxPQUhILEVBSUd3RCxJQUpILENBSVEsWUFBTTtBQUNWLGVBQUt1TCxRQUFMLENBQWMsRUFBQzdPLFFBQVEsbURBQVQsRUFBZDtBQUNBLGVBQU8sT0FBSzh2Qix5QkFBTCxDQUErQixPQUFLam1CLEtBQUwsQ0FBVy9KLE9BQTFDLEVBQW1ELE9BQUsrSixLQUFMLENBQVdwSCxRQUE5RCxDQUFQO0FBQ0QsT0FQSCxFQVFHYSxJQVJILENBUVEsa0JBQVU7QUFDZCxlQUFLdUwsUUFBTCxDQUFjLEVBQUM3TyxRQUFRLElBQVQsRUFBZDtBQUNBLGVBQUtnTyxLQUFMLENBQVdySSxjQUFYLENBQTBCNkUsT0FBT3BLLFdBQWpDLEVBQThDb0ssT0FBT29SLGNBQXJELEVBQXFFcFIsT0FBTytJLGNBQTVFO0FBQ0QsT0FYSCxFQVlHL1AsS0FaSCxDQVlTLFVBQUNDLEtBQUQsRUFBVztBQUNoQixZQUFJQSxNQUFNeEQsT0FBVixFQUFtQjtBQUNqQixpQkFBSzRPLFFBQUwsQ0FBYyxFQUFDLFNBQVNwTCxNQUFNeEQsT0FBaEIsRUFBeUJELFFBQVEsSUFBakMsRUFBZDtBQUNELFNBRkQsTUFFTztBQUNMLGlCQUFLNk8sUUFBTCxDQUFjLEVBQUMsU0FBU3BMLEtBQVYsRUFBaUJ6RCxRQUFRLElBQXpCLEVBQWQ7QUFDRDtBQUNGLE9BbEJIO0FBbUJEOzs7NkJBQ1M7QUFDUixhQUNFO0FBQUE7QUFBQTtBQUNJLFNBQUMsS0FBSzZKLEtBQUwsQ0FBVzdKLE1BQVosR0FDQTtBQUFBO0FBQUEsWUFBTSxJQUFHLHNCQUFUO0FBQ0U7QUFBQTtBQUFBLGNBQUssV0FBVSwwQkFBZjtBQUNFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLGlDQUFmO0FBQ0U7QUFBQTtBQUFBLGtCQUFPLFdBQVUsT0FBakIsRUFBeUIsU0FBUSxrQkFBakM7QUFBQTtBQUFBO0FBREYsYUFERjtBQUdRO0FBQUE7QUFBQSxnQkFBSyxXQUFVLGlDQUFmO0FBQ0o7QUFBQTtBQUFBLGtCQUFLLFdBQVUsb0ZBQWY7QUFDRTtBQUFBO0FBQUE7QUFBQTtBQUFBLGlCQURGO0FBRUUseURBQU8sTUFBSyxNQUFaLEVBQW1CLE1BQUssU0FBeEIsRUFBa0MsSUFBRyxrQkFBckMsRUFBd0QsV0FBVSxZQUFsRSxFQUErRSxhQUFZLG9CQUEzRixFQUFnSCxPQUFPLEtBQUs2SixLQUFMLENBQVcvSixPQUFsSSxFQUEySSxVQUFVLEtBQUswdkIsa0JBQTFKLEdBRkY7QUFHSyxxQkFBSzNsQixLQUFMLENBQVcvSixPQUFYLElBQXNCLENBQUMsS0FBSytKLEtBQUwsQ0FBV3BHLEtBQW5DLElBQTZDO0FBQUE7QUFBQSxvQkFBTSxJQUFHLDRCQUFULEVBQXNDLFdBQVUsc0NBQWhEO0FBQXdGO0FBQXhGLGlCQUhqRDtBQUlJLHFCQUFLb0csS0FBTCxDQUFXcEcsS0FBWCxJQUFvQjtBQUFBO0FBQUEsb0JBQU0sSUFBRyw0QkFBVCxFQUFzQyxXQUFVLHNDQUFoRDtBQUF3RjtBQUF4RjtBQUp4QjtBQURJO0FBSFIsV0FERjtBQWFFO0FBQUE7QUFBQSxjQUFLLFdBQVUsMEJBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxpQ0FBZjtBQUNFO0FBQUE7QUFBQSxrQkFBTyxXQUFVLE9BQWpCLEVBQXlCLFNBQVEsc0JBQWpDO0FBQUE7QUFBQTtBQURGLGFBREY7QUFHUTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxpQ0FBZjtBQUNKO0FBQUE7QUFBQSxrQkFBSyxXQUFVLHFCQUFmO0FBQ0UseURBQU8sTUFBSyxVQUFaLEVBQXVCLE1BQUssVUFBNUIsRUFBdUMsSUFBRyxzQkFBMUMsRUFBaUUsV0FBVSxZQUEzRSxFQUF5RixhQUFZLEVBQXJHLEVBQXdHLE9BQU8sS0FBS29HLEtBQUwsQ0FBV3BILFFBQTFILEVBQW9JLFVBQVUsS0FBSzhuQixXQUFuSjtBQURGO0FBREk7QUFIUixXQWJGO0FBc0JHLGVBQUsxZ0IsS0FBTCxDQUFXcEcsS0FBWCxHQUNDO0FBQUE7QUFBQSxjQUFHLFdBQVUsdUJBQWI7QUFBc0MsaUJBQUtvRyxLQUFMLENBQVdwRztBQUFqRCxXQURELEdBR0M7QUFBQTtBQUFBLGNBQUcsV0FBVSxjQUFiO0FBQUE7QUFBQSxXQXpCSjtBQTJCRTtBQUFBO0FBQUEsY0FBSyxXQUFVLGVBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQVEsV0FBVSxpQkFBbEIsRUFBb0MsU0FBUyxLQUFLaUksYUFBbEQ7QUFBQTtBQUFBO0FBREY7QUEzQkYsU0FEQSxHQWlDQTtBQUFBO0FBQUE7QUFDRTtBQUFBO0FBQUEsY0FBRyxXQUFVLFlBQWI7QUFBMkIsaUJBQUs3QixLQUFMLENBQVc3SjtBQUF0QyxXQURGO0FBRUUsaUVBQWEsTUFBTSxFQUFuQjtBQUZGO0FBbENKLE9BREY7QUEwQ0Q7Ozs7RUEzSTZCLGdCQUFNbVAsUzs7a0JBOEl2Qm9nQixpQjs7Ozs7Ozs7Ozs7OztBQ2xKZjs7Ozs7O0FBRUEsSUFBTVEsa0JBQWtCLFNBQWxCQSxlQUFrQixHQUFNO0FBQzVCLFNBQU87QUFBQTtBQUFBLE1BQU0sV0FBVSxtQ0FBaEI7QUFBQTtBQUFBLEdBQVA7QUFDRCxDQUZEOztrQkFJZUEsZTs7Ozs7Ozs7Ozs7OztBQ05mOzs7Ozs7QUFFQSxJQUFNQyxvQkFBb0IsU0FBcEJBLGlCQUFvQixHQUFNO0FBQzlCLFNBQU87QUFBQTtBQUFBLE1BQU0sV0FBVSxxQ0FBaEI7QUFBQTtBQUFBLEdBQVA7QUFDRCxDQUZEOztrQkFJZUEsaUI7Ozs7Ozs7Ozs7Ozs7QUNOZjs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsSUFBTTlxQixrQkFBa0IsU0FBbEJBLGVBQWtCLE9BQWlCO0FBQUEsTUFBZGlRLE9BQWMsUUFBZEEsT0FBYzs7QUFDdkMsU0FBTztBQUNMblYsWUFBU21WLFFBQVFuVixNQUFSLENBQWVBLE1BRG5CO0FBRUxDLGFBQVNrVixRQUFRblYsTUFBUixDQUFlQztBQUZuQixHQUFQO0FBSUQsQ0FMRDs7QUFPQSxJQUFNeUYscUJBQXFCO0FBQ3pCaEg7QUFEeUIsQ0FBM0I7O2tCQUllLHlCQUFRd0csZUFBUixFQUF5QlEsa0JBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNmZjs7OztBQUNBOzs7O0FBQ0E7O0lBQVl1cUIsYTs7Ozs7Ozs7Ozs7O0lBRU5DLGE7Ozs7Ozs7Ozs7OzZCQUNNO0FBQUEsbUJBQytCLEtBQUtsaUIsS0FEcEM7QUFBQSxVQUNBaE8sTUFEQSxVQUNBQSxNQURBO0FBQUEsVUFDUUMsT0FEUixVQUNRQSxPQURSO0FBQUEsVUFDaUJ2QixTQURqQixVQUNpQkEsU0FEakI7O0FBRVIsYUFDRTtBQUFBO0FBQUEsVUFBSyxXQUFVLG9FQUFmO0FBQ0dzQixtQkFBV2l3QixjQUFjRSxVQUF6QixJQUNEO0FBQUE7QUFBQSxZQUFLLFdBQVUsMEJBQWY7QUFDRTtBQUFBO0FBQUE7QUFBQTtBQUFBLFdBREY7QUFFRTtBQUFBO0FBQUEsY0FBRyxXQUFVLE1BQWI7QUFBQTtBQUFBO0FBRkYsU0FGRjtBQU9HbndCLG1CQUFXaXdCLGNBQWNHLE9BQXpCLElBQ0Q7QUFBQTtBQUFBO0FBQ0U7QUFBQTtBQUFBLGNBQUssV0FBVSwwQkFBZjtBQUNFO0FBQUE7QUFBQTtBQUFBO0FBQUEsYUFERjtBQUVFO0FBQUE7QUFBQSxnQkFBRyxXQUFVLE1BQWI7QUFBcUJud0I7QUFBckI7QUFGRjtBQURGLFNBUkY7QUFlR0QsbUJBQVdpd0IsY0FBY0ksVUFBekIsSUFDRDtBQUFBO0FBQUEsWUFBSyxXQUFVLDBCQUFmO0FBQ0U7QUFBQTtBQUFBO0FBQUE7QUFBQSxXQURGO0FBRUUsaUVBQWEsTUFBTSxFQUFuQixHQUZGO0FBR0U7QUFBQTtBQUFBO0FBQUE7QUFBeUM7QUFBQTtBQUFBLGdCQUFHLFdBQVUsZUFBYixFQUE2QixRQUFPLE9BQXBDLEVBQTRDLE1BQUssa0NBQWpEO0FBQUE7QUFBQTtBQUF6QztBQUhGLFNBaEJGO0FBc0JHcndCLG1CQUFXaXdCLGNBQWNLLE9BQXpCLElBQ0Q7QUFBQTtBQUFBLFlBQUssV0FBVSwwQkFBZjtBQUNFO0FBQUE7QUFBQTtBQUFBO0FBQUEsV0FERjtBQUVFO0FBQUE7QUFBQTtBQUFBO0FBQTRDO0FBQUE7QUFBQSxnQkFBRyxXQUFVLGVBQWIsRUFBNkIsUUFBTyxRQUFwQyxFQUE2QyxNQUFNcndCLE9BQW5EO0FBQUE7QUFBQTtBQUE1QztBQUZGLFNBdkJGO0FBNEJHRCxtQkFBV2l3QixjQUFjTSxNQUF6QixJQUNEO0FBQUE7QUFBQSxZQUFLLFdBQVUsMEJBQWY7QUFDRTtBQUFBO0FBQUE7QUFBQTtBQUFBLFdBREY7QUFFRTtBQUFBO0FBQUE7QUFBRztBQUFBO0FBQUE7QUFBU3R3QjtBQUFUO0FBQUgsV0FGRjtBQUdFO0FBQUE7QUFBQTtBQUFBO0FBQXFFO0FBQUE7QUFBQSxnQkFBRyxXQUFVLGVBQWIsRUFBNkIsTUFBSyw0QkFBbEMsRUFBK0QsUUFBTyxRQUF0RTtBQUFBO0FBQUE7QUFBckUsV0FIRjtBQUlFO0FBQUE7QUFBQSxjQUFRLFdBQVUsbUJBQWxCLEVBQXNDLFNBQVN2QixTQUEvQztBQUFBO0FBQUE7QUFKRjtBQTdCRixPQURGO0FBdUNEOzs7O0VBMUN5QixnQkFBTXlRLFM7O0FBMkNqQzs7a0JBRWMrZ0IsYTs7Ozs7Ozs7Ozs7O0FDakRSLElBQU1DLGtDQUFhLFlBQW5CO0FBQ0EsSUFBTUMsNEJBQVUsU0FBaEI7QUFDQSxJQUFNQyxrQ0FBYSxZQUFuQjtBQUNBLElBQU1DLDRCQUFVLFNBQWhCO0FBQ0EsSUFBTUMsMEJBQVMsUUFBZixDOzs7Ozs7Ozs7Ozs7O0FDSlA7O0FBQ0E7Ozs7OztBQUVBLElBQU1yckIsa0JBQWtCLFNBQWxCQSxlQUFrQixPQUFpQjtBQUFBLE1BQWRpUSxPQUFjLFFBQWRBLE9BQWM7O0FBQ3ZDLFNBQU87QUFDTGxWLGFBQVNrVixRQUFReFQ7QUFEWixHQUFQO0FBR0QsQ0FKRDs7a0JBTWUseUJBQVF1RCxlQUFSLEVBQXlCLElBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNUZjs7Ozs7Ozs7Ozs7O0lBRU1zckIsc0I7Ozs7Ozs7Ozs7OzZCQUNNO0FBQ1IsVUFBTXZ3QixVQUFVLEtBQUsrTixLQUFMLENBQVcvTixPQUEzQjtBQUNBb0MsY0FBUUMsR0FBUixDQUFZLHFCQUFaLEVBQW1DckMsT0FBbkM7QUFDQSxhQUNFO0FBQUE7QUFBQSxVQUFLLFdBQVUsdUZBQWY7QUFDRTtBQUFBO0FBQUEsWUFBRyxXQUFVLGdCQUFiO0FBQUE7QUFBQSxTQURGO0FBRUU7QUFBQTtBQUFBLFlBQUcsV0FBVSxnQkFBYjtBQUErQkE7QUFBL0I7QUFGRixPQURGO0FBTUQ7Ozs7RUFWa0MsZ0JBQU1rUCxTOztrQkFhNUJxaEIsc0I7Ozs7Ozs7Ozs7Ozs7OztBQ2ZmOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7Ozs7O0lBRU1DLFM7Ozs7Ozs7Ozs7OzZCQUNNO0FBQ1IsYUFDRTtBQUFBO0FBQUE7QUFDRSx1REFBSyxXQUFXLE9BQWhCLEVBQXlCLFNBQVMsT0FBbEMsR0FERjtBQUVFLDZEQUZGO0FBR0U7QUFBQTtBQUFBLFlBQUssV0FBVSxpQkFBZjtBQUNFO0FBQUE7QUFBQSxjQUFLLFdBQVUsbURBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxpQ0FBZjtBQUNFO0FBQUE7QUFBQSxrQkFBRyxXQUFVLFlBQWI7QUFBQTtBQUFBLGVBREY7QUFFRTtBQUFBO0FBQUE7QUFBRztBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLFFBQU8sUUFBcEMsRUFBNkMsTUFBSyw2QkFBbEQ7QUFBQTtBQUFBO0FBQUgsZUFGRjtBQUdFO0FBQUE7QUFBQTtBQUFHO0FBQUE7QUFBQSxvQkFBRyxXQUFVLGVBQWIsRUFBNkIsUUFBTyxRQUFwQyxFQUE2QyxNQUFLLG1DQUFsRDtBQUFBO0FBQUE7QUFBSCxlQUhGO0FBSUU7QUFBQTtBQUFBO0FBQUc7QUFBQTtBQUFBLG9CQUFHLFdBQVUsZUFBYixFQUE2QixRQUFPLFFBQXBDLEVBQTZDLE1BQUssNEJBQWxEO0FBQUE7QUFBQTtBQUFILGVBSkY7QUFLRTtBQUFBO0FBQUE7QUFBRztBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLFFBQU8sUUFBcEMsRUFBNkMsTUFBSyx5REFBbEQ7QUFBQTtBQUFBO0FBQUg7QUFMRjtBQURGLFdBREY7QUFTUTtBQUFBO0FBQUEsY0FBSyxXQUFVLG1EQUFmO0FBQ0o7QUFBQTtBQUFBLGdCQUFLLFdBQVUsaUNBQWY7QUFDRTtBQUFBO0FBQUE7QUFBQTtBQUFnRjtBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLE1BQUssaUJBQWxDO0FBQUE7QUFBQSxpQkFBaEY7QUFBQTtBQUFBLGVBREY7QUFFRTtBQUFBO0FBQUE7QUFBQTtBQUF1STtBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLE1BQUsscUJBQWxDO0FBQUE7QUFBQSxpQkFBdkk7QUFBQTtBQUFBLGVBRkY7QUFHRTtBQUFBO0FBQUE7QUFBQTtBQUFBLGVBSEY7QUFJRTtBQUFBO0FBQUE7QUFBQTtBQUErRTtBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLE1BQUssbUNBQWxDO0FBQUE7QUFBQSxpQkFBL0U7QUFBQTtBQUFBLGVBSkY7QUFLRTtBQUFBO0FBQUE7QUFBQTtBQUE0QztBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLE1BQUssNEJBQWxDO0FBQUE7QUFBQSxpQkFBNUM7QUFBQTtBQUFtSjtBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLE1BQUssMENBQWxDO0FBQUE7QUFBQSxpQkFBbko7QUFBQTtBQUFBO0FBTEY7QUFESTtBQVRSO0FBSEYsT0FERjtBQXlCRDs7OztFQTNCcUIsZ0JBQU10aEIsUzs7QUE0QjdCOztrQkFFY3NoQixTOzs7Ozs7Ozs7Ozs7O0FDbENmOztBQUNBOzs7Ozs7QUFFQSxJQUFNdnJCLGtCQUFrQixTQUFsQkEsZUFBa0IsT0FBaUI7QUFBQSxNQUFkcEYsT0FBYyxRQUFkQSxPQUFjOztBQUN2QyxTQUFPO0FBQ0wycUIseUJBQXFCM3FCLFFBQVFzRixlQUFSLENBQXdCMUY7QUFEeEMsR0FBUDtBQUdELENBSkQ7O2tCQU1lLHlCQUFRd0YsZUFBUixFQUF5QixJQUF6QixpQjs7Ozs7Ozs7Ozs7Ozs7O0FDVGY7Ozs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7Ozs7O0lBRU13ckIsUzs7Ozs7Ozs7Ozs7OENBQ3VCOUcsUSxFQUFVO0FBQ25DO0FBQ0EsVUFBSUEsU0FBU2EsbUJBQVQsS0FBaUMsS0FBS3pjLEtBQUwsQ0FBV3ljLG1CQUFoRCxFQUFxRTtBQUNuRSxhQUFLemMsS0FBTCxDQUFXdk4sT0FBWCxDQUFtQmtPLElBQW5CO0FBQ0Q7QUFDRjs7OzZCQUNTO0FBQ1IsYUFDRTtBQUFBO0FBQUE7QUFDRSx1REFBSyxXQUFXLE9BQWhCLEVBQXlCLFNBQVMsT0FBbEMsR0FERjtBQUVFLDZEQUZGO0FBR0U7QUFBQTtBQUFBLFlBQUssV0FBVSxpQkFBZjtBQUNFO0FBQUE7QUFBQSxjQUFLLFdBQVUsbURBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxpQ0FBZjtBQUNFO0FBQUE7QUFBQTtBQUFBO0FBQXlNO0FBQUE7QUFBQSxvQkFBRyxXQUFVLGVBQWIsRUFBNkIsUUFBTyxRQUFwQyxFQUE2QyxNQUFLLDBEQUFsRDtBQUFBO0FBQUEsaUJBQXpNO0FBQUE7QUFBMFg7QUFBQTtBQUFBLG9CQUFHLFdBQVUsZUFBYixFQUE2QixRQUFPLFFBQXBDLEVBQTZDLE1BQUssV0FBbEQ7QUFBQTtBQUFBLGlCQUExWDtBQUFBO0FBQUE7QUFERjtBQURGLFdBREY7QUFLUTtBQUFBO0FBQUEsY0FBSyxXQUFVLG1EQUFmO0FBQ0o7QUFBQTtBQUFBLGdCQUFLLFdBQVUsaUNBQWY7QUFDRTtBQUFBO0FBQUEsa0JBQUksV0FBVSxlQUFkO0FBQUE7QUFBQSxlQURGO0FBRUUsNkVBRkY7QUFHRTtBQUFBO0FBQUEsa0JBQUksV0FBVSxlQUFkO0FBQUE7QUFBQSxlQUhGO0FBSUU7QUFKRjtBQURJO0FBTFI7QUFIRixPQURGO0FBb0JEOzs7O0VBNUJxQixnQkFBTVEsUzs7QUE2QjdCOztrQkFFYyxnQ0FBV3VoQixTQUFYLEM7Ozs7Ozs7Ozs7Ozs7QUN0Q2Y7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLElBQU14ckIsa0JBQWtCLFNBQWxCQSxlQUFrQixPQUFjO0FBQUEsTUFBWHNFLElBQVcsUUFBWEEsSUFBVzs7QUFDcEMsU0FBTztBQUNML0YsV0FBYStGLEtBQUtiLE9BQUwsQ0FBYWxGLEtBRHJCO0FBRUxzRCxpQkFBYXlDLEtBQUtiLE9BQUwsQ0FBYXJKO0FBRnJCLEdBQVA7QUFJRCxDQUxEOztBQU9BLElBQU1vRyxxQkFBcUI7QUFDekJJO0FBRHlCLENBQTNCOztrQkFJZSx5QkFBUVosZUFBUixFQUF5QlEsa0JBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNmZjs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBRUE7Ozs7Ozs7Ozs7SUFFTWlyQixROzs7Ozs7Ozs7Ozt3Q0FDaUI7QUFDbkIsV0FBSzNpQixLQUFMLENBQVdsSSxtQkFBWCxDQUErQixLQUFLa0ksS0FBTCxDQUFXNGlCLEtBQVgsQ0FBaUJqcUIsTUFBaEQ7QUFDRDs7OzhDQUMwQjhsQixTLEVBQVc7QUFDcEMsVUFBSUEsVUFBVW1FLEtBQVYsQ0FBZ0JqcUIsTUFBaEIsS0FBMkIsS0FBS3FILEtBQUwsQ0FBVzRpQixLQUFYLENBQWlCanFCLE1BQWhELEVBQXdEO0FBQ3RELGFBQUtxSCxLQUFMLENBQVdsSSxtQkFBWCxDQUErQjJtQixVQUFVbUUsS0FBVixDQUFnQmpxQixNQUEvQztBQUNEO0FBQ0Y7Ozs2QkFDUztBQUFBLG1CQUN1QixLQUFLcUgsS0FENUI7QUFBQSxVQUNBdkssS0FEQSxVQUNBQSxLQURBO0FBQUEsVUFDT3NELFdBRFAsVUFDT0EsV0FEUDs7QUFFUixVQUFJdEQsS0FBSixFQUFXO0FBQ1QsZUFDRSxxREFBVyxPQUFPQSxLQUFsQixHQURGO0FBR0Q7QUFDRCxjQUFRc0QsV0FBUjtBQUNFO0FBQ0UsaUJBQU8sMERBQVA7QUFDRjtBQUNFLGlCQUFPLDREQUFQO0FBQ0Y7QUFDRSxpQkFBTywrREFBUDtBQUNGO0FBQ0UsaUJBQU87QUFBQTtBQUFBO0FBQUE7QUFBQSxXQUFQO0FBUko7QUFVRDs7OztFQTFCb0IsZ0JBQU1vSSxTOztBQTJCNUI7O2tCQUVjd2hCLFE7Ozs7Ozs7Ozs7Ozs7QUNyQ2Y7O0FBQ0E7Ozs7OztBQUVBLElBQU16ckIsa0JBQWtCLFNBQWxCQSxlQUFrQixPQUFjO0FBQUEsTUFBWHNFLElBQVcsUUFBWEEsSUFBVzs7QUFDcEM7QUFDQSxNQUFNeEMsWUFBWXdDLEtBQUtiLE9BQUwsQ0FBYXpCLEVBQS9CO0FBQ0E7QUFDQSxNQUFJd1AsY0FBSjtBQUNBLE1BQU0vTixVQUFVYSxLQUFLQyxXQUFMLENBQWlCekMsU0FBakIsS0FBK0IsSUFBL0M7QUFDQSxNQUFNMkMsWUFBWUgsS0FBS0csU0FBdkI7QUFDQSxNQUFJaEIsV0FBV2dCLFNBQWYsRUFBMEI7QUFDeEIsUUFBTUQsV0FBV2YsUUFBUXBCLEdBQXpCLENBRHdCLENBQ087QUFDL0JtUCxZQUFRL00sVUFBVUQsUUFBVixLQUF1QixJQUEvQjtBQUNEO0FBQ0Q7QUFDQSxTQUFPO0FBQ0xnTjtBQURLLEdBQVA7QUFHRCxDQWZEOztrQkFpQmUseUJBQVF4UixlQUFSLEVBQXlCLElBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNwQmY7Ozs7QUFDQTs7OztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7SUFFTTJyQixROzs7Ozs7Ozs7Ozs2QkFDTTtBQUFBLFVBQ0FuYSxLQURBLEdBQ1UsS0FBSzFJLEtBRGYsQ0FDQTBJLEtBREE7O0FBRVIsVUFBSUEsS0FBSixFQUFXO0FBQUEsK0JBQ2lCQSxNQUFNaFAsU0FEdkI7QUFBQSxZQUNEaEksSUFEQyxvQkFDREEsSUFEQztBQUFBLFlBQ0srSCxPQURMLG9CQUNLQSxPQURMOztBQUVULGVBQ0U7QUFBQTtBQUFBLFlBQUssV0FBVSx3RkFBZjtBQUNFLHlEQUFLLFdBQVcvSCxJQUFoQixFQUFzQixPQUFPZ1gsS0FBN0IsR0FERjtBQUVFLHFFQUZGO0FBR0U7QUFBQTtBQUFBLGNBQU0sSUFBRyxrQkFBVCxFQUE0QixXQUFVLDBCQUF0QyxFQUFpRSxVQUFRalAsT0FBUixTQUFtQi9ILElBQXBGO0FBQUE7QUFBQTtBQUhGLFNBREY7QUFRRDtBQUNELGFBQ0U7QUFBQTtBQUFBLFVBQUssV0FBVSxnRkFBZjtBQUNFO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFERixPQURGO0FBS0Q7Ozs7RUFuQm9CLGdCQUFNeVAsUzs7QUFvQjVCOztrQkFFYzBoQixROzs7Ozs7Ozs7Ozs7Ozs7QUMzQmY7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7Ozs7O0lBRU1DLFk7Ozs7Ozs7Ozs7O3dDQUNpQjtBQUFBLGtDQUNpQyxLQUFLOWlCLEtBRHRDLENBQ1gwSSxLQURXLENBQ0ZoUCxTQURFO0FBQUEsVUFDV2hJLElBRFgseUJBQ1dBLElBRFg7QUFBQSxVQUNpQitILE9BRGpCLHlCQUNpQkEsT0FEakI7O0FBRW5CLFdBQUt1RyxLQUFMLENBQVcySSxhQUFYLENBQXlCalgsSUFBekIsRUFBK0IrSCxPQUEvQjtBQUNEOzs7NkJBQ1M7QUFBQSxtQkFDNEYsS0FBS3VHLEtBRGpHO0FBQUEsVUFDQWhPLE1BREEsVUFDQUEsTUFEQTtBQUFBLFVBQ1F5RCxLQURSLFVBQ1FBLEtBRFI7QUFBQSwwQ0FDZWlULEtBRGYsQ0FDd0JoUCxTQUR4QjtBQUFBLFVBQ3FDaEksSUFEckMsMEJBQ3FDQSxJQURyQztBQUFBLFVBQzJDK0gsT0FEM0MsMEJBQzJDQSxPQUQzQztBQUFBLFVBQ29EK0ssV0FEcEQsMEJBQ29EQSxXQURwRDtBQUFBLFVBQ2lFc1QsT0FEakUsMEJBQ2lFQSxPQURqRTtBQUFBLFVBQzBFOWtCLFNBRDFFLDBCQUMwRUEsU0FEMUU7O0FBRVIsYUFDRTtBQUFBO0FBQUEsVUFBSyxJQUFHLHlCQUFSO0FBQ0loQixvREFBRCxJQUNEO0FBQUE7QUFBQTtBQUNFO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFERixTQUZGO0FBTUlBLG9EQUFELElBQ0Q7QUFBQTtBQUFBO0FBQ0U7QUFBQTtBQUFBO0FBQUE7QUFBQSxXQURGO0FBRUUsaUVBQWEsTUFBTSxFQUFuQixHQUZGO0FBR0U7QUFBQTtBQUFBO0FBQUE7QUFBeUM7QUFBQTtBQUFBLGdCQUFHLFdBQVUsZUFBYixFQUE2QixRQUFPLE9BQXBDLEVBQTRDLE1BQUssa0NBQWpEO0FBQUE7QUFBQTtBQUF6QztBQUhGLFNBUEY7QUFhSUEsOENBQUQsSUFDRDtBQUFBO0FBQUE7QUFDRTtBQUFBO0FBQUE7QUFBQTtBQUE0SDtBQUFBO0FBQUEsZ0JBQUcsV0FBVSxlQUFiLEVBQTZCLE1BQUssNEJBQWxDLEVBQStELFFBQU8sUUFBdEU7QUFBQTtBQUFBLGFBQTVIO0FBQUE7QUFBQSxXQURGO0FBRUU7QUFBQTtBQUFBO0FBQUc7QUFBQTtBQUFBLGdCQUFHLElBQUcsZUFBTjtBQUF1QnlEO0FBQXZCO0FBQUg7QUFGRixTQWRGO0FBbUJJekQsa0RBQUQsSUFDQSxZQUFNO0FBQ0wsa0JBQVF3UyxXQUFSO0FBQ0UsaUJBQUssWUFBTDtBQUNBLGlCQUFLLFdBQUw7QUFDQSxpQkFBSyxXQUFMO0FBQ0UscUJBQ0U7QUFDRSwyQkFBVSxPQURaO0FBRUUsMkJBQVMvSyxPQUFULFNBQW9CL0gsSUFBcEIsU0FBNEJvbUIsT0FGOUI7QUFHRSxxQkFBS3BtQixJQUhQLEdBREY7QUFNRixpQkFBSyxXQUFMO0FBQ0UscUJBQ0U7QUFDRSwyQkFBVSxPQURaO0FBRUUsMkJBQVMrSCxPQUFULFNBQW9CL0gsSUFBcEIsU0FBNEJvbUIsT0FGOUI7QUFHRSxxQkFBS3BtQjtBQUhQLGdCQURGO0FBT0YsaUJBQUssV0FBTDtBQUNFLHFCQUNFO0FBQUE7QUFBQSxrQkFBTyxXQUFVLGFBQWpCLEVBQStCLGNBQS9CLEVBQXdDLFFBQVFzQixTQUFoRDtBQUNFO0FBQ0UsNkJBQVN5RyxPQUFULFNBQW9CL0gsSUFBcEIsU0FBNEJvbUI7QUFEOUIsa0JBREY7QUFJRTtBQUFBO0FBQUE7QUFBQTtBQUFxQztBQUFBO0FBQUE7QUFBQTtBQUFBLG1CQUFyQztBQUFBO0FBQUE7QUFKRixlQURGO0FBUUY7QUFDRSxxQkFDRTtBQUFBO0FBQUE7QUFBQTtBQUFBLGVBREY7QUE1Qko7QUFnQ0QsU0FqQ0Q7QUFwQkYsT0FERjtBQTBERDs7OztFQWpFd0IsZ0JBQU0zVyxTOztBQWtFaEM7O2tCQUVjMmhCLFk7Ozs7Ozs7Ozs7Ozs7QUN4RWY7O0FBQ0E7Ozs7OztBQUVBLElBQU01ckIsa0JBQWtCLFNBQWxCQSxlQUFrQixPQUFjO0FBQUEsTUFBWHNFLElBQVcsUUFBWEEsSUFBVzs7QUFDcEM7QUFDQSxNQUFNeEMsWUFBWXdDLEtBQUtiLE9BQUwsQ0FBYXpCLEVBQS9CO0FBQ0E7QUFDQSxNQUFJd1AsY0FBSjtBQUNBLE1BQU0vTixVQUFVYSxLQUFLQyxXQUFMLENBQWlCekMsU0FBakIsS0FBK0IsSUFBL0M7QUFDQSxNQUFNMkMsWUFBWUgsS0FBS0csU0FBdkI7QUFDQSxNQUFJaEIsV0FBV2dCLFNBQWYsRUFBMEI7QUFDeEIsUUFBTUQsV0FBV2YsUUFBUXBCLEdBQXpCLENBRHdCLENBQ087QUFDL0JtUCxZQUFRL00sVUFBVUQsUUFBVixLQUF1QixJQUEvQjtBQUNEO0FBQ0Q7QUFDQSxTQUFPO0FBQ0xnTjtBQURLLEdBQVA7QUFHRCxDQWZEOztrQkFpQmUseUJBQVF4UixlQUFSLEVBQXlCLElBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNwQmY7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7Ozs7Ozs7OztJQUVNNnJCLGdCOzs7Ozs7Ozs7Ozs2QkFDTTtBQUFBLFVBQ0FyYSxLQURBLEdBQ1UsS0FBSzFJLEtBRGYsQ0FDQTBJLEtBREE7O0FBRVIsVUFBSUEsS0FBSixFQUFXO0FBQUEsWUFDWWhYLElBRFosR0FDdUJnWCxLQUR2QixDQUNEaFAsU0FEQyxDQUNZaEksSUFEWjs7QUFFVCxlQUNFO0FBQUE7QUFBQTtBQUNFLHlEQUFLLFdBQWNBLElBQWQsZUFBTCxFQUFxQyxPQUFPZ1gsS0FBNUMsR0FERjtBQUVFLCtEQUZGO0FBR0U7QUFBQTtBQUFBLGNBQUssV0FBVSwyQkFBZjtBQUNFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLG1CQUFmO0FBQ0U7QUFERixhQURGO0FBSUU7QUFBQTtBQUFBLGdCQUFLLFdBQVUsbURBQWY7QUFDRTtBQUFBO0FBQUEsa0JBQUssV0FBVSx3Q0FBZjtBQUNFO0FBREY7QUFERixhQUpGO0FBUVE7QUFBQTtBQUFBLGdCQUFLLFdBQVUsbURBQWY7QUFDSjtBQUFBO0FBQUEsa0JBQUssV0FBVSxpQkFBZjtBQUNFO0FBREY7QUFESTtBQVJSO0FBSEYsU0FERjtBQW9CRDtBQUNELGFBQ0UscURBQVcsT0FBTyx1QkFBbEIsR0FERjtBQUdEOzs7O0VBN0I0QixnQkFBTXZILFM7O0FBOEJwQzs7a0JBRWM0aEIsZ0I7Ozs7Ozs7Ozs7Ozs7QUN4Q2Y7O0FBQ0E7Ozs7QUFDQTs7OztBQUVBLElBQU03ckIsa0JBQWtCLFNBQWxCQSxlQUFrQixPQUFjO0FBQUEsTUFBWHNFLElBQVcsUUFBWEEsSUFBVzs7QUFBQSxxQkFDSCx1QkFBWUEsSUFBWixDQURHO0FBQUEsTUFDZnZJLEtBRGUsZ0JBQzVCeUcsU0FENEIsQ0FDZnpHLEtBRGU7O0FBRXBDLFNBQU87QUFDTEE7QUFESyxHQUFQO0FBR0QsQ0FMRDs7a0JBT2UseUJBQVFpRSxlQUFSLEVBQXlCLElBQXpCLGlCOzs7Ozs7Ozs7Ozs7O0FDWGY7Ozs7OztBQUVBLElBQU04ckIsYUFBYSxTQUFiQSxVQUFhLE9BQWU7QUFBQSxNQUFaL3ZCLEtBQVksUUFBWkEsS0FBWTs7QUFDaEMsU0FDRTtBQUFBO0FBQUE7QUFDRTtBQUFBO0FBQUEsUUFBTSxXQUFVLGFBQWhCO0FBQStCQTtBQUEvQjtBQURGLEdBREY7QUFLRCxDQU5EOztrQkFRZSt2QixVOzs7Ozs7Ozs7Ozs7O0FDVmY7O0FBQ0E7Ozs7QUFDQTs7OztBQUVBLElBQU05ckIsa0JBQWtCLFNBQWxCQSxlQUFrQixPQUFjO0FBQUEsTUFBWHNFLElBQVcsUUFBWEEsSUFBVzs7QUFDcEM7QUFDQSxNQUFNa04sUUFBUSx1QkFBWWxOLElBQVosQ0FBZDtBQUNBO0FBQ0EsU0FBTztBQUNMa047QUFESyxHQUFQO0FBR0QsQ0FQRDs7a0JBU2UseUJBQVF4UixlQUFSLEVBQXlCLElBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNiZjs7OztBQUNBOzs7Ozs7Ozs7O0lBRU0rckIsUzs7O0FBQ0oscUJBQWFqakIsS0FBYixFQUFvQjtBQUFBOztBQUFBLHNIQUNaQSxLQURZOztBQUVsQixVQUFLa2pCLGVBQUwsR0FBdUIsTUFBS0EsZUFBTCxDQUFxQjdpQixJQUFyQixPQUF2QjtBQUZrQjtBQUduQjs7OztvQ0FDZ0JiLEssRUFBTztBQUN0QixVQUFJMmpCLGdCQUFnQjNqQixNQUFNK1osTUFBTixDQUFhNkosT0FBYixDQUFxQkMsYUFBekM7QUFDQSxVQUFJdGhCLFVBQVVxWixTQUFTQyxjQUFULENBQXdCOEgsYUFBeEIsQ0FBZDtBQUNBcGhCLGNBQVF1aEIsTUFBUjtBQUNBLFVBQUk7QUFDRmxJLGlCQUFTbUksV0FBVCxDQUFxQixNQUFyQjtBQUNELE9BRkQsQ0FFRSxPQUFPN3RCLEdBQVAsRUFBWTtBQUNaLGFBQUttTCxRQUFMLENBQWMsRUFBQ3BMLE9BQU8sc0JBQVIsRUFBZDtBQUNEO0FBQ0Y7Ozs2QkFDUztBQUFBLHlCQUNzSSxLQUFLdUssS0FEM0ksQ0FDQTBJLEtBREE7QUFBQSxVQUNTcFIsT0FEVCxnQkFDU0EsT0FEVDtBQUFBLCtDQUNrQm9DLFNBRGxCO0FBQUEsVUFDZ0N0SCxXQURoQyx5QkFDZ0NBLFdBRGhDO0FBQUEsVUFDNkNnZSxhQUQ3Qyx5QkFDNkNBLGFBRDdDO0FBQUEsVUFDNERyZCxXQUQ1RCx5QkFDNERBLFdBRDVEO0FBQUEsVUFDeUVyQixJQUR6RSx5QkFDeUVBLElBRHpFO0FBQUEsVUFDK0UrSCxPQUQvRSx5QkFDK0VBLE9BRC9FO0FBQUEsVUFDd0ZxZSxPQUR4Rix5QkFDd0ZBLE9BRHhGO0FBQUEsVUFDaUd0VCxXQURqRyx5QkFDaUdBLFdBRGpHO0FBQUEsVUFDOEd4UixTQUQ5Ryx5QkFDOEdBLFNBRDlHO0FBQUEsVUFDeUhLLElBRHpILHlCQUN5SEEsSUFEekg7O0FBRVIsYUFDRTtBQUFBO0FBQUE7QUFDR2pCLHVCQUNEO0FBQUE7QUFBQSxZQUFLLFdBQVUsdUNBQWY7QUFDRTtBQUFBO0FBQUEsY0FBSyxXQUFVLGlDQUFmO0FBQ0U7QUFBQTtBQUFBLGdCQUFNLFdBQVUsTUFBaEI7QUFBQTtBQUFBO0FBREYsV0FERjtBQUlFO0FBQUE7QUFBQSxjQUFLLFdBQVUsaUNBQWY7QUFDRTtBQUFBO0FBQUEsZ0JBQU0sV0FBVSxNQUFoQjtBQUF1QjtBQUFBO0FBQUEsa0JBQU0sVUFBUUEsV0FBUixTQUF1QmdlLGFBQTdCO0FBQStDaGU7QUFBL0M7QUFBdkI7QUFERjtBQUpGLFNBRkY7QUFZR1csdUJBQ0Q7QUFBQTtBQUFBLFlBQUssV0FBVSx1Q0FBZjtBQUNFO0FBQUE7QUFBQSxjQUFNLFdBQVUsTUFBaEI7QUFBd0JBO0FBQXhCO0FBREYsU0FiRjtBQWtCRTtBQUFBO0FBQUEsWUFBSyxJQUFHLG9CQUFSO0FBQ0U7QUFBQTtBQUFBLGNBQUssV0FBVSx1Q0FBZjtBQUNFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLGlDQUFmO0FBQ0U7QUFBQTtBQUFBLGtCQUFNLFdBQVUsTUFBaEI7QUFBQTtBQUFBO0FBREYsYUFERjtBQUlFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLGlDQUFmO0FBQ0U7QUFBQTtBQUFBO0FBQ0UsNkJBQVUsd0dBRFo7QUFFRTtBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLFFBQU8sUUFBcEMsRUFBNkMsaURBQStDTSxJQUEvQyxTQUF1RGlFLE9BQXZELFNBQWtFNUYsSUFBL0c7QUFBQTtBQUFBLGlCQUZGO0FBR0U7QUFBQTtBQUFBLG9CQUFHLFdBQVUsZUFBYixFQUE2QixRQUFPLFFBQXBDLEVBQTZDLHdEQUFzRDJCLElBQXRELFNBQThEaUUsT0FBOUQsU0FBeUU1RixJQUF0SDtBQUFBO0FBQUEsaUJBSEY7QUFJRTtBQUFBO0FBQUEsb0JBQUcsV0FBVSxlQUFiLEVBQTZCLFFBQU8sUUFBcEMsRUFBNkMsNkRBQTJEMkIsSUFBM0QsU0FBbUVpRSxPQUFuRSxTQUE4RTVGLElBQTNIO0FBQUE7QUFBQSxpQkFKRjtBQUtFO0FBQUE7QUFBQSxvQkFBRyxXQUFVLGVBQWIsRUFBNkIsUUFBTyxRQUFwQyxFQUE2Qyw2Q0FBMkMyQixJQUEzQyxTQUFtRGlFLE9BQW5ELFNBQThENUYsSUFBOUQsZUFBNEVBLElBQXpIO0FBQUE7QUFBQTtBQUxGO0FBREY7QUFKRjtBQURGLFNBbEJGO0FBbUNFO0FBQUE7QUFBQSxZQUFLLFdBQVUsdUNBQWY7QUFDRTtBQUFBO0FBQUEsY0FBSyxJQUFHLGlCQUFSO0FBQ0U7QUFBQTtBQUFBLGdCQUFLLFdBQVUsaUNBQWY7QUFDRTtBQUFBO0FBQUEsa0JBQU0sV0FBVSxNQUFoQjtBQUFBO0FBQUE7QUFERixhQURGO0FBSUU7QUFBQTtBQUFBLGdCQUFLLFdBQVUsaUNBQWY7QUFDRTtBQUFBO0FBQUEsa0JBQUssV0FBVSwwQkFBZjtBQUNFO0FBQUE7QUFBQSxvQkFBSyxXQUFVLGtCQUFmO0FBQ0U7QUFBQTtBQUFBLHNCQUFLLFdBQVUsYUFBZixFQUE2QixJQUFHLDZCQUFoQyxFQUE4RCxRQUFPLE1BQXJFO0FBQUE7QUFBQSxtQkFERjtBQUVFLDJEQUFPLE1BQUssTUFBWixFQUFtQixJQUFHLFlBQXRCLEVBQW1DLFdBQVUsdUNBQTdDLEVBQXFGLGNBQXJGO0FBQ0UsZ0NBQVcsT0FEYjtBQUVFLDJCQUFVMkIsSUFBVixTQUFrQmlFLE9BQWxCLFNBQTZCNUYsSUFBN0IsU0FBcUNvbUIsT0FGdkM7QUFHRSw2QkFBUyxLQUFLd0wsTUFIaEI7QUFGRixpQkFERjtBQVFFLHVEQUFLLFdBQVUsa0JBQWYsR0FSRjtBQVNFO0FBQUE7QUFBQSxvQkFBSyxXQUFVLGtCQUFmO0FBQ0U7QUFBQTtBQUFBLHNCQUFRLFdBQVUsOEJBQWxCLEVBQWlELHNCQUFtQixZQUFwRTtBQUNFLCtCQUFTLEtBQUtKLGVBRGhCO0FBQUE7QUFBQTtBQURGO0FBVEY7QUFERjtBQUpGLFdBREY7QUF3QkU7QUFBQTtBQUFBLGNBQUssSUFBRyxpQkFBUjtBQUNFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLGlDQUFmO0FBQ0U7QUFBQTtBQUFBLGtCQUFNLFdBQVUsTUFBaEI7QUFBQTtBQUFBO0FBREYsYUFERjtBQUlFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLGlDQUFmO0FBQ0U7QUFBQTtBQUFBLGtCQUFLLFdBQVUsMEJBQWY7QUFDRTtBQUFBO0FBQUEsb0JBQUssV0FBVSxrQkFBZjtBQUNFO0FBQUE7QUFBQSxzQkFBSyxXQUFVLGFBQWYsRUFBNkIsSUFBRyw2QkFBaEMsRUFBOEQsUUFBTyxNQUFyRTtBQUFBO0FBQUEsbUJBREY7QUFFSTFlLGtDQUFnQixXQUFqQixHQUNDLHlDQUFPLE1BQUssTUFBWixFQUFtQixJQUFHLFlBQXRCLEVBQW1DLFdBQVUsdUNBQTdDLEVBQXFGLGNBQXJGO0FBQ0UsNkJBQVMsS0FBSzhlLE1BRGhCLEVBQ3dCLFlBQVcsT0FEbkM7QUFFRSxxRUFBK0N0d0IsU0FBL0MsZUFBa0VLLElBQWxFLFNBQTBFb0csT0FBMUUsU0FBcUYvSCxJQUFyRixTQUE2Rm9tQixPQUE3RixnQkFGRixHQURELEdBS0MseUNBQU8sTUFBSyxNQUFaLEVBQW1CLElBQUcsWUFBdEIsRUFBbUMsV0FBVSx1Q0FBN0MsRUFBcUYsY0FBckY7QUFDRSw2QkFBUyxLQUFLd0wsTUFEaEIsRUFDd0IsWUFBVyxPQURuQztBQUVFLDBDQUFvQmp3QixJQUFwQixTQUE0Qm9HLE9BQTVCLFNBQXVDL0gsSUFBdkMsU0FBK0NvbUIsT0FBL0M7QUFGRjtBQVBKLGlCQURGO0FBY0UsdURBQUssV0FBVSxrQkFBZixHQWRGO0FBZUU7QUFBQTtBQUFBLG9CQUFLLFdBQVUsa0JBQWY7QUFDRTtBQUFBO0FBQUEsc0JBQVEsV0FBVSw4QkFBbEIsRUFBaUQsc0JBQW1CLFlBQXBFO0FBQ0UsK0JBQVMsS0FBS29MLGVBRGhCO0FBQUE7QUFBQTtBQURGO0FBZkY7QUFERjtBQUpGO0FBeEJGLFNBbkNGO0FBeUZFO0FBQUE7QUFBQSxZQUFLLFdBQVUsMERBQWY7QUFDRTtBQUFBO0FBQUEsY0FBTSxXQUFVLGVBQWhCLEVBQWdDLFVBQVE1ckIsT0FBUixTQUFtQjVGLElBQW5CLFNBQTJCb21CLE9BQTNEO0FBQXNFO0FBQUE7QUFBQTtBQUNwRSwyQkFBVSxNQUQwRDtBQUFBO0FBQUE7QUFBdEUsV0FERjtBQUdFO0FBQUE7QUFBQSxjQUFHLFdBQVUsZUFBYixFQUE2QixNQUFTemtCLElBQVQsU0FBaUJvRyxPQUFqQixTQUE0Qi9ILElBQTVCLFNBQW9Db21CLE9BQWpFLEVBQTRFLFVBQVVwbUIsSUFBdEY7QUFBQTtBQUFBLFdBSEY7QUFJRTtBQUFBO0FBQUEsY0FBRyxXQUFVLGVBQWIsRUFBNkIsUUFBTyxRQUFwQyxFQUE2QyxNQUFLLHNCQUFsRDtBQUFBO0FBQUE7QUFKRjtBQXpGRixPQURGO0FBbUdEOzs7O0VBcEhxQixnQkFBTXlQLFM7O0FBcUg3Qjs7a0JBRWM4aEIsUzs7Ozs7Ozs7Ozs7OztBQzFIZjs7QUFDQTs7Ozs7O0FBRUEsSUFBTS9yQixrQkFBa0IsU0FBbEJBLGVBQWtCLE9BQWM7QUFBQSxNQUFYc0UsSUFBVyxRQUFYQSxJQUFXOztBQUNwQztBQUNBLE1BQU14QyxZQUFZd0MsS0FBS2IsT0FBTCxDQUFhekIsRUFBL0I7QUFDQTtBQUNBLE1BQU1zcUIsa0JBQWtCaG9CLEtBQUtDLFdBQUwsQ0FBaUJ6QyxTQUFqQixLQUErQixJQUF2RDtBQUNBO0FBQ0EsTUFBSWxILGdCQUFKO0FBQ0EsTUFBSTB4QixlQUFKLEVBQXFCO0FBQ25CLFFBQU0xcEIsYUFBYTBwQixnQkFBZ0JqcUIsR0FBbkM7QUFDQXpILGNBQVUwSixLQUFLd2IsV0FBTCxDQUFpQmxkLFVBQWpCLEtBQWdDLElBQTFDO0FBQ0Q7QUFDRCxTQUFPO0FBQ0xoSTtBQURLLEdBQVA7QUFHRCxDQWREOztrQkFnQmUseUJBQVFvRixlQUFSLEVBQXlCLElBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNuQmY7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7Ozs7O0lBRU11c0IsVzs7Ozs7Ozs7Ozs7NkJBQ007QUFBQSxVQUNBM3hCLE9BREEsR0FDWSxLQUFLa08sS0FEakIsQ0FDQWxPLE9BREE7O0FBRVIsVUFBSUEsT0FBSixFQUFhO0FBQUEsWUFDSEosSUFERyxHQUN1QkksT0FEdkIsQ0FDSEosSUFERztBQUFBLFlBQ0c4RixNQURILEdBQ3VCMUYsT0FEdkIsQ0FDRzBGLE1BREg7QUFBQSxZQUNXRixPQURYLEdBQ3VCeEYsT0FEdkIsQ0FDV3dGLE9BRFg7O0FBRVgsZUFDRTtBQUFBO0FBQUE7QUFDRSx5REFBSyxXQUFXNUYsSUFBaEIsRUFBc0IsU0FBU0ksT0FBL0IsR0FERjtBQUVFLCtEQUZGO0FBR0U7QUFBQTtBQUFBLGNBQUssV0FBVSwyQkFBZjtBQUNFO0FBQUE7QUFBQSxnQkFBSyxXQUFVLG1CQUFmO0FBQ0U7QUFBQTtBQUFBO0FBQUE7QUFBbUJKO0FBQW5CLGVBREY7QUFFRTtBQUFBO0FBQUEsa0JBQUcsV0FBVyxZQUFkO0FBQUE7QUFBOEM4RjtBQUE5QyxlQUZGO0FBR0U7QUFBQTtBQUFBLGtCQUFHLFdBQVcsWUFBZDtBQUFBO0FBQStDRjtBQUEvQztBQUhGLGFBREY7QUFNRTtBQUFBO0FBQUEsZ0JBQUssV0FBVSxtQkFBZjtBQUNFO0FBREY7QUFORjtBQUhGLFNBREY7QUFnQkQ7QUFDRCxhQUNFLHFEQUFXLE9BQU8seUJBQWxCLEdBREY7QUFHRDs7OztFQXpCdUIsZ0JBQU02SixTOztBQTBCL0I7O2tCQUVjc2lCLFc7Ozs7Ozs7Ozs7Ozs7QUNsQ2Y7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLElBQU12c0Isa0JBQWtCLFNBQWxCQSxlQUFrQixPQUFjO0FBQUEsTUFBWHNFLElBQVcsUUFBWEEsSUFBVzs7QUFDcEM7QUFDQSxNQUFNYixVQUFVYSxLQUFLQyxXQUFMLENBQWlCRCxLQUFLYixPQUFMLENBQWF6QixFQUE5QixDQUFoQjtBQUNBLE1BQU1ZLGFBQWFhLFFBQVFwQixHQUEzQjtBQUNBO0FBQ0EsTUFBTXpILFVBQVUwSixLQUFLd2IsV0FBTCxDQUFpQmxkLFVBQWpCLEtBQWdDLElBQWhEO0FBQ0E7QUFDQSxTQUFPO0FBQ0xBLDBCQURLO0FBRUxoSTtBQUZLLEdBQVA7QUFJRCxDQVhEOztBQWFBLElBQU00RixxQkFBcUI7QUFDekJZO0FBRHlCLENBQTNCOztrQkFJZSx5QkFBUXBCLGVBQVIsRUFBeUJRLGtCQUF6QixpQjs7Ozs7Ozs7Ozs7Ozs7O0FDckJmOzs7O0FBQ0E7Ozs7Ozs7Ozs7OztJQUVNZ3NCLG9COzs7QUFDSixnQ0FBYTFqQixLQUFiLEVBQW9CO0FBQUE7O0FBQUEsNElBQ1pBLEtBRFk7O0FBRWxCLFVBQUsyakIsbUJBQUwsR0FBMkIsTUFBS0EsbUJBQUwsQ0FBeUJ0akIsSUFBekIsT0FBM0I7QUFDQSxVQUFLdWpCLHVCQUFMLEdBQStCLE1BQUtBLHVCQUFMLENBQTZCdmpCLElBQTdCLE9BQS9CO0FBSGtCO0FBSW5COzs7OzhDQUMwQjtBQUFBLFVBQ1FvVixXQURSLEdBQzRCLEtBQUt6VixLQURqQyxDQUNqQmxPLE9BRGlCLENBQ044SCxVQURNLENBQ1E2YixXQURSOztBQUV6QixVQUFNRixlQUFlTyxTQUFTTCxXQUFULElBQXdCLENBQTdDO0FBQ0EsV0FBS29PLFdBQUwsQ0FBaUJ0TyxZQUFqQjtBQUNEOzs7MENBQ3NCO0FBQUEsVUFDWUUsV0FEWixHQUNnQyxLQUFLelYsS0FEckMsQ0FDYmxPLE9BRGEsQ0FDRjhILFVBREUsQ0FDWTZiLFdBRFo7O0FBRXJCLFVBQU1DLFdBQVdJLFNBQVNMLFdBQVQsSUFBd0IsQ0FBekM7QUFDQSxXQUFLb08sV0FBTCxDQUFpQm5PLFFBQWpCO0FBQ0Q7OztnQ0FDWTNiLEksRUFBTTtBQUFBLG1CQUNpQyxLQUFLaUcsS0FEdEM7QUFBQSxVQUNUbEcsVUFEUyxVQUNUQSxVQURTO0FBQUEsa0NBQ0doSSxPQURIO0FBQUEsVUFDY0osSUFEZCxrQkFDY0EsSUFEZDtBQUFBLFVBQ29COEYsTUFEcEIsa0JBQ29CQSxNQURwQjs7QUFFakIsV0FBS3dJLEtBQUwsQ0FBVzFILHFCQUFYLENBQWlDd0IsVUFBakMsRUFBNkNwSSxJQUE3QyxFQUFtRDhGLE1BQW5ELEVBQTJEdUMsSUFBM0Q7QUFDRDs7OzZCQUNTO0FBQUEsa0NBQ2lFLEtBQUtpRyxLQUR0RSxDQUNBbE8sT0FEQSxDQUNXOEgsVUFEWDtBQUFBLFVBQ3lCb2IsTUFEekIseUJBQ3lCQSxNQUR6QjtBQUFBLFVBQ2lDUyxXQURqQyx5QkFDaUNBLFdBRGpDO0FBQUEsVUFDOENSLFVBRDlDLHlCQUM4Q0EsVUFEOUM7O0FBRVIsYUFDRTtBQUFBO0FBQUEsVUFBSyxXQUFVLGVBQWY7QUFDSUQsZUFBTzlTLE1BQVAsR0FBZ0IsQ0FBakIsR0FDQztBQUFBO0FBQUE7QUFDRzhTLGlCQUFPL1QsR0FBUCxDQUFXLFVBQUNrUCxLQUFELEVBQVFqUSxLQUFSO0FBQUEsbUJBQWtCO0FBQzVCLHlCQUFXaVEsS0FEaUI7QUFFNUIsbUJBQVFBLE1BQU16ZSxJQUFkLFNBQXNCd087QUFGTSxjQUFsQjtBQUFBLFdBQVgsQ0FESDtBQUtFO0FBQUE7QUFBQTtBQUNJdVYsMEJBQWMsQ0FBZixJQUNEO0FBQUE7QUFBQSxnQkFBUSxXQUFXLG1CQUFuQixFQUF3QyxTQUFTLEtBQUttTyx1QkFBdEQ7QUFBQTtBQUFBLGFBRkY7QUFJSW5PLDBCQUFjUixVQUFmLElBQ0Q7QUFBQTtBQUFBLGdCQUFRLFdBQVcsbUJBQW5CLEVBQXdDLFNBQVMsS0FBSzBPLG1CQUF0RDtBQUFBO0FBQUE7QUFMRjtBQUxGLFNBREQsR0FnQkM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWpCSixPQURGO0FBc0JEOzs7O0VBNUNnQyxnQkFBTXhpQixTOztBQTZDeEM7O2tCQUVjdWlCLG9COzs7Ozs7Ozs7Ozs7O0FDbERmOztBQUNBOzs7Ozs7QUFFQSxJQUFNeHNCLGtCQUFrQixTQUFsQkEsZUFBa0IsT0FBOEM7QUFBQSxNQUF6QnFELGdCQUF5QixRQUE1Q3BELElBQTRDLENBQXJDMnNCLFFBQXFDLENBQXpCdnBCLGdCQUF5Qjs7QUFDcEUsU0FBTztBQUNMQTtBQURLLEdBQVA7QUFHRCxDQUpEOztrQkFNZSx5QkFBUXJELGVBQVIsRUFBeUIsSUFBekIsaUI7Ozs7Ozs7Ozs7Ozs7QUNUZjs7OztBQUNBOzs7O0FBRUEsSUFBTTZzQixlQUFlLFNBQWZBLFlBQWUsT0FBeUY7QUFBQSxNQUF0RnhwQixnQkFBc0YsUUFBdEZBLGdCQUFzRjtBQUFBLDRCQUFwRWIsU0FBb0U7QUFBQSxNQUF2RGhJLElBQXVELGtCQUF2REEsSUFBdUQ7QUFBQSxNQUFqRCtILE9BQWlELGtCQUFqREEsT0FBaUQ7QUFBQSxNQUF4Q3FlLE9BQXdDLGtCQUF4Q0EsT0FBd0M7QUFBQSxNQUEvQnRULFdBQStCLGtCQUEvQkEsV0FBK0I7QUFBQSxNQUFsQnhSLFNBQWtCLGtCQUFsQkEsU0FBa0I7O0FBQzVHLE1BQU1neEIsbUJBQXNCdnFCLE9BQXRCLFNBQWlDL0gsSUFBakMsU0FBeUNvbUIsT0FBL0M7QUFDQSxNQUFNbU0sb0JBQWtCeHFCLE9BQWxCLFNBQTZCL0gsSUFBbkM7QUFDQSxTQUNFO0FBQUE7QUFBQSxNQUFLLFdBQVUsY0FBZjtBQUNFO0FBQUE7QUFBQSxRQUFNLElBQUl1eUIsV0FBVjtBQUNJLGtCQUFNO0FBQ04sZ0JBQVF6ZixXQUFSO0FBQ0UsZUFBSyxZQUFMO0FBQ0EsZUFBSyxXQUFMO0FBQ0EsZUFBSyxXQUFMO0FBQ0EsZUFBSyxXQUFMO0FBQ0UsbUJBQ0U7QUFDRSx5QkFBVyxlQURiO0FBRUUsbUJBQUt3ZixnQkFGUDtBQUdFLG1CQUFLdHlCO0FBSFAsY0FERjtBQU9GLGVBQUssV0FBTDtBQUNFLG1CQUNFO0FBQ0UseUJBQVcscUJBRGI7QUFFRSxtQkFBS3NCLGFBQWF1SCxnQkFGcEI7QUFHRSxtQkFBSzdJO0FBSFAsY0FERjtBQU9GO0FBQ0UsbUJBQ0U7QUFBQTtBQUFBO0FBQUE7QUFBQSxhQURGO0FBckJKO0FBeUJELE9BMUJBO0FBREg7QUFERixHQURGO0FBaUNELENBcENEOztrQkFzQ2VxeUIsWTs7Ozs7Ozs7Ozs7OztBQ3pDZjs7QUFDQTs7Ozs7O0FBRUEsSUFBTTdzQixrQkFBa0IsU0FBbEJBLGVBQWtCLE9BQStCO0FBQUEsdUJBQTVCQyxJQUE0QjtBQUFBLE1BQXBCOUQsSUFBb0IsYUFBcEJBLElBQW9CO0FBQUEsTUFBZEosS0FBYyxhQUFkQSxLQUFjOztBQUNyRCxTQUFPO0FBQ0xJLGNBREs7QUFFTEo7QUFGSyxHQUFQO0FBSUQsQ0FMRDs7a0JBT2UseUJBQVFpRSxlQUFSLEVBQXlCLElBQXpCLGlCOzs7Ozs7Ozs7Ozs7Ozs7QUNWZjs7OztBQUNBOzs7O0FBQ0E7Ozs7Ozs7Ozs7OztJQUVNZ3RCLGE7Ozs7Ozs7Ozs7OzZCQUNNO0FBQUEsbUJBQ2MsS0FBS2xrQixLQURuQjtBQUFBLFVBQ0QvTSxLQURDLFVBQ0RBLEtBREM7QUFBQSxVQUNNSSxJQUROLFVBQ01BLElBRE47O0FBRVIsYUFDRTtBQUFBO0FBQUE7QUFDRTtBQUFBO0FBQUE7QUFDRTtBQUFBO0FBQUE7QUFBUUosaUJBQVI7QUFBQTtBQUFBLFdBREY7QUFFRSxrREFBTSxLQUFJLFdBQVYsRUFBc0IsTUFBU0ksSUFBVCxTQUF0QjtBQUZGLFNBREY7QUFLRSw2REFMRjtBQU1FO0FBQUE7QUFBQSxZQUFLLFdBQVUsaUJBQWY7QUFDRTtBQUFBO0FBQUE7QUFBQTtBQUFBLFdBREY7QUFFRTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRkY7QUFORixPQURGO0FBYUQ7Ozs7RUFoQnlCLGdCQUFNOE4sUzs7QUFpQmpDOztrQkFFYytpQixhOzs7Ozs7Ozs7OztlQ3ZCYyxtQkFBQS92QixDQUFRLEVBQVIsQztJQUFyQndMLGdCLFlBQUFBLGdCOztnQkFDZ0gsbUJBQUF4TCxDQUFRLEdBQVIsQztJQUFoSGd3QixxQixhQUFBQSxxQjtJQUF1QkMsMkMsYUFBQUEsMkM7SUFBNkNDLGMsYUFBQUEsYztJQUFnQkMsdUIsYUFBQUEsdUI7O0FBQzVGLElBQU1DLFVBQVUsbUJBQUFwd0IsQ0FBUSxHQUFSLENBQWhCO0FBQ0EsSUFBTXF3QixtQkFBbUIsbUJBQUFyd0IsQ0FBUSxHQUFSLENBQXpCO0FBQ0EsSUFBTXN3QixRQUFRLE9BQWQ7O0FBRUF6d0IsT0FBT0MsT0FBUCxHQUFpQixVQUFDMFYsR0FBRCxFQUFTO0FBQ3hCO0FBQ0FBLE1BQUlnSixHQUFKLENBQVEscUJBQVIsRUFBK0IsVUFBQ2xNLEdBQUQsRUFBTS9CLEdBQU4sRUFBYztBQUFBLFFBQ25DM0csT0FEbUMsR0FDRTBJLEdBREYsQ0FDbkMxSSxPQURtQztBQUFBLFFBQzFCQyxFQUQwQixHQUNFeUksR0FERixDQUMxQnpJLEVBRDBCO0FBQUEsUUFDdEJDLFdBRHNCLEdBQ0V3SSxHQURGLENBQ3RCeEksV0FEc0I7QUFBQSxRQUNUdEYsTUFEUyxHQUNFOE4sR0FERixDQUNUOU4sTUFEUztBQUUzQzs7QUFDQSxRQUFJK3JCLHlCQUFKO0FBQ0EsUUFBSTtBQUFBLGtDQUNzQkgsUUFBUUksYUFBUixDQUFzQmhzQixPQUFPd1gsS0FBN0IsQ0FEdEI7O0FBQ0N1VSxzQkFERCx5QkFDQ0EsZ0JBREQ7QUFFSCxLQUZELENBRUUsT0FBT2p2QixLQUFQLEVBQWM7QUFDZCxhQUFPaVAsSUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIsRUFBQ21LLFNBQVMsS0FBVixFQUFpQmhULFNBQVN3RCxNQUFNeEQsT0FBaEMsRUFBckIsQ0FBUDtBQUNEO0FBQ0QsUUFBSTJ5QixlQUFlVCxzQkFBc0JPLGdCQUF0QixFQUF3QzNtQixPQUF4QyxDQUFuQjtBQUNBLFFBQUk2bUIsaUJBQWlCSCxLQUFyQixFQUE0QjtBQUMxQixhQUFPRCxpQkFBaUIvZCxHQUFqQixFQUFzQi9CLEdBQXRCLENBQVA7QUFDRDtBQUNEO0FBQ0E7QUFDQS9FLHFCQUFpQjVCLE9BQWpCLEVBQTBCQyxFQUExQixFQUE4QkMsV0FBOUI7QUFDQTtBQUNBLFFBQUlYLGtCQUFKO0FBQ0EsUUFBSTtBQUFBLGdDQUNlaW5CLFFBQVFNLFVBQVIsQ0FBbUJsc0IsT0FBT3dYLEtBQTFCLENBRGY7O0FBQ0M3UyxlQURELHVCQUNDQSxTQUREO0FBRUgsS0FGRCxDQUVFLE9BQU83SCxLQUFQLEVBQWM7QUFDZCxhQUFPaVAsSUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIsRUFBQ21LLFNBQVMsS0FBVixFQUFpQmhULFNBQVN3RCxNQUFNeEQsT0FBaEMsRUFBckIsQ0FBUDtBQUNEO0FBQ0Q7QUFDQSxRQUFJNnlCLGtCQUFKO0FBQUEsUUFBZTF5QixvQkFBZjtBQUFBLFFBQTRCbVQsdUJBQTVCO0FBQUEsUUFBNEM5TCxnQkFBNUM7QUFDQSxRQUFJO0FBQUEsa0NBQ3FEOHFCLFFBQVFRLGVBQVIsQ0FBd0Jwc0IsT0FBT3FzQixVQUEvQixDQURyRDs7QUFDQ0YsZUFERCx5QkFDQ0EsU0FERDtBQUNZMXlCLGlCQURaLHlCQUNZQSxXQURaO0FBQ3lCbVQsb0JBRHpCLHlCQUN5QkEsY0FEekI7QUFDeUM5TCxhQUR6Qyx5QkFDeUNBLE9BRHpDO0FBRUgsS0FGRCxDQUVFLE9BQU9oRSxLQUFQLEVBQWM7QUFDZCxhQUFPaVAsSUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOEksSUFBaEIsQ0FBcUIsRUFBQ21LLFNBQVMsS0FBVixFQUFpQmhULFNBQVN3RCxNQUFNeEQsT0FBaEMsRUFBckIsQ0FBUDtBQUNEO0FBQ0QsUUFBSSxDQUFDNnlCLFNBQUwsRUFBZ0I7QUFBQSxrQ0FDU1YsNENBQTRDM3FCLE9BQTVDLEVBQXFENkQsU0FBckQsQ0FEVDs7QUFBQTs7QUFDYjdELGFBRGE7QUFDSjZELGVBREk7QUFFZjtBQUNEO0FBQ0ErbUIsbUJBQWVPLFlBQWYsRUFBNkJ0bkIsU0FBN0IsRUFBd0NsTCxXQUF4QyxFQUFxRHFILE9BQXJEO0FBQ0E7QUFDQTZxQiw0QkFBd0JseUIsV0FBeEIsRUFBcUNtVCxjQUFyQyxFQUFxRGpJLFNBQXJELEVBQWdFN0QsT0FBaEUsRUFBeUV3RSxXQUF6RSxFQUFzRkQsRUFBdEYsRUFBMEYwRyxHQUExRjtBQUNELEdBckNEO0FBc0NBO0FBQ0FpRixNQUFJZ0osR0FBSixDQUFRLFNBQVIsRUFBbUIsVUFBQ2xNLEdBQUQsRUFBTS9CLEdBQU4sRUFBYztBQUFBLFFBQ3ZCM0csT0FEdUIsR0FDYzBJLEdBRGQsQ0FDdkIxSSxPQUR1QjtBQUFBLFFBQ2RDLEVBRGMsR0FDY3lJLEdBRGQsQ0FDZHpJLEVBRGM7QUFBQSxRQUNWQyxXQURVLEdBQ2N3SSxHQURkLENBQ1Z4SSxXQURVO0FBQUEsUUFDR3RGLE1BREgsR0FDYzhOLEdBRGQsQ0FDRzlOLE1BREg7QUFFL0I7O0FBQ0EsUUFBSStyQix5QkFBSjtBQUNBLFFBQUk7QUFBQSxtQ0FDc0JILFFBQVFJLGFBQVIsQ0FBc0Joc0IsT0FBT3dYLEtBQTdCLENBRHRCOztBQUNDdVUsc0JBREQsMEJBQ0NBLGdCQUREO0FBRUgsS0FGRCxDQUVFLE9BQU9qdkIsS0FBUCxFQUFjO0FBQ2QsYUFBT2lQLElBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCLEVBQUNtSyxTQUFTLEtBQVYsRUFBaUJoVCxTQUFTd0QsTUFBTXhELE9BQWhDLEVBQXJCLENBQVA7QUFDRDtBQUNELFFBQUkyeUIsZUFBZVQsc0JBQXNCTyxnQkFBdEIsRUFBd0MzbUIsT0FBeEMsQ0FBbkI7QUFDQSxRQUFJNm1CLGlCQUFpQkgsS0FBckIsRUFBNEI7QUFDMUIsYUFBT0QsaUJBQWlCL2QsR0FBakIsRUFBc0IvQixHQUF0QixDQUFQO0FBQ0Q7QUFDRDtBQUNBO0FBQ0EvRSxxQkFBaUI1QixPQUFqQixFQUEwQkMsRUFBMUIsRUFBOEJDLFdBQTlCO0FBQ0E7QUFDQSxRQUFJWCxrQkFBSjtBQUNBLFFBQUk7QUFBQSxpQ0FDYWluQixRQUFRTSxVQUFSLENBQW1CbHNCLE9BQU93WCxLQUExQixDQURiOztBQUNBN1MsZUFEQSx3QkFDQUEsU0FEQTtBQUVILEtBRkQsQ0FFRSxPQUFPN0gsS0FBUCxFQUFjO0FBQ2QsYUFBT2lQLElBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQjhJLElBQWhCLENBQXFCLEVBQUNtSyxTQUFTLEtBQVYsRUFBaUJoVCxTQUFTd0QsTUFBTXhELE9BQWhDLEVBQXJCLENBQVA7QUFDRDtBQUNEO0FBQ0FveUIsbUJBQWVPLFlBQWYsRUFBNkJ0bkIsU0FBN0IsRUFBd0MsSUFBeEMsRUFBOEMsSUFBOUM7QUFDQTtBQUNBZ25CLDRCQUF3QixJQUF4QixFQUE4QixJQUE5QixFQUFvQ2huQixTQUFwQyxFQUErQyxJQUEvQyxFQUFxRFcsV0FBckQsRUFBa0VELEVBQWxFLEVBQXNFMEcsR0FBdEU7QUFDRCxHQTNCRDtBQTRCRCxDQXJFRCxDOzs7Ozs7Ozs7QUNOQSxJQUFNdFEsU0FBUyxtQkFBQUQsQ0FBUSxDQUFSLENBQWY7O2VBQzJDLG1CQUFBQSxDQUFRLEVBQVIsQztJQUFuQ21SLFUsWUFBQUEsVTtJQUFZaUIsa0IsWUFBQUEsa0I7O2dCQUNZLG1CQUFBcFMsQ0FBUSxFQUFSLEM7SUFBeEJzUSxtQixhQUFBQSxtQjs7QUFFUixJQUFNZ2dCLFFBQVEsT0FBZDtBQUNBLElBQU1RLE9BQU8sTUFBYjtBQUNBLElBQU01ZixVQUFVLFNBQWhCO0FBQ0EsSUFBTUYsYUFBYSxZQUFuQjtBQUNBLElBQU1DLFdBQVcsVUFBakI7O0FBRUEsU0FBUzhmLGlCQUFULE9BQXNDO0FBQUEsTUFBVEMsTUFBUyxRQUFUQSxNQUFTOztBQUNwQyxTQUFPQSxVQUFVQSxPQUFPdkMsS0FBUCxDQUFhLFlBQWIsQ0FBakI7QUFDRDs7QUFFRCxTQUFTd0Msb0JBQVQsQ0FBK0JybkIsT0FBL0IsRUFBd0M7QUFDdEMsU0FBT0EsUUFBUSxZQUFSLEtBQXlCQSxRQUFRLFlBQVIsRUFBc0I2a0IsS0FBdEIsQ0FBNEIsU0FBNUIsQ0FBaEM7QUFDRDs7QUFFRCxTQUFTeUMsZ0JBQVQsUUFBNEM7QUFBQSxNQUFoQkYsTUFBZ0IsU0FBaEJBLE1BQWdCO0FBQUEsTUFBUkcsS0FBUSxTQUFSQSxLQUFROztBQUMxQyxNQUFNQyxnQkFBZ0JKLFVBQVVBLE9BQU92QyxLQUFQLENBQWEsV0FBYixDQUFWLElBQXVDLENBQUN1QyxPQUFPdkMsS0FBUCxDQUFhLFlBQWIsQ0FBeEMsSUFBc0UsQ0FBQ3VDLE9BQU92QyxLQUFQLENBQWEsVUFBYixDQUE3RjtBQUNBLE1BQU00QyxnQkFBZ0JMLFVBQVVHLEtBQWhDO0FBQ0EsU0FBT0MsaUJBQWlCQyxhQUF4QjtBQUNEOztBQUVELFNBQVNDLGNBQVQsQ0FBeUJoc0IsT0FBekIsRUFBa0M7QUFDaEMsU0FBU0EsUUFBUXlJLE1BQVIsS0FBbUIsRUFBcEIsSUFBMkIsQ0FBQyxnQkFBZ0JVLElBQWhCLENBQXFCbkosT0FBckIsQ0FBcEM7QUFDRDs7QUFFRCxTQUFTaXNCLGNBQVQsQ0FBeUJqc0IsT0FBekIsRUFBa0M7QUFDaEMsU0FBT0EsUUFBUXlJLE1BQVIsS0FBbUIsQ0FBMUIsQ0FEZ0MsQ0FDRjtBQUMvQjs7QUFFRCxTQUFTeWpCLHVCQUFULENBQWtDekksS0FBbEMsRUFBeUM7QUFDdkMsU0FBUXVJLGVBQWV2SSxLQUFmLEtBQXlCd0ksZUFBZXhJLEtBQWYsQ0FBakM7QUFDRDs7QUFFRCxTQUFTMEksa0JBQVQsQ0FBNkJuc0IsT0FBN0IsRUFBc0MvSCxJQUF0QyxFQUE0Q2dULEdBQTVDLEVBQWlEO0FBQy9DLFNBQU82QixtQkFBbUI5TSxPQUFuQixFQUE0Qi9ILElBQTVCLEVBQ0o0RCxJQURJLENBQ0Msc0JBQWM7QUFDbEI7QUFDQSxRQUFJbWUsZUFBZXBPLE9BQW5CLEVBQTRCO0FBQzFCLGFBQU9YLElBQUkxUyxNQUFKLENBQVcsR0FBWCxFQUFnQitVLFFBQWhCLHFCQUEyQ3JWLElBQTNDLFNBQW1EK0gsT0FBbkQsQ0FBUDtBQUNEO0FBQ0Q7QUFMa0IsUUFNWHNKLFFBTlcsR0FNVzBRLFVBTlgsQ0FNWDFRLFFBTlc7QUFBQSxRQU1EQyxRQU5DLEdBTVd5USxVQU5YLENBTUR6USxRQU5DOztBQU9sQjVPLFdBQU8rVixPQUFQLG9CQUFnQ3BILFFBQWhDO0FBQ0EsUUFBTThpQixrQkFBa0I7QUFDdEI5bkIsZUFBUztBQUNQLGtDQUEwQixTQURuQjtBQUVQLHdCQUEwQmlGLFlBQVk7QUFGL0I7QUFEYSxLQUF4QjtBQU1BMEIsUUFBSTFTLE1BQUosQ0FBVyxHQUFYLEVBQWdCOHpCLFFBQWhCLENBQXlCL2lCLFFBQXpCLEVBQW1DOGlCLGVBQW5DO0FBQ0QsR0FoQkksRUFpQkpyd0IsS0FqQkksQ0FpQkUsaUJBQVM7QUFDZCxVQUFNQyxLQUFOO0FBQ0QsR0FuQkksQ0FBUDtBQW9CRDs7QUFFRHpCLE9BQU9DLE9BQVAsR0FBaUI7QUFDZnF3Qix5QkFEZSxtQ0FDVWx5QixXQURWLEVBQ3VCbVQsY0FEdkIsRUFDdUNqSSxTQUR2QyxFQUNrRDdELE9BRGxELEVBQzJEd0UsV0FEM0QsRUFDd0VELEVBRHhFLEVBQzRFMEcsR0FENUUsRUFDaUY7QUFDOUY7QUFDQVksZUFBV2xULFdBQVgsRUFBd0JtVCxjQUF4QixFQUF3Q2pJLFNBQXhDLEVBQW1EN0QsT0FBbkQsRUFDR25FLElBREgsQ0FDUSx1QkFBZTtBQUNuQixVQUFJeXdCLGdCQUFnQjNnQixRQUFwQixFQUE4QjtBQUM1QixlQUFPVixJQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxLQUFWLEVBQWlCaFQsU0FBUyw0QkFBMUIsRUFBckIsQ0FBUDtBQUNELE9BRkQsTUFFTyxJQUFJOHpCLGdCQUFnQjVnQixVQUFwQixFQUFnQztBQUNyQyxlQUFPVCxJQUFJMVMsTUFBSixDQUFXLEdBQVgsRUFBZ0I4SSxJQUFoQixDQUFxQixFQUFDbUssU0FBUyxLQUFWLEVBQWlCaFQsU0FBUyw4QkFBMUIsRUFBckIsQ0FBUDtBQUNEO0FBQ0QyekIseUJBQW1CRyxXQUFuQixFQUFnQ3pvQixTQUFoQyxFQUEyQ29ILEdBQTNDO0FBQ0E7QUFDRCxLQVRILEVBVUdsUCxLQVZILENBVVMsaUJBQVM7QUFDZGlQLDBCQUFvQnhHLFdBQXBCLEVBQWlDRCxFQUFqQyxFQUFxQ3ZJLEtBQXJDLEVBQTRDaVAsR0FBNUM7QUFDQTtBQUNELEtBYkg7QUFjRCxHQWpCYztBQWtCZnlmLHVCQWxCZSxpQ0FrQlFPLGdCQWxCUixFQWtCMEIzbUIsT0FsQjFCLEVBa0JtQztBQUNoRCxRQUFJNm1CLHFCQUFKO0FBQ0EsUUFBSUYsZ0JBQUosRUFBc0I7QUFDcEJFLHFCQUFlSCxLQUFmLENBRG9CLENBQ0c7QUFDdkIsVUFBSVMsa0JBQWtCbm5CLE9BQWxCLENBQUosRUFBZ0M7QUFBRztBQUNqQzZtQix1QkFBZUssSUFBZjtBQUNEO0FBQ0YsS0FMRCxNQUtPO0FBQ0xMLHFCQUFlSyxJQUFmO0FBQ0EsVUFBSUksaUJBQWlCdG5CLE9BQWpCLEtBQTZCcW5CLHFCQUFxQnJuQixPQUFyQixDQUFqQyxFQUFnRTtBQUFHO0FBQ2pFM0osZUFBTzJDLEtBQVAsQ0FBYSx3RkFBYjtBQUNBNnRCLHVCQUFlSCxLQUFmO0FBQ0Q7QUFDRjtBQUNELFdBQU9HLFlBQVA7QUFDRCxHQWpDYztBQWtDZlIsNkNBbENlLHVEQWtDOEJZLFVBbEM5QixFQWtDMEN0ekIsSUFsQzFDLEVBa0NnRDtBQUM3RDtBQUNBLFFBQUlpMEIsd0JBQXdCajBCLElBQXhCLEtBQWlDLENBQUNpMEIsd0JBQXdCWCxVQUF4QixDQUF0QyxFQUEyRTtBQUN6RSxVQUFNZ0IsV0FBV3QwQixJQUFqQjtBQUNBQSxhQUFPc3pCLFVBQVA7QUFDQUEsbUJBQWFnQixRQUFiO0FBQ0Q7QUFDRCxXQUFPLENBQUNoQixVQUFELEVBQWF0ekIsSUFBYixDQUFQO0FBQ0QsR0ExQ2M7QUEyQ2YyeUIsZ0JBM0NlLDBCQTJDQ08sWUEzQ0QsRUEyQ2V0bkIsU0EzQ2YsRUEyQzBCbEwsV0EzQzFCLEVBMkN1Q3FILE9BM0N2QyxFQTJDZ0Q7QUFDN0RyRixXQUFPMkMsS0FBUCxDQUFhLGtCQUFiLEVBQWlDNnRCLFlBQWpDO0FBQ0F4d0IsV0FBTzJDLEtBQVAsQ0FBYSxpQkFBYixFQUFnQ3VHLFNBQWhDO0FBQ0FsSixXQUFPMkMsS0FBUCxDQUFhLGtCQUFiLEVBQWlDM0UsV0FBakM7QUFDQWdDLFdBQU8yQyxLQUFQLENBQWEsY0FBYixFQUE2QjBDLE9BQTdCO0FBQ0Q7QUFoRGMsQ0FBakIsQzs7Ozs7Ozs7Ozs7QUMzREEsSUFBTXJGLFNBQVMsbUJBQUFELENBQVEsQ0FBUixDQUFmOztBQUVBSCxPQUFPQyxPQUFQLEdBQWlCO0FBQ2ZneUIsd0JBQXdCLGdCQURUO0FBRWZDLDBCQUF3QixpQkFGVDtBQUdmQyxrQkFBd0IseUNBSFQ7QUFJZkMsZ0JBQXdCLEdBSlQ7QUFLZnJCLG1CQUF3Qix5QkFBVUMsVUFBVixFQUFzQjtBQUM1QzV3QixXQUFPMkMsS0FBUCxDQUFhLHFCQUFiLEVBQW9DaXVCLFVBQXBDO0FBQ0EsUUFBTXFCLGtCQUFrQixJQUFJQyxNQUFKLENBQ3RCLGVBQWU7QUFDZixxQkFGc0IsQ0FFSjtBQUZJLEtBQXhCOztBQUY0QyxnQ0FNUUQsZ0JBQ2pENWpCLElBRGlELENBQzVDdWlCLFVBRDRDLEVBRWpEL2pCLEdBRmlELENBRTdDO0FBQUEsYUFBUzJoQixTQUFTLElBQWxCO0FBQUEsS0FGNkMsQ0FOUjtBQUFBO0FBQUEsUUFNckMyRCxLQU5xQztBQUFBLFFBTTlCNTBCLEtBTjhCO0FBQUEsUUFNdkI2MEIsaUJBTnVCO0FBQUEsUUFNSm50QixRQU5JOztBQVM1Q2pGLFdBQU8yQyxLQUFQLENBQWdCd3ZCLEtBQWhCLFVBQTBCNTBCLEtBQTFCLFVBQW9DNjBCLGlCQUFwQyxVQUEwRG50QixRQUExRDs7QUFFQTtBQUNBLFFBQUksQ0FBQzFILEtBQUwsRUFBWTtBQUNWLFlBQU0sSUFBSXNKLEtBQUosd0RBQStEdXJCLGlCQUEvRCxPQUFOO0FBQ0Q7QUFDRCxRQUFNMUIsWUFBWW56QixNQUFNODBCLFVBQU4sQ0FBaUJ6eUIsT0FBT0MsT0FBUCxDQUFlbXlCLFlBQWhDLENBQWxCO0FBQ0EsUUFBTWgwQixjQUFjMHlCLFlBQVluekIsS0FBWixHQUFvQixJQUF4QztBQUNBLFFBQUk4SCxnQkFBSjtBQUNBLFFBQUlxckIsU0FBSixFQUFlO0FBQ2IsVUFBSSxDQUFDMXlCLFdBQUwsRUFBa0I7QUFDaEIsY0FBTSxJQUFJNkksS0FBSixDQUFVLDBCQUFWLENBQU47QUFDRDtBQUNELFVBQU15ckIsZUFBZ0J0MEIsV0FBRCxDQUFjd3dCLEtBQWQsQ0FBb0I1dUIsT0FBT0MsT0FBUCxDQUFlaXlCLHNCQUFuQyxDQUFyQjtBQUNBLFVBQUlRLFlBQUosRUFBa0I7QUFDaEIsY0FBTSxJQUFJenJCLEtBQUosMENBQWlEeXJCLGFBQWFDLElBQWIsQ0FBa0IsSUFBbEIsQ0FBakQsT0FBTjtBQUNEO0FBQ0YsS0FSRCxNQVFPO0FBQ0xsdEIsZ0JBQVU5SCxLQUFWO0FBQ0Q7O0FBRUQ7QUFDQSxRQUFJNFQsdUJBQUo7QUFDQSxRQUFJaWhCLGlCQUFKLEVBQXVCO0FBQ3JCLFVBQUksQ0FBQ250QixRQUFMLEVBQWU7QUFDYixjQUFNLElBQUk0QixLQUFKLDRDQUFtRHVyQixpQkFBbkQsT0FBTjtBQUNEOztBQUVELFVBQUlBLHNCQUFzQixHQUExQixFQUErQjtBQUM3QmpoQix5QkFBaUJsTSxRQUFqQjtBQUNELE9BRkQsTUFFTztBQUNMLGNBQU0sSUFBSTRCLEtBQUosV0FBa0J1ckIsaUJBQWxCLDJDQUFOO0FBQ0Q7QUFDRjtBQUNELFdBQU87QUFDTDFCLDBCQURLO0FBRUwxeUIsOEJBRks7QUFHTG1ULG9DQUhLO0FBSUw5TDtBQUpLLEtBQVA7QUFNRCxHQXREYztBQXVEZm9yQixjQUFZLG9CQUFVMVUsS0FBVixFQUFpQjtBQUMzQi9iLFdBQU8yQyxLQUFQLENBQWEsZUFBYixFQUE4Qm9aLEtBQTlCO0FBQ0EsUUFBTWtXLGtCQUFrQixJQUFJQyxNQUFKLENBQ3RCLGdCQUFnQjtBQUNoQixzQkFGc0IsQ0FFSDtBQUZHLEtBQXhCOztBQUYyQixpQ0FNNkJELGdCQUNyRDVqQixJQURxRCxDQUNoRDBOLEtBRGdELEVBRXJEbFAsR0FGcUQsQ0FFakQ7QUFBQSxhQUFTMmhCLFNBQVMsSUFBbEI7QUFBQSxLQUZpRCxDQU43QjtBQUFBO0FBQUEsUUFNcEIyRCxLQU5vQjtBQUFBLFFBTWJqcEIsU0FOYTtBQUFBLFFBTUZrcEIsaUJBTkU7QUFBQSxRQU1pQm50QixRQU5qQjs7QUFTM0JqRixXQUFPMkMsS0FBUCxDQUFnQnd2QixLQUFoQixVQUEwQmpwQixTQUExQixVQUF3Q2twQixpQkFBeEMsVUFBOERudEIsUUFBOUQ7O0FBRUE7QUFDQSxRQUFJLENBQUNpRSxTQUFMLEVBQWdCO0FBQ2QsWUFBTSxJQUFJckMsS0FBSixDQUFVLGlDQUFWLENBQU47QUFDRDtBQUNELFFBQU15ckIsZUFBZ0JwcEIsU0FBRCxDQUFZc2xCLEtBQVosQ0FBa0I1dUIsT0FBT0MsT0FBUCxDQUFlZ3lCLG9CQUFqQyxDQUFyQjtBQUNBLFFBQUlTLFlBQUosRUFBa0I7QUFDaEIsWUFBTSxJQUFJenJCLEtBQUosd0NBQStDeXJCLGFBQWFDLElBQWIsQ0FBa0IsSUFBbEIsQ0FBL0MsT0FBTjtBQUNEO0FBQ0Q7QUFDQSxRQUFJSCxpQkFBSixFQUF1QjtBQUNyQixVQUFJLENBQUNudEIsUUFBTCxFQUFlO0FBQ2IsY0FBTSxJQUFJNEIsS0FBSixpREFBd0R1ckIsaUJBQXhELE9BQU47QUFDRDtBQUNELFVBQUlBLHNCQUFzQixHQUExQixFQUErQjtBQUM3QixjQUFNLElBQUl2ckIsS0FBSixVQUFpQnVyQixpQkFBakIsa0RBQU47QUFDRDtBQUNGO0FBQ0Q7QUFDQSxXQUFPO0FBQ0xscEI7QUFESyxLQUFQO0FBR0QsR0F2RmM7QUF3RmZxbkIsaUJBQWUsdUJBQVV4VSxLQUFWLEVBQWlCO0FBQzlCL2IsV0FBTzJDLEtBQVAsQ0FBYSxtQkFBYixFQUFrQ29aLEtBQWxDO0FBQ0EsUUFBTWtXLGtCQUFrQixJQUFJQyxNQUFKLENBQ3RCLGdCQUFnQjtBQUNoQixzQkFGc0IsQ0FFSDtBQUZHLEtBQXhCOztBQUY4QixpQ0FNMEJELGdCQUNyRDVqQixJQURxRCxDQUNoRDBOLEtBRGdELEVBRXJEbFAsR0FGcUQsQ0FFakQ7QUFBQSxhQUFTMmhCLFNBQVMsSUFBbEI7QUFBQSxLQUZpRCxDQU4xQjtBQUFBO0FBQUEsUUFNdkIyRCxLQU51QjtBQUFBLFFBTWhCanBCLFNBTmdCO0FBQUEsUUFNTGtwQixpQkFOSztBQUFBLFFBTWNudEIsUUFOZDs7QUFTOUJqRixXQUFPMkMsS0FBUCxDQUFnQnd2QixLQUFoQixVQUEwQmpwQixTQUExQixVQUF3Q2twQixpQkFBeEMsVUFBOERudEIsUUFBOUQ7QUFDQTtBQUNBLFFBQUlxckIsbUJBQW1CLEtBQXZCO0FBQ0EsUUFBSThCLGlCQUFKLEVBQXVCO0FBQ3JCOUIseUJBQW1CLElBQW5CO0FBQ0Q7QUFDRCxXQUFPO0FBQ0xBO0FBREssS0FBUDtBQUdEO0FBMUdjLENBQWpCLEM7Ozs7Ozs7OztBQ0ZBOzs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOztBQUVBOzs7Ozs7QUFFQSxJQUFNa0MsdUJBQXVCLFNBQXZCQSxvQkFBdUIsQ0FBQ0MsSUFBRCxFQUFPbHVCLE1BQVAsRUFBa0I7QUFDN0MsK0NBQU87QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEscUJBQ0MsbUJBQUtrdUIsSUFBTCxFQUFXbHVCLE1BQVgsQ0FERDs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxLQUFQO0FBQUE7QUFHRCxDQUpEOztBQU1BM0UsT0FBT0MsT0FBUCxHQUFpQixVQUFDd1MsR0FBRCxFQUFNL0IsR0FBTixFQUFjO0FBQzdCLE1BQUlnQyxVQUFVLEVBQWQ7O0FBRUE7QUFDQSxNQUFNb2dCLGlCQUFpQiwwQkFBdkI7QUFDQSxNQUFNQyxhQUFhLDRCQUFnQkQsY0FBaEIsQ0FBbkI7O0FBRUE7QUFDQSxNQUFNbmdCLFFBQVEseUNBQXFCb2dCLFVBQXJCLENBQWQ7O0FBRUE7QUFDQSxNQUFNdlYsU0FBUywrQkFBb0IvSyxJQUFJOU4sTUFBeEIsQ0FBZjtBQUNBLE1BQU1rdUIsT0FBT0Qsa0RBQXdDcFYsTUFBeEMsQ0FBYjs7QUFFQTtBQUNBc1YsaUJBQ0dFLEdBREgsQ0FDT0gsSUFEUCxFQUVHM2IsSUFGSCxDQUdHNVYsSUFISCxDQUdRLFlBQU07QUFDVjtBQUNBLFFBQU1zUixPQUFPLDRCQUNYO0FBQUE7QUFBQSxRQUFVLE9BQU9ELEtBQWpCO0FBQ0U7QUFBQTtBQUFBLFVBQWMsVUFBVUYsSUFBSXZMLEdBQTVCLEVBQWlDLFNBQVN3TCxPQUExQztBQUNFO0FBQUE7QUFBQTtBQUNFO0FBREY7QUFERjtBQURGLEtBRFcsQ0FBYjs7QUFVQTtBQUNBLFFBQU1HLFNBQVMsc0JBQU9DLFlBQVAsRUFBZjs7QUFFQTtBQUNBLFFBQUlKLFFBQVF4TCxHQUFaLEVBQWlCO0FBQ2YsYUFBT3dKLElBQUlxQyxRQUFKLENBQWEsR0FBYixFQUFrQkwsUUFBUXhMLEdBQTFCLENBQVA7QUFDRDs7QUFFRDtBQUNBLFFBQU04TCxpQkFBaUJMLE1BQU1NLFFBQU4sRUFBdkI7O0FBRUE7QUFDQXZDLFFBQUl3QyxJQUFKLENBQVMsOEJBQWVMLE1BQWYsRUFBdUJELElBQXZCLEVBQTZCSSxjQUE3QixDQUFUO0FBQ0QsR0E1Qkg7QUE2QkQsQ0E1Q0QsQzs7Ozs7O0FDdEJBLHVDOzs7Ozs7Ozs7Ozs7UUNnRGtCaWdCLGlCLEdBQUFBLGlCO1FBUUFDLHNCLEdBQUFBLHNCOztBQXhEbEI7O0FBQ0E7O0lBQVk5MUIsTzs7QUFDWjs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7bURBRVcrMUIsZ0M7b0RBaUJBQyx1QjtvREF3Qk9ILGlCO29EQVFBQyxzQjs7QUFqRGxCLFNBQVdDLGdDQUFYLENBQTZDOXRCLFFBQTdDLEVBQXVEOFcsS0FBdkQ7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNFO0FBQ0E7QUFDQTtBQUNJMlUsbUJBSk4sV0FJaUIxeUIsV0FKakIsV0FJOEJtVCxjQUo5QixXQUk4QzlMLE9BSjlDLFdBSXVENkQsU0FKdkQsV0FJa0VuRSxTQUpsRTtBQUFBO0FBQUEsa0NBTTJELGtCQUFRNHJCLGVBQVIsQ0FBd0IxckIsUUFBeEIsQ0FOM0Q7QUFNT3lyQixtQkFOUCx5QkFNT0EsU0FOUDtBQU1rQjF5QixxQkFObEIseUJBTWtCQSxXQU5sQjtBQU0rQm1ULHdCQU4vQix5QkFNK0JBLGNBTi9CO0FBTStDOUwsaUJBTi9DLHlCQU0rQ0EsT0FOL0M7QUFBQSxnQ0FPZ0Msa0JBQVFvckIsVUFBUixDQUFtQjFVLEtBQW5CLENBUGhDO0FBT083UyxtQkFQUCx1QkFPT0EsU0FQUDtBQU9rQm5FLG1CQVBsQix1QkFPa0JBLFNBUGxCO0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGlCQVNpQixrQkFBSSwwQkFBZSxZQUFNbEgsT0FBckIsQ0FBSixDQVRqQjs7QUFBQTtBQUFBOztBQUFBO0FBQUEsZUFZTTZ5QixTQVpOO0FBQUE7QUFBQTtBQUFBOztBQUFBO0FBQUEsaUJBYWlCLGdEQUFzQiw2QkFBa0J4bkIsU0FBbEIsRUFBNkIsSUFBN0IsRUFBbUNsTCxXQUFuQyxFQUFnRG1ULGNBQWhELEVBQWdFcE0sU0FBaEUsQ0FBdEIsQ0FiakI7O0FBQUE7QUFBQTs7QUFBQTtBQWNHO0FBZEg7QUFBQSxpQkFlUSxnREFBc0IsNkJBQWtCbUUsU0FBbEIsRUFBNkI3RCxPQUE3QixFQUFzQyxJQUF0QyxFQUE0QyxJQUE1QyxFQUFrRE4sU0FBbEQsQ0FBdEIsQ0FmUjs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWlCQSxTQUFXaXVCLHVCQUFYLENBQW9DalgsS0FBcEM7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNFO0FBQ0E7QUFDSTJVLG1CQUhOLFdBR2lCMXlCLFdBSGpCLFdBRzhCbVQsY0FIOUI7QUFBQTtBQUFBLG1DQUtrRCxrQkFBUXdmLGVBQVIsQ0FBd0I1VSxLQUF4QixDQUxsRDtBQUtPMlUsbUJBTFAsMEJBS09BLFNBTFA7QUFLa0IxeUIscUJBTGxCLDBCQUtrQkEsV0FMbEI7QUFLK0JtVCx3QkFML0IsMEJBSytCQSxjQUwvQjtBQUFBO0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxpQkFPaUIsa0JBQUksMEJBQWUsYUFBTXRULE9BQXJCLENBQUosQ0FQakI7O0FBQUE7QUFBQTs7QUFBQTtBQUFBLGVBV002eUIsU0FYTjtBQUFBO0FBQUE7QUFBQTs7QUFBQTtBQUFBLGlCQVlpQixvREFBd0IsK0JBQW9CMXlCLFdBQXBCLEVBQWlDbVQsY0FBakMsQ0FBeEIsQ0FaakI7O0FBQUE7QUFBQTs7QUFBQTtBQWNFO0FBQ0lqSSxtQkFmTixXQWVpQm5FLFNBZmpCO0FBQUE7QUFBQSxpQ0FpQjhCLGtCQUFRMHJCLFVBQVIsQ0FBbUIxVSxLQUFuQixDQWpCOUI7QUFpQk03UyxtQkFqQk4sd0JBaUJNQSxTQWpCTjtBQWlCaUJuRSxtQkFqQmpCLHdCQWlCaUJBLFNBakJqQjtBQUFBO0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxpQkFtQmlCLGtCQUFJLDBCQUFlLGFBQU1sSCxPQUFyQixDQUFKLENBbkJqQjs7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQSxpQkFxQlEsZ0RBQXNCLDZCQUFrQnFMLFNBQWxCLEVBQTZCLElBQTdCLEVBQW1DLElBQW5DLEVBQXlDLElBQXpDLEVBQStDbkUsU0FBL0MsQ0FBdEIsQ0FyQlI7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBd0JPLFNBQVc4dEIsaUJBQVgsQ0FBOEJ6VixNQUE5QjtBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEseUJBQ3lCQSxPQUFPaGdCLElBRGhDLEVBQ0d3ekIsVUFESCxnQkFDR0EsVUFESCxFQUNlN1UsS0FEZixnQkFDZUEsS0FEZjs7QUFBQSxlQUVENlUsVUFGQztBQUFBO0FBQUE7QUFBQTs7QUFBQTtBQUFBLGlCQUdVLG1CQUFLbUMsZ0NBQUwsRUFBdUNuQyxVQUF2QyxFQUFtRDdVLEtBQW5ELENBSFY7O0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUEsaUJBS0MsbUJBQUtpWCx1QkFBTCxFQUE4QmpYLEtBQTlCLENBTEQ7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsQ0FNTjs7QUFFTSxTQUFXK1csc0JBQVg7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsaUJBQ0MseUJBQVc5MUIsUUFBUXdILGVBQW5CLEVBQW9DcXVCLGlCQUFwQyxDQUREOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLENBRU4sQzs7Ozs7Ozs7Ozs7O1FDbkRpQkksZSxHQUFBQSxlO1FBNkNBQyxvQixHQUFBQSxvQjs7QUFwRGxCOztBQUNBOztJQUFZbDJCLE87O0FBQ1o7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7bURBRWtCaTJCLGU7b0RBNkNBQyxvQjs7QUE3Q1gsU0FBV0QsZUFBWCxDQUE0QjdWLE1BQTVCO0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSx5QkFDOENBLE9BQU9oZ0IsSUFEckQsRUFDR3VILFdBREgsZ0JBQ0dBLFdBREgsRUFDZ0JDLFNBRGhCLGdCQUNnQkEsU0FEaEIsRUFDMkJ0SCxJQUQzQixnQkFDMkJBLElBRDNCLEVBQ2lDMkgsUUFEakMsZ0JBQ2lDQSxRQURqQztBQUVMOztBQUZLO0FBQUEsaUJBR0Msa0JBQUksMkJBQWdCTixXQUFoQixFQUE2QkMsU0FBN0IsQ0FBSixDQUhEOztBQUFBO0FBQUE7QUFBQSxpQkFNZSw0Q0FOZjs7QUFBQTtBQU1DNkMsZUFORDtBQUFBO0FBQUEsaUJBT2MsMENBUGQ7O0FBQUE7QUFPQ3hJLGNBUEQ7O0FBQUEsZUFRRHdJLE1BQU1KLFdBQU4sQ0FBa0J6QyxTQUFsQixDQVJDO0FBQUE7QUFBQTtBQUFBOztBQUFBLDJDQVNJLElBVEo7O0FBQUE7QUFXTDtBQUNJeEIsZ0JBWkM7QUFBQTtBQUFBO0FBQUEsaUJBY3FCLDZDQUFxQm5FLElBQXJCLEVBQTJCM0IsSUFBM0IsRUFBaUMySCxRQUFqQyxDQWRyQjs7QUFBQTtBQUFBO0FBY0s3QixnQkFkTCxRQWNEaEcsSUFkQztBQUFBO0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxpQkFnQlUsa0JBQUksMEJBQWUsWUFBTVMsT0FBckIsQ0FBSixDQWhCVjs7QUFBQTtBQUFBOztBQUFBO0FBa0JDeUosa0JBbEJELFVBa0JpQmhLLElBbEJqQixTQWtCeUI4RixNQWxCekI7QUFBQTtBQUFBLGlCQW1CQyxrQkFBSSxtQ0FBd0J3QixTQUF4QixFQUFtQyxJQUFuQyxFQUF5QzBDLFFBQXpDLENBQUosQ0FuQkQ7O0FBQUE7QUFBQSxlQXNCREcsTUFBTUYsU0FBTixDQUFnQkQsUUFBaEIsQ0F0QkM7QUFBQTtBQUFBO0FBQUE7O0FBQUEsMkNBdUJJLElBdkJKOztBQUFBO0FBeUJMO0FBQ0lwRSxpQkExQkM7QUFBQTtBQUFBO0FBQUEsaUJBNEJzQix5Q0FBaUJqRSxJQUFqQixFQUF1QjNCLElBQXZCLEVBQTZCOEYsTUFBN0IsQ0E1QnRCOztBQUFBO0FBQUE7QUE0QktGLGlCQTVCTCxTQTRCRDlGLElBNUJDO0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGlCQThCVSxrQkFBSSwwQkFBZSxZQUFNUyxPQUFyQixDQUFKLENBOUJWOztBQUFBO0FBQUE7O0FBQUE7QUFnQ0w7QUFDSXlILG1CQWpDQztBQUFBO0FBQUE7QUFBQSxpQkFtQ3dCLDJDQUFtQnJHLElBQW5CLEVBQXlCM0IsSUFBekIsRUFBK0I4RixNQUEvQixDQW5DeEI7O0FBQUE7QUFBQTtBQW1DS2tDLG1CQW5DTCxTQW1DRGxJLElBbkNDO0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGlCQXFDVSxrQkFBSSwwQkFBZSxZQUFNUyxPQUFyQixDQUFKLENBckNWOztBQUFBO0FBQUE7O0FBQUE7QUFBQTtBQUFBLGlCQXdDQyxrQkFBSSwrQkFBb0J5SixRQUFwQixFQUE4QixJQUE5QixFQUFvQ2hLLElBQXBDLEVBQTBDOEYsTUFBMUMsRUFBa0RGLE9BQWxELEVBQTJEb0MsU0FBM0QsQ0FBSixDQXhDRDs7QUFBQTtBQUFBO0FBQUEsaUJBMENDLGtCQUFJLDBCQUFlLElBQWYsQ0FBSixDQTFDRDs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxDQTJDTjs7QUFFTSxTQUFXNHRCLG9CQUFYO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGlCQUNDLHlCQUFXbDJCLFFBQVFnSSxpQkFBbkIsRUFBc0NpdUIsZUFBdEMsQ0FERDs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxDQUVOLEM7Ozs7Ozs7Ozs7OztRQ3BEZTNoQixjLEdBQUFBLGM7UUF1QkE2aEIsVSxHQUFBQSxVO1FBS0FDLFksR0FBQUEsWTs7QUE5QmhCOzs7Ozs7QUFFTyxTQUFTOWhCLGNBQVQsQ0FBeUJyUyxJQUF6QixFQUErQjNCLElBQS9CLEVBQXFDMkgsUUFBckMsRUFBK0M7QUFDcEQsTUFBSWdhLE9BQU8sRUFBWDtBQUNBO0FBQ0EsTUFBSWhhLFFBQUosRUFBYztBQUNaLFFBQUlBLFNBQVNILEVBQWIsRUFBaUI7QUFDZm1hLFdBQUssU0FBTCxJQUFrQmhhLFNBQVNILEVBQTNCO0FBQ0QsS0FGRCxNQUVPO0FBQ0xtYSxXQUFLLGFBQUwsSUFBc0JoYSxTQUFTdkgsT0FBVCxDQUFpQkosSUFBdkM7QUFDQTJoQixXQUFLLGdCQUFMLElBQXlCaGEsU0FBU3ZILE9BQVQsQ0FBaUJvSCxFQUExQztBQUNEO0FBQ0Y7QUFDRG1hLE9BQUssV0FBTCxJQUFvQjNoQixJQUFwQjtBQUNBLE1BQU1pSCxTQUFTO0FBQ2JzRSxZQUFTLE1BREk7QUFFYmMsYUFBUyxFQUFFLGdCQUFnQixrQkFBbEIsRUFGSTtBQUdic1YsVUFBUzVXLEtBQUtDLFNBQUwsQ0FBZTJXLElBQWY7QUFISSxHQUFmO0FBS0E7QUFDQSxNQUFNblksTUFBUzdILElBQVQsdUJBQU47QUFDQTtBQUNBLFNBQU8sdUJBQVE2SCxHQUFSLEVBQWF2QyxNQUFiLENBQVA7QUFDRDs7QUFFTSxTQUFTNHVCLFVBQVQsQ0FBcUJsMEIsSUFBckIsRUFBMkIzQixJQUEzQixFQUFpQytILE9BQWpDLEVBQTBDO0FBQy9DLE1BQU15QixNQUFTN0gsSUFBVCw0QkFBb0NvRyxPQUFwQyxTQUErQy9ILElBQXJEO0FBQ0EsU0FBTyx1QkFBUXdKLEdBQVIsQ0FBUDtBQUNEOztBQUVNLFNBQVNzc0IsWUFBVCxDQUF1Qm4wQixJQUF2QixFQUE2QjNCLElBQTdCLEVBQW1DK0gsT0FBbkMsRUFBNEM7QUFDakQsTUFBTXlCLE1BQVM3SCxJQUFULHdCQUFnQzNCLElBQWhDLFNBQXdDK0gsT0FBOUM7QUFDQSxTQUFPLHVCQUFReUIsR0FBUixDQUFQO0FBQ0QsRTs7Ozs7Ozs7Ozs7O1FDMUJpQnVzQixpQixHQUFBQSxpQjtRQXVDQUMsc0IsR0FBQUEsc0I7UUFnQkFDLHdCLEdBQUFBLHdCOztBQTlEbEI7O0FBQ0E7O0lBQVl2MkIsTzs7QUFDWjs7QUFDQTs7QUFDQTs7QUFDQTs7OzttREFFa0JxMkIsaUI7b0RBdUNBQyxzQjtvREFJUEUsNEI7b0RBWU9ELHdCOztBQXZEWCxTQUFXRixpQkFBWCxDQUE4QmpXLE1BQTlCO0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSx5QkFDc0RBLE9BQU9oZ0IsSUFEN0QsRUFDR3VILFdBREgsZ0JBQ0dBLFdBREgsRUFDZ0JDLFNBRGhCLGdCQUNnQkEsU0FEaEIsRUFDMkI1RyxXQUQzQixnQkFDMkJBLFdBRDNCLEVBQ3dDMEcsU0FEeEMsZ0JBQ3dDQSxTQUR4QztBQUVMOztBQUZLO0FBQUEsaUJBR0Msa0JBQUksMkJBQWdCQyxXQUFoQixFQUE2QkMsU0FBN0IsQ0FBSixDQUhEOztBQUFBO0FBQUE7QUFBQSxpQkFNZSw0Q0FOZjs7QUFBQTtBQU1DNkMsZUFORDtBQUFBO0FBQUEsaUJBT2MsMENBUGQ7O0FBQUE7QUFPQ3hJLGNBUEQ7O0FBQUEsZUFRRHdJLE1BQU1KLFdBQU4sQ0FBa0J6QyxTQUFsQixDQVJDO0FBQUE7QUFBQTtBQUFBOztBQUFBLDJDQVNJLElBVEo7O0FBQUE7QUFXTDtBQUNJeEIsZ0JBWkMsV0FZT0YsT0FaUDtBQUFBO0FBQUE7QUFBQSxpQkFjMkUsK0NBQXFCakUsSUFBckIsRUFBMkJqQixXQUEzQixFQUF3QzBHLFNBQXhDLENBZDNFOztBQUFBO0FBQUE7QUFBQSwyQkFjQXRILElBZEE7QUFjMkJnRyxnQkFkM0IsYUFjT3dPLGtCQWRQO0FBY3dEMU8saUJBZHhELGFBY21DNE8sbUJBZG5DO0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGlCQWdCVSxrQkFBSSwwQkFBZSxZQUFNalUsT0FBckIsQ0FBSixDQWhCVjs7QUFBQTtBQUFBOztBQUFBO0FBa0JMO0FBQ002SCxvQkFuQkQsVUFtQm1CMUgsV0FuQm5CLFNBbUJrQ29GLE1BbkJsQztBQUFBO0FBQUEsaUJBb0JDLGtCQUFJLG1DQUF3QndCLFNBQXhCLEVBQW1DLElBQW5DLEVBQXlDYyxVQUF6QyxDQUFKLENBcEJEOztBQUFBO0FBQUEsZUF1QkQrQixNQUFNbWIsV0FBTixDQUFrQmxkLFVBQWxCLENBdkJDO0FBQUE7QUFBQTtBQUFBOztBQUFBLDJDQXdCSSxJQXhCSjs7QUFBQTtBQTBCTDtBQUNJRixvQkEzQkM7QUFBQTtBQUFBO0FBQUEsaUJBNkIyQixpREFBdUJ2RyxJQUF2QixFQUE2Qm1FLE1BQTdCLEVBQXFDcEYsV0FBckMsRUFBa0QsQ0FBbEQsQ0E3QjNCOztBQUFBO0FBQUE7QUE2Qk13SCxvQkE3Qk4sU0E2QkFwSSxJQTdCQTtBQUFBO0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxpQkErQlUsa0JBQUksMEJBQWUsWUFBTVMsT0FBckIsQ0FBSixDQS9CVjs7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQSxpQkFrQ0Msa0JBQUksc0NBQTJCNkgsVUFBM0IsRUFBdUMxSCxXQUF2QyxFQUFvRGtGLE9BQXBELEVBQTZERSxNQUE3RCxFQUFxRW9DLFVBQXJFLENBQUosQ0FsQ0Q7O0FBQUE7QUFBQTtBQUFBLGlCQW9DQyxrQkFBSSwwQkFBZSxJQUFmLENBQUosQ0FwQ0Q7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBdUNBLFNBQVc4dEIsc0JBQVg7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsaUJBQ0MseUJBQVd0MkIsUUFBUTZILG1CQUFuQixFQUF3Q3d1QixpQkFBeEMsQ0FERDs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxDQUVOOztBQUVELFNBQVdHLDRCQUFYLENBQXlDcFcsTUFBekM7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLDBCQUM2Q0EsT0FBT2hnQixJQURwRCxFQUNVc0ksVUFEVixpQkFDVUEsVUFEVixFQUNzQnBJLElBRHRCLGlCQUNzQkEsSUFEdEIsRUFDNEI4RixNQUQ1QixpQkFDNEJBLE1BRDVCLEVBQ29DdUMsSUFEcEMsaUJBQ29DQSxJQURwQztBQUFBO0FBQUEsaUJBRXFCLDBDQUZyQjs7QUFBQTtBQUVRMUcsY0FGUjtBQUdNdUcsb0JBSE47QUFBQTtBQUFBO0FBQUEsaUJBS2tDLGlEQUF1QnZHLElBQXZCLEVBQTZCbUUsTUFBN0IsRUFBcUM5RixJQUFyQyxFQUEyQ3FJLElBQTNDLENBTGxDOztBQUFBO0FBQUE7QUFLYUgsb0JBTGIsU0FLT3BJLElBTFA7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsaUJBT2lCLGtCQUFJLDBCQUFlLGFBQU1TLE9BQXJCLENBQUosQ0FQakI7O0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUEsaUJBU1Esa0JBQUksK0JBQW9CNkgsVUFBcEIsRUFBZ0NGLFVBQWhDLENBQUosQ0FUUjs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFZTyxTQUFXK3RCLHdCQUFYO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGlCQUNDLHlCQUFXdjJCLFFBQVE0SSwyQkFBbkIsRUFBZ0Q0dEIsNEJBQWhELENBREQ7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsQzs7Ozs7Ozs7Ozs7O1FDNURTN2hCLGMsR0FBQUEsYztRQU1BSSxnQixHQUFBQSxnQjs7QUFSaEI7Ozs7OztBQUVPLFNBQVNKLGNBQVQsQ0FBeUIxUyxJQUF6QixFQUErQjZGLEVBQS9CLEVBQW1DeEgsSUFBbkMsRUFBeUM7QUFDOUMsTUFBSSxDQUFDd0gsRUFBTCxFQUFTQSxLQUFLLE1BQUw7QUFDVCxNQUFNZ0MsTUFBUzdILElBQVQsMEJBQWtDM0IsSUFBbEMsU0FBMEN3SCxFQUFoRDtBQUNBLFNBQU8sdUJBQVFnQyxHQUFSLENBQVA7QUFDRDs7QUFFTSxTQUFTaUwsZ0JBQVQsQ0FBMkI5UyxJQUEzQixFQUFpQ21FLE1BQWpDLEVBQXlDOUYsSUFBekMsRUFBK0NxSSxJQUEvQyxFQUFxRDtBQUMxRCxNQUFJLENBQUNBLElBQUwsRUFBV0EsT0FBTyxDQUFQO0FBQ1gsTUFBTW1CLE1BQVM3SCxJQUFULDRCQUFvQzNCLElBQXBDLFNBQTRDOEYsTUFBNUMsU0FBc0R1QyxJQUE1RDtBQUNBLFNBQU8sdUJBQVFtQixHQUFSLENBQVA7QUFDRCxFOzs7Ozs7Ozs7OztBQ1pEbEgsT0FBT0MsT0FBUCxHQUFpQjtBQUNmZ3lCLHdCQUF3QixnQkFEVDtBQUVmQywwQkFBd0IsaUJBRlQ7QUFHZkMsa0JBQXdCLHlDQUhUO0FBSWZDLGdCQUF3QixHQUpUO0FBS2ZyQixtQkFBd0IseUJBQVVDLFVBQVYsRUFBc0I7QUFDNUMsUUFBTXFCLGtCQUFrQixJQUFJQyxNQUFKLENBQ3RCLGVBQWU7QUFDZixxQkFGc0IsQ0FFSjtBQUZJLEtBQXhCOztBQUQ0QyxnQ0FLUUQsZ0JBQWlCO0FBQWpCLEtBQ2pENWpCLElBRGlELENBQzVDdWlCLFVBRDRDLEVBRWpEL2pCLEdBRmlELENBRTdDO0FBQUEsYUFBUzJoQixTQUFTLElBQWxCO0FBQUEsS0FGNkMsQ0FMUjtBQUFBO0FBQUEsUUFLckMyRCxLQUxxQztBQUFBLFFBSzlCNTBCLEtBTDhCO0FBQUEsUUFLdkI2MEIsaUJBTHVCO0FBQUEsUUFLSm50QixRQUxJOztBQVM1Qzs7O0FBQ0EsUUFBSSxDQUFDMUgsS0FBTCxFQUFZO0FBQ1YsWUFBTSxJQUFJc0osS0FBSix3REFBK0R1ckIsaUJBQS9ELE9BQU47QUFDRDtBQUNELFFBQU0xQixZQUFZbnpCLE1BQU04MEIsVUFBTixDQUFpQnp5QixPQUFPQyxPQUFQLENBQWVteUIsWUFBaEMsQ0FBbEI7QUFDQSxRQUFNaDBCLGNBQWMweUIsWUFBWW56QixLQUFaLEdBQW9CLElBQXhDO0FBQ0EsUUFBSThILGdCQUFKO0FBQ0EsUUFBSXFyQixTQUFKLEVBQWU7QUFDYixVQUFJLENBQUMxeUIsV0FBTCxFQUFrQjtBQUNoQixjQUFNLElBQUk2SSxLQUFKLENBQVUsNkNBQVYsQ0FBTjtBQUNEO0FBQ0QsVUFBTXlyQixlQUFnQnQwQixXQUFELENBQWN3d0IsS0FBZCxDQUFvQjV1QixPQUFPQyxPQUFQLENBQWVpeUIsc0JBQW5DLENBQXJCO0FBQ0EsVUFBSVEsWUFBSixFQUFrQjtBQUNoQixjQUFNLElBQUl6ckIsS0FBSiw0REFBbUV5ckIsYUFBYUMsSUFBYixDQUFrQixJQUFsQixDQUFuRSxRQUFOO0FBQ0Q7QUFDRixLQVJELE1BUU87QUFDTGx0QixnQkFBVTlILEtBQVY7QUFDRDs7QUFFRDtBQUNBLFFBQUk0VCx1QkFBSjtBQUNBLFFBQUlpaEIsaUJBQUosRUFBdUI7QUFDckIsVUFBSSxDQUFDbnRCLFFBQUwsRUFBZTtBQUNiLGNBQU0sSUFBSTRCLEtBQUosNkRBQW9FdXJCLGlCQUFwRSxPQUFOO0FBQ0Q7O0FBRUQsVUFBSUEsc0JBQXNCLEdBQTFCLEVBQStCO0FBQzdCamhCLHlCQUFpQmxNLFFBQWpCO0FBQ0QsT0FGRCxNQUVPO0FBQ0wsY0FBTSxJQUFJNEIsS0FBSiw0QkFBbUN1ckIsaUJBQW5DLDJDQUFOO0FBQ0Q7QUFDRjtBQUNELFdBQU87QUFDTDFCLDBCQURLO0FBRUwxeUIsOEJBRks7QUFHTG1ULHNCQUFnQkEsa0JBQWtCLElBSDdCO0FBSUw5TCxlQUFnQkEsV0FBVztBQUp0QixLQUFQO0FBTUQsR0FwRGM7QUFxRGZvckIsY0FBWSxvQkFBVW56QixJQUFWLEVBQWdCO0FBQzFCLFFBQU0yMEIsa0JBQWtCLElBQUlDLE1BQUosQ0FDdEIsZ0JBQWdCO0FBQ2hCLHNCQUZzQixDQUVIO0FBRkcsS0FBeEI7O0FBRDBCLGlDQUtnQ0QsZ0JBQWdCO0FBQWhCLEtBQ3ZENWpCLElBRHVELENBQ2xEL1EsSUFEa0QsRUFFdkR1UCxHQUZ1RCxDQUVuRDtBQUFBLGFBQVMyaEIsU0FBUyxJQUFsQjtBQUFBLEtBRm1ELENBTGhDO0FBQUE7QUFBQSxRQUtuQjJELEtBTG1CO0FBQUEsUUFLWmpwQixTQUxZO0FBQUEsUUFLRHVxQixrQkFMQztBQUFBLFFBS21CMXVCLFNBTG5COztBQVMxQjs7O0FBQ0EsUUFBSSxDQUFDbUUsU0FBTCxFQUFnQjtBQUNkLFlBQU0sSUFBSXJDLEtBQUosQ0FBVSxvREFBVixDQUFOO0FBQ0Q7QUFDRCxRQUFNeXJCLGVBQWdCcHBCLFNBQUQsQ0FBWXNsQixLQUFaLENBQWtCNXVCLE9BQU9DLE9BQVAsQ0FBZWd5QixvQkFBakMsQ0FBckI7QUFDQSxRQUFJUyxZQUFKLEVBQWtCO0FBQ2hCLFlBQU0sSUFBSXpyQixLQUFKLDBEQUFpRXlyQixhQUFhQyxJQUFiLENBQWtCLElBQWxCLENBQWpFLFFBQU47QUFDRDtBQUNEO0FBQ0EsUUFBSWtCLGtCQUFKLEVBQXdCO0FBQ3RCLFVBQUksQ0FBQzF1QixTQUFMLEVBQWdCO0FBQ2QsY0FBTSxJQUFJOEIsS0FBSixtRUFBMEU0c0Isa0JBQTFFLFFBQU47QUFDRDtBQUNELFVBQUlBLHVCQUF1QixHQUEzQixFQUFnQztBQUM5QixjQUFNLElBQUk1c0IsS0FBSiw0QkFBbUM0c0Isa0JBQW5DLHFEQUFOO0FBQ0Q7QUFDRjtBQUNELFdBQU87QUFDTHZxQiwwQkFESztBQUVMbkUsaUJBQVdBLGFBQWE7QUFGbkIsS0FBUDtBQUlEO0FBbkZjLENBQWpCLEM7Ozs7Ozs7OztBQ0FBLElBQU1xZCxtQkFBbUIsbUJBQUFyaUIsQ0FBUSxFQUFSLENBQXpCOztBQUVBSCxPQUFPQyxPQUFQLEdBQWlCLGVBQU87QUFDdEI7QUFDQTBWLE1BQUlFLEdBQUosQ0FBUSxHQUFSLEVBQWEsVUFBQ3BELEdBQUQsRUFBTS9CLEdBQU4sRUFBYztBQUN6QjtBQUNBOFIscUJBQWlCL1AsR0FBakIsRUFBc0IvQixHQUF0QjtBQUNELEdBSEQ7QUFJRCxDQU5ELEMiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCIvXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gNDUpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHdlYnBhY2svYm9vdHN0cmFwIGZkYmJiYjI3MDM0NDk4Y2QyMDQ3IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3RcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdFwiXG4vLyBtb2R1bGUgaWQgPSAwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LXJlZHV4XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVhY3QtcmVkdXhcIlxuLy8gbW9kdWxlIGlkID0gMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ3aW5zdG9uXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwid2luc3RvblwiXG4vLyBtb2R1bGUgaWQgPSAyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LXJvdXRlci1kb21cIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdC1yb3V0ZXItZG9tXCJcbi8vIG1vZHVsZSBpZCA9IDNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMnO1xuXG4vLyBleHBvcnQgYWN0aW9uIGNyZWF0b3JzXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0RmlsZSAoZmlsZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuRklMRV9TRUxFQ1RFRCxcbiAgICBkYXRhOiBmaWxlLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyRmlsZSAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5GSUxFX0NMRUFSLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZU1ldGFkYXRhIChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuTUVUQURBVEFfVVBEQVRFLFxuICAgIGRhdGE6IHtcbiAgICAgIG5hbWUsXG4gICAgICB2YWx1ZSxcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUNsYWltICh2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0xBSU1fVVBEQVRFLFxuICAgIGRhdGE6IHZhbHVlLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldFB1Ymxpc2hJbkNoYW5uZWwgKGNoYW5uZWwpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlNFVF9QVUJMSVNIX0lOX0NIQU5ORUwsXG4gICAgY2hhbm5lbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVQdWJsaXNoU3RhdHVzIChzdGF0dXMsIG1lc3NhZ2UpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlBVQkxJU0hfU1RBVFVTX1VQREFURSxcbiAgICBkYXRhOiB7XG4gICAgICBzdGF0dXMsXG4gICAgICBtZXNzYWdlLFxuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlRXJyb3IgKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5FUlJPUl9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgbmFtZSxcbiAgICAgIHZhbHVlLFxuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU2VsZWN0ZWRDaGFubmVsIChjaGFubmVsTmFtZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuU0VMRUNURURfQ0hBTk5FTF9VUERBVEUsXG4gICAgZGF0YTogY2hhbm5lbE5hbWUsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdG9nZ2xlTWV0YWRhdGFJbnB1dHMgKHNob3dNZXRhZGF0YUlucHV0cykge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuVE9HR0xFX01FVEFEQVRBX0lOUFVUUyxcbiAgICBkYXRhOiBzaG93TWV0YWRhdGFJbnB1dHMsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gb25OZXdUaHVtYm5haWwgKGZpbGUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlRIVU1CTkFJTF9ORVcsXG4gICAgZGF0YTogZmlsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGFydFB1Ymxpc2ggKGhpc3RvcnkpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlBVQkxJU0hfU1RBUlQsXG4gICAgZGF0YTogeyBoaXN0b3J5IH0sXG4gIH07XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvYWN0aW9ucy9wdWJsaXNoLmpzIiwiZnVuY3Rpb24gU2l0ZUNvbmZpZyAoKSB7XG4gIHRoaXMuYW5hbHl0aWNzID0ge1xuICAgIGdvb2dsZUlkOiAnZGVmYXVsdCcsXG4gIH07XG4gIHRoaXMuYXNzZXREZWZhdWx0cyA9IHtcbiAgICBkZXNjcmlwdGlvbjogJ0FuIGFzc2V0IHB1Ymxpc2hlZCBvbiBTcGVlLmNoJyxcbiAgICB0aHVtYm5haWwgIDogJ2h0dHBzOi8vc3BlZS5jaC9hc3NldHMvaW1nL3ZpZGVvX3RodW1iX2RlZmF1bHQucG5nJyxcbiAgICB0aXRsZSAgICAgIDogJ1NwZWUuY2gnLFxuICB9O1xuICB0aGlzLmF1dGggPSB7XG4gICAgc2Vzc2lvbktleTogJ2RlZmF1bHQnLFxuICB9O1xuICB0aGlzLmRldGFpbHMgPSB7XG4gICAgZGVzY3JpcHRpb246ICdPcGVuLXNvdXJjZSwgZGVjZW50cmFsaXplZCBpbWFnZSBhbmQgdmlkZW8gc2hhcmluZy4nLFxuICAgIGhvc3QgICAgICAgOiAnZGVmYXVsdCcsXG4gICAgcG9ydCAgICAgICA6IDMwMDAsXG4gICAgdGl0bGUgICAgICA6ICdTcGVlLmNoJyxcbiAgICB0d2l0dGVyICAgIDogJ0BzcGVlX2NoJyxcbiAgfTtcbiAgdGhpcy5wdWJsaXNoaW5nID0ge1xuICAgIGFkZGl0aW9uYWxDbGFpbUFkZHJlc3NlczogW10sXG4gICAgZGlzYWJsZWQgICAgICAgICAgICAgICAgOiBmYWxzZSxcbiAgICBkaXNhYmxlZE1lc3NhZ2UgICAgICAgICA6ICdQbGVhc2UgY2hlY2sgYmFjayBzb29uLicsXG4gICAgcHJpbWFyeUNsYWltQWRkcmVzcyAgICAgOiAnZGVmYXVsdCcsXG4gICAgdGh1bWJuYWlsQ2hhbm5lbCAgICAgICAgOiAnZGVmYXVsdCcsXG4gICAgdGh1bWJuYWlsQ2hhbm5lbElkICAgICAgOiAnZGVmYXVsdCcsXG4gICAgdXBsb2FkRGlyZWN0b3J5ICAgICAgICAgOiAnL2hvbWUvbGJyeS9VcGxvYWRzJyxcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNpdGVDb25maWcoKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NvbmZpZy9zaXRlQ29uZmlnLmpzIiwiY29uc3QgU2VxdWVsaXplID0gcmVxdWlyZSgnc2VxdWVsaXplJyk7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbmNvbnNvbGUubG9nKCdleHBvcnRpbmcgc2VxdWVsaXplIG1vZGVscycpO1xuY29uc3QgeyBkYXRhYmFzZSwgdXNlcm5hbWUsIHBhc3N3b3JkIH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvbXlzcWxDb25maWcnKTtcbmNvbnN0IGRiID0ge307XG4vLyBzZXQgc2VxdWVsaXplIG9wdGlvbnNcbmNvbnN0IHNlcXVlbGl6ZSA9IG5ldyBTZXF1ZWxpemUoZGF0YWJhc2UsIHVzZXJuYW1lLCBwYXNzd29yZCwge1xuICBob3N0ICAgICAgICAgIDogJ2xvY2FsaG9zdCcsXG4gIGRpYWxlY3QgICAgICAgOiAnbXlzcWwnLFxuICBkaWFsZWN0T3B0aW9uczoge2RlY2ltYWxOdW1iZXJzOiB0cnVlfSwgLy8gZml4IHRvIGVuc3VyZSBERUNJTUFMIHdpbGwgbm90IGJlIHN0b3JlZCBhcyBhIHN0cmluZ1xuICBsb2dnaW5nICAgICAgIDogZmFsc2UsXG4gIHBvb2wgICAgICAgICAgOiB7XG4gICAgbWF4ICAgIDogNSxcbiAgICBtaW4gICAgOiAwLFxuICAgIGlkbGUgICA6IDEwMDAwLFxuICAgIGFjcXVpcmU6IDEwMDAwLFxuICB9LFxufSk7XG5cbi8vIGVzdGFibGlzaCBteXNxbCBjb25uZWN0aW9uXG5zZXF1ZWxpemVcbiAgLmF1dGhlbnRpY2F0ZSgpXG4gIC50aGVuKCgpID0+IHtcbiAgICBsb2dnZXIuaW5mbygnU2VxdWVsaXplIGhhcyBlc3RhYmxpc2hlZCBteXNxbCBjb25uZWN0aW9uIHN1Y2Nlc3NmdWxseS4nKTtcbiAgfSlcbiAgLmNhdGNoKGVyciA9PiB7XG4gICAgbG9nZ2VyLmVycm9yKCdTZXF1ZWxpemUgd2FzIHVuYWJsZSB0byBjb25uZWN0IHRvIHRoZSBkYXRhYmFzZTonLCBlcnIpO1xuICB9KTtcblxuLy8gbWFudWFsbHkgYWRkIGVhY2ggbW9kZWwgdG8gdGhlIGRiIG9iamVjdFxuY29uc3QgQ2VydGlmaWNhdGUgPSByZXF1aXJlKCcuL2NlcnRpZmljYXRlLmpzJyk7XG5jb25zdCBDaGFubmVsID0gcmVxdWlyZSgnLi9jaGFubmVsLmpzJyk7XG5jb25zdCBDbGFpbSA9IHJlcXVpcmUoJy4vY2xhaW0uanMnKTtcbmNvbnN0IEZpbGUgPSByZXF1aXJlKCcuL2ZpbGUuanMnKTtcbmNvbnN0IFJlcXVlc3QgPSByZXF1aXJlKCcuL3JlcXVlc3QuanMnKTtcbmNvbnN0IFVzZXIgPSByZXF1aXJlKCcuL3VzZXIuanMnKTtcbmRiWydDZXJ0aWZpY2F0ZSddID0gc2VxdWVsaXplLmltcG9ydCgnQ2VydGlmaWNhdGUnLCBDZXJ0aWZpY2F0ZSk7XG5kYlsnQ2hhbm5lbCddID0gc2VxdWVsaXplLmltcG9ydCgnQ2hhbm5lbCcsIENoYW5uZWwpO1xuZGJbJ0NsYWltJ10gPSBzZXF1ZWxpemUuaW1wb3J0KCdDbGFpbScsIENsYWltKTtcbmRiWydGaWxlJ10gPSBzZXF1ZWxpemUuaW1wb3J0KCdGaWxlJywgRmlsZSk7XG5kYlsnUmVxdWVzdCddID0gc2VxdWVsaXplLmltcG9ydCgnUmVxdWVzdCcsIFJlcXVlc3QpO1xuZGJbJ1VzZXInXSA9IHNlcXVlbGl6ZS5pbXBvcnQoJ1VzZXInLCBVc2VyKTtcblxuLy8gcnVuIG1vZGVsLmFzc29jaWF0aW9uIGZvciBlYWNoIG1vZGVsIGluIHRoZSBkYiBvYmplY3QgdGhhdCBoYXMgYW4gYXNzb2NpYXRpb25cbk9iamVjdC5rZXlzKGRiKS5mb3JFYWNoKG1vZGVsTmFtZSA9PiB7XG4gIGlmIChkYlttb2RlbE5hbWVdLmFzc29jaWF0ZSkge1xuICAgIGxvZ2dlci5pbmZvKCdBc3NvY2lhdGluZyBtb2RlbDonLCBtb2RlbE5hbWUpO1xuICAgIGRiW21vZGVsTmFtZV0uYXNzb2NpYXRlKGRiKTtcbiAgfVxufSk7XG5cbmRiLnNlcXVlbGl6ZSA9IHNlcXVlbGl6ZTtcbmRiLlNlcXVlbGl6ZSA9IFNlcXVlbGl6ZTtcblxuLy8gYWRkIGFuICd1cHNlcnQnIG1ldGhvZCB0byB0aGUgZGIgb2JqZWN0XG5kYi51cHNlcnQgPSAoTW9kZWwsIHZhbHVlcywgY29uZGl0aW9uLCB0YWJsZU5hbWUpID0+IHtcbiAgcmV0dXJuIE1vZGVsXG4gICAgLmZpbmRPbmUoe1xuICAgICAgd2hlcmU6IGNvbmRpdGlvbixcbiAgICB9KVxuICAgIC50aGVuKG9iaiA9PiB7XG4gICAgICBpZiAob2JqKSB7ICAvLyB1cGRhdGVcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGB1cGRhdGluZyByZWNvcmQgaW4gZGIuJHt0YWJsZU5hbWV9YCk7XG4gICAgICAgIHJldHVybiBvYmoudXBkYXRlKHZhbHVlcyk7XG4gICAgICB9IGVsc2UgeyAgLy8gaW5zZXJ0XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY3JlYXRpbmcgcmVjb3JkIGluIGRiLiR7dGFibGVOYW1lfWApO1xuICAgICAgICByZXR1cm4gTW9kZWwuY3JlYXRlKHZhbHVlcyk7XG4gICAgICB9XG4gICAgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYCR7dGFibGVOYW1lfS51cHNlcnQgZXJyb3JgLCBlcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZGI7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2luZGV4LmpzIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbCB9IGZyb20gJ2FjdGlvbnMvY2hhbm5lbCc7XG5pbXBvcnQge3VwZGF0ZVNlbGVjdGVkQ2hhbm5lbH0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IGNoYW5uZWwsIHNpdGUgfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGNoYW5uZWxOYW1lICAgOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5uYW1lLFxuICAgIGNoYW5uZWxTaG9ydElkOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5zaG9ydElkLFxuICAgIGNoYW5uZWxMb25nSWQgOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5sb25nSWQsXG4gICAgc2l0ZURlc2NyaXB0aW9uOiBzaXRlLmRlc2NyaXB0aW9uLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2hhbm5lbExvZ2luOiAobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVTZWxlY3RlZENoYW5uZWwobmFtZSkpO1xuICAgIH0sXG4gICAgb25DaGFubmVsTG9nb3V0OiAoKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobnVsbCwgbnVsbCwgbnVsbCkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL05hdkJhci9pbmRleC5qcyIsImltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL3Nob3dfYWN0aW9uX3R5cGVzJztcblxuaW1wb3J0IHsgQ0hBTk5FTCwgQVNTRVRfTElURSwgQVNTRVRfREVUQUlMUyB9IGZyb20gJ2NvbnN0YW50cy9zaG93X3JlcXVlc3RfdHlwZXMnO1xuXG4vLyBiYXNpYyByZXF1ZXN0IHBhcnNpbmdcbmV4cG9ydCBmdW5jdGlvbiBvbkhhbmRsZVNob3dQYWdlVXJpIChwYXJhbXMpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkhBTkRMRV9TSE9XX1VSSSxcbiAgICBkYXRhOiBwYXJhbXMsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gb25SZXF1ZXN0RXJyb3IgKGVycm9yKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5SRVFVRVNUX0VSUk9SLFxuICAgIGRhdGE6IGVycm9yLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uTmV3Q2hhbm5lbFJlcXVlc3QgKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQpIHtcbiAgY29uc3QgcmVxdWVzdFR5cGUgPSBDSEFOTkVMO1xuICBjb25zdCByZXF1ZXN0SWQgPSBgY3IjJHtjaGFubmVsTmFtZX0jJHtjaGFubmVsSWR9YDtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkNIQU5ORUxfUkVRVUVTVF9ORVcsXG4gICAgZGF0YTogeyByZXF1ZXN0VHlwZSwgcmVxdWVzdElkLCBjaGFubmVsTmFtZSwgY2hhbm5lbElkIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gb25OZXdBc3NldFJlcXVlc3QgKG5hbWUsIGlkLCBjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBleHRlbnNpb24pIHtcbiAgY29uc3QgcmVxdWVzdFR5cGUgPSBleHRlbnNpb24gPyBBU1NFVF9MSVRFIDogQVNTRVRfREVUQUlMUztcbiAgY29uc3QgcmVxdWVzdElkID0gYGFyIyR7bmFtZX0jJHtpZH0jJHtjaGFubmVsTmFtZX0jJHtjaGFubmVsSWR9YDtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkFTU0VUX1JFUVVFU1RfTkVXLFxuICAgIGRhdGE6IHtcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgcmVxdWVzdElkLFxuICAgICAgbmFtZSxcbiAgICAgIG1vZGlmaWVyOiB7XG4gICAgICAgIGlkLFxuICAgICAgICBjaGFubmVsOiB7XG4gICAgICAgICAgbmFtZTogY2hhbm5lbE5hbWUsXG4gICAgICAgICAgaWQgIDogY2hhbm5lbElkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uUmVxdWVzdFVwZGF0ZSAocmVxdWVzdFR5cGUsIHJlcXVlc3RJZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuUkVRVUVTVF9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgcmVxdWVzdFR5cGUsXG4gICAgICByZXF1ZXN0SWQsXG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdCAoaWQsIGVycm9yLCBrZXkpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlJFUVVFU1RfTElTVF9BREQsXG4gICAgZGF0YTogeyBpZCwgZXJyb3IsIGtleSB9LFxuICB9O1xufTtcblxuLy8gYXNzZXQgYWN0aW9uc1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkQXNzZXRUb0Fzc2V0TGlzdCAoaWQsIGVycm9yLCBuYW1lLCBjbGFpbUlkLCBzaG9ydElkLCBjbGFpbURhdGEpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkFTU0VUX0FERCxcbiAgICBkYXRhOiB7IGlkLCBlcnJvciwgbmFtZSwgY2xhaW1JZCwgc2hvcnRJZCwgY2xhaW1EYXRhIH0sXG4gIH07XG59XG5cbi8vIGNoYW5uZWwgYWN0aW9uc1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkTmV3Q2hhbm5lbFRvQ2hhbm5lbExpc3QgKGlkLCBuYW1lLCBzaG9ydElkLCBsb25nSWQsIGNsYWltc0RhdGEpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkNIQU5ORUxfQURELFxuICAgIGRhdGE6IHsgaWQsIG5hbWUsIHNob3J0SWQsIGxvbmdJZCwgY2xhaW1zRGF0YSB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uVXBkYXRlQ2hhbm5lbENsYWltcyAoY2hhbm5lbEtleSwgbmFtZSwgbG9uZ0lkLCBwYWdlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5DSEFOTkVMX0NMQUlNU19VUERBVEVfQVNZTkMsXG4gICAgZGF0YToge2NoYW5uZWxLZXksIG5hbWUsIGxvbmdJZCwgcGFnZX0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQ2hhbm5lbENsYWltcyAoY2hhbm5lbExpc3RJZCwgY2xhaW1zRGF0YSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MsXG4gICAgZGF0YToge2NoYW5uZWxMaXN0SWQsIGNsYWltc0RhdGF9LFxuICB9O1xufTtcblxuLy8gZGlzcGxheSBhIGZpbGVcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbGVSZXF1ZXN0ZWQgKG5hbWUsIGNsYWltSWQpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkZJTEVfUkVRVUVTVEVELFxuICAgIGRhdGE6IHsgbmFtZSwgY2xhaW1JZCB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUZpbGVBdmFpbGFiaWxpdHkgKHN0YXR1cykge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuRklMRV9BVkFJTEFCSUxJVFlfVVBEQVRFLFxuICAgIGRhdGE6IHN0YXR1cyxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVEaXNwbGF5QXNzZXRFcnJvciAoZXJyb3IpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkRJU1BMQVlfQVNTRVRfRVJST1IsXG4gICAgZGF0YTogZXJyb3IsXG4gIH07XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2FjdGlvbnMvc2hvdy5qcyIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaXRlIH0pID0+IHtcbiAgY29uc3QgeyBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwsIGRlc2NyaXB0aW9uOiBzaXRlRGVzY3JpcHRpb24sIGhvc3Q6IHNpdGVIb3N0LCB0aXRsZTogc2l0ZVRpdGxlLCB0d2l0dGVyOiBzaXRlVHdpdHRlciB9ID0gc2l0ZTtcbiAgcmV0dXJuIHtcbiAgICBkZWZhdWx0RGVzY3JpcHRpb24sXG4gICAgZGVmYXVsdFRodW1ibmFpbCxcbiAgICBzaXRlRGVzY3JpcHRpb24sXG4gICAgc2l0ZUhvc3QsXG4gICAgc2l0ZVRpdGxlLFxuICAgIHNpdGVUd2l0dGVyLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvU0VPL2luZGV4LmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicHJvcC10eXBlc1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInByb3AtdHlwZXNcIlxuLy8gbW9kdWxlIGlkID0gMTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0ICdjcm9zcy1mZXRjaC9wb2x5ZmlsbCc7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBKU09OIHJldHVybmVkIGJ5IGEgbmV0d29yayByZXF1ZXN0XG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSByZXNwb25zZSBBIHJlc3BvbnNlIGZyb20gYSBuZXR3b3JrIHJlcXVlc3RcbiAqXG4gKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgIFRoZSBwYXJzZWQgSlNPTiBmcm9tIHRoZSByZXF1ZXN0XG4gKi9cbmZ1bmN0aW9uIHBhcnNlSlNPTiAocmVzcG9uc2UpIHtcbiAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA0IHx8IHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA1KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbn1cblxuLyoqXG4gKiBQYXJzZXMgdGhlIHN0YXR1cyByZXR1cm5lZCBieSBhIG5ldHdvcmsgcmVxdWVzdFxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gcmVzcG9uc2UgICBBIHJlc3BvbnNlIGZyb20gYSBuZXR3b3JrIHJlcXVlc3RcbiAqIEBwYXJhbSAge29iamVjdH0gcmVzcG9uc2UgICBUaGUgcGFyc2VkIEpTT04gZnJvbSB0aGUgbmV0d29yayByZXF1ZXN0XG4gKlxuICogQHJldHVybiB7b2JqZWN0IHwgdW5kZWZpbmVkfSBSZXR1cm5zIG9iamVjdCB3aXRoIHN0YXR1cyBhbmQgc3RhdHVzVGV4dCwgb3IgdW5kZWZpbmVkXG4gKi9cbmZ1bmN0aW9uIGNoZWNrU3RhdHVzIChyZXNwb25zZSwganNvblJlc3BvbnNlKSB7XG4gIGlmIChyZXNwb25zZS5zdGF0dXMgPj0gMjAwICYmIHJlc3BvbnNlLnN0YXR1cyA8IDMwMCkge1xuICAgIHJldHVybiBqc29uUmVzcG9uc2U7XG4gIH1cbiAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoanNvblJlc3BvbnNlLm1lc3NhZ2UpO1xuICBlcnJvci5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICB0aHJvdyBlcnJvcjtcbn1cblxuLyoqXG4gKiBSZXF1ZXN0cyBhIFVSTCwgcmV0dXJuaW5nIGEgcHJvbWlzZVxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gdXJsICAgICAgIFRoZSBVUkwgd2Ugd2FudCB0byByZXF1ZXN0XG4gKiBAcGFyYW0gIHtvYmplY3R9IFtvcHRpb25zXSBUaGUgb3B0aW9ucyB3ZSB3YW50IHRvIHBhc3MgdG8gXCJmZXRjaFwiXG4gKlxuICogQHJldHVybiB7b2JqZWN0fSAgICAgICAgICAgVGhlIHJlc3BvbnNlIGRhdGFcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZXF1ZXN0ICh1cmwsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGZldGNoKHVybCwgb3B0aW9ucylcbiAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3Jlc3BvbnNlLCBwYXJzZUpTT04ocmVzcG9uc2UpXSk7XG4gICAgfSlcbiAgICAudGhlbigoW3Jlc3BvbnNlLCBqc29uUmVzcG9uc2VdKSA9PiB7XG4gICAgICByZXR1cm4gY2hlY2tTdGF0dXMocmVzcG9uc2UsIGpzb25SZXNwb25zZSk7XG4gICAgfSk7XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvcmVxdWVzdC5qcyIsIi8vIHJlcXVlc3QgYWN0aW9uc1xuZXhwb3J0IGNvbnN0IEhBTkRMRV9TSE9XX1VSSSA9ICdIQU5ETEVfU0hPV19VUkknO1xuZXhwb3J0IGNvbnN0IFJFUVVFU1RfRVJST1IgPSAnUkVRVUVTVF9FUlJPUic7XG5leHBvcnQgY29uc3QgUkVRVUVTVF9VUERBVEUgPSAnUkVRVUVTVF9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IEFTU0VUX1JFUVVFU1RfTkVXID0gJ0FTU0VUX1JFUVVFU1RfTkVXJztcbmV4cG9ydCBjb25zdCBDSEFOTkVMX1JFUVVFU1RfTkVXID0gJ0NIQU5ORUxfUkVRVUVTVF9ORVcnO1xuZXhwb3J0IGNvbnN0IFJFUVVFU1RfTElTVF9BREQgPSAnUkVRVUVTVF9MSVNUX0FERCc7XG5cbi8vIGFzc2V0IGFjdGlvbnNcbmV4cG9ydCBjb25zdCBBU1NFVF9BREQgPSBgQVNTRVRfQUREYDtcblxuLy8gY2hhbm5lbCBhY3Rpb25zXG5leHBvcnQgY29uc3QgQ0hBTk5FTF9BREQgPSAnQ0hBTk5FTF9BREQnO1xuXG5leHBvcnQgY29uc3QgQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DID0gJ0NIQU5ORUxfQ0xBSU1TX1VQREFURV9BU1lOQyc7XG5leHBvcnQgY29uc3QgQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MgPSAnQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MnO1xuXG4vLyBhc3NldC9maWxlIGRpc3BsYXkgYWN0aW9uc1xuZXhwb3J0IGNvbnN0IEZJTEVfUkVRVUVTVEVEID0gJ0ZJTEVfUkVRVUVTVEVEJztcbmV4cG9ydCBjb25zdCBGSUxFX0FWQUlMQUJJTElUWV9VUERBVEUgPSAnRklMRV9BVkFJTEFCSUxJVFlfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBESVNQTEFZX0FTU0VUX0VSUk9SID0gJ0RJU1BMQVlfQVNTRVRfRVJST1InO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcy5qcyIsImV4cG9ydCBjb25zdCBzZWxlY3RBc3NldCA9IChzaG93KSA9PiB7XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3Nob3cucmVxdWVzdC5pZF07XG4gIGNvbnN0IGFzc2V0S2V5ID0gcmVxdWVzdC5rZXk7XG4gIHJldHVybiBzaG93LmFzc2V0TGlzdFthc3NldEtleV07XG59O1xuXG5leHBvcnQgY29uc3Qgc2VsZWN0U2hvd1N0YXRlID0gKHN0YXRlKSA9PiB7XG4gIHJldHVybiBzdGF0ZS5zaG93O1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9zZWxlY3RvcnMvc2hvdy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LWhlbG1ldFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWhlbG1ldFwiXG4vLyBtb2R1bGUgaWQgPSAxNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWR1eC1zYWdhL2VmZmVjdHNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWR1eC1zYWdhL2VmZmVjdHNcIlxuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgYXhpb3MgPSByZXF1aXJlKCdheGlvcycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyBhcGk6IHsgYXBpSG9zdCwgYXBpUG9ydCB9IH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvbGJyeUNvbmZpZy5qcycpO1xuY29uc3QgbGJyeUFwaVVyaSA9ICdodHRwOi8vJyArIGFwaUhvc3QgKyAnOicgKyBhcGlQb3J0O1xuY29uc3QgeyBjaG9vc2VHYUxicnluZXRQdWJsaXNoTGFiZWwsIHNlbmRHQVRpbWluZ0V2ZW50IH0gPSByZXF1aXJlKCcuL2dvb2dsZUFuYWx5dGljcy5qcycpO1xuXG5jb25zdCBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UgPSAoeyBkYXRhIH0sIHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICBsb2dnZXIuZGVidWcoJ2xicnkgYXBpIGRhdGE6JywgZGF0YSk7XG4gIGlmIChkYXRhLnJlc3VsdCkge1xuICAgIC8vIGNoZWNrIGZvciBhbiBlcnJvclxuICAgIGlmIChkYXRhLnJlc3VsdC5lcnJvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdMYnJ5bmV0IGFwaSBlcnJvcjonLCBkYXRhLnJlc3VsdC5lcnJvcik7XG4gICAgICByZWplY3QobmV3IEVycm9yKGRhdGEucmVzdWx0LmVycm9yKSk7XG4gICAgICByZXR1cm47XG4gICAgfTtcbiAgICByZXNvbHZlKGRhdGEucmVzdWx0KTtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gZmFsbGJhY2sgaW4gY2FzZSBpdCBqdXN0IHRpbWVkIG91dFxuICByZWplY3QoSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHB1Ymxpc2hDbGFpbSAocHVibGlzaFBhcmFtcykge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBQdWJsaXNoaW5nIGNsYWltIHRvIFwiJHtwdWJsaXNoUGFyYW1zLm5hbWV9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdwdWJsaXNoJyxcbiAgICAgICAgICBwYXJhbXM6IHB1Ymxpc2hQYXJhbXMsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdwdWJsaXNoJywgY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsKHB1Ymxpc2hQYXJhbXMpLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDbGFpbSAodXJpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBsYnJ5QXBpID4+IEdldHRpbmcgQ2xhaW0gZm9yIFwiJHt1cml9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdnZXQnLFxuICAgICAgICAgIHBhcmFtczogeyB1cmksIHRpbWVvdXQ6IDIwIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdnZXRDbGFpbScsICdHRVQnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDbGFpbUxpc3QgKGNsYWltTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBHZXR0aW5nIGNsYWltX2xpc3QgZm9yIFwiJHtjbGFpbU5hbWV9XCJgKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdjbGFpbV9saXN0JyxcbiAgICAgICAgICBwYXJhbXM6IHsgbmFtZTogY2xhaW1OYW1lIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdnZXRDbGFpbUxpc3QnLCAnQ0xBSU1fTElTVCcsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgICAgICBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UocmVzcG9uc2UsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIHJlc29sdmVVcmkgKHVyaSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBSZXNvbHZpbmcgVVJJIGZvciBcIiR7dXJpfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAncmVzb2x2ZScsXG4gICAgICAgICAgcGFyYW1zOiB7IHVyaSB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbigoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnbGJyeW5ldCcsICdyZXNvbHZlVXJpJywgJ1JFU09MVkUnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaWYgKGRhdGEucmVzdWx0W3VyaV0uZXJyb3IpIHsgIC8vIGNoZWNrIGZvciBlcnJvcnNcbiAgICAgICAgICAgIHJlamVjdChkYXRhLnJlc3VsdFt1cmldLmVycm9yKTtcbiAgICAgICAgICB9IGVsc2UgeyAgLy8gaWYgbm8gZXJyb3JzLCByZXNvbHZlXG4gICAgICAgICAgICByZXNvbHZlKGRhdGEucmVzdWx0W3VyaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0RG93bmxvYWREaXJlY3RvcnkgKCkge1xuICAgIGxvZ2dlci5kZWJ1ZygnbGJyeUFwaSA+PiBSZXRyaWV2aW5nIHRoZSBkb3dubG9hZCBkaXJlY3RvcnkgcGF0aCBmcm9tIGxicnkgZGFlbW9uLi4uJyk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnc2V0dGluZ3NfZ2V0JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHsgZGF0YSB9KSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnZ2V0RG93bmxvYWREaXJlY3RvcnknLCAnU0VUVElOR1NfR0VUJywgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGlmIChkYXRhLnJlc3VsdCkge1xuICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnJlc3VsdC5kb3dubG9hZF9kaXJlY3RvcnkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKCdTdWNjZXNzZnVsbHkgY29ubmVjdGVkIHRvIGxicnkgZGFlbW9uLCBidXQgdW5hYmxlIHRvIHJldHJpZXZlIHRoZSBkb3dubG9hZCBkaXJlY3RvcnkuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignTGJyeW5ldCBFcnJvcjonLCBlcnJvcik7XG4gICAgICAgICAgcmVzb2x2ZSgnL2hvbWUvbGJyeS9Eb3dubG9hZHMvJyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBjcmVhdGVDaGFubmVsIChuYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBsYnJ5QXBpID4+IENyZWF0aW5nIGNoYW5uZWwgZm9yICR7bmFtZX0uLi5gKTtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF4aW9zXG4gICAgICAgIC5wb3N0KGxicnlBcGlVcmksIHtcbiAgICAgICAgICBtZXRob2Q6ICdjaGFubmVsX25ldycsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBjaGFubmVsX25hbWU6IG5hbWUsXG4gICAgICAgICAgICBhbW91bnQgICAgICA6IDAuMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnY3JlYXRlQ2hhbm5lbCcsICdDSEFOTkVMX05FVycsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgICAgICBoYW5kbGVMYnJ5bmV0UmVzcG9uc2UocmVzcG9uc2UsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvbGJyeUFwaS5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHVhID0gcmVxdWlyZSgndW5pdmVyc2FsLWFuYWx5dGljcycpO1xuY29uc3QgeyBhbmFseXRpY3MgOiB7IGdvb2dsZUlkIH0sIGRldGFpbHM6IHsgdGl0bGUgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxuZnVuY3Rpb24gY3JlYXRlU2VydmVFdmVudFBhcmFtcyAoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKSB7XG4gIHJldHVybiB7XG4gICAgZXZlbnRDYXRlZ29yeSAgICA6ICdjbGllbnQgcmVxdWVzdHMnLFxuICAgIGV2ZW50QWN0aW9uICAgICAgOiAnc2VydmUgcmVxdWVzdCcsXG4gICAgZXZlbnRMYWJlbCAgICAgICA6IG9yaWdpbmFsVXJsLFxuICAgIGlwT3ZlcnJpZGUgICAgICAgOiBpcCxcbiAgICB1c2VyQWdlbnRPdmVycmlkZTogaGVhZGVyc1sndXNlci1hZ2VudCddLFxuICB9O1xufTtcblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaFRpbWluZ0V2ZW50UGFyYW1zIChjYXRlZ29yeSwgdmFyaWFibGUsIGxhYmVsLCBzdGFydFRpbWUsIGVuZFRpbWUpIHtcbiAgY29uc3QgZHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lO1xuICByZXR1cm4ge1xuICAgIHVzZXJUaW1pbmdDYXRlZ29yeSAgICA6IGNhdGVnb3J5LFxuICAgIHVzZXJUaW1pbmdWYXJpYWJsZU5hbWU6IHZhcmlhYmxlLFxuICAgIHVzZXJUaW1pbmdUaW1lICAgICAgICA6IGR1cmF0aW9uLFxuICAgIHVzZXJUaW1pbmdMYWJlbCAgICAgICA6IGxhYmVsLFxuICB9O1xufTtcblxuZnVuY3Rpb24gc2VuZEdvb2dsZUFuYWx5dGljc0V2ZW50IChpcCwgcGFyYW1zKSB7XG4gIGNvbnN0IHZpc2l0b3JJZCA9IGlwLnJlcGxhY2UoL1xcLi9nLCAnLScpO1xuICBjb25zdCB2aXNpdG9yID0gdWEoZ29vZ2xlSWQsIHZpc2l0b3JJZCwgeyBzdHJpY3RDaWRGb3JtYXQ6IGZhbHNlLCBodHRwczogdHJ1ZSB9KTtcbiAgdmlzaXRvci5ldmVudChwYXJhbXMsIChlcnIpID0+IHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0dvb2dsZSBBbmFseXRpY3MgRXZlbnQgRXJyb3IgPj4nLCBlcnIpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBzZW5kR29vZ2xlQW5hbHl0aWNzVGltaW5nICh2aXNpdG9ySWQsIHBhcmFtcykge1xuICBjb25zdCB2aXNpdG9yID0gdWEoZ29vZ2xlSWQsIHZpc2l0b3JJZCwgeyBzdHJpY3RDaWRGb3JtYXQ6IGZhbHNlLCBodHRwczogdHJ1ZSB9KTtcbiAgdmlzaXRvci50aW1pbmcocGFyYW1zLCAoZXJyKSA9PiB7XG4gICAgaWYgKGVycikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdHb29nbGUgQW5hbHl0aWNzIEV2ZW50IEVycm9yID4+JywgZXJyKTtcbiAgICB9XG4gICAgbG9nZ2VyLmRlYnVnKGBUaW1pbmcgZXZlbnQgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gZ29vZ2xlIGFuYWx5dGljc2ApO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZW5kR0FTZXJ2ZUV2ZW50IChoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBjcmVhdGVTZXJ2ZUV2ZW50UGFyYW1zKGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCk7XG4gICAgc2VuZEdvb2dsZUFuYWx5dGljc0V2ZW50KGlwLCBwYXJhbXMpO1xuICB9LFxuICBzZW5kR0FUaW1pbmdFdmVudCAoY2F0ZWdvcnksIHZhcmlhYmxlLCBsYWJlbCwgc3RhcnRUaW1lLCBlbmRUaW1lKSB7XG4gICAgY29uc3QgcGFyYW1zID0gY3JlYXRlUHVibGlzaFRpbWluZ0V2ZW50UGFyYW1zKGNhdGVnb3J5LCB2YXJpYWJsZSwgbGFiZWwsIHN0YXJ0VGltZSwgZW5kVGltZSk7XG4gICAgc2VuZEdvb2dsZUFuYWx5dGljc1RpbWluZyh0aXRsZSwgcGFyYW1zKTtcbiAgfSxcbiAgY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsICh7IGNoYW5uZWxfbmFtZTogY2hhbm5lbE5hbWUsIGNoYW5uZWxfaWQ6IGNoYW5uZWxJZCB9KSB7XG4gICAgcmV0dXJuIChjaGFubmVsTmFtZSB8fCBjaGFubmVsSWQgPyAnUFVCTElTSF9JTl9DSEFOTkVMX0NMQUlNJyA6ICdQVUJMSVNIX0FOT05ZTU9VU19DTEFJTScpO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2dvb2dsZUFuYWx5dGljcy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlZHV4XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVkdXhcIlxuLy8gbW9kdWxlIGlkID0gMThcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvY2hhbm5lbF9hY3Rpb25fdHlwZXMnO1xuXG4vLyBleHBvcnQgYWN0aW9uIGNyZWF0b3JzXG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVMb2dnZWRJbkNoYW5uZWwgKG5hbWUsIHNob3J0SWQsIGxvbmdJZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0hBTk5FTF9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgbmFtZSxcbiAgICAgIHNob3J0SWQsXG4gICAgICBsb25nSWQsXG4gICAgfSxcbiAgfTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvYWN0aW9ucy9jaGFubmVsLmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgQWN0aXZlU3RhdHVzQmFyIGZyb20gJ2NvbXBvbmVudHMvQWN0aXZlU3RhdHVzQmFyJztcbmltcG9ydCBJbmFjdGl2ZVN0YXR1c0JhciBmcm9tICdjb21wb25lbnRzL0luYWN0aXZlU3RhdHVzQmFyJztcblxuY2xhc3MgUHJvZ3Jlc3NCYXIgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGJhcnMgICAgICAgOiBbXSxcbiAgICAgIGluZGV4ICAgICAgOiAwLFxuICAgICAgaW5jcmVtZW50ZXI6IDEsXG4gICAgfTtcbiAgICB0aGlzLmNyZWF0ZUJhcnMgPSB0aGlzLmNyZWF0ZUJhcnMuYmluZCh0aGlzKTtcbiAgICB0aGlzLnN0YXJ0UHJvZ3Jlc3NCYXIgPSB0aGlzLnN0YXJ0UHJvZ3Jlc3NCYXIuYmluZCh0aGlzKTtcbiAgICB0aGlzLnVwZGF0ZVByb2dyZXNzQmFyID0gdGhpcy51cGRhdGVQcm9ncmVzc0Jhci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc3RvcFByb2dyZXNzQmFyID0gdGhpcy5zdG9wUHJvZ3Jlc3NCYXIuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgdGhpcy5jcmVhdGVCYXJzKCk7XG4gICAgdGhpcy5zdGFydFByb2dyZXNzQmFyKCk7XG4gIH1cbiAgY29tcG9uZW50V2lsbFVubW91bnQgKCkge1xuICAgIHRoaXMuc3RvcFByb2dyZXNzQmFyKCk7XG4gIH1cbiAgY3JlYXRlQmFycyAoKSB7XG4gICAgY29uc3QgYmFycyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHRoaXMucHJvcHMuc2l6ZTsgaSsrKSB7XG4gICAgICBiYXJzLnB1c2goe2lzQWN0aXZlOiBmYWxzZX0pO1xuICAgIH1cbiAgICB0aGlzLnNldFN0YXRlKHsgYmFycyB9KTtcbiAgfVxuICBzdGFydFByb2dyZXNzQmFyICgpIHtcbiAgICB0aGlzLnVwZGF0ZUludGVydmFsID0gc2V0SW50ZXJ2YWwodGhpcy51cGRhdGVQcm9ncmVzc0Jhci5iaW5kKHRoaXMpLCAzMDApO1xuICB9O1xuICB1cGRhdGVQcm9ncmVzc0JhciAoKSB7XG4gICAgbGV0IGluZGV4ID0gdGhpcy5zdGF0ZS5pbmRleDtcbiAgICBsZXQgaW5jcmVtZW50ZXIgPSB0aGlzLnN0YXRlLmluY3JlbWVudGVyO1xuICAgIGxldCBiYXJzID0gdGhpcy5zdGF0ZS5iYXJzO1xuICAgIC8vIGZsaXAgaW5jcmVtZW50ZXIgaWYgbmVjZXNzYXJ5LCB0byBzdGF5IGluIGJvdW5kc1xuICAgIGlmICgoaW5kZXggPCAwKSB8fCAoaW5kZXggPiB0aGlzLnByb3BzLnNpemUpKSB7XG4gICAgICBpbmNyZW1lbnRlciA9IGluY3JlbWVudGVyICogLTE7XG4gICAgICBpbmRleCArPSBpbmNyZW1lbnRlcjtcbiAgICB9XG4gICAgLy8gdXBkYXRlIHRoZSBpbmRleGVkIGJhclxuICAgIGlmIChpbmNyZW1lbnRlciA+IDApIHtcbiAgICAgIGJhcnNbaW5kZXhdLmlzQWN0aXZlID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgYmFyc1tpbmRleF0uaXNBY3RpdmUgPSBmYWxzZTtcbiAgICB9O1xuICAgIC8vIGluY3JlbWVudCBpbmRleFxuICAgIGluZGV4ICs9IGluY3JlbWVudGVyO1xuICAgIC8vIHVwZGF0ZSBzdGF0ZVxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgYmFycyxcbiAgICAgIGluY3JlbWVudGVyLFxuICAgICAgaW5kZXgsXG4gICAgfSk7XG4gIH07XG4gIHN0b3BQcm9ncmVzc0JhciAoKSB7XG4gICAgY2xlYXJJbnRlcnZhbCh0aGlzLnVwZGF0ZUludGVydmFsKTtcbiAgfTtcbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAge3RoaXMuc3RhdGUuYmFycy5tYXAoKGJhciwgaW5kZXgpID0+IGJhci5pc0FjdGl2ZSA/IDxBY3RpdmVTdGF0dXNCYXIga2V5PXtpbmRleH0gLz4gOiA8SW5hY3RpdmVTdGF0dXNCYXIga2V5PXtpbmRleH0vPil9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5Qcm9ncmVzc0Jhci5wcm9wVHlwZXMgPSB7XG4gIHNpemU6IFByb3BUeXBlcy5udW1iZXIuaXNSZXF1aXJlZCxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFByb2dyZXNzQmFyO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvUHJvZ3Jlc3NCYXIvaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgTmF2QmFyIGZyb20gJ2NvbnRhaW5lcnMvTmF2QmFyJztcblxuY2xhc3MgRXJyb3JQYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGVycm9yIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxwPntlcnJvcn08L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufTtcblxuRXJyb3JQYWdlLnByb3BUeXBlcyA9IHtcbiAgZXJyb3I6IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEVycm9yUGFnZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9wYWdlcy9FcnJvclBhZ2UvaW5kZXguanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicGFzc3BvcnRcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJwYXNzcG9ydFwiXG4vLyBtb2R1bGUgaWQgPSAyMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXNzcG9ydC1sb2NhbFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInBhc3Nwb3J0LWxvY2FsXCJcbi8vIG1vZHVsZSBpZCA9IDIzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInNlcXVlbGl6ZVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInNlcXVlbGl6ZVwiXG4vLyBtb2R1bGUgaWQgPSAyNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmV0dXJuU2hvcnRJZDogZnVuY3Rpb24gKGNsYWltc0FycmF5LCBsb25nSWQpIHtcbiAgICBsZXQgY2xhaW1JbmRleDtcbiAgICBsZXQgc2hvcnRJZCA9IGxvbmdJZC5zdWJzdHJpbmcoMCwgMSk7IC8vIGRlZmF1bHQgc2hvcnQgaWQgaXMgdGhlIGZpcnN0IGxldHRlclxuICAgIGxldCBzaG9ydElkTGVuZ3RoID0gMDtcbiAgICAvLyBmaW5kIHRoZSBpbmRleCBvZiB0aGlzIGNsYWltIGlkXG4gICAgY2xhaW1JbmRleCA9IGNsYWltc0FycmF5LmZpbmRJbmRleChlbGVtZW50ID0+IHtcbiAgICAgIHJldHVybiBlbGVtZW50LmNsYWltSWQgPT09IGxvbmdJZDtcbiAgICB9KTtcbiAgICBpZiAoY2xhaW1JbmRleCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2xhaW0gaWQgbm90IGZvdW5kIGluIGNsYWltcyBsaXN0Jyk7XG4gICAgfVxuICAgIC8vIGdldCBhbiBhcnJheSBvZiBhbGwgY2xhaW1zIHdpdGggbG93ZXIgaGVpZ2h0XG4gICAgbGV0IHBvc3NpYmxlTWF0Y2hlcyA9IGNsYWltc0FycmF5LnNsaWNlKDAsIGNsYWltSW5kZXgpO1xuICAgIC8vIHJlbW92ZSBjZXJ0aWZpY2F0ZXMgd2l0aCB0aGUgc2FtZSBwcmVmaXhlcyB1bnRpbCBub25lIGFyZSBsZWZ0LlxuICAgIHdoaWxlIChwb3NzaWJsZU1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgICAgc2hvcnRJZExlbmd0aCArPSAxO1xuICAgICAgc2hvcnRJZCA9IGxvbmdJZC5zdWJzdHJpbmcoMCwgc2hvcnRJZExlbmd0aCk7XG4gICAgICBwb3NzaWJsZU1hdGNoZXMgPSBwb3NzaWJsZU1hdGNoZXMuZmlsdGVyKGVsZW1lbnQgPT4ge1xuICAgICAgICByZXR1cm4gKGVsZW1lbnQuY2xhaW1JZCAmJiAoZWxlbWVudC5jbGFpbUlkLnN1YnN0cmluZygwLCBzaG9ydElkTGVuZ3RoKSA9PT0gc2hvcnRJZCkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBzaG9ydElkO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL3NlcXVlbGl6ZUhlbHBlcnMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmNvbnN0IHsgZGV0YWlscywgcHVibGlzaGluZyB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5ICh7bmFtZSwgbnNmdywgbGljZW5zZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCB0aHVtYm5haWx9KSB7XG4gICAgLy8gdmFsaWRhdGUgbmFtZVxuICAgIGlmICghbmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBuYW1lIGZpZWxkIGZvdW5kIGluIHJlcXVlc3QnKTtcbiAgICB9XG4gICAgY29uc3QgaW52YWxpZE5hbWVDaGFyYWN0ZXJzID0gL1teQS1aYS16MC05LC1dLy5leGVjKG5hbWUpO1xuICAgIGlmIChpbnZhbGlkTmFtZUNoYXJhY3RlcnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNsYWltIG5hbWUgeW91IHByb3ZpZGVkIGlzIG5vdCBhbGxvd2VkLiAgT25seSB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnMgYXJlIGFsbG93ZWQ6IEEtWiwgYS16LCAwLTksIGFuZCBcIi1cIicpO1xuICAgIH1cbiAgICAvLyBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgbnNmdyA9IChuc2Z3ID09PSAndHJ1ZScpO1xuICAgIGxpY2Vuc2UgPSBsaWNlbnNlIHx8IG51bGw7XG4gICAgdGl0bGUgPSB0aXRsZSB8fCBudWxsO1xuICAgIGRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24gfHwgbnVsbDtcbiAgICB0aHVtYm5haWwgPSB0aHVtYm5haWwgfHwgbnVsbDtcbiAgICAvLyByZXR1cm4gcmVzdWx0c1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lLFxuICAgICAgbnNmdyxcbiAgICAgIGxpY2Vuc2UsXG4gICAgICB0aXRsZSxcbiAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgdGh1bWJuYWlsLFxuICAgIH07XG4gIH0sXG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyAoe2ZpbGUsIHRodW1ibmFpbH0pIHtcbiAgICAvLyBtYWtlIHN1cmUgYSBmaWxlIHdhcyBwcm92aWRlZFxuICAgIGlmICghZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHdpdGgga2V5IG9mIFtmaWxlXSBmb3VuZCBpbiByZXF1ZXN0Jyk7XG4gICAgfVxuICAgIGlmICghZmlsZS5wYXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGZpbGUgcGF0aCBmb3VuZCcpO1xuICAgIH1cbiAgICBpZiAoIWZpbGUudHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHR5cGUgZm91bmQnKTtcbiAgICB9XG4gICAgaWYgKCFmaWxlLnNpemUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gZmlsZSB0eXBlIGZvdW5kJyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHRoZSBmaWxlIG5hbWVcbiAgICBpZiAoLycvLnRlc3QoZmlsZS5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcG9zdHJvcGhlcyBhcmUgbm90IGFsbG93ZWQgaW4gdGhlIGZpbGUgbmFtZScpO1xuICAgIH1cbiAgICAvLyB2YWxpZGF0ZSB0aGUgZmlsZVxuICAgIG1vZHVsZS5leHBvcnRzLnZhbGlkYXRlRmlsZVR5cGVBbmRTaXplKGZpbGUpO1xuICAgIC8vIHJldHVybiByZXN1bHRzXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbGVOYW1lICAgICAgICAgOiBmaWxlLm5hbWUsXG4gICAgICBmaWxlUGF0aCAgICAgICAgIDogZmlsZS5wYXRoLFxuICAgICAgZmlsZVR5cGUgICAgICAgICA6IGZpbGUudHlwZSxcbiAgICAgIHRodW1ibmFpbEZpbGVOYW1lOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLm5hbWUgOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVQYXRoOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnBhdGggOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVUeXBlOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnR5cGUgOiBudWxsKSxcbiAgICB9O1xuICB9LFxuICB2YWxpZGF0ZUZpbGVUeXBlQW5kU2l6ZSAoZmlsZSkge1xuICAgIC8vIGNoZWNrIGZpbGUgdHlwZSBhbmQgc2l6ZVxuICAgIHN3aXRjaCAoZmlsZS50eXBlKSB7XG4gICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICBpZiAoZmlsZS5zaXplID4gMTAwMDAwMDApIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ3B1Ymxpc2ggPiBmaWxlIHZhbGlkYXRpb24gPiAuanBlZy8uanBnLy5wbmcgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCBpbWFnZXMgYXJlIGxpbWl0ZWQgdG8gMTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gLmdpZiB3YXMgdG9vIGJpZycpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU29ycnksIC5naWZzIGFyZSBsaW1pdGVkIHRvIDUwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgIGlmIChmaWxlLnNpemUgPiA1MDAwMDAwMCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygncHVibGlzaCA+IGZpbGUgdmFsaWRhdGlvbiA+IC5tcDQgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCB2aWRlb3MgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gdW5yZWNvZ25pemVkIGZpbGUgdHlwZScpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSAnICsgZmlsZS50eXBlICsgJyBjb250ZW50IHR5cGUgaXMgbm90IHN1cHBvcnRlZC4gIE9ubHksIC5qcGVnLCAucG5nLCAuZ2lmLCBhbmQgLm1wNCBmaWxlcyBhcmUgY3VycmVudGx5IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0sXG4gIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcyAoZmlsZVBhdGgsIG5hbWUsIHRpdGxlLCBkZXNjcmlwdGlvbiwgbGljZW5zZSwgbnNmdywgdGh1bWJuYWlsKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBQdWJsaXNoIFBhcmFtZXRlcnNgKTtcbiAgICAvLyBwcm92aWRlIGRlZmF1bHRzIGZvciB0aXRsZVxuICAgIGlmICh0aXRsZSA9PT0gbnVsbCB8fCB0aXRsZS50cmltKCkgPT09ICcnKSB7XG4gICAgICB0aXRsZSA9IG5hbWU7XG4gICAgfVxuICAgIC8vIHByb3ZpZGUgZGVmYXVsdCBmb3IgZGVzY3JpcHRpb25cbiAgICBpZiAoZGVzY3JpcHRpb24gPT09IG51bGwgfHwgZGVzY3JpcHRpb24udHJpbSgpID09PSAnJykge1xuICAgICAgZGVzY3JpcHRpb24gPSAnJztcbiAgICB9XG4gICAgLy8gcHJvdmlkZSBkZWZhdWx0IGZvciBsaWNlbnNlXG4gICAgaWYgKGxpY2Vuc2UgPT09IG51bGwgfHwgbGljZW5zZS50cmltKCkgPT09ICcnKSB7XG4gICAgICBsaWNlbnNlID0gJyAnOyAgLy8gZGVmYXVsdCB0byBlbXB0eSBzdHJpbmdcbiAgICB9XG4gICAgLy8gY3JlYXRlIHRoZSBwdWJsaXNoIHBhcmFtc1xuICAgIGNvbnN0IHB1Ymxpc2hQYXJhbXMgPSB7XG4gICAgICBuYW1lLFxuICAgICAgZmlsZV9wYXRoOiBmaWxlUGF0aCxcbiAgICAgIGJpZCAgICAgIDogMC4wMSxcbiAgICAgIG1ldGFkYXRhIDoge1xuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGF1dGhvciAgOiBkZXRhaWxzLnRpdGxlLFxuICAgICAgICBsYW5ndWFnZTogJ2VuJyxcbiAgICAgICAgbGljZW5zZSxcbiAgICAgICAgbnNmdyxcbiAgICAgIH0sXG4gICAgICBjbGFpbV9hZGRyZXNzOiBwdWJsaXNoaW5nLnByaW1hcnlDbGFpbUFkZHJlc3MsXG4gICAgfTtcbiAgICAvLyBhZGQgdGh1bWJuYWlsIHRvIGNoYW5uZWwgaWYgdmlkZW9cbiAgICBpZiAodGh1bWJuYWlsKSB7XG4gICAgICBwdWJsaXNoUGFyYW1zWydtZXRhZGF0YSddWyd0aHVtYm5haWwnXSA9IHRodW1ibmFpbDtcbiAgICB9XG4gICAgcmV0dXJuIHB1Ymxpc2hQYXJhbXM7XG4gIH0sXG4gIGNyZWF0ZVRodW1ibmFpbFB1Ymxpc2hQYXJhbXMgKHRodW1ibmFpbEZpbGVQYXRoLCBjbGFpbU5hbWUsIGxpY2Vuc2UsIG5zZncpIHtcbiAgICBpZiAoIXRodW1ibmFpbEZpbGVQYXRoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxvZ2dlci5kZWJ1ZyhgQ3JlYXRpbmcgVGh1bWJuYWlsIFB1Ymxpc2ggUGFyYW1ldGVyc2ApO1xuICAgIC8vIGNyZWF0ZSB0aGUgcHVibGlzaCBwYXJhbXNcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSAgICAgOiBgJHtjbGFpbU5hbWV9LXRodW1iYCxcbiAgICAgIGZpbGVfcGF0aDogdGh1bWJuYWlsRmlsZVBhdGgsXG4gICAgICBiaWQgICAgICA6IDAuMDEsXG4gICAgICBtZXRhZGF0YSA6IHtcbiAgICAgICAgdGl0bGUgICAgICA6IGAke2NsYWltTmFtZX0gdGh1bWJuYWlsYCxcbiAgICAgICAgZGVzY3JpcHRpb246IGBhIHRodW1ibmFpbCBmb3IgJHtjbGFpbU5hbWV9YCxcbiAgICAgICAgYXV0aG9yICAgICA6IGRldGFpbHMudGl0bGUsXG4gICAgICAgIGxhbmd1YWdlICAgOiAnZW4nLFxuICAgICAgICBsaWNlbnNlLFxuICAgICAgICBuc2Z3LFxuICAgICAgfSxcbiAgICAgIGNsYWltX2FkZHJlc3M6IHB1Ymxpc2hpbmcucHJpbWFyeUNsYWltQWRkcmVzcyxcbiAgICAgIGNoYW5uZWxfbmFtZSA6IHB1Ymxpc2hpbmcudGh1bWJuYWlsQ2hhbm5lbCxcbiAgICAgIGNoYW5uZWxfaWQgICA6IHB1Ymxpc2hpbmcudGh1bWJuYWlsQ2hhbm5lbElkLFxuICAgIH07XG4gIH0sXG4gIGRlbGV0ZVRlbXBvcmFyeUZpbGUgKGZpbGVQYXRoKSB7XG4gICAgZnMudW5saW5rKGZpbGVQYXRoLCBlcnIgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYGVycm9yIGRlbGV0aW5nIHRlbXBvcmFyeSBmaWxlICR7ZmlsZVBhdGh9YCk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5kZWJ1Zyhgc3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgJHtmaWxlUGF0aH1gKTtcbiAgICB9KTtcbiAgfSxcbiAgYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEgKGZpbGVJbmZvLCBnZXRSZXN1bHQpIHtcbiAgICBmaWxlSW5mby5maWxlTmFtZSA9IGdldFJlc3VsdC5maWxlX25hbWU7XG4gICAgZmlsZUluZm8uZmlsZVBhdGggPSBnZXRSZXN1bHQuZG93bmxvYWRfcGF0aDtcbiAgICByZXR1cm4gZmlsZUluZm87XG4gIH0sXG4gIGNyZWF0ZUZpbGVEYXRhICh7IG5hbWUsIGNsYWltSWQsIG91dHBvaW50LCBoZWlnaHQsIGFkZHJlc3MsIG5zZncsIGNvbnRlbnRUeXBlIH0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSxcbiAgICAgIGNsYWltSWQsXG4gICAgICBvdXRwb2ludCxcbiAgICAgIGhlaWdodCxcbiAgICAgIGFkZHJlc3MsXG4gICAgICBmaWxlTmFtZTogJycsXG4gICAgICBmaWxlUGF0aDogJycsXG4gICAgICBmaWxlVHlwZTogY29udGVudFR5cGUsXG4gICAgICBuc2Z3LFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBoYW5kbGVFcnJvclJlc3BvbnNlOiBmdW5jdGlvbiAob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKSB7XG4gICAgbG9nZ2VyLmVycm9yKGBFcnJvciBvbiAke29yaWdpbmFsVXJsfWAsIG1vZHVsZS5leHBvcnRzLnVzZU9iamVjdFByb3BlcnRpZXNJZk5vS2V5cyhlcnJvcikpO1xuICAgIGNvbnN0IFtzdGF0dXMsIG1lc3NhZ2VdID0gbW9kdWxlLmV4cG9ydHMucmV0dXJuRXJyb3JNZXNzYWdlQW5kU3RhdHVzKGVycm9yKTtcbiAgICByZXNcbiAgICAgIC5zdGF0dXMoc3RhdHVzKVxuICAgICAgLmpzb24obW9kdWxlLmV4cG9ydHMuY3JlYXRlRXJyb3JSZXNwb25zZVBheWxvYWQoc3RhdHVzLCBtZXNzYWdlKSk7XG4gIH0sXG4gIHJldHVybkVycm9yTWVzc2FnZUFuZFN0YXR1czogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgbGV0IHN0YXR1cywgbWVzc2FnZTtcbiAgICAvLyBjaGVjayBmb3IgZGFlbW9uIGJlaW5nIHR1cm5lZCBvZmZcbiAgICBpZiAoZXJyb3IuY29kZSA9PT0gJ0VDT05OUkVGVVNFRCcpIHtcbiAgICAgIHN0YXR1cyA9IDUwMztcbiAgICAgIG1lc3NhZ2UgPSAnQ29ubmVjdGlvbiByZWZ1c2VkLiAgVGhlIGRhZW1vbiBtYXkgbm90IGJlIHJ1bm5pbmcuJztcbiAgICAgIC8vIGZhbGxiYWNrIGZvciBldmVyeXRoaW5nIGVsc2VcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdHVzID0gNDAwO1xuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZXNzYWdlID0gZXJyb3I7XG4gICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIFtzdGF0dXMsIG1lc3NhZ2VdO1xuICB9LFxuICB1c2VPYmplY3RQcm9wZXJ0aWVzSWZOb0tleXM6IGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoT2JqZWN0LmtleXMoZXJyKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGxldCBuZXdFcnJvck9iamVjdCA9IHt9O1xuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZXJyKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgbmV3RXJyb3JPYmplY3Rba2V5XSA9IGVycltrZXldO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3RXJyb3JPYmplY3Q7XG4gICAgfVxuICAgIHJldHVybiBlcnI7XG4gIH0sXG4gIGNyZWF0ZUVycm9yUmVzcG9uc2VQYXlsb2FkIChzdGF0dXMsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzLFxuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBtZXNzYWdlLFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcyIsImNvbnN0IGRiID0gcmVxdWlyZSgnLi4vbW9kZWxzL2luZGV4Jyk7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IHJldHVyblBhZ2luYXRlZENoYW5uZWxDbGFpbXMgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvY2hhbm5lbFBhZ2luYXRpb24uanMnKTtcblxuY29uc3QgTk9fQ0hBTk5FTCA9ICdOT19DSEFOTkVMJztcbmNvbnN0IE5PX0NMQUlNID0gJ05PX0NMQUlNJztcbmNvbnN0IE5PX0ZJTEUgPSAnTk9fRklMRSc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDbGFpbUlkIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIG5hbWUsIGNsYWltSWQpIHtcbiAgICBpZiAoY2hhbm5lbE5hbWUpIHtcbiAgICAgIHJldHVybiBtb2R1bGUuZXhwb3J0cy5nZXRDbGFpbUlkQnlDaGFubmVsKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgbmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBtb2R1bGUuZXhwb3J0cy5nZXRDbGFpbUlkQnlDbGFpbShuYW1lLCBjbGFpbUlkKTtcbiAgICB9XG4gIH0sXG4gIGdldENsYWltSWRCeUNsYWltIChjbGFpbU5hbWUsIGNsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldENsYWltSWRCeUNsYWltKCR7Y2xhaW1OYW1lfSwgJHtjbGFpbUlkfSlgKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZGIuQ2xhaW0uZ2V0TG9uZ0NsYWltSWQoY2xhaW1OYW1lLCBjbGFpbUlkKVxuICAgICAgICAudGhlbihsb25nQ2xhaW1JZCA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmVzb2x2ZShOT19DTEFJTSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUobG9uZ0NsYWltSWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDbGFpbUlkQnlDaGFubmVsIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0Q2xhaW1JZEJ5Q2hhbm5lbCgke2NoYW5uZWxOYW1lfSwgJHtjaGFubmVsQ2xhaW1JZH0sICR7Y2xhaW1OYW1lfSlgKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZGIuQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpIC8vIDEuIGdldCB0aGUgbG9uZyBjaGFubmVsIGlkXG4gICAgICAgIC50aGVuKGxvbmdDaGFubmVsSWQgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxJZCkge1xuICAgICAgICAgICAgcmV0dXJuIFtudWxsLCBudWxsXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtsb25nQ2hhbm5lbElkLCBkYi5DbGFpbS5nZXRDbGFpbUlkQnlMb25nQ2hhbm5lbElkKGxvbmdDaGFubmVsSWQsIGNsYWltTmFtZSldKTsgIC8vIDIuIGdldCB0aGUgbG9uZyBjbGFpbSBpZFxuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2xvbmdDaGFubmVsSWQsIGxvbmdDbGFpbUlkXSkgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxJZCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoTk9fQ0hBTk5FTCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghbG9uZ0NsYWltSWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKE5PX0NMQUlNKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShsb25nQ2xhaW1JZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGdldENoYW5uZWxEYXRhIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIHBhZ2UpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gMS4gZ2V0IHRoZSBsb25nIGNoYW5uZWwgSWQgKG1ha2Ugc3VyZSBjaGFubmVsIGV4aXN0cylcbiAgICAgIGRiLkNlcnRpZmljYXRlLmdldExvbmdDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKVxuICAgICAgICAudGhlbihsb25nQ2hhbm5lbENsYWltSWQgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gW251bGwsIG51bGwsIG51bGxdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyAyLiBnZXQgdGhlIHNob3J0IElEIGFuZCBhbGwgY2xhaW1zIGZvciB0aGF0IGNoYW5uZWxcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2xvbmdDaGFubmVsQ2xhaW1JZCwgZGIuQ2VydGlmaWNhdGUuZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZChsb25nQ2hhbm5lbENsYWltSWQsIGNoYW5uZWxOYW1lKV0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2xvbmdDaGFubmVsQ2xhaW1JZCwgc2hvcnRDaGFubmVsQ2xhaW1JZF0pID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoTk9fQ0hBTk5FTCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIDMuIHJldHVybiBhbGwgdGhlIGNoYW5uZWwgaW5mb3JtYXRpb25cbiAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgIGNoYW5uZWxOYW1lLFxuICAgICAgICAgICAgbG9uZ0NoYW5uZWxDbGFpbUlkLFxuICAgICAgICAgICAgc2hvcnRDaGFubmVsQ2xhaW1JZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2hhbm5lbENsYWltcyAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBwYWdlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIDEuIGdldCB0aGUgbG9uZyBjaGFubmVsIElkIChtYWtlIHN1cmUgY2hhbm5lbCBleGlzdHMpXG4gICAgICBkYi5DZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZClcbiAgICAgICAgLnRoZW4obG9uZ0NoYW5uZWxDbGFpbUlkID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIFtudWxsLCBudWxsLCBudWxsXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gMi4gZ2V0IHRoZSBzaG9ydCBJRCBhbmQgYWxsIGNsYWltcyBmb3IgdGhhdCBjaGFubmVsXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtsb25nQ2hhbm5lbENsYWltSWQsIGRiLkNsYWltLmdldEFsbENoYW5uZWxDbGFpbXMobG9uZ0NoYW5uZWxDbGFpbUlkKV0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2xvbmdDaGFubmVsQ2xhaW1JZCwgY2hhbm5lbENsYWltc0FycmF5XSkgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShOT19DSEFOTkVMKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gMy4gZm9ybWF0IHRoZSBkYXRhIGZvciB0aGUgdmlldywgaW5jbHVkaW5nIHBhZ2luYXRpb25cbiAgICAgICAgICBsZXQgcGFnaW5hdGVkQ2hhbm5lbFZpZXdEYXRhID0gcmV0dXJuUGFnaW5hdGVkQ2hhbm5lbENsYWltcyhjaGFubmVsTmFtZSwgbG9uZ0NoYW5uZWxDbGFpbUlkLCBjaGFubmVsQ2xhaW1zQXJyYXksIHBhZ2UpO1xuICAgICAgICAgIC8vIDQuIHJldHVybiBhbGwgdGhlIGNoYW5uZWwgaW5mb3JtYXRpb24gYW5kIGNvbnRlbnRzXG4gICAgICAgICAgcmVzb2x2ZShwYWdpbmF0ZWRDaGFubmVsVmlld0RhdGEpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRMb2NhbEZpbGVSZWNvcmQgKGNsYWltSWQsIG5hbWUpIHtcbiAgICByZXR1cm4gZGIuRmlsZS5maW5kT25lKHt3aGVyZToge2NsYWltSWQsIG5hbWV9fSlcbiAgICAgIC50aGVuKGZpbGUgPT4ge1xuICAgICAgICBpZiAoIWZpbGUpIHtcbiAgICAgICAgICByZXR1cm4gTk9fRklMRTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsZS5kYXRhVmFsdWVzO1xuICAgICAgfSk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXJUb1N0cmluZyB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IHsgY3JlYXRlU3RvcmUgfSBmcm9tICdyZWR1eCc7XG5pbXBvcnQgUmVkdWNlciBmcm9tICcuLi8uLi9jbGllbnQvcmVkdWNlcnMvaW5kZXgnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBTdGF0aWNSb3V0ZXIgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmltcG9ydCBHQUxpc3RlbmVyIGZyb20gJy4uLy4uL2NsaWVudC9jb21wb25lbnRzL0dBTGlzdGVuZXIvaW5kZXgnO1xuaW1wb3J0IEFwcCBmcm9tICcuLi8uLi9jbGllbnQvYXBwJztcbmltcG9ydCByZW5kZXJGdWxsUGFnZSBmcm9tICcuL3JlbmRlckZ1bGxQYWdlLmpzJztcbmltcG9ydCBIZWxtZXQgZnJvbSAncmVhY3QtaGVsbWV0JztcblxubW9kdWxlLmV4cG9ydHMgPSAocmVxLCByZXMpID0+IHtcbiAgbGV0IGNvbnRleHQgPSB7fTtcblxuICAvLyBjcmVhdGUgYSBuZXcgUmVkdXggc3RvcmUgaW5zdGFuY2VcbiAgY29uc3Qgc3RvcmUgPSBjcmVhdGVTdG9yZShSZWR1Y2VyKTtcblxuICAvLyByZW5kZXIgY29tcG9uZW50IHRvIGEgc3RyaW5nXG4gIGNvbnN0IGh0bWwgPSByZW5kZXJUb1N0cmluZyhcbiAgICA8UHJvdmlkZXIgc3RvcmU9e3N0b3JlfT5cbiAgICAgIDxTdGF0aWNSb3V0ZXIgbG9jYXRpb249e3JlcS51cmx9IGNvbnRleHQ9e2NvbnRleHR9PlxuICAgICAgICA8R0FMaXN0ZW5lcj5cbiAgICAgICAgICA8QXBwIC8+XG4gICAgICAgIDwvR0FMaXN0ZW5lcj5cbiAgICAgIDwvU3RhdGljUm91dGVyPlxuICAgIDwvUHJvdmlkZXI+XG4gICk7XG5cbiAgLy8gZ2V0IGhlYWQgdGFncyBmcm9tIGhlbG1ldFxuICBjb25zdCBoZWxtZXQgPSBIZWxtZXQucmVuZGVyU3RhdGljKCk7XG5cbiAgLy8gY2hlY2sgZm9yIGEgcmVkaXJlY3RcbiAgaWYgKGNvbnRleHQudXJsKSB7XG4gICAgLy8gU29tZXdoZXJlIGEgYDxSZWRpcmVjdD5gIHdhcyByZW5kZXJlZFxuICAgIHJldHVybiByZXMucmVkaXJlY3QoMzAxLCBjb250ZXh0LnVybCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gd2UncmUgZ29vZCwgc2VuZCB0aGUgcmVzcG9uc2VcbiAgfVxuXG4gIC8vIGdldCB0aGUgaW5pdGlhbCBzdGF0ZSBmcm9tIG91ciBSZWR1eCBzdG9yZVxuICBjb25zdCBwcmVsb2FkZWRTdGF0ZSA9IHN0b3JlLmdldFN0YXRlKCk7XG5cbiAgLy8gc2VuZCB0aGUgcmVuZGVyZWQgcGFnZSBiYWNrIHRvIHRoZSBjbGllbnRcbiAgcmVzLnNlbmQocmVuZGVyRnVsbFBhZ2UoaGVsbWV0LCBodG1sLCBwcmVsb2FkZWRTdGF0ZSkpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3QtZG9tL3NlcnZlclwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWRvbS9zZXJ2ZXJcIlxuLy8gbW9kdWxlIGlkID0gMzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHsgY29tYmluZVJlZHVjZXJzIH0gZnJvbSAncmVkdXgnO1xuaW1wb3J0IFB1Ymxpc2hSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3B1Ymxpc2gnO1xuaW1wb3J0IENoYW5uZWxSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL2NoYW5uZWwnO1xuaW1wb3J0IFNob3dSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3Nob3cnO1xuaW1wb3J0IFNpdGVSZWR1Y2VyIGZyb20gJ3JlZHVjZXJzL3NpdGUnO1xuXG5leHBvcnQgZGVmYXVsdCBjb21iaW5lUmVkdWNlcnMoe1xuICBjaGFubmVsOiBDaGFubmVsUmVkdWNlcixcbiAgcHVibGlzaDogUHVibGlzaFJlZHVjZXIsXG4gIHNob3cgICA6IFNob3dSZWR1Y2VyLFxuICBzaXRlICAgOiBTaXRlUmVkdWNlcixcbn0pO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3JlZHVjZXJzL2luZGV4LmpzIiwiZXhwb3J0IGNvbnN0IEZJTEVfU0VMRUNURUQgPSAnRklMRV9TRUxFQ1RFRCc7XG5leHBvcnQgY29uc3QgRklMRV9DTEVBUiA9ICdGSUxFX0NMRUFSJztcbmV4cG9ydCBjb25zdCBNRVRBREFUQV9VUERBVEUgPSAnTUVUQURBVEFfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBDTEFJTV9VUERBVEUgPSAnQ0xBSU1fVVBEQVRFJztcbmV4cG9ydCBjb25zdCBTRVRfUFVCTElTSF9JTl9DSEFOTkVMID0gJ1NFVF9QVUJMSVNIX0lOX0NIQU5ORUwnO1xuZXhwb3J0IGNvbnN0IFBVQkxJU0hfU1RBVFVTX1VQREFURSA9ICdQVUJMSVNIX1NUQVRVU19VUERBVEUnO1xuZXhwb3J0IGNvbnN0IEVSUk9SX1VQREFURSA9ICdFUlJPUl9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IFNFTEVDVEVEX0NIQU5ORUxfVVBEQVRFID0gJ1NFTEVDVEVEX0NIQU5ORUxfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBUT0dHTEVfTUVUQURBVEFfSU5QVVRTID0gJ1RPR0dMRV9NRVRBREFUQV9JTlBVVFMnO1xuZXhwb3J0IGNvbnN0IFRIVU1CTkFJTF9ORVcgPSAnVEhVTUJOQUlMX05FVyc7XG5leHBvcnQgY29uc3QgUFVCTElTSF9TVEFSVCA9ICdQVUJMSVNIX1NUQVJUJztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMuanMiLCJleHBvcnQgY29uc3QgTE9HSU4gPSAnRXhpc3RpbmcnO1xuZXhwb3J0IGNvbnN0IENSRUFURSA9ICdOZXcnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9wdWJsaXNoX2NoYW5uZWxfc2VsZWN0X3N0YXRlcy5qcyIsImV4cG9ydCBjb25zdCBDSEFOTkVMX1VQREFURSA9ICdDSEFOTkVMX1VQREFURSc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29uc3RhbnRzL2NoYW5uZWxfYWN0aW9uX3R5cGVzLmpzIiwiZXhwb3J0IGNvbnN0IExPQ0FMX0NIRUNLID0gJ0xPQ0FMX0NIRUNLJztcbmV4cG9ydCBjb25zdCBVTkFWQUlMQUJMRSA9ICdVTkFWQUlMQUJMRSc7XG5leHBvcnQgY29uc3QgRVJST1IgPSAnRVJST1InO1xuZXhwb3J0IGNvbnN0IEFWQUlMQUJMRSA9ICdBVkFJTEFCTEUnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9hc3NldF9kaXNwbGF5X3N0YXRlcy5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgR29vZ2xlQW5hbHl0aWNzIGZyb20gJ3JlYWN0LWdhJztcbmltcG9ydCB7IHdpdGhSb3V0ZXIgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmNvbnN0IHsgYW5hbHl0aWNzOiB7IGdvb2dsZUlkIH0gfSA9IHJlcXVpcmUoJy4uLy4uLy4uL2NvbmZpZy9zaXRlQ29uZmlnLmpzJyk7XG5cbkdvb2dsZUFuYWx5dGljcy5pbml0aWFsaXplKGdvb2dsZUlkKTtcblxuY2xhc3MgR0FMaXN0ZW5lciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnNlbmRQYWdlVmlldyh0aGlzLnByb3BzLmhpc3RvcnkubG9jYXRpb24pO1xuICAgIHRoaXMucHJvcHMuaGlzdG9yeS5saXN0ZW4odGhpcy5zZW5kUGFnZVZpZXcpO1xuICB9XG5cbiAgc2VuZFBhZ2VWaWV3IChsb2NhdGlvbikge1xuICAgIEdvb2dsZUFuYWx5dGljcy5zZXQoeyBwYWdlOiBsb2NhdGlvbi5wYXRobmFtZSB9KTtcbiAgICBHb29nbGVBbmFseXRpY3MucGFnZXZpZXcobG9jYXRpb24ucGF0aG5hbWUpO1xuICB9XG5cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5jaGlsZHJlbjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKEdBTGlzdGVuZXIpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvR0FMaXN0ZW5lci9pbmRleC5qc3giLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgUm91dGUsIFN3aXRjaCB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEhvbWVQYWdlIGZyb20gJ3BhZ2VzL0hvbWVQYWdlJzsgLy8gb3IgdXNlIHRoZSBwcm92aWRlZCBsb2NhbCBob21lcGFnZVxuaW1wb3J0IEFib3V0UGFnZSBmcm9tICdwYWdlcy9BYm91dFBhZ2UnO1xuaW1wb3J0IExvZ2luUGFnZSBmcm9tICdwYWdlcy9Mb2dpblBhZ2UnO1xuaW1wb3J0IFNob3dQYWdlIGZyb20gJ3BhZ2VzL1Nob3dQYWdlJztcbmltcG9ydCBGb3VyT2hGb3VyUGFnZSBmcm9tICdjb250YWluZXJzL0ZvdXJPaEZvdXJQYWdlJztcblxuY29uc3QgQXBwID0gKCkgPT4ge1xuICByZXR1cm4gKFxuICAgIDxTd2l0Y2g+XG4gICAgICA8Um91dGUgZXhhY3QgcGF0aD0nLycgY29tcG9uZW50PXtIb21lUGFnZX0gLz5cbiAgICAgIDxSb3V0ZSBleGFjdCBwYXRoPScvYWJvdXQnIGNvbXBvbmVudD17QWJvdXRQYWdlfSAvPlxuICAgICAgPFJvdXRlIGV4YWN0IHBhdGg9Jy9sb2dpbicgY29tcG9uZW50PXtMb2dpblBhZ2V9IC8+XG4gICAgICA8Um91dGUgZXhhY3QgcGF0aD0nLzppZGVudGlmaWVyLzpjbGFpbScgY29tcG9uZW50PXtTaG93UGFnZX0gLz5cbiAgICAgIDxSb3V0ZSBleGFjdCBwYXRoPScvOmNsYWltJyBjb21wb25lbnQ9e1Nob3dQYWdlfSAvPlxuICAgICAgPFJvdXRlIGNvbXBvbmVudD17Rm91ck9oRm91clBhZ2V9IC8+XG4gICAgPC9Td2l0Y2g+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBcHA7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvYXBwLmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBzZWxlY3RGaWxlLCB1cGRhdGVFcnJvciwgY2xlYXJGaWxlIH0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHB1Ymxpc2ggfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIGZpbGUgICAgIDogcHVibGlzaC5maWxlLFxuICAgIHRodW1ibmFpbDogcHVibGlzaC50aHVtYm5haWwsXG4gICAgZmlsZUVycm9yOiBwdWJsaXNoLmVycm9yLmZpbGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgc2VsZWN0RmlsZTogKGZpbGUpID0+IHtcbiAgICAgIGRpc3BhdGNoKHNlbGVjdEZpbGUoZmlsZSkpO1xuICAgIH0sXG4gICAgc2V0RmlsZUVycm9yOiAodmFsdWUpID0+IHtcbiAgICAgIGRpc3BhdGNoKGNsZWFyRmlsZSgpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUVycm9yKCdmaWxlJywgdmFsdWUpKTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9Ecm9wem9uZS9pbmRleC5qcyIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyB1cGRhdGVMb2dnZWRJbkNoYW5uZWwgfSBmcm9tICdhY3Rpb25zL2NoYW5uZWwnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcbmltcG9ydCB7dXBkYXRlU2VsZWN0ZWRDaGFubmVsfSBmcm9tICcuLi8uLi9hY3Rpb25zL3B1Ymxpc2gnO1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25DaGFubmVsTG9naW46IChuYW1lLCBzaG9ydElkLCBsb25nSWQpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbChuYW1lLCBzaG9ydElkLCBsb25nSWQpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbChuYW1lKSk7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobnVsbCwgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vaW5kZXguanMiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgdXBkYXRlTG9nZ2VkSW5DaGFubmVsIH0gZnJvbSAnYWN0aW9ucy9jaGFubmVsJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQge3VwZGF0ZVNlbGVjdGVkQ2hhbm5lbH0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2hhbm5lbExvZ2luOiAobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVTZWxlY3RlZENoYW5uZWwobmFtZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG51bGwsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9DaGFubmVsQ3JlYXRlRm9ybS9pbmRleC5qcyIsImV4cG9ydCBjb25zdCBDSEFOTkVMID0gJ0NIQU5ORUwnO1xuZXhwb3J0IGNvbnN0IEFTU0VUX0xJVEUgPSAnQVNTRVRfTElURSc7XG5leHBvcnQgY29uc3QgQVNTRVRfREVUQUlMUyA9ICdBU1NFVF9ERVRBSUxTJztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb25zdGFudHMvc2hvd19yZXF1ZXN0X3R5cGVzLmpzIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQgeyBmaWxlUmVxdWVzdGVkIH0gZnJvbSAnYWN0aW9ucy9zaG93JztcbmltcG9ydCB7IHNlbGVjdEFzc2V0IH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IGVycm9yIGFuZCBzdGF0dXNcbiAgY29uc3QgZXJyb3IgID0gc2hvdy5kaXNwbGF5QXNzZXQuZXJyb3I7XG4gIGNvbnN0IHN0YXR1cyA9IHNob3cuZGlzcGxheUFzc2V0LnN0YXR1cztcbiAgLy8gc2VsZWN0IGFzc2V0XG4gIGNvbnN0IGFzc2V0ID0gc2VsZWN0QXNzZXQoc2hvdyk7XG4gIC8vICByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBlcnJvcixcbiAgICBzdGF0dXMsXG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25GaWxlUmVxdWVzdDogKG5hbWUsIGNsYWltSWQpID0+IHtcbiAgICAgIGRpc3BhdGNoKGZpbGVSZXF1ZXN0ZWQobmFtZSwgY2xhaW1JZCkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0RGlzcGxheS9pbmRleC5qcyIsIm1vZHVsZS5leHBvcnRzID0gKGhlbG1ldCwgaHRtbCwgcHJlbG9hZGVkU3RhdGUpID0+IHtcbiAgLy8gdGFrZSB0aGUgaHRtbCBhbmQgcHJlbG9hZGVkU3RhdGUgYW5kIHJldHVybiB0aGUgZnVsbCBwYWdlXG4gIHJldHVybiBgXG4gICAgPCFET0NUWVBFIGh0bWw+XG4gICAgPGh0bWwgbGFuZz1cImVuXCIgcHJlZml4PVwib2c6IGh0dHA6Ly9vZ3AubWUvbnMjIGZiOiBodHRwOi8vb2dwLm1lL25zL2ZiI1wiPlxuICAgICAgICA8aGVhZD5cbiAgICAgICAgICAgIDxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPlxuICAgICAgICAgICAgPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAsIG1heGltdW0tc2NhbGU9MSwgdXNlci1zY2FsYWJsZT1ub1wiPlxuICAgICAgICAgICAgPG1ldGEgaHR0cC1lcXVpdj1cIlgtVUEtQ29tcGF0aWJsZVwiIGNvbnRlbnQ9XCJpZT1lZGdlXCI+XG4gICAgICAgICAgICA8IS0taGVsbWV0LS0+XG4gICAgICAgICAgICAke2hlbG1ldC50aXRsZS50b1N0cmluZygpfVxuICAgICAgICAgICAgJHtoZWxtZXQubWV0YS50b1N0cmluZygpfVxuICAgICAgICAgICAgJHtoZWxtZXQubGluay50b1N0cmluZygpfVxuICAgICAgICAgICAgPCEtLXN0eWxlIHNoZWV0cy0tPlxuICAgICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvYXNzZXRzL2Nzcy9yZXNldC5jc3NcIiB0eXBlPVwidGV4dC9jc3NcIj5cbiAgICAgICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL2Fzc2V0cy9jc3MvZ2VuZXJhbC5jc3NcIiB0eXBlPVwidGV4dC9jc3NcIj5cbiAgICAgICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL2Fzc2V0cy9jc3MvbWVkaWFRdWVyaWVzLmNzc1wiIHR5cGU9XCJ0ZXh0L2Nzc1wiPlxuICAgICAgICAgICAgPCEtLWdvb2dsZSBmb250LS0+XG4gICAgICAgICAgICA8bGluayBocmVmPVwiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PVJvYm90bzozMDBcIiByZWw9XCJzdHlsZXNoZWV0XCI+XG4gICAgICAgIDwvaGVhZD5cbiAgICAgICAgPGJvZHkgaWQ9XCJtYWluLWJvZHlcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3cgcm93LS10YWxsIGZsZXgtY29udGFpbmVyLS1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGlkPVwicmVhY3QtYXBwXCIgY2xhc3M9XCJyb3cgcm93LS10YWxsIGZsZXgtY29udGFpbmVyLS1jb2x1bW5cIj4ke2h0bWx9PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzY3JpcHQ+XG4gICAgICAgICAgICAgICAgd2luZG93Ll9fUFJFTE9BREVEX1NUQVRFX18gPSAke0pTT04uc3RyaW5naWZ5KHByZWxvYWRlZFN0YXRlKS5yZXBsYWNlKC88L2csICdcXFxcXFx1MDAzYycpfVxuICAgICAgICAgICAgPC9zY3JpcHQ+XG4gICAgICAgICAgICA8c2NyaXB0IHNyYz1cIi9idW5kbGUvYnVuZGxlLmpzXCI+PC9zY3JpcHQ+XG4gICAgICAgIDwvYm9keT5cbiAgICA8L2h0bWw+XG4gIGA7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvcmVuZGVyRnVsbFBhZ2UuanMiLCJleHBvcnQgY29uc3Qgc2VsZWN0U2l0ZVN0YXRlID0gKHN0YXRlKSA9PiB7XG4gIHJldHVybiBzdGF0ZS5zaXRlO1xufTtcblxuZXhwb3J0IGNvbnN0IHNlbGVjdFNpdGVIb3N0ID0gKHN0YXRlKSA9PiB7XG4gIHJldHVybiBzdGF0ZS5zaXRlLmhvc3Q7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NlbGVjdG9ycy9zaXRlLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYmFiZWwtcG9seWZpbGxcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJiYWJlbC1wb2x5ZmlsbFwiXG4vLyBtb2R1bGUgaWQgPSA0NlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ3aGF0d2ctZmV0Y2hcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ3aGF0d2ctZmV0Y2hcIlxuLy8gbW9kdWxlIGlkID0gNDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gYXBwIGRlcGVuZGVuY2llc1xuY29uc3QgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKTtcbmNvbnN0IGJvZHlQYXJzZXIgPSByZXF1aXJlKCdib2R5LXBhcnNlcicpO1xuY29uc3QgZXhwcmVzc0hhbmRsZWJhcnMgPSByZXF1aXJlKCdleHByZXNzLWhhbmRsZWJhcnMnKTtcbmNvbnN0IEhhbmRsZWJhcnMgPSByZXF1aXJlKCdoYW5kbGViYXJzJyk7XG5jb25zdCBoZWxtZXQgPSByZXF1aXJlKCdoZWxtZXQnKTtcbmNvbnN0IHBhc3Nwb3J0ID0gcmVxdWlyZSgncGFzc3BvcnQnKTtcbmNvbnN0IHsgc2VyaWFsaXplU3BlZWNoVXNlciwgZGVzZXJpYWxpemVTcGVlY2hVc2VyIH0gPSByZXF1aXJlKCcuL2hlbHBlcnMvYXV0aEhlbHBlcnMuanMnKTtcbmNvbnN0IGNvb2tpZVNlc3Npb24gPSByZXF1aXJlKCdjb29raWUtc2Vzc2lvbicpO1xuY29uc3QgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcbi8vIGxvZ2dpbmcgZGVwZW5kZW5jaWVzXG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG4vLyBjb25maWd1cmUgbG9nZ2VyXG5yZXF1aXJlKCcuL2hlbHBlcnMvY29uZmlndXJlTG9nZ2VyLmpzJykobG9nZ2VyKTtcbnJlcXVpcmUoJy4vaGVscGVycy9jb25maWd1cmVTbGFjay5qcycpKGxvZ2dlcik7XG5cbmNvbnN0IHthdXRoOiB7IHNlc3Npb25LZXkgfSwgZGV0YWlsczogeyBwb3J0OiBQT1JUIH19ID0gcmVxdWlyZSgnLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxuLy8gY3JlYXRlIGFuIEV4cHJlc3MgYXBwbGljYXRpb25cbmNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcblxuLy8gdHJ1c3QgdGhlIHByb3h5IHRvIGdldCBpcCBhZGRyZXNzIGZvciB1c1xuYXBwLmVuYWJsZSgndHJ1c3QgcHJveHknKTtcblxuLy8gYWRkIG1pZGRsZXdhcmVcbmFwcC51c2UoaGVsbWV0KCkpOyAvLyBzZXQgSFRUUCBoZWFkZXJzIHRvIHByb3RlY3QgYWdhaW5zdCB3ZWxsLWtub3duIHdlYiB2dWxuZXJhYmlsdGllc1xuYXBwLnVzZShleHByZXNzLnN0YXRpYyhgJHtfX2Rpcm5hbWV9L3B1YmxpY2ApKTsgLy8gJ2V4cHJlc3Muc3RhdGljJyB0byBzZXJ2ZSBzdGF0aWMgZmlsZXMgZnJvbSBwdWJsaWMgZGlyZWN0b3J5XG5hcHAudXNlKGJvZHlQYXJzZXIuanNvbigpKTsgLy8gJ2JvZHkgcGFyc2VyJyBmb3IgcGFyc2luZyBhcHBsaWNhdGlvbi9qc29uXG5hcHAudXNlKGJvZHlQYXJzZXIudXJsZW5jb2RlZCh7IGV4dGVuZGVkOiB0cnVlIH0pKTsgLy8gJ2JvZHkgcGFyc2VyJyBmb3IgcGFyc2luZyBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcbmFwcC51c2UoKHJlcSwgcmVzLCBuZXh0KSA9PiB7ICAvLyBjdXN0b20gbG9nZ2luZyBtaWRkbGV3YXJlIHRvIGxvZyBhbGwgaW5jb21pbmcgaHR0cCByZXF1ZXN0c1xuICBsb2dnZXIudmVyYm9zZShgUmVxdWVzdCBvbiAke3JlcS5vcmlnaW5hbFVybH0gZnJvbSAke3JlcS5pcH1gKTtcbiAgbmV4dCgpO1xufSk7XG5cbi8vIGNvbmZpZ3VyZSBwYXNzcG9ydFxucGFzc3BvcnQuc2VyaWFsaXplVXNlcihzZXJpYWxpemVTcGVlY2hVc2VyKTtcbnBhc3Nwb3J0LmRlc2VyaWFsaXplVXNlcihkZXNlcmlhbGl6ZVNwZWVjaFVzZXIpO1xuY29uc3QgbG9jYWxTaWdudXBTdHJhdGVneSA9IHJlcXVpcmUoJy4vcGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzJyk7XG5jb25zdCBsb2NhbExvZ2luU3RyYXRlZ3kgPSByZXF1aXJlKCcuL3Bhc3Nwb3J0L2xvY2FsLWxvZ2luLmpzJyk7XG5wYXNzcG9ydC51c2UoJ2xvY2FsLXNpZ251cCcsIGxvY2FsU2lnbnVwU3RyYXRlZ3kpO1xucGFzc3BvcnQudXNlKCdsb2NhbC1sb2dpbicsIGxvY2FsTG9naW5TdHJhdGVneSk7XG4vLyBpbml0aWFsaXplIHBhc3Nwb3J0XG5hcHAudXNlKGNvb2tpZVNlc3Npb24oe1xuICBuYW1lICA6ICdzZXNzaW9uJyxcbiAga2V5cyAgOiBbc2Vzc2lvbktleV0sXG4gIG1heEFnZTogMjQgKiA2MCAqIDYwICogMTAwMCwgLy8gaS5lLiAyNCBob3Vyc1xufSkpO1xuYXBwLnVzZShwYXNzcG9ydC5pbml0aWFsaXplKCkpO1xuYXBwLnVzZShwYXNzcG9ydC5zZXNzaW9uKCkpO1xuXG4vLyBjb25maWd1cmUgaGFuZGxlYmFycyAmIHJlZ2lzdGVyIGl0IHdpdGggZXhwcmVzcyBhcHBcbmNvbnN0IGhicyA9IGV4cHJlc3NIYW5kbGViYXJzLmNyZWF0ZSh7XG4gIGRlZmF1bHRMYXlvdXQ6ICdlbWJlZCcsXG4gIGhhbmRsZWJhcnMgICA6IEhhbmRsZWJhcnMsXG59KTtcbmFwcC5lbmdpbmUoJ2hhbmRsZWJhcnMnLCBoYnMuZW5naW5lKTtcbmFwcC5zZXQoJ3ZpZXcgZW5naW5lJywgJ2hhbmRsZWJhcnMnKTtcblxuLy8gc2V0IHRoZSByb3V0ZXMgb24gdGhlIGFwcFxucmVxdWlyZSgnLi9yb3V0ZXMvYXV0aC1yb3V0ZXMuanMnKShhcHApO1xucmVxdWlyZSgnLi9yb3V0ZXMvYXBpLXJvdXRlcy5qcycpKGFwcCk7XG5yZXF1aXJlKCcuL3JvdXRlcy9wYWdlLXJvdXRlcy5qcycpKGFwcCk7XG5yZXF1aXJlKCcuL3JvdXRlcy9hc3NldC1yb3V0ZXMuanMnKShhcHApO1xucmVxdWlyZSgnLi9yb3V0ZXMvZmFsbGJhY2stcm91dGVzLmpzJykoYXBwKTtcblxuLy8gY3JlYXRlIHNlcnZlclxuY29uc3Qgc2VydmVyID0gaHR0cC5TZXJ2ZXIoYXBwKTtcblxuLy8gc3luYyBzZXF1ZWxpemVcbmNvbnN0IGRiID0gcmVxdWlyZSgnLi9tb2RlbHMvaW5kZXgnKTtcbmRiLnNlcXVlbGl6ZS5zeW5jKClcbiAgLy8gc3RhcnQgdGhlIHNlcnZlclxuICAudGhlbigoKSA9PiB7XG4gICAgc2VydmVyLmxpc3RlbihQT1JULCAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgU2VydmVyIGlzIGxpc3RlbmluZyBvbiBQT1JUICR7UE9SVH1gKTtcbiAgICB9KTtcbiAgfSlcbiAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgIGxvZ2dlci5lcnJvcihgU3RhcnR1cCBFcnJvcjpgLCBlcnJvcik7XG4gIH0pO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3NlcnZlci5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImV4cHJlc3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJleHByZXNzXCJcbi8vIG1vZHVsZSBpZCA9IDQ5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImJvZHktcGFyc2VyXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiYm9keS1wYXJzZXJcIlxuLy8gbW9kdWxlIGlkID0gNTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXhwcmVzcy1oYW5kbGViYXJzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiZXhwcmVzcy1oYW5kbGViYXJzXCJcbi8vIG1vZHVsZSBpZCA9IDUxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImhhbmRsZWJhcnNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJoYW5kbGViYXJzXCJcbi8vIG1vZHVsZSBpZCA9IDUyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImhlbG1ldFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImhlbG1ldFwiXG4vLyBtb2R1bGUgaWQgPSA1M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXJpYWxpemVTcGVlY2hVc2VyICh1c2VyLCBkb25lKSB7ICAvLyByZXR1cm5zIHVzZXIgZGF0YSB0byBiZSBzZXJpYWxpemVkIGludG8gc2Vzc2lvblxuICAgIGxvZ2dlci5kZWJ1Zygnc2VyaWFsaXppbmcgdXNlcicpO1xuICAgIGRvbmUobnVsbCwgdXNlcik7XG4gIH0sXG4gIGRlc2VyaWFsaXplU3BlZWNoVXNlciAodXNlciwgZG9uZSkgeyAgLy8gZGVzZXJpYWxpemVzIHNlc3Npb24gYW5kIHBvcHVsYXRlcyBhZGRpdGlvbmFsIGluZm8gdG8gcmVxLnVzZXJcbiAgICBsb2dnZXIuZGVidWcoJ2Rlc2VyaWFsaXppbmcgdXNlcicpO1xuICAgIGRvbmUobnVsbCwgdXNlcik7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvYXV0aEhlbHBlcnMuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjb29raWUtc2Vzc2lvblwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImNvb2tpZS1zZXNzaW9uXCJcbi8vIG1vZHVsZSBpZCA9IDU1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImh0dHBcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJodHRwXCJcbi8vIG1vZHVsZSBpZCA9IDU2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IHsgbG9nTGV2ZWwgfSA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9sb2dnZXJDb25maWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAod2luc3RvbikgPT4ge1xuICAvLyBjb25maWd1cmVcbiAgd2luc3Rvbi5jb25maWd1cmUoe1xuICAgIHRyYW5zcG9ydHM6IFtcbiAgICAgIG5ldyAod2luc3Rvbi50cmFuc3BvcnRzLkNvbnNvbGUpKHtcbiAgICAgICAgbGV2ZWwgICAgICAgICAgICAgICAgICAgICAgICAgIDogbG9nTGV2ZWwsXG4gICAgICAgIHRpbWVzdGFtcCAgICAgICAgICAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICBjb2xvcml6ZSAgICAgICAgICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBwcmV0dHlQcmludCAgICAgICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBoYW5kbGVFeGNlcHRpb25zICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICBodW1hblJlYWRhYmxlVW5oYW5kbGVkRXhjZXB0aW9uOiB0cnVlLFxuICAgICAgfSksXG4gICAgXSxcbiAgfSk7XG4gIC8vIHRlc3QgYWxsIHRoZSBsb2cgbGV2ZWxzXG4gIHdpbnN0b24uZXJyb3IoJ0xldmVsIDAnKTtcbiAgd2luc3Rvbi53YXJuKCdMZXZlbCAxJyk7XG4gIHdpbnN0b24uaW5mbygnTGV2ZWwgMicpO1xuICB3aW5zdG9uLnZlcmJvc2UoJ0xldmVsIDMnKTtcbiAgd2luc3Rvbi5kZWJ1ZygnTGV2ZWwgNCcpO1xuICB3aW5zdG9uLnNpbGx5KCdMZXZlbCA1Jyk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvY29uZmlndXJlTG9nZ2VyLmpzIiwiY29uc3QgbG9nZ2VyQ29uZmlnID0ge1xuICBsb2dMZXZlbDogJ2RlYnVnJywgIC8vIG9wdGlvbnM6IHNpbGx5LCBkZWJ1ZywgdmVyYm9zZSwgaW5mb1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2dnZXJDb25maWc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvbG9nZ2VyQ29uZmlnLmpzIiwiY29uc3Qgd2luc3RvblNsYWNrV2ViSG9vayA9IHJlcXVpcmUoJ3dpbnN0b24tc2xhY2std2ViaG9vaycpLlNsYWNrV2ViSG9vaztcbmNvbnN0IHNsYWNrQ29uZmlnID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NsYWNrQ29uZmlnLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKHdpbnN0b24pID0+IHtcbiAgY29uc3Qge3NsYWNrV2ViSG9vaywgc2xhY2tFcnJvckNoYW5uZWwsIHNsYWNrSW5mb0NoYW5uZWx9ID0gc2xhY2tDb25maWc7XG4gIGlmIChzbGFja1dlYkhvb2spIHtcbiAgICAvLyBhZGQgYSB0cmFuc3BvcnQgZm9yIGVycm9ycyB0byBzbGFja1xuICAgIGlmIChzbGFja0Vycm9yQ2hhbm5lbCkge1xuICAgICAgd2luc3Rvbi5hZGQod2luc3RvblNsYWNrV2ViSG9vaywge1xuICAgICAgICBuYW1lICAgICAgOiAnc2xhY2stZXJyb3JzLXRyYW5zcG9ydCcsXG4gICAgICAgIGxldmVsICAgICA6ICd3YXJuJyxcbiAgICAgICAgd2ViaG9va1VybDogc2xhY2tXZWJIb29rLFxuICAgICAgICBjaGFubmVsICAgOiBzbGFja0Vycm9yQ2hhbm5lbCxcbiAgICAgICAgdXNlcm5hbWUgIDogJ3NwZWUuY2gnLFxuICAgICAgICBpY29uRW1vamkgOiAnOmZhY2Vfd2l0aF9oZWFkX2JhbmRhZ2U6JyxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgaWYgKHNsYWNrSW5mb0NoYW5uZWwpIHtcbiAgICAgIHdpbnN0b24uYWRkKHdpbnN0b25TbGFja1dlYkhvb2ssIHtcbiAgICAgICAgbmFtZSAgICAgIDogJ3NsYWNrLWluZm8tdHJhbnNwb3J0JyxcbiAgICAgICAgbGV2ZWwgICAgIDogJ2luZm8nLFxuICAgICAgICB3ZWJob29rVXJsOiBzbGFja1dlYkhvb2ssXG4gICAgICAgIGNoYW5uZWwgICA6IHNsYWNrSW5mb0NoYW5uZWwsXG4gICAgICAgIHVzZXJuYW1lICA6ICdzcGVlLmNoJyxcbiAgICAgICAgaWNvbkVtb2ppIDogJzpuZXJkX2ZhY2U6JyxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgLy8gc2VuZCB0ZXN0IG1lc3NhZ2VcbiAgICB3aW5zdG9uLmVycm9yKCdTbGFjayBcImVycm9yXCIgbG9nZ2luZyBpcyBvbmxpbmUuJyk7XG4gICAgd2luc3Rvbi5pbmZvKCdTbGFjayBcImluZm9cIiBsb2dnaW5nIGlzIG9ubGluZS4nKTtcbiAgfSBlbHNlIHtcbiAgICB3aW5zdG9uLndhcm4oJ1NsYWNrIGxvZ2dpbmcgaXMgbm90IGVuYWJsZWQgYmVjYXVzZSBubyBzbGFja1dlYkhvb2sgY29uZmlnIHZhciBwcm92aWRlZC4nKTtcbiAgfVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2NvbmZpZ3VyZVNsYWNrLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwid2luc3Rvbi1zbGFjay13ZWJob29rXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwid2luc3Rvbi1zbGFjay13ZWJob29rXCJcbi8vIG1vZHVsZSBpZCA9IDYwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImZ1bmN0aW9uIFNsYWNrQ29uZmlnICgpIHtcbiAgdGhpcy5zbGFja1dlYkhvb2sgICAgICA9ICdkZWZhdWx0JztcbiAgdGhpcy5zbGFja0Vycm9yQ2hhbm5lbCA9ICdkZWZhdWx0JztcbiAgdGhpcy5zbGFja0luZm9DaGFubmVsICA9ICdkZWZhdWx0Jztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNsYWNrQ29uZmlnKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvc2xhY2tDb25maWcuanMiLCJjb25zdCBQYXNzcG9ydExvY2FsU3RyYXRlZ3kgPSByZXF1aXJlKCdwYXNzcG9ydC1sb2NhbCcpLlN0cmF0ZWd5O1xuY29uc3QgbGJyeUFwaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeUFwaS5qcycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgZGIgPSByZXF1aXJlKCcuLi9tb2RlbHMvaW5kZXgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgUGFzc3BvcnRMb2NhbFN0cmF0ZWd5KFxuICB7XG4gICAgdXNlcm5hbWVGaWVsZDogJ3VzZXJuYW1lJyxcbiAgICBwYXNzd29yZEZpZWxkOiAncGFzc3dvcmQnLFxuICB9LFxuICAodXNlcm5hbWUsIHBhc3N3b3JkLCBkb25lKSA9PiB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoYG5ldyBjaGFubmVsIHNpZ251cCByZXF1ZXN0LiB1c2VyOiAke3VzZXJuYW1lfSBwYXNzOiAke3Bhc3N3b3JkfSAuYCk7XG4gICAgbGV0IHVzZXJJbmZvID0ge307XG4gICAgLy8gc2VydmVyLXNpZGUgdmFsaWRhdG9uIG9mIGlucHV0cyAodXNlcm5hbWUsIHBhc3N3b3JkKVxuXG4gICAgLy8gY3JlYXRlIHRoZSBjaGFubmVsIGFuZCByZXRyaWV2ZSB0aGUgbWV0YWRhdGFcbiAgICByZXR1cm4gbGJyeUFwaS5jcmVhdGVDaGFubmVsKGBAJHt1c2VybmFtZX1gKVxuICAgICAgLnRoZW4odHggPT4ge1xuICAgICAgICAvLyBjcmVhdGUgdXNlciByZWNvcmRcbiAgICAgICAgY29uc3QgdXNlckRhdGEgPSB7XG4gICAgICAgICAgdXNlck5hbWU6IHVzZXJuYW1lLFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXNzd29yZCxcbiAgICAgICAgfTtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ3VzZXJEYXRhID4nLCB1c2VyRGF0YSk7XG4gICAgICAgIC8vIGNyZWF0ZSB1c2VyIHJlY29yZFxuICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IHtcbiAgICAgICAgICBjaGFubmVsTmFtZSAgIDogYEAke3VzZXJuYW1lfWAsXG4gICAgICAgICAgY2hhbm5lbENsYWltSWQ6IHR4LmNsYWltX2lkLFxuICAgICAgICB9O1xuICAgICAgICBsb2dnZXIudmVyYm9zZSgnY2hhbm5lbERhdGEgPicsIGNoYW5uZWxEYXRhKTtcbiAgICAgICAgLy8gY3JlYXRlIGNlcnRpZmljYXRlIHJlY29yZFxuICAgICAgICBjb25zdCBjZXJ0aWZpY2F0ZURhdGEgPSB7XG4gICAgICAgICAgY2xhaW1JZDogdHguY2xhaW1faWQsXG4gICAgICAgICAgbmFtZSAgIDogYEAke3VzZXJuYW1lfWAsXG4gICAgICAgICAgLy8gYWRkcmVzcyxcbiAgICAgICAgfTtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ2NlcnRpZmljYXRlRGF0YSA+JywgY2VydGlmaWNhdGVEYXRhKTtcbiAgICAgICAgLy8gc2F2ZSB1c2VyIGFuZCBjZXJ0aWZpY2F0ZSB0byBkYlxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2RiLlVzZXIuY3JlYXRlKHVzZXJEYXRhKSwgZGIuQ2hhbm5lbC5jcmVhdGUoY2hhbm5lbERhdGEpLCBkYi5DZXJ0aWZpY2F0ZS5jcmVhdGUoY2VydGlmaWNhdGVEYXRhKV0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKChbbmV3VXNlciwgbmV3Q2hhbm5lbCwgbmV3Q2VydGlmaWNhdGVdKSA9PiB7XG4gICAgICAgIGxvZ2dlci52ZXJib3NlKCd1c2VyIGFuZCBjZXJ0aWZpY2F0ZSBzdWNjZXNzZnVsbHkgY3JlYXRlZCcpO1xuICAgICAgICAvLyBzdG9yZSB0aGUgcmVsZXZhbnQgbmV3VXNlciBpbmZvIHRvIGJlIHBhc3NlZCBiYWNrIGZvciByZXEuVXNlclxuICAgICAgICB1c2VySW5mb1snaWQnXSA9IG5ld1VzZXIuaWQ7XG4gICAgICAgIHVzZXJJbmZvWyd1c2VyTmFtZSddID0gbmV3VXNlci51c2VyTmFtZTtcbiAgICAgICAgdXNlckluZm9bJ2NoYW5uZWxOYW1lJ10gPSBuZXdDaGFubmVsLmNoYW5uZWxOYW1lO1xuICAgICAgICB1c2VySW5mb1snY2hhbm5lbENsYWltSWQnXSA9IG5ld0NoYW5uZWwuY2hhbm5lbENsYWltSWQ7XG4gICAgICAgIC8vIGFzc29jaWF0ZSB0aGUgaW5zdGFuY2VzXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbbmV3Q2VydGlmaWNhdGUuc2V0Q2hhbm5lbChuZXdDaGFubmVsKSwgbmV3Q2hhbm5lbC5zZXRVc2VyKG5ld1VzZXIpXSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBsb2dnZXIudmVyYm9zZSgndXNlciBhbmQgY2VydGlmaWNhdGUgc3VjY2Vzc2Z1bGx5IGFzc29jaWF0ZWQnKTtcbiAgICAgICAgcmV0dXJuIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQodXNlckluZm8uY2hhbm5lbENsYWltSWQsIHVzZXJJbmZvLmNoYW5uZWxOYW1lKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihzaG9ydENoYW5uZWxJZCA9PiB7XG4gICAgICAgIHVzZXJJbmZvWydzaG9ydENoYW5uZWxJZCddID0gc2hvcnRDaGFubmVsSWQ7XG4gICAgICAgIHJldHVybiBkb25lKG51bGwsIHVzZXJJbmZvKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ3NpZ251cCBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIGRvbmUoZXJyb3IpO1xuICAgICAgfSk7XG4gIH1cbik7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYXhpb3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJheGlvc1wiXG4vLyBtb2R1bGUgaWQgPSA2M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsYnJ5Q29uZmlnID0ge1xuICBhcGk6IHtcbiAgICBhcGlIb3N0OiAnbG9jYWxob3N0JyxcbiAgICBhcGlQb3J0OiAnNTI3OScsXG4gIH0sXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGxicnlDb25maWc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvbGJyeUNvbmZpZy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInVuaXZlcnNhbC1hbmFseXRpY3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ1bml2ZXJzYWwtYW5hbHl0aWNzXCJcbi8vIG1vZHVsZSBpZCA9IDY1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImZ1bmN0aW9uIE15c3FsQ29uZmlnICgpIHtcbiAgdGhpcy5kYXRhYmFzZSA9ICdkZWZhdWx0JztcbiAgdGhpcy51c2VybmFtZSA9ICdkZWZhdWx0JztcbiAgdGhpcy5wYXNzd29yZCA9ICdkZWZhdWx0Jztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IE15c3FsQ29uZmlnKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvbXlzcWxDb25maWcuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IHJldHVyblNob3J0SWQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvc2VxdWVsaXplSGVscGVycy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HLCBCT09MRUFOLCBJTlRFR0VSLCBURVhULCBERUNJTUFMIH0pID0+IHtcbiAgY29uc3QgQ2VydGlmaWNhdGUgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdDZXJ0aWZpY2F0ZScsXG4gICAge1xuICAgICAgYWRkcmVzczoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgYW1vdW50OiB7XG4gICAgICAgIHR5cGUgICA6IERFQ0lNQUwoMTksIDgpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNsYWltU2VxdWVuY2U6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBkZWNvZGVkQ2xhaW06IHtcbiAgICAgICAgdHlwZSAgIDogQk9PTEVBTixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBkZXB0aDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGVmZmVjdGl2ZUFtb3VudDoge1xuICAgICAgICB0eXBlICAgOiBERUNJTUFMKDE5LCA4KSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoYXNTaWduYXR1cmU6IHtcbiAgICAgICAgdHlwZSAgIDogQk9PTEVBTixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoZXg6IHtcbiAgICAgICAgdHlwZSAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG5hbWU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG5vdXQ6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB0eGlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB2YWxpZEF0SGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgb3V0cG9pbnQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHZhbHVlVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1UeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjZXJ0aWZpY2F0ZVZlcnNpb246IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGtleVR5cGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHB1YmxpY0tleToge1xuICAgICAgICB0eXBlICAgOiBURVhUKCdsb25nJyksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBDZXJ0aWZpY2F0ZS5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2VydGlmaWNhdGUuYmVsb25nc1RvKGRiLkNoYW5uZWwsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkID0gZnVuY3Rpb24gKGxvbmdDaGFubmVsSWQsIGNoYW5uZWxOYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBnZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkICR7Y2hhbm5lbE5hbWV9OiR7bG9uZ0NoYW5uZWxJZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHtuYW1lOiBjaGFubmVsTmFtZX0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2hhbm5lbChzKSBmb3VuZCB3aXRoIHRoYXQgY2hhbm5lbCBuYW1lJyk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXR1cm5TaG9ydElkKHJlc3VsdCwgbG9uZ0NoYW5uZWxJZCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkRnJvbVNob3J0Q2hhbm5lbElkID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZCgke2NoYW5uZWxOYW1lfSwgJHtjaGFubmVsQ2xhaW1JZH0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7XG4gICAgICAgICAgICBuYW1lICAgOiBjaGFubmVsTmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgICAgICAgJGxpa2U6IGAke2NoYW5uZWxDbGFpbUlkfSVgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9yZGVyOiBbWydoZWlnaHQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6IC8vIG5vdGUgcmVzdWx0cyBtdXN0IGJlIHNvcnRlZFxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXN1bHRbMF0uY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENlcnRpZmljYXRlLmdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUgPSBmdW5jdGlvbiAoY2hhbm5lbE5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUoJHtjaGFubmVsTmFtZX0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWU6IGNoYW5uZWxOYW1lIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2VmZmVjdGl2ZUFtb3VudCcsICdERVNDJ10sIFsnaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXN1bHRbMF0uY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENlcnRpZmljYXRlLnZhbGlkYXRlTG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChuYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGB2YWxpZGF0ZUxvbmdDaGFubmVsSWQoJHtuYW1lfSwgJHtjbGFpbUlkfSlgKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5maW5kT25lKHtcbiAgICAgICAgd2hlcmU6IHtuYW1lLCBjbGFpbUlkfSxcbiAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgcmVzb2x2ZShjbGFpbUlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NoYW5uZWxJZCgke2NoYW5uZWxOYW1lfSwgJHtjaGFubmVsQ2xhaW1JZH0pYCk7XG4gICAgaWYgKGNoYW5uZWxDbGFpbUlkICYmIChjaGFubmVsQ2xhaW1JZC5sZW5ndGggPT09IDQwKSkgeyAgLy8gaWYgYSBmdWxsIGNoYW5uZWwgaWQgaXMgcHJvdmlkZWRcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlTG9uZ0NoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbENsYWltSWQgJiYgY2hhbm5lbENsYWltSWQubGVuZ3RoIDwgNDApIHsgIC8vIGlmIGEgc2hvcnQgY2hhbm5lbCBpZCBpcyBwcm92aWRlZFxuICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRMb25nQ2hhbm5lbElkRnJvbUNoYW5uZWxOYW1lKGNoYW5uZWxOYW1lKTsgIC8vIGlmIG5vIGNoYW5uZWwgaWQgcHJvdmlkZWRcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIENlcnRpZmljYXRlO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvY2VydGlmaWNhdGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HIH0pID0+IHtcbiAgY29uc3QgQ2hhbm5lbCA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ0NoYW5uZWwnLFxuICAgIHtcbiAgICAgIGNoYW5uZWxOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGNoYW5uZWxDbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgQ2hhbm5lbC5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2hhbm5lbC5iZWxvbmdzVG8oZGIuVXNlcik7XG4gICAgQ2hhbm5lbC5oYXNPbmUoZGIuQ2VydGlmaWNhdGUpO1xuICB9O1xuXG4gIHJldHVybiBDaGFubmVsO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvY2hhbm5lbC5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHsgcmV0dXJuU2hvcnRJZCB9ID0gcmVxdWlyZSgnLi4vaGVscGVycy9zZXF1ZWxpemVIZWxwZXJzLmpzJyk7XG5jb25zdCB7IGFzc2V0RGVmYXVsdHM6IHsgdGh1bWJuYWlsOiBkZWZhdWx0VGh1bWJuYWlsIH0sIGRldGFpbHM6IHsgaG9zdCB9IH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvc2l0ZUNvbmZpZy5qcycpO1xuXG5mdW5jdGlvbiBkZXRlcm1pbmVGaWxlRXh0ZW5zaW9uRnJvbUNvbnRlbnRUeXBlIChjb250ZW50VHlwZSkge1xuICBzd2l0Y2ggKGNvbnRlbnRUeXBlKSB7XG4gICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgY2FzZSAnaW1hZ2UvanBnJzpcbiAgICAgIHJldHVybiAnanBlZyc7XG4gICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgIHJldHVybiAncG5nJztcbiAgICBjYXNlICdpbWFnZS9naWYnOlxuICAgICAgcmV0dXJuICdnaWYnO1xuICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICByZXR1cm4gJ21wNCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIGxvZ2dlci5kZWJ1Zygnc2V0dGluZyB1bmtub3duIGZpbGUgdHlwZSBhcyBmaWxlIGV4dGVuc2lvbiBqcGVnJyk7XG4gICAgICByZXR1cm4gJ2pwZWcnO1xuICB9XG59O1xuXG5mdW5jdGlvbiBkZXRlcm1pbmVUaHVtYm5haWwgKHN0b3JlZFRodW1ibmFpbCwgZGVmYXVsdFRodW1ibmFpbCkge1xuICBpZiAoc3RvcmVkVGh1bWJuYWlsID09PSAnJykge1xuICAgIHJldHVybiBkZWZhdWx0VGh1bWJuYWlsO1xuICB9XG4gIHJldHVybiBzdG9yZWRUaHVtYm5haWw7XG59O1xuXG5mdW5jdGlvbiBwcmVwYXJlQ2xhaW1EYXRhIChjbGFpbSkge1xuICAvLyBsb2dnZXIuZGVidWcoJ3ByZXBhcmluZyBjbGFpbSBkYXRhIGJhc2VkIG9uIHJlc29sdmVkIGRhdGE6JywgY2xhaW0pO1xuICBjbGFpbVsndGh1bWJuYWlsJ10gPSBkZXRlcm1pbmVUaHVtYm5haWwoY2xhaW0udGh1bWJuYWlsLCBkZWZhdWx0VGh1bWJuYWlsKTtcbiAgY2xhaW1bJ2ZpbGVFeHQnXSA9IGRldGVybWluZUZpbGVFeHRlbnNpb25Gcm9tQ29udGVudFR5cGUoY2xhaW0uY29udGVudFR5cGUpO1xuICBjbGFpbVsnaG9zdCddID0gaG9zdDtcbiAgcmV0dXJuIGNsYWltO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgSU5URUdFUiwgVEVYVCwgREVDSU1BTCB9KSA9PiB7XG4gIGNvbnN0IENsYWltID0gc2VxdWVsaXplLmRlZmluZShcbiAgICAnQ2xhaW0nLFxuICAgIHtcbiAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGFtb3VudDoge1xuICAgICAgICB0eXBlICAgOiBERUNJTUFMKDE5LCA4KSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbVNlcXVlbmNlOiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVjb2RlZENsYWltOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVwdGg6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBlZmZlY3RpdmVBbW91bnQ6IHtcbiAgICAgICAgdHlwZSAgIDogREVDSU1BTCgxOSwgOCksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGFzU2lnbmF0dXJlOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGV4OiB7XG4gICAgICAgIHR5cGUgICA6IFRFWFQoJ2xvbmcnKSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBuYW1lOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBub3V0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdHhpZDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdmFsaWRBdEhlaWdodDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG91dHBvaW50OiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbVR5cGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNlcnRpZmljYXRlSWQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGF1dGhvcjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVzY3JpcHRpb246IHtcbiAgICAgICAgdHlwZSAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGxhbmd1YWdlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBsaWNlbnNlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBsaWNlbnNlVXJsOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBuc2Z3OiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgcHJldmlldzoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdGh1bWJuYWlsOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB0aXRsZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbWV0YWRhdGFWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjb250ZW50VHlwZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc291cmNlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzb3VyY2VUeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzb3VyY2VWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzdHJlYW1WZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB2YWx1ZVZlcnNpb246IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNoYW5uZWxOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICAgIGRlZmF1bHQgIDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIENsYWltLmFzc29jaWF0ZSA9IGRiID0+IHtcbiAgICBDbGFpbS5iZWxvbmdzVG8oZGIuRmlsZSwge1xuICAgICAgZm9yZWlnbktleToge1xuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICB9LFxuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCA9IGZ1bmN0aW9uIChjbGFpbUlkLCBjbGFpbU5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYENsYWltLmdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCBmb3IgJHtjbGFpbU5hbWV9IyR7Y2xhaW1JZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgbmFtZTogY2xhaW1OYW1lIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2xhaW0ocykgZm91bmQgd2l0aCB0aGF0IGNsYWltIG5hbWUnKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJlc29sdmUocmV0dXJuU2hvcnRJZChyZXN1bHQsIGNsYWltSWQpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0QWxsQ2hhbm5lbENsYWltcyA9IGZ1bmN0aW9uIChjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xhaW0uZ2V0QWxsQ2hhbm5lbENsYWltcyBmb3IgJHtjaGFubmVsQ2xhaW1JZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgY2VydGlmaWNhdGVJZDogY2hhbm5lbENsYWltSWQgfSxcbiAgICAgICAgICBvcmRlcjogW1snaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgICByYXcgIDogdHJ1ZSwgIC8vIHJldHVybnMgYW4gYXJyYXkgb2Ygb25seSBkYXRhLCBub3QgYW4gYXJyYXkgb2YgaW5zdGFuY2VzXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNoYW5uZWxDbGFpbXNBcnJheSA9PiB7XG4gICAgICAgICAgLy8gbG9nZ2VyLmRlYnVnKCdjaGFubmVsY2xhaW1zYXJyYXkgbGVuZ3RoOicsIGNoYW5uZWxDbGFpbXNBcnJheS5sZW5ndGgpO1xuICAgICAgICAgIHN3aXRjaCAoY2hhbm5lbENsYWltc0FycmF5Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGNoYW5uZWxDbGFpbXNBcnJheS5mb3JFYWNoKGNsYWltID0+IHtcbiAgICAgICAgICAgICAgICBjbGFpbVsnZmlsZUV4dCddID0gZGV0ZXJtaW5lRmlsZUV4dGVuc2lvbkZyb21Db250ZW50VHlwZShjbGFpbS5jb250ZW50VHlwZSk7XG4gICAgICAgICAgICAgICAgY2xhaW1bJ3RodW1ibmFpbCddID0gZGV0ZXJtaW5lVGh1bWJuYWlsKGNsYWltLnRodW1ibmFpbCwgZGVmYXVsdFRodW1ibmFpbCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNsYWltO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoY2hhbm5lbENsYWltc0FycmF5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0Q2xhaW1JZEJ5TG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBmaW5kaW5nIGNsYWltIGlkIGZvciBjbGFpbSAke2NsYWltTmFtZX0gZnJvbSBjaGFubmVsICR7Y2hhbm5lbENsYWltSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWU6IGNsYWltTmFtZSwgY2VydGlmaWNhdGVJZDogY2hhbm5lbENsYWltSWQgfSxcbiAgICAgICAgICBvcmRlcjogW1snaWQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGAke3Jlc3VsdC5sZW5ndGh9IHJlY29yZHMgZm91bmQgZm9yIFwiJHtjbGFpbU5hbWV9XCIgaW4gY2hhbm5lbCBcIiR7Y2hhbm5lbENsYWltSWR9XCJgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRMb25nQ2xhaW1JZEZyb21TaG9ydENsYWltSWQgPSBmdW5jdGlvbiAobmFtZSwgc2hvcnRJZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZToge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgICAgICAgJGxpa2U6IGAke3Nob3J0SWR9JWAsXG4gICAgICAgICAgICB9fSxcbiAgICAgICAgICBvcmRlcjogW1snaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OiAvLyBub3RlIHJlc3VsdHMgbXVzdCBiZSBzb3J0ZWRcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRUb3BGcmVlQ2xhaW1JZEJ5Q2xhaW1OYW1lID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgbmFtZSB9LFxuICAgICAgICAgIG9yZGVyOiBbWydlZmZlY3RpdmVBbW91bnQnLCAnREVTQyddLCBbJ2hlaWdodCcsICdBU0MnXV0sICAvLyBub3RlOiBtYXliZSBoZWlnaHQgYW5kIGVmZmVjdGl2ZSBhbW91bnQgbmVlZCB0byBzd2l0Y2g/XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdsZW5ndGggb2YgcmVzdWx0JywgcmVzdWx0Lmxlbmd0aCk7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmRhdGFWYWx1ZXMuY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLnZhbGlkYXRlTG9uZ0NsYWltSWQgPSBmdW5jdGlvbiAobmFtZSwgY2xhaW1JZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmZpbmRPbmUoe1xuICAgICAgICB3aGVyZToge25hbWUsIGNsYWltSWR9LFxuICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXNvbHZlKGNsYWltSWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldExvbmdDbGFpbUlkID0gZnVuY3Rpb24gKGNsYWltTmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NsYWltSWQoJHtjbGFpbU5hbWV9LCAke2NsYWltSWR9KWApO1xuICAgIGlmIChjbGFpbUlkICYmIChjbGFpbUlkLmxlbmd0aCA9PT0gNDApKSB7ICAvLyBpZiBhIGZ1bGwgY2xhaW0gaWQgaXMgcHJvdmlkZWRcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlTG9uZ0NsYWltSWQoY2xhaW1OYW1lLCBjbGFpbUlkKTtcbiAgICB9IGVsc2UgaWYgKGNsYWltSWQgJiYgY2xhaW1JZC5sZW5ndGggPCA0MCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9uZ0NsYWltSWRGcm9tU2hvcnRDbGFpbUlkKGNsYWltTmFtZSwgY2xhaW1JZCk7ICAvLyBpZiBhIHNob3J0IGNsYWltIGlkIGlzIHByb3ZpZGVkXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFRvcEZyZWVDbGFpbUlkQnlDbGFpbU5hbWUoY2xhaW1OYW1lKTsgIC8vIGlmIG5vIGNsYWltIGlkIGlzIHByb3ZpZGVkXG4gICAgfVxuICB9O1xuXG4gIENsYWltLnJlc29sdmVDbGFpbSA9IGZ1bmN0aW9uIChuYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbGFpbS5yZXNvbHZlQ2xhaW06ICR7bmFtZX0gJHtjbGFpbUlkfWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZTogeyBuYW1lLCBjbGFpbUlkIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNsYWltQXJyYXkgPT4ge1xuICAgICAgICAgIHN3aXRjaCAoY2xhaW1BcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHByZXBhcmVDbGFpbURhdGEoY2xhaW1BcnJheVswXS5kYXRhVmFsdWVzKSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYG1vcmUgdGhhbiBvbmUgcmVjb3JkIG1hdGNoZXMgJHtuYW1lfSMke2NsYWltSWR9IGluIGRiLkNsYWltYCk7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHByZXBhcmVDbGFpbURhdGEoY2xhaW1BcnJheVswXS5kYXRhVmFsdWVzKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBDbGFpbTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2NsYWltLmpzIiwibW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgSU5URUdFUiB9KSA9PiB7XG4gIGNvbnN0IEZpbGUgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdGaWxlJyxcbiAgICB7XG4gICAgICBuYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgYWRkcmVzczoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBvdXRwb2ludDoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBJTlRFR0VSLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0ICA6IDAsXG4gICAgICB9LFxuICAgICAgZmlsZU5hbWU6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZmlsZVBhdGg6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZmlsZVR5cGU6IHtcbiAgICAgICAgdHlwZTogU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIG5zZnc6IHtcbiAgICAgICAgdHlwZSAgICAgICAgOiBCT09MRUFOLFxuICAgICAgICBhbGxvd051bGwgICA6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIHRyZW5kaW5nRWxpZ2libGU6IHtcbiAgICAgICAgdHlwZSAgICAgICAgOiBCT09MRUFOLFxuICAgICAgICBhbGxvd051bGwgICA6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IHRydWUsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBGaWxlLmFzc29jaWF0ZSA9IGRiID0+IHtcbiAgICBGaWxlLmhhc01hbnkoZGIuUmVxdWVzdCk7XG4gICAgRmlsZS5oYXNPbmUoZGIuQ2xhaW0pO1xuICB9O1xuXG4gIEZpbGUuZ2V0UmVjZW50Q2xhaW1zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmRBbGwoe1xuICAgICAgd2hlcmU6IHsgbnNmdzogZmFsc2UsIHRyZW5kaW5nRWxpZ2libGU6IHRydWUgfSxcbiAgICAgIG9yZGVyOiBbWydjcmVhdGVkQXQnLCAnREVTQyddXSxcbiAgICAgIGxpbWl0OiAyNSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gRmlsZTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2ZpbGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HLCBCT09MRUFOLCBURVhUIH0pID0+IHtcbiAgY29uc3QgUmVxdWVzdCA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ1JlcXVlc3QnLFxuICAgIHtcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICB1cmw6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgaXBBZGRyZXNzOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICB9LFxuICAgICAgcmVzdWx0OiB7XG4gICAgICAgIHR5cGUgICAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICAgIGRlZmF1bHQgIDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIFJlcXVlc3QuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIFJlcXVlc3QuYmVsb25nc1RvKGRiLkZpbGUsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gUmVxdWVzdDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL3JlcXVlc3QuanMiLCIndXNlIHN0cmljdCc7XG5jb25zdCBiY3J5cHQgPSByZXF1aXJlKCdiY3J5cHQnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORyB9KSA9PiB7XG4gIGNvbnN0IFVzZXIgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdVc2VyJyxcbiAgICB7XG4gICAgICB1c2VyTmFtZToge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBwYXNzd29yZDoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIFVzZXIuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIFVzZXIuaGFzT25lKGRiLkNoYW5uZWwpO1xuICB9O1xuXG4gIFVzZXIucHJvdG90eXBlLmNvbXBhcmVQYXNzd29yZCA9IGZ1bmN0aW9uIChwYXNzd29yZCkge1xuICAgIHJldHVybiBiY3J5cHQuY29tcGFyZShwYXNzd29yZCwgdGhpcy5wYXNzd29yZCk7XG4gIH07XG5cbiAgVXNlci5wcm90b3R5cGUuY2hhbmdlUGFzc3dvcmQgPSBmdW5jdGlvbiAobmV3UGFzc3dvcmQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gZ2VuZXJhdGUgYSBzYWx0IHN0cmluZyB0byB1c2UgZm9yIGhhc2hpbmdcbiAgICAgIGJjcnlwdC5nZW5TYWx0KChzYWx0RXJyb3IsIHNhbHQpID0+IHtcbiAgICAgICAgaWYgKHNhbHRFcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignc2FsdCBlcnJvcicsIHNhbHRFcnJvcik7XG4gICAgICAgICAgcmVqZWN0KHNhbHRFcnJvcik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdlbmVyYXRlIGEgaGFzaGVkIHZlcnNpb24gb2YgdGhlIHVzZXIncyBwYXNzd29yZFxuICAgICAgICBiY3J5cHQuaGFzaChuZXdQYXNzd29yZCwgc2FsdCwgKGhhc2hFcnJvciwgaGFzaCkgPT4ge1xuICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIGVycm9yIHdpdGggdGhlIGhhc2ggZ2VuZXJhdGlvbiByZXR1cm4gdGhlIGVycm9yXG4gICAgICAgICAgaWYgKGhhc2hFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdoYXNoIGVycm9yJywgaGFzaEVycm9yKTtcbiAgICAgICAgICAgIHJlamVjdChoYXNoRXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyByZXBsYWNlIHRoZSBjdXJyZW50IHBhc3N3b3JkIHdpdGggdGhlIG5ldyBoYXNoXG4gICAgICAgICAgdGhpc1xuICAgICAgICAgICAgLnVwZGF0ZSh7cGFzc3dvcmQ6IGhhc2h9KVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIHByZS1zYXZlIGhvb2sgbWV0aG9kIHRvIGhhc2ggdGhlIHVzZXIncyBwYXNzd29yZCBiZWZvcmUgdGhlIHVzZXIncyBpbmZvIGlzIHNhdmVkIHRvIHRoZSBkYi5cbiAgVXNlci5ob29rKCdiZWZvcmVDcmVhdGUnLCAodXNlciwgb3B0aW9ucykgPT4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnVXNlci5iZWZvcmVDcmVhdGUgaG9vay4uLicpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBnZW5lcmF0ZSBhIHNhbHQgc3RyaW5nIHRvIHVzZSBmb3IgaGFzaGluZ1xuICAgICAgYmNyeXB0LmdlblNhbHQoKHNhbHRFcnJvciwgc2FsdCkgPT4ge1xuICAgICAgICBpZiAoc2FsdEVycm9yKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdzYWx0IGVycm9yJywgc2FsdEVycm9yKTtcbiAgICAgICAgICByZWplY3Qoc2FsdEVycm9yKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2VuZXJhdGUgYSBoYXNoZWQgdmVyc2lvbiBvZiB0aGUgdXNlcidzIHBhc3N3b3JkXG4gICAgICAgIGJjcnlwdC5oYXNoKHVzZXIucGFzc3dvcmQsIHNhbHQsIChoYXNoRXJyb3IsIGhhc2gpID0+IHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBlcnJvciB3aXRoIHRoZSBoYXNoIGdlbmVyYXRpb24gcmV0dXJuIHRoZSBlcnJvclxuICAgICAgICAgIGlmIChoYXNoRXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignaGFzaCBlcnJvcicsIGhhc2hFcnJvcik7XG4gICAgICAgICAgICByZWplY3QoaGFzaEVycm9yKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gcmVwbGFjZSB0aGUgcGFzc3dvcmQgc3RyaW5nIHdpdGggdGhlIGhhc2ggcGFzc3dvcmQgdmFsdWVcbiAgICAgICAgICB1c2VyLnBhc3N3b3JkID0gaGFzaDtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiBVc2VyO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvdXNlci5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImJjcnlwdFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImJjcnlwdFwiXG4vLyBtb2R1bGUgaWQgPSA3M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBQYXNzcG9ydExvY2FsU3RyYXRlZ3kgPSByZXF1aXJlKCdwYXNzcG9ydC1sb2NhbCcpLlN0cmF0ZWd5O1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgZGIgPSByZXF1aXJlKCcuLi9tb2RlbHMvaW5kZXgnKTtcblxuY29uc3QgcmV0dXJuVXNlckFuZENoYW5uZWxJbmZvID0gKHVzZXJJbnN0YW5jZSkgPT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCB1c2VySW5mbyA9IHt9O1xuICAgIHVzZXJJbmZvWydpZCddID0gdXNlckluc3RhbmNlLmlkO1xuICAgIHVzZXJJbmZvWyd1c2VyTmFtZSddID0gdXNlckluc3RhbmNlLnVzZXJOYW1lO1xuICAgIHVzZXJJbnN0YW5jZVxuICAgICAgLmdldENoYW5uZWwoKVxuICAgICAgLnRoZW4oKHtjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWR9KSA9PiB7XG4gICAgICAgIHVzZXJJbmZvWydjaGFubmVsTmFtZSddID0gY2hhbm5lbE5hbWU7XG4gICAgICAgIHVzZXJJbmZvWydjaGFubmVsQ2xhaW1JZCddID0gY2hhbm5lbENsYWltSWQ7XG4gICAgICAgIHJldHVybiBkYi5DZXJ0aWZpY2F0ZS5nZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkKGNoYW5uZWxDbGFpbUlkLCBjaGFubmVsTmFtZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oc2hvcnRDaGFubmVsSWQgPT4ge1xuICAgICAgICB1c2VySW5mb1snc2hvcnRDaGFubmVsSWQnXSA9IHNob3J0Q2hhbm5lbElkO1xuICAgICAgICByZXNvbHZlKHVzZXJJbmZvKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgUGFzc3BvcnRMb2NhbFN0cmF0ZWd5KFxuICB7XG4gICAgdXNlcm5hbWVGaWVsZDogJ3VzZXJuYW1lJyxcbiAgICBwYXNzd29yZEZpZWxkOiAncGFzc3dvcmQnLFxuICB9LFxuICAodXNlcm5hbWUsIHBhc3N3b3JkLCBkb25lKSA9PiB7XG4gICAgcmV0dXJuIGRiLlVzZXJcbiAgICAgIC5maW5kT25lKHtcbiAgICAgICAgd2hlcmU6IHt1c2VyTmFtZTogdXNlcm5hbWV9LFxuICAgICAgfSlcbiAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ25vIHVzZXIgZm91bmQnKTtcbiAgICAgICAgICByZXR1cm4gZG9uZShudWxsLCBmYWxzZSwge21lc3NhZ2U6ICdJbmNvcnJlY3QgdXNlcm5hbWUgb3IgcGFzc3dvcmQnfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVzZXIuY29tcGFyZVBhc3N3b3JkKHBhc3N3b3JkKVxuICAgICAgICAgIC50aGVuKGlzTWF0Y2ggPT4ge1xuICAgICAgICAgICAgaWYgKCFpc01hdGNoKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnaW5jb3JyZWN0IHBhc3N3b3JkJyk7XG4gICAgICAgICAgICAgIHJldHVybiBkb25lKG51bGwsIGZhbHNlLCB7bWVzc2FnZTogJ0luY29ycmVjdCB1c2VybmFtZSBvciBwYXNzd29yZCd9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnUGFzc3dvcmQgd2FzIGEgbWF0Y2gsIHJldHVybmluZyBVc2VyJyk7XG4gICAgICAgICAgICByZXR1cm4gcmV0dXJuVXNlckFuZENoYW5uZWxJbmZvKHVzZXIpXG4gICAgICAgICAgICAgIC50aGVuKHVzZXJJbmZvID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZG9uZShudWxsLCB1c2VySW5mbyk7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgcmV0dXJuIGRvbmUoZXJyb3IpO1xuICAgICAgfSk7XG4gIH0sXG4pO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3Bhc3Nwb3J0L2xvY2FsLWxvZ2luLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgcGFzc3BvcnQgPSByZXF1aXJlKCdwYXNzcG9ydCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChhcHApID0+IHtcbiAgLy8gcm91dGUgZm9yIHNpZ24gdXBcbiAgYXBwLnBvc3QoJy9zaWdudXAnLCBwYXNzcG9ydC5hdXRoZW50aWNhdGUoJ2xvY2FsLXNpZ251cCcpLCAocmVxLCByZXMpID0+IHtcbiAgICBsb2dnZXIudmVyYm9zZShgc3VjY2Vzc2Z1bCBzaWdudXAgZm9yICR7cmVxLnVzZXIuY2hhbm5lbE5hbWV9YCk7XG4gICAgcmVzLnN0YXR1cygyMDApLmpzb24oe1xuICAgICAgc3VjY2VzcyAgICAgICA6IHRydWUsXG4gICAgICBjaGFubmVsTmFtZSAgIDogcmVxLnVzZXIuY2hhbm5lbE5hbWUsXG4gICAgICBjaGFubmVsQ2xhaW1JZDogcmVxLnVzZXIuY2hhbm5lbENsYWltSWQsXG4gICAgICBzaG9ydENoYW5uZWxJZDogcmVxLnVzZXIuc2hvcnRDaGFubmVsSWQsXG4gICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSBmb3IgbG9nIGluXG4gIGFwcC5wb3N0KCcvbG9naW4nLCAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICBwYXNzcG9ydC5hdXRoZW50aWNhdGUoJ2xvY2FsLWxvZ2luJywgKGVyciwgdXNlciwgaW5mbykgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXR1cm4gbmV4dChlcnIpO1xuICAgICAgfVxuICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgbWVzc2FnZTogaW5mby5tZXNzYWdlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5kZWJ1Zygnc3VjY2Vzc2Z1bCBsb2dpbicpO1xuICAgICAgcmVxLmxvZ0luKHVzZXIsIChlcnIpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiBuZXh0KGVycik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtcbiAgICAgICAgICBzdWNjZXNzICAgICAgIDogdHJ1ZSxcbiAgICAgICAgICBjaGFubmVsTmFtZSAgIDogcmVxLnVzZXIuY2hhbm5lbE5hbWUsXG4gICAgICAgICAgY2hhbm5lbENsYWltSWQ6IHJlcS51c2VyLmNoYW5uZWxDbGFpbUlkLFxuICAgICAgICAgIHNob3J0Q2hhbm5lbElkOiByZXEudXNlci5zaG9ydENoYW5uZWxJZCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KShyZXEsIHJlcywgbmV4dCk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBsb2cgb3V0XG4gIGFwcC5nZXQoJy9sb2dvdXQnLCAocmVxLCByZXMpID0+IHtcbiAgICByZXEubG9nb3V0KCk7XG4gICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIG1lc3NhZ2U6ICd5b3Ugc3VjY2Vzc2Z1bGx5IGxvZ2dlZCBvdXQnfSk7XG4gIH0pO1xuICAvLyBzZWUgaWYgdXNlciBpcyBhdXRoZW50aWNhdGVkLCBhbmQgcmV0dXJuIGNyZWRlbnRpYWxzIGlmIHNvXG4gIGFwcC5nZXQoJy91c2VyJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgaWYgKHJlcS51c2VyKSB7XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogcmVxLnVzZXJ9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzLnN0YXR1cyg0MDEpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAndXNlciBpcyBub3QgbG9nZ2VkIGluJ30pO1xuICAgIH1cbiAgfSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hdXRoLXJvdXRlcy5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IG11bHRpcGFydCA9IHJlcXVpcmUoJ2Nvbm5lY3QtbXVsdGlwYXJ0eScpO1xuY29uc3QgeyBwdWJsaXNoaW5nOiB7IHVwbG9hZERpcmVjdG9yeSB9LCBkZXRhaWxzOiB7IGhvc3QgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcbmNvbnN0IG11bHRpcGFydE1pZGRsZXdhcmUgPSBtdWx0aXBhcnQoe3VwbG9hZERpcjogdXBsb2FkRGlyZWN0b3J5fSk7XG5jb25zdCBkYiA9IHJlcXVpcmUoJy4uL21vZGVscy9pbmRleCcpO1xuY29uc3QgeyBjbGFpbU5hbWVJc0F2YWlsYWJsZSwgY2hlY2tDaGFubmVsQXZhaWxhYmlsaXR5LCBwdWJsaXNoIH0gPSByZXF1aXJlKCcuLi9jb250cm9sbGVycy9wdWJsaXNoQ29udHJvbGxlci5qcycpO1xuY29uc3QgeyBnZXRDbGFpbUxpc3QsIHJlc29sdmVVcmksIGdldENsYWltIH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2xicnlBcGkuanMnKTtcbmNvbnN0IHsgYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEsIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcywgY3JlYXRlVGh1bWJuYWlsUHVibGlzaFBhcmFtcywgcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEJvZHksIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcywgY3JlYXRlRmlsZURhdGEgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMnKTtcbmNvbnN0IGVycm9ySGFuZGxlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcbmNvbnN0IHsgc2VuZEdBVGltaW5nRXZlbnQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzJyk7XG5jb25zdCB7IGF1dGhlbnRpY2F0ZVVzZXIgfSA9IHJlcXVpcmUoJy4uL2F1dGgvYXV0aGVudGljYXRpb24uanMnKTtcbmNvbnN0IHsgZ2V0Q2hhbm5lbERhdGEsIGdldENoYW5uZWxDbGFpbXMsIGdldENsYWltSWQgfSA9IHJlcXVpcmUoJy4uL2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcycpO1xuXG5jb25zdCBOT19DSEFOTkVMID0gJ05PX0NIQU5ORUwnO1xuY29uc3QgTk9fQ0xBSU0gPSAnTk9fQ0xBSU0nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChhcHApID0+IHtcbiAgLy8gcm91dGUgdG8gY2hlY2sgd2hldGhlciBzaXRlIGhhcyBwdWJsaXNoZWQgdG8gYSBjaGFubmVsXG4gIGFwcC5nZXQoJy9hcGkvY2hhbm5lbC9hdmFpbGFiaWxpdHkvOm5hbWUnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtczogeyBuYW1lIH0gfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGNoZWNrQ2hhbm5lbEF2YWlsYWJpbGl0eShuYW1lKVxuICAgICAgLnRoZW4oYXZhaWxhYmxlTmFtZSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKGF2YWlsYWJsZU5hbWUpO1xuICAgICAgICBzZW5kR0FUaW1pbmdFdmVudCgnZW5kLXRvLWVuZCcsICdjbGFpbSBuYW1lIGF2YWlsYWJpbGl0eScsIG5hbWUsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gZ2V0IGEgc2hvcnQgY2hhbm5lbCBpZCBmcm9tIGxvbmcgY2hhbm5lbCBJZFxuICBhcHAuZ2V0KCcvYXBpL2NoYW5uZWwvc2hvcnQtaWQvOmxvbmdJZC86bmFtZScsICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQocGFyYW1zLmxvbmdJZCwgcGFyYW1zLm5hbWUpXG4gICAgICAudGhlbihzaG9ydElkID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oc2hvcnRJZCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIGFwcC5nZXQoJy9hcGkvY2hhbm5lbC9kYXRhLzpjaGFubmVsTmFtZS86Y2hhbm5lbENsYWltSWQnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IHBhcmFtcy5jaGFubmVsTmFtZTtcbiAgICBsZXQgY2hhbm5lbENsYWltSWQgPSBwYXJhbXMuY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKGNoYW5uZWxDbGFpbUlkID09PSAnbm9uZScpIGNoYW5uZWxDbGFpbUlkID0gbnVsbDtcbiAgICBnZXRDaGFubmVsRGF0YShjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIDApXG4gICAgICAudGhlbihkYXRhID0+IHtcbiAgICAgICAgaWYgKGRhdGEgPT09IE5PX0NIQU5ORUwpIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gbWF0Y2hpbmcgY2hhbm5lbCB3YXMgZm91bmQnfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGF9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgYXBwLmdldCgnL2FwaS9jaGFubmVsL2NsYWltcy86Y2hhbm5lbE5hbWUvOmNoYW5uZWxDbGFpbUlkLzpwYWdlJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgY2hhbm5lbE5hbWUgPSBwYXJhbXMuY2hhbm5lbE5hbWU7XG4gICAgbGV0IGNoYW5uZWxDbGFpbUlkID0gcGFyYW1zLmNoYW5uZWxDbGFpbUlkO1xuICAgIGlmIChjaGFubmVsQ2xhaW1JZCA9PT0gJ25vbmUnKSBjaGFubmVsQ2xhaW1JZCA9IG51bGw7XG4gICAgY29uc3QgcGFnZSA9IHBhcmFtcy5wYWdlO1xuICAgIGdldENoYW5uZWxDbGFpbXMoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBwYWdlKVxuICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgIGlmIChkYXRhID09PSBOT19DSEFOTkVMKSB7XG4gICAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ05vIG1hdGNoaW5nIGNoYW5uZWwgd2FzIGZvdW5kJ30pO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIHJ1biBhIGNsYWltX2xpc3QgcmVxdWVzdCBvbiB0aGUgZGFlbW9uXG4gIGFwcC5nZXQoJy9hcGkvY2xhaW0vbGlzdC86bmFtZScsICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGdldENsYWltTGlzdChwYXJhbXMubmFtZSlcbiAgICAgIC50aGVuKGNsYWltc0xpc3QgPT4ge1xuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbihjbGFpbXNMaXN0KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gZ2V0IGFuIGFzc2V0XG4gIGFwcC5nZXQoJy9hcGkvY2xhaW0vZ2V0LzpuYW1lLzpjbGFpbUlkJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IHBhcmFtcy5uYW1lO1xuICAgIGNvbnN0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcbiAgICAvLyByZXNvbHZlIHRoZSBjbGFpbVxuICAgIGRiLkNsYWltLnJlc29sdmVDbGFpbShuYW1lLCBjbGFpbUlkKVxuICAgICAgLnRoZW4ocmVzb2x2ZVJlc3VsdCA9PiB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSBhIGNsYWltIGFjdHVhbGx5IGV4aXN0cyBhdCB0aGF0IHVyaVxuICAgICAgICBpZiAoIXJlc29sdmVSZXN1bHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIG1hdGNoaW5nIHVyaSBmb3VuZCBpbiBDbGFpbSB0YWJsZScpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBmaWxlRGF0YSA9IGNyZWF0ZUZpbGVEYXRhKHJlc29sdmVSZXN1bHQpO1xuICAgICAgICAvLyBnZXQgdGhlIGNsYWltXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZmlsZURhdGEsIGdldENsYWltKGAke25hbWV9IyR7Y2xhaW1JZH1gKV0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKChbIGZpbGVEYXRhLCBnZXRSZXN1bHQgXSkgPT4ge1xuICAgICAgICBmaWxlRGF0YSA9IGFkZEdldFJlc3VsdHNUb0ZpbGVEYXRhKGZpbGVEYXRhLCBnZXRSZXN1bHQpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2RiLnVwc2VydChkYi5GaWxlLCBmaWxlRGF0YSwge25hbWUsIGNsYWltSWR9LCAnRmlsZScpLCBnZXRSZXN1bHRdKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoWyBmaWxlUmVjb3JkLCB7bWVzc2FnZSwgY29tcGxldGVkfSBdKSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHsgc3VjY2VzczogdHJ1ZSwgbWVzc2FnZSwgY29tcGxldGVkIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBjaGVjayB3aGV0aGVyIHRoaXMgc2l0ZSBwdWJsaXNoZWQgdG8gYSBjbGFpbVxuICBhcHAuZ2V0KCcvYXBpL2NsYWltL2F2YWlsYWJpbGl0eS86bmFtZScsICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zOiB7IG5hbWUgfSB9LCByZXMpID0+IHtcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgY2xhaW1OYW1lSXNBdmFpbGFibGUobmFtZSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHJlc3VsdCk7XG4gICAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdlbmQtdG8tZW5kJywgJ2NsYWltIG5hbWUgYXZhaWxhYmlsaXR5JywgbmFtZSwgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBydW4gYSByZXNvbHZlIHJlcXVlc3Qgb24gdGhlIGRhZW1vblxuICBhcHAuZ2V0KCcvYXBpL2NsYWltL3Jlc29sdmUvOm5hbWUvOmNsYWltSWQnLCAoeyBoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICByZXNvbHZlVXJpKGAke3BhcmFtcy5uYW1lfSMke3BhcmFtcy5jbGFpbUlkfWApXG4gICAgICAudGhlbihyZXNvbHZlZFVyaSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHJlc29sdmVkVXJpKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gcnVuIGEgcHVibGlzaCByZXF1ZXN0IG9uIHRoZSBkYWVtb25cbiAgYXBwLnBvc3QoJy9hcGkvY2xhaW0vcHVibGlzaCcsIG11bHRpcGFydE1pZGRsZXdhcmUsICh7IGJvZHksIGZpbGVzLCBoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwsIHVzZXIgfSwgcmVzKSA9PiB7XG4gICAgLy8gZGVmaW5lIHZhcmlhYmxlc1xuICAgIGxldCAgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgY2hhbm5lbFBhc3N3b3JkLCBkZXNjcmlwdGlvbiwgZmlsZU5hbWUsIGZpbGVQYXRoLCBmaWxlVHlwZSwgZ2FTdGFydFRpbWUsIGxpY2Vuc2UsIG5hbWUsIG5zZncsIHRodW1ibmFpbCwgdGh1bWJuYWlsRmlsZU5hbWUsIHRodW1ibmFpbEZpbGVQYXRoLCB0aHVtYm5haWxGaWxlVHlwZSwgdGl0bGU7XG4gICAgLy8gcmVjb3JkIHRoZSBzdGFydCB0aW1lIG9mIHRoZSByZXF1ZXN0XG4gICAgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIC8vIHZhbGlkYXRlIHRoZSBib2R5IGFuZCBmaWxlcyBvZiB0aGUgcmVxdWVzdFxuICAgIHRyeSB7XG4gICAgICAvLyB2YWxpZGF0ZUFwaVB1Ymxpc2hSZXF1ZXN0KGJvZHksIGZpbGVzKTtcbiAgICAgICh7bmFtZSwgbnNmdywgbGljZW5zZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCB0aHVtYm5haWx9ID0gcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEJvZHkoYm9keSkpO1xuICAgICAgKHtmaWxlTmFtZSwgZmlsZVBhdGgsIGZpbGVUeXBlLCB0aHVtYm5haWxGaWxlTmFtZSwgdGh1bWJuYWlsRmlsZVBhdGgsIHRodW1ibmFpbEZpbGVUeXBlfSA9IHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyhmaWxlcykpO1xuICAgICAgKHtjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBjaGFubmVsUGFzc3dvcmR9ID0gYm9keSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgICB9XG4gICAgLy8gY2hlY2sgY2hhbm5lbCBhdXRob3JpemF0aW9uXG4gICAgUHJvbWlzZS5hbGwoW1xuICAgICAgYXV0aGVudGljYXRlVXNlcihjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBjaGFubmVsUGFzc3dvcmQsIHVzZXIpLFxuICAgICAgY2xhaW1OYW1lSXNBdmFpbGFibGUobmFtZSksXG4gICAgICBjcmVhdGVCYXNpY1B1Ymxpc2hQYXJhbXMoZmlsZVBhdGgsIG5hbWUsIHRpdGxlLCBkZXNjcmlwdGlvbiwgbGljZW5zZSwgbnNmdywgdGh1bWJuYWlsKSxcbiAgICAgIGNyZWF0ZVRodW1ibmFpbFB1Ymxpc2hQYXJhbXModGh1bWJuYWlsRmlsZVBhdGgsIG5hbWUsIGxpY2Vuc2UsIG5zZncpLFxuICAgIF0pXG4gICAgICAudGhlbigoW3tjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWR9LCB2YWxpZGF0ZWRDbGFpbU5hbWUsIHB1Ymxpc2hQYXJhbXMsIHRodW1ibmFpbFB1Ymxpc2hQYXJhbXNdKSA9PiB7XG4gICAgICAgIC8vIGFkZCBjaGFubmVsIGRldGFpbHMgdG8gdGhlIHB1Ymxpc2ggcGFyYW1zXG4gICAgICAgIGlmIChjaGFubmVsTmFtZSAmJiBjaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgIHB1Ymxpc2hQYXJhbXNbJ2NoYW5uZWxfbmFtZSddID0gY2hhbm5lbE5hbWU7XG4gICAgICAgICAgcHVibGlzaFBhcmFtc1snY2hhbm5lbF9pZCddID0gY2hhbm5lbENsYWltSWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcHVibGlzaCB0aGUgdGh1bWJuYWlsXG4gICAgICAgIGlmICh0aHVtYm5haWxQdWJsaXNoUGFyYW1zKSB7XG4gICAgICAgICAgcHVibGlzaCh0aHVtYm5haWxQdWJsaXNoUGFyYW1zLCB0aHVtYm5haWxGaWxlTmFtZSwgdGh1bWJuYWlsRmlsZVR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHB1Ymxpc2ggdGhlIGFzc2V0XG4gICAgICAgIHJldHVybiBwdWJsaXNoKHB1Ymxpc2hQYXJhbXMsIGZpbGVOYW1lLCBmaWxlVHlwZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgbWVzc2FnZTogJ3B1Ymxpc2ggY29tcGxldGVkIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgZGF0YSAgIDoge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHJlc3VsdC5jbGFpbV9pZCxcbiAgICAgICAgICAgIHVybCAgICA6IGAke2hvc3R9LyR7cmVzdWx0LmNsYWltX2lkfS8ke25hbWV9YCxcbiAgICAgICAgICAgIGxicnlUeCA6IHJlc3VsdCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gcmVjb3JkIHRoZSBwdWJsaXNoIGVuZCB0aW1lIGFuZCBzZW5kIHRvIGdvb2dsZSBhbmFseXRpY3NcbiAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2VuZC10by1lbmQnLCAncHVibGlzaCcsIGZpbGVUeXBlLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGdldCBhIHNob3J0IGNsYWltIGlkIGZyb20gbG9uZyBjbGFpbSBJZFxuICBhcHAuZ2V0KCcvYXBpL2NsYWltL3Nob3J0LWlkLzpsb25nSWQvOm5hbWUnLCAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgICBkYi5DbGFpbS5nZXRTaG9ydENsYWltSWRGcm9tTG9uZ0NsYWltSWQocGFyYW1zLmxvbmdJZCwgcGFyYW1zLm5hbWUpXG4gICAgICAudGhlbihzaG9ydElkID0+IHtcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHNob3J0SWR9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBlcnJvckhhbmRsZXJzLmhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICAgIH0pO1xuICB9KTtcbiAgYXBwLnBvc3QoJy9hcGkvY2xhaW0vbG9uZy1pZCcsICh7IGlwLCBvcmlnaW5hbFVybCwgYm9keSwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnYm9keTonLCBib2R5KTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGJvZHkuY2hhbm5lbE5hbWU7XG4gICAgY29uc3QgY2hhbm5lbENsYWltSWQgPSBib2R5LmNoYW5uZWxDbGFpbUlkO1xuICAgIGNvbnN0IGNsYWltTmFtZSA9IGJvZHkuY2xhaW1OYW1lO1xuICAgIGNvbnN0IGNsYWltSWQgPSBib2R5LmNsYWltSWQ7XG4gICAgZ2V0Q2xhaW1JZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSwgY2xhaW1JZClcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQgPT09IE5PX0NIQU5ORUwpIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gbWF0Y2hpbmcgY2hhbm5lbCBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0ID09PSBOT19DTEFJTSkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdObyBtYXRjaGluZyBjbGFpbSBpZCBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfVxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogcmVzdWx0fSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIGFwcC5nZXQoJy9hcGkvY2xhaW0vZGF0YS86Y2xhaW1OYW1lLzpjbGFpbUlkJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgY2xhaW1OYW1lID0gcGFyYW1zLmNsYWltTmFtZTtcbiAgICBsZXQgY2xhaW1JZCA9IHBhcmFtcy5jbGFpbUlkO1xuICAgIGlmIChjbGFpbUlkID09PSAnbm9uZScpIGNsYWltSWQgPSBudWxsO1xuICAgIGRiLkNsYWltLnJlc29sdmVDbGFpbShjbGFpbU5hbWUsIGNsYWltSWQpXG4gICAgICAudGhlbihjbGFpbUluZm8gPT4ge1xuICAgICAgICBpZiAoIWNsYWltSW5mbykge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdObyBjbGFpbSBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfVxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogY2xhaW1JbmZvfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgZXJyb3JIYW5kbGVycy5oYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICB9KTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIHNlZSBpZiBhc3NldCBpcyBhdmFpbGFibGUgbG9jYWxseVxuICBhcHAuZ2V0KCcvYXBpL2ZpbGUvYXZhaWxhYmlsaXR5LzpuYW1lLzpjbGFpbUlkJywgKHsgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IHBhcmFtcy5uYW1lO1xuICAgIGNvbnN0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcbiAgICBkYi5GaWxlLmZpbmRPbmUoe3doZXJlOiB7bmFtZSwgY2xhaW1JZH19KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogdHJ1ZX0pO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhOiBmYWxzZX0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGVycm9ySGFuZGxlcnMuaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgfSk7XG4gIH0pO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpLXJvdXRlcy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNvbm5lY3QtbXVsdGlwYXJ0eVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImNvbm5lY3QtbXVsdGlwYXJ0eVwiXG4vLyBtb2R1bGUgaWQgPSA3N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBkYiA9IHJlcXVpcmUoJy4uL21vZGVscy9pbmRleCcpO1xuY29uc3QgbGJyeUFwaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeUFwaS5qcycpO1xuY29uc3QgcHVibGlzaEhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL3B1Ymxpc2hIZWxwZXJzLmpzJyk7XG5jb25zdCB7IHB1Ymxpc2hpbmc6IHsgcHJpbWFyeUNsYWltQWRkcmVzcywgYWRkaXRpb25hbENsYWltQWRkcmVzc2VzIH0gfSA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9zaXRlQ29uZmlnLmpzJyk7XG5jb25zdCBTZXF1ZWxpemUgPSByZXF1aXJlKCdzZXF1ZWxpemUnKTtcbmNvbnN0IE9wID0gU2VxdWVsaXplLk9wO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcHVibGlzaCAocHVibGlzaFBhcmFtcywgZmlsZU5hbWUsIGZpbGVUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxldCBwdWJsaXNoUmVzdWx0cywgY2VydGlmaWNhdGVJZCwgY2hhbm5lbE5hbWU7XG4gICAgICAvLyBwdWJsaXNoIHRoZSBmaWxlXG4gICAgICByZXR1cm4gbGJyeUFwaS5wdWJsaXNoQ2xhaW0ocHVibGlzaFBhcmFtcylcbiAgICAgICAgLnRoZW4odHggPT4ge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKGBTdWNjZXNzZnVsbHkgcHVibGlzaGVkICR7cHVibGlzaFBhcmFtcy5uYW1lfSAke2ZpbGVOYW1lfWAsIHR4KTtcbiAgICAgICAgICBwdWJsaXNoUmVzdWx0cyA9IHR4O1xuICAgICAgICAgIC8vIGdldCB0aGUgY2hhbm5lbCBpbmZvcm1hdGlvblxuICAgICAgICAgIGlmIChwdWJsaXNoUGFyYW1zLmNoYW5uZWxfbmFtZSkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGB0aGlzIGNsYWltIHdhcyBwdWJsaXNoZWQgaW4gY2hhbm5lbDogJHtwdWJsaXNoUGFyYW1zLmNoYW5uZWxfbmFtZX1gKTtcbiAgICAgICAgICAgIHJldHVybiBkYi5DaGFubmVsLmZpbmRPbmUoe3doZXJlOiB7Y2hhbm5lbE5hbWU6IHB1Ymxpc2hQYXJhbXMuY2hhbm5lbF9uYW1lfX0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ3RoaXMgY2xhaW0gd2FzIG5vdCBwdWJsaXNoZWQgaW4gYSBjaGFubmVsJyk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNoYW5uZWwgPT4ge1xuICAgICAgICAvLyBzZXQgY2hhbm5lbCBpbmZvcm1hdGlvblxuICAgICAgICAgIGNlcnRpZmljYXRlSWQgPSBudWxsO1xuICAgICAgICAgIGNoYW5uZWxOYW1lID0gbnVsbDtcbiAgICAgICAgICBpZiAoY2hhbm5lbCkge1xuICAgICAgICAgICAgY2VydGlmaWNhdGVJZCA9IGNoYW5uZWwuY2hhbm5lbENsYWltSWQ7XG4gICAgICAgICAgICBjaGFubmVsTmFtZSA9IGNoYW5uZWwuY2hhbm5lbE5hbWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgY2VydGlmaWNhdGVJZDogJHtjZXJ0aWZpY2F0ZUlkfWApO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgRmlsZSByZWNvcmRcbiAgICAgICAgICBjb25zdCBmaWxlUmVjb3JkID0ge1xuICAgICAgICAgICAgbmFtZSAgICAgICA6IHB1Ymxpc2hQYXJhbXMubmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQgICAgOiBwdWJsaXNoUmVzdWx0cy5jbGFpbV9pZCxcbiAgICAgICAgICAgIHRpdGxlICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLnRpdGxlLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBhZGRyZXNzICAgIDogcHVibGlzaFBhcmFtcy5jbGFpbV9hZGRyZXNzLFxuICAgICAgICAgICAgb3V0cG9pbnQgICA6IGAke3B1Ymxpc2hSZXN1bHRzLnR4aWR9OiR7cHVibGlzaFJlc3VsdHMubm91dH1gLFxuICAgICAgICAgICAgaGVpZ2h0ICAgICA6IDAsXG4gICAgICAgICAgICBmaWxlTmFtZSxcbiAgICAgICAgICAgIGZpbGVQYXRoICAgOiBwdWJsaXNoUGFyYW1zLmZpbGVfcGF0aCxcbiAgICAgICAgICAgIGZpbGVUeXBlLFxuICAgICAgICAgICAgbnNmdyAgICAgICA6IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEubnNmdyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgQ2xhaW0gcmVjb3JkXG4gICAgICAgICAgY29uc3QgY2xhaW1SZWNvcmQgPSB7XG4gICAgICAgICAgICBuYW1lICAgICAgIDogcHVibGlzaFBhcmFtcy5uYW1lLFxuICAgICAgICAgICAgY2xhaW1JZCAgICA6IHB1Ymxpc2hSZXN1bHRzLmNsYWltX2lkLFxuICAgICAgICAgICAgdGl0bGUgICAgICA6IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEudGl0bGUsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICAgICAgICAgIGFkZHJlc3MgICAgOiBwdWJsaXNoUGFyYW1zLmNsYWltX2FkZHJlc3MsXG4gICAgICAgICAgICB0aHVtYm5haWwgIDogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS50aHVtYm5haWwsXG4gICAgICAgICAgICBvdXRwb2ludCAgIDogYCR7cHVibGlzaFJlc3VsdHMudHhpZH06JHtwdWJsaXNoUmVzdWx0cy5ub3V0fWAsXG4gICAgICAgICAgICBoZWlnaHQgICAgIDogMCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmaWxlVHlwZSxcbiAgICAgICAgICAgIG5zZncgICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLm5zZncsXG4gICAgICAgICAgICBhbW91bnQgICAgIDogcHVibGlzaFBhcmFtcy5iaWQsXG4gICAgICAgICAgICBjZXJ0aWZpY2F0ZUlkLFxuICAgICAgICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyB1cHNlcnQgY3JpdGVyaWFcbiAgICAgICAgICBjb25zdCB1cHNlcnRDcml0ZXJpYSA9IHtcbiAgICAgICAgICAgIG5hbWUgICA6IHB1Ymxpc2hQYXJhbXMubmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHB1Ymxpc2hSZXN1bHRzLmNsYWltX2lkLFxuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gdXBzZXJ0IHRoZSByZWNvcmRzXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtkYi51cHNlcnQoZGIuRmlsZSwgZmlsZVJlY29yZCwgdXBzZXJ0Q3JpdGVyaWEsICdGaWxlJyksIGRiLnVwc2VydChkYi5DbGFpbSwgY2xhaW1SZWNvcmQsIHVwc2VydENyaXRlcmlhLCAnQ2xhaW0nKV0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoW2ZpbGUsIGNsYWltXSkgPT4ge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnRmlsZSBhbmQgQ2xhaW0gcmVjb3JkcyBzdWNjZXNzZnVsbHkgY3JlYXRlZCcpO1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZmlsZS5zZXRDbGFpbShjbGFpbSksIGNsYWltLnNldEZpbGUoZmlsZSldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnRmlsZSBhbmQgQ2xhaW0gcmVjb3JkcyBzdWNjZXNzZnVsbHkgYXNzb2NpYXRlZCcpO1xuICAgICAgICAgIHJlc29sdmUocHVibGlzaFJlc3VsdHMpOyAvLyByZXNvbHZlIHRoZSBwcm9taXNlIHdpdGggdGhlIHJlc3VsdCBmcm9tIGxicnlBcGkucHVibGlzaENsYWltO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignUFVCTElTSCBFUlJPUicsIGVycm9yKTtcbiAgICAgICAgICBwdWJsaXNoSGVscGVycy5kZWxldGVUZW1wb3JhcnlGaWxlKHB1Ymxpc2hQYXJhbXMuZmlsZV9wYXRoKTsgLy8gZGVsZXRlIHRoZSBsb2NhbCBmaWxlXG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGNsYWltTmFtZUlzQXZhaWxhYmxlIChuYW1lKSB7XG4gICAgY29uc3QgY2xhaW1BZGRyZXNzZXMgPSBhZGRpdGlvbmFsQ2xhaW1BZGRyZXNzZXMgfHwgW107XG4gICAgY2xhaW1BZGRyZXNzZXMucHVzaChwcmltYXJ5Q2xhaW1BZGRyZXNzKTtcbiAgICAvLyBmaW5kIGFueSByZWNvcmRzIHdoZXJlIHRoZSBuYW1lIGlzIHVzZWRcbiAgICByZXR1cm4gZGIuQ2xhaW1cbiAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgYXR0cmlidXRlczogWydhZGRyZXNzJ10sXG4gICAgICAgIHdoZXJlICAgICA6IHtcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgICAgIFtPcC5vcl06IGNsYWltQWRkcmVzc2VzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPj0gMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhhdCBjbGFpbSBpcyBhbHJlYWR5IGluIHVzZScpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICB9LFxuICBjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkgKG5hbWUpIHtcbiAgICByZXR1cm4gZGIuQ2hhbm5lbFxuICAgICAgLmZpbmRBbGwoe1xuICAgICAgICB3aGVyZTogeyBjaGFubmVsTmFtZTogbmFtZSB9LFxuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID49IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoYXQgY2hhbm5lbCBoYXMgYWxyZWFkeSBiZWVuIGNsYWltZWQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9jb250cm9sbGVycy9wdWJsaXNoQ29udHJvbGxlci5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImZzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiZnNcIlxuLy8gbW9kdWxlIGlkID0gNzlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgZGIgPSByZXF1aXJlKCcuLi9tb2RlbHMvaW5kZXgnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGF1dGhlbnRpY2F0ZVVzZXIgKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCwgdXNlcikge1xuICAgIC8vIGNhc2U6IG5vIGNoYW5uZWxOYW1lIG9yIGNoYW5uZWwgSWQgYXJlIHByb3ZpZGVkIChhbm9ueW1vdXMpLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdXNlciB0b2tlbiBpcyBwcm92aWRlZFxuICAgIGlmICghY2hhbm5lbE5hbWUgJiYgIWNoYW5uZWxJZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2hhbm5lbE5hbWUgICA6IG51bGwsXG4gICAgICAgIGNoYW5uZWxDbGFpbUlkOiBudWxsLFxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gY2FzZTogY2hhbm5lbE5hbWUgb3IgY2hhbm5lbCBJZCBhcmUgcHJvdmlkZWQgd2l0aCB1c2VyIHRva2VuXG4gICAgaWYgKHVzZXIpIHtcbiAgICAgIGlmIChjaGFubmVsTmFtZSAmJiBjaGFubmVsTmFtZSAhPT0gdXNlci5jaGFubmVsTmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBwcm92aWRlZCBjaGFubmVsIG5hbWUgZG9lcyBub3QgbWF0Y2ggdXNlciBjcmVkZW50aWFscycpO1xuICAgICAgfVxuICAgICAgaWYgKGNoYW5uZWxJZCAmJiBjaGFubmVsSWQgIT09IHVzZXIuY2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgcHJvdmlkZWQgY2hhbm5lbCBpZCBkb2VzIG5vdCBtYXRjaCB1c2VyIGNyZWRlbnRpYWxzJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjaGFubmVsTmFtZSAgIDogdXNlci5jaGFubmVsTmFtZSxcbiAgICAgICAgY2hhbm5lbENsYWltSWQ6IHVzZXIuY2hhbm5lbENsYWltSWQsXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBjYXNlOiBjaGFubmVsTmFtZSBvciBjaGFubmVsIElkIGFyZSBwcm92aWRlZCB3aXRoIHBhc3N3b3JkIGluc3RlYWQgb2YgdXNlciB0b2tlblxuICAgIGlmICghY2hhbm5lbFBhc3N3b3JkKSB0aHJvdyBuZXcgRXJyb3IoJ25vIGNoYW5uZWwgcGFzc3dvcmQgcHJvdmlkZWQnKTtcbiAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuYXV0aGVudGljYXRlQ2hhbm5lbENyZWRlbnRpYWxzKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCk7XG4gIH0sXG4gIGF1dGhlbnRpY2F0ZUNoYW5uZWxDcmVkZW50aWFscyAoY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgdXNlclBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIGhvaXN0ZWQgdmFyaWFibGVzXG4gICAgICBsZXQgY2hhbm5lbERhdGE7XG4gICAgICAvLyBidWlsZCB0aGUgcGFyYW1zIGZvciBmaW5kaW5nIHRoZSBjaGFubmVsXG4gICAgICBsZXQgY2hhbm5lbEZpbmRQYXJhbXMgPSB7fTtcbiAgICAgIGlmIChjaGFubmVsTmFtZSkgY2hhbm5lbEZpbmRQYXJhbXNbJ2NoYW5uZWxOYW1lJ10gPSBjaGFubmVsTmFtZTtcbiAgICAgIGlmIChjaGFubmVsSWQpIGNoYW5uZWxGaW5kUGFyYW1zWydjaGFubmVsQ2xhaW1JZCddID0gY2hhbm5lbElkO1xuICAgICAgLy8gZmluZCB0aGUgY2hhbm5lbFxuICAgICAgZGIuQ2hhbm5lbFxuICAgICAgICAuZmluZE9uZSh7XG4gICAgICAgICAgd2hlcmU6IGNoYW5uZWxGaW5kUGFyYW1zLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihjaGFubmVsID0+IHtcbiAgICAgICAgICBpZiAoIWNoYW5uZWwpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1Zygnbm8gY2hhbm5lbCBmb3VuZCcpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBdXRoZW50aWNhdGlvbiBmYWlsZWQsIHlvdSBkbyBub3QgaGF2ZSBhY2Nlc3MgdG8gdGhhdCBjaGFubmVsJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNoYW5uZWxEYXRhID0gY2hhbm5lbC5nZXQoKTtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ2NoYW5uZWwgZGF0YTonLCBjaGFubmVsRGF0YSk7XG4gICAgICAgICAgcmV0dXJuIGRiLlVzZXIuZmluZE9uZSh7XG4gICAgICAgICAgICB3aGVyZTogeyB1c2VyTmFtZTogY2hhbm5lbERhdGEuY2hhbm5lbE5hbWUuc3Vic3RyaW5nKDEpIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdubyB1c2VyIGZvdW5kJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCwgeW91IGRvIG5vdCBoYXZlIGFjY2VzcyB0byB0aGF0IGNoYW5uZWwnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHVzZXIuY29tcGFyZVBhc3N3b3JkKHVzZXJQYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGlzTWF0Y2ggPT4ge1xuICAgICAgICAgIGlmICghaXNNYXRjaCkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdpbmNvcnJlY3QgcGFzc3dvcmQnKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQXV0aGVudGljYXRpb24gZmFpbGVkLCB5b3UgZG8gbm90IGhhdmUgYWNjZXNzIHRvIHRoYXQgY2hhbm5lbCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsb2dnZXIuZGVidWcoJy4uLnBhc3N3b3JkIHdhcyBhIG1hdGNoLi4uJyk7XG4gICAgICAgICAgcmVzb2x2ZShjaGFubmVsRGF0YSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2F1dGgvYXV0aGVudGljYXRpb24uanMiLCJjb25zdCBDTEFJTVNfUEVSX1BBR0UgPSAxMjtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJldHVyblBhZ2luYXRlZENoYW5uZWxDbGFpbXMgKGNoYW5uZWxOYW1lLCBsb25nQ2hhbm5lbENsYWltSWQsIGNsYWltcywgcGFnZSkge1xuICAgIGNvbnN0IHRvdGFsUGFnZXMgPSBtb2R1bGUuZXhwb3J0cy5kZXRlcm1pbmVUb3RhbFBhZ2VzKGNsYWltcyk7XG4gICAgY29uc3QgcGFnaW5hdGlvblBhZ2UgPSBtb2R1bGUuZXhwb3J0cy5nZXRQYWdlRnJvbVF1ZXJ5KHBhZ2UpO1xuICAgIGNvbnN0IHZpZXdEYXRhID0ge1xuICAgICAgY2hhbm5lbE5hbWUgICAgICAgOiBjaGFubmVsTmFtZSxcbiAgICAgIGxvbmdDaGFubmVsQ2xhaW1JZDogbG9uZ0NoYW5uZWxDbGFpbUlkLFxuICAgICAgY2xhaW1zICAgICAgICAgICAgOiBtb2R1bGUuZXhwb3J0cy5leHRyYWN0UGFnZUZyb21DbGFpbXMoY2xhaW1zLCBwYWdpbmF0aW9uUGFnZSksXG4gICAgICBwcmV2aW91c1BhZ2UgICAgICA6IG1vZHVsZS5leHBvcnRzLmRldGVybWluZVByZXZpb3VzUGFnZShwYWdpbmF0aW9uUGFnZSksXG4gICAgICBjdXJyZW50UGFnZSAgICAgICA6IHBhZ2luYXRpb25QYWdlLFxuICAgICAgbmV4dFBhZ2UgICAgICAgICAgOiBtb2R1bGUuZXhwb3J0cy5kZXRlcm1pbmVOZXh0UGFnZSh0b3RhbFBhZ2VzLCBwYWdpbmF0aW9uUGFnZSksXG4gICAgICB0b3RhbFBhZ2VzICAgICAgICA6IHRvdGFsUGFnZXMsXG4gICAgICB0b3RhbFJlc3VsdHMgICAgICA6IG1vZHVsZS5leHBvcnRzLmRldGVybWluZVRvdGFsQ2xhaW1zKGNsYWltcyksXG4gICAgfTtcbiAgICByZXR1cm4gdmlld0RhdGE7XG4gIH0sXG4gIGdldFBhZ2VGcm9tUXVlcnkgKHBhZ2UpIHtcbiAgICBpZiAocGFnZSkge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHBhZ2UpO1xuICAgIH1cbiAgICByZXR1cm4gMTtcbiAgfSxcbiAgZXh0cmFjdFBhZ2VGcm9tQ2xhaW1zIChjbGFpbXMsIHBhZ2VOdW1iZXIpIHtcbiAgICBpZiAoIWNsYWltcykge1xuICAgICAgcmV0dXJuIFtdOyAgLy8gaWYgbm8gY2xhaW1zLCByZXR1cm4gdGhpcyBkZWZhdWx0XG4gICAgfVxuICAgIC8vIGxvZ2dlci5kZWJ1ZygnY2xhaW1zIGlzIGFycmF5PycsIEFycmF5LmlzQXJyYXkoY2xhaW1zKSk7XG4gICAgLy8gbG9nZ2VyLmRlYnVnKGBwYWdlTnVtYmVyICR7cGFnZU51bWJlcn0gaXMgbnVtYmVyP2AsIE51bWJlci5pc0ludGVnZXIocGFnZU51bWJlcikpO1xuICAgIGNvbnN0IGNsYWltU3RhcnRJbmRleCA9IChwYWdlTnVtYmVyIC0gMSkgKiBDTEFJTVNfUEVSX1BBR0U7XG4gICAgY29uc3QgY2xhaW1FbmRJbmRleCA9IGNsYWltU3RhcnRJbmRleCArIENMQUlNU19QRVJfUEFHRTtcbiAgICBjb25zdCBwYWdlT2ZDbGFpbXMgPSBjbGFpbXMuc2xpY2UoY2xhaW1TdGFydEluZGV4LCBjbGFpbUVuZEluZGV4KTtcbiAgICByZXR1cm4gcGFnZU9mQ2xhaW1zO1xuICB9LFxuICBkZXRlcm1pbmVUb3RhbFBhZ2VzIChjbGFpbXMpIHtcbiAgICBpZiAoIWNsYWltcykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRvdGFsQ2xhaW1zID0gY2xhaW1zLmxlbmd0aDtcbiAgICAgIGlmICh0b3RhbENsYWltcyA8IENMQUlNU19QRVJfUEFHRSkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZ1bGxQYWdlcyA9IE1hdGguZmxvb3IodG90YWxDbGFpbXMgLyBDTEFJTVNfUEVSX1BBR0UpO1xuICAgICAgY29uc3QgcmVtYWluZGVyID0gdG90YWxDbGFpbXMgJSBDTEFJTVNfUEVSX1BBR0U7XG4gICAgICBpZiAocmVtYWluZGVyID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmdWxsUGFnZXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVsbFBhZ2VzICsgMTtcbiAgICB9XG4gIH0sXG4gIGRldGVybWluZVByZXZpb3VzUGFnZSAoY3VycmVudFBhZ2UpIHtcbiAgICBpZiAoY3VycmVudFBhZ2UgPT09IDEpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudFBhZ2UgLSAxO1xuICB9LFxuICBkZXRlcm1pbmVOZXh0UGFnZSAodG90YWxQYWdlcywgY3VycmVudFBhZ2UpIHtcbiAgICBpZiAoY3VycmVudFBhZ2UgPT09IHRvdGFsUGFnZXMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudFBhZ2UgKyAxO1xuICB9LFxuICBkZXRlcm1pbmVUb3RhbENsYWltcyAoY2xhaW1zKSB7XG4gICAgaWYgKCFjbGFpbXMpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gY2xhaW1zLmxlbmd0aDtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvaGVscGVycy9jaGFubmVsUGFnaW5hdGlvbi5qcyIsImNvbnN0IHsgZGV0YWlsczogaG9zdCB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcbmNvbnN0IGhhbmRsZVBhZ2VSZW5kZXIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKGFwcCkgPT4ge1xuICAvLyByb3V0ZSBmb3IgdGhlIGhvbWUgcGFnZVxuICBhcHAuZ2V0KCcvJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgaGFuZGxlUGFnZVJlbmRlcihyZXEsIHJlcyk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBkaXNwbGF5IGxvZ2luIHBhZ2VcbiAgYXBwLmdldCgnL2xvZ2luJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgaGFuZGxlUGFnZVJlbmRlcihyZXEsIHJlcyk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBzaG93ICdhYm91dCcgcGFnZVxuICBhcHAuZ2V0KCcvYWJvdXQnLCAocmVxLCByZXMpID0+IHtcbiAgICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGRpc3BsYXkgYSBsaXN0IG9mIHRoZSB0cmVuZGluZyBpbWFnZXNcbiAgYXBwLmdldCgnL3RyZW5kaW5nJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgcmVzLnN0YXR1cygzMDEpLnJlZGlyZWN0KCcvcG9wdWxhcicpO1xuICB9KTtcbiAgYXBwLmdldCgnL3BvcHVsYXInLCAocmVxLCByZXMpID0+IHtcbiAgICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbiAgfSk7XG4gIC8vIHJvdXRlIHRvIGRpc3BsYXkgYSBsaXN0IG9mIHRoZSB0cmVuZGluZyBpbWFnZXNcbiAgYXBwLmdldCgnL25ldycsIChyZXEsIHJlcykgPT4ge1xuICAgIGhhbmRsZVBhZ2VSZW5kZXIocmVxLCByZXMpO1xuICB9KTtcbiAgLy8gcm91dGUgdG8gc2VuZCBlbWJlZGFibGUgdmlkZW8gcGxheWVyIChmb3IgdHdpdHRlcilcbiAgYXBwLmdldCgnL2VtYmVkLzpjbGFpbUlkLzpuYW1lJywgKHsgcGFyYW1zIH0sIHJlcykgPT4ge1xuICAgIGNvbnN0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcbiAgICBjb25zdCBuYW1lID0gcGFyYW1zLm5hbWU7XG4gICAgLy8gZ2V0IGFuZCByZW5kZXIgdGhlIGNvbnRlbnRcbiAgICByZXMuc3RhdHVzKDIwMCkucmVuZGVyKCdlbWJlZCcsIHsgbGF5b3V0OiAnZW1iZWQnLCBob3N0LCBjbGFpbUlkLCBuYW1lIH0pO1xuICB9KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL3BhZ2Utcm91dGVzLmpzIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgTE9HSU4gfSBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jaGFubmVsX3NlbGVjdF9zdGF0ZXMnO1xuY29uc3QgeyBwdWJsaXNoaW5nIH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvc2l0ZUNvbmZpZy5qcycpO1xuXG5jb25zdCBpbml0aWFsU3RhdGUgPSB7XG4gIGRpc2FibGVkICAgICAgICAgIDogcHVibGlzaGluZy5kaXNhYmxlZCxcbiAgZGlzYWJsZWRNZXNzYWdlICAgOiBwdWJsaXNoaW5nLmRpc2FibGVkTWVzc2FnZSxcbiAgcHVibGlzaEluQ2hhbm5lbCAgOiBmYWxzZSxcbiAgc2VsZWN0ZWRDaGFubmVsICAgOiBMT0dJTixcbiAgc2hvd01ldGFkYXRhSW5wdXRzOiBmYWxzZSxcbiAgc3RhdHVzICAgICAgICAgICAgOiB7XG4gICAgc3RhdHVzIDogbnVsbCxcbiAgICBtZXNzYWdlOiBudWxsLFxuICB9LFxuICBlcnJvcjoge1xuICAgIGZpbGUgICAgICAgICA6IG51bGwsXG4gICAgdXJsICAgICAgICAgIDogbnVsbCxcbiAgICBjaGFubmVsICAgICAgOiBudWxsLFxuICAgIHB1Ymxpc2hTdWJtaXQ6IG51bGwsXG4gIH0sXG4gIGZpbGUgICAgOiBudWxsLFxuICBjbGFpbSAgIDogJycsXG4gIG1ldGFkYXRhOiB7XG4gICAgdGl0bGUgICAgICA6ICcnLFxuICAgIGRlc2NyaXB0aW9uOiAnJyxcbiAgICBsaWNlbnNlICAgIDogJycsXG4gICAgbnNmdyAgICAgICA6IGZhbHNlLFxuICB9LFxuICB0aHVtYm5haWw6IG51bGwsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUgPSBpbml0aWFsU3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgY2FzZSBhY3Rpb25zLkZJTEVfU0VMRUNURUQ6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgaW5pdGlhbFN0YXRlLCB7ICAvLyBub3RlOiBjbGVhcnMgdG8gaW5pdGlhbCBzdGF0ZVxuICAgICAgICBmaWxlOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5GSUxFX0NMRUFSOlxuICAgICAgcmV0dXJuIGluaXRpYWxTdGF0ZTtcbiAgICBjYXNlIGFjdGlvbnMuTUVUQURBVEFfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIG1ldGFkYXRhOiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5tZXRhZGF0YSwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5uYW1lXTogYWN0aW9uLmRhdGEudmFsdWUsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLkNMQUlNX1VQREFURTpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBjbGFpbTogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuU0VUX1BVQkxJU0hfSU5fQ0hBTk5FTDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBwdWJsaXNoSW5DaGFubmVsOiBhY3Rpb24uY2hhbm5lbCxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5QVUJMSVNIX1NUQVRVU19VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgc3RhdHVzOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5FUlJPUl9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgZXJyb3I6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmVycm9yLCB7XG4gICAgICAgICAgW2FjdGlvbi5kYXRhLm5hbWVdOiBhY3Rpb24uZGF0YS52YWx1ZSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuU0VMRUNURURfQ0hBTk5FTF9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgc2VsZWN0ZWRDaGFubmVsOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5UT0dHTEVfTUVUQURBVEFfSU5QVVRTOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHNob3dNZXRhZGF0YUlucHV0czogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuVEhVTUJOQUlMX05FVzpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICB0aHVtYm5haWw6IGFjdGlvbi5kYXRhLFxuICAgICAgfSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3JlZHVjZXJzL3B1Ymxpc2guanMiLCJpbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9jaGFubmVsX2FjdGlvbl90eXBlcyc7XG5cbmNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgbG9nZ2VkSW5DaGFubmVsOiB7XG4gICAgbmFtZSAgIDogbnVsbCxcbiAgICBzaG9ydElkOiBudWxsLFxuICAgIGxvbmdJZCA6IG51bGwsXG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUgPSBpbml0aWFsU3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgY2FzZSBhY3Rpb25zLkNIQU5ORUxfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGxvZ2dlZEluQ2hhbm5lbDogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcmVkdWNlcnMvY2hhbm5lbC5qcyIsImltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL3Nob3dfYWN0aW9uX3R5cGVzJztcbmltcG9ydCB7IExPQ0FMX0NIRUNLLCBFUlJPUiB9IGZyb20gJ2NvbnN0YW50cy9hc3NldF9kaXNwbGF5X3N0YXRlcyc7XG5cbmNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgcmVxdWVzdDoge1xuICAgIGVycm9yOiBudWxsLFxuICAgIHR5cGUgOiBudWxsLFxuICAgIGlkICAgOiBudWxsLFxuICB9LFxuICByZXF1ZXN0TGlzdCA6IHt9LFxuICBjaGFubmVsTGlzdCA6IHt9LFxuICBhc3NldExpc3QgICA6IHt9LFxuICBkaXNwbGF5QXNzZXQ6IHtcbiAgICBlcnJvciA6IG51bGwsXG4gICAgc3RhdHVzOiBMT0NBTF9DSEVDSyxcbiAgfSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGF0ZSA9IGluaXRpYWxTdGF0ZSwgYWN0aW9uKSB7XG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAvLyBoYW5kbGUgcmVxdWVzdFxuICAgIGNhc2UgYWN0aW9ucy5SRVFVRVNUX0VSUk9SOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHJlcXVlc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlcXVlc3QsIHtcbiAgICAgICAgICBlcnJvcjogYWN0aW9uLmRhdGEsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLlJFUVVFU1RfVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHJlcXVlc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlcXVlc3QsIHtcbiAgICAgICAgICB0eXBlOiBhY3Rpb24uZGF0YS5yZXF1ZXN0VHlwZSxcbiAgICAgICAgICBpZCAgOiBhY3Rpb24uZGF0YS5yZXF1ZXN0SWQsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgLy8gc3RvcmUgcmVxdWVzdHNcbiAgICBjYXNlIGFjdGlvbnMuUkVRVUVTVF9MSVNUX0FERDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICByZXF1ZXN0TGlzdDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVxdWVzdExpc3QsIHtcbiAgICAgICAgICBbYWN0aW9uLmRhdGEuaWRdOiB7XG4gICAgICAgICAgICBlcnJvcjogYWN0aW9uLmRhdGEuZXJyb3IsXG4gICAgICAgICAgICBrZXkgIDogYWN0aW9uLmRhdGEua2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgLy8gYXNzZXQgZGF0YVxuICAgIGNhc2UgYWN0aW9ucy5BU1NFVF9BREQ6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgYXNzZXRMaXN0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5hc3NldExpc3QsIHtcbiAgICAgICAgICBbYWN0aW9uLmRhdGEuaWRdOiB7XG4gICAgICAgICAgICBlcnJvciAgICA6IGFjdGlvbi5kYXRhLmVycm9yLFxuICAgICAgICAgICAgbmFtZSAgICAgOiBhY3Rpb24uZGF0YS5uYW1lLFxuICAgICAgICAgICAgY2xhaW1JZCAgOiBhY3Rpb24uZGF0YS5jbGFpbUlkLFxuICAgICAgICAgICAgc2hvcnRJZCAgOiBhY3Rpb24uZGF0YS5zaG9ydElkLFxuICAgICAgICAgICAgY2xhaW1EYXRhOiBhY3Rpb24uZGF0YS5jbGFpbURhdGEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAvLyBjaGFubmVsIGRhdGFcbiAgICBjYXNlIGFjdGlvbnMuQ0hBTk5FTF9BREQ6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgY2hhbm5lbExpc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmNoYW5uZWxMaXN0LCB7XG4gICAgICAgICAgW2FjdGlvbi5kYXRhLmlkXToge1xuICAgICAgICAgICAgbmFtZSAgICAgIDogYWN0aW9uLmRhdGEubmFtZSxcbiAgICAgICAgICAgIGxvbmdJZCAgICA6IGFjdGlvbi5kYXRhLmxvbmdJZCxcbiAgICAgICAgICAgIHNob3J0SWQgICA6IGFjdGlvbi5kYXRhLnNob3J0SWQsXG4gICAgICAgICAgICBjbGFpbXNEYXRhOiBhY3Rpb24uZGF0YS5jbGFpbXNEYXRhLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLkNIQU5ORUxfQ0xBSU1TX1VQREFURV9TVUNDRVNTOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGNoYW5uZWxMaXN0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5jaGFubmVsTGlzdCwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5jaGFubmVsTGlzdElkXTogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuY2hhbm5lbExpc3RbYWN0aW9uLmRhdGEuY2hhbm5lbExpc3RJZF0sIHtcbiAgICAgICAgICAgIGNsYWltc0RhdGE6IGFjdGlvbi5kYXRhLmNsYWltc0RhdGEsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgLy8gZGlzcGxheSBhbiBhc3NldFxuICAgIGNhc2UgYWN0aW9ucy5GSUxFX0FWQUlMQUJJTElUWV9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgZGlzcGxheUFzc2V0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5kaXNwbGF5QXNzZXQsIHtcbiAgICAgICAgICBzdGF0dXM6IGFjdGlvbi5kYXRhLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5ESVNQTEFZX0FTU0VUX0VSUk9SOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGRpc3BsYXlBc3NldDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuZGlzcGxheUFzc2V0LCB7XG4gICAgICAgICAgZXJyb3IgOiBhY3Rpb24uZGF0YSxcbiAgICAgICAgICBzdGF0dXM6IEVSUk9SLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9yZWR1Y2Vycy9zaG93LmpzIiwiY29uc3Qgc2l0ZUNvbmZpZyA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9zaXRlQ29uZmlnLmpzJyk7XG5cbmNvbnN0IHtcbiAgYW5hbHl0aWNzOiB7XG4gICAgZ29vZ2xlSWQ6IGdvb2dsZUFuYWx5dGljc0lkLFxuICB9LFxuICBhc3NldERlZmF1bHRzOiB7XG4gICAgdGh1bWJuYWlsOiBkZWZhdWx0VGh1bWJuYWlsLFxuICAgIGRlc2NyaXB0aW9uOiBkZWZhdWx0RGVzY3JpcHRpb24sXG4gIH0sXG4gIGRldGFpbHM6IHtcbiAgICBkZXNjcmlwdGlvbixcbiAgICBob3N0LFxuICAgIHRpdGxlLFxuICAgIHR3aXR0ZXIsXG4gIH0sXG59ID0gc2l0ZUNvbmZpZztcblxuY29uc3QgaW5pdGlhbFN0YXRlID0ge1xuICBkZXNjcmlwdGlvbixcbiAgZ29vZ2xlQW5hbHl0aWNzSWQsXG4gIGhvc3QsXG4gIHRpdGxlLFxuICB0d2l0dGVyLFxuICBkZWZhdWx0RGVzY3JpcHRpb24sXG4gIGRlZmF1bHRUaHVtYm5haWwsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUgPSBpbml0aWFsU3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3JlZHVjZXJzL3NpdGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdC1nYVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWdhXCJcbi8vIG1vZHVsZSBpZCA9IDg3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IFB1Ymxpc2hUb29sIGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaFRvb2wnO1xuXG5jbGFzcyBIb21lUGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPXsncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uJ30+XG4gICAgICAgIDxTRU8gLz5cbiAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT17J3JvdyByb3ctLXRhbGwgcm93LS1wYWRkZWQgZmxleC1jb250YWluZXItLWNvbHVtbid9PlxuICAgICAgICAgIDxQdWJsaXNoVG9vbCAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEhvbWVQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3BhZ2VzL0hvbWVQYWdlL2luZGV4LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgSGVsbWV0IGZyb20gJ3JlYWN0LWhlbG1ldCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVQYWdlVGl0bGUgfSBmcm9tICd1dGlscy9wYWdlVGl0bGUnO1xuaW1wb3J0IHsgY3JlYXRlTWV0YVRhZ3MgfSBmcm9tICd1dGlscy9tZXRhVGFncyc7XG5pbXBvcnQgeyBjcmVhdGVDYW5vbmljYWxMaW5rIH0gZnJvbSAndXRpbHMvY2Fub25pY2FsTGluayc7XG5cbmNsYXNzIFNFTyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgLy8gcHJvcHMgZnJvbSBzdGF0ZVxuICAgIGNvbnN0IHsgZGVmYXVsdERlc2NyaXB0aW9uLCBkZWZhdWx0VGh1bWJuYWlsLCBzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyIH0gPSB0aGlzLnByb3BzO1xuICAgIC8vIHByb3BzIGZyb20gcGFyZW50XG4gICAgY29uc3QgeyBhc3NldCwgY2hhbm5lbCwgcGFnZVVyaSB9ID0gdGhpcy5wcm9wcztcbiAgICBsZXQgeyBwYWdlVGl0bGUgfSA9IHRoaXMucHJvcHM7XG4gICAgLy8gY3JlYXRlIHBhZ2UgdGl0bGUsIHRhZ3MsIGFuZCBjYW5vbmljYWwgbGlua1xuICAgIHBhZ2VUaXRsZSA9IGNyZWF0ZVBhZ2VUaXRsZShzaXRlVGl0bGUsIHBhZ2VUaXRsZSk7XG4gICAgY29uc3QgbWV0YVRhZ3MgPSBjcmVhdGVNZXRhVGFncyhzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyLCBhc3NldCwgY2hhbm5lbCwgZGVmYXVsdERlc2NyaXB0aW9uLCBkZWZhdWx0VGh1bWJuYWlsKTtcbiAgICBjb25zdCBjYW5vbmljYWxMaW5rID0gY3JlYXRlQ2Fub25pY2FsTGluayhhc3NldCwgY2hhbm5lbCwgcGFnZVVyaSwgc2l0ZUhvc3QpO1xuICAgIC8vIHJlbmRlciByZXN1bHRzXG4gICAgcmV0dXJuIChcbiAgICAgIDxIZWxtZXRcbiAgICAgICAgdGl0bGU9e3BhZ2VUaXRsZX1cbiAgICAgICAgbWV0YT17bWV0YVRhZ3N9XG4gICAgICAgIGxpbms9e1t7cmVsOiAnY2Fub25pY2FsJywgaHJlZjogY2Fub25pY2FsTGlua31dfVxuICAgICAgLz5cbiAgICApO1xuICB9XG59O1xuXG5TRU8ucHJvcFR5cGVzID0ge1xuICBwYWdlVGl0bGU6IFByb3BUeXBlcy5zdHJpbmcsXG4gIHBhZ2VVcmkgIDogUHJvcFR5cGVzLnN0cmluZyxcbiAgY2hhbm5lbCAgOiBQcm9wVHlwZXMub2JqZWN0LFxuICBhc3NldCAgICA6IFByb3BUeXBlcy5vYmplY3QsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBTRU87XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9TRU8vdmlldy5qc3giLCJleHBvcnQgY29uc3QgY3JlYXRlUGFnZVRpdGxlID0gKHNpdGVUaXRsZSwgcGFnZVRpdGxlKSA9PiB7XG4gIGlmICghcGFnZVRpdGxlKSB7XG4gICAgcmV0dXJuIGAke3NpdGVUaXRsZX1gO1xuICB9XG4gIHJldHVybiBgJHtzaXRlVGl0bGV9IC0gJHtwYWdlVGl0bGV9YDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvcGFnZVRpdGxlLmpzIiwiY29uc3QgZGV0ZXJtaW5lT2dUaHVtYm5haWxDb250ZW50VHlwZSA9ICh0aHVtYm5haWwpID0+IHtcbiAgaWYgKHRodW1ibmFpbCkge1xuICAgIGNvbnN0IGZpbGVFeHQgPSB0aHVtYm5haWwuc3Vic3RyaW5nKHRodW1ibmFpbC5sYXN0SW5kZXhPZignLicpKTtcbiAgICBzd2l0Y2ggKGZpbGVFeHQpIHtcbiAgICAgIGNhc2UgJ2pwZWcnOlxuICAgICAgY2FzZSAnanBnJzpcbiAgICAgICAgcmV0dXJuICdpbWFnZS9qcGVnJztcbiAgICAgIGNhc2UgJ3BuZyc6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvcG5nJztcbiAgICAgIGNhc2UgJ2dpZic6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvZ2lmJztcbiAgICAgIGNhc2UgJ21wNCc6XG4gICAgICAgIHJldHVybiAndmlkZW8vbXA0JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvanBlZyc7XG4gICAgfVxuICB9XG4gIHJldHVybiAnJztcbn07XG5cbmNvbnN0IGNyZWF0ZUJhc2ljTWV0YVRhZ3MgPSAoc2l0ZUhvc3QsIHNpdGVEZXNjcmlwdGlvbiwgc2l0ZVRpdGxlLCBzaXRlVHdpdHRlcikgPT4ge1xuICByZXR1cm4gW1xuICAgIHtwcm9wZXJ0eTogJ29nOnRpdGxlJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBzaXRlSG9zdH0sXG4gICAge3Byb3BlcnR5OiAnb2c6c2l0ZV9uYW1lJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzpkZXNjcmlwdGlvbicsIGNvbnRlbnQ6IHNpdGVEZXNjcmlwdGlvbn0sXG4gICAge3Byb3BlcnR5OiAndHdpdHRlcjpzaXRlJywgY29udGVudDogc2l0ZVR3aXR0ZXJ9LFxuICAgIHtwcm9wZXJ0eTogJ3R3aXR0ZXI6Y2FyZCcsIGNvbnRlbnQ6ICdzdW1tYXJ5J30sXG4gIF07XG59O1xuXG5jb25zdCBjcmVhdGVDaGFubmVsTWV0YVRhZ3MgPSAoc2l0ZVRpdGxlLCBzaXRlSG9zdCwgc2l0ZVR3aXR0ZXIsIGNoYW5uZWwpID0+IHtcbiAgY29uc3QgeyBuYW1lLCBsb25nSWQgfSA9IGNoYW5uZWw7XG4gIHJldHVybiBbXG4gICAge3Byb3BlcnR5OiAnb2c6dGl0bGUnLCBjb250ZW50OiBgJHtuYW1lfSBvbiAke3NpdGVUaXRsZX1gfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBgJHtzaXRlSG9zdH0vJHtuYW1lfToke2xvbmdJZH1gfSxcbiAgICB7cHJvcGVydHk6ICdvZzpzaXRlX25hbWUnLCBjb250ZW50OiBzaXRlVGl0bGV9LFxuICAgIHtwcm9wZXJ0eTogJ29nOmRlc2NyaXB0aW9uJywgY29udGVudDogYCR7bmFtZX0sIGEgY2hhbm5lbCBvbiAke3NpdGVUaXRsZX1gfSxcbiAgICB7cHJvcGVydHk6ICd0d2l0dGVyOnNpdGUnLCBjb250ZW50OiBzaXRlVHdpdHRlcn0sXG4gICAge3Byb3BlcnR5OiAndHdpdHRlcjpjYXJkJywgY29udGVudDogJ3N1bW1hcnknfSxcbiAgXTtcbn07XG5cbmNvbnN0IGNyZWF0ZUFzc2V0TWV0YVRhZ3MgPSAoc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpID0+IHtcbiAgY29uc3QgeyBjbGFpbURhdGEgfSA9IGFzc2V0O1xuICBjb25zdCB7IGNvbnRlbnRUeXBlIH0gPSBjbGFpbURhdGE7XG4gIGNvbnN0IGVtYmVkVXJsID0gYCR7c2l0ZUhvc3R9LyR7Y2xhaW1EYXRhLmNsYWltSWR9LyR7Y2xhaW1EYXRhLm5hbWV9YDtcbiAgY29uc3Qgc2hvd1VybCA9IGAke3NpdGVIb3N0fS8ke2NsYWltRGF0YS5jbGFpbUlkfS8ke2NsYWltRGF0YS5uYW1lfWA7XG4gIGNvbnN0IHNvdXJjZSA9IGAke3NpdGVIb3N0fS8ke2NsYWltRGF0YS5jbGFpbUlkfS8ke2NsYWltRGF0YS5uYW1lfS4ke2NsYWltRGF0YS5maWxlRXh0fWA7XG4gIGNvbnN0IG9nVGl0bGUgPSBjbGFpbURhdGEudGl0bGUgfHwgY2xhaW1EYXRhLm5hbWU7XG4gIGNvbnN0IG9nRGVzY3JpcHRpb24gPSBjbGFpbURhdGEuZGVzY3JpcHRpb24gfHwgZGVmYXVsdERlc2NyaXB0aW9uO1xuICBjb25zdCBvZ1RodW1ibmFpbENvbnRlbnRUeXBlID0gZGV0ZXJtaW5lT2dUaHVtYm5haWxDb250ZW50VHlwZShjbGFpbURhdGEudGh1bWJuYWlsKTtcbiAgY29uc3Qgb2dUaHVtYm5haWwgPSBjbGFpbURhdGEudGh1bWJuYWlsIHx8IGRlZmF1bHRUaHVtYm5haWw7XG4gIGNvbnN0IG1ldGFUYWdzID0gW1xuICAgIHtwcm9wZXJ0eTogJ29nOnRpdGxlJywgY29udGVudDogb2dUaXRsZX0sXG4gICAge3Byb3BlcnR5OiAnb2c6dXJsJywgY29udGVudDogc2hvd1VybH0sXG4gICAge3Byb3BlcnR5OiAnb2c6c2l0ZV9uYW1lJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzpkZXNjcmlwdGlvbicsIGNvbnRlbnQ6IG9nRGVzY3JpcHRpb259LFxuICAgIHtwcm9wZXJ0eTogJ29nOmltYWdlOndpZHRoJywgY29udGVudDogNjAwfSxcbiAgICB7cHJvcGVydHk6ICdvZzppbWFnZTpoZWlnaHQnLCBjb250ZW50OiAzMTV9LFxuICAgIHtwcm9wZXJ0eTogJ3R3aXR0ZXI6c2l0ZScsIGNvbnRlbnQ6IHNpdGVUd2l0dGVyfSxcbiAgXTtcbiAgaWYgKGNvbnRlbnRUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50VHlwZSA9PT0gJ3ZpZGVvL3dlYm0nKSB7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzp2aWRlbycsIGNvbnRlbnQ6IHNvdXJjZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dmlkZW86c2VjdXJlX3VybCcsIGNvbnRlbnQ6IHNvdXJjZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dmlkZW86dHlwZScsIGNvbnRlbnQ6IGNvbnRlbnRUeXBlfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzppbWFnZScsIGNvbnRlbnQ6IG9nVGh1bWJuYWlsfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzppbWFnZTp0eXBlJywgY29udGVudDogb2dUaHVtYm5haWxDb250ZW50VHlwZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dHlwZScsIGNvbnRlbnQ6ICd2aWRlbyd9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ3R3aXR0ZXI6Y2FyZCcsIGNvbnRlbnQ6ICdwbGF5ZXInfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcicsIGNvbnRlbnQ6IGVtYmVkVXJsfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcjp3aWR0aCcsIGNvbnRlbnQ6IDYwMH0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjp0ZXh0OnBsYXllcl93aWR0aCcsIGNvbnRlbnQ6IDYwMH0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjpwbGF5ZXI6aGVpZ2h0JywgY29udGVudDogMzM3fSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcjpzdHJlYW0nLCBjb250ZW50OiBzb3VyY2V9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ3R3aXR0ZXI6cGxheWVyOnN0cmVhbTpjb250ZW50X3R5cGUnLCBjb250ZW50OiBjb250ZW50VHlwZX0pO1xuICB9IGVsc2Uge1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6aW1hZ2UnLCBjb250ZW50OiBzb3VyY2V9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ29nOmltYWdlOnR5cGUnLCBjb250ZW50OiBjb250ZW50VHlwZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dHlwZScsIGNvbnRlbnQ6ICdhcnRpY2xlJ30pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjpjYXJkJywgY29udGVudDogJ3N1bW1hcnlfbGFyZ2VfaW1hZ2UnfSk7XG4gIH1cbiAgcmV0dXJuIG1ldGFUYWdzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1ldGFUYWdzID0gKHNpdGVEZXNjcmlwdGlvbiwgc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBjaGFubmVsLCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpID0+IHtcbiAgaWYgKGFzc2V0KSB7XG4gICAgcmV0dXJuIGNyZWF0ZUFzc2V0TWV0YVRhZ3Moc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpO1xuICB9O1xuICBpZiAoY2hhbm5lbCkge1xuICAgIHJldHVybiBjcmVhdGVDaGFubmVsTWV0YVRhZ3Moc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGNoYW5uZWwpO1xuICB9O1xuICByZXR1cm4gY3JlYXRlQmFzaWNNZXRhVGFncyhzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyKTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvbWV0YVRhZ3MuanMiLCJjb25zdCBjcmVhdGVCYXNpY0Nhbm9uaWNhbExpbmsgPSAocGFnZSwgc2l0ZUhvc3QpID0+IHtcbiAgcmV0dXJuIGAke3NpdGVIb3N0fS8ke3BhZ2V9YDtcbn07XG5cbmNvbnN0IGNyZWF0ZUFzc2V0Q2Fub25pY2FsTGluayA9IChhc3NldCwgc2l0ZUhvc3QpID0+IHtcbiAgbGV0IGNoYW5uZWxOYW1lLCBjZXJ0aWZpY2F0ZUlkLCBuYW1lLCBjbGFpbUlkO1xuICBpZiAoYXNzZXQuY2xhaW1EYXRhKSB7XG4gICAgKHsgY2hhbm5lbE5hbWUsIGNlcnRpZmljYXRlSWQsIG5hbWUsIGNsYWltSWQgfSA9IGFzc2V0LmNsYWltRGF0YSk7XG4gIH07XG4gIGlmIChjaGFubmVsTmFtZSkge1xuICAgIHJldHVybiBgJHtzaXRlSG9zdH0vJHtjaGFubmVsTmFtZX06JHtjZXJ0aWZpY2F0ZUlkfS8ke25hbWV9YDtcbiAgfTtcbiAgcmV0dXJuIGAke3NpdGVIb3N0fS8ke2NsYWltSWR9LyR7bmFtZX1gO1xufTtcblxuY29uc3QgY3JlYXRlQ2hhbm5lbENhbm9uaWNhbExpbmsgPSAoY2hhbm5lbCwgc2l0ZUhvc3QpID0+IHtcbiAgY29uc3QgeyBuYW1lLCBsb25nSWQgfSA9IGNoYW5uZWw7XG4gIHJldHVybiBgJHtzaXRlSG9zdH0vJHtuYW1lfToke2xvbmdJZH1gO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUNhbm9uaWNhbExpbmsgPSAoYXNzZXQsIGNoYW5uZWwsIHBhZ2UsIHNpdGVIb3N0KSA9PiB7XG4gIGlmIChhc3NldCkge1xuICAgIHJldHVybiBjcmVhdGVBc3NldENhbm9uaWNhbExpbmsoYXNzZXQsIHNpdGVIb3N0KTtcbiAgfVxuICBpZiAoY2hhbm5lbCkge1xuICAgIHJldHVybiBjcmVhdGVDaGFubmVsQ2Fub25pY2FsTGluayhjaGFubmVsLCBzaXRlSG9zdCk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJhc2ljQ2Fub25pY2FsTGluayhwYWdlLCBzaXRlSG9zdCk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3V0aWxzL2Nhbm9uaWNhbExpbmsuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgTmF2TGluaywgd2l0aFJvdXRlciB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IExvZ28gZnJvbSAnY29tcG9uZW50cy9Mb2dvJztcbmltcG9ydCBOYXZCYXJDaGFubmVsRHJvcGRvd24gZnJvbSAnY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duJztcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5jb25zdCBWSUVXID0gJ1ZJRVcnO1xuY29uc3QgTE9HT1VUID0gJ0xPR09VVCc7XG5cbmNsYXNzIE5hdkJhciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmNoZWNrRm9yTG9nZ2VkSW5Vc2VyID0gdGhpcy5jaGVja0ZvckxvZ2dlZEluVXNlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMubG9nb3V0VXNlciA9IHRoaXMubG9nb3V0VXNlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVTZWxlY3Rpb24uYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgLy8gY2hlY2sgdG8gc2VlIGlmIHRoZSB1c2VyIGlzIGFscmVhZHkgbG9nZ2VkIGluXG4gICAgdGhpcy5jaGVja0ZvckxvZ2dlZEluVXNlcigpO1xuICB9XG4gIGNoZWNrRm9yTG9nZ2VkSW5Vc2VyICgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB7Y3JlZGVudGlhbHM6ICdpbmNsdWRlJ307XG4gICAgcmVxdWVzdCgnL3VzZXInLCBwYXJhbXMpXG4gICAgICAudGhlbigoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihkYXRhLmNoYW5uZWxOYW1lLCBkYXRhLnNob3J0Q2hhbm5lbElkLCBkYXRhLmNoYW5uZWxDbGFpbUlkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnL3VzZXIgZXJyb3I6JywgZXJyb3IubWVzc2FnZSk7XG4gICAgICB9KTtcbiAgfVxuICBsb2dvdXRVc2VyICgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB7Y3JlZGVudGlhbHM6ICdpbmNsdWRlJ307XG4gICAgcmVxdWVzdCgnL2xvZ291dCcsIHBhcmFtcylcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dvdXQoKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnL2xvZ291dCBlcnJvcicsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfSk7XG4gIH1cbiAgaGFuZGxlU2VsZWN0aW9uIChldmVudCkge1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnNlbGVjdGVkT3B0aW9uc1swXS52YWx1ZTtcbiAgICBzd2l0Y2ggKHZhbHVlKSB7XG4gICAgICBjYXNlIExPR09VVDpcbiAgICAgICAgdGhpcy5sb2dvdXRVc2VyKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBWSUVXOlxuICAgICAgICAvLyByZWRpcmVjdCB0byBjaGFubmVsIHBhZ2VcbiAgICAgICAgdGhpcy5wcm9wcy5oaXN0b3J5LnB1c2goYC8ke3RoaXMucHJvcHMuY2hhbm5lbE5hbWV9OiR7dGhpcy5wcm9wcy5jaGFubmVsTG9uZ0lkfWApO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgc2l0ZURlc2NyaXB0aW9uIH0gPSAgdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXdpZGUgbmF2LWJhcic+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1zaG9ydCBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWNlbnRlcic+XG4gICAgICAgICAgPExvZ28gLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbmF2LWJhci0tY2VudGVyJz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0nbmF2LWJhci10YWdsaW5lJz57c2l0ZURlc2NyaXB0aW9ufTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbmF2LWJhci0tcmlnaHQnPlxuICAgICAgICAgICAgPE5hdkxpbmsgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyBhY3RpdmVDbGFzc05hbWU9J2xpbmstLW5hdi1hY3RpdmUnIHRvPScvJyBleGFjdD5QdWJsaXNoPC9OYXZMaW5rPlxuICAgICAgICAgICAgPE5hdkxpbmsgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyAgYWN0aXZlQ2xhc3NOYW1lPSdsaW5rLS1uYXYtYWN0aXZlJyB0bz0nL2Fib3V0Jz5BYm91dDwvTmF2TGluaz5cbiAgICAgICAgICAgIHsgdGhpcy5wcm9wcy5jaGFubmVsTmFtZSA/IChcbiAgICAgICAgICAgICAgPE5hdkJhckNoYW5uZWxEcm9wZG93blxuICAgICAgICAgICAgICAgIGNoYW5uZWxOYW1lPXt0aGlzLnByb3BzLmNoYW5uZWxOYW1lfVxuICAgICAgICAgICAgICAgIGhhbmRsZVNlbGVjdGlvbj17dGhpcy5oYW5kbGVTZWxlY3Rpb259XG4gICAgICAgICAgICAgICAgZGVmYXVsdFNlbGVjdGlvbj17dGhpcy5wcm9wcy5jaGFubmVsTmFtZX1cbiAgICAgICAgICAgICAgICBWSUVXPXtWSUVXfVxuICAgICAgICAgICAgICAgIExPR09VVD17TE9HT1VUfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgPE5hdkxpbmsgaWQ9J25hdi1iYXItbG9naW4tbGluaycgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyBhY3RpdmVDbGFzc05hbWU9J2xpbmstLW5hdi1hY3RpdmUnIHRvPScvbG9naW4nPkNoYW5uZWw8L05hdkxpbms+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aFJvdXRlcihOYXZCYXIpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvTmF2QmFyL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IExpbmsgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcblxuZnVuY3Rpb24gTG9nbyAoKSB7XG4gIHJldHVybiAoXG4gICAgPHN2ZyB2ZXJzaW9uPScxLjEnIGlkPSdMYXllcl8xJyB4PScwcHgnIHk9JzBweCcgaGVpZ2h0PScyNHB4JyB2aWV3Qm94PScwIDAgODAgMzEnIGVuYWJsZUJhY2tncm91bmQ9J25ldyAwIDAgODAgMzEnIGNsYXNzTmFtZT0nbmF2LWJhci1sb2dvJz5cbiAgICAgIDxMaW5rIHRvPScvJz5cbiAgICAgICAgPHRpdGxlPkxvZ288L3RpdGxlPlxuICAgICAgICA8ZGVzYz5TcGVlLmNoIGxvZ288L2Rlc2M+XG4gICAgICAgIDxnIGlkPSdBYm91dCc+XG4gICAgICAgICAgPGcgaWQ9J1B1Ymxpc2gtRm9ybS1WMi1feDI4X2ZpbGxlZF94MjlfJyB0cmFuc2Zvcm09J3RyYW5zbGF0ZSgtNDIuMDAwMDAwLCAtMjMuMDAwMDAwKSc+XG4gICAgICAgICAgICA8ZyBpZD0nR3JvdXAtMTcnIHRyYW5zZm9ybT0ndHJhbnNsYXRlKDQyLjAwMDAwMCwgMjIuMDAwMDAwKSc+XG4gICAgICAgICAgICAgIDx0ZXh0IHRyYW5zZm9ybT0nbWF0cml4KDEgMCAwIDEgMCAyMCknIGZvbnRTaXplPScyNScgZm9udEZhbWlseT0nUm9ib3RvJz5TcGVlJmx0O2g8L3RleHQ+XG4gICAgICAgICAgICAgIDxnIGlkPSdHcm91cC0xNicgdHJhbnNmb3JtPSd0cmFuc2xhdGUoMC4wMDAwMDAsIDMwLjAwMDAwMCknPlxuICAgICAgICAgICAgICAgIDxwYXRoIGlkPSdMaW5lLTgnIGZpbGw9J25vbmUnIHN0cm9rZT0nIzA5RjkxMScgc3Ryb2tlV2lkdGg9JzEnIHN0cm9rZUxpbmVjYXA9J3NxdWFyZScgZD0nTTAuNSwxLjVoMTUnIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggaWQ9J0xpbmUtOC1Db3B5JyBmaWxsPSdub25lJyBzdHJva2U9JyMwMjlENzQnIHN0cm9rZVdpZHRoPScxJyBzdHJva2VMaW5lY2FwPSdzcXVhcmUnIGQ9J00xNi41LDEuNWgxNScgLz5cbiAgICAgICAgICAgICAgICA8cGF0aCBpZD0nTGluZS04LUNvcHktMicgZmlsbD0nbm9uZScgc3Ryb2tlPScjRTM1QkQ4JyBzdHJva2VXaWR0aD0nMScgc3Ryb2tlTGluZWNhcD0nc3F1YXJlJyBkPSdNMzIuNSwxLjVoMTUnIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggaWQ9J0xpbmUtOC1Db3B5LTMnIGZpbGw9J25vbmUnIHN0cm9rZT0nIzQxNTZDNScgc3Ryb2tlV2lkdGg9JzEnIHN0cm9rZUxpbmVjYXA9J3NxdWFyZScgZD0nTTQ4LjUsMS41aDE1JyAvPlxuICAgICAgICAgICAgICAgIDxwYXRoIGlkPSdMaW5lLTgtQ29weS00JyBmaWxsPSdub25lJyBzdHJva2U9JyM2MzU2ODgnIHN0cm9rZVdpZHRoPScxJyBzdHJva2VMaW5lY2FwPSdzcXVhcmUnIGQ9J002NC41LDEuNWgxNScgLz5cbiAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgPC9nPlxuICAgICAgICAgIDwvZz5cbiAgICAgICAgPC9nPlxuICAgICAgPC9MaW5rPlxuICAgIDwvc3ZnPlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgTG9nbztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0xvZ28vaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuZnVuY3Rpb24gTmF2QmFyQ2hhbm5lbERyb3Bkb3duICh7IGNoYW5uZWxOYW1lLCBoYW5kbGVTZWxlY3Rpb24sIGRlZmF1bHRTZWxlY3Rpb24sIFZJRVcsIExPR09VVCB9KSB7XG4gIHJldHVybiAoXG4gICAgPHNlbGVjdCB0eXBlPSd0ZXh0JyBpZD0nbmF2LWJhci1jaGFubmVsLXNlbGVjdCcgY2xhc3NOYW1lPSdzZWxlY3Qgc2VsZWN0LS1hcnJvdyBsaW5rLS1uYXYnIG9uQ2hhbmdlPXtoYW5kbGVTZWxlY3Rpb259IHZhbHVlPXtkZWZhdWx0U2VsZWN0aW9ufT5cbiAgICAgIDxvcHRpb24gaWQ9J25hdi1iYXItY2hhbm5lbC1zZWxlY3QtY2hhbm5lbC1vcHRpb24nPntjaGFubmVsTmFtZX08L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9e1ZJRVd9PlZpZXc8L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9e0xPR09VVH0+TG9nb3V0PC9vcHRpb24+XG4gICAgPC9zZWxlY3Q+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBOYXZCYXJDaGFubmVsRHJvcGRvd247XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duL2luZGV4LmpzeCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNyb3NzLWZldGNoL3BvbHlmaWxsXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiY3Jvc3MtZmV0Y2gvcG9seWZpbGxcIlxuLy8gbW9kdWxlIGlkID0gOTZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBkaXNhYmxlZDogcHVibGlzaC5kaXNhYmxlZCxcbiAgICBmaWxlICAgIDogcHVibGlzaC5maWxlLFxuICAgIHN0YXR1cyAgOiBwdWJsaXNoLnN0YXR1cy5zdGF0dXMsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVG9vbC9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRHJvcHpvbmUgZnJvbSAnY29udGFpbmVycy9Ecm9wem9uZSc7XG5pbXBvcnQgUHVibGlzaERldGFpbHMgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoRGV0YWlscyc7XG5pbXBvcnQgUHVibGlzaFN0YXR1cyBmcm9tICdjb250YWluZXJzL1B1Ymxpc2hTdGF0dXMnO1xuaW1wb3J0IFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlJztcblxuY2xhc3MgUHVibGlzaFRvb2wgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGlmICh0aGlzLnByb3BzLmRpc2FibGVkKSB7XG4gICAgICBjb25zb2xlLmxvZygncHVibGlzaCBpcyBkaXNhYmxlZCcpO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UgLz5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKCdwdWJsaXNoIGlzIG5vdCBkaXNhYmxlZCcpO1xuICAgICAgaWYgKHRoaXMucHJvcHMuZmlsZSkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5zdGF0dXMpIHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPFB1Ymxpc2hTdGF0dXMgLz5cbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiA8UHVibGlzaERldGFpbHMgLz47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiA8RHJvcHpvbmUgLz47XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBQdWJsaXNoVG9vbDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUb29sL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHZhbGlkYXRlRmlsZSB9IGZyb20gJ3V0aWxzL2ZpbGUnO1xuaW1wb3J0IFB1Ymxpc2hQcmV2aWV3IGZyb20gJ2NvbXBvbmVudHMvUHVibGlzaFByZXZpZXcnO1xuXG5jbGFzcyBEcm9wem9uZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgZHJhZ092ZXIgIDogZmFsc2UsXG4gICAgICBtb3VzZU92ZXIgOiBmYWxzZSxcbiAgICAgIGRpbVByZXZpZXc6IGZhbHNlLFxuICAgIH07XG4gICAgdGhpcy5oYW5kbGVEcm9wID0gdGhpcy5oYW5kbGVEcm9wLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVEcmFnT3ZlciA9IHRoaXMuaGFuZGxlRHJhZ092ZXIuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZURyYWdFbmQgPSB0aGlzLmhhbmRsZURyYWdFbmQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZURyYWdFbnRlciA9IHRoaXMuaGFuZGxlRHJhZ0VudGVyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVEcmFnTGVhdmUgPSB0aGlzLmhhbmRsZURyYWdMZWF2ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlTW91c2VFbnRlciA9IHRoaXMuaGFuZGxlTW91c2VFbnRlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlTW91c2VMZWF2ZSA9IHRoaXMuaGFuZGxlTW91c2VMZWF2ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlQ2xpY2sgPSB0aGlzLmhhbmRsZUNsaWNrLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVGaWxlSW5wdXQgPSB0aGlzLmhhbmRsZUZpbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuY2hvb3NlRmlsZSA9IHRoaXMuY2hvb3NlRmlsZS5iaW5kKHRoaXMpO1xuICB9XG4gIGhhbmRsZURyb3AgKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLnNldFN0YXRlKHtkcmFnT3ZlcjogZmFsc2V9KTtcbiAgICAvLyBpZiBkcm9wcGVkIGl0ZW1zIGFyZW4ndCBmaWxlcywgcmVqZWN0IHRoZW1cbiAgICBjb25zdCBkdCA9IGV2ZW50LmRhdGFUcmFuc2ZlcjtcbiAgICBpZiAoZHQuaXRlbXMpIHtcbiAgICAgIGlmIChkdC5pdGVtc1swXS5raW5kID09PSAnZmlsZScpIHtcbiAgICAgICAgY29uc3QgZHJvcHBlZEZpbGUgPSBkdC5pdGVtc1swXS5nZXRBc0ZpbGUoKTtcbiAgICAgICAgdGhpcy5jaG9vc2VGaWxlKGRyb3BwZWRGaWxlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaGFuZGxlRHJhZ092ZXIgKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuICBoYW5kbGVEcmFnRW5kIChldmVudCkge1xuICAgIHZhciBkdCA9IGV2ZW50LmRhdGFUcmFuc2ZlcjtcbiAgICBpZiAoZHQuaXRlbXMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZHQuaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZHQuaXRlbXMucmVtb3ZlKGkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBldmVudC5kYXRhVHJhbnNmZXIuY2xlYXJEYXRhKCk7XG4gICAgfVxuICB9XG4gIGhhbmRsZURyYWdFbnRlciAoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7ZHJhZ092ZXI6IHRydWUsIGRpbVByZXZpZXc6IHRydWV9KTtcbiAgfVxuICBoYW5kbGVEcmFnTGVhdmUgKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe2RyYWdPdmVyOiBmYWxzZSwgZGltUHJldmlldzogZmFsc2V9KTtcbiAgfVxuICBoYW5kbGVNb3VzZUVudGVyICgpIHtcbiAgICB0aGlzLnNldFN0YXRlKHttb3VzZU92ZXI6IHRydWUsIGRpbVByZXZpZXc6IHRydWV9KTtcbiAgfVxuICBoYW5kbGVNb3VzZUxlYXZlICgpIHtcbiAgICB0aGlzLnNldFN0YXRlKHttb3VzZU92ZXI6IGZhbHNlLCBkaW1QcmV2aWV3OiBmYWxzZX0pO1xuICB9XG4gIGhhbmRsZUNsaWNrIChldmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbGVfaW5wdXQnKS5jbGljaygpO1xuICB9XG4gIGhhbmRsZUZpbGVJbnB1dCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IGZpbGVMaXN0ID0gZXZlbnQudGFyZ2V0LmZpbGVzO1xuICAgIHRoaXMuY2hvb3NlRmlsZShmaWxlTGlzdFswXSk7XG4gIH1cbiAgY2hvb3NlRmlsZSAoZmlsZSkge1xuICAgIGlmIChmaWxlKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWxpZGF0ZUZpbGUoZmlsZSk7IC8vIHZhbGlkYXRlIHRoZSBmaWxlJ3MgbmFtZSwgdHlwZSwgYW5kIHNpemVcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BzLnNldEZpbGVFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIC8vIHN0YWdlIGl0IHNvIGl0IHdpbGwgYmUgcmVhZHkgd2hlbiB0aGUgcHVibGlzaCBidXR0b24gaXMgY2xpY2tlZFxuICAgICAgdGhpcy5wcm9wcy5zZWxlY3RGaWxlKGZpbGUpO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uJz5cbiAgICAgICAgPGZvcm0+XG4gICAgICAgICAgPGlucHV0IGNsYXNzTmFtZT0naW5wdXQtZmlsZScgdHlwZT0nZmlsZScgaWQ9J2ZpbGVfaW5wdXQnIG5hbWU9J2ZpbGVfaW5wdXQnIGFjY2VwdD0ndmlkZW8vKixpbWFnZS8qJyBvbkNoYW5nZT17dGhpcy5oYW5kbGVGaWxlSW5wdXR9IGVuY1R5cGU9J211bHRpcGFydC9mb3JtLWRhdGEnIC8+XG4gICAgICAgIDwvZm9ybT5cbiAgICAgICAgPGRpdiBpZD0ncHJldmlldy1kcm9wem9uZScgY2xhc3NOYW1lPXsncm93IHJvdy0tcGFkZGVkIHJvdy0tdGFsbCBkcm9wem9uZScgKyAodGhpcy5zdGF0ZS5kcmFnT3ZlciA/ICcgZHJvcHpvbmUtLWRyYWctb3ZlcicgOiAnJyl9IG9uRHJvcD17dGhpcy5oYW5kbGVEcm9wfSBvbkRyYWdPdmVyPXt0aGlzLmhhbmRsZURyYWdPdmVyfSBvbkRyYWdFbmQ9e3RoaXMuaGFuZGxlRHJhZ0VuZH0gb25EcmFnRW50ZXI9e3RoaXMuaGFuZGxlRHJhZ0VudGVyfSBvbkRyYWdMZWF2ZT17dGhpcy5oYW5kbGVEcmFnTGVhdmV9IG9uTW91c2VFbnRlcj17dGhpcy5oYW5kbGVNb3VzZUVudGVyfSBvbk1vdXNlTGVhdmU9e3RoaXMuaGFuZGxlTW91c2VMZWF2ZX0gb25DbGljaz17dGhpcy5oYW5kbGVDbGlja30+XG4gICAgICAgICAge3RoaXMucHJvcHMuZmlsZSA/IChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxQdWJsaXNoUHJldmlld1xuICAgICAgICAgICAgICAgIGRpbVByZXZpZXc9e3RoaXMuc3RhdGUuZGltUHJldmlld31cbiAgICAgICAgICAgICAgICBmaWxlPXt0aGlzLnByb3BzLmZpbGV9XG4gICAgICAgICAgICAgICAgdGh1bWJuYWlsPXt0aGlzLnByb3BzLnRodW1ibmFpbH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPGRpdiBpZD0nZHJvcHpvbmUtdGV4dC1ob2xkZXInIGNsYXNzTmFtZT17J2ZsZXgtY29udGFpbmVyLS1jb2x1bW4gZmxleC1jb250YWluZXItLWNlbnRlci1jZW50ZXInfT5cbiAgICAgICAgICAgICAgICB7IHRoaXMuc3RhdGUuZHJhZ092ZXIgPyAoXG4gICAgICAgICAgICAgICAgICA8ZGl2IGlkPSdkcm9wem9uZS1kcmFnb3Zlcic+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nYmx1ZSc+RHJvcCBpdC48L3A+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgeyB0aGlzLnN0YXRlLm1vdXNlT3ZlciA/IChcbiAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLWluc3RydWN0aW9ucyc+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLXBsYWNlaG9sZGVyIGluZm8tbWVzc2FnZS0tZmFpbHVyZScgaWQ9J2lucHV0LWVycm9yLWZpbGUtc2VsZWN0aW9uJz57dGhpcy5wcm9wcy5maWxlRXJyb3J9PC9wPlxuICAgICAgICAgICAgICAgICAgICA8cD5EcmFnICYgZHJvcCBpbWFnZSBvciB2aWRlbyBoZXJlIHRvIHB1Ymxpc2g8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+T1I8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nYmx1ZS0tdW5kZXJsaW5lZCc+Q0hPT1NFIEZJTEU8L3A+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLXRleHQtaG9sZGVyJyBjbGFzc05hbWU9eydmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJ30+XG4gICAgICAgICAgICAgIHsgdGhpcy5zdGF0ZS5kcmFnT3ZlciA/IChcbiAgICAgICAgICAgICAgICA8ZGl2IGlkPSdkcm9wem9uZS1kcmFnb3Zlcic+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2JsdWUnPkRyb3AgaXQuPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLWluc3RydWN0aW9ucyc+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS1wbGFjZWhvbGRlciBpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnIGlkPSdpbnB1dC1lcnJvci1maWxlLXNlbGVjdGlvbic+e3RoaXMucHJvcHMuZmlsZUVycm9yfTwvcD5cbiAgICAgICAgICAgICAgICAgIDxwPkRyYWcgJiBkcm9wIGltYWdlIG9yIHZpZGVvIGhlcmUgdG8gcHVibGlzaDwvcD5cbiAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+T1I8L3A+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2JsdWUtLXVuZGVybGluZWQnPkNIT09TRSBGSUxFPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBEcm9wem9uZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Ryb3B6b25lL3ZpZXcuanN4IiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlRmlsZSAoZmlsZSkge1xuICAgIGlmICghZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHByb3ZpZGVkJyk7XG4gICAgfVxuICAgIGlmICgvJy8udGVzdChmaWxlLm5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Fwb3N0cm9waGVzIGFyZSBub3QgYWxsb3dlZCBpbiB0aGUgZmlsZSBuYW1lJyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHNpemUgYW5kIHR5cGVcbiAgICBzd2l0Y2ggKGZpbGUudHlwZSkge1xuICAgICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgICBjYXNlICdpbWFnZS9qcGcnOlxuICAgICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDEwMDAwMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb3JyeSwgaW1hZ2VzIGFyZSBsaW1pdGVkIHRvIDEwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ltYWdlL2dpZic6XG4gICAgICAgIGlmIChmaWxlLnNpemUgPiA1MDAwMDAwMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU29ycnksIEdJRnMgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndmlkZW8vbXA0JzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb3JyeSwgdmlkZW9zIGFyZSBsaW1pdGVkIHRvIDUwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihmaWxlLnR5cGUgKyAnIGlzIG5vdCBhIHN1cHBvcnRlZCBmaWxlIHR5cGUuIE9ubHksIC5qcGVnLCAucG5nLCAuZ2lmLCBhbmQgLm1wNCBmaWxlcyBhcmUgY3VycmVudGx5IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3V0aWxzL2ZpbGUuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcblxuY2xhc3MgUHVibGlzaFByZXZpZXcgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGltZ1NvdXJjZSAgICAgICA6ICcnLFxuICAgICAgZGVmYXVsdFRodW1ibmFpbDogJy9hc3NldHMvaW1nL3ZpZGVvX3RodW1iX2RlZmF1bHQucG5nJyxcbiAgICB9O1xuICB9XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnNldFByZXZpZXdJbWFnZVNvdXJjZSh0aGlzLnByb3BzLmZpbGUpO1xuICB9XG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgKG5ld1Byb3BzKSB7XG4gICAgaWYgKG5ld1Byb3BzLmZpbGUgIT09IHRoaXMucHJvcHMuZmlsZSkge1xuICAgICAgdGhpcy5zZXRQcmV2aWV3SW1hZ2VTb3VyY2UobmV3UHJvcHMuZmlsZSk7XG4gICAgfVxuICAgIGlmIChuZXdQcm9wcy50aHVtYm5haWwgIT09IHRoaXMucHJvcHMudGh1bWJuYWlsKSB7XG4gICAgICBpZiAobmV3UHJvcHMudGh1bWJuYWlsKSB7XG4gICAgICAgIHRoaXMuc2V0UHJldmlld0ltYWdlU291cmNlRnJvbUZpbGUobmV3UHJvcHMudGh1bWJuYWlsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe2ltZ1NvdXJjZTogdGhpcy5zdGF0ZS5kZWZhdWx0VGh1bWJuYWlsfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlIChmaWxlKSB7XG4gICAgY29uc3QgcHJldmlld1JlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcHJldmlld1JlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIHByZXZpZXdSZWFkZXIub25sb2FkZW5kID0gKCkgPT4ge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7aW1nU291cmNlOiBwcmV2aWV3UmVhZGVyLnJlc3VsdH0pO1xuICAgIH07XG4gIH1cbiAgc2V0UHJldmlld0ltYWdlU291cmNlIChmaWxlKSB7XG4gICAgaWYgKGZpbGUudHlwZSAhPT0gJ3ZpZGVvL21wNCcpIHtcbiAgICAgIHRoaXMuc2V0UHJldmlld0ltYWdlU291cmNlRnJvbUZpbGUoZmlsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnByb3BzLnRodW1ibmFpbCkge1xuICAgICAgICB0aGlzLnNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlKHRoaXMucHJvcHMudGh1bWJuYWlsKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoe2ltZ1NvdXJjZTogdGhpcy5zdGF0ZS5kZWZhdWx0VGh1bWJuYWlsfSk7XG4gICAgfVxuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxpbWdcbiAgICAgICAgaWQ9J2Ryb3B6b25lLXByZXZpZXcnXG4gICAgICAgIHNyYz17dGhpcy5zdGF0ZS5pbWdTb3VyY2V9XG4gICAgICAgIGNsYXNzTmFtZT17dGhpcy5wcm9wcy5kaW1QcmV2aWV3ID8gJ2RpbScgOiAnJ31cbiAgICAgICAgYWx0PSdwdWJsaXNoIHByZXZpZXcnXG4gICAgICAvPlxuICAgICk7XG4gIH1cbn07XG5cblB1Ymxpc2hQcmV2aWV3LnByb3BUeXBlcyA9IHtcbiAgZGltUHJldmlldzogUHJvcFR5cGVzLmJvb2wuaXNSZXF1aXJlZCxcbiAgZmlsZSAgICAgIDogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICB0aHVtYm5haWwgOiBQcm9wVHlwZXMub2JqZWN0LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgUHVibGlzaFByZXZpZXc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9QdWJsaXNoUHJldmlldy9pbmRleC5qc3giLCJpbXBvcnQge2Nvbm5lY3R9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7Y2xlYXJGaWxlLCBzdGFydFB1Ymxpc2h9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBjaGFubmVsLCBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBmaWxlOiBwdWJsaXNoLmZpbGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIGNsZWFyRmlsZSxcbiAgc3RhcnRQdWJsaXNoLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGV0YWlscy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgRHJvcHpvbmUgZnJvbSAnY29udGFpbmVycy9Ecm9wem9uZSc7XG5pbXBvcnQgUHVibGlzaFRpdGxlSW5wdXQgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoVGl0bGVJbnB1dCc7XG5pbXBvcnQgUHVibGlzaFVybElucHV0IGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaFVybElucHV0JztcbmltcG9ydCBQdWJsaXNoVGh1bWJuYWlsSW5wdXQgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQnO1xuaW1wb3J0IFB1Ymxpc2hNZXRhZGF0YUlucHV0cyBmcm9tICdjb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cyc7XG5pbXBvcnQgQ2hhbm5lbFNlbGVjdCBmcm9tICdjb250YWluZXJzL0NoYW5uZWxTZWxlY3QnO1xuXG5jbGFzcyBQdWJsaXNoRGV0YWlscyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKVxuICAgIHRoaXMub25QdWJsaXNoU3VibWl0ID0gdGhpcy5vblB1Ymxpc2hTdWJtaXQuYmluZCh0aGlzKTtcbiAgfVxuICBvblB1Ymxpc2hTdWJtaXQgKCkge1xuICAgIHRoaXMucHJvcHMuc3RhcnRQdWJsaXNoKHRoaXMucHJvcHMuaGlzdG9yeSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLW5vLWJvdHRvbSc+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xMCc+XG4gICAgICAgICAgPFB1Ymxpc2hUaXRsZUlucHV0IC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7LyogbGVmdCBjb2x1bW4gKi99XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwJyA+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8RHJvcHpvbmUgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIHsvKiByaWdodCBjb2x1bW4gKi99XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICA8ZGl2IGlkPSdwdWJsaXNoLWFjdGl2ZS1hcmVhJyBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0tbm8tdG9wIHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgIDxQdWJsaXNoVXJsSW5wdXQgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUnPlxuICAgICAgICAgICAgICA8Q2hhbm5lbFNlbGVjdCAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB7ICh0aGlzLnByb3BzLmZpbGUudHlwZSA9PT0gJ3ZpZGVvL21wNCcpICYmIChcbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUgJz5cbiAgICAgICAgICAgICAgICA8UHVibGlzaFRodW1ibmFpbElucHV0IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1uby10b3Agcm93LS1uby1ib3R0b20gcm93LS13aWRlJz5cbiAgICAgICAgICAgICAgPFB1Ymxpc2hNZXRhZGF0YUlucHV0cyAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICAgIDxidXR0b24gaWQ9J3B1Ymxpc2gtc3VibWl0JyBjbGFzc05hbWU9J2J1dHRvbi0tcHJpbWFyeSBidXR0b24tLWxhcmdlJyBvbkNsaWNrPXt0aGlzLm9uUHVibGlzaFN1Ym1pdH0+UHVibGlzaDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0tbm8tYm90dG9tIGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9J2J1dHRvbi0tY2FuY2VsJyBvbkNsaWNrPXt0aGlzLnByb3BzLmNsZWFyRmlsZX0+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1zaG9ydCBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+QnkgY2xpY2tpbmcgJ1B1Ymxpc2gnLCB5b3UgYWZmaXJtIHRoYXQgeW91IGhhdmUgdGhlIHJpZ2h0cyB0byBwdWJsaXNoIHRoaXMgY29udGVudCB0byB0aGUgTEJSWSBuZXR3b3JrLCBhbmQgdGhhdCB5b3UgdW5kZXJzdGFuZCB0aGUgcHJvcGVydGllcyBvZiBwdWJsaXNoaW5nIGl0IHRvIGEgZGVjZW50cmFsaXplZCwgdXNlci1jb250cm9sbGVkIG5ldHdvcmsuIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9sZWFybic+UmVhZCBtb3JlLjwvYT48L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKFB1Ymxpc2hEZXRhaWxzKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEZXRhaWxzL3ZpZXcuanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge3VwZGF0ZU1ldGFkYXRhfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgdGl0bGU6IHB1Ymxpc2gubWV0YWRhdGEudGl0bGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25NZXRhZGF0YUNoYW5nZTogKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVNZXRhZGF0YShuYW1lLCB2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY2xhc3MgUHVibGlzaFRpdGxlSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgfVxuICBoYW5kbGVJbnB1dCAoZSkge1xuICAgIGNvbnN0IG5hbWUgPSBlLnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZS50YXJnZXQudmFsdWU7XG4gICAgdGhpcy5wcm9wcy5vbk1ldGFkYXRhQ2hhbmdlKG5hbWUsIHZhbHVlKTtcbiAgfVxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8aW5wdXQgdHlwZT0ndGV4dCcgaWQ9J3B1Ymxpc2gtdGl0bGUnIGNsYXNzTmFtZT0naW5wdXQtdGV4dCB0ZXh0LS1sYXJnZSBpbnB1dC10ZXh0LS1mdWxsLXdpZHRoJyBuYW1lPSd0aXRsZScgcGxhY2Vob2xkZXI9J0dpdmUgeW91ciBwb3N0IGEgdGl0bGUuLi4nIG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSB2YWx1ZT17dGhpcy5wcm9wcy50aXRsZX0gLz5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hUaXRsZUlucHV0O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFRpdGxlSW5wdXQvdmlldy5qc3giLCJpbXBvcnQge3VwZGF0ZUNsYWltLCB1cGRhdGVFcnJvcn0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgY2hhbm5lbCwgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgbG9nZ2VkSW5DaGFubmVsTmFtZSAgIDogY2hhbm5lbC5sb2dnZWRJbkNoYW5uZWwubmFtZSxcbiAgICBsb2dnZWRJbkNoYW5uZWxTaG9ydElkOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5zaG9ydElkLFxuICAgIGZpbGVOYW1lICAgICAgICAgICAgICA6IHB1Ymxpc2guZmlsZS5uYW1lLFxuICAgIHB1Ymxpc2hJbkNoYW5uZWwgICAgICA6IHB1Ymxpc2gucHVibGlzaEluQ2hhbm5lbCxcbiAgICBzZWxlY3RlZENoYW5uZWwgICAgICAgOiBwdWJsaXNoLnNlbGVjdGVkQ2hhbm5lbCxcbiAgICBjbGFpbSAgICAgICAgICAgICAgICAgOiBwdWJsaXNoLmNsYWltLFxuICAgIHVybEVycm9yICAgICAgICAgICAgICA6IHB1Ymxpc2guZXJyb3IudXJsLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2xhaW1DaGFuZ2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgZGlzcGF0Y2godXBkYXRlQ2xhaW0odmFsdWUpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUVycm9yKCdwdWJsaXNoU3VibWl0JywgbnVsbCkpO1xuICAgIH0sXG4gICAgb25VcmxFcnJvcjogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcigndXJsJywgdmFsdWUpKTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHJlcXVlc3QgZnJvbSAndXRpbHMvcmVxdWVzdCc7XG5pbXBvcnQgVXJsTWlkZGxlIGZyb20gJ2NvbXBvbmVudHMvUHVibGlzaFVybE1pZGRsZURpc3BsYXknO1xuXG5jbGFzcyBQdWJsaXNoVXJsSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBjbGFpbSwgZmlsZU5hbWUgfSA9IHRoaXMucHJvcHM7XG4gICAgaWYgKCFjbGFpbSkge1xuICAgICAgdGhpcy5zZXRDbGFpbU5hbWUoZmlsZU5hbWUpO1xuICAgIH1cbiAgfVxuICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzICh7IGNsYWltLCBmaWxlTmFtZSB9KSB7XG4gICAgLy8gaWYgYSBuZXcgZmlsZSB3YXMgY2hvc2VuLCB1cGRhdGUgdGhlIGNsYWltIG5hbWVcbiAgICBpZiAoZmlsZU5hbWUgIT09IHRoaXMucHJvcHMuZmlsZU5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldENsYWltTmFtZShmaWxlTmFtZSk7XG4gICAgfVxuICAgIC8vIGlmIHRoZSBjbGFpbSBoYXMgdXBkYXRlZCwgY2hlY2sgaXRzIGF2YWlsYWJpbGl0eVxuICAgIGlmIChjbGFpbSAhPT0gdGhpcy5wcm9wcy5jbGFpbSkge1xuICAgICAgdGhpcy52YWxpZGF0ZUNsYWltKGNsYWltKTtcbiAgICB9XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgbGV0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHZhbHVlID0gdGhpcy5jbGVhbnNlSW5wdXQodmFsdWUpO1xuICAgIC8vIHVwZGF0ZSB0aGUgc3RhdGVcbiAgICB0aGlzLnByb3BzLm9uQ2xhaW1DaGFuZ2UodmFsdWUpO1xuICB9XG4gIGNsZWFuc2VJbnB1dCAoaW5wdXQpIHtcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1xccysvZywgJy0nKTsgLy8gcmVwbGFjZSBzcGFjZXMgd2l0aCBkYXNoZXNcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05LV0vZywgJycpOyAgLy8gcmVtb3ZlIGFsbCBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBBLVosIGEteiwgMC05LCBvciAnLSdcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cbiAgc2V0Q2xhaW1OYW1lIChmaWxlTmFtZSkge1xuICAgIGNvbnN0IGZpbGVOYW1lV2l0aG91dEVuZGluZyA9IGZpbGVOYW1lLnN1YnN0cmluZygwLCBmaWxlTmFtZS5sYXN0SW5kZXhPZignLicpKTtcbiAgICBjb25zdCBjbGVhbkNsYWltTmFtZSA9IHRoaXMuY2xlYW5zZUlucHV0KGZpbGVOYW1lV2l0aG91dEVuZGluZyk7XG4gICAgdGhpcy5wcm9wcy5vbkNsYWltQ2hhbmdlKGNsZWFuQ2xhaW1OYW1lKTtcbiAgfVxuICB2YWxpZGF0ZUNsYWltIChjbGFpbSkge1xuICAgIGlmICghY2xhaW0pIHtcbiAgICAgIHJldHVybiB0aGlzLnByb3BzLm9uVXJsRXJyb3IoJ0VudGVyIGEgdXJsIGFib3ZlJyk7XG4gICAgfVxuICAgIHJlcXVlc3QoYC9hcGkvY2xhaW0vYXZhaWxhYmlsaXR5LyR7Y2xhaW19YClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVybEVycm9yKG51bGwpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVybEVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGNsYWltLCBsb2dnZWRJbkNoYW5uZWxOYW1lLCBsb2dnZWRJbkNoYW5uZWxTaG9ydElkLCBwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwsIHVybEVycm9yIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBzcGFuLS1yZWxhdGl2ZSc+XG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd1cmwtdGV4dC0tc2Vjb25kYXJ5Jz5zcGVlLmNoIC8gPC9zcGFuPlxuICAgICAgICAgIDxVcmxNaWRkbGVcbiAgICAgICAgICAgIHB1Ymxpc2hJbkNoYW5uZWw9e3B1Ymxpc2hJbkNoYW5uZWx9XG4gICAgICAgICAgICBzZWxlY3RlZENoYW5uZWw9e3NlbGVjdGVkQ2hhbm5lbH1cbiAgICAgICAgICAgIGxvZ2dlZEluQ2hhbm5lbE5hbWU9e2xvZ2dlZEluQ2hhbm5lbE5hbWV9XG4gICAgICAgICAgICBsb2dnZWRJbkNoYW5uZWxTaG9ydElkPXtsb2dnZWRJbkNoYW5uZWxTaG9ydElkfVxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdjbGFpbS1uYW1lLWlucHV0JyBjbGFzc05hbWU9J2lucHV0LXRleHQnIG5hbWU9J2NsYWltJyBwbGFjZWhvbGRlcj0neW91ci11cmwtaGVyZScgb25DaGFuZ2U9e3RoaXMuaGFuZGxlSW5wdXR9IHZhbHVlPXtjbGFpbX0gLz5cbiAgICAgICAgICB7IChjbGFpbSAmJiAhdXJsRXJyb3IpICYmIDxzcGFuIGlkPSdpbnB1dC1zdWNjZXNzLWNsYWltLW5hbWUnIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1zdWNjZXNzIHNwYW4tLWFic29sdXRlJz57J1xcdTI3MTMnfTwvc3Bhbj4gfVxuICAgICAgICAgIHsgdXJsRXJyb3IgJiYgPHNwYW4gaWQ9J2lucHV0LXN1Y2Nlc3MtY2hhbm5lbC1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSBzcGFuLS1hYnNvbHV0ZSc+eydcXHUyNzE2J308L3NwYW4+IH1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgeyB1cmxFcnJvciA/IChcbiAgICAgICAgICAgIDxwIGlkPSdpbnB1dC1lcnJvci1jbGFpbS1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e3VybEVycm9yfTwvcD5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPkNob29zZSBhIGN1c3RvbSB1cmw8L3A+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hVcmxJbnB1dDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hVcmxJbnB1dC92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5mdW5jdGlvbiBVcmxNaWRkbGUgKHtwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwsIGxvZ2dlZEluQ2hhbm5lbE5hbWUsIGxvZ2dlZEluQ2hhbm5lbFNob3J0SWR9KSB7XG4gIGlmIChwdWJsaXNoSW5DaGFubmVsKSB7XG4gICAgaWYgKHNlbGVjdGVkQ2hhbm5lbCA9PT0gbG9nZ2VkSW5DaGFubmVsTmFtZSkge1xuICAgICAgcmV0dXJuIDxzcGFuIGlkPSd1cmwtY2hhbm5lbCcgY2xhc3NOYW1lPSd1cmwtdGV4dC0tc2Vjb25kYXJ5Jz57bG9nZ2VkSW5DaGFubmVsTmFtZX06e2xvZ2dlZEluQ2hhbm5lbFNob3J0SWR9IC88L3NwYW4+O1xuICAgIH1cbiAgICByZXR1cm4gPHNwYW4gaWQ9J3VybC1jaGFubmVsLXBsYWNlaG9sZGVyJyBjbGFzc05hbWU9J3VybC10ZXh0LS1zZWNvbmRhcnkgdG9vbHRpcCc+QGNoYW5uZWw8c3BhblxuICAgICAgY2xhc3NOYW1lPSd0b29sdGlwLXRleHQnPlNlbGVjdCBhIGNoYW5uZWwgYmVsb3c8L3NwYW4+IC88L3NwYW4+O1xuICB9XG4gIHJldHVybiAoXG4gICAgPHNwYW4gaWQ9J3VybC1uby1jaGFubmVsLXBsYWNlaG9sZGVyJyBjbGFzc05hbWU9J3VybC10ZXh0LS1zZWNvbmRhcnkgdG9vbHRpcCc+eHl6PHNwYW4gY2xhc3NOYW1lPSd0b29sdGlwLXRleHQnPlRoaXMgd2lsbCBiZSBhIHJhbmRvbSBpZDwvc3Bhbj4gLzwvc3Bhbj5cbiAgKTtcbn1cblxuVXJsTWlkZGxlLnByb3BUeXBlcyA9IHtcbiAgcHVibGlzaEluQ2hhbm5lbCAgICAgIDogUHJvcFR5cGVzLmJvb2wuaXNSZXF1aXJlZCxcbiAgbG9nZ2VkSW5DaGFubmVsTmFtZSAgIDogUHJvcFR5cGVzLnN0cmluZyxcbiAgbG9nZ2VkSW5DaGFubmVsU2hvcnRJZDogUHJvcFR5cGVzLnN0cmluZyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFVybE1pZGRsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL1B1Ymxpc2hVcmxNaWRkbGVEaXNwbGF5L2luZGV4LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBvbk5ld1RodW1ibmFpbCB9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoOiB7IGZpbGUgfSB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZmlsZSxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IHtcbiAgb25OZXdUaHVtYm5haWwsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaHVtYm5haWxJbnB1dC9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmZ1bmN0aW9uIGRhdGFVUkl0b0Jsb2IoZGF0YVVSSSkge1xuICAvLyBjb252ZXJ0IGJhc2U2NC9VUkxFbmNvZGVkIGRhdGEgY29tcG9uZW50IHRvIHJhdyBiaW5hcnkgZGF0YSBoZWxkIGluIGEgc3RyaW5nXG4gIGxldCBieXRlU3RyaW5nID0gYXRvYihkYXRhVVJJLnNwbGl0KCcsJylbMV0pO1xuICAvLyBzZXBhcmF0ZSBvdXQgdGhlIG1pbWUgY29tcG9uZW50XG4gIGxldCBtaW1lU3RyaW5nID0gZGF0YVVSSS5zcGxpdCgnLCcpWzBdLnNwbGl0KCc6JylbMV0uc3BsaXQoJzsnKVswXTtcbiAgLy8gd3JpdGUgdGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmcgdG8gYSB0eXBlZCBhcnJheVxuICBsZXQgaWEgPSBuZXcgVWludDhBcnJheShieXRlU3RyaW5nLmxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZVN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgIGlhW2ldID0gYnl0ZVN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICB9XG4gIHJldHVybiBuZXcgQmxvYihbaWFdLCB7dHlwZTogbWltZVN0cmluZ30pO1xufVxuXG5jbGFzcyBQdWJsaXNoVGh1bWJuYWlsSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIHZpZGVvU291cmNlICAgOiBudWxsLFxuICAgICAgZXJyb3IgICAgICAgICA6IG51bGwsXG4gICAgICBzbGlkZXJNaW5SYW5nZTogMSxcbiAgICAgIHNsaWRlck1heFJhbmdlOiBudWxsLFxuICAgICAgc2xpZGVyVmFsdWUgICA6IG51bGwsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZVZpZGVvTG9hZGVkRGF0YSA9IHRoaXMuaGFuZGxlVmlkZW9Mb2FkZWREYXRhLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVTbGlkZXJDaGFuZ2UgPSB0aGlzLmhhbmRsZVNsaWRlckNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuY3JlYXRlVGh1bWJuYWlsID0gdGhpcy5jcmVhdGVUaHVtYm5haWwuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBmaWxlIH0gPSB0aGlzLnByb3BzO1xuICAgIHRoaXMuc2V0VmlkZW9Tb3VyY2UoZmlsZSk7XG4gIH1cbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyAobmV4dFByb3BzKSB7XG4gICAgLy8gaWYgZmlsZSBjaGFuZ2VzXG4gICAgaWYgKG5leHRQcm9wcy5maWxlICYmIG5leHRQcm9wcy5maWxlICE9PSB0aGlzLnByb3BzLmZpbGUpIHtcbiAgICAgIGNvbnN0IHsgZmlsZSB9ID0gbmV4dFByb3BzO1xuICAgICAgdGhpcy5zZXRWaWRlb1NvdXJjZShmaWxlKTtcbiAgICB9O1xuICB9XG4gIHNldFZpZGVvU291cmNlIChmaWxlKSB7XG4gICAgY29uc3QgcHJldmlld1JlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcHJldmlld1JlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIHByZXZpZXdSZWFkZXIub25sb2FkZW5kID0gKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVVyaSA9IHByZXZpZXdSZWFkZXIucmVzdWx0O1xuICAgICAgY29uc3QgYmxvYiA9IGRhdGFVUkl0b0Jsb2IoZGF0YVVyaSk7XG4gICAgICBjb25zdCB2aWRlb1NvdXJjZSA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlkZW9Tb3VyY2UgfSk7XG4gICAgfTtcbiAgfVxuICBoYW5kbGVWaWRlb0xvYWRlZERhdGEgKGV2ZW50KSB7XG4gICAgY29uc3QgZHVyYXRpb24gPSBldmVudC50YXJnZXQuZHVyYXRpb247XG4gICAgY29uc3QgdG90YWxNaW51dGVzID0gTWF0aC5mbG9vcihkdXJhdGlvbiAvIDYwKTtcbiAgICBjb25zdCB0b3RhbFNlY29uZHMgPSBNYXRoLmZsb29yKGR1cmF0aW9uICUgNjApO1xuICAgIC8vIHNldCB0aGUgc2xpZGVyXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzbGlkZXJNYXhSYW5nZTogZHVyYXRpb24gKiAxMDAsXG4gICAgICBzbGlkZXJWYWx1ZSAgIDogZHVyYXRpb24gKiAxMDAgLyAyLFxuICAgICAgdG90YWxNaW51dGVzLFxuICAgICAgdG90YWxTZWNvbmRzLFxuICAgIH0pO1xuICAgIC8vIHVwZGF0ZSB0aGUgY3VycmVudCB0aW1lIG9mIHRoZSB2aWRlb1xuICAgIGxldCB2aWRlbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWRlby10aHVtYi1wbGF5ZXInKTtcbiAgICB2aWRlby5jdXJyZW50VGltZSA9IGR1cmF0aW9uIC8gMjtcbiAgfVxuICBoYW5kbGVTbGlkZXJDaGFuZ2UgKGV2ZW50KSB7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZUludChldmVudC50YXJnZXQudmFsdWUpO1xuICAgIC8vIHVwZGF0ZSB0aGUgc2xpZGVyIHZhbHVlXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzbGlkZXJWYWx1ZTogdmFsdWUsXG4gICAgfSk7XG4gICAgLy8gdXBkYXRlIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIHZpZGVvXG4gICAgbGV0IHZpZGVvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpZGVvLXRodW1iLXBsYXllcicpO1xuICAgIHZpZGVvLmN1cnJlbnRUaW1lID0gdmFsdWUgLyAxMDA7XG4gIH1cbiAgY3JlYXRlVGh1bWJuYWlsICgpIHtcbiAgICAvLyB0YWtlIGEgc25hcHNob3RcbiAgICBsZXQgdmlkZW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlkZW8tdGh1bWItcGxheWVyJyk7XG4gICAgbGV0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IHZpZGVvLnZpZGVvV2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IHZpZGVvLnZpZGVvSGVpZ2h0O1xuICAgIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmRyYXdJbWFnZSh2aWRlbywgMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICBjb25zdCBkYXRhVXJsID0gY2FudmFzLnRvRGF0YVVSTCgpO1xuICAgIGNvbnN0IGJsb2IgPSBkYXRhVVJJdG9CbG9iKGRhdGFVcmwpO1xuICAgIGNvbnN0IHNuYXBzaG90ID0gbmV3IEZpbGUoW2Jsb2JdLCBgdGh1bWJuYWlsLnBuZ2AsIHtcbiAgICAgIHR5cGU6ICdpbWFnZS9wbmcnLFxuICAgIH0pO1xuICAgIC8vIHNldCB0aGUgdGh1bWJuYWlsIGluIHJlZHV4IHN0b3JlXG4gICAgaWYgKHNuYXBzaG90KSB7XG4gICAgICB0aGlzLnByb3BzLm9uTmV3VGh1bWJuYWlsKHNuYXBzaG90KTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGVycm9yLCB2aWRlb1NvdXJjZSwgc2xpZGVyTWluUmFuZ2UsIHNsaWRlck1heFJhbmdlLCBzbGlkZXJWYWx1ZSwgdG90YWxNaW51dGVzLCB0b3RhbFNlY29uZHMgfSA9IHRoaXMuc3RhdGU7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJz5UaHVtYm5haWw6PC9sYWJlbD5cbiAgICAgICAgPHZpZGVvXG4gICAgICAgICAgaWQ9J3ZpZGVvLXRodW1iLXBsYXllcidcbiAgICAgICAgICBwcmVsb2FkPSdtZXRhZGF0YSdcbiAgICAgICAgICBtdXRlZFxuICAgICAgICAgIHN0eWxlPXt7ZGlzcGxheTogJ25vbmUnfX1cbiAgICAgICAgICBwbGF5c0lubGluZVxuICAgICAgICAgIG9uTG9hZGVkRGF0YT17dGhpcy5oYW5kbGVWaWRlb0xvYWRlZERhdGF9XG4gICAgICAgICAgc3JjPXt2aWRlb1NvdXJjZX1cbiAgICAgICAgICBvblNlZWtlZD17dGhpcy5jcmVhdGVUaHVtYm5haWx9XG4gICAgICAgIC8+XG4gICAgICAgIHtcbiAgICAgICAgICBzbGlkZXJWYWx1ZSA/IChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWNlbnRlcicgc3R5bGU9e3t3aWR0aDogJzEwMCUnfX0+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPjAnMDBcIjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+e3RvdGFsTWludXRlc30ne3RvdGFsU2Vjb25kc31cIjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPSdyYW5nZSdcbiAgICAgICAgICAgICAgICAgIG1pbj17c2xpZGVyTWluUmFuZ2V9XG4gICAgICAgICAgICAgICAgICBtYXg9e3NsaWRlck1heFJhbmdlfVxuICAgICAgICAgICAgICAgICAgdmFsdWU9e3NsaWRlclZhbHVlfVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPSdzbGlkZXInXG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5oYW5kbGVTbGlkZXJDaGFuZ2V9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnID5sb2FkaW5nLi4uIDwvcD5cbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgeyBlcnJvciA/IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e2Vycm9yfTwvcD5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+VXNlIHNsaWRlciB0byBzZXQgdGh1bWJuYWlsPC9wPlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQdWJsaXNoVGh1bWJuYWlsSW5wdXQ7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQvdmlldy5qc3giLCJpbXBvcnQge2Nvbm5lY3R9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7dXBkYXRlTWV0YWRhdGEsIHRvZ2dsZU1ldGFkYXRhSW5wdXRzfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgc2hvd01ldGFkYXRhSW5wdXRzOiBwdWJsaXNoLnNob3dNZXRhZGF0YUlucHV0cyxcbiAgICBkZXNjcmlwdGlvbiAgICAgICA6IHB1Ymxpc2gubWV0YWRhdGEuZGVzY3JpcHRpb24sXG4gICAgbGljZW5zZSAgICAgICAgICAgOiBwdWJsaXNoLm1ldGFkYXRhLmxpY2Vuc2UsXG4gICAgbnNmdyAgICAgICAgICAgICAgOiBwdWJsaXNoLm1ldGFkYXRhLm5zZncsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25NZXRhZGF0YUNoYW5nZTogKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVNZXRhZGF0YShuYW1lLCB2YWx1ZSkpO1xuICAgIH0sXG4gICAgb25Ub2dnbGVNZXRhZGF0YUlucHV0czogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh0b2dnbGVNZXRhZGF0YUlucHV0cyh2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRXhwYW5kaW5nVGV4dEFyZWEgZnJvbSAnY29tcG9uZW50cy9FeHBhbmRpbmdUZXh0QXJlYSc7XG5cbmNsYXNzIFB1Ymxpc2hNZXRhZGF0YUlucHV0cyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnRvZ2dsZVNob3dJbnB1dHMgPSB0aGlzLnRvZ2dsZVNob3dJbnB1dHMuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0ID0gdGhpcy5oYW5kbGVTZWxlY3QuYmluZCh0aGlzKTtcbiAgfVxuICB0b2dnbGVTaG93SW5wdXRzICgpIHtcbiAgICB0aGlzLnByb3BzLm9uVG9nZ2xlTWV0YWRhdGFJbnB1dHMoIXRoaXMucHJvcHMuc2hvd01ldGFkYXRhSW5wdXRzKTtcbiAgfVxuICBoYW5kbGVJbnB1dCAoZXZlbnQpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgY29uc3QgdmFsdWUgPSB0YXJnZXQudHlwZSA9PT0gJ2NoZWNrYm94JyA/IHRhcmdldC5jaGVja2VkIDogdGFyZ2V0LnZhbHVlO1xuICAgIGNvbnN0IG5hbWUgPSB0YXJnZXQubmFtZTtcbiAgICB0aGlzLnByb3BzLm9uTWV0YWRhdGFDaGFuZ2UobmFtZSwgdmFsdWUpO1xuICB9XG4gIGhhbmRsZVNlbGVjdCAoZXZlbnQpIHtcbiAgICBjb25zdCBuYW1lID0gZXZlbnQudGFyZ2V0Lm5hbWU7XG4gICAgY29uc3Qgc2VsZWN0ZWRPcHRpb24gPSBldmVudC50YXJnZXQuc2VsZWN0ZWRPcHRpb25zWzBdLnZhbHVlO1xuICAgIHRoaXMucHJvcHMub25NZXRhZGF0YUNoYW5nZShuYW1lLCBzZWxlY3RlZE9wdGlvbik7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBpZD0ncHVibGlzaC1kZXRhaWxzJyBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUnPlxuICAgICAgICB7dGhpcy5wcm9wcy5zaG93TWV0YWRhdGFJbnB1dHMgJiYgKFxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBodG1sRm9yPSdwdWJsaXNoLWxpY2Vuc2UnIGNsYXNzTmFtZT0nbGFiZWwnPkRlc2NyaXB0aW9uOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03IGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgICAgICA8RXhwYW5kaW5nVGV4dEFyZWFcbiAgICAgICAgICAgICAgICAgIGlkPSdwdWJsaXNoLWRlc2NyaXB0aW9uJ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPSd0ZXh0YXJlYSB0ZXh0YXJlYS0tcHJpbWFyeSB0ZXh0YXJlYS0tZnVsbC13aWR0aCdcbiAgICAgICAgICAgICAgICAgIHJvd3M9ezF9XG4gICAgICAgICAgICAgICAgICBtYXhMZW5ndGg9ezIwMDB9XG4gICAgICAgICAgICAgICAgICBzdHlsZT17eyBtYXhIZWlnaHQ6IDIwMCB9fVxuICAgICAgICAgICAgICAgICAgbmFtZT0nZGVzY3JpcHRpb24nXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj0nT3B0aW9uYWwgZGVzY3JpcHRpb24nXG4gICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5wcm9wcy5kZXNjcmlwdGlvbn1cbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBodG1sRm9yPSdwdWJsaXNoLWxpY2Vuc2UnIGNsYXNzTmFtZT0nbGFiZWwnPkxpY2Vuc2U6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxzZWxlY3QgdHlwZT0ndGV4dCcgbmFtZT0nbGljZW5zZScgaWQ9J3B1Ymxpc2gtbGljZW5zZScgY2xhc3NOYW1lPSdzZWxlY3Qgc2VsZWN0LS1wcmltYXJ5JyBvbkNoYW5nZT17dGhpcy5oYW5kbGVTZWxlY3R9PlxuICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0nICc+VW5zcGVjaWZpZWQ8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9J1B1YmxpYyBEb21haW4nPlB1YmxpYyBEb21haW48L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9J0NyZWF0aXZlIENvbW1vbnMnPkNyZWF0aXZlIENvbW1vbnM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLW5vLXRvcCc+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zJz5cbiAgICAgICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj0ncHVibGlzaC1uc2Z3JyBjbGFzc05hbWU9J2xhYmVsJz5NYXR1cmU6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzc05hbWU9J2lucHV0LWNoZWNrYm94JyB0eXBlPSdjaGVja2JveCcgaWQ9J3B1Ymxpc2gtbnNmdycgbmFtZT0nbnNmdycgdmFsdWU9e3RoaXMucHJvcHMubnNmd30gb25DaGFuZ2U9e3RoaXMuaGFuZGxlSW5wdXR9IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICl9XG4gICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXNlY29uZGFyeScgb25DbGljaz17dGhpcy50b2dnbGVTaG93SW5wdXRzfT57dGhpcy5wcm9wcy5zaG93TWV0YWRhdGFJbnB1dHMgPyAnbGVzcycgOiAnbW9yZSd9PC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hNZXRhZGF0YUlucHV0cztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy92aWV3LmpzeCIsImltcG9ydCBSZWFjdCwgeyBDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5jbGFzcyBFeHBhbmRpbmdUZXh0YXJlYSBleHRlbmRzIENvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLl9oYW5kbGVDaGFuZ2UgPSB0aGlzLl9oYW5kbGVDaGFuZ2UuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgdGhpcy5hZGp1c3RUZXh0YXJlYSh7fSk7XG4gIH1cbiAgX2hhbmRsZUNoYW5nZSAoZXZlbnQpIHtcbiAgICBjb25zdCB7IG9uQ2hhbmdlIH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChvbkNoYW5nZSkgb25DaGFuZ2UoZXZlbnQpO1xuICAgIHRoaXMuYWRqdXN0VGV4dGFyZWEoZXZlbnQpO1xuICB9XG4gIGFkanVzdFRleHRhcmVhICh7IHRhcmdldCA9IHRoaXMuZWwgfSkge1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSAwO1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBgJHt0YXJnZXQuc2Nyb2xsSGVpZ2h0fXB4YDtcbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgLi4ucmVzdCB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPHRleHRhcmVhXG4gICAgICAgIHsuLi5yZXN0fVxuICAgICAgICByZWY9e3ggPT4gdGhpcy5lbCA9IHh9XG4gICAgICAgIG9uQ2hhbmdlPXt0aGlzLl9oYW5kbGVDaGFuZ2V9XG4gICAgICAvPlxuICAgICk7XG4gIH1cbn1cblxuRXhwYW5kaW5nVGV4dGFyZWEucHJvcFR5cGVzID0ge1xuICBvbkNoYW5nZTogUHJvcFR5cGVzLmZ1bmMsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBFeHBhbmRpbmdUZXh0YXJlYTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0V4cGFuZGluZ1RleHRBcmVhL2luZGV4LmpzeCIsImltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHtzZXRQdWJsaXNoSW5DaGFubmVsLCB1cGRhdGVTZWxlY3RlZENoYW5uZWwsIHVwZGF0ZUVycm9yfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgY2hhbm5lbCwgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgbG9nZ2VkSW5DaGFubmVsTmFtZTogY2hhbm5lbC5sb2dnZWRJbkNoYW5uZWwubmFtZSxcbiAgICBwdWJsaXNoSW5DaGFubmVsICAgOiBwdWJsaXNoLnB1Ymxpc2hJbkNoYW5uZWwsXG4gICAgc2VsZWN0ZWRDaGFubmVsICAgIDogcHVibGlzaC5zZWxlY3RlZENoYW5uZWwsXG4gICAgY2hhbm5lbEVycm9yICAgICAgIDogcHVibGlzaC5lcnJvci5jaGFubmVsLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uUHVibGlzaEluQ2hhbm5lbENoYW5nZTogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcignY2hhbm5lbCcsIG51bGwpKTtcbiAgICAgIGRpc3BhdGNoKHNldFB1Ymxpc2hJbkNoYW5uZWwodmFsdWUpKTtcbiAgICB9LFxuICAgIG9uQ2hhbm5lbFNlbGVjdDogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcignY2hhbm5lbCcsIG51bGwpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbCh2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxTZWxlY3QvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IENoYW5uZWxMb2dpbkZvcm0gZnJvbSAnY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtJztcbmltcG9ydCBDaGFubmVsQ3JlYXRlRm9ybSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtJztcbmltcG9ydCAqIGFzIHN0YXRlcyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jaGFubmVsX3NlbGVjdF9zdGF0ZXMnO1xuXG5jbGFzcyBDaGFubmVsU2VsZWN0IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IgKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMudG9nZ2xlQW5vbnltb3VzUHVibGlzaCA9IHRoaXMudG9nZ2xlQW5vbnltb3VzUHVibGlzaC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVTZWxlY3Rpb24uYmluZCh0aGlzKTtcbiAgfVxuICB0b2dnbGVBbm9ueW1vdXNQdWJsaXNoIChldmVudCkge1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gJ2Fub255bW91cycpIHtcbiAgICAgIHRoaXMucHJvcHMub25QdWJsaXNoSW5DaGFubmVsQ2hhbmdlKGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wcm9wcy5vblB1Ymxpc2hJbkNoYW5uZWxDaGFuZ2UodHJ1ZSk7XG4gICAgfVxuICB9XG4gIGhhbmRsZVNlbGVjdGlvbiAoZXZlbnQpIHtcbiAgICBjb25zdCBzZWxlY3RlZE9wdGlvbiA9IGV2ZW50LnRhcmdldC5zZWxlY3RlZE9wdGlvbnNbMF0udmFsdWU7XG4gICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxTZWxlY3Qoc2VsZWN0ZWRPcHRpb24pO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxmb3JtPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdyYWRpbycgbmFtZT0nYW5vbnltb3VzLW9yLWNoYW5uZWwnIGlkPSdhbm9ueW1vdXMtcmFkaW8nIGNsYXNzTmFtZT0naW5wdXQtcmFkaW8nIHZhbHVlPSdhbm9ueW1vdXMnIGNoZWNrZWQ9eyF0aGlzLnByb3BzLnB1Ymxpc2hJbkNoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLnRvZ2dsZUFub255bW91c1B1Ymxpc2h9IC8+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCBsYWJlbC0tcG9pbnRlcicgaHRtbEZvcj0nYW5vbnltb3VzLXJhZGlvJz5Bbm9ueW1vdXM8L2xhYmVsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdyYWRpbycgbmFtZT0nYW5vbnltb3VzLW9yLWNoYW5uZWwnIGlkPSdjaGFubmVsLXJhZGlvJyBjbGFzc05hbWU9J2lucHV0LXJhZGlvJyB2YWx1ZT0naW4gYSBjaGFubmVsJyBjaGVja2VkPXt0aGlzLnByb3BzLnB1Ymxpc2hJbkNoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLnRvZ2dsZUFub255bW91c1B1Ymxpc2h9IC8+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCBsYWJlbC0tcG9pbnRlcicgaHRtbEZvcj0nY2hhbm5lbC1yYWRpbyc+SW4gYSBjaGFubmVsPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB7IHRoaXMucHJvcHMuY2hhbm5lbEVycm9yID8gKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnPnt0aGlzLnByb3BzLmNoYW5uZWxFcnJvcn08L3A+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlJz5QdWJsaXNoIGFub255bW91c2x5IG9yIGluIGEgY2hhbm5lbDwvcD5cbiAgICAgICAgICApfVxuICAgICAgICA8L2Zvcm0+XG4gICAgICAgIHsgdGhpcy5wcm9wcy5wdWJsaXNoSW5DaGFubmVsICYmIChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMnPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCcgaHRtbEZvcj0nY2hhbm5lbC1uYW1lLXNlbGVjdCc+Q2hhbm5lbDo8L2xhYmVsPlxuICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICA8c2VsZWN0IHR5cGU9J3RleHQnIGlkPSdjaGFubmVsLW5hbWUtc2VsZWN0JyBjbGFzc05hbWU9J3NlbGVjdCBzZWxlY3QtLWFycm93JyB2YWx1ZT17dGhpcy5wcm9wcy5zZWxlY3RlZENoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZVNlbGVjdGlvbn0+XG4gICAgICAgICAgICAgICAgeyB0aGlzLnByb3BzLmxvZ2dlZEluQ2hhbm5lbE5hbWUgJiYgPG9wdGlvbiB2YWx1ZT17dGhpcy5wcm9wcy5sb2dnZWRJbkNoYW5uZWxOYW1lfSBpZD0ncHVibGlzaC1jaGFubmVsLXNlbGVjdC1jaGFubmVsLW9wdGlvbic+e3RoaXMucHJvcHMubG9nZ2VkSW5DaGFubmVsTmFtZX08L29wdGlvbj4gfVxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9e3N0YXRlcy5MT0dJTn0+RXhpc3Rpbmc8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPXtzdGF0ZXMuQ1JFQVRFfT5OZXc8L29wdGlvbj5cbiAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIHsgKHRoaXMucHJvcHMuc2VsZWN0ZWRDaGFubmVsID09PSBzdGF0ZXMuTE9HSU4pICYmIDxDaGFubmVsTG9naW5Gb3JtIC8+IH1cbiAgICAgICAgICAgIHsgKHRoaXMucHJvcHMuc2VsZWN0ZWRDaGFubmVsID09PSBzdGF0ZXMuQ1JFQVRFKSAmJiA8Q2hhbm5lbENyZWF0ZUZvcm0gLz4gfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsU2VsZWN0O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbFNlbGVjdC92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcblxuY2xhc3MgQ2hhbm5lbExvZ2luRm9ybSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgZXJyb3IgICA6IG51bGwsXG4gICAgICBuYW1lICAgIDogJycsXG4gICAgICBwYXNzd29yZDogJycsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMubG9naW5Ub0NoYW5uZWwgPSB0aGlzLmxvZ2luVG9DaGFubmVsLmJpbmQodGhpcyk7XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgY29uc3QgbmFtZSA9IGV2ZW50LnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1tuYW1lXTogdmFsdWV9KTtcbiAgfVxuICBsb2dpblRvQ2hhbm5lbCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICAgIGJvZHkgICA6IEpTT04uc3RyaW5naWZ5KHt1c2VybmFtZTogdGhpcy5zdGF0ZS5uYW1lLCBwYXNzd29yZDogdGhpcy5zdGF0ZS5wYXNzd29yZH0pLFxuICAgICAgaGVhZGVyczogbmV3IEhlYWRlcnMoe1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgfSksXG4gICAgICBjcmVkZW50aWFsczogJ2luY2x1ZGUnLFxuICAgIH07XG4gICAgcmVxdWVzdCgnbG9naW4nLCBwYXJhbXMpXG4gICAgICAudGhlbigoe3N1Y2Nlc3MsIGNoYW5uZWxOYW1lLCBzaG9ydENoYW5uZWxJZCwgY2hhbm5lbENsYWltSWQsIG1lc3NhZ2V9KSA9PiB7XG4gICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihjaGFubmVsTmFtZSwgc2hvcnRDaGFubmVsSWQsIGNoYW5uZWxDbGFpbUlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBtZXNzYWdlfSk7XG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3J9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGZvcm0gaWQ9J2NoYW5uZWwtbG9naW4tZm9ybSc+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlIHJvdy0tc2hvcnQnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJyBodG1sRm9yPSdjaGFubmVsLWxvZ2luLW5hbWUtaW5wdXQnPk5hbWU6PC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj48ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNiBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1sZWZ0LWJvdHRvbSc+XG4gICAgICAgICAgICAgIDxzcGFuPkA8L3NwYW4+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nY2hhbm5lbC1sb2dpbi1uYW1lLWlucHV0JyBjbGFzc05hbWU9J2lucHV0LXRleHQnIG5hbWU9J25hbWUnIHBsYWNlaG9sZGVyPSdZb3VyIENoYW5uZWwgTmFtZScgdmFsdWU9e3RoaXMuc3RhdGUuY2hhbm5lbE5hbWV9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSByb3ctLXNob3J0Jz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCcgaHRtbEZvcj0nY2hhbm5lbC1sb2dpbi1wYXNzd29yZC1pbnB1dCcgPlBhc3N3b3JkOjwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LXRleHQtLXByaW1hcnknPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ncGFzc3dvcmQnIGlkPSdjaGFubmVsLWxvZ2luLXBhc3N3b3JkLWlucHV0JyBuYW1lPSdwYXNzd29yZCcgY2xhc3NOYW1lPSdpbnB1dC10ZXh0JyBwbGFjZWhvbGRlcj0nJyB2YWx1ZT17dGhpcy5zdGF0ZS5jaGFubmVsUGFzc3dvcmR9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7IHRoaXMuc3RhdGUuZXJyb3IgPyAoXG4gICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnPnt0aGlzLnN0YXRlLmVycm9yfTwvcD5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+RW50ZXIgdGhlIG5hbWUgYW5kIHBhc3N3b3JkIGZvciB5b3VyIGNoYW5uZWw8L3A+XG4gICAgICAgICl9XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlJz5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1wcmltYXJ5JyBvbkNsaWNrPXt0aGlzLmxvZ2luVG9DaGFubmVsfT5BdXRoZW50aWNhdGU8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Zvcm0+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsTG9naW5Gb3JtO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbExvZ2luRm9ybS92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvZ3Jlc3NCYXIgZnJvbSAnY29tcG9uZW50cy9Qcm9ncmVzc0Jhcic7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcblxuY2xhc3MgQ2hhbm5lbENyZWF0ZUZvcm0gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGVycm9yICAgOiBudWxsLFxuICAgICAgY2hhbm5lbCA6ICcnLFxuICAgICAgcGFzc3dvcmQ6ICcnLFxuICAgICAgc3RhdHVzICA6IG51bGwsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZUNoYW5uZWxJbnB1dCA9IHRoaXMuaGFuZGxlQ2hhbm5lbElucHV0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmNyZWF0ZUNoYW5uZWwgPSB0aGlzLmNyZWF0ZUNoYW5uZWwuYmluZCh0aGlzKTtcbiAgfVxuICBjbGVhbnNlQ2hhbm5lbElucHV0IChpbnB1dCkge1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvXFxzKy9nLCAnLScpOyAvLyByZXBsYWNlIHNwYWNlcyB3aXRoIGRhc2hlc1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15BLVphLXowLTktXS9nLCAnJyk7ICAvLyByZW1vdmUgYWxsIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IEEtWiwgYS16LCAwLTksIG9yICctJ1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuICBoYW5kbGVDaGFubmVsSW5wdXQgKGV2ZW50KSB7XG4gICAgbGV0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHZhbHVlID0gdGhpcy5jbGVhbnNlQ2hhbm5lbElucHV0KHZhbHVlKTtcbiAgICB0aGlzLnNldFN0YXRlKHtjaGFubmVsOiB2YWx1ZX0pO1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy51cGRhdGVJc0NoYW5uZWxBdmFpbGFibGUodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtlcnJvcjogJ1BsZWFzZSBlbnRlciBhIGNoYW5uZWwgbmFtZSd9KTtcbiAgICB9XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgY29uc3QgbmFtZSA9IGV2ZW50LnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1tuYW1lXTogdmFsdWV9KTtcbiAgfVxuICB1cGRhdGVJc0NoYW5uZWxBdmFpbGFibGUgKGNoYW5uZWwpIHtcbiAgICBjb25zdCBjaGFubmVsV2l0aEF0U3ltYm9sID0gYEAke2NoYW5uZWx9YDtcbiAgICByZXF1ZXN0KGAvYXBpL2NoYW5uZWwvYXZhaWxhYmlsaXR5LyR7Y2hhbm5lbFdpdGhBdFN5bWJvbH1gKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBudWxsfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgICB9KTtcbiAgfVxuICBjaGVja0lzQ2hhbm5lbEF2YWlsYWJsZSAoY2hhbm5lbCkge1xuICAgIGNvbnN0IGNoYW5uZWxXaXRoQXRTeW1ib2wgPSBgQCR7Y2hhbm5lbH1gO1xuICAgIHJldHVybiByZXF1ZXN0KGAvYXBpL2NoYW5uZWwvYXZhaWxhYmlsaXR5LyR7Y2hhbm5lbFdpdGhBdFN5bWJvbH1gKTtcbiAgfVxuICBjaGVja0lzUGFzc3dvcmRQcm92aWRlZCAocGFzc3dvcmQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaWYgKCFwYXNzd29yZCB8fCBwYXNzd29yZC5sZW5ndGggPCAxKSB7XG4gICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdQbGVhc2UgcHJvdmlkZSBhIHBhc3N3b3JkJykpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9XG4gIG1ha2VQdWJsaXNoQ2hhbm5lbFJlcXVlc3QgKHVzZXJuYW1lLCBwYXNzd29yZCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICAgIGJvZHkgICA6IEpTT04uc3RyaW5naWZ5KHt1c2VybmFtZSwgcGFzc3dvcmR9KSxcbiAgICAgIGhlYWRlcnM6IG5ldyBIZWFkZXJzKHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0pLFxuICAgICAgY3JlZGVudGlhbHM6ICdpbmNsdWRlJyxcbiAgICB9O1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICByZXF1ZXN0KCcvc2lnbnVwJywgcGFyYW1zKVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgVW5mb3J0dW5hdGVseSwgd2UgZW5jb3VudGVyZWQgYW4gZXJyb3Igd2hpbGUgY3JlYXRpbmcgeW91ciBjaGFubmVsLiBQbGVhc2UgbGV0IHVzIGtub3cgaW4gRGlzY29yZCEgJHtlcnJvci5tZXNzYWdlfWApKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgY3JlYXRlQ2hhbm5lbCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuY2hlY2tJc1Bhc3N3b3JkUHJvdmlkZWQodGhpcy5zdGF0ZS5wYXNzd29yZClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tJc0NoYW5uZWxBdmFpbGFibGUodGhpcy5zdGF0ZS5jaGFubmVsKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe3N0YXR1czogJ1dlIGFyZSBwdWJsaXNoaW5nIHlvdXIgbmV3IGNoYW5uZWwuICBTaXQgdGlnaHQuLi4nfSk7XG4gICAgICAgIHJldHVybiB0aGlzLm1ha2VQdWJsaXNoQ2hhbm5lbFJlcXVlc3QodGhpcy5zdGF0ZS5jaGFubmVsLCB0aGlzLnN0YXRlLnBhc3N3b3JkKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtzdGF0dXM6IG51bGx9KTtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihyZXN1bHQuY2hhbm5lbE5hbWUsIHJlc3VsdC5zaG9ydENoYW5uZWxJZCwgcmVzdWx0LmNoYW5uZWxDbGFpbUlkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3IubWVzc2FnZSwgc3RhdHVzOiBudWxsfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3IsIHN0YXR1czogbnVsbH0pO1xuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgeyAhdGhpcy5zdGF0ZS5zdGF0dXMgPyAoXG4gICAgICAgICAgPGZvcm0gaWQ9J3B1Ymxpc2gtY2hhbm5lbC1mb3JtJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlIHJvdy0tc2hvcnQnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzTmFtZT0nbGFiZWwnIGh0bWxGb3I9J25ldy1jaGFubmVsLW5hbWUnPk5hbWU6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdpbnB1dC10ZXh0LS1wcmltYXJ5IGZsZXgtY29udGFpbmVyLS1yb3cgZmxleC1jb250YWluZXItLWxlZnQtYm90dG9tIHNwYW4tLXJlbGF0aXZlJz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPkA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0nY2hhbm5lbCcgaWQ9J25ldy1jaGFubmVsLW5hbWUnIGNsYXNzTmFtZT0naW5wdXQtdGV4dCcgcGxhY2Vob2xkZXI9J2V4YW1wbGVDaGFubmVsTmFtZScgdmFsdWU9e3RoaXMuc3RhdGUuY2hhbm5lbH0gb25DaGFuZ2U9e3RoaXMuaGFuZGxlQ2hhbm5lbElucHV0fSAvPlxuICAgICAgICAgICAgICAgICAgeyAodGhpcy5zdGF0ZS5jaGFubmVsICYmICF0aGlzLnN0YXRlLmVycm9yKSAmJiA8c3BhbiBpZD0naW5wdXQtc3VjY2Vzcy1jaGFubmVsLW5hbWUnIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1zdWNjZXNzIHNwYW4tLWFic29sdXRlJz57J1xcdTI3MTMnfTwvc3Bhbj4gfVxuICAgICAgICAgICAgICAgICAgeyB0aGlzLnN0YXRlLmVycm9yICYmIDxzcGFuIGlkPSdpbnB1dC1zdWNjZXNzLWNoYW5uZWwtbmFtZScgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUgc3Bhbi0tYWJzb2x1dGUnPnsnXFx1MjcxNid9PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSByb3ctLXNob3J0Jz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJyBodG1sRm9yPSduZXctY2hhbm5lbC1wYXNzd29yZCc+UGFzc3dvcmQ6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdpbnB1dC10ZXh0LS1wcmltYXJ5Jz5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdwYXNzd29yZCcgbmFtZT0ncGFzc3dvcmQnIGlkPSduZXctY2hhbm5lbC1wYXNzd29yZCcgY2xhc3NOYW1lPSdpbnB1dC10ZXh0JyAgcGxhY2Vob2xkZXI9JycgdmFsdWU9e3RoaXMuc3RhdGUucGFzc3dvcmR9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAge3RoaXMuc3RhdGUuZXJyb3IgPyAoXG4gICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1mYWlsdXJlJz57dGhpcy5zdGF0ZS5lcnJvcn08L3A+XG4gICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+Q2hvb3NlIGEgbmFtZSBhbmQgcGFzc3dvcmQgZm9yIHlvdXIgY2hhbm5lbDwvcD5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXByaW1hcnknIG9uQ2xpY2s9e3RoaXMuY3JlYXRlQ2hhbm5lbH0+Q3JlYXRlIENoYW5uZWw8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdmaW5lLXByaW50Jz57dGhpcy5zdGF0ZS5zdGF0dXN9PC9wPlxuICAgICAgICAgICAgPFByb2dyZXNzQmFyIHNpemU9ezEyfSAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsQ3JlYXRlRm9ybTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY29uc3QgQWN0aXZlU3RhdHVzQmFyID0gKCkgPT4ge1xuICByZXR1cm4gPHNwYW4gY2xhc3NOYW1lPSdwcm9ncmVzcy1iYXIgcHJvZ3Jlc3MtYmFyLS1hY3RpdmUnPnwgPC9zcGFuPjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFjdGl2ZVN0YXR1c0JhcjtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0FjdGl2ZVN0YXR1c0Jhci9pbmRleC5qc3giLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jb25zdCBJbmFjdGl2ZVN0YXR1c0JhciA9ICgpID0+IHtcbiAgcmV0dXJuIDxzcGFuIGNsYXNzTmFtZT0ncHJvZ3Jlc3MtYmFyIHByb2dyZXNzLWJhci0taW5hY3RpdmUnPnwgPC9zcGFuPjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEluYWN0aXZlU3RhdHVzQmFyO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvSW5hY3RpdmVTdGF0dXNCYXIvaW5kZXguanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge2NsZWFyRmlsZX0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHB1Ymxpc2ggfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIHN0YXR1cyA6IHB1Ymxpc2guc3RhdHVzLnN0YXR1cyxcbiAgICBtZXNzYWdlOiBwdWJsaXNoLnN0YXR1cy5tZXNzYWdlLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0ge1xuICBjbGVhckZpbGUsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hTdGF0dXMvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb2dyZXNzQmFyIGZyb20gJ2NvbXBvbmVudHMvUHJvZ3Jlc3NCYXInO1xuaW1wb3J0ICogYXMgcHVibGlzaFN0YXRlcyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jbGFpbV9zdGF0ZXMnO1xuXG5jbGFzcyBQdWJsaXNoU3RhdHVzIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IHN0YXR1cywgbWVzc2FnZSwgY2xlYXJGaWxlIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJz5cbiAgICAgICAge3N0YXR1cyA9PT0gcHVibGlzaFN0YXRlcy5MT0FEX1NUQVJUICYmXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgYWxpZ24tY29udGVudC1jZW50ZXInPlxuICAgICAgICAgIDxwPkZpbGUgaXMgbG9hZGluZyB0byBzZXJ2ZXI8L3A+XG4gICAgICAgICAgPHAgY2xhc3NOYW1lPSdibHVlJz4wJTwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAge3N0YXR1cyA9PT0gcHVibGlzaFN0YXRlcy5MT0FESU5HICYmXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICA8cD5GaWxlIGlzIGxvYWRpbmcgdG8gc2VydmVyPC9wPlxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdibHVlJz57bWVzc2FnZX08L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHtzdGF0dXMgPT09IHB1Ymxpc2hTdGF0ZXMuUFVCTElTSElORyAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5VcGxvYWQgY29tcGxldGUuICBZb3VyIGZpbGUgaXMgbm93IGJlaW5nIHB1Ymxpc2hlZCBvbiB0aGUgYmxvY2tjaGFpbi4uLjwvcD5cbiAgICAgICAgICA8UHJvZ3Jlc3NCYXIgc2l6ZT17MTJ9IC8+XG4gICAgICAgICAgPHA+Q3VyaW91cyB3aGF0IG1hZ2ljIGlzIGhhcHBlbmluZyBoZXJlPyA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9mYXEvd2hhdC1pcy1sYnJ5Jz5MZWFybiBtb3JlLjwvYT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHtzdGF0dXMgPT09IHB1Ymxpc2hTdGF0ZXMuU1VDQ0VTUyAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5Zb3VyIHB1Ymxpc2ggaXMgY29tcGxldGUhIFlvdSBhcmUgYmVpbmcgcmVkaXJlY3RlZCB0byBpdCBub3cuPC9wPlxuICAgICAgICAgIDxwPklmIHlvdSBhcmUgbm90IGF1dG9tYXRpY2FsbHkgcmVkaXJlY3RlZCwgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj17bWVzc2FnZX0+Y2xpY2sgaGVyZS48L2E+PC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICB7c3RhdHVzID09PSBwdWJsaXNoU3RhdGVzLkZBSUxFRCAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5Tb21ldGhpbmcgd2VudCB3cm9uZy4uLjwvcD5cbiAgICAgICAgICA8cD48c3Ryb25nPnttZXNzYWdlfTwvc3Ryb25nPjwvcD5cbiAgICAgICAgICA8cD5Gb3IgaGVscCwgcG9zdCB0aGUgYWJvdmUgZXJyb3IgdGV4dCBpbiB0aGUgI3NwZWVjaCBjaGFubmVsIG9uIHRoZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZGlzY29yZC5nZy9Zallid2hTJyB0YXJnZXQ9J19ibGFuayc+bGJyeSBkaXNjb3JkPC9hPjwvcD5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1zZWNvbmRhcnknIG9uQ2xpY2s9e2NsZWFyRmlsZX0+UmVzZXQ8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hTdGF0dXM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoU3RhdHVzL3ZpZXcuanN4IiwiZXhwb3J0IGNvbnN0IExPQURfU1RBUlQgPSAnTE9BRF9TVEFSVCc7XG5leHBvcnQgY29uc3QgTE9BRElORyA9ICdMT0FESU5HJztcbmV4cG9ydCBjb25zdCBQVUJMSVNISU5HID0gJ1BVQkxJU0hJTkcnO1xuZXhwb3J0IGNvbnN0IFNVQ0NFU1MgPSAnU1VDQ0VTUyc7XG5leHBvcnQgY29uc3QgRkFJTEVEID0gJ0ZBSUxFRCc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29uc3RhbnRzL3B1Ymxpc2hfY2xhaW1fc3RhdGVzLmpzIiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBtZXNzYWdlOiBwdWJsaXNoLmRpc2FibGVkTWVzc2FnZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jbGFzcyBQdWJsaXNoRGlzYWJsZWRNZXNzYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gdGhpcy5wcm9wcy5tZXNzYWdlO1xuICAgIGNvbnNvbGUubG9nKCd0aGlzLnByb3BzLm1lc3NhZ2U6JywgbWVzc2FnZSk7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgZHJvcHpvbmUtLWRpc2FibGVkIHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJz5cbiAgICAgICAgPHAgY2xhc3NOYW1lPSd0ZXh0LS1kaXNhYmxlZCc+UHVibGlzaGluZyBpcyBjdXJyZW50bHkgZGlzYWJsZWQuPC9wPlxuICAgICAgICA8cCBjbGFzc05hbWU9J3RleHQtLWRpc2FibGVkJz57bWVzc2FnZX08L3A+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2U7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IFNFTyBmcm9tICdjb21wb25lbnRzL1NFTyc7XG5cbmNsYXNzIEFib3V0UGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxTRU8gcGFnZVRpdGxlPXsnQWJvdXQnfSBwYWdlVXJpPXsnYWJvdXQnfSAvPlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdwdWxsLXF1b3RlJz5TcGVlLmNoIGlzIGFuIG9wZW4tc291cmNlIHByb2plY3QuICBQbGVhc2UgY29udHJpYnV0ZSB0byB0aGUgZXhpc3Rpbmcgc2l0ZSwgb3IgZm9yayBpdCBhbmQgbWFrZSB5b3VyIG93bi48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vdHdpdHRlci5jb20vc3BlZV9jaCc+VFdJVFRFUjwvYT48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaCc+R0lUSFVCPC9hPjwvcD5cbiAgICAgICAgICAgICAgPHA+PGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj0naHR0cHM6Ly9kaXNjb3JkLmdnL1lqWWJ3aFMnPkRJU0NPUkQgQ0hBTk5FTDwvYT48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaC9ibG9iL21hc3Rlci9SRUFETUUubWQnPkRPQ1VNRU5UQVRJT048L2E+PC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICA8cD5TcGVlLmNoIGlzIGEgbWVkaWEtaG9zdGluZyBzaXRlIHRoYXQgcmVhZHMgZnJvbSBhbmQgcHVibGlzaGVzIGNvbnRlbnQgdG8gdGhlIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9sYnJ5LmlvJz5MQlJZPC9hPiBibG9ja2NoYWluLjwvcD5cbiAgICAgICAgICAgICAgPHA+U3BlZS5jaCBpcyBhIGhvc3Rpbmcgc2VydmljZSwgYnV0IHdpdGggdGhlIGFkZGVkIGJlbmVmaXQgdGhhdCBpdCBzdG9yZXMgeW91ciBjb250ZW50IG9uIGEgZGVjZW50cmFsaXplZCBuZXR3b3JrIG9mIGNvbXB1dGVycyAtLSB0aGUgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyBocmVmPSdodHRwczovL2xicnkuaW8vZ2V0Jz5MQlJZPC9hPiBuZXR3b3JrLiAgVGhpcyBtZWFucyB0aGF0IHlvdXIgaW1hZ2VzIGFyZSBzdG9yZWQgaW4gbXVsdGlwbGUgbG9jYXRpb25zIHdpdGhvdXQgYSBzaW5nbGUgcG9pbnQgb2YgZmFpbHVyZS48L3A+XG4gICAgICAgICAgICAgIDxoMz5Db250cmlidXRlPC9oMz5cbiAgICAgICAgICAgICAgPHA+SWYgeW91IGhhdmUgYW4gaWRlYSBmb3IgeW91ciBvd24gc3BlZS5jaC1saWtlIHNpdGUgb24gdG9wIG9mIExCUlksIGZvcmsgb3VyIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9naXRodWIuY29tL2xicnlpby9zcGVlLmNoJz5naXRodWIgcmVwbzwvYT4gYW5kIGdvIHRvIHRvd24hPC9wPlxuICAgICAgICAgICAgICA8cD5JZiB5b3Ugd2FudCB0byBpbXByb3ZlIHNwZWUuY2gsIGpvaW4gb3VyIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9kaXNjb3JkLmdnL1lqWWJ3aFMnPmRpc2NvcmQgY2hhbm5lbDwvYT4gb3Igc29sdmUgb25lIG9mIG91ciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaC9pc3N1ZXMnPmdpdGh1YiBpc3N1ZXM8L2E+LjwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFib3V0UGFnZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9wYWdlcy9BYm91dFBhZ2UvaW5kZXguanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBjaGFubmVsIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBsb2dnZWRJbkNoYW5uZWxOYW1lOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5uYW1lLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3BhZ2VzL0xvZ2luUGFnZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IENoYW5uZWxMb2dpbkZvcm0gZnJvbSAnY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtJztcbmltcG9ydCBDaGFubmVsQ3JlYXRlRm9ybSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtJztcblxuY2xhc3MgTG9naW5QYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyAobmV3UHJvcHMpIHtcbiAgICAvLyByZS1yb3V0ZSB0aGUgdXNlciB0byB0aGUgaG9tZXBhZ2UgaWYgdGhlIHVzZXIgaXMgbG9nZ2VkIGluXG4gICAgaWYgKG5ld1Byb3BzLmxvZ2dlZEluQ2hhbm5lbE5hbWUgIT09IHRoaXMucHJvcHMubG9nZ2VkSW5DaGFubmVsTmFtZSkge1xuICAgICAgdGhpcy5wcm9wcy5oaXN0b3J5LnB1c2goYC9gKTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPFNFTyBwYWdlVGl0bGU9eydMb2dpbid9IHBhZ2VVcmk9eydsb2dpbid9IC8+XG4gICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICA8cD5DaGFubmVscyBhbGxvdyB5b3UgdG8gcHVibGlzaCBhbmQgZ3JvdXAgY29udGVudCB1bmRlciBhbiBpZGVudGl0eS4gWW91IGNhbiBjcmVhdGUgYSBjaGFubmVsIGZvciB5b3Vyc2VsZiwgb3Igc2hhcmUgb25lIHdpdGggbGlrZS1taW5kZWQgZnJpZW5kcy4gIFlvdSBjYW4gY3JlYXRlIDEgY2hhbm5lbCwgb3IgMTAwLCBzbyB3aGV0aGVyIHlvdSdyZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPScvQGNhdGFsb25pYTIwMTc6NDNkY2Y0NzE2M2NhYTIxZDg0MDRkOWZlOWIzMGY3OGVmM2UxNDZhOCc+ZG9jdW1lbnRpbmcgaW1wb3J0YW50IGV2ZW50czwvYT4sIG9yIG1ha2luZyBhIHB1YmxpYyByZXBvc2l0b3J5IGZvciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPScvQGNhdEdpZnMnPmNhdCBnaWZzPC9hPiAocGFzc3dvcmQ6ICcxMjM0JyksIHRyeSBjcmVhdGluZyBhIGNoYW5uZWwgZm9yIGl0ITwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZT0naDMtLW5vLWJvdHRvbSc+TG9nIGluIHRvIGFuIGV4aXN0aW5nIGNoYW5uZWw6PC9oMz5cbiAgICAgICAgICAgICAgPENoYW5uZWxMb2dpbkZvcm0gLz5cbiAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZT0naDMtLW5vLWJvdHRvbSc+Q3JlYXRlIGEgYnJhbmQgbmV3IGNoYW5uZWw6PC9oMz5cbiAgICAgICAgICAgICAgPENoYW5uZWxDcmVhdGVGb3JtIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKExvZ2luUGFnZSk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcGFnZXMvTG9naW5QYWdlL3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IG9uSGFuZGxlU2hvd1BhZ2VVcmkgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZXJyb3IgICAgICA6IHNob3cucmVxdWVzdC5lcnJvcixcbiAgICByZXF1ZXN0VHlwZTogc2hvdy5yZXF1ZXN0LnR5cGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIG9uSGFuZGxlU2hvd1BhZ2VVcmksXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9wYWdlcy9TaG93UGFnZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgU2hvd0Fzc2V0TGl0ZSBmcm9tICdjb250YWluZXJzL1Nob3dBc3NldExpdGUnO1xuaW1wb3J0IFNob3dBc3NldERldGFpbHMgZnJvbSAnY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzJztcbmltcG9ydCBTaG93Q2hhbm5lbCBmcm9tICdjb250YWluZXJzL1Nob3dDaGFubmVsJztcblxuaW1wb3J0IHsgQ0hBTk5FTCwgQVNTRVRfTElURSwgQVNTRVRfREVUQUlMUyB9IGZyb20gJ2NvbnN0YW50cy9zaG93X3JlcXVlc3RfdHlwZXMnO1xuXG5jbGFzcyBTaG93UGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnByb3BzLm9uSGFuZGxlU2hvd1BhZ2VVcmkodGhpcy5wcm9wcy5tYXRjaC5wYXJhbXMpO1xuICB9XG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgKG5leHRQcm9wcykge1xuICAgIGlmIChuZXh0UHJvcHMubWF0Y2gucGFyYW1zICE9PSB0aGlzLnByb3BzLm1hdGNoLnBhcmFtcykge1xuICAgICAgdGhpcy5wcm9wcy5vbkhhbmRsZVNob3dQYWdlVXJpKG5leHRQcm9wcy5tYXRjaC5wYXJhbXMpO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgZXJyb3IsIHJlcXVlc3RUeXBlIH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPEVycm9yUGFnZSBlcnJvcj17ZXJyb3J9IC8+XG4gICAgICApO1xuICAgIH1cbiAgICBzd2l0Y2ggKHJlcXVlc3RUeXBlKSB7XG4gICAgICBjYXNlIENIQU5ORUw6XG4gICAgICAgIHJldHVybiA8U2hvd0NoYW5uZWwgLz47XG4gICAgICBjYXNlIEFTU0VUX0xJVEU6XG4gICAgICAgIHJldHVybiA8U2hvd0Fzc2V0TGl0ZSAvPjtcbiAgICAgIGNhc2UgQVNTRVRfREVUQUlMUzpcbiAgICAgICAgcmV0dXJuIDxTaG93QXNzZXREZXRhaWxzIC8+O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIDxwPmxvYWRpbmcuLi48L3A+O1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2hvd1BhZ2U7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcGFnZXMvU2hvd1BhZ2Uvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCByZXF1ZXN0IGluZm9cbiAgY29uc3QgcmVxdWVzdElkID0gc2hvdy5yZXF1ZXN0LmlkO1xuICAvLyBzZWxlY3QgYXNzZXQgaW5mb1xuICBsZXQgYXNzZXQ7XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0gfHwgbnVsbDtcbiAgY29uc3QgYXNzZXRMaXN0ID0gc2hvdy5hc3NldExpc3Q7XG4gIGlmIChyZXF1ZXN0ICYmIGFzc2V0TGlzdCkge1xuICAgIGNvbnN0IGFzc2V0S2V5ID0gcmVxdWVzdC5rZXk7ICAvLyBub3RlOiBqdXN0IHN0b3JlIHRoaXMgaW4gdGhlIHJlcXVlc3RcbiAgICBhc3NldCA9IGFzc2V0TGlzdFthc3NldEtleV0gfHwgbnVsbDtcbiAgfTtcbiAgLy8gcmV0dXJuIHByb3BzXG4gIHJldHVybiB7XG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXRMaXRlL2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBTRU8gZnJvbSAnY29tcG9uZW50cy9TRU8nO1xuaW1wb3J0IHsgTGluayB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEFzc2V0RGlzcGxheSBmcm9tICdjb250YWluZXJzL0Fzc2V0RGlzcGxheSc7XG5cbmNsYXNzIFNob3dMaXRlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGFzc2V0IH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChhc3NldCkge1xuICAgICAgY29uc3QgeyBuYW1lLCBjbGFpbUlkIH0gPSBhc3NldC5jbGFpbURhdGE7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyIHNob3ctbGl0ZS1jb250YWluZXInPlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtuYW1lfSBhc3NldD17YXNzZXR9IC8+XG4gICAgICAgICAgPEFzc2V0RGlzcGxheSAvPlxuICAgICAgICAgIDxMaW5rIGlkPSdhc3NldC1ib2lsZXJwYXRlJyBjbGFzc05hbWU9J2xpbmstLXByaW1hcnkgZmluZS1wcmludCcgdG89e2AvJHtjbGFpbUlkfS8ke25hbWV9YH0+aG9zdGVkXG4gICAgICAgICAgICB2aWEgU3BlZS5jaDwvTGluaz5cbiAgICAgICAgPC9kaXY+XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXRhbGwgcm93LS1wYWRkZWQgZmxleC1jb250YWluZXItLWNvbHVtbiBmbGV4LWNvbnRhaW5lci0tY2VudGVyLWNlbnRlcic+XG4gICAgICAgIDxwPmxvYWRpbmcgYXNzZXQgZGF0YS4uLjwvcD5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNob3dMaXRlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0TGl0ZS92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvZ3Jlc3NCYXIgZnJvbSAnY29tcG9uZW50cy9Qcm9ncmVzc0Jhcic7XG5pbXBvcnQgeyBMT0NBTF9DSEVDSywgVU5BVkFJTEFCTEUsIEVSUk9SLCBBVkFJTEFCTEUgfSBmcm9tICdjb25zdGFudHMvYXNzZXRfZGlzcGxheV9zdGF0ZXMnO1xuXG5jbGFzcyBBc3NldERpc3BsYXkgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBhc3NldDogeyBjbGFpbURhdGE6IHsgbmFtZSwgY2xhaW1JZCB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgdGhpcy5wcm9wcy5vbkZpbGVSZXF1ZXN0KG5hbWUsIGNsYWltSWQpO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBzdGF0dXMsIGVycm9yLCBhc3NldDogeyBjbGFpbURhdGE6IHsgbmFtZSwgY2xhaW1JZCwgY29udGVudFR5cGUsIGZpbGVFeHQsIHRodW1ibmFpbCB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgaWQ9J2Fzc2V0LWRpc3BsYXktY29tcG9uZW50Jz5cbiAgICAgICAgeyhzdGF0dXMgPT09IExPQ0FMX0NIRUNLKSAmJlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxwPkNoZWNraW5nIHRvIHNlZSBpZiBTcGVlLmNoIGhhcyB5b3VyIGFzc2V0IGxvY2FsbHkuLi48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHsoc3RhdHVzID09PSBVTkFWQUlMQUJMRSkgJiZcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8cD5TaXQgdGlnaHQsIHdlJ3JlIHNlYXJjaGluZyB0aGUgTEJSWSBibG9ja2NoYWluIGZvciB5b3VyIGFzc2V0ITwvcD5cbiAgICAgICAgICA8UHJvZ3Jlc3NCYXIgc2l6ZT17MTJ9IC8+XG4gICAgICAgICAgPHA+Q3VyaW91cyB3aGF0IG1hZ2ljIGlzIGhhcHBlbmluZyBoZXJlPyA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9mYXEvd2hhdC1pcy1sYnJ5Jz5MZWFybiBtb3JlLjwvYT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHsoc3RhdHVzID09PSBFUlJPUikgJiZcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8cD5VbmZvcnR1bmF0ZWx5LCB3ZSBjb3VsZG4ndCBkb3dubG9hZCB5b3VyIGFzc2V0IGZyb20gTEJSWS4gIFlvdSBjYW4gaGVscCB1cyBvdXQgYnkgc2hhcmluZyB0aGUgYmVsb3cgZXJyb3IgbWVzc2FnZSBpbiB0aGUgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyBocmVmPSdodHRwczovL2Rpc2NvcmQuZ2cvWWpZYndoUycgdGFyZ2V0PSdfYmxhbmsnPkxCUlkgZGlzY29yZDwvYT4uPC9wPlxuICAgICAgICAgIDxpPjxwIGlkPSdlcnJvci1tZXNzYWdlJz57ZXJyb3J9PC9wPjwvaT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgeyhzdGF0dXMgPT09IEFWQUlMQUJMRSkgJiZcbiAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGNvbnRlbnRUeXBlKSB7XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgICAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0nYXNzZXQnXG4gICAgICAgICAgICAgICAgICBzcmM9e2AvJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfVxuICAgICAgICAgICAgICAgICAgYWx0PXtuYW1lfSAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9J2Fzc2V0J1xuICAgICAgICAgICAgICAgICAgc3JjPXtgLyR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH1cbiAgICAgICAgICAgICAgICAgIGFsdD17bmFtZX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSAndmlkZW8vbXA0JzpcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8dmlkZW8gY2xhc3NOYW1lPSdhc3NldCB2aWRlbycgY29udHJvbHMgcG9zdGVyPXt0aHVtYm5haWx9PlxuICAgICAgICAgICAgICAgICAgPHNvdXJjZVxuICAgICAgICAgICAgICAgICAgICBzcmM9e2AvJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDxwPllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSA8Y29kZT52aWRlbzwvY29kZT4gZWxlbWVudC48L3A+XG4gICAgICAgICAgICAgICAgPC92aWRlbz5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPHA+VW5zdXBwb3J0ZWQgZmlsZSB0eXBlPC9wPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldERpc3BsYXk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9Bc3NldERpc3BsYXkvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCByZXF1ZXN0IGluZm9cbiAgY29uc3QgcmVxdWVzdElkID0gc2hvdy5yZXF1ZXN0LmlkO1xuICAvLyBzZWxlY3QgYXNzZXQgaW5mb1xuICBsZXQgYXNzZXQ7XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0gfHwgbnVsbDtcbiAgY29uc3QgYXNzZXRMaXN0ID0gc2hvdy5hc3NldExpc3Q7XG4gIGlmIChyZXF1ZXN0ICYmIGFzc2V0TGlzdCkge1xuICAgIGNvbnN0IGFzc2V0S2V5ID0gcmVxdWVzdC5rZXk7ICAvLyBub3RlOiBqdXN0IHN0b3JlIHRoaXMgaW4gdGhlIHJlcXVlc3RcbiAgICBhc3NldCA9IGFzc2V0TGlzdFthc3NldEtleV0gfHwgbnVsbDtcbiAgfTtcbiAgLy8gcmV0dXJuIHByb3BzXG4gIHJldHVybiB7XG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzL2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBTRU8gZnJvbSAnY29tcG9uZW50cy9TRU8nO1xuaW1wb3J0IE5hdkJhciBmcm9tICdjb250YWluZXJzL05hdkJhcic7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgQXNzZXRUaXRsZSBmcm9tICdjb250YWluZXJzL0Fzc2V0VGl0bGUnO1xuaW1wb3J0IEFzc2V0RGlzcGxheSBmcm9tICdjb250YWluZXJzL0Fzc2V0RGlzcGxheSc7XG5pbXBvcnQgQXNzZXRJbmZvIGZyb20gJ2NvbnRhaW5lcnMvQXNzZXRJbmZvJztcblxuY2xhc3MgU2hvd0Fzc2V0RGV0YWlscyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBhc3NldCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoYXNzZXQpIHtcbiAgICAgIGNvbnN0IHsgY2xhaW1EYXRhOiB7IG5hbWUgfSB9ID0gYXNzZXQ7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtgJHtuYW1lfSAtIGRldGFpbHNgfSBhc3NldD17YXNzZXR9IC8+XG4gICAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS10YWxsIHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xMCc+XG4gICAgICAgICAgICAgIDxBc3NldFRpdGxlIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCBzaG93LWRldGFpbHMtY29udGFpbmVyJz5cbiAgICAgICAgICAgICAgICA8QXNzZXREaXNwbGF5IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1zbWwtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICAgICAgICA8QXNzZXRJbmZvIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKTtcbiAgICB9O1xuICAgIHJldHVybiAoXG4gICAgICA8RXJyb3JQYWdlIGVycm9yPXsnbG9hZGluZyBhc3NldCBkYXRhLi4uJ30gLz5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTaG93QXNzZXREZXRhaWxzO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscy92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuaW1wb3J0IHsgc2VsZWN0QXNzZXQgfSBmcm9tICdzZWxlY3RvcnMvc2hvdyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHNob3cgfSkgPT4ge1xuICBjb25zdCB7IGNsYWltRGF0YTogeyB0aXRsZSB9IH0gPSBzZWxlY3RBc3NldChzaG93KTtcbiAgcmV0dXJuIHtcbiAgICB0aXRsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0VGl0bGUvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jb25zdCBBc3NldFRpdGxlID0gKHsgdGl0bGUgfSkgPT4ge1xuICByZXR1cm4gKFxuICAgIDxkaXY+XG4gICAgICA8c3BhbiBjbGFzc05hbWU9J3RleHQtLWxhcmdlJz57dGl0bGV9PC9zcGFuPlxuICAgIDwvZGl2PlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgQXNzZXRUaXRsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0VGl0bGUvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcbmltcG9ydCB7IHNlbGVjdEFzc2V0IH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IGFzc2V0XG4gIGNvbnN0IGFzc2V0ID0gc2VsZWN0QXNzZXQoc2hvdyk7XG4gIC8vICByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBhc3NldCxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0SW5mby9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5cbmNsYXNzIEFzc2V0SW5mbyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmNvcHlUb0NsaXBib2FyZCA9IHRoaXMuY29weVRvQ2xpcGJvYXJkLmJpbmQodGhpcyk7XG4gIH1cbiAgY29weVRvQ2xpcGJvYXJkIChldmVudCkge1xuICAgIHZhciBlbGVtZW50VG9Db3B5ID0gZXZlbnQudGFyZ2V0LmRhdGFzZXQuZWxlbWVudHRvY29weTtcbiAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRUb0NvcHkpO1xuICAgIGVsZW1lbnQuc2VsZWN0KCk7XG4gICAgdHJ5IHtcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtlcnJvcjogJ09vcHMsIHVuYWJsZSB0byBjb3B5J30pO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgYXNzZXQ6IHsgc2hvcnRJZCwgY2xhaW1EYXRhIDogeyBjaGFubmVsTmFtZSwgY2VydGlmaWNhdGVJZCwgZGVzY3JpcHRpb24sIG5hbWUsIGNsYWltSWQsIGZpbGVFeHQsIGNvbnRlbnRUeXBlLCB0aHVtYm5haWwsIGhvc3QgfSB9IH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICB7Y2hhbm5lbE5hbWUgJiZcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLXdpZGUgcm93LS1uby10b3AnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+Q2hhbm5lbDo8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd0ZXh0Jz48TGluayB0bz17YC8ke2NoYW5uZWxOYW1lfToke2NlcnRpZmljYXRlSWR9YH0+e2NoYW5uZWxOYW1lfTwvTGluaz48L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAge2Rlc2NyaXB0aW9uICYmXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS13aWRlIHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9J3RleHQnPntkZXNjcmlwdGlvbn08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgPGRpdiBpZD0nc2hvdy1zaGFyZS1idXR0b25zJz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0td2lkZSByb3ctLW5vLXRvcCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMiBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+U2hhcmU6PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tOCBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWJvdHRvbSBmbGV4LWNvbnRhaW5lci0td3JhcCc+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj17YGh0dHBzOi8vdHdpdHRlci5jb20vaW50ZW50L3R3ZWV0P3RleHQ9JHtob3N0fS8ke3Nob3J0SWR9LyR7bmFtZX1gfT50d2l0dGVyPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwczovL3d3dy5mYWNlYm9vay5jb20vc2hhcmVyL3NoYXJlci5waHA/dT0ke2hvc3R9LyR7c2hvcnRJZH0vJHtuYW1lfWB9PmZhY2Vib29rPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwOi8vdHVtYmxyLmNvbS93aWRnZXRzL3NoYXJlL3Rvb2w/Y2Fub25pY2FsVXJsPSR7aG9zdH0vJHtzaG9ydElkfS8ke25hbWV9YH0+dHVtYmxyPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwczovL3d3dy5yZWRkaXQuY29tL3N1Ym1pdD91cmw9JHtob3N0fS8ke3Nob3J0SWR9LyR7bmFtZX0mdGl0bGU9JHtuYW1lfWB9PnJlZGRpdDwvYT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLXdpZGUgcm93LS1uby10b3AnPlxuICAgICAgICAgIDxkaXYgaWQ9J3Nob3ctc2hvcnQtbGluayc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMiBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+TGluazo8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LWVycm9yJyBpZD0naW5wdXQtZXJyb3ItY29weS1zaG9ydC1saW5rJyBoaWRkZW49J3RydWUnPmVycm9yIGhlcmU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nc2hvcnQtbGluaycgY2xhc3NOYW1lPSdpbnB1dC1kaXNhYmxlZCBpbnB1dC10ZXh0LS1mdWxsLXdpZHRoJyByZWFkT25seVxuICAgICAgICAgICAgICAgICAgICBzcGVsbENoZWNrPSdmYWxzZSdcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9e2Ake2hvc3R9LyR7c2hvcnRJZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH1cbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTEnIC8+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTInPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9J2J1dHRvbi0tcHJpbWFyeSBidXR0b24tLXdpZGUnIGRhdGEtZWxlbWVudHRvY29weT0nc2hvcnQtbGluaydcbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5jb3B5VG9DbGlwYm9hcmR9PmNvcHlcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBpZD0nc2hvdy1lbWJlZC1jb2RlJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd0ZXh0Jz5FbWJlZDo8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LWVycm9yJyBpZD0naW5wdXQtZXJyb3ItY29weS1lbWJlZC10ZXh0JyBoaWRkZW49J3RydWUnPmVycm9yIGhlcmU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIHsoY29udGVudFR5cGUgPT09ICd2aWRlby9tcDQnKSA/IChcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdlbWJlZC10ZXh0JyBjbGFzc05hbWU9J2lucHV0LWRpc2FibGVkIGlucHV0LXRleHQtLWZ1bGwtd2lkdGgnIHJlYWRPbmx5XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IHNwZWxsQ2hlY2s9J2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXtgPHZpZGVvIHdpZHRoPVwiMTAwJVwiIGNvbnRyb2xzIHBvc3Rlcj1cIiR7dGh1bWJuYWlsfVwiIHNyYz1cIiR7aG9zdH0vJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1cIi8+PC92aWRlbz5gfSAvPlxuICAgICAgICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdlbWJlZC10ZXh0JyBjbGFzc05hbWU9J2lucHV0LWRpc2FibGVkIGlucHV0LXRleHQtLWZ1bGwtd2lkdGgnIHJlYWRPbmx5XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IHNwZWxsQ2hlY2s9J2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXtgPGltZyBzcmM9XCIke2hvc3R9LyR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9XCIvPmB9XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xJyAvPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yJz5cbiAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXByaW1hcnkgYnV0dG9uLS13aWRlJyBkYXRhLWVsZW1lbnR0b2NvcHk9J2VtYmVkLXRleHQnXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMuY29weVRvQ2xpcGJvYXJkfT5jb3B5XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J2ZsZXgtY29udGFpbmVyLS1yb3cgZmxleC1jb250YWluZXItLXNwYWNlLWJldHdlZW4tYm90dG9tJz5cbiAgICAgICAgICA8TGluayBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRvPXtgLyR7c2hvcnRJZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH0+PHNwYW5cbiAgICAgICAgICAgIGNsYXNzTmFtZT0ndGV4dCc+RGlyZWN0IExpbms8L3NwYW4+PC9MaW5rPlxuICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj17YCR7aG9zdH0vJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfSBkb3dubG9hZD17bmFtZX0+RG93bmxvYWQ8L2E+XG4gICAgICAgICAgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj0naHR0cHM6Ly9sYnJ5LmlvL2RtY2EnPlJlcG9ydDwvYT5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFzc2V0SW5mbztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0SW5mby92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IHJlcXVlc3QgaW5mb1xuICBjb25zdCByZXF1ZXN0SWQgPSBzaG93LnJlcXVlc3QuaWQ7XG4gIC8vIHNlbGVjdCByZXF1ZXN0XG4gIGNvbnN0IHByZXZpb3VzUmVxdWVzdCA9IHNob3cucmVxdWVzdExpc3RbcmVxdWVzdElkXSB8fCBudWxsO1xuICAvLyBzZWxlY3QgY2hhbm5lbFxuICBsZXQgY2hhbm5lbDtcbiAgaWYgKHByZXZpb3VzUmVxdWVzdCkge1xuICAgIGNvbnN0IGNoYW5uZWxLZXkgPSBwcmV2aW91c1JlcXVlc3Qua2V5O1xuICAgIGNoYW5uZWwgPSBzaG93LmNoYW5uZWxMaXN0W2NoYW5uZWxLZXldIHx8IG51bGw7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBjaGFubmVsLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0NoYW5uZWwvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFNFTyBmcm9tICdjb21wb25lbnRzL1NFTyc7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgTmF2QmFyIGZyb20gJ2NvbnRhaW5lcnMvTmF2QmFyJztcbmltcG9ydCBDaGFubmVsQ2xhaW1zRGlzcGxheSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5JztcblxuY2xhc3MgU2hvd0NoYW5uZWwgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgY2hhbm5lbCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoY2hhbm5lbCkge1xuICAgICAgY29uc3QgeyBuYW1lLCBsb25nSWQsIHNob3J0SWQgfSA9IGNoYW5uZWw7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtuYW1lfSBjaGFubmVsPXtjaGFubmVsfSAvPlxuICAgICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAnPlxuICAgICAgICAgICAgICA8aDI+Y2hhbm5lbCBuYW1lOiB7bmFtZX08L2gyPlxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9eydmaW5lLXByaW50J30+ZnVsbCBjaGFubmVsIGlkOiB7bG9uZ0lkfTwvcD5cbiAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPXsnZmluZS1wcmludCd9PnNob3J0IGNoYW5uZWwgaWQ6IHtzaG9ydElkfTwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTEwJz5cbiAgICAgICAgICAgICAgPENoYW5uZWxDbGFpbXNEaXNwbGF5IC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICApO1xuICAgIH07XG4gICAgcmV0dXJuIChcbiAgICAgIDxFcnJvclBhZ2UgZXJyb3I9eydsb2FkaW5nIGNoYW5uZWwgZGF0YS4uLid9IC8+XG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2hvd0NoYW5uZWw7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93Q2hhbm5lbC92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBvblVwZGF0ZUNoYW5uZWxDbGFpbXMgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCBjaGFubmVsIGtleVxuICBjb25zdCByZXF1ZXN0ID0gc2hvdy5yZXF1ZXN0TGlzdFtzaG93LnJlcXVlc3QuaWRdO1xuICBjb25zdCBjaGFubmVsS2V5ID0gcmVxdWVzdC5rZXk7XG4gIC8vIHNlbGVjdCBjaGFubmVsIGNsYWltc1xuICBjb25zdCBjaGFubmVsID0gc2hvdy5jaGFubmVsTGlzdFtjaGFubmVsS2V5XSB8fCBudWxsO1xuICAvLyByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBjaGFubmVsS2V5LFxuICAgIGNoYW5uZWwsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIG9uVXBkYXRlQ2hhbm5lbENsYWltcyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENsYWltc0Rpc3BsYXkvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEFzc2V0UHJldmlldyBmcm9tICdjb21wb25lbnRzL0Fzc2V0UHJldmlldyc7XG5cbmNsYXNzIENoYW5uZWxDbGFpbXNEaXNwbGF5IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IgKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMuc2hvd05leHRSZXN1bHRzUGFnZSA9IHRoaXMuc2hvd05leHRSZXN1bHRzUGFnZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UgPSB0aGlzLnNob3dQcmV2aW91c1Jlc3VsdHNQYWdlLmJpbmQodGhpcyk7XG4gIH1cbiAgc2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UgKCkge1xuICAgIGNvbnN0IHsgY2hhbm5lbDogeyBjbGFpbXNEYXRhOiB7IGN1cnJlbnRQYWdlIH0gfSB9ID0gdGhpcy5wcm9wcztcbiAgICBjb25zdCBwcmV2aW91c1BhZ2UgPSBwYXJzZUludChjdXJyZW50UGFnZSkgLSAxO1xuICAgIHRoaXMuc2hvd05ld1BhZ2UocHJldmlvdXNQYWdlKTtcbiAgfVxuICBzaG93TmV4dFJlc3VsdHNQYWdlICgpIHtcbiAgICBjb25zdCB7IGNoYW5uZWw6IHsgY2xhaW1zRGF0YTogeyBjdXJyZW50UGFnZSB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgbmV4dFBhZ2UgPSBwYXJzZUludChjdXJyZW50UGFnZSkgKyAxO1xuICAgIHRoaXMuc2hvd05ld1BhZ2UobmV4dFBhZ2UpO1xuICB9XG4gIHNob3dOZXdQYWdlIChwYWdlKSB7XG4gICAgY29uc3QgeyBjaGFubmVsS2V5LCBjaGFubmVsOiB7IG5hbWUsIGxvbmdJZCB9IH0gPSB0aGlzLnByb3BzO1xuICAgIHRoaXMucHJvcHMub25VcGRhdGVDaGFubmVsQ2xhaW1zKGNoYW5uZWxLZXksIG5hbWUsIGxvbmdJZCwgcGFnZSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGNoYW5uZWw6IHsgY2xhaW1zRGF0YTogeyBjbGFpbXMsIGN1cnJlbnRQYWdlLCB0b3RhbFBhZ2VzIH0gfSB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXRhbGwnPlxuICAgICAgICB7KGNsYWltcy5sZW5ndGggPiAwKSA/IChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAge2NsYWltcy5tYXAoKGNsYWltLCBpbmRleCkgPT4gPEFzc2V0UHJldmlld1xuICAgICAgICAgICAgICBjbGFpbURhdGE9e2NsYWltfVxuICAgICAgICAgICAgICBrZXk9e2Ake2NsYWltLm5hbWV9LSR7aW5kZXh9YH1cbiAgICAgICAgICAgIC8+KX1cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIHsoY3VycmVudFBhZ2UgPiAxKSAmJlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT17J2J1dHRvbi0tc2Vjb25kYXJ5J30gb25DbGljaz17dGhpcy5zaG93UHJldmlvdXNSZXN1bHRzUGFnZX0+UHJldmlvdXMgUGFnZTwvYnV0dG9uPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHsoY3VycmVudFBhZ2UgPCB0b3RhbFBhZ2VzKSAmJlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT17J2J1dHRvbi0tc2Vjb25kYXJ5J30gb25DbGljaz17dGhpcy5zaG93TmV4dFJlc3VsdHNQYWdlfT5OZXh0IFBhZ2U8L2J1dHRvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICkgOiAoXG4gICAgICAgICAgPHA+VGhlcmUgYXJlIG5vIGNsYWltcyBpbiB0aGlzIGNoYW5uZWw8L3A+XG4gICAgICAgICl9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsQ2xhaW1zRGlzcGxheTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7c2l0ZToge2RlZmF1bHRzOiB7IGRlZmF1bHRUaHVtYm5haWwgfX19KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZGVmYXVsdFRodW1ibmFpbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0Fzc2V0UHJldmlldy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5cbmNvbnN0IEFzc2V0UHJldmlldyA9ICh7IGRlZmF1bHRUaHVtYm5haWwsIGNsYWltRGF0YTogeyBuYW1lLCBjbGFpbUlkLCBmaWxlRXh0LCBjb250ZW50VHlwZSwgdGh1bWJuYWlsIH0gfSkgPT4ge1xuICBjb25zdCBkaXJlY3RTb3VyY2VMaW5rID0gYCR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YDtcbiAgY29uc3Qgc2hvd1VybExpbmsgPSBgLyR7Y2xhaW1JZH0vJHtuYW1lfWA7XG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9J2Fzc2V0LWhvbGRlcic+XG4gICAgICA8TGluayB0bz17c2hvd1VybExpbmt9ID5cbiAgICAgICAgeygoKSA9PiB7XG4gICAgICAgICAgc3dpdGNoIChjb250ZW50VHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9qcGcnOlxuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgICAgICAgIGNhc2UgJ2ltYWdlL2dpZic6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsnYXNzZXQtcHJldmlldyd9XG4gICAgICAgICAgICAgICAgICBzcmM9e2RpcmVjdFNvdXJjZUxpbmt9XG4gICAgICAgICAgICAgICAgICBhbHQ9e25hbWV9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsnYXNzZXQtcHJldmlldyB2aWRlbyd9XG4gICAgICAgICAgICAgICAgICBzcmM9e3RodW1ibmFpbCB8fCBkZWZhdWx0VGh1bWJuYWlsfVxuICAgICAgICAgICAgICAgICAgYWx0PXtuYW1lfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxwPnVuc3VwcG9ydGVkIGZpbGUgdHlwZTwvcD5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCl9XG4gICAgICA8L0xpbms+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldFByZXZpZXc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9Bc3NldFByZXZpZXcvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2l0ZTogeyBob3N0LCB0aXRsZSB9IH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBob3N0LFxuICAgIHRpdGxlLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2UvaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IEhlbG1ldCBmcm9tICdyZWFjdC1oZWxtZXQnO1xuXG5jbGFzcyBGb3VyT2hGb3JQYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7dGl0bGUsIGhvc3R9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPEhlbG1ldD5cbiAgICAgICAgICA8dGl0bGU+e3RpdGxlfSAtIDQwNDwvdGl0bGU+XG4gICAgICAgICAgPGxpbmsgcmVsPSdjYW5vbmljYWwnIGhyZWY9e2Ake2hvc3R9LzQwNGB9IC8+XG4gICAgICAgIDwvSGVsbWV0PlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxoMj40MDQ8L2gyPlxuICAgICAgICAgIDxwPlRoYXQgcGFnZSBkb2VzIG5vdCBleGlzdDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBGb3VyT2hGb3JQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2Uvdmlldy5qc3giLCJjb25zdCB7IHNlbmRHQVNlcnZlRXZlbnQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzJyk7XG5jb25zdCB7IGRldGVybWluZVJlc3BvbnNlVHlwZSwgZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eSwgbG9nUmVxdWVzdERhdGEsIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0IH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL3NlcnZlSGVscGVycy5qcycpO1xuY29uc3QgbGJyeVVyaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeVVyaS5qcycpO1xuY29uc3QgaGFuZGxlU2hvd1JlbmRlciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaGFuZGxlU2hvd1JlbmRlci5qc3gnKTtcbmNvbnN0IFNFUlZFID0gJ1NFUlZFJztcblxubW9kdWxlLmV4cG9ydHMgPSAoYXBwKSA9PiB7XG4gIC8vIHJvdXRlIHRvIHNlcnZlIGEgc3BlY2lmaWMgYXNzZXQgdXNpbmcgdGhlIGNoYW5uZWwgb3IgY2xhaW0gaWRcbiAgYXBwLmdldCgnLzppZGVudGlmaWVyLzpjbGFpbScsIChyZXEsIHJlcykgPT4ge1xuICAgIGNvbnN0IHsgaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSA9IHJlcTtcbiAgICAvLyBkZWNpZGUgaWYgdGhpcyBpcyBhIHNob3cgcmVxdWVzdFxuICAgIGxldCBoYXNGaWxlRXh0ZW5zaW9uO1xuICAgIHRyeSB7XG4gICAgICAoeyBoYXNGaWxlRXh0ZW5zaW9uIH0gPSBsYnJ5VXJpLnBhcnNlTW9kaWZpZXIocGFyYW1zLmNsYWltKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgICB9XG4gICAgbGV0IHJlc3BvbnNlVHlwZSA9IGRldGVybWluZVJlc3BvbnNlVHlwZShoYXNGaWxlRXh0ZW5zaW9uLCBoZWFkZXJzKTtcbiAgICBpZiAocmVzcG9uc2VUeXBlICE9PSBTRVJWRSkge1xuICAgICAgcmV0dXJuIGhhbmRsZVNob3dSZW5kZXIocmVxLCByZXMpO1xuICAgIH1cbiAgICAvLyBoYW5kbGUgc2VydmUgcmVxdWVzdFxuICAgIC8vIHNlbmQgZ29vZ2xlIGFuYWx5dGljc1xuICAgIHNlbmRHQVNlcnZlRXZlbnQoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKTtcbiAgICAvLyBwYXJzZSB0aGUgY2xhaW1cbiAgICBsZXQgY2xhaW1OYW1lO1xuICAgIHRyeSB7XG4gICAgICAoeyBjbGFpbU5hbWUgfSA9IGxicnlVcmkucGFyc2VDbGFpbShwYXJhbXMuY2xhaW0pKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZX0pO1xuICAgIH1cbiAgICAvLyBwYXJzZSB0aGUgaWRlbnRpZmllclxuICAgIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1JZDtcbiAgICB0cnkge1xuICAgICAgKHsgaXNDaGFubmVsLCBjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltSWQgfSA9IGxicnlVcmkucGFyc2VJZGVudGlmaWVyKHBhcmFtcy5pZGVudGlmaWVyKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgICB9XG4gICAgaWYgKCFpc0NoYW5uZWwpIHtcbiAgICAgIFtjbGFpbUlkLCBjbGFpbU5hbWVdID0gZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eShjbGFpbUlkLCBjbGFpbU5hbWUpO1xuICAgIH1cbiAgICAvLyBsb2cgdGhlIHJlcXVlc3QgZGF0YSBmb3IgZGVidWdnaW5nXG4gICAgbG9nUmVxdWVzdERhdGEocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIGNoYW5uZWxOYW1lLCBjbGFpbUlkKTtcbiAgICAvLyBnZXQgdGhlIGNsYWltIElkIGFuZCB0aGVuIHNlcnZlIHRoZSBhc3NldFxuICAgIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0KGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lLCBjbGFpbUlkLCBvcmlnaW5hbFVybCwgaXAsIHJlcyk7XG4gIH0pO1xuICAvLyByb3V0ZSB0byBzZXJ2ZSB0aGUgd2lubmluZyBhc3NldCBhdCBhIGNsYWltIG9yIGEgY2hhbm5lbCBwYWdlXG4gIGFwcC5nZXQoJy86Y2xhaW0nLCAocmVxLCByZXMpID0+IHtcbiAgICBjb25zdCB7IGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0gPSByZXE7XG4gICAgLy8gZGVjaWRlIGlmIHRoaXMgaXMgYSBzaG93IHJlcXVlc3RcbiAgICBsZXQgaGFzRmlsZUV4dGVuc2lvbjtcbiAgICB0cnkge1xuICAgICAgKHsgaGFzRmlsZUV4dGVuc2lvbiB9ID0gbGJyeVVyaS5wYXJzZU1vZGlmaWVyKHBhcmFtcy5jbGFpbSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgfVxuICAgIGxldCByZXNwb25zZVR5cGUgPSBkZXRlcm1pbmVSZXNwb25zZVR5cGUoaGFzRmlsZUV4dGVuc2lvbiwgaGVhZGVycyk7XG4gICAgaWYgKHJlc3BvbnNlVHlwZSAhPT0gU0VSVkUpIHtcbiAgICAgIHJldHVybiBoYW5kbGVTaG93UmVuZGVyKHJlcSwgcmVzKTtcbiAgICB9XG4gICAgLy8gaGFuZGxlIHNlcnZlIHJlcXVlc3RcbiAgICAvLyBzZW5kIGdvb2dsZSBhbmFseXRpY3NcbiAgICBzZW5kR0FTZXJ2ZUV2ZW50KGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCk7XG4gICAgLy8gcGFyc2UgdGhlIGNsYWltXG4gICAgbGV0IGNsYWltTmFtZTtcbiAgICB0cnkge1xuICAgICAgKHtjbGFpbU5hbWV9ID0gbGJyeVVyaS5wYXJzZUNsYWltKHBhcmFtcy5jbGFpbSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgfVxuICAgIC8vIGxvZyB0aGUgcmVxdWVzdCBkYXRhIGZvciBkZWJ1Z2dpbmdcbiAgICBsb2dSZXF1ZXN0RGF0YShyZXNwb25zZVR5cGUsIGNsYWltTmFtZSwgbnVsbCwgbnVsbCk7XG4gICAgLy8gZ2V0IHRoZSBjbGFpbSBJZCBhbmQgdGhlbiBzZXJ2ZSB0aGUgYXNzZXRcbiAgICBnZXRDbGFpbUlkQW5kU2VydmVBc3NldChudWxsLCBudWxsLCBjbGFpbU5hbWUsIG51bGwsIG9yaWdpbmFsVXJsLCBpcCwgcmVzKTtcbiAgfSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hc3NldC1yb3V0ZXMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IGdldENsYWltSWQsIGdldExvY2FsRmlsZVJlY29yZCB9ID0gcmVxdWlyZSgnLi4vY29udHJvbGxlcnMvc2VydmVDb250cm9sbGVyLmpzJyk7XG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJy4vZXJyb3JIYW5kbGVycy5qcycpO1xuXG5jb25zdCBTRVJWRSA9ICdTRVJWRSc7XG5jb25zdCBTSE9XID0gJ1NIT1cnO1xuY29uc3QgTk9fRklMRSA9ICdOT19GSUxFJztcbmNvbnN0IE5PX0NIQU5ORUwgPSAnTk9fQ0hBTk5FTCc7XG5jb25zdCBOT19DTEFJTSA9ICdOT19DTEFJTSc7XG5cbmZ1bmN0aW9uIGNsaWVudEFjY2VwdHNIdG1sICh7YWNjZXB0fSkge1xuICByZXR1cm4gYWNjZXB0ICYmIGFjY2VwdC5tYXRjaCgvdGV4dFxcL2h0bWwvKTtcbn07XG5cbmZ1bmN0aW9uIHJlcXVlc3RJc0Zyb21Ccm93c2VyIChoZWFkZXJzKSB7XG4gIHJldHVybiBoZWFkZXJzWyd1c2VyLWFnZW50J10gJiYgaGVhZGVyc1sndXNlci1hZ2VudCddLm1hdGNoKC9Nb3ppbGxhLyk7XG59O1xuXG5mdW5jdGlvbiBjbGllbnRXYW50c0Fzc2V0ICh7YWNjZXB0LCByYW5nZX0pIHtcbiAgY29uc3QgaW1hZ2VJc1dhbnRlZCA9IGFjY2VwdCAmJiBhY2NlcHQubWF0Y2goL2ltYWdlXFwvLiovKSAmJiAhYWNjZXB0Lm1hdGNoKC90ZXh0XFwvaHRtbC8pICYmICFhY2NlcHQubWF0Y2goL3RleHRcXC9cXCovKTtcbiAgY29uc3QgdmlkZW9Jc1dhbnRlZCA9IGFjY2VwdCAmJiByYW5nZTtcbiAgcmV0dXJuIGltYWdlSXNXYW50ZWQgfHwgdmlkZW9Jc1dhbnRlZDtcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRDbGFpbUlkIChjbGFpbUlkKSB7XG4gIHJldHVybiAoKGNsYWltSWQubGVuZ3RoID09PSA0MCkgJiYgIS9bXkEtWmEtejAtOV0vZy50ZXN0KGNsYWltSWQpKTtcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRTaG9ydElkIChjbGFpbUlkKSB7XG4gIHJldHVybiBjbGFpbUlkLmxlbmd0aCA9PT0gMTsgIC8vIGl0IHNob3VsZCByZWFsbHkgZXZhbHVhdGUgdGhlIHNob3J0IHVybCBpdHNlbGZcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRTaG9ydElkT3JDbGFpbUlkIChpbnB1dCkge1xuICByZXR1cm4gKGlzVmFsaWRDbGFpbUlkKGlucHV0KSB8fCBpc1ZhbGlkU2hvcnRJZChpbnB1dCkpO1xufTtcblxuZnVuY3Rpb24gc2VydmVBc3NldFRvQ2xpZW50IChjbGFpbUlkLCBuYW1lLCByZXMpIHtcbiAgcmV0dXJuIGdldExvY2FsRmlsZVJlY29yZChjbGFpbUlkLCBuYW1lKVxuICAgIC50aGVuKGZpbGVSZWNvcmQgPT4ge1xuICAgICAgLy8gY2hlY2sgdGhhdCBhIGxvY2FsIHJlY29yZCB3YXMgZm91bmRcbiAgICAgIGlmIChmaWxlUmVjb3JkID09PSBOT19GSUxFKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDMwNykucmVkaXJlY3QoYC9hcGkvY2xhaW0vZ2V0LyR7bmFtZX0vJHtjbGFpbUlkfWApO1xuICAgICAgfVxuICAgICAgLy8gc2VydmUgdGhlIGZpbGVcbiAgICAgIGNvbnN0IHtmaWxlUGF0aCwgZmlsZVR5cGV9ID0gZmlsZVJlY29yZDtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBzZXJ2aW5nIGZpbGU6ICR7ZmlsZVBhdGh9YCk7XG4gICAgICBjb25zdCBzZW5kRmlsZU9wdGlvbnMgPSB7XG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnWC1Db250ZW50LVR5cGUtT3B0aW9ucyc6ICdub3NuaWZmJyxcbiAgICAgICAgICAnQ29udGVudC1UeXBlJyAgICAgICAgICA6IGZpbGVUeXBlIHx8ICdpbWFnZS9qcGVnJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICByZXMuc3RhdHVzKDIwMCkuc2VuZEZpbGUoZmlsZVBhdGgsIHNlbmRGaWxlT3B0aW9ucyk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQgKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lLCBjbGFpbUlkLCBvcmlnaW5hbFVybCwgaXAsIHJlcykge1xuICAgIC8vIGdldCB0aGUgY2xhaW0gSWQgYW5kIHRoZW4gc2VydmUgdGhlIGFzc2V0XG4gICAgZ2V0Q2xhaW1JZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSwgY2xhaW1JZClcbiAgICAgIC50aGVuKGZ1bGxDbGFpbUlkID0+IHtcbiAgICAgICAgaWYgKGZ1bGxDbGFpbUlkID09PSBOT19DTEFJTSkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdubyBjbGFpbSBpZCBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfSBlbHNlIGlmIChmdWxsQ2xhaW1JZCA9PT0gTk9fQ0hBTk5FTCkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdubyBjaGFubmVsIGlkIGNvdWxkIGJlIGZvdW5kJ30pO1xuICAgICAgICB9XG4gICAgICAgIHNlcnZlQXNzZXRUb0NsaWVudChmdWxsQ2xhaW1JZCwgY2xhaW1OYW1lLCByZXMpO1xuICAgICAgICAvLyBwb3N0VG9TdGF0cyhyZXNwb25zZVR5cGUsIG9yaWdpbmFsVXJsLCBpcCwgY2xhaW1OYW1lLCBmdWxsQ2xhaW1JZCwgJ3N1Y2Nlc3MnKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICAgIC8vIHBvc3RUb1N0YXRzKHJlc3BvbnNlVHlwZSwgb3JpZ2luYWxVcmwsIGlwLCBjbGFpbU5hbWUsIGZ1bGxDbGFpbUlkLCAnZmFpbCcpO1xuICAgICAgfSk7XG4gIH0sXG4gIGRldGVybWluZVJlc3BvbnNlVHlwZSAoaGFzRmlsZUV4dGVuc2lvbiwgaGVhZGVycykge1xuICAgIGxldCByZXNwb25zZVR5cGU7XG4gICAgaWYgKGhhc0ZpbGVFeHRlbnNpb24pIHtcbiAgICAgIHJlc3BvbnNlVHlwZSA9IFNFUlZFOyAgLy8gYXNzdW1lIGEgc2VydmUgcmVxdWVzdCBpZiBmaWxlIGV4dGVuc2lvbiBpcyBwcmVzZW50XG4gICAgICBpZiAoY2xpZW50QWNjZXB0c0h0bWwoaGVhZGVycykpIHsgIC8vIGlmIHRoZSByZXF1ZXN0IGNvbWVzIGZyb20gYSBicm93c2VyLCBjaGFuZ2UgaXQgdG8gYSBzaG93IHJlcXVlc3RcbiAgICAgICAgcmVzcG9uc2VUeXBlID0gU0hPVztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzcG9uc2VUeXBlID0gU0hPVztcbiAgICAgIGlmIChjbGllbnRXYW50c0Fzc2V0KGhlYWRlcnMpICYmIHJlcXVlc3RJc0Zyb21Ccm93c2VyKGhlYWRlcnMpKSB7ICAvLyB0aGlzIGlzIGluIGNhc2Ugc29tZW9uZSBlbWJlZHMgYSBzaG93IHVybFxuICAgICAgICBsb2dnZXIuZGVidWcoJ1Nob3cgcmVxdWVzdCBjYW1lIGZyb20gYnJvd3NlciBidXQgd2FudHMgYW4gaW1hZ2UvdmlkZW8uIENoYW5naW5nIHJlc3BvbnNlIHRvIHNlcnZlLi4uJyk7XG4gICAgICAgIHJlc3BvbnNlVHlwZSA9IFNFUlZFO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2VUeXBlO1xuICB9LFxuICBmbGlwQ2xhaW1OYW1lQW5kSWRGb3JCYWNrd2FyZHNDb21wYXRpYmlsaXR5IChpZGVudGlmaWVyLCBuYW1lKSB7XG4gICAgLy8gdGhpcyBpcyBhIHBhdGNoIGZvciBiYWNrd2FyZHMgY29tcGF0YWJpbGl0eSB3aXRoICcvbmFtZS9jbGFpbV9pZCcgdXJsIGZvcm1hdFxuICAgIGlmIChpc1ZhbGlkU2hvcnRJZE9yQ2xhaW1JZChuYW1lKSAmJiAhaXNWYWxpZFNob3J0SWRPckNsYWltSWQoaWRlbnRpZmllcikpIHtcbiAgICAgIGNvbnN0IHRlbXBOYW1lID0gbmFtZTtcbiAgICAgIG5hbWUgPSBpZGVudGlmaWVyO1xuICAgICAgaWRlbnRpZmllciA9IHRlbXBOYW1lO1xuICAgIH1cbiAgICByZXR1cm4gW2lkZW50aWZpZXIsIG5hbWVdO1xuICB9LFxuICBsb2dSZXF1ZXN0RGF0YSAocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIGNoYW5uZWxOYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdyZXNwb25zZVR5cGUgPT09JywgcmVzcG9uc2VUeXBlKTtcbiAgICBsb2dnZXIuZGVidWcoJ2NsYWltIG5hbWUgPT09ICcsIGNsYWltTmFtZSk7XG4gICAgbG9nZ2VyLmRlYnVnKCdjaGFubmVsIG5hbWUgPT09JywgY2hhbm5lbE5hbWUpO1xuICAgIGxvZ2dlci5kZWJ1ZygnY2xhaW0gaWQgPT09JywgY2xhaW1JZCk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvc2VydmVIZWxwZXJzLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgUkVHRVhQX0lOVkFMSURfQ0xBSU0gIDogL1teQS1aYS16MC05LV0vZyxcbiAgUkVHRVhQX0lOVkFMSURfQ0hBTk5FTDogL1teQS1aYS16MC05LUBdL2csXG4gIFJFR0VYUF9BRERSRVNTICAgICAgICA6IC9eYig/PVteME9JbF17MzIsMzN9KVswLTlBLVphLXpdezMyLDMzfSQvLFxuICBDSEFOTkVMX0NIQVIgICAgICAgICAgOiAnQCcsXG4gIHBhcnNlSWRlbnRpZmllciAgICAgICA6IGZ1bmN0aW9uIChpZGVudGlmaWVyKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdwYXJzaW5nIGlkZW50aWZpZXI6JywgaWRlbnRpZmllcik7XG4gICAgY29uc3QgY29tcG9uZW50c1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICAgICcoW146JCMvXSopJyArIC8vIHZhbHVlIChzdG9wcyBhdCB0aGUgZmlyc3Qgc2VwYXJhdG9yIG9yIGVuZClcbiAgICAgICcoWzokI10/KShbXi9dKiknIC8vIG1vZGlmaWVyIHNlcGFyYXRvciwgbW9kaWZpZXIgKHN0b3BzIGF0IHRoZSBmaXJzdCBwYXRoIHNlcGFyYXRvciBvciBlbmQpXG4gICAgKTtcbiAgICBjb25zdCBbcHJvdG8sIHZhbHVlLCBtb2RpZmllclNlcGVyYXRvciwgbW9kaWZpZXJdID0gY29tcG9uZW50c1JlZ2V4XG4gICAgICAuZXhlYyhpZGVudGlmaWVyKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcbiAgICBsb2dnZXIuZGVidWcoYCR7cHJvdG99LCAke3ZhbHVlfSwgJHttb2RpZmllclNlcGVyYXRvcn0sICR7bW9kaWZpZXJ9YCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIHVybC4gIE5vIGNoYW5uZWwgbmFtZSBwcm92aWRlZCBiZWZvcmUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IGlzQ2hhbm5lbCA9IHZhbHVlLnN0YXJ0c1dpdGgobW9kdWxlLmV4cG9ydHMuQ0hBTk5FTF9DSEFSKTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGlzQ2hhbm5lbCA/IHZhbHVlIDogbnVsbDtcbiAgICBsZXQgY2xhaW1JZDtcbiAgICBpZiAoaXNDaGFubmVsKSB7XG4gICAgICBpZiAoIWNoYW5uZWxOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2hhbm5lbCBuYW1lIGFmdGVyIEAuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2hhbm5lbE5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NIQU5ORUwpO1xuICAgICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgY2hhcmFjdGVycyBpbiBjaGFubmVsIG5hbWU6ICR7bmFtZUJhZENoYXJzLmpvaW4oJywgJyl9LmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjbGFpbUlkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gbW9kaWZpZXIgcHJvdmlkZWQgYWZ0ZXIgc2VwYXJhdG9yIFwiJHttb2RpZmllclNlcGVyYXRvcn1cImApO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IgPT09ICc6Jykge1xuICAgICAgICBjaGFubmVsQ2xhaW1JZCA9IG1vZGlmaWVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiIG1vZGlmaWVyIGlzIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkYCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBpc0NoYW5uZWwsXG4gICAgICBjaGFubmVsTmFtZSxcbiAgICAgIGNoYW5uZWxDbGFpbUlkLFxuICAgICAgY2xhaW1JZCxcbiAgICB9O1xuICB9LFxuICBwYXJzZUNsYWltOiBmdW5jdGlvbiAoY2xhaW0pIHtcbiAgICBsb2dnZXIuZGVidWcoJ3BhcnNpbmcgbmFtZTonLCBjbGFpbSk7XG4gICAgY29uc3QgY29tcG9uZW50c1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICAgICcoW146JCMvLl0qKScgKyAvLyBuYW1lIChzdG9wcyBhdCB0aGUgZmlyc3QgbW9kaWZpZXIpXG4gICAgICAnKFs6JCMuXT8pKFteL10qKScgLy8gbW9kaWZpZXIgc2VwYXJhdG9yLCBtb2RpZmllciAoc3RvcHMgYXQgdGhlIGZpcnN0IHBhdGggc2VwYXJhdG9yIG9yIGVuZClcbiAgICApO1xuICAgIGNvbnN0IFtwcm90bywgY2xhaW1OYW1lLCBtb2RpZmllclNlcGVyYXRvciwgbW9kaWZpZXJdID0gY29tcG9uZW50c1JlZ2V4XG4gICAgICAuZXhlYyhjbGFpbSlcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG4gICAgbG9nZ2VyLmRlYnVnKGAke3Byb3RvfSwgJHtjbGFpbU5hbWV9LCAke21vZGlmaWVyU2VwZXJhdG9yfSwgJHttb2RpZmllcn1gKTtcblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG5hbWVcbiAgICBpZiAoIWNsYWltTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjbGFpbSBuYW1lIHByb3ZpZGVkIGJlZm9yZSAuJyk7XG4gICAgfVxuICAgIGNvbnN0IG5hbWVCYWRDaGFycyA9IChjbGFpbU5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NMQUlNKTtcbiAgICBpZiAobmFtZUJhZENoYXJzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgY2hhcmFjdGVycyBpbiBjbGFpbSBuYW1lOiAke25hbWVCYWRDaGFycy5qb2luKCcsICcpfS5gKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IpIHtcbiAgICAgIGlmICghbW9kaWZpZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBmaWxlIGV4dGVuc2lvbiBwcm92aWRlZCBhZnRlciBzZXBhcmF0b3IgJHttb2RpZmllclNlcGVyYXRvcn0uYCk7XG4gICAgICB9XG4gICAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IgIT09ICcuJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSAke21vZGlmaWVyU2VwZXJhdG9yfSBtb2RpZmllciBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjbGFpbSBuYW1lYCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHJldHVybiByZXN1bHRzXG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYWltTmFtZSxcbiAgICB9O1xuICB9LFxuICBwYXJzZU1vZGlmaWVyOiBmdW5jdGlvbiAoY2xhaW0pIHtcbiAgICBsb2dnZXIuZGVidWcoJ3BhcnNpbmcgbW9kaWZpZXI6JywgY2xhaW0pO1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjLy5dKiknICsgLy8gbmFtZSAoc3RvcHMgYXQgdGhlIGZpcnN0IG1vZGlmaWVyKVxuICAgICAgJyhbOiQjLl0/KShbXi9dKiknIC8vIG1vZGlmaWVyIHNlcGFyYXRvciwgbW9kaWZpZXIgKHN0b3BzIGF0IHRoZSBmaXJzdCBwYXRoIHNlcGFyYXRvciBvciBlbmQpXG4gICAgKTtcbiAgICBjb25zdCBbcHJvdG8sIGNsYWltTmFtZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleFxuICAgICAgLmV4ZWMoY2xhaW0pXG4gICAgICAubWFwKG1hdGNoID0+IG1hdGNoIHx8IG51bGwpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgJHtwcm90b30sICR7Y2xhaW1OYW1lfSwgJHttb2RpZmllclNlcGVyYXRvcn0sICR7bW9kaWZpZXJ9YCk7XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgaGFzRmlsZUV4dGVuc2lvbiA9IGZhbHNlO1xuICAgIGlmIChtb2RpZmllclNlcGVyYXRvcikge1xuICAgICAgaGFzRmlsZUV4dGVuc2lvbiA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBoYXNGaWxlRXh0ZW5zaW9uLFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvbGJyeVVyaS5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXJUb1N0cmluZyB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IHsgY3JlYXRlU3RvcmUsIGFwcGx5TWlkZGxld2FyZSB9IGZyb20gJ3JlZHV4JztcbmltcG9ydCBSZWR1Y2VyIGZyb20gJy4uLy4uL2NsaWVudC9yZWR1Y2Vycy9pbmRleCc7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IFN0YXRpY1JvdXRlciB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEdBTGlzdGVuZXIgZnJvbSAnLi4vLi4vY2xpZW50L2NvbXBvbmVudHMvR0FMaXN0ZW5lci9pbmRleCc7XG5pbXBvcnQgQXBwIGZyb20gJy4uLy4uL2NsaWVudC9hcHAnO1xuaW1wb3J0IHJlbmRlckZ1bGxQYWdlIGZyb20gJy4vcmVuZGVyRnVsbFBhZ2UnO1xuaW1wb3J0IGNyZWF0ZVNhZ2FNaWRkbGV3YXJlIGZyb20gJ3JlZHV4LXNhZ2EnO1xuaW1wb3J0IHsgY2FsbCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgeyBoYW5kbGVTaG93UGFnZVVyaSB9IGZyb20gJy4uLy4uL2NsaWVudC9zYWdhcy9zaG93X3VyaSc7XG5pbXBvcnQgeyBvbkhhbmRsZVNob3dQYWdlVXJpIH0gZnJvbSAnLi4vLi4vY2xpZW50L2FjdGlvbnMvc2hvdyc7XG5cbmltcG9ydCBIZWxtZXQgZnJvbSAncmVhY3QtaGVsbWV0JztcblxuY29uc3QgcmV0dXJuU2FnYVdpdGhQYXJhbXMgPSAoc2FnYSwgcGFyYW1zKSA9PiB7XG4gIHJldHVybiBmdW5jdGlvbiAqICgpIHtcbiAgICB5aWVsZCBjYWxsKHNhZ2EsIHBhcmFtcyk7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChyZXEsIHJlcykgPT4ge1xuICBsZXQgY29udGV4dCA9IHt9O1xuXG4gIC8vIGNyZWF0ZSBhbmQgYXBwbHkgbWlkZGxld2FyZVxuICBjb25zdCBzYWdhTWlkZGxld2FyZSA9IGNyZWF0ZVNhZ2FNaWRkbGV3YXJlKCk7XG4gIGNvbnN0IG1pZGRsZXdhcmUgPSBhcHBseU1pZGRsZXdhcmUoc2FnYU1pZGRsZXdhcmUpO1xuXG4gIC8vIGNyZWF0ZSBhIG5ldyBSZWR1eCBzdG9yZSBpbnN0YW5jZVxuICBjb25zdCBzdG9yZSA9IGNyZWF0ZVN0b3JlKFJlZHVjZXIsIG1pZGRsZXdhcmUpO1xuXG4gIC8vIGNyZWF0ZSBzYWdhXG4gIGNvbnN0IGFjdGlvbiA9IG9uSGFuZGxlU2hvd1BhZ2VVcmkocmVxLnBhcmFtcyk7XG4gIGNvbnN0IHNhZ2EgPSByZXR1cm5TYWdhV2l0aFBhcmFtcyhoYW5kbGVTaG93UGFnZVVyaSwgYWN0aW9uKTtcblxuICAvLyBydW4gdGhlIHNhZ2EgbWlkZGxld2FyZVxuICBzYWdhTWlkZGxld2FyZVxuICAgIC5ydW4oc2FnYSlcbiAgICAuZG9uZVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIC8vIHJlbmRlciBjb21wb25lbnQgdG8gYSBzdHJpbmdcbiAgICAgIGNvbnN0IGh0bWwgPSByZW5kZXJUb1N0cmluZyhcbiAgICAgICAgPFByb3ZpZGVyIHN0b3JlPXtzdG9yZX0+XG4gICAgICAgICAgPFN0YXRpY1JvdXRlciBsb2NhdGlvbj17cmVxLnVybH0gY29udGV4dD17Y29udGV4dH0+XG4gICAgICAgICAgICA8R0FMaXN0ZW5lcj5cbiAgICAgICAgICAgICAgPEFwcCAvPlxuICAgICAgICAgICAgPC9HQUxpc3RlbmVyPlxuICAgICAgICAgIDwvU3RhdGljUm91dGVyPlxuICAgICAgICA8L1Byb3ZpZGVyPlxuICAgICAgKTtcblxuICAgICAgLy8gZ2V0IGhlYWQgdGFncyBmcm9tIGhlbG1ldFxuICAgICAgY29uc3QgaGVsbWV0ID0gSGVsbWV0LnJlbmRlclN0YXRpYygpO1xuXG4gICAgICAvLyBjaGVjayBmb3IgYSByZWRpcmVjdFxuICAgICAgaWYgKGNvbnRleHQudXJsKSB7XG4gICAgICAgIHJldHVybiByZXMucmVkaXJlY3QoMzAxLCBjb250ZXh0LnVybCk7XG4gICAgICB9XG5cbiAgICAgIC8vIGdldCB0aGUgaW5pdGlhbCBzdGF0ZSBmcm9tIG91ciBSZWR1eCBzdG9yZVxuICAgICAgY29uc3QgcHJlbG9hZGVkU3RhdGUgPSBzdG9yZS5nZXRTdGF0ZSgpO1xuXG4gICAgICAvLyBzZW5kIHRoZSByZW5kZXJlZCBwYWdlIGJhY2sgdG8gdGhlIGNsaWVudFxuICAgICAgcmVzLnNlbmQocmVuZGVyRnVsbFBhZ2UoaGVsbWV0LCBodG1sLCBwcmVsb2FkZWRTdGF0ZSkpO1xuICAgIH0pO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVkdXgtc2FnYVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlZHV4LXNhZ2FcIlxuLy8gbW9kdWxlIGlkID0gMTUxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImltcG9ydCB7IGNhbGwsIHB1dCwgdGFrZUxhdGVzdCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBvblJlcXVlc3RFcnJvciwgb25OZXdDaGFubmVsUmVxdWVzdCwgb25OZXdBc3NldFJlcXVlc3QgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IHsgbmV3QXNzZXRSZXF1ZXN0IH0gZnJvbSAnc2FnYXMvc2hvd19hc3NldCc7XG5pbXBvcnQgeyBuZXdDaGFubmVsUmVxdWVzdCB9IGZyb20gJ3NhZ2FzL3Nob3dfY2hhbm5lbCc7XG5pbXBvcnQgbGJyeVVyaSBmcm9tICd1dGlscy9sYnJ5VXJpJztcblxuZnVuY3Rpb24gKiBwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSAobW9kaWZpZXIsIGNsYWltKSB7XG4gIC8vIHRoaXMgaXMgYSByZXF1ZXN0IGZvciBhbiBhc3NldFxuICAvLyBjbGFpbSB3aWxsIGJlIGFuIGFzc2V0IGNsYWltXG4gIC8vIHRoZSBpZGVudGlmaWVyIGNvdWxkIGJlIGEgY2hhbm5lbCBvciBhIGNsYWltIGlkXG4gIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1JZCwgY2xhaW1OYW1lLCBleHRlbnNpb247XG4gIHRyeSB7XG4gICAgKHsgaXNDaGFubmVsLCBjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltSWQgfSA9IGxicnlVcmkucGFyc2VJZGVudGlmaWVyKG1vZGlmaWVyKSk7XG4gICAgKHsgY2xhaW1OYW1lLCBleHRlbnNpb24gfSA9IGxicnlVcmkucGFyc2VDbGFpbShjbGFpbSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIHRyaWdnZXIgYW4gbmV3IGFjdGlvbiB0byB1cGRhdGUgdGhlIHN0b3JlXG4gIGlmIChpc0NoYW5uZWwpIHtcbiAgICByZXR1cm4geWllbGQgY2FsbChuZXdBc3NldFJlcXVlc3QsIG9uTmV3QXNzZXRSZXF1ZXN0KGNsYWltTmFtZSwgbnVsbCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBleHRlbnNpb24pKTtcbiAgfTtcbiAgeWllbGQgY2FsbChuZXdBc3NldFJlcXVlc3QsIG9uTmV3QXNzZXRSZXF1ZXN0KGNsYWltTmFtZSwgY2xhaW1JZCwgbnVsbCwgbnVsbCwgZXh0ZW5zaW9uKSk7XG59XG5mdW5jdGlvbiAqIHBhcnNlQW5kVXBkYXRlQ2xhaW1Pbmx5IChjbGFpbSkge1xuICAvLyB0aGlzIGNvdWxkIGJlIGEgcmVxdWVzdCBmb3IgYW4gYXNzZXQgb3IgYSBjaGFubmVsIHBhZ2VcbiAgLy8gY2xhaW0gY291bGQgYmUgYW4gYXNzZXQgY2xhaW0gb3IgYSBjaGFubmVsIGNsYWltXG4gIGxldCBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZDtcbiAgdHJ5IHtcbiAgICAoeyBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCB9ID0gbGJyeVVyaS5wYXJzZUlkZW50aWZpZXIoY2xhaW0pKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyB0cmlnZ2VyIGFuIG5ldyBhY3Rpb24gdG8gdXBkYXRlIHRoZSBzdG9yZVxuICAvLyByZXR1cm4gZWFybHkgaWYgdGhpcyByZXF1ZXN0IGlzIGZvciBhIGNoYW5uZWxcbiAgaWYgKGlzQ2hhbm5lbCkge1xuICAgIHJldHVybiB5aWVsZCBjYWxsKG5ld0NoYW5uZWxSZXF1ZXN0LCBvbk5ld0NoYW5uZWxSZXF1ZXN0KGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkpO1xuICB9XG4gIC8vIGlmIG5vdCBmb3IgYSBjaGFubmVsLCBwYXJzZSB0aGUgY2xhaW0gcmVxdWVzdFxuICBsZXQgY2xhaW1OYW1lLCBleHRlbnNpb247XG4gIHRyeSB7XG4gICAgKHtjbGFpbU5hbWUsIGV4dGVuc2lvbn0gPSBsYnJ5VXJpLnBhcnNlQ2xhaW0oY2xhaW0pKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICB5aWVsZCBjYWxsKG5ld0Fzc2V0UmVxdWVzdCwgb25OZXdBc3NldFJlcXVlc3QoY2xhaW1OYW1lLCBudWxsLCBudWxsLCBudWxsLCBleHRlbnNpb24pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uICogaGFuZGxlU2hvd1BhZ2VVcmkgKGFjdGlvbikge1xuICBjb25zdCB7IGlkZW50aWZpZXIsIGNsYWltIH0gPSBhY3Rpb24uZGF0YTtcbiAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICByZXR1cm4geWllbGQgY2FsbChwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSwgaWRlbnRpZmllciwgY2xhaW0pO1xuICB9XG4gIHlpZWxkIGNhbGwocGFyc2VBbmRVcGRhdGVDbGFpbU9ubHksIGNsYWltKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoSGFuZGxlU2hvd1BhZ2VVcmkgKCkge1xuICB5aWVsZCB0YWtlTGF0ZXN0KGFjdGlvbnMuSEFORExFX1NIT1dfVVJJLCBoYW5kbGVTaG93UGFnZVVyaSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NhZ2FzL3Nob3dfdXJpLmpzIiwiaW1wb3J0IHsgY2FsbCwgcHV0LCBzZWxlY3QsIHRha2VMYXRlc3QgfSBmcm9tICdyZWR1eC1zYWdhL2VmZmVjdHMnO1xuaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvc2hvd19hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgYWRkUmVxdWVzdFRvUmVxdWVzdExpc3QsIG9uUmVxdWVzdEVycm9yLCBvblJlcXVlc3RVcGRhdGUsIGFkZEFzc2V0VG9Bc3NldExpc3QgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IHsgZ2V0TG9uZ0NsYWltSWQsIGdldFNob3J0SWQsIGdldENsYWltRGF0YSB9IGZyb20gJ2FwaS9hc3NldEFwaSc7XG5pbXBvcnQgeyBzZWxlY3RTaG93U3RhdGUgfSBmcm9tICdzZWxlY3RvcnMvc2hvdyc7XG5pbXBvcnQgeyBzZWxlY3RTaXRlSG9zdCB9IGZyb20gJ3NlbGVjdG9ycy9zaXRlJztcblxuZXhwb3J0IGZ1bmN0aW9uICogbmV3QXNzZXRSZXF1ZXN0IChhY3Rpb24pIHtcbiAgY29uc3QgeyByZXF1ZXN0VHlwZSwgcmVxdWVzdElkLCBuYW1lLCBtb2RpZmllciB9ID0gYWN0aW9uLmRhdGE7XG4gIC8vIHB1dCBhbiBhY3Rpb24gdG8gdXBkYXRlIHRoZSByZXF1ZXN0IGluIHJlZHV4XG4gIHlpZWxkIHB1dChvblJlcXVlc3RVcGRhdGUocmVxdWVzdFR5cGUsIHJlcXVlc3RJZCkpO1xuICAvLyBpcyB0aGlzIGFuIGV4aXN0aW5nIHJlcXVlc3Q/XG4gIC8vIElmIHRoaXMgdXJpIGlzIGluIHRoZSByZXF1ZXN0IGxpc3QsIGl0J3MgYWxyZWFkeSBiZWVuIGZldGNoZWRcbiAgY29uc3Qgc3RhdGUgPSB5aWVsZCBzZWxlY3Qoc2VsZWN0U2hvd1N0YXRlKTtcbiAgY29uc3QgaG9zdCA9IHlpZWxkIHNlbGVjdChzZWxlY3RTaXRlSG9zdCk7XG4gIGlmIChzdGF0ZS5yZXF1ZXN0TGlzdFtyZXF1ZXN0SWRdKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLy8gZ2V0IGxvbmcgaWQgJiYgYWRkIHJlcXVlc3QgdG8gcmVxdWVzdCBsaXN0XG4gIGxldCBsb25nSWQ7XG4gIHRyeSB7XG4gICAgKHtkYXRhOiBsb25nSWR9ID0geWllbGQgY2FsbChnZXRMb25nQ2xhaW1JZCwgaG9zdCwgbmFtZSwgbW9kaWZpZXIpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICBjb25zdCBhc3NldEtleSA9IGBhIyR7bmFtZX0jJHtsb25nSWR9YDtcbiAgeWllbGQgcHV0KGFkZFJlcXVlc3RUb1JlcXVlc3RMaXN0KHJlcXVlc3RJZCwgbnVsbCwgYXNzZXRLZXkpKTtcbiAgLy8gaXMgdGhpcyBhbiBleGlzdGluZyBhc3NldD9cbiAgLy8gSWYgdGhpcyBhc3NldCBpcyBpbiB0aGUgYXNzZXQgbGlzdCwgaXQncyBhbHJlYWR5IGJlZW4gZmV0Y2hlZFxuICBpZiAoc3RhdGUuYXNzZXRMaXN0W2Fzc2V0S2V5XSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIC8vIGdldCBzaG9ydCBJZFxuICBsZXQgc2hvcnRJZDtcbiAgdHJ5IHtcbiAgICAoe2RhdGE6IHNob3J0SWR9ID0geWllbGQgY2FsbChnZXRTaG9ydElkLCBob3N0LCBuYW1lLCBsb25nSWQpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyBnZXQgYXNzZXQgY2xhaW0gZGF0YVxuICBsZXQgY2xhaW1EYXRhO1xuICB0cnkge1xuICAgICh7ZGF0YTogY2xhaW1EYXRhfSA9IHlpZWxkIGNhbGwoZ2V0Q2xhaW1EYXRhLCBob3N0LCBuYW1lLCBsb25nSWQpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyBhZGQgYXNzZXQgdG8gYXNzZXQgbGlzdFxuICB5aWVsZCBwdXQoYWRkQXNzZXRUb0Fzc2V0TGlzdChhc3NldEtleSwgbnVsbCwgbmFtZSwgbG9uZ0lkLCBzaG9ydElkLCBjbGFpbURhdGEpKTtcbiAgLy8gY2xlYXIgYW55IGVycm9ycyBpbiByZXF1ZXN0IGVycm9yXG4gIHlpZWxkIHB1dChvblJlcXVlc3RFcnJvcihudWxsKSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gKiB3YXRjaE5ld0Fzc2V0UmVxdWVzdCAoKSB7XG4gIHlpZWxkIHRha2VMYXRlc3QoYWN0aW9ucy5BU1NFVF9SRVFVRVNUX05FVywgbmV3QXNzZXRSZXF1ZXN0KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvc2FnYXMvc2hvd19hc3NldC5qcyIsImltcG9ydCBSZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9uZ0NsYWltSWQgKGhvc3QsIG5hbWUsIG1vZGlmaWVyKSB7XG4gIGxldCBib2R5ID0ge307XG4gIC8vIGNyZWF0ZSByZXF1ZXN0IHBhcmFtc1xuICBpZiAobW9kaWZpZXIpIHtcbiAgICBpZiAobW9kaWZpZXIuaWQpIHtcbiAgICAgIGJvZHlbJ2NsYWltSWQnXSA9IG1vZGlmaWVyLmlkO1xuICAgIH0gZWxzZSB7XG4gICAgICBib2R5WydjaGFubmVsTmFtZSddID0gbW9kaWZpZXIuY2hhbm5lbC5uYW1lO1xuICAgICAgYm9keVsnY2hhbm5lbENsYWltSWQnXSA9IG1vZGlmaWVyLmNoYW5uZWwuaWQ7XG4gICAgfVxuICB9XG4gIGJvZHlbJ2NsYWltTmFtZSddID0gbmFtZTtcbiAgY29uc3QgcGFyYW1zID0ge1xuICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICBib2R5ICAgOiBKU09OLnN0cmluZ2lmeShib2R5KSxcbiAgfTtcbiAgLy8gY3JlYXRlIHVybFxuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2xhaW0vbG9uZy1pZGA7XG4gIC8vIHJldHVybiB0aGUgcmVxdWVzdCBwcm9taXNlXG4gIHJldHVybiBSZXF1ZXN0KHVybCwgcGFyYW1zKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTaG9ydElkIChob3N0LCBuYW1lLCBjbGFpbUlkKSB7XG4gIGNvbnN0IHVybCA9IGAke2hvc3R9L2FwaS9jbGFpbS9zaG9ydC1pZC8ke2NsYWltSWR9LyR7bmFtZX1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENsYWltRGF0YSAoaG9zdCwgbmFtZSwgY2xhaW1JZCkge1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2xhaW0vZGF0YS8ke25hbWV9LyR7Y2xhaW1JZH1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9hcGkvYXNzZXRBcGkuanMiLCJpbXBvcnQge2NhbGwsIHB1dCwgc2VsZWN0LCB0YWtlTGF0ZXN0fSBmcm9tICdyZWR1eC1zYWdhL2VmZmVjdHMnO1xuaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvc2hvd19hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgYWRkTmV3Q2hhbm5lbFRvQ2hhbm5lbExpc3QsIGFkZFJlcXVlc3RUb1JlcXVlc3RMaXN0LCBvblJlcXVlc3RFcnJvciwgb25SZXF1ZXN0VXBkYXRlLCB1cGRhdGVDaGFubmVsQ2xhaW1zIH0gZnJvbSAnYWN0aW9ucy9zaG93JztcbmltcG9ydCB7IGdldENoYW5uZWxDbGFpbXMsIGdldENoYW5uZWxEYXRhIH0gZnJvbSAnYXBpL2NoYW5uZWxBcGknO1xuaW1wb3J0IHsgc2VsZWN0U2hvd1N0YXRlIH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuaW1wb3J0IHsgc2VsZWN0U2l0ZUhvc3QgfSBmcm9tICdzZWxlY3RvcnMvc2l0ZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiAqIG5ld0NoYW5uZWxSZXF1ZXN0IChhY3Rpb24pIHtcbiAgY29uc3QgeyByZXF1ZXN0VHlwZSwgcmVxdWVzdElkLCBjaGFubmVsTmFtZSwgY2hhbm5lbElkIH0gPSBhY3Rpb24uZGF0YTtcbiAgLy8gcHV0IGFuIGFjdGlvbiB0byB1cGRhdGUgdGhlIHJlcXVlc3QgaW4gcmVkdXhcbiAgeWllbGQgcHV0KG9uUmVxdWVzdFVwZGF0ZShyZXF1ZXN0VHlwZSwgcmVxdWVzdElkKSk7XG4gIC8vIGlzIHRoaXMgYW4gZXhpc3RpbmcgcmVxdWVzdD9cbiAgLy8gSWYgdGhpcyB1cmkgaXMgaW4gdGhlIHJlcXVlc3QgbGlzdCwgaXQncyBhbHJlYWR5IGJlZW4gZmV0Y2hlZFxuICBjb25zdCBzdGF0ZSA9IHlpZWxkIHNlbGVjdChzZWxlY3RTaG93U3RhdGUpO1xuICBjb25zdCBob3N0ID0geWllbGQgc2VsZWN0KHNlbGVjdFNpdGVIb3N0KTtcbiAgaWYgKHN0YXRlLnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBnZXQgY2hhbm5lbCBsb25nIGlkXG4gIGxldCBsb25nSWQsIHNob3J0SWQ7XG4gIHRyeSB7XG4gICAgKHsgZGF0YToge2xvbmdDaGFubmVsQ2xhaW1JZDogbG9uZ0lkLCBzaG9ydENoYW5uZWxDbGFpbUlkOiBzaG9ydElkfSB9ID0geWllbGQgY2FsbChnZXRDaGFubmVsRGF0YSwgaG9zdCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIHN0b3JlIHRoZSByZXF1ZXN0IGluIHRoZSBjaGFubmVsIHJlcXVlc3RzIGxpc3RcbiAgY29uc3QgY2hhbm5lbEtleSA9IGBjIyR7Y2hhbm5lbE5hbWV9IyR7bG9uZ0lkfWA7XG4gIHlpZWxkIHB1dChhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdChyZXF1ZXN0SWQsIG51bGwsIGNoYW5uZWxLZXkpKTtcbiAgLy8gaXMgdGhpcyBhbiBleGlzdGluZyBjaGFubmVsP1xuICAvLyBJZiB0aGlzIGNoYW5uZWwgaXMgaW4gdGhlIGNoYW5uZWwgbGlzdCwgaXQncyBhbHJlYWR5IGJlZW4gZmV0Y2hlZFxuICBpZiAoc3RhdGUuY2hhbm5lbExpc3RbY2hhbm5lbEtleV0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBnZXQgY2hhbm5lbCBjbGFpbXMgZGF0YVxuICBsZXQgY2xhaW1zRGF0YTtcbiAgdHJ5IHtcbiAgICAoeyBkYXRhOiBjbGFpbXNEYXRhIH0gPSB5aWVsZCBjYWxsKGdldENoYW5uZWxDbGFpbXMsIGhvc3QsIGxvbmdJZCwgY2hhbm5lbE5hbWUsIDEpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyBzdG9yZSB0aGUgY2hhbm5lbCBkYXRhIGluIHRoZSBjaGFubmVsIGxpc3RcbiAgeWllbGQgcHV0KGFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0KGNoYW5uZWxLZXksIGNoYW5uZWxOYW1lLCBzaG9ydElkLCBsb25nSWQsIGNsYWltc0RhdGEpKTtcbiAgLy8gY2xlYXIgYW55IHJlcXVlc3QgZXJyb3JzXG4gIHlpZWxkIHB1dChvblJlcXVlc3RFcnJvcihudWxsKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoTmV3Q2hhbm5lbFJlcXVlc3QgKCkge1xuICB5aWVsZCB0YWtlTGF0ZXN0KGFjdGlvbnMuQ0hBTk5FTF9SRVFVRVNUX05FVywgbmV3Q2hhbm5lbFJlcXVlc3QpO1xufTtcblxuZnVuY3Rpb24gKiBnZXROZXdDbGFpbXNBbmRVcGRhdGVDaGFubmVsIChhY3Rpb24pIHtcbiAgY29uc3QgeyBjaGFubmVsS2V5LCBuYW1lLCBsb25nSWQsIHBhZ2UgfSA9IGFjdGlvbi5kYXRhO1xuICBjb25zdCBob3N0ID0geWllbGQgc2VsZWN0KHNlbGVjdFNpdGVIb3N0KTtcbiAgbGV0IGNsYWltc0RhdGE7XG4gIHRyeSB7XG4gICAgKHsgZGF0YTogY2xhaW1zRGF0YSB9ID0geWllbGQgY2FsbChnZXRDaGFubmVsQ2xhaW1zLCBob3N0LCBsb25nSWQsIG5hbWUsIHBhZ2UpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICB5aWVsZCBwdXQodXBkYXRlQ2hhbm5lbENsYWltcyhjaGFubmVsS2V5LCBjbGFpbXNEYXRhKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoVXBkYXRlQ2hhbm5lbENsYWltcyAoKSB7XG4gIHlpZWxkIHRha2VMYXRlc3QoYWN0aW9ucy5DSEFOTkVMX0NMQUlNU19VUERBVEVfQVNZTkMsIGdldE5ld0NsYWltc0FuZFVwZGF0ZUNoYW5uZWwpO1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NhZ2FzL3Nob3dfY2hhbm5lbC5qcyIsImltcG9ydCBSZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2hhbm5lbERhdGEgKGhvc3QsIGlkLCBuYW1lKSB7XG4gIGlmICghaWQpIGlkID0gJ25vbmUnO1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2hhbm5lbC9kYXRhLyR7bmFtZX0vJHtpZH1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYW5uZWxDbGFpbXMgKGhvc3QsIGxvbmdJZCwgbmFtZSwgcGFnZSkge1xuICBpZiAoIXBhZ2UpIHBhZ2UgPSAxO1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2hhbm5lbC9jbGFpbXMvJHtuYW1lfS8ke2xvbmdJZH0vJHtwYWdlfWA7XG4gIHJldHVybiBSZXF1ZXN0KHVybCk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2FwaS9jaGFubmVsQXBpLmpzIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIFJFR0VYUF9JTlZBTElEX0NMQUlNICA6IC9bXkEtWmEtejAtOS1dL2csXG4gIFJFR0VYUF9JTlZBTElEX0NIQU5ORUw6IC9bXkEtWmEtejAtOS1AXS9nLFxuICBSRUdFWFBfQUREUkVTUyAgICAgICAgOiAvXmIoPz1bXjBPSWxdezMyLDMzfSlbMC05QS1aYS16XXszMiwzM30kLyxcbiAgQ0hBTk5FTF9DSEFSICAgICAgICAgIDogJ0AnLFxuICBwYXJzZUlkZW50aWZpZXIgICAgICAgOiBmdW5jdGlvbiAoaWRlbnRpZmllcikge1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjL10qKScgKyAvLyB2YWx1ZSAoc3RvcHMgYXQgdGhlIGZpcnN0IHNlcGFyYXRvciBvciBlbmQpXG4gICAgICAnKFs6JCNdPykoW14vXSopJyAvLyBtb2RpZmllciBzZXBhcmF0b3IsIG1vZGlmaWVyIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCB2YWx1ZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleCAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgLmV4ZWMoaWRlbnRpZmllcilcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIFVSTC4gIE5vIGNoYW5uZWwgbmFtZSBwcm92aWRlZCBiZWZvcmUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IGlzQ2hhbm5lbCA9IHZhbHVlLnN0YXJ0c1dpdGgobW9kdWxlLmV4cG9ydHMuQ0hBTk5FTF9DSEFSKTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGlzQ2hhbm5lbCA/IHZhbHVlIDogbnVsbDtcbiAgICBsZXQgY2xhaW1JZDtcbiAgICBpZiAoaXNDaGFubmVsKSB7XG4gICAgICBpZiAoIWNoYW5uZWxOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2hlY2sgeW91ciBVUkwuICBObyBjaGFubmVsIG5hbWUgYWZ0ZXIgXCJAXCIuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2hhbm5lbE5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NIQU5ORUwpO1xuICAgICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgSW52YWxpZCBjaGFyYWN0ZXJzIGluIGNoYW5uZWwgbmFtZTogXCIke25hbWVCYWRDaGFycy5qb2luKCcsICcpfVwiLmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjbGFpbUlkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciBVUkwuICBObyBtb2RpZmllciBwcm92aWRlZCBhZnRlciBzZXBhcmF0b3IgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RpZmllclNlcGVyYXRvciA9PT0gJzonKSB7XG4gICAgICAgIGNoYW5uZWxDbGFpbUlkID0gbW9kaWZpZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgVGhlIFwiJHttb2RpZmllclNlcGVyYXRvcn1cIiBtb2RpZmllciBpcyBub3QgY3VycmVudGx5IHN1cHBvcnRlZGApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaXNDaGFubmVsLFxuICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICBjaGFubmVsQ2xhaW1JZDogY2hhbm5lbENsYWltSWQgfHwgbnVsbCxcbiAgICAgIGNsYWltSWQgICAgICAgOiBjbGFpbUlkIHx8IG51bGwsXG4gICAgfTtcbiAgfSxcbiAgcGFyc2VDbGFpbTogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBjb25zdCBjb21wb25lbnRzUmVnZXggPSBuZXcgUmVnRXhwKFxuICAgICAgJyhbXjokIy8uXSopJyArIC8vIG5hbWUgKHN0b3BzIGF0IHRoZSBmaXJzdCBleHRlbnNpb24pXG4gICAgICAnKFs6JCMuXT8pKFteL10qKScgLy8gZXh0ZW5zaW9uIHNlcGFyYXRvciwgZXh0ZW5zaW9uIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCBjbGFpbU5hbWUsIGV4dGVuc2lvblNlcGVyYXRvciwgZXh0ZW5zaW9uXSA9IGNvbXBvbmVudHNSZWdleCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICAuZXhlYyhuYW1lKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG5hbWVcbiAgICBpZiAoIWNsYWltTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGVjayB5b3VyIFVSTC4gIE5vIGNsYWltIG5hbWUgcHJvdmlkZWQgYmVmb3JlIFwiLlwiJyk7XG4gICAgfVxuICAgIGNvbnN0IG5hbWVCYWRDaGFycyA9IChjbGFpbU5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NMQUlNKTtcbiAgICBpZiAobmFtZUJhZENoYXJzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgSW52YWxpZCBjaGFyYWN0ZXJzIGluIGNsYWltIG5hbWU6IFwiJHtuYW1lQmFkQ2hhcnMuam9pbignLCAnKX1cIi5gKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgZXh0ZW5zaW9uXG4gICAgaWYgKGV4dGVuc2lvblNlcGVyYXRvcikge1xuICAgICAgaWYgKCFleHRlbnNpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIFVSTC4gIE5vIGZpbGUgZXh0ZW5zaW9uIHByb3ZpZGVkIGFmdGVyIHNlcGFyYXRvciBcIiR7ZXh0ZW5zaW9uU2VwZXJhdG9yfVwiLmApO1xuICAgICAgfVxuICAgICAgaWYgKGV4dGVuc2lvblNlcGVyYXRvciAhPT0gJy4nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciBVUkwuICBUaGUgXCIke2V4dGVuc2lvblNlcGVyYXRvcn1cIiBzZXBhcmF0b3IgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY2xhaW0gbmFtZS5gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYWltTmFtZSxcbiAgICAgIGV4dGVuc2lvbjogZXh0ZW5zaW9uIHx8IG51bGwsXG4gICAgfTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvbGJyeVVyaS5qcyIsImNvbnN0IGhhbmRsZVBhZ2VSZW5kZXIgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gYXBwID0+IHtcbiAgLy8gYSBjYXRjaC1hbGwgcm91dGUgaWYgc29tZW9uZSB2aXNpdHMgYSBwYWdlIHRoYXQgZG9lcyBub3QgZXhpc3RcbiAgYXBwLnVzZSgnKicsIChyZXEsIHJlcykgPT4ge1xuICAgIC8vIHNlbmQgcmVzcG9uc2VcbiAgICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbiAgfSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9mYWxsYmFjay1yb3V0ZXMuanMiXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/index.js.map b/index.js.map new file mode 100644 index 00000000..a44c415d --- /dev/null +++ b/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///index.js","webpack:///webpack/bootstrap e7360edfffe873533ea7","webpack:///external \"react\"","webpack:///external \"react-redux\"","webpack:///external \"winston\"","webpack:///external \"react-router-dom\"","webpack:///./client/actions/publish.js","webpack:///./config/siteConfig.js","webpack:///./server/models/index.js","webpack:///./client/containers/NavBar/index.js","webpack:///./client/actions/show.js","webpack:///./client/components/SEO/index.js","webpack:///external \"prop-types\"","webpack:///./client/utils/request.js","webpack:///./client/constants/show_action_types.js","webpack:///./client/selectors/show.js","webpack:///external \"react-helmet\"","webpack:///external \"redux-saga/effects\"","webpack:///./server/helpers/lbryApi.js","webpack:///./server/helpers/googleAnalytics.js","webpack:///external \"redux\"","webpack:///./client/actions/channel.js","webpack:///./client/components/ProgressBar/index.jsx","webpack:///./client/pages/ErrorPage/index.jsx","webpack:///external \"passport\"","webpack:///external \"passport-local\"","webpack:///external \"sequelize\"","webpack:///./server/helpers/sequelizeHelpers.js","webpack:///./server/helpers/publishHelpers.js","webpack:///./server/helpers/errorHandlers.js","webpack:///./server/controllers/serveController.js","webpack:///./server/helpers/handlePageRender.jsx","webpack:///external \"react-dom/server\"","webpack:///./client/reducers/index.js","webpack:///./client/constants/publish_action_types.js","webpack:///./client/constants/publish_channel_select_states.js","webpack:///./client/constants/channel_action_types.js","webpack:///./client/constants/asset_display_states.js","webpack:///./client/components/GAListener/index.jsx","webpack:///./client/app.jsx","webpack:///./client/containers/Dropzone/index.js","webpack:///./client/containers/ChannelLoginForm/index.js","webpack:///./client/containers/ChannelCreateForm/index.js","webpack:///./client/constants/show_request_types.js","webpack:///./client/containers/AssetDisplay/index.js","webpack:///./server/helpers/renderFullPage.js","webpack:///./client/selectors/site.js","webpack:///external \"babel-polyfill\"","webpack:///external \"whatwg-fetch\"","webpack:///./server/server.js","webpack:///external \"express\"","webpack:///external \"body-parser\"","webpack:///external \"express-handlebars\"","webpack:///external \"handlebars\"","webpack:///external \"helmet\"","webpack:///./server/helpers/authHelpers.js","webpack:///external \"cookie-session\"","webpack:///external \"http\"","webpack:///./server/passport/local-signup.js","webpack:///external \"axios\"","webpack:///./config/lbryConfig.js","webpack:///external \"universal-analytics\"","webpack:///./config/mysqlConfig.js","webpack:///./server/models/certificate.js","webpack:///./server/models/channel.js","webpack:///./server/models/claim.js","webpack:///./server/models/file.js","webpack:///./server/models/request.js","webpack:///./server/models/user.js","webpack:///external \"bcrypt\"","webpack:///./server/passport/local-login.js","webpack:///./server/routes/auth-routes.js","webpack:///./server/routes/api-routes.js","webpack:///external \"connect-multiparty\"","webpack:///./server/controllers/publishController.js","webpack:///external \"fs\"","webpack:///./server/auth/authentication.js","webpack:///./server/helpers/channelPagination.js","webpack:///./server/routes/page-routes.js","webpack:///./client/reducers/publish.js","webpack:///./client/reducers/channel.js","webpack:///./client/reducers/show.js","webpack:///./client/reducers/site.js","webpack:///external \"react-ga\"","webpack:///./client/pages/HomePage/index.jsx","webpack:///./client/components/SEO/view.jsx","webpack:///./client/utils/pageTitle.js","webpack:///./client/utils/metaTags.js","webpack:///./client/utils/canonicalLink.js","webpack:///./client/containers/NavBar/view.jsx","webpack:///./client/components/Logo/index.jsx","webpack:///./client/components/NavBarChannelOptionsDropdown/index.jsx","webpack:///external \"cross-fetch/polyfill\"","webpack:///./client/containers/PublishTool/index.js","webpack:///./client/containers/PublishTool/view.jsx","webpack:///./client/containers/Dropzone/view.jsx","webpack:///./client/utils/file.js","webpack:///./client/components/PublishPreview/index.jsx","webpack:///./client/containers/PublishDetails/index.js","webpack:///./client/containers/PublishDetails/view.jsx","webpack:///./client/containers/PublishTitleInput/index.js","webpack:///./client/containers/PublishTitleInput/view.jsx","webpack:///./client/containers/PublishUrlInput/index.js","webpack:///./client/containers/PublishUrlInput/view.jsx","webpack:///./client/components/PublishUrlMiddleDisplay/index.jsx","webpack:///./client/containers/PublishThumbnailInput/index.js","webpack:///./client/containers/PublishThumbnailInput/view.jsx","webpack:///./client/containers/PublishMetadataInputs/index.js","webpack:///./client/containers/PublishMetadataInputs/view.jsx","webpack:///./client/components/ExpandingTextArea/index.jsx","webpack:///./client/containers/ChannelSelect/index.js","webpack:///./client/containers/ChannelSelect/view.jsx","webpack:///./client/containers/ChannelLoginForm/view.jsx","webpack:///./client/containers/ChannelCreateForm/view.jsx","webpack:///./client/components/ActiveStatusBar/index.jsx","webpack:///./client/components/InactiveStatusBar/index.jsx","webpack:///./client/containers/PublishStatus/index.js","webpack:///./client/containers/PublishStatus/view.jsx","webpack:///./client/constants/publish_claim_states.js","webpack:///./client/containers/PublishDisabledMessage/index.js","webpack:///./client/containers/PublishDisabledMessage/view.jsx","webpack:///./client/pages/AboutPage/index.jsx","webpack:///./client/pages/LoginPage/index.js","webpack:///./client/pages/LoginPage/view.jsx","webpack:///./client/pages/ShowPage/index.js","webpack:///./client/pages/ShowPage/view.jsx","webpack:///./client/containers/ShowAssetLite/index.js","webpack:///./client/containers/ShowAssetLite/view.jsx","webpack:///./client/containers/AssetDisplay/view.jsx","webpack:///./client/containers/ShowAssetDetails/index.js","webpack:///./client/containers/ShowAssetDetails/view.jsx","webpack:///./client/containers/AssetTitle/index.js","webpack:///./client/containers/AssetTitle/view.jsx","webpack:///./client/containers/AssetInfo/index.js","webpack:///./client/containers/AssetInfo/view.jsx","webpack:///./client/containers/ShowChannel/index.js","webpack:///./client/containers/ShowChannel/view.jsx","webpack:///./client/containers/ChannelClaimsDisplay/index.js","webpack:///./client/containers/ChannelClaimsDisplay/view.jsx","webpack:///./client/components/AssetPreview/index.js","webpack:///./client/components/AssetPreview/view.jsx","webpack:///./client/containers/FourOhFourPage/index.jsx","webpack:///./client/containers/FourOhFourPage/view.jsx","webpack:///./server/routes/asset-routes.js","webpack:///./server/helpers/serveHelpers.js","webpack:///./server/helpers/lbryUri.js","webpack:///./server/helpers/handleShowRender.jsx","webpack:///external \"redux-saga\"","webpack:///./client/sagas/show_uri.js","webpack:///./client/sagas/show_asset.js","webpack:///./client/api/assetApi.js","webpack:///./client/sagas/show_channel.js","webpack:///./client/api/channelApi.js","webpack:///./client/utils/lbryUri.js","webpack:///./server/routes/fallback-routes.js","webpack:///./server/helpers/configureLogger.js","webpack:///./config/loggerConfig.js","webpack:///./server/helpers/configureSlack.js","webpack:///external \"winston-slack-webhook\"","webpack:///./config/slackConfig.js"],"names":["module","exports","modules","__webpack_require__","moduleId","installedModules","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","require","selectFile","file","type","actions","FILE_SELECTED","data","clearFile","FILE_CLEAR","updateMetadata","value","METADATA_UPDATE","updateClaim","CLAIM_UPDATE","setPublishInChannel","channel","SET_PUBLISH_IN_CHANNEL","updatePublishStatus","status","message","PUBLISH_STATUS_UPDATE","updateError","ERROR_UPDATE","updateSelectedChannel","channelName","SELECTED_CHANNEL_UPDATE","toggleMetadataInputs","showMetadataInputs","TOGGLE_METADATA_INPUTS","onNewThumbnail","THUMBNAIL_NEW","startPublish","history","PUBLISH_START","_publish_action_types","obj","newObj","key","default","SiteConfig","this","analytics","googleId","assetDefaults","description","thumbnail","title","auth","sessionKey","details","host","port","twitter","publishing","additionalClaimAddresses","disabled","disabledMessage","primaryClaimAddress","thumbnailChannel","thumbnailChannelId","uploadDirectory","Sequelize","logger","console","log","_require","database","username","password","db","sequelize","dialect","dialectOptions","decimalNumbers","logging","pool","max","min","idle","acquire","authenticate","then","info","catch","err","error","Certificate","Channel","Claim","File","Request","User","import","keys","forEach","modelName","associate","upsert","Model","values","condition","tableName","findOne","where","debug","update","create","_reactRedux","_channel","_publish","_view","_view2","mapStateToProps","_ref","site","loggedInChannel","channelShortId","shortId","channelLongId","longId","siteDescription","mapDispatchToProps","dispatch","onChannelLogin","updateLoggedInChannel","onChannelLogout","connect","onHandleShowPageUri","params","HANDLE_SHOW_URI","onRequestError","REQUEST_ERROR","onNewChannelRequest","channelId","requestType","requestId","CHANNEL_REQUEST_NEW","onNewAssetRequest","id","extension","ASSET_REQUEST_NEW","modifier","onRequestUpdate","REQUEST_UPDATE","addRequestToRequestList","REQUEST_LIST_ADD","addAssetToAssetList","claimId","claimData","ASSET_ADD","addNewChannelToChannelList","claimsData","CHANNEL_ADD","onUpdateChannelClaims","channelKey","page","CHANNEL_CLAIMS_UPDATE_ASYNC","updateChannelClaims","channelListId","CHANNEL_CLAIMS_UPDATE_SUCCESS","fileRequested","FILE_REQUESTED","updateFileAvailability","FILE_AVAILABILITY_UPDATE","updateDisplayAssetError","DISPLAY_ASSET_ERROR","_show_action_types","_show_request_types","defaultDescription","defaultThumbnail","siteHost","siteTitle","siteTwitter","parseJSON","response","json","checkStatus","jsonResponse","Error","request","url","options","fetch","Promise","all","_ref2","_slicedToArray","sliceIterator","arr","_arr","_n","_d","_e","undefined","_s","_i","Symbol","iterator","next","done","push","length","Array","isArray","TypeError","selectAsset","show","requestList","assetKey","assetList","selectShowState","state","axios","_require$api","api","apiHost","apiPort","lbryApiUri","_require2","chooseGaLbrynetPublishLabel","sendGATimingEvent","handleLbrynetResponse","resolve","reject","result","JSON","stringify","publishClaim","publishParams","gaStartTime","Date","now","post","method","getClaim","uri","timeout","getClaimList","claimName","resolveUri","getDownloadDirectory","_ref3","download_directory","createChannel","channel_name","amount","createServeEventParams","headers","ip","originalUrl","eventCategory","eventAction","eventLabel","ipOverride","userAgentOverride","createPublishTimingEventParams","category","variable","label","startTime","endTime","userTimingCategory","userTimingVariableName","userTimingTime","userTimingLabel","sendGoogleAnalyticsEvent","visitorId","replace","ua","strictCidFormat","https","event","sendGoogleAnalyticsTiming","timing","sendGAServeEvent","channel_id","CHANNEL_UPDATE","_channel_action_types","_interopRequireDefault","_classCallCheck","instance","Constructor","_possibleConstructorReturn","self","ReferenceError","_inherits","subClass","superClass","constructor","writable","setPrototypeOf","__proto__","_createClass","defineProperties","target","props","descriptor","protoProps","staticProps","_react","_react2","_propTypes","_propTypes2","_ActiveStatusBar","_ActiveStatusBar2","_InactiveStatusBar","_InactiveStatusBar2","ProgressBar","_React$Component","_this","getPrototypeOf","bars","index","incrementer","createBars","bind","startProgressBar","updateProgressBar","stopProgressBar","size","isActive","setState","updateInterval","setInterval","clearInterval","createElement","map","bar","Component","propTypes","number","isRequired","_NavBar","_NavBar2","ErrorPage","apply","arguments","className","string","returnShortId","claimsArray","claimIndex","substring","shortIdLength","findIndex","element","possibleMatches","slice","filter","fs","parsePublishApiRequestBody","nsfw","license","exec","parsePublishApiRequestFiles","path","test","validateFileTypeAndSize","fileName","filePath","fileType","thumbnailFileName","thumbnailFilePath","thumbnailFileType","createBasicPublishParams","trim","file_path","bid","metadata","author","language","claim_address","createThumbnailPublishParams","deleteTemporaryFile","unlink","addGetResultsToFileData","fileInfo","getResult","file_name","download_path","createFileData","outpoint","height","address","contentType","handleErrorResponse","res","useObjectPropertiesIfNoKeys","_module$exports$retur","returnErrorMessageAndStatus","_module$exports$retur2","createErrorResponsePayload","code","newErrorObject","getOwnPropertyNames","success","returnPaginatedChannelClaims","getClaimId","channelClaimId","getClaimIdByChannel","getClaimIdByClaim","getLongClaimId","longClaimId","getLongChannelId","longChannelId","getClaimIdByLongChannelId","getChannelData","longChannelClaimId","getShortChannelIdFromLongChannelId","_ref4","shortChannelClaimId","getChannelClaims","getAllChannelClaims","_ref5","_ref6","channelClaimsArray","paginatedChannelViewData","getLocalFileRecord","dataValues","_server","_redux","_index","_index2","_reactRouterDom","_index3","_index4","_app","_app2","_renderFullPage","_renderFullPage2","_reactHelmet","_reactHelmet2","req","context","store","createStore","html","renderToString","Provider","StaticRouter","location","helmet","renderStatic","redirect","preloadedState","getState","send","_publish2","_channel2","_show","_show2","_site","_site2","combineReducers","publish","LOGIN","CREATE","LOCAL_CHECK","UNAVAILABLE","ERROR","AVAILABLE","_reactGa","_reactGa2","initialize","GAListener","sendPageView","listen","set","pathname","pageview","children","withRouter","_HomePage","_HomePage2","_AboutPage","_AboutPage2","_LoginPage","_LoginPage2","_ShowPage","_ShowPage2","_FourOhFourPage","_FourOhFourPage2","App","Switch","Route","exact","component","fileError","setFileError","CHANNEL","ASSET_LITE","ASSET_DETAILS","displayAsset","asset","onFileRequest","toString","meta","link","selectSiteState","selectSiteHost","express","bodyParser","expressHandlebars","Handlebars","passport","serializeSpeechUser","deserializeSpeechUser","cookieSession","http","PORT","app","enable","use","static","__dirname","urlencoded","extended","verbose","serializeUser","deserializeUser","localSignupStrategy","localLoginStrategy","maxAge","session","hbs","defaultLayout","handlebars","engine","server","Server","sync","user","PassportLocalStrategy","Strategy","lbryApi","usernameField","passwordField","userInfo","tx","userData","userName","channelData","claim_id","certificateData","newUser","newChannel","newCertificate","setChannel","setUser","shortChannelId","lbryConfig","MysqlConfig","STRING","BOOLEAN","INTEGER","TEXT","DECIMAL","define","claimSequence","decodedClaim","depth","effectiveAmount","hasSignature","hex","nout","txid","validAtHeight","valueVersion","claimType","certificateVersion","keyType","publicKey","freezeTableName","belongsTo","foreignKey","allowNull","findAll","order","getLongChannelIdFromShortChannelId","_this2","$like","getLongChannelIdFromChannelName","_this3","validateLongChannelId","_this4","hasOne","determineFileExtensionFromContentType","determineThumbnail","storedThumbnail","prepareClaimData","claim","certificateId","licenseUrl","preview","metadataVersion","source","sourceType","sourceVersion","streamVersion","getShortClaimIdFromLongClaimId","raw","getLongClaimIdFromShortClaimId","getTopFreeClaimIdByClaimName","_this5","validateLongClaimId","_this6","resolveClaim","_this7","claimArray","defaultValue","trendingEligible","hasMany","getRecentClaims","limit","action","ipAddress","bcrypt","comparePassword","compare","changePassword","newPassword","genSalt","saltError","salt","hash","hashError","hook","returnUserAndChannelInfo","userInstance","getChannel","isMatch","logIn","logout","multipart","multipartMiddleware","uploadDir","claimNameIsAvailable","checkChannelAvailability","_require3","_require4","errorHandlers","_require5","_require6","authenticateUser","_require7","availableName","body","claimsList","resolveResult","fileData","_ref7","_ref8","_ref9","_ref10","_ref10$","completed","_ref11","_ref12","resolvedUri","_ref13","files","channelPassword","_parsePublishApiReque","_parsePublishApiReque2","_ref14","_ref15","_ref15$","thumbnailPublishParams","lbryTx","_ref16","_ref17","_ref18","claimInfo","_ref19","_defineProperty","publishHelpers","_require$publishing","Op","publishResults","fileRecord","claimRecord","upsertCriteria","setClaim","setFile","claimAddresses","attributes","or","authenticateChannelCredentials","userPassword","channelFindParams","claims","totalPages","determineTotalPages","paginationPage","getPageFromQuery","extractPageFromClaims","previousPage","determinePreviousPage","currentPage","nextPage","determineNextPage","totalResults","determineTotalClaims","parseInt","pageNumber","claimStartIndex","claimEndIndex","totalClaims","fullPages","Math","floor","handlePageRender","render","layout","initialState","assign","publishInChannel","selectedChannel","_publish_channel_select_states","publishSubmit","channelList","_asset_display_states","siteConfig","googleAnalyticsId","_siteConfig$assetDefa","_siteConfig$details","_SEO","_SEO2","_PublishTool","_PublishTool2","HomePage","_pageTitle","_metaTags","_canonicalLink","SEO","_props","_props2","pageUri","pageTitle","createPageTitle","metaTags","createMetaTags","canonicalLink","createCanonicalLink","rel","href","determineOgThumbnailContentType","lastIndexOf","createBasicMetaTags","content","createChannelMetaTags","createAssetMetaTags","embedUrl","showUrl","fileExt","ogTitle","ogDescription","ogThumbnailContentType","ogThumbnail","createBasicCanonicalLink","createAssetCanonicalLink","_asset$claimData","createChannelCanonicalLink","_Logo","_Logo2","_NavBarChannelOptionsDropdown","_NavBarChannelOptionsDropdown2","_request","_request2","NavBar","checkForLoggedInUser","logoutUser","handleSelection","credentials","selectedOptions","NavLink","activeClassName","to","defaultSelection","VIEW","LOGOUT","Logo","version","x","y","viewBox","enableBackground","Link","transform","fontSize","fontFamily","fill","stroke","strokeWidth","strokeLinecap","NavBarChannelDropdown","onChange","_Dropzone","_Dropzone2","_PublishDetails","_PublishDetails2","_PublishStatus","_PublishStatus2","_PublishDisabledMessage","_PublishDisabledMessage2","PublishTool","_file","_PublishPreview","_PublishPreview2","Dropzone","dragOver","mouseOver","dimPreview","handleDrop","handleDragOver","handleDragEnd","handleDragEnter","handleDragLeave","handleMouseEnter","handleMouseLeave","handleClick","handleFileInput","chooseFile","preventDefault","dt","dataTransfer","items","kind","droppedFile","getAsFile","remove","clearData","document","getElementById","click","fileList","validateFile","accept","encType","onDrop","onDragOver","onDragEnd","onDragEnter","onDragLeave","onMouseEnter","onMouseLeave","onClick","PublishPreview","imgSource","setPreviewImageSource","newProps","setPreviewImageSourceFromFile","previewReader","FileReader","readAsDataURL","onloadend","src","alt","bool","_PublishTitleInput","_PublishTitleInput2","_PublishUrlInput","_PublishUrlInput2","_PublishThumbnailInput","_PublishThumbnailInput2","_PublishMetadataInputs","_PublishMetadataInputs2","_ChannelSelect","_ChannelSelect2","PublishDetails","onPublishSubmit","onMetadataChange","PublishTitleInput","handleInput","e","placeholder","loggedInChannelName","loggedInChannelShortId","urlError","onClaimChange","onUrlError","_PublishUrlMiddleDisplay","_PublishUrlMiddleDisplay2","PublishUrlInput","setClaimName","validateClaim","cleanseInput","input","fileNameWithoutEnding","cleanClaimName","UrlMiddle","dataURItoBlob","dataURI","byteString","atob","split","mimeString","ia","Uint8Array","charCodeAt","Blob","PublishThumbnailInput","videoSource","sliderMinRange","sliderMaxRange","sliderValue","handleVideoLoadedData","handleSliderChange","createThumbnail","setVideoSource","nextProps","dataUri","blob","URL","createObjectURL","duration","totalMinutes","totalSeconds","currentTime","video","canvas","width","videoWidth","videoHeight","getContext","drawImage","dataUrl","toDataURL","snapshot","_state","preload","muted","style","display","playsInline","onLoadedData","onSeeked","onToggleMetadataInputs","_ExpandingTextArea","_ExpandingTextArea2","PublishMetadataInputs","toggleShowInputs","handleSelect","checked","selectedOption","htmlFor","rows","maxLength","maxHeight","_objectWithoutProperties","indexOf","_extends","ExpandingTextarea","_Component","_handleChange","adjustTextarea","_ref$target","el","scrollHeight","rest","ref","func","channelError","onPublishInChannelChange","onChannelSelect","_ChannelLoginForm","_ChannelLoginForm2","_ChannelCreateForm","_ChannelCreateForm2","states","ChannelSelect","toggleAnonymousPublish","ChannelLoginForm","loginToChannel","Headers","Content-Type","_ProgressBar","_ProgressBar2","ChannelCreateForm","handleChannelInput","cleanseChannelInput","updateIsChannelAvailable","channelWithAtSymbol","checkIsPasswordProvided","checkIsChannelAvailable","makePublishChannelRequest","ActiveStatusBar","InactiveStatusBar","_publish_claim_states","publishStates","PublishStatus","LOAD_START","LOADING","PUBLISHING","SUCCESS","FAILED","PublishDisabledMessage","AboutPage","LoginPage","_ErrorPage","_ErrorPage2","_ShowAssetLite","_ShowAssetLite2","_ShowAssetDetails","_ShowAssetDetails2","_ShowChannel","_ShowChannel2","ShowPage","match","_AssetDisplay","_AssetDisplay2","ShowLite","AssetDisplay","_props$asset$claimDat","_props$asset$claimDat2","controls","poster","_AssetTitle","_AssetTitle2","_AssetInfo","_AssetInfo2","ShowAssetDetails","AssetTitle","AssetInfo","copyToClipboard","elementToCopy","dataset","elementtocopy","select","execCommand","_props$asset","hidden","readOnly","spellCheck","data-elementtocopy","download","previousRequest","_ChannelClaimsDisplay","_ChannelClaimsDisplay2","ShowChannel","_AssetPreview","_AssetPreview2","ChannelClaimsDisplay","showNextResultsPage","showPreviousResultsPage","showNewPage","_props$channel","_props$channel$claims","defaults","AssetPreview","_ref$claimData","directSourceLink","showUrlLink","_ref$site","FourOhForPage","determineResponseType","flipClaimNameAndIdForBackwardsCompatibility","logRequestData","getClaimIdAndServeAsset","lbryUri","handleShowRender","hasFileExtension","parseModifier","responseType","parseClaim","isChannel","_lbryUri$parseIdentif","parseIdentifier","identifier","_flipClaimNameAndIdFo","_flipClaimNameAndIdFo2","clientAcceptsHtml","requestIsFromBrowser","clientWantsAsset","range","imageIsWanted","videoIsWanted","isValidClaimId","isValidShortId","isValidShortIdOrClaimId","serveAssetToClient","NO_FILE","sendFileOptions","X-Content-Type-Options","sendFile","fullClaimId","tempName","REGEXP_INVALID_CLAIM","REGEXP_INVALID_CHANNEL","REGEXP_ADDRESS","CHANNEL_CHAR","componentsRegex","RegExp","_componentsRegex$exec","_componentsRegex$exec2","proto","modifierSeperator","startsWith","nameBadChars","join","_componentsRegex$exec3","_componentsRegex$exec4","_componentsRegex$exec5","_componentsRegex$exec6","_reduxSaga","_reduxSaga2","_effects","_show_uri","returnSagaWithParams","saga","regeneratorRuntime","mark","_callee","wrap","_context","prev","stop","sagaMiddleware","middleware","applyMiddleware","run","parseAndUpdateIdentifierAndClaim","_lbryUri$parseClaim","_lbryUri2","t0","put","abrupt","sent","_show_asset","newAssetRequest","_marked","parseAndUpdateClaimOnly","_lbryUri$parseIdentif2","_lbryUri$parseClaim2","_context2","_show_channel","newChannelRequest","t1","_marked2","handleShowPageUri","_action$data","_context3","_marked3","watchHandleShowPageUri","_context4","takeLatest","_marked4","_lbryUri","_assetApi","getShortId","getClaimData","t2","watchNewAssetRequest","_ref$data","_channelApi","watchNewChannelRequest","getNewClaimsAndUpdateChannel","_action$data2","watchUpdateChannelClaims","extensionSeperator","logLevel","winston","configure","transports","Console","level","timestamp","colorize","prettyPrint","handleExceptions","humanReadableUnhandledException","warn","silly","loggerConfig","winstonSlackWebHook","SlackWebHook","slackConfig","slackWebHook","slackErrorChannel","slackInfoChannel","add","webhookUrl","iconEmoji","SlackConfig"],"mappings":"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","file":"index.js","sourcesContent":["module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 45);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react\");\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-redux\");\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"winston\");\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-router-dom\");\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.selectFile = selectFile;\nexports.clearFile = clearFile;\nexports.updateMetadata = updateMetadata;\nexports.updateClaim = updateClaim;\nexports.setPublishInChannel = setPublishInChannel;\nexports.updatePublishStatus = updatePublishStatus;\nexports.updateError = updateError;\nexports.updateSelectedChannel = updateSelectedChannel;\nexports.toggleMetadataInputs = toggleMetadataInputs;\nexports.onNewThumbnail = onNewThumbnail;\nexports.startPublish = startPublish;\n\nvar _publish_action_types = __webpack_require__(32);\n\nvar actions = _interopRequireWildcard(_publish_action_types);\n\nfunction _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; } }\n\n// export action creators\nfunction selectFile(file) {\n return {\n type: actions.FILE_SELECTED,\n data: file\n };\n};\n\nfunction clearFile() {\n return {\n type: actions.FILE_CLEAR\n };\n};\n\nfunction updateMetadata(name, value) {\n return {\n type: actions.METADATA_UPDATE,\n data: {\n name: name,\n value: value\n }\n };\n};\n\nfunction updateClaim(value) {\n return {\n type: actions.CLAIM_UPDATE,\n data: value\n };\n};\n\nfunction setPublishInChannel(channel) {\n return {\n type: actions.SET_PUBLISH_IN_CHANNEL,\n channel: channel\n };\n};\n\nfunction updatePublishStatus(status, message) {\n return {\n type: actions.PUBLISH_STATUS_UPDATE,\n data: {\n status: status,\n message: message\n }\n };\n};\n\nfunction updateError(name, value) {\n return {\n type: actions.ERROR_UPDATE,\n data: {\n name: name,\n value: value\n }\n };\n};\n\nfunction updateSelectedChannel(channelName) {\n return {\n type: actions.SELECTED_CHANNEL_UPDATE,\n data: channelName\n };\n};\n\nfunction toggleMetadataInputs(showMetadataInputs) {\n return {\n type: actions.TOGGLE_METADATA_INPUTS,\n data: showMetadataInputs\n };\n};\n\nfunction onNewThumbnail(file) {\n return {\n type: actions.THUMBNAIL_NEW,\n data: file\n };\n};\n\nfunction startPublish(history) {\n return {\n type: actions.PUBLISH_START,\n data: { history: history }\n };\n}\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction SiteConfig() {\n this.analytics = {\n googleId: 'default'\n };\n this.assetDefaults = {\n description: 'An asset published on Spee.ch',\n thumbnail: 'https://spee.ch/assets/img/video_thumb_default.png',\n title: 'Spee.ch'\n };\n this.auth = {\n sessionKey: 'default'\n };\n this.details = {\n description: 'Open-source, decentralized image and video sharing.',\n host: 'default',\n port: 3000,\n title: 'Spee.ch',\n twitter: '@spee_ch'\n };\n this.publishing = {\n additionalClaimAddresses: [],\n disabled: false,\n disabledMessage: 'Please check back soon.',\n primaryClaimAddress: 'default',\n thumbnailChannel: 'default',\n thumbnailChannelId: 'default',\n uploadDirectory: '/home/lbry/Uploads'\n };\n};\n\nmodule.exports = new SiteConfig();\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar Sequelize = __webpack_require__(24);\nvar logger = __webpack_require__(2);\n\nconsole.log('exporting sequelize models');\n\nvar _require = __webpack_require__(61),\n database = _require.database,\n username = _require.username,\n password = _require.password;\n\nvar db = {};\n// set sequelize options\nvar sequelize = new Sequelize(database, username, password, {\n host: 'localhost',\n dialect: 'mysql',\n dialectOptions: { decimalNumbers: true }, // fix to ensure DECIMAL will not be stored as a string\n logging: false,\n pool: {\n max: 5,\n min: 0,\n idle: 10000,\n acquire: 10000\n }\n});\n\n// establish mysql connection\nsequelize.authenticate().then(function () {\n logger.info('Sequelize has established mysql connection successfully.');\n}).catch(function (err) {\n logger.error('Sequelize was unable to connect to the database:', err);\n});\n\n// manually add each model to the db object\nvar Certificate = __webpack_require__(62);\nvar Channel = __webpack_require__(63);\nvar Claim = __webpack_require__(64);\nvar File = __webpack_require__(65);\nvar Request = __webpack_require__(66);\nvar User = __webpack_require__(67);\ndb['Certificate'] = sequelize.import('Certificate', Certificate);\ndb['Channel'] = sequelize.import('Channel', Channel);\ndb['Claim'] = sequelize.import('Claim', Claim);\ndb['File'] = sequelize.import('File', File);\ndb['Request'] = sequelize.import('Request', Request);\ndb['User'] = sequelize.import('User', User);\n\n// run model.association for each model in the db object that has an association\nObject.keys(db).forEach(function (modelName) {\n if (db[modelName].associate) {\n logger.info('Associating model:', modelName);\n db[modelName].associate(db);\n }\n});\n\ndb.sequelize = sequelize;\ndb.Sequelize = Sequelize;\n\n// add an 'upsert' method to the db object\ndb.upsert = function (Model, values, condition, tableName) {\n return Model.findOne({\n where: condition\n }).then(function (obj) {\n if (obj) {\n // update\n logger.debug('updating record in db.' + tableName);\n return obj.update(values);\n } else {\n // insert\n logger.debug('creating record in db.' + tableName);\n return Model.create(values);\n }\n }).catch(function (error) {\n logger.error(tableName + '.upsert error', error);\n throw error;\n });\n};\n\nmodule.exports = db;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _channel = __webpack_require__(19);\n\nvar _publish = __webpack_require__(4);\n\nvar _view = __webpack_require__(88);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var channel = _ref.channel,\n site = _ref.site;\n\n return {\n channelName: channel.loggedInChannel.name,\n channelShortId: channel.loggedInChannel.shortId,\n channelLongId: channel.loggedInChannel.longId,\n siteDescription: site.description\n };\n};\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n onChannelLogin: function onChannelLogin(name, shortId, longId) {\n dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));\n dispatch((0, _publish.updateSelectedChannel)(name));\n },\n onChannelLogout: function onChannelLogout() {\n dispatch((0, _channel.updateLoggedInChannel)(null, null, null));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.onHandleShowPageUri = onHandleShowPageUri;\nexports.onRequestError = onRequestError;\nexports.onNewChannelRequest = onNewChannelRequest;\nexports.onNewAssetRequest = onNewAssetRequest;\nexports.onRequestUpdate = onRequestUpdate;\nexports.addRequestToRequestList = addRequestToRequestList;\nexports.addAssetToAssetList = addAssetToAssetList;\nexports.addNewChannelToChannelList = addNewChannelToChannelList;\nexports.onUpdateChannelClaims = onUpdateChannelClaims;\nexports.updateChannelClaims = updateChannelClaims;\nexports.fileRequested = fileRequested;\nexports.updateFileAvailability = updateFileAvailability;\nexports.updateDisplayAssetError = updateDisplayAssetError;\n\nvar _show_action_types = __webpack_require__(12);\n\nvar actions = _interopRequireWildcard(_show_action_types);\n\nvar _show_request_types = __webpack_require__(41);\n\nfunction _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; } }\n\n// basic request parsing\nfunction onHandleShowPageUri(params) {\n return {\n type: actions.HANDLE_SHOW_URI,\n data: params\n };\n};\n\nfunction onRequestError(error) {\n return {\n type: actions.REQUEST_ERROR,\n data: error\n };\n};\n\nfunction onNewChannelRequest(channelName, channelId) {\n var requestType = _show_request_types.CHANNEL;\n var requestId = 'cr#' + channelName + '#' + channelId;\n return {\n type: actions.CHANNEL_REQUEST_NEW,\n data: { requestType: requestType, requestId: requestId, channelName: channelName, channelId: channelId }\n };\n};\n\nfunction onNewAssetRequest(name, id, channelName, channelId, extension) {\n var requestType = extension ? _show_request_types.ASSET_LITE : _show_request_types.ASSET_DETAILS;\n var requestId = 'ar#' + name + '#' + id + '#' + channelName + '#' + channelId;\n return {\n type: actions.ASSET_REQUEST_NEW,\n data: {\n requestType: requestType,\n requestId: requestId,\n name: name,\n modifier: {\n id: id,\n channel: {\n name: channelName,\n id: channelId\n }\n }\n }\n };\n};\n\nfunction onRequestUpdate(requestType, requestId) {\n return {\n type: actions.REQUEST_UPDATE,\n data: {\n requestType: requestType,\n requestId: requestId\n }\n };\n};\n\nfunction addRequestToRequestList(id, error, key) {\n return {\n type: actions.REQUEST_LIST_ADD,\n data: { id: id, error: error, key: key }\n };\n};\n\n// asset actions\n\nfunction addAssetToAssetList(id, error, name, claimId, shortId, claimData) {\n return {\n type: actions.ASSET_ADD,\n data: { id: id, error: error, name: name, claimId: claimId, shortId: shortId, claimData: claimData }\n };\n}\n\n// channel actions\n\nfunction addNewChannelToChannelList(id, name, shortId, longId, claimsData) {\n return {\n type: actions.CHANNEL_ADD,\n data: { id: id, name: name, shortId: shortId, longId: longId, claimsData: claimsData }\n };\n};\n\nfunction onUpdateChannelClaims(channelKey, name, longId, page) {\n return {\n type: actions.CHANNEL_CLAIMS_UPDATE_ASYNC,\n data: { channelKey: channelKey, name: name, longId: longId, page: page }\n };\n};\n\nfunction updateChannelClaims(channelListId, claimsData) {\n return {\n type: actions.CHANNEL_CLAIMS_UPDATE_SUCCESS,\n data: { channelListId: channelListId, claimsData: claimsData }\n };\n};\n\n// display a file\n\nfunction fileRequested(name, claimId) {\n return {\n type: actions.FILE_REQUESTED,\n data: { name: name, claimId: claimId }\n };\n};\n\nfunction updateFileAvailability(status) {\n return {\n type: actions.FILE_AVAILABILITY_UPDATE,\n data: status\n };\n};\n\nfunction updateDisplayAssetError(error) {\n return {\n type: actions.DISPLAY_ASSET_ERROR,\n data: error\n };\n};\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(84);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var site = _ref.site;\n var defaultDescription = site.defaultDescription,\n defaultThumbnail = site.defaultThumbnail,\n siteDescription = site.description,\n siteHost = site.host,\n siteTitle = site.title,\n siteTwitter = site.twitter;\n\n return {\n defaultDescription: defaultDescription,\n defaultThumbnail: defaultThumbnail,\n siteDescription: siteDescription,\n siteHost: siteHost,\n siteTitle: siteTitle,\n siteTwitter: siteTwitter\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"prop-types\");\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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\"); } }; }();\n\nexports.default = request;\n\n__webpack_require__(91);\n\n/**\n * Parses the JSON returned by a network request\n *\n * @param {object} response A response from a network request\n *\n * @return {object} The parsed JSON from the request\n */\nfunction parseJSON(response) {\n if (response.status === 204 || response.status === 205) {\n return null;\n }\n return response.json();\n}\n\n/**\n * Parses the status returned by a network request\n *\n * @param {object} response A response from a network request\n * @param {object} response The parsed JSON from the network request\n *\n * @return {object | undefined} Returns object with status and statusText, or undefined\n */\nfunction checkStatus(response, jsonResponse) {\n if (response.status >= 200 && response.status < 300) {\n return jsonResponse;\n }\n var error = new Error(jsonResponse.message);\n error.response = response;\n throw error;\n}\n\n/**\n * Requests a URL, returning a promise\n *\n * @param {string} url The URL we want to request\n * @param {object} [options] The options we want to pass to \"fetch\"\n *\n * @return {object} The response data\n */\n\nfunction request(url, options) {\n return fetch(url, options).then(function (response) {\n return Promise.all([response, parseJSON(response)]);\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n response = _ref2[0],\n jsonResponse = _ref2[1];\n\n return checkStatus(response, jsonResponse);\n });\n}\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n// request actions\nvar HANDLE_SHOW_URI = exports.HANDLE_SHOW_URI = 'HANDLE_SHOW_URI';\nvar REQUEST_ERROR = exports.REQUEST_ERROR = 'REQUEST_ERROR';\nvar REQUEST_UPDATE = exports.REQUEST_UPDATE = 'REQUEST_UPDATE';\nvar ASSET_REQUEST_NEW = exports.ASSET_REQUEST_NEW = 'ASSET_REQUEST_NEW';\nvar CHANNEL_REQUEST_NEW = exports.CHANNEL_REQUEST_NEW = 'CHANNEL_REQUEST_NEW';\nvar REQUEST_LIST_ADD = exports.REQUEST_LIST_ADD = 'REQUEST_LIST_ADD';\n\n// asset actions\nvar ASSET_ADD = exports.ASSET_ADD = 'ASSET_ADD';\n\n// channel actions\nvar CHANNEL_ADD = exports.CHANNEL_ADD = 'CHANNEL_ADD';\n\nvar CHANNEL_CLAIMS_UPDATE_ASYNC = exports.CHANNEL_CLAIMS_UPDATE_ASYNC = 'CHANNEL_CLAIMS_UPDATE_ASYNC';\nvar CHANNEL_CLAIMS_UPDATE_SUCCESS = exports.CHANNEL_CLAIMS_UPDATE_SUCCESS = 'CHANNEL_CLAIMS_UPDATE_SUCCESS';\n\n// asset/file display actions\nvar FILE_REQUESTED = exports.FILE_REQUESTED = 'FILE_REQUESTED';\nvar FILE_AVAILABILITY_UPDATE = exports.FILE_AVAILABILITY_UPDATE = 'FILE_AVAILABILITY_UPDATE';\nvar DISPLAY_ASSET_ERROR = exports.DISPLAY_ASSET_ERROR = 'DISPLAY_ASSET_ERROR';\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar selectAsset = exports.selectAsset = function selectAsset(show) {\n var request = show.requestList[show.request.id];\n var assetKey = request.key;\n return show.assetList[assetKey];\n};\n\nvar selectShowState = exports.selectShowState = function selectShowState(state) {\n return state.show;\n};\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-helmet\");\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"redux-saga/effects\");\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar axios = __webpack_require__(58);\nvar logger = __webpack_require__(2);\n\nvar _require = __webpack_require__(59),\n _require$api = _require.api,\n apiHost = _require$api.apiHost,\n apiPort = _require$api.apiPort;\n\nvar lbryApiUri = 'http://' + apiHost + ':' + apiPort;\n\nvar _require2 = __webpack_require__(17),\n chooseGaLbrynetPublishLabel = _require2.chooseGaLbrynetPublishLabel,\n sendGATimingEvent = _require2.sendGATimingEvent;\n\nvar handleLbrynetResponse = function handleLbrynetResponse(_ref, resolve, reject) {\n var data = _ref.data;\n\n logger.debug('lbry api data:', data);\n if (data.result) {\n // check for an error\n if (data.result.error) {\n logger.debug('Lbrynet api error:', data.result.error);\n reject(new Error(data.result.error));\n return;\n };\n resolve(data.result);\n return;\n }\n // fallback in case it just timed out\n reject(JSON.stringify(data));\n};\n\nmodule.exports = {\n publishClaim: function publishClaim(publishParams) {\n logger.debug('lbryApi >> Publishing claim to \"' + publishParams.name + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'publish',\n params: publishParams\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaim: function getClaim(uri) {\n logger.debug('lbryApi >> Getting Claim for \"' + uri + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'get',\n params: { uri: uri, timeout: 20 }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaimList: function getClaimList(claimName) {\n logger.debug('lbryApi >> Getting claim_list for \"' + claimName + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'claim_list',\n params: { name: claimName }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n resolveUri: function resolveUri(uri) {\n logger.debug('lbryApi >> Resolving URI for \"' + uri + '\"');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'resolve',\n params: { uri: uri }\n }).then(function (_ref2) {\n var data = _ref2.data;\n\n sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now());\n if (data.result[uri].error) {\n // check for errors\n reject(data.result[uri].error);\n } else {\n // if no errors, resolve\n resolve(data.result[uri]);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getDownloadDirectory: function getDownloadDirectory() {\n logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'settings_get'\n }).then(function (_ref3) {\n var data = _ref3.data;\n\n sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now());\n if (data.result) {\n resolve(data.result.download_directory);\n } else {\n return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.');\n }\n }).catch(function (error) {\n logger.error('Lbrynet Error:', error);\n resolve('/home/lbry/Downloads/');\n });\n });\n },\n createChannel: function createChannel(name) {\n logger.debug('lbryApi >> Creating channel for ' + name + '...');\n var gaStartTime = Date.now();\n return new Promise(function (resolve, reject) {\n axios.post(lbryApiUri, {\n method: 'channel_new',\n params: {\n channel_name: name,\n amount: 0.1\n }\n }).then(function (response) {\n sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n }).catch(function (error) {\n reject(error);\n });\n });\n }\n};\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(2);\nvar ua = __webpack_require__(60);\n\nvar _require = __webpack_require__(5),\n googleId = _require.analytics.googleId,\n title = _require.details.title;\n\nfunction createServeEventParams(headers, ip, originalUrl) {\n return {\n eventCategory: 'client requests',\n eventAction: 'serve request',\n eventLabel: originalUrl,\n ipOverride: ip,\n userAgentOverride: headers['user-agent']\n };\n};\n\nfunction createPublishTimingEventParams(category, variable, label, startTime, endTime) {\n var duration = endTime - startTime;\n return {\n userTimingCategory: category,\n userTimingVariableName: variable,\n userTimingTime: duration,\n userTimingLabel: label\n };\n};\n\nfunction sendGoogleAnalyticsEvent(ip, params) {\n var visitorId = ip.replace(/\\./g, '-');\n var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.event(params, function (err) {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n });\n};\n\nfunction sendGoogleAnalyticsTiming(visitorId, params) {\n var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.timing(params, function (err) {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n logger.debug('Timing event successfully sent to google analytics');\n });\n};\n\nmodule.exports = {\n sendGAServeEvent: function sendGAServeEvent(headers, ip, originalUrl) {\n var params = createServeEventParams(headers, ip, originalUrl);\n sendGoogleAnalyticsEvent(ip, params);\n },\n sendGATimingEvent: function sendGATimingEvent(category, variable, label, startTime, endTime) {\n var params = createPublishTimingEventParams(category, variable, label, startTime, endTime);\n sendGoogleAnalyticsTiming(title, params);\n },\n chooseGaLbrynetPublishLabel: function chooseGaLbrynetPublishLabel(_ref) {\n var channelName = _ref.channel_name,\n channelId = _ref.channel_id;\n\n return channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM';\n }\n};\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"redux\");\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.updateLoggedInChannel = updateLoggedInChannel;\n\nvar _channel_action_types = __webpack_require__(34);\n\nvar actions = _interopRequireWildcard(_channel_action_types);\n\nfunction _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; } }\n\n// export action creators\n\nfunction updateLoggedInChannel(name, shortId, longId) {\n return {\n type: actions.CHANNEL_UPDATE,\n data: {\n name: name,\n shortId: shortId,\n longId: longId\n }\n };\n};\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _propTypes = __webpack_require__(10);\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nvar _ActiveStatusBar = __webpack_require__(113);\n\nvar _ActiveStatusBar2 = _interopRequireDefault(_ActiveStatusBar);\n\nvar _InactiveStatusBar = __webpack_require__(114);\n\nvar _InactiveStatusBar2 = _interopRequireDefault(_InactiveStatusBar);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ProgressBar = function (_React$Component) {\n _inherits(ProgressBar, _React$Component);\n\n function ProgressBar(props) {\n _classCallCheck(this, ProgressBar);\n\n var _this = _possibleConstructorReturn(this, (ProgressBar.__proto__ || Object.getPrototypeOf(ProgressBar)).call(this, props));\n\n _this.state = {\n bars: [],\n index: 0,\n incrementer: 1\n };\n _this.createBars = _this.createBars.bind(_this);\n _this.startProgressBar = _this.startProgressBar.bind(_this);\n _this.updateProgressBar = _this.updateProgressBar.bind(_this);\n _this.stopProgressBar = _this.stopProgressBar.bind(_this);\n return _this;\n }\n\n _createClass(ProgressBar, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n this.createBars();\n this.startProgressBar();\n }\n }, {\n key: 'componentWillUnmount',\n value: function componentWillUnmount() {\n this.stopProgressBar();\n }\n }, {\n key: 'createBars',\n value: function createBars() {\n var bars = [];\n for (var i = 0; i <= this.props.size; i++) {\n bars.push({ isActive: false });\n }\n this.setState({ bars: bars });\n }\n }, {\n key: 'startProgressBar',\n value: function startProgressBar() {\n this.updateInterval = setInterval(this.updateProgressBar.bind(this), 300);\n }\n }, {\n key: 'updateProgressBar',\n value: function updateProgressBar() {\n var index = this.state.index;\n var incrementer = this.state.incrementer;\n var bars = this.state.bars;\n // flip incrementer if necessary, to stay in bounds\n if (index < 0 || index > this.props.size) {\n incrementer = incrementer * -1;\n index += incrementer;\n }\n // update the indexed bar\n if (incrementer > 0) {\n bars[index].isActive = true;\n } else {\n bars[index].isActive = false;\n };\n // increment index\n index += incrementer;\n // update state\n this.setState({\n bars: bars,\n incrementer: incrementer,\n index: index\n });\n }\n }, {\n key: 'stopProgressBar',\n value: function stopProgressBar() {\n clearInterval(this.updateInterval);\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n null,\n this.state.bars.map(function (bar, index) {\n return bar.isActive ? _react2.default.createElement(_ActiveStatusBar2.default, { key: index }) : _react2.default.createElement(_InactiveStatusBar2.default, { key: index });\n })\n );\n }\n }]);\n\n return ProgressBar;\n}(_react2.default.Component);\n\n;\n\nProgressBar.propTypes = {\n size: _propTypes2.default.number.isRequired\n};\n\nexports.default = ProgressBar;\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _propTypes = __webpack_require__(10);\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nvar _NavBar = __webpack_require__(7);\n\nvar _NavBar2 = _interopRequireDefault(_NavBar);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ErrorPage = function (_React$Component) {\n _inherits(ErrorPage, _React$Component);\n\n function ErrorPage() {\n _classCallCheck(this, ErrorPage);\n\n return _possibleConstructorReturn(this, (ErrorPage.__proto__ || Object.getPrototypeOf(ErrorPage)).apply(this, arguments));\n }\n\n _createClass(ErrorPage, [{\n key: 'render',\n value: function render() {\n var error = this.props.error;\n\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(_NavBar2.default, null),\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded' },\n _react2.default.createElement(\n 'p',\n null,\n error\n )\n )\n );\n }\n }]);\n\n return ErrorPage;\n}(_react2.default.Component);\n\n;\n\nErrorPage.propTypes = {\n error: _propTypes2.default.string.isRequired\n};\n\nexports.default = ErrorPage;\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"passport\");\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"passport-local\");\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"sequelize\");\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = {\n returnShortId: function returnShortId(claimsArray, longId) {\n var claimIndex = void 0;\n var shortId = longId.substring(0, 1); // default short id is the first letter\n var shortIdLength = 0;\n // find the index of this claim id\n claimIndex = claimsArray.findIndex(function (element) {\n return element.claimId === longId;\n });\n if (claimIndex < 0) {\n throw new Error('claim id not found in claims list');\n }\n // get an array of all claims with lower height\n var possibleMatches = claimsArray.slice(0, claimIndex);\n // remove certificates with the same prefixes until none are left.\n while (possibleMatches.length > 0) {\n shortIdLength += 1;\n shortId = longId.substring(0, shortIdLength);\n possibleMatches = possibleMatches.filter(function (element) {\n return element.claimId && element.claimId.substring(0, shortIdLength) === shortId;\n });\n }\n return shortId;\n }\n};\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(2);\nvar fs = __webpack_require__(74);\n\nvar _require = __webpack_require__(5),\n details = _require.details,\n publishing = _require.publishing;\n\nmodule.exports = {\n parsePublishApiRequestBody: function parsePublishApiRequestBody(_ref) {\n var name = _ref.name,\n nsfw = _ref.nsfw,\n license = _ref.license,\n title = _ref.title,\n description = _ref.description,\n thumbnail = _ref.thumbnail;\n\n // validate name\n if (!name) {\n throw new Error('no name field found in request');\n }\n var invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name);\n if (invalidNameCharacters) {\n throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and \"-\"');\n }\n // optional parameters\n nsfw = nsfw === 'true';\n license = license || null;\n title = title || null;\n description = description || null;\n thumbnail = thumbnail || null;\n // return results\n return {\n name: name,\n nsfw: nsfw,\n license: license,\n title: title,\n description: description,\n thumbnail: thumbnail\n };\n },\n parsePublishApiRequestFiles: function parsePublishApiRequestFiles(_ref2) {\n var file = _ref2.file,\n thumbnail = _ref2.thumbnail;\n\n // make sure a file was provided\n if (!file) {\n throw new Error('no file with key of [file] found in request');\n }\n if (!file.path) {\n throw new Error('no file path found');\n }\n if (!file.type) {\n throw new Error('no file type found');\n }\n if (!file.size) {\n throw new Error('no file type found');\n }\n // validate the file name\n if (/'/.test(file.name)) {\n throw new Error('apostrophes are not allowed in the file name');\n }\n // validate the file\n module.exports.validateFileTypeAndSize(file);\n // return results\n return {\n fileName: file.name,\n filePath: file.path,\n fileType: file.type,\n thumbnailFileName: thumbnail ? thumbnail.name : null,\n thumbnailFilePath: thumbnail ? thumbnail.path : null,\n thumbnailFileType: thumbnail ? thumbnail.type : null\n };\n },\n validateFileTypeAndSize: function validateFileTypeAndSize(file) {\n // check file type and size\n switch (file.type) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n if (file.size > 10000000) {\n logger.debug('publish > file validation > .jpeg/.jpg/.png was too big');\n throw new Error('Sorry, images are limited to 10 megabytes.');\n }\n break;\n case 'image/gif':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .gif was too big');\n throw new Error('Sorry, .gifs are limited to 50 megabytes.');\n }\n break;\n case 'video/mp4':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .mp4 was too big');\n throw new Error('Sorry, videos are limited to 50 megabytes.');\n }\n break;\n default:\n logger.debug('publish > file validation > unrecognized file type');\n throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');\n }\n return file;\n },\n createBasicPublishParams: function createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail) {\n logger.debug('Creating Publish Parameters');\n // provide defaults for title\n if (title === null || title.trim() === '') {\n title = name;\n }\n // provide default for description\n if (description === null || description.trim() === '') {\n description = '';\n }\n // provide default for license\n if (license === null || license.trim() === '') {\n license = ' '; // default to empty string\n }\n // create the publish params\n var publishParams = {\n name: name,\n file_path: filePath,\n bid: 0.01,\n metadata: {\n description: description,\n title: title,\n author: details.title,\n language: 'en',\n license: license,\n nsfw: nsfw\n },\n claim_address: publishing.primaryClaimAddress\n };\n // add thumbnail to channel if video\n if (thumbnail) {\n publishParams['metadata']['thumbnail'] = thumbnail;\n }\n return publishParams;\n },\n createThumbnailPublishParams: function createThumbnailPublishParams(thumbnailFilePath, claimName, license, nsfw) {\n if (!thumbnailFilePath) {\n return;\n }\n logger.debug('Creating Thumbnail Publish Parameters');\n // create the publish params\n return {\n name: claimName + '-thumb',\n file_path: thumbnailFilePath,\n bid: 0.01,\n metadata: {\n title: claimName + ' thumbnail',\n description: 'a thumbnail for ' + claimName,\n author: details.title,\n language: 'en',\n license: license,\n nsfw: nsfw\n },\n claim_address: publishing.primaryClaimAddress,\n channel_name: publishing.thumbnailChannel,\n channel_id: publishing.thumbnailChannelId\n };\n },\n deleteTemporaryFile: function deleteTemporaryFile(filePath) {\n fs.unlink(filePath, function (err) {\n if (err) {\n logger.error('error deleting temporary file ' + filePath);\n throw err;\n }\n logger.debug('successfully deleted ' + filePath);\n });\n },\n addGetResultsToFileData: function addGetResultsToFileData(fileInfo, getResult) {\n fileInfo.fileName = getResult.file_name;\n fileInfo.filePath = getResult.download_path;\n return fileInfo;\n },\n createFileData: function createFileData(_ref3) {\n var name = _ref3.name,\n claimId = _ref3.claimId,\n outpoint = _ref3.outpoint,\n height = _ref3.height,\n address = _ref3.address,\n nsfw = _ref3.nsfw,\n contentType = _ref3.contentType;\n\n return {\n name: name,\n claimId: claimId,\n outpoint: outpoint,\n height: height,\n address: address,\n fileName: '',\n filePath: '',\n fileType: contentType,\n nsfw: nsfw\n };\n }\n};\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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\"); } }; }();\n\nvar logger = __webpack_require__(2);\n\nmodule.exports = {\n handleErrorResponse: function handleErrorResponse(originalUrl, ip, error, res) {\n logger.error('Error on ' + originalUrl, module.exports.useObjectPropertiesIfNoKeys(error));\n\n var _module$exports$retur = module.exports.returnErrorMessageAndStatus(error),\n _module$exports$retur2 = _slicedToArray(_module$exports$retur, 2),\n status = _module$exports$retur2[0],\n message = _module$exports$retur2[1];\n\n res.status(status).json(module.exports.createErrorResponsePayload(status, message));\n },\n returnErrorMessageAndStatus: function returnErrorMessageAndStatus(error) {\n var status = void 0,\n message = void 0;\n // check for daemon being turned off\n if (error.code === 'ECONNREFUSED') {\n status = 503;\n message = 'Connection refused. The daemon may not be running.';\n // fallback for everything else\n } else {\n status = 400;\n if (error.message) {\n message = error.message;\n } else {\n message = error;\n };\n };\n return [status, message];\n },\n useObjectPropertiesIfNoKeys: function useObjectPropertiesIfNoKeys(err) {\n if (Object.keys(err).length === 0) {\n var newErrorObject = {};\n Object.getOwnPropertyNames(err).forEach(function (key) {\n newErrorObject[key] = err[key];\n });\n return newErrorObject;\n }\n return err;\n },\n createErrorResponsePayload: function createErrorResponsePayload(status, message) {\n return {\n status: status,\n success: false,\n message: message\n };\n }\n};\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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\"); } }; }();\n\nvar db = __webpack_require__(6);\nvar logger = __webpack_require__(2);\n\nvar _require = __webpack_require__(76),\n returnPaginatedChannelClaims = _require.returnPaginatedChannelClaims;\n\nvar NO_CHANNEL = 'NO_CHANNEL';\nvar NO_CLAIM = 'NO_CLAIM';\nvar NO_FILE = 'NO_FILE';\n\nmodule.exports = {\n getClaimId: function getClaimId(channelName, channelClaimId, name, claimId) {\n if (channelName) {\n return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);\n } else {\n return module.exports.getClaimIdByClaim(name, claimId);\n }\n },\n getClaimIdByClaim: function getClaimIdByClaim(claimName, claimId) {\n logger.debug('getClaimIdByClaim(' + claimName + ', ' + claimId + ')');\n return new Promise(function (resolve, reject) {\n db.Claim.getLongClaimId(claimName, claimId).then(function (longClaimId) {\n if (!longClaimId) {\n resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getClaimIdByChannel: function getClaimIdByChannel(channelName, channelClaimId, claimName) {\n logger.debug('getClaimIdByChannel(' + channelName + ', ' + channelClaimId + ', ' + claimName + ')');\n return new Promise(function (resolve, reject) {\n db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id\n .then(function (longChannelId) {\n if (!longChannelId) {\n return [null, null];\n }\n return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n longChannelId = _ref2[0],\n longClaimId = _ref2[1];\n\n if (!longChannelId) {\n return resolve(NO_CHANNEL);\n }\n if (!longClaimId) {\n return resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getChannelData: function getChannelData(channelName, channelClaimId, page) {\n return new Promise(function (resolve, reject) {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);\n }).then(function (_ref3) {\n var _ref4 = _slicedToArray(_ref3, 2),\n longChannelClaimId = _ref4[0],\n shortChannelClaimId = _ref4[1];\n\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. return all the channel information\n resolve({\n channelName: channelName,\n longChannelClaimId: longChannelClaimId,\n shortChannelClaimId: shortChannelClaimId\n });\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getChannelClaims: function getChannelClaims(channelName, channelClaimId, page) {\n return new Promise(function (resolve, reject) {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);\n }).then(function (_ref5) {\n var _ref6 = _slicedToArray(_ref5, 2),\n longChannelClaimId = _ref6[0],\n channelClaimsArray = _ref6[1];\n\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. format the data for the view, including pagination\n var paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);\n // 4. return all the channel information and contents\n resolve(paginatedChannelViewData);\n }).catch(function (error) {\n reject(error);\n });\n });\n },\n getLocalFileRecord: function getLocalFileRecord(claimId, name) {\n return db.File.findOne({ where: { claimId: claimId, name: name } }).then(function (file) {\n if (!file) {\n return NO_FILE;\n }\n return file.dataValues;\n });\n }\n};\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _server = __webpack_require__(30);\n\nvar _redux = __webpack_require__(18);\n\nvar _index = __webpack_require__(31);\n\nvar _index2 = _interopRequireDefault(_index);\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nvar _index3 = __webpack_require__(36);\n\nvar _index4 = _interopRequireDefault(_index3);\n\nvar _app = __webpack_require__(37);\n\nvar _app2 = _interopRequireDefault(_app);\n\nvar _renderFullPage = __webpack_require__(43);\n\nvar _renderFullPage2 = _interopRequireDefault(_renderFullPage);\n\nvar _reactHelmet = __webpack_require__(14);\n\nvar _reactHelmet2 = _interopRequireDefault(_reactHelmet);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nmodule.exports = function (req, res) {\n var context = {};\n\n // create a new Redux store instance\n var store = (0, _redux.createStore)(_index2.default);\n\n // render component to a string\n var html = (0, _server.renderToString)(_react2.default.createElement(\n _reactRedux.Provider,\n { store: store },\n _react2.default.createElement(\n _reactRouterDom.StaticRouter,\n { location: req.url, context: context },\n _react2.default.createElement(\n _index4.default,\n null,\n _react2.default.createElement(_app2.default, null)\n )\n )\n ));\n\n // get head tags from helmet\n var helmet = _reactHelmet2.default.renderStatic();\n\n // check for a redirect\n if (context.url) {\n // Somewhere a `` was rendered\n return res.redirect(301, context.url);\n } else {}\n // we're good, send the response\n\n\n // get the initial state from our Redux store\n var preloadedState = store.getState();\n\n // send the rendered page back to the client\n res.send((0, _renderFullPage2.default)(helmet, html, preloadedState));\n};\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-dom/server\");\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _redux = __webpack_require__(18);\n\nvar _publish = __webpack_require__(78);\n\nvar _publish2 = _interopRequireDefault(_publish);\n\nvar _channel = __webpack_require__(79);\n\nvar _channel2 = _interopRequireDefault(_channel);\n\nvar _show = __webpack_require__(80);\n\nvar _show2 = _interopRequireDefault(_show);\n\nvar _site = __webpack_require__(81);\n\nvar _site2 = _interopRequireDefault(_site);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = (0, _redux.combineReducers)({\n channel: _channel2.default,\n publish: _publish2.default,\n show: _show2.default,\n site: _site2.default\n});\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar FILE_SELECTED = exports.FILE_SELECTED = 'FILE_SELECTED';\nvar FILE_CLEAR = exports.FILE_CLEAR = 'FILE_CLEAR';\nvar METADATA_UPDATE = exports.METADATA_UPDATE = 'METADATA_UPDATE';\nvar CLAIM_UPDATE = exports.CLAIM_UPDATE = 'CLAIM_UPDATE';\nvar SET_PUBLISH_IN_CHANNEL = exports.SET_PUBLISH_IN_CHANNEL = 'SET_PUBLISH_IN_CHANNEL';\nvar PUBLISH_STATUS_UPDATE = exports.PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE';\nvar ERROR_UPDATE = exports.ERROR_UPDATE = 'ERROR_UPDATE';\nvar SELECTED_CHANNEL_UPDATE = exports.SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE';\nvar TOGGLE_METADATA_INPUTS = exports.TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS';\nvar THUMBNAIL_NEW = exports.THUMBNAIL_NEW = 'THUMBNAIL_NEW';\nvar PUBLISH_START = exports.PUBLISH_START = 'PUBLISH_START';\n\n/***/ }),\n/* 33 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar LOGIN = exports.LOGIN = 'Existing';\nvar CREATE = exports.CREATE = 'New';\n\n/***/ }),\n/* 34 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar CHANNEL_UPDATE = exports.CHANNEL_UPDATE = 'CHANNEL_UPDATE';\n\n/***/ }),\n/* 35 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar LOCAL_CHECK = exports.LOCAL_CHECK = 'LOCAL_CHECK';\nvar UNAVAILABLE = exports.UNAVAILABLE = 'UNAVAILABLE';\nvar ERROR = exports.ERROR = 'ERROR';\nvar AVAILABLE = exports.AVAILABLE = 'AVAILABLE';\n\n/***/ }),\n/* 36 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactGa = __webpack_require__(82);\n\nvar _reactGa2 = _interopRequireDefault(_reactGa);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar _require = __webpack_require__(5),\n googleId = _require.analytics.googleId;\n\n_reactGa2.default.initialize(googleId);\n\nvar GAListener = function (_React$Component) {\n _inherits(GAListener, _React$Component);\n\n function GAListener() {\n _classCallCheck(this, GAListener);\n\n return _possibleConstructorReturn(this, (GAListener.__proto__ || Object.getPrototypeOf(GAListener)).apply(this, arguments));\n }\n\n _createClass(GAListener, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n this.sendPageView(this.props.history.location);\n this.props.history.listen(this.sendPageView);\n }\n }, {\n key: 'sendPageView',\n value: function sendPageView(location) {\n _reactGa2.default.set({ page: location.pathname });\n _reactGa2.default.pageview(location.pathname);\n }\n }, {\n key: 'render',\n value: function render() {\n return this.props.children;\n }\n }]);\n\n return GAListener;\n}(_react2.default.Component);\n\nexports.default = (0, _reactRouterDom.withRouter)(GAListener);\n\n/***/ }),\n/* 37 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nvar _HomePage = __webpack_require__(83);\n\nvar _HomePage2 = _interopRequireDefault(_HomePage);\n\nvar _AboutPage = __webpack_require__(120);\n\nvar _AboutPage2 = _interopRequireDefault(_AboutPage);\n\nvar _LoginPage = __webpack_require__(121);\n\nvar _LoginPage2 = _interopRequireDefault(_LoginPage);\n\nvar _ShowPage = __webpack_require__(123);\n\nvar _ShowPage2 = _interopRequireDefault(_ShowPage);\n\nvar _FourOhFourPage = __webpack_require__(140);\n\nvar _FourOhFourPage2 = _interopRequireDefault(_FourOhFourPage);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// or use the provided local homepage\nvar App = function App() {\n return _react2.default.createElement(\n _reactRouterDom.Switch,\n null,\n _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/', component: _HomePage2.default }),\n _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/about', component: _AboutPage2.default }),\n _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/login', component: _LoginPage2.default }),\n _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/:identifier/:claim', component: _ShowPage2.default }),\n _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/:claim', component: _ShowPage2.default }),\n _react2.default.createElement(_reactRouterDom.Route, { component: _FourOhFourPage2.default })\n );\n};\n\nexports.default = App;\n\n/***/ }),\n/* 38 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _publish = __webpack_require__(4);\n\nvar _view = __webpack_require__(94);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var publish = _ref.publish;\n\n return {\n file: publish.file,\n thumbnail: publish.thumbnail,\n fileError: publish.error.file\n };\n};\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n selectFile: function selectFile(file) {\n dispatch((0, _publish.selectFile)(file));\n },\n setFileError: function setFileError(value) {\n dispatch((0, _publish.clearFile)());\n dispatch((0, _publish.updateError)('file', value));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 39 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _channel = __webpack_require__(19);\n\nvar _view = __webpack_require__(111);\n\nvar _view2 = _interopRequireDefault(_view);\n\nvar _publish = __webpack_require__(4);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n onChannelLogin: function onChannelLogin(name, shortId, longId) {\n dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));\n dispatch((0, _publish.updateSelectedChannel)(name));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(null, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 40 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _channel = __webpack_require__(19);\n\nvar _view = __webpack_require__(112);\n\nvar _view2 = _interopRequireDefault(_view);\n\nvar _publish = __webpack_require__(4);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n onChannelLogin: function onChannelLogin(name, shortId, longId) {\n dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));\n dispatch((0, _publish.updateSelectedChannel)(name));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(null, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 41 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar CHANNEL = exports.CHANNEL = 'CHANNEL';\nvar ASSET_LITE = exports.ASSET_LITE = 'ASSET_LITE';\nvar ASSET_DETAILS = exports.ASSET_DETAILS = 'ASSET_DETAILS';\n\n/***/ }),\n/* 42 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(127);\n\nvar _view2 = _interopRequireDefault(_view);\n\nvar _show = __webpack_require__(8);\n\nvar _show2 = __webpack_require__(13);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var show = _ref.show;\n\n // select error and status\n var error = show.displayAsset.error;\n var status = show.displayAsset.status;\n // select asset\n var asset = (0, _show2.selectAsset)(show);\n // return props\n return {\n error: error,\n status: status,\n asset: asset\n };\n};\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n onFileRequest: function onFileRequest(name, claimId) {\n dispatch((0, _show.fileRequested)(name, claimId));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 43 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (helmet, html, preloadedState) {\n // take the html and preloadedState and return the full page\n return '\\n \\n \\n \\n \\n \\n \\n \\n ' + helmet.title.toString() + '\\n ' + helmet.meta.toString() + '\\n ' + helmet.link.toString() + '\\n \\n \\n \\n \\n \\n \\n \\n \\n
\\n
' + html + '
\\n
\\n \\n \\n \\n \\n ';\n};\n\n/***/ }),\n/* 44 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar selectSiteState = exports.selectSiteState = function selectSiteState(state) {\n return state.site;\n};\n\nvar selectSiteHost = exports.selectSiteHost = function selectSiteHost(state) {\n return state.site.host;\n};\n\n/***/ }),\n/* 45 */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(46);\n__webpack_require__(47);\nmodule.exports = __webpack_require__(48);\n\n\n/***/ }),\n/* 46 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"babel-polyfill\");\n\n/***/ }),\n/* 47 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"whatwg-fetch\");\n\n/***/ }),\n/* 48 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n// app dependencies\nvar express = __webpack_require__(49);\nvar bodyParser = __webpack_require__(50);\nvar expressHandlebars = __webpack_require__(51);\nvar Handlebars = __webpack_require__(52);\nvar helmet = __webpack_require__(53);\nvar passport = __webpack_require__(22);\n\nvar _require = __webpack_require__(54),\n serializeSpeechUser = _require.serializeSpeechUser,\n deserializeSpeechUser = _require.deserializeSpeechUser;\n\nvar cookieSession = __webpack_require__(55);\nvar http = __webpack_require__(56);\n// logging dependencies\nvar logger = __webpack_require__(2);\n\nvar _require2 = __webpack_require__(5),\n sessionKey = _require2.auth.sessionKey,\n PORT = _require2.details.port;\n\n// create an Express application\n\n\nvar app = express();\n\n// trust the proxy to get ip address for us\napp.enable('trust proxy');\n\n// add middleware\napp.use(helmet()); // set HTTP headers to protect against well-known web vulnerabilties\napp.use(express.static(__dirname + '/public')); // 'express.static' to serve static files from public directory\napp.use(bodyParser.json()); // 'body parser' for parsing application/json\napp.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded\napp.use(function (req, res, next) {\n // custom logging middleware to log all incoming http requests\n logger.verbose('Request on ' + req.originalUrl + ' from ' + req.ip);\n next();\n});\n\n// configure passport\npassport.serializeUser(serializeSpeechUser);\npassport.deserializeUser(deserializeSpeechUser);\nvar localSignupStrategy = __webpack_require__(57);\nvar localLoginStrategy = __webpack_require__(69);\npassport.use('local-signup', localSignupStrategy);\npassport.use('local-login', localLoginStrategy);\n// initialize passport\napp.use(cookieSession({\n name: 'session',\n keys: [sessionKey],\n maxAge: 24 * 60 * 60 * 1000 // i.e. 24 hours\n}));\napp.use(passport.initialize());\napp.use(passport.session());\n\n// configure handlebars & register it with express app\nvar hbs = expressHandlebars.create({\n defaultLayout: 'embed',\n handlebars: Handlebars\n});\napp.engine('handlebars', hbs.engine);\napp.set('view engine', 'handlebars');\n\n// set the routes on the app\n__webpack_require__(70)(app);\n__webpack_require__(71)(app);\n__webpack_require__(77)(app);\n__webpack_require__(142)(app);\n__webpack_require__(153)(app);\n\n// create server\nvar server = http.Server(app);\n\n// configure logger\n__webpack_require__(154)(logger);\n__webpack_require__(156)(logger);\n\n// sync sequelize\nvar db = __webpack_require__(6);\ndb.sequelize.sync()\n// start the server\n.then(function () {\n server.listen(PORT, function () {\n logger.info('Server is listening on PORT ' + PORT);\n });\n}).catch(function (error) {\n logger.error('Startup Error:', error);\n});\n\n/***/ }),\n/* 49 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"express\");\n\n/***/ }),\n/* 50 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"body-parser\");\n\n/***/ }),\n/* 51 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"express-handlebars\");\n\n/***/ }),\n/* 52 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"handlebars\");\n\n/***/ }),\n/* 53 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"helmet\");\n\n/***/ }),\n/* 54 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(2);\n\nmodule.exports = {\n serializeSpeechUser: function serializeSpeechUser(user, done) {\n // returns user data to be serialized into session\n logger.debug('serializing user');\n done(null, user);\n },\n deserializeSpeechUser: function deserializeSpeechUser(user, done) {\n // deserializes session and populates additional info to req.user\n logger.debug('deserializing user');\n done(null, user);\n }\n};\n\n/***/ }),\n/* 55 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"cookie-session\");\n\n/***/ }),\n/* 56 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"http\");\n\n/***/ }),\n/* 57 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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\"); } }; }();\n\nvar PassportLocalStrategy = __webpack_require__(23).Strategy;\nvar lbryApi = __webpack_require__(16);\nvar logger = __webpack_require__(2);\nvar db = __webpack_require__(6);\n\nmodule.exports = new PassportLocalStrategy({\n usernameField: 'username',\n passwordField: 'password'\n}, function (username, password, done) {\n logger.verbose('new channel signup request. user: ' + username + ' pass: ' + password + ' .');\n var userInfo = {};\n // server-side validaton of inputs (username, password)\n\n // create the channel and retrieve the metadata\n return lbryApi.createChannel('@' + username).then(function (tx) {\n // create user record\n var userData = {\n userName: username,\n password: password\n };\n logger.verbose('userData >', userData);\n // create user record\n var channelData = {\n channelName: '@' + username,\n channelClaimId: tx.claim_id\n };\n logger.verbose('channelData >', channelData);\n // create certificate record\n var certificateData = {\n claimId: tx.claim_id,\n name: '@' + username\n // address,\n };\n logger.verbose('certificateData >', certificateData);\n // save user and certificate to db\n return Promise.all([db.User.create(userData), db.Channel.create(channelData), db.Certificate.create(certificateData)]);\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 3),\n newUser = _ref2[0],\n newChannel = _ref2[1],\n newCertificate = _ref2[2];\n\n logger.verbose('user and certificate successfully created');\n // store the relevant newUser info to be passed back for req.User\n userInfo['id'] = newUser.id;\n userInfo['userName'] = newUser.userName;\n userInfo['channelName'] = newChannel.channelName;\n userInfo['channelClaimId'] = newChannel.channelClaimId;\n // associate the instances\n return Promise.all([newCertificate.setChannel(newChannel), newChannel.setUser(newUser)]);\n }).then(function () {\n logger.verbose('user and certificate successfully associated');\n return db.Certificate.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName);\n }).then(function (shortChannelId) {\n userInfo['shortChannelId'] = shortChannelId;\n return done(null, userInfo);\n }).catch(function (error) {\n logger.error('signup error', error);\n return done(error);\n });\n});\n\n/***/ }),\n/* 58 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"axios\");\n\n/***/ }),\n/* 59 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar lbryConfig = {\n api: {\n apiHost: 'localhost',\n apiPort: '5279'\n }\n};\n\nmodule.exports = lbryConfig;\n\n/***/ }),\n/* 60 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"universal-analytics\");\n\n/***/ }),\n/* 61 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction MysqlConfig() {\n this.database = 'default';\n this.username = 'default';\n this.password = 'default';\n};\n\nmodule.exports = new MysqlConfig();\n\n/***/ }),\n/* 62 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(2);\n\nvar _require = __webpack_require__(25),\n returnShortId = _require.returnShortId;\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER,\n TEXT = _ref.TEXT,\n DECIMAL = _ref.DECIMAL;\n\n var Certificate = sequelize.define('Certificate', {\n address: {\n type: STRING,\n default: null\n },\n amount: {\n type: DECIMAL(19, 8),\n default: null\n },\n claimId: {\n type: STRING,\n default: null\n },\n claimSequence: {\n type: INTEGER,\n default: null\n },\n decodedClaim: {\n type: BOOLEAN,\n default: null\n },\n depth: {\n type: INTEGER,\n default: null\n },\n effectiveAmount: {\n type: DECIMAL(19, 8),\n default: null\n },\n hasSignature: {\n type: BOOLEAN,\n default: null\n },\n height: {\n type: INTEGER,\n default: null\n },\n hex: {\n type: TEXT('long'),\n default: null\n },\n name: {\n type: STRING,\n default: null\n },\n nout: {\n type: INTEGER,\n default: null\n },\n txid: {\n type: STRING,\n default: null\n },\n validAtHeight: {\n type: INTEGER,\n default: null\n },\n outpoint: {\n type: STRING,\n default: null\n },\n valueVersion: {\n type: STRING,\n default: null\n },\n claimType: {\n type: STRING,\n default: null\n },\n certificateVersion: {\n type: STRING,\n default: null\n },\n keyType: {\n type: STRING,\n default: null\n },\n publicKey: {\n type: TEXT('long'),\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Certificate.associate = function (db) {\n Certificate.belongsTo(db.Channel, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {\n var _this = this;\n\n logger.debug('getShortChannelIdFromLongChannelId ' + channelName + ':' + longChannelId);\n return new Promise(function (resolve, reject) {\n _this.findAll({\n where: { name: channelName },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n throw new Error('No channel(s) found with that channel name');\n default:\n return resolve(returnShortId(result, longChannelId));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {\n var _this2 = this;\n\n logger.debug('getLongChannelIdFromShortChannelId(' + channelName + ', ' + channelClaimId + ')');\n return new Promise(function (resolve, reject) {\n _this2.findAll({\n where: {\n name: channelName,\n claimId: {\n $like: channelClaimId + '%'\n }\n },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n // note results must be sorted\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromChannelName = function (channelName) {\n var _this3 = this;\n\n logger.debug('getLongChannelIdFromChannelName(' + channelName + ')');\n return new Promise(function (resolve, reject) {\n _this3.findAll({\n where: { name: channelName },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.validateLongChannelId = function (name, claimId) {\n var _this4 = this;\n\n logger.debug('validateLongChannelId(' + name + ', ' + claimId + ')');\n return new Promise(function (resolve, reject) {\n _this4.findOne({\n where: { name: name, claimId: claimId }\n }).then(function (result) {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelId = function (channelName, channelClaimId) {\n logger.debug('getLongChannelId(' + channelName + ', ' + channelClaimId + ')');\n if (channelClaimId && channelClaimId.length === 40) {\n // if a full channel id is provided\n return this.validateLongChannelId(channelName, channelClaimId);\n } else if (channelClaimId && channelClaimId.length < 40) {\n // if a short channel id is provided\n return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);\n } else {\n return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided\n }\n };\n\n return Certificate;\n};\n\n/***/ }),\n/* 63 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING;\n\n var Channel = sequelize.define('Channel', {\n channelName: {\n type: STRING,\n allowNull: false\n },\n channelClaimId: {\n type: STRING,\n allowNull: false\n }\n }, {\n freezeTableName: true\n });\n\n Channel.associate = function (db) {\n Channel.belongsTo(db.User);\n Channel.hasOne(db.Certificate);\n };\n\n return Channel;\n};\n\n/***/ }),\n/* 64 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(2);\n\nvar _require = __webpack_require__(25),\n returnShortId = _require.returnShortId;\n\nvar _require2 = __webpack_require__(5),\n defaultThumbnail = _require2.assetDefaults.thumbnail,\n host = _require2.details.host;\n\nfunction determineFileExtensionFromContentType(contentType) {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n return 'jpeg';\n case 'image/png':\n return 'png';\n case 'image/gif':\n return 'gif';\n case 'video/mp4':\n return 'mp4';\n default:\n logger.debug('setting unknown file type as file extension jpeg');\n return 'jpeg';\n }\n};\n\nfunction determineThumbnail(storedThumbnail, defaultThumbnail) {\n if (storedThumbnail === '') {\n return defaultThumbnail;\n }\n return storedThumbnail;\n};\n\nfunction prepareClaimData(claim) {\n // logger.debug('preparing claim data based on resolved data:', claim);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['host'] = host;\n return claim;\n};\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER,\n TEXT = _ref.TEXT,\n DECIMAL = _ref.DECIMAL;\n\n var Claim = sequelize.define('Claim', {\n address: {\n type: STRING,\n default: null\n },\n amount: {\n type: DECIMAL(19, 8),\n default: null\n },\n claimId: {\n type: STRING,\n default: null\n },\n claimSequence: {\n type: INTEGER,\n default: null\n },\n decodedClaim: {\n type: BOOLEAN,\n default: null\n },\n depth: {\n type: INTEGER,\n default: null\n },\n effectiveAmount: {\n type: DECIMAL(19, 8),\n default: null\n },\n hasSignature: {\n type: BOOLEAN,\n default: null\n },\n height: {\n type: INTEGER,\n default: null\n },\n hex: {\n type: TEXT('long'),\n default: null\n },\n name: {\n type: STRING,\n default: null\n },\n nout: {\n type: INTEGER,\n default: null\n },\n txid: {\n type: STRING,\n default: null\n },\n validAtHeight: {\n type: INTEGER,\n default: null\n },\n outpoint: {\n type: STRING,\n default: null\n },\n claimType: {\n type: STRING,\n default: null\n },\n certificateId: {\n type: STRING,\n default: null\n },\n author: {\n type: STRING,\n default: null\n },\n description: {\n type: TEXT('long'),\n default: null\n },\n language: {\n type: STRING,\n default: null\n },\n license: {\n type: STRING,\n default: null\n },\n licenseUrl: {\n type: STRING,\n default: null\n },\n nsfw: {\n type: BOOLEAN,\n default: null\n },\n preview: {\n type: STRING,\n default: null\n },\n thumbnail: {\n type: STRING,\n default: null\n },\n title: {\n type: STRING,\n default: null\n },\n metadataVersion: {\n type: STRING,\n default: null\n },\n contentType: {\n type: STRING,\n default: null\n },\n source: {\n type: STRING,\n default: null\n },\n sourceType: {\n type: STRING,\n default: null\n },\n sourceVersion: {\n type: STRING,\n default: null\n },\n streamVersion: {\n type: STRING,\n default: null\n },\n valueVersion: {\n type: STRING,\n default: null\n },\n channelName: {\n type: STRING,\n allowNull: true,\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Claim.associate = function (db) {\n Claim.belongsTo(db.File, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {\n var _this = this;\n\n logger.debug('Claim.getShortClaimIdFromLongClaimId for ' + claimName + '#' + claimId);\n return new Promise(function (resolve, reject) {\n _this.findAll({\n where: { name: claimName },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n throw new Error('No claim(s) found with that claim name');\n default:\n resolve(returnShortId(result, claimId));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getAllChannelClaims = function (channelClaimId) {\n var _this2 = this;\n\n logger.debug('Claim.getAllChannelClaims for ' + channelClaimId);\n return new Promise(function (resolve, reject) {\n _this2.findAll({\n where: { certificateId: channelClaimId },\n order: [['height', 'ASC']],\n raw: true // returns an array of only data, not an array of instances\n }).then(function (channelClaimsArray) {\n // logger.debug('channelclaimsarray length:', channelClaimsArray.length);\n switch (channelClaimsArray.length) {\n case 0:\n return resolve(null);\n default:\n channelClaimsArray.forEach(function (claim) {\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n return claim;\n });\n return resolve(channelClaimsArray);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) {\n var _this3 = this;\n\n logger.debug('finding claim id for claim ' + claimName + ' from channel ' + channelClaimId);\n return new Promise(function (resolve, reject) {\n _this3.findAll({\n where: { name: claimName, certificateId: channelClaimId },\n order: [['id', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(result[0].claimId);\n default:\n logger.error(result.length + ' records found for \"' + claimName + '\" in channel \"' + channelClaimId + '\"');\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {\n var _this4 = this;\n\n return new Promise(function (resolve, reject) {\n _this4.findAll({\n where: {\n name: name,\n claimId: {\n $like: shortId + '%'\n } },\n order: [['height', 'ASC']]\n }).then(function (result) {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n // note results must be sorted\n return resolve(result[0].claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getTopFreeClaimIdByClaimName = function (name) {\n var _this5 = this;\n\n return new Promise(function (resolve, reject) {\n _this5.findAll({\n where: { name: name },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']] // note: maybe height and effective amount need to switch?\n }).then(function (result) {\n logger.debug('length of result', result.length);\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].dataValues.claimId);\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.validateLongClaimId = function (name, claimId) {\n var _this6 = this;\n\n return new Promise(function (resolve, reject) {\n _this6.findOne({\n where: { name: name, claimId: claimId }\n }).then(function (result) {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimId = function (claimName, claimId) {\n logger.debug('getLongClaimId(' + claimName + ', ' + claimId + ')');\n if (claimId && claimId.length === 40) {\n // if a full claim id is provided\n return this.validateLongClaimId(claimName, claimId);\n } else if (claimId && claimId.length < 40) {\n return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided\n } else {\n return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided\n }\n };\n\n Claim.resolveClaim = function (name, claimId) {\n var _this7 = this;\n\n logger.debug('Claim.resolveClaim: ' + name + ' ' + claimId);\n return new Promise(function (resolve, reject) {\n _this7.findAll({\n where: { name: name, claimId: claimId }\n }).then(function (claimArray) {\n switch (claimArray.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(prepareClaimData(claimArray[0].dataValues));\n default:\n logger.error('more than one record matches ' + name + '#' + claimId + ' in db.Claim');\n return resolve(prepareClaimData(claimArray[0].dataValues));\n }\n }).catch(function (error) {\n reject(error);\n });\n });\n };\n\n return Claim;\n};\n\n/***/ }),\n/* 65 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n INTEGER = _ref.INTEGER;\n\n var File = sequelize.define('File', {\n name: {\n type: STRING,\n allowNull: false\n },\n claimId: {\n type: STRING,\n allowNull: false\n },\n address: {\n type: STRING,\n allowNull: false\n },\n outpoint: {\n type: STRING,\n allowNull: false\n },\n height: {\n type: INTEGER,\n allowNull: false,\n default: 0\n },\n fileName: {\n type: STRING,\n allowNull: false\n },\n filePath: {\n type: STRING,\n allowNull: false\n },\n fileType: {\n type: STRING\n },\n nsfw: {\n type: BOOLEAN,\n allowNull: false,\n defaultValue: false\n },\n trendingEligible: {\n type: BOOLEAN,\n allowNull: false,\n defaultValue: true\n }\n }, {\n freezeTableName: true\n });\n\n File.associate = function (db) {\n File.hasMany(db.Request);\n File.hasOne(db.Claim);\n };\n\n File.getRecentClaims = function () {\n return this.findAll({\n where: { nsfw: false, trendingEligible: true },\n order: [['createdAt', 'DESC']],\n limit: 25\n });\n };\n\n return File;\n};\n\n/***/ }),\n/* 66 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING,\n BOOLEAN = _ref.BOOLEAN,\n TEXT = _ref.TEXT;\n\n var Request = sequelize.define('Request', {\n action: {\n type: STRING,\n allowNull: false\n },\n url: {\n type: STRING,\n allowNull: false\n },\n ipAddress: {\n type: STRING,\n allowNull: true\n },\n result: {\n type: TEXT('long'),\n allowNull: true,\n default: null\n }\n }, {\n freezeTableName: true\n });\n\n Request.associate = function (db) {\n Request.belongsTo(db.File, {\n foreignKey: {\n allowNull: true\n }\n });\n };\n\n return Request;\n};\n\n/***/ }),\n/* 67 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar bcrypt = __webpack_require__(68);\nvar logger = __webpack_require__(2);\n\nmodule.exports = function (sequelize, _ref) {\n var STRING = _ref.STRING;\n\n var User = sequelize.define('User', {\n userName: {\n type: STRING,\n allowNull: false\n },\n password: {\n type: STRING,\n allowNull: false\n }\n }, {\n freezeTableName: true\n });\n\n User.associate = function (db) {\n User.hasOne(db.Channel);\n };\n\n User.prototype.comparePassword = function (password) {\n return bcrypt.compare(password, this.password);\n };\n\n User.prototype.changePassword = function (newPassword) {\n var _this = this;\n\n return new Promise(function (resolve, reject) {\n // generate a salt string to use for hashing\n bcrypt.genSalt(function (saltError, salt) {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(newPassword, salt, function (hashError, hash) {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the current password with the new hash\n _this.update({ password: hash }).then(function () {\n resolve();\n }).catch(function (error) {\n reject(error);\n });\n });\n });\n });\n };\n\n // pre-save hook method to hash the user's password before the user's info is saved to the db.\n User.hook('beforeCreate', function (user, options) {\n logger.debug('User.beforeCreate hook...');\n return new Promise(function (resolve, reject) {\n // generate a salt string to use for hashing\n bcrypt.genSalt(function (saltError, salt) {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(user.password, salt, function (hashError, hash) {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the password string with the hash password value\n user.password = hash;\n resolve();\n });\n });\n });\n });\n\n return User;\n};\n\n/***/ }),\n/* 68 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"bcrypt\");\n\n/***/ }),\n/* 69 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar PassportLocalStrategy = __webpack_require__(23).Strategy;\nvar logger = __webpack_require__(2);\nvar db = __webpack_require__(6);\n\nvar returnUserAndChannelInfo = function returnUserAndChannelInfo(userInstance) {\n return new Promise(function (resolve, reject) {\n var userInfo = {};\n userInfo['id'] = userInstance.id;\n userInfo['userName'] = userInstance.userName;\n userInstance.getChannel().then(function (_ref) {\n var channelName = _ref.channelName,\n channelClaimId = _ref.channelClaimId;\n\n userInfo['channelName'] = channelName;\n userInfo['channelClaimId'] = channelClaimId;\n return db.Certificate.getShortChannelIdFromLongChannelId(channelClaimId, channelName);\n }).then(function (shortChannelId) {\n userInfo['shortChannelId'] = shortChannelId;\n resolve(userInfo);\n }).catch(function (error) {\n reject(error);\n });\n });\n};\n\nmodule.exports = new PassportLocalStrategy({\n usernameField: 'username',\n passwordField: 'password'\n}, function (username, password, done) {\n return db.User.findOne({\n where: { userName: username }\n }).then(function (user) {\n if (!user) {\n logger.debug('no user found');\n return done(null, false, { message: 'Incorrect username or password' });\n }\n return user.comparePassword(password).then(function (isMatch) {\n if (!isMatch) {\n logger.debug('incorrect password');\n return done(null, false, { message: 'Incorrect username or password' });\n }\n logger.debug('Password was a match, returning User');\n return returnUserAndChannelInfo(user).then(function (userInfo) {\n return done(null, userInfo);\n }).catch(function (error) {\n return error;\n });\n }).catch(function (error) {\n return error;\n });\n }).catch(function (error) {\n return done(error);\n });\n});\n\n/***/ }),\n/* 70 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(2);\nvar passport = __webpack_require__(22);\n\nmodule.exports = function (app) {\n // route for sign up\n app.post('/signup', passport.authenticate('local-signup'), function (req, res) {\n logger.verbose('successful signup for ' + req.user.channelName);\n res.status(200).json({\n success: true,\n channelName: req.user.channelName,\n channelClaimId: req.user.channelClaimId,\n shortChannelId: req.user.shortChannelId\n });\n });\n // route for log in\n app.post('/login', function (req, res, next) {\n passport.authenticate('local-login', function (err, user, info) {\n if (err) {\n return next(err);\n }\n if (!user) {\n return res.status(400).json({\n success: false,\n message: info.message\n });\n }\n logger.debug('successful login');\n req.logIn(user, function (err) {\n if (err) {\n return next(err);\n }\n return res.status(200).json({\n success: true,\n channelName: req.user.channelName,\n channelClaimId: req.user.channelClaimId,\n shortChannelId: req.user.shortChannelId\n });\n });\n })(req, res, next);\n });\n // route to log out\n app.get('/logout', function (req, res) {\n req.logout();\n res.status(200).json({ success: true, message: 'you successfully logged out' });\n });\n // see if user is authenticated, and return credentials if so\n app.get('/user', function (req, res) {\n if (req.user) {\n res.status(200).json({ success: true, data: req.user });\n } else {\n res.status(401).json({ success: false, message: 'user is not logged in' });\n }\n });\n};\n\n/***/ }),\n/* 71 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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\"); } }; }();\n\nvar logger = __webpack_require__(2);\nvar multipart = __webpack_require__(72);\n\nvar _require = __webpack_require__(5),\n uploadDirectory = _require.publishing.uploadDirectory,\n host = _require.details.host;\n\nvar multipartMiddleware = multipart({ uploadDir: uploadDirectory });\nvar db = __webpack_require__(6);\n\nvar _require2 = __webpack_require__(73),\n claimNameIsAvailable = _require2.claimNameIsAvailable,\n checkChannelAvailability = _require2.checkChannelAvailability,\n publish = _require2.publish;\n\nvar _require3 = __webpack_require__(16),\n getClaimList = _require3.getClaimList,\n resolveUri = _require3.resolveUri,\n getClaim = _require3.getClaim;\n\nvar _require4 = __webpack_require__(26),\n addGetResultsToFileData = _require4.addGetResultsToFileData,\n createBasicPublishParams = _require4.createBasicPublishParams,\n createThumbnailPublishParams = _require4.createThumbnailPublishParams,\n parsePublishApiRequestBody = _require4.parsePublishApiRequestBody,\n parsePublishApiRequestFiles = _require4.parsePublishApiRequestFiles,\n createFileData = _require4.createFileData;\n\nvar errorHandlers = __webpack_require__(27);\n\nvar _require5 = __webpack_require__(17),\n sendGATimingEvent = _require5.sendGATimingEvent;\n\nvar _require6 = __webpack_require__(75),\n authenticateUser = _require6.authenticateUser;\n\nvar _require7 = __webpack_require__(28),\n getChannelData = _require7.getChannelData,\n getChannelClaims = _require7.getChannelClaims,\n getClaimId = _require7.getClaimId;\n\nvar NO_CHANNEL = 'NO_CHANNEL';\nvar NO_CLAIM = 'NO_CLAIM';\n\nmodule.exports = function (app) {\n // route to check whether site has published to a channel\n app.get('/api/channel/availability/:name', function (_ref, res) {\n var ip = _ref.ip,\n originalUrl = _ref.originalUrl,\n name = _ref.params.name;\n\n var gaStartTime = Date.now();\n checkChannelAvailability(name).then(function (availableName) {\n res.status(200).json(availableName);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to get a short channel id from long channel Id\n app.get('/api/channel/short-id/:longId/:name', function (_ref2, res) {\n var ip = _ref2.ip,\n originalUrl = _ref2.originalUrl,\n params = _ref2.params;\n\n db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name).then(function (shortId) {\n res.status(200).json(shortId);\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n app.get('/api/channel/data/:channelName/:channelClaimId', function (_ref3, res) {\n var ip = _ref3.ip,\n originalUrl = _ref3.originalUrl,\n body = _ref3.body,\n params = _ref3.params;\n\n var channelName = params.channelName;\n var channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n getChannelData(channelName, channelClaimId, 0).then(function (data) {\n if (data === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel was found' });\n }\n res.status(200).json({ success: true, data: data });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n app.get('/api/channel/claims/:channelName/:channelClaimId/:page', function (_ref4, res) {\n var ip = _ref4.ip,\n originalUrl = _ref4.originalUrl,\n body = _ref4.body,\n params = _ref4.params;\n\n var channelName = params.channelName;\n var channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n var page = params.page;\n getChannelClaims(channelName, channelClaimId, page).then(function (data) {\n if (data === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel was found' });\n }\n res.status(200).json({ success: true, data: data });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to run a claim_list request on the daemon\n app.get('/api/claim/list/:name', function (_ref5, res) {\n var ip = _ref5.ip,\n originalUrl = _ref5.originalUrl,\n params = _ref5.params;\n\n getClaimList(params.name).then(function (claimsList) {\n res.status(200).json(claimsList);\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to get an asset\n app.get('/api/claim/get/:name/:claimId', function (_ref6, res) {\n var ip = _ref6.ip,\n originalUrl = _ref6.originalUrl,\n params = _ref6.params;\n\n var name = params.name;\n var claimId = params.claimId;\n // resolve the claim\n db.Claim.resolveClaim(name, claimId).then(function (resolveResult) {\n // make sure a claim actually exists at that uri\n if (!resolveResult) {\n throw new Error('No matching uri found in Claim table');\n }\n var fileData = createFileData(resolveResult);\n // get the claim\n return Promise.all([fileData, getClaim(name + '#' + claimId)]);\n }).then(function (_ref7) {\n var _ref8 = _slicedToArray(_ref7, 2),\n fileData = _ref8[0],\n getResult = _ref8[1];\n\n fileData = addGetResultsToFileData(fileData, getResult);\n return Promise.all([db.upsert(db.File, fileData, { name: name, claimId: claimId }, 'File'), getResult]);\n }).then(function (_ref9) {\n var _ref10 = _slicedToArray(_ref9, 2),\n fileRecord = _ref10[0],\n _ref10$ = _ref10[1],\n message = _ref10$.message,\n completed = _ref10$.completed;\n\n res.status(200).json({ success: true, message: message, completed: completed });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to check whether this site published to a claim\n app.get('/api/claim/availability/:name', function (_ref11, res) {\n var ip = _ref11.ip,\n originalUrl = _ref11.originalUrl,\n name = _ref11.params.name;\n\n var gaStartTime = Date.now();\n claimNameIsAvailable(name).then(function (result) {\n res.status(200).json(result);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to run a resolve request on the daemon\n app.get('/api/claim/resolve/:name/:claimId', function (_ref12, res) {\n var headers = _ref12.headers,\n ip = _ref12.ip,\n originalUrl = _ref12.originalUrl,\n params = _ref12.params;\n\n resolveUri(params.name + '#' + params.claimId).then(function (resolvedUri) {\n res.status(200).json(resolvedUri);\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to run a publish request on the daemon\n app.post('/api/claim/publish', multipartMiddleware, function (_ref13, res) {\n var body = _ref13.body,\n files = _ref13.files,\n headers = _ref13.headers,\n ip = _ref13.ip,\n originalUrl = _ref13.originalUrl,\n user = _ref13.user;\n\n // define variables\n var channelName = void 0,\n channelId = void 0,\n channelPassword = void 0,\n description = void 0,\n fileName = void 0,\n filePath = void 0,\n fileType = void 0,\n gaStartTime = void 0,\n license = void 0,\n name = void 0,\n nsfw = void 0,\n thumbnail = void 0,\n thumbnailFileName = void 0,\n thumbnailFilePath = void 0,\n thumbnailFileType = void 0,\n title = void 0;\n // record the start time of the request\n gaStartTime = Date.now();\n // validate the body and files of the request\n try {\n var _parsePublishApiReque = parsePublishApiRequestBody(body);\n // validateApiPublishRequest(body, files);\n\n\n name = _parsePublishApiReque.name;\n nsfw = _parsePublishApiReque.nsfw;\n license = _parsePublishApiReque.license;\n title = _parsePublishApiReque.title;\n description = _parsePublishApiReque.description;\n thumbnail = _parsePublishApiReque.thumbnail;\n\n var _parsePublishApiReque2 = parsePublishApiRequestFiles(files);\n\n fileName = _parsePublishApiReque2.fileName;\n filePath = _parsePublishApiReque2.filePath;\n fileType = _parsePublishApiReque2.fileType;\n thumbnailFileName = _parsePublishApiReque2.thumbnailFileName;\n thumbnailFilePath = _parsePublishApiReque2.thumbnailFilePath;\n thumbnailFileType = _parsePublishApiReque2.thumbnailFileType;\n channelName = body.channelName;\n channelId = body.channelId;\n channelPassword = body.channelPassword;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n // check channel authorization\n 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) {\n var _ref15 = _slicedToArray(_ref14, 4),\n _ref15$ = _ref15[0],\n channelName = _ref15$.channelName,\n channelClaimId = _ref15$.channelClaimId,\n validatedClaimName = _ref15[1],\n publishParams = _ref15[2],\n thumbnailPublishParams = _ref15[3];\n\n // add channel details to the publish params\n if (channelName && channelClaimId) {\n publishParams['channel_name'] = channelName;\n publishParams['channel_id'] = channelClaimId;\n }\n // publish the thumbnail\n if (thumbnailPublishParams) {\n publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType);\n }\n // publish the asset\n return publish(publishParams, fileName, fileType);\n }).then(function (result) {\n res.status(200).json({\n success: true,\n message: 'publish completed successfully',\n data: {\n name: name,\n claimId: result.claim_id,\n url: host + '/' + result.claim_id + '/' + name,\n lbryTx: result\n }\n });\n // record the publish end time and send to google analytics\n sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to get a short claim id from long claim Id\n app.get('/api/claim/short-id/:longId/:name', function (_ref16, res) {\n var ip = _ref16.ip,\n originalUrl = _ref16.originalUrl,\n body = _ref16.body,\n params = _ref16.params;\n\n db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name).then(function (shortId) {\n res.status(200).json({ success: true, data: shortId });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n app.post('/api/claim/long-id', function (_ref17, res) {\n var ip = _ref17.ip,\n originalUrl = _ref17.originalUrl,\n body = _ref17.body,\n params = _ref17.params;\n\n logger.debug('body:', body);\n var channelName = body.channelName;\n var channelClaimId = body.channelClaimId;\n var claimName = body.claimName;\n var claimId = body.claimId;\n getClaimId(channelName, channelClaimId, claimName, claimId).then(function (result) {\n if (result === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'No matching channel could be found' });\n }\n if (result === NO_CLAIM) {\n return res.status(404).json({ success: false, message: 'No matching claim id could be found' });\n }\n res.status(200).json({ success: true, data: result });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n app.get('/api/claim/data/:claimName/:claimId', function (_ref18, res) {\n var ip = _ref18.ip,\n originalUrl = _ref18.originalUrl,\n body = _ref18.body,\n params = _ref18.params;\n\n var claimName = params.claimName;\n var claimId = params.claimId;\n if (claimId === 'none') claimId = null;\n db.Claim.resolveClaim(claimName, claimId).then(function (claimInfo) {\n if (!claimInfo) {\n return res.status(404).json({ success: false, message: 'No claim could be found' });\n }\n res.status(200).json({ success: true, data: claimInfo });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to see if asset is available locally\n app.get('/api/file/availability/:name/:claimId', function (_ref19, res) {\n var ip = _ref19.ip,\n originalUrl = _ref19.originalUrl,\n params = _ref19.params;\n\n var name = params.name;\n var claimId = params.claimId;\n db.File.findOne({ where: { name: name, claimId: claimId } }).then(function (result) {\n if (result) {\n return res.status(200).json({ success: true, data: true });\n }\n res.status(200).json({ success: true, data: false });\n }).catch(function (error) {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n};\n\n/***/ }),\n/* 72 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"connect-multiparty\");\n\n/***/ }),\n/* 73 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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\"); } }; }();\n\nfunction _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; }\n\nvar logger = __webpack_require__(2);\nvar db = __webpack_require__(6);\nvar lbryApi = __webpack_require__(16);\nvar publishHelpers = __webpack_require__(26);\n\nvar _require = __webpack_require__(5),\n _require$publishing = _require.publishing,\n primaryClaimAddress = _require$publishing.primaryClaimAddress,\n additionalClaimAddresses = _require$publishing.additionalClaimAddresses;\n\nvar Sequelize = __webpack_require__(24);\nvar Op = Sequelize.Op;\n\nmodule.exports = {\n publish: function publish(publishParams, fileName, fileType) {\n return new Promise(function (resolve, reject) {\n var publishResults = void 0,\n certificateId = void 0,\n channelName = void 0;\n // publish the file\n return lbryApi.publishClaim(publishParams).then(function (tx) {\n logger.info('Successfully published ' + publishParams.name + ' ' + fileName, tx);\n publishResults = tx;\n // get the channel information\n if (publishParams.channel_name) {\n logger.debug('this claim was published in channel: ' + publishParams.channel_name);\n return db.Channel.findOne({ where: { channelName: publishParams.channel_name } });\n } else {\n logger.debug('this claim was not published in a channel');\n return null;\n }\n }).then(function (channel) {\n // set channel information\n certificateId = null;\n channelName = null;\n if (channel) {\n certificateId = channel.channelClaimId;\n channelName = channel.channelName;\n }\n logger.debug('certificateId: ' + certificateId);\n }).then(function () {\n // create the File record\n var fileRecord = {\n name: publishParams.name,\n claimId: publishResults.claim_id,\n title: publishParams.metadata.title,\n description: publishParams.metadata.description,\n address: publishParams.claim_address,\n outpoint: publishResults.txid + ':' + publishResults.nout,\n height: 0,\n fileName: fileName,\n filePath: publishParams.file_path,\n fileType: fileType,\n nsfw: publishParams.metadata.nsfw\n };\n // create the Claim record\n var claimRecord = {\n name: publishParams.name,\n claimId: publishResults.claim_id,\n title: publishParams.metadata.title,\n description: publishParams.metadata.description,\n address: publishParams.claim_address,\n thumbnail: publishParams.metadata.thumbnail,\n outpoint: publishResults.txid + ':' + publishResults.nout,\n height: 0,\n contentType: fileType,\n nsfw: publishParams.metadata.nsfw,\n amount: publishParams.bid,\n certificateId: certificateId,\n channelName: channelName\n };\n // upsert criteria\n var upsertCriteria = {\n name: publishParams.name,\n claimId: publishResults.claim_id\n };\n // upsert the records\n return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]);\n }).then(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n file = _ref2[0],\n claim = _ref2[1];\n\n logger.debug('File and Claim records successfully created');\n return Promise.all([file.setClaim(claim), claim.setFile(file)]);\n }).then(function () {\n logger.debug('File and Claim records successfully associated');\n resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim;\n }).catch(function (error) {\n logger.error('PUBLISH ERROR', error);\n publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file\n reject(error);\n });\n });\n },\n claimNameIsAvailable: function claimNameIsAvailable(name) {\n var claimAddresses = additionalClaimAddresses || [];\n claimAddresses.push(primaryClaimAddress);\n // find any records where the name is used\n return db.Claim.findAll({\n attributes: ['address'],\n where: {\n name: name,\n address: _defineProperty({}, Op.or, claimAddresses)\n }\n }).then(function (result) {\n if (result.length >= 1) {\n throw new Error('That claim is already in use');\n };\n return name;\n }).catch(function (error) {\n throw error;\n });\n },\n checkChannelAvailability: function checkChannelAvailability(name) {\n return db.Channel.findAll({\n where: { channelName: name }\n }).then(function (result) {\n if (result.length >= 1) {\n throw new Error('That channel has already been claimed');\n }\n return name;\n }).catch(function (error) {\n throw error;\n });\n }\n};\n\n/***/ }),\n/* 74 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"fs\");\n\n/***/ }),\n/* 75 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar db = __webpack_require__(6);\nvar logger = __webpack_require__(2);\n\nmodule.exports = {\n authenticateUser: function authenticateUser(channelName, channelId, channelPassword, user) {\n // case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided\n if (!channelName && !channelId) {\n return {\n channelName: null,\n channelClaimId: null\n };\n }\n // case: channelName or channel Id are provided with user token\n if (user) {\n if (channelName && channelName !== user.channelName) {\n throw new Error('the provided channel name does not match user credentials');\n }\n if (channelId && channelId !== user.channelClaimId) {\n throw new Error('the provided channel id does not match user credentials');\n }\n return {\n channelName: user.channelName,\n channelClaimId: user.channelClaimId\n };\n }\n // case: channelName or channel Id are provided with password instead of user token\n if (!channelPassword) throw new Error('no channel password provided');\n return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword);\n },\n authenticateChannelCredentials: function authenticateChannelCredentials(channelName, channelId, userPassword) {\n return new Promise(function (resolve, reject) {\n // hoisted variables\n var channelData = void 0;\n // build the params for finding the channel\n var channelFindParams = {};\n if (channelName) channelFindParams['channelName'] = channelName;\n if (channelId) channelFindParams['channelClaimId'] = channelId;\n // find the channel\n db.Channel.findOne({\n where: channelFindParams\n }).then(function (channel) {\n if (!channel) {\n logger.debug('no channel found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n channelData = channel.get();\n logger.debug('channel data:', channelData);\n return db.User.findOne({\n where: { userName: channelData.channelName.substring(1) }\n });\n }).then(function (user) {\n if (!user) {\n logger.debug('no user found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n return user.comparePassword(userPassword);\n }).then(function (isMatch) {\n if (!isMatch) {\n logger.debug('incorrect password');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n logger.debug('...password was a match...');\n resolve(channelData);\n }).catch(function (error) {\n reject(error);\n });\n });\n }\n};\n\n/***/ }),\n/* 76 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar CLAIMS_PER_PAGE = 12;\n\nmodule.exports = {\n returnPaginatedChannelClaims: function returnPaginatedChannelClaims(channelName, longChannelClaimId, claims, page) {\n var totalPages = module.exports.determineTotalPages(claims);\n var paginationPage = module.exports.getPageFromQuery(page);\n var viewData = {\n channelName: channelName,\n longChannelClaimId: longChannelClaimId,\n claims: module.exports.extractPageFromClaims(claims, paginationPage),\n previousPage: module.exports.determinePreviousPage(paginationPage),\n currentPage: paginationPage,\n nextPage: module.exports.determineNextPage(totalPages, paginationPage),\n totalPages: totalPages,\n totalResults: module.exports.determineTotalClaims(claims)\n };\n return viewData;\n },\n getPageFromQuery: function getPageFromQuery(page) {\n if (page) {\n return parseInt(page);\n }\n return 1;\n },\n extractPageFromClaims: function extractPageFromClaims(claims, pageNumber) {\n if (!claims) {\n return []; // if no claims, return this default\n }\n // logger.debug('claims is array?', Array.isArray(claims));\n // logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));\n var claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;\n var claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;\n var pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);\n return pageOfClaims;\n },\n determineTotalPages: function determineTotalPages(claims) {\n if (!claims) {\n return 0;\n } else {\n var totalClaims = claims.length;\n if (totalClaims < CLAIMS_PER_PAGE) {\n return 1;\n }\n var fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE);\n var remainder = totalClaims % CLAIMS_PER_PAGE;\n if (remainder === 0) {\n return fullPages;\n }\n return fullPages + 1;\n }\n },\n determinePreviousPage: function determinePreviousPage(currentPage) {\n if (currentPage === 1) {\n return null;\n }\n return currentPage - 1;\n },\n determineNextPage: function determineNextPage(totalPages, currentPage) {\n if (currentPage === totalPages) {\n return null;\n }\n return currentPage + 1;\n },\n determineTotalClaims: function determineTotalClaims(claims) {\n if (!claims) {\n return 0;\n }\n return claims.length;\n }\n};\n\n/***/ }),\n/* 77 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(5),\n host = _require.details;\n\nvar handlePageRender = __webpack_require__(29);\n\nmodule.exports = function (app) {\n // route for the home page\n app.get('/', function (req, res) {\n handlePageRender(req, res);\n });\n // route to display login page\n app.get('/login', function (req, res) {\n handlePageRender(req, res);\n });\n // route to show 'about' page\n app.get('/about', function (req, res) {\n handlePageRender(req, res);\n });\n // route to display a list of the trending images\n app.get('/trending', function (req, res) {\n res.status(301).redirect('/popular');\n });\n app.get('/popular', function (req, res) {\n handlePageRender(req, res);\n });\n // route to display a list of the trending images\n app.get('/new', function (req, res) {\n handlePageRender(req, res);\n });\n // route to send embedable video player (for twitter)\n app.get('/embed/:claimId/:name', function (_ref, res) {\n var params = _ref.params;\n\n var claimId = params.claimId;\n var name = params.name;\n // get and render the content\n res.status(200).render('embed', { layout: 'embed', host: host, claimId: claimId, name: name });\n });\n};\n\n/***/ }),\n/* 78 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function () {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;\n var action = arguments[1];\n\n switch (action.type) {\n case actions.FILE_SELECTED:\n return Object.assign({}, initialState, { // note: clears to initial state\n file: action.data\n });\n case actions.FILE_CLEAR:\n return initialState;\n case actions.METADATA_UPDATE:\n return Object.assign({}, state, {\n metadata: Object.assign({}, state.metadata, _defineProperty({}, action.data.name, action.data.value))\n });\n case actions.CLAIM_UPDATE:\n return Object.assign({}, state, {\n claim: action.data\n });\n case actions.SET_PUBLISH_IN_CHANNEL:\n return Object.assign({}, state, {\n publishInChannel: action.channel\n });\n case actions.PUBLISH_STATUS_UPDATE:\n return Object.assign({}, state, {\n status: action.data\n });\n case actions.ERROR_UPDATE:\n return Object.assign({}, state, {\n error: Object.assign({}, state.error, _defineProperty({}, action.data.name, action.data.value))\n });\n case actions.SELECTED_CHANNEL_UPDATE:\n return Object.assign({}, state, {\n selectedChannel: action.data\n });\n case actions.TOGGLE_METADATA_INPUTS:\n return Object.assign({}, state, {\n showMetadataInputs: action.data\n });\n case actions.THUMBNAIL_NEW:\n return Object.assign({}, state, {\n thumbnail: action.data\n });\n default:\n return state;\n }\n};\n\nvar _publish_action_types = __webpack_require__(32);\n\nvar actions = _interopRequireWildcard(_publish_action_types);\n\nvar _publish_channel_select_states = __webpack_require__(33);\n\nfunction _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; } }\n\nfunction _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; }\n\nvar _require = __webpack_require__(5),\n publishing = _require.publishing;\n\nvar initialState = {\n disabled: publishing.disabled,\n disabledMessage: publishing.disabledMessage,\n publishInChannel: false,\n selectedChannel: _publish_channel_select_states.LOGIN,\n showMetadataInputs: false,\n status: {\n status: null,\n message: null\n },\n error: {\n file: null,\n url: null,\n channel: null,\n publishSubmit: null\n },\n file: null,\n claim: '',\n metadata: {\n title: '',\n description: '',\n license: '',\n nsfw: false\n },\n thumbnail: null\n};\n\n/***/ }),\n/* 79 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function () {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;\n var action = arguments[1];\n\n switch (action.type) {\n case actions.CHANNEL_UPDATE:\n return Object.assign({}, state, {\n loggedInChannel: action.data\n });\n default:\n return state;\n }\n};\n\nvar _channel_action_types = __webpack_require__(34);\n\nvar actions = _interopRequireWildcard(_channel_action_types);\n\nfunction _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; } }\n\nvar initialState = {\n loggedInChannel: {\n name: null,\n shortId: null,\n longId: null\n }\n};\n\n/***/ }),\n/* 80 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function () {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;\n var action = arguments[1];\n\n switch (action.type) {\n // handle request\n case actions.REQUEST_ERROR:\n return Object.assign({}, state, {\n request: Object.assign({}, state.request, {\n error: action.data\n })\n });\n case actions.REQUEST_UPDATE:\n return Object.assign({}, state, {\n request: Object.assign({}, state.request, {\n type: action.data.requestType,\n id: action.data.requestId\n })\n });\n // store requests\n case actions.REQUEST_LIST_ADD:\n return Object.assign({}, state, {\n requestList: Object.assign({}, state.requestList, _defineProperty({}, action.data.id, {\n error: action.data.error,\n key: action.data.key\n }))\n });\n // asset data\n case actions.ASSET_ADD:\n return Object.assign({}, state, {\n assetList: Object.assign({}, state.assetList, _defineProperty({}, action.data.id, {\n error: action.data.error,\n name: action.data.name,\n claimId: action.data.claimId,\n shortId: action.data.shortId,\n claimData: action.data.claimData\n }))\n });\n // channel data\n case actions.CHANNEL_ADD:\n return Object.assign({}, state, {\n channelList: Object.assign({}, state.channelList, _defineProperty({}, action.data.id, {\n name: action.data.name,\n longId: action.data.longId,\n shortId: action.data.shortId,\n claimsData: action.data.claimsData\n }))\n });\n case actions.CHANNEL_CLAIMS_UPDATE_SUCCESS:\n return Object.assign({}, state, {\n channelList: Object.assign({}, state.channelList, _defineProperty({}, action.data.channelListId, Object.assign({}, state.channelList[action.data.channelListId], {\n claimsData: action.data.claimsData\n })))\n });\n // display an asset\n case actions.FILE_AVAILABILITY_UPDATE:\n return Object.assign({}, state, {\n displayAsset: Object.assign({}, state.displayAsset, {\n status: action.data\n })\n });\n case actions.DISPLAY_ASSET_ERROR:\n return Object.assign({}, state, {\n displayAsset: Object.assign({}, state.displayAsset, {\n error: action.data,\n status: _asset_display_states.ERROR\n })\n });\n default:\n return state;\n }\n};\n\nvar _show_action_types = __webpack_require__(12);\n\nvar actions = _interopRequireWildcard(_show_action_types);\n\nvar _asset_display_states = __webpack_require__(35);\n\nfunction _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; } }\n\nfunction _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; }\n\nvar initialState = {\n request: {\n error: null,\n type: null,\n id: null\n },\n requestList: {},\n channelList: {},\n assetList: {},\n displayAsset: {\n error: null,\n status: _asset_display_states.LOCAL_CHECK\n }\n};\n\n/***/ }),\n/* 81 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function () {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;\n var action = arguments[1];\n\n switch (action.type) {\n default:\n return state;\n }\n};\n\nvar siteConfig = __webpack_require__(5);\n\nvar googleAnalyticsId = siteConfig.analytics.googleId,\n _siteConfig$assetDefa = siteConfig.assetDefaults,\n defaultThumbnail = _siteConfig$assetDefa.thumbnail,\n defaultDescription = _siteConfig$assetDefa.description,\n _siteConfig$details = siteConfig.details,\n description = _siteConfig$details.description,\n host = _siteConfig$details.host,\n title = _siteConfig$details.title,\n twitter = _siteConfig$details.twitter;\n\n\nvar initialState = {\n description: description,\n googleAnalyticsId: googleAnalyticsId,\n host: host,\n title: title,\n twitter: twitter,\n defaultDescription: defaultDescription,\n defaultThumbnail: defaultThumbnail\n};\n\n/***/ }),\n/* 82 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"react-ga\");\n\n/***/ }),\n/* 83 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _SEO = __webpack_require__(9);\n\nvar _SEO2 = _interopRequireDefault(_SEO);\n\nvar _NavBar = __webpack_require__(7);\n\nvar _NavBar2 = _interopRequireDefault(_NavBar);\n\nvar _PublishTool = __webpack_require__(92);\n\nvar _PublishTool2 = _interopRequireDefault(_PublishTool);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar HomePage = function (_React$Component) {\n _inherits(HomePage, _React$Component);\n\n function HomePage() {\n _classCallCheck(this, HomePage);\n\n return _possibleConstructorReturn(this, (HomePage.__proto__ || Object.getPrototypeOf(HomePage)).apply(this, arguments));\n }\n\n _createClass(HomePage, [{\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n { className: 'row row--tall flex-container--column' },\n _react2.default.createElement(_SEO2.default, null),\n _react2.default.createElement(_NavBar2.default, null),\n _react2.default.createElement(\n 'div',\n { className: 'row row--tall row--padded flex-container--column' },\n _react2.default.createElement(_PublishTool2.default, null)\n )\n );\n }\n }]);\n\n return HomePage;\n}(_react2.default.Component);\n\n;\n\nexports.default = HomePage;\n\n/***/ }),\n/* 84 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactHelmet = __webpack_require__(14);\n\nvar _reactHelmet2 = _interopRequireDefault(_reactHelmet);\n\nvar _propTypes = __webpack_require__(10);\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nvar _pageTitle = __webpack_require__(85);\n\nvar _metaTags = __webpack_require__(86);\n\nvar _canonicalLink = __webpack_require__(87);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar SEO = function (_React$Component) {\n _inherits(SEO, _React$Component);\n\n function SEO() {\n _classCallCheck(this, SEO);\n\n return _possibleConstructorReturn(this, (SEO.__proto__ || Object.getPrototypeOf(SEO)).apply(this, arguments));\n }\n\n _createClass(SEO, [{\n key: 'render',\n value: function render() {\n // props from state\n var _props = this.props,\n defaultDescription = _props.defaultDescription,\n defaultThumbnail = _props.defaultThumbnail,\n siteDescription = _props.siteDescription,\n siteHost = _props.siteHost,\n siteTitle = _props.siteTitle,\n siteTwitter = _props.siteTwitter;\n // props from parent\n\n var _props2 = this.props,\n asset = _props2.asset,\n channel = _props2.channel,\n pageUri = _props2.pageUri;\n var pageTitle = this.props.pageTitle;\n // create page title, tags, and canonical link\n\n pageTitle = (0, _pageTitle.createPageTitle)(siteTitle, pageTitle);\n var metaTags = (0, _metaTags.createMetaTags)(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail);\n var canonicalLink = (0, _canonicalLink.createCanonicalLink)(asset, channel, pageUri, siteHost);\n // render results\n return _react2.default.createElement(_reactHelmet2.default, {\n title: pageTitle,\n meta: metaTags,\n link: [{ rel: 'canonical', href: canonicalLink }]\n });\n }\n }]);\n\n return SEO;\n}(_react2.default.Component);\n\n;\n\nSEO.propTypes = {\n pageTitle: _propTypes2.default.string,\n pageUri: _propTypes2.default.string,\n channel: _propTypes2.default.object,\n asset: _propTypes2.default.object\n};\n\nexports.default = SEO;\n\n/***/ }),\n/* 85 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar createPageTitle = exports.createPageTitle = function createPageTitle(siteTitle, pageTitle) {\n if (!pageTitle) {\n return \"\" + siteTitle;\n }\n return siteTitle + \" - \" + pageTitle;\n};\n\n/***/ }),\n/* 86 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar determineOgThumbnailContentType = function determineOgThumbnailContentType(thumbnail) {\n if (thumbnail) {\n var fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));\n switch (fileExt) {\n case 'jpeg':\n case 'jpg':\n return 'image/jpeg';\n case 'png':\n return 'image/png';\n case 'gif':\n return 'image/gif';\n case 'mp4':\n return 'video/mp4';\n default:\n return 'image/jpeg';\n }\n }\n return '';\n};\n\nvar createBasicMetaTags = function createBasicMetaTags(siteHost, siteDescription, siteTitle, siteTwitter) {\n return [{ property: 'og:title', content: siteTitle }, { property: 'og:url', content: siteHost }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: siteDescription }, { property: 'twitter:site', content: siteTwitter }, { property: 'twitter:card', content: 'summary' }];\n};\n\nvar createChannelMetaTags = function createChannelMetaTags(siteTitle, siteHost, siteTwitter, channel) {\n var name = channel.name,\n longId = channel.longId;\n\n return [{ property: 'og:title', content: name + ' on ' + siteTitle }, { property: 'og:url', content: siteHost + '/' + name + ':' + longId }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: name + ', a channel on ' + siteTitle }, { property: 'twitter:site', content: siteTwitter }, { property: 'twitter:card', content: 'summary' }];\n};\n\nvar createAssetMetaTags = function createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail) {\n var claimData = asset.claimData;\n var contentType = claimData.contentType;\n\n var embedUrl = siteHost + '/' + claimData.claimId + '/' + claimData.name;\n var showUrl = siteHost + '/' + claimData.claimId + '/' + claimData.name;\n var source = siteHost + '/' + claimData.claimId + '/' + claimData.name + '.' + claimData.fileExt;\n var ogTitle = claimData.title || claimData.name;\n var ogDescription = claimData.description || defaultDescription;\n var ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);\n var ogThumbnail = claimData.thumbnail || defaultThumbnail;\n var metaTags = [{ property: 'og:title', content: ogTitle }, { property: 'og:url', content: showUrl }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: ogDescription }, { property: 'og:image:width', content: 600 }, { property: 'og:image:height', content: 315 }, { property: 'twitter:site', content: siteTwitter }];\n if (contentType === 'video/mp4' || contentType === 'video/webm') {\n metaTags.push({ property: 'og:video', content: source });\n metaTags.push({ property: 'og:video:secure_url', content: source });\n metaTags.push({ property: 'og:video:type', content: contentType });\n metaTags.push({ property: 'og:image', content: ogThumbnail });\n metaTags.push({ property: 'og:image:type', content: ogThumbnailContentType });\n metaTags.push({ property: 'og:type', content: 'video' });\n metaTags.push({ property: 'twitter:card', content: 'player' });\n metaTags.push({ property: 'twitter:player', content: embedUrl });\n metaTags.push({ property: 'twitter:player:width', content: 600 });\n metaTags.push({ property: 'twitter:text:player_width', content: 600 });\n metaTags.push({ property: 'twitter:player:height', content: 337 });\n metaTags.push({ property: 'twitter:player:stream', content: source });\n metaTags.push({ property: 'twitter:player:stream:content_type', content: contentType });\n } else {\n metaTags.push({ property: 'og:image', content: source });\n metaTags.push({ property: 'og:image:type', content: contentType });\n metaTags.push({ property: 'og:type', content: 'article' });\n metaTags.push({ property: 'twitter:card', content: 'summary_large_image' });\n }\n return metaTags;\n};\n\nvar createMetaTags = exports.createMetaTags = function createMetaTags(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail) {\n if (asset) {\n return createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail);\n };\n if (channel) {\n return createChannelMetaTags(siteHost, siteTitle, siteTwitter, channel);\n };\n return createBasicMetaTags(siteDescription, siteHost, siteTitle, siteTwitter);\n};\n\n/***/ }),\n/* 87 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar createBasicCanonicalLink = function createBasicCanonicalLink(page, siteHost) {\n return siteHost + \"/\" + page;\n};\n\nvar createAssetCanonicalLink = function createAssetCanonicalLink(asset, siteHost) {\n var channelName = void 0,\n certificateId = void 0,\n name = void 0,\n claimId = void 0;\n if (asset.claimData) {\n var _asset$claimData = asset.claimData;\n channelName = _asset$claimData.channelName;\n certificateId = _asset$claimData.certificateId;\n name = _asset$claimData.name;\n claimId = _asset$claimData.claimId;\n };\n if (channelName) {\n return siteHost + \"/\" + channelName + \":\" + certificateId + \"/\" + name;\n };\n return siteHost + \"/\" + claimId + \"/\" + name;\n};\n\nvar createChannelCanonicalLink = function createChannelCanonicalLink(channel, siteHost) {\n var name = channel.name,\n longId = channel.longId;\n\n return siteHost + \"/\" + name + \":\" + longId;\n};\n\nvar createCanonicalLink = exports.createCanonicalLink = function createCanonicalLink(asset, channel, page, siteHost) {\n if (asset) {\n return createAssetCanonicalLink(asset, siteHost);\n }\n if (channel) {\n return createChannelCanonicalLink(channel, siteHost);\n }\n return createBasicCanonicalLink(page, siteHost);\n};\n\n/***/ }),\n/* 88 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nvar _Logo = __webpack_require__(89);\n\nvar _Logo2 = _interopRequireDefault(_Logo);\n\nvar _NavBarChannelOptionsDropdown = __webpack_require__(90);\n\nvar _NavBarChannelOptionsDropdown2 = _interopRequireDefault(_NavBarChannelOptionsDropdown);\n\nvar _request = __webpack_require__(11);\n\nvar _request2 = _interopRequireDefault(_request);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar VIEW = 'VIEW';\nvar LOGOUT = 'LOGOUT';\n\nvar NavBar = function (_React$Component) {\n _inherits(NavBar, _React$Component);\n\n function NavBar(props) {\n _classCallCheck(this, NavBar);\n\n var _this = _possibleConstructorReturn(this, (NavBar.__proto__ || Object.getPrototypeOf(NavBar)).call(this, props));\n\n _this.checkForLoggedInUser = _this.checkForLoggedInUser.bind(_this);\n _this.logoutUser = _this.logoutUser.bind(_this);\n _this.handleSelection = _this.handleSelection.bind(_this);\n return _this;\n }\n\n _createClass(NavBar, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n // check to see if the user is already logged in\n this.checkForLoggedInUser();\n }\n }, {\n key: 'checkForLoggedInUser',\n value: function checkForLoggedInUser() {\n var _this2 = this;\n\n var params = { credentials: 'include' };\n (0, _request2.default)('/user', params).then(function (_ref) {\n var data = _ref.data;\n\n _this2.props.onChannelLogin(data.channelName, data.shortChannelId, data.channelClaimId);\n }).catch(function (error) {\n console.log('/user error:', error.message);\n });\n }\n }, {\n key: 'logoutUser',\n value: function logoutUser() {\n var _this3 = this;\n\n var params = { credentials: 'include' };\n (0, _request2.default)('/logout', params).then(function () {\n _this3.props.onChannelLogout();\n }).catch(function (error) {\n console.log('/logout error', error.message);\n });\n }\n }, {\n key: 'handleSelection',\n value: function handleSelection(event) {\n var value = event.target.selectedOptions[0].value;\n switch (value) {\n case LOGOUT:\n this.logoutUser();\n break;\n case VIEW:\n // redirect to channel page\n this.props.history.push('/' + this.props.channelName + ':' + this.props.channelLongId);\n break;\n default:\n break;\n }\n }\n }, {\n key: 'render',\n value: function render() {\n var siteDescription = this.props.siteDescription;\n\n return _react2.default.createElement(\n 'div',\n { className: 'row row--wide nav-bar' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--short flex-container--row flex-container--space-between-center' },\n _react2.default.createElement(_Logo2.default, null),\n _react2.default.createElement(\n 'div',\n { className: 'nav-bar--center' },\n _react2.default.createElement(\n 'span',\n { className: 'nav-bar-tagline' },\n siteDescription\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'nav-bar--right' },\n _react2.default.createElement(\n _reactRouterDom.NavLink,\n { className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/', exact: true },\n 'Publish'\n ),\n _react2.default.createElement(\n _reactRouterDom.NavLink,\n { className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/about' },\n 'About'\n ),\n this.props.channelName ? _react2.default.createElement(_NavBarChannelOptionsDropdown2.default, {\n channelName: this.props.channelName,\n handleSelection: this.handleSelection,\n defaultSelection: this.props.channelName,\n VIEW: VIEW,\n LOGOUT: LOGOUT\n }) : _react2.default.createElement(\n _reactRouterDom.NavLink,\n { id: 'nav-bar-login-link', className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/login' },\n 'Channel'\n )\n )\n )\n );\n }\n }]);\n\n return NavBar;\n}(_react2.default.Component);\n\nexports.default = (0, _reactRouterDom.withRouter)(NavBar);\n\n/***/ }),\n/* 89 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction Logo() {\n return _react2.default.createElement(\n 'svg',\n { 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' },\n _react2.default.createElement(\n _reactRouterDom.Link,\n { to: '/' },\n _react2.default.createElement(\n 'title',\n null,\n 'Logo'\n ),\n _react2.default.createElement(\n 'desc',\n null,\n 'Spee.ch logo'\n ),\n _react2.default.createElement(\n 'g',\n { id: 'About' },\n _react2.default.createElement(\n 'g',\n { id: 'Publish-Form-V2-_x28_filled_x29_', transform: 'translate(-42.000000, -23.000000)' },\n _react2.default.createElement(\n 'g',\n { id: 'Group-17', transform: 'translate(42.000000, 22.000000)' },\n _react2.default.createElement(\n 'text',\n { transform: 'matrix(1 0 0 1 0 20)', fontSize: '25', fontFamily: 'Roboto' },\n 'Spee 10000000) {\n throw new Error('Sorry, images are limited to 10 megabytes.');\n }\n break;\n case 'image/gif':\n if (file.size > 50000000) {\n throw new Error('Sorry, GIFs are limited to 50 megabytes.');\n }\n break;\n case 'video/mp4':\n if (file.size > 50000000) {\n throw new Error('Sorry, videos are limited to 50 megabytes.');\n }\n break;\n default:\n throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');\n }\n }\n};\n\n/***/ }),\n/* 96 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _propTypes = __webpack_require__(10);\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar PublishPreview = function (_React$Component) {\n _inherits(PublishPreview, _React$Component);\n\n function PublishPreview(props) {\n _classCallCheck(this, PublishPreview);\n\n var _this = _possibleConstructorReturn(this, (PublishPreview.__proto__ || Object.getPrototypeOf(PublishPreview)).call(this, props));\n\n _this.state = {\n imgSource: '',\n defaultThumbnail: '/assets/img/video_thumb_default.png'\n };\n return _this;\n }\n\n _createClass(PublishPreview, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n this.setPreviewImageSource(this.props.file);\n }\n }, {\n key: 'componentWillReceiveProps',\n value: function componentWillReceiveProps(newProps) {\n if (newProps.file !== this.props.file) {\n this.setPreviewImageSource(newProps.file);\n }\n if (newProps.thumbnail !== this.props.thumbnail) {\n if (newProps.thumbnail) {\n this.setPreviewImageSourceFromFile(newProps.thumbnail);\n } else {\n this.setState({ imgSource: this.state.defaultThumbnail });\n }\n }\n }\n }, {\n key: 'setPreviewImageSourceFromFile',\n value: function setPreviewImageSourceFromFile(file) {\n var _this2 = this;\n\n var previewReader = new FileReader();\n previewReader.readAsDataURL(file);\n previewReader.onloadend = function () {\n _this2.setState({ imgSource: previewReader.result });\n };\n }\n }, {\n key: 'setPreviewImageSource',\n value: function setPreviewImageSource(file) {\n if (file.type !== 'video/mp4') {\n this.setPreviewImageSourceFromFile(file);\n } else {\n if (this.props.thumbnail) {\n this.setPreviewImageSourceFromFile(this.props.thumbnail);\n }\n this.setState({ imgSource: this.state.defaultThumbnail });\n }\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement('img', {\n id: 'dropzone-preview',\n src: this.state.imgSource,\n className: this.props.dimPreview ? 'dim' : '',\n alt: 'publish preview'\n });\n }\n }]);\n\n return PublishPreview;\n}(_react2.default.Component);\n\n;\n\nPublishPreview.propTypes = {\n dimPreview: _propTypes2.default.bool.isRequired,\n file: _propTypes2.default.object.isRequired,\n thumbnail: _propTypes2.default.object\n};\n\nexports.default = PublishPreview;\n\n/***/ }),\n/* 97 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _publish = __webpack_require__(4);\n\nvar _view = __webpack_require__(98);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var channel = _ref.channel,\n publish = _ref.publish;\n\n return {\n file: publish.file\n };\n};\n\nvar mapDispatchToProps = {\n clearFile: _publish.clearFile,\n startPublish: _publish.startPublish\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 98 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nvar _Dropzone = __webpack_require__(38);\n\nvar _Dropzone2 = _interopRequireDefault(_Dropzone);\n\nvar _PublishTitleInput = __webpack_require__(99);\n\nvar _PublishTitleInput2 = _interopRequireDefault(_PublishTitleInput);\n\nvar _PublishUrlInput = __webpack_require__(101);\n\nvar _PublishUrlInput2 = _interopRequireDefault(_PublishUrlInput);\n\nvar _PublishThumbnailInput = __webpack_require__(104);\n\nvar _PublishThumbnailInput2 = _interopRequireDefault(_PublishThumbnailInput);\n\nvar _PublishMetadataInputs = __webpack_require__(106);\n\nvar _PublishMetadataInputs2 = _interopRequireDefault(_PublishMetadataInputs);\n\nvar _ChannelSelect = __webpack_require__(109);\n\nvar _ChannelSelect2 = _interopRequireDefault(_ChannelSelect);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar PublishDetails = function (_React$Component) {\n _inherits(PublishDetails, _React$Component);\n\n function PublishDetails(props) {\n _classCallCheck(this, PublishDetails);\n\n var _this = _possibleConstructorReturn(this, (PublishDetails.__proto__ || Object.getPrototypeOf(PublishDetails)).call(this, props));\n\n _this.onPublishSubmit = _this.onPublishSubmit.bind(_this);\n return _this;\n }\n\n _createClass(PublishDetails, [{\n key: 'onPublishSubmit',\n value: function onPublishSubmit() {\n this.props.startPublish(this.props.history);\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n { className: 'row row--no-bottom' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--10' },\n _react2.default.createElement(_PublishTitleInput2.default, null)\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--5 column--sml-10' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded' },\n _react2.default.createElement(_Dropzone2.default, null)\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--5 column--sml-10 align-content-top' },\n _react2.default.createElement(\n 'div',\n { id: 'publish-active-area', className: 'row row--padded' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--no-top row--wide' },\n _react2.default.createElement(_PublishUrlInput2.default, null)\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--no-top row--wide' },\n _react2.default.createElement(_ChannelSelect2.default, null)\n ),\n this.props.file.type === 'video/mp4' && _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--no-top row--wide ' },\n _react2.default.createElement(_PublishThumbnailInput2.default, null)\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--no-top row--no-bottom row--wide' },\n _react2.default.createElement(_PublishMetadataInputs2.default, null)\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--wide align-content-center' },\n _react2.default.createElement(\n 'button',\n { id: 'publish-submit', className: 'button--primary button--large', onClick: this.onPublishSubmit },\n 'Publish'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--no-bottom align-content-center' },\n _react2.default.createElement(\n 'button',\n { className: 'button--cancel', onClick: this.props.clearFile },\n 'Cancel'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--short align-content-center' },\n _react2.default.createElement(\n 'p',\n { className: 'fine-print' },\n '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. ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://lbry.io/learn' },\n 'Read more.'\n )\n )\n )\n )\n )\n );\n }\n }]);\n\n return PublishDetails;\n}(_react2.default.Component);\n\n;\n\nexports.default = (0, _reactRouterDom.withRouter)(PublishDetails);\n\n/***/ }),\n/* 99 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _publish = __webpack_require__(4);\n\nvar _view = __webpack_require__(100);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var publish = _ref.publish;\n\n return {\n title: publish.metadata.title\n };\n};\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n onMetadataChange: function onMetadataChange(name, value) {\n dispatch((0, _publish.updateMetadata)(name, value));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 100 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar PublishTitleInput = function (_React$Component) {\n _inherits(PublishTitleInput, _React$Component);\n\n function PublishTitleInput(props) {\n _classCallCheck(this, PublishTitleInput);\n\n var _this = _possibleConstructorReturn(this, (PublishTitleInput.__proto__ || Object.getPrototypeOf(PublishTitleInput)).call(this, props));\n\n _this.handleInput = _this.handleInput.bind(_this);\n return _this;\n }\n\n _createClass(PublishTitleInput, [{\n key: 'handleInput',\n value: function handleInput(e) {\n var name = e.target.name;\n var value = e.target.value;\n this.props.onMetadataChange(name, value);\n }\n }, {\n key: 'render',\n value: function render() {\n 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 });\n }\n }]);\n\n return PublishTitleInput;\n}(_react2.default.Component);\n\nexports.default = PublishTitleInput;\n\n/***/ }),\n/* 101 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _publish = __webpack_require__(4);\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(102);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var channel = _ref.channel,\n publish = _ref.publish;\n\n return {\n loggedInChannelName: channel.loggedInChannel.name,\n loggedInChannelShortId: channel.loggedInChannel.shortId,\n fileName: publish.file.name,\n publishInChannel: publish.publishInChannel,\n selectedChannel: publish.selectedChannel,\n claim: publish.claim,\n urlError: publish.error.url\n };\n};\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n onClaimChange: function onClaimChange(value) {\n dispatch((0, _publish.updateClaim)(value));\n dispatch((0, _publish.updateError)('publishSubmit', null));\n },\n onUrlError: function onUrlError(value) {\n dispatch((0, _publish.updateError)('url', value));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 102 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _request = __webpack_require__(11);\n\nvar _request2 = _interopRequireDefault(_request);\n\nvar _PublishUrlMiddleDisplay = __webpack_require__(103);\n\nvar _PublishUrlMiddleDisplay2 = _interopRequireDefault(_PublishUrlMiddleDisplay);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar PublishUrlInput = function (_React$Component) {\n _inherits(PublishUrlInput, _React$Component);\n\n function PublishUrlInput(props) {\n _classCallCheck(this, PublishUrlInput);\n\n var _this = _possibleConstructorReturn(this, (PublishUrlInput.__proto__ || Object.getPrototypeOf(PublishUrlInput)).call(this, props));\n\n _this.handleInput = _this.handleInput.bind(_this);\n return _this;\n }\n\n _createClass(PublishUrlInput, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n var _props = this.props,\n claim = _props.claim,\n fileName = _props.fileName;\n\n if (!claim) {\n this.setClaimName(fileName);\n }\n }\n }, {\n key: 'componentWillReceiveProps',\n value: function componentWillReceiveProps(_ref) {\n var claim = _ref.claim,\n fileName = _ref.fileName;\n\n // if a new file was chosen, update the claim name\n if (fileName !== this.props.fileName) {\n return this.setClaimName(fileName);\n }\n // if the claim has updated, check its availability\n if (claim !== this.props.claim) {\n this.validateClaim(claim);\n }\n }\n }, {\n key: 'handleInput',\n value: function handleInput(event) {\n var value = event.target.value;\n value = this.cleanseInput(value);\n // update the state\n this.props.onClaimChange(value);\n }\n }, {\n key: 'cleanseInput',\n value: function cleanseInput(input) {\n input = input.replace(/\\s+/g, '-'); // replace spaces with dashes\n input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'\n return input;\n }\n }, {\n key: 'setClaimName',\n value: function setClaimName(fileName) {\n var fileNameWithoutEnding = fileName.substring(0, fileName.lastIndexOf('.'));\n var cleanClaimName = this.cleanseInput(fileNameWithoutEnding);\n this.props.onClaimChange(cleanClaimName);\n }\n }, {\n key: 'validateClaim',\n value: function validateClaim(claim) {\n var _this2 = this;\n\n if (!claim) {\n return this.props.onUrlError('Enter a url above');\n }\n (0, _request2.default)('/api/claim/availability/' + claim).then(function () {\n _this2.props.onUrlError(null);\n }).catch(function (error) {\n _this2.props.onUrlError(error.message);\n });\n }\n }, {\n key: 'render',\n value: function render() {\n var _props2 = this.props,\n claim = _props2.claim,\n loggedInChannelName = _props2.loggedInChannelName,\n loggedInChannelShortId = _props2.loggedInChannelShortId,\n publishInChannel = _props2.publishInChannel,\n selectedChannel = _props2.selectedChannel,\n urlError = _props2.urlError;\n\n return _react2.default.createElement(\n 'div',\n { className: 'column column--10 column--sml-10' },\n _react2.default.createElement(\n 'div',\n { className: 'input-text--primary span--relative' },\n _react2.default.createElement(\n 'span',\n { className: 'url-text--secondary' },\n 'spee.ch / '\n ),\n _react2.default.createElement(_PublishUrlMiddleDisplay2.default, {\n publishInChannel: publishInChannel,\n selectedChannel: selectedChannel,\n loggedInChannelName: loggedInChannelName,\n loggedInChannelShortId: loggedInChannelShortId\n }),\n _react2.default.createElement('input', { type: 'text', id: 'claim-name-input', className: 'input-text', name: 'claim', placeholder: 'your-url-here', onChange: this.handleInput, value: claim }),\n claim && !urlError && _react2.default.createElement(\n 'span',\n { id: 'input-success-claim-name', className: 'info-message--success span--absolute' },\n '\\u2713'\n ),\n urlError && _react2.default.createElement(\n 'span',\n { id: 'input-success-channel-name', className: 'info-message--failure span--absolute' },\n '\\u2716'\n )\n ),\n _react2.default.createElement(\n 'div',\n null,\n urlError ? _react2.default.createElement(\n 'p',\n { id: 'input-error-claim-name', className: 'info-message--failure' },\n urlError\n ) : _react2.default.createElement(\n 'p',\n { className: 'info-message' },\n 'Choose a custom url'\n )\n )\n );\n }\n }]);\n\n return PublishUrlInput;\n}(_react2.default.Component);\n\nexports.default = PublishUrlInput;\n\n/***/ }),\n/* 103 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _propTypes = __webpack_require__(10);\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction UrlMiddle(_ref) {\n var publishInChannel = _ref.publishInChannel,\n selectedChannel = _ref.selectedChannel,\n loggedInChannelName = _ref.loggedInChannelName,\n loggedInChannelShortId = _ref.loggedInChannelShortId;\n\n if (publishInChannel) {\n if (selectedChannel === loggedInChannelName) {\n return _react2.default.createElement(\n 'span',\n { id: 'url-channel', className: 'url-text--secondary' },\n loggedInChannelName,\n ':',\n loggedInChannelShortId,\n ' /'\n );\n }\n return _react2.default.createElement(\n 'span',\n { id: 'url-channel-placeholder', className: 'url-text--secondary tooltip' },\n '@channel',\n _react2.default.createElement(\n 'span',\n {\n className: 'tooltip-text' },\n 'Select a channel below'\n ),\n ' /'\n );\n }\n return _react2.default.createElement(\n 'span',\n { id: 'url-no-channel-placeholder', className: 'url-text--secondary tooltip' },\n 'xyz',\n _react2.default.createElement(\n 'span',\n { className: 'tooltip-text' },\n 'This will be a random id'\n ),\n ' /'\n );\n}\n\nUrlMiddle.propTypes = {\n publishInChannel: _propTypes2.default.bool.isRequired,\n loggedInChannelName: _propTypes2.default.string,\n loggedInChannelShortId: _propTypes2.default.string\n};\n\nexports.default = UrlMiddle;\n\n/***/ }),\n/* 104 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _publish = __webpack_require__(4);\n\nvar _view = __webpack_require__(105);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var file = _ref.publish.file;\n\n return {\n file: file\n };\n};\n\nvar mapDispatchToProps = {\n onNewThumbnail: _publish.onNewThumbnail\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 105 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nfunction dataURItoBlob(dataURI) {\n // convert base64/URLEncoded data component to raw binary data held in a string\n var byteString = atob(dataURI.split(',')[1]);\n // separate out the mime component\n var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];\n // write the bytes of the string to a typed array\n var ia = new Uint8Array(byteString.length);\n for (var i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n return new Blob([ia], { type: mimeString });\n}\n\nvar PublishThumbnailInput = function (_React$Component) {\n _inherits(PublishThumbnailInput, _React$Component);\n\n function PublishThumbnailInput(props) {\n _classCallCheck(this, PublishThumbnailInput);\n\n var _this = _possibleConstructorReturn(this, (PublishThumbnailInput.__proto__ || Object.getPrototypeOf(PublishThumbnailInput)).call(this, props));\n\n _this.state = {\n videoSource: null,\n error: null,\n sliderMinRange: 1,\n sliderMaxRange: null,\n sliderValue: null\n };\n _this.handleVideoLoadedData = _this.handleVideoLoadedData.bind(_this);\n _this.handleSliderChange = _this.handleSliderChange.bind(_this);\n _this.createThumbnail = _this.createThumbnail.bind(_this);\n return _this;\n }\n\n _createClass(PublishThumbnailInput, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n var file = this.props.file;\n\n this.setVideoSource(file);\n }\n }, {\n key: 'componentWillReceiveProps',\n value: function componentWillReceiveProps(nextProps) {\n // if file changes\n if (nextProps.file && nextProps.file !== this.props.file) {\n var file = nextProps.file;\n\n this.setVideoSource(file);\n };\n }\n }, {\n key: 'setVideoSource',\n value: function setVideoSource(file) {\n var _this2 = this;\n\n var previewReader = new FileReader();\n previewReader.readAsDataURL(file);\n previewReader.onloadend = function () {\n var dataUri = previewReader.result;\n var blob = dataURItoBlob(dataUri);\n var videoSource = URL.createObjectURL(blob);\n _this2.setState({ videoSource: videoSource });\n };\n }\n }, {\n key: 'handleVideoLoadedData',\n value: function handleVideoLoadedData(event) {\n var duration = event.target.duration;\n var totalMinutes = Math.floor(duration / 60);\n var totalSeconds = Math.floor(duration % 60);\n // set the slider\n this.setState({\n sliderMaxRange: duration * 100,\n sliderValue: duration * 100 / 2,\n totalMinutes: totalMinutes,\n totalSeconds: totalSeconds\n });\n // update the current time of the video\n var video = document.getElementById('video-thumb-player');\n video.currentTime = duration / 2;\n }\n }, {\n key: 'handleSliderChange',\n value: function handleSliderChange(event) {\n var value = parseInt(event.target.value);\n // update the slider value\n this.setState({\n sliderValue: value\n });\n // update the current time of the video\n var video = document.getElementById('video-thumb-player');\n video.currentTime = value / 100;\n }\n }, {\n key: 'createThumbnail',\n value: function createThumbnail() {\n // take a snapshot\n var video = document.getElementById('video-thumb-player');\n var canvas = document.createElement('canvas');\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);\n var dataUrl = canvas.toDataURL();\n var blob = dataURItoBlob(dataUrl);\n var snapshot = new File([blob], 'thumbnail.png', {\n type: 'image/png'\n });\n // set the thumbnail in redux store\n if (snapshot) {\n this.props.onNewThumbnail(snapshot);\n }\n }\n }, {\n key: 'render',\n value: function render() {\n var _state = this.state,\n error = _state.error,\n videoSource = _state.videoSource,\n sliderMinRange = _state.sliderMinRange,\n sliderMaxRange = _state.sliderMaxRange,\n sliderValue = _state.sliderValue,\n totalMinutes = _state.totalMinutes,\n totalSeconds = _state.totalSeconds;\n\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'label',\n { className: 'label' },\n 'Thumbnail:'\n ),\n _react2.default.createElement('video', {\n id: 'video-thumb-player',\n preload: 'metadata',\n muted: true,\n style: { display: 'none' },\n playsInline: true,\n onLoadedData: this.handleVideoLoadedData,\n src: videoSource,\n onSeeked: this.createThumbnail\n }),\n sliderValue ? _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'div',\n { className: 'flex-container--row flex-container--space-between-center', style: { width: '100%' } },\n _react2.default.createElement(\n 'span',\n { className: 'info-message' },\n '0\\'00\"'\n ),\n _react2.default.createElement(\n 'span',\n { className: 'info-message' },\n totalMinutes,\n '\\'',\n totalSeconds,\n '\"'\n )\n ),\n _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement('input', {\n type: 'range',\n min: sliderMinRange,\n max: sliderMaxRange,\n value: sliderValue,\n className: 'slider',\n onChange: this.handleSliderChange\n })\n )\n ) : _react2.default.createElement(\n 'p',\n { className: 'info-message' },\n 'loading... '\n ),\n error ? _react2.default.createElement(\n 'p',\n { className: 'info-message--failure' },\n error\n ) : _react2.default.createElement(\n 'p',\n { className: 'info-message' },\n 'Use slider to set thumbnail'\n )\n );\n }\n }]);\n\n return PublishThumbnailInput;\n}(_react2.default.Component);\n\nexports.default = PublishThumbnailInput;\n\n/***/ }),\n/* 106 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _publish = __webpack_require__(4);\n\nvar _view = __webpack_require__(107);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var publish = _ref.publish;\n\n return {\n showMetadataInputs: publish.showMetadataInputs,\n description: publish.metadata.description,\n license: publish.metadata.license,\n nsfw: publish.metadata.nsfw\n };\n};\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n onMetadataChange: function onMetadataChange(name, value) {\n dispatch((0, _publish.updateMetadata)(name, value));\n },\n onToggleMetadataInputs: function onToggleMetadataInputs(value) {\n dispatch((0, _publish.toggleMetadataInputs)(value));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 107 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _ExpandingTextArea = __webpack_require__(108);\n\nvar _ExpandingTextArea2 = _interopRequireDefault(_ExpandingTextArea);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar PublishMetadataInputs = function (_React$Component) {\n _inherits(PublishMetadataInputs, _React$Component);\n\n function PublishMetadataInputs(props) {\n _classCallCheck(this, PublishMetadataInputs);\n\n var _this = _possibleConstructorReturn(this, (PublishMetadataInputs.__proto__ || Object.getPrototypeOf(PublishMetadataInputs)).call(this, props));\n\n _this.toggleShowInputs = _this.toggleShowInputs.bind(_this);\n _this.handleInput = _this.handleInput.bind(_this);\n _this.handleSelect = _this.handleSelect.bind(_this);\n return _this;\n }\n\n _createClass(PublishMetadataInputs, [{\n key: 'toggleShowInputs',\n value: function toggleShowInputs() {\n this.props.onToggleMetadataInputs(!this.props.showMetadataInputs);\n }\n }, {\n key: 'handleInput',\n value: function handleInput(event) {\n var target = event.target;\n var value = target.type === 'checkbox' ? target.checked : target.value;\n var name = target.name;\n this.props.onMetadataChange(name, value);\n }\n }, {\n key: 'handleSelect',\n value: function handleSelect(event) {\n var name = event.target.name;\n var selectedOption = event.target.selectedOptions[0].value;\n this.props.onMetadataChange(name, selectedOption);\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n { id: 'publish-details', className: 'row row--padded row--no-top row--wide' },\n this.props.showMetadataInputs && _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'div',\n { className: 'row row--no-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--3 column--med-10 align-content-top' },\n _react2.default.createElement(\n 'label',\n { htmlFor: 'publish-license', className: 'label' },\n 'Description:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--7 column--sml-10' },\n _react2.default.createElement(_ExpandingTextArea2.default, {\n id: 'publish-description',\n className: 'textarea textarea--primary textarea--full-width',\n rows: 1,\n maxLength: 2000,\n style: { maxHeight: 200 },\n name: 'description',\n placeholder: 'Optional description',\n value: this.props.description,\n onChange: this.handleInput })\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--no-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--3 column--med-10' },\n _react2.default.createElement(\n 'label',\n { htmlFor: 'publish-license', className: 'label' },\n 'License:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--7 column--sml-10' },\n _react2.default.createElement(\n 'select',\n { type: 'text', name: 'license', id: 'publish-license', className: 'select select--primary', onChange: this.handleSelect },\n _react2.default.createElement(\n 'option',\n { value: ' ' },\n 'Unspecified'\n ),\n _react2.default.createElement(\n 'option',\n { value: 'Public Domain' },\n 'Public Domain'\n ),\n _react2.default.createElement(\n 'option',\n { value: 'Creative Commons' },\n 'Creative Commons'\n )\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--no-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--3' },\n _react2.default.createElement(\n 'label',\n { htmlFor: 'publish-nsfw', className: 'label' },\n 'Mature:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--7' },\n _react2.default.createElement('input', { className: 'input-checkbox', type: 'checkbox', id: 'publish-nsfw', name: 'nsfw', value: this.props.nsfw, onChange: this.handleInput })\n )\n )\n ),\n _react2.default.createElement(\n 'button',\n { className: 'button--secondary', onClick: this.toggleShowInputs },\n this.props.showMetadataInputs ? 'less' : 'more'\n )\n );\n }\n }]);\n\n return PublishMetadataInputs;\n}(_react2.default.Component);\n\nexports.default = PublishMetadataInputs;\n\n/***/ }),\n/* 108 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; };\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _propTypes = __webpack_require__(10);\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _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; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ExpandingTextarea = function (_Component) {\n _inherits(ExpandingTextarea, _Component);\n\n function ExpandingTextarea(props) {\n _classCallCheck(this, ExpandingTextarea);\n\n var _this = _possibleConstructorReturn(this, (ExpandingTextarea.__proto__ || Object.getPrototypeOf(ExpandingTextarea)).call(this, props));\n\n _this._handleChange = _this._handleChange.bind(_this);\n return _this;\n }\n\n _createClass(ExpandingTextarea, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n this.adjustTextarea({});\n }\n }, {\n key: '_handleChange',\n value: function _handleChange(event) {\n var onChange = this.props.onChange;\n\n if (onChange) onChange(event);\n this.adjustTextarea(event);\n }\n }, {\n key: 'adjustTextarea',\n value: function adjustTextarea(_ref) {\n var _ref$target = _ref.target,\n target = _ref$target === undefined ? this.el : _ref$target;\n\n target.style.height = 0;\n target.style.height = target.scrollHeight + 'px';\n }\n }, {\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n var rest = _objectWithoutProperties(this.props, []);\n\n return _react2.default.createElement('textarea', _extends({}, rest, {\n ref: function ref(x) {\n return _this2.el = x;\n },\n onChange: this._handleChange\n }));\n }\n }]);\n\n return ExpandingTextarea;\n}(_react.Component);\n\nExpandingTextarea.propTypes = {\n onChange: _propTypes2.default.func\n};\n\nexports.default = ExpandingTextarea;\n\n/***/ }),\n/* 109 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _publish = __webpack_require__(4);\n\nvar _view = __webpack_require__(110);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var channel = _ref.channel,\n publish = _ref.publish;\n\n return {\n loggedInChannelName: channel.loggedInChannel.name,\n publishInChannel: publish.publishInChannel,\n selectedChannel: publish.selectedChannel,\n channelError: publish.error.channel\n };\n};\n\nvar mapDispatchToProps = function mapDispatchToProps(dispatch) {\n return {\n onPublishInChannelChange: function onPublishInChannelChange(value) {\n dispatch((0, _publish.updateError)('channel', null));\n dispatch((0, _publish.setPublishInChannel)(value));\n },\n onChannelSelect: function onChannelSelect(value) {\n dispatch((0, _publish.updateError)('channel', null));\n dispatch((0, _publish.updateSelectedChannel)(value));\n }\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 110 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _ChannelLoginForm = __webpack_require__(39);\n\nvar _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm);\n\nvar _ChannelCreateForm = __webpack_require__(40);\n\nvar _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm);\n\nvar _publish_channel_select_states = __webpack_require__(33);\n\nvar states = _interopRequireWildcard(_publish_channel_select_states);\n\nfunction _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; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ChannelSelect = function (_React$Component) {\n _inherits(ChannelSelect, _React$Component);\n\n function ChannelSelect(props) {\n _classCallCheck(this, ChannelSelect);\n\n var _this = _possibleConstructorReturn(this, (ChannelSelect.__proto__ || Object.getPrototypeOf(ChannelSelect)).call(this, props));\n\n _this.toggleAnonymousPublish = _this.toggleAnonymousPublish.bind(_this);\n _this.handleSelection = _this.handleSelection.bind(_this);\n return _this;\n }\n\n _createClass(ChannelSelect, [{\n key: 'toggleAnonymousPublish',\n value: function toggleAnonymousPublish(event) {\n var value = event.target.value;\n if (value === 'anonymous') {\n this.props.onPublishInChannelChange(false);\n } else {\n this.props.onPublishInChannelChange(true);\n }\n }\n }, {\n key: 'handleSelection',\n value: function handleSelection(event) {\n var selectedOption = event.target.selectedOptions[0].value;\n this.props.onChannelSelect(selectedOption);\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'form',\n null,\n _react2.default.createElement(\n 'div',\n { className: 'column column--3 column--med-10' },\n _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 }),\n _react2.default.createElement(\n 'label',\n { className: 'label label--pointer', htmlFor: 'anonymous-radio' },\n 'Anonymous'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--7 column--med-10' },\n _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 }),\n _react2.default.createElement(\n 'label',\n { className: 'label label--pointer', htmlFor: 'channel-radio' },\n 'In a channel'\n )\n ),\n this.props.channelError ? _react2.default.createElement(\n 'p',\n { className: 'info-message--failure' },\n this.props.channelError\n ) : _react2.default.createElement(\n 'p',\n { className: 'info-message' },\n 'Publish anonymously or in a channel'\n )\n ),\n this.props.publishInChannel && _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'div',\n { className: 'column column--3' },\n _react2.default.createElement(\n 'label',\n { className: 'label', htmlFor: 'channel-name-select' },\n 'Channel:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--7' },\n _react2.default.createElement(\n 'select',\n { type: 'text', id: 'channel-name-select', className: 'select select--arrow', value: this.props.selectedChannel, onChange: this.handleSelection },\n this.props.loggedInChannelName && _react2.default.createElement(\n 'option',\n { value: this.props.loggedInChannelName, id: 'publish-channel-select-channel-option' },\n this.props.loggedInChannelName\n ),\n _react2.default.createElement(\n 'option',\n { value: states.LOGIN },\n 'Existing'\n ),\n _react2.default.createElement(\n 'option',\n { value: states.CREATE },\n 'New'\n )\n )\n ),\n this.props.selectedChannel === states.LOGIN && _react2.default.createElement(_ChannelLoginForm2.default, null),\n this.props.selectedChannel === states.CREATE && _react2.default.createElement(_ChannelCreateForm2.default, null)\n )\n );\n }\n }]);\n\n return ChannelSelect;\n}(_react2.default.Component);\n\nexports.default = ChannelSelect;\n\n/***/ }),\n/* 111 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _request = __webpack_require__(11);\n\nvar _request2 = _interopRequireDefault(_request);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _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; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ChannelLoginForm = function (_React$Component) {\n _inherits(ChannelLoginForm, _React$Component);\n\n function ChannelLoginForm(props) {\n _classCallCheck(this, ChannelLoginForm);\n\n var _this = _possibleConstructorReturn(this, (ChannelLoginForm.__proto__ || Object.getPrototypeOf(ChannelLoginForm)).call(this, props));\n\n _this.state = {\n error: null,\n name: '',\n password: ''\n };\n _this.handleInput = _this.handleInput.bind(_this);\n _this.loginToChannel = _this.loginToChannel.bind(_this);\n return _this;\n }\n\n _createClass(ChannelLoginForm, [{\n key: 'handleInput',\n value: function handleInput(event) {\n var name = event.target.name;\n var value = event.target.value;\n this.setState(_defineProperty({}, name, value));\n }\n }, {\n key: 'loginToChannel',\n value: function loginToChannel(event) {\n var _this2 = this;\n\n event.preventDefault();\n var params = {\n method: 'POST',\n body: JSON.stringify({ username: this.state.name, password: this.state.password }),\n headers: new Headers({\n 'Content-Type': 'application/json'\n }),\n credentials: 'include'\n };\n (0, _request2.default)('login', params).then(function (_ref) {\n var success = _ref.success,\n channelName = _ref.channelName,\n shortChannelId = _ref.shortChannelId,\n channelClaimId = _ref.channelClaimId,\n message = _ref.message;\n\n if (success) {\n _this2.props.onChannelLogin(channelName, shortChannelId, channelClaimId);\n } else {\n _this2.setState({ 'error': message });\n };\n }).catch(function (error) {\n if (error.message) {\n _this2.setState({ 'error': error.message });\n } else {\n _this2.setState({ 'error': error });\n }\n });\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'form',\n { id: 'channel-login-form' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--wide row--short' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--3 column--sml-10' },\n _react2.default.createElement(\n 'label',\n { className: 'label', htmlFor: 'channel-login-name-input' },\n 'Name:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--6 column--sml-10' },\n _react2.default.createElement(\n 'div',\n { className: 'input-text--primary flex-container--row flex-container--left-bottom' },\n _react2.default.createElement(\n 'span',\n null,\n '@'\n ),\n _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 })\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--wide row--short' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--3 column--sml-10' },\n _react2.default.createElement(\n 'label',\n { className: 'label', htmlFor: 'channel-login-password-input' },\n 'Password:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--6 column--sml-10' },\n _react2.default.createElement(\n 'div',\n { className: 'input-text--primary' },\n _react2.default.createElement('input', { type: 'password', id: 'channel-login-password-input', name: 'password', className: 'input-text', placeholder: '', value: this.state.channelPassword, onChange: this.handleInput })\n )\n )\n ),\n this.state.error ? _react2.default.createElement(\n 'p',\n { className: 'info-message--failure' },\n this.state.error\n ) : _react2.default.createElement(\n 'p',\n { className: 'info-message' },\n 'Enter the name and password for your channel'\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--wide' },\n _react2.default.createElement(\n 'button',\n { className: 'button--primary', onClick: this.loginToChannel },\n 'Authenticate'\n )\n )\n );\n }\n }]);\n\n return ChannelLoginForm;\n}(_react2.default.Component);\n\nexports.default = ChannelLoginForm;\n\n/***/ }),\n/* 112 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _ProgressBar = __webpack_require__(20);\n\nvar _ProgressBar2 = _interopRequireDefault(_ProgressBar);\n\nvar _request = __webpack_require__(11);\n\nvar _request2 = _interopRequireDefault(_request);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _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; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ChannelCreateForm = function (_React$Component) {\n _inherits(ChannelCreateForm, _React$Component);\n\n function ChannelCreateForm(props) {\n _classCallCheck(this, ChannelCreateForm);\n\n var _this = _possibleConstructorReturn(this, (ChannelCreateForm.__proto__ || Object.getPrototypeOf(ChannelCreateForm)).call(this, props));\n\n _this.state = {\n error: null,\n channel: '',\n password: '',\n status: null\n };\n _this.handleChannelInput = _this.handleChannelInput.bind(_this);\n _this.handleInput = _this.handleInput.bind(_this);\n _this.createChannel = _this.createChannel.bind(_this);\n return _this;\n }\n\n _createClass(ChannelCreateForm, [{\n key: 'cleanseChannelInput',\n value: function cleanseChannelInput(input) {\n input = input.replace(/\\s+/g, '-'); // replace spaces with dashes\n input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'\n return input;\n }\n }, {\n key: 'handleChannelInput',\n value: function handleChannelInput(event) {\n var value = event.target.value;\n value = this.cleanseChannelInput(value);\n this.setState({ channel: value });\n if (value) {\n this.updateIsChannelAvailable(value);\n } else {\n this.setState({ error: 'Please enter a channel name' });\n }\n }\n }, {\n key: 'handleInput',\n value: function handleInput(event) {\n var name = event.target.name;\n var value = event.target.value;\n this.setState(_defineProperty({}, name, value));\n }\n }, {\n key: 'updateIsChannelAvailable',\n value: function updateIsChannelAvailable(channel) {\n var _this2 = this;\n\n var channelWithAtSymbol = '@' + channel;\n (0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol).then(function () {\n _this2.setState({ 'error': null });\n }).catch(function (error) {\n _this2.setState({ 'error': error.message });\n });\n }\n }, {\n key: 'checkIsChannelAvailable',\n value: function checkIsChannelAvailable(channel) {\n var channelWithAtSymbol = '@' + channel;\n return (0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol);\n }\n }, {\n key: 'checkIsPasswordProvided',\n value: function checkIsPasswordProvided(password) {\n return new Promise(function (resolve, reject) {\n if (!password || password.length < 1) {\n return reject(new Error('Please provide a password'));\n }\n resolve();\n });\n }\n }, {\n key: 'makePublishChannelRequest',\n value: function makePublishChannelRequest(username, password) {\n var params = {\n method: 'POST',\n body: JSON.stringify({ username: username, password: password }),\n headers: new Headers({\n 'Content-Type': 'application/json'\n }),\n credentials: 'include'\n };\n return new Promise(function (resolve, reject) {\n (0, _request2.default)('/signup', params).then(function (result) {\n return resolve(result);\n }).catch(function (error) {\n reject(new Error('Unfortunately, we encountered an error while creating your channel. Please let us know in Discord! ' + error.message));\n });\n });\n }\n }, {\n key: 'createChannel',\n value: function createChannel(event) {\n var _this3 = this;\n\n event.preventDefault();\n this.checkIsPasswordProvided(this.state.password).then(function () {\n return _this3.checkIsChannelAvailable(_this3.state.channel);\n }).then(function () {\n _this3.setState({ status: 'We are publishing your new channel. Sit tight...' });\n return _this3.makePublishChannelRequest(_this3.state.channel, _this3.state.password);\n }).then(function (result) {\n _this3.setState({ status: null });\n _this3.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId);\n }).catch(function (error) {\n if (error.message) {\n _this3.setState({ 'error': error.message, status: null });\n } else {\n _this3.setState({ 'error': error, status: null });\n };\n });\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n null,\n !this.state.status ? _react2.default.createElement(\n 'form',\n { id: 'publish-channel-form' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--wide row--short' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--3 column--sml-10' },\n _react2.default.createElement(\n 'label',\n { className: 'label', htmlFor: 'new-channel-name' },\n 'Name:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--6 column--sml-10' },\n _react2.default.createElement(\n 'div',\n { className: 'input-text--primary flex-container--row flex-container--left-bottom span--relative' },\n _react2.default.createElement(\n 'span',\n null,\n '@'\n ),\n _react2.default.createElement('input', { type: 'text', name: 'channel', id: 'new-channel-name', className: 'input-text', placeholder: 'exampleChannelName', value: this.state.channel, onChange: this.handleChannelInput }),\n this.state.channel && !this.state.error && _react2.default.createElement(\n 'span',\n { id: 'input-success-channel-name', className: 'info-message--success span--absolute' },\n '\\u2713'\n ),\n this.state.error && _react2.default.createElement(\n 'span',\n { id: 'input-success-channel-name', className: 'info-message--failure span--absolute' },\n '\\u2716'\n )\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--wide row--short' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--3 column--sml-10' },\n _react2.default.createElement(\n 'label',\n { className: 'label', htmlFor: 'new-channel-password' },\n 'Password:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--6 column--sml-10' },\n _react2.default.createElement(\n 'div',\n { className: 'input-text--primary' },\n _react2.default.createElement('input', { type: 'password', name: 'password', id: 'new-channel-password', className: 'input-text', placeholder: '', value: this.state.password, onChange: this.handleInput })\n )\n )\n ),\n this.state.error ? _react2.default.createElement(\n 'p',\n { className: 'info-message--failure' },\n this.state.error\n ) : _react2.default.createElement(\n 'p',\n { className: 'info-message' },\n 'Choose a name and password for your channel'\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--wide' },\n _react2.default.createElement(\n 'button',\n { className: 'button--primary', onClick: this.createChannel },\n 'Create Channel'\n )\n )\n ) : _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'p',\n { className: 'fine-print' },\n this.state.status\n ),\n _react2.default.createElement(_ProgressBar2.default, { size: 12 })\n )\n );\n }\n }]);\n\n return ChannelCreateForm;\n}(_react2.default.Component);\n\nexports.default = ChannelCreateForm;\n\n/***/ }),\n/* 113 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar ActiveStatusBar = function ActiveStatusBar() {\n return _react2.default.createElement(\n 'span',\n { className: 'progress-bar progress-bar--active' },\n '| '\n );\n};\n\nexports.default = ActiveStatusBar;\n\n/***/ }),\n/* 114 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar InactiveStatusBar = function InactiveStatusBar() {\n return _react2.default.createElement(\n 'span',\n { className: 'progress-bar progress-bar--inactive' },\n '| '\n );\n};\n\nexports.default = InactiveStatusBar;\n\n/***/ }),\n/* 115 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _publish = __webpack_require__(4);\n\nvar _view = __webpack_require__(116);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var publish = _ref.publish;\n\n return {\n status: publish.status.status,\n message: publish.status.message\n };\n};\n\nvar mapDispatchToProps = {\n clearFile: _publish.clearFile\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 116 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _ProgressBar = __webpack_require__(20);\n\nvar _ProgressBar2 = _interopRequireDefault(_ProgressBar);\n\nvar _publish_claim_states = __webpack_require__(117);\n\nvar publishStates = _interopRequireWildcard(_publish_claim_states);\n\nfunction _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; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar PublishStatus = function (_React$Component) {\n _inherits(PublishStatus, _React$Component);\n\n function PublishStatus() {\n _classCallCheck(this, PublishStatus);\n\n return _possibleConstructorReturn(this, (PublishStatus.__proto__ || Object.getPrototypeOf(PublishStatus)).apply(this, arguments));\n }\n\n _createClass(PublishStatus, [{\n key: 'render',\n value: function render() {\n var _props = this.props,\n status = _props.status,\n message = _props.message,\n clearFile = _props.clearFile;\n\n return _react2.default.createElement(\n 'div',\n { className: 'row row--tall flex-container--column flex-container--center-center' },\n status === publishStates.LOAD_START && _react2.default.createElement(\n 'div',\n { className: 'row align-content-center' },\n _react2.default.createElement(\n 'p',\n null,\n 'File is loading to server'\n ),\n _react2.default.createElement(\n 'p',\n { className: 'blue' },\n '0%'\n )\n ),\n status === publishStates.LOADING && _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'div',\n { className: 'row align-content-center' },\n _react2.default.createElement(\n 'p',\n null,\n 'File is loading to server'\n ),\n _react2.default.createElement(\n 'p',\n { className: 'blue' },\n message\n )\n )\n ),\n status === publishStates.PUBLISHING && _react2.default.createElement(\n 'div',\n { className: 'row align-content-center' },\n _react2.default.createElement(\n 'p',\n null,\n 'Upload complete. Your file is now being published on the blockchain...'\n ),\n _react2.default.createElement(_ProgressBar2.default, { size: 12 }),\n _react2.default.createElement(\n 'p',\n null,\n 'Curious what magic is happening here? ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: 'blank', href: 'https://lbry.io/faq/what-is-lbry' },\n 'Learn more.'\n )\n )\n ),\n status === publishStates.SUCCESS && _react2.default.createElement(\n 'div',\n { className: 'row align-content-center' },\n _react2.default.createElement(\n 'p',\n null,\n 'Your publish is complete! You are being redirected to it now.'\n ),\n _react2.default.createElement(\n 'p',\n null,\n 'If you are not automatically redirected, ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: message },\n 'click here.'\n )\n )\n ),\n status === publishStates.FAILED && _react2.default.createElement(\n 'div',\n { className: 'row align-content-center' },\n _react2.default.createElement(\n 'p',\n null,\n 'Something went wrong...'\n ),\n _react2.default.createElement(\n 'p',\n null,\n _react2.default.createElement(\n 'strong',\n null,\n message\n )\n ),\n _react2.default.createElement(\n 'p',\n null,\n 'For help, post the above error text in the #speech channel on the ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', href: 'https://discord.gg/YjYbwhS', target: '_blank' },\n 'lbry discord'\n )\n ),\n _react2.default.createElement(\n 'button',\n { className: 'button--secondary', onClick: clearFile },\n 'Reset'\n )\n )\n );\n }\n }]);\n\n return PublishStatus;\n}(_react2.default.Component);\n\n;\n\nexports.default = PublishStatus;\n\n/***/ }),\n/* 117 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar LOAD_START = exports.LOAD_START = 'LOAD_START';\nvar LOADING = exports.LOADING = 'LOADING';\nvar PUBLISHING = exports.PUBLISHING = 'PUBLISHING';\nvar SUCCESS = exports.SUCCESS = 'SUCCESS';\nvar FAILED = exports.FAILED = 'FAILED';\n\n/***/ }),\n/* 118 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(119);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var publish = _ref.publish;\n\n return {\n message: publish.disabledMessage\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 119 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar PublishDisabledMessage = function (_React$Component) {\n _inherits(PublishDisabledMessage, _React$Component);\n\n function PublishDisabledMessage() {\n _classCallCheck(this, PublishDisabledMessage);\n\n return _possibleConstructorReturn(this, (PublishDisabledMessage.__proto__ || Object.getPrototypeOf(PublishDisabledMessage)).apply(this, arguments));\n }\n\n _createClass(PublishDisabledMessage, [{\n key: 'render',\n value: function render() {\n var message = this.props.message;\n console.log('this.props.message:', message);\n return _react2.default.createElement(\n 'div',\n { className: 'row dropzone--disabled row--tall flex-container--column flex-container--center-center' },\n _react2.default.createElement(\n 'p',\n { className: 'text--disabled' },\n 'Publishing is currently disabled.'\n ),\n _react2.default.createElement(\n 'p',\n { className: 'text--disabled' },\n message\n )\n );\n }\n }]);\n\n return PublishDisabledMessage;\n}(_react2.default.Component);\n\nexports.default = PublishDisabledMessage;\n\n/***/ }),\n/* 120 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _NavBar = __webpack_require__(7);\n\nvar _NavBar2 = _interopRequireDefault(_NavBar);\n\nvar _SEO = __webpack_require__(9);\n\nvar _SEO2 = _interopRequireDefault(_SEO);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar AboutPage = function (_React$Component) {\n _inherits(AboutPage, _React$Component);\n\n function AboutPage() {\n _classCallCheck(this, AboutPage);\n\n return _possibleConstructorReturn(this, (AboutPage.__proto__ || Object.getPrototypeOf(AboutPage)).apply(this, arguments));\n }\n\n _createClass(AboutPage, [{\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(_SEO2.default, { pageTitle: 'About', pageUri: 'about' }),\n _react2.default.createElement(_NavBar2.default, null),\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--5 column--med-10 align-content-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--8 column--med-10' },\n _react2.default.createElement(\n 'p',\n { className: 'pull-quote' },\n 'Spee.ch is an open-source project. Please contribute to the existing site, or fork it and make your own.'\n ),\n _react2.default.createElement(\n 'p',\n null,\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://twitter.com/spee_ch' },\n 'TWITTER'\n )\n ),\n _react2.default.createElement(\n 'p',\n null,\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://github.com/lbryio/spee.ch' },\n 'GITHUB'\n )\n ),\n _react2.default.createElement(\n 'p',\n null,\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://discord.gg/YjYbwhS' },\n 'DISCORD CHANNEL'\n )\n ),\n _react2.default.createElement(\n 'p',\n null,\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://github.com/lbryio/spee.ch/blob/master/README.md' },\n 'DOCUMENTATION'\n )\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--5 column--med-10 align-content-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--8 column--med-10' },\n _react2.default.createElement(\n 'p',\n null,\n 'Spee.ch is a media-hosting site that reads from and publishes content to the ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', href: 'https://lbry.io' },\n 'LBRY'\n ),\n ' blockchain.'\n ),\n _react2.default.createElement(\n 'p',\n null,\n 'Spee.ch is a hosting service, but with the added benefit that it stores your content on a decentralized network of computers -- the ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', href: 'https://lbry.io/get' },\n 'LBRY'\n ),\n ' network. This means that your images are stored in multiple locations without a single point of failure.'\n ),\n _react2.default.createElement(\n 'h3',\n null,\n 'Contribute'\n ),\n _react2.default.createElement(\n 'p',\n null,\n 'If you have an idea for your own spee.ch-like site on top of LBRY, fork our ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', href: 'https://github.com/lbryio/spee.ch' },\n 'github repo'\n ),\n ' and go to town!'\n ),\n _react2.default.createElement(\n 'p',\n null,\n 'If you want to improve spee.ch, join our ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', href: 'https://discord.gg/YjYbwhS' },\n 'discord channel'\n ),\n ' or solve one of our ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', href: 'https://github.com/lbryio/spee.ch/issues' },\n 'github issues'\n ),\n '.'\n )\n )\n )\n )\n );\n }\n }]);\n\n return AboutPage;\n}(_react2.default.Component);\n\n;\n\nexports.default = AboutPage;\n\n/***/ }),\n/* 121 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(122);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var channel = _ref.channel;\n\n return {\n loggedInChannelName: channel.loggedInChannel.name\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 122 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nvar _SEO = __webpack_require__(9);\n\nvar _SEO2 = _interopRequireDefault(_SEO);\n\nvar _NavBar = __webpack_require__(7);\n\nvar _NavBar2 = _interopRequireDefault(_NavBar);\n\nvar _ChannelLoginForm = __webpack_require__(39);\n\nvar _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm);\n\nvar _ChannelCreateForm = __webpack_require__(40);\n\nvar _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar LoginPage = function (_React$Component) {\n _inherits(LoginPage, _React$Component);\n\n function LoginPage() {\n _classCallCheck(this, LoginPage);\n\n return _possibleConstructorReturn(this, (LoginPage.__proto__ || Object.getPrototypeOf(LoginPage)).apply(this, arguments));\n }\n\n _createClass(LoginPage, [{\n key: 'componentWillReceiveProps',\n value: function componentWillReceiveProps(newProps) {\n // re-route the user to the homepage if the user is logged in\n if (newProps.loggedInChannelName !== this.props.loggedInChannelName) {\n this.props.history.push('/');\n }\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(_SEO2.default, { pageTitle: 'Login', pageUri: 'login' }),\n _react2.default.createElement(_NavBar2.default, null),\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--5 column--med-10 align-content-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--8 column--med-10' },\n _react2.default.createElement(\n 'p',\n null,\n '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 ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: '/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8' },\n 'documenting important events'\n ),\n ', or making a public repository for ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: '/@catGifs' },\n 'cat gifs'\n ),\n ' (password: \\'1234\\'), try creating a channel for it!'\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--5 column--med-10 align-content-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--8 column--med-10' },\n _react2.default.createElement(\n 'h3',\n { className: 'h3--no-bottom' },\n 'Log in to an existing channel:'\n ),\n _react2.default.createElement(_ChannelLoginForm2.default, null),\n _react2.default.createElement(\n 'h3',\n { className: 'h3--no-bottom' },\n 'Create a brand new channel:'\n ),\n _react2.default.createElement(_ChannelCreateForm2.default, null)\n )\n )\n )\n );\n }\n }]);\n\n return LoginPage;\n}(_react2.default.Component);\n\n;\n\nexports.default = (0, _reactRouterDom.withRouter)(LoginPage);\n\n/***/ }),\n/* 123 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _show = __webpack_require__(8);\n\nvar _view = __webpack_require__(124);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var show = _ref.show;\n\n return {\n error: show.request.error,\n requestType: show.request.type\n };\n};\n\nvar mapDispatchToProps = {\n onHandleShowPageUri: _show.onHandleShowPageUri\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 124 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _ErrorPage = __webpack_require__(21);\n\nvar _ErrorPage2 = _interopRequireDefault(_ErrorPage);\n\nvar _ShowAssetLite = __webpack_require__(125);\n\nvar _ShowAssetLite2 = _interopRequireDefault(_ShowAssetLite);\n\nvar _ShowAssetDetails = __webpack_require__(128);\n\nvar _ShowAssetDetails2 = _interopRequireDefault(_ShowAssetDetails);\n\nvar _ShowChannel = __webpack_require__(134);\n\nvar _ShowChannel2 = _interopRequireDefault(_ShowChannel);\n\nvar _show_request_types = __webpack_require__(41);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ShowPage = function (_React$Component) {\n _inherits(ShowPage, _React$Component);\n\n function ShowPage() {\n _classCallCheck(this, ShowPage);\n\n return _possibleConstructorReturn(this, (ShowPage.__proto__ || Object.getPrototypeOf(ShowPage)).apply(this, arguments));\n }\n\n _createClass(ShowPage, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n this.props.onHandleShowPageUri(this.props.match.params);\n }\n }, {\n key: 'componentWillReceiveProps',\n value: function componentWillReceiveProps(nextProps) {\n if (nextProps.match.params !== this.props.match.params) {\n this.props.onHandleShowPageUri(nextProps.match.params);\n }\n }\n }, {\n key: 'render',\n value: function render() {\n var _props = this.props,\n error = _props.error,\n requestType = _props.requestType;\n\n if (error) {\n return _react2.default.createElement(_ErrorPage2.default, { error: error });\n }\n switch (requestType) {\n case _show_request_types.CHANNEL:\n return _react2.default.createElement(_ShowChannel2.default, null);\n case _show_request_types.ASSET_LITE:\n return _react2.default.createElement(_ShowAssetLite2.default, null);\n case _show_request_types.ASSET_DETAILS:\n return _react2.default.createElement(_ShowAssetDetails2.default, null);\n default:\n return _react2.default.createElement(\n 'p',\n null,\n 'loading...'\n );\n }\n }\n }]);\n\n return ShowPage;\n}(_react2.default.Component);\n\n;\n\nexports.default = ShowPage;\n\n/***/ }),\n/* 125 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(126);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var show = _ref.show;\n\n // select request info\n var requestId = show.request.id;\n // select asset info\n var asset = void 0;\n var request = show.requestList[requestId] || null;\n var assetList = show.assetList;\n if (request && assetList) {\n var assetKey = request.key; // note: just store this in the request\n asset = assetList[assetKey] || null;\n };\n // return props\n return {\n asset: asset\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 126 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _SEO = __webpack_require__(9);\n\nvar _SEO2 = _interopRequireDefault(_SEO);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nvar _AssetDisplay = __webpack_require__(42);\n\nvar _AssetDisplay2 = _interopRequireDefault(_AssetDisplay);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ShowLite = function (_React$Component) {\n _inherits(ShowLite, _React$Component);\n\n function ShowLite() {\n _classCallCheck(this, ShowLite);\n\n return _possibleConstructorReturn(this, (ShowLite.__proto__ || Object.getPrototypeOf(ShowLite)).apply(this, arguments));\n }\n\n _createClass(ShowLite, [{\n key: 'render',\n value: function render() {\n var asset = this.props.asset;\n\n if (asset) {\n var _asset$claimData = asset.claimData,\n name = _asset$claimData.name,\n claimId = _asset$claimData.claimId;\n\n return _react2.default.createElement(\n 'div',\n { className: 'row row--tall flex-container--column flex-container--center-center show-lite-container' },\n _react2.default.createElement(_SEO2.default, { pageTitle: name, asset: asset }),\n _react2.default.createElement(_AssetDisplay2.default, null),\n _react2.default.createElement(\n _reactRouterDom.Link,\n { id: 'asset-boilerpate', className: 'link--primary fine-print', to: '/' + claimId + '/' + name },\n 'hosted via Spee.ch'\n )\n );\n }\n return _react2.default.createElement(\n 'div',\n { className: 'row row--tall row--padded flex-container--column flex-container--center-center' },\n _react2.default.createElement(\n 'p',\n null,\n 'loading asset data...'\n )\n );\n }\n }]);\n\n return ShowLite;\n}(_react2.default.Component);\n\n;\n\nexports.default = ShowLite;\n\n/***/ }),\n/* 127 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _ProgressBar = __webpack_require__(20);\n\nvar _ProgressBar2 = _interopRequireDefault(_ProgressBar);\n\nvar _asset_display_states = __webpack_require__(35);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar AssetDisplay = function (_React$Component) {\n _inherits(AssetDisplay, _React$Component);\n\n function AssetDisplay() {\n _classCallCheck(this, AssetDisplay);\n\n return _possibleConstructorReturn(this, (AssetDisplay.__proto__ || Object.getPrototypeOf(AssetDisplay)).apply(this, arguments));\n }\n\n _createClass(AssetDisplay, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n var _props$asset$claimDat = this.props.asset.claimData,\n name = _props$asset$claimDat.name,\n claimId = _props$asset$claimDat.claimId;\n\n this.props.onFileRequest(name, claimId);\n }\n }, {\n key: 'render',\n value: function render() {\n var _props = this.props,\n status = _props.status,\n error = _props.error,\n _props$asset$claimDat2 = _props.asset.claimData,\n name = _props$asset$claimDat2.name,\n claimId = _props$asset$claimDat2.claimId,\n contentType = _props$asset$claimDat2.contentType,\n fileExt = _props$asset$claimDat2.fileExt,\n thumbnail = _props$asset$claimDat2.thumbnail;\n\n return _react2.default.createElement(\n 'div',\n { id: 'asset-display-component' },\n status === _asset_display_states.LOCAL_CHECK && _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'p',\n null,\n 'Checking to see if Spee.ch has your asset locally...'\n )\n ),\n status === _asset_display_states.UNAVAILABLE && _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'p',\n null,\n 'Sit tight, we\\'re searching the LBRY blockchain for your asset!'\n ),\n _react2.default.createElement(_ProgressBar2.default, { size: 12 }),\n _react2.default.createElement(\n 'p',\n null,\n 'Curious what magic is happening here? ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: 'blank', href: 'https://lbry.io/faq/what-is-lbry' },\n 'Learn more.'\n )\n )\n ),\n status === _asset_display_states.ERROR && _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'p',\n null,\n 'Unfortunately, we couldn\\'t download your asset from LBRY. You can help us out by sharing the below error message in the ',\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', href: 'https://discord.gg/YjYbwhS', target: '_blank' },\n 'LBRY discord'\n ),\n '.'\n ),\n _react2.default.createElement(\n 'i',\n null,\n _react2.default.createElement(\n 'p',\n { id: 'error-message' },\n error\n )\n )\n ),\n status === _asset_display_states.AVAILABLE && function () {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n return _react2.default.createElement('img', {\n className: 'asset',\n src: '/' + claimId + '/' + name + '.' + fileExt,\n alt: name });\n case 'image/gif':\n return _react2.default.createElement('img', {\n className: 'asset',\n src: '/' + claimId + '/' + name + '.' + fileExt,\n alt: name\n });\n case 'video/mp4':\n return _react2.default.createElement(\n 'video',\n { className: 'asset video', controls: true, poster: thumbnail },\n _react2.default.createElement('source', {\n src: '/' + claimId + '/' + name + '.' + fileExt\n }),\n _react2.default.createElement(\n 'p',\n null,\n 'Your browser does not support the ',\n _react2.default.createElement(\n 'code',\n null,\n 'video'\n ),\n ' element.'\n )\n );\n default:\n return _react2.default.createElement(\n 'p',\n null,\n 'Unsupported file type'\n );\n }\n }()\n );\n }\n }]);\n\n return AssetDisplay;\n}(_react2.default.Component);\n\n;\n\nexports.default = AssetDisplay;\n\n/***/ }),\n/* 128 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(129);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var show = _ref.show;\n\n // select request info\n var requestId = show.request.id;\n // select asset info\n var asset = void 0;\n var request = show.requestList[requestId] || null;\n var assetList = show.assetList;\n if (request && assetList) {\n var assetKey = request.key; // note: just store this in the request\n asset = assetList[assetKey] || null;\n };\n // return props\n return {\n asset: asset\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 129 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _SEO = __webpack_require__(9);\n\nvar _SEO2 = _interopRequireDefault(_SEO);\n\nvar _NavBar = __webpack_require__(7);\n\nvar _NavBar2 = _interopRequireDefault(_NavBar);\n\nvar _ErrorPage = __webpack_require__(21);\n\nvar _ErrorPage2 = _interopRequireDefault(_ErrorPage);\n\nvar _AssetTitle = __webpack_require__(130);\n\nvar _AssetTitle2 = _interopRequireDefault(_AssetTitle);\n\nvar _AssetDisplay = __webpack_require__(42);\n\nvar _AssetDisplay2 = _interopRequireDefault(_AssetDisplay);\n\nvar _AssetInfo = __webpack_require__(132);\n\nvar _AssetInfo2 = _interopRequireDefault(_AssetInfo);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ShowAssetDetails = function (_React$Component) {\n _inherits(ShowAssetDetails, _React$Component);\n\n function ShowAssetDetails() {\n _classCallCheck(this, ShowAssetDetails);\n\n return _possibleConstructorReturn(this, (ShowAssetDetails.__proto__ || Object.getPrototypeOf(ShowAssetDetails)).apply(this, arguments));\n }\n\n _createClass(ShowAssetDetails, [{\n key: 'render',\n value: function render() {\n var asset = this.props.asset;\n\n if (asset) {\n var name = asset.claimData.name;\n\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(_SEO2.default, { pageTitle: name + ' - details', asset: asset }),\n _react2.default.createElement(_NavBar2.default, null),\n _react2.default.createElement(\n 'div',\n { className: 'row row--tall row--padded' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--10' },\n _react2.default.createElement(_AssetTitle2.default, null)\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--5 column--sml-10 align-content-top' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded show-details-container' },\n _react2.default.createElement(_AssetDisplay2.default, null)\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--5 column--sml-10 align-content-top' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded' },\n _react2.default.createElement(_AssetInfo2.default, null)\n )\n )\n )\n );\n };\n return _react2.default.createElement(_ErrorPage2.default, { error: 'loading asset data...' });\n }\n }]);\n\n return ShowAssetDetails;\n}(_react2.default.Component);\n\n;\n\nexports.default = ShowAssetDetails;\n\n/***/ }),\n/* 130 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(131);\n\nvar _view2 = _interopRequireDefault(_view);\n\nvar _show = __webpack_require__(13);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var show = _ref.show;\n\n var _selectAsset = (0, _show.selectAsset)(show),\n title = _selectAsset.claimData.title;\n\n return {\n title: title\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 131 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar AssetTitle = function AssetTitle(_ref) {\n var title = _ref.title;\n\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'span',\n { className: 'text--large' },\n title\n )\n );\n};\n\nexports.default = AssetTitle;\n\n/***/ }),\n/* 132 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(133);\n\nvar _view2 = _interopRequireDefault(_view);\n\nvar _show = __webpack_require__(13);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var show = _ref.show;\n\n // select asset\n var asset = (0, _show.selectAsset)(show);\n // return props\n return {\n asset: asset\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 133 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar AssetInfo = function (_React$Component) {\n _inherits(AssetInfo, _React$Component);\n\n function AssetInfo(props) {\n _classCallCheck(this, AssetInfo);\n\n var _this = _possibleConstructorReturn(this, (AssetInfo.__proto__ || Object.getPrototypeOf(AssetInfo)).call(this, props));\n\n _this.copyToClipboard = _this.copyToClipboard.bind(_this);\n return _this;\n }\n\n _createClass(AssetInfo, [{\n key: 'copyToClipboard',\n value: function copyToClipboard(event) {\n var elementToCopy = event.target.dataset.elementtocopy;\n var element = document.getElementById(elementToCopy);\n element.select();\n try {\n document.execCommand('copy');\n } catch (err) {\n this.setState({ error: 'Oops, unable to copy' });\n }\n }\n }, {\n key: 'render',\n value: function render() {\n var _props$asset = this.props.asset,\n shortId = _props$asset.shortId,\n _props$asset$claimDat = _props$asset.claimData,\n channelName = _props$asset$claimDat.channelName,\n certificateId = _props$asset$claimDat.certificateId,\n description = _props$asset$claimDat.description,\n name = _props$asset$claimDat.name,\n claimId = _props$asset$claimDat.claimId,\n fileExt = _props$asset$claimDat.fileExt,\n contentType = _props$asset$claimDat.contentType,\n thumbnail = _props$asset$claimDat.thumbnail,\n host = _props$asset$claimDat.host;\n\n return _react2.default.createElement(\n 'div',\n null,\n channelName && _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--wide row--no-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--2 column--med-10' },\n _react2.default.createElement(\n 'span',\n { className: 'text' },\n 'Channel:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--8 column--med-10' },\n _react2.default.createElement(\n 'span',\n { className: 'text' },\n _react2.default.createElement(\n _reactRouterDom.Link,\n { to: '/' + channelName + ':' + certificateId },\n channelName\n )\n )\n )\n ),\n description && _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--wide row--no-top' },\n _react2.default.createElement(\n 'span',\n { className: 'text' },\n description\n )\n ),\n _react2.default.createElement(\n 'div',\n { id: 'show-share-buttons' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--wide row--no-top' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--2 column--med-10' },\n _react2.default.createElement(\n 'span',\n { className: 'text' },\n 'Share:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--8 column--med-10' },\n _react2.default.createElement(\n 'div',\n {\n className: 'row row--short row--wide flex-container--row flex-container--space-between-bottom flex-container--wrap' },\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://twitter.com/intent/tweet?text=' + host + '/' + shortId + '/' + name },\n 'twitter'\n ),\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://www.facebook.com/sharer/sharer.php?u=' + host + '/' + shortId + '/' + name },\n 'facebook'\n ),\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'http://tumblr.com/widgets/share/tool?canonicalUrl=' + host + '/' + shortId + '/' + name },\n 'tumblr'\n ),\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://www.reddit.com/submit?url=' + host + '/' + shortId + '/' + name + '&title=' + name },\n 'reddit'\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded row--wide row--no-top' },\n _react2.default.createElement(\n 'div',\n { id: 'show-short-link' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--2 column--med-10' },\n _react2.default.createElement(\n 'span',\n { className: 'text' },\n 'Link:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--8 column--med-10' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--short row--wide' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--7' },\n _react2.default.createElement(\n 'div',\n { className: 'input-error', id: 'input-error-copy-short-link', hidden: 'true' },\n 'error here'\n ),\n _react2.default.createElement('input', { type: 'text', id: 'short-link', className: 'input-disabled input-text--full-width', readOnly: true,\n spellCheck: 'false',\n value: host + '/' + shortId + '/' + name + '.' + fileExt,\n onClick: this.select })\n ),\n _react2.default.createElement('div', { className: 'column column--1' }),\n _react2.default.createElement(\n 'div',\n { className: 'column column--2' },\n _react2.default.createElement(\n 'button',\n { className: 'button--primary button--wide', 'data-elementtocopy': 'short-link',\n onClick: this.copyToClipboard },\n 'copy'\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { id: 'show-embed-code' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--2 column--med-10' },\n _react2.default.createElement(\n 'span',\n { className: 'text' },\n 'Embed:'\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--8 column--med-10' },\n _react2.default.createElement(\n 'div',\n { className: 'row row--short row--wide' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--7' },\n _react2.default.createElement(\n 'div',\n { className: 'input-error', id: 'input-error-copy-embed-text', hidden: 'true' },\n 'error here'\n ),\n contentType === 'video/mp4' ? _react2.default.createElement('input', { type: 'text', id: 'embed-text', className: 'input-disabled input-text--full-width', readOnly: true,\n onClick: this.select, spellCheck: 'false',\n value: '' }) : _react2.default.createElement('input', { type: 'text', id: 'embed-text', className: 'input-disabled input-text--full-width', readOnly: true,\n onClick: this.select, spellCheck: 'false',\n value: ''\n })\n ),\n _react2.default.createElement('div', { className: 'column column--1' }),\n _react2.default.createElement(\n 'div',\n { className: 'column column--2' },\n _react2.default.createElement(\n 'button',\n { className: 'button--primary button--wide', 'data-elementtocopy': 'embed-text',\n onClick: this.copyToClipboard },\n 'copy'\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'flex-container--row flex-container--space-between-bottom' },\n _react2.default.createElement(\n _reactRouterDom.Link,\n { className: 'link--primary', to: '/' + shortId + '/' + name + '.' + fileExt },\n _react2.default.createElement(\n 'span',\n {\n className: 'text' },\n 'Direct Link'\n )\n ),\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', href: host + '/' + claimId + '/' + name + '.' + fileExt, download: name },\n 'Download'\n ),\n _react2.default.createElement(\n 'a',\n { className: 'link--primary', target: '_blank', href: 'https://lbry.io/dmca' },\n 'Report'\n )\n )\n );\n }\n }]);\n\n return AssetInfo;\n}(_react2.default.Component);\n\n;\n\nexports.default = AssetInfo;\n\n/***/ }),\n/* 134 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(135);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var show = _ref.show;\n\n // select request info\n var requestId = show.request.id;\n // select request\n var previousRequest = show.requestList[requestId] || null;\n // select channel\n var channel = void 0;\n if (previousRequest) {\n var channelKey = previousRequest.key;\n channel = show.channelList[channelKey] || null;\n }\n return {\n channel: channel\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 135 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _SEO = __webpack_require__(9);\n\nvar _SEO2 = _interopRequireDefault(_SEO);\n\nvar _ErrorPage = __webpack_require__(21);\n\nvar _ErrorPage2 = _interopRequireDefault(_ErrorPage);\n\nvar _NavBar = __webpack_require__(7);\n\nvar _NavBar2 = _interopRequireDefault(_NavBar);\n\nvar _ChannelClaimsDisplay = __webpack_require__(136);\n\nvar _ChannelClaimsDisplay2 = _interopRequireDefault(_ChannelClaimsDisplay);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ShowChannel = function (_React$Component) {\n _inherits(ShowChannel, _React$Component);\n\n function ShowChannel() {\n _classCallCheck(this, ShowChannel);\n\n return _possibleConstructorReturn(this, (ShowChannel.__proto__ || Object.getPrototypeOf(ShowChannel)).apply(this, arguments));\n }\n\n _createClass(ShowChannel, [{\n key: 'render',\n value: function render() {\n var channel = this.props.channel;\n\n if (channel) {\n var name = channel.name,\n longId = channel.longId,\n shortId = channel.shortId;\n\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(_SEO2.default, { pageTitle: name, channel: channel }),\n _react2.default.createElement(_NavBar2.default, null),\n _react2.default.createElement(\n 'div',\n { className: 'row row--tall row--padded' },\n _react2.default.createElement(\n 'div',\n { className: 'column column--10' },\n _react2.default.createElement(\n 'h2',\n null,\n 'channel name: ',\n name\n ),\n _react2.default.createElement(\n 'p',\n { className: 'fine-print' },\n 'full channel id: ',\n longId\n ),\n _react2.default.createElement(\n 'p',\n { className: 'fine-print' },\n 'short channel id: ',\n shortId\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'column column--10' },\n _react2.default.createElement(_ChannelClaimsDisplay2.default, null)\n )\n )\n );\n };\n return _react2.default.createElement(_ErrorPage2.default, { error: 'loading channel data...' });\n }\n }]);\n\n return ShowChannel;\n}(_react2.default.Component);\n\n;\n\nexports.default = ShowChannel;\n\n/***/ }),\n/* 136 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _show = __webpack_require__(8);\n\nvar _view = __webpack_require__(137);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var show = _ref.show;\n\n // select channel key\n var request = show.requestList[show.request.id];\n var channelKey = request.key;\n // select channel claims\n var channel = show.channelList[channelKey] || null;\n // return props\n return {\n channelKey: channelKey,\n channel: channel\n };\n};\n\nvar mapDispatchToProps = {\n onUpdateChannelClaims: _show.onUpdateChannelClaims\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);\n\n/***/ }),\n/* 137 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _AssetPreview = __webpack_require__(138);\n\nvar _AssetPreview2 = _interopRequireDefault(_AssetPreview);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar ChannelClaimsDisplay = function (_React$Component) {\n _inherits(ChannelClaimsDisplay, _React$Component);\n\n function ChannelClaimsDisplay(props) {\n _classCallCheck(this, ChannelClaimsDisplay);\n\n var _this = _possibleConstructorReturn(this, (ChannelClaimsDisplay.__proto__ || Object.getPrototypeOf(ChannelClaimsDisplay)).call(this, props));\n\n _this.showNextResultsPage = _this.showNextResultsPage.bind(_this);\n _this.showPreviousResultsPage = _this.showPreviousResultsPage.bind(_this);\n return _this;\n }\n\n _createClass(ChannelClaimsDisplay, [{\n key: 'showPreviousResultsPage',\n value: function showPreviousResultsPage() {\n var currentPage = this.props.channel.claimsData.currentPage;\n\n var previousPage = parseInt(currentPage) - 1;\n this.showNewPage(previousPage);\n }\n }, {\n key: 'showNextResultsPage',\n value: function showNextResultsPage() {\n var currentPage = this.props.channel.claimsData.currentPage;\n\n var nextPage = parseInt(currentPage) + 1;\n this.showNewPage(nextPage);\n }\n }, {\n key: 'showNewPage',\n value: function showNewPage(page) {\n var _props = this.props,\n channelKey = _props.channelKey,\n _props$channel = _props.channel,\n name = _props$channel.name,\n longId = _props$channel.longId;\n\n this.props.onUpdateChannelClaims(channelKey, name, longId, page);\n }\n }, {\n key: 'render',\n value: function render() {\n var _props$channel$claims = this.props.channel.claimsData,\n claims = _props$channel$claims.claims,\n currentPage = _props$channel$claims.currentPage,\n totalPages = _props$channel$claims.totalPages;\n\n return _react2.default.createElement(\n 'div',\n { className: 'row row--tall' },\n claims.length > 0 ? _react2.default.createElement(\n 'div',\n null,\n claims.map(function (claim, index) {\n return _react2.default.createElement(_AssetPreview2.default, {\n claimData: claim,\n key: claim.name + '-' + index\n });\n }),\n _react2.default.createElement(\n 'div',\n null,\n currentPage > 1 && _react2.default.createElement(\n 'button',\n { className: 'button--secondary', onClick: this.showPreviousResultsPage },\n 'Previous Page'\n ),\n currentPage < totalPages && _react2.default.createElement(\n 'button',\n { className: 'button--secondary', onClick: this.showNextResultsPage },\n 'Next Page'\n )\n )\n ) : _react2.default.createElement(\n 'p',\n null,\n 'There are no claims in this channel'\n )\n );\n }\n }]);\n\n return ChannelClaimsDisplay;\n}(_react2.default.Component);\n\n;\n\nexports.default = ChannelClaimsDisplay;\n\n/***/ }),\n/* 138 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(139);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var defaultThumbnail = _ref.site.defaults.defaultThumbnail;\n\n return {\n defaultThumbnail: defaultThumbnail\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 139 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar AssetPreview = function AssetPreview(_ref) {\n var defaultThumbnail = _ref.defaultThumbnail,\n _ref$claimData = _ref.claimData,\n name = _ref$claimData.name,\n claimId = _ref$claimData.claimId,\n fileExt = _ref$claimData.fileExt,\n contentType = _ref$claimData.contentType,\n thumbnail = _ref$claimData.thumbnail;\n\n var directSourceLink = claimId + '/' + name + '.' + fileExt;\n var showUrlLink = '/' + claimId + '/' + name;\n return _react2.default.createElement(\n 'div',\n { className: 'asset-holder' },\n _react2.default.createElement(\n _reactRouterDom.Link,\n { to: showUrlLink },\n function () {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n case 'image/gif':\n return _react2.default.createElement('img', {\n className: 'asset-preview',\n src: directSourceLink,\n alt: name\n });\n case 'video/mp4':\n return _react2.default.createElement('img', {\n className: 'asset-preview video',\n src: thumbnail || defaultThumbnail,\n alt: name\n });\n default:\n return _react2.default.createElement(\n 'p',\n null,\n 'unsupported file type'\n );\n }\n }()\n )\n );\n};\n\nexports.default = AssetPreview;\n\n/***/ }),\n/* 140 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _view = __webpack_require__(141);\n\nvar _view2 = _interopRequireDefault(_view);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar mapStateToProps = function mapStateToProps(_ref) {\n var _ref$site = _ref.site,\n host = _ref$site.host,\n title = _ref$site.title;\n\n return {\n host: host,\n title: title\n };\n};\n\nexports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);\n\n/***/ }),\n/* 141 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _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; }; }();\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _NavBar = __webpack_require__(7);\n\nvar _NavBar2 = _interopRequireDefault(_NavBar);\n\nvar _reactHelmet = __webpack_require__(14);\n\nvar _reactHelmet2 = _interopRequireDefault(_reactHelmet);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _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; }\n\nfunction _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; }\n\nvar FourOhForPage = function (_React$Component) {\n _inherits(FourOhForPage, _React$Component);\n\n function FourOhForPage() {\n _classCallCheck(this, FourOhForPage);\n\n return _possibleConstructorReturn(this, (FourOhForPage.__proto__ || Object.getPrototypeOf(FourOhForPage)).apply(this, arguments));\n }\n\n _createClass(FourOhForPage, [{\n key: 'render',\n value: function render() {\n var _props = this.props,\n title = _props.title,\n host = _props.host;\n\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n _reactHelmet2.default,\n null,\n _react2.default.createElement(\n 'title',\n null,\n title,\n ' - 404'\n ),\n _react2.default.createElement('link', { rel: 'canonical', href: host + '/404' })\n ),\n _react2.default.createElement(_NavBar2.default, null),\n _react2.default.createElement(\n 'div',\n { className: 'row row--padded' },\n _react2.default.createElement(\n 'h2',\n null,\n '404'\n ),\n _react2.default.createElement(\n 'p',\n null,\n 'That page does not exist'\n )\n )\n );\n }\n }]);\n\n return FourOhForPage;\n}(_react2.default.Component);\n\n;\n\nexports.default = FourOhForPage;\n\n/***/ }),\n/* 142 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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\"); } }; }();\n\nvar _require = __webpack_require__(17),\n sendGAServeEvent = _require.sendGAServeEvent;\n\nvar _require2 = __webpack_require__(143),\n determineResponseType = _require2.determineResponseType,\n flipClaimNameAndIdForBackwardsCompatibility = _require2.flipClaimNameAndIdForBackwardsCompatibility,\n logRequestData = _require2.logRequestData,\n getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;\n\nvar lbryUri = __webpack_require__(144);\nvar handleShowRender = __webpack_require__(145);\nvar SERVE = 'SERVE';\n\nmodule.exports = function (app) {\n // route to serve a specific asset using the channel or claim id\n app.get('/:identifier/:claim', function (req, res) {\n var headers = req.headers,\n ip = req.ip,\n originalUrl = req.originalUrl,\n params = req.params;\n // decide if this is a show request\n\n var hasFileExtension = void 0;\n try {\n var _lbryUri$parseModifie = lbryUri.parseModifier(params.claim);\n\n hasFileExtension = _lbryUri$parseModifie.hasFileExtension;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n var responseType = determineResponseType(hasFileExtension, headers);\n if (responseType !== SERVE) {\n return handleShowRender(req, res);\n }\n // handle serve request\n // send google analytics\n sendGAServeEvent(headers, ip, originalUrl);\n // parse the claim\n var claimName = void 0;\n try {\n var _lbryUri$parseClaim = lbryUri.parseClaim(params.claim);\n\n claimName = _lbryUri$parseClaim.claimName;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n // parse the identifier\n var isChannel = void 0,\n channelName = void 0,\n channelClaimId = void 0,\n claimId = void 0;\n try {\n var _lbryUri$parseIdentif = lbryUri.parseIdentifier(params.identifier);\n\n isChannel = _lbryUri$parseIdentif.isChannel;\n channelName = _lbryUri$parseIdentif.channelName;\n channelClaimId = _lbryUri$parseIdentif.channelClaimId;\n claimId = _lbryUri$parseIdentif.claimId;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n if (!isChannel) {\n var _flipClaimNameAndIdFo = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);\n\n var _flipClaimNameAndIdFo2 = _slicedToArray(_flipClaimNameAndIdFo, 2);\n\n claimId = _flipClaimNameAndIdFo2[0];\n claimName = _flipClaimNameAndIdFo2[1];\n }\n // log the request data for debugging\n logRequestData(responseType, claimName, channelName, claimId);\n // get the claim Id and then serve the asset\n getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);\n });\n // route to serve the winning asset at a claim or a channel page\n app.get('/:claim', function (req, res) {\n var headers = req.headers,\n ip = req.ip,\n originalUrl = req.originalUrl,\n params = req.params;\n // decide if this is a show request\n\n var hasFileExtension = void 0;\n try {\n var _lbryUri$parseModifie2 = lbryUri.parseModifier(params.claim);\n\n hasFileExtension = _lbryUri$parseModifie2.hasFileExtension;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n var responseType = determineResponseType(hasFileExtension, headers);\n if (responseType !== SERVE) {\n return handleShowRender(req, res);\n }\n // handle serve request\n // send google analytics\n sendGAServeEvent(headers, ip, originalUrl);\n // parse the claim\n var claimName = void 0;\n try {\n var _lbryUri$parseClaim2 = lbryUri.parseClaim(params.claim);\n\n claimName = _lbryUri$parseClaim2.claimName;\n } catch (error) {\n return res.status(400).json({ success: false, message: error.message });\n }\n // log the request data for debugging\n logRequestData(responseType, claimName, null, null);\n // get the claim Id and then serve the asset\n getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);\n });\n};\n\n/***/ }),\n/* 143 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar logger = __webpack_require__(2);\n\nvar _require = __webpack_require__(28),\n getClaimId = _require.getClaimId,\n getLocalFileRecord = _require.getLocalFileRecord;\n\nvar _require2 = __webpack_require__(27),\n handleErrorResponse = _require2.handleErrorResponse;\n\nvar SERVE = 'SERVE';\nvar SHOW = 'SHOW';\nvar NO_FILE = 'NO_FILE';\nvar NO_CHANNEL = 'NO_CHANNEL';\nvar NO_CLAIM = 'NO_CLAIM';\n\nfunction clientAcceptsHtml(_ref) {\n var accept = _ref.accept;\n\n return accept && accept.match(/text\\/html/);\n};\n\nfunction requestIsFromBrowser(headers) {\n return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);\n};\n\nfunction clientWantsAsset(_ref2) {\n var accept = _ref2.accept,\n range = _ref2.range;\n\n var imageIsWanted = accept && accept.match(/image\\/.*/) && !accept.match(/text\\/html/) && !accept.match(/text\\/\\*/);\n var videoIsWanted = accept && range;\n return imageIsWanted || videoIsWanted;\n};\n\nfunction isValidClaimId(claimId) {\n return claimId.length === 40 && !/[^A-Za-z0-9]/g.test(claimId);\n};\n\nfunction isValidShortId(claimId) {\n return claimId.length === 1; // it should really evaluate the short url itself\n};\n\nfunction isValidShortIdOrClaimId(input) {\n return isValidClaimId(input) || isValidShortId(input);\n};\n\nfunction serveAssetToClient(claimId, name, res) {\n return getLocalFileRecord(claimId, name).then(function (fileRecord) {\n // check that a local record was found\n if (fileRecord === NO_FILE) {\n return res.status(307).redirect('/api/claim/get/' + name + '/' + claimId);\n }\n // serve the file\n var filePath = fileRecord.filePath,\n fileType = fileRecord.fileType;\n\n logger.verbose('serving file: ' + filePath);\n var sendFileOptions = {\n headers: {\n 'X-Content-Type-Options': 'nosniff',\n 'Content-Type': fileType || 'image/jpeg'\n }\n };\n res.status(200).sendFile(filePath, sendFileOptions);\n }).catch(function (error) {\n throw error;\n });\n};\n\nmodule.exports = {\n getClaimIdAndServeAsset: function getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res) {\n // get the claim Id and then serve the asset\n getClaimId(channelName, channelClaimId, claimName, claimId).then(function (fullClaimId) {\n if (fullClaimId === NO_CLAIM) {\n return res.status(404).json({ success: false, message: 'no claim id could be found' });\n } else if (fullClaimId === NO_CHANNEL) {\n return res.status(404).json({ success: false, message: 'no channel id could be found' });\n }\n serveAssetToClient(fullClaimId, claimName, res);\n // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');\n }).catch(function (error) {\n handleErrorResponse(originalUrl, ip, error, res);\n // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');\n });\n },\n determineResponseType: function determineResponseType(hasFileExtension, headers) {\n var responseType = void 0;\n if (hasFileExtension) {\n responseType = SERVE; // assume a serve request if file extension is present\n if (clientAcceptsHtml(headers)) {\n // if the request comes from a browser, change it to a show request\n responseType = SHOW;\n }\n } else {\n responseType = SHOW;\n if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) {\n // this is in case someone embeds a show url\n logger.debug('Show request came from browser but wants an image/video. Changing response to serve...');\n responseType = SERVE;\n }\n }\n return responseType;\n },\n flipClaimNameAndIdForBackwardsCompatibility: function flipClaimNameAndIdForBackwardsCompatibility(identifier, name) {\n // this is a patch for backwards compatability with '/name/claim_id' url format\n if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) {\n var tempName = name;\n name = identifier;\n identifier = tempName;\n }\n return [identifier, name];\n },\n logRequestData: function logRequestData(responseType, claimName, channelName, claimId) {\n logger.debug('responseType ===', responseType);\n logger.debug('claim name === ', claimName);\n logger.debug('channel name ===', channelName);\n logger.debug('claim id ===', claimId);\n }\n};\n\n/***/ }),\n/* 144 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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\"); } }; }();\n\nvar logger = __webpack_require__(2);\n\nmodule.exports = {\n REGEXP_INVALID_CLAIM: /[^A-Za-z0-9-]/g,\n REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,\n REGEXP_ADDRESS: /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,\n CHANNEL_CHAR: '@',\n parseIdentifier: function parseIdentifier(identifier) {\n logger.debug('parsing identifier:', identifier);\n var componentsRegex = new RegExp('([^:$#/]*)' + // value (stops at the first separator or end)\n '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n\n var _componentsRegex$exec = componentsRegex.exec(identifier).map(function (match) {\n return match || null;\n }),\n _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 4),\n proto = _componentsRegex$exec2[0],\n value = _componentsRegex$exec2[1],\n modifierSeperator = _componentsRegex$exec2[2],\n modifier = _componentsRegex$exec2[3];\n\n logger.debug(proto + ', ' + value + ', ' + modifierSeperator + ', ' + modifier);\n\n // Validate and process name\n if (!value) {\n throw new Error('Check your url. No channel name provided before \"' + modifierSeperator + '\"');\n }\n var isChannel = value.startsWith(module.exports.CHANNEL_CHAR);\n var channelName = isChannel ? value : null;\n var claimId = void 0;\n if (isChannel) {\n if (!channelName) {\n throw new Error('No channel name after @.');\n }\n var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL);\n if (nameBadChars) {\n throw new Error('Invalid characters in channel name: ' + nameBadChars.join(', ') + '.');\n }\n } else {\n claimId = value;\n }\n\n // Validate and process modifier\n var channelClaimId = void 0;\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error('No modifier provided after separator \"' + modifierSeperator + '\"');\n }\n\n if (modifierSeperator === ':') {\n channelClaimId = modifier;\n } else {\n throw new Error('The \"' + modifierSeperator + '\" modifier is not currently supported');\n }\n }\n return {\n isChannel: isChannel,\n channelName: channelName,\n channelClaimId: channelClaimId,\n claimId: claimId\n };\n },\n parseClaim: function parseClaim(claim) {\n logger.debug('parsing name:', claim);\n var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier)\n '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n\n var _componentsRegex$exec3 = componentsRegex.exec(claim).map(function (match) {\n return match || null;\n }),\n _componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4),\n proto = _componentsRegex$exec4[0],\n claimName = _componentsRegex$exec4[1],\n modifierSeperator = _componentsRegex$exec4[2],\n modifier = _componentsRegex$exec4[3];\n\n logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier);\n\n // Validate and process name\n if (!claimName) {\n throw new Error('No claim name provided before .');\n }\n var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM);\n if (nameBadChars) {\n throw new Error('Invalid characters in claim name: ' + nameBadChars.join(', ') + '.');\n }\n // Validate and process modifier\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error('No file extension provided after separator ' + modifierSeperator + '.');\n }\n if (modifierSeperator !== '.') {\n throw new Error('The ' + modifierSeperator + ' modifier is not supported in the claim name');\n }\n }\n // return results\n return {\n claimName: claimName\n };\n },\n parseModifier: function parseModifier(claim) {\n logger.debug('parsing modifier:', claim);\n var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier)\n '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n\n var _componentsRegex$exec5 = componentsRegex.exec(claim).map(function (match) {\n return match || null;\n }),\n _componentsRegex$exec6 = _slicedToArray(_componentsRegex$exec5, 4),\n proto = _componentsRegex$exec6[0],\n claimName = _componentsRegex$exec6[1],\n modifierSeperator = _componentsRegex$exec6[2],\n modifier = _componentsRegex$exec6[3];\n\n logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier);\n // Validate and process modifier\n var hasFileExtension = false;\n if (modifierSeperator) {\n hasFileExtension = true;\n }\n return {\n hasFileExtension: hasFileExtension\n };\n }\n};\n\n/***/ }),\n/* 145 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _react = __webpack_require__(0);\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _server = __webpack_require__(30);\n\nvar _redux = __webpack_require__(18);\n\nvar _index = __webpack_require__(31);\n\nvar _index2 = _interopRequireDefault(_index);\n\nvar _reactRedux = __webpack_require__(1);\n\nvar _reactRouterDom = __webpack_require__(3);\n\nvar _index3 = __webpack_require__(36);\n\nvar _index4 = _interopRequireDefault(_index3);\n\nvar _app = __webpack_require__(37);\n\nvar _app2 = _interopRequireDefault(_app);\n\nvar _renderFullPage = __webpack_require__(43);\n\nvar _renderFullPage2 = _interopRequireDefault(_renderFullPage);\n\nvar _reduxSaga = __webpack_require__(146);\n\nvar _reduxSaga2 = _interopRequireDefault(_reduxSaga);\n\nvar _effects = __webpack_require__(15);\n\nvar _show_uri = __webpack_require__(147);\n\nvar _show = __webpack_require__(8);\n\nvar _reactHelmet = __webpack_require__(14);\n\nvar _reactHelmet2 = _interopRequireDefault(_reactHelmet);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar returnSagaWithParams = function returnSagaWithParams(saga, params) {\n return (/*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _context.next = 2;\n return (0, _effects.call)(saga, params);\n\n case 2:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n })\n );\n};\n\nmodule.exports = function (req, res) {\n var context = {};\n\n // create and apply middleware\n var sagaMiddleware = (0, _reduxSaga2.default)();\n var middleware = (0, _redux.applyMiddleware)(sagaMiddleware);\n\n // create a new Redux store instance\n var store = (0, _redux.createStore)(_index2.default, middleware);\n\n // create saga\n var action = (0, _show.onHandleShowPageUri)(req.params);\n var saga = returnSagaWithParams(_show_uri.handleShowPageUri, action);\n\n // run the saga middleware\n sagaMiddleware.run(saga).done.then(function () {\n // render component to a string\n var html = (0, _server.renderToString)(_react2.default.createElement(\n _reactRedux.Provider,\n { store: store },\n _react2.default.createElement(\n _reactRouterDom.StaticRouter,\n { location: req.url, context: context },\n _react2.default.createElement(\n _index4.default,\n null,\n _react2.default.createElement(_app2.default, null)\n )\n )\n ));\n\n // get head tags from helmet\n var helmet = _reactHelmet2.default.renderStatic();\n\n // check for a redirect\n if (context.url) {\n return res.redirect(301, context.url);\n }\n\n // get the initial state from our Redux store\n var preloadedState = store.getState();\n\n // send the rendered page back to the client\n res.send((0, _renderFullPage2.default)(helmet, html, preloadedState));\n });\n};\n\n/***/ }),\n/* 146 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"redux-saga\");\n\n/***/ }),\n/* 147 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.handleShowPageUri = handleShowPageUri;\nexports.watchHandleShowPageUri = watchHandleShowPageUri;\n\nvar _effects = __webpack_require__(15);\n\nvar _show_action_types = __webpack_require__(12);\n\nvar actions = _interopRequireWildcard(_show_action_types);\n\nvar _show = __webpack_require__(8);\n\nvar _show_asset = __webpack_require__(148);\n\nvar _show_channel = __webpack_require__(150);\n\nvar _lbryUri = __webpack_require__(152);\n\nvar _lbryUri2 = _interopRequireDefault(_lbryUri);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _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; } }\n\nvar _marked = /*#__PURE__*/regeneratorRuntime.mark(parseAndUpdateIdentifierAndClaim),\n _marked2 = /*#__PURE__*/regeneratorRuntime.mark(parseAndUpdateClaimOnly),\n _marked3 = /*#__PURE__*/regeneratorRuntime.mark(handleShowPageUri),\n _marked4 = /*#__PURE__*/regeneratorRuntime.mark(watchHandleShowPageUri);\n\nfunction parseAndUpdateIdentifierAndClaim(modifier, claim) {\n var isChannel, channelName, channelClaimId, claimId, claimName, extension, _lbryUri$parseIdentif, _lbryUri$parseClaim;\n\n return regeneratorRuntime.wrap(function parseAndUpdateIdentifierAndClaim$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n // this is a request for an asset\n // claim will be an asset claim\n // the identifier could be a channel or a claim id\n isChannel = void 0, channelName = void 0, channelClaimId = void 0, claimId = void 0, claimName = void 0, extension = void 0;\n _context.prev = 1;\n _lbryUri$parseIdentif = _lbryUri2.default.parseIdentifier(modifier);\n isChannel = _lbryUri$parseIdentif.isChannel;\n channelName = _lbryUri$parseIdentif.channelName;\n channelClaimId = _lbryUri$parseIdentif.channelClaimId;\n claimId = _lbryUri$parseIdentif.claimId;\n _lbryUri$parseClaim = _lbryUri2.default.parseClaim(claim);\n claimName = _lbryUri$parseClaim.claimName;\n extension = _lbryUri$parseClaim.extension;\n _context.next = 17;\n break;\n\n case 12:\n _context.prev = 12;\n _context.t0 = _context['catch'](1);\n _context.next = 16;\n return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));\n\n case 16:\n return _context.abrupt('return', _context.sent);\n\n case 17:\n if (!isChannel) {\n _context.next = 21;\n break;\n }\n\n _context.next = 20;\n return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, null, channelName, channelClaimId, extension));\n\n case 20:\n return _context.abrupt('return', _context.sent);\n\n case 21:\n ;\n _context.next = 24;\n return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, claimId, null, null, extension));\n\n case 24:\n case 'end':\n return _context.stop();\n }\n }\n }, _marked, this, [[1, 12]]);\n}\nfunction parseAndUpdateClaimOnly(claim) {\n var isChannel, channelName, channelClaimId, _lbryUri$parseIdentif2, claimName, extension, _lbryUri$parseClaim2;\n\n return regeneratorRuntime.wrap(function parseAndUpdateClaimOnly$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n // this could be a request for an asset or a channel page\n // claim could be an asset claim or a channel claim\n isChannel = void 0, channelName = void 0, channelClaimId = void 0;\n _context2.prev = 1;\n _lbryUri$parseIdentif2 = _lbryUri2.default.parseIdentifier(claim);\n isChannel = _lbryUri$parseIdentif2.isChannel;\n channelName = _lbryUri$parseIdentif2.channelName;\n channelClaimId = _lbryUri$parseIdentif2.channelClaimId;\n _context2.next = 13;\n break;\n\n case 8:\n _context2.prev = 8;\n _context2.t0 = _context2['catch'](1);\n _context2.next = 12;\n return (0, _effects.put)((0, _show.onRequestError)(_context2.t0.message));\n\n case 12:\n return _context2.abrupt('return', _context2.sent);\n\n case 13:\n if (!isChannel) {\n _context2.next = 17;\n break;\n }\n\n _context2.next = 16;\n return (0, _effects.call)(_show_channel.newChannelRequest, (0, _show.onNewChannelRequest)(channelName, channelClaimId));\n\n case 16:\n return _context2.abrupt('return', _context2.sent);\n\n case 17:\n // if not for a channel, parse the claim request\n claimName = void 0, extension = void 0;\n _context2.prev = 18;\n _lbryUri$parseClaim2 = _lbryUri2.default.parseClaim(claim);\n claimName = _lbryUri$parseClaim2.claimName;\n extension = _lbryUri$parseClaim2.extension;\n _context2.next = 29;\n break;\n\n case 24:\n _context2.prev = 24;\n _context2.t1 = _context2['catch'](18);\n _context2.next = 28;\n return (0, _effects.put)((0, _show.onRequestError)(_context2.t1.message));\n\n case 28:\n return _context2.abrupt('return', _context2.sent);\n\n case 29:\n _context2.next = 31;\n return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, null, null, null, extension));\n\n case 31:\n case 'end':\n return _context2.stop();\n }\n }\n }, _marked2, this, [[1, 8], [18, 24]]);\n}\n\nfunction handleShowPageUri(action) {\n var _action$data, identifier, claim;\n\n return regeneratorRuntime.wrap(function handleShowPageUri$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _action$data = action.data, identifier = _action$data.identifier, claim = _action$data.claim;\n\n if (!identifier) {\n _context3.next = 5;\n break;\n }\n\n _context3.next = 4;\n return (0, _effects.call)(parseAndUpdateIdentifierAndClaim, identifier, claim);\n\n case 4:\n return _context3.abrupt('return', _context3.sent);\n\n case 5:\n _context3.next = 7;\n return (0, _effects.call)(parseAndUpdateClaimOnly, claim);\n\n case 7:\n case 'end':\n return _context3.stop();\n }\n }\n }, _marked3, this);\n};\n\nfunction watchHandleShowPageUri() {\n return regeneratorRuntime.wrap(function watchHandleShowPageUri$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.next = 2;\n return (0, _effects.takeLatest)(actions.HANDLE_SHOW_URI, handleShowPageUri);\n\n case 2:\n case 'end':\n return _context4.stop();\n }\n }\n }, _marked4, this);\n};\n\n/***/ }),\n/* 148 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.newAssetRequest = newAssetRequest;\nexports.watchNewAssetRequest = watchNewAssetRequest;\n\nvar _effects = __webpack_require__(15);\n\nvar _show_action_types = __webpack_require__(12);\n\nvar actions = _interopRequireWildcard(_show_action_types);\n\nvar _show = __webpack_require__(8);\n\nvar _assetApi = __webpack_require__(149);\n\nvar _show2 = __webpack_require__(13);\n\nvar _site = __webpack_require__(44);\n\nfunction _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; } }\n\nvar _marked = /*#__PURE__*/regeneratorRuntime.mark(newAssetRequest),\n _marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchNewAssetRequest);\n\nfunction newAssetRequest(action) {\n var _action$data, requestType, requestId, name, modifier, state, host, longId, _ref, assetKey, shortId, _ref2, claimData, _ref3;\n\n return regeneratorRuntime.wrap(function newAssetRequest$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _action$data = action.data, requestType = _action$data.requestType, requestId = _action$data.requestId, name = _action$data.name, modifier = _action$data.modifier;\n // put an action to update the request in redux\n\n _context.next = 3;\n return (0, _effects.put)((0, _show.onRequestUpdate)(requestType, requestId));\n\n case 3:\n _context.next = 5;\n return (0, _effects.select)(_show2.selectShowState);\n\n case 5:\n state = _context.sent;\n _context.next = 8;\n return (0, _effects.select)(_site.selectSiteHost);\n\n case 8:\n host = _context.sent;\n\n if (!state.requestList[requestId]) {\n _context.next = 11;\n break;\n }\n\n return _context.abrupt('return', null);\n\n case 11:\n // get long id && add request to request list\n longId = void 0;\n _context.prev = 12;\n _context.next = 15;\n return (0, _effects.call)(_assetApi.getLongClaimId, host, name, modifier);\n\n case 15:\n _ref = _context.sent;\n longId = _ref.data;\n _context.next = 24;\n break;\n\n case 19:\n _context.prev = 19;\n _context.t0 = _context['catch'](12);\n _context.next = 23;\n return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));\n\n case 23:\n return _context.abrupt('return', _context.sent);\n\n case 24:\n assetKey = 'a#' + name + '#' + longId;\n _context.next = 27;\n return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, assetKey));\n\n case 27:\n if (!state.assetList[assetKey]) {\n _context.next = 29;\n break;\n }\n\n return _context.abrupt('return', null);\n\n case 29:\n // get short Id\n shortId = void 0;\n _context.prev = 30;\n _context.next = 33;\n return (0, _effects.call)(_assetApi.getShortId, host, name, longId);\n\n case 33:\n _ref2 = _context.sent;\n shortId = _ref2.data;\n _context.next = 42;\n break;\n\n case 37:\n _context.prev = 37;\n _context.t1 = _context['catch'](30);\n _context.next = 41;\n return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message));\n\n case 41:\n return _context.abrupt('return', _context.sent);\n\n case 42:\n // get asset claim data\n claimData = void 0;\n _context.prev = 43;\n _context.next = 46;\n return (0, _effects.call)(_assetApi.getClaimData, host, name, longId);\n\n case 46:\n _ref3 = _context.sent;\n claimData = _ref3.data;\n _context.next = 55;\n break;\n\n case 50:\n _context.prev = 50;\n _context.t2 = _context['catch'](43);\n _context.next = 54;\n return (0, _effects.put)((0, _show.onRequestError)(_context.t2.message));\n\n case 54:\n return _context.abrupt('return', _context.sent);\n\n case 55:\n _context.next = 57;\n return (0, _effects.put)((0, _show.addAssetToAssetList)(assetKey, null, name, longId, shortId, claimData));\n\n case 57:\n _context.next = 59;\n return (0, _effects.put)((0, _show.onRequestError)(null));\n\n case 59:\n case 'end':\n return _context.stop();\n }\n }\n }, _marked, this, [[12, 19], [30, 37], [43, 50]]);\n};\n\nfunction watchNewAssetRequest() {\n return regeneratorRuntime.wrap(function watchNewAssetRequest$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _context2.next = 2;\n return (0, _effects.takeLatest)(actions.ASSET_REQUEST_NEW, newAssetRequest);\n\n case 2:\n case 'end':\n return _context2.stop();\n }\n }\n }, _marked2, this);\n};\n\n/***/ }),\n/* 149 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getLongClaimId = getLongClaimId;\nexports.getShortId = getShortId;\nexports.getClaimData = getClaimData;\n\nvar _request = __webpack_require__(11);\n\nvar _request2 = _interopRequireDefault(_request);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction getLongClaimId(host, name, modifier) {\n var body = {};\n // create request params\n if (modifier) {\n if (modifier.id) {\n body['claimId'] = modifier.id;\n } else {\n body['channelName'] = modifier.channel.name;\n body['channelClaimId'] = modifier.channel.id;\n }\n }\n body['claimName'] = name;\n var params = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body)\n };\n // create url\n var url = host + '/api/claim/long-id';\n // return the request promise\n return (0, _request2.default)(url, params);\n};\n\nfunction getShortId(host, name, claimId) {\n var url = host + '/api/claim/short-id/' + claimId + '/' + name;\n return (0, _request2.default)(url);\n};\n\nfunction getClaimData(host, name, claimId) {\n var url = host + '/api/claim/data/' + name + '/' + claimId;\n return (0, _request2.default)(url);\n};\n\n/***/ }),\n/* 150 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.newChannelRequest = newChannelRequest;\nexports.watchNewChannelRequest = watchNewChannelRequest;\nexports.watchUpdateChannelClaims = watchUpdateChannelClaims;\n\nvar _effects = __webpack_require__(15);\n\nvar _show_action_types = __webpack_require__(12);\n\nvar actions = _interopRequireWildcard(_show_action_types);\n\nvar _show = __webpack_require__(8);\n\nvar _channelApi = __webpack_require__(151);\n\nvar _show2 = __webpack_require__(13);\n\nvar _site = __webpack_require__(44);\n\nfunction _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; } }\n\nvar _marked = /*#__PURE__*/regeneratorRuntime.mark(newChannelRequest),\n _marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchNewChannelRequest),\n _marked3 = /*#__PURE__*/regeneratorRuntime.mark(getNewClaimsAndUpdateChannel),\n _marked4 = /*#__PURE__*/regeneratorRuntime.mark(watchUpdateChannelClaims);\n\nfunction newChannelRequest(action) {\n var _action$data, requestType, requestId, channelName, channelId, state, host, longId, shortId, _ref, _ref$data, channelKey, claimsData, _ref2;\n\n return regeneratorRuntime.wrap(function newChannelRequest$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _action$data = action.data, requestType = _action$data.requestType, requestId = _action$data.requestId, channelName = _action$data.channelName, channelId = _action$data.channelId;\n // put an action to update the request in redux\n\n _context.next = 3;\n return (0, _effects.put)((0, _show.onRequestUpdate)(requestType, requestId));\n\n case 3:\n _context.next = 5;\n return (0, _effects.select)(_show2.selectShowState);\n\n case 5:\n state = _context.sent;\n _context.next = 8;\n return (0, _effects.select)(_site.selectSiteHost);\n\n case 8:\n host = _context.sent;\n\n if (!state.requestList[requestId]) {\n _context.next = 11;\n break;\n }\n\n return _context.abrupt('return', null);\n\n case 11:\n // get channel long id\n longId = void 0, shortId = void 0;\n _context.prev = 12;\n _context.next = 15;\n return (0, _effects.call)(_channelApi.getChannelData, host, channelName, channelId);\n\n case 15:\n _ref = _context.sent;\n _ref$data = _ref.data;\n longId = _ref$data.longChannelClaimId;\n shortId = _ref$data.shortChannelClaimId;\n _context.next = 26;\n break;\n\n case 21:\n _context.prev = 21;\n _context.t0 = _context['catch'](12);\n _context.next = 25;\n return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));\n\n case 25:\n return _context.abrupt('return', _context.sent);\n\n case 26:\n // store the request in the channel requests list\n channelKey = 'c#' + channelName + '#' + longId;\n _context.next = 29;\n return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, channelKey));\n\n case 29:\n if (!state.channelList[channelKey]) {\n _context.next = 31;\n break;\n }\n\n return _context.abrupt('return', null);\n\n case 31:\n // get channel claims data\n claimsData = void 0;\n _context.prev = 32;\n _context.next = 35;\n return (0, _effects.call)(_channelApi.getChannelClaims, host, longId, channelName, 1);\n\n case 35:\n _ref2 = _context.sent;\n claimsData = _ref2.data;\n _context.next = 44;\n break;\n\n case 39:\n _context.prev = 39;\n _context.t1 = _context['catch'](32);\n _context.next = 43;\n return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message));\n\n case 43:\n return _context.abrupt('return', _context.sent);\n\n case 44:\n _context.next = 46;\n return (0, _effects.put)((0, _show.addNewChannelToChannelList)(channelKey, channelName, shortId, longId, claimsData));\n\n case 46:\n _context.next = 48;\n return (0, _effects.put)((0, _show.onRequestError)(null));\n\n case 48:\n case 'end':\n return _context.stop();\n }\n }\n }, _marked, this, [[12, 21], [32, 39]]);\n}\n\nfunction watchNewChannelRequest() {\n return regeneratorRuntime.wrap(function watchNewChannelRequest$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _context2.next = 2;\n return (0, _effects.takeLatest)(actions.CHANNEL_REQUEST_NEW, newChannelRequest);\n\n case 2:\n case 'end':\n return _context2.stop();\n }\n }\n }, _marked2, this);\n};\n\nfunction getNewClaimsAndUpdateChannel(action) {\n var _action$data2, channelKey, name, longId, page, host, claimsData, _ref3;\n\n return regeneratorRuntime.wrap(function getNewClaimsAndUpdateChannel$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _action$data2 = action.data, channelKey = _action$data2.channelKey, name = _action$data2.name, longId = _action$data2.longId, page = _action$data2.page;\n _context3.next = 3;\n return (0, _effects.select)(_site.selectSiteHost);\n\n case 3:\n host = _context3.sent;\n claimsData = void 0;\n _context3.prev = 5;\n _context3.next = 8;\n return (0, _effects.call)(_channelApi.getChannelClaims, host, longId, name, page);\n\n case 8:\n _ref3 = _context3.sent;\n claimsData = _ref3.data;\n _context3.next = 17;\n break;\n\n case 12:\n _context3.prev = 12;\n _context3.t0 = _context3['catch'](5);\n _context3.next = 16;\n return (0, _effects.put)((0, _show.onRequestError)(_context3.t0.message));\n\n case 16:\n return _context3.abrupt('return', _context3.sent);\n\n case 17:\n _context3.next = 19;\n return (0, _effects.put)((0, _show.updateChannelClaims)(channelKey, claimsData));\n\n case 19:\n case 'end':\n return _context3.stop();\n }\n }\n }, _marked3, this, [[5, 12]]);\n}\n\nfunction watchUpdateChannelClaims() {\n return regeneratorRuntime.wrap(function watchUpdateChannelClaims$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.next = 2;\n return (0, _effects.takeLatest)(actions.CHANNEL_CLAIMS_UPDATE_ASYNC, getNewClaimsAndUpdateChannel);\n\n case 2:\n case 'end':\n return _context4.stop();\n }\n }\n }, _marked4, this);\n}\n\n/***/ }),\n/* 151 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getChannelData = getChannelData;\nexports.getChannelClaims = getChannelClaims;\n\nvar _request = __webpack_require__(11);\n\nvar _request2 = _interopRequireDefault(_request);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction getChannelData(host, id, name) {\n if (!id) id = 'none';\n var url = host + '/api/channel/data/' + name + '/' + id;\n return (0, _request2.default)(url);\n};\n\nfunction getChannelClaims(host, longId, name, page) {\n if (!page) page = 1;\n var url = host + '/api/channel/claims/' + name + '/' + longId + '/' + page;\n return (0, _request2.default)(url);\n};\n\n/***/ }),\n/* 152 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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\"); } }; }();\n\nmodule.exports = {\n REGEXP_INVALID_CLAIM: /[^A-Za-z0-9-]/g,\n REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,\n REGEXP_ADDRESS: /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,\n CHANNEL_CHAR: '@',\n parseIdentifier: function parseIdentifier(identifier) {\n var componentsRegex = new RegExp('([^:$#/]*)' + // value (stops at the first separator or end)\n '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n\n var _componentsRegex$exec = componentsRegex // eslint-disable-line no-unused-vars\n .exec(identifier).map(function (match) {\n return match || null;\n }),\n _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 4),\n proto = _componentsRegex$exec2[0],\n value = _componentsRegex$exec2[1],\n modifierSeperator = _componentsRegex$exec2[2],\n modifier = _componentsRegex$exec2[3];\n\n // Validate and process name\n\n\n if (!value) {\n throw new Error('Check your URL. No channel name provided before \"' + modifierSeperator + '\"');\n }\n var isChannel = value.startsWith(module.exports.CHANNEL_CHAR);\n var channelName = isChannel ? value : null;\n var claimId = void 0;\n if (isChannel) {\n if (!channelName) {\n throw new Error('Check your URL. No channel name after \"@\".');\n }\n var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL);\n if (nameBadChars) {\n throw new Error('Check your URL. Invalid characters in channel name: \"' + nameBadChars.join(', ') + '\".');\n }\n } else {\n claimId = value;\n }\n\n // Validate and process modifier\n var channelClaimId = void 0;\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error('Check your URL. No modifier provided after separator \"' + modifierSeperator + '\"');\n }\n\n if (modifierSeperator === ':') {\n channelClaimId = modifier;\n } else {\n throw new Error('Check your URL. The \"' + modifierSeperator + '\" modifier is not currently supported');\n }\n }\n return {\n isChannel: isChannel,\n channelName: channelName,\n channelClaimId: channelClaimId || null,\n claimId: claimId || null\n };\n },\n parseClaim: function parseClaim(name) {\n var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first extension)\n '([:$#.]?)([^/]*)' // extension separator, extension (stops at the first path separator or end)\n );\n\n var _componentsRegex$exec3 = componentsRegex // eslint-disable-line no-unused-vars\n .exec(name).map(function (match) {\n return match || null;\n }),\n _componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4),\n proto = _componentsRegex$exec4[0],\n claimName = _componentsRegex$exec4[1],\n extensionSeperator = _componentsRegex$exec4[2],\n extension = _componentsRegex$exec4[3];\n\n // Validate and process name\n\n\n if (!claimName) {\n throw new Error('Check your URL. No claim name provided before \".\"');\n }\n var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM);\n if (nameBadChars) {\n throw new Error('Check your URL. Invalid characters in claim name: \"' + nameBadChars.join(', ') + '\".');\n }\n // Validate and process extension\n if (extensionSeperator) {\n if (!extension) {\n throw new Error('Check your URL. No file extension provided after separator \"' + extensionSeperator + '\".');\n }\n if (extensionSeperator !== '.') {\n throw new Error('Check your URL. The \"' + extensionSeperator + '\" separator is not supported in the claim name.');\n }\n }\n return {\n claimName: claimName,\n extension: extension || null\n };\n }\n};\n\n/***/ }),\n/* 153 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar handlePageRender = __webpack_require__(29);\n\nmodule.exports = function (app) {\n // a catch-all route if someone visits a page that does not exist\n app.use('*', function (req, res) {\n // send response\n handlePageRender(req, res);\n });\n};\n\n/***/ }),\n/* 154 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(155),\n logLevel = _require.logLevel;\n\nmodule.exports = function (winston) {\n // configure\n winston.configure({\n transports: [new winston.transports.Console({\n level: logLevel,\n timestamp: false,\n colorize: true,\n prettyPrint: true,\n handleExceptions: true,\n humanReadableUnhandledException: true\n })]\n });\n // test all the log levels\n winston.error('Level 0');\n winston.warn('Level 1');\n winston.info('Level 2');\n winston.verbose('Level 3');\n winston.debug('Level 4');\n winston.silly('Level 5');\n};\n\n/***/ }),\n/* 155 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar loggerConfig = {\n logLevel: 'debug' // options: silly, debug, verbose, info\n};\n\nmodule.exports = loggerConfig;\n\n/***/ }),\n/* 156 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar winstonSlackWebHook = __webpack_require__(157).SlackWebHook;\nvar slackConfig = __webpack_require__(158);\n\nmodule.exports = function (winston) {\n var slackWebHook = slackConfig.slackWebHook,\n slackErrorChannel = slackConfig.slackErrorChannel,\n slackInfoChannel = slackConfig.slackInfoChannel;\n\n if (slackWebHook) {\n // add a transport for errors to slack\n if (slackErrorChannel) {\n winston.add(winstonSlackWebHook, {\n name: 'slack-errors-transport',\n level: 'warn',\n webhookUrl: slackWebHook,\n channel: slackErrorChannel,\n username: 'spee.ch',\n iconEmoji: ':face_with_head_bandage:'\n });\n };\n if (slackInfoChannel) {\n winston.add(winstonSlackWebHook, {\n name: 'slack-info-transport',\n level: 'info',\n webhookUrl: slackWebHook,\n channel: slackInfoChannel,\n username: 'spee.ch',\n iconEmoji: ':nerd_face:'\n });\n };\n // send test message\n winston.error('Slack \"error\" logging is online.');\n winston.info('Slack \"info\" logging is online.');\n } else {\n winston.warn('Slack logging is not enabled because no slackWebHook config var provided.');\n }\n};\n\n/***/ }),\n/* 157 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"winston-slack-webhook\");\n\n/***/ }),\n/* 158 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction SlackConfig() {\n this.slackWebHook = 'default';\n this.slackErrorChannel = 'default';\n this.slackInfoChannel = 'default';\n};\n\nmodule.exports = new SlackConfig();\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// index.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 45);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap e7360edfffe873533ea7","module.exports = require(\"react\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react\"\n// module id = 0\n// module chunks = 0","module.exports = require(\"react-redux\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-redux\"\n// module id = 1\n// module chunks = 0","module.exports = require(\"winston\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"winston\"\n// module id = 2\n// module chunks = 0","module.exports = require(\"react-router-dom\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-router-dom\"\n// module id = 3\n// module chunks = 0","import * as actions from 'constants/publish_action_types';\n\n// export action creators\nexport function selectFile (file) {\n return {\n type: actions.FILE_SELECTED,\n data: file,\n };\n};\n\nexport function clearFile () {\n return {\n type: actions.FILE_CLEAR,\n };\n};\n\nexport function updateMetadata (name, value) {\n return {\n type: actions.METADATA_UPDATE,\n data: {\n name,\n value,\n },\n };\n};\n\nexport function updateClaim (value) {\n return {\n type: actions.CLAIM_UPDATE,\n data: value,\n };\n};\n\nexport function setPublishInChannel (channel) {\n return {\n type: actions.SET_PUBLISH_IN_CHANNEL,\n channel,\n };\n};\n\nexport function updatePublishStatus (status, message) {\n return {\n type: actions.PUBLISH_STATUS_UPDATE,\n data: {\n status,\n message,\n },\n };\n};\n\nexport function updateError (name, value) {\n return {\n type: actions.ERROR_UPDATE,\n data: {\n name,\n value,\n },\n };\n};\n\nexport function updateSelectedChannel (channelName) {\n return {\n type: actions.SELECTED_CHANNEL_UPDATE,\n data: channelName,\n };\n};\n\nexport function toggleMetadataInputs (showMetadataInputs) {\n return {\n type: actions.TOGGLE_METADATA_INPUTS,\n data: showMetadataInputs,\n };\n};\n\nexport function onNewThumbnail (file) {\n return {\n type: actions.THUMBNAIL_NEW,\n data: file,\n };\n};\n\nexport function startPublish (history) {\n return {\n type: actions.PUBLISH_START,\n data: { history },\n };\n}\n\n\n\n// WEBPACK FOOTER //\n// ./client/actions/publish.js","function SiteConfig () {\n this.analytics = {\n googleId: 'default',\n };\n this.assetDefaults = {\n description: 'An asset published on Spee.ch',\n thumbnail : 'https://spee.ch/assets/img/video_thumb_default.png',\n title : 'Spee.ch',\n };\n this.auth = {\n sessionKey: 'default',\n };\n this.details = {\n description: 'Open-source, decentralized image and video sharing.',\n host : 'default',\n port : 3000,\n title : 'Spee.ch',\n twitter : '@spee_ch',\n };\n this.publishing = {\n additionalClaimAddresses: [],\n disabled : false,\n disabledMessage : 'Please check back soon.',\n primaryClaimAddress : 'default',\n thumbnailChannel : 'default',\n thumbnailChannelId : 'default',\n uploadDirectory : '/home/lbry/Uploads',\n };\n};\n\nmodule.exports = new SiteConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/siteConfig.js","const Sequelize = require('sequelize');\nconst logger = require('winston');\n\nconsole.log('exporting sequelize models');\nconst { database, username, password } = require('../../config/mysqlConfig');\nconst db = {};\n// set sequelize options\nconst sequelize = new Sequelize(database, username, password, {\n host : 'localhost',\n dialect : 'mysql',\n dialectOptions: {decimalNumbers: true}, // fix to ensure DECIMAL will not be stored as a string\n logging : false,\n pool : {\n max : 5,\n min : 0,\n idle : 10000,\n acquire: 10000,\n },\n});\n\n// establish mysql connection\nsequelize\n .authenticate()\n .then(() => {\n logger.info('Sequelize has established mysql connection successfully.');\n })\n .catch(err => {\n logger.error('Sequelize was unable to connect to the database:', err);\n });\n\n// manually add each model to the db object\nconst Certificate = require('./certificate.js');\nconst Channel = require('./channel.js');\nconst Claim = require('./claim.js');\nconst File = require('./file.js');\nconst Request = require('./request.js');\nconst User = require('./user.js');\ndb['Certificate'] = sequelize.import('Certificate', Certificate);\ndb['Channel'] = sequelize.import('Channel', Channel);\ndb['Claim'] = sequelize.import('Claim', Claim);\ndb['File'] = sequelize.import('File', File);\ndb['Request'] = sequelize.import('Request', Request);\ndb['User'] = sequelize.import('User', User);\n\n// run model.association for each model in the db object that has an association\nObject.keys(db).forEach(modelName => {\n if (db[modelName].associate) {\n logger.info('Associating model:', modelName);\n db[modelName].associate(db);\n }\n});\n\ndb.sequelize = sequelize;\ndb.Sequelize = Sequelize;\n\n// add an 'upsert' method to the db object\ndb.upsert = (Model, values, condition, tableName) => {\n return Model\n .findOne({\n where: condition,\n })\n .then(obj => {\n if (obj) { // update\n logger.debug(`updating record in db.${tableName}`);\n return obj.update(values);\n } else { // insert\n logger.debug(`creating record in db.${tableName}`);\n return Model.create(values);\n }\n })\n .catch(function (error) {\n logger.error(`${tableName}.upsert error`, error);\n throw error;\n });\n};\n\nmodule.exports = db;\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/index.js","import { connect } from 'react-redux';\nimport { updateLoggedInChannel } from 'actions/channel';\nimport {updateSelectedChannel} from 'actions/publish';\nimport View from './view';\n\nconst mapStateToProps = ({ channel, site }) => {\n return {\n channelName : channel.loggedInChannel.name,\n channelShortId: channel.loggedInChannel.shortId,\n channelLongId : channel.loggedInChannel.longId,\n siteDescription: site.description,\n };\n};\n\nconst mapDispatchToProps = dispatch => {\n return {\n onChannelLogin: (name, shortId, longId) => {\n dispatch(updateLoggedInChannel(name, shortId, longId));\n dispatch(updateSelectedChannel(name));\n },\n onChannelLogout: () => {\n dispatch(updateLoggedInChannel(null, null, null));\n },\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/NavBar/index.js","import * as actions from 'constants/show_action_types';\n\nimport { CHANNEL, ASSET_LITE, ASSET_DETAILS } from 'constants/show_request_types';\n\n// basic request parsing\nexport function onHandleShowPageUri (params) {\n return {\n type: actions.HANDLE_SHOW_URI,\n data: params,\n };\n};\n\nexport function onRequestError (error) {\n return {\n type: actions.REQUEST_ERROR,\n data: error,\n };\n};\n\nexport function onNewChannelRequest (channelName, channelId) {\n const requestType = CHANNEL;\n const requestId = `cr#${channelName}#${channelId}`;\n return {\n type: actions.CHANNEL_REQUEST_NEW,\n data: { requestType, requestId, channelName, channelId },\n };\n};\n\nexport function onNewAssetRequest (name, id, channelName, channelId, extension) {\n const requestType = extension ? ASSET_LITE : ASSET_DETAILS;\n const requestId = `ar#${name}#${id}#${channelName}#${channelId}`;\n return {\n type: actions.ASSET_REQUEST_NEW,\n data: {\n requestType,\n requestId,\n name,\n modifier: {\n id,\n channel: {\n name: channelName,\n id : channelId,\n },\n },\n },\n };\n};\n\nexport function onRequestUpdate (requestType, requestId) {\n return {\n type: actions.REQUEST_UPDATE,\n data: {\n requestType,\n requestId,\n },\n };\n};\n\nexport function addRequestToRequestList (id, error, key) {\n return {\n type: actions.REQUEST_LIST_ADD,\n data: { id, error, key },\n };\n};\n\n// asset actions\n\nexport function addAssetToAssetList (id, error, name, claimId, shortId, claimData) {\n return {\n type: actions.ASSET_ADD,\n data: { id, error, name, claimId, shortId, claimData },\n };\n}\n\n// channel actions\n\nexport function addNewChannelToChannelList (id, name, shortId, longId, claimsData) {\n return {\n type: actions.CHANNEL_ADD,\n data: { id, name, shortId, longId, claimsData },\n };\n};\n\nexport function onUpdateChannelClaims (channelKey, name, longId, page) {\n return {\n type: actions.CHANNEL_CLAIMS_UPDATE_ASYNC,\n data: {channelKey, name, longId, page},\n };\n};\n\nexport function updateChannelClaims (channelListId, claimsData) {\n return {\n type: actions.CHANNEL_CLAIMS_UPDATE_SUCCESS,\n data: {channelListId, claimsData},\n };\n};\n\n// display a file\n\nexport function fileRequested (name, claimId) {\n return {\n type: actions.FILE_REQUESTED,\n data: { name, claimId },\n };\n};\n\nexport function updateFileAvailability (status) {\n return {\n type: actions.FILE_AVAILABILITY_UPDATE,\n data: status,\n };\n};\n\nexport function updateDisplayAssetError (error) {\n return {\n type: actions.DISPLAY_ASSET_ERROR,\n data: error,\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/actions/show.js","import { connect } from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ site }) => {\n const { defaultDescription, defaultThumbnail, description: siteDescription, host: siteHost, title: siteTitle, twitter: siteTwitter } = site;\n return {\n defaultDescription,\n defaultThumbnail,\n siteDescription,\n siteHost,\n siteTitle,\n siteTwitter,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/SEO/index.js","module.exports = require(\"prop-types\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"prop-types\"\n// module id = 10\n// module chunks = 0","import 'cross-fetch/polyfill';\n\n/**\n * Parses the JSON returned by a network request\n *\n * @param {object} response A response from a network request\n *\n * @return {object} The parsed JSON from the request\n */\nfunction parseJSON (response) {\n if (response.status === 204 || response.status === 205) {\n return null;\n }\n return response.json();\n}\n\n/**\n * Parses the status returned by a network request\n *\n * @param {object} response A response from a network request\n * @param {object} response The parsed JSON from the network request\n *\n * @return {object | undefined} Returns object with status and statusText, or undefined\n */\nfunction checkStatus (response, jsonResponse) {\n if (response.status >= 200 && response.status < 300) {\n return jsonResponse;\n }\n const error = new Error(jsonResponse.message);\n error.response = response;\n throw error;\n}\n\n/**\n * Requests a URL, returning a promise\n *\n * @param {string} url The URL we want to request\n * @param {object} [options] The options we want to pass to \"fetch\"\n *\n * @return {object} The response data\n */\n\nexport default function request (url, options) {\n return fetch(url, options)\n .then(response => {\n return Promise.all([response, parseJSON(response)]);\n })\n .then(([response, jsonResponse]) => {\n return checkStatus(response, jsonResponse);\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ./client/utils/request.js","// request actions\nexport const HANDLE_SHOW_URI = 'HANDLE_SHOW_URI';\nexport const REQUEST_ERROR = 'REQUEST_ERROR';\nexport const REQUEST_UPDATE = 'REQUEST_UPDATE';\nexport const ASSET_REQUEST_NEW = 'ASSET_REQUEST_NEW';\nexport const CHANNEL_REQUEST_NEW = 'CHANNEL_REQUEST_NEW';\nexport const REQUEST_LIST_ADD = 'REQUEST_LIST_ADD';\n\n// asset actions\nexport const ASSET_ADD = `ASSET_ADD`;\n\n// channel actions\nexport const CHANNEL_ADD = 'CHANNEL_ADD';\n\nexport const CHANNEL_CLAIMS_UPDATE_ASYNC = 'CHANNEL_CLAIMS_UPDATE_ASYNC';\nexport const CHANNEL_CLAIMS_UPDATE_SUCCESS = 'CHANNEL_CLAIMS_UPDATE_SUCCESS';\n\n// asset/file display actions\nexport const FILE_REQUESTED = 'FILE_REQUESTED';\nexport const FILE_AVAILABILITY_UPDATE = 'FILE_AVAILABILITY_UPDATE';\nexport const DISPLAY_ASSET_ERROR = 'DISPLAY_ASSET_ERROR';\n\n\n\n// WEBPACK FOOTER //\n// ./client/constants/show_action_types.js","export const selectAsset = (show) => {\n const request = show.requestList[show.request.id];\n const assetKey = request.key;\n return show.assetList[assetKey];\n};\n\nexport const selectShowState = (state) => {\n return state.show;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/selectors/show.js","module.exports = require(\"react-helmet\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-helmet\"\n// module id = 14\n// module chunks = 0","module.exports = require(\"redux-saga/effects\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"redux-saga/effects\"\n// module id = 15\n// module chunks = 0","const axios = require('axios');\nconst logger = require('winston');\nconst { api: { apiHost, apiPort } } = require('../../config/lbryConfig.js');\nconst lbryApiUri = 'http://' + apiHost + ':' + apiPort;\nconst { chooseGaLbrynetPublishLabel, sendGATimingEvent } = require('./googleAnalytics.js');\n\nconst handleLbrynetResponse = ({ data }, resolve, reject) => {\n logger.debug('lbry api data:', data);\n if (data.result) {\n // check for an error\n if (data.result.error) {\n logger.debug('Lbrynet api error:', data.result.error);\n reject(new Error(data.result.error));\n return;\n };\n resolve(data.result);\n return;\n }\n // fallback in case it just timed out\n reject(JSON.stringify(data));\n};\n\nmodule.exports = {\n publishClaim (publishParams) {\n logger.debug(`lbryApi >> Publishing claim to \"${publishParams.name}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'publish',\n params: publishParams,\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaim (uri) {\n logger.debug(`lbryApi >> Getting Claim for \"${uri}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'get',\n params: { uri, timeout: 20 },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaimList (claimName) {\n logger.debug(`lbryApi >> Getting claim_list for \"${claimName}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'claim_list',\n params: { name: claimName },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n resolveUri (uri) {\n logger.debug(`lbryApi >> Resolving URI for \"${uri}\"`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'resolve',\n params: { uri },\n })\n .then(({ data }) => {\n sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now());\n if (data.result[uri].error) { // check for errors\n reject(data.result[uri].error);\n } else { // if no errors, resolve\n resolve(data.result[uri]);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getDownloadDirectory () {\n logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...');\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'settings_get',\n })\n .then(({ data }) => {\n sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now());\n if (data.result) {\n resolve(data.result.download_directory);\n } else {\n return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.');\n }\n })\n .catch(error => {\n logger.error('Lbrynet Error:', error);\n resolve('/home/lbry/Downloads/');\n });\n });\n },\n createChannel (name) {\n logger.debug(`lbryApi >> Creating channel for ${name}...`);\n const gaStartTime = Date.now();\n return new Promise((resolve, reject) => {\n axios\n .post(lbryApiUri, {\n method: 'channel_new',\n params: {\n channel_name: name,\n amount : 0.1,\n },\n })\n .then(response => {\n sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now());\n handleLbrynetResponse(response, resolve, reject);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/lbryApi.js","const logger = require('winston');\nconst ua = require('universal-analytics');\nconst { analytics : { googleId }, details: { title } } = require('../../config/siteConfig.js');\n\nfunction createServeEventParams (headers, ip, originalUrl) {\n return {\n eventCategory : 'client requests',\n eventAction : 'serve request',\n eventLabel : originalUrl,\n ipOverride : ip,\n userAgentOverride: headers['user-agent'],\n };\n};\n\nfunction createPublishTimingEventParams (category, variable, label, startTime, endTime) {\n const duration = endTime - startTime;\n return {\n userTimingCategory : category,\n userTimingVariableName: variable,\n userTimingTime : duration,\n userTimingLabel : label,\n };\n};\n\nfunction sendGoogleAnalyticsEvent (ip, params) {\n const visitorId = ip.replace(/\\./g, '-');\n const visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.event(params, (err) => {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n });\n};\n\nfunction sendGoogleAnalyticsTiming (visitorId, params) {\n const visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });\n visitor.timing(params, (err) => {\n if (err) {\n logger.error('Google Analytics Event Error >>', err);\n }\n logger.debug(`Timing event successfully sent to google analytics`);\n });\n};\n\nmodule.exports = {\n sendGAServeEvent (headers, ip, originalUrl) {\n const params = createServeEventParams(headers, ip, originalUrl);\n sendGoogleAnalyticsEvent(ip, params);\n },\n sendGATimingEvent (category, variable, label, startTime, endTime) {\n const params = createPublishTimingEventParams(category, variable, label, startTime, endTime);\n sendGoogleAnalyticsTiming(title, params);\n },\n chooseGaLbrynetPublishLabel ({ channel_name: channelName, channel_id: channelId }) {\n return (channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM');\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/googleAnalytics.js","module.exports = require(\"redux\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"redux\"\n// module id = 18\n// module chunks = 0","import * as actions from 'constants/channel_action_types';\n\n// export action creators\n\nexport function updateLoggedInChannel (name, shortId, longId) {\n return {\n type: actions.CHANNEL_UPDATE,\n data: {\n name,\n shortId,\n longId,\n },\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/actions/channel.js","import React from 'react';\nimport PropTypes from 'prop-types';\nimport ActiveStatusBar from 'components/ActiveStatusBar';\nimport InactiveStatusBar from 'components/InactiveStatusBar';\n\nclass ProgressBar extends React.Component {\n constructor (props) {\n super(props);\n this.state = {\n bars : [],\n index : 0,\n incrementer: 1,\n };\n this.createBars = this.createBars.bind(this);\n this.startProgressBar = this.startProgressBar.bind(this);\n this.updateProgressBar = this.updateProgressBar.bind(this);\n this.stopProgressBar = this.stopProgressBar.bind(this);\n }\n componentDidMount () {\n this.createBars();\n this.startProgressBar();\n }\n componentWillUnmount () {\n this.stopProgressBar();\n }\n createBars () {\n const bars = [];\n for (let i = 0; i <= this.props.size; i++) {\n bars.push({isActive: false});\n }\n this.setState({ bars });\n }\n startProgressBar () {\n this.updateInterval = setInterval(this.updateProgressBar.bind(this), 300);\n };\n updateProgressBar () {\n let index = this.state.index;\n let incrementer = this.state.incrementer;\n let bars = this.state.bars;\n // flip incrementer if necessary, to stay in bounds\n if ((index < 0) || (index > this.props.size)) {\n incrementer = incrementer * -1;\n index += incrementer;\n }\n // update the indexed bar\n if (incrementer > 0) {\n bars[index].isActive = true;\n } else {\n bars[index].isActive = false;\n };\n // increment index\n index += incrementer;\n // update state\n this.setState({\n bars,\n incrementer,\n index,\n });\n };\n stopProgressBar () {\n clearInterval(this.updateInterval);\n };\n render () {\n return (\n
\n {this.state.bars.map((bar, index) => bar.isActive ? : )}\n
\n );\n }\n};\n\nProgressBar.propTypes = {\n size: PropTypes.number.isRequired,\n};\n\nexport default ProgressBar;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/ProgressBar/index.jsx","import React from 'react';\nimport PropTypes from 'prop-types';\nimport NavBar from 'containers/NavBar';\n\nclass ErrorPage extends React.Component {\n render () {\n const { error } = this.props;\n return (\n
\n \n
\n

{error}

\n
\n
\n );\n }\n};\n\nErrorPage.propTypes = {\n error: PropTypes.string.isRequired,\n};\n\nexport default ErrorPage;\n\n\n\n// WEBPACK FOOTER //\n// ./client/pages/ErrorPage/index.jsx","module.exports = require(\"passport\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"passport\"\n// module id = 22\n// module chunks = 0","module.exports = require(\"passport-local\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"passport-local\"\n// module id = 23\n// module chunks = 0","module.exports = require(\"sequelize\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"sequelize\"\n// module id = 24\n// module chunks = 0","module.exports = {\n returnShortId: function (claimsArray, longId) {\n let claimIndex;\n let shortId = longId.substring(0, 1); // default short id is the first letter\n let shortIdLength = 0;\n // find the index of this claim id\n claimIndex = claimsArray.findIndex(element => {\n return element.claimId === longId;\n });\n if (claimIndex < 0) {\n throw new Error('claim id not found in claims list');\n }\n // get an array of all claims with lower height\n let possibleMatches = claimsArray.slice(0, claimIndex);\n // remove certificates with the same prefixes until none are left.\n while (possibleMatches.length > 0) {\n shortIdLength += 1;\n shortId = longId.substring(0, shortIdLength);\n possibleMatches = possibleMatches.filter(element => {\n return (element.claimId && (element.claimId.substring(0, shortIdLength) === shortId));\n });\n }\n return shortId;\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/sequelizeHelpers.js","const logger = require('winston');\nconst fs = require('fs');\n\nconst { details, publishing } = require('../../config/siteConfig.js');\n\nmodule.exports = {\n parsePublishApiRequestBody ({name, nsfw, license, title, description, thumbnail}) {\n // validate name\n if (!name) {\n throw new Error('no name field found in request');\n }\n const invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name);\n if (invalidNameCharacters) {\n throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and \"-\"');\n }\n // optional parameters\n nsfw = (nsfw === 'true');\n license = license || null;\n title = title || null;\n description = description || null;\n thumbnail = thumbnail || null;\n // return results\n return {\n name,\n nsfw,\n license,\n title,\n description,\n thumbnail,\n };\n },\n parsePublishApiRequestFiles ({file, thumbnail}) {\n // make sure a file was provided\n if (!file) {\n throw new Error('no file with key of [file] found in request');\n }\n if (!file.path) {\n throw new Error('no file path found');\n }\n if (!file.type) {\n throw new Error('no file type found');\n }\n if (!file.size) {\n throw new Error('no file type found');\n }\n // validate the file name\n if (/'/.test(file.name)) {\n throw new Error('apostrophes are not allowed in the file name');\n }\n // validate the file\n module.exports.validateFileTypeAndSize(file);\n // return results\n return {\n fileName : file.name,\n filePath : file.path,\n fileType : file.type,\n thumbnailFileName: (thumbnail ? thumbnail.name : null),\n thumbnailFilePath: (thumbnail ? thumbnail.path : null),\n thumbnailFileType: (thumbnail ? thumbnail.type : null),\n };\n },\n validateFileTypeAndSize (file) {\n // check file type and size\n switch (file.type) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n if (file.size > 10000000) {\n logger.debug('publish > file validation > .jpeg/.jpg/.png was too big');\n throw new Error('Sorry, images are limited to 10 megabytes.');\n }\n break;\n case 'image/gif':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .gif was too big');\n throw new Error('Sorry, .gifs are limited to 50 megabytes.');\n }\n break;\n case 'video/mp4':\n if (file.size > 50000000) {\n logger.debug('publish > file validation > .mp4 was too big');\n throw new Error('Sorry, videos are limited to 50 megabytes.');\n }\n break;\n default:\n logger.debug('publish > file validation > unrecognized file type');\n throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');\n }\n return file;\n },\n createBasicPublishParams (filePath, name, title, description, license, nsfw, thumbnail) {\n logger.debug(`Creating Publish Parameters`);\n // provide defaults for title\n if (title === null || title.trim() === '') {\n title = name;\n }\n // provide default for description\n if (description === null || description.trim() === '') {\n description = '';\n }\n // provide default for license\n if (license === null || license.trim() === '') {\n license = ' '; // default to empty string\n }\n // create the publish params\n const publishParams = {\n name,\n file_path: filePath,\n bid : 0.01,\n metadata : {\n description,\n title,\n author : details.title,\n language: 'en',\n license,\n nsfw,\n },\n claim_address: publishing.primaryClaimAddress,\n };\n // add thumbnail to channel if video\n if (thumbnail) {\n publishParams['metadata']['thumbnail'] = thumbnail;\n }\n return publishParams;\n },\n createThumbnailPublishParams (thumbnailFilePath, claimName, license, nsfw) {\n if (!thumbnailFilePath) {\n return;\n }\n logger.debug(`Creating Thumbnail Publish Parameters`);\n // create the publish params\n return {\n name : `${claimName}-thumb`,\n file_path: thumbnailFilePath,\n bid : 0.01,\n metadata : {\n title : `${claimName} thumbnail`,\n description: `a thumbnail for ${claimName}`,\n author : details.title,\n language : 'en',\n license,\n nsfw,\n },\n claim_address: publishing.primaryClaimAddress,\n channel_name : publishing.thumbnailChannel,\n channel_id : publishing.thumbnailChannelId,\n };\n },\n deleteTemporaryFile (filePath) {\n fs.unlink(filePath, err => {\n if (err) {\n logger.error(`error deleting temporary file ${filePath}`);\n throw err;\n }\n logger.debug(`successfully deleted ${filePath}`);\n });\n },\n addGetResultsToFileData (fileInfo, getResult) {\n fileInfo.fileName = getResult.file_name;\n fileInfo.filePath = getResult.download_path;\n return fileInfo;\n },\n createFileData ({ name, claimId, outpoint, height, address, nsfw, contentType }) {\n return {\n name,\n claimId,\n outpoint,\n height,\n address,\n fileName: '',\n filePath: '',\n fileType: contentType,\n nsfw,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/publishHelpers.js","const logger = require('winston');\n\nmodule.exports = {\n handleErrorResponse: function (originalUrl, ip, error, res) {\n logger.error(`Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));\n const [status, message] = module.exports.returnErrorMessageAndStatus(error);\n res\n .status(status)\n .json(module.exports.createErrorResponsePayload(status, message));\n },\n returnErrorMessageAndStatus: function (error) {\n let status, message;\n // check for daemon being turned off\n if (error.code === 'ECONNREFUSED') {\n status = 503;\n message = 'Connection refused. The daemon may not be running.';\n // fallback for everything else\n } else {\n status = 400;\n if (error.message) {\n message = error.message;\n } else {\n message = error;\n };\n };\n return [status, message];\n },\n useObjectPropertiesIfNoKeys: function (err) {\n if (Object.keys(err).length === 0) {\n let newErrorObject = {};\n Object.getOwnPropertyNames(err).forEach((key) => {\n newErrorObject[key] = err[key];\n });\n return newErrorObject;\n }\n return err;\n },\n createErrorResponsePayload (status, message) {\n return {\n status,\n success: false,\n message,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/errorHandlers.js","const db = require('../models/index');\nconst logger = require('winston');\nconst { returnPaginatedChannelClaims } = require('../helpers/channelPagination.js');\n\nconst NO_CHANNEL = 'NO_CHANNEL';\nconst NO_CLAIM = 'NO_CLAIM';\nconst NO_FILE = 'NO_FILE';\n\nmodule.exports = {\n getClaimId (channelName, channelClaimId, name, claimId) {\n if (channelName) {\n return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);\n } else {\n return module.exports.getClaimIdByClaim(name, claimId);\n }\n },\n getClaimIdByClaim (claimName, claimId) {\n logger.debug(`getClaimIdByClaim(${claimName}, ${claimId})`);\n return new Promise((resolve, reject) => {\n db.Claim.getLongClaimId(claimName, claimId)\n .then(longClaimId => {\n if (!longClaimId) {\n resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getClaimIdByChannel (channelName, channelClaimId, claimName) {\n logger.debug(`getClaimIdByChannel(${channelName}, ${channelClaimId}, ${claimName})`);\n return new Promise((resolve, reject) => {\n db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id\n .then(longChannelId => {\n if (!longChannelId) {\n return [null, null];\n }\n return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id\n })\n .then(([longChannelId, longClaimId]) => {\n if (!longChannelId) {\n return resolve(NO_CHANNEL);\n }\n if (!longClaimId) {\n return resolve(NO_CLAIM);\n }\n resolve(longClaimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getChannelData (channelName, channelClaimId, page) {\n return new Promise((resolve, reject) => {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId)\n .then(longChannelClaimId => {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);\n })\n .then(([longChannelClaimId, shortChannelClaimId]) => {\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. return all the channel information\n resolve({\n channelName,\n longChannelClaimId,\n shortChannelClaimId,\n });\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getChannelClaims (channelName, channelClaimId, page) {\n return new Promise((resolve, reject) => {\n // 1. get the long channel Id (make sure channel exists)\n db.Certificate.getLongChannelId(channelName, channelClaimId)\n .then(longChannelClaimId => {\n if (!longChannelClaimId) {\n return [null, null, null];\n }\n // 2. get the short ID and all claims for that channel\n return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);\n })\n .then(([longChannelClaimId, channelClaimsArray]) => {\n if (!longChannelClaimId) {\n return resolve(NO_CHANNEL);\n }\n // 3. format the data for the view, including pagination\n let paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);\n // 4. return all the channel information and contents\n resolve(paginatedChannelViewData);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n getLocalFileRecord (claimId, name) {\n return db.File.findOne({where: {claimId, name}})\n .then(file => {\n if (!file) {\n return NO_FILE;\n }\n return file.dataValues;\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/controllers/serveController.js","import React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport { createStore } from 'redux';\nimport Reducer from '../../client/reducers/index';\nimport { Provider } from 'react-redux';\nimport { StaticRouter } from 'react-router-dom';\nimport GAListener from '../../client/components/GAListener/index';\nimport App from '../../client/app';\nimport renderFullPage from './renderFullPage.js';\nimport Helmet from 'react-helmet';\n\nmodule.exports = (req, res) => {\n let context = {};\n\n // create a new Redux store instance\n const store = createStore(Reducer);\n\n // render component to a string\n const html = renderToString(\n \n \n \n \n \n \n \n );\n\n // get head tags from helmet\n const helmet = Helmet.renderStatic();\n\n // check for a redirect\n if (context.url) {\n // Somewhere a `` was rendered\n return res.redirect(301, context.url);\n } else {\n // we're good, send the response\n }\n\n // get the initial state from our Redux store\n const preloadedState = store.getState();\n\n // send the rendered page back to the client\n res.send(renderFullPage(helmet, html, preloadedState));\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/handlePageRender.jsx","module.exports = require(\"react-dom/server\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-dom/server\"\n// module id = 30\n// module chunks = 0","import { combineReducers } from 'redux';\nimport PublishReducer from 'reducers/publish';\nimport ChannelReducer from 'reducers/channel';\nimport ShowReducer from 'reducers/show';\nimport SiteReducer from 'reducers/site';\n\nexport default combineReducers({\n channel: ChannelReducer,\n publish: PublishReducer,\n show : ShowReducer,\n site : SiteReducer,\n});\n\n\n\n// WEBPACK FOOTER //\n// ./client/reducers/index.js","export const FILE_SELECTED = 'FILE_SELECTED';\nexport const FILE_CLEAR = 'FILE_CLEAR';\nexport const METADATA_UPDATE = 'METADATA_UPDATE';\nexport const CLAIM_UPDATE = 'CLAIM_UPDATE';\nexport const SET_PUBLISH_IN_CHANNEL = 'SET_PUBLISH_IN_CHANNEL';\nexport const PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE';\nexport const ERROR_UPDATE = 'ERROR_UPDATE';\nexport const SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE';\nexport const TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS';\nexport const THUMBNAIL_NEW = 'THUMBNAIL_NEW';\nexport const PUBLISH_START = 'PUBLISH_START';\n\n\n\n// WEBPACK FOOTER //\n// ./client/constants/publish_action_types.js","export const LOGIN = 'Existing';\nexport const CREATE = 'New';\n\n\n\n// WEBPACK FOOTER //\n// ./client/constants/publish_channel_select_states.js","export const CHANNEL_UPDATE = 'CHANNEL_UPDATE';\n\n\n\n// WEBPACK FOOTER //\n// ./client/constants/channel_action_types.js","export const LOCAL_CHECK = 'LOCAL_CHECK';\nexport const UNAVAILABLE = 'UNAVAILABLE';\nexport const ERROR = 'ERROR';\nexport const AVAILABLE = 'AVAILABLE';\n\n\n\n// WEBPACK FOOTER //\n// ./client/constants/asset_display_states.js","import React from 'react';\nimport GoogleAnalytics from 'react-ga';\nimport { withRouter } from 'react-router-dom';\nconst { analytics: { googleId } } = require('../../../config/siteConfig.js');\n\nGoogleAnalytics.initialize(googleId);\n\nclass GAListener extends React.Component {\n componentDidMount () {\n this.sendPageView(this.props.history.location);\n this.props.history.listen(this.sendPageView);\n }\n\n sendPageView (location) {\n GoogleAnalytics.set({ page: location.pathname });\n GoogleAnalytics.pageview(location.pathname);\n }\n\n render () {\n return this.props.children;\n }\n}\n\nexport default withRouter(GAListener);\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/GAListener/index.jsx","import React from 'react';\nimport { Route, Switch } from 'react-router-dom';\nimport HomePage from 'pages/HomePage'; // or use the provided local homepage\nimport AboutPage from 'pages/AboutPage';\nimport LoginPage from 'pages/LoginPage';\nimport ShowPage from 'pages/ShowPage';\nimport FourOhFourPage from 'containers/FourOhFourPage';\n\nconst App = () => {\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nexport default App;\n\n\n\n// WEBPACK FOOTER //\n// ./client/app.jsx","import { connect } from 'react-redux';\nimport { selectFile, updateError, clearFile } from 'actions/publish';\nimport View from './view';\n\nconst mapStateToProps = ({ publish }) => {\n return {\n file : publish.file,\n thumbnail: publish.thumbnail,\n fileError: publish.error.file,\n };\n};\n\nconst mapDispatchToProps = dispatch => {\n return {\n selectFile: (file) => {\n dispatch(selectFile(file));\n },\n setFileError: (value) => {\n dispatch(clearFile());\n dispatch(updateError('file', value));\n },\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/Dropzone/index.js","import { connect } from 'react-redux';\nimport { updateLoggedInChannel } from 'actions/channel';\nimport View from './view';\nimport {updateSelectedChannel} from '../../actions/publish';\n\nconst mapDispatchToProps = dispatch => {\n return {\n onChannelLogin: (name, shortId, longId) => {\n dispatch(updateLoggedInChannel(name, shortId, longId));\n dispatch(updateSelectedChannel(name));\n },\n };\n};\n\nexport default connect(null, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ChannelLoginForm/index.js","import { connect } from 'react-redux';\nimport { updateLoggedInChannel } from 'actions/channel';\nimport View from './view';\nimport {updateSelectedChannel} from 'actions/publish';\n\nconst mapDispatchToProps = dispatch => {\n return {\n onChannelLogin: (name, shortId, longId) => {\n dispatch(updateLoggedInChannel(name, shortId, longId));\n dispatch(updateSelectedChannel(name));\n },\n };\n};\n\nexport default connect(null, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ChannelCreateForm/index.js","export const CHANNEL = 'CHANNEL';\nexport const ASSET_LITE = 'ASSET_LITE';\nexport const ASSET_DETAILS = 'ASSET_DETAILS';\n\n\n\n// WEBPACK FOOTER //\n// ./client/constants/show_request_types.js","import { connect } from 'react-redux';\nimport View from './view';\nimport { fileRequested } from 'actions/show';\nimport { selectAsset } from 'selectors/show';\n\nconst mapStateToProps = ({ show }) => {\n // select error and status\n const error = show.displayAsset.error;\n const status = show.displayAsset.status;\n // select asset\n const asset = selectAsset(show);\n // return props\n return {\n error,\n status,\n asset,\n };\n};\n\nconst mapDispatchToProps = dispatch => {\n return {\n onFileRequest: (name, claimId) => {\n dispatch(fileRequested(name, claimId));\n },\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/AssetDisplay/index.js","module.exports = (helmet, html, preloadedState) => {\n // take the html and preloadedState and return the full page\n return `\n \n \n \n \n \n \n \n ${helmet.title.toString()}\n ${helmet.meta.toString()}\n ${helmet.link.toString()}\n \n \n \n \n \n \n \n \n
\n
${html}
\n
\n \n \n \n \n `;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/renderFullPage.js","export const selectSiteState = (state) => {\n return state.site;\n};\n\nexport const selectSiteHost = (state) => {\n return state.site.host;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/selectors/site.js","module.exports = require(\"babel-polyfill\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"babel-polyfill\"\n// module id = 46\n// module chunks = 0","module.exports = require(\"whatwg-fetch\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"whatwg-fetch\"\n// module id = 47\n// module chunks = 0","// app dependencies\nconst express = require('express');\nconst bodyParser = require('body-parser');\nconst expressHandlebars = require('express-handlebars');\nconst Handlebars = require('handlebars');\nconst helmet = require('helmet');\nconst passport = require('passport');\nconst { serializeSpeechUser, deserializeSpeechUser } = require('./helpers/authHelpers.js');\nconst cookieSession = require('cookie-session');\nconst http = require('http');\n// logging dependencies\nconst logger = require('winston');\n\nconst {auth: { sessionKey }, details: { port: PORT }} = require('../config/siteConfig.js');\n\n// create an Express application\nconst app = express();\n\n// trust the proxy to get ip address for us\napp.enable('trust proxy');\n\n// add middleware\napp.use(helmet()); // set HTTP headers to protect against well-known web vulnerabilties\napp.use(express.static(`${__dirname}/public`)); // 'express.static' to serve static files from public directory\napp.use(bodyParser.json()); // 'body parser' for parsing application/json\napp.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded\napp.use((req, res, next) => { // custom logging middleware to log all incoming http requests\n logger.verbose(`Request on ${req.originalUrl} from ${req.ip}`);\n next();\n});\n\n// configure passport\npassport.serializeUser(serializeSpeechUser);\npassport.deserializeUser(deserializeSpeechUser);\nconst localSignupStrategy = require('./passport/local-signup.js');\nconst localLoginStrategy = require('./passport/local-login.js');\npassport.use('local-signup', localSignupStrategy);\npassport.use('local-login', localLoginStrategy);\n// initialize passport\napp.use(cookieSession({\n name : 'session',\n keys : [sessionKey],\n maxAge: 24 * 60 * 60 * 1000, // i.e. 24 hours\n}));\napp.use(passport.initialize());\napp.use(passport.session());\n\n// configure handlebars & register it with express app\nconst hbs = expressHandlebars.create({\n defaultLayout: 'embed',\n handlebars : Handlebars,\n});\napp.engine('handlebars', hbs.engine);\napp.set('view engine', 'handlebars');\n\n// set the routes on the app\nrequire('./routes/auth-routes.js')(app);\nrequire('./routes/api-routes.js')(app);\nrequire('./routes/page-routes.js')(app);\nrequire('./routes/asset-routes.js')(app);\nrequire('./routes/fallback-routes.js')(app);\n\n// create server\nconst server = http.Server(app);\n\n// configure logger\nrequire('./helpers/configureLogger.js')(logger);\nrequire('./helpers/configureSlack.js')(logger);\n\n// sync sequelize\nconst db = require('./models/index');\ndb.sequelize.sync()\n // start the server\n .then(() => {\n server.listen(PORT, () => {\n logger.info(`Server is listening on PORT ${PORT}`);\n });\n })\n .catch((error) => {\n logger.error(`Startup Error:`, error);\n });\n\n\n\n// WEBPACK FOOTER //\n// ./server/server.js","module.exports = require(\"express\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"express\"\n// module id = 49\n// module chunks = 0","module.exports = require(\"body-parser\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"body-parser\"\n// module id = 50\n// module chunks = 0","module.exports = require(\"express-handlebars\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"express-handlebars\"\n// module id = 51\n// module chunks = 0","module.exports = require(\"handlebars\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"handlebars\"\n// module id = 52\n// module chunks = 0","module.exports = require(\"helmet\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"helmet\"\n// module id = 53\n// module chunks = 0","const logger = require('winston');\n\nmodule.exports = {\n serializeSpeechUser (user, done) { // returns user data to be serialized into session\n logger.debug('serializing user');\n done(null, user);\n },\n deserializeSpeechUser (user, done) { // deserializes session and populates additional info to req.user\n logger.debug('deserializing user');\n done(null, user);\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/authHelpers.js","module.exports = require(\"cookie-session\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"cookie-session\"\n// module id = 55\n// module chunks = 0","module.exports = require(\"http\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"http\"\n// module id = 56\n// module chunks = 0","const PassportLocalStrategy = require('passport-local').Strategy;\nconst lbryApi = require('../helpers/lbryApi.js');\nconst logger = require('winston');\nconst db = require('../models/index');\n\nmodule.exports = new PassportLocalStrategy(\n {\n usernameField: 'username',\n passwordField: 'password',\n },\n (username, password, done) => {\n logger.verbose(`new channel signup request. user: ${username} pass: ${password} .`);\n let userInfo = {};\n // server-side validaton of inputs (username, password)\n\n // create the channel and retrieve the metadata\n return lbryApi.createChannel(`@${username}`)\n .then(tx => {\n // create user record\n const userData = {\n userName: username,\n password: password,\n };\n logger.verbose('userData >', userData);\n // create user record\n const channelData = {\n channelName : `@${username}`,\n channelClaimId: tx.claim_id,\n };\n logger.verbose('channelData >', channelData);\n // create certificate record\n const certificateData = {\n claimId: tx.claim_id,\n name : `@${username}`,\n // address,\n };\n logger.verbose('certificateData >', certificateData);\n // save user and certificate to db\n return Promise.all([db.User.create(userData), db.Channel.create(channelData), db.Certificate.create(certificateData)]);\n })\n .then(([newUser, newChannel, newCertificate]) => {\n logger.verbose('user and certificate successfully created');\n // store the relevant newUser info to be passed back for req.User\n userInfo['id'] = newUser.id;\n userInfo['userName'] = newUser.userName;\n userInfo['channelName'] = newChannel.channelName;\n userInfo['channelClaimId'] = newChannel.channelClaimId;\n // associate the instances\n return Promise.all([newCertificate.setChannel(newChannel), newChannel.setUser(newUser)]);\n })\n .then(() => {\n logger.verbose('user and certificate successfully associated');\n return db.Certificate.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName);\n })\n .then(shortChannelId => {\n userInfo['shortChannelId'] = shortChannelId;\n return done(null, userInfo);\n })\n .catch(error => {\n logger.error('signup error', error);\n return done(error);\n });\n }\n);\n\n\n\n// WEBPACK FOOTER //\n// ./server/passport/local-signup.js","module.exports = require(\"axios\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"axios\"\n// module id = 58\n// module chunks = 0","const lbryConfig = {\n api: {\n apiHost: 'localhost',\n apiPort: '5279',\n },\n};\n\nmodule.exports = lbryConfig;\n\n\n\n// WEBPACK FOOTER //\n// ./config/lbryConfig.js","module.exports = require(\"universal-analytics\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"universal-analytics\"\n// module id = 60\n// module chunks = 0","function MysqlConfig () {\n this.database = 'default';\n this.username = 'default';\n this.password = 'default';\n};\n\nmodule.exports = new MysqlConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/mysqlConfig.js","const logger = require('winston');\nconst { returnShortId } = require('../helpers/sequelizeHelpers.js');\n\nmodule.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {\n const Certificate = sequelize.define(\n 'Certificate',\n {\n address: {\n type : STRING,\n default: null,\n },\n amount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n claimId: {\n type : STRING,\n default: null,\n },\n claimSequence: {\n type : INTEGER,\n default: null,\n },\n decodedClaim: {\n type : BOOLEAN,\n default: null,\n },\n depth: {\n type : INTEGER,\n default: null,\n },\n effectiveAmount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n hasSignature: {\n type : BOOLEAN,\n default: null,\n },\n height: {\n type : INTEGER,\n default: null,\n },\n hex: {\n type : TEXT('long'),\n default: null,\n },\n name: {\n type : STRING,\n default: null,\n },\n nout: {\n type : INTEGER,\n default: null,\n },\n txid: {\n type : STRING,\n default: null,\n },\n validAtHeight: {\n type : INTEGER,\n default: null,\n },\n outpoint: {\n type : STRING,\n default: null,\n },\n valueVersion: {\n type : STRING,\n default: null,\n },\n claimType: {\n type : STRING,\n default: null,\n },\n certificateVersion: {\n type : STRING,\n default: null,\n },\n keyType: {\n type : STRING,\n default: null,\n },\n publicKey: {\n type : TEXT('long'),\n default: null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Certificate.associate = db => {\n Certificate.belongsTo(db.Channel, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {\n logger.debug(`getShortChannelIdFromLongChannelId ${channelName}:${longChannelId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {name: channelName},\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n throw new Error('No channel(s) found with that channel name');\n default:\n return resolve(returnShortId(result, longChannelId));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {\n logger.debug(`getLongChannelIdFromShortChannelId(${channelName}, ${channelClaimId})`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {\n name : channelName,\n claimId: {\n $like: `${channelClaimId}%`,\n },\n },\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default: // note results must be sorted\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelIdFromChannelName = function (channelName) {\n logger.debug(`getLongChannelIdFromChannelName(${channelName})`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: channelName },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.validateLongChannelId = function (name, claimId) {\n logger.debug(`validateLongChannelId(${name}, ${claimId})`);\n return new Promise((resolve, reject) => {\n this.findOne({\n where: {name, claimId},\n })\n .then(result => {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Certificate.getLongChannelId = function (channelName, channelClaimId) {\n logger.debug(`getLongChannelId(${channelName}, ${channelClaimId})`);\n if (channelClaimId && (channelClaimId.length === 40)) { // if a full channel id is provided\n return this.validateLongChannelId(channelName, channelClaimId);\n } else if (channelClaimId && channelClaimId.length < 40) { // if a short channel id is provided\n return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);\n } else {\n return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided\n }\n };\n\n return Certificate;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/certificate.js","module.exports = (sequelize, { STRING }) => {\n const Channel = sequelize.define(\n 'Channel',\n {\n channelName: {\n type : STRING,\n allowNull: false,\n },\n channelClaimId: {\n type : STRING,\n allowNull: false,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Channel.associate = db => {\n Channel.belongsTo(db.User);\n Channel.hasOne(db.Certificate);\n };\n\n return Channel;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/channel.js","const logger = require('winston');\nconst { returnShortId } = require('../helpers/sequelizeHelpers.js');\nconst { assetDefaults: { thumbnail: defaultThumbnail }, details: { host } } = require('../../config/siteConfig.js');\n\nfunction determineFileExtensionFromContentType (contentType) {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n return 'jpeg';\n case 'image/png':\n return 'png';\n case 'image/gif':\n return 'gif';\n case 'video/mp4':\n return 'mp4';\n default:\n logger.debug('setting unknown file type as file extension jpeg');\n return 'jpeg';\n }\n};\n\nfunction determineThumbnail (storedThumbnail, defaultThumbnail) {\n if (storedThumbnail === '') {\n return defaultThumbnail;\n }\n return storedThumbnail;\n};\n\nfunction prepareClaimData (claim) {\n // logger.debug('preparing claim data based on resolved data:', claim);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['host'] = host;\n return claim;\n};\n\nmodule.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {\n const Claim = sequelize.define(\n 'Claim',\n {\n address: {\n type : STRING,\n default: null,\n },\n amount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n claimId: {\n type : STRING,\n default: null,\n },\n claimSequence: {\n type : INTEGER,\n default: null,\n },\n decodedClaim: {\n type : BOOLEAN,\n default: null,\n },\n depth: {\n type : INTEGER,\n default: null,\n },\n effectiveAmount: {\n type : DECIMAL(19, 8),\n default: null,\n },\n hasSignature: {\n type : BOOLEAN,\n default: null,\n },\n height: {\n type : INTEGER,\n default: null,\n },\n hex: {\n type : TEXT('long'),\n default: null,\n },\n name: {\n type : STRING,\n default: null,\n },\n nout: {\n type : INTEGER,\n default: null,\n },\n txid: {\n type : STRING,\n default: null,\n },\n validAtHeight: {\n type : INTEGER,\n default: null,\n },\n outpoint: {\n type : STRING,\n default: null,\n },\n claimType: {\n type : STRING,\n default: null,\n },\n certificateId: {\n type : STRING,\n default: null,\n },\n author: {\n type : STRING,\n default: null,\n },\n description: {\n type : TEXT('long'),\n default: null,\n },\n language: {\n type : STRING,\n default: null,\n },\n license: {\n type : STRING,\n default: null,\n },\n licenseUrl: {\n type : STRING,\n default: null,\n },\n nsfw: {\n type : BOOLEAN,\n default: null,\n },\n preview: {\n type : STRING,\n default: null,\n },\n thumbnail: {\n type : STRING,\n default: null,\n },\n title: {\n type : STRING,\n default: null,\n },\n metadataVersion: {\n type : STRING,\n default: null,\n },\n contentType: {\n type : STRING,\n default: null,\n },\n source: {\n type : STRING,\n default: null,\n },\n sourceType: {\n type : STRING,\n default: null,\n },\n sourceVersion: {\n type : STRING,\n default: null,\n },\n streamVersion: {\n type : STRING,\n default: null,\n },\n valueVersion: {\n type : STRING,\n default: null,\n },\n channelName: {\n type : STRING,\n allowNull: true,\n default : null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Claim.associate = db => {\n Claim.belongsTo(db.File, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {\n logger.debug(`Claim.getShortClaimIdFromLongClaimId for ${claimName}#${claimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: claimName },\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n throw new Error('No claim(s) found with that claim name');\n default:\n resolve(returnShortId(result, claimId));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getAllChannelClaims = function (channelClaimId) {\n logger.debug(`Claim.getAllChannelClaims for ${channelClaimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { certificateId: channelClaimId },\n order: [['height', 'ASC']],\n raw : true, // returns an array of only data, not an array of instances\n })\n .then(channelClaimsArray => {\n // logger.debug('channelclaimsarray length:', channelClaimsArray.length);\n switch (channelClaimsArray.length) {\n case 0:\n return resolve(null);\n default:\n channelClaimsArray.forEach(claim => {\n claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);\n claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);\n return claim;\n });\n return resolve(channelClaimsArray);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) {\n logger.debug(`finding claim id for claim ${claimName} from channel ${channelClaimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name: claimName, certificateId: channelClaimId },\n order: [['id', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(result[0].claimId);\n default:\n logger.error(`${result.length} records found for \"${claimName}\" in channel \"${channelClaimId}\"`);\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: {\n name,\n claimId: {\n $like: `${shortId}%`,\n }},\n order: [['height', 'ASC']],\n })\n .then(result => {\n switch (result.length) {\n case 0:\n return resolve(null);\n default: // note results must be sorted\n return resolve(result[0].claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getTopFreeClaimIdByClaimName = function (name) {\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name },\n order: [['effectiveAmount', 'DESC'], ['height', 'ASC']], // note: maybe height and effective amount need to switch?\n })\n .then(result => {\n logger.debug('length of result', result.length);\n switch (result.length) {\n case 0:\n return resolve(null);\n default:\n return resolve(result[0].dataValues.claimId);\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.validateLongClaimId = function (name, claimId) {\n return new Promise((resolve, reject) => {\n this.findOne({\n where: {name, claimId},\n })\n .then(result => {\n if (!result) {\n return resolve(null);\n };\n resolve(claimId);\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n Claim.getLongClaimId = function (claimName, claimId) {\n logger.debug(`getLongClaimId(${claimName}, ${claimId})`);\n if (claimId && (claimId.length === 40)) { // if a full claim id is provided\n return this.validateLongClaimId(claimName, claimId);\n } else if (claimId && claimId.length < 40) {\n return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided\n } else {\n return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided\n }\n };\n\n Claim.resolveClaim = function (name, claimId) {\n logger.debug(`Claim.resolveClaim: ${name} ${claimId}`);\n return new Promise((resolve, reject) => {\n this\n .findAll({\n where: { name, claimId },\n })\n .then(claimArray => {\n switch (claimArray.length) {\n case 0:\n return resolve(null);\n case 1:\n return resolve(prepareClaimData(claimArray[0].dataValues));\n default:\n logger.error(`more than one record matches ${name}#${claimId} in db.Claim`);\n return resolve(prepareClaimData(claimArray[0].dataValues));\n }\n })\n .catch(error => {\n reject(error);\n });\n });\n };\n\n return Claim;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/claim.js","module.exports = (sequelize, { STRING, BOOLEAN, INTEGER }) => {\n const File = sequelize.define(\n 'File',\n {\n name: {\n type : STRING,\n allowNull: false,\n },\n claimId: {\n type : STRING,\n allowNull: false,\n },\n address: {\n type : STRING,\n allowNull: false,\n },\n outpoint: {\n type : STRING,\n allowNull: false,\n },\n height: {\n type : INTEGER,\n allowNull: false,\n default : 0,\n },\n fileName: {\n type : STRING,\n allowNull: false,\n },\n filePath: {\n type : STRING,\n allowNull: false,\n },\n fileType: {\n type: STRING,\n },\n nsfw: {\n type : BOOLEAN,\n allowNull : false,\n defaultValue: false,\n },\n trendingEligible: {\n type : BOOLEAN,\n allowNull : false,\n defaultValue: true,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n File.associate = db => {\n File.hasMany(db.Request);\n File.hasOne(db.Claim);\n };\n\n File.getRecentClaims = function () {\n return this.findAll({\n where: { nsfw: false, trendingEligible: true },\n order: [['createdAt', 'DESC']],\n limit: 25,\n });\n };\n\n return File;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/file.js","module.exports = (sequelize, { STRING, BOOLEAN, TEXT }) => {\n const Request = sequelize.define(\n 'Request',\n {\n action: {\n type : STRING,\n allowNull: false,\n },\n url: {\n type : STRING,\n allowNull: false,\n },\n ipAddress: {\n type : STRING,\n allowNull: true,\n },\n result: {\n type : TEXT('long'),\n allowNull: true,\n default : null,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n Request.associate = db => {\n Request.belongsTo(db.File, {\n foreignKey: {\n allowNull: true,\n },\n });\n };\n\n return Request;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/request.js","'use strict';\nconst bcrypt = require('bcrypt');\nconst logger = require('winston');\n\nmodule.exports = (sequelize, { STRING }) => {\n const User = sequelize.define(\n 'User',\n {\n userName: {\n type : STRING,\n allowNull: false,\n },\n password: {\n type : STRING,\n allowNull: false,\n },\n },\n {\n freezeTableName: true,\n }\n );\n\n User.associate = db => {\n User.hasOne(db.Channel);\n };\n\n User.prototype.comparePassword = function (password) {\n return bcrypt.compare(password, this.password);\n };\n\n User.prototype.changePassword = function (newPassword) {\n return new Promise((resolve, reject) => {\n // generate a salt string to use for hashing\n bcrypt.genSalt((saltError, salt) => {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(newPassword, salt, (hashError, hash) => {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the current password with the new hash\n this\n .update({password: hash})\n .then(() => {\n resolve();\n })\n .catch(error => {\n reject(error);\n });\n });\n });\n });\n };\n\n // pre-save hook method to hash the user's password before the user's info is saved to the db.\n User.hook('beforeCreate', (user, options) => {\n logger.debug('User.beforeCreate hook...');\n return new Promise((resolve, reject) => {\n // generate a salt string to use for hashing\n bcrypt.genSalt((saltError, salt) => {\n if (saltError) {\n logger.error('salt error', saltError);\n reject(saltError);\n return;\n }\n // generate a hashed version of the user's password\n bcrypt.hash(user.password, salt, (hashError, hash) => {\n // if there is an error with the hash generation return the error\n if (hashError) {\n logger.error('hash error', hashError);\n reject(hashError);\n return;\n }\n // replace the password string with the hash password value\n user.password = hash;\n resolve();\n });\n });\n });\n });\n\n return User;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/models/user.js","module.exports = require(\"bcrypt\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"bcrypt\"\n// module id = 68\n// module chunks = 0","const PassportLocalStrategy = require('passport-local').Strategy;\nconst logger = require('winston');\nconst db = require('../models/index');\n\nconst returnUserAndChannelInfo = (userInstance) => {\n return new Promise((resolve, reject) => {\n let userInfo = {};\n userInfo['id'] = userInstance.id;\n userInfo['userName'] = userInstance.userName;\n userInstance\n .getChannel()\n .then(({channelName, channelClaimId}) => {\n userInfo['channelName'] = channelName;\n userInfo['channelClaimId'] = channelClaimId;\n return db.Certificate.getShortChannelIdFromLongChannelId(channelClaimId, channelName);\n })\n .then(shortChannelId => {\n userInfo['shortChannelId'] = shortChannelId;\n resolve(userInfo);\n })\n .catch(error => {\n reject(error);\n });\n });\n};\n\nmodule.exports = new PassportLocalStrategy(\n {\n usernameField: 'username',\n passwordField: 'password',\n },\n (username, password, done) => {\n return db.User\n .findOne({\n where: {userName: username},\n })\n .then(user => {\n if (!user) {\n logger.debug('no user found');\n return done(null, false, {message: 'Incorrect username or password'});\n }\n return user.comparePassword(password)\n .then(isMatch => {\n if (!isMatch) {\n logger.debug('incorrect password');\n return done(null, false, {message: 'Incorrect username or password'});\n }\n logger.debug('Password was a match, returning User');\n return returnUserAndChannelInfo(user)\n .then(userInfo => {\n return done(null, userInfo);\n })\n .catch(error => {\n return error;\n });\n })\n .catch(error => {\n return error;\n });\n })\n .catch(error => {\n return done(error);\n });\n },\n);\n\n\n\n// WEBPACK FOOTER //\n// ./server/passport/local-login.js","const logger = require('winston');\nconst passport = require('passport');\n\nmodule.exports = (app) => {\n // route for sign up\n app.post('/signup', passport.authenticate('local-signup'), (req, res) => {\n logger.verbose(`successful signup for ${req.user.channelName}`);\n res.status(200).json({\n success : true,\n channelName : req.user.channelName,\n channelClaimId: req.user.channelClaimId,\n shortChannelId: req.user.shortChannelId,\n });\n });\n // route for log in\n app.post('/login', (req, res, next) => {\n passport.authenticate('local-login', (err, user, info) => {\n if (err) {\n return next(err);\n }\n if (!user) {\n return res.status(400).json({\n success: false,\n message: info.message,\n });\n }\n logger.debug('successful login');\n req.logIn(user, (err) => {\n if (err) {\n return next(err);\n }\n return res.status(200).json({\n success : true,\n channelName : req.user.channelName,\n channelClaimId: req.user.channelClaimId,\n shortChannelId: req.user.shortChannelId,\n });\n });\n })(req, res, next);\n });\n // route to log out\n app.get('/logout', (req, res) => {\n req.logout();\n res.status(200).json({success: true, message: 'you successfully logged out'});\n });\n // see if user is authenticated, and return credentials if so\n app.get('/user', (req, res) => {\n if (req.user) {\n res.status(200).json({success: true, data: req.user});\n } else {\n res.status(401).json({success: false, message: 'user is not logged in'});\n }\n });\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/auth-routes.js","const logger = require('winston');\nconst multipart = require('connect-multiparty');\nconst { publishing: { uploadDirectory }, details: { host } } = require('../../config/siteConfig.js');\nconst multipartMiddleware = multipart({uploadDir: uploadDirectory});\nconst db = require('../models/index');\nconst { claimNameIsAvailable, checkChannelAvailability, publish } = require('../controllers/publishController.js');\nconst { getClaimList, resolveUri, getClaim } = require('../helpers/lbryApi.js');\nconst { addGetResultsToFileData, createBasicPublishParams, createThumbnailPublishParams, parsePublishApiRequestBody, parsePublishApiRequestFiles, createFileData } = require('../helpers/publishHelpers.js');\nconst errorHandlers = require('../helpers/errorHandlers.js');\nconst { sendGATimingEvent } = require('../helpers/googleAnalytics.js');\nconst { authenticateUser } = require('../auth/authentication.js');\nconst { getChannelData, getChannelClaims, getClaimId } = require('../controllers/serveController.js');\n\nconst NO_CHANNEL = 'NO_CHANNEL';\nconst NO_CLAIM = 'NO_CLAIM';\n\nmodule.exports = (app) => {\n // route to check whether site has published to a channel\n app.get('/api/channel/availability/:name', ({ ip, originalUrl, params: { name } }, res) => {\n const gaStartTime = Date.now();\n checkChannelAvailability(name)\n .then(availableName => {\n res.status(200).json(availableName);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to get a short channel id from long channel Id\n app.get('/api/channel/short-id/:longId/:name', ({ ip, originalUrl, params }, res) => {\n db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name)\n .then(shortId => {\n res.status(200).json(shortId);\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n app.get('/api/channel/data/:channelName/:channelClaimId', ({ ip, originalUrl, body, params }, res) => {\n const channelName = params.channelName;\n let channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n getChannelData(channelName, channelClaimId, 0)\n .then(data => {\n if (data === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel was found'});\n }\n res.status(200).json({success: true, data});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n app.get('/api/channel/claims/:channelName/:channelClaimId/:page', ({ ip, originalUrl, body, params }, res) => {\n const channelName = params.channelName;\n let channelClaimId = params.channelClaimId;\n if (channelClaimId === 'none') channelClaimId = null;\n const page = params.page;\n getChannelClaims(channelName, channelClaimId, page)\n .then(data => {\n if (data === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel was found'});\n }\n res.status(200).json({success: true, data});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to run a claim_list request on the daemon\n app.get('/api/claim/list/:name', ({ ip, originalUrl, params }, res) => {\n getClaimList(params.name)\n .then(claimsList => {\n res.status(200).json(claimsList);\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to get an asset\n app.get('/api/claim/get/:name/:claimId', ({ ip, originalUrl, params }, res) => {\n const name = params.name;\n const claimId = params.claimId;\n // resolve the claim\n db.Claim.resolveClaim(name, claimId)\n .then(resolveResult => {\n // make sure a claim actually exists at that uri\n if (!resolveResult) {\n throw new Error('No matching uri found in Claim table');\n }\n let fileData = createFileData(resolveResult);\n // get the claim\n return Promise.all([fileData, getClaim(`${name}#${claimId}`)]);\n })\n .then(([ fileData, getResult ]) => {\n fileData = addGetResultsToFileData(fileData, getResult);\n return Promise.all([db.upsert(db.File, fileData, {name, claimId}, 'File'), getResult]);\n })\n .then(([ fileRecord, {message, completed} ]) => {\n res.status(200).json({ success: true, message, completed });\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to check whether this site published to a claim\n app.get('/api/claim/availability/:name', ({ ip, originalUrl, params: { name } }, res) => {\n const gaStartTime = Date.now();\n claimNameIsAvailable(name)\n .then(result => {\n res.status(200).json(result);\n sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to run a resolve request on the daemon\n app.get('/api/claim/resolve/:name/:claimId', ({ headers, ip, originalUrl, params }, res) => {\n resolveUri(`${params.name}#${params.claimId}`)\n .then(resolvedUri => {\n res.status(200).json(resolvedUri);\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to run a publish request on the daemon\n app.post('/api/claim/publish', multipartMiddleware, ({ body, files, headers, ip, originalUrl, user }, res) => {\n // define variables\n let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title;\n // record the start time of the request\n gaStartTime = Date.now();\n // validate the body and files of the request\n try {\n // validateApiPublishRequest(body, files);\n ({name, nsfw, license, title, description, thumbnail} = parsePublishApiRequestBody(body));\n ({fileName, filePath, fileType, thumbnailFileName, thumbnailFilePath, thumbnailFileType} = parsePublishApiRequestFiles(files));\n ({channelName, channelId, channelPassword} = body);\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n // check channel authorization\n Promise.all([\n authenticateUser(channelName, channelId, channelPassword, user),\n claimNameIsAvailable(name),\n createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail),\n createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw),\n ])\n .then(([{channelName, channelClaimId}, validatedClaimName, publishParams, thumbnailPublishParams]) => {\n // add channel details to the publish params\n if (channelName && channelClaimId) {\n publishParams['channel_name'] = channelName;\n publishParams['channel_id'] = channelClaimId;\n }\n // publish the thumbnail\n if (thumbnailPublishParams) {\n publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType);\n }\n // publish the asset\n return publish(publishParams, fileName, fileType);\n })\n .then(result => {\n res.status(200).json({\n success: true,\n message: 'publish completed successfully',\n data : {\n name,\n claimId: result.claim_id,\n url : `${host}/${result.claim_id}/${name}`,\n lbryTx : result,\n },\n });\n // record the publish end time and send to google analytics\n sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to get a short claim id from long claim Id\n app.get('/api/claim/short-id/:longId/:name', ({ ip, originalUrl, body, params }, res) => {\n db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name)\n .then(shortId => {\n res.status(200).json({success: true, data: shortId});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n app.post('/api/claim/long-id', ({ ip, originalUrl, body, params }, res) => {\n logger.debug('body:', body);\n const channelName = body.channelName;\n const channelClaimId = body.channelClaimId;\n const claimName = body.claimName;\n const claimId = body.claimId;\n getClaimId(channelName, channelClaimId, claimName, claimId)\n .then(result => {\n if (result === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'No matching channel could be found'});\n }\n if (result === NO_CLAIM) {\n return res.status(404).json({success: false, message: 'No matching claim id could be found'});\n }\n res.status(200).json({success: true, data: result});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n app.get('/api/claim/data/:claimName/:claimId', ({ ip, originalUrl, body, params }, res) => {\n const claimName = params.claimName;\n let claimId = params.claimId;\n if (claimId === 'none') claimId = null;\n db.Claim.resolveClaim(claimName, claimId)\n .then(claimInfo => {\n if (!claimInfo) {\n return res.status(404).json({success: false, message: 'No claim could be found'});\n }\n res.status(200).json({success: true, data: claimInfo});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n // route to see if asset is available locally\n app.get('/api/file/availability/:name/:claimId', ({ ip, originalUrl, params }, res) => {\n const name = params.name;\n const claimId = params.claimId;\n db.File.findOne({where: {name, claimId}})\n .then(result => {\n if (result) {\n return res.status(200).json({success: true, data: true});\n }\n res.status(200).json({success: true, data: false});\n })\n .catch(error => {\n errorHandlers.handleErrorResponse(originalUrl, ip, error, res);\n });\n });\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/api-routes.js","module.exports = require(\"connect-multiparty\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"connect-multiparty\"\n// module id = 72\n// module chunks = 0","const logger = require('winston');\nconst db = require('../models/index');\nconst lbryApi = require('../helpers/lbryApi.js');\nconst publishHelpers = require('../helpers/publishHelpers.js');\nconst { publishing: { primaryClaimAddress, additionalClaimAddresses } } = require('../../config/siteConfig.js');\nconst Sequelize = require('sequelize');\nconst Op = Sequelize.Op;\n\nmodule.exports = {\n publish (publishParams, fileName, fileType) {\n return new Promise((resolve, reject) => {\n let publishResults, certificateId, channelName;\n // publish the file\n return lbryApi.publishClaim(publishParams)\n .then(tx => {\n logger.info(`Successfully published ${publishParams.name} ${fileName}`, tx);\n publishResults = tx;\n // get the channel information\n if (publishParams.channel_name) {\n logger.debug(`this claim was published in channel: ${publishParams.channel_name}`);\n return db.Channel.findOne({where: {channelName: publishParams.channel_name}});\n } else {\n logger.debug('this claim was not published in a channel');\n return null;\n }\n })\n .then(channel => {\n // set channel information\n certificateId = null;\n channelName = null;\n if (channel) {\n certificateId = channel.channelClaimId;\n channelName = channel.channelName;\n }\n logger.debug(`certificateId: ${certificateId}`);\n })\n .then(() => {\n // create the File record\n const fileRecord = {\n name : publishParams.name,\n claimId : publishResults.claim_id,\n title : publishParams.metadata.title,\n description: publishParams.metadata.description,\n address : publishParams.claim_address,\n outpoint : `${publishResults.txid}:${publishResults.nout}`,\n height : 0,\n fileName,\n filePath : publishParams.file_path,\n fileType,\n nsfw : publishParams.metadata.nsfw,\n };\n // create the Claim record\n const claimRecord = {\n name : publishParams.name,\n claimId : publishResults.claim_id,\n title : publishParams.metadata.title,\n description: publishParams.metadata.description,\n address : publishParams.claim_address,\n thumbnail : publishParams.metadata.thumbnail,\n outpoint : `${publishResults.txid}:${publishResults.nout}`,\n height : 0,\n contentType: fileType,\n nsfw : publishParams.metadata.nsfw,\n amount : publishParams.bid,\n certificateId,\n channelName,\n };\n // upsert criteria\n const upsertCriteria = {\n name : publishParams.name,\n claimId: publishResults.claim_id,\n };\n // upsert the records\n return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]);\n })\n .then(([file, claim]) => {\n logger.debug('File and Claim records successfully created');\n return Promise.all([file.setClaim(claim), claim.setFile(file)]);\n })\n .then(() => {\n logger.debug('File and Claim records successfully associated');\n resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim;\n })\n .catch(error => {\n logger.error('PUBLISH ERROR', error);\n publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file\n reject(error);\n });\n });\n },\n claimNameIsAvailable (name) {\n const claimAddresses = additionalClaimAddresses || [];\n claimAddresses.push(primaryClaimAddress);\n // find any records where the name is used\n return db.Claim\n .findAll({\n attributes: ['address'],\n where : {\n name,\n address: {\n [Op.or]: claimAddresses,\n },\n },\n })\n .then(result => {\n if (result.length >= 1) {\n throw new Error('That claim is already in use');\n };\n return name;\n })\n .catch(error => {\n throw error;\n });\n },\n checkChannelAvailability (name) {\n return db.Channel\n .findAll({\n where: { channelName: name },\n })\n .then(result => {\n if (result.length >= 1) {\n throw new Error('That channel has already been claimed');\n }\n return name;\n })\n .catch(error => {\n throw error;\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/controllers/publishController.js","module.exports = require(\"fs\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"fs\"\n// module id = 74\n// module chunks = 0","const db = require('../models/index');\nconst logger = require('winston');\n\nmodule.exports = {\n authenticateUser (channelName, channelId, channelPassword, user) {\n // case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided\n if (!channelName && !channelId) {\n return {\n channelName : null,\n channelClaimId: null,\n };\n }\n // case: channelName or channel Id are provided with user token\n if (user) {\n if (channelName && channelName !== user.channelName) {\n throw new Error('the provided channel name does not match user credentials');\n }\n if (channelId && channelId !== user.channelClaimId) {\n throw new Error('the provided channel id does not match user credentials');\n }\n return {\n channelName : user.channelName,\n channelClaimId: user.channelClaimId,\n };\n }\n // case: channelName or channel Id are provided with password instead of user token\n if (!channelPassword) throw new Error('no channel password provided');\n return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword);\n },\n authenticateChannelCredentials (channelName, channelId, userPassword) {\n return new Promise((resolve, reject) => {\n // hoisted variables\n let channelData;\n // build the params for finding the channel\n let channelFindParams = {};\n if (channelName) channelFindParams['channelName'] = channelName;\n if (channelId) channelFindParams['channelClaimId'] = channelId;\n // find the channel\n db.Channel\n .findOne({\n where: channelFindParams,\n })\n .then(channel => {\n if (!channel) {\n logger.debug('no channel found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n channelData = channel.get();\n logger.debug('channel data:', channelData);\n return db.User.findOne({\n where: { userName: channelData.channelName.substring(1) },\n });\n })\n .then(user => {\n if (!user) {\n logger.debug('no user found');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n return user.comparePassword(userPassword);\n })\n .then(isMatch => {\n if (!isMatch) {\n logger.debug('incorrect password');\n throw new Error('Authentication failed, you do not have access to that channel');\n }\n logger.debug('...password was a match...');\n resolve(channelData);\n })\n .catch(error => {\n reject(error);\n });\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/auth/authentication.js","const CLAIMS_PER_PAGE = 12;\n\nmodule.exports = {\n returnPaginatedChannelClaims (channelName, longChannelClaimId, claims, page) {\n const totalPages = module.exports.determineTotalPages(claims);\n const paginationPage = module.exports.getPageFromQuery(page);\n const viewData = {\n channelName : channelName,\n longChannelClaimId: longChannelClaimId,\n claims : module.exports.extractPageFromClaims(claims, paginationPage),\n previousPage : module.exports.determinePreviousPage(paginationPage),\n currentPage : paginationPage,\n nextPage : module.exports.determineNextPage(totalPages, paginationPage),\n totalPages : totalPages,\n totalResults : module.exports.determineTotalClaims(claims),\n };\n return viewData;\n },\n getPageFromQuery (page) {\n if (page) {\n return parseInt(page);\n }\n return 1;\n },\n extractPageFromClaims (claims, pageNumber) {\n if (!claims) {\n return []; // if no claims, return this default\n }\n // logger.debug('claims is array?', Array.isArray(claims));\n // logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));\n const claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;\n const claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;\n const pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);\n return pageOfClaims;\n },\n determineTotalPages (claims) {\n if (!claims) {\n return 0;\n } else {\n const totalClaims = claims.length;\n if (totalClaims < CLAIMS_PER_PAGE) {\n return 1;\n }\n const fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE);\n const remainder = totalClaims % CLAIMS_PER_PAGE;\n if (remainder === 0) {\n return fullPages;\n }\n return fullPages + 1;\n }\n },\n determinePreviousPage (currentPage) {\n if (currentPage === 1) {\n return null;\n }\n return currentPage - 1;\n },\n determineNextPage (totalPages, currentPage) {\n if (currentPage === totalPages) {\n return null;\n }\n return currentPage + 1;\n },\n determineTotalClaims (claims) {\n if (!claims) {\n return 0;\n }\n return claims.length;\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/channelPagination.js","const { details: host } = require('../../config/siteConfig.js');\nconst handlePageRender = require('../helpers/handlePageRender.jsx');\n\nmodule.exports = (app) => {\n // route for the home page\n app.get('/', (req, res) => {\n handlePageRender(req, res);\n });\n // route to display login page\n app.get('/login', (req, res) => {\n handlePageRender(req, res);\n });\n // route to show 'about' page\n app.get('/about', (req, res) => {\n handlePageRender(req, res);\n });\n // route to display a list of the trending images\n app.get('/trending', (req, res) => {\n res.status(301).redirect('/popular');\n });\n app.get('/popular', (req, res) => {\n handlePageRender(req, res);\n });\n // route to display a list of the trending images\n app.get('/new', (req, res) => {\n handlePageRender(req, res);\n });\n // route to send embedable video player (for twitter)\n app.get('/embed/:claimId/:name', ({ params }, res) => {\n const claimId = params.claimId;\n const name = params.name;\n // get and render the content\n res.status(200).render('embed', { layout: 'embed', host, claimId, name });\n });\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/page-routes.js","import * as actions from 'constants/publish_action_types';\nimport { LOGIN } from 'constants/publish_channel_select_states';\nconst { publishing } = require('../../config/siteConfig.js');\n\nconst initialState = {\n disabled : publishing.disabled,\n disabledMessage : publishing.disabledMessage,\n publishInChannel : false,\n selectedChannel : LOGIN,\n showMetadataInputs: false,\n status : {\n status : null,\n message: null,\n },\n error: {\n file : null,\n url : null,\n channel : null,\n publishSubmit: null,\n },\n file : null,\n claim : '',\n metadata: {\n title : '',\n description: '',\n license : '',\n nsfw : false,\n },\n thumbnail: null,\n};\n\nexport default function (state = initialState, action) {\n switch (action.type) {\n case actions.FILE_SELECTED:\n return Object.assign({}, initialState, { // note: clears to initial state\n file: action.data,\n });\n case actions.FILE_CLEAR:\n return initialState;\n case actions.METADATA_UPDATE:\n return Object.assign({}, state, {\n metadata: Object.assign({}, state.metadata, {\n [action.data.name]: action.data.value,\n }),\n });\n case actions.CLAIM_UPDATE:\n return Object.assign({}, state, {\n claim: action.data,\n });\n case actions.SET_PUBLISH_IN_CHANNEL:\n return Object.assign({}, state, {\n publishInChannel: action.channel,\n });\n case actions.PUBLISH_STATUS_UPDATE:\n return Object.assign({}, state, {\n status: action.data,\n });\n case actions.ERROR_UPDATE:\n return Object.assign({}, state, {\n error: Object.assign({}, state.error, {\n [action.data.name]: action.data.value,\n }),\n });\n case actions.SELECTED_CHANNEL_UPDATE:\n return Object.assign({}, state, {\n selectedChannel: action.data,\n });\n case actions.TOGGLE_METADATA_INPUTS:\n return Object.assign({}, state, {\n showMetadataInputs: action.data,\n });\n case actions.THUMBNAIL_NEW:\n return Object.assign({}, state, {\n thumbnail: action.data,\n });\n default:\n return state;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./client/reducers/publish.js","import * as actions from 'constants/channel_action_types';\n\nconst initialState = {\n loggedInChannel: {\n name : null,\n shortId: null,\n longId : null,\n },\n};\n\nexport default function (state = initialState, action) {\n switch (action.type) {\n case actions.CHANNEL_UPDATE:\n return Object.assign({}, state, {\n loggedInChannel: action.data,\n });\n default:\n return state;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./client/reducers/channel.js","import * as actions from 'constants/show_action_types';\nimport { LOCAL_CHECK, ERROR } from 'constants/asset_display_states';\n\nconst initialState = {\n request: {\n error: null,\n type : null,\n id : null,\n },\n requestList : {},\n channelList : {},\n assetList : {},\n displayAsset: {\n error : null,\n status: LOCAL_CHECK,\n },\n};\n\nexport default function (state = initialState, action) {\n switch (action.type) {\n // handle request\n case actions.REQUEST_ERROR:\n return Object.assign({}, state, {\n request: Object.assign({}, state.request, {\n error: action.data,\n }),\n });\n case actions.REQUEST_UPDATE:\n return Object.assign({}, state, {\n request: Object.assign({}, state.request, {\n type: action.data.requestType,\n id : action.data.requestId,\n }),\n });\n // store requests\n case actions.REQUEST_LIST_ADD:\n return Object.assign({}, state, {\n requestList: Object.assign({}, state.requestList, {\n [action.data.id]: {\n error: action.data.error,\n key : action.data.key,\n },\n }),\n });\n // asset data\n case actions.ASSET_ADD:\n return Object.assign({}, state, {\n assetList: Object.assign({}, state.assetList, {\n [action.data.id]: {\n error : action.data.error,\n name : action.data.name,\n claimId : action.data.claimId,\n shortId : action.data.shortId,\n claimData: action.data.claimData,\n },\n }),\n });\n // channel data\n case actions.CHANNEL_ADD:\n return Object.assign({}, state, {\n channelList: Object.assign({}, state.channelList, {\n [action.data.id]: {\n name : action.data.name,\n longId : action.data.longId,\n shortId : action.data.shortId,\n claimsData: action.data.claimsData,\n },\n }),\n });\n case actions.CHANNEL_CLAIMS_UPDATE_SUCCESS:\n return Object.assign({}, state, {\n channelList: Object.assign({}, state.channelList, {\n [action.data.channelListId]: Object.assign({}, state.channelList[action.data.channelListId], {\n claimsData: action.data.claimsData,\n }),\n }),\n });\n // display an asset\n case actions.FILE_AVAILABILITY_UPDATE:\n return Object.assign({}, state, {\n displayAsset: Object.assign({}, state.displayAsset, {\n status: action.data,\n }),\n });\n case actions.DISPLAY_ASSET_ERROR:\n return Object.assign({}, state, {\n displayAsset: Object.assign({}, state.displayAsset, {\n error : action.data,\n status: ERROR,\n }),\n });\n default:\n return state;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./client/reducers/show.js","const siteConfig = require('../../config/siteConfig.js');\n\nconst {\n analytics: {\n googleId: googleAnalyticsId,\n },\n assetDefaults: {\n thumbnail: defaultThumbnail,\n description: defaultDescription,\n },\n details: {\n description,\n host,\n title,\n twitter,\n },\n} = siteConfig;\n\nconst initialState = {\n description,\n googleAnalyticsId,\n host,\n title,\n twitter,\n defaultDescription,\n defaultThumbnail,\n};\n\nexport default function (state = initialState, action) {\n switch (action.type) {\n default:\n return state;\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./client/reducers/site.js","module.exports = require(\"react-ga\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"react-ga\"\n// module id = 82\n// module chunks = 0","import React from 'react';\nimport SEO from 'components/SEO';\nimport NavBar from 'containers/NavBar';\nimport PublishTool from 'containers/PublishTool';\n\nclass HomePage extends React.Component {\n render () {\n return (\n
\n \n \n
\n \n
\n
\n );\n }\n};\n\nexport default HomePage;\n\n\n\n// WEBPACK FOOTER //\n// ./client/pages/HomePage/index.jsx","import React from 'react';\nimport Helmet from 'react-helmet';\nimport PropTypes from 'prop-types';\n\nimport { createPageTitle } from 'utils/pageTitle';\nimport { createMetaTags } from 'utils/metaTags';\nimport { createCanonicalLink } from 'utils/canonicalLink';\n\nclass SEO extends React.Component {\n render () {\n // props from state\n const { defaultDescription, defaultThumbnail, siteDescription, siteHost, siteTitle, siteTwitter } = this.props;\n // props from parent\n const { asset, channel, pageUri } = this.props;\n let { pageTitle } = this.props;\n // create page title, tags, and canonical link\n pageTitle = createPageTitle(siteTitle, pageTitle);\n const metaTags = createMetaTags(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail);\n const canonicalLink = createCanonicalLink(asset, channel, pageUri, siteHost);\n // render results\n return (\n \n );\n }\n};\n\nSEO.propTypes = {\n pageTitle: PropTypes.string,\n pageUri : PropTypes.string,\n channel : PropTypes.object,\n asset : PropTypes.object,\n};\n\nexport default SEO;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/SEO/view.jsx","export const createPageTitle = (siteTitle, pageTitle) => {\n if (!pageTitle) {\n return `${siteTitle}`;\n }\n return `${siteTitle} - ${pageTitle}`;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/utils/pageTitle.js","const determineOgThumbnailContentType = (thumbnail) => {\n if (thumbnail) {\n const fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));\n switch (fileExt) {\n case 'jpeg':\n case 'jpg':\n return 'image/jpeg';\n case 'png':\n return 'image/png';\n case 'gif':\n return 'image/gif';\n case 'mp4':\n return 'video/mp4';\n default:\n return 'image/jpeg';\n }\n }\n return '';\n};\n\nconst createBasicMetaTags = (siteHost, siteDescription, siteTitle, siteTwitter) => {\n return [\n {property: 'og:title', content: siteTitle},\n {property: 'og:url', content: siteHost},\n {property: 'og:site_name', content: siteTitle},\n {property: 'og:description', content: siteDescription},\n {property: 'twitter:site', content: siteTwitter},\n {property: 'twitter:card', content: 'summary'},\n ];\n};\n\nconst createChannelMetaTags = (siteTitle, siteHost, siteTwitter, channel) => {\n const { name, longId } = channel;\n return [\n {property: 'og:title', content: `${name} on ${siteTitle}`},\n {property: 'og:url', content: `${siteHost}/${name}:${longId}`},\n {property: 'og:site_name', content: siteTitle},\n {property: 'og:description', content: `${name}, a channel on ${siteTitle}`},\n {property: 'twitter:site', content: siteTwitter},\n {property: 'twitter:card', content: 'summary'},\n ];\n};\n\nconst createAssetMetaTags = (siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail) => {\n const { claimData } = asset;\n const { contentType } = claimData;\n const embedUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`;\n const showUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`;\n const source = `${siteHost}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`;\n const ogTitle = claimData.title || claimData.name;\n const ogDescription = claimData.description || defaultDescription;\n const ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);\n const ogThumbnail = claimData.thumbnail || defaultThumbnail;\n const metaTags = [\n {property: 'og:title', content: ogTitle},\n {property: 'og:url', content: showUrl},\n {property: 'og:site_name', content: siteTitle},\n {property: 'og:description', content: ogDescription},\n {property: 'og:image:width', content: 600},\n {property: 'og:image:height', content: 315},\n {property: 'twitter:site', content: siteTwitter},\n ];\n if (contentType === 'video/mp4' || contentType === 'video/webm') {\n metaTags.push({property: 'og:video', content: source});\n metaTags.push({property: 'og:video:secure_url', content: source});\n metaTags.push({property: 'og:video:type', content: contentType});\n metaTags.push({property: 'og:image', content: ogThumbnail});\n metaTags.push({property: 'og:image:type', content: ogThumbnailContentType});\n metaTags.push({property: 'og:type', content: 'video'});\n metaTags.push({property: 'twitter:card', content: 'player'});\n metaTags.push({property: 'twitter:player', content: embedUrl});\n metaTags.push({property: 'twitter:player:width', content: 600});\n metaTags.push({property: 'twitter:text:player_width', content: 600});\n metaTags.push({property: 'twitter:player:height', content: 337});\n metaTags.push({property: 'twitter:player:stream', content: source});\n metaTags.push({property: 'twitter:player:stream:content_type', content: contentType});\n } else {\n metaTags.push({property: 'og:image', content: source});\n metaTags.push({property: 'og:image:type', content: contentType});\n metaTags.push({property: 'og:type', content: 'article'});\n metaTags.push({property: 'twitter:card', content: 'summary_large_image'});\n }\n return metaTags;\n};\n\nexport const createMetaTags = (siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail) => {\n if (asset) {\n return createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail);\n };\n if (channel) {\n return createChannelMetaTags(siteHost, siteTitle, siteTwitter, channel);\n };\n return createBasicMetaTags(siteDescription, siteHost, siteTitle, siteTwitter);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/utils/metaTags.js","const createBasicCanonicalLink = (page, siteHost) => {\n return `${siteHost}/${page}`;\n};\n\nconst createAssetCanonicalLink = (asset, siteHost) => {\n let channelName, certificateId, name, claimId;\n if (asset.claimData) {\n ({ channelName, certificateId, name, claimId } = asset.claimData);\n };\n if (channelName) {\n return `${siteHost}/${channelName}:${certificateId}/${name}`;\n };\n return `${siteHost}/${claimId}/${name}`;\n};\n\nconst createChannelCanonicalLink = (channel, siteHost) => {\n const { name, longId } = channel;\n return `${siteHost}/${name}:${longId}`;\n};\n\nexport const createCanonicalLink = (asset, channel, page, siteHost) => {\n if (asset) {\n return createAssetCanonicalLink(asset, siteHost);\n }\n if (channel) {\n return createChannelCanonicalLink(channel, siteHost);\n }\n return createBasicCanonicalLink(page, siteHost);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/utils/canonicalLink.js","import React from 'react';\nimport { NavLink, withRouter } from 'react-router-dom';\nimport Logo from 'components/Logo';\nimport NavBarChannelDropdown from 'components/NavBarChannelOptionsDropdown';\nimport request from 'utils/request';\n\nconst VIEW = 'VIEW';\nconst LOGOUT = 'LOGOUT';\n\nclass NavBar extends React.Component {\n constructor (props) {\n super(props);\n this.checkForLoggedInUser = this.checkForLoggedInUser.bind(this);\n this.logoutUser = this.logoutUser.bind(this);\n this.handleSelection = this.handleSelection.bind(this);\n }\n componentDidMount () {\n // check to see if the user is already logged in\n this.checkForLoggedInUser();\n }\n checkForLoggedInUser () {\n const params = {credentials: 'include'};\n request('/user', params)\n .then(({ data }) => {\n this.props.onChannelLogin(data.channelName, data.shortChannelId, data.channelClaimId);\n })\n .catch(error => {\n console.log('/user error:', error.message);\n });\n }\n logoutUser () {\n const params = {credentials: 'include'};\n request('/logout', params)\n .then(() => {\n this.props.onChannelLogout();\n })\n .catch(error => {\n console.log('/logout error', error.message);\n });\n }\n handleSelection (event) {\n const value = event.target.selectedOptions[0].value;\n switch (value) {\n case LOGOUT:\n this.logoutUser();\n break;\n case VIEW:\n // redirect to channel page\n this.props.history.push(`/${this.props.channelName}:${this.props.channelLongId}`);\n break;\n default:\n break;\n }\n }\n render () {\n const { siteDescription } = this.props;\n return (\n
\n
\n \n
\n {siteDescription}\n
\n
\n Publish\n About\n { this.props.channelName ? (\n \n ) : (\n Channel\n )}\n
\n
\n
\n );\n }\n}\n\nexport default withRouter(NavBar);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/NavBar/view.jsx","import React from 'react';\nimport { Link } from 'react-router-dom';\n\nfunction Logo () {\n return (\n \n \n Logo\n Spee.ch logo\n \n \n \n Spee<h\n \n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nexport default Logo;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/Logo/index.jsx","import React from 'react';\n\nfunction NavBarChannelDropdown ({ channelName, handleSelection, defaultSelection, VIEW, LOGOUT }) {\n return (\n \n );\n};\n\nexport default NavBarChannelDropdown;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/NavBarChannelOptionsDropdown/index.jsx","module.exports = require(\"cross-fetch/polyfill\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"cross-fetch/polyfill\"\n// module id = 91\n// module chunks = 0","import {connect} from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ publish }) => {\n return {\n disabled: publish.disabled,\n file : publish.file,\n status : publish.status.status,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishTool/index.js","import React from 'react';\nimport Dropzone from 'containers/Dropzone';\nimport PublishDetails from 'containers/PublishDetails';\nimport PublishStatus from 'containers/PublishStatus';\nimport PublishDisabledMessage from 'containers/PublishDisabledMessage';\n\nclass PublishTool extends React.Component {\n render () {\n if (this.props.disabled) {\n console.log('publish is disabled');\n return (\n \n );\n } else {\n console.log('publish is not disabled');\n if (this.props.file) {\n if (this.props.status) {\n return (\n \n );\n } else {\n return ;\n }\n }\n return ;\n }\n }\n};\n\nexport default PublishTool;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishTool/view.jsx","import React from 'react';\nimport { validateFile } from 'utils/file';\nimport PublishPreview from 'components/PublishPreview';\n\nclass Dropzone extends React.Component {\n constructor (props) {\n super(props);\n this.state = {\n dragOver : false,\n mouseOver : false,\n dimPreview: false,\n };\n this.handleDrop = this.handleDrop.bind(this);\n this.handleDragOver = this.handleDragOver.bind(this);\n this.handleDragEnd = this.handleDragEnd.bind(this);\n this.handleDragEnter = this.handleDragEnter.bind(this);\n this.handleDragLeave = this.handleDragLeave.bind(this);\n this.handleMouseEnter = this.handleMouseEnter.bind(this);\n this.handleMouseLeave = this.handleMouseLeave.bind(this);\n this.handleClick = this.handleClick.bind(this);\n this.handleFileInput = this.handleFileInput.bind(this);\n this.chooseFile = this.chooseFile.bind(this);\n }\n handleDrop (event) {\n event.preventDefault();\n this.setState({dragOver: false});\n // if dropped items aren't files, reject them\n const dt = event.dataTransfer;\n if (dt.items) {\n if (dt.items[0].kind === 'file') {\n const droppedFile = dt.items[0].getAsFile();\n this.chooseFile(droppedFile);\n }\n }\n }\n handleDragOver (event) {\n event.preventDefault();\n }\n handleDragEnd (event) {\n var dt = event.dataTransfer;\n if (dt.items) {\n for (var i = 0; i < dt.items.length; i++) {\n dt.items.remove(i);\n }\n } else {\n event.dataTransfer.clearData();\n }\n }\n handleDragEnter () {\n this.setState({dragOver: true, dimPreview: true});\n }\n handleDragLeave () {\n this.setState({dragOver: false, dimPreview: false});\n }\n handleMouseEnter () {\n this.setState({mouseOver: true, dimPreview: true});\n }\n handleMouseLeave () {\n this.setState({mouseOver: false, dimPreview: false});\n }\n handleClick (event) {\n event.preventDefault();\n document.getElementById('file_input').click();\n }\n handleFileInput (event) {\n event.preventDefault();\n const fileList = event.target.files;\n this.chooseFile(fileList[0]);\n }\n chooseFile (file) {\n if (file) {\n try {\n validateFile(file); // validate the file's name, type, and size\n } catch (error) {\n return this.props.setFileError(error.message);\n }\n // stage it so it will be ready when the publish button is clicked\n this.props.selectFile(file);\n }\n }\n render () {\n return (\n
\n
\n \n
\n
\n {this.props.file ? (\n
\n \n
\n { this.state.dragOver ? (\n
\n

Drop it.

\n
\n ) : (\n null\n )}\n { this.state.mouseOver ? (\n
\n

{this.props.fileError}

\n

Drag & drop image or video here to publish

\n

OR

\n

CHOOSE FILE

\n
\n ) : (\n null\n )}\n
\n
\n ) : (\n
\n { this.state.dragOver ? (\n
\n

Drop it.

\n
\n ) : (\n
\n

{this.props.fileError}

\n

Drag & drop image or video here to publish

\n

OR

\n

CHOOSE FILE

\n
\n )}\n
\n )}\n
\n
\n );\n }\n};\n\nexport default Dropzone;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/Dropzone/view.jsx","module.exports = {\n validateFile (file) {\n if (!file) {\n throw new Error('no file provided');\n }\n if (/'/.test(file.name)) {\n throw new Error('apostrophes are not allowed in the file name');\n }\n // validate size and type\n switch (file.type) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n if (file.size > 10000000) {\n throw new Error('Sorry, images are limited to 10 megabytes.');\n }\n break;\n case 'image/gif':\n if (file.size > 50000000) {\n throw new Error('Sorry, GIFs are limited to 50 megabytes.');\n }\n break;\n case 'video/mp4':\n if (file.size > 50000000) {\n throw new Error('Sorry, videos are limited to 50 megabytes.');\n }\n break;\n default:\n throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');\n }\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/utils/file.js","import React from 'react';\nimport PropTypes from 'prop-types';\n\nclass PublishPreview extends React.Component {\n constructor (props) {\n super(props);\n this.state = {\n imgSource : '',\n defaultThumbnail: '/assets/img/video_thumb_default.png',\n };\n }\n componentDidMount () {\n this.setPreviewImageSource(this.props.file);\n }\n componentWillReceiveProps (newProps) {\n if (newProps.file !== this.props.file) {\n this.setPreviewImageSource(newProps.file);\n }\n if (newProps.thumbnail !== this.props.thumbnail) {\n if (newProps.thumbnail) {\n this.setPreviewImageSourceFromFile(newProps.thumbnail);\n } else {\n this.setState({imgSource: this.state.defaultThumbnail});\n }\n }\n }\n setPreviewImageSourceFromFile (file) {\n const previewReader = new FileReader();\n previewReader.readAsDataURL(file);\n previewReader.onloadend = () => {\n this.setState({imgSource: previewReader.result});\n };\n }\n setPreviewImageSource (file) {\n if (file.type !== 'video/mp4') {\n this.setPreviewImageSourceFromFile(file);\n } else {\n if (this.props.thumbnail) {\n this.setPreviewImageSourceFromFile(this.props.thumbnail);\n }\n this.setState({imgSource: this.state.defaultThumbnail});\n }\n }\n render () {\n return (\n \n );\n }\n};\n\nPublishPreview.propTypes = {\n dimPreview: PropTypes.bool.isRequired,\n file : PropTypes.object.isRequired,\n thumbnail : PropTypes.object,\n};\n\nexport default PublishPreview;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/PublishPreview/index.jsx","import {connect} from 'react-redux';\nimport {clearFile, startPublish} from 'actions/publish';\nimport View from './view';\n\nconst mapStateToProps = ({ channel, publish }) => {\n return {\n file: publish.file,\n };\n};\n\nconst mapDispatchToProps = {\n clearFile,\n startPublish,\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishDetails/index.js","import React from 'react';\nimport { withRouter } from 'react-router-dom';\nimport Dropzone from 'containers/Dropzone';\nimport PublishTitleInput from 'containers/PublishTitleInput';\nimport PublishUrlInput from 'containers/PublishUrlInput';\nimport PublishThumbnailInput from 'containers/PublishThumbnailInput';\nimport PublishMetadataInputs from 'containers/PublishMetadataInputs';\nimport ChannelSelect from 'containers/ChannelSelect';\n\nclass PublishDetails extends React.Component {\n constructor (props) {\n super(props)\n this.onPublishSubmit = this.onPublishSubmit.bind(this);\n }\n onPublishSubmit () {\n this.props.startPublish(this.props.history);\n }\n render () {\n return (\n
\n
\n \n
\n {/* left column */}\n
\n
\n \n
\n
\n {/* right column */}\n
\n
\n
\n \n
\n
\n \n
\n { (this.props.file.type === 'video/mp4') && (\n
\n \n
\n )}\n
\n \n
\n
\n \n
\n
\n \n
\n
\n

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. Read more.

\n
\n
\n
\n
\n );\n }\n};\n\nexport default withRouter(PublishDetails);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishDetails/view.jsx","import {connect} from 'react-redux';\nimport {updateMetadata} from 'actions/publish';\nimport View from './view';\n\nconst mapStateToProps = ({ publish }) => {\n return {\n title: publish.metadata.title,\n };\n};\n\nconst mapDispatchToProps = dispatch => {\n return {\n onMetadataChange: (name, value) => {\n dispatch(updateMetadata(name, value));\n },\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishTitleInput/index.js","import React from 'react';\n\nclass PublishTitleInput extends React.Component {\n constructor (props) {\n super(props);\n this.handleInput = this.handleInput.bind(this);\n }\n handleInput (e) {\n const name = e.target.name;\n const value = e.target.value;\n this.props.onMetadataChange(name, value);\n }\n render () {\n return (\n \n );\n }\n}\n\nexport default PublishTitleInput;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishTitleInput/view.jsx","import {updateClaim, updateError} from 'actions/publish';\nimport {connect} from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ channel, publish }) => {\n return {\n loggedInChannelName : channel.loggedInChannel.name,\n loggedInChannelShortId: channel.loggedInChannel.shortId,\n fileName : publish.file.name,\n publishInChannel : publish.publishInChannel,\n selectedChannel : publish.selectedChannel,\n claim : publish.claim,\n urlError : publish.error.url,\n };\n};\n\nconst mapDispatchToProps = dispatch => {\n return {\n onClaimChange: (value) => {\n dispatch(updateClaim(value));\n dispatch(updateError('publishSubmit', null));\n },\n onUrlError: (value) => {\n dispatch(updateError('url', value));\n },\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishUrlInput/index.js","import React from 'react';\nimport request from 'utils/request';\nimport UrlMiddle from 'components/PublishUrlMiddleDisplay';\n\nclass PublishUrlInput extends React.Component {\n constructor (props) {\n super(props);\n this.handleInput = this.handleInput.bind(this);\n }\n componentDidMount () {\n const { claim, fileName } = this.props;\n if (!claim) {\n this.setClaimName(fileName);\n }\n }\n componentWillReceiveProps ({ claim, fileName }) {\n // if a new file was chosen, update the claim name\n if (fileName !== this.props.fileName) {\n return this.setClaimName(fileName);\n }\n // if the claim has updated, check its availability\n if (claim !== this.props.claim) {\n this.validateClaim(claim);\n }\n }\n handleInput (event) {\n let value = event.target.value;\n value = this.cleanseInput(value);\n // update the state\n this.props.onClaimChange(value);\n }\n cleanseInput (input) {\n input = input.replace(/\\s+/g, '-'); // replace spaces with dashes\n input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'\n return input;\n }\n setClaimName (fileName) {\n const fileNameWithoutEnding = fileName.substring(0, fileName.lastIndexOf('.'));\n const cleanClaimName = this.cleanseInput(fileNameWithoutEnding);\n this.props.onClaimChange(cleanClaimName);\n }\n validateClaim (claim) {\n if (!claim) {\n return this.props.onUrlError('Enter a url above');\n }\n request(`/api/claim/availability/${claim}`)\n .then(() => {\n this.props.onUrlError(null);\n })\n .catch((error) => {\n this.props.onUrlError(error.message);\n });\n }\n render () {\n const { claim, loggedInChannelName, loggedInChannelShortId, publishInChannel, selectedChannel, urlError } = this.props;\n return (\n
\n
\n spee.ch / \n \n \n { (claim && !urlError) && {'\\u2713'} }\n { urlError && {'\\u2716'} }\n
\n
\n { urlError ? (\n

{urlError}

\n ) : (\n

Choose a custom url

\n )}\n
\n
\n );\n }\n}\n\nexport default PublishUrlInput;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishUrlInput/view.jsx","import React from 'react';\nimport PropTypes from 'prop-types';\n\nfunction UrlMiddle ({publishInChannel, selectedChannel, loggedInChannelName, loggedInChannelShortId}) {\n if (publishInChannel) {\n if (selectedChannel === loggedInChannelName) {\n return {loggedInChannelName}:{loggedInChannelShortId} /;\n }\n return @channelSelect a channel below /;\n }\n return (\n xyzThis will be a random id /\n );\n}\n\nUrlMiddle.propTypes = {\n publishInChannel : PropTypes.bool.isRequired,\n loggedInChannelName : PropTypes.string,\n loggedInChannelShortId: PropTypes.string,\n};\n\nexport default UrlMiddle;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/PublishUrlMiddleDisplay/index.jsx","import { connect } from 'react-redux';\nimport { onNewThumbnail } from 'actions/publish';\nimport View from './view';\n\nconst mapStateToProps = ({ publish: { file } }) => {\n return {\n file,\n };\n};\n\nconst mapDispatchToProps = {\n onNewThumbnail,\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishThumbnailInput/index.js","import React from 'react';\n\nfunction dataURItoBlob(dataURI) {\n // convert base64/URLEncoded data component to raw binary data held in a string\n let byteString = atob(dataURI.split(',')[1]);\n // separate out the mime component\n let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];\n // write the bytes of the string to a typed array\n let ia = new Uint8Array(byteString.length);\n for (let i = 0; i < byteString.length; i++) {\n ia[i] = byteString.charCodeAt(i);\n }\n return new Blob([ia], {type: mimeString});\n}\n\nclass PublishThumbnailInput extends React.Component {\n constructor (props) {\n super(props);\n this.state = {\n videoSource : null,\n error : null,\n sliderMinRange: 1,\n sliderMaxRange: null,\n sliderValue : null,\n };\n this.handleVideoLoadedData = this.handleVideoLoadedData.bind(this);\n this.handleSliderChange = this.handleSliderChange.bind(this);\n this.createThumbnail = this.createThumbnail.bind(this);\n }\n componentDidMount () {\n const { file } = this.props;\n this.setVideoSource(file);\n }\n componentWillReceiveProps (nextProps) {\n // if file changes\n if (nextProps.file && nextProps.file !== this.props.file) {\n const { file } = nextProps;\n this.setVideoSource(file);\n };\n }\n setVideoSource (file) {\n const previewReader = new FileReader();\n previewReader.readAsDataURL(file);\n previewReader.onloadend = () => {\n const dataUri = previewReader.result;\n const blob = dataURItoBlob(dataUri);\n const videoSource = URL.createObjectURL(blob);\n this.setState({ videoSource });\n };\n }\n handleVideoLoadedData (event) {\n const duration = event.target.duration;\n const totalMinutes = Math.floor(duration / 60);\n const totalSeconds = Math.floor(duration % 60);\n // set the slider\n this.setState({\n sliderMaxRange: duration * 100,\n sliderValue : duration * 100 / 2,\n totalMinutes,\n totalSeconds,\n });\n // update the current time of the video\n let video = document.getElementById('video-thumb-player');\n video.currentTime = duration / 2;\n }\n handleSliderChange (event) {\n const value = parseInt(event.target.value);\n // update the slider value\n this.setState({\n sliderValue: value,\n });\n // update the current time of the video\n let video = document.getElementById('video-thumb-player');\n video.currentTime = value / 100;\n }\n createThumbnail () {\n // take a snapshot\n let video = document.getElementById('video-thumb-player');\n let canvas = document.createElement('canvas');\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);\n const dataUrl = canvas.toDataURL();\n const blob = dataURItoBlob(dataUrl);\n const snapshot = new File([blob], `thumbnail.png`, {\n type: 'image/png',\n });\n // set the thumbnail in redux store\n if (snapshot) {\n this.props.onNewThumbnail(snapshot);\n }\n }\n render () {\n const { error, videoSource, sliderMinRange, sliderMaxRange, sliderValue, totalMinutes, totalSeconds } = this.state;\n return (\n
\n \n \n {\n sliderValue ? (\n
\n
\n 0'00\"\n {totalMinutes}'{totalSeconds}\"\n
\n
\n \n
\n
\n ) : (\n

loading...

\n )\n }\n { error ? (\n

{error}

\n ) : (\n

Use slider to set thumbnail

\n )}\n
\n );\n }\n}\n\nexport default PublishThumbnailInput;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishThumbnailInput/view.jsx","import {connect} from 'react-redux';\nimport {updateMetadata, toggleMetadataInputs} from 'actions/publish';\nimport View from './view';\n\nconst mapStateToProps = ({ publish }) => {\n return {\n showMetadataInputs: publish.showMetadataInputs,\n description : publish.metadata.description,\n license : publish.metadata.license,\n nsfw : publish.metadata.nsfw,\n };\n};\n\nconst mapDispatchToProps = dispatch => {\n return {\n onMetadataChange: (name, value) => {\n dispatch(updateMetadata(name, value));\n },\n onToggleMetadataInputs: (value) => {\n dispatch(toggleMetadataInputs(value));\n },\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishMetadataInputs/index.js","import React from 'react';\nimport ExpandingTextArea from 'components/ExpandingTextArea';\n\nclass PublishMetadataInputs extends React.Component {\n constructor (props) {\n super(props);\n this.toggleShowInputs = this.toggleShowInputs.bind(this);\n this.handleInput = this.handleInput.bind(this);\n this.handleSelect = this.handleSelect.bind(this);\n }\n toggleShowInputs () {\n this.props.onToggleMetadataInputs(!this.props.showMetadataInputs);\n }\n handleInput (event) {\n const target = event.target;\n const value = target.type === 'checkbox' ? target.checked : target.value;\n const name = target.name;\n this.props.onMetadataChange(name, value);\n }\n handleSelect (event) {\n const name = event.target.name;\n const selectedOption = event.target.selectedOptions[0].value;\n this.props.onMetadataChange(name, selectedOption);\n }\n render () {\n return (\n
\n {this.props.showMetadataInputs && (\n
\n
\n
\n \n
\n \n
\n
\n\n
\n
\n \n
\n \n
\n
\n\n
\n
\n \n
\n \n
\n
\n
\n )}\n \n
\n );\n }\n}\n\nexport default PublishMetadataInputs;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishMetadataInputs/view.jsx","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nclass ExpandingTextarea extends Component {\n constructor (props) {\n super(props);\n this._handleChange = this._handleChange.bind(this);\n }\n componentDidMount () {\n this.adjustTextarea({});\n }\n _handleChange (event) {\n const { onChange } = this.props;\n if (onChange) onChange(event);\n this.adjustTextarea(event);\n }\n adjustTextarea ({ target = this.el }) {\n target.style.height = 0;\n target.style.height = `${target.scrollHeight}px`;\n }\n render () {\n const { ...rest } = this.props;\n return (\n this.el = x}\n onChange={this._handleChange}\n />\n );\n }\n}\n\nExpandingTextarea.propTypes = {\n onChange: PropTypes.func,\n};\n\nexport default ExpandingTextarea;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/ExpandingTextArea/index.jsx","import {connect} from 'react-redux';\nimport {setPublishInChannel, updateSelectedChannel, updateError} from 'actions/publish';\nimport View from './view';\n\nconst mapStateToProps = ({ channel, publish }) => {\n return {\n loggedInChannelName: channel.loggedInChannel.name,\n publishInChannel : publish.publishInChannel,\n selectedChannel : publish.selectedChannel,\n channelError : publish.error.channel,\n };\n};\n\nconst mapDispatchToProps = dispatch => {\n return {\n onPublishInChannelChange: (value) => {\n dispatch(updateError('channel', null));\n dispatch(setPublishInChannel(value));\n },\n onChannelSelect: (value) => {\n dispatch(updateError('channel', null));\n dispatch(updateSelectedChannel(value));\n },\n };\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ChannelSelect/index.js","import React from 'react';\nimport ChannelLoginForm from 'containers/ChannelLoginForm';\nimport ChannelCreateForm from 'containers/ChannelCreateForm';\nimport * as states from 'constants/publish_channel_select_states';\n\nclass ChannelSelect extends React.Component {\n constructor (props) {\n super(props);\n this.toggleAnonymousPublish = this.toggleAnonymousPublish.bind(this);\n this.handleSelection = this.handleSelection.bind(this);\n }\n toggleAnonymousPublish (event) {\n const value = event.target.value;\n if (value === 'anonymous') {\n this.props.onPublishInChannelChange(false);\n } else {\n this.props.onPublishInChannelChange(true);\n }\n }\n handleSelection (event) {\n const selectedOption = event.target.selectedOptions[0].value;\n this.props.onChannelSelect(selectedOption);\n }\n render () {\n return (\n
\n
\n
\n \n \n
\n
\n \n \n
\n { this.props.channelError ? (\n

{this.props.channelError}

\n ) : (\n

Publish anonymously or in a channel

\n )}\n
\n { this.props.publishInChannel && (\n
\n
\n \n
\n \n
\n { (this.props.selectedChannel === states.LOGIN) && }\n { (this.props.selectedChannel === states.CREATE) && }\n
\n )}\n
\n );\n }\n}\n\nexport default ChannelSelect;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ChannelSelect/view.jsx","import React from 'react';\nimport request from 'utils/request';\n\nclass ChannelLoginForm extends React.Component {\n constructor (props) {\n super(props);\n this.state = {\n error : null,\n name : '',\n password: '',\n };\n this.handleInput = this.handleInput.bind(this);\n this.loginToChannel = this.loginToChannel.bind(this);\n }\n handleInput (event) {\n const name = event.target.name;\n const value = event.target.value;\n this.setState({[name]: value});\n }\n loginToChannel (event) {\n event.preventDefault();\n const params = {\n method : 'POST',\n body : JSON.stringify({username: this.state.name, password: this.state.password}),\n headers: new Headers({\n 'Content-Type': 'application/json',\n }),\n credentials: 'include',\n };\n request('login', params)\n .then(({success, channelName, shortChannelId, channelClaimId, message}) => {\n if (success) {\n this.props.onChannelLogin(channelName, shortChannelId, channelClaimId);\n } else {\n this.setState({'error': message});\n };\n })\n .catch(error => {\n if (error.message) {\n this.setState({'error': error.message});\n } else {\n this.setState({'error': error});\n }\n });\n }\n render () {\n return (\n
\n
\n
\n \n
\n
\n @\n \n
\n
\n
\n
\n
\n \n
\n
\n \n
\n
\n
\n { this.state.error ? (\n

{this.state.error}

\n ) : (\n

Enter the name and password for your channel

\n )}\n
\n \n
\n
\n );\n }\n}\n\nexport default ChannelLoginForm;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ChannelLoginForm/view.jsx","import React from 'react';\nimport ProgressBar from 'components/ProgressBar';\nimport request from 'utils/request';\n\nclass ChannelCreateForm extends React.Component {\n constructor (props) {\n super(props);\n this.state = {\n error : null,\n channel : '',\n password: '',\n status : null,\n };\n this.handleChannelInput = this.handleChannelInput.bind(this);\n this.handleInput = this.handleInput.bind(this);\n this.createChannel = this.createChannel.bind(this);\n }\n cleanseChannelInput (input) {\n input = input.replace(/\\s+/g, '-'); // replace spaces with dashes\n input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'\n return input;\n }\n handleChannelInput (event) {\n let value = event.target.value;\n value = this.cleanseChannelInput(value);\n this.setState({channel: value});\n if (value) {\n this.updateIsChannelAvailable(value);\n } else {\n this.setState({error: 'Please enter a channel name'});\n }\n }\n handleInput (event) {\n const name = event.target.name;\n const value = event.target.value;\n this.setState({[name]: value});\n }\n updateIsChannelAvailable (channel) {\n const channelWithAtSymbol = `@${channel}`;\n request(`/api/channel/availability/${channelWithAtSymbol}`)\n .then(() => {\n this.setState({'error': null});\n })\n .catch((error) => {\n this.setState({'error': error.message});\n });\n }\n checkIsChannelAvailable (channel) {\n const channelWithAtSymbol = `@${channel}`;\n return request(`/api/channel/availability/${channelWithAtSymbol}`);\n }\n checkIsPasswordProvided (password) {\n return new Promise((resolve, reject) => {\n if (!password || password.length < 1) {\n return reject(new Error('Please provide a password'));\n }\n resolve();\n });\n }\n makePublishChannelRequest (username, password) {\n const params = {\n method : 'POST',\n body : JSON.stringify({username, password}),\n headers: new Headers({\n 'Content-Type': 'application/json',\n }),\n credentials: 'include',\n };\n return new Promise((resolve, reject) => {\n request('/signup', params)\n .then(result => {\n return resolve(result);\n })\n .catch(error => {\n reject(new Error(`Unfortunately, we encountered an error while creating your channel. Please let us know in Discord! ${error.message}`));\n });\n });\n }\n createChannel (event) {\n event.preventDefault();\n this.checkIsPasswordProvided(this.state.password)\n .then(() => {\n return this.checkIsChannelAvailable(this.state.channel);\n })\n .then(() => {\n this.setState({status: 'We are publishing your new channel. Sit tight...'});\n return this.makePublishChannelRequest(this.state.channel, this.state.password);\n })\n .then(result => {\n this.setState({status: null});\n this.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId);\n })\n .catch((error) => {\n if (error.message) {\n this.setState({'error': error.message, status: null});\n } else {\n this.setState({'error': error, status: null});\n };\n });\n }\n render () {\n return (\n
\n { !this.state.status ? (\n
\n
\n
\n \n
\n
\n @\n \n { (this.state.channel && !this.state.error) && {'\\u2713'} }\n { this.state.error && {'\\u2716'} }\n
\n
\n
\n
\n
\n \n
\n
\n \n
\n
\n
\n {this.state.error ? (\n

{this.state.error}

\n ) : (\n

Choose a name and password for your channel

\n )}\n
\n \n
\n
\n ) : (\n
\n

{this.state.status}

\n \n
\n )}\n
\n );\n }\n}\n\nexport default ChannelCreateForm;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ChannelCreateForm/view.jsx","import React from 'react';\n\nconst ActiveStatusBar = () => {\n return | ;\n};\n\nexport default ActiveStatusBar;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/ActiveStatusBar/index.jsx","import React from 'react';\n\nconst InactiveStatusBar = () => {\n return | ;\n};\n\nexport default InactiveStatusBar;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/InactiveStatusBar/index.jsx","import {connect} from 'react-redux';\nimport {clearFile} from 'actions/publish';\nimport View from './view';\n\nconst mapStateToProps = ({ publish }) => {\n return {\n status : publish.status.status,\n message: publish.status.message,\n };\n};\n\nconst mapDispatchToProps = {\n clearFile,\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishStatus/index.js","import React from 'react';\nimport ProgressBar from 'components/ProgressBar';\nimport * as publishStates from 'constants/publish_claim_states';\n\nclass PublishStatus extends React.Component {\n render () {\n const { status, message, clearFile } = this.props;\n return (\n
\n {status === publishStates.LOAD_START &&\n
\n

File is loading to server

\n

0%

\n
\n }\n {status === publishStates.LOADING &&\n
\n
\n

File is loading to server

\n

{message}

\n
\n
\n }\n {status === publishStates.PUBLISHING &&\n
\n

Upload complete. Your file is now being published on the blockchain...

\n \n

Curious what magic is happening here? Learn more.

\n
\n }\n {status === publishStates.SUCCESS &&\n
\n

Your publish is complete! You are being redirected to it now.

\n

If you are not automatically redirected, click here.

\n
\n }\n {status === publishStates.FAILED &&\n
\n

Something went wrong...

\n

{message}

\n

For help, post the above error text in the #speech channel on the lbry discord

\n \n
\n }\n
\n );\n }\n};\n\nexport default PublishStatus;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishStatus/view.jsx","export const LOAD_START = 'LOAD_START';\nexport const LOADING = 'LOADING';\nexport const PUBLISHING = 'PUBLISHING';\nexport const SUCCESS = 'SUCCESS';\nexport const FAILED = 'FAILED';\n\n\n\n// WEBPACK FOOTER //\n// ./client/constants/publish_claim_states.js","import {connect} from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ publish }) => {\n return {\n message: publish.disabledMessage,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishDisabledMessage/index.js","import React from 'react';\n\nclass PublishDisabledMessage extends React.Component {\n render () {\n const message = this.props.message;\n console.log('this.props.message:', message);\n return (\n
\n

Publishing is currently disabled.

\n

{message}

\n
\n );\n }\n}\n\nexport default PublishDisabledMessage;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/PublishDisabledMessage/view.jsx","import React from 'react';\nimport NavBar from 'containers/NavBar';\nimport SEO from 'components/SEO';\n\nclass AboutPage extends React.Component {\n render () {\n return (\n
\n \n \n
\n
\n
\n

Spee.ch is an open-source project. Please contribute to the existing site, or fork it and make your own.

\n

TWITTER

\n

GITHUB

\n

DISCORD CHANNEL

\n

DOCUMENTATION

\n
\n
\n
\n

Spee.ch is a media-hosting site that reads from and publishes content to the LBRY blockchain.

\n

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.

\n

Contribute

\n

If you have an idea for your own spee.ch-like site on top of LBRY, fork our github repo and go to town!

\n

If you want to improve spee.ch, join our discord channel or solve one of our github issues.

\n
\n
\n
\n
\n );\n }\n};\n\nexport default AboutPage;\n\n\n\n// WEBPACK FOOTER //\n// ./client/pages/AboutPage/index.jsx","import {connect} from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ channel }) => {\n return {\n loggedInChannelName: channel.loggedInChannel.name,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/pages/LoginPage/index.js","import React from 'react';\nimport { withRouter } from 'react-router-dom';\nimport SEO from 'components/SEO';\nimport NavBar from 'containers/NavBar';\nimport ChannelLoginForm from 'containers/ChannelLoginForm';\nimport ChannelCreateForm from 'containers/ChannelCreateForm';\n\nclass LoginPage extends React.Component {\n componentWillReceiveProps (newProps) {\n // re-route the user to the homepage if the user is logged in\n if (newProps.loggedInChannelName !== this.props.loggedInChannelName) {\n this.props.history.push(`/`);\n }\n }\n render () {\n return (\n
\n \n \n
\n
\n
\n

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 documenting important events, or making a public repository for cat gifs (password: '1234'), try creating a channel for it!

\n
\n
\n
\n

Log in to an existing channel:

\n \n

Create a brand new channel:

\n \n
\n
\n
\n
\n );\n }\n};\n\nexport default withRouter(LoginPage);\n\n\n\n// WEBPACK FOOTER //\n// ./client/pages/LoginPage/view.jsx","import { connect } from 'react-redux';\nimport { onHandleShowPageUri } from 'actions/show';\nimport View from './view';\n\nconst mapStateToProps = ({ show }) => {\n return {\n error : show.request.error,\n requestType: show.request.type,\n };\n};\n\nconst mapDispatchToProps = {\n onHandleShowPageUri,\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/pages/ShowPage/index.js","import React from 'react';\nimport ErrorPage from 'pages/ErrorPage';\nimport ShowAssetLite from 'containers/ShowAssetLite';\nimport ShowAssetDetails from 'containers/ShowAssetDetails';\nimport ShowChannel from 'containers/ShowChannel';\n\nimport { CHANNEL, ASSET_LITE, ASSET_DETAILS } from 'constants/show_request_types';\n\nclass ShowPage extends React.Component {\n componentDidMount () {\n this.props.onHandleShowPageUri(this.props.match.params);\n }\n componentWillReceiveProps (nextProps) {\n if (nextProps.match.params !== this.props.match.params) {\n this.props.onHandleShowPageUri(nextProps.match.params);\n }\n }\n render () {\n const { error, requestType } = this.props;\n if (error) {\n return (\n \n );\n }\n switch (requestType) {\n case CHANNEL:\n return ;\n case ASSET_LITE:\n return ;\n case ASSET_DETAILS:\n return ;\n default:\n return

loading...

;\n }\n }\n};\n\nexport default ShowPage;\n\n\n\n// WEBPACK FOOTER //\n// ./client/pages/ShowPage/view.jsx","import { connect } from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ show }) => {\n // select request info\n const requestId = show.request.id;\n // select asset info\n let asset;\n const request = show.requestList[requestId] || null;\n const assetList = show.assetList;\n if (request && assetList) {\n const assetKey = request.key; // note: just store this in the request\n asset = assetList[assetKey] || null;\n };\n // return props\n return {\n asset,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ShowAssetLite/index.js","import React from 'react';\nimport SEO from 'components/SEO';\nimport { Link } from 'react-router-dom';\nimport AssetDisplay from 'containers/AssetDisplay';\n\nclass ShowLite extends React.Component {\n render () {\n const { asset } = this.props;\n if (asset) {\n const { name, claimId } = asset.claimData;\n return (\n
\n \n \n hosted\n via Spee.ch\n
\n );\n }\n return (\n
\n

loading asset data...

\n
\n );\n }\n};\n\nexport default ShowLite;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ShowAssetLite/view.jsx","import React from 'react';\nimport ProgressBar from 'components/ProgressBar';\nimport { LOCAL_CHECK, UNAVAILABLE, ERROR, AVAILABLE } from 'constants/asset_display_states';\n\nclass AssetDisplay extends React.Component {\n componentDidMount () {\n const { asset: { claimData: { name, claimId } } } = this.props;\n this.props.onFileRequest(name, claimId);\n }\n render () {\n const { status, error, asset: { claimData: { name, claimId, contentType, fileExt, thumbnail } } } = this.props;\n return (\n
\n {(status === LOCAL_CHECK) &&\n
\n

Checking to see if Spee.ch has your asset locally...

\n
\n }\n {(status === UNAVAILABLE) &&\n
\n

Sit tight, we're searching the LBRY blockchain for your asset!

\n \n

Curious what magic is happening here? Learn more.

\n
\n }\n {(status === ERROR) &&\n
\n

Unfortunately, we couldn't download your asset from LBRY. You can help us out by sharing the below error message in the LBRY discord.

\n

{error}

\n
\n }\n {(status === AVAILABLE) &&\n (() => {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n return (\n \n );\n case 'image/gif':\n return (\n \n );\n case 'video/mp4':\n return (\n \n );\n default:\n return (\n

Unsupported file type

\n );\n }\n })()\n }\n
\n );\n }\n};\n\nexport default AssetDisplay;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/AssetDisplay/view.jsx","import { connect } from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ show }) => {\n // select request info\n const requestId = show.request.id;\n // select asset info\n let asset;\n const request = show.requestList[requestId] || null;\n const assetList = show.assetList;\n if (request && assetList) {\n const assetKey = request.key; // note: just store this in the request\n asset = assetList[assetKey] || null;\n };\n // return props\n return {\n asset,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ShowAssetDetails/index.js","import React from 'react';\nimport SEO from 'components/SEO';\nimport NavBar from 'containers/NavBar';\nimport ErrorPage from 'pages/ErrorPage';\nimport AssetTitle from 'containers/AssetTitle';\nimport AssetDisplay from 'containers/AssetDisplay';\nimport AssetInfo from 'containers/AssetInfo';\n\nclass ShowAssetDetails extends React.Component {\n render () {\n const { asset } = this.props;\n if (asset) {\n const { claimData: { name } } = asset;\n return (\n
\n \n \n
\n
\n \n
\n
\n
\n \n
\n
\n
\n \n
\n
\n
\n
\n );\n };\n return (\n \n );\n }\n};\n\nexport default ShowAssetDetails;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ShowAssetDetails/view.jsx","import { connect } from 'react-redux';\nimport View from './view';\nimport { selectAsset } from 'selectors/show';\n\nconst mapStateToProps = ({ show }) => {\n const { claimData: { title } } = selectAsset(show);\n return {\n title,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/AssetTitle/index.js","import React from 'react';\n\nconst AssetTitle = ({ title }) => {\n return (\n
\n {title}\n
\n );\n};\n\nexport default AssetTitle;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/AssetTitle/view.jsx","import { connect } from 'react-redux';\nimport View from './view';\nimport { selectAsset } from 'selectors/show';\n\nconst mapStateToProps = ({ show }) => {\n // select asset\n const asset = selectAsset(show);\n // return props\n return {\n asset,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/AssetInfo/index.js","import React from 'react';\nimport { Link } from 'react-router-dom';\n\nclass AssetInfo extends React.Component {\n constructor (props) {\n super(props);\n this.copyToClipboard = this.copyToClipboard.bind(this);\n }\n copyToClipboard (event) {\n var elementToCopy = event.target.dataset.elementtocopy;\n var element = document.getElementById(elementToCopy);\n element.select();\n try {\n document.execCommand('copy');\n } catch (err) {\n this.setState({error: 'Oops, unable to copy'});\n }\n }\n render () {\n const { asset: { shortId, claimData : { channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host } } } = this.props;\n return (\n
\n {channelName &&\n
\n
\n Channel:\n
\n
\n {channelName}\n
\n
\n }\n\n {description &&\n
\n {description}\n
\n }\n\n
\n
\n
\n Share:\n
\n
\n \n twitter\n facebook\n tumblr\n reddit\n
\n
\n
\n
\n\n
\n \n );\n }\n};\n\nexport default AssetInfo;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/AssetInfo/view.jsx","import { connect } from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ show }) => {\n // select request info\n const requestId = show.request.id;\n // select request\n const previousRequest = show.requestList[requestId] || null;\n // select channel\n let channel;\n if (previousRequest) {\n const channelKey = previousRequest.key;\n channel = show.channelList[channelKey] || null;\n }\n return {\n channel,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ShowChannel/index.js","import React from 'react';\nimport SEO from 'components/SEO';\nimport ErrorPage from 'pages/ErrorPage';\nimport NavBar from 'containers/NavBar';\nimport ChannelClaimsDisplay from 'containers/ChannelClaimsDisplay';\n\nclass ShowChannel extends React.Component {\n render () {\n const { channel } = this.props;\n if (channel) {\n const { name, longId, shortId } = channel;\n return (\n
\n \n \n
\n
\n

channel name: {name}

\n

full channel id: {longId}

\n

short channel id: {shortId}

\n
\n
\n \n
\n
\n
\n );\n };\n return (\n \n );\n }\n};\n\nexport default ShowChannel;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ShowChannel/view.jsx","import { connect } from 'react-redux';\nimport { onUpdateChannelClaims } from 'actions/show';\nimport View from './view';\n\nconst mapStateToProps = ({ show }) => {\n // select channel key\n const request = show.requestList[show.request.id];\n const channelKey = request.key;\n // select channel claims\n const channel = show.channelList[channelKey] || null;\n // return props\n return {\n channelKey,\n channel,\n };\n};\n\nconst mapDispatchToProps = {\n onUpdateChannelClaims,\n};\n\nexport default connect(mapStateToProps, mapDispatchToProps)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ChannelClaimsDisplay/index.js","import React from 'react';\nimport AssetPreview from 'components/AssetPreview';\n\nclass ChannelClaimsDisplay extends React.Component {\n constructor (props) {\n super(props);\n this.showNextResultsPage = this.showNextResultsPage.bind(this);\n this.showPreviousResultsPage = this.showPreviousResultsPage.bind(this);\n }\n showPreviousResultsPage () {\n const { channel: { claimsData: { currentPage } } } = this.props;\n const previousPage = parseInt(currentPage) - 1;\n this.showNewPage(previousPage);\n }\n showNextResultsPage () {\n const { channel: { claimsData: { currentPage } } } = this.props;\n const nextPage = parseInt(currentPage) + 1;\n this.showNewPage(nextPage);\n }\n showNewPage (page) {\n const { channelKey, channel: { name, longId } } = this.props;\n this.props.onUpdateChannelClaims(channelKey, name, longId, page);\n }\n render () {\n const { channel: { claimsData: { claims, currentPage, totalPages } } } = this.props;\n return (\n
\n {(claims.length > 0) ? (\n
\n {claims.map((claim, index) => )}\n
\n {(currentPage > 1) &&\n \n }\n {(currentPage < totalPages) &&\n \n }\n
\n
\n ) : (\n

There are no claims in this channel

\n )}\n
\n );\n }\n};\n\nexport default ChannelClaimsDisplay;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/ChannelClaimsDisplay/view.jsx","import { connect } from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({site: {defaults: { defaultThumbnail }}}) => {\n return {\n defaultThumbnail,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/AssetPreview/index.js","import React from 'react';\nimport { Link } from 'react-router-dom';\n\nconst AssetPreview = ({ defaultThumbnail, claimData: { name, claimId, fileExt, contentType, thumbnail } }) => {\n const directSourceLink = `${claimId}/${name}.${fileExt}`;\n const showUrlLink = `/${claimId}/${name}`;\n return (\n
\n \n {(() => {\n switch (contentType) {\n case 'image/jpeg':\n case 'image/jpg':\n case 'image/png':\n case 'image/gif':\n return (\n \n );\n case 'video/mp4':\n return (\n \n );\n default:\n return (\n

unsupported file type

\n );\n }\n })()}\n \n
\n );\n};\n\nexport default AssetPreview;\n\n\n\n// WEBPACK FOOTER //\n// ./client/components/AssetPreview/view.jsx","import { connect } from 'react-redux';\nimport View from './view';\n\nconst mapStateToProps = ({ site: { host, title } }) => {\n return {\n host,\n title,\n };\n};\n\nexport default connect(mapStateToProps, null)(View);\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/FourOhFourPage/index.jsx","import React from 'react';\nimport NavBar from 'containers/NavBar';\nimport Helmet from 'react-helmet';\n\nclass FourOhForPage extends React.Component {\n render () {\n const {title, host} = this.props;\n return (\n
\n \n {title} - 404\n \n \n \n
\n

404

\n

That page does not exist

\n
\n
\n );\n }\n};\n\nexport default FourOhForPage;\n\n\n\n// WEBPACK FOOTER //\n// ./client/containers/FourOhFourPage/view.jsx","const { sendGAServeEvent } = require('../helpers/googleAnalytics');\nconst { determineResponseType, flipClaimNameAndIdForBackwardsCompatibility, logRequestData, getClaimIdAndServeAsset } = require('../helpers/serveHelpers.js');\nconst lbryUri = require('../helpers/lbryUri.js');\nconst handleShowRender = require('../helpers/handleShowRender.jsx');\nconst SERVE = 'SERVE';\n\nmodule.exports = (app) => {\n // route to serve a specific asset using the channel or claim id\n app.get('/:identifier/:claim', (req, res) => {\n const { headers, ip, originalUrl, params } = req;\n // decide if this is a show request\n let hasFileExtension;\n try {\n ({ hasFileExtension } = lbryUri.parseModifier(params.claim));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n let responseType = determineResponseType(hasFileExtension, headers);\n if (responseType !== SERVE) {\n return handleShowRender(req, res);\n }\n // handle serve request\n // send google analytics\n sendGAServeEvent(headers, ip, originalUrl);\n // parse the claim\n let claimName;\n try {\n ({ claimName } = lbryUri.parseClaim(params.claim));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n // parse the identifier\n let isChannel, channelName, channelClaimId, claimId;\n try {\n ({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(params.identifier));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n if (!isChannel) {\n [claimId, claimName] = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);\n }\n // log the request data for debugging\n logRequestData(responseType, claimName, channelName, claimId);\n // get the claim Id and then serve the asset\n getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);\n });\n // route to serve the winning asset at a claim or a channel page\n app.get('/:claim', (req, res) => {\n const { headers, ip, originalUrl, params } = req;\n // decide if this is a show request\n let hasFileExtension;\n try {\n ({ hasFileExtension } = lbryUri.parseModifier(params.claim));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n let responseType = determineResponseType(hasFileExtension, headers);\n if (responseType !== SERVE) {\n return handleShowRender(req, res);\n }\n // handle serve request\n // send google analytics\n sendGAServeEvent(headers, ip, originalUrl);\n // parse the claim\n let claimName;\n try {\n ({claimName} = lbryUri.parseClaim(params.claim));\n } catch (error) {\n return res.status(400).json({success: false, message: error.message});\n }\n // log the request data for debugging\n logRequestData(responseType, claimName, null, null);\n // get the claim Id and then serve the asset\n getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);\n });\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/asset-routes.js","const logger = require('winston');\nconst { getClaimId, getLocalFileRecord } = require('../controllers/serveController.js');\nconst { handleErrorResponse } = require('./errorHandlers.js');\n\nconst SERVE = 'SERVE';\nconst SHOW = 'SHOW';\nconst NO_FILE = 'NO_FILE';\nconst NO_CHANNEL = 'NO_CHANNEL';\nconst NO_CLAIM = 'NO_CLAIM';\n\nfunction clientAcceptsHtml ({accept}) {\n return accept && accept.match(/text\\/html/);\n};\n\nfunction requestIsFromBrowser (headers) {\n return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);\n};\n\nfunction clientWantsAsset ({accept, range}) {\n const imageIsWanted = accept && accept.match(/image\\/.*/) && !accept.match(/text\\/html/) && !accept.match(/text\\/\\*/);\n const videoIsWanted = accept && range;\n return imageIsWanted || videoIsWanted;\n};\n\nfunction isValidClaimId (claimId) {\n return ((claimId.length === 40) && !/[^A-Za-z0-9]/g.test(claimId));\n};\n\nfunction isValidShortId (claimId) {\n return claimId.length === 1; // it should really evaluate the short url itself\n};\n\nfunction isValidShortIdOrClaimId (input) {\n return (isValidClaimId(input) || isValidShortId(input));\n};\n\nfunction serveAssetToClient (claimId, name, res) {\n return getLocalFileRecord(claimId, name)\n .then(fileRecord => {\n // check that a local record was found\n if (fileRecord === NO_FILE) {\n return res.status(307).redirect(`/api/claim/get/${name}/${claimId}`);\n }\n // serve the file\n const {filePath, fileType} = fileRecord;\n logger.verbose(`serving file: ${filePath}`);\n const sendFileOptions = {\n headers: {\n 'X-Content-Type-Options': 'nosniff',\n 'Content-Type' : fileType || 'image/jpeg',\n },\n };\n res.status(200).sendFile(filePath, sendFileOptions);\n })\n .catch(error => {\n throw error;\n });\n};\n\nmodule.exports = {\n getClaimIdAndServeAsset (channelName, channelClaimId, claimName, claimId, originalUrl, ip, res) {\n // get the claim Id and then serve the asset\n getClaimId(channelName, channelClaimId, claimName, claimId)\n .then(fullClaimId => {\n if (fullClaimId === NO_CLAIM) {\n return res.status(404).json({success: false, message: 'no claim id could be found'});\n } else if (fullClaimId === NO_CHANNEL) {\n return res.status(404).json({success: false, message: 'no channel id could be found'});\n }\n serveAssetToClient(fullClaimId, claimName, res);\n // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');\n })\n .catch(error => {\n handleErrorResponse(originalUrl, ip, error, res);\n // postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');\n });\n },\n determineResponseType (hasFileExtension, headers) {\n let responseType;\n if (hasFileExtension) {\n responseType = SERVE; // assume a serve request if file extension is present\n if (clientAcceptsHtml(headers)) { // if the request comes from a browser, change it to a show request\n responseType = SHOW;\n }\n } else {\n responseType = SHOW;\n if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) { // this is in case someone embeds a show url\n logger.debug('Show request came from browser but wants an image/video. Changing response to serve...');\n responseType = SERVE;\n }\n }\n return responseType;\n },\n flipClaimNameAndIdForBackwardsCompatibility (identifier, name) {\n // this is a patch for backwards compatability with '/name/claim_id' url format\n if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) {\n const tempName = name;\n name = identifier;\n identifier = tempName;\n }\n return [identifier, name];\n },\n logRequestData (responseType, claimName, channelName, claimId) {\n logger.debug('responseType ===', responseType);\n logger.debug('claim name === ', claimName);\n logger.debug('channel name ===', channelName);\n logger.debug('claim id ===', claimId);\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/serveHelpers.js","const logger = require('winston');\n\nmodule.exports = {\n REGEXP_INVALID_CLAIM : /[^A-Za-z0-9-]/g,\n REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,\n REGEXP_ADDRESS : /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,\n CHANNEL_CHAR : '@',\n parseIdentifier : function (identifier) {\n logger.debug('parsing identifier:', identifier);\n const componentsRegex = new RegExp(\n '([^:$#/]*)' + // value (stops at the first separator or end)\n '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n const [proto, value, modifierSeperator, modifier] = componentsRegex\n .exec(identifier)\n .map(match => match || null);\n logger.debug(`${proto}, ${value}, ${modifierSeperator}, ${modifier}`);\n\n // Validate and process name\n if (!value) {\n throw new Error(`Check your url. No channel name provided before \"${modifierSeperator}\"`);\n }\n const isChannel = value.startsWith(module.exports.CHANNEL_CHAR);\n const channelName = isChannel ? value : null;\n let claimId;\n if (isChannel) {\n if (!channelName) {\n throw new Error('No channel name after @.');\n }\n const nameBadChars = (channelName).match(module.exports.REGEXP_INVALID_CHANNEL);\n if (nameBadChars) {\n throw new Error(`Invalid characters in channel name: ${nameBadChars.join(', ')}.`);\n }\n } else {\n claimId = value;\n }\n\n // Validate and process modifier\n let channelClaimId;\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error(`No modifier provided after separator \"${modifierSeperator}\"`);\n }\n\n if (modifierSeperator === ':') {\n channelClaimId = modifier;\n } else {\n throw new Error(`The \"${modifierSeperator}\" modifier is not currently supported`);\n }\n }\n return {\n isChannel,\n channelName,\n channelClaimId,\n claimId,\n };\n },\n parseClaim: function (claim) {\n logger.debug('parsing name:', claim);\n const componentsRegex = new RegExp(\n '([^:$#/.]*)' + // name (stops at the first modifier)\n '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n const [proto, claimName, modifierSeperator, modifier] = componentsRegex\n .exec(claim)\n .map(match => match || null);\n logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);\n\n // Validate and process name\n if (!claimName) {\n throw new Error('No claim name provided before .');\n }\n const nameBadChars = (claimName).match(module.exports.REGEXP_INVALID_CLAIM);\n if (nameBadChars) {\n throw new Error(`Invalid characters in claim name: ${nameBadChars.join(', ')}.`);\n }\n // Validate and process modifier\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error(`No file extension provided after separator ${modifierSeperator}.`);\n }\n if (modifierSeperator !== '.') {\n throw new Error(`The ${modifierSeperator} modifier is not supported in the claim name`);\n }\n }\n // return results\n return {\n claimName,\n };\n },\n parseModifier: function (claim) {\n logger.debug('parsing modifier:', claim);\n const componentsRegex = new RegExp(\n '([^:$#/.]*)' + // name (stops at the first modifier)\n '([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n const [proto, claimName, modifierSeperator, modifier] = componentsRegex\n .exec(claim)\n .map(match => match || null);\n logger.debug(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);\n // Validate and process modifier\n let hasFileExtension = false;\n if (modifierSeperator) {\n hasFileExtension = true;\n }\n return {\n hasFileExtension,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/lbryUri.js","import React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport { createStore, applyMiddleware } from 'redux';\nimport Reducer from '../../client/reducers/index';\nimport { Provider } from 'react-redux';\nimport { StaticRouter } from 'react-router-dom';\nimport GAListener from '../../client/components/GAListener/index';\nimport App from '../../client/app';\nimport renderFullPage from './renderFullPage';\nimport createSagaMiddleware from 'redux-saga';\nimport { call } from 'redux-saga/effects';\nimport { handleShowPageUri } from '../../client/sagas/show_uri';\nimport { onHandleShowPageUri } from '../../client/actions/show';\n\nimport Helmet from 'react-helmet';\n\nconst returnSagaWithParams = (saga, params) => {\n return function * () {\n yield call(saga, params);\n };\n};\n\nmodule.exports = (req, res) => {\n let context = {};\n\n // create and apply middleware\n const sagaMiddleware = createSagaMiddleware();\n const middleware = applyMiddleware(sagaMiddleware);\n\n // create a new Redux store instance\n const store = createStore(Reducer, middleware);\n\n // create saga\n const action = onHandleShowPageUri(req.params);\n const saga = returnSagaWithParams(handleShowPageUri, action);\n\n // run the saga middleware\n sagaMiddleware\n .run(saga)\n .done\n .then(() => {\n // render component to a string\n const html = renderToString(\n \n \n \n \n \n \n \n );\n\n // get head tags from helmet\n const helmet = Helmet.renderStatic();\n\n // check for a redirect\n if (context.url) {\n return res.redirect(301, context.url);\n }\n\n // get the initial state from our Redux store\n const preloadedState = store.getState();\n\n // send the rendered page back to the client\n res.send(renderFullPage(helmet, html, preloadedState));\n });\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/handleShowRender.jsx","module.exports = require(\"redux-saga\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"redux-saga\"\n// module id = 146\n// module chunks = 0","import { call, put, takeLatest } from 'redux-saga/effects';\nimport * as actions from 'constants/show_action_types';\nimport { onRequestError, onNewChannelRequest, onNewAssetRequest } from 'actions/show';\nimport { newAssetRequest } from 'sagas/show_asset';\nimport { newChannelRequest } from 'sagas/show_channel';\nimport lbryUri from 'utils/lbryUri';\n\nfunction * parseAndUpdateIdentifierAndClaim (modifier, claim) {\n // this is a request for an asset\n // claim will be an asset claim\n // the identifier could be a channel or a claim id\n let isChannel, channelName, channelClaimId, claimId, claimName, extension;\n try {\n ({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(modifier));\n ({ claimName, extension } = lbryUri.parseClaim(claim));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n // trigger an new action to update the store\n if (isChannel) {\n return yield call(newAssetRequest, onNewAssetRequest(claimName, null, channelName, channelClaimId, extension));\n };\n yield call(newAssetRequest, onNewAssetRequest(claimName, claimId, null, null, extension));\n}\nfunction * parseAndUpdateClaimOnly (claim) {\n // this could be a request for an asset or a channel page\n // claim could be an asset claim or a channel claim\n let isChannel, channelName, channelClaimId;\n try {\n ({ isChannel, channelName, channelClaimId } = lbryUri.parseIdentifier(claim));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n // trigger an new action to update the store\n // return early if this request is for a channel\n if (isChannel) {\n return yield call(newChannelRequest, onNewChannelRequest(channelName, channelClaimId));\n }\n // if not for a channel, parse the claim request\n let claimName, extension;\n try {\n ({claimName, extension} = lbryUri.parseClaim(claim));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n yield call(newAssetRequest, onNewAssetRequest(claimName, null, null, null, extension));\n}\n\nexport function * handleShowPageUri (action) {\n const { identifier, claim } = action.data;\n if (identifier) {\n return yield call(parseAndUpdateIdentifierAndClaim, identifier, claim);\n }\n yield call(parseAndUpdateClaimOnly, claim);\n};\n\nexport function * watchHandleShowPageUri () {\n yield takeLatest(actions.HANDLE_SHOW_URI, handleShowPageUri);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/sagas/show_uri.js","import { call, put, select, takeLatest } from 'redux-saga/effects';\nimport * as actions from 'constants/show_action_types';\nimport { addRequestToRequestList, onRequestError, onRequestUpdate, addAssetToAssetList } from 'actions/show';\nimport { getLongClaimId, getShortId, getClaimData } from 'api/assetApi';\nimport { selectShowState } from 'selectors/show';\nimport { selectSiteHost } from 'selectors/site';\n\nexport function * newAssetRequest (action) {\n const { requestType, requestId, name, modifier } = action.data;\n // put an action to update the request in redux\n yield put(onRequestUpdate(requestType, requestId));\n // is this an existing request?\n // If this uri is in the request list, it's already been fetched\n const state = yield select(selectShowState);\n const host = yield select(selectSiteHost);\n if (state.requestList[requestId]) {\n return null;\n }\n // get long id && add request to request list\n let longId;\n try {\n ({data: longId} = yield call(getLongClaimId, host, name, modifier));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n const assetKey = `a#${name}#${longId}`;\n yield put(addRequestToRequestList(requestId, null, assetKey));\n // is this an existing asset?\n // If this asset is in the asset list, it's already been fetched\n if (state.assetList[assetKey]) {\n return null;\n }\n // get short Id\n let shortId;\n try {\n ({data: shortId} = yield call(getShortId, host, name, longId));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n // get asset claim data\n let claimData;\n try {\n ({data: claimData} = yield call(getClaimData, host, name, longId));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n // add asset to asset list\n yield put(addAssetToAssetList(assetKey, null, name, longId, shortId, claimData));\n // clear any errors in request error\n yield put(onRequestError(null));\n};\n\nexport function * watchNewAssetRequest () {\n yield takeLatest(actions.ASSET_REQUEST_NEW, newAssetRequest);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/sagas/show_asset.js","import Request from 'utils/request';\n\nexport function getLongClaimId (host, name, modifier) {\n let body = {};\n // create request params\n if (modifier) {\n if (modifier.id) {\n body['claimId'] = modifier.id;\n } else {\n body['channelName'] = modifier.channel.name;\n body['channelClaimId'] = modifier.channel.id;\n }\n }\n body['claimName'] = name;\n const params = {\n method : 'POST',\n headers: { 'Content-Type': 'application/json' },\n body : JSON.stringify(body),\n };\n // create url\n const url = `${host}/api/claim/long-id`;\n // return the request promise\n return Request(url, params);\n};\n\nexport function getShortId (host, name, claimId) {\n const url = `${host}/api/claim/short-id/${claimId}/${name}`;\n return Request(url);\n};\n\nexport function getClaimData (host, name, claimId) {\n const url = `${host}/api/claim/data/${name}/${claimId}`;\n return Request(url);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/api/assetApi.js","import {call, put, select, takeLatest} from 'redux-saga/effects';\nimport * as actions from 'constants/show_action_types';\nimport { addNewChannelToChannelList, addRequestToRequestList, onRequestError, onRequestUpdate, updateChannelClaims } from 'actions/show';\nimport { getChannelClaims, getChannelData } from 'api/channelApi';\nimport { selectShowState } from 'selectors/show';\nimport { selectSiteHost } from 'selectors/site';\n\nexport function * newChannelRequest (action) {\n const { requestType, requestId, channelName, channelId } = action.data;\n // put an action to update the request in redux\n yield put(onRequestUpdate(requestType, requestId));\n // is this an existing request?\n // If this uri is in the request list, it's already been fetched\n const state = yield select(selectShowState);\n const host = yield select(selectSiteHost);\n if (state.requestList[requestId]) {\n return null;\n }\n // get channel long id\n let longId, shortId;\n try {\n ({ data: {longChannelClaimId: longId, shortChannelClaimId: shortId} } = yield call(getChannelData, host, channelName, channelId));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n // store the request in the channel requests list\n const channelKey = `c#${channelName}#${longId}`;\n yield put(addRequestToRequestList(requestId, null, channelKey));\n // is this an existing channel?\n // If this channel is in the channel list, it's already been fetched\n if (state.channelList[channelKey]) {\n return null;\n }\n // get channel claims data\n let claimsData;\n try {\n ({ data: claimsData } = yield call(getChannelClaims, host, longId, channelName, 1));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n // store the channel data in the channel list\n yield put(addNewChannelToChannelList(channelKey, channelName, shortId, longId, claimsData));\n // clear any request errors\n yield put(onRequestError(null));\n}\n\nexport function * watchNewChannelRequest () {\n yield takeLatest(actions.CHANNEL_REQUEST_NEW, newChannelRequest);\n};\n\nfunction * getNewClaimsAndUpdateChannel (action) {\n const { channelKey, name, longId, page } = action.data;\n const host = yield select(selectSiteHost);\n let claimsData;\n try {\n ({ data: claimsData } = yield call(getChannelClaims, host, longId, name, page));\n } catch (error) {\n return yield put(onRequestError(error.message));\n }\n yield put(updateChannelClaims(channelKey, claimsData));\n}\n\nexport function * watchUpdateChannelClaims () {\n yield takeLatest(actions.CHANNEL_CLAIMS_UPDATE_ASYNC, getNewClaimsAndUpdateChannel);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./client/sagas/show_channel.js","import Request from 'utils/request';\n\nexport function getChannelData (host, id, name) {\n if (!id) id = 'none';\n const url = `${host}/api/channel/data/${name}/${id}`;\n return Request(url);\n};\n\nexport function getChannelClaims (host, longId, name, page) {\n if (!page) page = 1;\n const url = `${host}/api/channel/claims/${name}/${longId}/${page}`;\n return Request(url);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/api/channelApi.js","module.exports = {\n REGEXP_INVALID_CLAIM : /[^A-Za-z0-9-]/g,\n REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,\n REGEXP_ADDRESS : /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,\n CHANNEL_CHAR : '@',\n parseIdentifier : function (identifier) {\n const componentsRegex = new RegExp(\n '([^:$#/]*)' + // value (stops at the first separator or end)\n '([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)\n );\n const [proto, value, modifierSeperator, modifier] = componentsRegex // eslint-disable-line no-unused-vars\n .exec(identifier)\n .map(match => match || null);\n\n // Validate and process name\n if (!value) {\n throw new Error(`Check your URL. No channel name provided before \"${modifierSeperator}\"`);\n }\n const isChannel = value.startsWith(module.exports.CHANNEL_CHAR);\n const channelName = isChannel ? value : null;\n let claimId;\n if (isChannel) {\n if (!channelName) {\n throw new Error('Check your URL. No channel name after \"@\".');\n }\n const nameBadChars = (channelName).match(module.exports.REGEXP_INVALID_CHANNEL);\n if (nameBadChars) {\n throw new Error(`Check your URL. Invalid characters in channel name: \"${nameBadChars.join(', ')}\".`);\n }\n } else {\n claimId = value;\n }\n\n // Validate and process modifier\n let channelClaimId;\n if (modifierSeperator) {\n if (!modifier) {\n throw new Error(`Check your URL. No modifier provided after separator \"${modifierSeperator}\"`);\n }\n\n if (modifierSeperator === ':') {\n channelClaimId = modifier;\n } else {\n throw new Error(`Check your URL. The \"${modifierSeperator}\" modifier is not currently supported`);\n }\n }\n return {\n isChannel,\n channelName,\n channelClaimId: channelClaimId || null,\n claimId : claimId || null,\n };\n },\n parseClaim: function (name) {\n const componentsRegex = new RegExp(\n '([^:$#/.]*)' + // name (stops at the first extension)\n '([:$#.]?)([^/]*)' // extension separator, extension (stops at the first path separator or end)\n );\n const [proto, claimName, extensionSeperator, extension] = componentsRegex // eslint-disable-line no-unused-vars\n .exec(name)\n .map(match => match || null);\n\n // Validate and process name\n if (!claimName) {\n throw new Error('Check your URL. No claim name provided before \".\"');\n }\n const nameBadChars = (claimName).match(module.exports.REGEXP_INVALID_CLAIM);\n if (nameBadChars) {\n throw new Error(`Check your URL. Invalid characters in claim name: \"${nameBadChars.join(', ')}\".`);\n }\n // Validate and process extension\n if (extensionSeperator) {\n if (!extension) {\n throw new Error(`Check your URL. No file extension provided after separator \"${extensionSeperator}\".`);\n }\n if (extensionSeperator !== '.') {\n throw new Error(`Check your URL. The \"${extensionSeperator}\" separator is not supported in the claim name.`);\n }\n }\n return {\n claimName,\n extension: extension || null,\n };\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./client/utils/lbryUri.js","const handlePageRender = require('../helpers/handlePageRender.jsx');\n\nmodule.exports = app => {\n // a catch-all route if someone visits a page that does not exist\n app.use('*', (req, res) => {\n // send response\n handlePageRender(req, res);\n });\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/routes/fallback-routes.js","const { logLevel } = require('../../config/loggerConfig');\n\nmodule.exports = (winston) => {\n // configure\n winston.configure({\n transports: [\n new (winston.transports.Console)({\n level : logLevel,\n timestamp : false,\n colorize : true,\n prettyPrint : true,\n handleExceptions : true,\n humanReadableUnhandledException: true,\n }),\n ],\n });\n // test all the log levels\n winston.error('Level 0');\n winston.warn('Level 1');\n winston.info('Level 2');\n winston.verbose('Level 3');\n winston.debug('Level 4');\n winston.silly('Level 5');\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/configureLogger.js","const loggerConfig = {\n logLevel: 'debug', // options: silly, debug, verbose, info\n};\n\nmodule.exports = loggerConfig;\n\n\n\n// WEBPACK FOOTER //\n// ./config/loggerConfig.js","const winstonSlackWebHook = require('winston-slack-webhook').SlackWebHook;\nconst slackConfig = require('../../config/slackConfig.js');\n\nmodule.exports = (winston) => {\n const {slackWebHook, slackErrorChannel, slackInfoChannel} = slackConfig;\n if (slackWebHook) {\n // add a transport for errors to slack\n if (slackErrorChannel) {\n winston.add(winstonSlackWebHook, {\n name : 'slack-errors-transport',\n level : 'warn',\n webhookUrl: slackWebHook,\n channel : slackErrorChannel,\n username : 'spee.ch',\n iconEmoji : ':face_with_head_bandage:',\n });\n };\n if (slackInfoChannel) {\n winston.add(winstonSlackWebHook, {\n name : 'slack-info-transport',\n level : 'info',\n webhookUrl: slackWebHook,\n channel : slackInfoChannel,\n username : 'spee.ch',\n iconEmoji : ':nerd_face:',\n });\n };\n // send test message\n winston.error('Slack \"error\" logging is online.');\n winston.info('Slack \"info\" logging is online.');\n } else {\n winston.warn('Slack logging is not enabled because no slackWebHook config var provided.');\n }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./server/helpers/configureSlack.js","module.exports = require(\"winston-slack-webhook\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"winston-slack-webhook\"\n// module id = 157\n// module chunks = 0","function SlackConfig () {\n this.slackWebHook = 'default';\n this.slackErrorChannel = 'default';\n this.slackInfoChannel = 'default';\n};\n\nmodule.exports = new SlackConfig();\n\n\n\n// WEBPACK FOOTER //\n// ./config/slackConfig.js"],"sourceRoot":""} \ No newline at end of file diff --git a/package.json b/package.json index c6d0dbce..c7c9672e 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,21 @@ { "name": "spee.ch", "version": "0.0.1", - "description": "a single-serving site that reads and publishes images to and from the LBRY blockchain", - "main": "speech.js", + "description": "a web application that reads and publishes images to and from the LBRY blockchain", + "main": "index.js", "scripts": { "test": "mocha --recursive", "test-all": "mocha --recursive", - "start": "node server.js", - "start-dev": "nodemon server.js", + "start": "node index.js", + "start-dev": "nodemon index.js", "lint": "eslint .", "fix": "eslint . --fix", "precommit": "eslint .", "babel": "babel", "build-dev": "webpack --config webpack.dev.js", - "build-prod": "webpack --config webpack.prod.js" + "build-dev-client": "webpack --config webpack.dev.client.js", + "build-dev-server": "webpack --config webpack.dev.server.js", + "build": "webpack --config webpack.prod.js" }, "repository": { "type": "git", @@ -34,6 +36,7 @@ "axios": "^0.16.1", "bcrypt": "^1.0.3", "body-parser": "^1.17.1", + "babel-polyfill": "^6.26.0", "config": "^1.26.1", "connect-multiparty": "^2.0.0", "cookie-session": "^2.0.0-beta.3", @@ -59,7 +62,6 @@ "request-promise": "^4.2.2", "sequelize": "^4.1.0", "sequelize-cli": "^3.0.0-3", - "sleep": "^5.1.1", "universal-analytics": "^0.4.13", "webpack-node-externals": "^1.6.0", "whatwg-fetch": "^2.0.3", @@ -70,7 +72,6 @@ "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-polyfill": "^6.26.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.24.1", diff --git a/react/api/publishApi.js b/react/api/publishApi.js deleted file mode 100644 index e69de29b..00000000 diff --git a/react/containers/PublishTool/view.jsx b/react/containers/PublishTool/view.jsx deleted file mode 100644 index ef7b4f26..00000000 --- a/react/containers/PublishTool/view.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import Dropzone from 'containers/Dropzone'; -import PublishDetails from 'containers/PublishDetails'; -import PublishStatus from 'containers/PublishStatus'; - -class PublishTool extends React.Component { - render () { - if (this.props.disabled) { - return ( -
-

Publishing is temporarily disabled.

-

Please check back soon or join our discord channel for updates.

-
- ); - } - if (this.props.file) { - if (this.props.status) { - return ( - - ); - } else { - return ; - } - } - return ; - } -}; - -export default PublishTool; diff --git a/react/reducers/site.js b/react/reducers/site.js deleted file mode 100644 index aa215467..00000000 --- a/react/reducers/site.js +++ /dev/null @@ -1,12 +0,0 @@ -const { site } = require('../../config/speechConfig.js'); - -const initialState = { - host: site.host, -}; - -export default function (state = initialState, action) { - switch (action.type) { - default: - return state; - } -} diff --git a/react/selectors/site.js b/react/selectors/site.js deleted file mode 100644 index 2ba7f269..00000000 --- a/react/selectors/site.js +++ /dev/null @@ -1,3 +0,0 @@ -export const selectSiteState = (state) => { - return state.site; -}; diff --git a/react/utils/canonicalLink.js b/react/utils/canonicalLink.js deleted file mode 100644 index a76f3c73..00000000 --- a/react/utils/canonicalLink.js +++ /dev/null @@ -1,37 +0,0 @@ -const { site: { host } } = require('../../config/speechConfig.js'); - -const createBasicCanonicalLink = (page) => { - if (!page) { - return `${host}`; - }; - return `${host}/${page}`; -}; - -const createAssetCanonicalLink = (asset) => { - let channelName, certificateId, name, claimId; - if (asset.claimData) { - ({ channelName, certificateId, name, claimId } = asset.claimData); - }; - if (channelName) { - return `${host}/${channelName}:${certificateId}/${name}`; - }; - return `${host}/${claimId}/${name}`; -}; - -const createChannelCanonicalLink = (channel) => { - const { name, longId } = channel; - return `${host}/${name}:${longId}`; -}; - -export const createCanonicalLink = (asset, channel, page) => { - if (asset) { - return createAssetCanonicalLink(asset); - } - if (channel) { - return createChannelCanonicalLink(channel); - } - if (page) { - return createBasicCanonicalLink(page); - } - return createBasicCanonicalLink(); -}; diff --git a/react/utils/pageTitle.js b/react/utils/pageTitle.js deleted file mode 100644 index 430f6c2a..00000000 --- a/react/utils/pageTitle.js +++ /dev/null @@ -1,8 +0,0 @@ -const { site: { title: siteTitle } } = require('../../config/speechConfig.js'); - -export const createPageTitle = (pageTitle) => { - if (!pageTitle) { - return `${siteTitle}`; - } - return `${siteTitle} - ${pageTitle}`; -}; diff --git a/server.js b/server.js new file mode 100644 index 00000000..bb0dbdf5 --- /dev/null +++ b/server.js @@ -0,0 +1,84 @@ +// dependencies +const express = require('express'); +const bodyParser = require('body-parser'); +const expressHandlebars = require('express-handlebars'); +const Handlebars = require('handlebars'); +const helmet = require('helmet'); +const passport = require('passport'); +const cookieSession = require('cookie-session'); +const { serializeSpeechUser, deserializeSpeechUser } = require('./server/helpers/authHelpers.js'); +const logger = require('winston'); + +// require configs +const {auth: { sessionKey }, details: { port: PORT }} = require('./config/siteConfig.js'); + +const db = require('./server/models'); + +// configure logging +require('./server/helpers/configureLogger.js')(logger); +// configure slack +require('./server/helpers/configureSlack.js')(logger); + +// create an Express application +const app = express(); + +// trust the proxy to get ip address for us +app.enable('trust proxy'); + +// add middleware +app.use(helmet()); // set HTTP headers to protect against well-known web vulnerabilties +app.use(express.static(`${__dirname}/public`)); // 'express.static' to serve static files from public directory +app.use(bodyParser.json()); // 'body parser' for parsing application/json +app.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded +app.use((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); +const localSignupStrategy = require('./server/passport/local-signup.js'); +const localLoginStrategy = require('./server/passport/local-login.js'); +passport.use('local-signup', localSignupStrategy); +passport.use('local-login', localLoginStrategy); +// initialize passport +app.use(cookieSession({ + name : 'session', + keys : [sessionKey], + maxAge: 24 * 60 * 60 * 1000, // i.e. 24 hours +})); +app.use(passport.initialize()); +app.use(passport.session()); + +// configure handlebars & register it with express app +const hbs = expressHandlebars.create({ + defaultLayout: 'embed', + handlebars : Handlebars, +}); +app.engine('handlebars', hbs.engine); +app.set('view engine', 'handlebars'); + +// sync sequelize +db.sequelize + .sync() + .then(() => { + // set the routes on the app + require('./server/routes/auth-routes.js')(app); + require('./server/routes/api-routes.js')(app); + require('./server/routes/page-routes.js')(app); + require('./server/routes/asset-routes.js')(app); + require('./server/routes/fallback-routes.js')(app); + // create server + const http = require('http'); + return http.Server(app); + }) + // start the server + .then(server => { + server.listen(PORT, () => { + logger.info(`Server is listening on PORT ${PORT}`); + }); + }) + .catch((error) => { + logger.error(`Startup Error:`, error); + }); diff --git a/auth/authentication.js b/server/auth/authentication.js similarity index 100% rename from auth/authentication.js rename to server/auth/authentication.js diff --git a/controllers/publishController.js b/server/controllers/publishController.js similarity index 97% rename from controllers/publishController.js rename to server/controllers/publishController.js index 8733a147..1d133b37 100644 --- a/controllers/publishController.js +++ b/server/controllers/publishController.js @@ -2,7 +2,7 @@ const logger = require('winston'); const db = require('../models'); const lbryApi = require('../helpers/lbryApi.js'); const publishHelpers = require('../helpers/publishHelpers.js'); -const { publish : { primaryClaimAddress, additionalClaimAddresses } } = require('../config/speechConfig.js'); +const { publishing: { primaryClaimAddress, additionalClaimAddresses } } = require('../../config/siteConfig.js'); const Sequelize = require('sequelize'); const Op = Sequelize.Op; diff --git a/controllers/serveController.js b/server/controllers/serveController.js similarity index 100% rename from controllers/serveController.js rename to server/controllers/serveController.js diff --git a/server/controllers/statsController.js b/server/controllers/statsController.js new file mode 100644 index 00000000..e4fd5f30 --- /dev/null +++ b/server/controllers/statsController.js @@ -0,0 +1,19 @@ +const logger = require('winston'); +const db = require('../models/index'); + +module.exports = { + getRecentClaims () { + logger.debug('retrieving most recent claims'); + return new Promise((resolve, reject) => { + // get the raw requests data + db.File.getRecentClaims() + .then(results => { + resolve(results); + }) + .catch(error => { + logger.error('sequelize error', error); + reject(error); + }); + }); + }, +}; diff --git a/server/helpers/authHelpers.js b/server/helpers/authHelpers.js new file mode 100644 index 00000000..109c03c6 --- /dev/null +++ b/server/helpers/authHelpers.js @@ -0,0 +1,12 @@ +const logger = require('winston'); + +module.exports = { + serializeSpeechUser (user, done) { // returns user data to be serialized into session + logger.debug('serializing user'); + done(null, user); + }, + deserializeSpeechUser (user, done) { // deserializes session and populates additional info to req.user + logger.debug('deserializing user'); + done(null, user); + }, +}; diff --git a/helpers/channelPagination.js b/server/helpers/channelPagination.js similarity index 100% rename from helpers/channelPagination.js rename to server/helpers/channelPagination.js diff --git a/helpers/configVarCheck.js b/server/helpers/configVarCheck.js similarity index 86% rename from helpers/configVarCheck.js rename to server/helpers/configVarCheck.js index c32af5a4..642125ba 100644 --- a/helpers/configVarCheck.js +++ b/server/helpers/configVarCheck.js @@ -1,9 +1,7 @@ -const config = require('../config/speechConfig.js'); const logger = require('winston'); -module.exports = function () { +module.exports = (config) => { // get the config file - for (let configCategoryKey in config) { if (config.hasOwnProperty(configCategoryKey)) { // get the final variables for each config category diff --git a/config/loggerConfig.js b/server/helpers/configureLogger.js similarity index 80% rename from config/loggerConfig.js rename to server/helpers/configureLogger.js index ffd4c970..cf78b453 100644 --- a/config/loggerConfig.js +++ b/server/helpers/configureLogger.js @@ -1,4 +1,7 @@ -module.exports = (winston, logLevel) => { +const { logLevel } = require('../../devConfig/loggerConfig'); + +module.exports = (winston) => { + // configure winston.configure({ transports: [ new (winston.transports.Console)({ @@ -11,7 +14,7 @@ module.exports = (winston, logLevel) => { }), ], }); - + // test all the log levels winston.error('Level 0'); winston.warn('Level 1'); winston.info('Level 2'); diff --git a/config/slackConfig.js b/server/helpers/configureSlack.js similarity index 88% rename from config/slackConfig.js rename to server/helpers/configureSlack.js index 0f7ed106..f94a3e8a 100644 --- a/config/slackConfig.js +++ b/server/helpers/configureSlack.js @@ -1,8 +1,8 @@ -const { logging } = require('./speechConfig.js'); -const { slackWebHook, slackErrorChannel, slackInfoChannel } = logging; const winstonSlackWebHook = require('winston-slack-webhook').SlackWebHook; +const slackConfig = require('../../devConfig/slackConfig.js'); module.exports = (winston) => { + const {slackWebHook, slackErrorChannel, slackInfoChannel} = slackConfig; if (slackWebHook) { // add a transport for errors to slack if (slackErrorChannel) { diff --git a/helpers/errorHandlers.js b/server/helpers/errorHandlers.js similarity index 100% rename from helpers/errorHandlers.js rename to server/helpers/errorHandlers.js diff --git a/helpers/googleAnalytics.js b/server/helpers/googleAnalytics.js similarity index 92% rename from helpers/googleAnalytics.js rename to server/helpers/googleAnalytics.js index b224638f..0f5da915 100644 --- a/helpers/googleAnalytics.js +++ b/server/helpers/googleAnalytics.js @@ -1,6 +1,6 @@ const logger = require('winston'); const ua = require('universal-analytics'); -const { analytics : { googleId }, site: { name: siteName } } = require('../config/speechConfig.js'); +const { analytics : { googleId }, details: { title } } = require('../../config/siteConfig.js'); function createServeEventParams (headers, ip, originalUrl) { return { @@ -49,7 +49,7 @@ module.exports = { }, sendGATimingEvent (category, variable, label, startTime, endTime) { const params = createPublishTimingEventParams(category, variable, label, startTime, endTime); - sendGoogleAnalyticsTiming(siteName, params); + sendGoogleAnalyticsTiming(title, params); }, chooseGaLbrynetPublishLabel ({ channel_name: channelName, channel_id: channelId }) { return (channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM'); diff --git a/helpers/handlePageRender.jsx b/server/helpers/handlePageRender.jsx similarity index 89% rename from helpers/handlePageRender.jsx rename to server/helpers/handlePageRender.jsx index 206303c4..1c01c8c3 100644 --- a/helpers/handlePageRender.jsx +++ b/server/helpers/handlePageRender.jsx @@ -1,11 +1,11 @@ import React from 'react'; import { renderToString } from 'react-dom/server'; import { createStore } from 'redux'; -import Reducer from '../react/reducers'; +import Reducer from 'reducers'; import { Provider } from 'react-redux'; import { StaticRouter } from 'react-router-dom'; -import GAListener from '../react/components/GAListener'; -import App from '../react/app'; +import GAListener from 'components/GAListener'; +import App from 'app.jsx'; import renderFullPage from './renderFullPage.js'; import Helmet from 'react-helmet'; diff --git a/helpers/handleShowRender.jsx b/server/helpers/handleShowRender.jsx similarity index 87% rename from helpers/handleShowRender.jsx rename to server/helpers/handleShowRender.jsx index ac9e2d32..e5076c95 100644 --- a/helpers/handleShowRender.jsx +++ b/server/helpers/handleShowRender.jsx @@ -1,16 +1,16 @@ import React from 'react'; import { renderToString } from 'react-dom/server'; import { createStore, applyMiddleware } from 'redux'; -import Reducer from '../react/reducers'; +import Reducer from 'reducers'; import { Provider } from 'react-redux'; import { StaticRouter } from 'react-router-dom'; -import GAListener from '../react/components/GAListener'; -import App from '../react/app'; +import GAListener from 'components/GAListener'; +import App from 'app.jsx'; import renderFullPage from './renderFullPage'; import createSagaMiddleware from 'redux-saga'; import { call } from 'redux-saga/effects'; -import { handleShowPageUri } from '../react/sagas/show_uri'; -import { onHandleShowPageUri } from '../react/actions/show'; +import { handleShowPageUri } from 'sagas/show_uri'; +import { onHandleShowPageUri } from 'actions/show'; import Helmet from 'react-helmet'; diff --git a/helpers/lbryApi.js b/server/helpers/lbryApi.js similarity index 97% rename from helpers/lbryApi.js rename to server/helpers/lbryApi.js index 47384316..72735cd0 100644 --- a/helpers/lbryApi.js +++ b/server/helpers/lbryApi.js @@ -1,7 +1,6 @@ const axios = require('axios'); const logger = require('winston'); -const config = require('../config/speechConfig.js'); -const { apiHost, apiPort } = config.api; +const { api: { apiHost, apiPort } } = require('../../devConfig/lbryConfig.js'); const lbryApiUri = 'http://' + apiHost + ':' + apiPort; const { chooseGaLbrynetPublishLabel, sendGATimingEvent } = require('./googleAnalytics.js'); diff --git a/helpers/lbryUri.js b/server/helpers/lbryUri.js similarity index 100% rename from helpers/lbryUri.js rename to server/helpers/lbryUri.js diff --git a/helpers/publishHelpers.js b/server/helpers/publishHelpers.js similarity index 93% rename from helpers/publishHelpers.js rename to server/helpers/publishHelpers.js index 1b894eea..03625d9e 100644 --- a/helpers/publishHelpers.js +++ b/server/helpers/publishHelpers.js @@ -1,6 +1,7 @@ const logger = require('winston'); const fs = require('fs'); -const { site, publish } = require('../config/speechConfig.js'); + +const { details, publishing } = require('../../config/siteConfig.js'); module.exports = { parsePublishApiRequestBody ({name, nsfw, license, title, description, thumbnail}) { @@ -109,12 +110,12 @@ module.exports = { metadata : { description, title, - author : site.title, + author : details.title, language: 'en', license, nsfw, }, - claim_address: publish.primaryClaimAddress, + claim_address: publishing.primaryClaimAddress, }; // add thumbnail to channel if video if (thumbnail) { @@ -135,14 +136,14 @@ module.exports = { metadata : { title : `${claimName} thumbnail`, description: `a thumbnail for ${claimName}`, - author : site.title, + author : details.title, language : 'en', license, nsfw, }, - claim_address: publish.primaryClaimAddress, - channel_name : publish.thumbnailChannel, - channel_id : publish.thumbnailChannelId, + claim_address: publishing.primaryClaimAddress, + channel_name : publishing.thumbnailChannel, + channel_id : publishing.thumbnailChannelId, }; }, deleteTemporaryFile (filePath) { diff --git a/helpers/renderFullPage.js b/server/helpers/renderFullPage.js similarity index 100% rename from helpers/renderFullPage.js rename to server/helpers/renderFullPage.js diff --git a/helpers/sequelizeHelpers.js b/server/helpers/sequelizeHelpers.js similarity index 100% rename from helpers/sequelizeHelpers.js rename to server/helpers/sequelizeHelpers.js diff --git a/helpers/serveHelpers.js b/server/helpers/serveHelpers.js similarity index 98% rename from helpers/serveHelpers.js rename to server/helpers/serveHelpers.js index 78447d6d..4a425327 100644 --- a/helpers/serveHelpers.js +++ b/server/helpers/serveHelpers.js @@ -1,6 +1,6 @@ const logger = require('winston'); const { getClaimId, getLocalFileRecord } = require('../controllers/serveController.js'); -const { handleErrorResponse } = require('../helpers/errorHandlers.js'); +const { handleErrorResponse } = require('./errorHandlers.js'); const SERVE = 'SERVE'; const SHOW = 'SHOW'; diff --git a/helpers/statsHelpers.js b/server/helpers/statsHelpers.js similarity index 100% rename from helpers/statsHelpers.js rename to server/helpers/statsHelpers.js diff --git a/migrations/ChangeCertificateColumnTypes2.js b/server/migrations/ChangeCertificateColumnTypes2.js similarity index 100% rename from migrations/ChangeCertificateColumnTypes2.js rename to server/migrations/ChangeCertificateColumnTypes2.js diff --git a/migrations/ChangeClaimColumnTypes.js b/server/migrations/ChangeClaimColumnTypes.js similarity index 100% rename from migrations/ChangeClaimColumnTypes.js rename to server/migrations/ChangeClaimColumnTypes.js diff --git a/models/certificate.js b/server/models/certificate.js similarity index 100% rename from models/certificate.js rename to server/models/certificate.js diff --git a/models/channel.js b/server/models/channel.js similarity index 100% rename from models/channel.js rename to server/models/channel.js diff --git a/models/claim.js b/server/models/claim.js similarity index 98% rename from models/claim.js rename to server/models/claim.js index 35d8c4bd..b7803cb6 100644 --- a/models/claim.js +++ b/server/models/claim.js @@ -1,7 +1,6 @@ const logger = require('winston'); const { returnShortId } = require('../helpers/sequelizeHelpers.js'); -const { claim, site } = require('../config/speechConfig.js'); -const { defaultThumbnail } = claim; +const { assetDefaults: { thumbnail: defaultThumbnail }, details: { host } } = require('../../config/siteConfig.js'); function determineFileExtensionFromContentType (contentType) { switch (contentType) { @@ -31,7 +30,7 @@ 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; + claim['host'] = host; return claim; }; diff --git a/models/file.js b/server/models/file.js similarity index 100% rename from models/file.js rename to server/models/file.js diff --git a/models/index.js b/server/models/index.js similarity index 75% rename from models/index.js rename to server/models/index.js index 370f43ee..c3ea52fa 100644 --- a/models/index.js +++ b/server/models/index.js @@ -1,9 +1,9 @@ const Sequelize = require('sequelize'); const logger = require('winston'); -const config = require('../config/speechConfig.js'); -const { database, username, password } = config.sql; -const db = {}; +console.log('exporting sequelize models'); +const { database, username, password } = require('../../config/mysqlConfig'); +const db = {}; // set sequelize options const sequelize = new Sequelize(database, username, password, { host : 'localhost', @@ -18,6 +18,7 @@ const sequelize = new Sequelize(database, username, password, { }, }); +// establish mysql connection sequelize .authenticate() .then(() => { @@ -27,7 +28,7 @@ sequelize logger.error('Sequelize was unable to connect to the database:', err); }); -// manually add each model to the db +// manually add each model to the db object const Certificate = require('./certificate.js'); const Channel = require('./channel.js'); const Claim = require('./claim.js'); @@ -55,7 +56,9 @@ db.Sequelize = Sequelize; // add an 'upsert' method to the db object db.upsert = (Model, values, condition, tableName) => { return Model - .findOne({ where: condition }) + .findOne({ + where: condition, + }) .then(obj => { if (obj) { // update logger.debug(`updating record in db.${tableName}`); @@ -71,9 +74,4 @@ db.upsert = (Model, values, condition, tableName) => { }); }; -// add a 'getTrendingFiles' method to the db object. note: change this to get claims directly. might need new association between Request and Claim -db.getTrendingFiles = (startDate) => { - return db.sequelize.query(`SELECT COUNT(*), File.* FROM Request LEFT JOIN File ON Request.FileId = File.id WHERE FileId IS NOT NULL AND nsfw != 1 AND trendingEligible = 1 AND Request.createdAt > "${startDate}" GROUP BY FileId ORDER BY COUNT(*) DESC LIMIT 25;`, { type: db.sequelize.QueryTypes.SELECT }); -}; - module.exports = db; diff --git a/models/request.js b/server/models/request.js similarity index 100% rename from models/request.js rename to server/models/request.js diff --git a/models/user.js b/server/models/user.js similarity index 100% rename from models/user.js rename to server/models/user.js diff --git a/passport/local-login.js b/server/passport/local-login.js similarity index 94% rename from passport/local-login.js rename to server/passport/local-login.js index 89b5a968..88dbc28d 100644 --- a/passport/local-login.js +++ b/server/passport/local-login.js @@ -1,8 +1,8 @@ const PassportLocalStrategy = require('passport-local').Strategy; -const db = require('../models'); const logger = require('winston'); +const db = require('../models/index'); -function returnUserAndChannelInfo (userInstance) { +const returnUserAndChannelInfo = (userInstance) => { return new Promise((resolve, reject) => { let userInfo = {}; userInfo['id'] = userInstance.id; @@ -22,7 +22,7 @@ function returnUserAndChannelInfo (userInstance) { reject(error); }); }); -} +}; module.exports = new PassportLocalStrategy( { @@ -61,5 +61,5 @@ module.exports = new PassportLocalStrategy( .catch(error => { return done(error); }); - } + }, ); diff --git a/passport/local-signup.js b/server/passport/local-signup.js similarity index 100% rename from passport/local-signup.js rename to server/passport/local-signup.js index 87087458..07971a9e 100644 --- a/passport/local-signup.js +++ b/server/passport/local-signup.js @@ -1,7 +1,7 @@ -const db = require('../models'); const PassportLocalStrategy = require('passport-local').Strategy; const lbryApi = require('../helpers/lbryApi.js'); const logger = require('winston'); +const db = require('../models'); module.exports = new PassportLocalStrategy( { diff --git a/routes/api-routes.js b/server/routes/api-routes.js similarity index 97% rename from routes/api-routes.js rename to server/routes/api-routes.js index 4f75ecb3..2db7b22a 100644 --- a/routes/api-routes.js +++ b/server/routes/api-routes.js @@ -1,7 +1,7 @@ const logger = require('winston'); const multipart = require('connect-multiparty'); -const { files, site } = require('../config/speechConfig.js'); -const multipartMiddleware = multipart({uploadDir: files.uploadDirectory}); +const { publishing: { uploadDirectory }, details: { host } } = require('../../config/siteConfig.js'); +const multipartMiddleware = multipart({uploadDir: uploadDirectory}); const db = require('../models'); const { claimNameIsAvailable, checkChannelAvailability, publish } = require('../controllers/publishController.js'); const { getClaimList, resolveUri, getClaim } = require('../helpers/lbryApi.js'); @@ -168,7 +168,7 @@ module.exports = (app) => { data : { name, claimId: result.claim_id, - url : `${site.host}/${result.claim_id}/${name}`, + url : `${host}/${result.claim_id}/${name}`, lbryTx : result, }, }); diff --git a/routes/serve-routes.js b/server/routes/asset-routes.js similarity index 100% rename from routes/serve-routes.js rename to server/routes/asset-routes.js diff --git a/routes/auth-routes.js b/server/routes/auth-routes.js similarity index 97% rename from routes/auth-routes.js rename to server/routes/auth-routes.js index 5c6013d7..3314a6d7 100644 --- a/routes/auth-routes.js +++ b/server/routes/auth-routes.js @@ -15,7 +15,6 @@ module.exports = (app) => { // route for log in app.post('/login', (req, res, next) => { passport.authenticate('local-login', (err, user, info) => { - logger.debug('info:', info); if (err) { return next(err); } diff --git a/routes/fallback-routes.js b/server/routes/fallback-routes.js similarity index 100% rename from routes/fallback-routes.js rename to server/routes/fallback-routes.js diff --git a/routes/page-routes.js b/server/routes/page-routes.js similarity index 92% rename from routes/page-routes.js rename to server/routes/page-routes.js index 2203710c..44c19be1 100644 --- a/routes/page-routes.js +++ b/server/routes/page-routes.js @@ -1,4 +1,4 @@ -const { site } = require('../config/speechConfig.js'); +const { details: host } = require('../../config/siteConfig.js'); const handlePageRender = require('../helpers/handlePageRender.jsx'); module.exports = (app) => { @@ -29,7 +29,6 @@ module.exports = (app) => { app.get('/embed/:claimId/:name', ({ params }, res) => { const claimId = params.claimId; const name = params.name; - const host = site.host; // get and render the content res.status(200).render('embed', { layout: 'embed', host, claimId, name }); }); diff --git a/task-scripts/update-channel-names.js b/server/task-scripts/update-channel-names.js similarity index 91% rename from task-scripts/update-channel-names.js rename to server/task-scripts/update-channel-names.js index e3032ddb..b04afdb8 100644 --- a/task-scripts/update-channel-names.js +++ b/server/task-scripts/update-channel-names.js @@ -2,9 +2,7 @@ const logger = require('winston'); const db = require('../models'); // require our models for syncing // configure logging -const config = require('../config/speechConfig.js'); -const { logLevel } = config.logging; -require('../config/loggerConfig.js')(logger, logLevel); +require('../helpers/configureLogger.js')(logger); let totalClaims = 0; let totalClaimsNoCertificate = 0; diff --git a/task-scripts/update-password.js b/server/task-scripts/update-password.js similarity index 82% rename from task-scripts/update-password.js rename to server/task-scripts/update-password.js index e5bfb7d5..dee96d8f 100644 --- a/task-scripts/update-password.js +++ b/server/task-scripts/update-password.js @@ -1,10 +1,8 @@ // load dependencies const logger = require('winston'); -const db = require('../models'); // require our models for syncing +const db = require('../models/index'); // configure logging -const config = require('../config/speechConfig.js'); -const { logLevel } = config.logging; -require('../config/loggerConfig.js')(logger, logLevel); +require('../helpers/configureLogger.js')(logger); const userName = process.argv[2]; logger.debug('user name:', userName); diff --git a/views/embed.handlebars b/server/views/embed.handlebars similarity index 100% rename from views/embed.handlebars rename to server/views/embed.handlebars diff --git a/views/layouts/embed.handlebars b/server/views/layouts/embed.handlebars similarity index 100% rename from views/layouts/embed.handlebars rename to server/views/layouts/embed.handlebars diff --git a/views/partials/maintenanceBanner.handlebars b/server/views/partials/maintenanceBanner.handlebars similarity index 100% rename from views/partials/maintenanceBanner.handlebars rename to server/views/partials/maintenanceBanner.handlebars diff --git a/views/partials/progressBar.handlebars b/server/views/partials/progressBar.handlebars similarity index 100% rename from views/partials/progressBar.handlebars rename to server/views/partials/progressBar.handlebars diff --git a/test/end-to-end/end-to-end.tests.js b/test/end-to-end/end-to-end.tests.js index f6ed4bc4..0c206c39 100644 --- a/test/end-to-end/end-to-end.tests.js +++ b/test/end-to-end/end-to-end.tests.js @@ -1,9 +1,8 @@ const chai = require('chai'); const expect = chai.expect; const chaiHttp = require('chai-http'); -const { site, testing } = require('../../config/speechConfig.js'); -const { host } = site; -const { testChannel, testChannelId, testChannelPassword } = testing; +const { details: { host } } = require('../../config/siteConfig.js'); +const { testChannel, testChannelId, testChannelPassword } = require('../../devConfig/testingConfig.js'); const requestTimeout = 20000; const publishTimeout = 120000; const fs = require('fs'); diff --git a/test/unit/publishHelpers.test.js b/test/unit/publishHelpers.test.js index 358e989a..c522b487 100644 --- a/test/unit/publishHelpers.test.js +++ b/test/unit/publishHelpers.test.js @@ -2,7 +2,7 @@ const chai = require('chai'); const expect = chai.expect; describe('publishHelpers.js', function () { - const publishHelpers = require('../../helpers/publishHelpers.js'); + const publishHelpers = require('../../server/helpers/publishHelpers.js'); describe('#parsePublishApiRequestBody()', function () { it('should throw an error if no body', function () { diff --git a/webpack.client.common.js b/webpack.client.common.js index 27ab2730..8370a688 100644 --- a/webpack.client.common.js +++ b/webpack.client.common.js @@ -1,9 +1,9 @@ const Path = require('path'); -const REACT_ROOT = Path.resolve(__dirname, 'react/'); +const CLIENT_ROOT = Path.resolve(__dirname, 'client/'); module.exports = { target: 'web', - entry : ['babel-polyfill', 'whatwg-fetch', './react/client.js'], + entry : ['babel-polyfill', 'whatwg-fetch', './client/client.js'], output: { path : Path.join(__dirname, 'public/bundle/'), publicPath: 'public/bundle/', @@ -23,7 +23,7 @@ module.exports = { }, resolve: { modules: [ - REACT_ROOT, + CLIENT_ROOT, 'node_modules', __dirname, ], diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 00000000..efcdc0b7 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,7 @@ +const serverBaseConfig = require('./webpack.server.common.js'); +const clientBaseConfig = require('./webpack.client.common.js'); + +module.exports = [ + serverBaseConfig, + clientBaseConfig, +]; diff --git a/webpack.dev.client.js b/webpack.dev.client.js new file mode 100644 index 00000000..ad9be8bc --- /dev/null +++ b/webpack.dev.client.js @@ -0,0 +1,11 @@ +const clientBaseConfig = require('./webpack.client.common.js'); +const merge = require('webpack-merge'); + +const devBuildConfig = { + watch : true, + devtool: 'inline-source-map', +}; + +module.exports = [ + merge(clientBaseConfig, devBuildConfig), +]; diff --git a/webpack.dev.server.js b/webpack.dev.server.js new file mode 100644 index 00000000..b8c812e3 --- /dev/null +++ b/webpack.dev.server.js @@ -0,0 +1,11 @@ +const serverBaseConfig = require('./webpack.server.common.js'); +const merge = require('webpack-merge'); + +const devBuildConfig = { + watch : true, + devtool: 'inline-source-map', +}; + +module.exports = [ + merge(serverBaseConfig, devBuildConfig), +]; diff --git a/webpack.server.common.js b/webpack.server.common.js index e5627ffc..6d21cdd8 100644 --- a/webpack.server.common.js +++ b/webpack.server.common.js @@ -1,6 +1,6 @@ const Path = require('path'); const nodeExternals = require('webpack-node-externals'); -const REACT_ROOT = Path.resolve(__dirname, 'react/'); +const CLIENT_ROOT = Path.resolve(__dirname, 'client/'); module.exports = { target: 'node', @@ -8,11 +8,13 @@ module.exports = { __dirname: false, }, externals: [nodeExternals()], - entry : ['babel-polyfill', 'whatwg-fetch', './index.js'], + entry : ['babel-polyfill', 'whatwg-fetch', './server.js'], output : { - path : Path.join(__dirname, '/'), - publicPath: '/', - filename : 'server.js', + path : Path.join(__dirname, '/'), + publicPath : '/', + filename : 'index.js', + library : '', + libraryTarget: 'commonjs-module', }, module: { rules: [ @@ -32,7 +34,7 @@ module.exports = { }, resolve: { modules: [ - REACT_ROOT, + CLIENT_ROOT, 'node_modules', __dirname, ],