react-image-lightbox
Version:
A lightbox component for React.js
727 lines (618 loc) • 79.9 kB
JavaScript
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var toolbarHeight = '50px';
var styles = {
outer: {
backgroundColor: 'rgba(0, 0, 0, 0.85)',
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 1000,
width: '100%',
height: '100%',
animating: function animating(duration) {
return {
transition: 'opacity ' + String(duration) + 'ms'
};
}
},
outerClosing: {
opacity: 0
},
inner: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0
},
image: {
position: 'absolute',
top: 0,
bottom: 0,
margin: 'auto',
maxWidth: '100%',
maxHeight: '100%'
},
imagePrev: {
left: '-100%',
right: '100%'
},
imageNext: {
left: '100%',
right: '-100%'
},
imageCurrent: {
left: 0,
right: 0
},
imageDiscourager: {
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
backgroundSize: 'contain'
},
imageAnimating: function imageAnimating(duration) {
return {
transition: ['left ' + String(duration) + 'ms', 'right ' + String(duration) + 'ms'].join(', ')
};
},
navButtons: {
border: 'none',
position: 'absolute',
top: 0,
bottom: 0,
width: '20px',
height: '34px',
padding: '40px 40px',
margin: 'auto',
cursor: 'pointer',
opacity: 0.7,
':hover': {
opacity: 1
},
':active': {
opacity: 0.7
}
},
navButtonPrev: {
left: 0,
background: 'url(\'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjM0Ij48cGF0aCBkPSJtIDE5LDMgLTIsLTIgLTE2LDE2IDE2LDE2IDEsLTEgLTE1LC0xNSAxNSwtMTUgeiIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==\') no-repeat center'
},
navButtonNext: {
right: 0,
background: 'url(\'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjM0Ij48cGF0aCBkPSJtIDEsMyAyLC0yIDE2LDE2IC0xNiwxNiAtMSwtMSAxNSwtMTUgLTE1LC0xNSB6IiBmaWxsPSIjRkZGIi8+PC9zdmc+\') no-repeat center'
},
downloadBlocker: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundImage: 'url(\'../img/please-use-download-button.gif\')',
backgroundSize: 'cover'
},
toolbar: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
position: 'absolute',
left: 0,
top: 0,
right: 0,
height: toolbarHeight
},
toolbarSide: {
lineHeight: toolbarHeight,
position: 'absolute',
top: 0,
bottom: 0,
margin: 0,
maxWidth: '48%'
},
toolbarLeftSide: {
paddingLeft: '20px',
paddingRight: 0,
left: 0
},
toolbarRightSide: {
paddingLeft: 0,
paddingRight: '20px',
right: 0
},
toolbarItem: {
display: 'inline-block',
lineHeight: toolbarHeight,
padding: '0 6px',
color: '#FFFFFF',
fontSize: '120%',
maxWidth: '100%',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
},
toolbarItemChild: {
verticalAlign: 'middle'
},
closeButton: {
width: '25px',
height: '25px',
cursor: 'pointer',
border: 'none',
background: 'url(\'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48cGF0aCBkPSJtIDEsMyAxLjI1LC0xLjI1IDcuNSw3LjUgNy41LC03LjUgMS4yNSwxLjI1IC03LjUsNy41IDcuNSw3LjUgLTEuMjUsMS4yNSAtNy41LC03LjUgLTcuNSw3LjUgLTEuMjUsLTEuMjUgNy41LC03LjUgLTcuNSwtNy41IHoiIGZpbGw9IiNGRkYiLz48L3N2Zz4=\') no-repeat center',
':hover': {
opacity: 0.7
},
':active': {
outline: 'none'
}
}
};
module.exports = styles;
},{}],"react-image-lightbox":[function(require,module,exports){
/*
* react-image-lightbox 1.0.0
* Copyright 2016 Chris Fritz All rights reserved.
* @license Open source under the MIT License
*/
'use strict';
var React = require('react');
var radium = require('radium');
var styles = require('./styles');
var ReactImageLightbox = React.createClass({
displayName: 'ReactImageLightbox',
propTypes: {
///////////////////////////////
// Image sources
///////////////////////////////
// Main display image url
mainSrc: React.PropTypes.string.isRequired,
// Previous display image url (displayed to the left)
// If left undefined, movePrev actions will not be performed, and the button not displayed
prevSrc: React.PropTypes.string,
// Next display image url (displayed to the right)
// If left undefined, moveNext actions will not be performed, and the button not displayed
nextSrc: React.PropTypes.string,
///////////////////////////////
// Image thumbnail sources
///////////////////////////////
// Thumbnail image url corresponding to props.mainSrc
mainSrcThumbnail: React.PropTypes.string,
// Thumbnail image url corresponding to props.prevSrc
prevSrcThumbnail: React.PropTypes.string,
// Thumbnail image url corresponding to props.nextSrc
nextSrcThumbnail: React.PropTypes.string,
///////////////////////////////
// Event Handlers
///////////////////////////////
// Close window event
// Should change the parent state such that the lightbox is not rendered
onCloseRequest: React.PropTypes.func.isRequired,
// Move to previous image event
// Should change the parent state such that props.prevSrc becomes props.mainSrc,
// props.mainSrc becomes props.nextSrc, etc.
onMovePrevRequest: React.PropTypes.func,
// Move to next image event
// Should change the parent state such that props.nextSrc becomes props.mainSrc,
// props.mainSrc becomes props.prevSrc, etc.
onMoveNextRequest: React.PropTypes.func,
///////////////////////////////
// Download discouragement settings
///////////////////////////////
// Enable download discouragement (prevents [right-click -> Save Image As...])
discourageDownloads: React.PropTypes.bool,
///////////////////////////////
// Animation settings
///////////////////////////////
// Disable all animation
animationDisabled: React.PropTypes.bool,
// Disable animation on actions performed with keyboard shortcuts
animationOnKeyInput: React.PropTypes.bool,
// Animation duration (ms)
animationDuration: React.PropTypes.number,
///////////////////////////////
// Keyboard shortcut settings
///////////////////////////////
// Required interval of time (ms) between key actions
// (prevents excessively fast navigation of images)
keyRepeatLimit: React.PropTypes.number,
// Amount of time (ms) restored after each keyup
// (makes rapid key presses slightly faster than holding down the key to navigate images)
keyRepeatKeyupBonus: React.PropTypes.number,
///////////////////////////////
// Image info
///////////////////////////////
// Image title
imageTitle: React.PropTypes.string,
///////////////////////////////
// Other
///////////////////////////////
// Array of custom toolbar buttons
toolbarButtons: React.PropTypes.arrayOf(React.PropTypes.node),
// Padding (px) between the edge of the window and the lightbox
imagePadding: React.PropTypes.number
},
getDefaultProps: function getDefaultProps() {
return {
onMovePrevRequest: function onMovePrevRequest() {},
onMoveNextRequest: function onMoveNextRequest() {},
discourageDownloads: false,
animationDisabled: false,
animationOnKeyInput: false,
animationDuration: 300,
keyRepeatLimit: 180,
keyRepeatKeyupBonus: 40,
imagePadding: 10
};
},
getInitialState: function getInitialState() {
return {
///////////////////////////////
// Animation
///////////////////////////////
// Lightbox is closing
// When Lightbox is mounted, if animation is enabled it will open with the reverse of the closing animation
isClosing: !this.props.animationDisabled,
// Main image is being replaced by the previous image
isMovingToPrev: false,
// Main image is being replaced by the next image
isMovingToNext: false
};
},
componentWillMount: function componentWillMount() {
// Whether event listeners for keyboard and mouse input have been attached or not
this.listenersAttached = false;
// Used to disable animation when changing props.mainSrc|nextSrc|prevSrc
this.keyPressed = false;
// Used to store load state / dimensions of images
this.imageCache = {};
// Time the last keydown event was called (used in keyboard action rate limiting)
this.lastKeyDownTime = 0;
},
componentDidMount: function componentDidMount() {
this.attachListeners();
if (!this.props.animationDisabled) {
// Make opening animation play
this.setState({ isClosing: false });
}
this.loadAllImages();
},
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
var sourcesChanged = this.getSrcTypes().some((function (srcType) {
return this.props[srcType] != nextProps[srcType];
}).bind(this));
if (sourcesChanged) {
// Enable animated states
if (!this.props.animationDisabled && (!this.keyPressed || this.props.animationOnKeyInput)) {
var movedToPrev = this.props.mainSrc == nextProps.nextSrc;
if (this.props.mainSrc == nextProps.nextSrc) {
this.setState({ isMovingToPrev: true });
setTimeout((function () {
this.setState({ isMovingToPrev: false });
}).bind(this), this.props.animationDuration);
} else if (this.props.mainSrc == nextProps.prevSrc) {
this.setState({ isMovingToNext: true });
setTimeout((function () {
this.setState({ isMovingToNext: false });
}).bind(this), this.props.animationDuration);
}
}
this.keyPressed = false;
// Load any new images
this.loadAllImages(nextProps);
}
},
componentWillUnmount: function componentWillUnmount() {
this.detachListeners();
},
// Handle user keyboard actions
handleKeyInput: function handleKeyInput(event) {
event.stopPropagation();
// Ignore key input during animations
if (this.isAnimating()) {
return;
}
// Allow slightly faster navigation through the images when user presses keys repeatedly
if (event.type === 'keyup') {
this.lastKeyDownTime -= this.props.keyRepeatKeyupBonus;
return;
}
var keyCode = event.which || event.keyCode;
var key = {
esc: 27,
leftArrow: 37,
rightArrow: 39
};
// Ignore key presses that happen too close to each other (when rapid fire key pressing or holding down the key)
// But allow it if it's a lightbox closing action
var currentTime = new Date();
if (currentTime.getTime() - this.lastKeyDownTime < this.props.keyRepeatLimit && keyCode != key.esc) {
return;
}
this.lastKeyDownTime = currentTime.getTime();
switch (keyCode) {
// ESC key closes the lightbox
case key.esc:
event.preventDefault();
if (this.props.animationDisabled || !this.props.animationOnKeyInput) {
this.props.onCloseRequest(event); // immediate
} else {
this.requestClose(event); // animated
}
break;
// Left arrow key moves to previous image
case key.leftArrow:
if (!this.props.prevSrc) {
return;
}
event.preventDefault();
this.keyPressed = true;
this.props.onMovePrevRequest(event);
break;
// Right arrow key moves to next image
case key.rightArrow:
if (!this.props.nextSrc) {
return;
}
event.preventDefault();
this.keyPressed = true;
this.props.onMoveNextRequest(event);
break;
default:
}
},
// Request that the lightbox be closed
requestClose: function requestClose(event) {
var closeLightbox = (function () {
// Call the parent close request
this.props.onCloseRequest(event);
}).bind(this);
if (!this.props.animationDisabled) {
// Start closing animation
this.setState({ isClosing: true });
// Perform the actual closing at the end of the animation
setTimeout(closeLightbox, this.props.animationDuration);
} else {
closeLightbox();
}
},
// Request to transition to the previous image
requestMovePrev: function requestMovePrev(event) {
this.props.onMovePrevRequest(event);
},
// Request to transition to the next image
requestMoveNext: function requestMoveNext(event) {
this.props.onMoveNextRequest(event);
},
// Attach key and mouse input events
attachListeners: function attachListeners() {
if (!this.listenersAttached) {
document.addEventListener('keydown', this.handleKeyInput);
document.addEventListener('keyup', this.handleKeyInput);
this.listenersAttached = true;
}
},
// Detach key and mouse input events
detachListeners: function detachListeners() {
if (this.listenersAttached) {
document.removeEventListener('keydown', this.handleKeyInput);
document.removeEventListener('keyup', this.handleKeyInput);
this.listenersAttached = false;
}
},
// Get image src types
getSrcTypes: function getSrcTypes() {
return ['mainSrc', 'mainSrcThumbnail', 'nextSrc', 'nextSrcThumbnail', 'prevSrc', 'prevSrcThumbnail'];
},
// Get sizing for when an image is larger than the window
getFitSizes: function getFitSizes(width, height) {
var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var maxHeight = Math.min(windowHeight - this.props.imagePadding * 2, height);
var maxWidth = Math.min(windowWidth - this.props.imagePadding * 2, width);
var maxRatio = maxWidth / maxHeight;
var srcRatio = width / height;
var fitSizes = {};
if (maxRatio > srcRatio) {
// height is the constraining dimension of the photo
fitSizes.width = width * maxHeight / height;
fitSizes.height = maxHeight;
} else {
fitSizes.width = maxWidth;
fitSizes.height = height * maxWidth / width;
}
return fitSizes;
},
// Detach key and mouse input events
isAnimating: function isAnimating() {
return this.state.isMovingToNext || this.state.isMovingToPrev || this.state.isClosing;
},
// Load image from src and call callback with image width and height on load
loadImage: function loadImage(imageSrc, callback) {
// Return the image info if it is already cached
if (this.isImageLoaded(imageSrc)) {
setTimeout(function () {
callback(null, this.imageCache[imageSrc].width, this.imageCache[imageSrc].height);
}, 1);
return;
}
var that = this;
var inMemoryImage = new Image();
inMemoryImage.onerror = function () {
callback('image load error');
};
inMemoryImage.onload = function () {
that.imageCache[imageSrc] = {
loaded: true,
width: this.width,
height: this.height
};
callback(null, this.width, this.height);
};
inMemoryImage.src = imageSrc;
},
// Load all images and their thumbnails
loadAllImages: function loadAllImages(props) {
props = props || this.props;
var generateImageLoadedCallback = (function (srcType, imageSrc) {
return (function (err) {
// Give up showing image on error
if (err) {
return;
}
// Don't rerender if the src is not the same as when the load started
if (this.props[srcType] != imageSrc) {
return;
}
// Force rerender with the new image
this.forceUpdate();
}).bind(this);
}).bind(this);
// Load the images
this.getSrcTypes().forEach((function (srcType) {
// Load unloaded images
if (props[srcType] && !this.isImageLoaded(props[srcType])) {
this.loadImage(props[srcType], generateImageLoadedCallback(srcType, props[srcType]));
}
}).bind(this));
},
// Load image from src and call callback with image width and height on load
isImageLoaded: function isImageLoaded(imageSrc) {
return imageSrc && imageSrc in this.imageCache && this.imageCache[imageSrc].loaded;
},
render: function render() {
// Transition settings for sliding animations
var transitionStyle = {};
if (!this.props.animationDisabled && this.isAnimating()) {
transitionStyle = styles.imageAnimating(this.props.animationDuration);
}
// Images to be displayed
var images = [];
var addImage = (function (srcType, imageClass, baseStyle) {
var imageSrc = this.props[srcType];
if (!imageSrc) {
return;
}
var imageStyle = [styles.image, baseStyle, transitionStyle];
var fitSizes = {};
if (this.isImageLoaded(imageSrc)) {
fitSizes = this.getFitSizes(this.imageCache[imageSrc].width, this.imageCache[imageSrc].height);
} else if (this.isImageLoaded(this.props[srcType + 'Thumbnail'])) {
// Fall back to using thumbnail if the image has not been loaded
imageSrc = this.props[srcType + 'Thumbnail'];
fitSizes = this.getFitSizes(this.imageCache[imageSrc].width, this.imageCache[imageSrc].height);
} else {
// Fall back to loading icon if the thumbnail has not been loaded
images.push(React.createElement('div', {
className: imageClass + ' not-loaded',
style: imageStyle,
key: imageSrc
}));
return;
}
imageStyle.push({
width: fitSizes.width,
height: fitSizes.height
});
if (this.props.discourageDownloads) {
imageStyle.push({ backgroundImage: 'url(\'' + imageSrc + '\')' });
imageStyle.push(styles.imageDiscourager);
images.push(React.createElement(
'div',
{
className: imageClass,
style: imageStyle,
key: imageSrc
},
React.createElement('div', { className: 'download-blocker', style: [styles.image.downloadBlocker] })
));
} else {
images.push(React.createElement('img', {
className: imageClass,
style: imageStyle,
src: imageSrc,
key: imageSrc
}));
}
}).bind(this);
// Next Image (displayed on the right)
addImage('nextSrc', 'image-next', styles.imageNext);
// Main Image
addImage('mainSrc', 'image-current', styles.imageCurrent);
// Previous Image (displayed on the left)
addImage('prevSrc', 'image-prev', styles.imagePrev);
var noop = function noop() {};
return React.createElement(
'div',
{ // Floating modal with closing animations
className: "outer" + (this.state.isClosing ? ' closing' : ''),
style: [styles.outer, styles.outer.animating(this.props.animationDuration), this.state.isClosing ? styles.outerClosing : {}]
},
React.createElement(
'div',
{ // Image holder
className: 'inner',
style: [styles.inner]
},
images
),
!this.props.prevSrc ? '' : React.createElement('button', { // Move to previous image button
type: 'button',
className: 'prev-button',
key: 'prev',
style: [styles.navButtons, styles.navButtonPrev],
onClick: !this.isAnimating() ? this.requestMovePrev : noop // Ignore clicks during animation
}),
!this.props.nextSrc ? '' : React.createElement('button', { // Move to next image button
type: 'button',
className: 'next-button',
key: 'next',
style: [styles.navButtons, styles.navButtonNext],
onClick: !this.isAnimating() ? this.requestMoveNext : noop // Ignore clicks during animation
}),
React.createElement(
'div',
{ // Lightbox toolbar
className: 'toolbar',
style: [styles.toolbar]
},
React.createElement(
'ul',
{ className: 'toolbar-left', style: [styles.toolbarSide, styles.toolbarLeftSide] },
React.createElement(
'li',
{ style: [styles.toolbarItem] },
React.createElement(
'span',
{ style: [styles.toolbarItemChild] },
this.props.imageTitle
)
)
),
React.createElement(
'ul',
{ className: 'toolbar-right', style: [styles.toolbarSide, styles.toolbarRightSide] },
!this.props.toolbarButtons ? '' : this.props.toolbarButtons.map(function (button, i) {
return React.createElement(
'li',
{ key: i, style: [styles.toolbarItem] },
button
);
}),
React.createElement(
'li',
{ style: [styles.toolbarItem] },
React.createElement('button', { // Lightbox close button
type: 'button',
className: 'close',
style: [styles.toolbarItemChild, styles.closeButton],
onClick: !this.isAnimating() ? this.requestClose : noop // Ignore clicks during animation
})
)
)
)
);
}
});
module.exports = radium(ReactImageLightbox);
},{"./styles":1,"radium":undefined,"react":undefined}]},{},[])
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9yZWFjdC1jb21wb25lbnQtZ3VscC10YXNrcy9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiL1VzZXJzL2ZyaXR6LmNocmlzdG9waGVyL1dvcmsvcmVhY3QtaW1hZ2UtbGlnaHRib3gvc3JjL3N0eWxlcy5qcyIsIi9Vc2Vycy9mcml0ei5jaHJpc3RvcGhlci9Xb3JrL3JlYWN0LWltYWdlLWxpZ2h0Ym94L3NyYy9SZWFjdEltYWdlTGlnaHRib3guanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztBQ0FBLElBQUksYUFBYSxHQUFHLE1BQU0sQ0FBQztBQUMzQixJQUFJLE1BQU0sR0FBRztBQUNULFNBQUssRUFBRTtBQUNILHVCQUFlLEVBQUcscUJBQXFCO0FBQ3ZDLGdCQUFRLEVBQVUsT0FBTztBQUN6QixXQUFHLEVBQWUsQ0FBQztBQUNuQixZQUFJLEVBQWMsQ0FBQztBQUNuQixhQUFLLEVBQWEsQ0FBQztBQUNuQixjQUFNLEVBQVksQ0FBQztBQUNuQixjQUFNLEVBQVksSUFBSTtBQUN0QixhQUFLLEVBQWEsTUFBTTtBQUN4QixjQUFNLEVBQVksTUFBTTs7QUFFeEIsaUJBQVMsRUFBRSxtQkFBUyxRQUFRLEVBQUU7QUFDMUIsbUJBQU87QUFDSCwwQkFBVSxFQUFFLFVBQVUsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSTthQUNuRCxDQUFDO1NBQ0w7S0FDSjtBQUNELGdCQUFZLEVBQUU7QUFDVixlQUFPLEVBQUUsQ0FBQztLQUNiO0FBQ0QsU0FBSyxFQUFFO0FBQ0gsZ0JBQVEsRUFBRyxVQUFVO0FBQ3JCLFdBQUcsRUFBUSxDQUFDO0FBQ1osWUFBSSxFQUFPLENBQUM7QUFDWixhQUFLLEVBQU0sQ0FBQztBQUNaLGNBQU0sRUFBSyxDQUFDO0tBQ2Y7O0FBRUQsU0FBSyxFQUFFO0FBQ0gsZ0JBQVEsRUFBSyxVQUFVO0FBQ3ZCLFdBQUcsRUFBVSxDQUFDO0FBQ2QsY0FBTSxFQUFPLENB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Um9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwidmFyIHRvb2xiYXJIZWlnaHQgPSAnNTBweCc7XG52YXIgc3R5bGVzID0ge1xuICAgIG91dGVyOiB7XG4gICAgICAgIGJhY2tncm91bmRDb2xvciA6ICdyZ2JhKDAsIDAsIDAsIDAuODUpJyxcbiAgICAgICAgcG9zaXRpb24gICAgICAgIDogJ2ZpeGVkJyxcbiAgICAgICAgdG9wICAgICAgICAgICAgIDogMCxcbiAgICAgICAgbGVmdCAgICAgICAgICAgIDogMCxcbiAgICAgICAgcmlnaHQgICAgICAgICAgIDogMCxcbiAgICAgICAgYm90dG9tICAgICAgICAgIDogMCxcbiAgICAgICAgekluZGV4ICAgICAgICAgIDogMTAwMCxcbiAgICAgICAgd2lkdGggICAgICAgICAgIDogJzEwMCUnLFxuICAgICAgICBoZWlnaHQgICAgICAgICAgOiAnMTAwJScsXG5cbiAgICAgICAgYW5pbWF0aW5nOiBmdW5jdGlvbihkdXJhdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0cmFuc2l0aW9uOiAnb3BhY2l0eSAnICsgU3RyaW5nKGR1cmF0aW9uKSArICdtcycsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgIH0sXG4gICAgb3V0ZXJDbG9zaW5nOiB7XG4gICAgICAgIG9wYWNpdHk6IDAsXG4gICAgfSxcbiAgICBpbm5lcjoge1xuICAgICAgICBwb3NpdGlvbiA6ICdhYnNvbHV0ZScsXG4gICAgICAgIHRvcCAgICAgIDogMCxcbiAgICAgICAgbGVmdCAgICAgOiAwLFxuICAgICAgICByaWdodCAgICA6IDAsXG4gICAgICAgIGJvdHRvbSAgIDogMCxcbiAgICB9LFxuXG4gICAgaW1hZ2U6IHtcbiAgICAgICAgcG9zaXRpb24gICA6ICdhYnNvbHV0ZScsXG4gICAgICAgIHRvcCAgICAgICAgOiAwLFxuICAgICAgICBib3R0b20gICAgIDogMCxcbiAgICAgICAgbWFyZ2luICAgICA6ICdhdXRvJyxcbiAgICAgICAgbWF4V2lkdGggICA6ICcxMDAlJyxcbiAgICAgICAgbWF4SGVpZ2h0ICA6ICcxMDAlJyxcbiAgICB9LFxuICAgIGltYWdlUHJldjoge1xuICAgICAgICBsZWZ0OiAnLTEwMCUnLFxuICAgICAgICByaWdodDogJzEwMCUnLFxuICAgIH0sXG4gICAgaW1hZ2VOZXh0OiB7XG4gICAgICAgIGxlZnQ6ICcxMDAlJyxcbiAgICAgICAgcmlnaHQ6ICctMTAwJScsXG4gICAgfSxcbiAgICBpbWFnZUN1cnJlbnQ6IHtcbiAgICAgICAgbGVmdDogMCxcbiAgICAgICAgcmlnaHQ6IDAsXG4gICAgfSxcbiAgICBpbWFnZURpc2NvdXJhZ2VyOiB7XG4gICAgICAgIGJhY2tncm91bmRSZXBlYXQgICA6ICduby1yZXBlYXQnLFxuICAgICAgICBiYWNrZ3JvdW5kUG9zaXRpb24gOiAnY2VudGVyJyxcbiAgICAgICAgYmFja2dyb3VuZFNpemUgICAgIDogJ2NvbnRhaW4nLFxuICAgIH0sXG4gICAgaW1hZ2VBbmltYXRpbmc6IGZ1bmN0aW9uKGR1cmF0aW9uKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0cmFuc2l0aW9uOiBbXG4gICAgICAgICAgICAgICAgJ2xlZnQgJyAgKyBTdHJpbmcoZHVyYXRpb24pICsgJ21zJyxcbiAgICAgICAgICAgICAgICAncmlnaHQgJyArIFN0cmluZyhkdXJhdGlvbikgKyAnbXMnLFxuICAgICAgICAgICAgXS5qb2luKCcsICcpLFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBuYXZCdXR0b25zOiB7XG4gICAgICAgIGJvcmRlciAgIDogJ25vbmUnLFxuICAgICAgICBwb3NpdGlvbiA6ICdhYnNvbHV0ZScsXG4gICAgICAgIHRvcCAgICAgIDogMCxcbiAgICAgICAgYm90dG9tICAgOiAwLFxuICAgICAgICB3aWR0aCAgICA6ICcyMHB4JyxcbiAgICAgICAgaGVpZ2h0ICAgOiAnMzRweCcsXG4gICAgICAgIHBhZGRpbmcgIDogJzQwcHggNDBweCcsXG4gICAgICAgIG1hcmdpbiAgIDogJ2F1dG8nLFxuICAgICAgICBjdXJzb3IgICA6ICdwb2ludGVyJyxcbiAgICAgICAgb3BhY2l0eSAgOiAwLjcsXG5cbiAgICAgICAgJzpob3Zlcic6IHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgIH0sXG5cbiAgICAgICAgJzphY3RpdmUnOiB7XG4gICAgICAgICAgICBvcGFjaXR5OiAwLjcsXG4gICAgICAgIH0sXG4gICAgfSxcbiAgICBuYXZCdXR0b25QcmV2OiB7XG4gICAgICAgIGxlZnQgICAgICAgOiAwLFxuICAgICAgICBiYWNrZ3JvdW5kIDogJ3VybChcXCdkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSFpsY25OcGIyNDlJakV1TVNJZ2QybGtkR2c5SWpJd0lpQm9aV2xuYUhROUlqTTBJajQ4Y0dGMGFDQmtQU0p0SURFNUxETWdMVElzTFRJZ0xURTJMREUySURFMkxERTJJREVzTFRFZ0xURTFMQzB4TlNBeE5Td3RNVFVnZWlJZ1ptbHNiRDBpSTBaR1JpSXZQand2YzNablBnPT1cXCcpIG5vLXJlcGVhdCBjZW50ZXInLFxuICAgIH0sXG4gICAgbmF2QnV0dG9uTmV4dDoge1xuICAgICAgICByaWdodCAgICAgIDogMCxcbiAgICAgICAgYmFja2dyb3VuZCA6ICd1cmwoXFwnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUhabGNuTnBiMjQ5SWpFdU1TSWdkMmxrZEdnOUlqSXdJaUJvWldsbmFIUTlJak0wSWo0OGNHRjBhQ0JrUFNKdElERXNNeUF5TEMweUlERTJMREUySUMweE5pd3hOaUF0TVN3dE1TQXhOU3d0TVRVZ0xURTFMQzB4TlNCNklpQm1hV3hzUFNJalJrWkdJaTgrUEM5emRtYytcXCcpIG5vLXJlcGVhdCBjZW50ZXInLFxuICAgIH0sXG5cbiAgICBkb3dubG9hZEJsb2NrZXI6IHtcbiAgICAgICAgcG9zaXRpb24gICAgICAgIDogJ2Fic29sdXRlJyxcbiAgICAgICAgdG9wICAgICAgICAgICAgIDogMCxcbiAgICAgICAgbGVmdCAgICAg