| | |
| | | /* |
| | | react-datetime v2.6.2 |
| | | https://github.com/arqex/react-datetime |
| | | MIT: https://github.com/arqex/react-datetime/raw/master/LICENSE |
| | | react-datetime v2.14.0 |
| | | https://github.com/YouCanBookMe/react-datetime |
| | | MIT: https://github.com/YouCanBookMe/react-datetime/raw/master/LICENSE |
| | | */ |
| | | (function webpackUniversalModuleDefinition(root, factory) { |
| | | if(typeof exports === 'object' && typeof module === 'object') |
| | |
| | | exports["Datetime"] = factory(require("React"), require("moment"), require("ReactDOM")); |
| | | else |
| | | root["Datetime"] = factory(root["React"], root["moment"], root["ReactDOM"]); |
| | | })(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_9__) { |
| | | })(this, function(__WEBPACK_EXTERNAL_MODULE_13__, __WEBPACK_EXTERNAL_MODULE_17__, __WEBPACK_EXTERNAL_MODULE_21__) { |
| | | return /******/ (function(modules) { // webpackBootstrap |
| | | /******/ // The module cache |
| | | /******/ var installedModules = {}; |
| | |
| | | /************************************************************************/ |
| | | /******/ ([ |
| | | /* 0 */ |
| | | /***/ function(module, exports, __webpack_require__) { |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | 'use strict'; |
| | | |
| | | var assign = __webpack_require__(1), |
| | | React = __webpack_require__(2), |
| | | DaysView = __webpack_require__(3), |
| | | MonthsView = __webpack_require__(5), |
| | | YearsView = __webpack_require__(6), |
| | | TimeView = __webpack_require__(7), |
| | | moment = __webpack_require__(4) |
| | | ; |
| | | PropTypes = __webpack_require__(2), |
| | | createClass = __webpack_require__(12), |
| | | moment = __webpack_require__(17), |
| | | React = __webpack_require__(13), |
| | | CalendarContainer = __webpack_require__(18) |
| | | ; |
| | | |
| | | var TYPES = React.PropTypes; |
| | | var Datetime = React.createClass({ |
| | | mixins: [ |
| | | __webpack_require__(8) |
| | | ], |
| | | viewComponents: { |
| | | days: DaysView, |
| | | months: MonthsView, |
| | | years: YearsView, |
| | | time: TimeView |
| | | }, |
| | | var viewModes = Object.freeze({ |
| | | YEARS: 'years', |
| | | MONTHS: 'months', |
| | | DAYS: 'days', |
| | | TIME: 'time', |
| | | }); |
| | | |
| | | var TYPES = PropTypes; |
| | | var Datetime = createClass({ |
| | | propTypes: { |
| | | // value: TYPES.object | TYPES.string, |
| | | // defaultValue: TYPES.object | TYPES.string, |
| | | // viewDate: TYPES.object | TYPES.string, |
| | | onFocus: TYPES.func, |
| | | onBlur: TYPES.func, |
| | | onChange: TYPES.func, |
| | | onViewModeChange: TYPES.func, |
| | | locale: TYPES.string, |
| | | utc: TYPES.bool, |
| | | input: TYPES.bool, |
| | | // dateFormat: TYPES.string | TYPES.bool, |
| | | // timeFormat: TYPES.string | TYPES.bool, |
| | | inputProps: TYPES.object, |
| | | timeConstraints: TYPES.object, |
| | | viewMode: TYPES.oneOf(['years', 'months', 'days', 'time']), |
| | | viewMode: TYPES.oneOf([viewModes.YEARS, viewModes.MONTHS, viewModes.DAYS, viewModes.TIME]), |
| | | isValidDate: TYPES.func, |
| | | open: TYPES.bool, |
| | | strictParsing: TYPES.bool, |
| | | closeOnSelect: TYPES.bool, |
| | | closeOnTab: TYPES.bool |
| | | }, |
| | | |
| | | getDefaultProps: function() { |
| | | var nof = function(){}; |
| | | return { |
| | | className: '', |
| | | defaultValue: '', |
| | | inputProps: {}, |
| | | input: true, |
| | | onFocus: nof, |
| | | onBlur: nof, |
| | | onChange: nof, |
| | | timeFormat: true, |
| | | timeConstraints: {}, |
| | | dateFormat: true, |
| | | strictParsing: true, |
| | | closeOnSelect: false, |
| | | closeOnTab: true |
| | | }; |
| | | }, |
| | | |
| | | getInitialState: function() { |
| | |
| | | if ( state.open === undefined ) |
| | | state.open = !this.props.input; |
| | | |
| | | state.currentView = this.props.dateFormat ? (this.props.viewMode || state.updateOn || 'days') : 'time'; |
| | | state.currentView = this.props.dateFormat ? |
| | | (this.props.viewMode || state.updateOn || viewModes.DAYS) : viewModes.TIME; |
| | | |
| | | return state; |
| | | }, |
| | | |
| | | getStateFromProps: function( props ){ |
| | | parseDate: function (date, formats) { |
| | | var parsedDate; |
| | | |
| | | if (date && typeof date === 'string') |
| | | parsedDate = this.localMoment(date, formats.datetime); |
| | | else if (date) |
| | | parsedDate = this.localMoment(date); |
| | | |
| | | if (parsedDate && !parsedDate.isValid()) |
| | | parsedDate = null; |
| | | |
| | | return parsedDate; |
| | | }, |
| | | |
| | | getStateFromProps: function( props ) { |
| | | var formats = this.getFormats( props ), |
| | | date = props.value || props.defaultValue, |
| | | selectedDate, viewDate, updateOn, inputValue |
| | | ; |
| | | ; |
| | | |
| | | if ( date && typeof date === 'string' ) |
| | | selectedDate = this.localMoment( date, formats.datetime ); |
| | | else if ( date ) |
| | | selectedDate = this.localMoment( date ); |
| | | selectedDate = this.parseDate(date, formats); |
| | | |
| | | if ( selectedDate && !selectedDate.isValid() ) |
| | | selectedDate = null; |
| | | viewDate = this.parseDate(props.viewDate, formats); |
| | | |
| | | viewDate = selectedDate ? |
| | | selectedDate.clone().startOf('month') : |
| | | this.localMoment().startOf('month') |
| | | ; |
| | | viewDate ? viewDate.clone().startOf('month') : this.localMoment().startOf('month'); |
| | | |
| | | updateOn = this.getUpdateOn(formats); |
| | | |
| | |
| | | }; |
| | | }, |
| | | |
| | | getUpdateOn: function(formats){ |
| | | if ( formats.date.match(/[lLD]/) ){ |
| | | return 'days'; |
| | | } |
| | | else if ( formats.date.indexOf('M') !== -1 ){ |
| | | return 'months'; |
| | | } |
| | | else if ( formats.date.indexOf('Y') !== -1 ){ |
| | | return 'years'; |
| | | getUpdateOn: function( formats ) { |
| | | if ( formats.date.match(/[lLD]/) ) { |
| | | return viewModes.DAYS; |
| | | } else if ( formats.date.indexOf('M') !== -1 ) { |
| | | return viewModes.MONTHS; |
| | | } else if ( formats.date.indexOf('Y') !== -1 ) { |
| | | return viewModes.YEARS; |
| | | } |
| | | |
| | | return 'days'; |
| | | return viewModes.DAYS; |
| | | }, |
| | | |
| | | getFormats: function( props ){ |
| | | getFormats: function( props ) { |
| | | var formats = { |
| | | date: props.dateFormat || '', |
| | | time: props.timeFormat || '' |
| | | }, |
| | | locale = this.localMoment( props.date ).localeData() |
| | | ; |
| | | locale = this.localMoment( props.date, null, props ).localeData() |
| | | ; |
| | | |
| | | if ( formats.date === true ){ |
| | | if ( formats.date === true ) { |
| | | formats.date = locale.longDateFormat('L'); |
| | | } |
| | | else if ( this.getUpdateOn(formats) !== 'days' ){ |
| | | else if ( this.getUpdateOn(formats) !== viewModes.DAYS ) { |
| | | formats.time = ''; |
| | | } |
| | | |
| | | if ( formats.time === true ){ |
| | | if ( formats.time === true ) { |
| | | formats.time = locale.longDateFormat('LT'); |
| | | } |
| | | |
| | |
| | | return formats; |
| | | }, |
| | | |
| | | componentWillReceiveProps: function(nextProps) { |
| | | componentWillReceiveProps: function( nextProps ) { |
| | | var formats = this.getFormats( nextProps ), |
| | | update = {} |
| | | updatedState = {} |
| | | ; |
| | | |
| | | if ( nextProps.value !== this.props.value ){ |
| | | update = this.getStateFromProps( nextProps ); |
| | | } |
| | | if ( formats.datetime !== this.getFormats( this.props ).datetime ) { |
| | | update.inputFormat = formats.datetime; |
| | | if ( nextProps.value !== this.props.value || |
| | | formats.datetime !== this.getFormats( this.props ).datetime ) { |
| | | updatedState = this.getStateFromProps( nextProps ); |
| | | } |
| | | |
| | | if ( update.open === undefined ){ |
| | | if ( this.props.closeOnSelect && this.state.currentView !== 'time' ){ |
| | | update.open = false; |
| | | } |
| | | else { |
| | | update.open = this.state.open; |
| | | if ( updatedState.open === undefined ) { |
| | | if ( typeof nextProps.open !== 'undefined' ) { |
| | | updatedState.open = nextProps.open; |
| | | } else if ( this.props.closeOnSelect && this.state.currentView !== viewModes.TIME ) { |
| | | updatedState.open = false; |
| | | } else { |
| | | updatedState.open = this.state.open; |
| | | } |
| | | } |
| | | |
| | | this.setState( update ); |
| | | if ( nextProps.viewMode !== this.props.viewMode ) { |
| | | updatedState.currentView = nextProps.viewMode; |
| | | } |
| | | |
| | | if ( nextProps.locale !== this.props.locale ) { |
| | | if ( this.state.viewDate ) { |
| | | var updatedViewDate = this.state.viewDate.clone().locale( nextProps.locale ); |
| | | updatedState.viewDate = updatedViewDate; |
| | | } |
| | | if ( this.state.selectedDate ) { |
| | | var updatedSelectedDate = this.state.selectedDate.clone().locale( nextProps.locale ); |
| | | updatedState.selectedDate = updatedSelectedDate; |
| | | updatedState.inputValue = updatedSelectedDate.format( formats.datetime ); |
| | | } |
| | | } |
| | | |
| | | if ( nextProps.utc !== this.props.utc ) { |
| | | if ( nextProps.utc ) { |
| | | if ( this.state.viewDate ) |
| | | updatedState.viewDate = this.state.viewDate.clone().utc(); |
| | | if ( this.state.selectedDate ) { |
| | | updatedState.selectedDate = this.state.selectedDate.clone().utc(); |
| | | updatedState.inputValue = updatedState.selectedDate.format( formats.datetime ); |
| | | } |
| | | } else { |
| | | if ( this.state.viewDate ) |
| | | updatedState.viewDate = this.state.viewDate.clone().local(); |
| | | if ( this.state.selectedDate ) { |
| | | updatedState.selectedDate = this.state.selectedDate.clone().local(); |
| | | updatedState.inputValue = updatedState.selectedDate.format(formats.datetime); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if ( nextProps.viewDate !== this.props.viewDate ) { |
| | | updatedState.viewDate = moment(nextProps.viewDate); |
| | | } |
| | | //we should only show a valid date if we are provided a isValidDate function. Removed in 2.10.3 |
| | | /*if (this.props.isValidDate) { |
| | | updatedState.viewDate = updatedState.viewDate || this.state.viewDate; |
| | | while (!this.props.isValidDate(updatedState.viewDate)) { |
| | | updatedState.viewDate = updatedState.viewDate.add(1, 'day'); |
| | | } |
| | | }*/ |
| | | this.setState( updatedState ); |
| | | }, |
| | | |
| | | onInputChange: function( e ) { |
| | | var value = e.target === null ? e : e.target.value, |
| | | localMoment = this.localMoment( value, this.state.inputFormat ), |
| | | update = { inputValue: value } |
| | | ; |
| | | ; |
| | | |
| | | if ( localMoment.isValid() && !this.props.value ) { |
| | | update.selectedDate = localMoment; |
| | | update.viewDate = localMoment.clone().startOf('month'); |
| | | } |
| | | else { |
| | | } else { |
| | | update.selectedDate = null; |
| | | } |
| | | |
| | |
| | | }); |
| | | }, |
| | | |
| | | onInputKey: function( e ){ |
| | | if ( e.which === 9 && this.props.closeOnTab ){ |
| | | onInputKey: function( e ) { |
| | | if ( e.which === 9 && this.props.closeOnTab ) { |
| | | this.closeCalendar(); |
| | | } |
| | | }, |
| | | |
| | | showView: function( view ){ |
| | | showView: function( view ) { |
| | | var me = this; |
| | | return function(){ |
| | | return function() { |
| | | me.state.currentView !== view && me.props.onViewModeChange( view ); |
| | | me.setState({ currentView: view }); |
| | | }; |
| | | }, |
| | | |
| | | setDate: function( type ){ |
| | | setDate: function( type ) { |
| | | var me = this, |
| | | nextViews = { |
| | | month: 'days', |
| | | year: 'months' |
| | | month: viewModes.DAYS, |
| | | year: viewModes.MONTHS, |
| | | } |
| | | ; |
| | | return function( e ){ |
| | | return function( e ) { |
| | | me.setState({ |
| | | viewDate: me.state.viewDate.clone()[ type ]( parseInt(e.target.getAttribute('data-value'), 10) ).startOf( type ), |
| | | currentView: nextViews[ type ] |
| | | }); |
| | | me.props.onViewModeChange( nextViews[ type ] ); |
| | | }; |
| | | }, |
| | | |
| | | addTime: function( amount, type, toSelected ){ |
| | | addTime: function( amount, type, toSelected ) { |
| | | return this.updateTime( 'add', amount, type, toSelected ); |
| | | }, |
| | | |
| | | subtractTime: function( amount, type, toSelected ){ |
| | | subtractTime: function( amount, type, toSelected ) { |
| | | return this.updateTime( 'subtract', amount, type, toSelected ); |
| | | }, |
| | | |
| | | updateTime: function( op, amount, type, toSelected ){ |
| | | updateTime: function( op, amount, type, toSelected ) { |
| | | var me = this; |
| | | |
| | | return function(){ |
| | | return function() { |
| | | var update = {}, |
| | | date = toSelected ? 'selectedDate' : 'viewDate' |
| | | ; |
| | |
| | | }, |
| | | |
| | | allowedSetTime: ['hours', 'minutes', 'seconds', 'milliseconds'], |
| | | setTime: function( type, value ){ |
| | | setTime: function( type, value ) { |
| | | var index = this.allowedSetTime.indexOf( type ) + 1, |
| | | state = this.state, |
| | | date = (state.selectedDate || state.viewDate).clone(), |
| | | nextType |
| | | ; |
| | | ; |
| | | |
| | | // It is needed to set all the time properties |
| | | // to not to reset the time |
| | |
| | | date[ nextType ]( date[nextType]() ); |
| | | } |
| | | |
| | | if ( !this.props.value ){ |
| | | if ( !this.props.value ) { |
| | | this.setState({ |
| | | selectedDate: date, |
| | | inputValue: date.format( state.inputFormat ) |
| | |
| | | viewDate = this.state.viewDate, |
| | | currentDate = this.state.selectedDate || viewDate, |
| | | date |
| | | ; |
| | | ; |
| | | |
| | | if (target.className.indexOf('rdtDay') !== -1){ |
| | | if (target.className.indexOf('rdtDay') !== -1) { |
| | | if (target.className.indexOf('rdtNew') !== -1) |
| | | modifier = 1; |
| | | else if (target.className.indexOf('rdtOld') !== -1) |
| | |
| | | date = viewDate.clone() |
| | | .month( viewDate.month() + modifier ) |
| | | .date( parseInt( target.getAttribute('data-value'), 10 ) ); |
| | | } else if (target.className.indexOf('rdtMonth') !== -1){ |
| | | } else if (target.className.indexOf('rdtMonth') !== -1) { |
| | | date = viewDate.clone() |
| | | .month( parseInt( target.getAttribute('data-value'), 10 ) ) |
| | | .date( currentDate.date() ); |
| | | } else if (target.className.indexOf('rdtYear') !== -1){ |
| | | } else if (target.className.indexOf('rdtYear') !== -1) { |
| | | date = viewDate.clone() |
| | | .month( currentDate.month() ) |
| | | .date( currentDate.date() ) |
| | |
| | | .seconds( currentDate.seconds() ) |
| | | .milliseconds( currentDate.milliseconds() ); |
| | | |
| | | if ( !this.props.value ){ |
| | | if ( !this.props.value ) { |
| | | var open = !( this.props.closeOnSelect && close ); |
| | | if ( !open ) { |
| | | this.props.onBlur( date ); |
| | | } |
| | | |
| | | this.setState({ |
| | | selectedDate: date, |
| | | viewDate: date.clone().startOf('month'), |
| | | inputValue: date.format( this.state.inputFormat ), |
| | | open: !(this.props.closeOnSelect && close ) |
| | | open: open |
| | | }); |
| | | } else { |
| | | if (this.props.closeOnSelect && close) { |
| | | if ( this.props.closeOnSelect && close ) { |
| | | this.closeCalendar(); |
| | | } |
| | | } |
| | |
| | | this.props.onChange( date ); |
| | | }, |
| | | |
| | | openCalendar: function() { |
| | | if (!this.state.open) { |
| | | this.props.onFocus(); |
| | | this.setState({ open: true }); |
| | | openCalendar: function( e ) { |
| | | if ( !this.state.open ) { |
| | | this.setState({ open: true }, function() { |
| | | this.props.onFocus( e ); |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | closeCalendar: function() { |
| | | this.setState({ open: false }); |
| | | this.props.onBlur( this.state.selectedDate || this.state.inputValue ); |
| | | this.setState({ open: false }, function () { |
| | | this.props.onBlur( this.state.selectedDate || this.state.inputValue ); |
| | | }); |
| | | }, |
| | | |
| | | handleClickOutside: function(){ |
| | | if ( this.props.input && this.state.open && !this.props.open ){ |
| | | this.setState({ open: false }); |
| | | this.props.onBlur( this.state.selectedDate || this.state.inputValue ); |
| | | handleClickOutside: function() { |
| | | if ( this.props.input && this.state.open && !this.props.open && !this.props.disableOnClickOutside ) { |
| | | this.setState({ open: false }, function() { |
| | | this.props.onBlur( this.state.selectedDate || this.state.inputValue ); |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | localMoment: function( date, format ){ |
| | | var m = moment( date, format, this.props.strictParsing ); |
| | | if ( this.props.locale ) |
| | | m.locale( this.props.locale ); |
| | | localMoment: function( date, format, props ) { |
| | | props = props || this.props; |
| | | var momentFn = props.utc ? moment.utc : moment; |
| | | var m = momentFn( date, format, props.strictParsing ); |
| | | if ( props.locale ) |
| | | m.locale( props.locale ); |
| | | return m; |
| | | }, |
| | | |
| | | componentProps: { |
| | | fromProps: ['value', 'isValidDate', 'renderDay', 'renderMonth', 'renderYear', 'timeConstraints'], |
| | | fromState: ['viewDate', 'selectedDate', 'updateOn'], |
| | | fromThis: ['setDate', 'setTime', 'showView', 'addTime', 'subtractTime', 'updateSelectedDate', 'localMoment'] |
| | | fromThis: ['setDate', 'setTime', 'showView', 'addTime', 'subtractTime', 'updateSelectedDate', 'localMoment', 'handleClickOutside'] |
| | | }, |
| | | |
| | | getComponentProps: function(){ |
| | | getComponentProps: function() { |
| | | var me = this, |
| | | formats = this.getFormats( this.props ), |
| | | props = {dateFormat: formats.date, timeFormat: formats.time} |
| | | ; |
| | | ; |
| | | |
| | | this.componentProps.fromProps.forEach( function( name ){ |
| | | this.componentProps.fromProps.forEach( function( name ) { |
| | | props[ name ] = me.props[ name ]; |
| | | }); |
| | | this.componentProps.fromState.forEach( function( name ){ |
| | | this.componentProps.fromState.forEach( function( name ) { |
| | | props[ name ] = me.state[ name ]; |
| | | }); |
| | | this.componentProps.fromThis.forEach( function( name ){ |
| | | this.componentProps.fromThis.forEach( function( name ) { |
| | | props[ name ] = me[ name ]; |
| | | }); |
| | | |
| | |
| | | }, |
| | | |
| | | render: function() { |
| | | var Component = this.viewComponents[ this.state.currentView ], |
| | | DOM = React.DOM, |
| | | className = 'rdt' + (this.props.className ? |
| | | // TODO: Make a function or clean up this code, |
| | | // logic right now is really hard to follow |
| | | var className = 'rdt' + (this.props.className ? |
| | | ( Array.isArray( this.props.className ) ? |
| | | ' ' + this.props.className.join( ' ' ) : ' ' + this.props.className) : ''), |
| | | children = [] |
| | | ; |
| | | children = []; |
| | | |
| | | if ( this.props.input ){ |
| | | children = [ DOM.input( assign({ |
| | | key: 'i', |
| | | type:'text', |
| | | if ( this.props.input ) { |
| | | var finalInputProps = assign({ |
| | | type: 'text', |
| | | className: 'form-control', |
| | | onClick: this.openCalendar, |
| | | onFocus: this.openCalendar, |
| | | onChange: this.onInputChange, |
| | | onKeyDown: this.onInputKey, |
| | | value: this.state.inputValue |
| | | }, this.props.inputProps ))]; |
| | | value: this.state.inputValue, |
| | | }, this.props.inputProps); |
| | | if ( this.props.renderInput ) { |
| | | children = [ React.createElement('div', { key: 'i' }, this.props.renderInput( finalInputProps, this.openCalendar, this.closeCalendar )) ]; |
| | | } else { |
| | | children = [ React.createElement('input', assign({ key: 'i' }, finalInputProps ))]; |
| | | } |
| | | } else { |
| | | className += ' rdtStatic'; |
| | | } |
| | |
| | | if ( this.state.open ) |
| | | className += ' rdtOpen'; |
| | | |
| | | return DOM.div({className: className}, children.concat( |
| | | DOM.div( |
| | | return React.createElement( 'div', { className: className }, children.concat( |
| | | React.createElement( 'div', |
| | | { key: 'dt', className: 'rdtPicker' }, |
| | | React.createElement( Component, this.getComponentProps()) |
| | | React.createElement( CalendarContainer, { view: this.state.currentView, viewProps: this.getComponentProps(), onClickOutside: this.handleClickOutside }) |
| | | ) |
| | | )); |
| | | } |
| | | }); |
| | | |
| | | Datetime.defaultProps = { |
| | | className: '', |
| | | defaultValue: '', |
| | | inputProps: {}, |
| | | input: true, |
| | | onFocus: function() {}, |
| | | onBlur: function() {}, |
| | | onChange: function() {}, |
| | | onViewModeChange: function() {}, |
| | | timeFormat: true, |
| | | timeConstraints: {}, |
| | | dateFormat: true, |
| | | strictParsing: true, |
| | | closeOnSelect: false, |
| | | closeOnTab: true, |
| | | utc: false |
| | | }; |
| | | |
| | | // Make moment accessible through the Datetime class |
| | | Datetime.moment = moment; |
| | |
| | | module.exports = Datetime; |
| | | |
| | | |
| | | /***/ }, |
| | | /***/ }), |
| | | /* 1 */ |
| | | /***/ function(module, exports) { |
| | | /***/ (function(module, exports) { |
| | | |
| | | 'use strict'; |
| | | var propIsEnumerable = Object.prototype.propertyIsEnumerable; |
| | |
| | | }; |
| | | |
| | | |
| | | /***/ }, |
| | | /***/ }), |
| | | /* 2 */ |
| | | /***/ function(module, exports) { |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | module.exports = __WEBPACK_EXTERNAL_MODULE_2__; |
| | | /* WEBPACK VAR INJECTION */(function(process) {/** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | */ |
| | | |
| | | /***/ }, |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' && |
| | | Symbol.for && |
| | | Symbol.for('react.element')) || |
| | | 0xeac7; |
| | | |
| | | var isValidElement = function(object) { |
| | | return typeof object === 'object' && |
| | | object !== null && |
| | | object.$$typeof === REACT_ELEMENT_TYPE; |
| | | }; |
| | | |
| | | // By explicitly using `prop-types` you are opting into new development behavior. |
| | | // http://fb.me/prop-types-in-prod |
| | | var throwOnDirectAccess = true; |
| | | module.exports = __webpack_require__(4)(isValidElement, throwOnDirectAccess); |
| | | } else { |
| | | // By explicitly using `prop-types` you are opting into new production behavior. |
| | | // http://fb.me/prop-types-in-prod |
| | | module.exports = __webpack_require__(11)(); |
| | | } |
| | | |
| | | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) |
| | | |
| | | /***/ }), |
| | | /* 3 */ |
| | | /***/ function(module, exports, __webpack_require__) { |
| | | /***/ (function(module, exports) { |
| | | |
| | | // shim for using process in browser |
| | | var process = module.exports = {}; |
| | | |
| | | // cached from whatever global is present so that test runners that stub it |
| | | // don't break things. But we need to wrap it in a try catch in case it is |
| | | // wrapped in strict mode code which doesn't define any globals. It's inside a |
| | | // function because try/catches deoptimize in certain engines. |
| | | |
| | | var cachedSetTimeout; |
| | | var cachedClearTimeout; |
| | | |
| | | function defaultSetTimout() { |
| | | throw new Error('setTimeout has not been defined'); |
| | | } |
| | | function defaultClearTimeout () { |
| | | throw new Error('clearTimeout has not been defined'); |
| | | } |
| | | (function () { |
| | | try { |
| | | if (typeof setTimeout === 'function') { |
| | | cachedSetTimeout = setTimeout; |
| | | } else { |
| | | cachedSetTimeout = defaultSetTimout; |
| | | } |
| | | } catch (e) { |
| | | cachedSetTimeout = defaultSetTimout; |
| | | } |
| | | try { |
| | | if (typeof clearTimeout === 'function') { |
| | | cachedClearTimeout = clearTimeout; |
| | | } else { |
| | | cachedClearTimeout = defaultClearTimeout; |
| | | } |
| | | } catch (e) { |
| | | cachedClearTimeout = defaultClearTimeout; |
| | | } |
| | | } ()) |
| | | function runTimeout(fun) { |
| | | if (cachedSetTimeout === setTimeout) { |
| | | //normal enviroments in sane situations |
| | | return setTimeout(fun, 0); |
| | | } |
| | | // if setTimeout wasn't available but was latter defined |
| | | if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { |
| | | cachedSetTimeout = setTimeout; |
| | | return setTimeout(fun, 0); |
| | | } |
| | | try { |
| | | // when when somebody has screwed with setTimeout but no I.E. maddness |
| | | return cachedSetTimeout(fun, 0); |
| | | } catch(e){ |
| | | try { |
| | | // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally |
| | | return cachedSetTimeout.call(null, fun, 0); |
| | | } catch(e){ |
| | | // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error |
| | | return cachedSetTimeout.call(this, fun, 0); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | function runClearTimeout(marker) { |
| | | if (cachedClearTimeout === clearTimeout) { |
| | | //normal enviroments in sane situations |
| | | return clearTimeout(marker); |
| | | } |
| | | // if clearTimeout wasn't available but was latter defined |
| | | if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { |
| | | cachedClearTimeout = clearTimeout; |
| | | return clearTimeout(marker); |
| | | } |
| | | try { |
| | | // when when somebody has screwed with setTimeout but no I.E. maddness |
| | | return cachedClearTimeout(marker); |
| | | } catch (e){ |
| | | try { |
| | | // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally |
| | | return cachedClearTimeout.call(null, marker); |
| | | } catch (e){ |
| | | // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. |
| | | // Some versions of I.E. have different rules for clearTimeout vs setTimeout |
| | | return cachedClearTimeout.call(this, marker); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | var queue = []; |
| | | var draining = false; |
| | | var currentQueue; |
| | | var queueIndex = -1; |
| | | |
| | | function cleanUpNextTick() { |
| | | if (!draining || !currentQueue) { |
| | | return; |
| | | } |
| | | draining = false; |
| | | if (currentQueue.length) { |
| | | queue = currentQueue.concat(queue); |
| | | } else { |
| | | queueIndex = -1; |
| | | } |
| | | if (queue.length) { |
| | | drainQueue(); |
| | | } |
| | | } |
| | | |
| | | function drainQueue() { |
| | | if (draining) { |
| | | return; |
| | | } |
| | | var timeout = runTimeout(cleanUpNextTick); |
| | | draining = true; |
| | | |
| | | var len = queue.length; |
| | | while(len) { |
| | | currentQueue = queue; |
| | | queue = []; |
| | | while (++queueIndex < len) { |
| | | if (currentQueue) { |
| | | currentQueue[queueIndex].run(); |
| | | } |
| | | } |
| | | queueIndex = -1; |
| | | len = queue.length; |
| | | } |
| | | currentQueue = null; |
| | | draining = false; |
| | | runClearTimeout(timeout); |
| | | } |
| | | |
| | | process.nextTick = function (fun) { |
| | | var args = new Array(arguments.length - 1); |
| | | if (arguments.length > 1) { |
| | | for (var i = 1; i < arguments.length; i++) { |
| | | args[i - 1] = arguments[i]; |
| | | } |
| | | } |
| | | queue.push(new Item(fun, args)); |
| | | if (queue.length === 1 && !draining) { |
| | | runTimeout(drainQueue); |
| | | } |
| | | }; |
| | | |
| | | // v8 likes predictible objects |
| | | function Item(fun, array) { |
| | | this.fun = fun; |
| | | this.array = array; |
| | | } |
| | | Item.prototype.run = function () { |
| | | this.fun.apply(null, this.array); |
| | | }; |
| | | process.title = 'browser'; |
| | | process.browser = true; |
| | | process.env = {}; |
| | | process.argv = []; |
| | | process.version = ''; // empty string to avoid regexp issues |
| | | process.versions = {}; |
| | | |
| | | function noop() {} |
| | | |
| | | process.on = noop; |
| | | process.addListener = noop; |
| | | process.once = noop; |
| | | process.off = noop; |
| | | process.removeListener = noop; |
| | | process.removeAllListeners = noop; |
| | | process.emit = noop; |
| | | process.prependListener = noop; |
| | | process.prependOnceListener = noop; |
| | | |
| | | process.listeners = function (name) { return [] } |
| | | |
| | | process.binding = function (name) { |
| | | throw new Error('process.binding is not supported'); |
| | | }; |
| | | |
| | | process.cwd = function () { return '/' }; |
| | | process.chdir = function (dir) { |
| | | throw new Error('process.chdir is not supported'); |
| | | }; |
| | | process.umask = function() { return 0; }; |
| | | |
| | | |
| | | /***/ }), |
| | | /* 4 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | /* WEBPACK VAR INJECTION */(function(process) {/** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | var React = __webpack_require__(2), |
| | | moment = __webpack_require__(4) |
| | | ; |
| | | var emptyFunction = __webpack_require__(5); |
| | | var invariant = __webpack_require__(6); |
| | | var warning = __webpack_require__(7); |
| | | var assign = __webpack_require__(8); |
| | | |
| | | var DOM = React.DOM; |
| | | var DateTimePickerDays = React.createClass({ |
| | | var ReactPropTypesSecret = __webpack_require__(9); |
| | | var checkPropTypes = __webpack_require__(10); |
| | | |
| | | module.exports = function(isValidElement, throwOnDirectAccess) { |
| | | /* global Symbol */ |
| | | var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; |
| | | var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. |
| | | |
| | | /** |
| | | * Returns the iterator method function contained on the iterable object. |
| | | * |
| | | * Be sure to invoke the function with the iterable as context: |
| | | * |
| | | * var iteratorFn = getIteratorFn(myIterable); |
| | | * if (iteratorFn) { |
| | | * var iterator = iteratorFn.call(myIterable); |
| | | * ... |
| | | * } |
| | | * |
| | | * @param {?object} maybeIterable |
| | | * @return {?function} |
| | | */ |
| | | function getIteratorFn(maybeIterable) { |
| | | var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); |
| | | if (typeof iteratorFn === 'function') { |
| | | return iteratorFn; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Collection of methods that allow declaration and validation of props that are |
| | | * supplied to React components. Example usage: |
| | | * |
| | | * var Props = require('ReactPropTypes'); |
| | | * var MyArticle = React.createClass({ |
| | | * propTypes: { |
| | | * // An optional string prop named "description". |
| | | * description: Props.string, |
| | | * |
| | | * // A required enum prop named "category". |
| | | * category: Props.oneOf(['News','Photos']).isRequired, |
| | | * |
| | | * // A prop named "dialog" that requires an instance of Dialog. |
| | | * dialog: Props.instanceOf(Dialog).isRequired |
| | | * }, |
| | | * render: function() { ... } |
| | | * }); |
| | | * |
| | | * A more formal specification of how these methods are used: |
| | | * |
| | | * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) |
| | | * decl := ReactPropTypes.{type}(.isRequired)? |
| | | * |
| | | * Each and every declaration produces a function with the same signature. This |
| | | * allows the creation of custom validation functions. For example: |
| | | * |
| | | * var MyLink = React.createClass({ |
| | | * propTypes: { |
| | | * // An optional string or URI prop named "href". |
| | | * href: function(props, propName, componentName) { |
| | | * var propValue = props[propName]; |
| | | * if (propValue != null && typeof propValue !== 'string' && |
| | | * !(propValue instanceof URI)) { |
| | | * return new Error( |
| | | * 'Expected a string or an URI for ' + propName + ' in ' + |
| | | * componentName |
| | | * ); |
| | | * } |
| | | * } |
| | | * }, |
| | | * render: function() {...} |
| | | * }); |
| | | * |
| | | * @internal |
| | | */ |
| | | |
| | | var ANONYMOUS = '<<anonymous>>'; |
| | | |
| | | // Important! |
| | | // Keep this list in sync with production version in `./factoryWithThrowingShims.js`. |
| | | var ReactPropTypes = { |
| | | array: createPrimitiveTypeChecker('array'), |
| | | bool: createPrimitiveTypeChecker('boolean'), |
| | | func: createPrimitiveTypeChecker('function'), |
| | | number: createPrimitiveTypeChecker('number'), |
| | | object: createPrimitiveTypeChecker('object'), |
| | | string: createPrimitiveTypeChecker('string'), |
| | | symbol: createPrimitiveTypeChecker('symbol'), |
| | | |
| | | any: createAnyTypeChecker(), |
| | | arrayOf: createArrayOfTypeChecker, |
| | | element: createElementTypeChecker(), |
| | | instanceOf: createInstanceTypeChecker, |
| | | node: createNodeChecker(), |
| | | objectOf: createObjectOfTypeChecker, |
| | | oneOf: createEnumTypeChecker, |
| | | oneOfType: createUnionTypeChecker, |
| | | shape: createShapeTypeChecker, |
| | | exact: createStrictShapeTypeChecker, |
| | | }; |
| | | |
| | | /** |
| | | * inlined Object.is polyfill to avoid requiring consumers ship their own |
| | | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is |
| | | */ |
| | | /*eslint-disable no-self-compare*/ |
| | | function is(x, y) { |
| | | // SameValue algorithm |
| | | if (x === y) { |
| | | // Steps 1-5, 7-10 |
| | | // Steps 6.b-6.e: +0 != -0 |
| | | return x !== 0 || 1 / x === 1 / y; |
| | | } else { |
| | | // Step 6.a: NaN == NaN |
| | | return x !== x && y !== y; |
| | | } |
| | | } |
| | | /*eslint-enable no-self-compare*/ |
| | | |
| | | /** |
| | | * We use an Error-like object for backward compatibility as people may call |
| | | * PropTypes directly and inspect their output. However, we don't use real |
| | | * Errors anymore. We don't inspect their stack anyway, and creating them |
| | | * is prohibitively expensive if they are created too often, such as what |
| | | * happens in oneOfType() for any type before the one that matched. |
| | | */ |
| | | function PropTypeError(message) { |
| | | this.message = message; |
| | | this.stack = ''; |
| | | } |
| | | // Make `instanceof Error` still work for returned errors. |
| | | PropTypeError.prototype = Error.prototype; |
| | | |
| | | function createChainableTypeChecker(validate) { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | var manualPropTypeCallCache = {}; |
| | | var manualPropTypeWarningCount = 0; |
| | | } |
| | | function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { |
| | | componentName = componentName || ANONYMOUS; |
| | | propFullName = propFullName || propName; |
| | | |
| | | if (secret !== ReactPropTypesSecret) { |
| | | if (throwOnDirectAccess) { |
| | | // New behavior only for users of `prop-types` package |
| | | invariant( |
| | | false, |
| | | 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + |
| | | 'Use `PropTypes.checkPropTypes()` to call them. ' + |
| | | 'Read more at http://fb.me/use-check-prop-types' |
| | | ); |
| | | } else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') { |
| | | // Old behavior for people using React.PropTypes |
| | | var cacheKey = componentName + ':' + propName; |
| | | if ( |
| | | !manualPropTypeCallCache[cacheKey] && |
| | | // Avoid spamming the console because they are often not actionable except for lib authors |
| | | manualPropTypeWarningCount < 3 |
| | | ) { |
| | | warning( |
| | | false, |
| | | 'You are manually calling a React.PropTypes validation ' + |
| | | 'function for the `%s` prop on `%s`. This is deprecated ' + |
| | | 'and will throw in the standalone `prop-types` package. ' + |
| | | 'You may be seeing this warning due to a third-party PropTypes ' + |
| | | 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.', |
| | | propFullName, |
| | | componentName |
| | | ); |
| | | manualPropTypeCallCache[cacheKey] = true; |
| | | manualPropTypeWarningCount++; |
| | | } |
| | | } |
| | | } |
| | | if (props[propName] == null) { |
| | | if (isRequired) { |
| | | if (props[propName] === null) { |
| | | return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); |
| | | } |
| | | return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); |
| | | } |
| | | return null; |
| | | } else { |
| | | return validate(props, propName, componentName, location, propFullName); |
| | | } |
| | | } |
| | | |
| | | var chainedCheckType = checkType.bind(null, false); |
| | | chainedCheckType.isRequired = checkType.bind(null, true); |
| | | |
| | | return chainedCheckType; |
| | | } |
| | | |
| | | function createPrimitiveTypeChecker(expectedType) { |
| | | function validate(props, propName, componentName, location, propFullName, secret) { |
| | | var propValue = props[propName]; |
| | | var propType = getPropType(propValue); |
| | | if (propType !== expectedType) { |
| | | // `propValue` being instance of, say, date/regexp, pass the 'object' |
| | | // check, but we can offer a more precise error message here rather than |
| | | // 'of type `object`'. |
| | | var preciseType = getPreciseType(propValue); |
| | | |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); |
| | | } |
| | | return null; |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createAnyTypeChecker() { |
| | | return createChainableTypeChecker(emptyFunction.thatReturnsNull); |
| | | } |
| | | |
| | | function createArrayOfTypeChecker(typeChecker) { |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | if (typeof typeChecker !== 'function') { |
| | | return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); |
| | | } |
| | | var propValue = props[propName]; |
| | | if (!Array.isArray(propValue)) { |
| | | var propType = getPropType(propValue); |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); |
| | | } |
| | | for (var i = 0; i < propValue.length; i++) { |
| | | var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); |
| | | if (error instanceof Error) { |
| | | return error; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createElementTypeChecker() { |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | var propValue = props[propName]; |
| | | if (!isValidElement(propValue)) { |
| | | var propType = getPropType(propValue); |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); |
| | | } |
| | | return null; |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createInstanceTypeChecker(expectedClass) { |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | if (!(props[propName] instanceof expectedClass)) { |
| | | var expectedClassName = expectedClass.name || ANONYMOUS; |
| | | var actualClassName = getClassName(props[propName]); |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); |
| | | } |
| | | return null; |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createEnumTypeChecker(expectedValues) { |
| | | if (!Array.isArray(expectedValues)) { |
| | | process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0; |
| | | return emptyFunction.thatReturnsNull; |
| | | } |
| | | |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | var propValue = props[propName]; |
| | | for (var i = 0; i < expectedValues.length; i++) { |
| | | if (is(propValue, expectedValues[i])) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | var valuesString = JSON.stringify(expectedValues); |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createObjectOfTypeChecker(typeChecker) { |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | if (typeof typeChecker !== 'function') { |
| | | return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); |
| | | } |
| | | var propValue = props[propName]; |
| | | var propType = getPropType(propValue); |
| | | if (propType !== 'object') { |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); |
| | | } |
| | | for (var key in propValue) { |
| | | if (propValue.hasOwnProperty(key)) { |
| | | var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); |
| | | if (error instanceof Error) { |
| | | return error; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createUnionTypeChecker(arrayOfTypeCheckers) { |
| | | if (!Array.isArray(arrayOfTypeCheckers)) { |
| | | process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0; |
| | | return emptyFunction.thatReturnsNull; |
| | | } |
| | | |
| | | for (var i = 0; i < arrayOfTypeCheckers.length; i++) { |
| | | var checker = arrayOfTypeCheckers[i]; |
| | | if (typeof checker !== 'function') { |
| | | warning( |
| | | false, |
| | | 'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + |
| | | 'received %s at index %s.', |
| | | getPostfixForTypeWarning(checker), |
| | | i |
| | | ); |
| | | return emptyFunction.thatReturnsNull; |
| | | } |
| | | } |
| | | |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | for (var i = 0; i < arrayOfTypeCheckers.length; i++) { |
| | | var checker = arrayOfTypeCheckers[i]; |
| | | if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createNodeChecker() { |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | if (!isNode(props[propName])) { |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); |
| | | } |
| | | return null; |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createShapeTypeChecker(shapeTypes) { |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | var propValue = props[propName]; |
| | | var propType = getPropType(propValue); |
| | | if (propType !== 'object') { |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); |
| | | } |
| | | for (var key in shapeTypes) { |
| | | var checker = shapeTypes[key]; |
| | | if (!checker) { |
| | | continue; |
| | | } |
| | | var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); |
| | | if (error) { |
| | | return error; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function createStrictShapeTypeChecker(shapeTypes) { |
| | | function validate(props, propName, componentName, location, propFullName) { |
| | | var propValue = props[propName]; |
| | | var propType = getPropType(propValue); |
| | | if (propType !== 'object') { |
| | | return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); |
| | | } |
| | | // We need to check all keys in case some are required but missing from |
| | | // props. |
| | | var allKeys = assign({}, props[propName], shapeTypes); |
| | | for (var key in allKeys) { |
| | | var checker = shapeTypes[key]; |
| | | if (!checker) { |
| | | return new PropTypeError( |
| | | 'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + |
| | | '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + |
| | | '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ') |
| | | ); |
| | | } |
| | | var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); |
| | | if (error) { |
| | | return error; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | return createChainableTypeChecker(validate); |
| | | } |
| | | |
| | | function isNode(propValue) { |
| | | switch (typeof propValue) { |
| | | case 'number': |
| | | case 'string': |
| | | case 'undefined': |
| | | return true; |
| | | case 'boolean': |
| | | return !propValue; |
| | | case 'object': |
| | | if (Array.isArray(propValue)) { |
| | | return propValue.every(isNode); |
| | | } |
| | | if (propValue === null || isValidElement(propValue)) { |
| | | return true; |
| | | } |
| | | |
| | | var iteratorFn = getIteratorFn(propValue); |
| | | if (iteratorFn) { |
| | | var iterator = iteratorFn.call(propValue); |
| | | var step; |
| | | if (iteratorFn !== propValue.entries) { |
| | | while (!(step = iterator.next()).done) { |
| | | if (!isNode(step.value)) { |
| | | return false; |
| | | } |
| | | } |
| | | } else { |
| | | // Iterator will provide entry [k,v] tuples rather than values. |
| | | while (!(step = iterator.next()).done) { |
| | | var entry = step.value; |
| | | if (entry) { |
| | | if (!isNode(entry[1])) { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | default: |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | function isSymbol(propType, propValue) { |
| | | // Native Symbol. |
| | | if (propType === 'symbol') { |
| | | return true; |
| | | } |
| | | |
| | | // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' |
| | | if (propValue['@@toStringTag'] === 'Symbol') { |
| | | return true; |
| | | } |
| | | |
| | | // Fallback for non-spec compliant Symbols which are polyfilled. |
| | | if (typeof Symbol === 'function' && propValue instanceof Symbol) { |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | // Equivalent of `typeof` but with special handling for array and regexp. |
| | | function getPropType(propValue) { |
| | | var propType = typeof propValue; |
| | | if (Array.isArray(propValue)) { |
| | | return 'array'; |
| | | } |
| | | if (propValue instanceof RegExp) { |
| | | // Old webkits (at least until Android 4.0) return 'function' rather than |
| | | // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ |
| | | // passes PropTypes.object. |
| | | return 'object'; |
| | | } |
| | | if (isSymbol(propType, propValue)) { |
| | | return 'symbol'; |
| | | } |
| | | return propType; |
| | | } |
| | | |
| | | // This handles more types than `getPropType`. Only used for error messages. |
| | | // See `createPrimitiveTypeChecker`. |
| | | function getPreciseType(propValue) { |
| | | if (typeof propValue === 'undefined' || propValue === null) { |
| | | return '' + propValue; |
| | | } |
| | | var propType = getPropType(propValue); |
| | | if (propType === 'object') { |
| | | if (propValue instanceof Date) { |
| | | return 'date'; |
| | | } else if (propValue instanceof RegExp) { |
| | | return 'regexp'; |
| | | } |
| | | } |
| | | return propType; |
| | | } |
| | | |
| | | // Returns a string that is postfixed to a warning about an invalid type. |
| | | // For example, "undefined" or "of type array" |
| | | function getPostfixForTypeWarning(value) { |
| | | var type = getPreciseType(value); |
| | | switch (type) { |
| | | case 'array': |
| | | case 'object': |
| | | return 'an ' + type; |
| | | case 'boolean': |
| | | case 'date': |
| | | case 'regexp': |
| | | return 'a ' + type; |
| | | default: |
| | | return type; |
| | | } |
| | | } |
| | | |
| | | // Returns class name of the object, if any. |
| | | function getClassName(propValue) { |
| | | if (!propValue.constructor || !propValue.constructor.name) { |
| | | return ANONYMOUS; |
| | | } |
| | | return propValue.constructor.name; |
| | | } |
| | | |
| | | ReactPropTypes.checkPropTypes = checkPropTypes; |
| | | ReactPropTypes.PropTypes = ReactPropTypes; |
| | | |
| | | return ReactPropTypes; |
| | | }; |
| | | |
| | | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) |
| | | |
| | | /***/ }), |
| | | /* 5 */ |
| | | /***/ (function(module, exports) { |
| | | |
| | | "use strict"; |
| | | |
| | | /** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | * |
| | | * |
| | | */ |
| | | |
| | | function makeEmptyFunction(arg) { |
| | | return function () { |
| | | return arg; |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * This function accepts and discards inputs; it has no side effects. This is |
| | | * primarily useful idiomatically for overridable function endpoints which |
| | | * always need to be callable, since JS lacks a null-call idiom ala Cocoa. |
| | | */ |
| | | var emptyFunction = function emptyFunction() {}; |
| | | |
| | | emptyFunction.thatReturns = makeEmptyFunction; |
| | | emptyFunction.thatReturnsFalse = makeEmptyFunction(false); |
| | | emptyFunction.thatReturnsTrue = makeEmptyFunction(true); |
| | | emptyFunction.thatReturnsNull = makeEmptyFunction(null); |
| | | emptyFunction.thatReturnsThis = function () { |
| | | return this; |
| | | }; |
| | | emptyFunction.thatReturnsArgument = function (arg) { |
| | | return arg; |
| | | }; |
| | | |
| | | module.exports = emptyFunction; |
| | | |
| | | /***/ }), |
| | | /* 6 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | /* WEBPACK VAR INJECTION */(function(process) {/** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | * |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | /** |
| | | * Use invariant() to assert state which your program assumes to be true. |
| | | * |
| | | * Provide sprintf-style format (only %s is supported) and arguments |
| | | * to provide information about what broke and what you were |
| | | * expecting. |
| | | * |
| | | * The invariant message will be stripped in production, but the invariant |
| | | * will remain to ensure logic does not differ in production. |
| | | */ |
| | | |
| | | var validateFormat = function validateFormat(format) {}; |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | validateFormat = function validateFormat(format) { |
| | | if (format === undefined) { |
| | | throw new Error('invariant requires an error message argument'); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | function invariant(condition, format, a, b, c, d, e, f) { |
| | | validateFormat(format); |
| | | |
| | | if (!condition) { |
| | | var error; |
| | | if (format === undefined) { |
| | | error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); |
| | | } else { |
| | | var args = [a, b, c, d, e, f]; |
| | | var argIndex = 0; |
| | | error = new Error(format.replace(/%s/g, function () { |
| | | return args[argIndex++]; |
| | | })); |
| | | error.name = 'Invariant Violation'; |
| | | } |
| | | |
| | | error.framesToPop = 1; // we don't care about invariant's own frame |
| | | throw error; |
| | | } |
| | | } |
| | | |
| | | module.exports = invariant; |
| | | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) |
| | | |
| | | /***/ }), |
| | | /* 7 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | /* WEBPACK VAR INJECTION */(function(process) {/** |
| | | * Copyright (c) 2014-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | * |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | var emptyFunction = __webpack_require__(5); |
| | | |
| | | /** |
| | | * Similar to invariant but only logs a warning if the condition is not met. |
| | | * This can be used to log issues in development environments in critical |
| | | * paths. Removing the logging code for production environments will keep the |
| | | * same logic and follow the same code paths. |
| | | */ |
| | | |
| | | var warning = emptyFunction; |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | var printWarning = function printWarning(format) { |
| | | for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { |
| | | args[_key - 1] = arguments[_key]; |
| | | } |
| | | |
| | | var argIndex = 0; |
| | | var message = 'Warning: ' + format.replace(/%s/g, function () { |
| | | return args[argIndex++]; |
| | | }); |
| | | if (typeof console !== 'undefined') { |
| | | console.error(message); |
| | | } |
| | | try { |
| | | // --- Welcome to debugging React --- |
| | | // This error was thrown as a convenience so that you can use this stack |
| | | // to find the callsite that caused this warning to fire. |
| | | throw new Error(message); |
| | | } catch (x) {} |
| | | }; |
| | | |
| | | warning = function warning(condition, format) { |
| | | if (format === undefined) { |
| | | throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); |
| | | } |
| | | |
| | | if (format.indexOf('Failed Composite propType: ') === 0) { |
| | | return; // Ignore CompositeComponent proptype check. |
| | | } |
| | | |
| | | if (!condition) { |
| | | for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { |
| | | args[_key2 - 2] = arguments[_key2]; |
| | | } |
| | | |
| | | printWarning.apply(undefined, [format].concat(args)); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | module.exports = warning; |
| | | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) |
| | | |
| | | /***/ }), |
| | | /* 8 */ |
| | | /***/ (function(module, exports) { |
| | | |
| | | /* |
| | | object-assign |
| | | (c) Sindre Sorhus |
| | | @license MIT |
| | | */ |
| | | |
| | | 'use strict'; |
| | | /* eslint-disable no-unused-vars */ |
| | | var getOwnPropertySymbols = Object.getOwnPropertySymbols; |
| | | var hasOwnProperty = Object.prototype.hasOwnProperty; |
| | | var propIsEnumerable = Object.prototype.propertyIsEnumerable; |
| | | |
| | | function toObject(val) { |
| | | if (val === null || val === undefined) { |
| | | throw new TypeError('Object.assign cannot be called with null or undefined'); |
| | | } |
| | | |
| | | return Object(val); |
| | | } |
| | | |
| | | function shouldUseNative() { |
| | | try { |
| | | if (!Object.assign) { |
| | | return false; |
| | | } |
| | | |
| | | // Detect buggy property enumeration order in older V8 versions. |
| | | |
| | | // https://bugs.chromium.org/p/v8/issues/detail?id=4118 |
| | | var test1 = new String('abc'); // eslint-disable-line no-new-wrappers |
| | | test1[5] = 'de'; |
| | | if (Object.getOwnPropertyNames(test1)[0] === '5') { |
| | | return false; |
| | | } |
| | | |
| | | // https://bugs.chromium.org/p/v8/issues/detail?id=3056 |
| | | var test2 = {}; |
| | | for (var i = 0; i < 10; i++) { |
| | | test2['_' + String.fromCharCode(i)] = i; |
| | | } |
| | | var order2 = Object.getOwnPropertyNames(test2).map(function (n) { |
| | | return test2[n]; |
| | | }); |
| | | if (order2.join('') !== '0123456789') { |
| | | return false; |
| | | } |
| | | |
| | | // https://bugs.chromium.org/p/v8/issues/detail?id=3056 |
| | | var test3 = {}; |
| | | 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { |
| | | test3[letter] = letter; |
| | | }); |
| | | if (Object.keys(Object.assign({}, test3)).join('') !== |
| | | 'abcdefghijklmnopqrst') { |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } catch (err) { |
| | | // We don't expect any of the above to throw, but better to be safe. |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | module.exports = shouldUseNative() ? Object.assign : function (target, source) { |
| | | var from; |
| | | var to = toObject(target); |
| | | var symbols; |
| | | |
| | | for (var s = 1; s < arguments.length; s++) { |
| | | from = Object(arguments[s]); |
| | | |
| | | for (var key in from) { |
| | | if (hasOwnProperty.call(from, key)) { |
| | | to[key] = from[key]; |
| | | } |
| | | } |
| | | |
| | | if (getOwnPropertySymbols) { |
| | | symbols = getOwnPropertySymbols(from); |
| | | for (var i = 0; i < symbols.length; i++) { |
| | | if (propIsEnumerable.call(from, symbols[i])) { |
| | | to[symbols[i]] = from[symbols[i]]; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return to; |
| | | }; |
| | | |
| | | |
| | | /***/ }), |
| | | /* 9 */ |
| | | /***/ (function(module, exports) { |
| | | |
| | | /** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; |
| | | |
| | | module.exports = ReactPropTypesSecret; |
| | | |
| | | |
| | | /***/ }), |
| | | /* 10 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | /* WEBPACK VAR INJECTION */(function(process) {/** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | var invariant = __webpack_require__(6); |
| | | var warning = __webpack_require__(7); |
| | | var ReactPropTypesSecret = __webpack_require__(9); |
| | | var loggedTypeFailures = {}; |
| | | } |
| | | |
| | | /** |
| | | * Assert that the values match with the type specs. |
| | | * Error messages are memorized and will only be shown once. |
| | | * |
| | | * @param {object} typeSpecs Map of name to a ReactPropType |
| | | * @param {object} values Runtime values that need to be type-checked |
| | | * @param {string} location e.g. "prop", "context", "child context" |
| | | * @param {string} componentName Name of the component for error messages. |
| | | * @param {?Function} getStack Returns the component stack. |
| | | * @private |
| | | */ |
| | | function checkPropTypes(typeSpecs, values, location, componentName, getStack) { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | for (var typeSpecName in typeSpecs) { |
| | | if (typeSpecs.hasOwnProperty(typeSpecName)) { |
| | | var error; |
| | | // Prop type validation may throw. In case they do, we don't want to |
| | | // fail the render phase where it didn't fail before. So we log it. |
| | | // After these have been cleaned up, we'll let them throw. |
| | | try { |
| | | // This is intentionally an invariant that gets caught. It's the same |
| | | // behavior as without this statement except with a better message. |
| | | invariant(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'the `prop-types` package, but received `%s`.', componentName || 'React class', location, typeSpecName, typeof typeSpecs[typeSpecName]); |
| | | error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); |
| | | } catch (ex) { |
| | | error = ex; |
| | | } |
| | | warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error); |
| | | if (error instanceof Error && !(error.message in loggedTypeFailures)) { |
| | | // Only monitor this failure once because there tends to be a lot of the |
| | | // same error. |
| | | loggedTypeFailures[error.message] = true; |
| | | |
| | | var stack = getStack ? getStack() : ''; |
| | | |
| | | warning(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : ''); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | module.exports = checkPropTypes; |
| | | |
| | | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) |
| | | |
| | | /***/ }), |
| | | /* 11 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | /** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | var emptyFunction = __webpack_require__(5); |
| | | var invariant = __webpack_require__(6); |
| | | var ReactPropTypesSecret = __webpack_require__(9); |
| | | |
| | | module.exports = function() { |
| | | function shim(props, propName, componentName, location, propFullName, secret) { |
| | | if (secret === ReactPropTypesSecret) { |
| | | // It is still safe when called from React. |
| | | return; |
| | | } |
| | | invariant( |
| | | false, |
| | | 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + |
| | | 'Use PropTypes.checkPropTypes() to call them. ' + |
| | | 'Read more at http://fb.me/use-check-prop-types' |
| | | ); |
| | | }; |
| | | shim.isRequired = shim; |
| | | function getShim() { |
| | | return shim; |
| | | }; |
| | | // Important! |
| | | // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`. |
| | | var ReactPropTypes = { |
| | | array: shim, |
| | | bool: shim, |
| | | func: shim, |
| | | number: shim, |
| | | object: shim, |
| | | string: shim, |
| | | symbol: shim, |
| | | |
| | | any: shim, |
| | | arrayOf: getShim, |
| | | element: shim, |
| | | instanceOf: getShim, |
| | | node: shim, |
| | | objectOf: getShim, |
| | | oneOf: getShim, |
| | | oneOfType: getShim, |
| | | shape: getShim, |
| | | exact: getShim |
| | | }; |
| | | |
| | | ReactPropTypes.checkPropTypes = emptyFunction; |
| | | ReactPropTypes.PropTypes = ReactPropTypes; |
| | | |
| | | return ReactPropTypes; |
| | | }; |
| | | |
| | | |
| | | /***/ }), |
| | | /* 12 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | /** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | * |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | var React = __webpack_require__(13); |
| | | var factory = __webpack_require__(14); |
| | | |
| | | if (typeof React === 'undefined') { |
| | | throw Error( |
| | | 'create-react-class could not find the React object. If you are using script tags, ' + |
| | | 'make sure that React is being loaded before create-react-class.' |
| | | ); |
| | | } |
| | | |
| | | // Hack to grab NoopUpdateQueue from isomorphic React |
| | | var ReactNoopUpdateQueue = new React.Component().updater; |
| | | |
| | | module.exports = factory( |
| | | React.Component, |
| | | React.isValidElement, |
| | | ReactNoopUpdateQueue |
| | | ); |
| | | |
| | | |
| | | /***/ }), |
| | | /* 13 */ |
| | | /***/ (function(module, exports) { |
| | | |
| | | module.exports = __WEBPACK_EXTERNAL_MODULE_13__; |
| | | |
| | | /***/ }), |
| | | /* 14 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | /* WEBPACK VAR INJECTION */(function(process) {/** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | * |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | var _assign = __webpack_require__(15); |
| | | |
| | | var emptyObject = __webpack_require__(16); |
| | | var _invariant = __webpack_require__(6); |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | var warning = __webpack_require__(7); |
| | | } |
| | | |
| | | var MIXINS_KEY = 'mixins'; |
| | | |
| | | // Helper function to allow the creation of anonymous functions which do not |
| | | // have .name set to the name of the variable being assigned to. |
| | | function identity(fn) { |
| | | return fn; |
| | | } |
| | | |
| | | var ReactPropTypeLocationNames; |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | ReactPropTypeLocationNames = { |
| | | prop: 'prop', |
| | | context: 'context', |
| | | childContext: 'child context' |
| | | }; |
| | | } else { |
| | | ReactPropTypeLocationNames = {}; |
| | | } |
| | | |
| | | function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) { |
| | | /** |
| | | * Policies that describe methods in `ReactClassInterface`. |
| | | */ |
| | | |
| | | var injectedMixins = []; |
| | | |
| | | /** |
| | | * Composite components are higher-level components that compose other composite |
| | | * or host components. |
| | | * |
| | | * To create a new type of `ReactClass`, pass a specification of |
| | | * your new class to `React.createClass`. The only requirement of your class |
| | | * specification is that you implement a `render` method. |
| | | * |
| | | * var MyComponent = React.createClass({ |
| | | * render: function() { |
| | | * return <div>Hello World</div>; |
| | | * } |
| | | * }); |
| | | * |
| | | * The class specification supports a specific protocol of methods that have |
| | | * special meaning (e.g. `render`). See `ReactClassInterface` for |
| | | * more the comprehensive protocol. Any other properties and methods in the |
| | | * class specification will be available on the prototype. |
| | | * |
| | | * @interface ReactClassInterface |
| | | * @internal |
| | | */ |
| | | var ReactClassInterface = { |
| | | /** |
| | | * An array of Mixin objects to include when defining your component. |
| | | * |
| | | * @type {array} |
| | | * @optional |
| | | */ |
| | | mixins: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * An object containing properties and methods that should be defined on |
| | | * the component's constructor instead of its prototype (static methods). |
| | | * |
| | | * @type {object} |
| | | * @optional |
| | | */ |
| | | statics: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Definition of prop types for this component. |
| | | * |
| | | * @type {object} |
| | | * @optional |
| | | */ |
| | | propTypes: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Definition of context types for this component. |
| | | * |
| | | * @type {object} |
| | | * @optional |
| | | */ |
| | | contextTypes: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Definition of context types this component sets for its children. |
| | | * |
| | | * @type {object} |
| | | * @optional |
| | | */ |
| | | childContextTypes: 'DEFINE_MANY', |
| | | |
| | | // ==== Definition methods ==== |
| | | |
| | | /** |
| | | * Invoked when the component is mounted. Values in the mapping will be set on |
| | | * `this.props` if that prop is not specified (i.e. using an `in` check). |
| | | * |
| | | * This method is invoked before `getInitialState` and therefore cannot rely |
| | | * on `this.state` or use `this.setState`. |
| | | * |
| | | * @return {object} |
| | | * @optional |
| | | */ |
| | | getDefaultProps: 'DEFINE_MANY_MERGED', |
| | | |
| | | /** |
| | | * Invoked once before the component is mounted. The return value will be used |
| | | * as the initial value of `this.state`. |
| | | * |
| | | * getInitialState: function() { |
| | | * return { |
| | | * isOn: false, |
| | | * fooBaz: new BazFoo() |
| | | * } |
| | | * } |
| | | * |
| | | * @return {object} |
| | | * @optional |
| | | */ |
| | | getInitialState: 'DEFINE_MANY_MERGED', |
| | | |
| | | /** |
| | | * @return {object} |
| | | * @optional |
| | | */ |
| | | getChildContext: 'DEFINE_MANY_MERGED', |
| | | |
| | | /** |
| | | * Uses props from `this.props` and state from `this.state` to render the |
| | | * structure of the component. |
| | | * |
| | | * No guarantees are made about when or how often this method is invoked, so |
| | | * it must not have side effects. |
| | | * |
| | | * render: function() { |
| | | * var name = this.props.name; |
| | | * return <div>Hello, {name}!</div>; |
| | | * } |
| | | * |
| | | * @return {ReactComponent} |
| | | * @required |
| | | */ |
| | | render: 'DEFINE_ONCE', |
| | | |
| | | // ==== Delegate methods ==== |
| | | |
| | | /** |
| | | * Invoked when the component is initially created and about to be mounted. |
| | | * This may have side effects, but any external subscriptions or data created |
| | | * by this method must be cleaned up in `componentWillUnmount`. |
| | | * |
| | | * @optional |
| | | */ |
| | | componentWillMount: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Invoked when the component has been mounted and has a DOM representation. |
| | | * However, there is no guarantee that the DOM node is in the document. |
| | | * |
| | | * Use this as an opportunity to operate on the DOM when the component has |
| | | * been mounted (initialized and rendered) for the first time. |
| | | * |
| | | * @param {DOMElement} rootNode DOM element representing the component. |
| | | * @optional |
| | | */ |
| | | componentDidMount: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Invoked before the component receives new props. |
| | | * |
| | | * Use this as an opportunity to react to a prop transition by updating the |
| | | * state using `this.setState`. Current props are accessed via `this.props`. |
| | | * |
| | | * componentWillReceiveProps: function(nextProps, nextContext) { |
| | | * this.setState({ |
| | | * likesIncreasing: nextProps.likeCount > this.props.likeCount |
| | | * }); |
| | | * } |
| | | * |
| | | * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop |
| | | * transition may cause a state change, but the opposite is not true. If you |
| | | * need it, you are probably looking for `componentWillUpdate`. |
| | | * |
| | | * @param {object} nextProps |
| | | * @optional |
| | | */ |
| | | componentWillReceiveProps: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Invoked while deciding if the component should be updated as a result of |
| | | * receiving new props, state and/or context. |
| | | * |
| | | * Use this as an opportunity to `return false` when you're certain that the |
| | | * transition to the new props/state/context will not require a component |
| | | * update. |
| | | * |
| | | * shouldComponentUpdate: function(nextProps, nextState, nextContext) { |
| | | * return !equal(nextProps, this.props) || |
| | | * !equal(nextState, this.state) || |
| | | * !equal(nextContext, this.context); |
| | | * } |
| | | * |
| | | * @param {object} nextProps |
| | | * @param {?object} nextState |
| | | * @param {?object} nextContext |
| | | * @return {boolean} True if the component should update. |
| | | * @optional |
| | | */ |
| | | shouldComponentUpdate: 'DEFINE_ONCE', |
| | | |
| | | /** |
| | | * Invoked when the component is about to update due to a transition from |
| | | * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` |
| | | * and `nextContext`. |
| | | * |
| | | * Use this as an opportunity to perform preparation before an update occurs. |
| | | * |
| | | * NOTE: You **cannot** use `this.setState()` in this method. |
| | | * |
| | | * @param {object} nextProps |
| | | * @param {?object} nextState |
| | | * @param {?object} nextContext |
| | | * @param {ReactReconcileTransaction} transaction |
| | | * @optional |
| | | */ |
| | | componentWillUpdate: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Invoked when the component's DOM representation has been updated. |
| | | * |
| | | * Use this as an opportunity to operate on the DOM when the component has |
| | | * been updated. |
| | | * |
| | | * @param {object} prevProps |
| | | * @param {?object} prevState |
| | | * @param {?object} prevContext |
| | | * @param {DOMElement} rootNode DOM element representing the component. |
| | | * @optional |
| | | */ |
| | | componentDidUpdate: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Invoked when the component is about to be removed from its parent and have |
| | | * its DOM representation destroyed. |
| | | * |
| | | * Use this as an opportunity to deallocate any external resources. |
| | | * |
| | | * NOTE: There is no `componentDidUnmount` since your component will have been |
| | | * destroyed by that point. |
| | | * |
| | | * @optional |
| | | */ |
| | | componentWillUnmount: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Replacement for (deprecated) `componentWillMount`. |
| | | * |
| | | * @optional |
| | | */ |
| | | UNSAFE_componentWillMount: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Replacement for (deprecated) `componentWillReceiveProps`. |
| | | * |
| | | * @optional |
| | | */ |
| | | UNSAFE_componentWillReceiveProps: 'DEFINE_MANY', |
| | | |
| | | /** |
| | | * Replacement for (deprecated) `componentWillUpdate`. |
| | | * |
| | | * @optional |
| | | */ |
| | | UNSAFE_componentWillUpdate: 'DEFINE_MANY', |
| | | |
| | | // ==== Advanced methods ==== |
| | | |
| | | /** |
| | | * Updates the component's currently mounted DOM representation. |
| | | * |
| | | * By default, this implements React's rendering and reconciliation algorithm. |
| | | * Sophisticated clients may wish to override this. |
| | | * |
| | | * @param {ReactReconcileTransaction} transaction |
| | | * @internal |
| | | * @overridable |
| | | */ |
| | | updateComponent: 'OVERRIDE_BASE' |
| | | }; |
| | | |
| | | /** |
| | | * Similar to ReactClassInterface but for static methods. |
| | | */ |
| | | var ReactClassStaticInterface = { |
| | | /** |
| | | * This method is invoked after a component is instantiated and when it |
| | | * receives new props. Return an object to update state in response to |
| | | * prop changes. Return null to indicate no change to state. |
| | | * |
| | | * If an object is returned, its keys will be merged into the existing state. |
| | | * |
| | | * @return {object || null} |
| | | * @optional |
| | | */ |
| | | getDerivedStateFromProps: 'DEFINE_MANY_MERGED' |
| | | }; |
| | | |
| | | /** |
| | | * Mapping from class specification keys to special processing functions. |
| | | * |
| | | * Although these are declared like instance properties in the specification |
| | | * when defining classes using `React.createClass`, they are actually static |
| | | * and are accessible on the constructor instead of the prototype. Despite |
| | | * being static, they must be defined outside of the "statics" key under |
| | | * which all other static methods are defined. |
| | | */ |
| | | var RESERVED_SPEC_KEYS = { |
| | | displayName: function(Constructor, displayName) { |
| | | Constructor.displayName = displayName; |
| | | }, |
| | | mixins: function(Constructor, mixins) { |
| | | if (mixins) { |
| | | for (var i = 0; i < mixins.length; i++) { |
| | | mixSpecIntoComponent(Constructor, mixins[i]); |
| | | } |
| | | } |
| | | }, |
| | | childContextTypes: function(Constructor, childContextTypes) { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | validateTypeDef(Constructor, childContextTypes, 'childContext'); |
| | | } |
| | | Constructor.childContextTypes = _assign( |
| | | {}, |
| | | Constructor.childContextTypes, |
| | | childContextTypes |
| | | ); |
| | | }, |
| | | contextTypes: function(Constructor, contextTypes) { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | validateTypeDef(Constructor, contextTypes, 'context'); |
| | | } |
| | | Constructor.contextTypes = _assign( |
| | | {}, |
| | | Constructor.contextTypes, |
| | | contextTypes |
| | | ); |
| | | }, |
| | | /** |
| | | * Special case getDefaultProps which should move into statics but requires |
| | | * automatic merging. |
| | | */ |
| | | getDefaultProps: function(Constructor, getDefaultProps) { |
| | | if (Constructor.getDefaultProps) { |
| | | Constructor.getDefaultProps = createMergedResultFunction( |
| | | Constructor.getDefaultProps, |
| | | getDefaultProps |
| | | ); |
| | | } else { |
| | | Constructor.getDefaultProps = getDefaultProps; |
| | | } |
| | | }, |
| | | propTypes: function(Constructor, propTypes) { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | validateTypeDef(Constructor, propTypes, 'prop'); |
| | | } |
| | | Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes); |
| | | }, |
| | | statics: function(Constructor, statics) { |
| | | mixStaticSpecIntoComponent(Constructor, statics); |
| | | }, |
| | | autobind: function() {} |
| | | }; |
| | | |
| | | function validateTypeDef(Constructor, typeDef, location) { |
| | | for (var propName in typeDef) { |
| | | if (typeDef.hasOwnProperty(propName)) { |
| | | // use a warning instead of an _invariant so components |
| | | // don't show up in prod but only in __DEV__ |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | warning( |
| | | typeof typeDef[propName] === 'function', |
| | | '%s: %s type `%s` is invalid; it must be a function, usually from ' + |
| | | 'React.PropTypes.', |
| | | Constructor.displayName || 'ReactClass', |
| | | ReactPropTypeLocationNames[location], |
| | | propName |
| | | ); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | function validateMethodOverride(isAlreadyDefined, name) { |
| | | var specPolicy = ReactClassInterface.hasOwnProperty(name) |
| | | ? ReactClassInterface[name] |
| | | : null; |
| | | |
| | | // Disallow overriding of base class methods unless explicitly allowed. |
| | | if (ReactClassMixin.hasOwnProperty(name)) { |
| | | _invariant( |
| | | specPolicy === 'OVERRIDE_BASE', |
| | | 'ReactClassInterface: You are attempting to override ' + |
| | | '`%s` from your class specification. Ensure that your method names ' + |
| | | 'do not overlap with React methods.', |
| | | name |
| | | ); |
| | | } |
| | | |
| | | // Disallow defining methods more than once unless explicitly allowed. |
| | | if (isAlreadyDefined) { |
| | | _invariant( |
| | | specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED', |
| | | 'ReactClassInterface: You are attempting to define ' + |
| | | '`%s` on your component more than once. This conflict may be due ' + |
| | | 'to a mixin.', |
| | | name |
| | | ); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Mixin helper which handles policy validation and reserved |
| | | * specification keys when building React classes. |
| | | */ |
| | | function mixSpecIntoComponent(Constructor, spec) { |
| | | if (!spec) { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | var typeofSpec = typeof spec; |
| | | var isMixinValid = typeofSpec === 'object' && spec !== null; |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | warning( |
| | | isMixinValid, |
| | | "%s: You're attempting to include a mixin that is either null " + |
| | | 'or not an object. Check the mixins included by the component, ' + |
| | | 'as well as any mixins they include themselves. ' + |
| | | 'Expected object but got %s.', |
| | | Constructor.displayName || 'ReactClass', |
| | | spec === null ? null : typeofSpec |
| | | ); |
| | | } |
| | | } |
| | | |
| | | return; |
| | | } |
| | | |
| | | _invariant( |
| | | typeof spec !== 'function', |
| | | "ReactClass: You're attempting to " + |
| | | 'use a component class or function as a mixin. Instead, just use a ' + |
| | | 'regular object.' |
| | | ); |
| | | _invariant( |
| | | !isValidElement(spec), |
| | | "ReactClass: You're attempting to " + |
| | | 'use a component as a mixin. Instead, just use a regular object.' |
| | | ); |
| | | |
| | | var proto = Constructor.prototype; |
| | | var autoBindPairs = proto.__reactAutoBindPairs; |
| | | |
| | | // By handling mixins before any other properties, we ensure the same |
| | | // chaining order is applied to methods with DEFINE_MANY policy, whether |
| | | // mixins are listed before or after these methods in the spec. |
| | | if (spec.hasOwnProperty(MIXINS_KEY)) { |
| | | RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); |
| | | } |
| | | |
| | | for (var name in spec) { |
| | | if (!spec.hasOwnProperty(name)) { |
| | | continue; |
| | | } |
| | | |
| | | if (name === MIXINS_KEY) { |
| | | // We have already handled mixins in a special case above. |
| | | continue; |
| | | } |
| | | |
| | | var property = spec[name]; |
| | | var isAlreadyDefined = proto.hasOwnProperty(name); |
| | | validateMethodOverride(isAlreadyDefined, name); |
| | | |
| | | if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { |
| | | RESERVED_SPEC_KEYS[name](Constructor, property); |
| | | } else { |
| | | // Setup methods on prototype: |
| | | // The following member methods should not be automatically bound: |
| | | // 1. Expected ReactClass methods (in the "interface"). |
| | | // 2. Overridden methods (that were mixed in). |
| | | var isReactClassMethod = ReactClassInterface.hasOwnProperty(name); |
| | | var isFunction = typeof property === 'function'; |
| | | var shouldAutoBind = |
| | | isFunction && |
| | | !isReactClassMethod && |
| | | !isAlreadyDefined && |
| | | spec.autobind !== false; |
| | | |
| | | if (shouldAutoBind) { |
| | | autoBindPairs.push(name, property); |
| | | proto[name] = property; |
| | | } else { |
| | | if (isAlreadyDefined) { |
| | | var specPolicy = ReactClassInterface[name]; |
| | | |
| | | // These cases should already be caught by validateMethodOverride. |
| | | _invariant( |
| | | isReactClassMethod && |
| | | (specPolicy === 'DEFINE_MANY_MERGED' || |
| | | specPolicy === 'DEFINE_MANY'), |
| | | 'ReactClass: Unexpected spec policy %s for key %s ' + |
| | | 'when mixing in component specs.', |
| | | specPolicy, |
| | | name |
| | | ); |
| | | |
| | | // For methods which are defined more than once, call the existing |
| | | // methods before calling the new property, merging if appropriate. |
| | | if (specPolicy === 'DEFINE_MANY_MERGED') { |
| | | proto[name] = createMergedResultFunction(proto[name], property); |
| | | } else if (specPolicy === 'DEFINE_MANY') { |
| | | proto[name] = createChainedFunction(proto[name], property); |
| | | } |
| | | } else { |
| | | proto[name] = property; |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | // Add verbose displayName to the function, which helps when looking |
| | | // at profiling tools. |
| | | if (typeof property === 'function' && spec.displayName) { |
| | | proto[name].displayName = spec.displayName + '_' + name; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | function mixStaticSpecIntoComponent(Constructor, statics) { |
| | | if (!statics) { |
| | | return; |
| | | } |
| | | |
| | | for (var name in statics) { |
| | | var property = statics[name]; |
| | | if (!statics.hasOwnProperty(name)) { |
| | | continue; |
| | | } |
| | | |
| | | var isReserved = name in RESERVED_SPEC_KEYS; |
| | | _invariant( |
| | | !isReserved, |
| | | 'ReactClass: You are attempting to define a reserved ' + |
| | | 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + |
| | | 'as an instance property instead; it will still be accessible on the ' + |
| | | 'constructor.', |
| | | name |
| | | ); |
| | | |
| | | var isAlreadyDefined = name in Constructor; |
| | | if (isAlreadyDefined) { |
| | | var specPolicy = ReactClassStaticInterface.hasOwnProperty(name) |
| | | ? ReactClassStaticInterface[name] |
| | | : null; |
| | | |
| | | _invariant( |
| | | specPolicy === 'DEFINE_MANY_MERGED', |
| | | 'ReactClass: You are attempting to define ' + |
| | | '`%s` on your component more than once. This conflict may be ' + |
| | | 'due to a mixin.', |
| | | name |
| | | ); |
| | | |
| | | Constructor[name] = createMergedResultFunction(Constructor[name], property); |
| | | |
| | | return; |
| | | } |
| | | |
| | | Constructor[name] = property; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Merge two objects, but throw if both contain the same key. |
| | | * |
| | | * @param {object} one The first object, which is mutated. |
| | | * @param {object} two The second object |
| | | * @return {object} one after it has been mutated to contain everything in two. |
| | | */ |
| | | function mergeIntoWithNoDuplicateKeys(one, two) { |
| | | _invariant( |
| | | one && two && typeof one === 'object' && typeof two === 'object', |
| | | 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.' |
| | | ); |
| | | |
| | | for (var key in two) { |
| | | if (two.hasOwnProperty(key)) { |
| | | _invariant( |
| | | one[key] === undefined, |
| | | 'mergeIntoWithNoDuplicateKeys(): ' + |
| | | 'Tried to merge two objects with the same key: `%s`. This conflict ' + |
| | | 'may be due to a mixin; in particular, this may be caused by two ' + |
| | | 'getInitialState() or getDefaultProps() methods returning objects ' + |
| | | 'with clashing keys.', |
| | | key |
| | | ); |
| | | one[key] = two[key]; |
| | | } |
| | | } |
| | | return one; |
| | | } |
| | | |
| | | /** |
| | | * Creates a function that invokes two functions and merges their return values. |
| | | * |
| | | * @param {function} one Function to invoke first. |
| | | * @param {function} two Function to invoke second. |
| | | * @return {function} Function that invokes the two argument functions. |
| | | * @private |
| | | */ |
| | | function createMergedResultFunction(one, two) { |
| | | return function mergedResult() { |
| | | var a = one.apply(this, arguments); |
| | | var b = two.apply(this, arguments); |
| | | if (a == null) { |
| | | return b; |
| | | } else if (b == null) { |
| | | return a; |
| | | } |
| | | var c = {}; |
| | | mergeIntoWithNoDuplicateKeys(c, a); |
| | | mergeIntoWithNoDuplicateKeys(c, b); |
| | | return c; |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * Creates a function that invokes two functions and ignores their return vales. |
| | | * |
| | | * @param {function} one Function to invoke first. |
| | | * @param {function} two Function to invoke second. |
| | | * @return {function} Function that invokes the two argument functions. |
| | | * @private |
| | | */ |
| | | function createChainedFunction(one, two) { |
| | | return function chainedFunction() { |
| | | one.apply(this, arguments); |
| | | two.apply(this, arguments); |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * Binds a method to the component. |
| | | * |
| | | * @param {object} component Component whose method is going to be bound. |
| | | * @param {function} method Method to be bound. |
| | | * @return {function} The bound method. |
| | | */ |
| | | function bindAutoBindMethod(component, method) { |
| | | var boundMethod = method.bind(component); |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | boundMethod.__reactBoundContext = component; |
| | | boundMethod.__reactBoundMethod = method; |
| | | boundMethod.__reactBoundArguments = null; |
| | | var componentName = component.constructor.displayName; |
| | | var _bind = boundMethod.bind; |
| | | boundMethod.bind = function(newThis) { |
| | | for ( |
| | | var _len = arguments.length, |
| | | args = Array(_len > 1 ? _len - 1 : 0), |
| | | _key = 1; |
| | | _key < _len; |
| | | _key++ |
| | | ) { |
| | | args[_key - 1] = arguments[_key]; |
| | | } |
| | | |
| | | // User is trying to bind() an autobound method; we effectively will |
| | | // ignore the value of "this" that the user is trying to use, so |
| | | // let's warn. |
| | | if (newThis !== component && newThis !== null) { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | warning( |
| | | false, |
| | | 'bind(): React component methods may only be bound to the ' + |
| | | 'component instance. See %s', |
| | | componentName |
| | | ); |
| | | } |
| | | } else if (!args.length) { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | warning( |
| | | false, |
| | | 'bind(): You are binding a component method to the component. ' + |
| | | 'React does this for you automatically in a high-performance ' + |
| | | 'way, so you can safely remove this call. See %s', |
| | | componentName |
| | | ); |
| | | } |
| | | return boundMethod; |
| | | } |
| | | var reboundMethod = _bind.apply(boundMethod, arguments); |
| | | reboundMethod.__reactBoundContext = component; |
| | | reboundMethod.__reactBoundMethod = method; |
| | | reboundMethod.__reactBoundArguments = args; |
| | | return reboundMethod; |
| | | }; |
| | | } |
| | | return boundMethod; |
| | | } |
| | | |
| | | /** |
| | | * Binds all auto-bound methods in a component. |
| | | * |
| | | * @param {object} component Component whose method is going to be bound. |
| | | */ |
| | | function bindAutoBindMethods(component) { |
| | | var pairs = component.__reactAutoBindPairs; |
| | | for (var i = 0; i < pairs.length; i += 2) { |
| | | var autoBindKey = pairs[i]; |
| | | var method = pairs[i + 1]; |
| | | component[autoBindKey] = bindAutoBindMethod(component, method); |
| | | } |
| | | } |
| | | |
| | | var IsMountedPreMixin = { |
| | | componentDidMount: function() { |
| | | this.__isMounted = true; |
| | | } |
| | | }; |
| | | |
| | | var IsMountedPostMixin = { |
| | | componentWillUnmount: function() { |
| | | this.__isMounted = false; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * Add more to the ReactClass base class. These are all legacy features and |
| | | * therefore not already part of the modern ReactComponent. |
| | | */ |
| | | var ReactClassMixin = { |
| | | /** |
| | | * TODO: This will be deprecated because state should always keep a consistent |
| | | * type signature and the only use case for this, is to avoid that. |
| | | */ |
| | | replaceState: function(newState, callback) { |
| | | this.updater.enqueueReplaceState(this, newState, callback); |
| | | }, |
| | | |
| | | /** |
| | | * Checks whether or not this composite component is mounted. |
| | | * @return {boolean} True if mounted, false otherwise. |
| | | * @protected |
| | | * @final |
| | | */ |
| | | isMounted: function() { |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | warning( |
| | | this.__didWarnIsMounted, |
| | | '%s: isMounted is deprecated. Instead, make sure to clean up ' + |
| | | 'subscriptions and pending requests in componentWillUnmount to ' + |
| | | 'prevent memory leaks.', |
| | | (this.constructor && this.constructor.displayName) || |
| | | this.name || |
| | | 'Component' |
| | | ); |
| | | this.__didWarnIsMounted = true; |
| | | } |
| | | return !!this.__isMounted; |
| | | } |
| | | }; |
| | | |
| | | var ReactClassComponent = function() {}; |
| | | _assign( |
| | | ReactClassComponent.prototype, |
| | | ReactComponent.prototype, |
| | | ReactClassMixin |
| | | ); |
| | | |
| | | /** |
| | | * Creates a composite component class given a class specification. |
| | | * See https://facebook.github.io/react/docs/top-level-api.html#react.createclass |
| | | * |
| | | * @param {object} spec Class specification (which must define `render`). |
| | | * @return {function} Component constructor function. |
| | | * @public |
| | | */ |
| | | function createClass(spec) { |
| | | // To keep our warnings more understandable, we'll use a little hack here to |
| | | // ensure that Constructor.name !== 'Constructor'. This makes sure we don't |
| | | // unnecessarily identify a class without displayName as 'Constructor'. |
| | | var Constructor = identity(function(props, context, updater) { |
| | | // This constructor gets overridden by mocks. The argument is used |
| | | // by mocks to assert on what gets mounted. |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | warning( |
| | | this instanceof Constructor, |
| | | 'Something is calling a React component directly. Use a factory or ' + |
| | | 'JSX instead. See: https://fb.me/react-legacyfactory' |
| | | ); |
| | | } |
| | | |
| | | // Wire up auto-binding |
| | | if (this.__reactAutoBindPairs.length) { |
| | | bindAutoBindMethods(this); |
| | | } |
| | | |
| | | this.props = props; |
| | | this.context = context; |
| | | this.refs = emptyObject; |
| | | this.updater = updater || ReactNoopUpdateQueue; |
| | | |
| | | this.state = null; |
| | | |
| | | // ReactClasses doesn't have constructors. Instead, they use the |
| | | // getInitialState and componentWillMount methods for initialization. |
| | | |
| | | var initialState = this.getInitialState ? this.getInitialState() : null; |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | // We allow auto-mocks to proceed as if they're returning null. |
| | | if ( |
| | | initialState === undefined && |
| | | this.getInitialState._isMockFunction |
| | | ) { |
| | | // This is probably bad practice. Consider warning here and |
| | | // deprecating this convenience. |
| | | initialState = null; |
| | | } |
| | | } |
| | | _invariant( |
| | | typeof initialState === 'object' && !Array.isArray(initialState), |
| | | '%s.getInitialState(): must return an object or null', |
| | | Constructor.displayName || 'ReactCompositeComponent' |
| | | ); |
| | | |
| | | this.state = initialState; |
| | | }); |
| | | Constructor.prototype = new ReactClassComponent(); |
| | | Constructor.prototype.constructor = Constructor; |
| | | Constructor.prototype.__reactAutoBindPairs = []; |
| | | |
| | | injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor)); |
| | | |
| | | mixSpecIntoComponent(Constructor, IsMountedPreMixin); |
| | | mixSpecIntoComponent(Constructor, spec); |
| | | mixSpecIntoComponent(Constructor, IsMountedPostMixin); |
| | | |
| | | // Initialize the defaultProps property after all mixins have been merged. |
| | | if (Constructor.getDefaultProps) { |
| | | Constructor.defaultProps = Constructor.getDefaultProps(); |
| | | } |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | // This is a tag to indicate that the use of these method names is ok, |
| | | // since it's used with createClass. If it's not, then it's likely a |
| | | // mistake so we'll warn you to use the static property, property |
| | | // initializer or constructor respectively. |
| | | if (Constructor.getDefaultProps) { |
| | | Constructor.getDefaultProps.isReactClassApproved = {}; |
| | | } |
| | | if (Constructor.prototype.getInitialState) { |
| | | Constructor.prototype.getInitialState.isReactClassApproved = {}; |
| | | } |
| | | } |
| | | |
| | | _invariant( |
| | | Constructor.prototype.render, |
| | | 'createClass(...): Class specification must implement a `render` method.' |
| | | ); |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | warning( |
| | | !Constructor.prototype.componentShouldUpdate, |
| | | '%s has a method called ' + |
| | | 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + |
| | | 'The name is phrased as a question because the function is ' + |
| | | 'expected to return a value.', |
| | | spec.displayName || 'A component' |
| | | ); |
| | | warning( |
| | | !Constructor.prototype.componentWillRecieveProps, |
| | | '%s has a method called ' + |
| | | 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', |
| | | spec.displayName || 'A component' |
| | | ); |
| | | warning( |
| | | !Constructor.prototype.UNSAFE_componentWillRecieveProps, |
| | | '%s has a method called UNSAFE_componentWillRecieveProps(). ' + |
| | | 'Did you mean UNSAFE_componentWillReceiveProps()?', |
| | | spec.displayName || 'A component' |
| | | ); |
| | | } |
| | | |
| | | // Reduce time spent doing lookups by setting these on the prototype. |
| | | for (var methodName in ReactClassInterface) { |
| | | if (!Constructor.prototype[methodName]) { |
| | | Constructor.prototype[methodName] = null; |
| | | } |
| | | } |
| | | |
| | | return Constructor; |
| | | } |
| | | |
| | | return createClass; |
| | | } |
| | | |
| | | module.exports = factory; |
| | | |
| | | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) |
| | | |
| | | /***/ }), |
| | | /* 15 */ |
| | | /***/ (function(module, exports) { |
| | | |
| | | /* |
| | | object-assign |
| | | (c) Sindre Sorhus |
| | | @license MIT |
| | | */ |
| | | |
| | | 'use strict'; |
| | | /* eslint-disable no-unused-vars */ |
| | | var getOwnPropertySymbols = Object.getOwnPropertySymbols; |
| | | var hasOwnProperty = Object.prototype.hasOwnProperty; |
| | | var propIsEnumerable = Object.prototype.propertyIsEnumerable; |
| | | |
| | | function toObject(val) { |
| | | if (val === null || val === undefined) { |
| | | throw new TypeError('Object.assign cannot be called with null or undefined'); |
| | | } |
| | | |
| | | return Object(val); |
| | | } |
| | | |
| | | function shouldUseNative() { |
| | | try { |
| | | if (!Object.assign) { |
| | | return false; |
| | | } |
| | | |
| | | // Detect buggy property enumeration order in older V8 versions. |
| | | |
| | | // https://bugs.chromium.org/p/v8/issues/detail?id=4118 |
| | | var test1 = new String('abc'); // eslint-disable-line no-new-wrappers |
| | | test1[5] = 'de'; |
| | | if (Object.getOwnPropertyNames(test1)[0] === '5') { |
| | | return false; |
| | | } |
| | | |
| | | // https://bugs.chromium.org/p/v8/issues/detail?id=3056 |
| | | var test2 = {}; |
| | | for (var i = 0; i < 10; i++) { |
| | | test2['_' + String.fromCharCode(i)] = i; |
| | | } |
| | | var order2 = Object.getOwnPropertyNames(test2).map(function (n) { |
| | | return test2[n]; |
| | | }); |
| | | if (order2.join('') !== '0123456789') { |
| | | return false; |
| | | } |
| | | |
| | | // https://bugs.chromium.org/p/v8/issues/detail?id=3056 |
| | | var test3 = {}; |
| | | 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { |
| | | test3[letter] = letter; |
| | | }); |
| | | if (Object.keys(Object.assign({}, test3)).join('') !== |
| | | 'abcdefghijklmnopqrst') { |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } catch (err) { |
| | | // We don't expect any of the above to throw, but better to be safe. |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | module.exports = shouldUseNative() ? Object.assign : function (target, source) { |
| | | var from; |
| | | var to = toObject(target); |
| | | var symbols; |
| | | |
| | | for (var s = 1; s < arguments.length; s++) { |
| | | from = Object(arguments[s]); |
| | | |
| | | for (var key in from) { |
| | | if (hasOwnProperty.call(from, key)) { |
| | | to[key] = from[key]; |
| | | } |
| | | } |
| | | |
| | | if (getOwnPropertySymbols) { |
| | | symbols = getOwnPropertySymbols(from); |
| | | for (var i = 0; i < symbols.length; i++) { |
| | | if (propIsEnumerable.call(from, symbols[i])) { |
| | | to[symbols[i]] = from[symbols[i]]; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return to; |
| | | }; |
| | | |
| | | |
| | | /***/ }), |
| | | /* 16 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | /* WEBPACK VAR INJECTION */(function(process) {/** |
| | | * Copyright (c) 2013-present, Facebook, Inc. |
| | | * |
| | | * This source code is licensed under the MIT license found in the |
| | | * LICENSE file in the root directory of this source tree. |
| | | * |
| | | */ |
| | | |
| | | 'use strict'; |
| | | |
| | | var emptyObject = {}; |
| | | |
| | | if (process.env.NODE_ENV !== 'production') { |
| | | Object.freeze(emptyObject); |
| | | } |
| | | |
| | | module.exports = emptyObject; |
| | | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) |
| | | |
| | | /***/ }), |
| | | /* 17 */ |
| | | /***/ (function(module, exports) { |
| | | |
| | | module.exports = __WEBPACK_EXTERNAL_MODULE_17__; |
| | | |
| | | /***/ }), |
| | | /* 18 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | 'use strict'; |
| | | |
| | | var React = __webpack_require__(13), |
| | | createClass = __webpack_require__(12), |
| | | DaysView = __webpack_require__(19), |
| | | MonthsView = __webpack_require__(22), |
| | | YearsView = __webpack_require__(23), |
| | | TimeView = __webpack_require__(24) |
| | | ; |
| | | |
| | | var CalendarContainer = createClass({ |
| | | viewComponents: { |
| | | days: DaysView, |
| | | months: MonthsView, |
| | | years: YearsView, |
| | | time: TimeView |
| | | }, |
| | | |
| | | render: function() { |
| | | return React.createElement( this.viewComponents[ this.props.view ], this.props.viewProps ); |
| | | } |
| | | }); |
| | | |
| | | module.exports = CalendarContainer; |
| | | |
| | | |
| | | /***/ }), |
| | | /* 19 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | 'use strict'; |
| | | |
| | | var React = __webpack_require__(13), |
| | | createClass = __webpack_require__(12), |
| | | moment = __webpack_require__(17), |
| | | onClickOutside = __webpack_require__(20).default |
| | | ; |
| | | |
| | | var DateTimePickerDays = onClickOutside( createClass({ |
| | | render: function() { |
| | | var footer = this.renderFooter(), |
| | | date = this.props.viewDate, |
| | | locale = date.localeData(), |
| | | tableChildren |
| | | ; |
| | | ; |
| | | |
| | | tableChildren = [ |
| | | DOM.thead({ key: 'th'}, [ |
| | | DOM.tr({ key: 'h'}, [ |
| | | DOM.th({ key: 'p', className: 'rdtPrev' }, DOM.span({onClick: this.props.subtractTime(1, 'months')}, '‹')), |
| | | DOM.th({ key: 's', className: 'rdtSwitch', onClick: this.props.showView('months'), colSpan: 5, 'data-value': this.props.viewDate.month() }, locale.months( date ) + ' ' + date.year() ), |
| | | DOM.th({ key: 'n', className: 'rdtNext' }, DOM.span({onClick: this.props.addTime(1, 'months')}, '›')) |
| | | React.createElement('thead', { key: 'th' }, [ |
| | | React.createElement('tr', { key: 'h' }, [ |
| | | React.createElement('th', { key: 'p', className: 'rdtPrev', onClick: this.props.subtractTime( 1, 'months' )}, React.createElement('span', {}, '‹' )), |
| | | React.createElement('th', { key: 's', className: 'rdtSwitch', onClick: this.props.showView( 'months' ), colSpan: 5, 'data-value': this.props.viewDate.month() }, locale.months( date ) + ' ' + date.year() ), |
| | | React.createElement('th', { key: 'n', className: 'rdtNext', onClick: this.props.addTime( 1, 'months' )}, React.createElement('span', {}, '›' )) |
| | | ]), |
| | | DOM.tr({ key: 'd'}, this.getDaysOfWeek( locale ).map( function( day, index ){ return DOM.th({ key: day + index, className: 'dow'}, day ); }) ) |
| | | React.createElement('tr', { key: 'd'}, this.getDaysOfWeek( locale ).map( function( day, index ) { return React.createElement('th', { key: day + index, className: 'dow'}, day ); }) ) |
| | | ]), |
| | | DOM.tbody({key: 'tb'}, this.renderDays()) |
| | | React.createElement('tbody', { key: 'tb' }, this.renderDays()) |
| | | ]; |
| | | |
| | | if ( footer ) |
| | | tableChildren.push( footer ); |
| | | |
| | | return DOM.div({ className: 'rdtDays' }, |
| | | DOM.table({}, tableChildren ) |
| | | return React.createElement('div', { className: 'rdtDays' }, |
| | | React.createElement('table', {}, tableChildren ) |
| | | ); |
| | | }, |
| | | |
| | |
| | | * depending on the current locale |
| | | * @return {array} A list with the shortname of the days |
| | | */ |
| | | getDaysOfWeek: function( locale ){ |
| | | getDaysOfWeek: function( locale ) { |
| | | var days = locale._weekdaysMin, |
| | | first = locale.firstDayOfWeek(), |
| | | dow = [], |
| | | i = 0 |
| | | ; |
| | | ; |
| | | |
| | | days.forEach( function( day ){ |
| | | dow[ (7 + (i++) - first) % 7 ] = day; |
| | | days.forEach( function( day ) { |
| | | dow[ (7 + ( i++ ) - first) % 7 ] = day; |
| | | }); |
| | | |
| | | return dow; |
| | |
| | | weeks = [], |
| | | days = [], |
| | | renderer = this.props.renderDay || this.renderDay, |
| | | isValid = this.props.isValidDate || this.isValidDate, |
| | | classes, disabled, dayProps, currentDate |
| | | ; |
| | | isValid = this.props.isValidDate || this.alwaysValidDate, |
| | | classes, isDisabled, dayProps, currentDate |
| | | ; |
| | | |
| | | // Go to the last week of the previous month |
| | | prevMonth.date( prevMonth.daysInMonth() ).startOf('week'); |
| | | var lastDay = prevMonth.clone().add(42, 'd'); |
| | | prevMonth.date( prevMonth.daysInMonth() ).startOf( 'week' ); |
| | | var lastDay = prevMonth.clone().add( 42, 'd' ); |
| | | |
| | | while ( prevMonth.isBefore( lastDay ) ){ |
| | | while ( prevMonth.isBefore( lastDay ) ) { |
| | | classes = 'rdtDay'; |
| | | currentDate = prevMonth.clone(); |
| | | |
| | |
| | | else if ( ( prevMonth.year() === currentYear && prevMonth.month() > currentMonth ) || ( prevMonth.year() > currentYear ) ) |
| | | classes += ' rdtNew'; |
| | | |
| | | if ( selected && prevMonth.isSame(selected, 'day') ) |
| | | if ( selected && prevMonth.isSame( selected, 'day' ) ) |
| | | classes += ' rdtActive'; |
| | | |
| | | if (prevMonth.isSame(moment(), 'day') ) |
| | | if ( prevMonth.isSame( moment(), 'day' ) ) |
| | | classes += ' rdtToday'; |
| | | |
| | | disabled = !isValid( currentDate, selected ); |
| | | if ( disabled ) |
| | | isDisabled = !isValid( currentDate, selected ); |
| | | if ( isDisabled ) |
| | | classes += ' rdtDisabled'; |
| | | |
| | | dayProps = { |
| | | key: prevMonth.format('M_D'), |
| | | key: prevMonth.format( 'M_D' ), |
| | | 'data-value': prevMonth.date(), |
| | | className: classes |
| | | }; |
| | | if ( !disabled ) |
| | | |
| | | if ( !isDisabled ) |
| | | dayProps.onClick = this.updateSelectedDate; |
| | | |
| | | days.push( renderer( dayProps, currentDate, selected ) ); |
| | | |
| | | if ( days.length === 7 ){ |
| | | weeks.push( DOM.tr( {key: prevMonth.format('M_D')}, days ) ); |
| | | if ( days.length === 7 ) { |
| | | weeks.push( React.createElement('tr', { key: prevMonth.format( 'M_D' )}, days ) ); |
| | | days = []; |
| | | } |
| | | |
| | |
| | | }, |
| | | |
| | | updateSelectedDate: function( event ) { |
| | | this.props.updateSelectedDate(event, true); |
| | | this.props.updateSelectedDate( event, true ); |
| | | }, |
| | | |
| | | renderDay: function( props, currentDate ){ |
| | | return DOM.td( props, currentDate.date() ); |
| | | renderDay: function( props, currentDate ) { |
| | | return React.createElement('td', props, currentDate.date() ); |
| | | }, |
| | | |
| | | renderFooter: function(){ |
| | | renderFooter: function() { |
| | | if ( !this.props.timeFormat ) |
| | | return ''; |
| | | |
| | | var date = this.props.selectedDate || this.props.viewDate; |
| | | |
| | | return DOM.tfoot({ key: 'tf'}, |
| | | DOM.tr({}, |
| | | DOM.td({ onClick: this.props.showView('time'), colSpan: 7, className: 'rdtTimeToggle'}, date.format( this.props.timeFormat )) |
| | | return React.createElement('tfoot', { key: 'tf'}, |
| | | React.createElement('tr', {}, |
| | | React.createElement('td', { onClick: this.props.showView( 'time' ), colSpan: 7, className: 'rdtTimeToggle' }, date.format( this.props.timeFormat )) |
| | | ) |
| | | ); |
| | | }, |
| | | isValidDate: function(){ return 1; } |
| | | }); |
| | | |
| | | alwaysValidDate: function() { |
| | | return 1; |
| | | }, |
| | | |
| | | handleClickOutside: function() { |
| | | this.props.handleClickOutside(); |
| | | } |
| | | })); |
| | | |
| | | module.exports = DateTimePickerDays; |
| | | |
| | | |
| | | /***/ }, |
| | | /* 4 */ |
| | | /***/ function(module, exports) { |
| | | |
| | | module.exports = __WEBPACK_EXTERNAL_MODULE_4__; |
| | | |
| | | /***/ }, |
| | | /* 5 */ |
| | | /***/ function(module, exports, __webpack_require__) { |
| | | /***/ }), |
| | | /* 20 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | 'use strict'; |
| | | |
| | | var React = __webpack_require__(2); |
| | | Object.defineProperty(exports, '__esModule', { value: true }); |
| | | |
| | | var DOM = React.DOM; |
| | | var DateTimePickerMonths = React.createClass({ |
| | | var react = __webpack_require__(13); |
| | | var reactDom = __webpack_require__(21); |
| | | |
| | | function _inheritsLoose(subClass, superClass) { |
| | | subClass.prototype = Object.create(superClass.prototype); |
| | | subClass.prototype.constructor = subClass; |
| | | subClass.__proto__ = superClass; |
| | | } |
| | | |
| | | function _objectWithoutProperties(source, excluded) { |
| | | if (source == null) return {}; |
| | | var target = {}; |
| | | var sourceKeys = Object.keys(source); |
| | | var key, i; |
| | | |
| | | for (i = 0; i < sourceKeys.length; i++) { |
| | | key = sourceKeys[i]; |
| | | if (excluded.indexOf(key) >= 0) continue; |
| | | target[key] = source[key]; |
| | | } |
| | | |
| | | if (Object.getOwnPropertySymbols) { |
| | | var sourceSymbolKeys = Object.getOwnPropertySymbols(source); |
| | | |
| | | for (i = 0; i < sourceSymbolKeys.length; i++) { |
| | | key = sourceSymbolKeys[i]; |
| | | if (excluded.indexOf(key) >= 0) continue; |
| | | if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; |
| | | target[key] = source[key]; |
| | | } |
| | | } |
| | | |
| | | return target; |
| | | } |
| | | |
| | | /** |
| | | * Check whether some DOM node is our Component's node. |
| | | */ |
| | | function isNodeFound(current, componentNode, ignoreClass) { |
| | | if (current === componentNode) { |
| | | return true; |
| | | } // SVG <use/> elements do not technically reside in the rendered DOM, so |
| | | // they do not have classList directly, but they offer a link to their |
| | | // corresponding element, which can have classList. This extra check is for |
| | | // that case. |
| | | // See: http://www.w3.org/TR/SVG11/struct.html#InterfaceSVGUseElement |
| | | // Discussion: https://github.com/Pomax/react-onclickoutside/pull/17 |
| | | |
| | | |
| | | if (current.correspondingElement) { |
| | | return current.correspondingElement.classList.contains(ignoreClass); |
| | | } |
| | | |
| | | return current.classList.contains(ignoreClass); |
| | | } |
| | | /** |
| | | * Try to find our node in a hierarchy of nodes, returning the document |
| | | * node as highest node if our node is not found in the path up. |
| | | */ |
| | | |
| | | function findHighest(current, componentNode, ignoreClass) { |
| | | if (current === componentNode) { |
| | | return true; |
| | | } // If source=local then this event came from 'somewhere' |
| | | // inside and should be ignored. We could handle this with |
| | | // a layered approach, too, but that requires going back to |
| | | // thinking in terms of Dom node nesting, running counter |
| | | // to React's 'you shouldn't care about the DOM' philosophy. |
| | | |
| | | |
| | | while (current.parentNode) { |
| | | if (isNodeFound(current, componentNode, ignoreClass)) { |
| | | return true; |
| | | } |
| | | |
| | | current = current.parentNode; |
| | | } |
| | | |
| | | return current; |
| | | } |
| | | /** |
| | | * Check if the browser scrollbar was clicked |
| | | */ |
| | | |
| | | function clickedScrollbar(evt) { |
| | | return document.documentElement.clientWidth <= evt.clientX || document.documentElement.clientHeight <= evt.clientY; |
| | | } |
| | | |
| | | // ideally will get replaced with external dep |
| | | // when rafrex/detect-passive-events#4 and rafrex/detect-passive-events#5 get merged in |
| | | var testPassiveEventSupport = function testPassiveEventSupport() { |
| | | if (typeof window === 'undefined' || typeof window.addEventListener !== 'function') { |
| | | return; |
| | | } |
| | | |
| | | var passive = false; |
| | | var options = Object.defineProperty({}, 'passive', { |
| | | get: function get() { |
| | | passive = true; |
| | | } |
| | | }); |
| | | |
| | | var noop = function noop() {}; |
| | | |
| | | window.addEventListener('testPassiveEventSupport', noop, options); |
| | | window.removeEventListener('testPassiveEventSupport', noop, options); |
| | | return passive; |
| | | }; |
| | | |
| | | function autoInc(seed) { |
| | | if (seed === void 0) { |
| | | seed = 0; |
| | | } |
| | | |
| | | return function () { |
| | | return ++seed; |
| | | }; |
| | | } |
| | | |
| | | var uid = autoInc(); |
| | | |
| | | var passiveEventSupport; |
| | | var handlersMap = {}; |
| | | var enabledInstances = {}; |
| | | var touchEvents = ['touchstart', 'touchmove']; |
| | | var IGNORE_CLASS_NAME = 'ignore-react-onclickoutside'; |
| | | /** |
| | | * Options for addEventHandler and removeEventHandler |
| | | */ |
| | | |
| | | function getEventHandlerOptions(instance, eventName) { |
| | | var handlerOptions = null; |
| | | var isTouchEvent = touchEvents.indexOf(eventName) !== -1; |
| | | |
| | | if (isTouchEvent && passiveEventSupport) { |
| | | handlerOptions = { |
| | | passive: !instance.props.preventDefault |
| | | }; |
| | | } |
| | | |
| | | return handlerOptions; |
| | | } |
| | | /** |
| | | * This function generates the HOC function that you'll use |
| | | * in order to impart onOutsideClick listening to an |
| | | * arbitrary component. It gets called at the end of the |
| | | * bootstrapping code to yield an instance of the |
| | | * onClickOutsideHOC function defined inside setupHOC(). |
| | | */ |
| | | |
| | | |
| | | function onClickOutsideHOC(WrappedComponent, config) { |
| | | var _class, _temp; |
| | | |
| | | return _temp = _class = |
| | | /*#__PURE__*/ |
| | | function (_Component) { |
| | | _inheritsLoose(onClickOutside, _Component); |
| | | |
| | | function onClickOutside(props) { |
| | | var _this; |
| | | |
| | | _this = _Component.call(this, props) || this; |
| | | |
| | | _this.__outsideClickHandler = function (event) { |
| | | if (typeof _this.__clickOutsideHandlerProp === 'function') { |
| | | _this.__clickOutsideHandlerProp(event); |
| | | |
| | | return; |
| | | } |
| | | |
| | | var instance = _this.getInstance(); |
| | | |
| | | if (typeof instance.props.handleClickOutside === 'function') { |
| | | instance.props.handleClickOutside(event); |
| | | return; |
| | | } |
| | | |
| | | if (typeof instance.handleClickOutside === 'function') { |
| | | instance.handleClickOutside(event); |
| | | return; |
| | | } |
| | | |
| | | throw new Error('WrappedComponent lacks a handleClickOutside(event) function for processing outside click events.'); |
| | | }; |
| | | |
| | | _this.enableOnClickOutside = function () { |
| | | if (typeof document === 'undefined' || enabledInstances[_this._uid]) { |
| | | return; |
| | | } |
| | | |
| | | if (typeof passiveEventSupport === 'undefined') { |
| | | passiveEventSupport = testPassiveEventSupport(); |
| | | } |
| | | |
| | | enabledInstances[_this._uid] = true; |
| | | var events = _this.props.eventTypes; |
| | | |
| | | if (!events.forEach) { |
| | | events = [events]; |
| | | } |
| | | |
| | | handlersMap[_this._uid] = function (event) { |
| | | if (_this.props.disableOnClickOutside) return; |
| | | if (_this.componentNode === null) return; |
| | | |
| | | if (_this.props.preventDefault) { |
| | | event.preventDefault(); |
| | | } |
| | | |
| | | if (_this.props.stopPropagation) { |
| | | event.stopPropagation(); |
| | | } |
| | | |
| | | if (_this.props.excludeScrollbar && clickedScrollbar(event)) return; |
| | | var current = event.target; |
| | | |
| | | if (findHighest(current, _this.componentNode, _this.props.outsideClickIgnoreClass) !== document) { |
| | | return; |
| | | } |
| | | |
| | | _this.__outsideClickHandler(event); |
| | | }; |
| | | |
| | | events.forEach(function (eventName) { |
| | | document.addEventListener(eventName, handlersMap[_this._uid], getEventHandlerOptions(_this, eventName)); |
| | | }); |
| | | }; |
| | | |
| | | _this.disableOnClickOutside = function () { |
| | | delete enabledInstances[_this._uid]; |
| | | var fn = handlersMap[_this._uid]; |
| | | |
| | | if (fn && typeof document !== 'undefined') { |
| | | var events = _this.props.eventTypes; |
| | | |
| | | if (!events.forEach) { |
| | | events = [events]; |
| | | } |
| | | |
| | | events.forEach(function (eventName) { |
| | | return document.removeEventListener(eventName, fn, getEventHandlerOptions(_this, eventName)); |
| | | }); |
| | | delete handlersMap[_this._uid]; |
| | | } |
| | | }; |
| | | |
| | | _this.getRef = function (ref) { |
| | | return _this.instanceRef = ref; |
| | | }; |
| | | |
| | | _this._uid = uid(); |
| | | return _this; |
| | | } |
| | | /** |
| | | * Access the WrappedComponent's instance. |
| | | */ |
| | | |
| | | |
| | | var _proto = onClickOutside.prototype; |
| | | |
| | | _proto.getInstance = function getInstance() { |
| | | if (!WrappedComponent.prototype.isReactComponent) { |
| | | return this; |
| | | } |
| | | |
| | | var ref = this.instanceRef; |
| | | return ref.getInstance ? ref.getInstance() : ref; |
| | | }; |
| | | |
| | | /** |
| | | * Add click listeners to the current document, |
| | | * linked to this component's state. |
| | | */ |
| | | _proto.componentDidMount = function componentDidMount() { |
| | | // If we are in an environment without a DOM such |
| | | // as shallow rendering or snapshots then we exit |
| | | // early to prevent any unhandled errors being thrown. |
| | | if (typeof document === 'undefined' || !document.createElement) { |
| | | return; |
| | | } |
| | | |
| | | var instance = this.getInstance(); |
| | | |
| | | if (config && typeof config.handleClickOutside === 'function') { |
| | | this.__clickOutsideHandlerProp = config.handleClickOutside(instance); |
| | | |
| | | if (typeof this.__clickOutsideHandlerProp !== 'function') { |
| | | throw new Error('WrappedComponent lacks a function for processing outside click events specified by the handleClickOutside config option.'); |
| | | } |
| | | } |
| | | |
| | | this.componentNode = reactDom.findDOMNode(this.getInstance()); |
| | | this.enableOnClickOutside(); |
| | | }; |
| | | |
| | | _proto.componentDidUpdate = function componentDidUpdate() { |
| | | this.componentNode = reactDom.findDOMNode(this.getInstance()); |
| | | }; |
| | | /** |
| | | * Remove all document's event listeners for this component |
| | | */ |
| | | |
| | | |
| | | _proto.componentWillUnmount = function componentWillUnmount() { |
| | | this.disableOnClickOutside(); |
| | | }; |
| | | /** |
| | | * Can be called to explicitly enable event listening |
| | | * for clicks and touches outside of this element. |
| | | */ |
| | | |
| | | |
| | | /** |
| | | * Pass-through render |
| | | */ |
| | | _proto.render = function render() { |
| | | // eslint-disable-next-line no-unused-vars |
| | | var _props = this.props, |
| | | excludeScrollbar = _props.excludeScrollbar, |
| | | props = _objectWithoutProperties(_props, ["excludeScrollbar"]); |
| | | |
| | | if (WrappedComponent.prototype.isReactComponent) { |
| | | props.ref = this.getRef; |
| | | } else { |
| | | props.wrappedRef = this.getRef; |
| | | } |
| | | |
| | | props.disableOnClickOutside = this.disableOnClickOutside; |
| | | props.enableOnClickOutside = this.enableOnClickOutside; |
| | | return react.createElement(WrappedComponent, props); |
| | | }; |
| | | |
| | | return onClickOutside; |
| | | }(react.Component), _class.displayName = "OnClickOutside(" + (WrappedComponent.displayName || WrappedComponent.name || 'Component') + ")", _class.defaultProps = { |
| | | eventTypes: ['mousedown', 'touchstart'], |
| | | excludeScrollbar: config && config.excludeScrollbar || false, |
| | | outsideClickIgnoreClass: IGNORE_CLASS_NAME, |
| | | preventDefault: false, |
| | | stopPropagation: false |
| | | }, _class.getClass = function () { |
| | | return WrappedComponent.getClass ? WrappedComponent.getClass() : WrappedComponent; |
| | | }, _temp; |
| | | } |
| | | |
| | | exports.IGNORE_CLASS_NAME = IGNORE_CLASS_NAME; |
| | | exports['default'] = onClickOutsideHOC; |
| | | |
| | | |
| | | /***/ }), |
| | | /* 21 */ |
| | | /***/ (function(module, exports) { |
| | | |
| | | module.exports = __WEBPACK_EXTERNAL_MODULE_21__; |
| | | |
| | | /***/ }), |
| | | /* 22 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | 'use strict'; |
| | | |
| | | var React = __webpack_require__(13), |
| | | createClass = __webpack_require__(12), |
| | | onClickOutside = __webpack_require__(20).default |
| | | ; |
| | | |
| | | var DateTimePickerMonths = onClickOutside( createClass({ |
| | | render: function() { |
| | | return DOM.div({ className: 'rdtMonths' }, [ |
| | | DOM.table({ key: 'a'}, DOM.thead({}, DOM.tr({}, [ |
| | | DOM.th({ key: 'prev', className: 'rdtPrev' }, DOM.span({onClick: this.props.subtractTime(1, 'years')}, '‹')), |
| | | DOM.th({ key: 'year', className: 'rdtSwitch', onClick: this.props.showView('years'), colSpan: 2, 'data-value': this.props.viewDate.year()}, this.props.viewDate.year() ), |
| | | DOM.th({ key: 'next', className: 'rdtNext' }, DOM.span({onClick: this.props.addTime(1, 'years')}, '›')) |
| | | return React.createElement('div', { className: 'rdtMonths' }, [ |
| | | React.createElement('table', { key: 'a' }, React.createElement('thead', {}, React.createElement('tr', {}, [ |
| | | React.createElement('th', { key: 'prev', className: 'rdtPrev', onClick: this.props.subtractTime( 1, 'years' )}, React.createElement('span', {}, '‹' )), |
| | | React.createElement('th', { key: 'year', className: 'rdtSwitch', onClick: this.props.showView( 'years' ), colSpan: 2, 'data-value': this.props.viewDate.year() }, this.props.viewDate.year() ), |
| | | React.createElement('th', { key: 'next', className: 'rdtNext', onClick: this.props.addTime( 1, 'years' )}, React.createElement('span', {}, '›' )) |
| | | ]))), |
| | | DOM.table({ key: 'months'}, DOM.tbody({ key: 'b'}, this.renderMonths())) |
| | | React.createElement('table', { key: 'months' }, React.createElement('tbody', { key: 'b' }, this.renderMonths())) |
| | | ]); |
| | | }, |
| | | |
| | |
| | | i = 0, |
| | | months = [], |
| | | renderer = this.props.renderMonth || this.renderMonth, |
| | | classes, props |
| | | ; |
| | | isValid = this.props.isValidDate || this.alwaysValidDate, |
| | | classes, props, currentMonth, isDisabled, noOfDaysInMonth, daysInMonth, validDay, |
| | | // Date is irrelevant because we're only interested in month |
| | | irrelevantDate = 1 |
| | | ; |
| | | |
| | | while (i < 12) { |
| | | classes = 'rdtMonth'; |
| | | if ( date && i === month && year === date.year() ) |
| | | currentMonth = |
| | | this.props.viewDate.clone().set({ year: year, month: i, date: irrelevantDate }); |
| | | |
| | | noOfDaysInMonth = currentMonth.endOf( 'month' ).format( 'D' ); |
| | | daysInMonth = Array.from({ length: noOfDaysInMonth }, function( e, i ) { |
| | | return i + 1; |
| | | }); |
| | | |
| | | validDay = daysInMonth.find(function( d ) { |
| | | var day = currentMonth.clone().set( 'date', d ); |
| | | return isValid( day ); |
| | | }); |
| | | |
| | | isDisabled = ( validDay === undefined ); |
| | | |
| | | if ( isDisabled ) |
| | | classes += ' rdtDisabled'; |
| | | |
| | | if ( date && i === date.month() && year === date.year() ) |
| | | classes += ' rdtActive'; |
| | | |
| | | props = { |
| | | key: i, |
| | | 'data-value': i, |
| | | className: classes, |
| | | onClick: this.props.updateOn === 'months'? this.updateSelectedMonth : this.props.setDate('month') |
| | | className: classes |
| | | }; |
| | | |
| | | months.push( renderer( props, i, year, date && date.clone() )); |
| | | if ( !isDisabled ) |
| | | props.onClick = ( this.props.updateOn === 'months' ? |
| | | this.updateSelectedMonth : this.props.setDate( 'month' ) ); |
| | | |
| | | if ( months.length === 4 ){ |
| | | rows.push( DOM.tr({ key: month + '_' + rows.length }, months) ); |
| | | months.push( renderer( props, i, year, date && date.clone() ) ); |
| | | |
| | | if ( months.length === 4 ) { |
| | | rows.push( React.createElement('tr', { key: month + '_' + rows.length }, months ) ); |
| | | months = []; |
| | | } |
| | | |
| | |
| | | }, |
| | | |
| | | updateSelectedMonth: function( event ) { |
| | | this.props.updateSelectedDate(event, true); |
| | | this.props.updateSelectedDate( event ); |
| | | }, |
| | | |
| | | renderMonth: function( props, month ) { |
| | | var monthsShort = this.props.viewDate.localeData()._monthsShort; |
| | | return DOM.td( props, monthsShort.standalone |
| | | ? capitalize( monthsShort.standalone[ month ] ) |
| | | : monthsShort[ month ] |
| | | ); |
| | | } |
| | | }); |
| | | var localMoment = this.props.viewDate; |
| | | var monthStr = localMoment.localeData().monthsShort( localMoment.month( month ) ); |
| | | var strLength = 3; |
| | | // Because some months are up to 5 characters long, we want to |
| | | // use a fixed string length for consistency |
| | | var monthStrFixedLength = monthStr.substring( 0, strLength ); |
| | | return React.createElement('td', props, capitalize( monthStrFixedLength ) ); |
| | | }, |
| | | |
| | | function capitalize(str) { |
| | | return str.charAt(0).toUpperCase() + str.slice(1); |
| | | alwaysValidDate: function() { |
| | | return 1; |
| | | }, |
| | | |
| | | handleClickOutside: function() { |
| | | this.props.handleClickOutside(); |
| | | } |
| | | })); |
| | | |
| | | function capitalize( str ) { |
| | | return str.charAt( 0 ).toUpperCase() + str.slice( 1 ); |
| | | } |
| | | |
| | | module.exports = DateTimePickerMonths; |
| | | |
| | | |
| | | /***/ }, |
| | | /* 6 */ |
| | | /***/ function(module, exports, __webpack_require__) { |
| | | /***/ }), |
| | | /* 23 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | 'use strict'; |
| | | |
| | | var React = __webpack_require__(2); |
| | | var React = __webpack_require__(13), |
| | | createClass = __webpack_require__(12), |
| | | onClickOutside = __webpack_require__(20).default |
| | | ; |
| | | |
| | | var DOM = React.DOM; |
| | | var DateTimePickerYears = React.createClass({ |
| | | var DateTimePickerYears = onClickOutside( createClass({ |
| | | render: function() { |
| | | var year = parseInt(this.props.viewDate.year() / 10, 10) * 10; |
| | | var year = parseInt( this.props.viewDate.year() / 10, 10 ) * 10; |
| | | |
| | | return DOM.div({ className: 'rdtYears' }, [ |
| | | DOM.table({ key: 'a'}, DOM.thead({}, DOM.tr({}, [ |
| | | DOM.th({ key: 'prev', className: 'rdtPrev' }, DOM.span({onClick: this.props.subtractTime(10, 'years')}, '‹')), |
| | | DOM.th({ key: 'year', className: 'rdtSwitch', onClick: this.props.showView('years'), colSpan: 2 }, year + '-' + (year + 9) ), |
| | | DOM.th({ key: 'next', className: 'rdtNext'}, DOM.span({onClick: this.props.addTime(10, 'years')}, '›')) |
| | | ]))), |
| | | DOM.table({ key: 'years'}, DOM.tbody({}, this.renderYears( year ))) |
| | | return React.createElement('div', { className: 'rdtYears' }, [ |
| | | React.createElement('table', { key: 'a' }, React.createElement('thead', {}, React.createElement('tr', {}, [ |
| | | React.createElement('th', { key: 'prev', className: 'rdtPrev', onClick: this.props.subtractTime( 10, 'years' )}, React.createElement('span', {}, '‹' )), |
| | | React.createElement('th', { key: 'year', className: 'rdtSwitch', onClick: this.props.showView( 'years' ), colSpan: 2 }, year + '-' + ( year + 9 ) ), |
| | | React.createElement('th', { key: 'next', className: 'rdtNext', onClick: this.props.addTime( 10, 'years' )}, React.createElement('span', {}, '›' )) |
| | | ]))), |
| | | React.createElement('table', { key: 'years' }, React.createElement('tbody', {}, this.renderYears( year ))) |
| | | ]); |
| | | }, |
| | | |
| | |
| | | rows = [], |
| | | renderer = this.props.renderYear || this.renderYear, |
| | | selectedDate = this.props.selectedDate, |
| | | classes, props |
| | | ; |
| | | isValid = this.props.isValidDate || this.alwaysValidDate, |
| | | classes, props, currentYear, isDisabled, noOfDaysInYear, daysInYear, validDay, |
| | | // Month and date are irrelevant here because |
| | | // we're only interested in the year |
| | | irrelevantMonth = 0, |
| | | irrelevantDate = 1 |
| | | ; |
| | | |
| | | year--; |
| | | while (i < 11) { |
| | | classes = 'rdtYear'; |
| | | if ( i === -1 | i === 10 ) |
| | | classes += ' rdtOld'; |
| | | currentYear = this.props.viewDate.clone().set( |
| | | { year: year, month: irrelevantMonth, date: irrelevantDate } ); |
| | | |
| | | // Not sure what 'rdtOld' is for, commenting out for now as it's not working properly |
| | | // if ( i === -1 | i === 10 ) |
| | | // classes += ' rdtOld'; |
| | | |
| | | noOfDaysInYear = currentYear.endOf( 'year' ).format( 'DDD' ); |
| | | daysInYear = Array.from({ length: noOfDaysInYear }, function( e, i ) { |
| | | return i + 1; |
| | | }); |
| | | |
| | | validDay = daysInYear.find(function( d ) { |
| | | var day = currentYear.clone().dayOfYear( d ); |
| | | return isValid( day ); |
| | | }); |
| | | |
| | | isDisabled = ( validDay === undefined ); |
| | | |
| | | if ( isDisabled ) |
| | | classes += ' rdtDisabled'; |
| | | |
| | | if ( selectedDate && selectedDate.year() === year ) |
| | | classes += ' rdtActive'; |
| | | |
| | | props = { |
| | | key: year, |
| | | 'data-value': year, |
| | | className: classes, |
| | | onClick: this.props.updateOn === 'years' ? this.updateSelectedYear : this.props.setDate('year') |
| | | className: classes |
| | | }; |
| | | |
| | | if ( !isDisabled ) |
| | | props.onClick = ( this.props.updateOn === 'years' ? |
| | | this.updateSelectedYear : this.props.setDate('year') ); |
| | | |
| | | years.push( renderer( props, year, selectedDate && selectedDate.clone() )); |
| | | |
| | | if ( years.length === 4 ){ |
| | | rows.push( DOM.tr({ key: i }, years ) ); |
| | | if ( years.length === 4 ) { |
| | | rows.push( React.createElement('tr', { key: i }, years ) ); |
| | | years = []; |
| | | } |
| | | |
| | |
| | | }, |
| | | |
| | | updateSelectedYear: function( event ) { |
| | | this.props.updateSelectedDate(event, true); |
| | | this.props.updateSelectedDate( event ); |
| | | }, |
| | | |
| | | renderYear: function( props, year ){ |
| | | return DOM.td( props, year ); |
| | | renderYear: function( props, year ) { |
| | | return React.createElement('td', props, year ); |
| | | }, |
| | | |
| | | alwaysValidDate: function() { |
| | | return 1; |
| | | }, |
| | | |
| | | handleClickOutside: function() { |
| | | this.props.handleClickOutside(); |
| | | } |
| | | }); |
| | | })); |
| | | |
| | | module.exports = DateTimePickerYears; |
| | | |
| | | |
| | | /***/ }, |
| | | /* 7 */ |
| | | /***/ function(module, exports, __webpack_require__) { |
| | | /***/ }), |
| | | /* 24 */ |
| | | /***/ (function(module, exports, __webpack_require__) { |
| | | |
| | | 'use strict'; |
| | | |
| | | var React = __webpack_require__(2), |
| | | assign = __webpack_require__(1); |
| | | var React = __webpack_require__(13), |
| | | createClass = __webpack_require__(12), |
| | | assign = __webpack_require__(1), |
| | | onClickOutside = __webpack_require__(20).default |
| | | ; |
| | | |
| | | var DOM = React.DOM; |
| | | var DateTimePickerTime = React.createClass({ |
| | | getInitialState: function(){ |
| | | var DateTimePickerTime = onClickOutside( createClass({ |
| | | getInitialState: function() { |
| | | return this.calculateState( this.props ); |
| | | }, |
| | | calculateState: function( props ){ |
| | | |
| | | calculateState: function( props ) { |
| | | var date = props.selectedDate || props.viewDate, |
| | | format = props.timeFormat, |
| | | counters = [] |
| | | ; |
| | | ; |
| | | |
| | | if ( format.indexOf('H') !== -1 || format.indexOf('h') !== -1 ){ |
| | | if ( format.toLowerCase().indexOf('h') !== -1 ) { |
| | | counters.push('hours'); |
| | | if ( format.indexOf('m') !== -1 ){ |
| | | if ( format.indexOf('m') !== -1 ) { |
| | | counters.push('minutes'); |
| | | if ( format.indexOf('s') !== -1 ){ |
| | | if ( format.indexOf('s') !== -1 ) { |
| | | counters.push('seconds'); |
| | | } |
| | | } |
| | | } |
| | | |
| | | var hours = date.format( 'H' ); |
| | | |
| | | var daypart = false; |
| | | if ( this.props.timeFormat.indexOf(' A') !== -1 && this.state !== null ){ |
| | | daypart = ( this.state.hours >= 12 ) ? 'PM' : 'AM'; |
| | | if ( this.state !== null && this.props.timeFormat.toLowerCase().indexOf( ' a' ) !== -1 ) { |
| | | if ( this.props.timeFormat.indexOf( ' A' ) !== -1 ) { |
| | | daypart = ( hours >= 12 ) ? 'PM' : 'AM'; |
| | | } else { |
| | | daypart = ( hours >= 12 ) ? 'pm' : 'am'; |
| | | } |
| | | } |
| | | |
| | | return { |
| | | hours: date.format('H'), |
| | | minutes: date.format('mm'), |
| | | seconds: date.format('ss'), |
| | | milliseconds: date.format('SSS'), |
| | | hours: hours, |
| | | minutes: date.format( 'mm' ), |
| | | seconds: date.format( 'ss' ), |
| | | milliseconds: date.format( 'SSS' ), |
| | | daypart: daypart, |
| | | counters: counters |
| | | }; |
| | | }, |
| | | renderCounter: function( type ){ |
| | | if (type !== 'daypart') { |
| | | var value = this.state[ type ]; |
| | | if (type === 'hours' && this.props.timeFormat.indexOf(' A') !== -1) { |
| | | value = (value - 1) % 12 + 1; |
| | | |
| | | if (value === 0) { |
| | | renderCounter: function( type ) { |
| | | if ( type !== 'daypart' ) { |
| | | var value = this.state[ type ]; |
| | | if ( type === 'hours' && this.props.timeFormat.toLowerCase().indexOf( ' a' ) !== -1 ) { |
| | | value = ( value - 1 ) % 12 + 1; |
| | | |
| | | if ( value === 0 ) { |
| | | value = 12; |
| | | } |
| | | } |
| | | return DOM.div({ key: type, className: 'rdtCounter'}, [ |
| | | DOM.span({ key:'up', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'increase', type ) }, 'â–²' ), |
| | | DOM.div({ key:'c', className: 'rdtCount' }, value ), |
| | | DOM.span({ key:'do', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'decrease', type ) }, 'â–¼' ) |
| | | return React.createElement('div', { key: type, className: 'rdtCounter' }, [ |
| | | React.createElement('span', { key: 'up', className: 'rdtBtn', onTouchStart: this.onStartClicking('increase', type), onMouseDown: this.onStartClicking( 'increase', type ), onContextMenu: this.disableContextMenu }, 'â–²' ), |
| | | React.createElement('div', { key: 'c', className: 'rdtCount' }, value ), |
| | | React.createElement('span', { key: 'do', className: 'rdtBtn', onTouchStart: this.onStartClicking('decrease', type), onMouseDown: this.onStartClicking( 'decrease', type ), onContextMenu: this.disableContextMenu }, 'â–¼' ) |
| | | ]); |
| | | } |
| | | return ''; |
| | | }, |
| | | |
| | | renderDayPart: function() { |
| | | return DOM.div({ className: 'rdtCounter', key: 'dayPart'}, [ |
| | | DOM.span({ key:'up', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'toggleDayPart', 'hours') }, 'â–²' ), |
| | | DOM.div({ key: this.state.daypart, className: 'rdtCount'}, this.state.daypart ), |
| | | DOM.span({ key:'do', className: 'rdtBtn', onMouseDown: this.onStartClicking( 'toggleDayPart', 'hours') }, 'â–¼' ) |
| | | return React.createElement('div', { key: 'dayPart', className: 'rdtCounter' }, [ |
| | | React.createElement('span', { key: 'up', className: 'rdtBtn', onTouchStart: this.onStartClicking('toggleDayPart', 'hours'), onMouseDown: this.onStartClicking( 'toggleDayPart', 'hours'), onContextMenu: this.disableContextMenu }, 'â–²' ), |
| | | React.createElement('div', { key: this.state.daypart, className: 'rdtCount' }, this.state.daypart ), |
| | | React.createElement('span', { key: 'do', className: 'rdtBtn', onTouchStart: this.onStartClicking('toggleDayPart', 'hours'), onMouseDown: this.onStartClicking( 'toggleDayPart', 'hours'), onContextMenu: this.disableContextMenu }, 'â–¼' ) |
| | | ]); |
| | | }, |
| | | |
| | | render: function() { |
| | | var me = this, |
| | | counters = [] |
| | | ; |
| | | |
| | | this.state.counters.forEach( function(c){ |
| | | this.state.counters.forEach( function( c ) { |
| | | if ( counters.length ) |
| | | counters.push( DOM.div( {key: 'sep' + counters.length, className: 'rdtCounterSeparator' }, ':' )); |
| | | counters.push( React.createElement('div', { key: 'sep' + counters.length, className: 'rdtCounterSeparator' }, ':' ) ); |
| | | counters.push( me.renderCounter( c ) ); |
| | | }); |
| | | |
| | | if (this.state.daypart !== false) { |
| | | if ( this.state.daypart !== false ) { |
| | | counters.push( me.renderDayPart() ); |
| | | } |
| | | |
| | | if ( this.state.counters.length === 3 && this.props.timeFormat.indexOf('S') !== -1 ){ |
| | | counters.push( DOM.div( {className: 'rdtCounterSeparator', key: 'sep5' }, ':' )); |
| | | if ( this.state.counters.length === 3 && this.props.timeFormat.indexOf( 'S' ) !== -1 ) { |
| | | counters.push( React.createElement('div', { className: 'rdtCounterSeparator', key: 'sep5' }, ':' ) ); |
| | | counters.push( |
| | | DOM.div( {className: 'rdtCounter rdtMilli', key:'m'}, |
| | | DOM.input({ value: this.state.milliseconds, type: 'text', onChange: this.updateMilli }) |
| | | React.createElement('div', { className: 'rdtCounter rdtMilli', key: 'm' }, |
| | | React.createElement('input', { value: this.state.milliseconds, type: 'text', onChange: this.updateMilli } ) |
| | | ) |
| | | ); |
| | | } |
| | | |
| | | return DOM.div( {className: 'rdtTime'}, |
| | | DOM.table( {}, [ |
| | | return React.createElement('div', { className: 'rdtTime' }, |
| | | React.createElement('table', {}, [ |
| | | this.renderHeader(), |
| | | DOM.tbody({key: 'b'}, DOM.tr({}, DOM.td({}, |
| | | DOM.div({ className: 'rdtCounters' }, counters ) |
| | | React.createElement('tbody', { key: 'b'}, React.createElement('tr', {}, React.createElement('td', {}, |
| | | React.createElement('div', { className: 'rdtCounters' }, counters ) |
| | | ))) |
| | | ]) |
| | | ); |
| | | }, |
| | | |
| | | componentWillMount: function() { |
| | | var me = this; |
| | | me.timeConstraints = { |
| | |
| | | seconds: { |
| | | min: 0, |
| | | max: 59, |
| | | step: 1, |
| | | step: 1 |
| | | }, |
| | | milliseconds: { |
| | | min: 0, |
| | |
| | | step: 1 |
| | | } |
| | | }; |
| | | ['hours', 'minutes', 'seconds', 'milliseconds'].forEach(function(type) { |
| | | assign(me.timeConstraints[type], me.props.timeConstraints[type]); |
| | | ['hours', 'minutes', 'seconds', 'milliseconds'].forEach( function( type ) { |
| | | assign(me.timeConstraints[ type ], me.props.timeConstraints[ type ]); |
| | | }); |
| | | this.setState( this.calculateState( this.props ) ); |
| | | }, |
| | | componentWillReceiveProps: function( nextProps ){ |
| | | |
| | | componentWillReceiveProps: function( nextProps ) { |
| | | this.setState( this.calculateState( nextProps ) ); |
| | | }, |
| | | updateMilli: function( e ){ |
| | | |
| | | updateMilli: function( e ) { |
| | | var milli = parseInt( e.target.value, 10 ); |
| | | if ( milli === e.target.value && milli >= 0 && milli < 1000 ){ |
| | | if ( milli === e.target.value && milli >= 0 && milli < 1000 ) { |
| | | this.props.setTime( 'milliseconds', milli ); |
| | | this.setState({ milliseconds: milli }); |
| | | this.setState( { milliseconds: milli } ); |
| | | } |
| | | }, |
| | | renderHeader: function(){ |
| | | |
| | | renderHeader: function() { |
| | | if ( !this.props.dateFormat ) |
| | | return null; |
| | | |
| | | var date = this.props.selectedDate || this.props.viewDate; |
| | | return DOM.thead({ key: 'h'}, DOM.tr({}, |
| | | DOM.th( {className: 'rdtSwitch', colSpan: 4, onClick: this.props.showView('days')}, date.format( this.props.dateFormat ) ) |
| | | return React.createElement('thead', { key: 'h' }, React.createElement('tr', {}, |
| | | React.createElement('th', { className: 'rdtSwitch', colSpan: 4, onClick: this.props.showView( 'days' ) }, date.format( this.props.dateFormat ) ) |
| | | )); |
| | | }, |
| | | onStartClicking: function( action, type ){ |
| | | |
| | | onStartClicking: function( action, type ) { |
| | | var me = this; |
| | | |
| | | return function(){ |
| | | return function() { |
| | | var update = {}; |
| | | update[ type ] = me[ action ]( type ); |
| | | me.setState( update ); |
| | | |
| | | me.timer = setTimeout( function(){ |
| | | me.increaseTimer = setInterval( function(){ |
| | | me.timer = setTimeout( function() { |
| | | me.increaseTimer = setInterval( function() { |
| | | update[ type ] = me[ action ]( type ); |
| | | me.setState( update ); |
| | | }, 70); |
| | | }, 500); |
| | | |
| | | me.mouseUpListener = function(){ |
| | | me.mouseUpListener = function() { |
| | | clearTimeout( me.timer ); |
| | | clearInterval( me.increaseTimer ); |
| | | me.props.setTime( type, me.state[ type ] ); |
| | | document.body.removeEventListener('mouseup', me.mouseUpListener); |
| | | document.body.removeEventListener( 'mouseup', me.mouseUpListener ); |
| | | document.body.removeEventListener( 'touchend', me.mouseUpListener ); |
| | | }; |
| | | |
| | | document.body.addEventListener('mouseup', me.mouseUpListener); |
| | | document.body.addEventListener( 'mouseup', me.mouseUpListener ); |
| | | document.body.addEventListener( 'touchend', me.mouseUpListener ); |
| | | }; |
| | | }, |
| | | |
| | | disableContextMenu: function( event ) { |
| | | event.preventDefault(); |
| | | return false; |
| | | }, |
| | | |
| | | padValues: { |
| | | hours: 1, |
| | | minutes: 2, |
| | | seconds: 2, |
| | | milliseconds: 3 |
| | | }, |
| | | toggleDayPart: function( type ){ // type is always 'hours' |
| | | var value = parseInt(this.state[ type ], 10) + 12; |
| | | |
| | | toggleDayPart: function( type ) { // type is always 'hours' |
| | | var value = parseInt( this.state[ type ], 10) + 12; |
| | | if ( value > this.timeConstraints[ type ].max ) |
| | | value = this.timeConstraints[ type ].min + (value - (this.timeConstraints[ type ].max + 1)); |
| | | value = this.timeConstraints[ type ].min + ( value - ( this.timeConstraints[ type ].max + 1 ) ); |
| | | return this.pad( type, value ); |
| | | }, |
| | | increase: function( type ){ |
| | | var value = parseInt(this.state[ type ], 10) + this.timeConstraints[ type ].step; |
| | | |
| | | increase: function( type ) { |
| | | var value = parseInt( this.state[ type ], 10) + this.timeConstraints[ type ].step; |
| | | if ( value > this.timeConstraints[ type ].max ) |
| | | value = this.timeConstraints[ type ].min + ( value - ( this.timeConstraints[ type ].max + 1) ); |
| | | value = this.timeConstraints[ type ].min + ( value - ( this.timeConstraints[ type ].max + 1 ) ); |
| | | return this.pad( type, value ); |
| | | }, |
| | | decrease: function( type ){ |
| | | var value = parseInt(this.state[ type ], 10) - this.timeConstraints[ type ].step; |
| | | |
| | | decrease: function( type ) { |
| | | var value = parseInt( this.state[ type ], 10) - this.timeConstraints[ type ].step; |
| | | if ( value < this.timeConstraints[ type ].min ) |
| | | value = this.timeConstraints[ type ].max + 1 - ( this.timeConstraints[ type ].min - value ); |
| | | return this.pad( type, value ); |
| | | }, |
| | | pad: function( type, value ){ |
| | | |
| | | pad: function( type, value ) { |
| | | var str = value + ''; |
| | | while ( str.length < this.padValues[ type ] ) |
| | | str = '0' + str; |
| | | return str; |
| | | }, |
| | | |
| | | handleClickOutside: function() { |
| | | this.props.handleClickOutside(); |
| | | } |
| | | }); |
| | | })); |
| | | |
| | | module.exports = DateTimePickerTime; |
| | | |
| | | |
| | | /***/ }, |
| | | /* 8 */ |
| | | /***/ function(module, exports, __webpack_require__) { |
| | | |
| | | 'use strict'; |
| | | |
| | | // This is extracted from https://github.com/Pomax/react-onclickoutside |
| | | // And modified to support react 0.13 and react 0.14 |
| | | |
| | | var React = __webpack_require__(2), |
| | | version = React.version && React.version.split('.') |
| | | ; |
| | | |
| | | if ( version && ( version[0] > 0 || version[1] > 13 ) ) |
| | | React = __webpack_require__(9); |
| | | |
| | | // Use a parallel array because we can't use |
| | | // objects as keys, they get toString-coerced |
| | | var registeredComponents = []; |
| | | var handlers = []; |
| | | |
| | | var IGNORE_CLASS = 'ignore-react-onclickoutside'; |
| | | |
| | | var isSourceFound = function(source, localNode) { |
| | | if (source === localNode) { |
| | | return true; |
| | | } |
| | | // SVG <use/> elements do not technically reside in the rendered DOM, so |
| | | // they do not have classList directly, but they offer a link to their |
| | | // corresponding element, which can have classList. This extra check is for |
| | | // that case. |
| | | // See: http://www.w3.org/TR/SVG11/struct.html#InterfaceSVGUseElement |
| | | // Discussion: https://github.com/Pomax/react-onclickoutside/pull/17 |
| | | if (source.correspondingElement) { |
| | | return source.correspondingElement.classList.contains(IGNORE_CLASS); |
| | | } |
| | | return source.classList.contains(IGNORE_CLASS); |
| | | }; |
| | | |
| | | module.exports = { |
| | | componentDidMount: function() { |
| | | if (typeof this.handleClickOutside !== 'function') |
| | | throw new Error('Component lacks a handleClickOutside(event) function for processing outside click events.'); |
| | | |
| | | var fn = this.__outsideClickHandler = (function(localNode, eventHandler) { |
| | | return function(evt) { |
| | | evt.stopPropagation(); |
| | | var source = evt.target; |
| | | var found = false; |
| | | // If source=local then this event came from "somewhere" |
| | | // inside and should be ignored. We could handle this with |
| | | // a layered approach, too, but that requires going back to |
| | | // thinking in terms of Dom node nesting, running counter |
| | | // to React's "you shouldn't care about the DOM" philosophy. |
| | | while (source.parentNode) { |
| | | found = isSourceFound(source, localNode); |
| | | if (found) return; |
| | | source = source.parentNode; |
| | | } |
| | | eventHandler(evt); |
| | | }; |
| | | }(React.findDOMNode(this), this.handleClickOutside)); |
| | | |
| | | var pos = registeredComponents.length; |
| | | registeredComponents.push(this); |
| | | handlers[pos] = fn; |
| | | |
| | | // If there is a truthy disableOnClickOutside property for this |
| | | // component, don't immediately start listening for outside events. |
| | | if (!this.props.disableOnClickOutside) { |
| | | this.enableOnClickOutside(); |
| | | } |
| | | }, |
| | | |
| | | componentWillUnmount: function() { |
| | | this.disableOnClickOutside(); |
| | | this.__outsideClickHandler = false; |
| | | var pos = registeredComponents.indexOf(this); |
| | | if ( pos>-1) { |
| | | if (handlers[pos]) { |
| | | // clean up so we don't leak memory |
| | | handlers.splice(pos, 1); |
| | | registeredComponents.splice(pos, 1); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * Can be called to explicitly enable event listening |
| | | * for clicks and touches outside of this element. |
| | | */ |
| | | enableOnClickOutside: function() { |
| | | var fn = this.__outsideClickHandler; |
| | | document.addEventListener('mousedown', fn); |
| | | document.addEventListener('touchstart', fn); |
| | | }, |
| | | |
| | | /** |
| | | * Can be called to explicitly disable event listening |
| | | * for clicks and touches outside of this element. |
| | | */ |
| | | disableOnClickOutside: function() { |
| | | var fn = this.__outsideClickHandler; |
| | | document.removeEventListener('mousedown', fn); |
| | | document.removeEventListener('touchstart', fn); |
| | | } |
| | | }; |
| | | |
| | | |
| | | /***/ }, |
| | | /* 9 */ |
| | | /***/ function(module, exports) { |
| | | |
| | | module.exports = __WEBPACK_EXTERNAL_MODULE_9__; |
| | | |
| | | /***/ } |
| | | /***/ }) |
| | | /******/ ]) |
| | | }); |
| | | ; |
| | | //# sourceMappingURL=react-datetime.js.map |
| | | //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJyZWFjdC1kYXRldGltZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gd2VicGFja1VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24ocm9vdCwgZmFjdG9yeSkge1xuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCJSZWFjdFwiKSwgcmVxdWlyZShcIm1vbWVudFwiKSwgcmVxdWlyZShcIlJlYWN0RE9NXCIpKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtcIlJlYWN0XCIsIFwibW9tZW50XCIsIFwiUmVhY3RET01cIl0sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiRGF0ZXRpbWVcIl0gPSBmYWN0b3J5KHJlcXVpcmUoXCJSZWFjdFwiKSwgcmVxdWlyZShcIm1vbWVudFwiKSwgcmVxdWlyZShcIlJlYWN0RE9NXCIpKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJEYXRldGltZVwiXSA9IGZhY3Rvcnkocm9vdFtcIlJlYWN0XCJdLCByb290W1wibW9tZW50XCJdLCByb290W1wiUmVhY3RET01cIl0pO1xufSkodGhpcywgZnVuY3Rpb24oX19XRUJQQUNLX0VYVEVSTkFMX01PRFVMRV8yX18sIF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfNF9fLCBfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFXzlfXykge1xucmV0dXJuIC8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4vKioqKioqLyBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4vKioqKioqLyBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuLyoqKioqKi8gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuLyoqKioqKi8gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKVxuLyoqKioqKi8gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuLyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9LFxuLyoqKioqKi8gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuLyoqKioqKi8gXHRcdFx0bG9hZGVkOiBmYWxzZVxuLyoqKioqKi8gXHRcdH07XG5cbi8qKioqKiovIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbi8qKioqKiovIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuLyoqKioqKi8gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbi8qKioqKiovIFx0XHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHR9XG5cblxuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuLyoqKioqKi8gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oMCk7XG4vKioqKioqLyB9KVxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qKioqKiovIChbXG4vKiAwICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIGFzc2lnbiA9IF9fd2VicGFja19yZXF1aXJlX18oMSksXG5cdFx0UmVhY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIpLFxuXHRcdERheXNWaWV3ID0gX193ZWJwYWNrX3JlcXVpcmVfXygzKSxcblx0XHRNb250aHNWaWV3ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg1KSxcblx0XHRZZWFyc1ZpZXcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpLFxuXHRcdFRpbWVWaWV3ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3KSxcblx0XHRtb21lbnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpXG5cdDtcblxuXHR2YXIgVFlQRVMgPSBSZWFjdC5Qcm9wVHlwZXM7XG5cdHZhciBEYXRldGltZSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0XHRtaXhpbnM6IFtcblx0XHRcdF9fd2VicGFja19yZXF1aXJlX18oOClcblx0XHRdLFxuXHRcdHZpZXdDb21wb25lbnRzOiB7XG5cdFx0XHRkYXlzOiBEYXlzVmlldyxcblx0XHRcdG1vbnRoczogTW9udGhzVmlldyxcblx0XHRcdHllYXJzOiBZZWFyc1ZpZXcsXG5cdFx0XHR0aW1lOiBUaW1lVmlld1xuXHRcdH0sXG5cdFx0cHJvcFR5cGVzOiB7XG5cdFx0XHQvLyB2YWx1ZTogVFlQRVMub2JqZWN0IHwgVFlQRVMuc3RyaW5nLFxuXHRcdFx0Ly8gZGVmYXVsdFZhbHVlOiBUWVBFUy5vYmplY3QgfCBUWVBFUy5zdHJpbmcsXG5cdFx0XHRvbkZvY3VzOiBUWVBFUy5mdW5jLFxuXHRcdFx0b25CbHVyOiBUWVBFUy5mdW5jLFxuXHRcdFx0b25DaGFuZ2U6IFRZUEVTLmZ1bmMsXG5cdFx0XHRsb2NhbGU6IFRZUEVTLnN0cmluZyxcblx0XHRcdGlucHV0OiBUWVBFUy5ib29sLFxuXHRcdFx0Ly8gZGF0ZUZvcm1hdDogVFlQRVMuc3RyaW5nIHwgVFlQRVMuYm9vbCxcblx0XHRcdC8vIHRpbWVGb3JtYXQ6IFRZUEVTLnN0cmluZyB8IFRZUEVTLmJvb2wsXG5cdFx0XHRpbnB1dFByb3BzOiBUWVBFUy5vYmplY3QsXG5cdFx0XHR0aW1lQ29uc3RyYWludHM6IFRZUEVTLm9iamVjdCxcblx0XHRcdHZpZXdNb2RlOiBUWVBFUy5vbmVPZihbJ3llYXJzJywgJ21vbnRocycsICdkYXlzJywgJ3RpbWUnXSksXG5cdFx0XHRpc1ZhbGlkRGF0ZTogVFlQRVMuZnVuYyxcblx0XHRcdG9wZW46IFRZUEVTLmJvb2wsXG5cdFx0XHRzdHJpY3RQYXJzaW5nOiBUWVBFUy5ib29sLFxuXHRcdFx0Y2xvc2VPblNlbGVjdDogVFlQRVMuYm9vbCxcblx0XHRcdGNsb3NlT25UYWI6IFRZUEVTLmJvb2xcblx0XHR9LFxuXG5cdFx0Z2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBub2YgPSBmdW5jdGlvbigpe307XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRjbGFzc05hbWU6ICcnLFxuXHRcdFx0XHRkZWZhdWx0VmFsdWU6ICcnLFxuXHRcdFx0XHRpbnB1dFByb3BzOiB7fSxcblx0XHRcdFx0aW5wdXQ6IHRydWUsXG5cdFx0XHRcdG9uRm9jdXM6IG5vZixcblx0XHRcdFx0b25CbHVyOiBub2YsXG5cdFx0XHRcdG9uQ2hhbmdlOiBub2YsXG5cdFx0XHRcdHRpbWVGb3JtYXQ6IHRydWUsXG5cdFx0XHRcdHRpbWVDb25zdHJhaW50czoge30sXG5cdFx0XHRcdGRhdGVGb3JtYXQ6IHRydWUsXG5cdFx0XHRcdHN0cmljdFBhcnNpbmc6IHRydWUsXG5cdFx0XHRcdGNsb3NlT25TZWxlY3Q6IGZhbHNlLFxuXHRcdFx0XHRjbG9zZU9uVGFiOiB0cnVlXG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHN0YXRlID0gdGhpcy5nZXRTdGF0ZUZyb21Qcm9wcyggdGhpcy5wcm9wcyApO1xuXG5cdFx0XHRpZiAoIHN0YXRlLm9wZW4gPT09IHVuZGVmaW5lZCApXG5cdFx0XHRcdHN0YXRlLm9wZW4gPSAhdGhpcy5wcm9wcy5pbnB1dDtcblxuXHRcdFx0c3RhdGUuY3VycmVudFZpZXcgPSB0aGlzLnByb3BzLmRhdGVGb3JtYXQgPyAodGhpcy5wcm9wcy52aWV3TW9kZSB8fCBzdGF0ZS51cGRhdGVPbiB8fCAnZGF5cycpIDogJ3RpbWUnO1xuXG5cdFx0XHRyZXR1cm4gc3RhdGU7XG5cdFx0fSxcblxuXHRcdGdldFN0YXRlRnJvbVByb3BzOiBmdW5jdGlvbiggcHJvcHMgKXtcblx0XHRcdHZhciBmb3JtYXRzID0gdGhpcy5nZXRGb3JtYXRzKCBwcm9wcyApLFxuXHRcdFx0XHRkYXRlID0gcHJvcHMudmFsdWUgfHwgcHJvcHMuZGVmYXVsdFZhbHVlLFxuXHRcdFx0XHRzZWxlY3RlZERhdGUsIHZpZXdEYXRlLCB1cGRhdGVPbiwgaW5wdXRWYWx1ZVxuXHRcdFx0O1xuXG5cdFx0XHRpZiAoIGRhdGUgJiYgdHlwZW9mIGRhdGUgPT09ICdzdHJpbmcnIClcblx0XHRcdFx0c2VsZWN0ZWREYXRlID0gdGhpcy5sb2NhbE1vbWVudCggZGF0ZSwgZm9ybWF0cy5kYXRldGltZSApO1xuXHRcdFx0ZWxzZSBpZiAoIGRhdGUgKVxuXHRcdFx0XHRzZWxlY3RlZERhdGUgPSB0aGlzLmxvY2FsTW9tZW50KCBkYXRlICk7XG5cblx0XHRcdGlmICggc2VsZWN0ZWREYXRlICYmICFzZWxlY3RlZERhdGUuaXNWYWxpZCgpIClcblx0XHRcdFx0c2VsZWN0ZWREYXRlID0gbnVsbDtcblxuXHRcdFx0dmlld0RhdGUgPSBzZWxlY3RlZERhdGUgP1xuXHRcdFx0XHRzZWxlY3RlZERhdGUuY2xvbmUoKS5zdGFydE9mKCdtb250aCcpIDpcblx0XHRcdFx0dGhpcy5sb2NhbE1vbWVudCgpLnN0YXJ0T2YoJ21vbnRoJylcblx0XHRcdDtcblxuXHRcdFx0dXBkYXRlT24gPSB0aGlzLmdldFVwZGF0ZU9uKGZvcm1hdHMpO1xuXG5cdFx0XHRpZiAoIHNlbGVjdGVkRGF0ZSApXG5cdFx0XHRcdGlucHV0VmFsdWUgPSBzZWxlY3RlZERhdGUuZm9ybWF0KGZvcm1hdHMuZGF0ZXRpbWUpO1xuXHRcdFx0ZWxzZSBpZiAoIGRhdGUuaXNWYWxpZCAmJiAhZGF0ZS5pc1ZhbGlkKCkgKVxuXHRcdFx0XHRpbnB1dFZhbHVlID0gJyc7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdGlucHV0VmFsdWUgPSBkYXRlIHx8ICcnO1xuXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHR1cGRhdGVPbjogdXBkYXRlT24sXG5cdFx0XHRcdGlucHV0Rm9ybWF0OiBmb3JtYXRzLmRhdGV0aW1lLFxuXHRcdFx0XHR2aWV3RGF0ZTogdmlld0RhdGUsXG5cdFx0XHRcdHNlbGVjdGVkRGF0ZTogc2VsZWN0ZWREYXRlLFxuXHRcdFx0XHRpbnB1dFZhbHVlOiBpbnB1dFZhbHVlLFxuXHRcdFx0XHRvcGVuOiBwcm9wcy5vcGVuXG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRnZXRVcGRhdGVPbjogZnVuY3Rpb24oZm9ybWF0cyl7XG5cdFx0XHRpZiAoIGZvcm1hdHMuZGF0ZS5tYXRjaCgvW2xMRF0vKSApe1xuXHRcdFx0XHRyZXR1cm4gJ2RheXMnO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSBpZiAoIGZvcm1hdHMuZGF0ZS5pbmRleE9mKCdNJykgIT09IC0xICl7XG5cdFx0XHRcdHJldHVybiAnbW9udGhzJztcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKCBmb3JtYXRzLmRhdGUuaW5kZXhPZignWScpICE9PSAtMSApe1xuXHRcdFx0XHRyZXR1cm4gJ3llYXJzJztcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuICdkYXlzJztcblx0XHR9LFxuXG5cdFx0Z2V0Rm9ybWF0czogZnVuY3Rpb24oIHByb3BzICl7XG5cdFx0XHR2YXIgZm9ybWF0cyA9IHtcblx0XHRcdFx0XHRkYXRlOiBwcm9wcy5kYXRlRm9ybWF0IHx8ICcnLFxuXHRcdFx0XHRcdHRpbWU6IHByb3BzLnRpbWVGb3JtYXQgfHwgJydcblx0XHRcdFx0fSxcblx0XHRcdFx0bG9jYWxlID0gdGhpcy5sb2NhbE1vbWVudCggcHJvcHMuZGF0ZSApLmxvY2FsZURhdGEoKVxuXHRcdFx0O1xuXG5cdFx0XHRpZiAoIGZvcm1hdHMuZGF0ZSA9PT0gdHJ1ZSApe1xuXHRcdFx0XHRmb3JtYXRzLmRhdGUgPSBsb2NhbGUubG9uZ0RhdGVGb3JtYXQoJ0wnKTtcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKCB0aGlzLmdldFVwZGF0ZU9uKGZvcm1hdHMpICE9PSAnZGF5cycgKXtcblx0XHRcdFx0Zm9ybWF0cy50aW1lID0gJyc7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZm9ybWF0cy50aW1lID09PSB0cnVlICl7XG5cdFx0XHRcdGZvcm1hdHMudGltZSA9IGxvY2FsZS5sb25nRGF0ZUZvcm1hdCgnTFQnKTtcblx0XHRcdH1cblxuXHRcdFx0Zm9ybWF0cy5kYXRldGltZSA9IGZvcm1hdHMuZGF0ZSAmJiBmb3JtYXRzLnRpbWUgP1xuXHRcdFx0XHRmb3JtYXRzLmRhdGUgKyAnICcgKyBmb3JtYXRzLnRpbWUgOlxuXHRcdFx0XHRmb3JtYXRzLmRhdGUgfHwgZm9ybWF0cy50aW1lXG5cdFx0XHQ7XG5cblx0XHRcdHJldHVybiBmb3JtYXRzO1xuXHRcdH0sXG5cblx0XHRjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbihuZXh0UHJvcHMpIHtcblx0XHRcdHZhciBmb3JtYXRzID0gdGhpcy5nZXRGb3JtYXRzKCBuZXh0UHJvcHMgKSxcblx0XHRcdFx0dXBkYXRlID0ge31cblx0XHRcdDtcblxuXHRcdFx0aWYgKCBuZXh0UHJvcHMudmFsdWUgIT09IHRoaXMucHJvcHMudmFsdWUgKXtcblx0XHRcdFx0dXBkYXRlID0gdGhpcy5nZXRTdGF0ZUZyb21Qcm9wcyggbmV4dFByb3BzICk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGZvcm1hdHMuZGF0ZXRpbWUgIT09IHRoaXMuZ2V0Rm9ybWF0cyggdGhpcy5wcm9wcyApLmRhdGV0aW1lICkge1xuXHRcdFx0XHR1cGRhdGUuaW5wdXRGb3JtYXQgPSBmb3JtYXRzLmRhdGV0aW1lO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHVwZGF0ZS5vcGVuID09PSB1bmRlZmluZWQgKXtcblx0XHRcdFx0aWYgKCB0aGlzLnByb3BzLmNsb3NlT25TZWxlY3QgJiYgdGhpcy5zdGF0ZS5jdXJyZW50VmlldyAhPT0gJ3RpbWUnICl7XG5cdFx0XHRcdFx0dXBkYXRlLm9wZW4gPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHR1cGRhdGUub3BlbiA9IHRoaXMuc3RhdGUub3Blbjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnNldFN0YXRlKCB1cGRhdGUgKTtcblx0XHR9LFxuXG5cdFx0b25JbnB1dENoYW5nZTogZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHR2YXIgdmFsdWUgPSBlLnRhcmdldCA9PT0gbnVsbCA/IGUgOiBlLnRhcmdldC52YWx1ZSxcblx0XHRcdFx0bG9jYWxNb21lbnQgPSB0aGlzLmxvY2FsTW9tZW50KCB2YWx1ZSwgdGhpcy5zdGF0ZS5pbnB1dEZvcm1hdCApLFxuXHRcdFx0XHR1cGRhdGUgPSB7IGlucHV0VmFsdWU6IHZhbHVlIH1cblx0XHRcdDtcblxuXHRcdFx0aWYgKCBsb2NhbE1vbWVudC5pc1ZhbGlkKCkgJiYgIXRoaXMucHJvcHMudmFsdWUgKSB7XG5cdFx0XHRcdHVwZGF0ZS5zZWxlY3RlZERhdGUgPSBsb2NhbE1vbWVudDtcblx0XHRcdFx0dXBkYXRlLnZpZXdEYXRlID0gbG9jYWxNb21lbnQuY2xvbmUoKS5zdGFydE9mKCdtb250aCcpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdHVwZGF0ZS5zZWxlY3RlZERhdGUgPSBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdGhpcy5zZXRTdGF0ZSggdXBkYXRlLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMucHJvcHMub25DaGFuZ2UoIGxvY2FsTW9tZW50LmlzVmFsaWQoKSA/IGxvY2FsTW9tZW50IDogdGhpcy5zdGF0ZS5pbnB1dFZhbHVlICk7XG5cdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0b25JbnB1dEtleTogZnVuY3Rpb24oIGUgKXtcblx0XHRcdGlmICggZS53aGljaCA9PT0gOSAmJiB0aGlzLnByb3BzLmNsb3NlT25UYWIgKXtcblx0XHRcdFx0dGhpcy5jbG9zZUNhbGVuZGFyKCk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdHNob3dWaWV3OiBmdW5jdGlvbiggdmlldyApe1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHJldHVybiBmdW5jdGlvbigpe1xuXHRcdFx0XHRtZS5zZXRTdGF0ZSh7IGN1cnJlbnRWaWV3OiB2aWV3IH0pO1xuXHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0c2V0RGF0ZTogZnVuY3Rpb24oIHR5cGUgKXtcblx0XHRcdHZhciBtZSA9IHRoaXMsXG5cdFx0XHRcdG5leHRWaWV3cyA9IHtcblx0XHRcdFx0XHRtb250aDogJ2RheXMnLFxuXHRcdFx0XHRcdHllYXI6ICdtb250aHMnXG5cdFx0XHRcdH1cblx0XHRcdDtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZSApe1xuXHRcdFx0XHRtZS5zZXRTdGF0ZSh7XG5cdFx0XHRcdFx0dmlld0RhdGU6IG1lLnN0YXRlLnZpZXdEYXRlLmNsb25lKClbIHR5cGUgXSggcGFyc2VJbnQoZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyksIDEwKSApLnN0YXJ0T2YoIHR5cGUgKSxcblx0XHRcdFx0XHRjdXJyZW50VmlldzogbmV4dFZpZXdzWyB0eXBlIF1cblx0XHRcdFx0fSk7XG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRhZGRUaW1lOiBmdW5jdGlvbiggYW1vdW50LCB0eXBlLCB0b1NlbGVjdGVkICl7XG5cdFx0XHRyZXR1cm4gdGhpcy51cGRhdGVUaW1lKCAnYWRkJywgYW1vdW50LCB0eXBlLCB0b1NlbGVjdGVkICk7XG5cdFx0fSxcblxuXHRcdHN1YnRyYWN0VGltZTogZnVuY3Rpb24oIGFtb3VudCwgdHlwZSwgdG9TZWxlY3RlZCApe1xuXHRcdFx0cmV0dXJuIHRoaXMudXBkYXRlVGltZSggJ3N1YnRyYWN0JywgYW1vdW50LCB0eXBlLCB0b1NlbGVjdGVkICk7XG5cdFx0fSxcblxuXHRcdHVwZGF0ZVRpbWU6IGZ1bmN0aW9uKCBvcCwgYW1vdW50LCB0eXBlLCB0b1NlbGVjdGVkICl7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oKXtcblx0XHRcdFx0dmFyIHVwZGF0ZSA9IHt9LFxuXHRcdFx0XHRcdGRhdGUgPSB0b1NlbGVjdGVkID8gJ3NlbGVjdGVkRGF0ZScgOiAndmlld0RhdGUnXG5cdFx0XHRcdDtcblxuXHRcdFx0XHR1cGRhdGVbIGRhdGUgXSA9IG1lLnN0YXRlWyBkYXRlIF0uY2xvbmUoKVsgb3AgXSggYW1vdW50LCB0eXBlICk7XG5cblx0XHRcdFx0bWUuc2V0U3RhdGUoIHVwZGF0ZSApO1xuXHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0YWxsb3dlZFNldFRpbWU6IFsnaG91cnMnLCAnbWludXRlcycsICdzZWNvbmRzJywgJ21pbGxpc2Vjb25kcyddLFxuXHRcdHNldFRpbWU6IGZ1bmN0aW9uKCB0eXBlLCB2YWx1ZSApe1xuXHRcdFx0dmFyIGluZGV4ID0gdGhpcy5hbGxvd2VkU2V0VGltZS5pbmRleE9mKCB0eXBlICkgKyAxLFxuXHRcdFx0XHRzdGF0ZSA9IHRoaXMuc3RhdGUsXG5cdFx0XHRcdGRhdGUgPSAoc3RhdGUuc2VsZWN0ZWREYXRlIHx8IHN0YXRlLnZpZXdEYXRlKS5jbG9uZSgpLFxuXHRcdFx0XHRuZXh0VHlwZVxuXHRcdFx0O1xuXG5cdFx0XHQvLyBJdCBpcyBuZWVkZWQgdG8gc2V0IGFsbCB0aGUgdGltZSBwcm9wZXJ0aWVzXG5cdFx0XHQvLyB0byBub3QgdG8gcmVzZXQgdGhlIHRpbWVcblx0XHRcdGRhdGVbIHR5cGUgXSggdmFsdWUgKTtcblx0XHRcdGZvciAoOyBpbmRleCA8IHRoaXMuYWxsb3dlZFNldFRpbWUubGVuZ3RoOyBpbmRleCsrKSB7XG5cdFx0XHRcdG5leHRUeXBlID0gdGhpcy5hbGxvd2VkU2V0VGltZVtpbmRleF07XG5cdFx0XHRcdGRhdGVbIG5leHRUeXBlIF0oIGRhdGVbbmV4dFR5cGVdKCkgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCAhdGhpcy5wcm9wcy52YWx1ZSApe1xuXHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdFx0XHRzZWxlY3RlZERhdGU6IGRhdGUsXG5cdFx0XHRcdFx0aW5wdXRWYWx1ZTogZGF0ZS5mb3JtYXQoIHN0YXRlLmlucHV0Rm9ybWF0IClcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnByb3BzLm9uQ2hhbmdlKCBkYXRlICk7XG5cdFx0fSxcblxuXHRcdHVwZGF0ZVNlbGVjdGVkRGF0ZTogZnVuY3Rpb24oIGUsIGNsb3NlICkge1xuXHRcdFx0dmFyIHRhcmdldCA9IGUudGFyZ2V0LFxuXHRcdFx0XHRtb2RpZmllciA9IDAsXG5cdFx0XHRcdHZpZXdEYXRlID0gdGhpcy5zdGF0ZS52aWV3RGF0ZSxcblx0XHRcdFx0Y3VycmVudERhdGUgPSB0aGlzLnN0YXRlLnNlbGVjdGVkRGF0ZSB8fCB2aWV3RGF0ZSxcblx0XHRcdFx0ZGF0ZVxuXHQgICAgO1xuXG5cdFx0XHRpZiAodGFyZ2V0LmNsYXNzTmFtZS5pbmRleE9mKCdyZHREYXknKSAhPT0gLTEpe1xuXHRcdFx0XHRpZiAodGFyZ2V0LmNsYXNzTmFtZS5pbmRleE9mKCdyZHROZXcnKSAhPT0gLTEpXG5cdFx0XHRcdFx0bW9kaWZpZXIgPSAxO1xuXHRcdFx0XHRlbHNlIGlmICh0YXJnZXQuY2xhc3NOYW1lLmluZGV4T2YoJ3JkdE9sZCcpICE9PSAtMSlcblx0XHRcdFx0XHRtb2RpZmllciA9IC0xO1xuXG5cdFx0XHRcdGRhdGUgPSB2aWV3RGF0ZS5jbG9uZSgpXG5cdFx0XHRcdFx0Lm1vbnRoKCB2aWV3RGF0ZS5tb250aCgpICsgbW9kaWZpZXIgKVxuXHRcdFx0XHRcdC5kYXRlKCBwYXJzZUludCggdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScpLCAxMCApICk7XG5cdFx0XHR9IGVsc2UgaWYgKHRhcmdldC5jbGFzc05hbWUuaW5kZXhPZigncmR0TW9udGgnKSAhPT0gLTEpe1xuXHRcdFx0XHRkYXRlID0gdmlld0RhdGUuY2xvbmUoKVxuXHRcdFx0XHRcdC5tb250aCggcGFyc2VJbnQoIHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKSwgMTAgKSApXG5cdFx0XHRcdFx0LmRhdGUoIGN1cnJlbnREYXRlLmRhdGUoKSApO1xuXHRcdFx0fSBlbHNlIGlmICh0YXJnZXQuY2xhc3NOYW1lLmluZGV4T2YoJ3JkdFllYXInKSAhPT0gLTEpe1xuXHRcdFx0XHRkYXRlID0gdmlld0RhdGUuY2xvbmUoKVxuXHRcdFx0XHRcdC5tb250aCggY3VycmVudERhdGUubW9udGgoKSApXG5cdFx0XHRcdFx0LmRhdGUoIGN1cnJlbnREYXRlLmRhdGUoKSApXG5cdFx0XHRcdFx0LnllYXIoIHBhcnNlSW50KCB0YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyksIDEwICkgKTtcblx0XHRcdH1cblxuXHRcdFx0ZGF0ZS5ob3VycyggY3VycmVudERhdGUuaG91cnMoKSApXG5cdFx0XHRcdC5taW51dGVzKCBjdXJyZW50RGF0ZS5taW51dGVzKCkgKVxuXHRcdFx0XHQuc2Vjb25kcyggY3VycmVudERhdGUuc2Vjb25kcygpIClcblx0XHRcdFx0Lm1pbGxpc2Vjb25kcyggY3VycmVudERhdGUubWlsbGlzZWNvbmRzKCkgKTtcblxuXHRcdFx0aWYgKCAhdGhpcy5wcm9wcy52YWx1ZSApe1xuXHRcdFx0XHR0aGlzLnNldFN0YXRlKHtcblx0XHRcdFx0XHRzZWxlY3RlZERhdGU6IGRhdGUsXG5cdFx0XHRcdFx0dmlld0RhdGU6IGRhdGUuY2xvbmUoKS5zdGFydE9mKCdtb250aCcpLFxuXHRcdFx0XHRcdGlucHV0VmFsdWU6IGRhdGUuZm9ybWF0KCB0aGlzLnN0YXRlLmlucHV0Rm9ybWF0ICksXG5cdFx0XHRcdFx0b3BlbjogISh0aGlzLnByb3BzLmNsb3NlT25TZWxlY3QgJiYgY2xvc2UgKVxuXHRcdFx0XHR9KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlmICh0aGlzLnByb3BzLmNsb3NlT25TZWxlY3QgJiYgY2xvc2UpIHtcblx0XHRcdFx0XHR0aGlzLmNsb3NlQ2FsZW5kYXIoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnByb3BzLm9uQ2hhbmdlKCBkYXRlICk7XG5cdFx0fSxcblxuXHRcdG9wZW5DYWxlbmRhcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIXRoaXMuc3RhdGUub3Blbikge1xuXHRcdFx0XHR0aGlzLnByb3BzLm9uRm9jdXMoKTtcblx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7IG9wZW46IHRydWUgfSk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGNsb3NlQ2FsZW5kYXI6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7IG9wZW46IGZhbHNlIH0pO1xuXHRcdFx0dGhpcy5wcm9wcy5vbkJsdXIoIHRoaXMuc3RhdGUuc2VsZWN0ZWREYXRlIHx8IHRoaXMuc3RhdGUuaW5wdXRWYWx1ZSApO1xuXHRcdH0sXG5cblx0XHRoYW5kbGVDbGlja091dHNpZGU6IGZ1bmN0aW9uKCl7XG5cdFx0XHRpZiAoIHRoaXMucHJvcHMuaW5wdXQgJiYgdGhpcy5zdGF0ZS5vcGVuICYmICF0aGlzLnByb3BzLm9wZW4gKXtcblx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7IG9wZW46IGZhbHNlIH0pO1xuXHRcdFx0XHR0aGlzLnByb3BzLm9uQmx1ciggdGhpcy5zdGF0ZS5zZWxlY3RlZERhdGUgfHwgdGhpcy5zdGF0ZS5pbnB1dFZhbHVlICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGxvY2FsTW9tZW50OiBmdW5jdGlvbiggZGF0ZSwgZm9ybWF0ICl7XG5cdFx0XHR2YXIgbSA9IG1vbWVudCggZGF0ZSwgZm9ybWF0LCB0aGlzLnByb3BzLnN0cmljdFBhcnNpbmcgKTtcblx0XHRcdGlmICggdGhpcy5wcm9wcy5sb2NhbGUgKVxuXHRcdFx0XHRtLmxvY2FsZSggdGhpcy5wcm9wcy5sb2NhbGUgKTtcblx0XHRcdHJldHVybiBtO1xuXHRcdH0sXG5cblx0XHRjb21wb25lbnRQcm9wczoge1xuXHRcdFx0ZnJvbVByb3BzOiBbJ3ZhbHVlJywgJ2lzVmFsaWREYXRlJywgJ3JlbmRlckRheScsICdyZW5kZXJNb250aCcsICdyZW5kZXJZZWFyJywgJ3RpbWVDb25zdHJhaW50cyddLFxuXHRcdFx0ZnJvbVN0YXRlOiBbJ3ZpZXdEYXRlJywgJ3NlbGVjdGVkRGF0ZScsICd1cGRhdGVPbiddLFxuXHRcdFx0ZnJvbVRoaXM6IFsnc2V0RGF0ZScsICdzZXRUaW1lJywgJ3Nob3dWaWV3JywgJ2FkZFRpbWUnLCAnc3VidHJhY3RUaW1lJywgJ3VwZGF0ZVNlbGVjdGVkRGF0ZScsICdsb2NhbE1vbWVudCddXG5cdFx0fSxcblxuXHRcdGdldENvbXBvbmVudFByb3BzOiBmdW5jdGlvbigpe1xuXHRcdFx0dmFyIG1lID0gdGhpcyxcblx0XHRcdFx0Zm9ybWF0cyA9IHRoaXMuZ2V0Rm9ybWF0cyggdGhpcy5wcm9wcyApLFxuXHRcdFx0XHRwcm9wcyA9IHtkYXRlRm9ybWF0OiBmb3JtYXRzLmRhdGUsIHRpbWVGb3JtYXQ6IGZvcm1hdHMudGltZX1cblx0XHRcdDtcblxuXHRcdFx0dGhpcy5jb21wb25lbnRQcm9wcy5mcm9tUHJvcHMuZm9yRWFjaCggZnVuY3Rpb24oIG5hbWUgKXtcblx0XHRcdFx0cHJvcHNbIG5hbWUgXSA9IG1lLnByb3BzWyBuYW1lIF07XG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuY29tcG9uZW50UHJvcHMuZnJvbVN0YXRlLmZvckVhY2goIGZ1bmN0aW9uKCBuYW1lICl7XG5cdFx0XHRcdHByb3BzWyBuYW1lIF0gPSBtZS5zdGF0ZVsgbmFtZSBdO1xuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLmNvbXBvbmVudFByb3BzLmZyb21UaGlzLmZvckVhY2goIGZ1bmN0aW9uKCBuYW1lICl7XG5cdFx0XHRcdHByb3BzWyBuYW1lIF0gPSBtZVsgbmFtZSBdO1xuXHRcdFx0fSk7XG5cblx0XHRcdHJldHVybiBwcm9wcztcblx0XHR9LFxuXG5cdFx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBDb21wb25lbnQgPSB0aGlzLnZpZXdDb21wb25lbnRzWyB0aGlzLnN0YXRlLmN1cnJlbnRWaWV3IF0sXG5cdFx0XHRcdERPTSA9IFJlYWN0LkRPTSxcblx0XHRcdFx0Y2xhc3NOYW1lID0gJ3JkdCcgKyAodGhpcy5wcm9wcy5jbGFzc05hbWUgP1xuXHQgICAgICAgICAgICAgICAgICAoIEFycmF5LmlzQXJyYXkoIHRoaXMucHJvcHMuY2xhc3NOYW1lICkgP1xuXHQgICAgICAgICAgICAgICAgICAnICcgKyB0aGlzLnByb3BzLmNsYXNzTmFtZS5qb2luKCAnICcgKSA6ICcgJyArIHRoaXMucHJvcHMuY2xhc3NOYW1lKSA6ICcnKSxcblx0XHRcdFx0Y2hpbGRyZW4gPSBbXVxuXHRcdFx0O1xuXG5cdFx0XHRpZiAoIHRoaXMucHJvcHMuaW5wdXQgKXtcblx0XHRcdFx0Y2hpbGRyZW4gPSBbIERPTS5pbnB1dCggYXNzaWduKHtcblx0XHRcdFx0XHRrZXk6ICdpJyxcblx0XHRcdFx0XHR0eXBlOid0ZXh0Jyxcblx0XHRcdFx0XHRjbGFzc05hbWU6ICdmb3JtLWNvbnRyb2wnLFxuXHRcdFx0XHRcdG9uRm9jdXM6IHRoaXMub3BlbkNhbGVuZGFyLFxuXHRcdFx0XHRcdG9uQ2hhbmdlOiB0aGlzLm9uSW5wdXRDaGFuZ2UsXG5cdFx0XHRcdFx0b25LZXlEb3duOiB0aGlzLm9uSW5wdXRLZXksXG5cdFx0XHRcdFx0dmFsdWU6IHRoaXMuc3RhdGUuaW5wdXRWYWx1ZVxuXHRcdFx0XHR9LCB0aGlzLnByb3BzLmlucHV0UHJvcHMgKSldO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2xhc3NOYW1lICs9ICcgcmR0U3RhdGljJztcblx0XHRcdH1cblxuXHRcdFx0aWYgKCB0aGlzLnN0YXRlLm9wZW4gKVxuXHRcdFx0XHRjbGFzc05hbWUgKz0gJyByZHRPcGVuJztcblxuXHRcdFx0cmV0dXJuIERPTS5kaXYoe2NsYXNzTmFtZTogY2xhc3NOYW1lfSwgY2hpbGRyZW4uY29uY2F0KFxuXHRcdFx0XHRET00uZGl2KFxuXHRcdFx0XHRcdHsga2V5OiAnZHQnLCBjbGFzc05hbWU6ICdyZHRQaWNrZXInIH0sXG5cdFx0XHRcdFx0UmVhY3QuY3JlYXRlRWxlbWVudCggQ29tcG9uZW50LCB0aGlzLmdldENvbXBvbmVudFByb3BzKCkpXG5cdFx0XHRcdClcblx0XHRcdCkpO1xuXHRcdH1cblx0fSk7XG5cblx0Ly8gTWFrZSBtb21lbnQgYWNjZXNzaWJsZSB0aHJvdWdoIHRoZSBEYXRldGltZSBjbGFzc1xuXHREYXRldGltZS5tb21lbnQgPSBtb21lbnQ7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBEYXRldGltZTtcblxuXG4vKioqLyB9LFxuLyogMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXHR2YXIgcHJvcElzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cblx0ZnVuY3Rpb24gVG9PYmplY3QodmFsKSB7XG5cdFx0aWYgKHZhbCA9PSBudWxsKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3QuYXNzaWduIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCBudWxsIG9yIHVuZGVmaW5lZCcpO1xuXHRcdH1cblxuXHRcdHJldHVybiBPYmplY3QodmFsKTtcblx0fVxuXG5cdGZ1bmN0aW9uIG93bkVudW1lcmFibGVLZXlzKG9iaikge1xuXHRcdHZhciBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqKTtcblxuXHRcdGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG5cdFx0XHRrZXlzID0ga2V5cy5jb25jYXQoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmopKTtcblx0XHR9XG5cblx0XHRyZXR1cm4ga2V5cy5maWx0ZXIoZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0cmV0dXJuIHByb3BJc0VudW1lcmFibGUuY2FsbChvYmosIGtleSk7XG5cdFx0fSk7XG5cdH1cblxuXHRtb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCwgc291cmNlKSB7XG5cdFx0dmFyIGZyb207XG5cdFx0dmFyIGtleXM7XG5cdFx0dmFyIHRvID0gVG9PYmplY3QodGFyZ2V0KTtcblxuXHRcdGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG5cdFx0XHRmcm9tID0gYXJndW1lbnRzW3NdO1xuXHRcdFx0a2V5cyA9IG93bkVudW1lcmFibGVLZXlzKE9iamVjdChmcm9tKSk7XG5cblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHR0b1trZXlzW2ldXSA9IGZyb21ba2V5c1tpXV07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRvO1xuXHR9O1xuXG5cbi8qKiovIH0sXG4vKiAyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHRtb2R1bGUuZXhwb3J0cyA9IF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfMl9fO1xuXG4vKioqLyB9LFxuLyogMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXG5cdHZhciBSZWFjdCA9IF9fd2VicGFja19yZXF1aXJlX18oMiksXG5cdFx0bW9tZW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KVxuXHQ7XG5cblx0dmFyIERPTSA9IFJlYWN0LkRPTTtcblx0dmFyIERhdGVUaW1lUGlja2VyRGF5cyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblxuXHRcdHJlbmRlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgZm9vdGVyID0gdGhpcy5yZW5kZXJGb290ZXIoKSxcblx0XHRcdFx0ZGF0ZSA9IHRoaXMucHJvcHMudmlld0RhdGUsXG5cdFx0XHRcdGxvY2FsZSA9IGRhdGUubG9jYWxlRGF0YSgpLFxuXHRcdFx0XHR0YWJsZUNoaWxkcmVuXG5cdFx0XHQ7XG5cblx0XHRcdHRhYmxlQ2hpbGRyZW4gPSBbXG5cdFx0XHRcdERPTS50aGVhZCh7IGtleTogJ3RoJ30sIFtcblx0XHRcdFx0XHRET00udHIoeyBrZXk6ICdoJ30sIFtcblx0XHRcdFx0XHRcdERPTS50aCh7IGtleTogJ3AnLCBjbGFzc05hbWU6ICdyZHRQcmV2JyB9LCBET00uc3Bhbih7b25DbGljazogdGhpcy5wcm9wcy5zdWJ0cmFjdFRpbWUoMSwgJ21vbnRocycpfSwgJ+KAuScpKSxcblx0XHRcdFx0XHRcdERPTS50aCh7IGtleTogJ3MnLCBjbGFzc05hbWU6ICdyZHRTd2l0Y2gnLCBvbkNsaWNrOiB0aGlzLnByb3BzLnNob3dWaWV3KCdtb250aHMnKSwgY29sU3BhbjogNSwgJ2RhdGEtdmFsdWUnOiB0aGlzLnByb3BzLnZpZXdEYXRlLm1vbnRoKCkgfSwgbG9jYWxlLm1vbnRocyggZGF0ZSApICsgJyAnICsgZGF0ZS55ZWFyKCkgKSxcblx0XHRcdFx0XHRcdERPTS50aCh7IGtleTogJ24nLCBjbGFzc05hbWU6ICdyZHROZXh0JyB9LCBET00uc3Bhbih7b25DbGljazogdGhpcy5wcm9wcy5hZGRUaW1lKDEsICdtb250aHMnKX0sICfigLonKSlcblx0XHRcdFx0XHRdKSxcblx0XHRcdFx0XHRET00udHIoeyBrZXk6ICdkJ30sIHRoaXMuZ2V0RGF5c09mV2VlayggbG9jYWxlICkubWFwKCBmdW5jdGlvbiggZGF5LCBpbmRleCApeyByZXR1cm4gRE9NLnRoKHsga2V5OiBkYXkgKyBpbmRleCwgY2xhc3NOYW1lOiAnZG93J30sIGRheSApOyB9KSApXG5cdFx0XHRcdF0pLFxuXHRcdFx0XHRET00udGJvZHkoe2tleTogJ3RiJ30sIHRoaXMucmVuZGVyRGF5cygpKVxuXHRcdFx0XTtcblxuXHRcdFx0aWYgKCBmb290ZXIgKVxuXHRcdFx0XHR0YWJsZUNoaWxkcmVuLnB1c2goIGZvb3RlciApO1xuXG5cdFx0XHRyZXR1cm4gRE9NLmRpdih7IGNsYXNzTmFtZTogJ3JkdERheXMnIH0sXG5cdFx0XHRcdERPTS50YWJsZSh7fSwgdGFibGVDaGlsZHJlbiApXG5cdFx0XHQpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBHZXQgYSBsaXN0IG9mIHRoZSBkYXlzIG9mIHRoZSB3ZWVrXG5cdFx0ICogZGVwZW5kaW5nIG9uIHRoZSBjdXJyZW50IGxvY2FsZVxuXHRcdCAqIEByZXR1cm4ge2FycmF5fSBBIGxpc3Qgd2l0aCB0aGUgc2hvcnRuYW1lIG9mIHRoZSBkYXlzXG5cdFx0ICovXG5cdFx0Z2V0RGF5c09mV2VlazogZnVuY3Rpb24oIGxvY2FsZSApe1xuXHRcdFx0dmFyIGRheXMgPSBsb2NhbGUuX3dlZWtkYXlzTWluLFxuXHRcdFx0XHRmaXJzdCA9IGxvY2FsZS5maXJzdERheU9mV2VlaygpLFxuXHRcdFx0XHRkb3cgPSBbXSxcblx0XHRcdFx0aSA9IDBcblx0XHRcdDtcblxuXHRcdFx0ZGF5cy5mb3JFYWNoKCBmdW5jdGlvbiggZGF5ICl7XG5cdFx0XHRcdGRvd1sgKDcgKyAoaSsrKSAtIGZpcnN0KSAlIDcgXSA9IGRheTtcblx0XHRcdH0pO1xuXG5cdFx0XHRyZXR1cm4gZG93O1xuXHRcdH0sXG5cblx0XHRyZW5kZXJEYXlzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkYXRlID0gdGhpcy5wcm9wcy52aWV3RGF0ZSxcblx0XHRcdFx0c2VsZWN0ZWQgPSB0aGlzLnByb3BzLnNlbGVjdGVkRGF0ZSAmJiB0aGlzLnByb3BzLnNlbGVjdGVkRGF0ZS5jbG9uZSgpLFxuXHRcdFx0XHRwcmV2TW9udGggPSBkYXRlLmNsb25lKCkuc3VidHJhY3QoIDEsICdtb250aHMnICksXG5cdFx0XHRcdGN1cnJlbnRZZWFyID0gZGF0ZS55ZWFyKCksXG5cdFx0XHRcdGN1cnJlbnRNb250aCA9IGRhdGUubW9udGgoKSxcblx0XHRcdFx0d2Vla3MgPSBbXSxcblx0XHRcdFx0ZGF5cyA9IFtdLFxuXHRcdFx0XHRyZW5kZXJlciA9IHRoaXMucHJvcHMucmVuZGVyRGF5IHx8IHRoaXMucmVuZGVyRGF5LFxuXHRcdFx0XHRpc1ZhbGlkID0gdGhpcy5wcm9wcy5pc1ZhbGlkRGF0ZSB8fCB0aGlzLmlzVmFsaWREYXRlLFxuXHRcdFx0XHRjbGFzc2VzLCBkaXNhYmxlZCwgZGF5UHJvcHMsIGN1cnJlbnREYXRlXG5cdFx0XHQ7XG5cblx0XHRcdC8vIEdvIHRvIHRoZSBsYXN0IHdlZWsgb2YgdGhlIHByZXZpb3VzIG1vbnRoXG5cdFx0XHRwcmV2TW9udGguZGF0ZSggcHJldk1vbnRoLmRheXNJbk1vbnRoKCkgKS5zdGFydE9mKCd3ZWVrJyk7XG5cdFx0XHR2YXIgbGFzdERheSA9IHByZXZNb250aC5jbG9uZSgpLmFkZCg0MiwgJ2QnKTtcblxuXHRcdFx0d2hpbGUgKCBwcmV2TW9udGguaXNCZWZvcmUoIGxhc3REYXkgKSApe1xuXHRcdFx0XHRjbGFzc2VzID0gJ3JkdERheSc7XG5cdFx0XHRcdGN1cnJlbnREYXRlID0gcHJldk1vbnRoLmNsb25lKCk7XG5cblx0XHRcdFx0aWYgKCAoIHByZXZNb250aC55ZWFyKCkgPT09IGN1cnJlbnRZZWFyICYmIHByZXZNb250aC5tb250aCgpIDwgY3VycmVudE1vbnRoICkgfHwgKCBwcmV2TW9udGgueWVhcigpIDwgY3VycmVudFllYXIgKSApXG5cdFx0XHRcdFx0Y2xhc3NlcyArPSAnIHJkdE9sZCc7XG5cdFx0XHRcdGVsc2UgaWYgKCAoIHByZXZNb250aC55ZWFyKCkgPT09IGN1cnJlbnRZZWFyICYmIHByZXZNb250aC5tb250aCgpID4gY3VycmVudE1vbnRoICkgfHwgKCBwcmV2TW9udGgueWVhcigpID4gY3VycmVudFllYXIgKSApXG5cdFx0XHRcdFx0Y2xhc3NlcyArPSAnIHJkdE5ldyc7XG5cblx0XHRcdFx0aWYgKCBzZWxlY3RlZCAmJiBwcmV2TW9udGguaXNTYW1lKHNlbGVjdGVkLCAnZGF5JykgKVxuXHRcdFx0XHRcdGNsYXNzZXMgKz0gJyByZHRBY3RpdmUnO1xuXG5cdFx0XHRcdGlmIChwcmV2TW9udGguaXNTYW1lKG1vbWVudCgpLCAnZGF5JykgKVxuXHRcdFx0XHRcdGNsYXNzZXMgKz0gJyByZHRUb2RheSc7XG5cblx0XHRcdFx0ZGlzYWJsZWQgPSAhaXNWYWxpZCggY3VycmVudERhdGUsIHNlbGVjdGVkICk7XG5cdFx0XHRcdGlmICggZGlzYWJsZWQgKVxuXHRcdFx0XHRcdGNsYXNzZXMgKz0gJyByZHREaXNhYmxlZCc7XG5cblx0XHRcdFx0ZGF5UHJvcHMgPSB7XG5cdFx0XHRcdFx0a2V5OiBwcmV2TW9udGguZm9ybWF0KCdNX0QnKSxcblx0XHRcdFx0XHQnZGF0YS12YWx1ZSc6IHByZXZNb250aC5kYXRlKCksXG5cdFx0XHRcdFx0Y2xhc3NOYW1lOiBjbGFzc2VzXG5cdFx0XHRcdH07XG5cdFx0XHRcdGlmICggIWRpc2FibGVkIClcblx0XHRcdFx0XHRkYXlQcm9wcy5vbkNsaWNrID0gdGhpcy51cGRhdGVTZWxlY3RlZERhdGU7XG5cblx0XHRcdFx0ZGF5cy5wdXNoKCByZW5kZXJlciggZGF5UHJvcHMsIGN1cnJlbnREYXRlLCBzZWxlY3RlZCApICk7XG5cblx0XHRcdFx0aWYgKCBkYXlzLmxlbmd0aCA9PT0gNyApe1xuXHRcdFx0XHRcdHdlZWtzLnB1c2goIERPTS50cigge2tleTogcHJldk1vbnRoLmZvcm1hdCgnTV9EJyl9LCBkYXlzICkgKTtcblx0XHRcdFx0XHRkYXlzID0gW107XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRwcmV2TW9udGguYWRkKCAxLCAnZCcgKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHdlZWtzO1xuXHRcdH0sXG5cblx0XHR1cGRhdGVTZWxlY3RlZERhdGU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHRoaXMucHJvcHMudXBkYXRlU2VsZWN0ZWREYXRlKGV2ZW50LCB0cnVlKTtcblx0XHR9LFxuXG5cdFx0cmVuZGVyRGF5OiBmdW5jdGlvbiggcHJvcHMsIGN1cnJlbnREYXRlICl7XG5cdFx0XHRyZXR1cm4gRE9NLnRkKCBwcm9wcywgY3VycmVudERhdGUuZGF0ZSgpICk7XG5cdFx0fSxcblxuXHRcdHJlbmRlckZvb3RlcjogZnVuY3Rpb24oKXtcblx0XHRcdGlmICggIXRoaXMucHJvcHMudGltZUZvcm1hdCApXG5cdFx0XHRcdHJldHVybiAnJztcblxuXHRcdFx0dmFyIGRhdGUgPSB0aGlzLnByb3BzLnNlbGVjdGVkRGF0ZSB8fCB0aGlzLnByb3BzLnZpZXdEYXRlO1xuXG5cdFx0XHRyZXR1cm4gRE9NLnRmb290KHsga2V5OiAndGYnfSxcblx0XHRcdFx0RE9NLnRyKHt9LFxuXHRcdFx0XHRcdERPTS50ZCh7IG9uQ2xpY2s6IHRoaXMucHJvcHMuc2hvd1ZpZXcoJ3RpbWUnKSwgY29sU3BhbjogNywgY2xhc3NOYW1lOiAncmR0VGltZVRvZ2dsZSd9LCBkYXRlLmZvcm1hdCggdGhpcy5wcm9wcy50aW1lRm9ybWF0ICkpXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0fSxcblx0XHRpc1ZhbGlkRGF0ZTogZnVuY3Rpb24oKXsgcmV0dXJuIDE7IH1cblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBEYXRlVGltZVBpY2tlckRheXM7XG5cblxuLyoqKi8gfSxcbi8qIDQgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5cdG1vZHVsZS5leHBvcnRzID0gX19XRUJQQUNLX0VYVEVSTkFMX01PRFVMRV80X187XG5cbi8qKiovIH0sXG4vKiA1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIFJlYWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKTtcblxuXHR2YXIgRE9NID0gUmVhY3QuRE9NO1xuXHR2YXIgRGF0ZVRpbWVQaWNrZXJNb250aHMgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdFx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBET00uZGl2KHsgY2xhc3NOYW1lOiAncmR0TW9udGhzJyB9LCBbXG5cdFx0XHRcdERPTS50YWJsZSh7IGtleTogJ2EnfSwgRE9NLnRoZWFkKHt9LCBET00udHIoe30sIFtcblx0XHRcdFx0XHRET00udGgoeyBrZXk6ICdwcmV2JywgY2xhc3NOYW1lOiAncmR0UHJldicgfSwgRE9NLnNwYW4oe29uQ2xpY2s6IHRoaXMucHJvcHMuc3VidHJhY3RUaW1lKDEsICd5ZWFycycpfSwgJ+KAuScpKSxcblx0XHRcdFx0XHRET00udGgoeyBrZXk6ICd5ZWFyJywgY2xhc3NOYW1lOiAncmR0U3dpdGNoJywgb25DbGljazogdGhpcy5wcm9wcy5zaG93VmlldygneWVhcnMnKSwgY29sU3BhbjogMiwgJ2RhdGEtdmFsdWUnOiB0aGlzLnByb3BzLnZpZXdEYXRlLnllYXIoKX0sIHRoaXMucHJvcHMudmlld0RhdGUueWVhcigpICksXG5cdFx0XHRcdFx0RE9NLnRoKHsga2V5OiAnbmV4dCcsIGNsYXNzTmFtZTogJ3JkdE5leHQnIH0sIERPTS5zcGFuKHtvbkNsaWNrOiB0aGlzLnByb3BzLmFkZFRpbWUoMSwgJ3llYXJzJyl9LCAn4oC6JykpXG5cdFx0XHRcdF0pKSksXG5cdFx0XHRcdERPTS50YWJsZSh7IGtleTogJ21vbnRocyd9LCBET00udGJvZHkoeyBrZXk6ICdiJ30sIHRoaXMucmVuZGVyTW9udGhzKCkpKVxuXHRcdFx0XSk7XG5cdFx0fSxcblxuXHRcdHJlbmRlck1vbnRoczogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgZGF0ZSA9IHRoaXMucHJvcHMuc2VsZWN0ZWREYXRlLFxuXHRcdFx0XHRtb250aCA9IHRoaXMucHJvcHMudmlld0RhdGUubW9udGgoKSxcblx0XHRcdFx0eWVhciA9IHRoaXMucHJvcHMudmlld0RhdGUueWVhcigpLFxuXHRcdFx0XHRyb3dzID0gW10sXG5cdFx0XHRcdGkgPSAwLFxuXHRcdFx0XHRtb250aHMgPSBbXSxcblx0XHRcdFx0cmVuZGVyZXIgPSB0aGlzLnByb3BzLnJlbmRlck1vbnRoIHx8IHRoaXMucmVuZGVyTW9udGgsXG5cdFx0XHRcdGNsYXNzZXMsIHByb3BzXG5cdFx0XHQ7XG5cblx0XHRcdHdoaWxlIChpIDwgMTIpIHtcblx0XHRcdFx0Y2xhc3NlcyA9ICdyZHRNb250aCc7XG5cdFx0XHRcdGlmICggZGF0ZSAmJiBpID09PSBtb250aCAmJiB5ZWFyID09PSBkYXRlLnllYXIoKSApXG5cdFx0XHRcdFx0Y2xhc3NlcyArPSAnIHJkdEFjdGl2ZSc7XG5cblx0XHRcdFx0cHJvcHMgPSB7XG5cdFx0XHRcdFx0a2V5OiBpLFxuXHRcdFx0XHRcdCdkYXRhLXZhbHVlJzogaSxcblx0XHRcdFx0XHRjbGFzc05hbWU6IGNsYXNzZXMsXG5cdFx0XHRcdFx0b25DbGljazogdGhpcy5wcm9wcy51cGRhdGVPbiA9PT0gJ21vbnRocyc/IHRoaXMudXBkYXRlU2VsZWN0ZWRNb250aCA6IHRoaXMucHJvcHMuc2V0RGF0ZSgnbW9udGgnKVxuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdG1vbnRocy5wdXNoKCByZW5kZXJlciggcHJvcHMsIGksIHllYXIsIGRhdGUgJiYgZGF0ZS5jbG9uZSgpICkpO1xuXG5cdFx0XHRcdGlmICggbW9udGhzLmxlbmd0aCA9PT0gNCApe1xuXHRcdFx0XHRcdHJvd3MucHVzaCggRE9NLnRyKHsga2V5OiBtb250aCArICdfJyArIHJvd3MubGVuZ3RoIH0sIG1vbnRocykgKTtcblx0XHRcdFx0XHRtb250aHMgPSBbXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGkrKztcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJvd3M7XG5cdFx0fSxcblxuXHRcdHVwZGF0ZVNlbGVjdGVkTW9udGg6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHRoaXMucHJvcHMudXBkYXRlU2VsZWN0ZWREYXRlKGV2ZW50LCB0cnVlKTtcblx0XHR9LFxuXG5cdFx0cmVuZGVyTW9udGg6IGZ1bmN0aW9uKCBwcm9wcywgbW9udGggKSB7XG5cdFx0XHR2YXIgbW9udGhzU2hvcnQgPSB0aGlzLnByb3BzLnZpZXdEYXRlLmxvY2FsZURhdGEoKS5fbW9udGhzU2hvcnQ7XG5cdFx0XHRyZXR1cm4gRE9NLnRkKCBwcm9wcywgbW9udGhzU2hvcnQuc3RhbmRhbG9uZVxuXHRcdFx0XHQ/IGNhcGl0YWxpemUoIG1vbnRoc1Nob3J0LnN0YW5kYWxvbmVbIG1vbnRoIF0gKVxuXHRcdFx0XHQ6IG1vbnRoc1Nob3J0WyBtb250aCBdXG5cdFx0XHQpO1xuXHRcdH1cblx0fSk7XG5cblx0ZnVuY3Rpb24gY2FwaXRhbGl6ZShzdHIpIHtcblx0XHRyZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xuXHR9XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBEYXRlVGltZVBpY2tlck1vbnRocztcblxuXG4vKioqLyB9LFxuLyogNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblx0J3VzZSBzdHJpY3QnO1xuXG5cdHZhciBSZWFjdCA9IF9fd2VicGFja19yZXF1aXJlX18oMik7XG5cblx0dmFyIERPTSA9IFJlYWN0LkRPTTtcblx0dmFyIERhdGVUaW1lUGlja2VyWWVhcnMgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdFx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciB5ZWFyID0gcGFyc2VJbnQodGhpcy5wcm9wcy52aWV3RGF0ZS55ZWFyKCkgLyAxMCwgMTApICogMTA7XG5cblx0XHRcdHJldHVybiBET00uZGl2KHsgY2xhc3NOYW1lOiAncmR0WWVhcnMnIH0sIFtcblx0XHRcdFx0RE9NLnRhYmxlKHsga2V5OiAnYSd9LCBET00udGhlYWQoe30sIERPTS50cih7fSwgW1xuXHRcdFx0XHRcdERPTS50aCh7IGtleTogJ3ByZXYnLCBjbGFzc05hbWU6ICdyZHRQcmV2JyB9LCBET00uc3Bhbih7b25DbGljazogdGhpcy5wcm9wcy5zdWJ0cmFjdFRpbWUoMTAsICd5ZWFycycpfSwgJ+KAuScpKSxcblx0XHRcdFx0XHRET00udGgoeyBrZXk6ICd5ZWFyJywgY2xhc3NOYW1lOiAncmR0U3dpdGNoJywgb25DbGljazogdGhpcy5wcm9wcy5zaG93VmlldygneWVhcnMnKSwgY29sU3BhbjogMiB9LCB5ZWFyICsgJy0nICsgKHllYXIgKyA5KSApLFxuXHRcdFx0XHRcdERPTS50aCh7IGtleTogJ25leHQnLCBjbGFzc05hbWU6ICdyZHROZXh0J30sIERPTS5zcGFuKHtvbkNsaWNrOiB0aGlzLnByb3BzLmFkZFRpbWUoMTAsICd5ZWFycycpfSwgJ+KAuicpKVxuXHRcdFx0XHRcdF0pKSksXG5cdFx0XHRcdERPTS50YWJsZSh7IGtleTogJ3llYXJzJ30sIERPTS50Ym9keSh7fSwgdGhpcy5yZW5kZXJZZWFycyggeWVhciApKSlcblx0XHRcdF0pO1xuXHRcdH0sXG5cblx0XHRyZW5kZXJZZWFyczogZnVuY3Rpb24oIHllYXIgKSB7XG5cdFx0XHR2YXIgeWVhcnMgPSBbXSxcblx0XHRcdFx0aSA9IC0xLFxuXHRcdFx0XHRyb3dzID0gW10sXG5cdFx0XHRcdHJlbmRlcmVyID0gdGhpcy5wcm9wcy5yZW5kZXJZZWFyIHx8IHRoaXMucmVuZGVyWWVhcixcblx0XHRcdFx0c2VsZWN0ZWREYXRlID0gdGhpcy5wcm9wcy5zZWxlY3RlZERhdGUsXG5cdFx0XHRcdGNsYXNzZXMsIHByb3BzXG5cdFx0XHQ7XG5cblx0XHRcdHllYXItLTtcblx0XHRcdHdoaWxlIChpIDwgMTEpIHtcblx0XHRcdFx0Y2xhc3NlcyA9ICdyZHRZZWFyJztcblx0XHRcdFx0aWYgKCBpID09PSAtMSB8IGkgPT09IDEwIClcblx0XHRcdFx0XHRjbGFzc2VzICs9ICcgcmR0T2xkJztcblx0XHRcdFx0aWYgKCBzZWxlY3RlZERhdGUgJiYgc2VsZWN0ZWREYXRlLnllYXIoKSA9PT0geWVhciApXG5cdFx0XHRcdFx0Y2xhc3NlcyArPSAnIHJkdEFjdGl2ZSc7XG5cblx0XHRcdFx0cHJvcHMgPSB7XG5cdFx0XHRcdFx0a2V5OiB5ZWFyLFxuXHRcdFx0XHRcdCdkYXRhLXZhbHVlJzogeWVhcixcblx0XHRcdFx0XHRjbGFzc05hbWU6IGNsYXNzZXMsXG5cdFx0XHRcdFx0b25DbGljazogdGhpcy5wcm9wcy51cGRhdGVPbiA9PT0gJ3llYXJzJyA/IHRoaXMudXBkYXRlU2VsZWN0ZWRZZWFyIDogdGhpcy5wcm9wcy5zZXREYXRlKCd5ZWFyJylcblx0XHRcdFx0fTtcblxuXHRcdFx0XHR5ZWFycy5wdXNoKCByZW5kZXJlciggcHJvcHMsIHllYXIsIHNlbGVjdGVkRGF0ZSAmJiBzZWxlY3RlZERhdGUuY2xvbmUoKSApKTtcblxuXHRcdFx0XHRpZiAoIHllYXJzLmxlbmd0aCA9PT0gNCApe1xuXHRcdFx0XHRcdHJvd3MucHVzaCggRE9NLnRyKHsga2V5OiBpIH0sIHllYXJzICkgKTtcblx0XHRcdFx0XHR5ZWFycyA9IFtdO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0eWVhcisrO1xuXHRcdFx0XHRpKys7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiByb3dzO1xuXHRcdH0sXG5cblx0XHR1cGRhdGVTZWxlY3RlZFllYXI6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHRoaXMucHJvcHMudXBkYXRlU2VsZWN0ZWREYXRlKGV2ZW50LCB0cnVlKTtcblx0XHR9LFxuXG5cdFx0cmVuZGVyWWVhcjogZnVuY3Rpb24oIHByb3BzLCB5ZWFyICl7XG5cdFx0XHRyZXR1cm4gRE9NLnRkKCBwcm9wcywgeWVhciApO1xuXHRcdH1cblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBEYXRlVGltZVBpY2tlclllYXJzO1xuXG5cbi8qKiovIH0sXG4vKiA3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIFJlYWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKSxcblx0XHRhc3NpZ24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuXG5cdHZhciBET00gPSBSZWFjdC5ET007XG5cdHZhciBEYXRlVGltZVBpY2tlclRpbWUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdFx0Z2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbigpe1xuXHRcdFx0cmV0dXJuIHRoaXMuY2FsY3VsYXRlU3RhdGUoIHRoaXMucHJvcHMgKTtcblx0XHR9LFxuXHRcdGNhbGN1bGF0ZVN0YXRlOiBmdW5jdGlvbiggcHJvcHMgKXtcblx0XHRcdHZhciBkYXRlID0gcHJvcHMuc2VsZWN0ZWREYXRlIHx8IHByb3BzLnZpZXdEYXRlLFxuXHRcdFx0XHRmb3JtYXQgPSBwcm9wcy50aW1lRm9ybWF0LFxuXHRcdFx0XHRjb3VudGVycyA9IFtdXG5cdFx0XHQ7XG5cblx0XHRcdGlmICggZm9ybWF0LmluZGV4T2YoJ0gnKSAhPT0gLTEgfHwgZm9ybWF0LmluZGV4T2YoJ2gnKSAhPT0gLTEgKXtcblx0XHRcdFx0Y291bnRlcnMucHVzaCgnaG91cnMnKTtcblx0XHRcdFx0aWYgKCBmb3JtYXQuaW5kZXhPZignbScpICE9PSAtMSApe1xuXHRcdFx0XHRcdGNvdW50ZXJzLnB1c2goJ21pbnV0ZXMnKTtcblx0XHRcdFx0XHRpZiAoIGZvcm1hdC5pbmRleE9mKCdzJykgIT09IC0xICl7XG5cdFx0XHRcdFx0XHRjb3VudGVycy5wdXNoKCdzZWNvbmRzJyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHZhciBkYXlwYXJ0ID0gZmFsc2U7XG5cdFx0XHRpZiAoIHRoaXMucHJvcHMudGltZUZvcm1hdC5pbmRleE9mKCcgQScpICE9PSAtMSAgJiYgdGhpcy5zdGF0ZSAhPT0gbnVsbCApe1xuXHRcdFx0XHRkYXlwYXJ0ID0gKCB0aGlzLnN0YXRlLmhvdXJzID49IDEyICkgPyAnUE0nIDogJ0FNJztcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0aG91cnM6IGRhdGUuZm9ybWF0KCdIJyksXG5cdFx0XHRcdG1pbnV0ZXM6IGRhdGUuZm9ybWF0KCdtbScpLFxuXHRcdFx0XHRzZWNvbmRzOiBkYXRlLmZvcm1hdCgnc3MnKSxcblx0XHRcdFx0bWlsbGlzZWNvbmRzOiBkYXRlLmZvcm1hdCgnU1NTJyksXG5cdFx0XHRcdGRheXBhcnQ6IGRheXBhcnQsXG5cdFx0XHRcdGNvdW50ZXJzOiBjb3VudGVyc1xuXHRcdFx0fTtcblx0XHR9LFxuXHRcdHJlbmRlckNvdW50ZXI6IGZ1bmN0aW9uKCB0eXBlICl7XG5cdFx0XHRpZiAodHlwZSAhPT0gJ2RheXBhcnQnKSB7XG5cdFx0XHRcdHZhciB2YWx1ZSA9IHRoaXMuc3RhdGVbIHR5cGUgXTtcblx0XHRcdFx0aWYgKHR5cGUgPT09ICdob3VycycgJiYgdGhpcy5wcm9wcy50aW1lRm9ybWF0LmluZGV4T2YoJyBBJykgIT09IC0xKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSAodmFsdWUgLSAxKSAlIDEyICsgMTtcblxuXHRcdFx0XHRcdGlmICh2YWx1ZSA9PT0gMCkge1xuXHRcdFx0XHRcdFx0dmFsdWUgPSAxMjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIERPTS5kaXYoeyBrZXk6IHR5cGUsIGNsYXNzTmFtZTogJ3JkdENvdW50ZXInfSwgW1xuXHRcdFx0XHRcdERPTS5zcGFuKHsga2V5Oid1cCcsIGNsYXNzTmFtZTogJ3JkdEJ0bicsIG9uTW91c2VEb3duOiB0aGlzLm9uU3RhcnRDbGlja2luZyggJ2luY3JlYXNlJywgdHlwZSApIH0sICfilrInICksXG5cdFx0XHRcdFx0RE9NLmRpdih7IGtleTonYycsIGNsYXNzTmFtZTogJ3JkdENvdW50JyB9LCB2YWx1ZSApLFxuXHRcdFx0XHRcdERPTS5zcGFuKHsga2V5OidkbycsIGNsYXNzTmFtZTogJ3JkdEJ0bicsIG9uTW91c2VEb3duOiB0aGlzLm9uU3RhcnRDbGlja2luZyggJ2RlY3JlYXNlJywgdHlwZSApIH0sICfilrwnIClcblx0XHRcdFx0XSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gJyc7XG5cdFx0fSxcblx0XHRyZW5kZXJEYXlQYXJ0OiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBET00uZGl2KHsgY2xhc3NOYW1lOiAncmR0Q291bnRlcicsIGtleTogJ2RheVBhcnQnfSwgW1xuXHRcdFx0XHRET00uc3Bhbih7IGtleTondXAnLCBjbGFzc05hbWU6ICdyZHRCdG4nLCBvbk1vdXNlRG93bjogdGhpcy5vblN0YXJ0Q2xpY2tpbmcoICd0b2dnbGVEYXlQYXJ0JywgJ2hvdXJzJykgfSwgJ+KWsicgKSxcblx0XHRcdFx0RE9NLmRpdih7IGtleTogdGhpcy5zdGF0ZS5kYXlwYXJ0LCBjbGFzc05hbWU6ICdyZHRDb3VudCd9LCB0aGlzLnN0YXRlLmRheXBhcnQgKSxcblx0XHRcdFx0RE9NLnNwYW4oeyBrZXk6J2RvJywgY2xhc3NOYW1lOiAncmR0QnRuJywgb25Nb3VzZURvd246IHRoaXMub25TdGFydENsaWNraW5nKCAndG9nZ2xlRGF5UGFydCcsICdob3VycycpIH0sICfilrwnIClcblx0XHRcdF0pO1xuXHRcdH0sXG5cdFx0cmVuZGVyOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXMsXG5cdFx0XHRcdGNvdW50ZXJzID0gW11cblx0XHRcdDtcblxuXHRcdFx0dGhpcy5zdGF0ZS5jb3VudGVycy5mb3JFYWNoKCBmdW5jdGlvbihjKXtcblx0XHRcdFx0aWYgKCBjb3VudGVycy5sZW5ndGggKVxuXHRcdFx0XHRcdGNvdW50ZXJzLnB1c2goIERPTS5kaXYoIHtrZXk6ICdzZXAnICsgY291bnRlcnMubGVuZ3RoLCBjbGFzc05hbWU6ICdyZHRDb3VudGVyU2VwYXJhdG9yJyB9LCAnOicgKSk7XG5cdFx0XHRcdGNvdW50ZXJzLnB1c2goIG1lLnJlbmRlckNvdW50ZXIoIGMgKSApO1xuXHRcdFx0fSk7XG5cblx0XHRcdGlmICh0aGlzLnN0YXRlLmRheXBhcnQgIT09IGZhbHNlKSB7XG5cdFx0XHRcdGNvdW50ZXJzLnB1c2goIG1lLnJlbmRlckRheVBhcnQoKSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHRoaXMuc3RhdGUuY291bnRlcnMubGVuZ3RoID09PSAzICYmIHRoaXMucHJvcHMudGltZUZvcm1hdC5pbmRleE9mKCdTJykgIT09IC0xICl7XG5cdFx0XHRcdGNvdW50ZXJzLnB1c2goIERPTS5kaXYoIHtjbGFzc05hbWU6ICdyZHRDb3VudGVyU2VwYXJhdG9yJywga2V5OiAnc2VwNScgfSwgJzonICkpO1xuXHRcdFx0XHRjb3VudGVycy5wdXNoKFxuXHRcdFx0XHRcdERPTS5kaXYoIHtjbGFzc05hbWU6ICdyZHRDb3VudGVyIHJkdE1pbGxpJywga2V5OidtJ30sXG5cdFx0XHRcdFx0XHRET00uaW5wdXQoeyB2YWx1ZTogdGhpcy5zdGF0ZS5taWxsaXNlY29uZHMsIHR5cGU6ICd0ZXh0Jywgb25DaGFuZ2U6IHRoaXMudXBkYXRlTWlsbGkgfSlcblx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHQpO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gRE9NLmRpdigge2NsYXNzTmFtZTogJ3JkdFRpbWUnfSxcblx0XHRcdFx0RE9NLnRhYmxlKCB7fSwgW1xuXHRcdFx0XHRcdHRoaXMucmVuZGVySGVhZGVyKCksXG5cdFx0XHRcdFx0RE9NLnRib2R5KHtrZXk6ICdiJ30sIERPTS50cih7fSwgRE9NLnRkKHt9LFxuXHRcdFx0XHRcdFx0RE9NLmRpdih7IGNsYXNzTmFtZTogJ3JkdENvdW50ZXJzJyB9LCBjb3VudGVycyApXG5cdFx0XHRcdFx0KSkpXG5cdFx0XHRcdF0pXG5cdFx0XHQpO1xuXHRcdH0sXG5cdFx0Y29tcG9uZW50V2lsbE1vdW50OiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHRtZS50aW1lQ29uc3RyYWludHMgPSB7XG5cdFx0XHRcdGhvdXJzOiB7XG5cdFx0XHRcdFx0bWluOiAwLFxuXHRcdFx0XHRcdG1heDogMjMsXG5cdFx0XHRcdFx0c3RlcDogMVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRtaW51dGVzOiB7XG5cdFx0XHRcdFx0bWluOiAwLFxuXHRcdFx0XHRcdG1heDogNTksXG5cdFx0XHRcdFx0c3RlcDogMVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRzZWNvbmRzOiB7XG5cdFx0XHRcdFx0bWluOiAwLFxuXHRcdFx0XHRcdG1heDogNTksXG5cdFx0XHRcdFx0c3RlcDogMSxcblx0XHRcdFx0fSxcblx0XHRcdFx0bWlsbGlzZWNvbmRzOiB7XG5cdFx0XHRcdFx0bWluOiAwLFxuXHRcdFx0XHRcdG1heDogOTk5LFxuXHRcdFx0XHRcdHN0ZXA6IDFcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHRcdFsnaG91cnMnLCAnbWludXRlcycsICdzZWNvbmRzJywgJ21pbGxpc2Vjb25kcyddLmZvckVhY2goZnVuY3Rpb24odHlwZSkge1xuXHRcdFx0XHRhc3NpZ24obWUudGltZUNvbnN0cmFpbnRzW3R5cGVdLCBtZS5wcm9wcy50aW1lQ29uc3RyYWludHNbdHlwZV0pO1xuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLnNldFN0YXRlKCB0aGlzLmNhbGN1bGF0ZVN0YXRlKCB0aGlzLnByb3BzICkgKTtcblx0XHR9LFxuXHRcdGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uKCBuZXh0UHJvcHMgKXtcblx0XHRcdHRoaXMuc2V0U3RhdGUoIHRoaXMuY2FsY3VsYXRlU3RhdGUoIG5leHRQcm9wcyApICk7XG5cdFx0fSxcblx0XHR1cGRhdGVNaWxsaTogZnVuY3Rpb24oIGUgKXtcblx0XHRcdHZhciBtaWxsaSA9IHBhcnNlSW50KCBlLnRhcmdldC52YWx1ZSwgMTAgKTtcblx0XHRcdGlmICggbWlsbGkgPT09IGUudGFyZ2V0LnZhbHVlICYmIG1pbGxpID49IDAgJiYgbWlsbGkgPCAxMDAwICl7XG5cdFx0XHRcdHRoaXMucHJvcHMuc2V0VGltZSggJ21pbGxpc2Vjb25kcycsIG1pbGxpICk7XG5cdFx0XHRcdHRoaXMuc2V0U3RhdGUoeyBtaWxsaXNlY29uZHM6IG1pbGxpIH0pO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0cmVuZGVySGVhZGVyOiBmdW5jdGlvbigpe1xuXHRcdFx0aWYgKCAhdGhpcy5wcm9wcy5kYXRlRm9ybWF0IClcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cblx0XHRcdHZhciBkYXRlID0gdGhpcy5wcm9wcy5zZWxlY3RlZERhdGUgfHwgdGhpcy5wcm9wcy52aWV3RGF0ZTtcblx0XHRcdHJldHVybiBET00udGhlYWQoeyBrZXk6ICdoJ30sIERPTS50cih7fSxcblx0XHRcdFx0RE9NLnRoKCB7Y2xhc3NOYW1lOiAncmR0U3dpdGNoJywgY29sU3BhbjogNCwgb25DbGljazogdGhpcy5wcm9wcy5zaG93VmlldygnZGF5cycpfSwgZGF0ZS5mb3JtYXQoIHRoaXMucHJvcHMuZGF0ZUZvcm1hdCApIClcblx0XHRcdCkpO1xuXHRcdH0sXG5cdFx0b25TdGFydENsaWNraW5nOiBmdW5jdGlvbiggYWN0aW9uLCB0eXBlICl7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oKXtcblx0XHRcdFx0dmFyIHVwZGF0ZSA9IHt9O1xuXHRcdFx0XHR1cGRhdGVbIHR5cGUgXSA9IG1lWyBhY3Rpb24gXSggdHlwZSApO1xuXHRcdFx0XHRtZS5zZXRTdGF0ZSggdXBkYXRlICk7XG5cblx0XHRcdFx0bWUudGltZXIgPSBzZXRUaW1lb3V0KCBmdW5jdGlvbigpe1xuXHRcdFx0XHRcdG1lLmluY3JlYXNlVGltZXIgPSBzZXRJbnRlcnZhbCggZnVuY3Rpb24oKXtcblx0XHRcdFx0XHRcdHVwZGF0ZVsgdHlwZSBdID0gbWVbIGFjdGlvbiBdKCB0eXBlICk7XG5cdFx0XHRcdFx0XHRtZS5zZXRTdGF0ZSggdXBkYXRlICk7XG5cdFx0XHRcdFx0fSwgNzApO1xuXHRcdFx0XHR9LCA1MDApO1xuXG5cdFx0XHRcdG1lLm1vdXNlVXBMaXN0ZW5lciA9IGZ1bmN0aW9uKCl7XG5cdFx0XHRcdFx0Y2xlYXJUaW1lb3V0KCBtZS50aW1lciApO1xuXHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoIG1lLmluY3JlYXNlVGltZXIgKTtcblx0XHRcdFx0XHRtZS5wcm9wcy5zZXRUaW1lKCB0eXBlLCBtZS5zdGF0ZVsgdHlwZSBdICk7XG5cdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgbWUubW91c2VVcExpc3RlbmVyKTtcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBtZS5tb3VzZVVwTGlzdGVuZXIpO1xuXHRcdFx0fTtcblx0XHR9LFxuXHRcdHBhZFZhbHVlczoge1xuXHRcdFx0aG91cnM6IDEsXG5cdFx0XHRtaW51dGVzOiAyLFxuXHRcdFx0c2Vjb25kczogMixcblx0XHRcdG1pbGxpc2Vjb25kczogM1xuXHRcdH0sXG5cdFx0dG9nZ2xlRGF5UGFydDogZnVuY3Rpb24oIHR5cGUgKXsgLy8gdHlwZSBpcyBhbHdheXMgJ2hvdXJzJ1xuXHRcdFx0dmFyIHZhbHVlID0gcGFyc2VJbnQodGhpcy5zdGF0ZVsgdHlwZSBdLCAxMCkgKyAxMjtcblx0XHRcdGlmICggdmFsdWUgPiB0aGlzLnRpbWVDb25zdHJhaW50c1sgdHlwZSBdLm1heCApXG5cdFx0XHRcdHZhbHVlID0gdGhpcy50aW1lQ29uc3RyYWludHNbIHR5cGUgXS5taW4gKyAodmFsdWUgLSAodGhpcy50aW1lQ29uc3RyYWludHNbIHR5cGUgXS5tYXggKyAxKSk7XG5cdFx0XHRyZXR1cm4gdGhpcy5wYWQoIHR5cGUsIHZhbHVlICk7XG5cdFx0fSxcblx0XHRpbmNyZWFzZTogZnVuY3Rpb24oIHR5cGUgKXtcblx0XHRcdHZhciB2YWx1ZSA9IHBhcnNlSW50KHRoaXMuc3RhdGVbIHR5cGUgXSwgMTApICsgdGhpcy50aW1lQ29uc3RyYWludHNbIHR5cGUgXS5zdGVwO1xuXHRcdFx0aWYgKCB2YWx1ZSA+IHRoaXMudGltZUNvbnN0cmFpbnRzWyB0eXBlIF0ubWF4IClcblx0XHRcdFx0dmFsdWUgPSB0aGlzLnRpbWVDb25zdHJhaW50c1sgdHlwZSBdLm1pbiArICggdmFsdWUgLSAoIHRoaXMudGltZUNvbnN0cmFpbnRzWyB0eXBlIF0ubWF4ICArIDEpICk7XG5cdFx0XHRyZXR1cm4gdGhpcy5wYWQoIHR5cGUsIHZhbHVlICk7XG5cdFx0fSxcblx0XHRkZWNyZWFzZTogZnVuY3Rpb24oIHR5cGUgKXtcblx0XHRcdHZhciB2YWx1ZSA9IHBhcnNlSW50KHRoaXMuc3RhdGVbIHR5cGUgXSwgMTApIC0gdGhpcy50aW1lQ29uc3RyYWludHNbIHR5cGUgXS5zdGVwO1xuXHRcdFx0aWYgKCB2YWx1ZSA8IHRoaXMudGltZUNvbnN0cmFpbnRzWyB0eXBlIF0ubWluIClcblx0XHRcdFx0dmFsdWUgPSB0aGlzLnRpbWVDb25zdHJhaW50c1sgdHlwZSBdLm1heCArIDEgLSAoIHRoaXMudGltZUNvbnN0cmFpbnRzWyB0eXBlIF0ubWluIC0gdmFsdWUgKTtcblx0XHRcdHJldHVybiB0aGlzLnBhZCggdHlwZSwgdmFsdWUgKTtcblx0XHR9LFxuXHRcdHBhZDogZnVuY3Rpb24oIHR5cGUsIHZhbHVlICl7XG5cdFx0XHR2YXIgc3RyID0gdmFsdWUgKyAnJztcblx0XHRcdHdoaWxlICggc3RyLmxlbmd0aCA8IHRoaXMucGFkVmFsdWVzWyB0eXBlIF0gKVxuXHRcdFx0XHRzdHIgPSAnMCcgKyBzdHI7XG5cdFx0XHRyZXR1cm4gc3RyO1xuXHRcdH1cblx0fSk7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBEYXRlVGltZVBpY2tlclRpbWU7XG5cblxuLyoqKi8gfSxcbi8qIDggKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cdCd1c2Ugc3RyaWN0JztcblxuXHQvLyBUaGlzIGlzIGV4dHJhY3RlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9Qb21heC9yZWFjdC1vbmNsaWNrb3V0c2lkZVxuXHQvLyBBbmQgbW9kaWZpZWQgdG8gc3VwcG9ydCByZWFjdCAwLjEzIGFuZCByZWFjdCAwLjE0XG5cblx0dmFyIFJlYWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKSxcblx0XHR2ZXJzaW9uID0gUmVhY3QudmVyc2lvbiAmJiBSZWFjdC52ZXJzaW9uLnNwbGl0KCcuJylcblx0O1xuXG5cdGlmICggdmVyc2lvbiAmJiAoIHZlcnNpb25bMF0gPiAwIHx8IHZlcnNpb25bMV0gPiAxMyApIClcblx0XHRSZWFjdCA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7XG5cblx0Ly8gVXNlIGEgcGFyYWxsZWwgYXJyYXkgYmVjYXVzZSB3ZSBjYW4ndCB1c2Vcblx0Ly8gb2JqZWN0cyBhcyBrZXlzLCB0aGV5IGdldCB0b1N0cmluZy1jb2VyY2VkXG5cdHZhciByZWdpc3RlcmVkQ29tcG9uZW50cyA9IFtdO1xuXHR2YXIgaGFuZGxlcnMgPSBbXTtcblxuXHR2YXIgSUdOT1JFX0NMQVNTID0gJ2lnbm9yZS1yZWFjdC1vbmNsaWNrb3V0c2lkZSc7XG5cblx0dmFyIGlzU291cmNlRm91bmQgPSBmdW5jdGlvbihzb3VyY2UsIGxvY2FsTm9kZSkge1xuXHQgaWYgKHNvdXJjZSA9PT0gbG9jYWxOb2RlKSB7XG5cdCAgIHJldHVybiB0cnVlO1xuXHQgfVxuXHQgLy8gU1ZHIDx1c2UvPiBlbGVtZW50cyBkbyBub3QgdGVjaG5pY2FsbHkgcmVzaWRlIGluIHRoZSByZW5kZXJlZCBET00sIHNvXG5cdCAvLyB0aGV5IGRvIG5vdCBoYXZlIGNsYXNzTGlzdCBkaXJlY3RseSwgYnV0IHRoZXkgb2ZmZXIgYSBsaW5rIHRvIHRoZWlyXG5cdCAvLyBjb3JyZXNwb25kaW5nIGVsZW1lbnQsIHdoaWNoIGNhbiBoYXZlIGNsYXNzTGlzdC4gVGhpcyBleHRyYSBjaGVjayBpcyBmb3Jcblx0IC8vIHRoYXQgY2FzZS5cblx0IC8vIFNlZTogaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvc3RydWN0Lmh0bWwjSW50ZXJmYWNlU1ZHVXNlRWxlbWVudFxuXHQgLy8gRGlzY3Vzc2lvbjogaHR0cHM6Ly9naXRodWIuY29tL1BvbWF4L3JlYWN0LW9uY2xpY2tvdXRzaWRlL3B1bGwvMTdcblx0IGlmIChzb3VyY2UuY29ycmVzcG9uZGluZ0VsZW1lbnQpIHtcblx0ICAgcmV0dXJuIHNvdXJjZS5jb3JyZXNwb25kaW5nRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoSUdOT1JFX0NMQVNTKTtcblx0IH1cblx0IHJldHVybiBzb3VyY2UuY2xhc3NMaXN0LmNvbnRhaW5zKElHTk9SRV9DTEFTUyk7XG5cdH07XG5cblx0bW9kdWxlLmV4cG9ydHMgPSB7XG5cdCBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24oKSB7XG5cdCAgIGlmICh0eXBlb2YgdGhpcy5oYW5kbGVDbGlja091dHNpZGUgIT09ICdmdW5jdGlvbicpXG5cdCAgICAgdGhyb3cgbmV3IEVycm9yKCdDb21wb25lbnQgbGFja3MgYSBoYW5kbGVDbGlja091dHNpZGUoZXZlbnQpIGZ1bmN0aW9uIGZvciBwcm9jZXNzaW5nIG91dHNpZGUgY2xpY2sgZXZlbnRzLicpO1xuXG5cdCAgIHZhciBmbiA9IHRoaXMuX19vdXRzaWRlQ2xpY2tIYW5kbGVyID0gKGZ1bmN0aW9uKGxvY2FsTm9kZSwgZXZlbnRIYW5kbGVyKSB7XG5cdCAgICAgcmV0dXJuIGZ1bmN0aW9uKGV2dCkge1xuXHQgICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuXHQgICAgICAgdmFyIHNvdXJjZSA9IGV2dC50YXJnZXQ7XG5cdCAgICAgICB2YXIgZm91bmQgPSBmYWxzZTtcblx0ICAgICAgIC8vIElmIHNvdXJjZT1sb2NhbCB0aGVuIHRoaXMgZXZlbnQgY2FtZSBmcm9tIFwic29tZXdoZXJlXCJcblx0ICAgICAgIC8vIGluc2lkZSBhbmQgc2hvdWxkIGJlIGlnbm9yZWQuIFdlIGNvdWxkIGhhbmRsZSB0aGlzIHdpdGhcblx0ICAgICAgIC8vIGEgbGF5ZXJlZCBhcHByb2FjaCwgdG9vLCBidXQgdGhhdCByZXF1aXJlcyBnb2luZyBiYWNrIHRvXG5cdCAgICAgICAvLyB0aGlua2luZyBpbiB0ZXJtcyBvZiBEb20gbm9kZSBuZXN0aW5nLCBydW5uaW5nIGNvdW50ZXJcblx0ICAgICAgIC8vIHRvIFJlYWN0J3MgXCJ5b3Ugc2hvdWxkbid0IGNhcmUgYWJvdXQgdGhlIERPTVwiIHBoaWxvc29waHkuXG5cdCAgICAgICB3aGlsZSAoc291cmNlLnBhcmVudE5vZGUpIHtcblx0ICAgICAgICAgZm91bmQgPSBpc1NvdXJjZUZvdW5kKHNvdXJjZSwgbG9jYWxOb2RlKTtcblx0ICAgICAgICAgaWYgKGZvdW5kKSByZXR1cm47XG5cdCAgICAgICAgIHNvdXJjZSA9IHNvdXJjZS5wYXJlbnROb2RlO1xuXHQgICAgICAgfVxuXHQgICAgICAgZXZlbnRIYW5kbGVyKGV2dCk7XG5cdCAgICAgfTtcblx0ICAgfShSZWFjdC5maW5kRE9NTm9kZSh0aGlzKSwgdGhpcy5oYW5kbGVDbGlja091dHNpZGUpKTtcblxuXHQgICB2YXIgcG9zID0gcmVnaXN0ZXJlZENvbXBvbmVudHMubGVuZ3RoO1xuXHQgICByZWdpc3RlcmVkQ29tcG9uZW50cy5wdXNoKHRoaXMpO1xuXHQgICBoYW5kbGVyc1twb3NdID0gZm47XG5cblx0ICAgLy8gSWYgdGhlcmUgaXMgYSB0cnV0aHkgZGlzYWJsZU9uQ2xpY2tPdXRzaWRlIHByb3BlcnR5IGZvciB0aGlzXG5cdCAgIC8vIGNvbXBvbmVudCwgZG9uJ3QgaW1tZWRpYXRlbHkgc3RhcnQgbGlzdGVuaW5nIGZvciBvdXRzaWRlIGV2ZW50cy5cblx0ICAgaWYgKCF0aGlzLnByb3BzLmRpc2FibGVPbkNsaWNrT3V0c2lkZSkge1xuXHQgICAgIHRoaXMuZW5hYmxlT25DbGlja091dHNpZGUoKTtcblx0ICAgfVxuXHQgfSxcblxuXHQgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uKCkge1xuXHQgICB0aGlzLmRpc2FibGVPbkNsaWNrT3V0c2lkZSgpO1xuXHQgICB0aGlzLl9fb3V0c2lkZUNsaWNrSGFuZGxlciA9IGZhbHNlO1xuXHQgICB2YXIgcG9zID0gcmVnaXN0ZXJlZENvbXBvbmVudHMuaW5kZXhPZih0aGlzKTtcblx0ICAgaWYgKCBwb3M+LTEpIHtcblx0ICAgICBpZiAoaGFuZGxlcnNbcG9zXSkge1xuXHQgICAgICAgLy8gY2xlYW4gdXAgc28gd2UgZG9uJ3QgbGVhayBtZW1vcnlcblx0ICAgICAgIGhhbmRsZXJzLnNwbGljZShwb3MsIDEpO1xuXHQgICAgICAgcmVnaXN0ZXJlZENvbXBvbmVudHMuc3BsaWNlKHBvcywgMSk7XG5cdCAgICAgfVxuXHQgICB9XG5cdCB9LFxuXG5cdCAvKipcblx0ICAqIENhbiBiZSBjYWxsZWQgdG8gZXhwbGljaXRseSBlbmFibGUgZXZlbnQgbGlzdGVuaW5nXG5cdCAgKiBmb3IgY2xpY2tzIGFuZCB0b3VjaGVzIG91dHNpZGUgb2YgdGhpcyBlbGVtZW50LlxuXHQgICovXG5cdCBlbmFibGVPbkNsaWNrT3V0c2lkZTogZnVuY3Rpb24oKSB7XG5cdCAgIHZhciBmbiA9IHRoaXMuX19vdXRzaWRlQ2xpY2tIYW5kbGVyO1xuXHQgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBmbik7XG5cdCAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBmbik7XG5cdCB9LFxuXG5cdCAvKipcblx0ICAqIENhbiBiZSBjYWxsZWQgdG8gZXhwbGljaXRseSBkaXNhYmxlIGV2ZW50IGxpc3RlbmluZ1xuXHQgICogZm9yIGNsaWNrcyBhbmQgdG91Y2hlcyBvdXRzaWRlIG9mIHRoaXMgZWxlbWVudC5cblx0ICAqL1xuXHQgZGlzYWJsZU9uQ2xpY2tPdXRzaWRlOiBmdW5jdGlvbigpIHtcblx0ICAgdmFyIGZuID0gdGhpcy5fX291dHNpZGVDbGlja0hhbmRsZXI7XG5cdCAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGZuKTtcblx0ICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGZuKTtcblx0IH1cblx0fTtcblxuXG4vKioqLyB9LFxuLyogOSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cblx0bW9kdWxlLmV4cG9ydHMgPSBfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFXzlfXztcblxuLyoqKi8gfVxuLyoqKioqKi8gXSlcbn0pO1xuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVhY3QtZGF0ZXRpbWUuanMubWFwIl0sImZpbGUiOiJyZWFjdC1kYXRldGltZS5qcyJ9 |