diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..3dfaa58df --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +dist: trusty +language: node_js +node_js: + - '6' +before_install: npm install -g grunt-cli +before_script: + - cd build +script: + - npm install + - grunt --level=ADVANCED diff --git a/apps/common/main/lib/component/ComboBox.js b/apps/common/main/lib/component/ComboBox.js index d45a3054c..d24a0181c 100644 --- a/apps/common/main/lib/component/ComboBox.js +++ b/apps/common/main/lib/component/ComboBox.js @@ -547,7 +547,7 @@ define([ '<% _.each(items, function(item) { %>', '
  • <%= scope.getDisplayValue(item) %>
  • ', '<% }); %>' - ].join(''), { + ].join(''))({ items: this.store.toJSON(), scope: this })); diff --git a/apps/common/main/lib/component/ComboBoxFonts.js b/apps/common/main/lib/component/ComboBoxFonts.js index af7cd2351..e58f26d70 100644 --- a/apps/common/main/lib/component/ComboBoxFonts.js +++ b/apps/common/main/lib/component/ComboBoxFonts.js @@ -353,7 +353,7 @@ define([ '
  • ', '', '
  • ' - ].join(''), { + ].join(''))({ item: item.attributes, scope: this })); diff --git a/apps/common/main/lib/component/ComboDataView.js b/apps/common/main/lib/component/ComboDataView.js index e6816a990..421f85653 100644 --- a/apps/common/main/lib/component/ComboDataView.js +++ b/apps/common/main/lib/component/ComboDataView.js @@ -59,7 +59,8 @@ define([ enableKeyEvents : false, beforeOpenHandler : null, additionalMenuItems : null, - showLast: true + showLast: true, + minWidth: -1 }, template: _.template([ @@ -86,6 +87,7 @@ define([ this.rootHeight = 0; this.rendered = false; this.needFillComboView = false; + this.minWidth = this.options.minWidth; this.fieldPicker = new Common.UI.DataView({ cls: 'field-picker', @@ -215,6 +217,8 @@ define([ width = this.cmpEl.width(), height = this.cmpEl.height(); + if (width < this.minWidth) return; + if (this.rootWidth != width || this.rootHeight != height) { this.rootWidth = width; this.rootHeight = height; @@ -420,7 +424,7 @@ define([ var indexRec = store.indexOf(record), countRec = store.length, - maxViewCount = Math.floor((fieldPickerEl.width()) / (me.itemWidth + (me.itemMarginLeft || 0) + (me.itemMarginRight || 0) + (me.itemPaddingLeft || 0) + (me.itemPaddingRight || 0) + + maxViewCount = Math.floor(Math.max(fieldPickerEl.width(), me.minWidth) / (me.itemWidth + (me.itemMarginLeft || 0) + (me.itemMarginRight || 0) + (me.itemPaddingLeft || 0) + (me.itemPaddingRight || 0) + (me.itemBorderLeft || 0) + (me.itemBorderRight || 0))), newStyles = []; @@ -452,6 +456,10 @@ define([ } }, + clearComboView: function() { + this.fieldPicker.store.reset([]); + }, + selectByIndex: function(index) { if (index < 0) this.fieldPicker.deselectAll(); diff --git a/apps/common/main/lib/component/MultiSliderGradient.js b/apps/common/main/lib/component/MultiSliderGradient.js index c738bb976..86290981b 100644 --- a/apps/common/main/lib/component/MultiSliderGradient.js +++ b/apps/common/main/lib/component/MultiSliderGradient.js @@ -150,6 +150,18 @@ define([ } style = Common.Utils.String.format('linear-gradient(to right, {0} {1}%, {2} {3}%)', this.colorValues[0], this.getValue(0), this.colorValues[1], this.getValue(1)); this.trackEl.css('background', style); + }, + + sortThumbs: function() { + var recalc_indexes = Common.UI.MultiSlider.prototype.sortThumbs.call(this), + new_colors = [], + me = this; + _.each (recalc_indexes, function(recalc_index) { + new_colors.push(me.colorValues[recalc_index]); + }); + this.colorValues = new_colors; + this.trigger('sortthumbs', me, recalc_indexes); + return recalc_indexes; } }); }); diff --git a/apps/common/main/lib/component/Slider.js b/apps/common/main/lib/component/Slider.js index 2d34c85e0..67a86d2d2 100644 --- a/apps/common/main/lib/component/Slider.js +++ b/apps/common/main/lib/component/Slider.js @@ -338,16 +338,21 @@ define([ e.preventDefault(); e.stopPropagation(); - var index = e.data, + var index = e.data.index, lastValue = me.thumbs[index].value, minValue = (index-1<0) ? 0 : me.thumbs[index-1].position, maxValue = (index+1 maxValue, + pos = Math.max(0, Math.min(100, position)), value = pos/me.delta + me.minValue; me.setThumbPosition(index, pos); me.thumbs[index].value = value; + if (need_sort) + me.sortThumbs(); + $(document).off('mouseup', onMouseUp); $(document).off('mousemove', onMouseMove); @@ -362,16 +367,21 @@ define([ e.preventDefault(); e.stopPropagation(); - var index = e.data, + var index = e.data.index, lastValue = me.thumbs[index].value, minValue = (index-1<0) ? 0 : me.thumbs[index-1].position, maxValue = (index+1 maxValue, + pos = Math.max(0, Math.min(100, position)), value = pos/me.delta + me.minValue; me.setThumbPosition(index, pos); me.thumbs[index].value = value; + if (need_sort) + me.sortThumbs(); + if (Math.abs(value-lastValue)>0.001) me.trigger('change', me, value, lastValue); }; @@ -379,7 +389,7 @@ define([ var onMouseDown = function (e) { if ( me.disabled ) return; - var index = e.data, + var index = e.data.index, thumb = me.thumbs[index].thumb; me._dragstart = e.pageX*Common.Utils.zoom() - thumb.offset().left - thumb.width()/2; @@ -389,8 +399,8 @@ define([ (index == idx) ? item.thumb.css('z-index', 500) : item.thumb.css('z-index', ''); }); - $(document).on('mouseup', null, index, onMouseUp); - $(document).on('mousemove', null, index, onMouseMove); + $(document).on('mouseup', null, e.data, onMouseUp); + $(document).on('mousemove', null, e.data, onMouseMove); }; var onTrackMouseDown = function (e) { @@ -441,7 +451,7 @@ define([ index: index }); me.setValue(index, me.options.values[index]); - thumb.on('mousedown', null, index, onMouseDown); + thumb.on('mousedown', null, me.thumbs[index], onMouseDown); }); me.setActiveThumb(0, true); @@ -489,6 +499,18 @@ define([ if (disabled !== this.disabled) this.cmpEl.toggleClass('disabled', disabled); this.disabled = disabled; + }, + + sortThumbs: function() { + this.thumbs.sort(function(a, b) { + return (a.position - b.position); + }); + var recalc_indexes = []; + _.each (this.thumbs, function(thumb, index) { + recalc_indexes.push(thumb.index); + thumb.index = index; + }); + return recalc_indexes; } }); }); diff --git a/apps/common/main/lib/component/Window.js b/apps/common/main/lib/component/Window.js index b9750e2ad..5ee828a96 100644 --- a/apps/common/main/lib/component/Window.js +++ b/apps/common/main/lib/component/Window.js @@ -421,7 +421,7 @@ define([ _.extend(options, { cls: 'alert', onprimary: onKeyDown, - tpl: _.template(template, options) + tpl: _.template(template)(options) }); var win = new Common.UI.Window(options), @@ -556,7 +556,7 @@ define([ render : function() { var renderto = this.initConfig.renderTo || document.body; $(renderto).append( - _.template(template, this.initConfig) + _.template(template)(this.initConfig) ); this.$window = $('#' + this.initConfig.id); diff --git a/apps/common/main/lib/view/AdvancedSettingsWindow.js b/apps/common/main/lib/view/AdvancedSettingsWindow.js index 9b87f1b71..5c8ece182 100644 --- a/apps/common/main/lib/view/AdvancedSettingsWindow.js +++ b/apps/common/main/lib/view/AdvancedSettingsWindow.js @@ -71,7 +71,7 @@ define([ '' ].join(''); - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.handler = _options.handler; this.toggleGroup = _options.toggleGroup; diff --git a/apps/common/main/lib/view/Chat.js b/apps/common/main/lib/view/Chat.js index 308854791..d84448032 100644 --- a/apps/common/main/lib/view/Chat.js +++ b/apps/common/main/lib/view/Chat.js @@ -67,7 +67,7 @@ define([ templateUserList: _.template('
      ' + '<% _.each(users, function(item) { %>' + - '<%= _.template(usertpl, {user: item, scope: scope}) %>' + + '<%= _.template(usertpl)({user: item, scope: scope}) %>' + '<% }); %>' + '
    '), @@ -82,7 +82,7 @@ define([ templateMsgList: _.template('
      ' + '<% _.each(messages, function(item) { %>' + - '<%= _.template(msgtpl, {msg: item, scope: scope}) %>' + + '<%= _.template(msgtpl)({msg: item, scope: scope}) %>' + '<% }); %>' + '
    '), @@ -162,7 +162,7 @@ define([ _onAddUser: function(m, c, opts) { if (this.panelUsers) { - this.panelUsers.find('ul').append(_.template(this.tplUser, {user: m, scope: this})); + this.panelUsers.find('ul').append(_.template(this.tplUser)({user: m, scope: this})); this.panelUsers.scroller.update({minScrollbarLength : 25, alwaysVisibleY: true}); } }, @@ -186,7 +186,7 @@ define([ var content = this.panelMessages.find('ul'); if (content && content.length) { this._prepareMessage(m); - content.append(_.template(this.tplMsg, {msg: m, scope: this})); + content.append(_.template(this.tplMsg)({msg: m, scope: this})); // scroll to end diff --git a/apps/common/main/lib/view/Comments.js b/apps/common/main/lib/view/Comments.js index 7b9389e4a..e238a5eb3 100644 --- a/apps/common/main/lib/view/Comments.js +++ b/apps/common/main/lib/view/Comments.js @@ -98,7 +98,7 @@ define([ this.store = options.store; this.delegate = options.delegate; - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.arrow = {margin: 20, width: 12, height: 34}; this.sdkBounds = {width: 0, height: 0, padding: 10, paddingTop: 20}; diff --git a/apps/common/main/lib/view/CopyWarningDialog.js b/apps/common/main/lib/view/CopyWarningDialog.js index b98fc3e78..7d8fff28c 100644 --- a/apps/common/main/lib/view/CopyWarningDialog.js +++ b/apps/common/main/lib/view/CopyWarningDialog.js @@ -83,7 +83,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, diff --git a/apps/common/main/lib/view/DocumentAccessDialog.js b/apps/common/main/lib/view/DocumentAccessDialog.js index e79ce6bf1..30fc76d9c 100644 --- a/apps/common/main/lib/view/DocumentAccessDialog.js +++ b/apps/common/main/lib/view/DocumentAccessDialog.js @@ -48,7 +48,7 @@ define([ var _options = {}; _.extend(_options, { title: this.textTitle, - width: 850, + width: 600, height: 536, header: true }, options); @@ -57,7 +57,7 @@ define([ '
    ' ].join(''); - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.settingsurl = options.settingsurl || ''; Common.UI.Window.prototype.initialize.call(this, _options); diff --git a/apps/common/main/lib/view/ExternalDiagramEditor.js b/apps/common/main/lib/view/ExternalDiagramEditor.js index fa55e24b0..5f917b156 100644 --- a/apps/common/main/lib/view/ExternalDiagramEditor.js +++ b/apps/common/main/lib/view/ExternalDiagramEditor.js @@ -66,7 +66,7 @@ define([ '' ].join(''); - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.handler = _options.handler; this._chartData = null; diff --git a/apps/common/main/lib/view/ExternalMergeEditor.js b/apps/common/main/lib/view/ExternalMergeEditor.js index dab4427a6..25138e485 100644 --- a/apps/common/main/lib/view/ExternalMergeEditor.js +++ b/apps/common/main/lib/view/ExternalMergeEditor.js @@ -66,7 +66,7 @@ define([ '' ].join(''); - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.handler = _options.handler; this._mergeData = null; diff --git a/apps/common/main/lib/view/ImageFromUrlDialog.js b/apps/common/main/lib/view/ImageFromUrlDialog.js index 46888b3dd..992257873 100644 --- a/apps/common/main/lib/view/ImageFromUrlDialog.js +++ b/apps/common/main/lib/view/ImageFromUrlDialog.js @@ -65,7 +65,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, diff --git a/apps/common/main/lib/view/InsertTableDialog.js b/apps/common/main/lib/view/InsertTableDialog.js index c24d11ea3..22655700a 100644 --- a/apps/common/main/lib/view/InsertTableDialog.js +++ b/apps/common/main/lib/view/InsertTableDialog.js @@ -73,7 +73,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, diff --git a/apps/common/main/lib/view/OpenDialog.js b/apps/common/main/lib/view/OpenDialog.js index cf70abcb3..cbac99dd7 100644 --- a/apps/common/main/lib/view/OpenDialog.js +++ b/apps/common/main/lib/view/OpenDialog.js @@ -93,7 +93,7 @@ define([ this.codepages = options.codepages; this.settings = options.settings; - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); Common.UI.Window.prototype.initialize.call(this, _options); }, diff --git a/apps/common/main/lib/view/Plugins.js b/apps/common/main/lib/view/Plugins.js index 2089c7753..61d02c715 100644 --- a/apps/common/main/lib/view/Plugins.js +++ b/apps/common/main/lib/view/Plugins.js @@ -225,7 +225,7 @@ define([ '<% } %>' ].join(''); - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.url = options.url || ''; Common.UI.Window.prototype.initialize.call(this, _options); diff --git a/apps/common/main/lib/view/RenameDialog.js b/apps/common/main/lib/view/RenameDialog.js index 11f9ebffe..95207e9bf 100644 --- a/apps/common/main/lib/view/RenameDialog.js +++ b/apps/common/main/lib/view/RenameDialog.js @@ -66,7 +66,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, diff --git a/apps/common/main/lib/view/ReviewChanges.js b/apps/common/main/lib/view/ReviewChanges.js index 28f6377a0..af8ca28a7 100644 --- a/apps/common/main/lib/view/ReviewChanges.js +++ b/apps/common/main/lib/view/ReviewChanges.js @@ -80,7 +80,7 @@ define([ this.store = options.store; this.delegate = options.delegate; - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.arrow = {margin: 20, width: 12, height: 34}; this.sdkBounds = {width: 0, height: 0, padding: 10, paddingTop: 20}; @@ -441,7 +441,7 @@ define([ var el = $(this.el), me = this; el.addClass('review-changes'); - el.html(_.template(this.template, { + el.html(_.template(this.template)({ scope: this })); diff --git a/apps/common/main/lib/view/SearchDialog.js b/apps/common/main/lib/view/SearchDialog.js index a6128c349..f518a9a88 100644 --- a/apps/common/main/lib/view/SearchDialog.js +++ b/apps/common/main/lib/view/SearchDialog.js @@ -105,7 +105,7 @@ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, diff --git a/apps/documenteditor/embed/index.html b/apps/documenteditor/embed/index.html index 9bf9f202b..b5bbca2db 100644 --- a/apps/documenteditor/embed/index.html +++ b/apps/documenteditor/embed/index.html @@ -323,7 +323,6 @@ - - diff --git a/apps/documenteditor/main/app.js b/apps/documenteditor/main/app.js index 5c2a4049d..3cb20c44f 100644 --- a/apps/documenteditor/main/app.js +++ b/apps/documenteditor/main/app.js @@ -56,7 +56,6 @@ require.config({ sockjs : '../vendor/sockjs/sockjs.min', jszip : '../vendor/jszip/jszip.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', allfonts : '../../sdkjs/common/AllFonts', sdk : '../../sdkjs/word/sdk-all-min', api : 'api/documents/api', @@ -112,8 +111,7 @@ require.config({ 'xregexp', 'sockjs', 'jszip', - 'jsziputils', - 'jsrsasign' + 'jsziputils' ] }, gateway: { diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js index e259e976a..ffe757087 100644 --- a/apps/documenteditor/main/app/controller/Main.js +++ b/apps/documenteditor/main/app/controller/Main.js @@ -231,6 +231,15 @@ define([ }); this.initNames(); //for shapes + + Common.util.Shortcuts.delegateShortcuts({ + shortcuts: { + 'command+s,ctrl+s': _.bind(function (e) { + e.preventDefault(); + e.stopPropagation(); + }, this) + } + }); } }, diff --git a/apps/documenteditor/main/app/controller/Toolbar.js b/apps/documenteditor/main/app/controller/Toolbar.js index 255e609d5..ca2da17ad 100644 --- a/apps/documenteditor/main/app/controller/Toolbar.js +++ b/apps/documenteditor/main/app/controller/Toolbar.js @@ -733,7 +733,7 @@ define([ var styleRec = listStyle.menuPicker.store.findWhere({ title: name }); - this._state.prstyle = (listStyle.menuPicker.store.length>0) ? name : undefined; + this._state.prstyle = (listStyle.menuPicker.store.length>0 || window.styles_loaded) ? name : undefined; listStyle.menuPicker.selectRecord(styleRec); listStyle.resumeEvents(); @@ -1892,7 +1892,7 @@ define([ me._state.prstyle = title; style.put_Name(title); characterStyle.put_Name(title + '_character'); - style.put_Next(nextStyle.asc_getName()); + style.put_Next((nextStyle) ? nextStyle.asc_getName() : null); me.api.asc_AddNewStyle(style); } Common.NotificationCenter.trigger('edit:complete', me.toolbar); @@ -2516,7 +2516,7 @@ define([ store: this.getApplication().getCollection('Common.Collections.TextArt'), parentMenu: this.toolbar.mnuInsertTextArt.menu, showLast: false, - itemTemplate: _.template('
    ') + itemTemplate: _.template('
    ') }); this.toolbar.mnuTextArtPicker.on('item:click', function(picker, item, record, e) { @@ -2630,7 +2630,8 @@ define([ if (self._state.prstyle) styleRec = listStyles.menuPicker.store.findWhere({title: self._state.prstyle}); listStyles.fillComboView((styleRec) ? styleRec : listStyles.menuPicker.store.at(0), true); Common.NotificationCenter.trigger('edit:complete', this); - } + } else if (listStyles.rendered) + listStyles.clearComboView(); window.styles_loaded = true; }, diff --git a/apps/documenteditor/main/app/view/HyperlinkSettingsDialog.js b/apps/documenteditor/main/app/view/HyperlinkSettingsDialog.js index 335bd1de5..eda22b39d 100644 --- a/apps/documenteditor/main/app/view/HyperlinkSettingsDialog.js +++ b/apps/documenteditor/main/app/view/HyperlinkSettingsDialog.js @@ -81,7 +81,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.api = this.options.api; Common.UI.Window.prototype.initialize.call(this, this.options); diff --git a/apps/documenteditor/main/app/view/MailMergeRecepients.js b/apps/documenteditor/main/app/view/MailMergeRecepients.js index 1d6421a77..9135a9886 100644 --- a/apps/documenteditor/main/app/view/MailMergeRecepients.js +++ b/apps/documenteditor/main/app/view/MailMergeRecepients.js @@ -54,7 +54,7 @@ define([ '
    ' ].join(''); - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.fileChoiceUrl = options.fileChoiceUrl || ''; Common.UI.Window.prototype.initialize.call(this, _options); diff --git a/apps/documenteditor/main/app/view/MailMergeSaveDlg.js b/apps/documenteditor/main/app/view/MailMergeSaveDlg.js index 7158ac534..3a76f35e6 100644 --- a/apps/documenteditor/main/app/view/MailMergeSaveDlg.js +++ b/apps/documenteditor/main/app/view/MailMergeSaveDlg.js @@ -55,7 +55,7 @@ define([ '
    ' ].join(''); - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); this.mergeFolderUrl = options.mergeFolderUrl || ''; this.mergedFileUrl = options.mergedFileUrl || ''; diff --git a/apps/documenteditor/main/app/view/PageMarginsDialog.js b/apps/documenteditor/main/app/view/PageMarginsDialog.js index d9fb32f4e..fcb925a01 100644 --- a/apps/documenteditor/main/app/view/PageMarginsDialog.js +++ b/apps/documenteditor/main/app/view/PageMarginsDialog.js @@ -89,7 +89,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.spinners = []; this._noApply = false; diff --git a/apps/documenteditor/main/app/view/PageSizeDialog.js b/apps/documenteditor/main/app/view/PageSizeDialog.js index 3537e1e3c..c3f5ac6da 100644 --- a/apps/documenteditor/main/app/view/PageSizeDialog.js +++ b/apps/documenteditor/main/app/view/PageSizeDialog.js @@ -79,7 +79,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.spinners = []; this._noApply = false; diff --git a/apps/documenteditor/main/app/view/ShapeSettings.js b/apps/documenteditor/main/app/view/ShapeSettings.js index 2d131a7ad..d33dec7d0 100644 --- a/apps/documenteditor/main/app/view/ShapeSettings.js +++ b/apps/documenteditor/main/app/view/ShapeSettings.js @@ -1341,6 +1341,18 @@ define([ this.sldrGradient.on('thumbdblclick', function(cmp){ me.btnGradColor.cmpEl.find('button').dropdown('toggle'); }); + this.sldrGradient.on('sortthumbs', function(cmp, recalc_indexes){ + var colors = [], + currentIdx; + _.each (recalc_indexes, function(recalc_index, index) { + colors.push(me.GradColor.colors[recalc_index]); + if (me.GradColor.currentIdx == recalc_index) + currentIdx = index; + }); + me.OriginalFillType = null; + me.GradColor.colors = colors; + me.GradColor.currentIdx = currentIdx; + }); this.fillControls.push(this.sldrGradient); this.cmbBorderSize = new Common.UI.ComboBorderSizeEditable({ diff --git a/apps/documenteditor/main/app/view/Statusbar.js b/apps/documenteditor/main/app/view/Statusbar.js index 4017ad6a0..fd3fe1a48 100644 --- a/apps/documenteditor/main/app/view/Statusbar.js +++ b/apps/documenteditor/main/app/view/Statusbar.js @@ -96,7 +96,7 @@ define([ templateUserList: _.template('
      ' + '<% _.each(users, function(item) { %>' + - '<%= _.template(usertpl, {user: item, scope: scope}) %>' + + '<%= _.template(usertpl)({user: item, scope: scope}) %>' + '<% }); %>' + '
    '), @@ -436,7 +436,7 @@ define([ _onAddUser: function(m, c, opts) { if (this.panelUsersList) { - this.panelUsersList.find('ul').append(_.template(this.tplUser, {user: m, scope: this})); + this.panelUsersList.find('ul').append(_.template(this.tplUser)({user: m, scope: this})); this.panelUsersList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true}); } }, @@ -566,7 +566,7 @@ define([ label: this.labelSelect, btns: {ok: this.btnOk, cancel: this.btnCancel} }); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, diff --git a/apps/documenteditor/main/app/view/StyleTitleDialog.js b/apps/documenteditor/main/app/view/StyleTitleDialog.js index 14e605088..8fd238dd1 100644 --- a/apps/documenteditor/main/app/view/StyleTitleDialog.js +++ b/apps/documenteditor/main/app/view/StyleTitleDialog.js @@ -70,7 +70,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, @@ -107,10 +107,11 @@ define([ menuStyle : 'width: 100%; max-height: 290px;', editable : false, cls : 'input-group-nr', - data : this.options.formats + data : this.options.formats, + disabled : (this.options.formats.length==0) }); - - this.cmbNextStyle.setValue(this.options.formats[0].value); + if (this.options.formats.length>0) + this.cmbNextStyle.setValue(this.options.formats[0].value); }, show: function() { @@ -129,7 +130,7 @@ define([ getNextStyle: function () { var me = this; - return me.cmbNextStyle.getValue(); + return (me.options.formats.length>0) ? me.cmbNextStyle.getValue() : null; }, onBtnClick: function(event) { diff --git a/apps/documenteditor/main/app/view/TextArtSettings.js b/apps/documenteditor/main/app/view/TextArtSettings.js index 4a8259e87..479909abb 100644 --- a/apps/documenteditor/main/app/view/TextArtSettings.js +++ b/apps/documenteditor/main/app/view/TextArtSettings.js @@ -916,6 +916,18 @@ define([ this.sldrGradient.on('thumbdblclick', function(cmp){ me.btnGradColor.cmpEl.find('button').dropdown('toggle'); }); + this.sldrGradient.on('sortthumbs', function(cmp, recalc_indexes){ + var colors = [], + currentIdx; + _.each (recalc_indexes, function(recalc_index, index) { + colors.push(me.GradColor.colors[recalc_index]); + if (me.GradColor.currentIdx == recalc_index) + currentIdx = index; + }); + me.OriginalFillType = null; + me.GradColor.colors = colors; + me.GradColor.currentIdx = currentIdx; + }); this.lockedControls.push(this.sldrGradient); this.cmbBorderSize = new Common.UI.ComboBorderSizeEditable({ diff --git a/apps/documenteditor/main/app_dev.js b/apps/documenteditor/main/app_dev.js index d15f17707..49d9e8fa0 100644 --- a/apps/documenteditor/main/app_dev.js +++ b/apps/documenteditor/main/app_dev.js @@ -56,7 +56,6 @@ require.config({ sockjs : '../vendor/sockjs/sockjs.min', jszip : '../vendor/jszip/jszip.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', api : 'api/documents/api', core : 'common/main/lib/core/application', notification : 'common/main/lib/core/NotificationCenter', @@ -125,7 +124,6 @@ require([ 'locale', 'jszip', 'jsziputils', - 'jsrsasign', 'sockjs', 'underscore' ], function (Backbone, Bootstrap, Core) { diff --git a/apps/documenteditor/mobile/app-dev.js b/apps/documenteditor/mobile/app-dev.js index 8f9d3a3be..43c8bce3c 100644 --- a/apps/documenteditor/mobile/app-dev.js +++ b/apps/documenteditor/mobile/app-dev.js @@ -53,7 +53,6 @@ require.config({ sockjs : '../vendor/sockjs/sockjs.min', jszip : '../vendor/jszip/jszip.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', api : 'api/documents/api', core : 'common/main/lib/core/application', extendes : 'common/mobile/utils/extendes', @@ -120,7 +119,6 @@ require([ 'locale', 'jszip', 'jsziputils', - 'jsrsasign', 'sockjs' ], function (Backbone, Framework7, Core) { Backbone.history.start(); diff --git a/apps/documenteditor/mobile/app.js b/apps/documenteditor/mobile/app.js index ebf92413d..0c8542859 100644 --- a/apps/documenteditor/mobile/app.js +++ b/apps/documenteditor/mobile/app.js @@ -53,7 +53,6 @@ require.config({ sockjs : '../vendor/sockjs/sockjs.min', jszip : '../vendor/jszip/jszip.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', allfonts : '../../sdkjs/common/AllFonts', sdk : '../../sdkjs/word/sdk-all-min', api : 'api/documents/api', @@ -105,8 +104,7 @@ require.config({ 'xregexp', 'sockjs', 'jszip', - 'jsziputils', - 'jsrsasign' + 'jsziputils' ] }, gateway: { diff --git a/apps/documenteditor/mobile/app/template/AddImage.template b/apps/documenteditor/mobile/app/template/AddImage.template index 0ac3570e4..f5bbcb0c8 100644 --- a/apps/documenteditor/mobile/app/template/AddImage.template +++ b/apps/documenteditor/mobile/app/template/AddImage.template @@ -40,12 +40,13 @@
    -
    <%= scope.textAddress %>
    + <% if (!android) { %>
    <%= scope.textAddress %>
    <% } %>
    • ' - ].join(''), { + ].join(''))({ android: Framework7.prototype.device.android, item: size, index: index, diff --git a/apps/documenteditor/mobile/app/view/edit/EditChart.js b/apps/documenteditor/mobile/app/view/edit/EditChart.js index 9c6e80151..0eba29262 100644 --- a/apps/documenteditor/mobile/app/view/edit/EditChart.js +++ b/apps/documenteditor/mobile/app/view/edit/EditChart.js @@ -203,7 +203,7 @@ define([ '<% }); %>', '
    ', '<% }); %>' - ].join(''), { + ].join(''))({ styles: styles }); diff --git a/apps/documenteditor/mobile/app/view/edit/EditTable.js b/apps/documenteditor/mobile/app/view/edit/EditTable.js index 2f546509b..172c53ec3 100644 --- a/apps/documenteditor/mobile/app/view/edit/EditTable.js +++ b/apps/documenteditor/mobile/app/view/edit/EditTable.js @@ -138,7 +138,7 @@ define([ '
    ', '<% }); %>', '
    ' - ].join(''), { + ].join(''))({ styles: styles }); diff --git a/apps/documenteditor/sdk_dev_scripts.js b/apps/documenteditor/sdk_dev_scripts.js index 86fc92358..b306b7857 100644 --- a/apps/documenteditor/sdk_dev_scripts.js +++ b/apps/documenteditor/sdk_dev_scripts.js @@ -19,9 +19,10 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/common/AdvancedOptions.js", "../../../../sdkjs/common/FontsFreeType/font_engine.js", "../../../../sdkjs/common/FontsFreeType/FontFile.js", - "../../../../sdkjs/common/FontsFreeType/font_map.js", + "../../../../sdkjs/common/FontsFreeType/font_map.js", "../../../../sdkjs/common/FontsFreeType/FontManager.js", "../../../../sdkjs/word/Editor/FontClassification.js", + "../../../../sdkjs/common/FontsFreeType/character.js", "../../../../sdkjs/common/Drawings/Metafile.js", "../../../../sdkjs/common/FontsFreeType/TextMeasurer.js", "../../../../sdkjs/common/Drawings/WorkEvents.js", @@ -86,10 +87,13 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/word/Editor/GraphicObjects/GraphicPage.js", "../../../../sdkjs/word/Editor/GraphicObjects/WrapManager.js", "../../../../sdkjs/word/Editor/CollaborativeEditing.js", + "../../../../sdkjs/word/Editor/DocumentContentElementBase.js", + "../../../../sdkjs/word/Editor/StructuredDocumentTags/BlockLevel.js", "../../../../sdkjs/word/Editor/Comments.js", "../../../../sdkjs/word/Editor/CommentsChanges.js", "../../../../sdkjs/word/Editor/Styles.js", "../../../../sdkjs/word/Editor/StylesChanges.js", + "../../../../sdkjs/word/Editor/RevisionsChange.js", "../../../../sdkjs/word/Editor/ParagraphContent.js", "../../../../sdkjs/word/Editor/Paragraph/ParaTextPr.js", "../../../../sdkjs/word/Editor/Paragraph/ParaTextPrChanges.js", diff --git a/apps/presentationeditor/embed/index.html b/apps/presentationeditor/embed/index.html index aa4c5f04b..ceabd4062 100644 --- a/apps/presentationeditor/embed/index.html +++ b/apps/presentationeditor/embed/index.html @@ -325,7 +325,6 @@ - - diff --git a/apps/presentationeditor/main/app.js b/apps/presentationeditor/main/app.js index 941fc47b2..8e30eb1c2 100644 --- a/apps/presentationeditor/main/app.js +++ b/apps/presentationeditor/main/app.js @@ -55,7 +55,6 @@ require.config({ xregexp : '../vendor/xregexp/xregexp-all-min', sockjs : '../vendor/sockjs/sockjs.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', allfonts : '../../sdkjs/common/AllFonts', sdk : '../../sdkjs/slide/sdk-all-min', api : 'api/documents/api', @@ -109,8 +108,7 @@ require.config({ 'allfonts', 'xregexp', 'sockjs', - 'jsziputils', - 'jsrsasign' + 'jsziputils' ] }, gateway: { diff --git a/apps/presentationeditor/main/app/controller/Main.js b/apps/presentationeditor/main/app/controller/Main.js index c8f5ec0b8..76575790f 100644 --- a/apps/presentationeditor/main/app/controller/Main.js +++ b/apps/presentationeditor/main/app/controller/Main.js @@ -221,6 +221,14 @@ define([ }); this.initNames(); + Common.util.Shortcuts.delegateShortcuts({ + shortcuts: { + 'command+s,ctrl+s': _.bind(function (e) { + e.preventDefault(); + e.stopPropagation(); + }, this) + } + }); } }, diff --git a/apps/presentationeditor/main/app/controller/Toolbar.js b/apps/presentationeditor/main/app/controller/Toolbar.js index 8fc9a531a..44cb29368 100644 --- a/apps/presentationeditor/main/app/controller/Toolbar.js +++ b/apps/presentationeditor/main/app/controller/Toolbar.js @@ -1718,7 +1718,7 @@ define([ store: this.getApplication().getCollection('Common.Collections.TextArt'), parentMenu: this.toolbar.mnuInsertTextArt.menu, showLast: false, - itemTemplate: _.template('
    ') + itemTemplate: _.template('
    ') }); this.toolbar.mnuTextArtPicker.on('item:click', function(picker, item, record, e) { diff --git a/apps/presentationeditor/main/app/view/DocumentPreview.js b/apps/presentationeditor/main/app/view/DocumentPreview.js index 39119c2e8..3db0f8d63 100644 --- a/apps/presentationeditor/main/app/view/DocumentPreview.js +++ b/apps/presentationeditor/main/app/view/DocumentPreview.js @@ -100,7 +100,7 @@ define([ render: function () { var el = $(this.el), me = this; - el.html(_.template(this.template, { + el.html(_.template(this.template)({ scope: this })); diff --git a/apps/presentationeditor/main/app/view/FileMenuPanels.js b/apps/presentationeditor/main/app/view/FileMenuPanels.js index 2bf939bce..e6b61a70a 100644 --- a/apps/presentationeditor/main/app/view/FileMenuPanels.js +++ b/apps/presentationeditor/main/app/view/FileMenuPanels.js @@ -54,7 +54,8 @@ define([ formats: [[ {name: 'PDF', imgCls: 'pdf', type: Asc.c_oAscFileType.PDF}, - {name: 'PPTX', imgCls: 'pptx', type: Asc.c_oAscFileType.PPTX} + {name: 'PPTX', imgCls: 'pptx', type: Asc.c_oAscFileType.PPTX}, + {name: 'ODP', imgCls: 'odp', type: Asc.c_oAscFileType.ODP} ]], diff --git a/apps/presentationeditor/main/app/view/HyperlinkSettingsDialog.js b/apps/presentationeditor/main/app/view/HyperlinkSettingsDialog.js index 6561093d6..4d79ef530 100644 --- a/apps/presentationeditor/main/app/view/HyperlinkSettingsDialog.js +++ b/apps/presentationeditor/main/app/view/HyperlinkSettingsDialog.js @@ -103,7 +103,7 @@ define([ '
    ' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.slides = this.options.slides; this.api = this.options.api; diff --git a/apps/presentationeditor/main/app/view/ShapeSettings.js b/apps/presentationeditor/main/app/view/ShapeSettings.js index f06f575a6..dadf43a91 100644 --- a/apps/presentationeditor/main/app/view/ShapeSettings.js +++ b/apps/presentationeditor/main/app/view/ShapeSettings.js @@ -1234,6 +1234,18 @@ define([ this.sldrGradient.on('thumbdblclick', function(cmp){ me.btnGradColor.cmpEl.find('button').dropdown('toggle'); }); + this.sldrGradient.on('sortthumbs', function(cmp, recalc_indexes){ + var colors = [], + currentIdx; + _.each (recalc_indexes, function(recalc_index, index) { + colors.push(me.GradColor.colors[recalc_index]); + if (me.GradColor.currentIdx == recalc_index) + currentIdx = index; + }); + me.OriginalFillType = null; + me.GradColor.colors = colors; + me.GradColor.currentIdx = currentIdx; + }); this.fillControls.push(this.sldrGradient); this.cmbBorderSize = new Common.UI.ComboBorderSizeEditable({ diff --git a/apps/presentationeditor/main/app/view/SlideSettings.js b/apps/presentationeditor/main/app/view/SlideSettings.js index faf85e79a..0c8f54bf0 100644 --- a/apps/presentationeditor/main/app/view/SlideSettings.js +++ b/apps/presentationeditor/main/app/view/SlideSettings.js @@ -755,6 +755,18 @@ define([ this.sldrGradient.on('thumbdblclick', function(cmp){ me.btnGradColor.cmpEl.find('button').dropdown('toggle'); }); + this.sldrGradient.on('sortthumbs', function(cmp, recalc_indexes){ + var colors = [], + currentIdx; + _.each (recalc_indexes, function(recalc_index, index) { + colors.push(me.GradColor.colors[recalc_index]); + if (me.GradColor.currentIdx == recalc_index) + currentIdx = index; + }); + me.OriginalFillType = null; + me.GradColor.colors = colors; + me.GradColor.currentIdx = currentIdx; + }); this.FillItems.push(this.sldrGradient); }, diff --git a/apps/presentationeditor/main/app/view/SlideSizeSettings.js b/apps/presentationeditor/main/app/view/SlideSizeSettings.js index 09a499c65..77ec2b563 100644 --- a/apps/presentationeditor/main/app/view/SlideSizeSettings.js +++ b/apps/presentationeditor/main/app/view/SlideSizeSettings.js @@ -87,7 +87,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.spinners = []; this._noApply = false; diff --git a/apps/presentationeditor/main/app/view/SlideshowSettings.js b/apps/presentationeditor/main/app/view/SlideshowSettings.js index d0ce309c2..41bc3ef22 100644 --- a/apps/presentationeditor/main/app/view/SlideshowSettings.js +++ b/apps/presentationeditor/main/app/view/SlideshowSettings.js @@ -68,7 +68,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.spinners = []; this._noApply = false; diff --git a/apps/presentationeditor/main/app/view/Statusbar.js b/apps/presentationeditor/main/app/view/Statusbar.js index 6723eae1f..0350076d5 100644 --- a/apps/presentationeditor/main/app/view/Statusbar.js +++ b/apps/presentationeditor/main/app/view/Statusbar.js @@ -80,7 +80,7 @@ define([ templateUserList: _.template('
      ' + '<% _.each(users, function(item) { %>' + - '<%= _.template(usertpl, {user: item, scope: scope}) %>' + + '<%= _.template(usertpl)({user: item, scope: scope}) %>' + '<% }); %>' + '
    '), @@ -338,7 +338,7 @@ define([ _onAddUser: function(m, c, opts) { if (this.panelUsersList) { - this.panelUsersList.find('ul').append(_.template(this.tplUser, {user: m, scope: this})); + this.panelUsersList.find('ul').append(_.template(this.tplUser)({user: m, scope: this})); this.panelUsersList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true}); } }, diff --git a/apps/presentationeditor/main/app/view/TextArtSettings.js b/apps/presentationeditor/main/app/view/TextArtSettings.js index 7aee796d9..a51b3d261 100644 --- a/apps/presentationeditor/main/app/view/TextArtSettings.js +++ b/apps/presentationeditor/main/app/view/TextArtSettings.js @@ -1224,6 +1224,18 @@ define([ this.sldrGradient.on('thumbdblclick', function(cmp){ me.btnGradColor.cmpEl.find('button').dropdown('toggle'); }); + this.sldrGradient.on('sortthumbs', function(cmp, recalc_indexes){ + var colors = [], + currentIdx; + _.each (recalc_indexes, function(recalc_index, index) { + colors.push(me.GradColor.colors[recalc_index]); + if (me.GradColor.currentIdx == recalc_index) + currentIdx = index; + }); + me.OriginalFillType = null; + me.GradColor.colors = colors; + me.GradColor.currentIdx = currentIdx; + }); this.lockedControls.push(this.sldrGradient); this.cmbBorderSize = new Common.UI.ComboBorderSizeEditable({ diff --git a/apps/presentationeditor/main/app_dev.js b/apps/presentationeditor/main/app_dev.js index 56aea9616..46dc5c451 100644 --- a/apps/presentationeditor/main/app_dev.js +++ b/apps/presentationeditor/main/app_dev.js @@ -55,7 +55,6 @@ require.config({ xregexp : '../vendor/xregexp/xregexp-all-min', sockjs : '../vendor/sockjs/sockjs.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', api : 'api/documents/api', core : 'common/main/lib/core/application', notification : 'common/main/lib/core/NotificationCenter', @@ -122,7 +121,6 @@ require([ 'gateway', 'locale', 'jsziputils', - 'jsrsasign', 'sockjs', 'xregexp', 'underscore' diff --git a/apps/presentationeditor/main/resources/img/docformat.png b/apps/presentationeditor/main/resources/img/docformat.png index 634b0ccbc..77528805a 100644 Binary files a/apps/presentationeditor/main/resources/img/docformat.png and b/apps/presentationeditor/main/resources/img/docformat.png differ diff --git a/apps/presentationeditor/main/resources/img/docformat@2x.png b/apps/presentationeditor/main/resources/img/docformat@2x.png index 4cc6f62ac..5cab80522 100644 Binary files a/apps/presentationeditor/main/resources/img/docformat@2x.png and b/apps/presentationeditor/main/resources/img/docformat@2x.png differ diff --git a/apps/presentationeditor/main/resources/less/leftmenu.less b/apps/presentationeditor/main/resources/less/leftmenu.less index 15678684c..5300f2365 100644 --- a/apps/presentationeditor/main/resources/less/leftmenu.less +++ b/apps/presentationeditor/main/resources/less/leftmenu.less @@ -189,7 +189,7 @@ background-repeat: no-repeat; background-position: 0 0; - .background-ximage('@{app-image-path}/docformat.png', '@{app-image-path}/docformat@2x.png', 714px); + .background-ximage('@{app-image-path}/docformat.png', '@{app-image-path}/docformat@2x.png', 918px); .icon-document-format(@shift-x, @shift-y: 0) { background-position: @shift-x @shift-y; @@ -201,6 +201,7 @@ &.pptx {.icon-document-format(-102px);} &.pdf {.icon-document-format(-306px);} + &.odp {.icon-document-format(-816px);} } } } diff --git a/apps/presentationeditor/mobile/app-dev.js b/apps/presentationeditor/mobile/app-dev.js index 020c907f2..013a3cf16 100644 --- a/apps/presentationeditor/mobile/app-dev.js +++ b/apps/presentationeditor/mobile/app-dev.js @@ -54,7 +54,6 @@ require.config({ sockjs : '../vendor/sockjs/sockjs.min', jszip : '../vendor/jszip/jszip.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', api : 'api/documents/api', core : 'common/main/lib/core/application', extendes : 'common/mobile/utils/extendes', @@ -121,7 +120,6 @@ require([ 'locale', 'jszip', 'jsziputils', - 'jsrsasign', 'sockjs' ], function (Backbone, Framework7, Core) { Backbone.history.start(); diff --git a/apps/presentationeditor/mobile/app.js b/apps/presentationeditor/mobile/app.js index c4606d588..4df2708c1 100644 --- a/apps/presentationeditor/mobile/app.js +++ b/apps/presentationeditor/mobile/app.js @@ -54,7 +54,6 @@ require.config({ sockjs : '../vendor/sockjs/sockjs.min', jszip : '../vendor/jszip/jszip.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', allfonts : '../../sdkjs/common/AllFonts', sdk : '../../sdkjs/slide/sdk-all-min', api : 'api/documents/api', @@ -106,8 +105,7 @@ require.config({ 'xregexp', 'sockjs', 'jszip', - 'jsziputils', - 'jsrsasign' + 'jsziputils' ] }, gateway: { diff --git a/apps/presentationeditor/mobile/app/template/AddImage.template b/apps/presentationeditor/mobile/app/template/AddImage.template index 0ac3570e4..f5bbcb0c8 100644 --- a/apps/presentationeditor/mobile/app/template/AddImage.template +++ b/apps/presentationeditor/mobile/app/template/AddImage.template @@ -40,12 +40,13 @@
    -
    <%= scope.textAddress %>
    + <% if (!android) { %>
    <%= scope.textAddress %>
    <% } %>
    diff --git a/apps/presentationeditor/mobile/app/view/add/AddSlide.js b/apps/presentationeditor/mobile/app/view/add/AddSlide.js index 91b5bef04..b2984c9ed 100644 --- a/apps/presentationeditor/mobile/app/view/add/AddSlide.js +++ b/apps/presentationeditor/mobile/app/view/add/AddSlide.js @@ -123,7 +123,7 @@ define([ '<% }); %>', '', '<% }); %>' - ].join(''), { + ].join(''))({ layouts: layouts }); diff --git a/apps/presentationeditor/mobile/app/view/edit/EditChart.js b/apps/presentationeditor/mobile/app/view/edit/EditChart.js index 63cee3905..7508662d9 100644 --- a/apps/presentationeditor/mobile/app/view/edit/EditChart.js +++ b/apps/presentationeditor/mobile/app/view/edit/EditChart.js @@ -203,7 +203,7 @@ define([ '<% }); %>', '', '<% }); %>' - ].join(''), { + ].join(''))({ styles: styles }); diff --git a/apps/presentationeditor/mobile/app/view/edit/EditSlide.js b/apps/presentationeditor/mobile/app/view/edit/EditSlide.js index 38ed167df..3acc66e2b 100644 --- a/apps/presentationeditor/mobile/app/view/edit/EditSlide.js +++ b/apps/presentationeditor/mobile/app/view/edit/EditSlide.js @@ -235,7 +235,7 @@ define([ '<% }); %>', '', '<% }); %>' - ].join(''), { + ].join(''))({ layouts: layouts }); @@ -268,7 +268,7 @@ define([ '<% }); %>', '
    ', '<% }); %>' - ].join(''), { + ].join(''))({ themes: themes }); @@ -291,7 +291,7 @@ define([ '', '', '<% }); %>' - ].join(''), { + ].join(''))({ android : Common.SharedSettings.get('android'), types: _arrCurrentEffectTypes }); diff --git a/apps/presentationeditor/mobile/app/view/edit/EditTable.js b/apps/presentationeditor/mobile/app/view/edit/EditTable.js index aa922581b..d0cf8c92a 100644 --- a/apps/presentationeditor/mobile/app/view/edit/EditTable.js +++ b/apps/presentationeditor/mobile/app/view/edit/EditTable.js @@ -138,7 +138,7 @@ define([ '', '<% }); %>', '' - ].join(''), { + ].join(''))({ styles: styles }); diff --git a/apps/presentationeditor/mobile/resources/css/app-ios.css b/apps/presentationeditor/mobile/resources/css/app-ios.css index 9e36ca66d..69c5bfa43 100644 --- a/apps/presentationeditor/mobile/resources/css/app-ios.css +++ b/apps/presentationeditor/mobile/resources/css/app-ios.css @@ -6624,6 +6624,11 @@ i.icon.icon-format-pptx { height: 22px; background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%22-238%20240%2022%2022%22%20style%3D%22enable-background%3Anew%20-238%20240%2022%2022%3B%22%20xml%3Aspace%3D%22preserve%22%20fill%3D%22%23DF6737%22%3E%3Cg%3E%3Cpath%20id%3D%22XMLID_2_%22%20d%3D%22M-236%2C261h18v-17l-3.9791718-4H-236V261z%20M-219%2C248v12h-16v-19h12l4%2C4V248z%22%2F%3E%3C%2Fg%3E%3Cg%3E%3Cpath%20d%3D%22M-228.8226929%2C250.8646851c0.137085-0.060791%2C0.2341919-0.2302246%2C0.3131104-0.3647461%09c0.0792847-0.1351929%2C0.0861816-0.2935181%2C0.0861816-0.473938c0-0.2221069-0.0613403-0.4186401-0.1723633-0.5601807%09c-0.1102905-0.1405029-0.296875-0.2628784-0.4628906-0.2931519c-0.1210938-0.0233154-0.2396851-0.0012817-0.4535522%2C0.0090942%20l-0.3115234%2C0.010376v1.7925415h0.4523926C-228.9815063%2C250.9927368-228.9586182%2C250.9249878-228.8226929%2C250.8646851z%22%2F%3E%3Cpath%20d%3D%22M-233%2C256.1141357l7.333313%2C1.3553467V245L-233%2C246.3268433V256.1141357z%20M-230.8660889%2C248.2818604l1.4968872-0.0977783%20c0.6077881-0.0397339%2C0.9075317-0.0557251%2C1.1018066-0.0071411c0.3032227%2C0.0736084%2C0.637207%2C0.2349854%2C0.8483276%2C0.538147%09c0.2138672%2C0.3070679%2C0.3555908%2C0.7592163%2C0.3555908%2C1.262085c0%2C0.3878784-0.0623169%2C0.7130737-0.1862793%2C0.9741211%09c-0.1230469%2C0.2590942-0.2780151%2C0.4591064-0.4640503%2C0.6001587c-0.18396%2C0.1394653-0.3991089%2C0.2700195-0.5587769%2C0.3272705%20c-0.3145752%2C0.0774536-0.5286865%2C0.1747437-0.9802856%2C0.1508179h-0.5708618v1.9562378l-1.0423584-0.1081543V248.2818604z%22%2F%3E%3Cpath%20d%3D%22M-221.7266846%2C247H-225v9h3.2733154C-221.3253479%2C256-221%2C255.6746521-221%2C255.2733154v-7.5466309%09C-221%2C247.3253479-221.3253479%2C247-221.7266846%2C247z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); } +i.icon.icon-format-odp { + width: 22px; + height: 22px; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%22-286%20409.89%2022%2022%22%20style%3D%22enable-background%3Anew%20-286%20409.89%2022%2022%3B%22%20xml%3Aspace%3D%22preserve%22%20fill%3D%22%23DF6737%22%3E%3Cg%3E%3Cpath%20id%3D%22XMLID_2_%22%20d%3D%22M-284%2C430.89h18v-17l-3.979-4H-284V430.89z%20M-267%2C417.89v12h-16v-19h12l4%2C4V417.89z%22%2F%3E%3C%2Fg%3E%3Cpath%20d%3D%22M-281.655%2C419.661c0%2C0%2C1.036-1.266%2C3.529-1.381c2.493-0.115%2C3.107%2C0.499%2C3.107%2C0.499s1.072-0.873%2C2.634-0.984%20c1.473-0.106%2C2.244%2C0.134%2C3.657%2C0.639c-3.107-0.038-5.408%2C1.189-6.022%2C1.956C-276.17%2C419.163-278.817%2C418.817-281.655%2C419.661z%22%2F%3E%3Cpath%20d%3D%22M-278.663%2C415.979c1.458-0.767%2C2.864-0.857%2C5.063%2C0c1.189-0.652%2C3.414-0.307%2C4.68%2C0.269c-3.145-0.23-4.104%2C0.422-4.68%2C0.69%09C-274.367%2C416.056-276.86%2C415.595-278.663%2C415.979z%22%2F%3E%3Cg%3E%3Cpath%20d%3D%22M-281.721%2C425.011c0-0.465%2C0.07-0.855%2C0.209-1.172c0.104-0.232%2C0.246-0.441%2C0.425-0.626s0.376-0.322%2C0.59-0.411%20c0.285-0.121%2C0.613-0.181%2C0.985-0.181c0.673%2C0%2C1.212%2C0.208%2C1.616%2C0.626c0.404%2C0.418%2C0.606%2C0.998%2C0.606%2C1.742%20c0%2C0.737-0.2%2C1.314-0.601%2C1.731c-0.401%2C0.417-0.938%2C0.625-1.608%2C0.625c-0.679%2C0-1.22-0.207-1.621-0.622%09C-281.521%2C426.31-281.721%2C425.739-281.721%2C425.011z%20M-280.771%2C424.981c0%2C0.517%2C0.119%2C0.909%2C0.358%2C1.176%09c0.239%2C0.268%2C0.542%2C0.4%2C0.91%2C0.4c0.368%2C0%2C0.669-0.132%2C0.905-0.397c0.236-0.265%2C0.354-0.662%2C0.354-1.191%09c0-0.523-0.115-0.914-0.344-1.172s-0.535-0.387-0.915-0.387c-0.38%2C0-0.687%2C0.131-0.919%2C0.392%20C-280.654%2C424.062-280.771%2C424.455-280.771%2C424.981z%22%2F%3E%3Cpath%20d%3D%22M-276.573%2C422.699h1.686c0.38%2C0%2C0.67%2C0.029%2C0.87%2C0.088c0.267%2C0.079%2C0.498%2C0.219%2C0.689%2C0.421%20c0.191%2C0.201%2C0.336%2C0.448%2C0.436%2C0.74s0.15%2C0.651%2C0.15%2C1.079c0%2C0.377-0.047%2C0.7-0.141%2C0.973c-0.114%2C0.333-0.277%2C0.602-0.489%2C0.808%20c-0.16%2C0.155-0.376%2C0.277-0.648%2C0.364c-0.204%2C0.064-0.476%2C0.097-0.816%2C0.097h-1.736V422.699z%20M-275.65%2C423.472v3.026h0.689%20c0.257%2C0%2C0.443-0.015%2C0.558-0.044c0.149-0.037%2C0.274-0.101%2C0.373-0.19c0.099-0.089%2C0.18-0.236%2C0.241-0.44%20c0.062-0.205%2C0.094-0.483%2C0.094-0.837s-0.031-0.624-0.094-0.813c-0.062-0.189-0.149-0.337-0.262-0.442%20c-0.112-0.106-0.254-0.178-0.427-0.215c-0.129-0.029-0.381-0.044-0.757-0.044H-275.65z%22%2F%3E%3Cpath%20d%3D%22M-271.96%2C427.268v-4.569h1.479c0.562%2C0%2C0.927%2C0.023%2C1.098%2C0.069c0.262%2C0.068%2C0.48%2C0.218%2C0.657%2C0.447%20s0.265%2C0.525%2C0.265%2C0.89c0%2C0.28-0.051%2C0.516-0.152%2C0.707s-0.231%2C0.342-0.388%2C0.45c-0.157%2C0.109-0.316%2C0.182-0.479%2C0.217%09c-0.221%2C0.044-0.539%2C0.065-0.957%2C0.065h-0.602v1.724H-271.96z%20M-271.038%2C423.472v1.297h0.505c0.363%2C0%2C0.606-0.024%2C0.729-0.072%20c0.122-0.048%2C0.219-0.122%2C0.288-0.225c0.069-0.102%2C0.104-0.22%2C0.104-0.354c0-0.167-0.049-0.304-0.146-0.412%09c-0.098-0.107-0.222-0.176-0.371-0.202c-0.109-0.021-0.331-0.031-0.663-0.031H-271.038z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} #editor_sdk { position: absolute; left: 0; @@ -6734,4 +6739,3 @@ html.pixel-ratio-3 .numbers li { z-index: 10; -webkit-appearance: none; } -/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL2ludHJvLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9ncmlkLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9fbWl4aW5zLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy92aWV3cy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvcGFnZXMubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3Rvb2xiYXJzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy90b29sYmFycy1wYWdlcy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3Mvc2VhcmNoYmFyLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9tZXNzYWdlYmFyLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9pY29ucy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvY29udGVudC1ibG9jay5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvbGlzdHMubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL2Zvcm1zLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9jYXJkcy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvbW9kYWxzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9wYW5lbHMubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3RhYnMubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL21lc3NhZ2VzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9zdGF0dXNiYXIubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3ByZWxvYWRlci5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvcHJvZ3Jlc3NiYXIubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3N3aXBlci5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvcGlja2VyLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9ub3RpZmljYXRpb25zLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9kaXNhYmxlZC5sZXNzIiwiYXBwLWlvcy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy9hcHBzL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvaW9zL19jb250YWluZXIubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvYXBwcy9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL2lvcy9fZGF0YXZpZXcubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvYXBwcy9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL2lvcy9fbGlzdHZpZXcubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvYXBwcy9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL2lvcy9fYnV0dG9uLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL2FwcHMvY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9pb3MvX2NvbnRleHRtZW51Lmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL2FwcHMvY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9pb3MvX2NvbG9yLXBhbGV0dGUubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvYXBwcy9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL2lvcy9fYWJvdXQubGVzcyIsImlvcy9fc2VhcmNoLmxlc3MiLCJpb3MvX2ljb25zLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL2FwcHMvY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9fbWl4aW5zLmxlc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0E7QUFBTTtBQUFNO0VBQ1Isa0JBQUE7RUFDQSxZQUFBO0VBQ0EsV0FBQTtFQUNBLGtCQUFBOztBQUVKO0VBQ0ksb0ZBQUE7RUFDQSxTQUFBO0VBQ0EsVUFBQTtFQUNBLFdBQUE7RUFDQSxlQUFBO0VBQ0EsZ0JBQUE7RUFDQSxXQUFBO0VBQ0EsOEJBQUE7RUFDQSxnQkFBQTtFQUNBLGdCQUFBOztBQUVKO0VBQ0ksZ0JBQUE7O0FBR0osZ0JBQThCLG9CQUFtQixvQkFBNEI7RUFDekU7RUFBTTtFQUFNO0lBQ1IsYUFBQTs7O0FBR1IsZ0JBQThCLG9CQUFtQixvQkFBNEI7RUFDekU7RUFBTTtFQUFNO0lBQ1IsYUFBQTs7O0FBSVI7RUFDSSw2Q0FBQTtFQUNBLDJCQUFBOztBQUVKO0FBQUc7QUFBTztBQUFVO0VBQ2hCLFVB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c291cmNlc0NvbnRlbnQiOlsiQGltZ0Jhc2VVcmw6IFwiLi4vaW1nXCI7XG5odG1sLCBib2R5LCAuZnJhbWV3b3JrNy1yb290IHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIG92ZXJmbG93LXg6IGhpZGRlbjtcbn1cbmJvZHkge1xuICAgIGZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLCBTRiBVSSBUZXh0LCBIZWx2ZXRpY2EgTmV1ZSwgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZjtcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMDtcbiAgICBjb2xvcjogIzAwMDtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDEuNDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICAtd2Via2l0LXRleHQtc2l6ZS1hZGp1c3Q6MTAwJTtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG59XG4uZnJhbWV3b3JrNy1yb290IHtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuLy8gRml4IGZvciBpUGFkIGluIFNhZmFyaSBpbiBMYW5zY2FwZSBtb2RlXG5AbWVkaWEgYWxsIGFuZCAod2lkdGg6MTAyNHB4KSBhbmQgKGhlaWdodDo2OTFweCkgYW5kIChvcmllbnRhdGlvbjpsYW5kc2NhcGUpIHtcbiAgICBodG1sLCBib2R5LCAuZnJhbWV3b3JrNy1yb290IHtcbiAgICAgICAgaGVpZ2h0OiA2NzFweDtcbiAgICB9XG59XG5AbWVkaWEgYWxsIGFuZCAod2lkdGg6MTAyNHB4KSBhbmQgKGhlaWdodDo2OTJweCkgYW5kIChvcmllbnRhdGlvbjpsYW5kc2NhcGUpIHtcbiAgICBodG1sLCBib2R5LCAuZnJhbWV3b3JrNy1yb290ICB7XG4gICAgICAgIGhlaWdodDogNjcycHg7XG4gICAgfVxufVxuXG4qIHtcbiAgICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMCwwLDAsMCk7XG4gICAgLXdlYmtpdC10b3VjaC1jYWxsb3V0Om5vbmU7XG59XG5hLCBpbnB1dCwgdGV4dGFyZWEsIHNlbGVjdCB7XG4gICAgb3V0bGluZTogMDtcbn1cblxuYSB7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgIGNvbG9yOiBAdGhlbWVDb2xvcjtcbn1cbnAge1xuICAgIG1hcmdpbjogMWVtIDA7XG59IiwiLyogPT09IEdyaWQgPT09ICovXG4ucm93IHtcbiAgICAuZmxleGJveCgpO1xuICAgIC5qdXN0aWZ5LWNvbnRlbnQoc3BhY2UtYmV0d2Vlbik7XG4gICAgLmZsZXgtd3JhcCh3cmFwKTtcbiAgICAuYWxpZ24taXRlbXMoZmxleC1zdGFydCk7XG4gICAgPiBbY2xhc3MqPVwiY29sLVwiXSB7XG4gICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgfVxufVxuQGNvbHM6IDUsIDEwLCAxNSwgMjAsIDI1LCAzMCwgMTAwLzMsIDM1LCA0MCwgNDUsIDUwLCA1NSwgNjAsIDY1LCAxMDAqKDIvMyksIDcwLCA3NSwgODAsIDg1LCA5MCwgOTUsIDEwMDtcbi5yb3cge1xuICAgIC5jb2wtYXV0byB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgIH1cbiAgICAuLShAaTogbGVuZ3RoKEBjb2xzKSkgd2hlbiAoQGkgPiAwKSB7XG4gICAgICAgIEBkaXZpZGVyOiBlKGV4dHJhY3QoQGNvbHMsIEBpKSk7XG4gICAgICAgIEBjbGFzc05hbWU6IGBNYXRoLmZsb29yKEB7ZGl2aWRlcn0pYDtcbiAgICAgICAgQG46IGAxMDAvcGFyc2VGbG9hdChAe2RpdmlkZXJ9KWA7XG4gICAgICAgIEBuLTE6IEBuIC0gMTtcbiAgICAgICAgLmNvbC1Ae2NsYXNzTmFtZX0ge1xuICAgICAgICAgICAgd2lkdGg6IH5cIkB7ZGl2aWRlcn0lXCI7XG4gICAgICAgICAgICB3aWR0aDogflwiLXdlYmtpdC1jYWxjKCgxMDAlIC0gMTVweCpAe24tMX0pIC8gQHtufSlcIjsgICBcbiAgICAgICAgICAgIHdpZHRoOiB+XCJjYWxjKCgxMDAlIC0gMTVweCpAe24tMX0pIC8gQHtufSlcIjsgICBcbiAgICAgICAgfVxuICAgICAgICAmLm5vLWd1dHRlciB7XG4gICAgICAgICAgICAuY29sLUB7Y2xhc3NOYW1lfSB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IH5cIkB7ZGl2aWRlcn0lXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLi0oKEBpIC0gMSkpO1xuICAgIH0gLi07XG4gICAgLi0tKEBqOiAxKSB3aGVuIChAaiA8IGxlbmd0aChAY29scykpIHtcbiAgICAgICAgQGRpdmlkZXI6IGUoZXh0cmFjdChAY29scywgQGopKTtcbiAgICAgICAgQGNsYXNzTmFtZTogYE1hdGguZmxvb3IoQHtkaXZpZGVyfSlgO1xuICAgICAgICAuY29sLWF1dG86bnRoLWxhc3QtY2hpbGQoQHtqfSksIC5jb2wtYXV0bzpudGgtbGFzdC1jaGlsZChAe2p9KSB+IC5jb2wtYXV0byB7XG4gICAgICAgICAgICBAai0xOiBAaiAtIDE7ICBcbiAgICAgICAgICAgIHdpZHRoOiAxMDAlIC8gQGo7XG4gICAgICAgICAgICB3aWR0aDogflwiLXdlYmtpdC1jYWxjKCgxMDAlIC0gMTVweCpAe2otMX0pIC8gQHtqfSlcIjsgICBcbiAgICAgICAgICAgIHdpZHRoOiB+XCJjYWxjKCgxMDAlIC0gMTVweCpAe2otMX0pIC8gQHtqfSlcIjsgICBcbiAgICAgICAgfVxuICAgICAgICAmLm5vLWd1dHRlciB7XG4gICAgICAgICAgICAuY29sLWF1dG86bnRoLWxhc3QtY2hpbGQoQHtqfSksIC5jb2wtYXV0bzpudGgtbGFzdC1jaGlsZChAe2p9KSB+IC5jb2wtYXV0byB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCUgLyBAajtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAuLS0oKEBqICsgMSkpO1xuICAgIH0gLi0tO1xuICAgIFxufVxuXG5AbWVkaWEgYWxsIGFuZCAobWluLXdpZHRoOjc2OHB4KSB7XG4gICAgLnJvdyB7XG4gICAgICAgIC4tKEBpOiBsZW5ndGgoQGNvbHMpKSB3aGVuIChAaSA+IDApIHtcbiAgICAgICAgICAgIEBkaXZpZGVyOiBlKGV4dHJhY3QoQGNvbHMsIEBpKSk7XG4gICAgICAgICAgICBAY2xhc3NOYW1lOiBgTWF0aC5mbG9vcihAe2RpdmlkZXJ9KWA7XG4gICAgICAgICAgICBAbjogYDEwMC9wYXJzZUZsb2F0KEB7ZGl2aWRlcn0pYDtcbiAgICAgICAgICAgIEBuLTE6IEBuIC0gMTtcbiAgICAgICAgICAgIC50YWJsZXQtQHtjbGFzc05hbWV9IHtcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiQHtkaXZpZGVyfSVcIjtcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiLXdlYmtpdC1jYWxjKCgxMDAlIC0gMTVweCpAe24tMX0pIC8gQHtufSlcIjsgICBcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiY2FsYygoMTAwJSAtIDE1cHgqQHtuLTF9KSAvIEB7bn0pXCI7ICAgXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmLm5vLWd1dHRlciB7XG4gICAgICAgICAgICAgICAgLnRhYmxldC1Ae2NsYXNzTmFtZX0ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogflwiQHtkaXZpZGVyfSVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAuLSgoQGkgLSAxKSk7XG4gICAgICAgIH0gLi07XG4gICAgICAgIC4tLShAajogMSkgd2hlbiAoQGogPCBsZW5ndGgoQGNvbHMpKSB7XG4gICAgICAgICAgICAudGFibGV0LWF1dG86bnRoLWxhc3QtY2hpbGQoQHtqfSksIC50YWJsZXQtYXV0bzpudGgtbGFzdC1jaGlsZChAe2p9KSB+IC5jb2wtYXV0byB7XG4gICAgICAgICAgICAgICAgQGotMTogQGogLSAxOyAgXG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCUgLyBAajtcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiLXdlYmtpdC1jYWxjKCgxMDAlIC0gMTVweCpAe2otMX0pIC8gQHtqfSlcIjsgICBcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiY2FsYygoMTAwJSAtIDE1cHgqQHtqLTF9KSAvIEB7an0pXCI7ICAgXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmLm5vLWd1dHRlciB7XG4gICAgICAgICAgICAgICAgLnRhYmxldC1hdXRvOm50aC1sYXN0LWNoaWxkKEB7an0pLCAudGFibGV0LWF1dG86bnRoLWxhc3QtY2hpbGQoQHtqfSkgfiAudGFibGV0LWF1dG8ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogMTAwJSAvIEBqO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC4tLSgoQGogKyAxKSk7XG4gICAgICAgIH0gLi0tO1xuICAgIH1cblxufVxuIiwiLnRyYW5zaXRpb24oQGQpIHtcbiAgICAtd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb246IEBkO1xuICAgIHRyYW5zaXRpb24tZHVyYXRpb246IEBkO1xufVxuLmRlbGF5KEBkKSB7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uLWRlbGF5OiBAZDtcbiAgICB0cmFuc2l0aW9uLWRlbGF5OiBAZDtcbn1cbi50cmFuc2Zvcm0oQHQpIHtcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogQHQ7XG4gICAgdHJhbnNmb3JtOiBAdDtcbn1cbi50cmFuc2Zvcm0tb3JpZ2luKEB0bykge1xuICAgIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogQHRvO1xuICAgIHRyYW5zZm9ybS1vcmlnaW46IEB0bztcbn1cbi50cmFuc2xhdGUzZChAeDowLCBAeTowLCBAejowKSB7XG4gICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKEB4LEB5LEB6KTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKEB4LEB5LEB6KTtcbn1cbi5hbmltYXRpb24oQGEpIHtcbiAgICAtd2Via2l0LWFuaW1hdGlvbjogQGE7XG4gICAgYW5pbWF0aW9uOiBAYTtcbn1cbi5zY3JvbGxhYmxlKCl7XG4gICAgb3ZlcmZsb3c6IGF1dG87XG4gICAgLXdlYmtpdC1vdmVyZmxvdy1zY3JvbGxpbmc6IHRvdWNoO1xufVxuLmZsZXhib3goKSB7XG4gICAgZGlzcGxheTogLXdlYmtpdC1ib3g7XG4gICAgZGlzcGxheTogLW1zLWZsZXhib3g7XG4gICAgZGlzcGxheTogLXdlYmtpdC1mbGV4O1xuICAgIGRpc3BsYXk6IGZsZXg7XG59XG4uZmxleGJveC1pbmxpbmUoKSB7XG4gICAgZGlzcGxheTogLXdlYmtpdC1pbmxpbmUtYm94O1xuICAgIGRpc3BsYXk6IC1tcy1pbmxpbmUtZmxleGJveDtcbiAgICBkaXNwbGF5OiAtd2Via2l0LWlubGluZS1mbGV4O1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xufVxuLmZsZXgtd3JhcChAZncpIHdoZW4gKEBmdyA9IG5vd3JhcCkge1xuICAgIC13ZWJraXQtYm94LWxpbmVzOiBzaW5nbGU7XG4gICAgLW1vei1ib3gtbGluZXM6IHNpbmdsZTtcbiAgICAtd2Via2l0LWZsZXgtd3JhcDogbm93cmFwO1xuICAgIC1tcy1mbGV4LXdyYXA6IG5vbmU7XG4gICAgLW1zLWZsZXgtd3JhcDogbm93cmFwO1xuICAgIGZsZXgtd3JhcDogbm93cmFwO1xufVxuLmZsZXgtd3JhcChAZncpIHdoZW4gKEBmdyA9IHdyYXApIHtcbiAgICAtd2Via2l0LWJveC1saW5lczogbXVsdGlwbGU7XG4gICAgLW1vei1ib3gtbGluZXM6IG11bHRpcGxlO1xuICAgIC13ZWJraXQtZmxleC13cmFwOiB3cmFwO1xuICAgIC1tcy1mbGV4LXdyYXA6IHdyYXA7XG4gICAgZmxleC13cmFwOiB3cmFwO1xufVxuLmZsZXgtd3JhcChAZncpIHdoZW4gbm90IChAZncgPSB3cmFwKSBhbmQgbm90IChAZncgPSBub3dyYXApIHtcbiAgICAtd2Via2l0LWZsZXgtd3JhcDogQGZ3O1xuICAgIC1tcy1mbGV4LXdyYXA6IEBmdztcbiAgICBmbGV4LXdyYXA6IEBmdztcbn1cbi5mbGV4LXNocmluayhAZnMpIHtcbiAgICAtd2Via2l0LWZsZXgtc2hyaW5rOiBAZnM7XG4gICAgLW1zLWZsZXg6IDAgQGZzIGF1dG87XG4gICAgZmxleC1zaHJpbms6IEBmcztcbn1cbi5qdXN0aWZ5LWNvbnRlbnQoQGpjKSB3aGVuIChAamMgPSBmbGV4LXN0YXJ0KSB7XG4gICAgLXdlYmtpdC1ib3gtcGFjazogc3RhcnQ7XG4gICAgLW1zLWZsZXgtcGFjazogc3RhcnQ7XG4gICAgLXdlYmtpdC1qdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtc3RhcnQ7XG4gICAganVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xufVxuLmp1c3RpZnktY29udGVudChAamMpIHdoZW4gKEBqYyA9IGZsZXgtZW5kKSB7XG4gICAgLXdlYmtpdC1ib3gtcGFjazogZW5kO1xuICAgIC1tcy1mbGV4LXBhY2s6IGVuZDtcbiAgICAtd2Via2l0LWp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG4gICAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbn1cbi5qdXN0aWZ5LWNvbnRlbnQoQGpjKSB3aGVuIChAamMgPSBzcGFjZS1iZXR3ZWVuKSB7XG4gICAgLXdlYmtpdC1ib3gtcGFjazoganVzdGlmeTtcbiAgICAtbXMtZmxleC1wYWNrOiBqdXN0aWZ5O1xuICAgIC13ZWJraXQtanVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2Vlbjtcbn1cbi5qdXN0aWZ5LWNvbnRlbnQoQGpjKSB3aGVuIG5vdCAoQGpjID0gZmxleC1zdGFydCkgYW5kIG5vdCAoQGpjID0gZmxleC1lbmQpIGFuZCBub3QgKEBqYyA9IHNwYWNlLWJldHdlZW4pIHtcbiAgICAtd2Via2l0LWJveC1wYWNrOiBAamM7XG4gICAgLW1zLWZsZXgtcGFjazogQGpjO1xuICAgIC13ZWJraXQtanVzdGlmeS1jb250ZW50OiBAamM7XG4gICAganVzdGlmeS1jb250ZW50OiBAamM7XG59XG4uYWxpZ24taXRlbXMoQGFpKSB3aGVuIChAYWkgPSBmbGV4LXN0YXJ0KSB7XG4gICAgLXdlYmtpdC1ib3gtYWxpZ246IHN0YXJ0O1xuICAgIC1tcy1mbGV4LWFsaWduOiBzdGFydDtcbiAgICAtd2Via2l0LWFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1xuICAgIGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1xufVxuLmFsaWduLWl0ZW1zKEBhaSkgd2hlbiAoQGFpID0gZmxleC1lbmQpIHtcbiAgICAtd2Via2l0LWJveC1hbGlnbjogZW5kO1xuICAgIC1tcy1mbGV4LWFsaWduOiBlbmQ7XG4gICAgLXdlYmtpdC1hbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gICAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xufVxuLmFsaWduLWl0ZW1zKEBhaSkgd2hlbiBub3QgKEBhaSA9IGZsZXgtc3RhcnQpIGFuZCBub3QgKEBhaSA9IGZsZXgtZW5kKSB7XG4gICAgLXdlYmtpdC1ib3gtYWxpZ246IEBhaTtcbiAgICAtbXMtZmxleC1hbGlnbjogQGFpO1xuICAgIC13ZWJraXQtYWxpZ24taXRlbXM6IEBhaTtcbiAgICBhbGlnbi1pdGVtczogQGFpO1xufVxuLmFsaWduLWNvbnRlbnQoQGFpKSB7XG4gICAgLW1zLWZsZXgtbGluZS1wYWNrOiBAYWk7XG4gICAgLXdlYmtpdC1hbGlnbi1jb250ZW50OiBAYWk7XG4gICAgYWxpZ24tY29udGVudDogQGFpO1xufVxuLmFsaWduLXNlbGYoQGFzKSB7XG4gICAgLW1zLWZsZXgtaXRlbS1hbGlnbjogQGFzO1xuICAgIC13ZWJraXQtYWxpZ24tc2VsZjogQGFzO1xuICAgIGFsaWduLXNlbGY6IEBhcztcbn1cbi5jbGVhcmZpeCgpIHtcbiAgICAmOmJlZm9yZSxcbiAgICAmOmFmdGVyIHtcbiAgICAgICAgY29udGVudDogXCIgXCI7XG4gICAgICAgIGRpc3BsYXk6IHRhYmxlO1xuICAgIH1cbiAgICAmOmFmdGVyIHtcbiAgICAgICAgY2xlYXI6IGJvdGg7XG4gICAgfVxufVxuLmhhaXJsaW5lKEBwb3NpdGlvbiwgQGNvbG9yKSB3aGVuIChAcG9zaXRpb24gPSB0b3ApIHtcbiAgICAmOmJlZm9yZSB7XG4gICAgICAgIGNvbnRlbnQ6ICcnO1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgYm90dG9tOiBhdXRvO1xuICAgICAgICByaWdodDogYXV0bztcbiAgICAgICAgaGVpZ2h0OiAxcHg7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAY29sb3I7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB6LWluZGV4OiAxNTtcbiAgICAgICAgLnRyYW5zZm9ybS1vcmlnaW4oNTAlIDAlKTtcbiAgICAgICAgaHRtbC5waXhlbC1yYXRpby0yICYge1xuICAgICAgICAgICAgLnRyYW5zZm9ybShzY2FsZVkoMC41KSk7XG4gICAgICAgIH1cbiAgICAgICAgaHRtbC5waXhlbC1yYXRpby0zICYge1xuICAgICAgICAgICAgLnRyYW5zZm9ybShzY2FsZVkoMC4zMykpO1xuICAgICAgICB9XG4gICAgfVxufVxuLmhhaXJsaW5lKEBwb3NpdGlvbiwgQGNvbG9yKSB3aGVuIChAcG9zaXRpb24gPSBsZWZ0KSB7XG4gICAgJjpiZWZvcmUge1xuICAgICAgICBjb250ZW50OiAnJztcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICBsZWZ0OiAwO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIGJvdHRvbTogYXV0bztcbiAgICAgICAgcmlnaHQ6IGF1dG87XG4gICAgICAgIHdpZHRoOiAxcHg7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQGNvbG9yO1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgei1pbmRleDogMTU7XG4gICAgICAgIC50cmFuc2Zvcm0tb3JpZ2luKDAlIDUwJSk7XG4gICAgICAgIGh0bWwucGl4ZWwtcmF0aW8tMiAmIHtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGVYKDAuNSkpO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwucGl4ZWwtcmF0aW8tMyAmIHtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGVYKDAuMzMpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi5oYWlybGluZShAcG9zaXRpb24sIEBjb2xvcikgd2hlbiAoQHBvc2l0aW9uID0gYm90dG9tKSB7XG4gICAgJjphZnRlciB7XG4gICAgICAgIGNvbnRlbnQ6ICcnO1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIGJvdHRvbTogMDtcbiAgICAgICAgcmlnaHQ6IGF1dG87XG4gICAgICAgIHRvcDogYXV0bztcbiAgICAgICAgaGVpZ2h0OiAxcHg7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAY29sb3I7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB6LWluZGV4OiAxNTtcbiAgICAgICAgLnRyYW5zZm9ybS1vcmlnaW4oNTAlIDEwMCUpO1xuICAgICAgICBodG1sLnBpeGVsLXJhdGlvLTIgJiB7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlWSgwLjUpKTtcbiAgICAgICAgfVxuICAgICAgICBodG1sLnBpeGVsLXJhdGlvLTMgJiB7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlWSgwLjMzKSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4uaGFpcmxpbmUoQHBvc2l0aW9uLCBAY29sb3IpIHdoZW4gKEBwb3NpdGlvbiA9IHJpZ2h0KSB7XG4gICAgJjphZnRlciB7XG4gICAgICAgIGNvbnRlbnQ6ICcnO1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHJpZ2h0OiAwO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIGxlZnQ6IGF1dG87XG4gICAgICAgIGJvdHRvbTogYXV0bztcbiAgICAgICAgd2lkdGg6IDFweDtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAY29sb3I7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB6LWluZGV4OiAxNTtcbiAgICAgICAgLnRyYW5zZm9ybS1vcmlnaW4oMTAwJSA1MCUpO1xuICAgICAgICBodG1sLnBpeGVsLXJhdGlvLTIgJiB7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlWCgwLjUpKTtcbiAgICAgICAgfVxuICAgICAgICBodG1sLnBpeGVsLXJhdGlvLTMgJiB7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlWCgwLjMzKSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyBGb3IgcmlnaHQgYW5kIGJvdHRvbVxuLmhhaXJsaW5lLXJlbW92ZShAcG9zaXRpb24pIHdoZW4gbm90IChAcG9zaXRpb24gPSBsZWZ0KSBhbmQgbm90IChAcG9zaXRpb24gPSB0b3ApIHtcbiAgICAmOmFmdGVyIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG59XG4vLyBGb3IgbGVmdCBhbmQgdG9wXG4uaGFpcmxpbmUtcmVtb3ZlKEBwb3NpdGlvbikgd2hlbiBub3QgKEBwb3NpdGlvbiA9IHJpZ2h0KSBhbmQgbm90IChAcG9zaXRpb24gPSBib3R0b20pIHtcbiAgICAmOmJlZm9yZSB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxufVxuLy8gRm9yIHJpZ2h0IGFuZCBib3R0b21cbi5oYWlybGluZS1jb2xvcihAcG9zaXRpb24sIEBjb2xvcikgd2hlbiBub3QgKEBwb3NpdGlvbiA9IGxlZnQpIGFuZCBub3QgKEBwb3NpdGlvbiA9IHRvcCkge1xuICAgICY6YWZ0ZXIge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAY29sb3I7XG4gICAgfVxufVxuLy8gRm9yIGxlZnQgYW5kIHRvcFxuLmhhaXJsaW5lLWNvbG9yKEBwb3NpdGlvbiwgQGNvbG9yKSB3aGVuIG5vdCAoQHBvc2l0aW9uID0gcmlnaHQpIGFuZCBub3QgKEBwb3NpdGlvbiA9IGJvdHRvbSkge1xuICAgICY6YmVmb3JlIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQGNvbG9yO1xuICAgIH1cbn1cblxuLy8gRW5jb2RlZCBTVkcgQmFja2dyb3VuZFxuLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoQHN2Zykge1xuICAgIEB1cmw6IGBlbmNvZGVVUklDb21wb25lbnQoQHtzdmd9KWA7XG4gICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKFwiZGF0YTppbWFnZS9zdmcreG1sO2NoYXJzZXQ9dXRmLTgsQHt1cmx9XCIpO1xufVxuXG4vLyBCYWNrZHJvcCBCbHVyXG4uYmFja2Ryb3AtYmx1cihAYmx1cikge1xuICAgIC13ZWJraXQtYmFja2Ryb3AtZmlsdGVyOiBibHVyKEBibHVyKTtcbiAgICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoQGJsdXIpO1xufVxuXG4vLyBQcmVzZXJ2ZTNEXG4ucHJlc2VydmUzZCgpIHtcbiAgICAtd2Via2l0LXRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgLW1vei10cmFuc2Zvcm0tc3R5bGU6IHByZXNlcnZlLTNkO1xuICAgIC1tcy10cmFuc2Zvcm0tc3R5bGU6IHByZXNlcnZlLTNkO1xuICAgIHRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG59XG5cbi8vIE5vIFNjcm9sbGJhclxuLm5vLXNjcm9sbGJhcigpIHtcbiAgICAmOjotd2Via2l0LXNjcm9sbGJhciB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbiAgICAgICAgd2lkdGg6IDAgIWltcG9ydGFudDtcbiAgICAgICAgaGVpZ2h0OiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgb3BhY2l0eTogMCAhaW1wb3J0YW50O1xuICAgIH1cbn1cbi8vIEJhcnMgSW5wdXRcbi5iYXJzLWlucHV0KCkge1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgLW1vei1hcHBlYXJhbmNlOiBub25lO1xuICAgIC1tcy1hcHBlYXJhbmNlOiBub25lO1xuICAgIGFwcGVhcmFuY2U6IG5vbmU7XG4gICAgYm9yZGVyLXJhZGl1czogNXB4O1xuICAgIGZvbnQtZmFtaWx5OiBpbmhlcml0O1xuICAgIGNvbG9yOiMwMDA7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gICAgcGFkZGluZzogMCA4cHg7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbn1cbi5uby1oYWlybGluZXMoKSB7XG4gICAgJi5uby1oYWlybGluZXMsICYubm8taGFpcmxpbmVzIHVsLCAmLm5vLWhhaXJsaW5lcyAuY29udGVudC1ibG9jay1pbm5lciB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUodG9wKTtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgIH1cbn1cbi5uby1oYWlybGluZXMtYmV0d2VlbigpIHtcbiAgICAmLm5vLWhhaXJsaW5lcy1iZXR3ZWVuIHtcbiAgICAgICAgLml0ZW0taW5uZXIsIC5saXN0LWJ1dHRvbiwgLml0ZW0tZGl2aWRlciwgLmxpc3QtZ3JvdXAtdGl0bGUsIC5saXN0LWdyb3VwLXRpdGxlIHtcbiAgICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICAgICAgfVxuICAgIH1cbn0iLCIvKiA9PT0gVmlld3MgPT09ICovXG4udmlld3MsIC52aWV3IHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIHotaW5kZXg6IDUwMDA7XG59XG4udmlld3Mge1xuICAgIC5zY3JvbGxhYmxlKCk7XG59XG4udmlldyB7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xufVxuIiwiLyogPT09IFBhZ2VzID09PSAqL1xuXG4vLyBQYWdlcyBhbmltYXRpb25zXG5AcGFnZUR1cmF0aW9uOiA0MDBtcztcblxuLnBhZ2VzIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYmFja2dyb3VuZDogIzAwMDtcbn1cbi5wYWdlIHtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIHRvcDogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogI2VmZWZmNDtcbiAgICAudHJhbnNsYXRlM2QoMCwwLDApO1xuICAgICYuY2FjaGVkIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG59XG4ucGFnZS1vbi1sZWZ0IHtcbiAgICBvcGFjaXR5OiAwLjk7XG4gICAgLnRyYW5zbGF0ZTNkKC0yMCUpO1xufVxuLnBhZ2Utb24tY2VudGVyIHtcbiAgICAuc3dpcGViYWNrLXBhZ2Utc2hhZG93IHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG59XG4ucGFnZS1vbi1yaWdodCB7XG4gICAgLnRyYW5zbGF0ZTNkKDEwMCUpO1xuICAgIC5zd2lwZWJhY2stcGFnZS1zaGFkb3cge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbn1cbi5wYWdlLWNvbnRlbnQge1xuICAgIC5zY3JvbGxhYmxlKCk7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHotaW5kZXg6IDE7XG59XG5cbi8vIFBhZ2UgU2hhZG93XG4ucGFnZS1mYWtlLXNoYWRvdygpIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcmlnaHQ6IDEwMCU7XG4gICAgdG9wOiAwO1xuICAgIHdpZHRoOiAxNnB4O1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBiYWNrZ3JvdW5kOiAtd2Via2l0LWxpbmVhci1ncmFkaWVudChsZWZ0LCByZ2JhKDAsMCwwLDApIDAlLCByZ2JhKDAsMCwwLDApIDEwJSwgcmdiYSgwLDAsMCwwLjAxKSA1MCUsIHJnYmEoMCwwLDAsMC4yKSAxMDAlKTtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsIHJnYmEoMCwwLDAsMCkgMCUsIHJnYmEoMCwwLDAsMCkgMTAlLCByZ2JhKDAsMCwwLDAuMDEpIDUwJSwgcmdiYSgwLDAsMCwwLjIpIDEwMCUpO1xuICAgIHotaW5kZXg6IC0xO1xuICAgIGNvbnRlbnQ6ICcnO1xuICAgIGh0bWwuYW5kcm9pZCAmIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgLmFuaW1hdGlvbihub25lKTtcbiAgICB9XG59XG4uc3dpcGViYWNrLXBhZ2Utc2hhZG93IHtcbiAgICAucGFnZS1mYWtlLXNoYWRvdygpO1xufVxuXG5cbi8vQ2xhc3MgdGhhdCB3aWxsIHRyaWdnZXIgdHJhbnNpdGlvbiBkdXJpbmcgcGFnZSBjdXN0b20gdHJhbnNpdGlvbnMgKGxpa2Ugc3dpcGUtYmFjaylcbi5wYWdlLXRyYW5zaXRpb25pbmcge1xuICAgICYsIC5zd2lwZWJhY2stcGFnZS1zaGFkb3cge1xuICAgICAgICAudHJhbnNpdGlvbihAcGFnZUR1cmF0aW9uKTtcbiAgICB9XG59XG4ucGFnZS1mcm9tLXJpZ2h0LXRvLWNlbnRlciwgLnBhZ2UtZnJvbS1jZW50ZXItdG8tcmlnaHQge1xuICAgICY6YmVmb3JlIHtcbiAgICAgICAgLnBhZ2UtZmFrZS1zaGFkb3coKTtcbiAgICB9XG59XG4vLyBGcm9tL3RvIFJpZ2h0IFRvL2Zyb20gQ2VudGVyIGFuaW1hdGlvbnNcbi5wYWdlLWZyb20tcmlnaHQtdG8tY2VudGVyIHtcbiAgICAmOmJlZm9yZSB7XG4gICAgICAgIC5hbmltYXRpb24ocGFnZUZyb21SaWdodFRvQ2VudGVyU2hhZG93IEBwYWdlRHVyYXRpb24gZm9yd2FyZHMpO1xuICAgIH1cbiAgICAuYW5pbWF0aW9uKHBhZ2VGcm9tUmlnaHRUb0NlbnRlciBAcGFnZUR1cmF0aW9uIGZvcndhcmRzKTtcbn1cbi5wYWdlLWZyb20tY2VudGVyLXRvLXJpZ2h0IHtcbiAgICAmOmJlZm9yZSB7XG4gICAgICAgIC5hbmltYXRpb24ocGFnZUZyb21DZW50ZXJUb1JpZ2h0U2hhZG93IEBwYWdlRHVyYXRpb24gZm9yd2FyZHMpO1xuICAgIH1cbiAgICAuYW5pbWF0aW9uKHBhZ2VGcm9tQ2VudGVyVG9SaWdodCBAcGFnZUR1cmF0aW9uIGZvcndhcmRzKTtcbn1cbkAtd2Via2l0LWtleWZyYW1lcyBwYWdlRnJvbVJpZ2h0VG9DZW50ZXIge1xuICAgIGZyb20ge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMTAwJSwwLDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxufVxuQGtleWZyYW1lcyBwYWdlRnJvbVJpZ2h0VG9DZW50ZXIge1xuICAgIGZyb20ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDEwMCUsMCwwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG59XG5ALXdlYmtpdC1rZXlmcmFtZXMgcGFnZUZyb21SaWdodFRvQ2VudGVyU2hhZG93IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcGFnZUZyb21SaWdodFRvQ2VudGVyU2hhZG93IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cbkAtd2Via2l0LWtleWZyYW1lcyBwYWdlRnJvbUNlbnRlclRvUmlnaHQge1xuICAgIGZyb20ge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgxMDAlLDAsMCk7XG4gICAgfVxufVxuQGtleWZyYW1lcyBwYWdlRnJvbUNlbnRlclRvUmlnaHQge1xuICAgIGZyb20ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDEwMCUsMCwwKTtcbiAgICB9XG59XG5ALXdlYmtpdC1rZXlmcmFtZXMgcGFnZUZyb21DZW50ZXJUb1JpZ2h0U2hhZG93IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcGFnZUZyb21DZW50ZXJUb1JpZ2h0U2hhZG93IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbn1cblxuXG4vLyBGcm9tL3RvIENlbnRlciBUby9mcm9tIExlZnQgYW5pbWF0aW9uc1xuLnBhZ2UtZnJvbS1jZW50ZXItdG8tbGVmdCB7XG4gICAgLmFuaW1hdGlvbihwYWdlRnJvbUNlbnRlclRvTGVmdCBAcGFnZUR1cmF0aW9uIGZvcndhcmRzKTtcbn1cbi5wYWdlLWZyb20tbGVmdC10by1jZW50ZXIge1xuICAgIC5hbmltYXRpb24ocGFnZUZyb21MZWZ0VG9DZW50ZXIgQHBhZ2VEdXJhdGlvbiBmb3J3YXJkcyk7XG59XG5cbkAtd2Via2l0LWtleWZyYW1lcyBwYWdlRnJvbUNlbnRlclRvTGVmdCB7XG4gICAgZnJvbSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgb3BhY2l0eTogMC45O1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlM2QoLTIwJSwwLDApO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcGFnZUZyb21DZW50ZXJUb0xlZnQge1xuICAgIGZyb20ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAwLjk7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoLTIwJSwwLDApO1xuICAgIH1cbn1cbkAtd2Via2l0LWtleWZyYW1lcyBwYWdlRnJvbUxlZnRUb0NlbnRlciB7XG4gICAgZnJvbSB7XG4gICAgICAgIG9wYWNpdHk6IDAuOTtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKC0yMCUsMCwwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcGFnZUZyb21MZWZ0VG9DZW50ZXIge1xuICAgIGZyb20ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKC0yMCUsMCwwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG59IiwiLyogPT09IFRvb2xiYXJzID09PSAqL1xuXG4vL1Rvb2xiYXIvTmF2YmFyXG5AdG9vbGJhckJnIDogI2Y3ZjdmODtcbkB0b29sYmFyQmdCbHVyZWQ6IHJnYmEoMjQ4LDI0OCwyNDksIDAuODUpO1xuQHRvb2xiYXJCb3JkZXJDb2xvcjogI2M0YzRjNDtcbkB0b29sYmFyTGlua3NDb2xvcjogQHRoZW1lQ29sb3I7XG5AdG9vbGJhclNpemU6IDQ0cHg7XG5cbi8vVGFiIGJhclxuQHRhYmJhckxhYmVsc1NpemU6IDUwcHg7XG5AdGFiYmFyTGlua3NDb2xvcjogIzkyOTI5MjtcbkB0YWJiYXJBY3RpdmVMaW5rc0NvbG9yOiBAdGhlbWVDb2xvcjtcbkB0YWJiYXJMYWJlbHNTaXplVGFibGV0OiA1NnB4O1xuXG4vLyBUb29sYmFycyBhbmltYXRpb25zXG5AdG9vbGJhckR1cmF0aW9uOiA0MDBtcztcblxuLm5hdmJhci1pbm5lciwgLnRvb2xiYXItaW5uZXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIHRvcDogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgcGFkZGluZzogMCA4cHg7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAuZmxleGJveCgpO1xuICAgIC5qdXN0aWZ5LWNvbnRlbnQoc3BhY2UtYmV0d2Vlbik7XG4gICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG59XG4ubmF2YmFyLWlubmVyLmNhY2hlZCB7XG4gICAgZGlzcGxheTogbm9uZTtcbn1cbi5uYXZiYXIsIC50b29sYmFyIHtcbiAgICBoZWlnaHQ6IEB0b29sYmFyU2l6ZTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIGZvbnQtc2l6ZTogMTdweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgbWFyZ2luOiAwO1xuICAgIHotaW5kZXg6IDUwMDtcbiAgICAtd2Via2l0LWJhY2tmYWNlLXZpc2liaWxpdHk6IGhpZGRlbjtcbiAgICBiYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgYiB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgICAgIGh0bWwuaW9zLWd0LTggJiB7XG4gICAgICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgICB9XG4gICAgfVxufVxuLm5hdmJhciwgLnRvb2xiYXIsIC5zdWJuYXZiYXIge1xuICAgIGJhY2tncm91bmQ6IEB0b29sYmFyQmc7XG4gICAgYS5saW5rIHtcbiAgICAgICAgbGluZS1oZWlnaHQ6IEB0b29sYmFyU2l6ZTtcbiAgICAgICAgaGVpZ2h0OiBAdG9vbGJhclNpemU7XG4gICAgICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICAuanVzdGlmeS1jb250ZW50KGZsZXgtc3RhcnQpO1xuICAgICAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZVooMHB4KSk7XG4gICAgICAgIGh0bWw6bm90KC53YXRjaC1hY3RpdmUtc3RhdGUpICY6YWN0aXZlLCAmLmFjdGl2ZS1zdGF0ZSB7XG4gICAgICAgICAgICBvcGFjaXR5OiAwLjM7XG4gICAgICAgICAgICAudHJhbnNpdGlvbigwbXMpO1xuICAgICAgICB9XG4gICAgICAgIGkrc3BhbiwgaStpLCBzcGFuK2ksIHNwYW4rc3BhbiB7XG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogN3B4O1xuICAgICAgICB9XG4gICAgfVxuICAgIGEuaWNvbi1vbmx5IHtcbiAgICAgICAgbWluLXdpZHRoOiBAdG9vbGJhclNpemU7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC5qdXN0aWZ5LWNvbnRlbnQoY2VudGVyKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICB9XG4gICAgaS5pY29uIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgfVxufVxuLm5hdmJhciB7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgLmhhaXJsaW5lKGJvdHRvbSwgQHRvb2xiYXJCb3JkZXJDb2xvcik7XG4gICAgJjphZnRlciB7XG4gICAgICAgIGJhY2tmYWNlLXZpc2liaWxpdHk6IGhpZGRlbjtcbiAgICB9XG4gICAgJi5uby1ib3JkZXIge1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgfVxuICAgIC5jZW50ZXIge1xuICAgICAgICBmb250LXNpemU6IDE3cHg7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgICAgIGh0bWwuaW9zLWd0LTggJiB7XG4gICAgICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgICB9XG4gICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgICAgbWFyZ2luOiAwO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6ZWxsaXBzaXM7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiBAdG9vbGJhclNpemU7XG4gICAgICAgIC5mbGV4LXNocmluaygxMCk7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC5hbGlnbi1pdGVtcyhjZW50ZXIpO1xuICAgIH1cbiAgICAubGVmdCwgLnJpZ2h0IHtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDApO1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICAuanVzdGlmeS1jb250ZW50KGZsZXgtc3RhcnQpO1xuICAgICAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAgICAgYSthIHtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiAxNXB4O1xuICAgICAgICB9XG4gICAgfVxuICAgIC5sZWZ0IHtcbiAgICAgICAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xuICAgIH1cbiAgICAucmlnaHQge1xuICAgICAgICBtYXJnaW4tbGVmdDogMTBweDtcbiAgICB9XG4gICAgLnJpZ2h0OmZpcnN0LWNoaWxkIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICByaWdodDogOHB4O1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgfVxuICAgIC5wb3B1cCAmIHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG59XG4uc3VibmF2YmFyIHtcbiAgICBoZWlnaHQ6IEB0b29sYmFyU2l6ZTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDEwMCU7XG4gICAgbWFyZ2luLXRvcDogLTFweDtcbiAgICB6LWluZGV4OiAyMDtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIHBhZGRpbmc6IDAgOHB4O1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmp1c3RpZnktY29udGVudChzcGFjZS1iZXR3ZWVuKTtcbiAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAuaGFpcmxpbmUoYm90dG9tLCBAdG9vbGJhckJvcmRlckNvbG9yKTtcbiAgICAmLm5vLWJvcmRlciB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICB9XG4gICAgLm5hdmJhci5uby1ib3JkZXIgJiB7XG4gICAgICAgIG1hcmdpbi10b3A6IDA7XG4gICAgfVxuICAgIC5uYXZiYXItb24tbGVmdCAmLCAubmF2YmFyLW9uLXJpZ2h0ICZ7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIH1cbiAgICAubmF2YmFyICYsIC5wYWdlICYge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgfVxuICAgIC5wYWdlID4gJiB7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgbWFyZ2luLXRvcDogMDtcbiAgICB9XG4gICAgPiAuYnV0dG9ucy1yb3cge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICB9XG4gICAgLnNlYXJjaGJhciwgJi5zZWFyY2hiYXIge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgfVxuICAgICYuc2VhcmNoYmFyLCAuc2VhcmNoYmFyIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIH1cbiAgICAuc2VhcmNoYmFyIHtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgdG9wOiAwO1xuICAgIH1cbn1cbi50b29sYmFyIHtcbiAgICBsZWZ0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICAuaGFpcmxpbmUodG9wLCBAdG9vbGJhckJvcmRlckNvbG9yKTtcbiAgICAmLm5vLWJvcmRlciB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUodG9wKTtcbiAgICB9XG4gICAgYSB7XG4gICAgICAgIC5mbGV4LXNocmluaygxKTtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgICB0ZXh0LW92ZXJmbG93OmVsbGlwc2lzO1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIH1cbn1cblxuLy8gVGFiYmFyXG4udGFiYmFyIHtcbiAgICBjb2xvcjogQHRhYmJhckxpbmtzQ29sb3I7XG4gICAgei1pbmRleDogNTAwMTtcbiAgICBhIHtcbiAgICAgICAgY29sb3I6IEB0YWJiYXJMaW5rc0NvbG9yO1xuICAgIH1cbiAgICBhLmFjdGl2ZSB7XG4gICAgICAgIGNvbG9yOiBAdGFiYmFyQWN0aXZlTGlua3NDb2xvcjtcbiAgICB9XG4gICAgYS5saW5rIHtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDEuNDtcbiAgICB9XG4gICAgYS50YWItbGluaywgYS5saW5rIHtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgLmZsZXhib3goKTtcbiAgICAgICAgLmp1c3RpZnktY29udGVudChjZW50ZXIpO1xuICAgICAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAgICAgb3ZlcmZsb3c6IHZpc2libGU7XG4gICAgICAgIC13ZWJraXQtYm94LWZsZXg6IDE7XG4gICAgICAgIC1tcy1mbGV4OiAxO1xuICAgICAgICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgICAgICAtbW96LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgICAgICAtbXMtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIH1cbiAgICBpLmljb24ge1xuICAgICAgICBoZWlnaHQ6IDMwcHg7XG4gICAgfVxufVxuLnRhYmJhci1sYWJlbHMge1xuICAgIGhlaWdodDogQHRhYmJhckxhYmVsc1NpemU7XG4gICAgYS50YWItbGluaywgYS5saW5rIHtcbiAgICAgICAgcGFkZGluZy10b3A6IDRweDtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IDRweDtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICAuanVzdGlmeS1jb250ZW50KHNwYWNlLWJldHdlZW4pO1xuICAgICAgICBpICsgc3BhbiB7XG4gICAgICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3Bhbi50YWJiYXItbGFiZWwge1xuICAgICAgICBsaW5lLWhlaWdodDogMTtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgbGV0dGVyLXNwYWNpbmc6IDAuMDFlbTtcbiAgICAgICAgZm9udC1zaXplOiAxMHB4O1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIH1cbn1cbi5zdWJuYXZiYXIsIC5uYXZiYXIge1xuICAgIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLCBpbnB1dFt0eXBlPVwicGFzc3dvcmRcIl0sIGlucHV0W3R5cGU9XCJzZWFyY2hcIl0sIGlucHV0W3R5cGU9XCJlbWFpbFwiXSwgaW5wdXRbdHlwZT1cInRlbFwiXSwgaW5wdXRbdHlwZT1cInVybFwiXSB7XG4gICAgICAgIC5iYXJzLWlucHV0KCk7XG4gICAgfVxufVxuQG1lZGlhIGFsbCBhbmQgKG1pbi13aWR0aDo3NjhweCkge1xuICAgIC50YWJiYXIge1xuICAgICAgICAudG9vbGJhci1pbm5lciB7XG4gICAgICAgICAgICAuanVzdGlmeS1jb250ZW50KGNlbnRlcik7XG4gICAgICAgIH1cbiAgICAgICAgYS50YWItbGluaywgYS5saW5rIHtcbiAgICAgICAgICAgIHdpZHRoOiBhdXRvO1xuICAgICAgICAgICAgbWluLXdpZHRoOiAxMDVweDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAudGFiYmFyLWxhYmVscyB7XG4gICAgICAgIGhlaWdodDogQHRhYmJhckxhYmVsc1NpemVUYWJsZXQ7XG4gICAgICAgIHNwYW4udGFiYmFyLWxhYmVsIHtcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLm5hdmJhci1mcm9tLXJpZ2h0LXRvLWNlbnRlciB7XG4gICAgLmxlZnQsIC5yaWdodCwgLmNlbnRlciwgLnN1Ym5hdmJhciwgLmZhZGluZyB7XG4gICAgICAgIC5hbmltYXRpb24obmF2YmFyRWxlbWVudEZhZGVJbiBAdG9vbGJhckR1cmF0aW9uIGZvcndhcmRzKTtcbiAgICB9XG4gICAgLnNsaWRpbmcge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICBcbn1cbi5uYXZiYXItZnJvbS1jZW50ZXItdG8tcmlnaHQge1xuICAgIC5sZWZ0LCAucmlnaHQsIC5jZW50ZXIsIC5zdWJuYXZiYXIsIC5mYWRpbmcge1xuICAgICAgICAuYW5pbWF0aW9uKG5hdmJhckVsZW1lbnRGYWRlT3V0IEB0b29sYmFyRHVyYXRpb24gZm9yd2FyZHMpO1xuICAgIH1cbiAgICAuc2xpZGluZyB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxuICAgIC5zdWJuYXZiYXIuc2xpZGluZyB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIG5hdmJhckVsZW1lbnRGYWRlSW4ge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxufVxuQGtleWZyYW1lcyBuYXZiYXJFbGVtZW50RmFkZUluIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cbi5uYXZiYXItZnJvbS1jZW50ZXItdG8tbGVmdCB7XG4gICAgLmxlZnQsIC5yaWdodCwgLmNlbnRlciwgLnN1Ym5hdmJhciwgLmZhZGluZyB7XG4gICAgICAgIC5hbmltYXRpb24obmF2YmFyRWxlbWVudEZhZGVPdXQgQHRvb2xiYXJEdXJhdGlvbiBmb3J3YXJkcyk7XG4gICAgfVxuICAgIC5zbGlkaW5nIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG4gICAgLnN1Ym5hdmJhci5zbGlkaW5nIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG59XG4ubmF2YmFyLWZyb20tbGVmdC10by1jZW50ZXIge1xuICAgIC5sZWZ0LCAucmlnaHQsIC5jZW50ZXIsIC5zdWJuYXZiYXIsIC5mYWRpbmcge1xuICAgICAgICAuYW5pbWF0aW9uKG5hdmJhckVsZW1lbnRGYWRlSW4gQHRvb2xiYXJEdXJhdGlvbiBmb3J3YXJkcyk7XG4gICAgfVxuICAgIC5zbGlkaW5nIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG59XG4ubmF2YmFyLW9uLWxlZnQge1xuICAgIC5sZWZ0LCAucmlnaHQsIC5jZW50ZXIsIC5zdWJuYXZiYXIsIC5mYWRpbmcge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbiAgICAuc2xpZGluZyB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxuICAgIC5zdWJuYXZiYXIuc2xpZGluZyB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIC50cmFuc2xhdGUzZCgtMTAwJSwwLDApO1xuICAgIH1cbn1cbi5uYXZiYXItb24tcmlnaHQge1xuICAgIC5sZWZ0LCAucmlnaHQsIC5jZW50ZXIsIC5zdWJuYXZiYXIsIC5mYWRpbmcge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbiAgICAuc2xpZGluZyB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxuICAgIC5zdWJuYXZiYXIuc2xpZGluZyB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgxMDAlLDAsMCk7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIG5hdmJhckVsZW1lbnRGYWRlT3V0IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgbmF2YmFyRWxlbWVudEZhZGVPdXQge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxufVxuLm5hdmJhci1mcm9tLXJpZ2h0LXRvLWNlbnRlciwgLm5hdmJhci1mcm9tLWNlbnRlci10by1yaWdodCwgLm5hdmJhci1mcm9tLWNlbnRlci10by1sZWZ0LCAubmF2YmFyLWZyb20tbGVmdC10by1jZW50ZXIge1xuICAgIC5sZWZ0LnNsaWRpbmcgLmJhY2subGluayAuaWNvbiB7XG4gICAgICAgIC50cmFuc2l0aW9uKEB0b29sYmFyRHVyYXRpb24pO1xuICAgIH1cbiAgICAuc2xpZGluZyB7XG4gICAgICAgIC50cmFuc2l0aW9uKEB0b29sYmFyRHVyYXRpb24pO1xuICAgICAgICAuYW5pbWF0aW9uKG5vbmUpO1xuICAgIH1cbn0iLCIvKiA9PT0gUmVsYXRpb24gYmV0d2VlbiB0b29sYmFyL25hdmJhciB0eXBlcyBhbmQgcGFnZXMgPT09ICovXG4ucGFnZSwgLnZpZXcsIC52aWV3c3tcbiAgICA+Lm5hdmJhciwgPi50b29sYmFyIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIH1cbn1cbi5zdWJuYXZiYXIgfiAucGFnZS1jb250ZW50IHtcbiAgICBwYWRkaW5nLXRvcDogQHRvb2xiYXJTaXplO1xufVxuLm5hdmJhci10aHJvdWdoLCAubmF2YmFyLWZpeGVkIHtcbiAgICAucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy10b3A6IEB0b29sYmFyU2l6ZTtcbiAgICB9XG4gICAgLndpdGgtc3VibmF2YmFyIC5wYWdlLWNvbnRlbnQsIC5wYWdlLWNvbnRlbnQud2l0aC1zdWJuYXZiYXIsIC5zdWJuYXZiYXIgfiAucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy10b3A6IEB0b29sYmFyU2l6ZSAqIDI7XG4gICAgfVxuICAgIC5wYWdlIC5zdWJuYXZiYXIsICYucGFnZSAuc3VibmF2YmFyIHtcbiAgICAgICAgdG9wOiBAdG9vbGJhclNpemU7XG4gICAgfVxufVxuXG4udG9vbGJhci10aHJvdWdoLCAudG9vbGJhci1maXhlZCwgLnRhYmJhci10aHJvdWdoLCAudGFiYmFyLWZpeGVkIHtcbiAgICAucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IEB0b29sYmFyU2l6ZTtcbiAgICB9XG59XG4udGFiYmFyLWxhYmVscy1maXhlZCwgLnRhYmJhci1sYWJlbHMtdGhyb3VnaCB7XG4gICAgLnBhZ2UtY29udGVudCB7XG4gICAgICAgIHBhZGRpbmctYm90dG9tOiBAdGFiYmFyTGFiZWxzU2l6ZTtcbiAgICAgICAgQG1lZGlhIGFsbCBhbmQgKG1pbi13aWR0aDo3NjhweCkge1xuICAgICAgICAgICAgcGFkZGluZy1ib3R0b206IEB0YWJiYXJMYWJlbHNTaXplVGFibGV0O1xuICAgICAgICB9XG4gICAgfVxufVxuLy8gUGFnZSBIaWRkZW4gTmF2YmFyXG4ubmF2YmFyIHtcbiAgICAmLm5hdmJhci1oaWRpbmcge1xuICAgICAgICAudHJhbnNpdGlvbig0MDBtcyk7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgICAgICYgfiAucGFnZS1jb250ZW50LCAmIH4gLnBhZ2VzLCAmIH4gLnBhZ2Uge1xuICAgICAgICAgICAgLmxpc3QtZ3JvdXAtdGl0bGUge1xuICAgICAgICAgICAgICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC5zdWJuYXZiYXIge1xuICAgICAgICAgICAgICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAmLm5hdmJhci1oaWRkZW4ge1xuICAgICAgICAudHJhbnNpdGlvbig0MDBtcyk7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLC0xMDAlLDApO1xuICAgICAgICAmIH4gLnBhZ2UtY29udGVudCwgJiB+IC5wYWdlcywgJiB+IC5wYWdlIHtcbiAgICAgICAgICAgIC5saXN0LWdyb3VwLXRpdGxlIHtcbiAgICAgICAgICAgICAgICAudHJhbnNpdGlvbig0MDBtcyk7XG4gICAgICAgICAgICAgICAgdG9wOi1AdG9vbGJhclNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAuc3VibmF2YmFyIHtcbiAgICAgICAgICAgICAgICAudHJhbnNsYXRlM2QoMCwtMTAwJSwwKTtcbiAgICAgICAgICAgICAgICAudHJhbnNpdGlvbig0MDBtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4ucGFnZS5uby1uYXZiYXIge1xuICAgIC5wYWdlLWNvbnRlbnQge1xuICAgICAgICBwYWRkaW5nLXRvcDogMDtcbiAgICB9XG4gICAgJi53aXRoLXN1Ym5hdmJhciAucGFnZS1jb250ZW50LCAud2l0aC1zdWJuYXZiYXIgJiAucGFnZS1jb250ZW50LCAucGFnZS1jb250ZW50LndpdGgtc3VibmF2YmFyIHtcbiAgICAgICAgcGFkZGluZy10b3A6IEB0b29sYmFyU2l6ZTtcbiAgICB9XG59XG4vLyBQYWdlIEhpZGRlbiBUb29sYmFyXG4udG9vbGJhciwgLnRhYmJhciB7XG4gICAgJi50b29sYmFyLWhpZGluZywgJi50YWJiYXItaGlkaW5nIHtcbiAgICAgICAgLnRyYW5zaXRpb24oNDAwbXMpO1xuICAgICAgICAudHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIH1cbiAgICAmLnRvb2xiYXItaGlkZGVuLCAmLnRhYmJhci1oaWRkZW4ge1xuICAgICAgICAudHJhbnNpdGlvbig0MDBtcyk7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLDEwMCUsMCk7XG4gICAgfVxufVxuLnBhZ2Uubm8tdG9vbGJhciAucGFnZS1jb250ZW50LCAucGFnZS5uby10YWJiYXIgLnBhZ2UtY29udGVudCB7XG4gICAgcGFkZGluZy1ib3R0b206IDA7XG59XG4iLCIvKiA9PT0gU2VhcmNoIEJhciA9PT0gKi9cbkBzZWFyY2hiYXJCZzogI2M5YzljZTtcbkBzZWFyY2hiYXJCb3JkZXJDb2xvcjogI2I0YjRiNDtcbkBzZWFyY2hiYXJTaXplOiA0NHB4O1xuLnNlYXJjaGJhciB7XG4gICAgaGVpZ2h0OiBAc2VhcmNoYmFyU2l6ZTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBiYWNrZ3JvdW5kOiBAc2VhcmNoYmFyQmc7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAuaGFpcmxpbmUoYm90dG9tLCBAc2VhcmNoYmFyQm9yZGVyQ29sb3IpO1xuICAgIHBhZGRpbmc6IDAgOHB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgLnNlYXJjaGJhci1pbnB1dCB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IDI4cHg7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDEpO1xuICAgIH1cbiAgICBpbnB1dFt0eXBlPVwic2VhcmNoXCJdIHtcbiAgICAgICAgLmJhcnMtaW5wdXQoKTtcbiAgICAgICAgcGFkZGluZzogMCAyOHB4O1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IDhweCBjZW50ZXI7XG4gICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxMyAxMycgZW5hYmxlLWJhY2tncm91bmQ9J25ldyAwIDAgMTMgMTMnPjxnPjxwYXRoIGZpbGw9JyM5MzkzOTgnIGQ9J001LDFjMi4yLDAsNCwxLjgsNCw0UzcuMiw5LDUsOVMxLDcuMiwxLDVTMi44LDEsNSwxIE01LDBDMi4yLDAsMCwyLjIsMCw1czIuMiw1LDUsNXM1LTIuMiw1LTVTNy44LDAsNSwwIEw1LDB6Jy8+PC9nPjxsaW5lIHN0cm9rZT0nIzkzOTM5OCcgc3Ryb2tlLW1pdGVybGltaXQ9JzEwJyB4MT0nMTIuNicgeTE9JzEyLjYnIHgyPSc4LjInIHkyPSc4LjInLz48L3N2Zz5cIik7XG4gICAgICAgIC13ZWJraXQtYmFja2dyb3VuZC1zaXplOiAxM3B4IDEzcHg7XG4gICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTNweCAxM3B4O1xuICAgICAgICAmOjotd2Via2l0LWlucHV0LXBsYWNlaG9sZGVyIHtcbiAgICAgICAgICAgIGNvbG9yOiAjOTM5Mzk4O1xuICAgICAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgfVxuICAgICAgICAmOjotd2Via2l0LXNlYXJjaC1jYW5jZWwtYnV0dG9uIHtcbiAgICAgICAgICAgIC13ZWJraXQtYXBwZWFyYW5jZTpub25lO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5zZWFyY2hiYXItY2xlYXIge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHdpZHRoOiAyOHB4O1xuICAgICAgICBoZWlnaHQ6IDI4cHg7XG4gICAgICAgIHJpZ2h0OiAwO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOm5vbmU7XG4gICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlcjtcbiAgICAgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoXCI8c3ZnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zycgdmlld0JveD0nMCAwIDI4IDI4Jz48Y2lyY2xlIGN4PScxNCcgY3k9JzE0JyByPScxNCcgZmlsbD0nIzhlOGU5MycvPjxsaW5lIHN0cm9rZT0nI2ZmZmZmZicgc3Ryb2tlLXdpZHRoPScyJyBzdHJva2UtbWl0ZXJsaW1pdD0nMTAnIHgxPSc4JyB5MT0nOCcgeDI9JzIwJyB5Mj0nMjAnLz48bGluZSBmaWxsPSdub25lJyBzdHJva2U9JyNmZmZmZmYnIHN0cm9rZS13aWR0aD0nMicgc3Ryb2tlLW1pdGVybGltaXQ9JzEwJyB4MT0nMjAnIHkxPSc4JyB4Mj0nOCcgeTI9JzIwJy8+PC9zdmc+XCIpO1xuICAgICAgICAtd2Via2l0LWJhY2tncm91bmQtc2l6ZTogMTRweCAxNHB4O1xuICAgICAgICBiYWNrZ3JvdW5kLXNpemU6IDE0cHggMTRweDtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuICAgIC5zZWFyY2hiYXItY2FuY2VsIHtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICAudHJhbnNsYXRlM2QoMCwwLDApO1xuICAgICAgICBmb250LXNpemU6IDE3cHg7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDApO1xuICAgICAgICBtYXJnaW4tbGVmdDogMDtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6bm9uZTtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gICAgJi5zZWFyY2hiYXItYWN0aXZlIHtcbiAgICAgICAgLnNlYXJjaGJhci1jYW5jZWwge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICAgICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgICAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbiAgICAgICAgICAgIGh0bWw6bm90KC53YXRjaC1hY3RpdmUtc3RhdGUpICY6YWN0aXZlLCAmLmFjdGl2ZS1zdGF0ZSB7XG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC4zO1xuICAgICAgICAgICAgICAgIC50cmFuc2l0aW9uKDBtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgJi5zZWFyY2hiYXItbm90LWVtcHR5IHtcbiAgICAgICAgLnNlYXJjaGJhci1jbGVhciB7XG4gICAgICAgICAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbiAgICAgICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIH1cbiAgICB9XG59XG4uc2VhcmNoYmFyLW92ZXJsYXkge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIHRvcDogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgei1pbmRleDogMTAwO1xuICAgIG9wYWNpdHk6IDA7XG4gICAgcG9pbnRlci1ldmVudHM6bm9uZTtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsMCwwLDAuNCk7XG4gICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgJi5zZWFyY2hiYXItb3ZlcmxheS1hY3RpdmUge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbiAgICB9XG59XG4uc2VhcmNoYmFyLW5vdC1mb3VuZCB7XG4gICAgZGlzcGxheTogbm9uZTtcbn1cbi5oaWRkZW4tYnktc2VhcmNoYmFyLCAubGlzdC1ibG9jayAuaGlkZGVuLWJ5LXNlYXJjaGJhciwgLmxpc3QtYmxvY2sgbGkuaGlkZGVuLWJ5LXNlYXJjaGJhciB7XG4gICAgZGlzcGxheTogbm9uZTtcbn1cbi5wYWdlID4gLnNlYXJjaGJhciB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGxlZnQ6IDA7XG4gICAgdG9wOiAwO1xuICAgIHotaW5kZXg6IDIwMDtcbiAgICAmIH4gLnBhZ2UtY29udGVudCB7XG4gICAgICAgIHBhZGRpbmctdG9wOiBAc2VhcmNoYmFyU2l6ZTtcbiAgICB9XG59XG4ubmF2YmFyLWZpeGVkLCAubmF2YmFyLXRocm91Z2gge1xuICAgIC5wYWdlID4gLnNlYXJjaGJhciwgPiAuc2VhcmNoYmFyIHtcbiAgICAgICAgdG9wOiBAdG9vbGJhclNpemU7XG4gICAgICAgICYgfiAucGFnZS1jb250ZW50IHtcbiAgICAgICAgICAgIHBhZGRpbmctdG9wOiBAc2VhcmNoYmFyU2l6ZSArIEB0b29sYmFyU2l6ZTtcbiAgICAgICAgfVxuICAgIH1cbn0iLCIvKiA9PT0gTWVzc2FnZSBCYXIgPT09ICovXG4ubWVzc2FnZWJhciB7XG4gICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAudHJhbnNpdGlvbigwbXMpO1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgLmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgIHRleHRhcmVhIHtcbiAgICAgICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtbW96LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tcy1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtd2Via2l0LWJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICAgIC1tb3otYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgI2M4YzhjZDtcbiAgICAgICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTdweDtcbiAgICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIHBhZGRpbmc6IDZweCAxNXB4O1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IDM0cHg7XG4gICAgICAgIGNvbG9yOiAjMDAwO1xuICAgICAgICBmb250LXNpemU6IDE3cHg7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiAyMHB4O1xuICAgICAgICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgICAgICAgcmVzaXplOm5vbmU7XG4gICAgICAgIC5mbGV4LXNocmluaygxKTtcbiAgICB9XG4gICAgLmxpbmsge1xuICAgICAgICAuYWxpZ24tc2VsZihmbGV4LWVuZCk7XG4gICAgfVxuICAgIC5saW5rLmljb24tb25seTpmaXJzdC1jaGlsZCB7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAtNnB4O1xuICAgIH1cbiAgICAubGluazpub3QoLmljb24tb25seSkgKyB0ZXh0YXJlYSB7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiA4cHg7XG4gICAgfVxuICAgIHRleHRhcmVhICsgLmxpbmsge1xuICAgICAgICBtYXJnaW4tbGVmdDogOHB4O1xuICAgIH1cbiAgICAubGluayB7XG4gICAgICAgIC5mbGV4LXNocmluaygwKTtcbiAgICB9XG4gICAgfiAucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IEB0b29sYmFyU2l6ZTtcbiAgICB9XG4gICAgLnBhZ2Uubm8tdG9vbGJhciAmIH4ucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IEB0b29sYmFyU2l6ZTtcbiAgICB9XG4gICAgLmhpZGRlbi10b29sYmFyICYge1xuICAgICAgICAudHJhbnNsYXRlM2QoMCwwLDApO1xuICAgICAgICAudHJhbnNpdGlvbigwbXMpO1xuICAgIH1cbn1cbiIsIi8qID09PSBJY29ucyA9PT0gKi9cbmkuaWNvbiB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gICAgYmFja2dyb3VuZC1zaXplOiAxMDAlIGF1dG87XG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogY2VudGVyO1xuICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgZm9udC1zdHlsZTogbm9ybWFsO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAmLmljb24tYmFjayB7XG4gICAgICAgIHdpZHRoOiAxMnB4O1xuICAgICAgICBoZWlnaHQ6IDIwcHg7XG4gICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxMiAyMCc+PHBhdGggZD0nTTEwLDBsMiwybC04LDhsOCw4bC0yLDJMMCwxMEwxMCwweicgZmlsbD0nQHt0aGVtZUNvbG9yfScvPjwvc3ZnPlwiKTtcbiAgICB9XG4gICAgJi5pY29uLWZvcndhcmQge1xuICAgICAgICB3aWR0aDogMTJweDtcbiAgICAgICAgaGVpZ2h0OiAyMHB4O1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB2aWV3Qm94PScwIDAgMTIgMjAnPjxwYXRoIGQ9J00yLDIwbC0yLTJsOC04TDAsMmwyLTJsMTAsMTBMMiwyMHonIGZpbGw9J0B7dGhlbWVDb2xvcn0nLz48L3N2Zz5cIik7XG4gICAgfVxuICAgICYuaWNvbi1iYXJzIHtcbiAgICAgICAgd2lkdGg6IDIxcHg7XG4gICAgICAgIGhlaWdodDogMTRweDtcbiAgICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoXCI8c3ZnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zycgdmlld0JveD0nMCAwIDIxIDE0Jz48cGF0aCBmaWxsPSdAe3RoZW1lQ29sb3J9JyBkPSdNMCwwaDJ2MkgwVjB6IE00LDBoMTd2MUg0VjB6IE0wLDZoMnYySDBWNnogTTQsNmgxN3YxSDRWNnogTTAsMTJoMnYySDBWMTJ6IE00LDEyaDE3djFINFYxMnonLz48L3N2Zz5cIik7XG4gICAgICAgIEBtZWRpYSAoLXdlYmtpdC1taW4tZGV2aWNlLXBpeGVsLXJhdGlvOiAyKSwgKG1pbi1yZXNvbHV0aW9uOiAyZGRweCkge1xuICAgICAgICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoXCI8c3ZnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zycgdmlld0JveD0nMCAwIDQyIDI2Jz48cGF0aCBmaWxsPSdAe3RoZW1lQ29sb3J9JyBkPSdNMCwwaDR2NEgwVjB6IE04LDFoMzR2Mkg4VjF6IE0wLDExaDR2NEgwVjExeiBNOCwxMmgzNHYySDhWMTJ6IE0wLDIyaDR2NEgwVjIyeiBNOCwyM2gzNHYySDhWMjN6Jy8+PC9zdmc+XCIpO1xuICAgICAgICAgICAgaGVpZ2h0OiAxM3B4O1xuICAgICAgICB9XG4gICAgfVxuICAgICYuaWNvbi1jYW1lcmEge1xuICAgICAgICB3aWR0aDogMjVweDtcbiAgICAgICAgaGVpZ2h0OiAyMHB4O1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB4PScwcHgnIHk9JzBweCcgdmlld0JveD0nMCAwIDI1IDIwJz48cGF0aCBmaWxsPScjOEM4RDkyJyBkPSdNMTMuMyw1LjVjLTIuNywwLTUsMi4yLTUsNXMyLjIsNSw1LDVjMi43LDAsNS0yLjIsNS01UzE2LDUuNSwxMy4zLDUuNXonLz48cGF0aCBmaWxsPScjOEM4RDkyJyBkPSdNMjIuOCwxLjhoLTMuM2MtMC4yLTEuMy0xLTEuOC0yLTEuOEg4LjFjLTEsMC0xLjgsMC40LTIsMS44SDIuOEMxLjQsMS44LDAsMi44LDAsNC4ydjEyLjYgYzAsMS40LDEuNCwyLjUsMi44LDIuNWgyMGMxLjQsMCwyLjItMS4xLDIuMi0yLjVWNC4yQzI1LDIuOCwyNC4yLDEuOCwyMi44LDEuOHogTTMuNSw2LjRDMi42LDYuNCwyLDUuOCwyLDVjMC0wLjgsMC43LTEuNSwxLjUtMS41IFM1LDQuMSw1LDVDNSw1LjgsNC4zLDYuNCwzLjUsNi40eiBNMTMuMywxNi44Yy0zLjUsMC02LjMtMi43LTYuMy02LjJjMC0zLjMsMi41LTYuMiw1LjctNi4yaDEuMmMzLjIsMCw1LjcsMi45LDUuNyw2LjIgQzE5LjYsMTQuMSwxNi43LDE2LjgsMTMuMywxNi44eicvPjwvc3ZnPlwiKTtcbiAgICB9XG4gICAgJi5pY29uLWY3IHtcbiAgICAgICAgd2lkdGg6IDI5cHg7XG4gICAgICAgIGhlaWdodDogMjlweDtcbiAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKFwiQHtpbWdCYXNlVXJsfS9pLWY3LWlvcy5wbmdcIik7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgICB9XG4gICAgJi5pY29uLW5leHQsICYuaWNvbi1wcmV2IHtcbiAgICAgICAgd2lkdGg6IDE1cHg7XG4gICAgICAgIGhlaWdodDogMTVweDtcbiAgICB9XG4gICAgJi5pY29uLW5leHQge1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB2aWV3Qm94PScwIDAgMTUgMTUnPjxnPjxwYXRoIGZpbGw9J0B7dGhlbWVDb2xvcn0nIGQ9J00xLDEuNmwxMS44LDUuOEwxLDEzLjRWMS42IE0wLDB2MTVsMTUtNy42TDAsMEwwLDB6Jy8+PC9nPjwvc3ZnPlwiKTtcbiAgICB9XG4gICAgJi5pY29uLXByZXYge1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB2aWV3Qm94PScwIDAgMTUgMTUnPjxnPjxwYXRoIGZpbGw9J0B7dGhlbWVDb2xvcn0nIGQ9J00xNCwxLjZ2MTEuOEwyLjIsNy42TDE0LDEuNiBNMTUsMEwwLDcuNkwxNSwxNVYwTDE1LDB6Jy8+PC9nPjwvc3ZnPlwiKTtcbiAgICB9XG4gICAgJi5pY29uLXBsdXMge1xuICAgICAgICB3aWR0aDogMjVweDtcbiAgICAgICAgaGVpZ2h0OiAyNXB4O1xuICAgICAgICBmb250LXNpemU6IDMxcHg7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiAyMHB4O1xuICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiAxMDA7XG4gICAgfVxufVxuLmZyYW1ld29yazctaWNvbnMsIC5mNy1pY29ucyB7XG4gICAgLm5hdmJhciAmLCAudG9vbGJhciAmIHtcbiAgICAgICAgZm9udC1zaXplOiAyMnB4O1xuICAgIH1cbiAgICAudGFiYmFyICYsIC50YWJiYXItbGFiZWxzICYge1xuICAgICAgICBmb250LXNpemU6IDI1cHg7XG4gICAgfVxufVxuIiwiLyogPT09IENvbnRlbnQgQmxvY2sgPT09ICovXG5AY29udGVudEJsb2NrQm9yZGVyQ29sb3I6ICNjOGM3Y2M7XG5AY29udGVudEJsb2NrQ29sb3I6ICM2ZDZkNzI7XG5AY29udGVudEJsb2NrVGl0bGU6IEBjb250ZW50QmxvY2tDb2xvcjtcbi5jb250ZW50LWJsb2NrIHtcbiAgICBtYXJnaW46IDM1cHggMDtcbiAgICBwYWRkaW5nOiAwIDE1cHg7XG4gICAgY29sb3I6IEBjb250ZW50QmxvY2tUaXRsZTtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIC5uby1oYWlybGluZXMoKTtcbn1cbi5jb250ZW50LWJsb2NrLXRpdGxlIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBtYXJnaW46IDA7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICBsaW5lLWhlaWdodDogMTtcbiAgICBjb2xvcjogQGNvbnRlbnRCbG9ja0NvbG9yO1xuICAgIG1hcmdpbjogMzVweCAxNXB4IDEwcHg7XG4gICAgKyAubGlzdC1ibG9jaywgKyAuY29udGVudC1ibG9jaywgKy5jYXJkIHtcbiAgICAgICAgbWFyZ2luLXRvcDogMTBweDtcbiAgICB9XG59XG4uY29udGVudC1ibG9jay1pbm5lciB7XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICBwYWRkaW5nOiAxMHB4IDE1cHg7XG4gICAgbWFyZ2luLWxlZnQ6IC0xNXB4O1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAuaGFpcmxpbmUodG9wLCBAY29udGVudEJsb2NrQm9yZGVyQ29sb3IpO1xuICAgIC5oYWlybGluZShib3R0b20sIEBjb250ZW50QmxvY2tCb3JkZXJDb2xvcik7XG4gICAgY29sb3I6ICMwMDA7XG59XG4uY29udGVudC1ibG9jay5pbnNldCB7XG4gICAgbWFyZ2luLWxlZnQ6IDE1cHg7XG4gICAgbWFyZ2luLXJpZ2h0OiAxNXB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDdweDtcbiAgICAuY29udGVudC1ibG9jay1pbm5lciB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUodG9wKTtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA3cHg7XG4gICAgfVxufVxuQG1lZGlhIGFsbCBhbmQgKG1pbi13aWR0aDo3NjhweCkge1xuICAgIC5jb250ZW50LWJsb2NrLnRhYmxldC1pbnNldCB7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAxNXB4O1xuICAgICAgICBtYXJnaW4tcmlnaHQ6IDE1cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDdweFxuICAgIH1cbiAgICBcbiAgICAuY29udGVudC1ibG9jay50YWJsZXQtaW5zZXQgLmNvbnRlbnQtYmxvY2staW5uZXIge1xuICAgIFx0LmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgXHRib3JkZXItcmFkaXVzOiA3cHg7XG4gICAgfVxufVxuIiwiLyogPT09IExpc3RzID09PSAqL1xuQGxpc3RCbG9ja0JvcmRlckNvbG9yOiAjYzhjN2NjO1xuQGxpc3RCbG9ja0JnOiAjZmZmO1xuQGRpdmlkZXJCZzogI0Y3RjdGNztcbkBkaXZpZGVyQ29sb3I6ICM4ZThlOTM7XG4ubGlzdC1ibG9jayB7XG4gICAgbWFyZ2luOiAzNXB4IDA7XG4gICAgZm9udC1zaXplOiAxN3B4O1xuICAgIHVsIHtcbiAgICAgICAgYmFja2dyb3VuZDogQGxpc3RCbG9ja0JnO1xuICAgICAgICBsaXN0LXN0eWxlOiBub25lO1xuICAgICAgICBwYWRkaW5nOiAwO1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgLmhhaXJsaW5lKHRvcCwgQGxpc3RCbG9ja0JvcmRlckNvbG9yKTtcbiAgICAgICAgLmhhaXJsaW5lKGJvdHRvbSwgQGxpc3RCbG9ja0JvcmRlckNvbG9yKTtcbiAgICAgICAgdWwge1xuICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiA0NXB4O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLmFsaWduLXRvcCwgLmFsaWduLXRvcCAuaXRlbS1jb250ZW50LCAuYWxpZ24tdG9wIC5pdGVtLWlubmVyIHtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGZsZXgtc3RhcnQpO1xuICAgIH1cbiAgICBcbiAgICAuaW5zZXQoKSB7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAxNXB4O1xuICAgICAgICBtYXJnaW4tcmlnaHQ6IDE1cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDdweDtcbiAgICAgICAgLmNvbnRlbnQtYmxvY2stdGl0bGUge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDA7XG4gICAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDA7XG4gICAgICAgIH1cbiAgICAgICAgdWwge1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogN3B4O1xuICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICB9XG4gICAgICAgIGxpOmZpcnN0LWNoaWxkID4gYXtcbiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDdweCA3cHggMCAwO1xuICAgICAgICB9XG4gICAgICAgIGxpOmxhc3QtY2hpbGQgPiBhe1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMCAwIDdweCA3cHg7XG4gICAgICAgIH1cbiAgICAgICAgbGk6Zmlyc3QtY2hpbGQ6bGFzdC1jaGlsZCA+IGEge1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogN3B4O1xuICAgICAgICB9XG4gICAgfVxuICAgICYuaW5zZXQge1xuICAgICAgICAuaW5zZXQoKVxuICAgIH1cbiAgICAmLnRhYmxldC1pbnNldCB7XG4gICAgICAgIEBtZWRpYSBhbGwgYW5kIChtaW4td2lkdGg6NzY4cHgpIHtcbiAgICAgICAgICAgIC5pbnNldCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTGlzdCBpdGVtc1xuICAgIGxpIHtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIH1cbiAgICBcbiAgICAuaXRlbS1tZWRpYSB7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC5mbGV4LXNocmluaygwKTtcbiAgICAgICAgLmZsZXgtd3JhcChub3dyYXApO1xuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAgICAgcGFkZGluZy10b3A6IDdweDtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IDhweDtcbiAgICAgICAgaSArIGkge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDVweDtcbiAgICAgICAgfVxuICAgICAgICBpICsgaW1nIHtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiA1cHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tbWVkaWEgKyAuaXRlbS1pbm5lciB7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAxNXB4O1xuICAgIH1cbiAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IDE1cHg7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgLmhhaXJsaW5lKGJvdHRvbSwgQGxpc3RCbG9ja0JvcmRlckNvbG9yKTtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIHBhZGRpbmctdG9wOiA4cHg7XG4gICAgICAgIHBhZGRpbmctYm90dG9tOiA3cHg7XG4gICAgICAgIG1pbi1oZWlnaHQ6IDQ0cHg7XG4gICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC13ZWJraXQtYm94LWZsZXg6MTtcbiAgICAgICAgLW1zLWZsZXg6MTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgLmp1c3RpZnktY29udGVudChzcGFjZS1iZXR3ZWVuKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgICAgIC5hbGlnbi1zZWxmKHN0cmV0Y2gpO1xuICAgIH1cbiAgICAuaXRlbS10aXRsZSB7XG4gICAgICAgIC5mbGV4LXNocmluaygxKTtcbiAgICAgICAgbWluLXdpZHRoOiAwO1xuICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgICAgICBtYXgtd2lkdGg6IDEwMCU7XG4gICAgfVxuICAgIC5pdGVtLWFmdGVyIHtcbiAgICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgICAgY29sb3I6ICM4ZThlOTM7XG4gICAgICAgIC5mbGV4LXNocmluaygwKTtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDVweDtcbiAgICAgICAgLmZsZXhib3goKTtcbiAgICAgICAgbWF4LWhlaWdodDogMjhweDtcbiAgICB9XG4gICAgLnNtYXJ0LXNlbGVjdCAuaXRlbS1hZnRlciwgLmF1dG9jb21wbGV0ZS1vcGVuZXIgLml0ZW0tYWZ0ZXIge1xuICAgICAgICBtYXgtd2lkdGg6IDcwJTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgfVxuICAgIC5pdGVtLWxpbmsge1xuICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICBjb2xvcjogaW5oZXJpdDtcblxuICAgICAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiAzNXB4O1xuICAgICAgICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoXCI8c3ZnIHZpZXdCb3g9JzAgMCA2MCAxMjAnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nbTYwIDYxLjUtMzguMjUgMzguMjUtOS43NS05Ljc1IDI5LjI1LTI4LjUtMjkuMjUtMjguNSA5Ljc1LTkuNzV6JyBmaWxsPScjYzdjN2NjJy8+PC9zdmc+XCIpO1xuICAgICAgICAgICAgYmFja2dyb3VuZC1zaXplOiAxMHB4IDIwcHg7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAgICAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogOTUlIGNlbnRlcjtcbiAgICAgICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IC13ZWJraXQtY2FsYyh+XCIxMDAlIC0gMTVweFwiKSBjZW50ZXI7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjYWxjKH5cIjEwMCUgLSAxNXB4XCIpIGNlbnRlcjtcbiAgICAgICAgfVxuICAgICAgICBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZSwgJi5hY3RpdmUtc3RhdGUge1xuICAgICAgICAgICAgLnRyYW5zaXRpb24oMG1zKTtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICNkOWQ5ZDk7XG4gICAgICAgICAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICAgICAgLmhhaXJsaW5lLWNvbG9yKGJvdHRvbSwgdHJhbnNwYXJlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgICYubGlzdC1idXR0b24ge1xuICAgICAgICAgICAgcGFkZGluZzogMCAxNXB4O1xuICAgICAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgICAgICAgY29sb3I6IEBibHVlO1xuICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICAuaGFpcmxpbmUoYm90dG9tLCBAbGlzdEJsb2NrQm9yZGVyQ29sb3IpO1xuICAgICAgICAgICAgbGluZS1oZWlnaHQ6IDQzcHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tY29udGVudCB7XG4gICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICAgIHBhZGRpbmctbGVmdDogMTVweDtcbiAgICAgICAgbWluLWhlaWdodDogNDRweDtcbiAgICAgICAgLmZsZXhib3goKTtcbiAgICAgICAgLmp1c3RpZnktY29udGVudChzcGFjZS1iZXR3ZWVuKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgfVxuICAgIC8vIExhYmVsIGFmdGVyIExpc3QgYmxvY2tcbiAgICAubGlzdC1ibG9jay1sYWJlbCB7XG4gICAgICAgIG1hcmdpbjogMTBweCAwIDM1cHg7XG4gICAgICAgIHBhZGRpbmc6IDAgMTVweDtcbiAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgICBjb2xvcjogIzhmOGY5NDtcbiAgICB9XG5cbiAgICAvLyBTd2lwZSBvdXRzXG4gICAgLnN3aXBlb3V0IHtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm0tc3R5bGU6IHByZXNlcnZlLTNkO1xuICAgICAgICB0cmFuc2Zvcm0tc3R5bGU6IHByZXNlcnZlLTNkO1xuICAgIH1cbiAgICAuc3dpcGVvdXQuZGVsZXRpbmcge1xuICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgICAgIC5zd2lwZW91dC1jb250ZW50IHtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlWCgtMTAwJSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5zd2lwZW91dC50cmFuc2l0aW9uaW5nIHtcbiAgICAgICAgLnN3aXBlb3V0LWNvbnRlbnQsIC5zd2lwZW91dC1hY3Rpb25zLXJpZ2h0IGEsIC5zd2lwZW91dC1hY3Rpb25zLWxlZnQgYSwgLnN3aXBlb3V0LW92ZXJzd2lwZSB7XG4gICAgICAgICAgICAtd2Via2l0LXRyYW5zaXRpb246IDMwMG1zO1xuICAgICAgICAgICAgdHJhbnNpdGlvbjogMzAwbXM7XG4gICAgICAgIH0gICAgXG4gICAgfVxuICAgIC5zd2lwZW91dC1jb250ZW50IHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICB6LWluZGV4OiAxMDtcbiAgICB9XG4gICAgLnN3aXBlb3V0LW92ZXJzd2lwZSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNpdGlvbjogMjAwbXMgbGVmdDtcbiAgICAgICAgdHJhbnNpdGlvbjogMjAwbXMgbGVmdDtcbiAgICB9XG4gICAgLnN3aXBlb3V0LWFjdGlvbnMtbGVmdCwgLnN3aXBlb3V0LWFjdGlvbnMtcmlnaHQge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICBhIHtcbiAgICAgICAgICAgIHBhZGRpbmc6IDAgMzBweDtcbiAgICAgICAgICAgIGNvbG9yOiNmZmY7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiAjYzdjN2NjO1xuICAgICAgICAgICAgLmZsZXhib3goKTtcbiAgICAgICAgICAgIC5hbGlnbi1pdGVtcyhjZW50ZXIpO1xuICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICAgICAgbGVmdDogMDtcbiAgICAgICAgICAgICY6YWZ0ZXIge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQ6Jyc7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgICAgICAgIHRvcDogMDtcbiAgICAgICAgICAgICAgICB3aWR0aDogNjAwJTtcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZDogaW5oZXJpdDtcbiAgICAgICAgICAgICAgICB6LWluZGV4OiAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhLnN3aXBlb3V0LWRlbGV0ZSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiBAcmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5zd2lwZW91dC1hY3Rpb25zLXJpZ2h0IHtcbiAgICAgICAgcmlnaHQ6IDAlO1xuICAgICAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZVgoMTAwJSkpO1xuICAgICAgICBhOmFmdGVyIHtcbiAgICAgICAgICAgIGxlZnQ6IDEwMCU7XG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogLTFweDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAuc3dpcGVvdXQtYWN0aW9ucy1sZWZ0IHtcbiAgICAgICAgbGVmdDogMCU7XG4gICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlWCgtMTAwJSkpO1xuICAgICAgICBhOmFmdGVyIHtcbiAgICAgICAgICAgIHJpZ2h0OiAxMDAlO1xuICAgICAgICAgICAgbWFyZ2luLXJpZ2h0OiAtMXB4O1xuICAgICAgICB9XG4gICAgfVxuICAgIC5pdGVtLXN1YnRpdGxlIHtcbiAgICAgICAgZm9udC1zaXplOiAxNXB4O1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICAgIG1heC13aWR0aDogMTAwJTtcbiAgICAgICAgdGV4dC1vdmVyZmxvdzplbGxpcHNpcztcbiAgICB9XG4gICAgLml0ZW0tdGV4dCB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTVweDtcbiAgICAgICAgY29sb3I6ICM4ZThlOTM7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiAyMXB4O1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIGhlaWdodDogNDJweDtcbiAgICAgICAgdGV4dC1vdmVyZmxvdzplbGxpcHNpcztcbiAgICAgICAgLXdlYmtpdC1saW5lLWNsYW1wOiAyO1xuICAgICAgICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgICAgICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgICB9XG4gICAgJi5tZWRpYS1saXN0LCBsaS5tZWRpYS1pdGVtIHtcbiAgICAgICAgLml0ZW0tdGl0bGUge1xuICAgICAgICAgICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICAgICAgICAgIGh0bWwuaW9zLWd0LTggJiB7XG4gICAgICAgICAgICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgICAgIHBhZGRpbmctdG9wOiAxMHB4O1xuICAgICAgICAgICAgcGFkZGluZy1ib3R0b206IDlweDtcbiAgICAgICAgICAgIC5hbGlnbi1zZWxmKHN0cmV0Y2gpO1xuICAgICAgICB9XG4gICAgICAgIC5pdGVtLWxpbmsgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDE1cHg7XG4gICAgICAgIH1cbiAgICAgICAgLml0ZW0tbGluayAuaXRlbS10aXRsZS1yb3cge1xuICAgICAgICAgICAgcGFkZGluZy1yaWdodDogMjBweDtcbiAgICAgICAgICAgIGJhY2tncm91bmQ6IG5vLXJlcGVhdCByaWdodCBjZW50ZXI7XG4gICAgICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgdmlld0JveD0nMCAwIDYwIDEyMCcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJz48cGF0aCBkPSdtNjAgNjEuNS0zOC4yNSAzOC4yNS05Ljc1LTkuNzUgMjkuMjUtMjguNS0yOS4yNS0yOC41IDkuNzUtOS43NXonIGZpbGw9JyNjN2M3Y2MnLz48L3N2Zz5cIik7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLXNpemU6IDEwcHggMjBweDtcbiAgICAgICAgfVxuICAgICAgICAuaXRlbS1tZWRpYSB7XG4gICAgICAgICAgICBwYWRkaW5nLXRvcDogOXB4O1xuICAgICAgICAgICAgcGFkZGluZy1ib3R0b206IDEwcHg7XG4gICAgICAgICAgICBpbWcge1xuICAgICAgICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC5pdGVtLXRpdGxlLXJvdyB7XG4gICAgICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICAgICAgLmp1c3RpZnktY29udGVudChzcGFjZS1iZXR3ZWVuKTtcbiAgICAgICAgfVxuICAgICAgICAuaXRlbS1jb250ZW50ID4gLml0ZW0tYWZ0ZXIge1xuICAgICAgICAgICAgbWFyZ2luLXJpZ2h0OiAxNXB4O1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDE1cHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLmxpc3QtZ3JvdXAge1xuICAgICAgICB1bCB7XG4gICAgICAgICAgICAmOmFmdGVyLCAmOmJlZm9yZSB7XG4gICAgICAgICAgICAgICAgei1pbmRleDogMjU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgKyAubGlzdC1ncm91cCB1bCB7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7ICAgXG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tZGl2aWRlciwgLmxpc3QtZ3JvdXAtdGl0bGUge1xuICAgICAgICBiYWNrZ3JvdW5kOiBAZGl2aWRlckJnO1xuICAgICAgICAuaGFpcmxpbmUodG9wLCBAbGlzdEJsb2NrQm9yZGVyQ29sb3IpO1xuICAgICAgICBtYXJnaW4tdG9wOiAtMXB4O1xuICAgICAgICBwYWRkaW5nOiA0cHggMTVweDtcbiAgICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBtYXgtd2lkdGg6IDEwMCU7XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICBjb2xvcjogQGRpdmlkZXJDb2xvcjtcbiAgICAgICAgei1pbmRleDogMTU7XG4gICAgfVxuICAgIC5saXN0LWdyb3VwLXRpdGxlIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBwb3NpdGlvbjogLXdlYmtpdC1zdGlja3k7XG4gICAgICAgIHBvc2l0aW9uOiAtbW96LXN0aWNreTtcbiAgICAgICAgcG9zaXRpb246IHN0aWNreTtcbiAgICAgICAgdG9wOiAwcHg7XG4gICAgICAgIHotaW5kZXg6IDIwO1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgfVxuICAgIC8vIFNvcnRhYmxlXG4gICAgLnNvcnRhYmxlLWhhbmRsZXIge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHJpZ2h0OiAwO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIGJvdHRvbTogMXB4O1xuICAgICAgICB6LWluZGV4OiAxMDtcbiAgICAgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgICAgICAgYmFja2dyb3VuZC1zaXplOiAxOHB4IDEycHg7XG4gICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlcjtcbiAgICAgICAgd2lkdGg6IDM1cHg7XG4gICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxOCAxMicgZmlsbD0nI2M3YzdjYyc+PHBhdGggZD0nTTAsMlYwaDIydjJIMHonLz48cGF0aCBkPSdNMCw3VjVoMjJ2MkgweicvPjxwYXRoIGQ9J00wLDEydi0yaDIydjJIMHonLz48L3N2Zz5cIik7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIHZpc2liaWxpdHk6IGhpZGRlbjtcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgfVxuICAgICYuc29ydGFibGUge1xuICAgICAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7ICAgICAgIFxuICAgICAgICB9XG4gICAgfVxuICAgICYuc29ydGFibGUtb3BlbmVkIHtcbiAgICAgICAgLnNvcnRhYmxlLWhhbmRsZXIge1xuICAgICAgICAgICAgdmlzaWJpbGl0eTogdmlzaWJsZTtcbiAgICAgICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIH1cbiAgICAgICAgLml0ZW0taW5uZXIsIC5pdGVtLWxpbmsgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgcGFkZGluZy1yaWdodDogMzVweDtcbiAgICAgICAgfVxuICAgICAgICAuaXRlbS1saW5rIC5pdGVtLWlubmVyLCAuaXRlbS1saW5rIC5pdGVtLXRpdGxlLXJvdyB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiBub25lO1xuICAgICAgICB9XG4gICAgfVxuICAgICYuc29ydGFibGUtc29ydGluZyB7XG4gICAgICAgIGxpIHtcbiAgICAgICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsaS5zb3J0aW5nIHtcbiAgICAgICAgei1pbmRleDogNTA7XG4gICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LDI1NSwyNTUsMC44KTtcbiAgICAgICAgYm94LXNoYWRvdzogMHB4IDJweCA4cHggcmdiYSgwLDAsMCwwLjYpO1xuICAgICAgICAudHJhbnNpdGlvbigwbXMpO1xuICAgICAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMYXN0LWNoaWxkc1xuICAgIGxpIHtcbiAgICAgICAgJjpsYXN0LWNoaWxkIHtcbiAgICAgICAgICAgIC5saXN0LWJ1dHRvbiB7XG4gICAgICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgICY6bGFzdC1jaGlsZCwgJjpsYXN0LWNoaWxkIGxpOmxhc3QtY2hpbGQge1xuICAgICAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsaTpsYXN0LWNoaWxkLCAmOmxhc3QtY2hpbGQgbGkge1xuICAgICAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgICAgIC5oYWlybGluZShib3R0b20sIEBsaXN0QmxvY2tCb3JkZXJDb2xvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLm5vLWhhaXJsaW5lcygpO1xuICAgIC5uby1oYWlybGluZXMtYmV0d2VlbigpXG59XG4iLCIvKiA9PT0gRm9ybXMgPT09ICovXG4vLyBJbnB1dHNcbi5saXN0LWJsb2NrIHtcbiAgICBpbnB1dFt0eXBlPVwidGV4dFwiXSwgaW5wdXRbdHlwZT1cInBhc3N3b3JkXCJdLCBpbnB1dFt0eXBlPVwic2VhcmNoXCJdLCBpbnB1dFt0eXBlPVwiZW1haWxcIl0sIGlucHV0W3R5cGU9XCJ0ZWxcIl0sIGlucHV0W3R5cGU9XCJ1cmxcIl0sIGlucHV0W3R5cGU9XCJkYXRlXCJdLCBpbnB1dFt0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIl0sIGlucHV0W3R5cGU9XCJ0aW1lXCJdLCBpbnB1dFt0eXBlPVwibnVtYmVyXCJdLCBzZWxlY3QsIHRleHRhcmVhIHtcbiAgICAgICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtbW96LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tcy1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICBib3JkZXI6IG5vbmU7XG4gICAgICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDAgMCAwIDA7XG4gICAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICBwYWRkaW5nOiAwcHg7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGhlaWdodDogNDNweDtcbiAgICAgICAgY29sb3I6ICMwMDA7XG4gICAgICAgIGZvbnQtc2l6ZTogMTdweDtcbiAgICAgICAgZm9udC1mYW1pbHk6IGluaGVyaXQ7XG5cbiAgICB9XG4gICAgLml0ZW0tdGl0bGUubGFiZWwge1xuICAgICAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wO1xuICAgICAgICArIC5pdGVtLWlucHV0IHtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiA1cHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaW5wdXRbdHlwZT1cImRhdGVcIl0sIGlucHV0W3R5cGU9XCJkYXRldGltZS1sb2NhbFwiXSB7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiA0NHB4O1xuICAgIH1cbiAgICBzZWxlY3Qge1xuICAgICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tb3otYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLW1zLWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIGFwcGVhcmFuY2U6IG5vbmU7XG4gICAgfVxuICAgIHRleHRhcmVhIHtcbiAgICAgICAgaGVpZ2h0OiAxMDBweDtcbiAgICAgICAgcmVzaXplOm5vbmU7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiAxLjQ7XG4gICAgICAgIHBhZGRpbmctdG9wOiA4cHg7XG4gICAgICAgIHBhZGRpbmctYm90dG9tOiA3cHg7XG4gICAgICAgICYucmVzaXphYmxlIHtcbiAgICAgICAgICAgIGhlaWdodDogNDNweDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAuaXRlbS1pbnB1dCB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBtYXJnaW4tdG9wOiAtOHB4O1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAtN3B4O1xuICAgICAgICAtd2Via2l0LWJveC1mbGV4OjE7XG4gICAgICAgIC1tcy1mbGV4OjE7XG4gICAgICAgIC5mbGV4LXNocmluaygxKTtcbiAgICB9XG4gICAgLml0ZW0tdGl0bGUubGFiZWwge1xuICAgICAgICB3aWR0aDogMzUlO1xuICAgICAgICAuZmxleC1zaHJpbmsoMCk7XG4gICAgfVxufVxuXG4vL1N3aXRjaFxuLmxhYmVsLXN3aXRjaCB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gICAgd2lkdGg6IDUycHg7XG4gICAgYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIGhlaWdodDogMzJweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIC5hbGlnbi1zZWxmKGNlbnRlcik7XG4gICAgLmNoZWNrYm94IHtcbiAgICAgICAgd2lkdGg6IDUycHg7IFxuICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICBoZWlnaHQ6IDMycHg7XG4gICAgICAgIGJhY2tncm91bmQ6ICNlNWU1ZTU7XG4gICAgICAgIHotaW5kZXg6IDA7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtbW96LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tcy1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgICAgICBib3JkZXI6bm9uZTtcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgJjpiZWZvcmUge1xuICAgICAgICAgICAgY29udGVudDonICc7XG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICBsZWZ0OiAycHg7XG4gICAgICAgICAgICB0b3A6IDJweDtcbiAgICAgICAgICAgIHdpZHRoOiA0OHB4O1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICAgICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICAgICAgICBoZWlnaHQ6IDI4cHg7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgICAgICAgICAgei1pbmRleDogMTtcbiAgICAgICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGUoMSkpO1xuICAgICAgICB9XG4gICAgICAgICY6YWZ0ZXIge1xuICAgICAgICAgICAgY29udGVudDonICc7XG4gICAgICAgICAgICBoZWlnaHQ6IDI4cHg7XG4gICAgICAgICAgICB3aWR0aDogMjhweDtcbiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDI4cHg7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgICAgei1pbmRleDogMjtcbiAgICAgICAgICAgIHRvcDogMnB4O1xuICAgICAgICAgICAgbGVmdDogMnB4O1xuICAgICAgICAgICAgYm94LXNoYWRvdzogMCAycHggNXB4IHJnYmEoMCwwLDAsMC40KTtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlWCgwcHgpKTtcbiAgICAgICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0ge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgICAmOmNoZWNrZWQge1xuICAgICAgICAgICAgJisgLmNoZWNrYm94IHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAjNGNkOTY0O1xuICAgICAgICAgICAgICAgICY6YmVmb3JlIHtcbiAgICAgICAgICAgICAgICAgICAgLnRyYW5zZm9ybShzY2FsZSgwKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICY6YWZ0ZXIge1xuICAgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZVgoMjBweCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbmh0bWwuYW5kcm9pZCB7XG4gICAgLmxhYmVsLXN3aXRjaCBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0ge1xuICAgICAgICAmKyAuY2hlY2tib3gge1xuICAgICAgICAgICAgLnRyYW5zaXRpb24oMCk7XG4gICAgICAgICAgICAmOmFmdGVyLCAmOmJlZm9yZSB7XG4gICAgICAgICAgICAgICAgLnRyYW5zaXRpb24oMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4vL0J1dHRvbnNcbi5idXR0b24ge1xuICAgIGJvcmRlcjogMXB4IHNvbGlkIEB0aGVtZUNvbG9yO1xuICAgIGNvbG9yOiBAdGhlbWVDb2xvcjtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgICBsaW5lLWhlaWdodDogMjdweDtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAtbW96LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgLW1zLWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgIHBhZGRpbmc6IDAgMTBweDtcbiAgICBtYXJnaW46IDA7XG4gICAgaGVpZ2h0OiAyOXB4O1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgdGV4dC1vdmVyZmxvdzplbGxpcHNpcztcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgZm9udC1mYW1pbHk6IGluaGVyaXQ7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIG91dGxpbmU6IDA7XG4gICAgaW5wdXRbdHlwZT1cInN1Ym1pdFwiXSYsIGlucHV0W3R5cGU9XCJidXR0b25cIl0me1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICB9XG5cbiAgICBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZSwgJi5hY3RpdmUtc3RhdGUge1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKHJlZChAdGhlbWVDb2xvciksIGdyZWVuKEB0aGVtZUNvbG9yKSwgYmx1ZShAdGhlbWVDb2xvciksIC4xNSk7XG4gICAgfVxuICAgICYuYnV0dG9uLXJvdW5kIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMjdweDtcbiAgICB9XG4gICAgJi5hY3RpdmUge1xuICAgICAgICBiYWNrZ3JvdW5kOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgY29sb3I6ICNmZmY7XG4gICAgfVxuICAgICYuYnV0dG9uLWJpZyB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTdweDtcbiAgICAgICAgaGVpZ2h0OiA0NHB4O1xuICAgICAgICBsaW5lLWhlaWdodDogNDJweDtcbiAgICB9XG4gICAgJi5idXR0b24tZmlsbCB7XG4gICAgICAgIGNvbG9yOiNmZmY7XG4gICAgICAgIGJhY2tncm91bmQ6IEB0aGVtZUNvbG9yO1xuICAgICAgICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgICBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZSwgJi5hY3RpdmUtc3RhdGUge1xuICAgICAgICAgICAgb3BhY2l0eTogMC44O1xuICAgICAgICB9XG4gICAgfVxuICAgIGkuaWNvbiB7XG4gICAgICAgICY6Zmlyc3QtY2hpbGQge1xuICAgICAgICAgICAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xuICAgICAgICB9XG4gICAgICAgICY6bGFzdC1jaGlsZCB7XG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogMTBweDtcbiAgICAgICAgfVxuICAgICAgICAmOmZpcnN0LWNoaWxkOmxhc3QtY2hpbGQge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDA7XG4gICAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDA7XG4gICAgICAgIH1cbiAgICB9XG59XG4uYnV0dG9ucy1yb3cge1xuICAgIC5hbGlnbi1zZWxmKGNlbnRlcik7XG4gICAgLmZsZXhib3goKTtcbiAgICAuZmxleC13cmFwKG5vd3JhcCk7XG4gICAgLmJ1dHRvbiB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDAgMCAwIDA7XG4gICAgICAgIGJvcmRlci1sZWZ0LXdpZHRoOiAwO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgLXdlYmtpdC1ib3gtZmxleDoxO1xuICAgICAgICAtbXMtZmxleDoxO1xuICAgIH1cbiAgICAuYnV0dG9uOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNXB4IDAgMCA1cHg7XG4gICAgICAgIGJvcmRlci1sZWZ0LXdpZHRoOiAxcHg7XG4gICAgICAgIGJvcmRlci1sZWZ0LXN0eWxlOiBzb2xpZDtcbiAgICB9XG4gICAgLmJ1dHRvbjpsYXN0LWNoaWxkIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMCA1cHggNXB4IDA7XG4gICAgfVxuICAgIC5idXR0b246Zmlyc3QtY2hpbGQ6bGFzdC1jaGlsZCB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgICB9XG4gICAgLmJ1dHRvbi5idXR0b24tcm91bmQ6Zmlyc3QtY2hpbGQge1xuICAgICAgICBib3JkZXItcmFkaXVzOiAyN3B4IDAgMCAyN3B4O1xuICAgIH1cbiAgICAuYnV0dG9uLmJ1dHRvbi1yb3VuZDpsYXN0LWNoaWxkIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMCAyN3B4IDI3cHggMDtcbiAgICB9XG59XG5cblxuLy8gU2xpZGVyXG4ucmFuZ2Utc2xpZGVyIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBwYWRkaW5nLWxlZnQ6IDNweDtcbiAgICBwYWRkaW5nLXJpZ2h0OiAzcHg7XG4gICAgbWFyZ2luLWxlZnQ6IC0xcHg7XG4gICAgLmFsaWduLXNlbGYoY2VudGVyKTtcbiAgICBpbnB1dFt0eXBlPVwicmFuZ2VcIl0ge1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIGhlaWdodDogMjhweDtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIG1hcmdpbjogNHB4IDAgNXB4IDA7XG4gICAgICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLW1vei1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtbXMtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgYmFja2dyb3VuZDogLXdlYmtpdC1ncmFkaWVudChsaW5lYXIsIDUwJSAwLCA1MCUgMTAwJSwgY29sb3Itc3RvcCgwLCAjYjdiOGI3KSwgY29sb3Itc3RvcCgxMDAlLCAjYjdiOGI3KSk7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgI2I3YjhiNyAwLCAjYjdiOGI3IDEwMCUpO1xuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7XG4gICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTAwJSAycHg7XG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgICAgIG91dGxpbmU6IDA7XG4gICAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgICAgYm94LXNpemluZzogY29udGVudC1ib3g7XG4gICAgICAgIC1tcy1iYWNrZ3JvdW5kLXBvc2l0aW9uLXk6IDUwMHB4O1xuICAgICAgICAmOmZvY3VzLCAmOmFjdGl2ZSB7XG4gICAgICAgICAgICBib3JkZXI6IDA7XG4gICAgICAgICAgICBvdXRsaW5lOiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIFxuXG4gICAgXG4gICAgLy8gUmFuZ2UgdGh1bWIgbWl4aW5cbiAgICAucmFuZ2UtdGh1bWIoKSB7XG4gICAgICAgIGhlaWdodDogMjhweDtcbiAgICAgICAgd2lkdGg6IDI4cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDI4cHg7XG4gICAgICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgICAgIHotaW5kZXg6IDEwO1xuICAgICAgICBib3gtc2hhZG93OiAwIDJweCA0cHggcmdiYSgwLDAsMCwwLjQpO1xuICAgICAgICBib3JkZXI6IDA7XG4gICAgICAgIG91dGxpbmU6IDA7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgY29udGVudDogJyAnO1xuICAgIH1cbiAgICBcbiAgICAvLyA9PT09PT09IFdlYktpdC9CbGluayA9PT09PT09PVxuXG4gICAgLy8gQmVmb3JlIFRyYWNrXG4gICAgaW5wdXRbdHlwZT1cInJhbmdlXCJdOmFmdGVyIHtcbiAgICAgICAgaGVpZ2h0OiAycHg7XG4gICAgICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgICAgIGNvbnRlbnQ6JyAnO1xuICAgICAgICB3aWR0aDogNXB4O1xuICAgICAgICB0b3A6IDUwJTtcbiAgICAgICAgbWFyZ2luLXRvcDogLTFweDtcbiAgICAgICAgbGVmdDogLTVweDtcbiAgICAgICAgei1pbmRleDogMTtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIH1cbiAgICAvLyBUaHVtYlxuICAgIGlucHV0W3R5cGU9XCJyYW5nZVwiXTo6LXdlYmtpdC1zbGlkZXItdGh1bWIge1xuICAgICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tb3otYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLW1zLWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIGFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgICAgaGVpZ2h0OiAyOHB4O1xuICAgICAgICB3aWR0aDogMjhweDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgIH1cbiAgICBpbnB1dFt0eXBlPVwicmFuZ2VcIl06Oi13ZWJraXQtc2xpZGVyLXRodW1iOmFmdGVyIHtcbiAgICAgICAgLnJhbmdlLXRodW1iKCk7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICB9XG4gICAgLy8gVHJhY2sgQWN0aXZlIEhpZ2hsaWdodFxuICAgIGlucHV0W3R5cGU9XCJyYW5nZVwiXTo6LXdlYmtpdC1zbGlkZXItdGh1bWI6YmVmb3JlIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICB0b3A6IDUwJTtcbiAgICAgICAgcmlnaHQ6IDEwMCU7XG4gICAgICAgIHdpZHRoOiAyMDAwcHg7XG4gICAgICAgIGhlaWdodDogMnB4O1xuICAgICAgICBtYXJnaW4tdG9wOiAtMXB4O1xuICAgICAgICB6LWluZGV4OiAxO1xuICAgICAgICBiYWNrZ3JvdW5kOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgY29udGVudDogJyAnO1xuICAgIH1cblxuICAgIC8vID09PT09PT0gRmlyZUZveCA9PT09PT09PVxuICAgIGlucHV0W3R5cGU9XCJyYW5nZVwiXTo6LW1vei1yYW5nZS10cmFjayB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IDJweDtcbiAgICAgICAgYmFja2dyb3VuZDogI2I3YjhiNztcbiAgICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgICBvdXRsaW5lOiAwO1xuICAgIH1cbiAgICBpbnB1dFt0eXBlPVwicmFuZ2VcIl06Oi1tb3otcmFuZ2UtdGh1bWIge1xuICAgICAgICAucmFuZ2UtdGh1bWIoKTtcbiAgICB9XG4gICAgXG4gICAgLy8gPT09PT09PSBJRSA9PT09PT09PVxuICAgIGlucHV0W3R5cGU9XCJyYW5nZVwiXTo6LW1zLXRyYWNrIHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGhlaWdodDogMnB4O1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgICAgICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgICBjb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgfVxuICAgIGlucHV0W3R5cGU9XCJyYW5nZVwiXTo6LW1zLXRodW1iIHtcbiAgICAgICAgLnJhbmdlLXRodW1iKCk7XG4gICAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMCwwLDAsMC4yKTtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgbWFyZ2luLXRvcDogMDtcbiAgICAgICAgdG9wOiA1MCU7XG4gICAgfVxuXG4gICAgaW5wdXRbdHlwZT1cInJhbmdlXCJdOjotbXMtZmlsbC1sb3dlciB7XG4gICAgICAgIGJhY2tncm91bmQ6IEB0aGVtZUNvbG9yO1xuICAgIH1cbiAgICBpbnB1dFt0eXBlPVwicmFuZ2VcIl06Oi1tcy1maWxsLXVwcGVyIHtcbiAgICAgICAgYmFja2dyb3VuZDogI2I3YjhiNztcbiAgICB9XG59XG5cbi8vIENoZWNrYm94ZXNcbmxhYmVsLmxhYmVsLWNoZWNrYm94IHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgaS5pY29uLWZvcm0tY2hlY2tib3gge1xuICAgICAgICB3aWR0aDogMjJweDtcbiAgICAgICAgaGVpZ2h0OiAyMnB4O1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDIycHg7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNjN2M3Y2M7XG4gICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG5cbiAgICAgICAgJjphZnRlciB7XG4gICAgICAgICAgICBjb250ZW50OicgJztcbiAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICAgIGxlZnQ6IDUwJTtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiAtNnB4O1xuICAgICAgICAgICAgdG9wOiA1MCU7XG4gICAgICAgICAgICBtYXJnaW4tdG9wOiAtNHB4O1xuICAgICAgICAgICAgd2lkdGg6IDEycHg7XG4gICAgICAgICAgICBoZWlnaHQ6IDlweDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0sIGlucHV0W3R5cGU9XCJyYWRpb1wiXSB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICAgICY6Y2hlY2tlZCArIC5pdGVtLW1lZGlhe1xuICAgICAgICAgICAgaS5pY29uLWZvcm0tY2hlY2tib3gge1xuICAgICAgICAgICAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGkuaWNvbi1mb3JtLWNoZWNrYm94OmFmdGVyIHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiBuby1yZXBlYXQgY2VudGVyO1xuICAgICAgICAgICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHg9JzBweCcgeT0nMHB4JyB2aWV3Qm94PScwIDAgMTIgOScgeG1sOnNwYWNlPSdwcmVzZXJ2ZSc+PHBvbHlnb24gZmlsbD0nI2ZmZmZmZicgcG9pbnRzPScxMiwwLjcgMTEuMywwIDMuOSw3LjQgMC43LDQuMiAwLDQuOSAzLjksOC44IDMuOSw4LjggMy45LDguOCAnLz48L3N2Zz5cIik7XG4gICAgICAgICAgICAgICAgLXdlYmtpdC1iYWNrZ3JvdW5kLXNpemU6IDEycHggOXB4O1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTJweCA5cHg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5sYWJlbC5sYWJlbC1yYWRpbyB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGlucHV0W3R5cGU9XCJjaGVja2JveFwiXSwgaW5wdXRbdHlwZT1cInJhZGlvXCJdIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgfiAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiAzNXB4O1xuICAgICAgICB9XG4gICAgICAgICY6Y2hlY2tlZCB+IC5pdGVtLWlubmVye1xuICAgICAgICAgICAgYmFja2dyb3VuZDogbm8tcmVwZWF0IGNlbnRlcjtcbiAgICAgICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxMyAxMCc+PHBvbHlnb24gZmlsbD0nQHt0aGVtZUNvbG9yfScgcG9pbnRzPScxMS42LDAgNC40LDcuMiAxLjQsNC4yIDAsNS42IDQuNCwxMCA0LjQsMTAgNC40LDEwIDEzLDEuNCAnLz48L3N2Zz5cIik7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiA5MCUgY2VudGVyO1xuICAgICAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogflwiLXdlYmtpdC1jYWxjKDEwMCUgLSAxNXB4KVwiIGNlbnRlcjtcbiAgICAgICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IH5cImNhbGMoMTAwJSAtIDE1cHgpXCIgY2VudGVyO1xuICAgICAgICAgICAgLXdlYmtpdC1iYWNrZ3JvdW5kLXNpemU6IDEzcHggMTBweDtcbiAgICAgICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTNweCAxMHB4O1xuICAgICAgICB9XG4gICAgfVxufVxubGFiZWwubGFiZWwtY2hlY2tib3gsIGxhYmVsLmxhYmVsLXJhZGlvIHtcbiAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgaHRtbDpub3QoLndhdGNoLWFjdGl2ZS1zdGF0ZSkgJjphY3RpdmUsICYuYWN0aXZlLXN0YXRlIHtcbiAgICAgICAgLnRyYW5zaXRpb24oMG1zKTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2Q5ZDlkOTtcbiAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgLmhhaXJsaW5lLWNvbG9yKGJvdHRvbSwgdHJhbnNwYXJlbnQpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vLyBTbWFydCBzZWxlY3RzXG4uc21hcnQtc2VsZWN0IHtcbiAgICBzZWxlY3Qge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbn1cbiIsIi8qID09PSBDYXJkcyA9PT0gKi9cbi5jYXJkcy1saXN0LCAuY2FyZCAubGlzdC1ibG9jayB7XG4gICAgdWwge1xuICAgICAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgIH1cbiAgICA+IHVsIHtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgfVxufVxuLmNhcmQge1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgYm94LXNoYWRvdzogMHB4IDFweCAycHggcmdiYSgwLDAsMCwwLjMpO1xuICAgIG1hcmdpbjogMTBweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgYm9yZGVyLXJhZGl1czogMnB4O1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAubGlzdC1ibG9jaywgLmNvbnRlbnQtYmxvY2sge1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgfVxuICAgIC5yb3c6bm90KC5uby1ndXR0ZXIpIC5jb2wgPiAmIHtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDA7XG4gICAgICAgIG1hcmdpbi1yaWdodDogMDtcbiAgICB9XG59XG4uY2FyZC1jb250ZW50IHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG4uY2FyZC1jb250ZW50LWlubmVyIHtcbiAgICBwYWRkaW5nOiAxNXB4O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICA+IHA6Zmlyc3QtY2hpbGQge1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgIH1cbiAgICA+IHA6bGFzdC1jaGlsZCB7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7XG4gICAgfVxuICAgID4gLmxpc3QtYmxvY2ssID4uY29udGVudC1ibG9jayB7XG4gICAgICAgIG1hcmdpbjogLTE1cHg7XG4gICAgfVxufVxuLmNhcmQtaGVhZGVyLCAuY2FyZC1mb290ZXIge1xuICAgIG1pbi1oZWlnaHQ6IDQ0cHg7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHBhZGRpbmc6IDEwcHggMTVweDtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmp1c3RpZnktY29udGVudChzcGFjZS1iZXR3ZWVuKTtcbiAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAmW3ZhbGlnbj1cInRvcFwiXSB7XG4gICAgICAgIC5hbGlnbi1pdGVtcyhmbGV4LXN0YXJ0KTtcbiAgICB9XG4gICAgJlt2YWxpZ249XCJib3R0b21cIl0ge1xuICAgICAgICAuYWxpZ24taXRlbXMoZmxleC1lbmQpO1xuICAgIH1cbiAgICBhLmxpbmsge1xuICAgICAgICBsaW5lLWhlaWdodDogNDRweDtcbiAgICAgICAgaGVpZ2h0OiA0NHB4O1xuICAgICAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgbWFyZ2luLXRvcDogLTEwcHg7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IC0xMHB4O1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICAuanVzdGlmeS1jb250ZW50KGZsZXgtc3RhcnQpO1xuICAgICAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZSwgJi5hY3RpdmUtc3RhdGUge1xuICAgICAgICAgICAgb3BhY2l0eTogMC4zO1xuICAgICAgICAgICAgLnRyYW5zaXRpb24oMG1zKTtcbiAgICAgICAgfVxuICAgICAgICBpK3NwYW4sIGkraSwgc3BhbitpLCBzcGFuK3NwYW4ge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDdweDtcbiAgICAgICAgfVxuICAgICAgICBpLmljb24ge1xuICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYS5pY29uLW9ubHkge1xuICAgICAgICBtaW4td2lkdGg6IDQ0cHg7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC5qdXN0aWZ5LWNvbnRlbnQoY2VudGVyKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICB9XG59XG4uY2FyZC1oZWFkZXIge1xuICAgIGJvcmRlci1yYWRpdXM6IDJweCAycHggMCAwO1xuICAgIGZvbnQtc2l6ZTogMTdweDtcbiAgICAuaGFpcmxpbmUoYm90dG9tLCAjZTFlMWUxKTtcbiAgICAmLm5vLWJvcmRlciB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICB9XG59XG4uY2FyZC1mb290ZXIge1xuICAgIGJvcmRlci1yYWRpdXM6IDAgMCAycHggMnB4O1xuICAgIGNvbG9yOiM2ZDZkNzI7XG4gICAgLmhhaXJsaW5lKHRvcCwgI2UxZTFlMSk7XG4gICAgJi5uby1ib3JkZXIge1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgfVxuXG59IiwiLyogPT09IE1vZGFscyA9PT0gKi9cbkBtb2RhbEJnOiByZ2JhKDI1NSwyNTUsMjU1LDAuOTUpO1xuQG1vZGFsQnV0b25Db2xvciA6IEB0aGVtZUNvbG9yO1xuQG1vZGFsQnV0b25BY3RpdmVCZzogcmdiYSgyMzAsMjMwLDIzMCwwLjk1KTtcbkBtb2RhbEhhaXJsaW5lQ29sb3I6IHJnYmEoMCwwLDAsMC4yKTtcbkBtb2RhbER1cmF0aW9uOiA0MDBtcztcblxuQGFjdGlvbnNNb2RhbEJnOiByZ2JhKDI1NSwyNTUsMjU1LDAuOTUpO1xuQGFjdGlvbnNNb2RhbEJ1dHRvbkFjdGl2ZUJnOiByZ2JhKDIzMCwyMzAsMjMwLDAuOSk7XG5AYWN0aW9uc01vZGFsSGFpcmxpbmVDb2xvcjogcmdiYSgwLDAsMCwwLjIpO1xuQGFjdGlvbnNNb2RhbER1cmF0aW9uOiAzMDBtcztcblxuQHBvcG92ZXJCZzogcmdiYSgyNTUsMjU1LDI1NSwwLjk1KTtcblxuQHBvcHVwRHVyYXRpb246IDQwMG1zO1xuXG5AYWN0aW9uc1BvcG92ZXJIYWlybGluZTogcmdiYSgwLDAsMCwwLjIpO1xuLm1vZGFsLW92ZXJsYXksIC5wcmVsb2FkZXItaW5kaWNhdG9yLW92ZXJsYXksIC5wb3B1cC1vdmVybGF5IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwwLDAsMC40KTtcbiAgICB6LWluZGV4OiAxMzAwMDtcbiAgICB2aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgb3BhY2l0eTogMDtcbiAgICAudHJhbnNpdGlvbihAbW9kYWxEdXJhdGlvbik7XG4gICAgJi5tb2RhbC1vdmVybGF5LXZpc2libGUge1xuICAgICAgICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cbi5wb3B1cC1vdmVybGF5IHtcbiAgICB6LWluZGV4OiAxMDUwMDtcbn1cbi5tb2RhbCB7XG4gICAgd2lkdGg6IDI3MHB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB6LWluZGV4OiAxMzUwMDtcbiAgICBsZWZ0OiA1MCU7XG4gICAgbWFyZ2luLWxlZnQ6IC0xMzVweDtcbiAgICBtYXJnaW4tdG9wOiAwO1xuICAgIHRvcDogNTAlO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBib3JkZXItcmFkaXVzOiAxM3B4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgb3BhY2l0eTogMDtcbiAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZTNkKDAsMCwwKSBzY2FsZSgxLjE4NSkpO1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbi1wcm9wZXJ0eTogLXdlYmtpdC10cmFuc2Zvcm0sIG9wYWNpdHk7XG4gICAgLW1vei10cmFuc2l0aW9uLXByb3BlcnR5OiAtbW96LXRyYW5zZm9ybSwgb3BhY2l0eTtcbiAgICAtbXMtdHJhbnNpdGlvbi1wcm9wZXJ0eTogLW1zLXRyYW5zZm9ybSwgb3BhY2l0eTtcbiAgICAtby10cmFuc2l0aW9uLXByb3BlcnR5OiAtby10cmFuc2Zvcm0sIG9wYWNpdHk7XG4gICAgdHJhbnNpdGlvbi1wcm9wZXJ0eTogdHJhbnNmb3JtLCBvcGFjaXR5O1xuICAgIGNvbG9yOiMwMDA7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICBcbiAgICAmLm1vZGFsLWluIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgLnRyYW5zaXRpb24oQG1vZGFsRHVyYXRpb24pO1xuICAgICAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZTNkKDAsMCwwKSBzY2FsZSgxKSk7XG4gICAgfVxuICAgICYubW9kYWwtb3V0IHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgei1pbmRleDogMTM1MDAtMTtcbiAgICAgICAgLnRyYW5zaXRpb24oQG1vZGFsRHVyYXRpb24pO1xuICAgICAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZTNkKDAsMCwwKSBzY2FsZSgxKSk7XG4gICAgfVxufVxuLm1vZGFsLWlubmVyIHtcbiAgICBwYWRkaW5nOiAxNXB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDEzcHggMTNweCAwIDA7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIGJhY2tncm91bmQ6IEBtb2RhbEJnO1xuICAgIC5oYWlybGluZShib3R0b20sIEBtb2RhbEhhaXJsaW5lQ29sb3IpO1xuICAgICAgICBcbn1cbi5tb2RhbC10aXRsZSB7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICBmb250LXNpemU6IDE4cHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIGh0bWwuaW9zLWd0LTggJiB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgfVxuICAgICsubW9kYWwtdGV4dCB7XG4gICAgICAgIG1hcmdpbi10b3A6IDVweDtcbiAgICB9XG59XG4ubW9kYWwtYnV0dG9ucyB7XG4gICAgaGVpZ2h0OiA0NHB4O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAuZmxleGJveCgpO1xuICAgIC5qdXN0aWZ5LWNvbnRlbnQoY2VudGVyKTtcbiAgICAmLm1vZGFsLWJ1dHRvbnMtdmVydGljYWwge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgaGVpZ2h0OiBhdXRvO1xuICAgIH1cbn1cbi5tb2RhbC1idXR0b24ge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHBhZGRpbmc6IDAgNXB4O1xuICAgIGhlaWdodDogNDRweDtcbiAgICBmb250LXNpemU6IDE3cHg7XG4gICAgbGluZS1oZWlnaHQ6IDQ0cHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIGNvbG9yOiBAbW9kYWxCdXRvbkNvbG9yO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIHRleHQtb3ZlcmZsb3c6ZWxsaXBzaXM7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAtd2Via2l0LWJveC1mbGV4OjE7XG4gICAgLW1zLWZsZXg6MTtcbiAgICBiYWNrZ3JvdW5kOiBAbW9kYWxCZztcbiAgICAuaGFpcmxpbmUocmlnaHQsIEBtb2RhbEhhaXJsaW5lQ29sb3IpO1xuICAgICY6Zmlyc3QtY2hpbGQge1xuICAgICAgICBib3JkZXItcmFkaXVzOiAwIDAgMCAxM3B4O1xuICAgIH1cbiAgICAmOmxhc3QtY2hpbGQge1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHJpZ2h0KTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMCAwIDEzcHggMDtcbiAgICB9XG4gICAgJjpmaXJzdC1jaGlsZDpsYXN0LWNoaWxkIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMCAwIDEzcHggMTNweDtcbiAgICB9XG4gICAgJi5tb2RhbC1idXR0b24tYm9sZCB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgICAgIGh0bWwuaW9zLWd0LTggJiB7XG4gICAgICAgICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIGh0bWw6bm90KC53YXRjaC1hY3RpdmUtc3RhdGUpICY6YWN0aXZlLCAmLmFjdGl2ZS1zdGF0ZSB7XG4gICAgICAgIGJhY2tncm91bmQ6IEBtb2RhbEJ1dG9uQWN0aXZlQmc7XG4gICAgfVxuICAgIC5tb2RhbC1idXR0b25zLXZlcnRpY2FsICYge1xuICAgICAgICBib3JkZXItcmFkaXVzOiAwO1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHJpZ2h0KTtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgICAgICAuaGFpcmxpbmUoYm90dG9tLCBAbW9kYWxIYWlybGluZUNvbG9yKTtcbiAgICAgICAgJjpsYXN0LWNoaWxkIHtcbiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDAgMCAxM3B4IDEzcHg7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4ubW9kYWwtbm8tYnV0dG9ucyB7XG4gICAgLm1vZGFsLWlubmVyIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTNweDtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgIH1cbiAgICAubW9kYWwtYnV0dG9ucyB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxufVxuLy8gQWN0aW9uIHNoZWV0XG4uYWN0aW9ucy1tb2RhbCB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IDA7XG4gICAgYm90dG9tOiAwO1xuICAgIHotaW5kZXg6IDEzNTAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwxMDAlLDApKTtcbiAgICBtYXgtaGVpZ2h0OiAxMDAlO1xuICAgIC5zY3JvbGxhYmxlKCk7XG4gICAgQG1lZGlhIChtaW4td2lkdGg6NDk2cHgpIHtcbiAgICAgICAgd2lkdGg6IDQ4MHB4O1xuICAgICAgICBsZWZ0OiA1MCU7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAtMjQwcHg7XG4gICAgfVxuICAgICYubW9kYWwtaW4ge1xuICAgICAgICAudHJhbnNpdGlvbihAYWN0aW9uc01vZGFsRHVyYXRpb24pO1xuICAgICAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZTNkKDAsMCwwKSk7XG4gICAgfVxuICAgICYubW9kYWwtb3V0IHtcbiAgICAgICAgei1pbmRleDogMTM1MDAtMTtcbiAgICAgICAgLnRyYW5zaXRpb24oQGFjdGlvbnNNb2RhbER1cmF0aW9uKTtcbiAgICAgICAgLnRyYW5zZm9ybSh0cmFuc2xhdGUzZCgwLDEwMCUsMCkpO1xuICAgIH1cbn1cbi5hY3Rpb25zLW1vZGFsLWdyb3VwIHtcbiAgICBtYXJnaW46IDhweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgYm9yZGVyLXJhZGl1czogMTNweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwwLDApKTtcbn1cbi5hY3Rpb25zLW1vZGFsLWJ1dHRvbiwgLmFjdGlvbnMtbW9kYWwtbGFiZWwge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBmb250LXdlaWdodDogbm9ybWFsO1xuICAgIG1hcmdpbjogMDtcbiAgICBiYWNrZ3JvdW5kOiBAYWN0aW9uc01vZGFsQmc7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAuaGFpcmxpbmUoYm90dG9tLCBAYWN0aW9uc01vZGFsSGFpcmxpbmVDb2xvcik7XG4gICAgYSB7XG4gICAgICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICAgICAgY29sb3I6IGluaGVyaXQ7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIH1cbiAgICBiIHtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICAgICAgaHRtbC5pb3MtZ3QtOCAmIHtcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgJi5hY3Rpb25zLW1vZGFsLWJ1dHRvbi1ib2xkIHtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICAgICAgaHRtbC5pb3MtZ3QtOCAmIHtcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgJi5hY3Rpb25zLW1vZGFsLWJ1dHRvbi1yZWQge1xuICAgICAgICBjb2xvcjogQHJlZDtcbiAgICB9XG4gICAgJjpmaXJzdC1jaGlsZCB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDEzcHggMTNweCAwIDA7XG4gICAgfVxuICAgICY6bGFzdC1jaGlsZCB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMCAwIDEzcHggMTNweDtcbiAgICB9XG4gICAgJjpmaXJzdC1jaGlsZDpsYXN0LWNoaWxkIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTNweDtcbiAgICB9XG4gICAgJi5kaXNhYmxlZCB7XG4gICAgICAgIG9wYWNpdHk6IDAuOTtcbiAgICAgICAgY29sb3I6QGdyYXk7XG4gICAgfVxufVxuLmFjdGlvbnMtbW9kYWwtYnV0dG9uIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgaGVpZ2h0OiA1N3B4O1xuICAgIGxpbmUtaGVpZ2h0OiA1N3B4O1xuICAgIGZvbnQtc2l6ZTogMjBweDtcbiAgICBjb2xvcjogQHRoZW1lQ29sb3I7XG4gICAgd2hpdGUtc3BhY2U6IG5vcm1hbDtcbiAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZSwgJi5hY3RpdmUtc3RhdGUge1xuICAgICAgICBiYWNrZ3JvdW5kOiBAYWN0aW9uc01vZGFsQnV0dG9uQWN0aXZlQmc7XG4gICAgfVxufVxuLmFjdGlvbnMtbW9kYWwtbGFiZWwge1xuICAgIGZvbnQtc2l6ZTogMTNweDtcbiAgICBsaW5lLWhlaWdodDogMS4zO1xuICAgIG1pbi1oZWlnaHQ6IDU3cHg7XG4gICAgcGFkZGluZzogOHB4IDEwcHg7XG4gICAgY29sb3I6ICM4YThhOGE7XG4gICAgLmZsZXhib3goKTtcbiAgICAuanVzdGlmeS1jb250ZW50KGNlbnRlcik7XG4gICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG59XG5AbWVkaWEgKG9yaWVudGF0aW9uOmxhbmRzY2FwZSkge1xuICAgIC5hY3Rpb25zLW1vZGFsLWxhYmVsIHtcbiAgICAgICAgbWluLWhlaWdodDogNDRweDtcbiAgICB9XG4gICAgLmFjdGlvbnMtbW9kYWwtYnV0dG9uIHtcbiAgICAgICAgaGVpZ2h0OiA0NHB4O1xuICAgICAgICBsaW5lLWhlaWdodDogNDRweDtcbiAgICB9XG59XG4vLyBQcm9tcHRcbmlucHV0Lm1vZGFsLXRleHQtaW5wdXQge1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgaGVpZ2h0OiAyNnB4O1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgbWFyZ2luOiAwO1xuICAgIG1hcmdpbi10b3A6IDE1cHg7XG4gICAgcGFkZGluZzogMCA1cHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgwLDAsMCwwLjMpO1xuICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGZvbnQtZmFtaWx5OiBpbmhlcml0O1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIHJnYmEoMCwwLDAsMCk7XG4gICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICAgIC1tb3otYXBwZWFyYW5jZTogbm9uZTtcbiAgICAtbXMtYXBwZWFyYW5jZTogbm9uZTtcbiAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgICsgaW5wdXQubW9kYWwtdGV4dC1pbnB1dCB7XG4gICAgICAgIG1hcmdpbi10b3A6IDVweDtcbiAgICB9XG59XG4ubW9kYWwtaW5wdXQtZG91YmxlIHtcbiAgICBpbnB1dC5tb2RhbC10ZXh0LWlucHV0IHtcbiAgICB9XG4gICAgLm1vZGFsLWlucHV0LWRvdWJsZSArICYge1xuICAgICAgICBpbnB1dC5tb2RhbC10ZXh0LWlucHV0IHtcbiAgICAgICAgICAgIGJvcmRlci10b3A6IDA7XG4gICAgICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8gUG9wb3ZlclxuLnBvcG92ZXIge1xuICAgIHdpZHRoOiAzMjBweDtcbiAgICBiYWNrZ3JvdW5kOkBwb3BvdmVyQmc7XG4gICAgei1pbmRleDogMTM1MDA7XG4gICAgbWFyZ2luOiAwO1xuICAgIHRvcDogMDtcbiAgICBvcGFjaXR5OiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgYm9yZGVyLXJhZGl1czogMTNweDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICAudHJhbnNmb3JtKG5vbmUpO1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbi1wcm9wZXJ0eTogb3BhY2l0eTtcbiAgICAtbW96LXRyYW5zaXRpb24tcHJvcGVydHk6IG9wYWNpdHk7XG4gICAgLW1zLXRyYW5zaXRpb24tcHJvcGVydHk6IG9wYWNpdHk7XG4gICAgLW8tdHJhbnNpdGlvbi1wcm9wZXJ0eTogb3BhY2l0eTtcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBvcGFjaXR5O1xuICAgICYubW9kYWwtaW4ge1xuICAgICAgICAudHJhbnNpdGlvbihAYWN0aW9uc01vZGFsRHVyYXRpb24pO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICAubGlzdC1ibG9jayB7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgdWwge1xuICAgICAgICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgICAgfVxuICAgICAgICAmOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgICAgIHVsIHtcbiAgICAgICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTNweCAxM3B4IDAgMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxpOmZpcnN0LWNoaWxkIGF7XG4gICAgICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTNweCAxM3B4IDAgMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAmOmxhc3QtY2hpbGQge1xuICAgICAgICAgICAgdWwge1xuICAgICAgICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiAwIDAgMTNweCAxM3B4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGk6bGFzdC1jaGlsZCBhe1xuICAgICAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDAgMCAxM3B4IDEzcHg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgJjpmaXJzdC1jaGlsZDpsYXN0LWNoaWxkIHtcbiAgICAgICAgICAgIGxpOmZpcnN0LWNoaWxkOmxhc3QtY2hpbGQgYSwgdWw6Zmlyc3QtY2hpbGQ6bGFzdC1jaGlsZCB7XG4gICAgICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTNweDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICArIC5saXN0LWJsb2NrIHtcbiAgICAgICAgICAgIG1hcmdpbi10b3A6IDM1cHg7XG4gICAgICAgIH1cbiAgICB9XG59XG4ucG9wb3Zlci1hbmdsZSB7XG4gICAgd2lkdGg6IDI2cHg7XG4gICAgaGVpZ2h0OiAyNnB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAtMjZweDtcbiAgICB0b3A6IDA7XG4gICAgei1pbmRleDogMTAwO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgJjphZnRlciB7XG4gICAgICAgIGNvbnRlbnQ6JyAnO1xuICAgICAgICBiYWNrZ3JvdW5kOiBAcG9wb3ZlckJnO1xuICAgICAgICB3aWR0aDogMjZweDtcbiAgICAgICAgaGVpZ2h0OiAyNnB4O1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xuICAgICAgICAudHJhbnNmb3JtKHJvdGF0ZSg0NWRlZykpO1xuICAgIH1cbiAgICAmLm9uLWxlZnQge1xuICAgICAgICBsZWZ0OiAtMjZweDtcbiAgICAgICAgJjphZnRlciB7XG4gICAgICAgICAgICBsZWZ0OiAxOXB4O1xuICAgICAgICAgICAgdG9wOiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgICYub24tcmlnaHQge1xuICAgICAgICBsZWZ0OiAxMDAlO1xuICAgICAgICAmOmFmdGVyIHtcbiAgICAgICAgICAgIGxlZnQ6IC0xOXB4O1xuICAgICAgICAgICAgdG9wOiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgICYub24tdG9wIHtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgdG9wOiAtMjZweDtcbiAgICAgICAgJjphZnRlciB7XG4gICAgICAgICAgICBsZWZ0OiAwO1xuICAgICAgICAgICAgdG9wOiAxOXB4O1xuICAgICAgICB9XG4gICAgfVxuICAgICYub24tYm90dG9tIHtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgdG9wOiAxMDAlO1xuICAgICAgICAmOmFmdGVyIHtcbiAgICAgICAgICAgIGxlZnQ6IDA7XG4gICAgICAgICAgICB0b3A6IC0xOXB4O1xuICAgICAgICB9XG4gICAgfVxufVxuLnBvcG92ZXItaW5uZXIge1xuICAgIC5zY3JvbGxhYmxlKCk7ICAgIFxufVxuLmFjdGlvbnMtcG9wb3ZlciB7XG4gICAgLmxpc3QtYmxvY2sgKyAubGlzdC1ibG9jayB7XG4gICAgICAgIG1hcmdpbi10b3A6IDIwcHg7XG4gICAgfVxuICAgIC5saXN0LWJsb2NrIHVsIHtcbiAgICAgICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICB9XG59XG4uYWN0aW9ucy1wb3BvdmVyLWxhYmVsIHtcbiAgICBwYWRkaW5nOiA4cHggMTBweDtcbiAgICBjb2xvcjojOGE4YThhO1xuICAgIGZvbnQtc2l6ZTogMTNweDtcbiAgICBsaW5lLWhlaWdodDogMS4zO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgLmhhaXJsaW5lKGJvdHRvbSwgQGFjdGlvbnNQb3BvdmVySGFpcmxpbmUpO1xuICAgICY6bGFzdC1jaGlsZCB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICB9XG59XG4vLyBQb3B1cFxuLnBvcHVwLCAubG9naW4tc2NyZWVuIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIHotaW5kZXg6IDExMDAwO1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBkaXNwbGF5OiBub25lO1xuICAgIC5zY3JvbGxhYmxlKCk7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uLXByb3BlcnR5OiAtd2Via2l0LXRyYW5zZm9ybTtcbiAgICAtbW96LXRyYW5zaXRpb24tcHJvcGVydHk6IC1tb3otdHJhbnNmb3JtO1xuICAgIC1tcy10cmFuc2l0aW9uLXByb3BlcnR5OiAtbXMtdHJhbnNmb3JtO1xuICAgIC1vLXRyYW5zaXRpb24tcHJvcGVydHk6IC1vLXRyYW5zZm9ybTtcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiB0cmFuc2Zvcm07XG4gICAgLnRyYW5zbGF0ZTNkKDAsMTAwJSwwKTtcbiAgICAmLm1vZGFsLWluLCAmLm1vZGFsLW91dCB7XG4gICAgICAgIC50cmFuc2l0aW9uKEBwb3B1cER1cmF0aW9uKTtcbiAgICB9XG4gICAgJi5tb2RhbC1pbiB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxuICAgICYubW9kYWwtb3V0IHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMTAwJSwwKTtcbiAgICB9XG59XG4ubG9naW4tc2NyZWVuLm1vZGFsLWluLCAubG9naW4tc2NyZWVuLm1vZGFsLW91dCB7XG4gICAgZGlzcGxheTogYmxvY2s7XG59XG4vLyBpUGFkIFBvcHVwXG5AbWVkaWEgYWxsIGFuZCAobWluLXdpZHRoOjYzMHB4KSBhbmQgKG1pbi1oZWlnaHQ6NjMwcHgpIHtcbiAgICAucG9wdXA6bm90KC50YWJsZXQtZnVsbHNjcmVlbikge1xuICAgICAgICB3aWR0aDogNjMwcHg7XG4gICAgICAgIGhlaWdodDogNjMwcHg7XG4gICAgICAgIGxlZnQ6IDUwJTtcbiAgICAgICAgdG9wOiA1MCU7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAtMzE1cHg7XG4gICAgICAgIG1hcmdpbi10b3A6IC0zMTVweDtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMTAyNHB4LDApO1xuICAgICAgICAmLm1vZGFsLWluIHtcbiAgICAgICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgICAgIH1cbiAgICAgICAgJi5tb2RhbC1vdXQge1xuICAgICAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMTAyNHB4LDApO1xuICAgICAgICB9XG4gICAgfVxufVxuaHRtbC53aXRoLXN0YXR1c2Jhci1vdmVybGF5IHtcbiAgICAvLyBpUGhvbmUgd2l0aCBzdGF0dXNiYXIgb3ZlcmxheVxuICAgIEBtZWRpYSBhbGwgYW5kIChtYXgtd2lkdGg6NjI5cHgpLCAobWF4LWhlaWdodDo2MjlweCkge1xuICAgICAgICAucG9wdXAge1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCItd2Via2l0LWNhbGMoMTAwJSAtIDIwcHgpXCI7XG4gICAgICAgICAgICBoZWlnaHQ6IH5cImNhbGMoMTAwJSAtIDIwcHgpXCI7XG4gICAgICAgICAgICB0b3A6IDIwcHg7XG4gICAgICAgIH1cbiAgICAgICAgLnBvcHVwLW92ZXJsYXkge1xuICAgICAgICAgICAgei1pbmRleDogOTUwMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAubG9naW4tc2NyZWVuLCAucG9wdXAudGFibGV0LWZ1bGxzY3JlZW4ge1xuICAgICAgICBoZWlnaHQ6IH5cIi13ZWJraXQtY2FsYygxMDAlIC0gMjBweClcIjtcbiAgICAgICAgaGVpZ2h0OiB+XCJjYWxjKDEwMCUgLSAyMHB4KVwiO1xuICAgICAgICB0b3A6IDIwcHg7XG4gICAgfVxufVxuXG4vL1ByZWxvYWRlcnMgbW9kYWxzXG4ubW9kYWwgLnByZWxvYWRlciB7XG4gICAgd2lkdGg6IDM0cHg7XG4gICAgaGVpZ2h0OiAzNHB4O1xufVxuLnByZWxvYWRlci1pbmRpY2F0b3Itb3ZlcmxheSB7XG4gICAgdmlzaWJpbGl0eTogdmlzaWJsZTtcbiAgICBvcGFjaXR5OiAwO1xuICAgIGJhY2tncm91bmQ6IG5vbmU7XG59XG4ucHJlbG9hZGVyLWluZGljYXRvci1tb2RhbCB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IDUwJTtcbiAgICB0b3A6IDUwJTtcbiAgICBwYWRkaW5nOiA4cHg7XG4gICAgbWFyZ2luLWxlZnQ6IC0yNXB4O1xuICAgIG1hcmdpbi10b3A6IC0yNXB4O1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwwLDAsMC44KTtcbiAgICB6LWluZGV4OiAxMzUwMDtcbiAgICBib3JkZXItcmFkaXVzOiA1cHg7XG4gICAgLnByZWxvYWRlciB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB3aWR0aDogMzRweDtcbiAgICAgICAgaGVpZ2h0OiAzNHB4O1xuICAgIH1cbn1cblxuLy8gUGlja2VyIE1vZGFsXG4ucGlja2VyLW1vZGFsIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICBib3R0b206IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAyNjBweDtcbiAgICB6LWluZGV4OiAxMjUwMDtcbiAgICBkaXNwbGF5OiBub25lO1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbi1wcm9wZXJ0eTogLXdlYmtpdC10cmFuc2Zvcm07XG4gICAgLW1vei10cmFuc2l0aW9uLXByb3BlcnR5OiAtbW96LXRyYW5zZm9ybTtcbiAgICAtbXMtdHJhbnNpdGlvbi1wcm9wZXJ0eTogLW1zLXRyYW5zZm9ybTtcbiAgICAtby10cmFuc2l0aW9uLXByb3BlcnR5OiAtby10cmFuc2Zvcm07XG4gICAgdHJhbnNpdGlvbi1wcm9wZXJ0eTogdHJhbnNmb3JtO1xuICAgIGJhY2tncm91bmQ6ICNjZmQ1ZGE7XG4gICAgLnRyYW5zbGF0ZTNkKDAsMTAwJSwwKTtcbiAgICAmLm1vZGFsLWluLCAmLm1vZGFsLW91dCB7XG4gICAgICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICB9XG4gICAgJi5tb2RhbC1pbiB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxuICAgICYubW9kYWwtb3V0IHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMTAwJSwwKTtcbiAgICB9XG4gICAgLnBpY2tlci1tb2RhbC1pbm5lciB7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIH1cbiAgICAudG9vbGJhciB7XG4gICAgICAgIC5oYWlybGluZSh0b3AsICM5Mjk0OTkpO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kOiAjZjdmN2Y4O1xuICAgICAgICArIC5waWNrZXItbW9kYWwtaW5uZXIge1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCItd2Via2l0LWNhbGMoMTAwJSAtIEB7dG9vbGJhclNpemV9KVwiO1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCItbW96LWNhbGMoMTAwJSAtIEB7dG9vbGJhclNpemV9KVwiO1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCJjYWxjKDEwMCUgLSBAe3Rvb2xiYXJTaXplfSlcIjsgICAgXG4gICAgICAgIH1cbiAgICB9XG4gICAgJi5waWNrZXItbW9kYWwtaW5saW5lLCAucG9wb3ZlciAmIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgICAgei1pbmRleDogaW5oZXJpdDtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAgICAgLnRvb2xiYXIge1xuICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgICAgICAgICAgLmhhaXJsaW5lKGJvdHRvbSwgIzkyOTQ5OSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLnBvcG92ZXIgJiB7XG4gICAgICAgIHdpZHRoOiBhdXRvO1xuICAgICAgICAudG9vbGJhciB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgICAgICB9XG4gICAgfVxuICAgICYuc21hcnQtc2VsZWN0LXBpY2tlciB7XG4gICAgICAgIC5wYWdlIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgICAgIH1cbiAgICAgICAgLnRvb2xiYXIge1xuICAgICAgICAgICAgLmhhaXJsaW5lKGJvdHRvbSwgI2M0YzRjNCk7XG4gICAgICAgIH1cbiAgICAgICAgLmxpc3QtYmxvY2sge1xuICAgICAgICAgICAgbWFyZ2luOiAwO1xuICAgICAgICAgICAgdWwge1xuICAgICAgICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUodG9wKTtcbiAgICAgICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59IiwiLyogPT09IFBhbmVscyA9PT0gKi9cbkBwYW5lbFdpZHRoOjI2MHB4O1xuQHBhbmVsc0R1cmF0aW9uOiA0MDBtcztcbi5wYW5lbC1vdmVybGF5IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwwLDAsMCk7XG4gICAgb3BhY2l0eTogMDtcbiAgICB6LWluZGV4OiA1OTk5O1xuICAgIGRpc3BsYXk6IG5vbmU7XG59XG4ucGFuZWwge1xuICAgIHotaW5kZXg6IDEwMDA7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiAjMTExO1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgLnNjcm9sbGFibGUoKTtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgd2lkdGg6IEBwYW5lbFdpZHRoO1xuICAgIHRvcDogMDtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgLnRyYW5zbGF0ZTNkKDApO1xuICAgIC50cmFuc2l0aW9uKEBwYW5lbHNEdXJhdGlvbik7XG5cbiAgICAmLnBhbmVsLWxlZnQge1xuICAgICAgICAmLnBhbmVsLWNvdmVyIHtcbiAgICAgICAgICAgIHotaW5kZXg6IDYwMDA7XG4gICAgICAgICAgICBsZWZ0OiAtQHBhbmVsV2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgJi5wYW5lbC1yZXZlYWwge1xuICAgICAgICAgICAgbGVmdDogMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAmLnBhbmVsLXJpZ2h0IHtcbiAgICAgICAgJi5wYW5lbC1jb3ZlciB7XG4gICAgICAgICAgICB6LWluZGV4OiA2MDAwO1xuICAgICAgICAgICAgcmlnaHQ6IC1AcGFuZWxXaWR0aDtcbiAgICAgICAgfVxuICAgICAgICAmLnBhbmVsLXJldmVhbCB7XG4gICAgICAgICAgICByaWdodDogMDtcbiAgICAgICAgfVxuICAgIH1cbn1cbmJvZHkud2l0aC1wYW5lbC1sZWZ0LWNvdmVyLCBib2R5LndpdGgtcGFuZWwtcmlnaHQtY292ZXIge1xuICAgIC52aWV3cyB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwKTtcbiAgICB9XG4gICAgLnBhbmVsLW92ZXJsYXkge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICB9XG59XG5ib2R5LndpdGgtcGFuZWwtbGVmdC1yZXZlYWwsIGJvZHkud2l0aC1wYW5lbC1yaWdodC1yZXZlYWwge1xuICAgIC52aWV3cyB7XG4gICAgICAgIC50cmFuc2l0aW9uKEBwYW5lbHNEdXJhdGlvbik7XG4gICAgICAgIC13ZWJraXQtdHJhbnNpdGlvbi1wcm9wZXJ0eTogLXdlYmtpdC10cmFuc2Zvcm07XG4gICAgICAgIC1tb3otdHJhbnNpdGlvbi1wcm9wZXJ0eTogLW1vei10cmFuc2Zvcm07XG4gICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybTtcbiAgICB9XG4gICAgLnBhbmVsLW92ZXJsYXkge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICB9XG59XG5ib2R5LndpdGgtcGFuZWwtbGVmdC1yZXZlYWwge1xuICAgIC52aWV3cyB7XG4gICAgICAgIC50cmFuc2xhdGUzZChAcGFuZWxXaWR0aCk7XG4gICAgfVxuICAgIC5wYW5lbC1vdmVybGF5IHtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IEBwYW5lbFdpZHRoO1xuICAgIH1cbn1cbmJvZHkud2l0aC1wYW5lbC1sZWZ0LWNvdmVyIHtcbiAgICAucGFuZWwtbGVmdCB7XG4gICAgICAgIC50cmFuc2xhdGUzZChAcGFuZWxXaWR0aCk7XG4gICAgfVxufVxuYm9keS53aXRoLXBhbmVsLXJpZ2h0LXJldmVhbCB7XG4gICAgLnZpZXdzIHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKC1AcGFuZWxXaWR0aCk7XG4gICAgfVxuICAgIC5wYW5lbC1vdmVybGF5IHtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IC1AcGFuZWxXaWR0aDtcbiAgICB9XG59XG5ib2R5LndpdGgtcGFuZWwtcmlnaHQtY292ZXIge1xuICAgIC5wYW5lbC1yaWdodCB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgtQHBhbmVsV2lkdGgpO1xuICAgIH1cbn1cbmJvZHkucGFuZWwtY2xvc2luZyB7XG4gICAgLnZpZXdzIHtcbiAgICAgICAgLnRyYW5zaXRpb24oQHBhbmVsc0R1cmF0aW9uKTtcbiAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uLXByb3BlcnR5OiAtd2Via2l0LXRyYW5zZm9ybTtcbiAgICAgICAgLW1vei10cmFuc2l0aW9uLXByb3BlcnR5OiAtbW96LXRyYW5zZm9ybTtcbiAgICAgICAgdHJhbnNpdGlvbi1wcm9wZXJ0eTogdHJhbnNmb3JtO1xuICAgIH1cbn0iLCIvKiA9PT0gVGFicyA9PT0gKi9cbi50YWJzIHtcbiAgICAudGFiIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gICAgLnRhYi5hY3RpdmUge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICB9XG59XG4udGFicy1hbmltYXRlZC13cmFwIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgPi50YWJzIHtcbiAgICAgICAgLmZsZXhib3goKTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgICAgID4udGFiIHtcbiAgICAgICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICAuZmxleC1zaHJpbmsoMCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4udGFicy1zd2lwZWFibGUtd3JhcCB7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgID4gLnRhYnMgPiAudGFiIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgfVxufSIsIi8qID09PSBNZXNzYWdlcyA9PT0gKi9cbi5tZXNzYWdlcy1jb250ZW50IHtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xufVxuLm1lc3NhZ2VzIHtcbiAgICAuZmxleGJveCgpO1xuICAgIC13ZWJraXQtYm94LW9yaWVudDogdmVydGljYWw7XG4gICAgLW1vei1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcbiAgICAtbXMtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbn1cbi5tZXNzYWdlcy1kYXRlIHtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICBmb250LXNpemU6IDExcHg7XG4gICAgbGluZS1oZWlnaHQ6IDE7XG4gICAgbWFyZ2luOiAxMHB4IDE1cHg7XG4gICAgY29sb3I6ICM4ZThlOTM7XG4gICAgaHRtbC5pb3MtZ3QtOCAmIHtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICB9XG4gICAgc3BhbiB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA0MDA7XG4gICAgfVxufVxuLm1lc3NhZ2Uge1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgbWFyZ2luOiAxcHggMTBweCAwO1xuICAgIG1heC13aWR0aDogNzAlO1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcbiAgICAtbW96LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgIC1tcy1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIC13ZWJraXQtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICY6Zmlyc3QtY2hpbGQge1xuICAgICAgICBtYXJnaW4tdG9wOiAxMHB4O1xuICAgIH1cbiAgICAubWVzc2FnZS10ZXh0IHtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICAgICAgcGFkZGluZzogNnB4IDE2cHggOXB4O1xuICAgICAgICBtaW4td2lkdGg6IDQ4cHg7XG4gICAgICAgIG1pbi1oZWlnaHQ6IDM1cHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTdweDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDEuMjtcbiAgICAgICAgd29yZC1icmVhazogYnJlYWstd29yZDtcbiAgICAgICAgaW1nIHtcbiAgICAgICAgICAgIG1heC13aWR0aDogMTAwJTtcbiAgICAgICAgICAgIGhlaWdodDogYXV0bztcbiAgICAgICAgfVxuICAgIH1cbiAgICAmLm1lc3NhZ2UtcGljIHtcbiAgICAgICAgLm1lc3NhZ2UtdGV4dCB7XG4gICAgICAgICAgICBwYWRkaW5nOiAwO1xuICAgICAgICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgICAgfVxuICAgICAgICBpbWcge1xuICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICAgICAgICB9XG4gICAgfVxufVxuLm1lc3NhZ2UtbmFtZSB7XG4gICAgZm9udC1zaXplOiAxMnB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxO1xuICAgIGNvbG9yOiAjOGU4ZTkzO1xuICAgIG1hcmdpbi1ib3R0b206IDJweDtcbiAgICBtYXJnaW4tdG9wOiA3cHg7XG4gICAgLm1lc3NhZ2UtaGlkZS1uYW1lICYge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbn1cbi5tZXNzYWdlLWxhYmVsIHtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgbGluZS1oZWlnaHQ6IDE7XG4gICAgY29sb3I6ICM4ZThlOTM7XG4gICAgbWFyZ2luLXRvcDogNHB4O1xuICAgIC5tZXNzYWdlLWhpZGUtbGFiZWwgJiB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxufVxuLm1lc3NhZ2UtYXZhdGFyIHtcbiAgICB3aWR0aDogMjlweDtcbiAgICBoZWlnaHQ6IDI5cHg7XG4gICAgYm9yZGVyLXJhZGl1czogMTAwJTtcbiAgICBtYXJnaW4tdG9wOiAtMjlweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgdG9wOiAxcHg7XG4gICAgYmFja2dyb3VuZC1zaXplOiBjb3ZlcjtcbiAgICBvcGFjaXR5OiAxO1xuICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICAubWVzc2FnZS1oaWRlLWF2YXRhciAmIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG59XG4ubWVzc2FnZS1kYXRlIHtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgbWFyZ2luLXRvcDogNHB4O1xuICAgIG9wYWNpdHk6IDAuODtcbiAgICAubWVzc2FnZS1waWMgaW1nICsgJiB7XG4gICAgICAgIG1hcmdpbi10b3A6IDhweDtcbiAgICB9XG4gICAgLm1lc3NhZ2Utc2VudCAmIHtcbiAgICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgfVxufVxuLm1lc3NhZ2Utc2VudCB7XG4gICAgLW1zLWZsZXgtaXRlbS1hbGlnbjogZW5kO1xuICAgIC13ZWJraXQtYWxpZ24tc2VsZjogZmxleC1lbmQ7XG4gICAgYWxpZ24tc2VsZjogZmxleC1lbmQ7XG4gICAgLmFsaWduLWl0ZW1zKGZsZXgtZW5kKTtcbiAgICAubWVzc2FnZS1uYW1lIHtcbiAgICAgICAgbWFyZ2luLXJpZ2h0OiAxNnB4O1xuICAgIH1cbiAgICAubWVzc2FnZS1sYWJlbCB7XG4gICAgICAgIG1hcmdpbi1yaWdodDogNnB4O1xuICAgIH1cbiAgICAmLm1lc3NhZ2Utd2l0aC1hdmF0YXIge1xuICAgICAgICAubWVzc2FnZS10ZXh0IHtcbiAgICAgICAgICAgIG1hcmdpbi1yaWdodDogMjlweDtcbiAgICAgICAgfVxuICAgICAgICAubWVzc2FnZS1uYW1lIHtcbiAgICAgICAgICAgIG1hcmdpbi1yaWdodDogNDVweDtcbiAgICAgICAgfVxuICAgICAgICAubWVzc2FnZS1sYWJlbCB7XG4gICAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDM0cHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLm1lc3NhZ2UtdGV4dCB7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IDIycHg7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICMwMGQ0NDk7XG4gICAgICAgIGNvbG9yOiB3aGl0ZTtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IGF1dG87XG4gICAgICAgIC13ZWJraXQtbWFzay1ib3gtaW1hZ2U6IHVybChcImRhdGE6aW1hZ2Uvc3ZnK3htbDtjaGFyc2V0PXV0Zi04LDxzdmcgaGVpZ2h0PSczNScgdmlld0JveD0nMCAwIDk2IDcwJyB3aWR0aD0nNDgnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nbTg0IDM1YzEgNy01IDM3LTQyIDM1LTM3IDItNDMtMjgtNDItMzUtMS03IDUtMzcgNDItMzUgMzctMiA0MyAyOCA0MiAzNXonLz48L3N2Zz5cIikgNTAlIDU2JSA0NiUgNDIlO1xuICAgIH1cbiAgICAmLm1lc3NhZ2UtbGFzdCwgJi5tZXNzYWdlLXdpdGgtdGFpbCB7XG4gICAgICAgIC5tZXNzYWdlLXRleHQge1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTZweCAxNnB4IDAgMTZweDtcbiAgICAgICAgICAgIC13ZWJraXQtbWFzay1ib3gtaW1hZ2U6IHVybChcImRhdGE6aW1hZ2Uvc3ZnK3htbDtjaGFyc2V0PXV0Zi04LDxzdmcgaGVpZ2h0PSczNScgdmlld0JveD0nMCAwIDk2IDcwJyB3aWR0aD0nNDgnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nbTg0IDM1YzEgNy01IDM3LTQyIDM1LTM3IDItNDMtMjgtNDItMzUtMS03IDUtMzcgNDItMzUgMzctMiA0MyAyOCA0MiAzNXonLz48cGF0aCBkPSdtOTYgNzBjLTYtMi0xMi0xMC0xMi0xOXYtMTZsLTE0IDI3czggOCAyNiA4eicvPjwvc3ZnPlwiKSA1MCUgNTYlIDQ2JSA0MiU7XG4gICAgICAgIH1cbiAgICAgICAgJi5tZXNzYWdlLXBpYyBpbWd7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4IDE2cHggMCAxNnB4O1xuICAgICAgICB9XG4gICAgfVxufVxuLm1lc3NhZ2UtcmVjZWl2ZWQge1xuICAgIC1tcy1mbGV4LWl0ZW0tYWxpZ246IHN0YXJ0O1xuICAgIC13ZWJraXQtYWxpZ24tc2VsZjogZmxleC1zdGFydDtcbiAgICBhbGlnbi1zZWxmOiBmbGV4LXN0YXJ0O1xuICAgIC5hbGlnbi1pdGVtcyhmbGV4LXN0YXJ0KTtcbiAgICAubWVzc2FnZS10ZXh0IHtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiAyMnB4O1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZTVlNWVhO1xuICAgICAgICBjb2xvcjogIzAwMDtcbiAgICAgICAgLXdlYmtpdC1tYXNrLWJveC1pbWFnZTogdXJsKFwiZGF0YTppbWFnZS9zdmcreG1sO2NoYXJzZXQ9dXRmLTgsPHN2ZyBoZWlnaHQ9JzM1JyB2aWV3Qm94PScwIDAgOTYgNzAnIHdpZHRoPSc0OCcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJz48cGF0aCBkPSdtOTYgMzVjMSA3LTUgMzctNDIgMzUtMzcgMi00My0yOC00Mi0zNS0xLTcgNS0zNyA0Mi0zNSAzNy0yIDQzIDI4IDQyIDM1eicvPjwvc3ZnPlwiKSA1MCUgNDIlIDQ2JSA1NiU7XG4gICAgfVxuICAgIC5tZXNzYWdlLW5hbWUge1xuICAgICAgICBtYXJnaW4tbGVmdDogMTZweDtcbiAgICB9XG4gICAgLm1lc3NhZ2UtbGFiZWwge1xuICAgICAgICBtYXJnaW4tbGVmdDogNnB4O1xuICAgIH1cbiAgICAmLm1lc3NhZ2Utd2l0aC1hdmF0YXIge1xuICAgICAgICAubWVzc2FnZS10ZXh0IHtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiAyOXB4O1xuICAgICAgICB9XG4gICAgICAgIC5tZXNzYWdlLW5hbWUge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDQ1cHg7XG4gICAgICAgIH1cbiAgICAgICAgLm1lc3NhZ2UtbGFiZWwge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDM0cHg7XG4gICAgICAgIH1cbiAgICB9ICAgIFxuICAgICYubWVzc2FnZS1sYXN0LCAmLm1lc3NhZ2Utd2l0aC10YWlsIHtcbiAgICAgICAgLm1lc3NhZ2UtdGV4dCB7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4IDE2cHggMTZweCAwO1xuICAgICAgICAgICAgLXdlYmtpdC1tYXNrLWJveC1pbWFnZTogdXJsKFwiZGF0YTppbWFnZS9zdmcreG1sO2NoYXJzZXQ9dXRmLTgsPHN2ZyBoZWlnaHQ9JzM1JyB2aWV3Qm94PScwIDAgOTYgNzAnIHdpZHRoPSc0OCcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJz48cGF0aCBkPSdtOTYgMzVjMSA3LTUgMzctNDIgMzUtMzcgMi00My0yOC00Mi0zNS0xLTcgNS0zNyA0Mi0zNSAzNy0yIDQzIDI4IDQyIDM1eicvPjxwYXRoIGQ9J20wIDcwYzYtMiAxMi0xMCAxMi0xOXYtMTZsMTQgMjdzLTggOC0yNiA4eicvPjwvc3ZnPlwiKSA1MCUgNDIlIDQ2JSA1NiU7XG4gICAgICAgIH1cbiAgICAgICAgJi5tZXNzYWdlLXBpYyBpbWd7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4IDE2cHggMTZweCAwO1xuICAgICAgICB9XG4gICAgfVxufVxuLm1lc3NhZ2UtbGFzdCB7XG4gICAgbWFyZ2luLWJvdHRvbTogOHB4O1xufVxuLm1lc3NhZ2UtYXBwZWFyLWZyb20tYm90dG9tIHtcbiAgICAtd2Via2l0LWFuaW1hdGlvbjogbWVzc2FnZUFwcGVhckZyb21Cb3R0b20gNDAwbXM7XG4gICAgYW5pbWF0aW9uOiBtZXNzYWdlQXBwZWFyRnJvbUJvdHRvbSA0MDBtcztcbn1cbi5tZXNzYWdlLWFwcGVhci1mcm9tLXRvcCB7XG4gICAgLXdlYmtpdC1hbmltYXRpb246IG1lc3NhZ2VBcHBlYXJGcm9tVG9wIDQwMG1zO1xuICAgIGFuaW1hdGlvbjogbWVzc2FnZUFwcGVhckZyb21Ub3AgNDAwbXM7ICAgXG59XG4ubWVzc2FnZXMtYXV0by1sYXlvdXQge1xuICAgIC5tZXNzYWdlLW5hbWUsIC5tZXNzYWdlLWxhYmVsIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gICAgLm1lc3NhZ2UtYXZhdGFyIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG4gICAgLm1lc3NhZ2UtZmlyc3Qge1xuICAgICAgICAubWVzc2FnZS1uYW1lIHtcbiAgICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5tZXNzYWdlLWxhc3Qge1xuICAgICAgICAubWVzc2FnZS1hdmF0YXIge1xuICAgICAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgfVxuICAgICAgICAubWVzc2FnZS1sYWJlbCB7XG4gICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgfVxuICAgIH1cbn1cbmh0bWwucmV0aW5hLmlvcy02IHtcbiAgICAubWVzc2FnZSwgLm1lc3NhZ2UubWVzc2FnZS1waWMgaW1nIHtcbiAgICAgICAgLXdlYmtpdC1tYXNrLWJveC1pbWFnZTpub25lO1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICAgIH1cbn1cbkAtd2Via2l0LWtleWZyYW1lcyBtZXNzYWdlQXBwZWFyRnJvbUJvdHRvbSB7XG4gICAgZnJvbSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDEwMCUsMCk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG59XG5Aa2V5ZnJhbWVzIG1lc3NhZ2VBcHBlYXJGcm9tQm90dG9tIHtcbiAgICBmcm9tIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDEwMCUsMCk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIG1lc3NhZ2VBcHBlYXJGcm9tVG9wIHtcbiAgICBmcm9tIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsLTEwMCUsMCk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG59XG5Aa2V5ZnJhbWVzIG1lc3NhZ2VBcHBlYXJGcm9tVG9wIHtcbiAgICBmcm9tIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLC0xMDAlLDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIH1cbn1cbiIsIi8qID09PSBTdGF0dXNiYXIgb3ZlcmxheSA9PT0gKi9cbmh0bWwud2l0aC1zdGF0dXNiYXItb3ZlcmxheSBib2R5e1xuICAgIHBhZGRpbmctdG9wOiAyMHB4O1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgLnN0YXR1c2Jhci1vdmVybGF5IHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgfVxuICAgIC5wYW5lbCB7XG4gICAgICAgIHBhZGRpbmctdG9wOiAyMHB4O1xuICAgIH1cbn1cbi5zdGF0dXNiYXItb3ZlcmxheSB7XG4gICAgYmFja2dyb3VuZDogQHRvb2xiYXJCZztcbiAgICB6LWluZGV4OiAxMDAwMDsgLy8gQSBiaXQgbG93ZXIgdGhhbiAubW9kYWxzLW92ZXJsYXlcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgaGVpZ2h0OiAyMHB4O1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgLnRyYW5zaXRpb24oQHBhbmVsc0R1cmF0aW9uKTtcbn0iLCIvKiA9PT0gUHJlbG9hZGVyID09PSAqL1xuLnByZWxvYWRlciB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHdpZHRoOiAyMHB4O1xuICAgIGhlaWdodDogMjBweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgdmlld0JveD0nMCAwIDEyMCAxMjAnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycgeG1sbnM6eGxpbms9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnPjxkZWZzPjxsaW5lIGlkPSdsJyB4MT0nNjAnIHgyPSc2MCcgeTE9JzcnIHkyPScyNycgc3Ryb2tlPScjNmM2YzZjJyBzdHJva2Utd2lkdGg9JzExJyBzdHJva2UtbGluZWNhcD0ncm91bmQnLz48L2RlZnM+PGc+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjI3Jy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjI3JyB0cmFuc2Zvcm09J3JvdGF0ZSgzMCA2MCw2MCknLz48dXNlIHhsaW5rOmhyZWY9JyNsJyBvcGFjaXR5PScuMjcnIHRyYW5zZm9ybT0ncm90YXRlKDYwIDYwLDYwKScvPjx1c2UgeGxpbms6aHJlZj0nI2wnIG9wYWNpdHk9Jy4yNycgdHJhbnNmb3JtPSdyb3RhdGUoOTAgNjAsNjApJy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjI3JyB0cmFuc2Zvcm09J3JvdGF0ZSgxMjAgNjAsNjApJy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjI3JyB0cmFuc2Zvcm09J3JvdGF0ZSgxNTAgNjAsNjApJy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjM3JyB0cmFuc2Zvcm09J3JvdGF0ZSgxODAgNjAsNjApJy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjQ2JyB0cmFuc2Zvcm09J3JvdGF0ZSgyMTAgNjAsNjApJy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjU2JyB0cmFuc2Zvcm09J3JvdGF0ZSgyNDAgNjAsNjApJy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjY2JyB0cmFuc2Zvcm09J3JvdGF0ZSgyNzAgNjAsNjApJy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjc1JyB0cmFuc2Zvcm09J3JvdGF0ZSgzMDAgNjAsNjApJy8+PHVzZSB4bGluazpocmVmPScjbCcgb3BhY2l0eT0nLjg1JyB0cmFuc2Zvcm09J3JvdGF0ZSgzMzAgNjAsNjApJy8+PC9nPjwvc3ZnPlwiKTtcbiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiA1MCU7XG4gICAgYmFja2dyb3VuZC1zaXplOiAxMDAlO1xuICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgLXdlYmtpdC1hbmltYXRpb246IHByZWxvYWRlci1zcGluIDFzIHN0ZXBzKDEyLCBlbmQpIGluZmluaXRlO1xuICAgIGFuaW1hdGlvbjogcHJlbG9hZGVyLXNwaW4gMXMgc3RlcHMoMTIsIGVuZCkgaW5maW5pdGU7XG59XG5ALXdlYmtpdC1rZXlmcmFtZXMgcHJlbG9hZGVyLXNwaW4ge1xuICAgIDEwMCUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7XG4gICAgfVxufVxuQGtleWZyYW1lcyBwcmVsb2FkZXItc3BpbiB7XG4gICAgMTAwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7XG4gICAgfVxufVxuIiwiLyogPT09IFByb2dyZXNzIEJhciA9PT0gKi9cbi5wcm9ncmVzc2JhciwgLnByb2dyZXNzYmFyLWluZmluaXRlIHtcbiAgICBoZWlnaHQ6IDJweDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBiYWNrZ3JvdW5kOiAjYjZiNmI2O1xuICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICAudHJhbnNmb3JtLW9yaWdpbihjZW50ZXIgdG9wKTtcbiAgICAtd2Via2l0LXRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgdHJhbnNmb3JtLXN0eWxlOiBwcmVzZXJ2ZS0zZDtcbn1cbi8vIERldGVybWluZWRcbi5wcm9ncmVzc2JhciB7XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgICBzcGFuIHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGJhY2tncm91bmQ6IEB0aGVtZUNvbG9yO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICAudHJhbnNsYXRlM2QoLTEwMCUsIDAsIDApO1xuICAgICAgICAudHJhbnNpdGlvbigxNTBtcyk7XG4gICAgfVxufVxuLy8gSW5maW5pdGVcbi5wcm9ncmVzc2Jhci1pbmZpbml0ZSB7XG4gICAgJjpiZWZvcmUge1xuICAgICAgICBjb250ZW50OiAnJztcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICBsZWZ0OiAwO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIGJhY2tncm91bmQ6IEB0aGVtZUNvbG9yO1xuICAgICAgICAudHJhbnNsYXRlM2QoMCwgMCwgMCk7XG4gICAgICAgIC50cmFuc2Zvcm0tb3JpZ2luKGxlZnQgY2VudGVyKTtcbiAgICAgICAgLmFuaW1hdGlvbihwcm9ncmVzc2Jhci1pbmZpbml0ZSAxcyBsaW5lYXIgaW5maW5pdGUpO1xuICAgIH1cbiAgICBodG1sLndpdGgtc3RhdHVzYmFyLW92ZXJsYXkgYm9keSA+ICYsIGh0bWwud2l0aC1zdGF0dXNiYXItb3ZlcmxheSAuZnJhbWV3b3JrNy1yb290ID4gJiB7XG4gICAgICAgIHRvcDogMjBweDtcbiAgICB9XG59XG4vLyBNdWx0aWNvbG9yXG4ucHJvZ3Jlc3NiYXItaW5maW5pdGUuY29sb3ItbXVsdGkge1xuICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgJjpiZWZvcmUge1xuICAgICAgICBjb250ZW50OiAnJztcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICBsZWZ0OiAwO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIHdpZHRoOiA0MDAlO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtbGluZWFyLWdyYWRpZW50KGxlZnQsICM0Y2Q5NjQsICM1YWM4ZmEsICMwMDdhZmYsICMzNGFhZGMsICM1ODU2ZDYsICNmZjJkNTUsICM1ODU2ZDYsICMzNGFhZGMsICMwMDdhZmYsICM1YWM4ZmEsICM0Y2Q5NjQpO1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICM0Y2Q5NjQsICM1YWM4ZmEsICMwMDdhZmYsICMzNGFhZGMsICM1ODU2ZDYsICNmZjJkNTUsICM1ODU2ZDYsICMzNGFhZGMsICMwMDdhZmYsICM1YWM4ZmEsICM0Y2Q5NjQpO1xuICAgICAgICBiYWNrZ3JvdW5kLXNpemU6IDI1JSAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0LXg7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLCAwLCAwKTtcbiAgICAgICAgLmFuaW1hdGlvbihwcm9ncmVzc2Jhci1pbmZpbml0ZS1tdWx0aWNvbG9yIDNzIGxpbmVhciBpbmZpbml0ZSk7XG4gICAgfVxuICAgIGh0bWwud2l0aC1zdGF0dXNiYXItb3ZlcmxheSBib2R5ID4gJiAsIGh0bWwud2l0aC1zdGF0dXNiYXItb3ZlcmxheSAuZnJhbWV3b3JrNy1yb290ID4gJiB7XG4gICAgICAgIHRvcDogMjBweDtcbiAgICB9XG59XG5ib2R5LCAudmlldywgLnZpZXdzLCAucGFnZSwgLnBhbmVsLCAucG9wdXAsIC5mcmFtZXdvcms3LXJvb3Qge1xuICAgID4gLnByb2dyZXNzYmFyLCA+IC5wcm9ncmVzc2Jhci1pbmZpbml0ZSB7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICB6LWluZGV4OiAxNTAwMDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMDtcbiAgICB9XG59XG4vLyBBbmltYXRpb25zXG4ucHJvZ3Jlc3NiYXItaW4ge1xuICAgIC5hbmltYXRpb24ocHJvZ3Jlc3NiYXItaW4gMzAwbXMgZm9yd2FyZHMpO1xufVxuLnByb2dyZXNzYmFyLW91dCB7XG4gICAgLmFuaW1hdGlvbihwcm9ncmVzc2Jhci1vdXQgMzAwbXMgZm9yd2FyZHMpO1xufVxuXG5odG1sLndpdGgtc3RhdHVzYmFyLW92ZXJsYXkgYm9keSA+IC5wcm9ncmVzc2JhciB7XG4gICAgdG9wOiAyMHB4O1xufVxuQC13ZWJraXQta2V5ZnJhbWVzIHByb2dyZXNzYmFyLWluIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlWSgwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVZKDEpO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcHJvZ3Jlc3NiYXItaW4ge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWSgwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWSgxKTtcbiAgICB9XG59XG5ALXdlYmtpdC1rZXlmcmFtZXMgcHJvZ3Jlc3NiYXItb3V0IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlWSgxKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVZKDApO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcHJvZ3Jlc3NiYXItb3V0IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZVkoMSk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZVkoMCk7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIHByb2dyZXNzYmFyLWluZmluaXRlIHtcbiAgICAwJSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgtNTAlLCAwLCAwKSBzY2FsZVgoMC41KTtcbiAgICB9XG4gICAgMTAwJSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgxMDAlLCAwLCAwKSBzY2FsZVgoMC41KTtcbiAgICB9XG59XG5Aa2V5ZnJhbWVzIHByb2dyZXNzYmFyLWluZmluaXRlIHtcbiAgICAwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoLTUwJSwgMCwgMCkgc2NhbGVYKDAuNSk7XG4gICAgfVxuICAgIDEwMCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDEwMCUsIDAsIDApIHNjYWxlWCgwLjUpO1xuICAgIH1cbn1cbkAtd2Via2l0LWtleWZyYW1lcyBwcm9ncmVzc2Jhci1pbmZpbml0ZS1tdWx0aWNvbG9yIHtcbiAgICBmcm9tIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAlLCAwLCAwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlM2QoLTUwJSwgMCwgMCk7XG4gICAgfVxufVxuQGtleWZyYW1lcyBwcm9ncmVzc2Jhci1pbmZpbml0ZS1tdWx0aWNvbG9yIHtcbiAgICBmcm9tIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwJSwgMCwgMCk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgtNTAlLCAwLCAwKTtcbiAgICB9XG59IiwiLyogPT09IFN3aXBlciA9PT0gKi9cbi5zd2lwZXItY29udGFpbmVyIHtcbiAgICBtYXJnaW4tbGVmdDogYXV0bztcbiAgICBtYXJnaW4tcmlnaHQ6IGF1dG87XG4gICAgcG9zaXRpb246cmVsYXRpdmU7XG4gICAgb3ZlcmZsb3c6aGlkZGVuO1xuICAgIC8qIEZpeCBvZiBXZWJraXQgZmxpY2tlcmluZyAqL1xuICAgIHotaW5kZXg6MTtcbn1cbi5zd2lwZXItY29udGFpbmVyLW5vLWZsZXhib3gge1xuICAgIC5zd2lwZXItc2xpZGUge1xuICAgICAgICBmbG9hdDogbGVmdDtcbiAgICB9XG59XG4uc3dpcGVyLWNvbnRhaW5lci12ZXJ0aWNhbCA+IC5zd2lwZXItd3JhcHBlcntcbiAgICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgIC1tb3otYm94LW9yaWVudDogdmVydGljYWw7XG4gICAgLW1zLWZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG59XG4uc3dpcGVyLXdyYXBwZXIge1xuICAgIHBvc2l0aW9uOnJlbGF0aXZlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICB6LWluZGV4OiAxO1xuICAgIGRpc3BsYXk6IC13ZWJraXQtYm94O1xuICAgIGRpc3BsYXk6IC1tb3otYm94O1xuICAgIGRpc3BsYXk6IC1tcy1mbGV4Ym94O1xuICAgIGRpc3BsYXk6IC13ZWJraXQtZmxleDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuXG4gICAgLXdlYmtpdC10cmFuc2l0aW9uLXByb3BlcnR5Oi13ZWJraXQtdHJhbnNmb3JtO1xuICAgIC1tb3otdHJhbnNpdGlvbi1wcm9wZXJ0eTotbW96LXRyYW5zZm9ybTtcbiAgICAtby10cmFuc2l0aW9uLXByb3BlcnR5Oi1vLXRyYW5zZm9ybTtcbiAgICAtbXMtdHJhbnNpdGlvbi1wcm9wZXJ0eTotbXMtdHJhbnNmb3JtO1xuICAgIHRyYW5zaXRpb24tcHJvcGVydHk6dHJhbnNmb3JtO1xuICAgIFxuICAgIC13ZWJraXQtYm94LXNpemluZzogY29udGVudC1ib3g7XG4gICAgLW1vei1ib3gtc2l6aW5nOiBjb250ZW50LWJveDtcbiAgICBib3gtc2l6aW5nOiBjb250ZW50LWJveDtcbn1cbi5zd2lwZXItY29udGFpbmVyLWFuZHJvaWQgLnN3aXBlci1zbGlkZSwgLnN3aXBlci13cmFwcGVyIHtcbiAgICAtd2Via2l0LXRyYW5zZm9ybTp0cmFuc2xhdGUzZCgwcHgsMCwwKTtcbiAgICAtbW96LXRyYW5zZm9ybTp0cmFuc2xhdGUzZCgwcHgsMCwwKTtcbiAgICAtby10cmFuc2Zvcm06dHJhbnNsYXRlKDBweCwwcHgpO1xuICAgIC1tcy10cmFuc2Zvcm06dHJhbnNsYXRlM2QoMHB4LDAsMCk7XG4gICAgdHJhbnNmb3JtOnRyYW5zbGF0ZTNkKDBweCwwLDApO1xufVxuLnN3aXBlci1jb250YWluZXItbXVsdGlyb3cgPiAuc3dpcGVyLXdyYXBwZXIge1xuICAgIC13ZWJraXQtYm94LWxpbmVzOiBtdWx0aXBsZTtcbiAgICAtbW96LWJveC1saW5lczogbXVsdGlwbGU7XG4gICAgLW1zLWZsZXgtd3JhcDogd3JhcDtcbiAgICAtd2Via2l0LWZsZXgtd3JhcDogd3JhcDtcbiAgICBmbGV4LXdyYXA6IHdyYXA7XG59XG4uc3dpcGVyLWNvbnRhaW5lci1mcmVlLW1vZGUgPiAuc3dpcGVyLXdyYXBwZXIge1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGVhc2Utb3V0O1xuICAgIC1tb3otdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGVhc2Utb3V0O1xuICAgIC1tcy10cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvbjogZWFzZS1vdXQ7XG4gICAgLW8tdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGVhc2Utb3V0O1xuICAgIHRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbiAgICBtYXJnaW46IDAgYXV0bztcbn1cbi5zd2lwZXItc2xpZGUge1xuICAgIC13ZWJraXQtZmxleC1zaHJpbms6IDA7XG4gICAgLW1zLWZsZXg6IDAgMCBhdXRvO1xuICAgIGZsZXgtc2hyaW5rOiAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG4vKiBBdXRvIEhlaWdodCAqL1xuLnN3aXBlci1jb250YWluZXItYXV0b2hlaWdodCwgLnN3aXBlci1jb250YWluZXItYXV0b2hlaWdodCAuc3dpcGVyLXNsaWRlIHtcbiAgICBoZWlnaHQ6IGF1dG87XG59XG4uc3dpcGVyLWNvbnRhaW5lci1hdXRvaGVpZ2h0IC5zd2lwZXItd3JhcHBlciB7XG4gICAgLXdlYmtpdC1ib3gtYWxpZ246IHN0YXJ0O1xuICAgIC1tcy1mbGV4LWFsaWduOiBzdGFydDtcbiAgICAtd2Via2l0LWFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1xuICAgIGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbi1wcm9wZXJ0eTogLXdlYmtpdC10cmFuc2Zvcm0sIGhlaWdodDtcbiAgICAtbW96LXRyYW5zaXRpb24tcHJvcGVydHk6IC1tb3otdHJhbnNmb3JtO1xuICAgIC1vLXRyYW5zaXRpb24tcHJvcGVydHk6IC1vLXRyYW5zZm9ybTtcbiAgICAtbXMtdHJhbnNpdGlvbi1wcm9wZXJ0eTogLW1zLXRyYW5zZm9ybTtcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiB0cmFuc2Zvcm0sIGhlaWdodDtcbn1cbi8qIGExMXkgKi9cbi5zd2lwZXItY29udGFpbmVyIC5zd2lwZXItbm90aWZpY2F0aW9uIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgb3BhY2l0eTogMDtcbiAgICB6LWluZGV4OiAtMTAwMDtcbn1cblxuLyogSUUxMCBXaW5kb3dzIFBob25lIDggRml4ZXMgKi9cbi5zd2lwZXItd3A4LWhvcml6b250YWwge1xuICAgIC1tcy10b3VjaC1hY3Rpb246IHBhbi15O1xuICAgIHRvdWNoLWFjdGlvbjogcGFuLXk7XG59XG4uc3dpcGVyLXdwOC12ZXJ0aWNhbCB7XG4gICAgLW1zLXRvdWNoLWFjdGlvbjogcGFuLXg7XG4gICAgdG91Y2gtYWN0aW9uOiBwYW4teDtcbn1cbi8qIEFycm93cyAqL1xuLnN3aXBlci1idXR0b24tcHJldiwgLnN3aXBlci1idXR0b24tbmV4dCB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogNTAlO1xuICAgIHdpZHRoOiAyN3B4O1xuICAgIGhlaWdodDogNDRweDtcbiAgICBtYXJnaW4tdG9wOiAtMjJweDtcbiAgICB6LWluZGV4OiAxMDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgLW1vei1iYWNrZ3JvdW5kLXNpemU6IDI3cHggNDRweDtcbiAgICAtd2Via2l0LWJhY2tncm91bmQtc2l6ZTogMjdweCA0NHB4O1xuICAgIGJhY2tncm91bmQtc2l6ZTogMjdweCA0NHB4O1xuICAgIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlcjtcbiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAgICYuc3dpcGVyLWJ1dHRvbi1kaXNhYmxlZCB7XG4gICAgICAgIG9wYWNpdHk6IDAuMzU7XG4gICAgICAgIGN1cnNvcjogYXV0bztcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgfVxufVxuLnN3aXBlci1idXR0b24tcHJldiwgLnN3aXBlci1jb250YWluZXItcnRsIC5zd2lwZXItYnV0dG9uLW5leHQge1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAyNyA0NCc+PHBhdGggZD0nTTAsMjJMMjIsMGwyLjEsMi4xTDQuMiwyMmwxOS45LDE5LjlMMjIsNDRMMCwyMkwwLDIyTDAsMjJ6JyBmaWxsPScjMDA3YWZmJy8+PC9zdmc+XCIpO1xuICAgIGxlZnQ6IDEwcHg7XG4gICAgcmlnaHQ6IGF1dG87XG59XG4uc3dpcGVyLWJ1dHRvbi1uZXh0LCAuc3dpcGVyLWNvbnRhaW5lci1ydGwgLnN3aXBlci1idXR0b24tcHJldiB7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoXCI8c3ZnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zycgdmlld0JveD0nMCAwIDI3IDQ0Jz48cGF0aCBkPSdNMjcsMjJMMjcsMjJMNSw0NGwtMi4xLTIuMUwyMi44LDIyTDIuOSwyLjFMNSwwTDI3LDIyTDI3LDIyeicgZmlsbD0nIzAwN2FmZicvPjwvc3ZnPlwiKTtcbiAgICByaWdodDogMTBweDtcbiAgICBsZWZ0OiBhdXRvO1xufVxuXG4vKiBQYWdpbmF0aW9uIFN0eWxlcyAqL1xuLnN3aXBlci1wYWdpbmF0aW9uIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbjogMzAwbXM7XG4gICAgLW1vei10cmFuc2l0aW9uOiAzMDBtcztcbiAgICAtby10cmFuc2l0aW9uOiAzMDBtcztcbiAgICB0cmFuc2l0aW9uOiAzMDBtcztcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIC1tcy10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAtby10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB6LWluZGV4OiAxMDtcbiAgICAmLnN3aXBlci1wYWdpbmF0aW9uLWhpZGRlbiB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxufVxuLyogQ29tbW9uIFN0eWxlcyAqL1xuLnN3aXBlci1wYWdpbmF0aW9uLWZyYWN0aW9uLCAuc3dpcGVyLXBhZ2luYXRpb24tY3VzdG9tLCAuc3dpcGVyLWNvbnRhaW5lci1ob3Jpem9udGFsID4gLnN3aXBlci1wYWdpbmF0aW9uLWJ1bGxldHN7XG4gICAgYm90dG9tOiAxMHB4O1xuICAgIGxlZnQ6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG59XG4vKiBCdWxsZXRzICovXG4uc3dpcGVyLXBhZ2luYXRpb24tYnVsbGV0IHtcbiAgICB3aWR0aDogOHB4O1xuICAgIGhlaWdodDogOHB4O1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBib3JkZXItcmFkaXVzOiAxMDAlO1xuICAgIGJhY2tncm91bmQ6ICMwMDA7XG4gICAgb3BhY2l0eTogMC4yO1xuICAgIGJ1dHRvbiYge1xuICAgICAgICBib3JkZXI6IG5vbmU7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICAgICAgLW1vei1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtbXMtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgIH1cbiAgICAuc3dpcGVyLXBhZ2luYXRpb24tY2xpY2thYmxlICYge1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxufVxuLnN3aXBlci1wYWdpbmF0aW9uLWJ1bGxldC1hY3RpdmUge1xuICAgIG9wYWNpdHk6IDE7XG4gICAgYmFja2dyb3VuZDogIzAwN2FmZjtcbn1cbi5zd2lwZXItY29udGFpbmVyLXZlcnRpY2FsIHtcbiAgICA+IC5zd2lwZXItcGFnaW5hdGlvbi1idWxsZXRzIHtcbiAgICAgICAgcmlnaHQ6IDEwcHg7XG4gICAgICAgIHRvcDogNTAlO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTp0cmFuc2xhdGUzZCgwcHgsLTUwJSwwKTtcbiAgICAgICAgLW1vei10cmFuc2Zvcm06dHJhbnNsYXRlM2QoMHB4LC01MCUsMCk7XG4gICAgICAgIC1vLXRyYW5zZm9ybTp0cmFuc2xhdGUoMHB4LC01MCUpO1xuICAgICAgICAtbXMtdHJhbnNmb3JtOnRyYW5zbGF0ZTNkKDBweCwtNTAlLDApO1xuICAgICAgICB0cmFuc2Zvcm06dHJhbnNsYXRlM2QoMHB4LC01MCUsMCk7XG4gICAgICAgIC5zd2lwZXItcGFnaW5hdGlvbi1idWxsZXQge1xuICAgICAgICAgICAgbWFyZ2luOiA1cHggMDtcbiAgICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB9XG4gICAgfVxufVxuLnN3aXBlci1jb250YWluZXItaG9yaXpvbnRhbCB7XG4gICAgPiAuc3dpcGVyLXBhZ2luYXRpb24tYnVsbGV0cyB7XG4gICAgICAgIC5zd2lwZXItcGFnaW5hdGlvbi1idWxsZXQge1xuICAgICAgICAgICAgbWFyZ2luOiAwIDVweDtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8qIFByb2dyZXNzICovXG4uc3dpcGVyLXBhZ2luYXRpb24tcHJvZ3Jlc3Mge1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwwLDAsMC4yNSk7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIC5zd2lwZXItcGFnaW5hdGlvbi1wcm9ncmVzc2JhciB7XG4gICAgICAgIGJhY2tncm91bmQ6ICMwMDdhZmY7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGUoMCk7XG4gICAgICAgIC1tcy10cmFuc2Zvcm06IHNjYWxlKDApO1xuICAgICAgICAtby10cmFuc2Zvcm06IHNjYWxlKDApO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlKDApO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IGxlZnQgdG9wO1xuICAgICAgICAtbW96LXRyYW5zZm9ybS1vcmlnaW46IGxlZnQgdG9wO1xuICAgICAgICAtbXMtdHJhbnNmb3JtLW9yaWdpbjogbGVmdCB0b3A7XG4gICAgICAgIC1vLXRyYW5zZm9ybS1vcmlnaW46IGxlZnQgdG9wO1xuICAgICAgICB0cmFuc2Zvcm0tb3JpZ2luOiBsZWZ0IHRvcDtcbiAgICB9XG4gICAgLnN3aXBlci1jb250YWluZXItcnRsICYgLnN3aXBlci1wYWdpbmF0aW9uLXByb2dyZXNzYmFyIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm0tb3JpZ2luOiByaWdodCB0b3A7XG4gICAgICAgIC1tb3otdHJhbnNmb3JtLW9yaWdpbjogcmlnaHQgdG9wO1xuICAgICAgICAtbXMtdHJhbnNmb3JtLW9yaWdpbjogcmlnaHQgdG9wO1xuICAgICAgICAtby10cmFuc2Zvcm0tb3JpZ2luOiByaWdodCB0b3A7XG4gICAgICAgIHRyYW5zZm9ybS1vcmlnaW46IHJpZ2h0IHRvcDtcbiAgICB9XG4gICAgLnN3aXBlci1jb250YWluZXItaG9yaXpvbnRhbCA+ICYge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiA0cHg7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICB9XG4gICAgLnN3aXBlci1jb250YWluZXItdmVydGljYWwgPiAmIHtcbiAgICAgICAgd2lkdGg6IDRweDtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBsZWZ0OiAwO1xuICAgICAgICB0b3A6IDA7XG4gICAgfVxufVxuLyogM0QgQ29udGFpbmVyICovXG4uc3dpcGVyLWNvbnRhaW5lci0zZCB7XG4gICAgLXdlYmtpdC1wZXJzcGVjdGl2ZTogMTIwMHB4O1xuICAgIC1tb3otcGVyc3BlY3RpdmU6IDEyMDBweDtcbiAgICAtby1wZXJzcGVjdGl2ZTogMTIwMHB4O1xuICAgIHBlcnNwZWN0aXZlOiAxMjAwcHg7XG4gICAgLnN3aXBlci13cmFwcGVyLCAuc3dpcGVyLXNsaWRlLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0LCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20sIC5zd2lwZXItY3ViZS1zaGFkb3cge1xuICAgICAgICAucHJlc2VydmUzZCgpO1xuICAgIH1cbiAgICAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0LCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20ge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICAgIHotaW5kZXg6IDEwO1xuICAgIH1cbiAgICAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0IHsgXG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgcmlnaHQgdG9wLCBmcm9tKHJnYmEoMCwwLDAsMC41KSksIHRvKHJnYmEoMCwwLDAsMCkpKTsgLyogU2FmYXJpIDQrLCBDaHJvbWUgKi9cbiAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogLXdlYmtpdC1saW5lYXItZ3JhZGllbnQocmlnaHQsIHJnYmEoMCwwLDAsMC41KSwgcmdiYSgwLDAsMCwwKSk7IC8qIENocm9tZSAxMCssIFNhZmFyaSA1LjErLCBpT1MgNSsgKi9cbiAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogICAgLW1vei1saW5lYXItZ3JhZGllbnQocmlnaHQsIHJnYmEoMCwwLDAsMC41KSwgcmdiYSgwLDAsMCwwKSk7IC8qIEZpcmVmb3ggMy42LTE1ICovXG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6ICAgICAgLW8tbGluZWFyLWdyYWRpZW50KHJpZ2h0LCByZ2JhKDAsMCwwLDAuNSksIHJnYmEoMCwwLDAsMCkpOyAvKiBPcGVyYSAxMS4xMC0xMi4wMCAqL1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiAgICAgICAgIGxpbmVhci1ncmFkaWVudCh0byBsZWZ0LCByZ2JhKDAsMCwwLDAuNSksIHJnYmEoMCwwLDAsMCkpOyAvKiBGaXJlZm94IDE2KywgSUUxMCwgT3BlcmEgMTIuNTArICovXG4gICAgfVxuICAgIC5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0IHsgICAgXG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCByaWdodCB0b3AsIGxlZnQgdG9wLCBmcm9tKHJnYmEoMCwwLDAsMC41KSksIHRvKHJnYmEoMCwwLDAsMCkpKTsgLyogU2FmYXJpIDQrLCBDaHJvbWUgKi9cbiAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogLXdlYmtpdC1saW5lYXItZ3JhZGllbnQobGVmdCwgcmdiYSgwLDAsMCwwLjUpLCByZ2JhKDAsMCwwLDApKTsgLyogQ2hyb21lIDEwKywgU2FmYXJpIDUuMSssIGlPUyA1KyAqL1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiAgICAtbW96LWxpbmVhci1ncmFkaWVudChsZWZ0LCByZ2JhKDAsMCwwLDAuNSksIHJnYmEoMCwwLDAsMCkpOyAvKiBGaXJlZm94IDMuNi0xNSAqL1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiAgICAgIC1vLWxpbmVhci1ncmFkaWVudChsZWZ0LCByZ2JhKDAsMCwwLDAuNSksIHJnYmEoMCwwLDAsMCkpOyAvKiBPcGVyYSAxMS4xMC0xMi4wMCAqL1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiAgICAgICAgIGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgcmdiYSgwLDAsMCwwLjUpLCByZ2JhKDAsMCwwLDApKTsgLyogRmlyZWZveCAxNissIElFMTAsIE9wZXJhIDEyLjUwKyAqLyAgXG4gICAgfVxuICAgIC5zd2lwZXItc2xpZGUtc2hhZG93LXRvcCB7ICBcbiAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogLXdlYmtpdC1ncmFkaWVudChsaW5lYXIsIGxlZnQgdG9wLCBsZWZ0IGJvdHRvbSwgZnJvbShyZ2JhKDAsMCwwLDAuNSkpLCB0byhyZ2JhKDAsMCwwLDApKSk7IC8qIFNhZmFyaSA0KywgQ2hyb21lICovXG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtbGluZWFyLWdyYWRpZW50KGJvdHRvbSwgcmdiYSgwLDAsMCwwLjUpLCByZ2JhKDAsMCwwLDApKTsgLyogQ2hyb21lIDEwKywgU2FmYXJpIDUuMSssIGlPUyA1KyAqL1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiAgICAtbW96LWxpbmVhci1ncmFkaWVudChib3R0b20sIHJnYmEoMCwwLDAsMC41KSwgcmdiYSgwLDAsMCwwKSk7IC8qIEZpcmVmb3ggMy42LTE1ICovXG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6ICAgICAgLW8tbGluZWFyLWdyYWRpZW50KGJvdHRvbSwgcmdiYSgwLDAsMCwwLjUpLCByZ2JhKDAsMCwwLDApKTsgLyogT3BlcmEgMTEuMTAtMTIuMDAgKi9cbiAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogICAgICAgICBsaW5lYXItZ3JhZGllbnQodG8gdG9wLCByZ2JhKDAsMCwwLDAuNSksIHJnYmEoMCwwLDAsMCkpOyAvKiBGaXJlZm94IDE2KywgSUUxMCwgT3BlcmEgMTIuNTArICovXG4gICAgfVxuICAgIC5zd2lwZXItc2xpZGUtc2hhZG93LWJvdHRvbSB7ICAgXG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IGJvdHRvbSwgbGVmdCB0b3AsIGZyb20ocmdiYSgwLDAsMCwwLjUpKSwgdG8ocmdiYSgwLDAsMCwwKSkpOyAvKiBTYWZhcmkgNCssIENocm9tZSAqL1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiAtd2Via2l0LWxpbmVhci1ncmFkaWVudCh0b3AsIHJnYmEoMCwwLDAsMC41KSwgcmdiYSgwLDAsMCwwKSk7IC8qIENocm9tZSAxMCssIFNhZmFyaSA1LjErLCBpT1MgNSsgKi9cbiAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogICAgLW1vei1saW5lYXItZ3JhZGllbnQodG9wLCByZ2JhKDAsMCwwLDAuNSksIHJnYmEoMCwwLDAsMCkpOyAvKiBGaXJlZm94IDMuNi0xNSAqL1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiAgICAgIC1vLWxpbmVhci1ncmFkaWVudCh0b3AsIHJnYmEoMCwwLDAsMC41KSwgcmdiYSgwLDAsMCwwKSk7IC8qIE9wZXJhIDExLjEwLTEyLjAwICovXG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6ICAgICAgICAgbGluZWFyLWdyYWRpZW50KHRvIGJvdHRvbSwgcmdiYSgwLDAsMCwwLjUpLCByZ2JhKDAsMCwwLDApKTsgLyogRmlyZWZveCAxNissIElFMTAsIE9wZXJhIDEyLjUwKyAqL1xuICAgIH1cbn1cbi8qIENvdmVyZmxvdyAqL1xuLnN3aXBlci1jb250YWluZXItY292ZXJmbG93LCAuc3dpcGVyLWNvbnRhaW5lci1mbGlwIHtcbiAgICAuc3dpcGVyLXdyYXBwZXIge1xuICAgICAgICAvKiBXaW5kb3dzIDggSUUgMTAgZml4ICovXG4gICAgICAgIC1tcy1wZXJzcGVjdGl2ZToxMjAwcHg7XG4gICAgfVxufVxuLyogQ3ViZSArIEZsaXAgKi9cbi5zd2lwZXItY29udGFpbmVyLWN1YmUsIC5zd2lwZXItY29udGFpbmVyLWZsaXAge1xuICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIC5zd2lwZXItc2xpZGUge1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgICAgLXdlYmtpdC1iYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgICAgIC1tb3otYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuO1xuICAgICAgICAtbXMtYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuO1xuICAgICAgICBiYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgICAgIHotaW5kZXg6IDE7XG4gICAgICAgIC5zd2lwZXItc2xpZGUge1xuICAgICAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLnN3aXBlci1zbGlkZS1hY3RpdmUge1xuICAgICAgICAmLCAmIC5zd2lwZXItc2xpZGUtYWN0aXZlIHtcbiAgICAgICAgICAgIHBvaW50ZXItZXZlbnRzOiBhdXRvO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5zd2lwZXItc2xpZGUtc2hhZG93LXRvcCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctYm90dG9tLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0LCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCB7XG4gICAgICAgIHotaW5kZXg6IDA7XG4gICAgICAgIC13ZWJraXQtYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuO1xuICAgICAgICAtbW96LWJhY2tmYWNlLXZpc2liaWxpdHk6IGhpZGRlbjtcbiAgICAgICAgLW1zLWJhY2tmYWNlLXZpc2liaWxpdHk6IGhpZGRlbjtcbiAgICAgICAgYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuO1xuICAgIH1cbn1cbi8qIEN1YmUgKi9cbi5zd2lwZXItY29udGFpbmVyLWN1YmUge1xuICAgIC5zd2lwZXItc2xpZGUge1xuICAgICAgICB2aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogMCAwO1xuICAgICAgICAtbW96LXRyYW5zZm9ybS1vcmlnaW46IDAgMDtcbiAgICAgICAgLW1zLXRyYW5zZm9ybS1vcmlnaW46IDAgMDtcbiAgICAgICAgdHJhbnNmb3JtLW9yaWdpbjogMCAwO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgIH1cbiAgICAmLnN3aXBlci1jb250YWluZXItcnRsIC5zd2lwZXItc2xpZGV7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogMTAwJSAwO1xuICAgICAgICAtbW96LXRyYW5zZm9ybS1vcmlnaW46IDEwMCUgMDtcbiAgICAgICAgLW1zLXRyYW5zZm9ybS1vcmlnaW46IDEwMCUgMDtcbiAgICAgICAgdHJhbnNmb3JtLW9yaWdpbjogMTAwJSAwO1xuICAgIH1cbiAgICAuc3dpcGVyLXNsaWRlLWFjdGl2ZSwgLnN3aXBlci1zbGlkZS1uZXh0LCAuc3dpcGVyLXNsaWRlLXByZXYsIC5zd2lwZXItc2xpZGUtbmV4dCArIC5zd2lwZXItc2xpZGUge1xuICAgICAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbiAgICAgICAgdmlzaWJpbGl0eTogdmlzaWJsZTtcbiAgICB9XG4gICAgLnN3aXBlci1jdWJlLXNoYWRvdyB7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgYm90dG9tOiAwcHg7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIGJhY2tncm91bmQ6ICMwMDA7XG4gICAgICAgIG9wYWNpdHk6IDAuNjtcbiAgICAgICAgLXdlYmtpdC1maWx0ZXI6IGJsdXIoNTBweCk7XG4gICAgICAgIGZpbHRlcjogYmx1cig1MHB4KTtcbiAgICAgICAgei1pbmRleDogMDtcbiAgICB9XG59XG4vKiBGYWRlICovXG4uc3dpcGVyLWNvbnRhaW5lci1mYWRlIHtcbiAgICAmLnN3aXBlci1jb250YWluZXItZnJlZS1tb2RlIHtcbiAgICAgICAgLnN3aXBlci1zbGlkZSB7XG4gICAgICAgICAgICAtd2Via2l0LXRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbiAgICAgICAgICAgIC1tb3otdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGVhc2Utb3V0O1xuICAgICAgICAgICAgLW1zLXRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbiAgICAgICAgICAgIC1vLXRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbiAgICAgICAgICAgIHRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAuc3dpcGVyLXNsaWRlIHtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICAgIC13ZWJraXQtdHJhbnNpdGlvbi1wcm9wZXJ0eTogb3BhY2l0eTtcbiAgICAgICAgLW1vei10cmFuc2l0aW9uLXByb3BlcnR5OiBvcGFjaXR5O1xuICAgICAgICAtby10cmFuc2l0aW9uLXByb3BlcnR5OiBvcGFjaXR5O1xuICAgICAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBvcGFjaXR5O1xuICAgICAgICAuc3dpcGVyLXNsaWRlIHtcbiAgICAgICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5zd2lwZXItc2xpZGUtYWN0aXZlIHtcbiAgICAgICAgJiwgJiAuc3dpcGVyLXNsaWRlLWFjdGl2ZSB7XG4gICAgICAgICAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbiAgICAgICAgfVxuICAgIH1cbn1cbi5zd2lwZXItem9vbS1jb250YWluZXIge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcblxuICAgIGRpc3BsYXk6IC13ZWJraXQtYm94O1xuICAgIGRpc3BsYXk6IC1tb3otYm94O1xuICAgIGRpc3BsYXk6IC1tcy1mbGV4Ym94O1xuICAgIGRpc3BsYXk6IC13ZWJraXQtZmxleDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuXG4gICAgLXdlYmtpdC1ib3gtcGFjazogY2VudGVyO1xuICAgIC1tb3otYm94LXBhY2s6IGNlbnRlcjtcbiAgICAtbXMtZmxleC1wYWNrOiBjZW50ZXI7XG4gICAgLXdlYmtpdC1qdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcblxuICAgIC13ZWJraXQtYm94LWFsaWduOiBjZW50ZXI7XG4gICAgLW1vei1ib3gtYWxpZ246IGNlbnRlcjtcbiAgICAtbXMtZmxleC1hbGlnbjogY2VudGVyO1xuICAgIC13ZWJraXQtYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgID4gaW1nLCA+IHN2ZywgPiBjYW52YXMge1xuICAgICAgICBtYXgtd2lkdGg6IDEwMCU7XG4gICAgICAgIG1heC1oZWlnaHQ6IDEwMCU7XG4gICAgICAgIG9iamVjdC1maXQ6IGNvbnRhaW47XG4gICAgfVxufVxuLyogU2Nyb2xsYmFyICovXG4uc3dpcGVyLXNjcm9sbGJhciB7XG4gICAgYm9yZGVyLXJhZGl1czogMTBweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgLW1zLXRvdWNoLWFjdGlvbjogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsMCwwLDAuMSk7XG4gICAgLnN3aXBlci1jb250YWluZXItaG9yaXpvbnRhbCA+ICYge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDElO1xuICAgICAgICBib3R0b206IDNweDtcbiAgICAgICAgei1pbmRleDogNTA7XG4gICAgICAgIGhlaWdodDogNXB4O1xuICAgICAgICB3aWR0aDogOTglO1xuICAgIH1cbiAgICAuc3dpcGVyLWNvbnRhaW5lci12ZXJ0aWNhbCA+ICYge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHJpZ2h0OiAzcHg7XG4gICAgICAgIHRvcDogMSU7XG4gICAgICAgIHotaW5kZXg6IDUwO1xuICAgICAgICB3aWR0aDogNXB4O1xuICAgICAgICBoZWlnaHQ6IDk4JTtcbiAgICB9XG59XG4uc3dpcGVyLXNjcm9sbGJhci1kcmFnIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwwLDAsMC41KTtcbiAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgIGxlZnQ6IDA7XG4gICAgdG9wOiAwO1xufVxuLnN3aXBlci1zY3JvbGxiYXItY3Vyc29yLWRyYWcge1xuICAgIGN1cnNvcjogbW92ZTtcbn1cbi8qIFByZWxvYWRlciAqL1xuLnN3aXBlci1zbGlkZSAucHJlbG9hZGVyIHtcbiAgICB3aWR0aDogNDJweDtcbiAgICBoZWlnaHQ6IDQycHg7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IDUwJTtcbiAgICB0b3A6IDUwJTtcbiAgICBtYXJnaW4tbGVmdDogLTIxcHg7XG4gICAgbWFyZ2luLXRvcDogLTIxcHg7XG4gICAgei1pbmRleDogMTA7XG59IiwiLyogPT09IENvbHVtbnMgUGlja2VyID09PSAqL1xuLnBpY2tlci1jb2x1bW5zIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDI2MHB4O1xuICAgIHotaW5kZXg6IDExNTAwO1xuICAgICYucGlja2VyLW1vZGFsLWlubGluZSwgLnBvcG92ZXIgJiB7XG4gICAgICAgIGhlaWdodDogMjAwcHg7XG4gICAgfVxuICAgIEBtZWRpYSAob3JpZW50YXRpb246IGxhbmRzY2FwZSkgYW5kIChtYXgtaGVpZ2h0OiA0MTVweCkge1xuICAgICAgICAmOm5vdCgucGlja2VyLW1vZGFsLWlubGluZSkge1xuICAgICAgICAgICAgaGVpZ2h0OiAyMDBweDtcbiAgICAgICAgfVxuICAgIH1cbn1cbi5wb3BvdmVyLnBvcG92ZXItcGlja2VyLWNvbHVtbnMge1xuICAgIHdpZHRoOiAyODBweDtcbn1cbi5waWNrZXItaXRlbXMge1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmp1c3RpZnktY29udGVudChjZW50ZXIpO1xuICAgIHBhZGRpbmc6IDA7XG4gICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgZm9udC1zaXplOiAyNHB4O1xuICAgIC13ZWJraXQtbWFzay1ib3gtaW1hZ2U6IC13ZWJraXQtbGluZWFyLWdyYWRpZW50KGJvdHRvbSwgdHJhbnNwYXJlbnQsIHRyYW5zcGFyZW50IDUlLCB3aGl0ZSAyMCUsIHdoaXRlIDgwJSwgdHJhbnNwYXJlbnQgOTUlLCB0cmFuc3BhcmVudCk7XG4gICAgLXdlYmtpdC1tYXNrLWJveC1pbWFnZTogbGluZWFyLWdyYWRpZW50KHRvIHRvcCwgdHJhbnNwYXJlbnQsIHRyYW5zcGFyZW50IDUlLCB3aGl0ZSAyMCUsIHdoaXRlIDgwJSwgdHJhbnNwYXJlbnQgOTUlLCB0cmFuc3BhcmVudCk7XG59XG4ucGlja2VyLWl0ZW1zLWNvbCB7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgbWF4LWhlaWdodDogMTAwJTtcblxuICAgICYucGlja2VyLWl0ZW1zLWNvbC1sZWZ0IHtcbiAgICAgICAgdGV4dC1hbGlnbjogbGVmdDtcbiAgICB9XG4gICAgJi5waWNrZXItaXRlbXMtY29sLWNlbnRlciB7XG4gICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB9XG4gICAgJi5waWNrZXItaXRlbXMtY29sLXJpZ2h0IHtcbiAgICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgfVxuICAgICYucGlja2VyLWl0ZW1zLWNvbC1kaXZpZGVyIHtcbiAgICAgICAgY29sb3I6IzAwMDtcbiAgICAgICAgLmZsZXhib3goKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgfVxufVxuLnBpY2tlci1pdGVtcy1jb2wtd3JhcHBlciB7XG4gICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgIFxuICAgIC13ZWJraXQtdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGVhc2Utb3V0O1xuICAgIHRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbn1cbi5waWNrZXItaXRlbSB7XG4gICAgaGVpZ2h0OiAzNnB4O1xuICAgIGxpbmUtaGVpZ2h0OiAzNnB4O1xuICAgIHBhZGRpbmc6IDAgMTBweDtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIGNvbG9yOiM3MDcyNzQ7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgLnBpY2tlci1pdGVtcy1jb2wtYWJzb2x1dGUgJntcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIH1cbiAgICAmLnBpY2tlci1pdGVtLWZhciB7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIH1cbiAgICAmLnBpY2tlci1zZWxlY3RlZCB7XG4gICAgICAgIGNvbG9yOiAjMDAwO1xuICAgICAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZTNkKDAsMCwwKSByb3RhdGVYKDBkZWcpKTtcbiAgICB9XG59XG4ucGlja2VyLWNlbnRlci1oaWdobGlnaHQge1xuICAgIGhlaWdodDogMzZweDtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHRvcDogNTAlO1xuICAgIG1hcmdpbi10b3A6IC0xOHB4O1xuICAgIC5oYWlybGluZSh0b3AsICNhOGFiYjApO1xuICAgIC5oYWlybGluZShib3R0b20sICNhOGFiYjApO1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuLy8gM0QgUGlja2VyXG4ucGlja2VyLTNkIHtcbiAgICAucGlja2VyLWl0ZW1zIHtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgLXdlYmtpdC1wZXJzcGVjdGl2ZTogMTIwMHB4O1xuICAgICAgICBwZXJzcGVjdGl2ZTogMTIwMHB4O1xuICAgIH1cbiAgICAucGlja2VyLWl0ZW1zLWNvbCwgLnBpY2tlci1pdGVtcy1jb2wtd3JhcHBlciwgLnBpY2tlci1pdGVtIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm0tc3R5bGU6IHByZXNlcnZlLTNkO1xuICAgICAgICB0cmFuc2Zvcm0tc3R5bGU6IHByZXNlcnZlLTNkO1xuICAgIH1cbiAgICAucGlja2VyLWl0ZW1zLWNvbCB7XG4gICAgICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIH1cbiAgICAucGlja2VyLWl0ZW0ge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IGNlbnRlciBjZW50ZXIgLTExMHB4O1xuICAgICAgICB0cmFuc2Zvcm0tb3JpZ2luOiBjZW50ZXIgY2VudGVyIC0xMTBweDtcbiAgICAgICAgLXdlYmtpdC1iYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgICAgIGJhY2tmYWNlLXZpc2liaWxpdHk6IGhpZGRlbjtcbiAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvbjogZWFzZS1vdXQ7XG4gICAgICAgIHRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbiAgICB9XG59IiwiLyogPT09IE5vdGlmaWNhdGlvbnMgPT09ICovXG5Abm90aWZpY2F0aW9uc0R1cmF0aW9uOiA0NTBtcztcbi5ub3RpZmljYXRpb25zIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgei1pbmRleDogMjAwMDA7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIG1hcmdpbjogMDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIG1heC1oZWlnaHQ6IDEwMCU7XG4gICAgLnRyYW5zaXRpb24oQG5vdGlmaWNhdGlvbnNEdXJhdGlvbik7XG4gICAgLXdlYmtpdC1wZXJzcGVjdGl2ZTogMTIwMHB4O1xuICAgIHBlcnNwZWN0aXZlOiAxMjAwcHg7XG4gICAgcGFkZGluZy10b3A6IDhweDtcbiAgICBwYWRkaW5nLWJvdHRvbTogOHB4O1xuICAgICYubGlzdC1ibG9jayA+IHVsIHtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgICAgIG1hcmdpbjogMCBhdXRvO1xuICAgICAgICBtYXgtd2lkdGg6IDU2OHB4ICsgMTZweDtcbiAgICB9XG4gICAgLndpdGgtc3RhdHVzYmFyLW92ZXJsYXkgJiB7XG4gICAgICAgIHBhZGRpbmctdG9wOiAyMHB4O1xuICAgICAgICAudHJhbnNsYXRlM2QoMCwgLTIwcHgsIDApO1xuICAgIH1cbiAgICAuaXRlbS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiA4cHg7XG4gICAgICAgIC5hbGlnbi1pdGVtcyhmbGV4LXN0YXJ0KTtcbiAgICB9XG4gICAgLml0ZW0tdGl0bGUtcm93IHtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogOHB4O1xuICAgICAgICAmOmJlZm9yZSB7XG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICBsZWZ0OiAwO1xuICAgICAgICAgICAgdG9wOiAwO1xuICAgICAgICAgICAgaGVpZ2h0OiAzNnB4O1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMTJweCAxMnB4IDAgMDtcbiAgICAgICAgICAgIHotaW5kZXg6IC0xO1xuICAgICAgICAgICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICAgICAgICAgIGNvbnRlbnQ6ICcnO1xuICAgICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tdGl0bGUge1xuICAgICAgICBmb250LXdlaWdodDogNDAwICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogMzZweDtcbiAgICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDM1cHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMTNweDtcbiAgICAgICAgaHRtbC5pb3MtZ3QtOCAmIHtcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA0MDAgIWltcG9ydGFudDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAuaXRlbS1zdWJ0aXRsZSB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTVweDtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICAgICAgaHRtbC5pb3MtZ3QtOCAmIHtcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tdGV4dCB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgY29sb3I6IGluaGVyaXQ7XG4gICAgICAgIGhlaWdodDogYXV0bztcbiAgICAgICAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7XG4gICAgfVxuICAgIC5pdGVtLXN1YnRpdGxlLCAuaXRlbS10ZXh0IHtcbiAgICAgICAgJjpmaXJzdC1jaGlsZCB7XG4gICAgICAgICAgICBtYXJnaW4tdG9wOiA4cHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tY29udGVudCwgLml0ZW0taW5uZXIge1xuICAgICAgICBtaW4taGVpZ2h0OiAwO1xuICAgIH1cbiAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgIHBvc2l0aW9uOiBzdGF0aWM7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICB9XG4gICAgLml0ZW0tbWVkaWEge1xuICAgICAgICB3aWR0aDogMjBweDtcbiAgICAgICAgaW1nIHtcbiAgICAgICAgICAgIG1heC13aWR0aDogMjBweDtcbiAgICAgICAgICAgIG1heC1oZWlnaHQ6IDIwcHg7XG4gICAgICAgIH1cbiAgICAgICAgaS5pY29uIHtcbiAgICAgICAgICAgIHdpZHRoOiAyMHB4O1xuICAgICAgICAgICAgaGVpZ2h0OiAyMHB4O1xuICAgICAgICAgICAgLXdlYmtpdC1iYWNrZ3JvdW5kLXNpemU6IGNvdmVyO1xuICAgICAgICAgICAgYmFja2dyb3VuZC1zaXplOiBjb3ZlcjtcbiAgICAgICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlcjtcbiAgICAgICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgICAgIH1cbiAgICAgICAgKyAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogOHB4O1xuICAgICAgICAgICAgb3ZlcmZsb3c6IHZpc2libGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGkubm90aWZpY2F0aW9uLWl0ZW0ge1xuICAgICAgICBib3gtc2hhZG93OiAwcHggMHB4IDEwcHggcmdiYSgwLDAsMCwwLjE1KTtcbiAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgcGFkZGluZy10b3A6IDA7XG4gICAgICAgIH1cbiAgICAgICAgLml0ZW0tbWVkaWEge1xuICAgICAgICAgICAgcGFkZGluZy10b3A6IDhweDtcbiAgICAgICAgfVxuXG4gICAgfVxuICAgIC5pdGVtLWFmdGVyIHtcbiAgICAgICAgbWFyZ2luLXRvcDogYXV0bztcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogYXV0bztcbiAgICB9XG4gICAgLmNsb3NlLW5vdGlmaWNhdGlvbiB7XG4gICAgICAgIHdpZHRoOiAyMnB4O1xuICAgICAgICBoZWlnaHQ6IDIycHg7XG4gICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB2aWV3Qm94PScwIDAgNDQgNDQnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PGcgc3Ryb2tlPSdub25lJyBzdHJva2Utd2lkdGg9JzEnIGZpbGw9J25vbmUnIGZpbGwtcnVsZT0nZXZlbm9kZCc+PHBhdGggZD0nTTIyLjUsMjAuMzc4Njc5NyBMMTQuNzIxODI1NCwxMi42MDA1MDUxIEwxMi42MDA1MDUxLDE0LjcyMTgyNTQgTDIwLjM3ODY3OTcsMjIuNSBMMTIuNjAwNTA1MSwzMC4yNzgxNzQ2IEwxNC43MjE4MjU0LDMyLjM5OTQ5NDkgTDIyLjUsMjQuNjIxMzIwMyBMMzAuMjc4MTc0NiwzMi4zOTk0OTQ5IEwzMi4zOTk0OTQ5LDMwLjI3ODE3NDYgTDI0LjYyMTMyMDMsMjIuNSBMMzIuMzk5NDk0OSwxNC43MjE4MjU0IEwzMC4yNzgxNzQ2LDEyLjYwMDUwNTEgTDIyLjUsMjAuMzc4Njc5NyBaIE0yMiw0NCBDMzQuMTUwMjY0NSw0NCA0NCwzNC4xNTAyNjQ1IDQ0LDIyIEM0NCw5Ljg0OTczNTUgMzQuMTUwMjY0NSwwIDIyLDAgQzkuODQ5NzM1NSwwIDAsOS44NDk3MzU1IDAsMjIgQzAsMzQuMTUwMjY0NSA5Ljg0OTczNTUsNDQgMjIsNDQgWicgZmlsbD0nIzAwMDAwMCc+PC9wYXRoPjwvZz48L3N2Zz5cIik7XG4gICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlciB0b3A7XG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgICAgIC13ZWJraXQtYmFja2dyb3VuZC1zaXplOiAxMDAlIGF1dG87XG4gICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTAwJSBhdXRvO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG9wYWNpdHk6IDAuMjtcbiAgICAgICAgc3BhbiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICB3aWR0aDogNDRweDtcbiAgICAgICAgICAgIGhlaWdodDogNDRweDtcbiAgICAgICAgICAgIGxlZnQ6IDUwJTtcbiAgICAgICAgICAgIHRvcDogNTAlO1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IC0yMnB4O1xuICAgICAgICAgICAgbWFyZ2luLXRvcDogLTIycHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLm5vdGlmaWNhdGlvbi1pdGVtIHtcbiAgICAgICAgbWF4LXdpZHRoOiA1NjhweDtcbiAgICAgICAgbWFyZ2luOiAwIGF1dG8gOHB4O1xuICAgICAgICAudHJhbnNpdGlvbihAbm90aWZpY2F0aW9uc0R1cmF0aW9uKTtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgyNTAsMjUwLDI1MCwwLjk1KTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMTJweDtcbiAgICAgICAgd2lkdGg6IH5cIi13ZWJraXQtY2FsYygxMDAlIC0gMTZweClcIjtcbiAgICAgICAgd2lkdGg6IH5cIi1tb3otY2FsYygxMDAlIC0gMTZweClcIjtcbiAgICAgICAgd2lkdGg6IH5cImNhbGMoMTAwJSAtIDE2cHgpXCI7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgbGVmdDogOHB4O1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgICY6bGFzdC1jaGlsZCB7XG4gICAgICAgICAgICBtYXJnaW4tYm90dG9tOiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5ub3RpZmljYXRpb24taGlkZGVuIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG59IiwiLyogPT09IERpc2FibGVkIGVsZW1lbnRzID09PSAqL1xuLmRpc2FibGVkLCBbZGlzYWJsZWRdIHtcbiAgICBvcGFjaXR5OiAwLjU1O1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIC5kaXNhYmxlZCAmLCBbZGlzYWJsZWRdICYge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn0iLCJAaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL19taXhpbnMubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9fY29sb3JzLXZhcnMubGVzcycpO1xuXG4vLyBDb2xvcnNcbkB0aGVtZUNvbG9yOiAjREY2NzM3OyAvLyAoMjIzLDEwMyw1NSlcblxuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9pbnRyby5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL2dyaWQubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy92aWV3cy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3BhZ2VzLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvdG9vbGJhcnMubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy90b29sYmFycy1wYWdlcy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3NlYXJjaGJhci5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL21lc3NhZ2ViYXIubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9pY29ucy5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvYmFkZ2VzLmxlc3MnKTtcbi8vQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9jaGlwcy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL2NvbnRlbnQtYmxvY2subGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9saXN0cy5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvY29udGFjdHMubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9mb3Jtcy5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvZmxvYXRpbmctYnV0dG9uLmxlc3MnKTtcbi8vQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9hY2NvcmRpb24ubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9jYXJkcy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL21vZGFscy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3BhbmVscy5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvbGF6eS1sb2FkLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvdGFicy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL21lc3NhZ2VzLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3Mvc3RhdHVzYmFyLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvcHJlbG9hZGVyLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvcHJvZ3Jlc3NiYXIubGVzcycpO1xuLy9AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3B1bGwtdG8tcmVmcmVzaC5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvaW5maW5pdGUtc2Nyb2xsLmxlc3MnKTtcbi8vQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9hdXRvY29tcGxldGUubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9zd2lwZXIubGVzcycpO1xuLy9AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL3Bob3RvLWJyb3dzZXIubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL2lvcy9waWNrZXIubGVzcycpO1xuLy9AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvaW9zL2NhbGVuZGFyLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3Mvbm90aWZpY2F0aW9ucy5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvbG9naW4tc2NyZWVuLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9pb3MvZGlzYWJsZWQubGVzcycpO1xuXG4vLyBEaXNhYmxlIHRleHQgc2VsZWN0XG4qIHtcbiAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbmlucHV0LCB0ZXh0YXJlYSB7XG4gIC13ZWJraXQtdG91Y2gtY2FsbG91dDpkZWZhdWx0O1xuICAtd2Via2l0LXVzZXItc2VsZWN0OnRleHQ7XG4gIHVzZXItc2VsZWN0OnRleHQ7XG59XG5cbi8vIE1haW4gVG9vbGJhclxuI2VkaXRvci1uYXZiYXIubmF2YmFyIC5yaWdodCBhICsgYSxcbiNlZGl0b3ItbmF2YmFyLm5hdmJhciAubGVmdCBhICsgYSB7XG4gIG1hcmdpbi1sZWZ0OiAwO1xuXG4gIGh0bWw6bm90KC5waG9uZSkgJiB7XG4gICAgbWFyZ2luLWxlZnQ6IDEwcHg7XG4gIH1cbn1cblxuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvX21peGlucy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9pb3MvX2NvbnRhaW5lci5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9pb3MvX2RhdGF2aWV3Lmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL2lvcy9fbGlzdHZpZXcubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvaW9zL19idXR0b24ubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvaW9zL19jb250ZXh0bWVudS5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9pb3MvX2NvbG9yLXBhbGV0dGUubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvaW9zL19hYm91dC5sZXNzJyk7XG5cbkBpbXBvcnQgdXJsKCdpb3MvX3NlYXJjaC5sZXNzJyk7XG5AaW1wb3J0IHVybCgnaW9zL19pY29ucy5sZXNzJyk7XG5cbi8vIFRvcCBvZmZzZXRcblxuI2VkaXRvcl9zZGsge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGxlZnQ6IDA7XG4gIHJpZ2h0OiAwO1xuICB0b3A6IEB0b29sYmFyU2l6ZTtcbiAgYm90dG9tOiAwO1xuICBoZWlnaHQ6IGF1dG87XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIC50cmFuc2l0aW9uKDMwMG1zKTtcbn1cblxuLy8gQWRkIENvbnRhaW5lclxuXG4jYWRkLXRhYmxlLFxuI2FkZC1zaGFwZSB7XG4gIC5wYWdlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICB9XG59XG5cbi8vIFRhYmxlIHN0eWxlc1xuXG4udGFibGUtc3R5bGVzIHtcbiAgLnJvdyB7XG4gICAgJiwgbGkge1xuICAgICAgbWFyZ2luLWJvdHRvbTogMTJweDtcbiAgICB9XG4gIH1cblxuICBsaSB7XG4gICAgbWFyZ2luOiAwO1xuICAgIHBhZGRpbmc6IDFweDtcblxuICAgIGltZyB7XG4gICAgICB3aWR0aDogNzBweDtcbiAgICAgIGhlaWdodDogNTBweDtcbiAgICB9XG4gIH1cbn1cblxuLy8gU2hhcGVzXG5cbi5zaGFwZXMge1xuICBsaSB7XG4gICAgd2lkdGg6IDcwcHg7XG4gICAgaGVpZ2h0OiA3MHB4O1xuICAgIG1hcmdpbjogMCAxcHg7XG5cbiAgICAudGh1bWIge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAdGhlbWVDb2xvcjtcbiAgICB9XG4gIH1cbn1cblxuLy8gQnVsbGV0cyBhbmQgbnVtYmVyc1xuXG4uYnVsbGV0cyxcbi5udW1iZXJzIHtcbiAgdWwge1xuICAgIG1hcmdpbi10b3A6IDEwcHg7XG4gIH1cblxuICBsaSB7XG4gICAgd2lkdGg6IDcwcHg7XG4gICAgaGVpZ2h0OiA3MHB4O1xuICAgIG1hcmdpbi1yaWdodDogMXB4O1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNjNGM0YzQ7XG4gICAgaHRtbC5waXhlbC1yYXRpby0yICYge1xuICAgICAgYm9yZGVyOiAwLjVweCBzb2xpZCAjYzRjNGM0O1xuICAgIH1cbiAgICBodG1sLnBpeGVsLXJhdGlvLTMgJiB7XG4gICAgICBib3JkZXI6IDAuMzNweCBzb2xpZCAjYzRjNGM0O1xuICAgIH1cblxuICAgICYuYWN0aXZlIHtcbiAgICAgIC8vXG4gICAgfVxuXG4gICAgLnRodW1iIHtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogQHdoaXRlO1xuICAgICAgYmFja2dyb3VuZC1zaXplOiBjb3ZlcjtcblxuICAgICAgbGFiZWwge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHRvcDogMzQlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBTbGlkZSBsYXlvdXRcblxuLnNsaWRlLWxheW91dCB7XG4gIC5yb3cge1xuICAgICAgbWFyZ2luLWJvdHRvbTogMTJweDtcbiAgfVxuXG4gIGxpIHtcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMXB4O1xuXG4gICAgaW1nIHtcbiAgICAgIGJveC1zaGFkb3c6IDAgMCAwIDFweCByZ2JhKDAsMCwwLDAuMTUpO1xuICAgIH1cbiAgfVxufVxuXG4vLyBTbGlkZSB0aGVtZVxuXG4uc2xpZGUtdGhlbWUge1xuICAucm93IHtcbiAgICBtYXJnaW4tdG9wOiAxNHB4O1xuICAgIG1hcmdpbi1ib3R0b206IDEycHg7XG5cbiAgICBkaXYge1xuICAgICAgbWFyZ2luOiAwO1xuICAgICAgcGFkZGluZzogM3B4O1xuICAgICAgYm94LXNoYWRvdzogMCAwIDAgMXB4IHJnYmEoMCwwLDAsMC4xNSk7XG4gICAgICB3aWR0aDogODVweDtcbiAgICAgIGhlaWdodDogMzhweDtcbiAgICB9XG4gIH1cbn1cblxuLy8gQ2hhcnRzXG5cbi5jaGFydC10eXBlcyB7XG4gIGxpIHtcbiAgICB3aWR0aDogNjBweDtcbiAgICBoZWlnaHQ6IDYwcHg7XG4gICAgbWFyZ2luOiA2cHg7XG5cbiAgICAudGh1bWIge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICBiYWNrZ3JvdW5kLXNpemU6IGNvbnRhaW47XG4gICAgfVxuICB9XG59XG5cbi8vIFdvcmthcm91bmQgaW9zIDEwLjNcblxuLnJhbmdlLXNsaWRlciBpbnB1dFt0eXBlPXJhbmdlXTo6LXdlYmtpdC1zbGlkZXItdGh1bWIge1xuICBoZWlnaHQ6IDI4cHg7XG4gIHdpZHRoOiAyOHB4O1xuICBib3JkZXItcmFkaXVzOiAyOHB4O1xuICBiYWNrZ3JvdW5kOiAjZmZmO1xuICBib3gtc2hhZG93OiAwIDJweCA0cHggcmdiYSgwLDAsMCwwLjQpO1xuICB6LWluZGV4OiAxMDtcbiAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xufSIsIi8vIENvbnRhaW5lclxuLnBob25lLmlvcyB7XG4gIC5jb250YWluZXItZWRpdCB7XG4gICAgLm5hdmJhciB7XG4gICAgICAuaGFpcmxpbmUodG9wLCBAdG9vbGJhckJvcmRlckNvbG9yKTtcbiAgICB9XG5cbiAgICAucGFnZS1jb250ZW50IHtcbiAgICAgIC5saXN0LWJsb2NrOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgbWFyZ2luLXRvcDogLTFweDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLmNvbnRhaW5lci1lZGl0LFxuLmNvbnRhaW5lci1hZGQsXG4uY29udGFpbmVyLXNldHRpbmdzIHtcbiAgJi5wb3BvdmVyIHtcbiAgICB3aWR0aDogMzYwcHg7XG4gIH1cbn1cblxuLnNldHRpbmdzIHtcbiAgJi5wb3B1cCxcbiAgJi5wb3BvdmVyIHtcbiAgICAubGlzdC1ibG9jayB7XG5cbiAgICAgIHVsIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMCAhaW1wb3J0YW50O1xuICAgICAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuXG4gICAgICAgICY6bGFzdC1jaGlsZCB7XG4gICAgICAgICAgLmhhaXJsaW5lKGJvdHRvbSwgQGxpc3RCbG9ja0JvcmRlckNvbG9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAmOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgbWFyZ2luLXRvcDogMDtcbiAgICAgIH1cblxuICAgICAgJjpsYXN0LWNoaWxkIHtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMzBweDtcbiAgICAgIH1cblxuICAgICAgbGk6Zmlyc3QtY2hpbGQgYSxcbiAgICAgIGxpOmxhc3QtY2hpbGQgYSB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDAgIWltcG9ydGFudDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAmLFxuICAgIC5wb3BvdmVyLWlubmVyIHtcbiAgICAgID4gLmNvbnRlbnQtYmxvY2sge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICAgIGNvbG9yOiAjMDAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIC5wb3BvdmVyLXZpZXcge1xuICAgICAgYm9yZGVyLXJhZGl1czogMTNweDtcblxuICAgICAgPiAucGFnZXMge1xuICAgICAgICBib3JkZXItcmFkaXVzOiAxM3B4O1xuICAgICAgfVxuICAgIH1cblxuICAgIC5jb250ZW50LWJsb2NrOmZpcnN0LWNoaWxkIHtcbiAgICAgIG1hcmdpbi10b3A6IDA7XG4gICAgICAuY29udGVudC1ibG9jay1pbm5lciB7XG4gICAgICAgICY6YmVmb3JlIHtcbiAgICAgICAgICBoZWlnaHQ6IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAuY2F0ZWdvcmllcyB7XG4gICAgd2lkdGg6IDEwMCU7XG5cbiAgICA+IC5idXR0b25zLXJvdyB7XG4gICAgICB3aWR0aDogMTAwJTtcblxuICAgICAgLmJ1dHRvbiB7XG4gICAgICAgIHBhZGRpbmc6IDAgMXB4O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC5wb3BvdmVyLWlubmVyIHtcbiAgICBoZWlnaHQ6IDQwMHB4O1xuICB9XG59IiwiLy8gRGF0YSB2aWV3XG5cbi5kYXRhdmlldyB7XG4gICYucGFnZS1jb250ZW50IHtcbiAgICBiYWNrZ3JvdW5kOiBAd2hpdGU7XG4gIH1cblxuICAucm93IHtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWFyb3VuZDtcbiAgfVxuXG4gIHVsIHtcbiAgICBwYWRkaW5nOiAwIDEwcHg7XG4gICAgbGlzdC1zdHlsZTogbm9uZTtcblxuICAgIGxpIHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICB9XG4gIH1cblxuICAuYWN0aXZlIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgei1pbmRleDogMTtcblxuICAgICY6OmFmdGVyIHtcbiAgICAgIGNvbnRlbnQ6ICcnO1xuICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgd2lkdGg6IDIycHg7XG4gICAgICBoZWlnaHQ6IDIycHg7XG4gICAgICByaWdodDogLTVweDtcbiAgICAgIGJvdHRvbTogLTVweDtcbiAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PGNpcmNsZSBmaWxsPVwiI2ZmZlwiIGN4PVwiMTFcIiBjeT1cIjExXCIgcj1cIjExXCIvPjxwYXRoIGQ9XCJNMTEsMjFBMTAsMTAsMCwxLDEsMjEsMTEsMTAsMTAsMCwwLDEsMTEsMjFoMFpNMTcuNCw3LjMyTDE3LjA2LDdhMC40OCwwLjQ4LDAsMCwwLS42NywwbC03LDYuODRMNi45NSwxMS4yNGEwLjUxLDAuNTEsMCwwLDAtLjU5LjA4TDYsMTEuNjZhMC41OCwwLjU4LDAsMCwwLDAsLjY1bDMuMTksMy4zNWEwLjM4LDAuMzgsMCwwLDAsLjM5LDBMMTcuNCw4YTAuNDgsMC40OCwwLDAsMCwwLS42N2gwWlwiLz48L2c+PC9zdmc+Jyk7XG4gICAgfVxuICB9XG59IiwiLy8gTGlzdCBleHRlbmRcblxuLml0ZW0tY29udGVudCB7XG4gIC5pdGVtLWFmdGVyIHtcbiAgICAmLnNwbGl0dGVyIHtcbiAgICAgIGNvbG9yOiAjMDAwO1xuXG4gICAgICBsYWJlbCB7XG4gICAgICAgIG1hcmdpbjogMCA1cHg7XG4gICAgICB9XG5cbiAgICAgIC5idXR0b25zLXJvdyB7XG4gICAgICAgIG1pbi13aWR0aDogOTBweDtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDEwcHg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgJi52YWx1ZSB7XG4gICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIG1pbi13aWR0aDogNjBweDtcbiAgICAgIGNvbG9yOiBAYmxhY2s7XG4gICAgICBtYXJnaW4tbGVmdDogMTBweDtcbiAgICAgIHRleHQtYWxpZ246IHJpZ2h0O1xuICAgIH1cblxuICAgIGlucHV0LmZpZWxkIHtcbiAgICAgIGNvbG9yOiBAdGhlbWVDb2xvcjtcblxuICAgICAgJi5wbGFjZWhvbGRlci1jb2xvcjo6LXdlYmtpdC1pbnB1dC1wbGFjZWhvbGRlciB7XG4gICAgICAgIGNvbG9yOiBAdGhlbWVDb2xvcjtcbiAgICAgIH1cblxuICAgICAgJi5yaWdodCB7XG4gICAgICAgIHRleHQtYWxpZ246IHJpZ2h0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gICYuYnV0dG9ucyB7XG4gICAgLml0ZW0taW5uZXIge1xuICAgICAgcGFkZGluZy10b3A6IDA7XG4gICAgICBwYWRkaW5nLWJvdHRvbTogMDtcbiAgICAgIGFsaWduLWl0ZW1zOiBzdHJldGNoO1xuXG4gICAgICA+IC5yb3cge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgYWxpZ24taXRlbXM6IHN0cmV0Y2g7XG5cbiAgICAgICAgLmJ1dHRvbiB7XG4gICAgICAgICAgZmxleDogMTtcbiAgICAgICAgICBib3JkZXI6IG5vbmU7XG4gICAgICAgICAgaGVpZ2h0OiBpbmhlcml0O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgICAgICAgZm9udC1zaXplOiAxN3B4O1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC5pdGVtLWFmdGVyIC5jb2xvci1wcmV2aWV3IHtcbiAgICB3aWR0aDogNzVweDtcbiAgICBoZWlnaHQ6IDMwcHg7XG4gICAgbWFyZ2luLXRvcDogLTNweDtcbiAgICBib3gtc2hhZG93OiAwIDAgMCAxcHggcmdiYSgwLDAsMCwwLjE1KSBpbnNldDtcbiAgfVxuXG4gIGkgLmNvbG9yLXByZXZpZXcge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogOHB4O1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBtYXJnaW4tdG9wOiAyMXB4O1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgYm94LXNoYWRvdzogMCAwIDAgMXB4IHJnYmEoMCwwLDAsMC4xNSkgaW5zZXQ7XG4gIH1cbn1cblxuLml0ZW0tbGluayB7XG4gICYubm8taW5kaWNhdG9yIHtcbiAgICAuaXRlbS1pbm5lciB7XG4gICAgICBiYWNrZ3JvdW5kLWltYWdlOiBub25lO1xuICAgICAgcGFkZGluZy1yaWdodDogMTVweDtcbiAgICB9XG4gIH1cbn1cblxuLmxpc3QtYmxvY2sge1xuICAuaXRlbS1saW5rLmxpc3QtYnV0dG9uIHtcbiAgICBjb2xvcjogQHRoZW1lQ29sb3I7XG4gIH1cbn0iLCIvLyBBY3RpdmUgYnV0dG9uIGljb24gY29sb3Jcbi5idXR0b24ge1xuICAmLmFjdGl2ZSB7XG4gICAgaS5pY29uIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gICAgfVxuICB9XG59IiwiLy8gQ29udGV4dCBtZW51XG5cbi5kb2N1bWVudC1tZW51IHtcbiAgQGNvbnRleHRNZW51Qmc6IHJnYmEoMCwwLDAsMC45KTtcbiAgQG1vZGFsSGFpcmxpbmVDb2xvcjogcmdiYSgyMzAsMjMwLDIzMCwwLjkpO1xuICBAbW9kYWxCdXR0b25Db2xvciA6IHJnYmEoMjAwLDIwMCwyMDAsMC45KTtcblxuICBiYWNrZ3JvdW5kLWNvbG9yOiBAY29udGV4dE1lbnVCZztcbiAgd2lkdGg6IGF1dG87XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgei1pbmRleDogMTI1MDA7XG5cbiAgLnBvcG92ZXItYW5nbGUge1xuICAgICY6YWZ0ZXIge1xuICAgICAgYmFja2dyb3VuZDogQGNvbnRleHRNZW51Qmc7XG4gICAgfVxuICB9XG5cbiAgLmxpc3QtYmxvY2sge1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICB3aGl0ZS1zcGFjZTogcHJlO1xuXG4gICAgJjpmaXJzdC1jaGlsZCB7XG4gICAgICB1bCB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUobGVmdCk7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDdweCAwIDAgN3B4O1xuICAgICAgfVxuICAgICAgbGk6Zmlyc3QtY2hpbGQgYXtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogN3B4IDAgMCA3cHg7XG4gICAgICB9XG4gICAgfVxuICAgICY6bGFzdC1jaGlsZCB7XG4gICAgICB1bCB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUocmlnaHQpO1xuICAgICAgICBib3JkZXItcmFkaXVzOiAwIDdweCA3cHggMDtcbiAgICAgIH1cbiAgICAgIGxpOmxhc3QtY2hpbGQgYXtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMCA3cHggN3B4IDA7XG4gICAgICB9XG4gICAgfVxuICAgICY6Zmlyc3QtY2hpbGQ6bGFzdC1jaGlsZCB7XG4gICAgICBsaTpmaXJzdC1jaGlsZDpsYXN0LWNoaWxkIGEsIHVsOmZpcnN0LWNoaWxkOmxhc3QtY2hpbGQge1xuICAgICAgICBib3JkZXItcmFkaXVzOiA3cHg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLml0ZW0tbGluayB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG5cbiAgICAgIGh0bWw6bm90KC53YXRjaC1hY3RpdmUtc3RhdGUpICY6YWN0aXZlLCAmLmFjdGl2ZS1zdGF0ZSB7XG4gICAgICAgIC8vLnRyYW5zaXRpb24oMG1zKTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2Q5ZDlkOTtcbiAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgIC5oYWlybGluZS1jb2xvcihyaWdodCwgdHJhbnNwYXJlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGh0bWwucGhvbmUgJiB7XG4gICAgICAgIHBhZGRpbmc6IDAgMTBweDtcbiAgICAgIH1cblxuICAgICAgJi5saXN0LWJ1dHRvbiB7XG4gICAgICAgIGNvbG9yOiBAd2hpdGU7XG4gICAgICAgIC5oYWlybGluZShyaWdodCwgQG1vZGFsSGFpcmxpbmVDb2xvcik7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiAzNnB4O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIExpc3QgaXRlbXNcbiAgICBsaSB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgfVxuXG4gICAgLy8gTGFzdC1jaGlsZHNcbiAgICBsaSB7XG4gICAgICAmOmxhc3QtY2hpbGQge1xuICAgICAgICAubGlzdC1idXR0b24ge1xuICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUocmlnaHQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAmOmxhc3QtY2hpbGQsICY6bGFzdC1jaGlsZCBsaTpsYXN0LWNoaWxkIHtcbiAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUocmlnaHQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBsaTpsYXN0LWNoaWxkLCAmOmxhc3QtY2hpbGQgbGkge1xuICAgICAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgLmhhaXJsaW5lKHJpZ2h0LCBAbW9kYWxIYWlybGluZUNvbG9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAubm8taGFpcmxpbmVzKCk7XG4gICAgLm5vLWhhaXJsaW5lcy1iZXR3ZWVuKClcbiAgfVxufSIsIi8vIENvbG9yIHBhbGV0dGVcblxuLmNvbG9yLXBhbGV0dGUge1xuICBhIHtcbiAgICBmbGV4LWdyb3c6IDE7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG1pbi13aWR0aDogMTBweDtcbiAgICBtaW4taGVpZ2h0OiAyNnB4O1xuICAgIG1hcmdpbjogMXB4IDFweCAwIDA7XG4gICAgYm94LXNoYWRvdzogMCAwIDAgMXB4IHJnYmEoMCwwLDAsMC4xNSkgaW5zZXQ7XG5cbiAgICAmLmFjdGl2ZSB7XG4gICAgICAmOmFmdGVyIHtcbiAgICAgICAgY29udGVudDonICc7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgYm94LXNoYWRvdzogMCAwIDAgMXB4IHdoaXRlLCAwIDAgMCA0cHggQHRoZW1lQ29sb3I7XG4gICAgICAgIHotaW5kZXg6IDE7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDFweDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAmLnRyYW5zcGFyZW50IHtcbiAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgICBiYWNrZ3JvdW5kLXNpemU6IDEwMCUgMTAwJTtcbiAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHg9JzBweCcgeT0nMHB4JyB2aWV3Qm94PScwIDAgMjIgMjInIHhtbDpzcGFjZT0ncHJlc2VydmUnPjxsaW5lIHN0cm9rZT0nI2ZmMDAwMCcgc3Ryb2tlLWxpbmVjYXA9J3VuZGVmaW5lZCcgc3Ryb2tlLWxpbmVqb2luPSd1bmRlZmluZWQnIGlkPSdzdmdfMScgeTI9JzAnIHgyPScyMicgeTE9JzIyJyB4MT0nMCcgc3Ryb2tlLXdpZHRoPScyJyBmaWxsPSdub25lJy8+PC9zdmc+XCIpO1xuICAgIH1cbiAgfVxuXG4gIC50aGVtZS1jb2xvcnMge1xuICAgIC5pdGVtLWlubmVyIHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIH1cbiAgfVxuXG4gIC5zdGFuZGFydC1jb2xvcnMge1xuICAgIC5pdGVtLWlubmVyIHtcbiAgICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIH1cbiAgfVxufSIsIi8vIEFib3V0XG4uYWJvdXQge1xuICAucGFnZS1jb250ZW50IHtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIH1cblxuICAuY29udGVudC1ibG9jazpmaXJzdC1jaGlsZCB7XG4gICAgbWFyZ2luOiAxNXB4IDA7XG4gIH1cblxuICAuY29udGVudC1ibG9jayB7XG4gICAgbWFyZ2luOiAwIGF1dG8gMTVweDtcblxuICAgIGEge1xuICAgICAgY29sb3I6ICMwMDA7XG4gICAgfVxuICB9XG5cbiAgaDMge1xuICAgIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gICAgbWFyZ2luOiAwO1xuXG4gICAgJi52ZW5kb3Ige1xuICAgICAgY29sb3I6ICMwMDA7XG4gICAgICBmb250LXdlaWdodDogYm9sZDtcbiAgICAgIG1hcmdpbi10b3A6IDE1cHg7XG4gICAgfVxuICB9XG5cbiAgcCA+IGxhYmVsIHtcbiAgICBtYXJnaW4tcmlnaHQ6IDVweDtcbiAgfVxuXG4gIC5sb2dvIHtcbiAgICBiYWNrZ3JvdW5kOiB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2ltZy9hYm91dC9vbmx5b2ZmaWNlLnN2ZycpIG5vLXJlcGVhdCBjZW50ZXI7XG4gICAgbWFyZ2luLXRvcDogMjBweDtcbiAgfVxufSIsIi8vIFNlYXJjaFxuXG4udGFibGV0IHtcbiAgLnNlYXJjaGJhci5kb2N1bWVudCB7XG4gICAgLmNlbnRlciB7XG4gICAgICB3aWR0aDogMTAwJTtcblxuICAgICAgLnNlYXJjaGJhciB7XG4gICAgICAgIGJhY2tncm91bmQ6IGluaGVyaXQ7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLnJpZ2h0IHtcbiAgICAgIC5wcmV2IHtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi5waG9uZSB7XG4gIC5zZWFyY2hiYXIuZG9jdW1lbnQge1xuICAgIC5sZWZ0LFxuICAgIC5jZW50ZXIsXG4gICAgLnJpZ2h0IHtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuXG4gICAgLmNlbnRlciB7XG4gICAgICB3aWR0aDogMTAwJTtcblxuICAgICAgLnNlYXJjaGJhciB7XG4gICAgICAgIGJhY2tncm91bmQ6IGluaGVyaXQ7XG4gICAgICAgIHBhZGRpbmc6IDA7XG5cbiAgICAgICAgJjphZnRlciB7XG4gICAgICAgICAgY29udGVudDogbm9uZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC5yaWdodCB7XG4gICAgICA+IHAge1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi5zZWFyY2hiYXIuZG9jdW1lbnQge1xuICBiYWNrZ3JvdW5kOiBsaWdodGVuKEBzZWFyY2hiYXJCZywgMTAlKTtcbn0iLCIvLyBJY29uc1xuaS5pY29uIHtcbiAgJi5pY29uLXNlYXJjaCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTE1LjgsMTVjMS40LTEuNiwyLjItMy43LDIuMi01LjljMC01LTQtOS05LTlDNCwwLDAsNCwwLDljMCw1LDQsOSw5LDljMi4zLDAsNC40LTAuOSw1LjktMi4ybDUuOCw1LjhsMC4yLTAuNmwwLjctMC4yTDE1LjgsMTV6IE05LDE3Yy00LjQsMC04LTMuNi04LThjMC00LjQsMy42LTgsOC04YzQuNCwwLDgsMy42LDgsOEMxNywxMy41LDEzLjUsMTcsOSwxN3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1idXJnZXIge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHJlY3QgeD1cIjJcIiB5PVwiMTdcIiB3aWR0aD1cIjE4XCIgaGVpZ2h0PVwiMVwiLz48cmVjdCB4PVwiMlwiIHk9XCIxM1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxXCIvPjxyZWN0IHg9XCIyXCIgeT1cIjlcIiB3aWR0aD1cIjE4XCIgaGVpZ2h0PVwiMVwiLz48cmVjdCB4PVwiMlwiIHk9XCI1XCIgd2lkdGg9XCIxOFwiIGhlaWdodD1cIjFcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1lZGl0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMCwyMGgyMnYxSDBWMjB6XCIvPjxwb2x5Z29uIHBvaW50cz1cIjE5LjMsNS4zIDYuMSwxOC40IDQuNiwxNi45IDE3LjgsMy44IDE3LjEsMy4xIDMuNSwxNi43IDMsMjAgNi4zLDE5LjUgMTkuOSw1LjkgXHRcIi8+PHBhdGggZD1cIk0yMC41LDUuM0wyMiwzLjhjMCwwLTAuMi0xLjItMC45LTEuOUMyMC40LDEuMSwxOS4yLDEsMTkuMiwxbC0xLjUsMS41TDIwLjUsNS4zelwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXBsYXkge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk00LjA0NjQzNjMsMi45ODg0NTUzYzAuMDA2NTI2LDAuMDAyOTYsMC4wMTQyMzQ1LDAuMDA2ODM1LDAuMDIzMTQzOCwwLjAxMTkwMjEgYzAuNTkwODYwNCwwLjMzNTc2MzcsMTIuNzExODM5Nyw3LjI5MjQ0MzMsMTMuODk3NzQ4OSw4LjAyNjg0MDJjLTAuNTgzMTU4NSwwLjM0MTc3NTktMTMuMDEzNzU4Nyw3LjQ4NzkyNzQtMTMuOTM0NjU5LDcuOTgyNjcyNyBMNC4wNDY0MzYzLDIuOTg4NDU1MyBNMy45ODg5MzU3LDJDMy40NDI3Nzk1LDIuMDAwMDU3NywzLjAwMDUyNSwyLjQ1MzM1NzUsMy4wMDA1MjUsMy4wMTUzNDhcdGMwLDAuNTczNDg3LDAsMTUuMTYzMjk1NywwLDE1Ljk5NDUyMjFDMy4wMDA1MjUsMTkuNjIyOTYzLDMuNDc5NjEwNCwyMCwzLjk5NDA1ODgsMjAgYzAuMTcyOTM3MiwwLDAuMzQ5OTE5MS0wLjA0MjYzMTEsMC41MTM5NzYzLTAuMTMzMjIyNmMwLjg5MDU2MDItMC40OTEwNDUsMTMuMTg4MDg5NC03LjU1ODMzNzIsMTMuOTQwNzM4Ny03Ljk5OTQ0NTkgYzAuNjc1MTIxMy0wLjM5NTUyMDIsMC42ODY3MzEzLTEuMzM3NTEyLDAtMS43MzI2NjAzQzE3LjQwMzE3NTQsOS41MzMzMjcxLDUuMTUyMzg1MiwyLjUwMTg1Miw0LjUzOTM5NTMsMi4xNTM1MTY1IEM0LjM1MjYyMDEsMi4wNDcyNzk0LDQuMTY1NDAxLDEuOTk5OTgxMywzLjk4ODkzNTcsMkwzLjk4ODkzNTcsMnpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi11bmRvIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMjIsMTZ2MmgtMXYtMmwwLDBjMC0yLjktMi4xLTUtNS01bDAsMEgxLjlMNSwxNGMwLjEsMC4xLDAuMSwwLjIsMCwwLjNsLTAuNCwwLjRjLTAuMSwwLjEtMC4yLDAuMS0wLjMsMGwtNC4yLTQuMmMtMC4xLTAuMS0wLjEtMC4yLDAtMC4zbDAuNC0wLjRoMC4xTDQuNCw2YzAuMS0wLjEsMC4yLTAuMSwwLjMsMGwwLjUsMC40YzAuMSwwLjEsMC4xLDAuMiwwLDAuM0wxLjksMTBIMTZsMCwwQzE5LjMsMTAsMjIsMTIuNywyMiwxNkwyMiwxNnpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1yZWRvIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMCwxNmMwLTMuMywyLjctNiw2LTZ2MGgxNC4xbC0zLjMtMy4zYy0wLjEtMC4xLTAuMS0wLjIsMC0wLjNMMTcuMyw2YzAuMS0wLjEsMC4yLTAuMSwwLjMsMGwzLjgsMy44YzAsMCwwLjEsMCwwLjEsMGwwLjQsMC40YzAuMSwwLjEsMC4xLDAuMiwwLDAuM2wtNC4yLDQuMmMtMC4xLDAuMS0wLjIsMC4xLTAuMywwbC0wLjQtMC40Yy0wLjEtMC4xLTAuMS0wLjIsMC0wLjNsMy4xLTNINnYwYy0yLjksMC01LDIuMS01LDVoMHYySDBMMCwxNkwwLDE2elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXJlYWRlciB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTE3LDIxSDFWOWg2VjJsMCwwaDEwdjVoMVYxSDYuMkwwLDcuNlYyMmgxOHYtM2gtMVYyMXogTTYsMi44VjhIMS4xTDYsMi44eiBNMTMsOGMtNS4xLDAtOSw1LTksNXM0LjEsNSw5LDVjNSwwLDktNSw5LTVTMTgsOCwxMyw4eiBNOC43LDE1LjVDNi44LDE0LjQsNi40LDEzLDYuNCwxM3MwLjQtMS41LDIuNC0yLjZDOC4zLDExLjIsOCwxMiw4LDEzQzgsMTMuOSw4LjMsMTQuOCw4LjcsMTUuNXogTTEzLDE2LjdjLTIuMSwwLTMuNy0xLjctMy43LTMuN2MwLTIuMSwxLjctMy43LDMuNy0zLjdjMi4xLDAsMy43LDEuNywzLjcsMy43QzE2LjcsMTUuMSwxNS4xLDE2LjcsMTMsMTYuN3ogTTE3LjMsMTUuNWMwLjQtMC43LDAuNy0xLjYsMC43LTIuNWMwLTEtMC4zLTEuOC0wLjctMi42YzIsMS4xLDMuNCwyLjYsMy40LDIuNlMxOS4yLDE0LjQsMTcuMywxNS41eiBNMTMsMTEuN2MtMC43LDAtMS4zLDAuNi0xLjMsMS4zczAuNiwxLjMsMS4zLDEuM3MxLjMtMC42LDEuMy0xLjNTMTMuNywxMS43LDEzLDExLjd6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tZG93bmxvYWQge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIi0xIDMgMjIgMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwb2x5Z29uIHBvaW50cz1cIjEwLDUuNiAxMCwyMS4yIDExLDIxLjIgMTEsNS42IDE0LjYsOS4zIDE1LjMsOC41IDEwLjUsMy42IDUuNyw4LjUgNi40LDkuMyBcdFwiLz48cG9seWdvbiBwb2ludHM9XCIxMywxMiAxMywxMyAxOSwxMyAxOSwzMCAyLDMwIDIsMTMgOCwxMyA4LDEyIDEsMTIgMSwxMyAxLDMwIDEsMzEgMjAsMzEgMjAsMzAgMjAsMTMgMjAsMTIgXHRcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1pbmZvIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMTAsMTdoMlY4aC0yVjE3eiBNMTEsMUM1LjUsMSwxLDUuNSwxLDExczQuNSwxMCwxMCwxMHMxMC00LjUsMTAtMTBTMTYuNSwxLDExLDF6IE0xMSwyMGMtNSwwLTktNC05LTlzNC05LDktOXM5LDQsOSw5UzE2LDIwLDExLDIweiBNMTAsN2gyVjVoLTJWN3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1wbHVzIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMjIsMTJIMTJ2MTBoLTFWMTJIMXYtMWgxMFYxaDF2MTBoMTBWMTJ6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tc2V0dGluZ3Mge1xuICAgIHdpZHRoOiAyNHB4O1xuICAgIGhlaWdodDogMjRweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xMS44LDNsMC40LDJjMC4xLDAuNywwLjYsMS4xLDEuMywxLjFjMC4zLDAsMC41LTAuMSwwLjctMC4ybDEuOS0xLjJsMS4xLDEuMWwtMS4xLDEuOEMxNS44LDgsMTUuOCw4LjUsMTYsOC45YzAuMiwwLjQsMC41LDAuNywxLDAuOGwyLjEsMC41djEuNkwxNywxMi4yYy0wLjUsMC4xLTAuOCwwLjQtMSwwLjhjLTAuMiwwLjQtMC4xLDAuOSwwLjEsMS4ybDEuMiwxLjlsLTEuMSwxLjFsLTEuOC0xLjFjLTAuMi0wLjItMC41LTAuMi0wLjgtMC4yYy0wLjYsMC0xLjIsMC41LTEuMywxLjFsLTAuNSwyLjFoLTEuNmwtMC40LTJDOS43LDE2LjQsOS4yLDE2LDguNSwxNmMtMC4zLDAtMC41LDAuMS0wLjcsMC4ybC0xLjksMS4ybC0xLjEtMS4xbDEuMS0xLjhjMC4zLTAuNCwwLjMtMC45LDAuMS0xLjNjLTAuMi0wLjQtMC41LTAuNy0xLTAuOGwtMi4xLTAuNXYtMS42bDItMC40YzAuNS0wLjEsMC44LTAuNCwxLTAuOEM2LjEsOC43LDYsOC4yLDUuOCw3LjlsLTEtMmwxLjEtMS4xbDEuOCwxLjFDOCw2LjEsOC4yLDYuMiw4LjUsNi4yYzAuNiwwLDEuMi0wLjUsMS4zLTEuMUwxMC4zLDNIMTEuOCBNMTEsMTUuNWMyLjUsMCw0LjUtMiw0LjUtNC41cy0yLTQuNS00LjUtNC41cy00LjUsMi00LjUsNC41UzguNSwxNS41LDExLDE1LjUgTTEyLjEsMkg5LjlDOS42LDIsOS40LDIuMiw5LjMsMi41TDguOCw0LjljMCwwLjItMC4yLDAuMy0wLjMsMC4zcy0wLjEsMC0wLjItMC4xTDYuMiwzLjhDNi4xLDMuNyw2LDMuNyw1LjgsMy43Yy0wLjEsMC0wLjMsMC0wLjQsMC4xTDMuOCw1LjRjLTAuMSwwLjItMC4yLDAuNSwwLDAuOGwxLjMsMi4xYzAuMSwwLjIsMC4xLDAuNC0wLjIsMC41TDIuNSw5LjNDMi4yLDkuNCwyLDkuNiwyLDkuOXYyLjJjMCwwLjMsMC4yLDAuNSwwLjUsMC42bDIuNCwwLjVjMC4zLDAuMSwwLjQsMC4zLDAuMiwwLjVsLTEuMywyLjFjLTAuMiwwLjItMC4xLDAuNiwwLjEsMC44bDEuNiwxLjZjMC4xLDAuMSwwLjMsMC4yLDAuNCwwLjJzMC4yLDAsMC4zLTAuMUw4LjMsMTdjMC4xLTAuMSwwLjEtMC4xLDAuMi0wLjFzMC4zLDAuMSwwLjMsMC4zbDAuNSwyLjNDOS40LDE5LjgsOS42LDIwLDkuOSwyMGgyLjJjMC4zLDAsMC41LTAuMiwwLjYtMC41bDAuNS0yLjRjMC0wLjIsMC4xLTAuMywwLjMtMC4zYzAuMSwwLDAuMSwwLDAuMiwwLjFsMi4xLDEuM2MwLjEsMC4xLDAuMiwwLjEsMC4zLDAuMWMwLjIsMCwwLjMtMC4xLDAuNC0wLjJsMS42LTEuNmMwLjItMC4yLDAuMi0wLjUsMC4xLTAuOGwtMS4zLTIuMWMtMC4yLTAuMi0wLjEtMC41LDAuMi0wLjVsMi40LTAuNWMwLjMtMC4xLDAuNS0wLjMsMC41LTAuNlY5LjhjMC0wLjMtMC4yLTAuNS0wLjUtMC42bC0yLjQtMC41Yy0wLjMtMC4xLTAuNC0wLjMtMC4yLTAuNWwxLjMtMi4xYzAuMi0wLjIsMC4xLTAuNi0wLjEtMC44bC0xLjYtMS42Yy0wLjEtMC4xLTAuMy0wLjItMC40LTAuMmMtMC4xLDAtMC4yLDAtMC4zLDAuMWwtMi4xLDEuM0MxMy42LDUsMTMuNiw1LDEzLjUsNWMtMC4xLDAtMC4zLTAuMS0wLjMtMC4zbC0wLjUtMi4yQzEyLjYsMi4yLDEyLjQsMiwxMi4xLDJMMTIuMSwyeiBNMTEsMTQuNWMtMS45LDAtMy41LTEuNi0zLjUtMy41UzkuMSw3LjUsMTEsNy41czMuNSwxLjYsMy41LDMuNVMxMi45LDE0LjUsMTEsMTQuNUwxMSwxNC41elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLWFib3V0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCItMSA3IDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTIxLDE4LjVjMC0wLjMtMC4xLTAuNi0wLjctMC45bC0yLjYtMS4ybDIuNi0xLjJjMC42LTAuMywwLjctMC42LDAuNy0wLjljMC0wLjMtMC4xLTAuNi0wLjctMC45bC04LjktNC4xYy0wLjctMC40LTEuOS0wLjQtMi44LDBsLTguOSw0LjFDLTAuOSwxMy44LTEsMTQuMS0xLDE0LjNzMC4xLDAuNiwwLjcsMC45bDIuNiwxLjJsLTIuNiwxLjJDLTAuOSwxOC0xLDE4LjQtMSwxOC41YzAsMC4yLDAuMSwwLjYsMC43LDAuOWwyLjUsMS4ybC0yLjUsMS4yQy0wLjksMjIuMS0xLDIyLjUtMSwyMi43YzAsMC4zLDAuMSwwLjYsMC43LDAuOWw4LjksNC4xYzAuNSwwLjIsMC44LDAuMywxLjQsMC4zczEtMC4xLDEuNC0wLjNsOC45LTQuMWMwLjYtMC40LDAuNy0wLjYsMC43LTAuOWMwLTAuMy0wLjEtMC42LTAuNy0wLjlsLTIuNS0xLjJsMi41LTEuMkMyMC45LDE5LjIsMjEsMTguOCwyMSwxOC41eiBNLTAuMiwxNC4zTC0wLjIsMTQuM2MwLDAsMC4xLTAuMSwwLjMtMC4yTDksMTBjMC42LTAuMywxLjUtMC4zLDIsMGw4LjksNC4xYzAuMiwwLjEsMC4zLDAuMiwwLjMsMC4ybDAsMGMwLDAtMC4xLDAuMS0wLjMsMC4yTDExLDE4LjZjLTAuNiwwLjMtMS41LDAuMy0yLDBsLTguOS00LjFDLTAuMSwxNC40LTAuMiwxNC4zLTAuMiwxNC4zeiBNMjAuMiwyMi43TDIwLjIsMjIuN2MwLDAtMC4xLDAuMS0wLjMsMC4yTDExLDI3LjFjLTAuNiwwLjMtMS41LDAuMy0yLDBsLTguOS00LjFjLTAuMi0wLjEtMC4zLTAuMi0wLjMtMC4ybDAsMGMwLDAsMC4xLTAuMSwwLjMtMC4ybDMtMS41bDUuNSwyLjZjMC43LDAuNCwxLjksMC40LDIuOCwwbDUuNS0yLjZsMywxLjVDMjAuMSwyMi43LDIwLjIsMjIuNywyMC4yLDIyLjd6IE0xOS45LDE4LjdMMTEsMjIuOGMtMC42LDAuMy0xLjUsMC4zLTIsMGwtOC45LTQuMWMtMC4yLTAuMS0wLjMtMC4yLTAuMy0wLjJsMCwwYzAsMCwwLjEtMC4xLDAuMy0wLjJsMy0xLjVsNS41LDIuNmMwLjcsMC40LDEuOSwwLjQsMi44LDBsNS41LTIuNmwzLDEuNWMwLjIsMC4xLDAuMywwLjIsMC4zLDAuMmwwLDBDMjAuMiwxOC41LDIwLjEsMTguNiwxOS45LDE4Ljd6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24taGVscCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTExLjYsMS4zYy0zLjMsMC02LDIuOC02LDYuMmMwLjMsMCwwLjcsMCwwLjksMGMwLTIuOSwyLjMtNS4yLDUuMS01LjJzNS4xLDIuMyw1LjEsNS4yYzAsMS43LTEuOSwzLjItMyw0LjNDMTIuOSwxMi42LDExLDE0LjIsMTEsMTZjMCwxLjIsMCwyLjIsMCwyLjdjMC4zLDAsMC42LDAsMC45LDBjMC0wLjYsMC0xLjYsMC0yLjVjMC0xLjQsMS4xLTIuNCwyLjItMy41YzEuNy0xLjUsMy41LTMuMSwzLjUtNS4yQzE3LjYsNC4xLDE0LjksMS4zLDExLjYsMS4zeiBNMTEuNSwyMC4yYy0wLjMsMC0wLjUsMC4yLTAuNSwwLjV2MC44YzAsMC4zLDAuMiwwLjUsMC41LDAuNXMwLjUtMC4yLDAuNS0wLjV2LTAuOEMxMS45LDIwLjQsMTEuNywyMC4yLDExLjUsMjAuMnpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1zZXR1cCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTAsM3YxNmgyMlYzSDB6IE0yMSwxN0gxVjVoMjBWMTd6IE0xNi41LDUuOWwtNy4yLDcuMkw4LjgsMTVINHYxYzAsMCwzLjIsMCw1LDBjMC40LDAsMC4yLDAsMC4yLTAuMmwyLjItMC42TDE4LjcsOEwxNi41LDUuOXogTTkuOSwxMy4xbDYuNS02LjRMMTgsOGwtNi41LDYuNEw5LjksMTMuMXpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi12ZXJzaW9ucyB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiLTEgNyAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xOSwxMmMwLTEuMS0wLjktMi0yLTJjMC0xLjEtMC45LTItMi0ySDVjLTEuMSwwLTIsMC45LTIsMmMtMS4xLDAtMiwwLjktMiwyYy0xLjEsMC0yLDAuOS0yLDJ2MTJjMCwxLjEsMC45LDIsMiwyaDE4YzEuMSwwLDItMC45LDItMlYxNEMyMSwxMi45LDIwLjEsMTIsMTksMTJ6IE01LDloMTBjMC42LDAsMSwwLjQsMSwxSDRDNCw5LjQsNC40LDksNSw5eiBNMywxMWgxNGMwLjYsMCwxLDAuNCwxLDFIMkMyLDExLjQsMi40LDExLDMsMTF6IE0yMCwyNmMwLDAuNi0wLjQsMS0xLDFIMWMtMC42LDAtMS0wLjQtMS0xVjE0YzAtMC42LDAuNC0xLDEtMWgxOGMwLjYsMCwxLDAuNCwxLDFWMjZ6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGV4dC1hZGRpdGlvbmFsIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMTguNSwxNS41Yy0xLjEsMC0yLDAuOS0yLDJzMC45LDIsMiwyczItMC45LDItMlMxOS42LDE1LjUsMTguNSwxNS41eiBNMTguNSwxOC41Yy0wLjYsMC0xLTAuNC0xLTFjMC0wLjYsMC40LTEsMS0xczEsMC40LDEsMUMxOS41LDE4LjEsMTkuMSwxOC41LDE4LjUsMTguNXogTTE4LjUsNy41YzEuMSwwLDItMC45LDItMmMwLTEuMS0wLjktMi0yLTJzLTIsMC45LTIsMkMxNi41LDYuNiwxNy40LDcuNSwxOC41LDcuNXogTTE4LjUsNC41YzAuNiwwLDEsMC40LDEsMXMtMC40LDEtMSwxcy0xLTAuNC0xLTFTMTcuOSw0LjUsMTguNSw0LjV6IE0xOC41LDkuNWMtMS4xLDAtMiwwLjktMiwyczAuOSwyLDIsMnMyLTAuOSwyLTJTMTkuNiw5LjUsMTguNSw5LjV6IE0xOC41LDEyLjVjLTAuNiwwLTEtMC40LTEtMWMwLTAuNiwwLjQtMSwxLTFzMSwwLjQsMSwxQzE5LjUsMTIuMSwxOS4xLDEyLjUsMTguNSwxMi41eiBNNi45LDMuOEwxLDE4LjloMS41bDEuOC00LjdoNi45bDEuNyw0LjdoMS41TDguNiwzLjhINi45eiBNNC43LDEyLjlsMy03LjlsMyw3LjlINC43elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRleHQtY29sb3Ige1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk04LjksMTJsMi4zLTYuM2wyLjIsNi4zSDguOXogTTQuNywxNy44aDJsMS42LTQuM2g1LjZsMS41LDQuM2gyLjFMMTIuMywzLjVoLTIuMkw0LjcsMTcuOHpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10ZXh0LXNlbGVjdGlvbiB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTcuNiwxMC4zYzAuMiwwLjMsMC40LDAuNCwwLjUsMC41YzAuMywwLjIsMC42LDAuMywxLDAuM2MwLjcsMCwxLjMtMC4zLDEuNy0wLjhjMC40LTAuNSwwLjYtMS4yLDAuNi0yLjFjMC0wLjktMC4yLTEuNS0wLjYtMmMtMC40LTAuNC0wLjktMC43LTEuNi0wLjdjLTAuMywwLTAuNiwwLjEtMC45LDAuMkM4LDYsNy44LDYuMiw3LjYsNi40VjMuOEg2LjhWMTFoMC44VjEwLjN6IE04LDYuOWMwLjMtMC4zLDAuNy0wLjQsMS4xLTAuNGMwLjUsMCwwLjgsMC4yLDEsMC41YzAuMiwwLjQsMC40LDAuOCwwLjQsMS40YzAsMC42LTAuMSwxLjEtMC40LDEuNWMtMC4yLDAuNC0wLjYsMC42LTEuMSwwLjZjLTAuNiwwLTEuMS0wLjMtMS4zLTAuOUM3LjYsOS4yLDcuNiw4LjgsNy42LDguM0M3LjYsNy43LDcuNyw3LjIsOCw2Ljl6IE01LjcsMTAuNGMtMC4xLDAtMC4yLDAtMC4yLTAuMWMwLTAuMS0wLjEtMC4xLTAuMS0wLjJ2LTNjMC0wLjUtMC4yLTAuOS0wLjYtMS4xQzQuNCw1LjgsNCw1LjYsMy4zLDUuNmMtMC41LDAtMSwwLjEtMS40LDAuNEMxLjUsNi4zLDEuMyw2LjcsMS4zLDcuNGgwLjhjMC0wLjMsMC4xLTAuNSwwLjItMC42YzAuMi0wLjIsMC41LTAuNCwxLTAuNGMwLjQsMCwwLjcsMC4xLDAuOSwwLjJjMC4yLDAuMSwwLjMsMC40LDAuMywwLjdjMCwwLjEsMCwwLjMtMC4xLDAuM0M0LjQsNy43LDQuMyw3LjgsNC4xLDcuOEwyLjcsOEMyLjIsOC4xLDEuOCw4LjIsMS41LDguNUMxLjIsOC44LDEsOS4xLDEsOS42YzAsMC40LDAuMiwwLjgsMC41LDEuMWMwLjMsMC4zLDAuNywwLjQsMS4yLDAuNGMwLjQsMCwwLjgtMC4xLDEuMS0wLjNjMC4zLTAuMiwwLjYtMC40LDAuOC0wLjZjMCwwLjIsMC4xLDAuNCwwLjIsMC41YzAuMSwwLjIsMC40LDAuMywwLjcsMC4zYzAuMSwwLDAuMiwwLDAuMywwYzAuMSwwLDAuMiwwLDAuMy0wLjF2LTAuNmMtMC4xLDAtMC4xLDAtMC4yLDBDNS44LDEwLjQsNS43LDEwLjQsNS43LDEwLjR6IE00LjUsOS4xYzAsMC41LTAuMiwwLjktMC43LDEuMmMtMC4zLDAuMS0wLjYsMC4yLTAuOSwwLjJjLTAuMywwLTAuNS0wLjEtMC43LTAuMkMyLDEwLjEsMiw5LjksMiw5LjZDMiw5LjMsMi4xLDksMi40LDguOWMwLjItMC4xLDAuNC0wLjIsMC43LTAuMmwwLjUtMC4xYzAuMiwwLDAuMy0wLjEsMC41LTAuMWMwLjIsMCwwLjMtMC4xLDAuNC0wLjJWOS4xeiBNMTguNSw1TDguMywxNS4zbC0wLjUsMmMtMC42LDAuNC0xLjMsMC4zLTEuNSwwLjZjLTAuMywwLjQsMC45LDAuNCwxLjUsMC4zYzAuNCwwLDAuNSwwLDAuNS0wLjJsMi4yLTAuNkwyMC43LDcuMUwxOC41LDV6IE05LDE1LjNsOS41LTkuNUwyMCw3LjFsLTkuNSw5LjVMOSwxNS4zelwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLWJ1bGxldHMge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk03LDR2MWgxNVY0SDd6IE0xLDZoM1YzSDFWNnogTTcsMTJoMTV2LTFIN1YxMnogTTEsMTNoM3YtM0gxVjEzeiBNNywxOWgxNXYtMUg3VjE5eiBNMSwyMGgzdi0zSDFWMjB6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tbnVtYmVycyB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTcsMy44djFoMTV2LTFIN3ogTTcsMTEuOGgxNXYtMUg3VjExLjh6IE03LDE4LjhoMTV2LTFIN1YxOC44eiBNMy4xLDYuOWgwLjdWMkgzLjNDMy4yLDIuNCwzLjEsMi42LDIuOSwyLjdDMi43LDIuOCwyLjQsMi45LDIsMi45djAuNWgxLjJWNi45eiBNMy4zLDlDMi42LDksMi4xLDkuMiwxLjksOS43Yy0wLjIsMC4zLTAuMiwwLjYtMC4yLDFoMC42YzAtMC4zLDAuMS0wLjUsMC4xLTAuN2MwLjItMC4zLDAuNS0wLjUsMC45LTAuNWMwLjMsMCwwLjUsMC4xLDAuNywwLjNzMC4zLDAuNCwwLjMsMC43YzAsMC4yLTAuMSwwLjUtMC4zLDAuN2MtMC4xLDAuMS0wLjMsMC4zLTAuNiwwLjRsLTAuNywwLjRjLTAuNCwwLjMtMC43LDAuNS0wLjksMC45Yy0wLjIsMC4zLTAuMiwwLjctMC4zLDEuMWgzLjR2LTAuNkgyLjJjMC4xLTAuMiwwLjItMC41LDAuNC0wLjdjMC4xLTAuMSwwLjMtMC4yLDAuNS0wLjRMMy42LDEyYzAuNC0wLjIsMC43LTAuNCwwLjktMC42YzAuMy0wLjMsMC40LTAuNiwwLjQtMWMwLTAuNC0wLjEtMC43LTAuNC0xQzQuMyw5LjEsMy45LDksMy4zLDl6IE00LjEsMTguM2MwLjItMC4xLDAuMy0wLjIsMC40LTAuM2MwLjItMC4yLDAuMi0wLjQsMC4yLTAuN2MwLTAuNC0wLjEtMC43LTAuNC0xQzQsMTYuMSwzLjYsMTYsMy4xLDE2Yy0wLjYsMC0xLjEsMC4yLTEuMywwLjdjLTAuMSwwLjMtMC4yLDAuNi0wLjIsMC45aDAuNmMwLTAuMywwLjEtMC41LDAuMS0wLjZjMC4yLTAuMywwLjQtMC40LDAuOS0wLjRjMC4yLDAsMC40LDAuMSwwLjYsMC4yQzQsMTYuOSw0LjEsMTcsNC4xLDE3LjNjMCwwLjMtMC4xLDAuNi0wLjQsMC43Yy0wLjEsMC4xLTAuMywwLjEtMC42LDAuMWMtMC4xLDAtMC4xLDAtMC4xLDBjMCwwLTAuMSwwLTAuMiwwdjAuNWMwLDAsMC4xLDAsMC4xLDBjMCwwLDAuMSwwLDAuMSwwYzAuNCwwLDAuNywwLjEsMC45LDAuMmMwLjIsMC4xLDAuMywwLjQsMC4zLDAuN2MwLDAuMy0wLjEsMC41LTAuMywwLjdjLTAuMiwwLjItMC41LDAuMy0wLjgsMC4zYy0wLjQsMC0wLjctMC4xLTAuOS0wLjRjLTAuMS0wLjEtMC4yLTAuNC0wLjItMC43SDEuNWMwLDAuNSwwLjEsMC44LDAuNCwxLjJDMi4xLDIwLjgsMi41LDIxLDMuMSwyMWMwLjYsMCwxLTAuMSwxLjMtMC40YzAuMy0wLjMsMC41LTAuNywwLjUtMS4xYzAtMC4zLTAuMS0wLjUtMC4yLTAuN0M0LjUsMTguNSw0LjMsMTguMyw0LjEsMTguM3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1saW5lc3BhY2luZyB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cG9seWdvbiBpZD1cIlhNTElEXzdfXCIgcG9pbnRzPVwiMjIsNCAyMiwzIDEyLDMgMTEsMyAxLDMgMSw0IDExLDQgMTEsNC4zIDgsNy40IDguNyw4LjEgMTEsNS43IDExLDE3LjMgOC43LDE0LjkgOCwxNS42IDExLDE4LjcgMTEsMTkgMSwxOSAxLDIwIDExLDIwIDEyLDIwIDIyLDIwIDIyLDE5IDEyLDE5IDEyLDE4LjYgMTUsMTUuNiAxNC4zLDE0LjkgMTIsMTcuMiAxMiw1LjggMTQuMyw4LjEgMTUsNy40IDEyLDQuNCAxMiw0IFx0XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGV4dC1hbGlnbi1jZW50ZXIge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctbWFzaygnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xLDN2MWgyMVYzSDF6IE00LDd2MWgxNFY3SDR6IE0xLDEyaDIxdi0xSDFWMTJ6IE00LDE1djFoMTR2LTFINHogTTEsMjBoMjF2LTFIMVYyMHpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10ZXh0LWFsaWduLWphc3Qge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctbWFzaygnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xLDN2MWgyMVYzSDF6IE0xLDhoMjFWN0gxVjh6IE0xLDEyaDIxdi0xSDFWMTJ6IE0xLDE2aDIxdi0xSDFWMTZ6IE0xLDIwaDIxdi0xSDFWMjB6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGV4dC1hbGlnbi1sZWZ0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLW1hc2soJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMSwzdjFoMjFWM0gxeiBNMTUsN0gxdjFoMTRWN3ogTTEsMTJoMjF2LTFIMVYxMnogTTE1LDE1SDF2MWgxNFYxNXogTTEsMjBoMjF2LTFIMVYyMHpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10ZXh0LWFsaWduLXJpZ2h0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLW1hc2soJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMSwzdjFoMjFWM0gxeiBNOCw4aDE0VjdIOFY4eiBNMjIsMTFIMXYxaDIxVjExeiBNOCwxNmgxNHYtMUg4VjE2eiBNMjIsMTlIMXYxaDIxVjE5elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLWRlLWluZGVudCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1tYXNrKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTEsMjB2LTFoMjF2MUgxeiBNMTEsMTVoMTF2MUgxMVYxNXogTTExLDExaDExdjFIMTFWMTF6IE0xMSw3aDExdjFIMTFWN3ogTTYuMyw3TDcsNy43bC0zLjgsMy44TDcsMTUuM0w2LjMsMTZMMiwxMS44bC0wLjItMC4zTDIsMTEuMkw2LjMsN3ogTTEsM2gyMXYxSDFWM3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1pbi1pbmRlbnQge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctbWFzaygnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xLDIwdi0xaDIxdjFIMXogTTEyLDE2SDF2LTFoMTFWMTZ6IE0xMiwxMkgxdi0xaDExVjEyeiBNMTIsOEgxVjdoMTFWOHogTTIxLDExLjJsMC4yLDAuM0wyMSwxMS44TDE2LjcsMTZMMTYsMTUuM2wzLjgtMy44TDE2LDcuN0wxNi43LDdMMjEsMTEuMnogTTIyLDRIMVYzaDIxVjR6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tcHJldiB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTE2LDIwLjVMMTUsMjEuNUw0LjUsMTFsMCwwbDAsMEwxNSwwLjVMMTYsMS41TDYuNiwxMUwxNiwyMC41elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLW5leHQge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xNS41LDExTDYsMS41bDEuMS0xLjFMMTcuNSwxMWwwLDBsMCwwTDcuMSwyMS41TDYsMjAuNUwxNS41LDExelwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWFkZC1jb2x1bW4tbGVmdCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTE1LDE5aC0xSDhIN3YtMXYtM0gwVjJoN2gxaDE0djR2MXYzdjF2M3YxdjN2MUgxNXogTTE1LDE4aDZ2LTNoLTZWMTh6IE0xNSwxNGg2di0zaC02VjE0eiBNOCwxOGg2di0zSDhWMTh6IE04LDE0aDZ2LTNIOFYxNHogTTE0LDEwVjdIOHYzSDE0eiBNOCwzdjNoNlYzSDh6IE0yMSwzaC02djNoNlYzeiBNMTUsN3YzaDZWN0gxNXogTTMsMTZoMXYyaDJ2MUg0djJIM3YtMkgxdi0xaDJWMTZ6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGFibGUtYWRkLWNvbHVtbi1yaWdodCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTAsMTlsMC0xbDAtM2wwLTFsMC0zbDAtMWwwLTNsMC0xbDAtNGgxNGgxaDd2MTNoLTd2M3YxaC0xSDhIN0gweiBNNywxNUgxdjNoNlYxNXogTTcsMTFIMXYzaDZWMTF6IE0xNCwxNUg4djNoNlYxNXogTTE0LDExSDh2M2g2VjExeiBNMTQsMTBWN0g4djNIMTR6IE04LDN2M2g2VjNIOHogTTEsNmg2VjNIMVY2eiBNMSw3djNoNlY3SDF6IE0xOSwxOGgydjFoLTJ2MmgtMXYtMmgtMnYtMWgydi0yaDFWMTh6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGFibGUtYWRkLXJvdy1hYm92ZSB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTIxLDIwaC02aC0xSDhIN0gwdi0xdi0zdi0xdi0zdi0xVjhWN1YxaDE1djZoNmgxdjF2M3YxdjN2MXYzdjFIMjF6IE03LDhIMXYzaDZWOHogTTcsMTJIMXYzaDZWMTJ6IE03LDE2SDF2M2g2VjE2eiBNOCwxOWg2di0zSDhWMTl6IE04LDE1aDZ2LTNIOFYxNXogTTgsMTFoNlY4SDhWMTF6IE0yMSw4aC02djNoNlY4eiBNMjEsMTJoLTZ2M2g2VjEyeiBNMjEsMTZoLTZ2M2g2VjE2eiBNMTksNmgtMVY0aC0yVjNoMlYxaDF2MmgydjFoLTJWNnpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1hZGQtcm93LWJlbG93IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMjIsMXYxdjN2MXYzdjF2M3YxaC0xaC02djZIMHYtNnYtMXYtM1Y5VjZWNVYyVjFoN2gxaDZoMWg2SDIyeiBNNywxMEgxdjNoNlYxMHogTTcsNkgxdjNoNlY2eiBNNywySDF2M2g2VjJ6IE04LDVoNlYySDhWNXogTTgsOWg2VjZIOFY5eiBNOCwxM2g2di0zSDhWMTN6IE0yMSwxMGgtNnYzaDZWMTB6IE0yMSw2aC02djNoNlY2eiBNMjEsMmgtNnYzaDZWMnogTTE5LDE3aDJ2MWgtMnYyaC0xdi0yaC0ydi0xaDJ2LTJoMVYxN3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1yZW1vdmUtY29sdW1uIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMjEsMTloLTZoLTFoLTEuNmMtMC45LDEuOC0yLjcsMy00LjksM3MtNC0xLjItNC45LTNIMUgwdi0xdi0zdi0xdi0zdi0xVjdWNlYzVjJoN2gxaDZoMWg2aDF2MXYzdjF2M3YxdjN2MXYzdjFIMjF6IE03LjUsMTJDNSwxMiwzLDE0LDMsMTYuNVM1LDIxLDcuNSwyMXM0LjUtMiw0LjUtNC41UzEwLDEyLDcuNSwxMnogTTE0LDNIOHYzaDZWM3ogTTE0LDdIOHYzaDZWN3ogTTE0LDExSDh2MC4xYzEuOSwwLjIsMy41LDEuMyw0LjQsMi45SDE0VjExeiBNMTQsMTVoLTEuMmMwLjEsMC41LDAuMiwxLDAuMiwxLjVjMCwwLjUtMC4xLDEtMC4yLDEuNUgxNFYxNXogTTIxLDNoLTZ2M2g2VjN6IE0yMSw3aC02djNoNlY3eiBNMjEsMTFoLTZ2M2g2VjExeiBNMjEsMTVoLTZ2M2g2VjE1eiBNOS42LDE5LjNsLTIuMS0yLjFsLTIuMSwyLjFsLTAuNy0wLjdsMi4xLTIuMWwtMi4xLTIuMWwwLjctMC43bDIuMSwyLjFsMi4xLTIuMWwwLjcsMC43bC0yLjEsMi4xbDIuMSwyLjFMOS42LDE5LjN6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGFibGUtcmVtb3ZlLXJvdyB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTIxLDE5aC02aC0xaC0xLjZjLTAuOSwxLjgtMi43LDMtNC45LDNzLTQtMS4yLTQuOS0zSDFIMHYtMXYtM3YtMXYtM3YtMVY3VjZWM1YyaDdoMWg2aDFoNmgxdjF2M3YxdjN2MXYzdjF2M3YxSDIxeiBNMSwxOGgxLjJDMi4xLDE3LjUsMiwxNywyLDE2LjVjMC0wLjUsMC4xLTEsMC4yLTEuNUgxVjE4eiBNNywzSDF2M2g2VjN6IE03LDdIMXYzaDZWN3ogTTcuNSwxMkM1LDEyLDMsMTQsMywxNi41UzUsMjEsNy41LDIxczQuNS0yLDQuNS00LjVTMTAsMTIsNy41LDEyeiBNMTQsM0g4djNoNlYzeiBNMTQsN0g4djNoNlY3eiBNMTQsMTVoLTEuMmMwLjEsMC41LDAuMiwxLDAuMiwxLjVjMCwwLjUtMC4xLDEtMC4yLDEuNUgxNFYxNXogTTIxLDNoLTZ2M2g2VjN6IE0yMSw3aC02djNoNlY3eiBNMjEsMTVoLTZ2M2g2VjE1eiBNOS42LDE5LjNsLTIuMS0yLjFsLTIuMSwyLjFsLTAuNy0wLjdsMi4xLTIuMWwtMi4xLTIuMWwwLjctMC43bDIuMSwyLjFsMi4xLTIuMWwwLjcsMC43bC0yLjEsMi4xbDIuMSwyLjFMOS42LDE5LjN6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tZXhwYW5kLWRvd24ge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0yMC41LDYuNWwxLjEsMS4xTDExLDE4bDAsMGwwLDBMMC41LDcuNWwxLjEtMS4xbDkuNSw5LjVMMjAuNSw2LjV6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tcGFnZWJyZWFrIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNOCwxNHYxaDF2LTFIOHogTTYsMTR2MWgxdi0xSDZ6IE0xOCwyMUgzdi02SDJ2N2gxN3YtN2gtMVYyMXogTTQsMTR2MWgxdi0xSDR6IE0xNCwxNHYxaDF2LTFIMTR6IE0xMCwxNHYxaDF2LTFIMTB6IE04LjIsMUwyLDcuNlYxNGgxVjloNlYybDAsMGg5djEyaDFWMUg4LjJ6IE04LDhIMy4xTDgsMi44Vjh6IE0xMiwxNHYxaDF2LTFIMTJ6IE0xNiwxNHYxaDF2LTFIMTZ6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tc2VjdGlvbmJyZWFrIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMjAsMTRWMkgzdjEySDJWMWgxOXYxM0gyMHogTTUsMTR2MUg0di0xSDV6IE03LDE0djFINnYtMUg3eiBNOSwxNHYxSDh2LTFIOXogTTExLDE0djFoLTF2LTFIMTF6IE0xMywxNHYxaC0xdi0xSDEzeiBNMTUsMTR2MWgtMXYtMUgxNXogTTE3LDE0djFoLTF2LTFIMTd6IE0xOCwxNGgxdjFoLTFWMTR6IE0zLDIxaDE3di02aDF2N0gydi03aDFWMjF6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tc3RyaW5nYnJlYWsge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xOCwxMkg1LjFMOSwxNS45bC0wLjcsMC43bC00LjUtNC41bC0wLjYtMC42bDAuNi0wLjZsNC41LTQuNUw5LDcuMUw1LjEsMTFIMThWNWgxdjZ2MUgxOHpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1wYWdlbnVtYmVyIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNOC4yLDFMMiw3LjZWMjJoMTdWMUg4LjJ6IE04LDIuOFY4SDMuMUw4LDIuOHogTTE4LDIxSDNWOWg2VjJsMCwwaDlWMjF6IE0xMiwxOWgxdi00aC0wLjdjMCwwLjItMC4xLTAuMS0wLjEsMGMtMC4xLDAuMS0wLjIsMC0wLjMsMGMtMC4xLDAuMS0wLjIsMC4xLTAuNCwwLjFjLTAuMSwwLTAuMywwLTAuNCwwVjE2SDEyVjE5eiBNMTUuMywxNy4zQzE1LDE3LjksMTUuMSwxOC40LDE1LDE5aDAuOWMwLTAuMywwLTAuNiwwLjEtMC45YzAuMS0wLjMsMC4xLTAuNiwwLjMtMC45YzAuMS0wLjMsMC4zLTAuNiwwLjQtMC45YzAuMi0wLjMsMC4xLTAuMywwLjMtMC41VjE1aC0zdjFoMS45QzE1LjYsMTYuNCwxNS41LDE2LjcsMTUuMywxNy4zelwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLWxpbmsge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xMi40LDkuOGMwLDAtMi4xLTAuMS0zLjgsMS4yYy0yLjgsMi0zLjMsNC4zLTMuMyw0LjNzMS42LTEuNywzLjUtMi41YzEuNy0wLjcsMy43LTAuNCwzLjctMC40djEuOWw0LjgtMy4zVjExbC00LjgtMy4zVjkuOHogTTExLDFDNS41LDEsMSw1LjUsMSwxMWMwLDUuNSw0LjUsMTAsMTAsMTBzMTAtNC41LDEwLTEwQzIxLDUuNSwxNi41LDEsMTEsMXogTTExLDIwYy01LDAtOS00LjEtOS05QzIsNiw2LDIsMTEsMnM5LDQuMSw5LDlDMjAsMTYsMTYsMjAsMTEsMjB6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24taW1hZ2UtbGlicmFyeSB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCI+PGRlZnM+PHN0eWxlPi5jbHMtMXtpc29sYXRpb246aXNvbGF0ZTt9LmNscy0ye29wYWNpdHk6MC4yO30uY2xzLTN7ZmlsbDojZmZmO30uY2xzLTEwLC5jbHMtMTEsLmNscy00LC5jbHMtNiwuY2xzLTcsLmNscy04LC5jbHMtOXttaXgtYmxlbmQtbW9kZTptdWx0aXBseTt9LmNscy00e2ZpbGw6dXJsKCNncmFkXzgpO30uY2xzLTV7ZmlsbDp1cmwoI2dyYWRfMTApO30uY2xzLTZ7ZmlsbDp1cmwoI2dyYWRfMTIpO30uY2xzLTd7ZmlsbDp1cmwoI2dyYWRfMTQpO30uY2xzLTh7ZmlsbDp1cmwoI2dyYWRfNzkpO30uY2xzLTl7ZmlsbDp1cmwoI2dyYWRfNzcpO30uY2xzLTEwe2ZpbGw6dXJsKCNncmFkXzc1KTt9LmNscy0xMXtmaWxsOnVybCgjZ3JhZF84MSk7fTwvc3R5bGU+PGxpbmVhckdyYWRpZW50IGlkPVwiZ3JhZF84XCIgeDE9XCIxMS4wOFwiIHkxPVwiMTAuMjZcIiB4Mj1cIjExLjA4XCIgeTI9XCIxLjI2XCIgZ3JhZGllbnRVbml0cz1cInVzZXJTcGFjZU9uVXNlXCI+PHN0b3Agb2Zmc2V0PVwiMFwiIHN0b3AtY29sb3I9XCIjZjNlOTE2XCIvPjxzdG9wIG9mZnNldD1cIjFcIiBzdG9wLWNvbG9yPVwiI2Y4OWQzNFwiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD1cImdyYWRfMTBcIiB4MT1cIjExLjA4XCIgeTE9XCIyMC40NFwiIHgyPVwiMTEuMDhcIiB5Mj1cIjExLjg4XCIgZ3JhZGllbnRVbml0cz1cInVzZXJTcGFjZU9uVXNlXCI+PHN0b3Agb2Zmc2V0PVwiMFwiIHN0b3AtY29sb3I9XCIjNWViNmU4XCIvPjxzdG9wIG9mZnNldD1cIjFcIiBzdG9wLWNvbG9yPVwiIzk1OGNjM1wiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD1cImdyYWRfMTJcIiB4MT1cIjEuNDZcIiB5MT1cIjExLjA1XCIgeDI9XCIxMC40NlwiIHkyPVwiMTEuMDVcIiBncmFkaWVudFRyYW5zZm9ybT1cInRyYW5zbGF0ZSgxNyA1LjA5KSByb3RhdGUoOTApXCIgZ3JhZGllbnRVbml0cz1cInVzZXJTcGFjZU9uVXNlXCI+PHN0b3Agb2Zmc2V0PVwiMFwiIHN0b3AtY29sb3I9XCIjY2M4ZGJhXCIvPjxzdG9wIG9mZnNldD1cIjFcIiBzdG9wLWNvbG9yPVwiI2Y4Njg2N1wiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD1cImdyYWRfMTRcIiB4MT1cIjExLjczXCIgeTE9XCIxMS4wNVwiIHgyPVwiMjAuNzNcIiB5Mj1cIjExLjA1XCIgZ3JhZGllbnRUcmFuc2Zvcm09XCJ0cmFuc2xhdGUoMjcuMjggLTUuMTgpIHJvdGF0ZSg5MClcIiBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIj48c3RvcCBvZmZzZXQ9XCIwXCIgc3RvcC1jb2xvcj1cIiM2YWMwN2ZcIi8+PHN0b3Agb2Zmc2V0PVwiMVwiIHN0b3AtY29sb3I9XCIjYzVkYTNkXCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPVwiZ3JhZF83OVwiIHgxPVwiMTEuNzRcIiB5MT1cIjEwLjQyXCIgeDI9XCIxNy41MlwiIHkyPVwiNC42M1wiIGdyYWRpZW50VHJhbnNmb3JtPVwidHJhbnNsYXRlKDMwLjI5IDIuNTEpIHJvdGF0ZSgxMzUpXCIgZ3JhZGllbnRVbml0cz1cInVzZXJTcGFjZU9uVXNlXCI+PHN0b3Agb2Zmc2V0PVwiMFwiIHN0b3AtY29sb3I9XCIjYzVkYTNkXCIvPjxzdG9wIG9mZnNldD1cIjFcIiBzdG9wLWNvbG9yPVwiI2YzZTkxNlwiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD1cImdyYWRfNzdcIiB4MT1cIjQuN1wiIHkxPVwiMTcuNDlcIiB4Mj1cIjEwLjQ4XCIgeTI9XCIxMS43MVwiIGdyYWRpZW50VHJhbnNmb3JtPVwidHJhbnNsYXRlKDIzLjI0IDE5LjY1KSByb3RhdGUoMTM1KVwiIGdyYWRpZW50VW5pdHM9XCJ1c2VyU3BhY2VPblVzZVwiPjxzdG9wIG9mZnNldD1cIjBcIiBzdG9wLWNvbG9yPVwiIzk1OTVjM1wiLz48c3RvcCBvZmZzZXQ9XCIxXCIgc3RvcC1jb2xvcj1cIiNjYzhkYmFcIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9XCJncmFkXzc1XCIgeDE9XCI0LjY5XCIgeTE9XCI0LjY0XCIgeDI9XCIxMC40N1wiIHkyPVwiMTAuNDJcIiBncmFkaWVudFRyYW5zZm9ybT1cInRyYW5zbGF0ZSg3LjU0IC0zLjE1KSByb3RhdGUoNDUpXCIgZ3JhZGllbnRVbml0cz1cInVzZXJTcGFjZU9uVXNlXCI+PHN0b3Agb2Zmc2V0PVwiMFwiIHN0b3AtY29sb3I9XCIjZjg2ODY3XCIvPjxzdG9wIG9mZnNldD1cIjFcIiBzdG9wLWNvbG9yPVwiI2Y4OWQzNFwiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD1cImdyYWRfODFcIiB4MT1cIjExLjc3XCIgeTE9XCIxMS43OFwiIHgyPVwiMTcuNTVcIiB5Mj1cIjE3LjU2XCIgZ3JhZGllbnRUcmFuc2Zvcm09XCJ0cmFuc2xhdGUoMTQuNjMgLTYuMDUpIHJvdGF0ZSg0NSlcIiBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIj48c3RvcCBvZmZzZXQ9XCIwXCIgc3RvcC1jb2xvcj1cIiM1ZWMwZThcIi8+PHN0b3Agb2Zmc2V0PVwiMVwiIHN0b3AtY29sb3I9XCIjNmFjMDdmXCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjx0aXRsZT5pY29uc19mb3Jfc3ZnPC90aXRsZT48ZyBjbGFzcz1cImNscy0xXCI+PGcgaWQ9XCLQodC70L7QuV8xXCIgZGF0YS1uYW1lPVwi0KHQu9C+0LkgMVwiPjxyZWN0IGNsYXNzPVwiY2xzLTJcIiB4PVwiMC4wOVwiIHk9XCIwLjAxXCIgd2lkdGg9XCIyMlwiIGhlaWdodD1cIjIyXCIgcng9XCI0XCIgcnk9XCI0XCIvPjxyZWN0IGNsYXNzPVwiY2xzLTNcIiB4PVwiMC41N1wiIHk9XCIwLjQ5XCIgd2lkdGg9XCIyMS4wNFwiIGhlaWdodD1cIjIxLjA0XCIgcng9XCIzLjZcIiByeT1cIjMuNlwiLz48cmVjdCBjbGFzcz1cImNscy00XCIgeD1cIjguMzNcIiB5PVwiMS4yNlwiIHdpZHRoPVwiNS41XCIgaGVpZ2h0PVwiOVwiIHJ4PVwiMi41XCIgcnk9XCIyLjVcIi8+PHJlY3QgY2xhc3M9XCJjbHMtNVwiIHg9XCI4LjMzXCIgeT1cIjExLjc2XCIgd2lkdGg9XCI1LjVcIiBoZWlnaHQ9XCI5XCIgcng9XCIyLjVcIiByeT1cIjIuNVwiLz48cmVjdCBjbGFzcz1cImNscy02XCIgeD1cIjMuMjFcIiB5PVwiNi41NVwiIHdpZHRoPVwiNS41XCIgaGVpZ2h0PVwiOVwiIHJ4PVwiMi41XCIgcnk9XCIyLjVcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTUuMDkgMTcpIHJvdGF0ZSgtOTApXCIvPjxyZWN0IGNsYXNzPVwiY2xzLTdcIiB4PVwiMTMuNDhcIiB5PVwiNi41NVwiIHdpZHRoPVwiNS41XCIgaGVpZ2h0PVwiOVwiIHJ4PVwiMi41XCIgcnk9XCIyLjVcIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoNS4xOCAyNy4yOCkgcm90YXRlKC05MClcIi8+PHJlY3QgY2xhc3M9XCJjbHMtOFwiIHg9XCIxMS44N1wiIHk9XCIzLjAzXCIgd2lkdGg9XCI1LjVcIiBoZWlnaHQ9XCI5XCIgcng9XCIyLjVcIiByeT1cIjIuNVwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgxOS42NCAyMy4xOSkgcm90YXRlKC0xMzUpXCIvPjxyZWN0IGNsYXNzPVwiY2xzLTlcIiB4PVwiNC44XCIgeT1cIjEwLjE0XCIgd2lkdGg9XCI1LjVcIiBoZWlnaHQ9XCI5XCIgcng9XCIyLjVcIiByeT1cIjIuNVwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgyLjU0IDMwLjMzKSByb3RhdGUoLTEzNSlcIi8+PHJlY3QgY2xhc3M9XCJjbHMtMTBcIiB4PVwiNC44M1wiIHk9XCIzLjAzXCIgd2lkdGg9XCI1LjVcIiBoZWlnaHQ9XCI5XCIgcng9XCIyLjVcIiByeT1cIjIuNVwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtMy4xIDcuNTYpIHJvdGF0ZSgtNDUpXCIvPjxyZWN0IGNsYXNzPVwiY2xzLTExXCIgeD1cIjExLjg3XCIgeT1cIjEwLjE0XCIgd2lkdGg9XCI1LjVcIiBoZWlnaHQ9XCI5XCIgcng9XCIyLjVcIiByeT1cIjIuNVwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNi4wNyAxNC42Mykgcm90YXRlKC00NSlcIi8+PC9nPjwvZz48L3N2Zz4nKTtcbiAgfVxuXG4gICYuaWNvbi10ZXh0LXZhbGlnbi10b3Age1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctbWFzaygnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHJlY3QgY2xhc3M9XCJjbHMtMVwiIHg9XCIyXCIgeT1cIjJcIiB3aWR0aD1cIjE5XCIgaGVpZ2h0PVwiMVwiLz48cmVjdCBjbGFzcz1cImNscy0xXCIgeD1cIjJcIiB5PVwiNFwiIHdpZHRoPVwiMTlcIiBoZWlnaHQ9XCIxXCIvPjxwb2x5Z29uIGNsYXNzPVwiY2xzLTFcIiBwb2ludHM9XCIxMiAxOCAxMSAxOCAxMSA3LjgzIDguNjUgOS44IDggOC45NCAxMS41IDYgMTUgOSAxNC4zNSA5LjggMTIgNy44MyAxMiAxOFwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRleHQtdmFsaWduLW1pZGRsZSB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1tYXNrKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cmVjdCBjbGFzcz1cImNscy0xXCIgeD1cIjJcIiB5PVwiMTBcIiB3aWR0aD1cIjE5XCIgaGVpZ2h0PVwiMVwiLz48cmVjdCBjbGFzcz1cImNscy0xXCIgeD1cIjJcIiB5PVwiMTJcIiB3aWR0aD1cIjE5XCIgaGVpZ2h0PVwiMVwiLz48cG9seWdvbiBjbGFzcz1cImNscy0xXCIgcG9pbnRzPVwiMTEgMiAxMiAyIDEyIDcuMTcgMTQuMzUgNS4yIDE1IDYuMDYgMTEuNSA5IDggNiA4LjY1IDUuMiAxMSA3LjE3IDExIDJcIi8+PHBvbHlnb24gY2xhc3M9XCJjbHMtMVwiIHBvaW50cz1cIjEyIDIxIDExIDIxIDExIDE1LjgzIDguNjUgMTcuOCA4IDE2Ljk0IDExLjUgMTQgMTUgMTcgMTQuMzUgMTcuOCAxMiAxNS44MyAxMiAyMVwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRleHQtdmFsaWduLWJvdHRvbSB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1tYXNrKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cmVjdCBjbGFzcz1cImNscy0xXCIgeD1cIjJcIiB5PVwiMThcIiB3aWR0aD1cIjE5XCIgaGVpZ2h0PVwiMVwiLz48cmVjdCBjbGFzcz1cImNscy0xXCIgeD1cIjJcIiB5PVwiMjBcIiB3aWR0aD1cIjE5XCIgaGVpZ2h0PVwiMVwiLz48cG9seWdvbiBjbGFzcz1cImNscy0xXCIgcG9pbnRzPVwiMTEgNCAxMiA0IDEyIDE1LjE3IDE0LjM1IDEzLjIgMTUgMTQuMDYgMTEuNSAxNyA4IDE0IDguNjUgMTMuMiAxMSAxNS4xNyAxMSA0XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuXG4gIC8vIFByZXNldHMgb2YgdGFibGUgYm9yZGVyc1xuXG4gICYuaWNvbi10YWJsZS1ib3JkZXJzLWFsbCB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0yNi45LDBIMFYyN0gyN1YwSDI2LjlaTTEzLDI2SDFWMTRIMTNWMjZabTAtMTNIMVYxSDEzVjEzWk0yNiwyNkgxNFYxNEgyNlYyNlptMC0xM0gxNFYxSDI2VjEzWlwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtbm9uZSB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMjYuOSwwSDBWMjdIMjdWMEgyNi45Wk0xMywyNkgxVjE0SDEzVjI2Wm0wLTEzSDFWMUgxM1YxM1pNMjYsMjZIMTRWMTRIMjZWMjZabTAtMTNIMTRWMUgyNlYxM1pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1ib3JkZXJzLWlubmVyIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cG9seWdvbiBwb2ludHM9XCIyNiAxMyAxNCAxMyAxNCAxIDEzIDEgMTMgMTMgMSAxMyAxIDE0IDEzIDE0IDEzIDI2IDE0IDI2IDE0IDE0IDI2IDE0IDI2IDEzXCIvPjxwYXRoIG9wYWNpdHk9XCIwLjNcIiBkPVwiTTI3LDBIMFYyN0gyN1YwWk0xLDI2VjFIMjZWMjZIMVpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1ib3JkZXJzLW91dGVyIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTI3LDBIMFYyN0gyN1YwWk0xLDI2VjFIMjZWMjZIMVpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1ib3JkZXJzLWxlZnQge1xuICAgIHdpZHRoOiAyOHB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIG9wYWNpdHk9XCIwLjNcIiBkPVwiTTI3LDBIMFYyN0gyN1YwWk0xLDI2VjFIMjZWMjZIMVpcIi8+PHJlY3Qgd2lkdGg9XCIxXCIgaGVpZ2h0PVwiMjdcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1ib3JkZXJzLWNlbnRlciB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMjcsMEgwVjI3SDI3VjBaTTEsMjZWMUgyNlYyNkgxWlwiLz48cmVjdCB4PVwiMTNcIiB3aWR0aD1cIjFcIiBoZWlnaHQ9XCIyN1wiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtcmlnaHQge1xuICAgIHdpZHRoOiAyOHB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIG9wYWNpdHk9XCIwLjNcIiBkPVwiTTI3LDBIMFYyN0gyN1YwWk0xLDI2VjFIMjZWMjZIMVpcIi8+PHJlY3QgeD1cIjI2XCIgd2lkdGg9XCIxXCIgaGVpZ2h0PVwiMjdcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1ib3JkZXJzLXRvcCB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMjcsMEgwVjI3SDI3VjBaTTEsMjZWMUgyNlYyNkgxWlwiLz48cmVjdCB3aWR0aD1cIjI3XCIgaGVpZ2h0PVwiMVwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtbWlkZGxlIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBvcGFjaXR5PVwiMC4zXCIgZD1cIk0yNywwSDBWMjdIMjdWMFpNMSwyNlYxSDI2VjI2SDFaXCIvPjxyZWN0IHk9XCIxM1wiIHdpZHRoPVwiMjdcIiBoZWlnaHQ9XCIxXCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGFibGUtYm9yZGVycy1ib3R0b20ge1xuICAgIHdpZHRoOiAyOHB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIG9wYWNpdHk9XCIwLjNcIiBkPVwiTTI3LDBIMFYyN0gyN1YwWk0xLDI2VjFIMjZWMjZIMVpcIi8+PHJlY3QgeT1cIjI2XCIgd2lkdGg9XCIyN1wiIGhlaWdodD1cIjFcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgLy8gUmVvcmRlclxuXG4gICYuaWNvbi1tb3ZlLWJhY2t3YXJkIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cmVjdCBvcGFjaXR5PVwiMC4zXCIgeD1cIjFcIiB5PVwiMVwiIHdpZHRoPVwiMTdcIiBoZWlnaHQ9XCIxN1wiLz48cGF0aCBkPVwiTTEwLDEwVjI3SDI3VjEwSDEwWk0yNiwyNkgxMVYxMUgyNlYyNlpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1tb3ZlLWZvcndhcmQge1xuICAgIHdpZHRoOiAyOHB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIG9wYWNpdHk9XCIwLjNcIiBkPVwiTTEwLDEwVjI3SDI3VjEwSDEwWk0yNiwyNkgxMVYxMUgyNlYyNlpcIi8+PHJlY3QgeD1cIjFcIiB5PVwiMVwiIHdpZHRoPVwiMTdcIiBoZWlnaHQ9XCIxN1wiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLW1vdmUtYmFja2dyb3VuZCB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHJlY3Qgb3BhY2l0eT1cIjAuM1wiIHg9XCI4XCIgeT1cIjhcIiB3aWR0aD1cIjEzXCIgaGVpZ2h0PVwiMTNcIi8+PHBhdGggZD1cIk0xLDFWMTNIMTNWMUgxWk0xMiwxMkgyVjJIMTJWMTJaXCIvPjxwYXRoIGQ9XCJNMTUsMTVWMjdIMjdWMTVIMTVaTTI2LDI2SDE2VjE2SDI2VjI2WlwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLW1vdmUtZm9yZWdyb3VuZCB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMSwxVjEzSDEzVjFIMVpNMTIsMTJIMlYySDEyVjEyWlwiLz48cGF0aCBvcGFjaXR5PVwiMC4zXCIgZD1cIk0xNSwxNVYyN0gyN1YxNUgxNVpNMjYsMjZIMTZWMTZIMjZWMjZaXCIvPjxyZWN0IHg9XCI4XCIgeT1cIjhcIiB3aWR0aD1cIjEzXCIgaGVpZ2h0PVwiMTNcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgJi5pY29uLWFsaWduLWxlZnQge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIHN0eWxlPVwiZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMiAyMjtcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PHN0eWxlIHR5cGU9XCJ0ZXh0L2Nzc1wiPi5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7fTwvc3R5bGU+PGc+PGcgaWQ9XCJYTUxJRF8zNV9cIj48cGF0aCBpZD1cIlhNTElEXzM2X1wiIGNsYXNzPVwic3QwXCIgZD1cIk0xLDIxaDFWMUgxVjIxeiBNNCwxM3Y0aDE2di00SDR6IE0xMiw1SDR2NGg4VjV6XCIvPjwvZz48L2c+PC9zdmc+Jyk7XG4gIH1cblxuICAmLmljb24tYWxpZ24tY2VudGVyIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBzdHlsZT1cImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjIgMjI7XCIgeG1sOnNwYWNlPVwicHJlc2VydmVcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxzdHlsZSB0eXBlPVwidGV4dC9jc3NcIj4uc3Qwe2ZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO308L3N0eWxlPjxnIGlkPVwiWE1MSURfNV9cIj48ZyBpZD1cIlhNTElEXzI0X1wiPjxwb2x5Z29uIGlkPVwiWE1MSURfMjVfXCIgY2xhc3M9XCJzdDBcIiBwb2ludHM9XCIxOSwxMyAxMSwxMyAxMSw5IDE1LDkgMTUsNSAxMSw1IDExLDEgMTAsMSAxMCw1IDYsNSA2LDkgMTAsOSAxMCwxMyAyLDEzIDIsMTcgMTAsMTcgMTAsMjEgMTEsMjEgMTEsMTcgMTksMTcgXHRcdFwiLz48L2c+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgJi5pY29uLWFsaWduLXJpZ2h0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBzdHlsZT1cImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjIgMjI7XCIgeG1sOnNwYWNlPVwicHJlc2VydmVcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxzdHlsZSB0eXBlPVwidGV4dC9jc3NcIj4uc3Qwe2ZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO308L3N0eWxlPjxnIGlkPVwiWE1MSURfNV9cIj48ZyBpZD1cIlhNTElEXzQyX1wiPjxwYXRoIGlkPVwiWE1MSURfNDRfXCIgY2xhc3M9XCJzdDBcIiBkPVwiTTIwLDF2MjBoMVYxSDIweiBNMiwxN2gxNnYtNEgyVjE3eiBNMTAsOWg4VjVoLThWOXpcIi8+PC9nPjwvZz48L3N2Zz4nKTtcbiAgfVxuXG4gICYuaWNvbi1hbGlnbi10b3Age1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIHN0eWxlPVwiZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMiAyMjtcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PGcgaWQ9XCJYTUxJRF8zNV9cIj48cGF0aCBpZD1cIlhNTElEXzM2X1wiIGQ9XCJNMSwxdjFoMjBWMUgxeiBNOSw0SDV2MTZoNFY0eiBNMTcsMTJWNGgtNHY4SDE3elwiLz48L2c+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgJi5pY29uLWFsaWduLW1pZGRsZSB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgc3R5bGU9XCJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDIyIDIyO1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48c3R5bGUgdHlwZT1cInRleHQvY3NzXCI+LnN0MHtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDt9PC9zdHlsZT48ZyBpZD1cIlhNTElEXzVfXCI+PGcgaWQ9XCJYTUxJRF8yNF9cIj48cG9seWdvbiBpZD1cIlhNTElEXzI1X1wiIGNsYXNzPVwic3QwXCIgcG9pbnRzPVwiMTMsMiAxMywxMCA5LDEwIDksNiA1LDYgNSwxMCAxLDEwIDEsMTEgNSwxMSA1LDE1IDksMTUgOSwxMSAxMywxMSAxMywxOSAxNywxOSAxNywxMSAyMSwxMSAyMSwxMCAxNywxMCAxNywyIFx0XHRcIi8+PC9nPjwvZz48L3N2Zz4nKTtcbiAgfVxuXG4gICYuaWNvbi1hbGlnbi1ib3R0b20ge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIHN0eWxlPVwiZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMiAyMjtcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PGcgaWQ9XCJYTUxJRF8zNV9cIj48cGF0aCBpZD1cIlhNTElEXzM2X1wiIGQ9XCJNMjEsMjB2LTFIMXYxSDIxeiBNOSwxSDV2MTZoNFYxeiBNMTMsOXY4aDRWOUgxM3pcIi8+PC9nPjwvZz48L3N2Zz4nKTtcbiAgfVxuXG4gICYuaWNvbi1hbGlnbi1ob3Jpem9udGFsIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBzdHlsZT1cImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjIgMjI7XCIgeG1sOnNwYWNlPVwicHJlc2VydmVcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxnIGlkPVwiWE1MSURfMzVfXCI+PHBhdGggaWQ9XCJYTUxJRF8zNl9cIiBkPVwiTTEsMXYxaDIwVjFIMXogTTAuOTk5OTk5LDE5LjAwMDAwNzZWMjBoMjB2LTAuOTk5OTkyNEgwLjk5OTk5OXogTTkuMDAwMDAxLDIuOTk5OTk5NWgtNHYxNWg0VjIuOTk5OTk5NXogTTE3LDEzLjk5OTk5OVY2Ljk5OTk5ODZoLTMuOTk5OTk5djcuMDAwMDAwNUgxN3pcIi8+PC9nPjwvZz48L3N2Zz4nKTtcbiAgfVxuXG4gICYuaWNvbi1hbGlnbi12ZXJ0aWNhbCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgc3R5bGU9XCJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDIyIDIyO1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48ZyBpZD1cIlhNTElEXzM1X1wiPjxwYXRoIGlkPVwiWE1MSURfMzZfXCIgZD1cIk0wLjk5OTk5OTgsMjFoMXYtMjBoLTFWMjF6IE0xOS4wMDAwMDc2LDIxSDIwdi0yMGgtMC45OTk5OTI0VjIxeiBNMi45OTk5OTk1LDEyLjk5OTk5OXYzLjk5OTk5OWgxNSB2LTMuOTk5OTk5SDIuOTk5OTk5NXogTTEzLjk5OTk5OSw0Ljk5OTk5OUg2Ljk5OTk5ODZ2NGg3LjAwMDAwMDVWNC45OTk5OTl6XCIvPjwvZz48L2c+PC9zdmc+Jyk7XG4gIH1cblxuICAvLyBGb3JtYXRzXG5cbiAgJi5pY29uLWZvcm1hdC1wZGYge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIHN0eWxlPVwiZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMiAyMjtcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggaWQ9XCJYTUxJRF8yX1wiIGQ9XCJNMiwyMWgxOFY0bC0zLjk3OTE2Ni00TDIsMFYyMXogTTE5LDh2MTJIM1YxaDEybDQsNFY4elwiLz48L2c+PGc+PHBhdGggZD1cIk05Ljk5OTYzMjgsNy4yOTk0MTIzTDkuOTk5NjMyOCw3LjI5OTQxMjNDMTAuMDk4ODI0NSw3LjI5OTQxMjMsMTAuMDk4ODI0NSw3LjI5OTQxMjMsOS45OTk2MzI4LDcuMjk5NDEyM1x0YzAuMDk5MTkxNy0wLjQwMDQ0MDcsMC4yMDAyMjAxLTAuNjAwNjYxOCwwLjIwMDIyMDEtMC45MDAwNzM1VjYuMTk5MTE4MWMwLjA5OTE5MTctMC40OTk2MzI0LDAuMDk5MTkxNy0wLjkwMDA3MzUsMC0wLjk5OTI2NTIgYzAsMCwwLDAsMC0wLjA5OTE5MTdsLTAuMDk5MTkxNy0wLjA5OTE5MTdsMCwwbDAsMGMwLDAsMCwwLjA5OTE5MTctMC4wOTkxOTE3LDAuMDk5MTkxNyBDOS43OTk0MTE4LDUuNjk5NDg1OCw5Ljc5OTQxMTgsNi4zOTkzMzg3LDkuOTk5NjMyOCw3LjI5OTQxMjNMOS45OTk2MzI4LDcuMjk5NDEyM3ogTTcsMTQuMjAwNTg3M1x0Yy0wLjIwMDIyMDEsMC4wOTkxOTI2LTAuNDAwNDQwNywwLjIwMDIyMTEtMC40OTk2MzI4LDAuMjk5NDExOGMtMC42OTk4NTI5LDAuNjAwNjYxMy0xLjE5OTQ4NTgsMS4zMDA1MTQyLTEuMzAwNTE0MiwxLjU5OTkyNjlsMCwwIGwwLDBsMCwwQzUuNzk4Njc3NCwxNi4wMDA3MzQzLDYuMzk5MzM4NywxNS40MDAwNzQsNywxNC4yMDA1ODczQzcuMDk5MTkxNywxNC4yMDA1ODczLDcuMDk5MTkxNywxNC4yMDA1ODczLDcsMTQuMjAwNTg3MyBDNy4wOTkxOTE3LDE0LjIwMDU4NzMsNywxNC4yMDA1ODczLDcsMTQuMjAwNTg3M3ogTTE2LjE5OTExOTYsMTIuNjk5ODUzOVx0Yy0wLjA5OTE5MzYtMC4wOTkxOTI2LTAuNDk5NjMzOC0wLjQwMDQ0MTItMS44OTkzMzk3LTAuNDAwNDQxMmMtMC4wOTkxOTI2LDAtMC4wOTkxOTI2LDAtMC4yMDAyMjExLDBsMCwwYzAsMCwwLDAsMCwwLjA5OTE5MjYgYzAuNjk5ODUyOSwwLjI5OTQxMTgsMS4zOTk3MDU5LDAuNDk5NjMyOCwxLjg5OTMzODcsMC40OTk2MzI4YzAuMDk5MTkxNywwLDAuMDk5MTkxNywwLDAuMjAwMjIyLDBsMCwwaDAuMDk5MTkxNyBjMCwwLDAsMCwwLTAuMDk5MTkyNmwwLDBDMTYuMzAwMTQ4LDEyLjc5OTA0NDYsMTYuMTk5MTE5NiwxMi43OTkwNDQ2LDE2LjE5OTExOTYsMTIuNjk5ODUzOXogTTE2LjU5OTU1OTgsMTMuNDk4ODk4NSBjLTAuMjAwMjIyLDAuMDk5MTkxNy0wLjQ5OTYzMzgsMC4yMDAyMjExLTAuOTAwMDc0LDAuMjAwMjIxMWMtMC44MDA4ODE0LDAtMi4wMDAzNjgxLTAuMjAwMjIxMS0yLjk5OTYzMTktMC42OTk4NTI5IGMtMS43MDA5NTU0LDAuMjAwMjIxMS0yLjk5OTYzMjgsMC40MDA0NDAyLTQuMDAwNzM1MywwLjgwMDg4MTRjLTAuMDk5MTkxNywwLTAuMDk5MTkxNywwLTAuMjAwMjIwMSwwLjA5OTE5MTcgQzcuMjk5NDEyMywxNi4wMDA3MzQzLDYuMjk4MzA5OCwxNyw1LjQ5OTI2NTIsMTdjLTAuMjAwMjIwNiwwLTAuMjk5NDEyMywwLTAuNDAwNDQxMi0wLjA5OTE5MTdsLTAuNDk5NjMyNC0wLjI5OTQxMThWMTYuNTAyMjAzXHRDNC41LDE2LjMwMTk4MjksNC41LDE2LjIwMjc5MTIsNC41LDE2LjAwMjU3MTFjMC4wOTkxOTE3LTAuNDk5NjMyOCwwLjY5OTg1MjktMS4zOTk3MDY4LDEuODk5MzM4Ny0yLjA5OTU1OTggYzAuMjAwMjIwMS0wLjA5OTE5MTcsMC40OTk2MzI4LTAuMjk5NDExOCwwLjkwMDA3MzUtMC40OTk2MzI4YzAuMjk5NDExOC0wLjQ5OTYzMjgsMC42MDA2NjEzLTEuMTAwMjk0MSwwLjk5OTI2NTItMS44MDAxNDYxIGMwLjQ5OTYzMjgtMC45OTkyNjU3LDAuODAwODgxNC0yLjAwMDM2ODEsMS4xMDAyOTMyLTIuOTAwNDQxMmwwLDBDOC45OTg1MzA0LDcuNTAzMzA1NCw4Ljc5ODMwOTMsNi44MDM0NTI1LDkuMTk4NzUwNSw1LjQwMTkwOTRDOS4yOTc5NDIyLDUuMDAxNDY4Nyw5LjU5OTE5MTcsNC42MDEwMjgsOS45OTk2MzI4LDQuNjAxMDI4aDAuMjAwMjIwMWMwLjIwMDIyMDEsMCwwLjQwMDQ0MDIsMC4wOTkxOTE3LDAuNjAwNjYxMywwLjIwMDIyMDYgYzAuNjk5ODUyOSwwLjY5OTg1MjksMC40MDA0NDEyLDIuMjk5Nzc5NCwwLDMuNjAwMjk0MWMwLDAuMDk5MTkxNywwLDAuMDk5MTkxNywwLDAuMDk5MTkxNyBjMC40MDA0NDEyLDEuMTAwMjkzMiwwLjk5OTI2NTcsMi4wMDAzNjcyLDEuNTk5OTI2LDIuNjAxMDI4NGMwLjI5OTQxMTgsMC4yMDAyMjExLDAuNDk5NjMyOCwwLjQwMDQ0MDIsMC45MDAwNzQsMC42MDA2NjEzIGMwLjQ5OTYzMjgsMCwwLjkwMDA3MzEtMC4wOTkxOTE3LDEuMzAwNTE0Mi0wLjA5OTE5MTdjMS4xOTk0ODQ4LDAsMi4wMDAzNjgxLDAuMjAwMjIwMSwyLjI5OTc3OTksMC42OTk4NTJcdEMxNywxMi41MDMzMDU0LDE3LDEyLjcwMzUyNTUsMTcsMTIuOTAzNzQ1N0MxNi45MDA4MDgzLDEyLjk5OTI2NTcsMTYuNzk5Nzc5OSwxMy4zMDA1MTQyLDE2LjU5OTU1OTgsMTMuNDk4ODk4NXogTTEwLjA5ODgyNDUsOS41OTkxOTE3QzkuODk4NjAzNCwxMC4yOTkwNDQ2LDkuNDk4MTYyMywxMS4wOTk5MjYsOS4wOTk1NTg4LDEyIGMtMC4yMDAyMjAxLDAuNDAwNDQwMi0wLjQwMDQ0MDIsMC42OTk4NTItMC42MDA2NjEzLDEuMTAwMjk0MWgwLjA5OTE5MTdoMC4wOTkxOTE3bDAsMCBjMS4zMDA1MTQyLTAuNDk5NjMyOCwyLjUtMC44MDA4ODE0LDMuMzAwODgxNC0wLjkwMDA3MzFDMTEuNzk3OTQxMiwxMi4xMDEwMjg0LDExLjY5ODc1MDUsMTIsMTEuNTk3NzIyMSwxMS45MDA4MDgzIEMxMS4wOTk5MjYsMTEuMzAwMTQ3MSwxMC40OTkyNjU3LDEwLjQ5OTI2NTcsMTAuMDk4ODI0NSw5LjU5OTE5MTd6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tZm9ybWF0LXBwdHgge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIi0yMzggMjQwIDIyIDIyXCIgc3R5bGU9XCJlbmFibGUtYmFja2dyb3VuZDpuZXcgLTIzOCAyNDAgMjIgMjI7XCIgeG1sOnNwYWNlPVwicHJlc2VydmVcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGlkPVwiWE1MSURfMl9cIiBkPVwiTS0yMzYsMjYxaDE4di0xN2wtMy45NzkxNzE4LTRILTIzNlYyNjF6IE0tMjE5LDI0OHYxMmgtMTZ2LTE5aDEybDQsNFYyNDh6XCIvPjwvZz48Zz48cGF0aCBkPVwiTS0yMjguODIyNjkyOSwyNTAuODY0Njg1MWMwLjEzNzA4NS0wLjA2MDc5MSwwLjIzNDE5MTktMC4yMzAyMjQ2LDAuMzEzMTEwNC0wLjM2NDc0NjFcdGMwLjA3OTI4NDctMC4xMzUxOTI5LDAuMDg2MTgxNi0wLjI5MzUxODEsMC4wODYxODE2LTAuNDczOTM4YzAtMC4yMjIxMDY5LTAuMDYxMzQwMy0wLjQxODY0MDEtMC4xNzIzNjMzLTAuNTYwMTgwN1x0Yy0wLjExMDI5MDUtMC4xNDA1MDI5LTAuMjk2ODc1LTAuMjYyODc4NC0wLjQ2Mjg5MDYtMC4yOTMxNTE5Yy0wLjEyMTA5MzgtMC4wMjMzMTU0LTAuMjM5Njg1MS0wLjAwMTI4MTctMC40NTM1NTIyLDAuMDA5MDk0MiBsLTAuMzExNTIzNCwwLjAxMDM3NnYxLjc5MjU0MTVoMC40NTIzOTI2Qy0yMjguOTgxNTA2MywyNTAuOTkyNzM2OC0yMjguOTU4NjE4MiwyNTAuOTI0OTg3OC0yMjguODIyNjkyOSwyNTAuODY0Njg1MXpcIi8+PHBhdGggZD1cIk0tMjMzLDI1Ni4xMTQxMzU3bDcuMzMzMzEzLDEuMzU1MzQ2N1YyNDVMLTIzMywyNDYuMzI2ODQzM1YyNTYuMTE0MTM1N3ogTS0yMzAuODY2MDg4OSwyNDguMjgxODYwNGwxLjQ5Njg4NzItMC4wOTc3NzgzIGMwLjYwNzc4ODEtMC4wMzk3MzM5LDAuOTA3NTMxNy0wLjA1NTcyNTEsMS4xMDE4MDY2LTAuMDA3MTQxMWMwLjMwMzIyMjcsMC4wNzM2MDg0LDAuNjM3MjA3LDAuMjM0OTg1NCwwLjg0ODMyNzYsMC41MzgxNDdcdGMwLjIxMzg2NzIsMC4zMDcwNjc5LDAuMzU1NTkwOCwwLjc1OTIxNjMsMC4zNTU1OTA4LDEuMjYyMDg1YzAsMC4zODc4Nzg0LTAuMDYyMzE2OSwwLjcxMzA3MzctMC4xODYyNzkzLDAuOTc0MTIxMVx0Yy0wLjEyMzA0NjksMC4yNTkwOTQyLTAuMjc4MDE1MSwwLjQ1OTEwNjQtMC40NjQwNTAzLDAuNjAwMTU4N2MtMC4xODM5NiwwLjEzOTQ2NTMtMC4zOTkxMDg5LDAuMjcwMDE5NS0wLjU1ODc3NjksMC4zMjcyNzA1IGMtMC4zMTQ1NzUyLDAuMDc3NDUzNi0wLjUyODY4NjUsMC4xNzQ3NDM3LTAuOTgwMjg1NiwwLjE1MDgxNzloLTAuNTcwODYxOHYxLjk1NjIzNzhsLTEuMDQyMzU4NC0wLjEwODE1NDNWMjQ4LjI4MTg2MDR6XCIvPjxwYXRoIGQ9XCJNLTIyMS43MjY2ODQ2LDI0N0gtMjI1djloMy4yNzMzMTU0Qy0yMjEuMzI1MzQ3OSwyNTYtMjIxLDI1NS42NzQ2NTIxLTIyMSwyNTUuMjczMzE1NHYtNy41NDY2MzA5XHRDLTIyMSwyNDcuMzI1MzQ3OS0yMjEuMzI1MzQ3OSwyNDctMjIxLjcyNjY4NDYsMjQ3elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbn0iLCIvLyBFbmNvZGVkIFNWRyBCYWNrZ3JvdW5kXG4uZW5jb2RlZC1zdmctbWFzayhAc3ZnKSB7XG4gIEB1cmw6IGBlbmNvZGVVUklDb21wb25lbnQoQHtzdmd9KWA7XG4gIGJhY2tncm91bmQtY29sb3I6IEB0aGVtZUNvbG9yO1xuICAtd2Via2l0LW1hc2staW1hZ2U6IHVybChcImRhdGE6aW1hZ2Uvc3ZnK3htbDtjaGFyc2V0PXV0Zi04LEB7dXJsfVwiKTtcbn0iXX0= */ \ No newline at end of file diff --git a/apps/presentationeditor/mobile/resources/css/app-material.css b/apps/presentationeditor/mobile/resources/css/app-material.css index 12b592435..cb5208d7d 100644 --- a/apps/presentationeditor/mobile/resources/css/app-material.css +++ b/apps/presentationeditor/mobile/resources/css/app-material.css @@ -6169,6 +6169,11 @@ i.icon.icon-format-pptx { height: 22px; background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%22-238%20240%2022%2022%22%20style%3D%22enable-background%3Anew%20-238%20240%2022%2022%3B%22%20xml%3Aspace%3D%22preserve%22%20fill%3D%22%23DF6737%22%3E%3Cg%3E%3Cpath%20id%3D%22XMLID_2_%22%20d%3D%22M-236%2C261h18v-17l-3.9791718-4H-236V261z%20M-219%2C248v12h-16v-19h12l4%2C4V248z%22%2F%3E%3C%2Fg%3E%3Cg%3E%3Cpath%20d%3D%22M-228.8226929%2C250.8646851c0.137085-0.060791%2C0.2341919-0.2302246%2C0.3131104-0.3647461%09c0.0792847-0.1351929%2C0.0861816-0.2935181%2C0.0861816-0.473938c0-0.2221069-0.0613403-0.4186401-0.1723633-0.5601807%09c-0.1102905-0.1405029-0.296875-0.2628784-0.4628906-0.2931519c-0.1210938-0.0233154-0.2396851-0.0012817-0.4535522%2C0.0090942%20l-0.3115234%2C0.010376v1.7925415h0.4523926C-228.9815063%2C250.9927368-228.9586182%2C250.9249878-228.8226929%2C250.8646851z%22%2F%3E%3Cpath%20d%3D%22M-233%2C256.1141357l7.333313%2C1.3553467V245L-233%2C246.3268433V256.1141357z%20M-230.8660889%2C248.2818604l1.4968872-0.0977783%20c0.6077881-0.0397339%2C0.9075317-0.0557251%2C1.1018066-0.0071411c0.3032227%2C0.0736084%2C0.637207%2C0.2349854%2C0.8483276%2C0.538147%09c0.2138672%2C0.3070679%2C0.3555908%2C0.7592163%2C0.3555908%2C1.262085c0%2C0.3878784-0.0623169%2C0.7130737-0.1862793%2C0.9741211%09c-0.1230469%2C0.2590942-0.2780151%2C0.4591064-0.4640503%2C0.6001587c-0.18396%2C0.1394653-0.3991089%2C0.2700195-0.5587769%2C0.3272705%20c-0.3145752%2C0.0774536-0.5286865%2C0.1747437-0.9802856%2C0.1508179h-0.5708618v1.9562378l-1.0423584-0.1081543V248.2818604z%22%2F%3E%3Cpath%20d%3D%22M-221.7266846%2C247H-225v9h3.2733154C-221.3253479%2C256-221%2C255.6746521-221%2C255.2733154v-7.5466309%09C-221%2C247.3253479-221.3253479%2C247-221.7266846%2C247z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); } +i.icon.icon-format-odp { + width: 22px; + height: 22px; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%22-286%20409.89%2022%2022%22%20style%3D%22enable-background%3Anew%20-286%20409.89%2022%2022%3B%22%20xml%3Aspace%3D%22preserve%22%20fill%3D%22%23DF6737%22%3E%3Cg%3E%3Cpath%20id%3D%22XMLID_2_%22%20d%3D%22M-284%2C430.89h18v-17l-3.979-4H-284V430.89z%20M-267%2C417.89v12h-16v-19h12l4%2C4V417.89z%22%2F%3E%3C%2Fg%3E%3Cpath%20d%3D%22M-281.655%2C419.661c0%2C0%2C1.036-1.266%2C3.529-1.381c2.493-0.115%2C3.107%2C0.499%2C3.107%2C0.499s1.072-0.873%2C2.634-0.984%20c1.473-0.106%2C2.244%2C0.134%2C3.657%2C0.639c-3.107-0.038-5.408%2C1.189-6.022%2C1.956C-276.17%2C419.163-278.817%2C418.817-281.655%2C419.661z%22%2F%3E%3Cpath%20d%3D%22M-278.663%2C415.979c1.458-0.767%2C2.864-0.857%2C5.063%2C0c1.189-0.652%2C3.414-0.307%2C4.68%2C0.269c-3.145-0.23-4.104%2C0.422-4.68%2C0.69%09C-274.367%2C416.056-276.86%2C415.595-278.663%2C415.979z%22%2F%3E%3Cg%3E%3Cpath%20d%3D%22M-281.721%2C425.011c0-0.465%2C0.07-0.855%2C0.209-1.172c0.104-0.232%2C0.246-0.441%2C0.425-0.626s0.376-0.322%2C0.59-0.411%20c0.285-0.121%2C0.613-0.181%2C0.985-0.181c0.673%2C0%2C1.212%2C0.208%2C1.616%2C0.626c0.404%2C0.418%2C0.606%2C0.998%2C0.606%2C1.742%20c0%2C0.737-0.2%2C1.314-0.601%2C1.731c-0.401%2C0.417-0.938%2C0.625-1.608%2C0.625c-0.679%2C0-1.22-0.207-1.621-0.622%09C-281.521%2C426.31-281.721%2C425.739-281.721%2C425.011z%20M-280.771%2C424.981c0%2C0.517%2C0.119%2C0.909%2C0.358%2C1.176%09c0.239%2C0.268%2C0.542%2C0.4%2C0.91%2C0.4c0.368%2C0%2C0.669-0.132%2C0.905-0.397c0.236-0.265%2C0.354-0.662%2C0.354-1.191%09c0-0.523-0.115-0.914-0.344-1.172s-0.535-0.387-0.915-0.387c-0.38%2C0-0.687%2C0.131-0.919%2C0.392%20C-280.654%2C424.062-280.771%2C424.455-280.771%2C424.981z%22%2F%3E%3Cpath%20d%3D%22M-276.573%2C422.699h1.686c0.38%2C0%2C0.67%2C0.029%2C0.87%2C0.088c0.267%2C0.079%2C0.498%2C0.219%2C0.689%2C0.421%20c0.191%2C0.201%2C0.336%2C0.448%2C0.436%2C0.74s0.15%2C0.651%2C0.15%2C1.079c0%2C0.377-0.047%2C0.7-0.141%2C0.973c-0.114%2C0.333-0.277%2C0.602-0.489%2C0.808%20c-0.16%2C0.155-0.376%2C0.277-0.648%2C0.364c-0.204%2C0.064-0.476%2C0.097-0.816%2C0.097h-1.736V422.699z%20M-275.65%2C423.472v3.026h0.689%20c0.257%2C0%2C0.443-0.015%2C0.558-0.044c0.149-0.037%2C0.274-0.101%2C0.373-0.19c0.099-0.089%2C0.18-0.236%2C0.241-0.44%20c0.062-0.205%2C0.094-0.483%2C0.094-0.837s-0.031-0.624-0.094-0.813c-0.062-0.189-0.149-0.337-0.262-0.442%20c-0.112-0.106-0.254-0.178-0.427-0.215c-0.129-0.029-0.381-0.044-0.757-0.044H-275.65z%22%2F%3E%3Cpath%20d%3D%22M-271.96%2C427.268v-4.569h1.479c0.562%2C0%2C0.927%2C0.023%2C1.098%2C0.069c0.262%2C0.068%2C0.48%2C0.218%2C0.657%2C0.447%20s0.265%2C0.525%2C0.265%2C0.89c0%2C0.28-0.051%2C0.516-0.152%2C0.707s-0.231%2C0.342-0.388%2C0.45c-0.157%2C0.109-0.316%2C0.182-0.479%2C0.217%09c-0.221%2C0.044-0.539%2C0.065-0.957%2C0.065h-0.602v1.724H-271.96z%20M-271.038%2C423.472v1.297h0.505c0.363%2C0%2C0.606-0.024%2C0.729-0.072%20c0.122-0.048%2C0.219-0.122%2C0.288-0.225c0.069-0.102%2C0.104-0.22%2C0.104-0.354c0-0.167-0.049-0.304-0.146-0.412%09c-0.098-0.107-0.222-0.176-0.371-0.202c-0.109-0.021-0.331-0.031-0.663-0.031H-271.038z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} .navbar i.icon.icon-undo { width: 22px; height: 22px; @@ -6335,4 +6340,3 @@ html.pixel-ratio-3 .numbers li { height: 100%; background-size: contain; } -/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvaW50cm8ubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvZ3JpZC5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9fbWl4aW5zLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3ZpZXdzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3BhZ2VzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3Rvb2xiYXJzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3Rvb2xiYXJzLXBhZ2VzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3NlYXJjaGJhci5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9tZXNzYWdlYmFyLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2ljb25zLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2JhZGdlcy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9jb250ZW50LWJsb2NrLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2xpc3RzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2Zvcm1zLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2Zsb2F0aW5nLWJ1dHRvbi5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9tb2RhbHMubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcmlwcGxlLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL2FwcHMvY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9tYXRlcmlhbC9fYnV0dG9uLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3BhbmVscy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC90YWJzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL21lc3NhZ2VzLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3N0YXR1c2Jhci5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9wcmVsb2FkZXIubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcHJvZ3Jlc3NiYXIubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcGlja2VyLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL25vdGlmaWNhdGlvbnMubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvZGlzYWJsZWQubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvYXBwcy9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL21hdGVyaWFsL19jb250YWluZXIubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvYXBwcy9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL21hdGVyaWFsL19kYXRhdmlldy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy9hcHBzL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvbWF0ZXJpYWwvX2xpc3R2aWV3Lmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL2FwcHMvY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9tYXRlcmlhbC9fY29udGV4dG1lbnUubGVzcyIsIi9Wb2x1bWVzL1N0b3JhZ2UvRGV2ZWxvcC9SZXBvc2l0b3JpZXMvd2ViLWFwcHMvYXBwcy9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL21hdGVyaWFsL19jb2xvci1wYWxldHRlLmxlc3MiLCIvVm9sdW1lcy9TdG9yYWdlL0RldmVsb3AvUmVwb3NpdG9yaWVzL3dlYi1hcHBzL2FwcHMvY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9tYXRlcmlhbC9fYWJvdXQubGVzcyIsIm1hdGVyaWFsL19zZWFyY2gubGVzcyIsIm1hdGVyaWFsL19pY29ucy5sZXNzIiwiL1ZvbHVtZXMvU3RvcmFnZS9EZXZlbG9wL1JlcG9zaXRvcmllcy93ZWItYXBwcy9hcHBzL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvX21peGlucy5sZXNzIiwiYXBwLW1hdGVyaWFsLmxlc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0E7QUFBTTtBQUFNO0VBQ1Isa0JBQUE7RUFDQSxZQUFBO0VBQ0EsV0FBQTtFQUNBLGtCQUFBOztBQUVKO0VBQ0ks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RTtBQXJCSixRQUtFLEdBZ0JFO0VBQ0UsV0FBQTtFQUNBLFlBQUE7RUFDQSx5QkFBQTtFQUNBLHNCQUFBOztBQTFCTixRQU1FLEdBZ0JFLE9BTUU7QUEzQk4sUUFLRSxHQWdCRSxPQU1FO0VBQ0UsV0FBQTtFQUNBLGtCQUFBO0VBQ0Esa0JBQUE7RUFDQSxRQUFBOztBQVFSLGFBQ0U7RUFDSSxtQkFBQTs7QUFGTixhQUtFO0VBQ0UsU0FBQTtFQUNBLFlBQUE7O0FBUEosYUFLRSxHQUlFO0VBQ0UseUNBQUE7O0FBT04sWUFDRTtFQUNFLGdCQUFBO0VBQ0EsbUJBQUE7O0FBSEosWUFDRSxLQUlFO0VBQ0UsU0FBQTtFQUNBLFlBQUE7RUFDQSx5Q0FBQTtFQUNBLFdBQUE7RUFDQSxZQUFBOztBQU9OLFlBQ0U7RUFDRSxXQUFBO0VBQ0EsWUFBQTtFQUNBLFdBQUE7O0FBSkosWUFDRSxHQUtFO0VBQ0UsV0FBQTtFQUNBLFlBQUE7RUFDQSx3QkFBQSIsInNvdXJjZXNDb250ZW50IjpbIkBpbWdCYXNlVXJsOiBcIi4uL2ltZ1wiO1xuaHRtbCwgYm9keSwgLmZyYW1ld29yazctcm9vdCB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBvdmVyZmxvdy14OiBoaWRkZW47XG59XG5ib2R5IHtcbiAgICBmb250LWZhbWlseTogUm9ib3RvLCBOb3RvLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmO1xuICAgIG1hcmdpbjogMDtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGNvbG9yOiAjMjEyMTIxO1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICBsaW5lLWhlaWdodDogMS41O1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIC13ZWJraXQtdGV4dC1zaXplLWFkanVzdDoxMDAlO1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cbi5mcmFtZXdvcms3LXJvb3Qge1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG59XG4qIHtcbiAgICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMCwwLDAsMCk7XG4gICAgLXdlYmtpdC10b3VjaC1jYWxsb3V0Om5vbmU7XG59XG5hLCBpbnB1dCwgdGV4dGFyZWEsIHNlbGVjdCB7XG4gICAgb3V0bGluZTogMDtcbn1cblxuYSB7XG4gICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgIGNvbG9yOiBAdGhlbWVDb2xvcjtcbn1cbnAge1xuICAgIG1hcmdpbjogMWVtIDA7XG59IiwiLyogPT09IEdyaWQgPT09ICovXG4ucm93IHtcbiAgICAuZmxleGJveCgpO1xuICAgIC5qdXN0aWZ5LWNvbnRlbnQoc3BhY2UtYmV0d2Vlbik7XG4gICAgLmZsZXgtd3JhcCh3cmFwKTtcbiAgICAuYWxpZ24taXRlbXMoZmxleC1zdGFydCk7XG4gICAgPiBbY2xhc3MqPVwiY29sLVwiXSB7XG4gICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgfVxufVxuQGNvbHM6IDUsIDEwLCAxNSwgMjAsIDI1LCAzMCwgMTAwLzMsIDM1LCA0MCwgNDUsIDUwLCA1NSwgNjAsIDY1LCAxMDAqKDIvMyksIDcwLCA3NSwgODAsIDg1LCA5MCwgOTUsIDEwMDtcbi5yb3cge1xuICAgIC5jb2wtYXV0byB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgIH1cbiAgICAuLShAaTogbGVuZ3RoKEBjb2xzKSkgd2hlbiAoQGkgPiAwKSB7XG4gICAgICAgIEBkaXZpZGVyOiBlKGV4dHJhY3QoQGNvbHMsIEBpKSk7XG4gICAgICAgIEBjbGFzc05hbWU6IGBNYXRoLmZsb29yKEB7ZGl2aWRlcn0pYDtcbiAgICAgICAgQG46IGAxMDAvcGFyc2VGbG9hdChAe2RpdmlkZXJ9KWA7XG4gICAgICAgIEBuLTE6IEBuIC0gMTtcbiAgICAgICAgLmNvbC1Ae2NsYXNzTmFtZX0ge1xuICAgICAgICAgICAgd2lkdGg6IH5cIkB7ZGl2aWRlcn0lXCI7XG4gICAgICAgICAgICB3aWR0aDogflwiLXdlYmtpdC1jYWxjKCgxMDAlIC0gMTZweCpAe24tMX0pIC8gQHtufSlcIjsgICBcbiAgICAgICAgICAgIHdpZHRoOiB+XCJjYWxjKCgxMDAlIC0gMTZweCpAe24tMX0pIC8gQHtufSlcIjsgICBcbiAgICAgICAgfVxuICAgICAgICAmLm5vLWd1dHRlciB7XG4gICAgICAgICAgICAuY29sLUB7Y2xhc3NOYW1lfSB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IH5cIkB7ZGl2aWRlcn0lXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLi0oKEBpIC0gMSkpO1xuICAgIH0gLi07XG4gICAgLi0tKEBqOiAxKSB3aGVuIChAaiA8IGxlbmd0aChAY29scykpIHtcbiAgICAgICAgQGRpdmlkZXI6IGUoZXh0cmFjdChAY29scywgQGopKTtcbiAgICAgICAgQGNsYXNzTmFtZTogYE1hdGguZmxvb3IoQHtkaXZpZGVyfSlgO1xuICAgICAgICAuY29sLWF1dG86bnRoLWxhc3QtY2hpbGQoQHtqfSksIC5jb2wtYXV0bzpudGgtbGFzdC1jaGlsZChAe2p9KSB+IC5jb2wtYXV0byB7XG4gICAgICAgICAgICBAai0xOiBAaiAtIDE7ICBcbiAgICAgICAgICAgIHdpZHRoOiAxMDAlIC8gQGo7XG4gICAgICAgICAgICB3aWR0aDogflwiLXdlYmtpdC1jYWxjKCgxMDAlIC0gMTZweCpAe2otMX0pIC8gQHtqfSlcIjsgICBcbiAgICAgICAgICAgIHdpZHRoOiB+XCJjYWxjKCgxMDAlIC0gMTZweCpAe2otMX0pIC8gQHtqfSlcIjsgICBcbiAgICAgICAgfVxuICAgICAgICAmLm5vLWd1dHRlciB7XG4gICAgICAgICAgICAuY29sLWF1dG86bnRoLWxhc3QtY2hpbGQoQHtqfSksIC5jb2wtYXV0bzpudGgtbGFzdC1jaGlsZChAe2p9KSB+IC5jb2wtYXV0byB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCUgLyBAajtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAuLS0oKEBqICsgMSkpO1xuICAgIH0gLi0tO1xuICAgIFxufVxuXG5AbWVkaWEgYWxsIGFuZCAobWluLXdpZHRoOjc2OHB4KSB7XG4gICAgLnJvdyB7XG4gICAgICAgIC4tKEBpOiBsZW5ndGgoQGNvbHMpKSB3aGVuIChAaSA+IDApIHtcbiAgICAgICAgICAgIEBkaXZpZGVyOiBlKGV4dHJhY3QoQGNvbHMsIEBpKSk7XG4gICAgICAgICAgICBAY2xhc3NOYW1lOiBgTWF0aC5mbG9vcihAe2RpdmlkZXJ9KWA7XG4gICAgICAgICAgICBAbjogYDEwMC9wYXJzZUZsb2F0KEB7ZGl2aWRlcn0pYDtcbiAgICAgICAgICAgIEBuLTE6IEBuIC0gMTtcbiAgICAgICAgICAgIC50YWJsZXQtQHtjbGFzc05hbWV9IHtcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiQHtkaXZpZGVyfSVcIjtcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiLXdlYmtpdC1jYWxjKCgxMDAlIC0gMTZweCpAe24tMX0pIC8gQHtufSlcIjsgICBcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiY2FsYygoMTAwJSAtIDE2cHgqQHtuLTF9KSAvIEB7bn0pXCI7ICAgXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmLm5vLWd1dHRlciB7XG4gICAgICAgICAgICAgICAgLnRhYmxldC1Ae2NsYXNzTmFtZX0ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogflwiQHtkaXZpZGVyfSVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAuLSgoQGkgLSAxKSk7XG4gICAgICAgIH0gLi07XG4gICAgICAgIC4tLShAajogMSkgd2hlbiAoQGogPCBsZW5ndGgoQGNvbHMpKSB7XG4gICAgICAgICAgICAudGFibGV0LWF1dG86bnRoLWxhc3QtY2hpbGQoQHtqfSksIC50YWJsZXQtYXV0bzpudGgtbGFzdC1jaGlsZChAe2p9KSB+IC5jb2wtYXV0byB7XG4gICAgICAgICAgICAgICAgQGotMTogQGogLSAxOyAgXG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCUgLyBAajtcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiLXdlYmtpdC1jYWxjKCgxMDAlIC0gMTZweCpAe2otMX0pIC8gQHtqfSlcIjsgICBcbiAgICAgICAgICAgICAgICB3aWR0aDogflwiY2FsYygoMTAwJSAtIDE2cHgqQHtqLTF9KSAvIEB7an0pXCI7ICAgXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmLm5vLWd1dHRlciB7XG4gICAgICAgICAgICAgICAgLnRhYmxldC1hdXRvOm50aC1sYXN0LWNoaWxkKEB7an0pLCAudGFibGV0LWF1dG86bnRoLWxhc3QtY2hpbGQoQHtqfSkgfiAudGFibGV0LWF1dG8ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDogMTAwJSAvIEBqO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC4tLSgoQGogKyAxKSk7XG4gICAgICAgIH0gLi0tO1xuICAgIH1cblxufVxuIiwiLnRyYW5zaXRpb24oQGQpIHtcbiAgICAtd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb246IEBkO1xuICAgIHRyYW5zaXRpb24tZHVyYXRpb246IEBkO1xufVxuLmRlbGF5KEBkKSB7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uLWRlbGF5OiBAZDtcbiAgICB0cmFuc2l0aW9uLWRlbGF5OiBAZDtcbn1cbi50cmFuc2Zvcm0oQHQpIHtcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogQHQ7XG4gICAgdHJhbnNmb3JtOiBAdDtcbn1cbi50cmFuc2Zvcm0tb3JpZ2luKEB0bykge1xuICAgIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogQHRvO1xuICAgIHRyYW5zZm9ybS1vcmlnaW46IEB0bztcbn1cbi50cmFuc2xhdGUzZChAeDowLCBAeTowLCBAejowKSB7XG4gICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKEB4LEB5LEB6KTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKEB4LEB5LEB6KTtcbn1cbi5hbmltYXRpb24oQGEpIHtcbiAgICAtd2Via2l0LWFuaW1hdGlvbjogQGE7XG4gICAgYW5pbWF0aW9uOiBAYTtcbn1cbi5zY3JvbGxhYmxlKCl7XG4gICAgb3ZlcmZsb3c6IGF1dG87XG4gICAgLXdlYmtpdC1vdmVyZmxvdy1zY3JvbGxpbmc6IHRvdWNoO1xufVxuLmZsZXhib3goKSB7XG4gICAgZGlzcGxheTogLXdlYmtpdC1ib3g7XG4gICAgZGlzcGxheTogLW1zLWZsZXhib3g7XG4gICAgZGlzcGxheTogLXdlYmtpdC1mbGV4O1xuICAgIGRpc3BsYXk6IGZsZXg7XG59XG4uZmxleGJveC1pbmxpbmUoKSB7XG4gICAgZGlzcGxheTogLXdlYmtpdC1pbmxpbmUtYm94O1xuICAgIGRpc3BsYXk6IC1tcy1pbmxpbmUtZmxleGJveDtcbiAgICBkaXNwbGF5OiAtd2Via2l0LWlubGluZS1mbGV4O1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xufVxuLmZsZXgtd3JhcChAZncpIHdoZW4gKEBmdyA9IG5vd3JhcCkge1xuICAgIC13ZWJraXQtYm94LWxpbmVzOiBzaW5nbGU7XG4gICAgLW1vei1ib3gtbGluZXM6IHNpbmdsZTtcbiAgICAtd2Via2l0LWZsZXgtd3JhcDogbm93cmFwO1xuICAgIC1tcy1mbGV4LXdyYXA6IG5vbmU7XG4gICAgLW1zLWZsZXgtd3JhcDogbm93cmFwO1xuICAgIGZsZXgtd3JhcDogbm93cmFwO1xufVxuLmZsZXgtd3JhcChAZncpIHdoZW4gKEBmdyA9IHdyYXApIHtcbiAgICAtd2Via2l0LWJveC1saW5lczogbXVsdGlwbGU7XG4gICAgLW1vei1ib3gtbGluZXM6IG11bHRpcGxlO1xuICAgIC13ZWJraXQtZmxleC13cmFwOiB3cmFwO1xuICAgIC1tcy1mbGV4LXdyYXA6IHdyYXA7XG4gICAgZmxleC13cmFwOiB3cmFwO1xufVxuLmZsZXgtd3JhcChAZncpIHdoZW4gbm90IChAZncgPSB3cmFwKSBhbmQgbm90IChAZncgPSBub3dyYXApIHtcbiAgICAtd2Via2l0LWZsZXgtd3JhcDogQGZ3O1xuICAgIC1tcy1mbGV4LXdyYXA6IEBmdztcbiAgICBmbGV4LXdyYXA6IEBmdztcbn1cbi5mbGV4LXNocmluayhAZnMpIHtcbiAgICAtd2Via2l0LWJveC1mbGV4OiBAZnM7XG4gICAgLXdlYmtpdC1mbGV4LXNocmluazogQGZzO1xuICAgIC1tcy1mbGV4OiAwIEBmcyBhdXRvO1xuICAgIGZsZXgtc2hyaW5rOiBAZnM7XG59XG4uanVzdGlmeS1jb250ZW50KEBqYykgd2hlbiAoQGpjID0gZmxleC1zdGFydCkge1xuICAgIC13ZWJraXQtYm94LXBhY2s6IHN0YXJ0O1xuICAgIC1tcy1mbGV4LXBhY2s6IHN0YXJ0O1xuICAgIC13ZWJraXQtanVzdGlmeS1jb250ZW50OiBmbGV4LXN0YXJ0O1xuICAgIGp1c3RpZnktY29udGVudDogZmxleC1zdGFydDtcbn1cbi5qdXN0aWZ5LWNvbnRlbnQoQGpjKSB3aGVuIChAamMgPSBmbGV4LWVuZCkge1xuICAgIC13ZWJraXQtYm94LXBhY2s6IGVuZDtcbiAgICAtbXMtZmxleC1wYWNrOiBlbmQ7XG4gICAgLXdlYmtpdC1qdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xuICAgIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG59XG4uanVzdGlmeS1jb250ZW50KEBqYykgd2hlbiAoQGpjID0gc3BhY2UtYmV0d2Vlbikge1xuICAgIC13ZWJraXQtYm94LXBhY2s6IGp1c3RpZnk7XG4gICAgLW1zLWZsZXgtcGFjazoganVzdGlmeTtcbiAgICAtd2Via2l0LWp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG59XG4uanVzdGlmeS1jb250ZW50KEBqYykgd2hlbiBub3QgKEBqYyA9IGZsZXgtc3RhcnQpIGFuZCBub3QgKEBqYyA9IGZsZXgtZW5kKSBhbmQgbm90IChAamMgPSBzcGFjZS1iZXR3ZWVuKSB7XG4gICAgLXdlYmtpdC1ib3gtcGFjazogQGpjO1xuICAgIC1tcy1mbGV4LXBhY2s6IEBqYztcbiAgICAtd2Via2l0LWp1c3RpZnktY29udGVudDogQGpjO1xuICAgIGp1c3RpZnktY29udGVudDogQGpjO1xufVxuLmFsaWduLWl0ZW1zKEBhaSkgd2hlbiAoQGFpID0gZmxleC1zdGFydCkge1xuICAgIC13ZWJraXQtYm94LWFsaWduOiBzdGFydDtcbiAgICAtbXMtZmxleC1hbGlnbjogc3RhcnQ7XG4gICAgLXdlYmtpdC1hbGlnbi1pdGVtczogZmxleC1zdGFydDtcbiAgICBhbGlnbi1pdGVtczogZmxleC1zdGFydDtcbn1cbi5hbGlnbi1pdGVtcyhAYWkpIHdoZW4gKEBhaSA9IGZsZXgtZW5kKSB7XG4gICAgLXdlYmtpdC1ib3gtYWxpZ246IGVuZDtcbiAgICAtbXMtZmxleC1hbGlnbjogZW5kO1xuICAgIC13ZWJraXQtYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICAgIGFsaWduLWl0ZW1zOiBmbGV4LWVuZDtcbn1cbi5hbGlnbi1pdGVtcyhAYWkpIHdoZW4gbm90IChAYWkgPSBmbGV4LXN0YXJ0KSBhbmQgbm90IChAYWkgPSBmbGV4LWVuZCkge1xuICAgIC13ZWJraXQtYm94LWFsaWduOiBAYWk7XG4gICAgLW1zLWZsZXgtYWxpZ246IEBhaTtcbiAgICAtd2Via2l0LWFsaWduLWl0ZW1zOiBAYWk7XG4gICAgYWxpZ24taXRlbXM6IEBhaTtcbn1cbi5hbGlnbi1jb250ZW50KEBhaSkge1xuICAgIC1tcy1mbGV4LWxpbmUtcGFjazogQGFpO1xuICAgIC13ZWJraXQtYWxpZ24tY29udGVudDogQGFpO1xuICAgIGFsaWduLWNvbnRlbnQ6IEBhaTtcbn1cbi5hbGlnbi1zZWxmKEBhcykge1xuICAgIC1tcy1mbGV4LWl0ZW0tYWxpZ246IEBhcztcbiAgICAtd2Via2l0LWFsaWduLXNlbGY6IEBhcztcbiAgICBhbGlnbi1zZWxmOiBAYXM7XG59XG4uY2xlYXJmaXgoKSB7XG4gICAgJjpiZWZvcmUsXG4gICAgJjphZnRlciB7XG4gICAgICAgIGNvbnRlbnQ6IFwiIFwiO1xuICAgICAgICBkaXNwbGF5OiB0YWJsZTtcbiAgICB9XG4gICAgJjphZnRlciB7XG4gICAgICAgIGNsZWFyOiBib3RoO1xuICAgIH1cbn1cbi5oYWlybGluZShAcG9zaXRpb24sIEBjb2xvcikgd2hlbiAoQHBvc2l0aW9uID0gdG9wKSB7XG4gICAgJjpiZWZvcmUge1xuICAgICAgICBjb250ZW50OiAnJztcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICBsZWZ0OiAwO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIGJvdHRvbTogYXV0bztcbiAgICAgICAgcmlnaHQ6IGF1dG87XG4gICAgICAgIGhlaWdodDogMXB4O1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQGNvbG9yO1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgei1pbmRleDogMTU7XG4gICAgICAgIC50cmFuc2Zvcm0tb3JpZ2luKDUwJSAwJSk7XG4gICAgICAgIGh0bWwucGl4ZWwtcmF0aW8tMiAme1xuICAgICAgICAgICAgLnRyYW5zZm9ybShzY2FsZVkoMC41KSk7XG4gICAgICAgIH1cbiAgICAgICAgaHRtbC5waXhlbC1yYXRpby0zICZ7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlWSgwLjMzKSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4uaGFpcmxpbmUoQHBvc2l0aW9uLCBAY29sb3IpIHdoZW4gKEBwb3NpdGlvbiA9IGxlZnQpIHtcbiAgICAmOmJlZm9yZSB7XG4gICAgICAgIGNvbnRlbnQ6ICcnO1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgYm90dG9tOiBhdXRvO1xuICAgICAgICByaWdodDogYXV0bztcbiAgICAgICAgd2lkdGg6IDFweDtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAY29sb3I7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB6LWluZGV4OiAxNTtcbiAgICAgICAgLnRyYW5zZm9ybS1vcmlnaW4oMCUgNTAlKTtcbiAgICAgICAgaHRtbC5waXhlbC1yYXRpby0yICZ7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlWCgwLjUpKTtcbiAgICAgICAgfVxuICAgICAgICBodG1sLnBpeGVsLXJhdGlvLTMgJntcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGVYKDAuMzMpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi5oYWlybGluZShAcG9zaXRpb24sIEBjb2xvcikgd2hlbiAoQHBvc2l0aW9uID0gYm90dG9tKSB7XG4gICAgJjphZnRlciB7XG4gICAgICAgIGNvbnRlbnQ6ICcnO1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIGJvdHRvbTogMDtcbiAgICAgICAgcmlnaHQ6IGF1dG87XG4gICAgICAgIHRvcDogYXV0bztcbiAgICAgICAgaGVpZ2h0OiAxcHg7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAY29sb3I7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB6LWluZGV4OiAxNTtcbiAgICAgICAgLnRyYW5zZm9ybS1vcmlnaW4oNTAlIDEwMCUpO1xuICAgICAgICBodG1sLnBpeGVsLXJhdGlvLTIgJntcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGVZKDAuNSkpO1xuICAgICAgICB9XG4gICAgICAgIGh0bWwucGl4ZWwtcmF0aW8tMyAme1xuICAgICAgICAgICAgLnRyYW5zZm9ybShzY2FsZVkoMC4zMykpO1xuICAgICAgICB9XG4gICAgfVxufVxuLmhhaXJsaW5lKEBwb3NpdGlvbiwgQGNvbG9yKSB3aGVuIChAcG9zaXRpb24gPSByaWdodCkge1xuICAgICY6YWZ0ZXIge1xuICAgICAgICBjb250ZW50OiAnJztcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICByaWdodDogMDtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICBsZWZ0OiBhdXRvO1xuICAgICAgICBib3R0b206IGF1dG87XG4gICAgICAgIHdpZHRoOiAxcHg7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQGNvbG9yO1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgei1pbmRleDogMTU7XG4gICAgICAgIC50cmFuc2Zvcm0tb3JpZ2luKDEwMCUgNTAlKTtcbiAgICAgICAgaHRtbC5waXhlbC1yYXRpby0yICZ7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlWCgwLjUpKTtcbiAgICAgICAgfVxuICAgICAgICBodG1sLnBpeGVsLXJhdGlvLTMgJntcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGVYKDAuMzMpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIEZvciByaWdodCBhbmQgYm90dG9tXG4uaGFpcmxpbmUtcmVtb3ZlKEBwb3NpdGlvbikgd2hlbiBub3QgKEBwb3NpdGlvbiA9IGxlZnQpIGFuZCBub3QgKEBwb3NpdGlvbiA9IHRvcCkge1xuICAgICY6YWZ0ZXIge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbn1cbi8vIEZvciBsZWZ0IGFuZCB0b3Bcbi5oYWlybGluZS1yZW1vdmUoQHBvc2l0aW9uKSB3aGVuIG5vdCAoQHBvc2l0aW9uID0gcmlnaHQpIGFuZCBub3QgKEBwb3NpdGlvbiA9IGJvdHRvbSkge1xuICAgICY6YmVmb3JlIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG59XG4vLyBGb3IgcmlnaHQgYW5kIGJvdHRvbVxuLmhhaXJsaW5lLWNvbG9yKEBwb3NpdGlvbiwgQGNvbG9yKSB3aGVuIG5vdCAoQHBvc2l0aW9uID0gbGVmdCkgYW5kIG5vdCAoQHBvc2l0aW9uID0gdG9wKSB7XG4gICAgJjphZnRlciB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IEBjb2xvcjtcbiAgICB9XG59XG4vLyBGb3IgbGVmdCBhbmQgdG9wXG4uaGFpcmxpbmUtY29sb3IoQHBvc2l0aW9uLCBAY29sb3IpIHdoZW4gbm90IChAcG9zaXRpb24gPSByaWdodCkgYW5kIG5vdCAoQHBvc2l0aW9uID0gYm90dG9tKSB7XG4gICAgJjpiZWZvcmUge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAY29sb3I7XG4gICAgfVxufVxuXG4vLyBFbmNvZGVkIFNWRyBCYWNrZ3JvdW5kXG4uZW5jb2RlZC1zdmctYmFja2dyb3VuZChAc3ZnKSB7XG4gICAgQHVybDogYGVuY29kZVVSSUNvbXBvbmVudChAe3N2Z30pYDtcbiAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoXCJkYXRhOmltYWdlL3N2Zyt4bWw7Y2hhcnNldD11dGYtOCxAe3VybH1cIik7XG59XG5cbi8vIFByZXNlcnZlM0Rcbi5wcmVzZXJ2ZTNkKCkge1xuICAgIC13ZWJraXQtdHJhbnNmb3JtLXN0eWxlOiBwcmVzZXJ2ZS0zZDtcbiAgICAtbW96LXRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgLW1zLXRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgdHJhbnNmb3JtLXN0eWxlOiBwcmVzZXJ2ZS0zZDtcbn1cblxuLy8gU2hhZG93XG4uZGVwdGgoQGxldmVsOjEpIHtcbiAgICAmIHdoZW4gKEBsZXZlbCA9IDEpIHtcbiAgICAgICAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwwLDAsMC4xMiksIDAgMXB4IDJweCByZ2JhKDAsMCwwLDAuMjQpO1xuICAgIH1cbiAgICAmIHdoZW4gKEBsZXZlbCA9IDIpIHtcbiAgICAgICAgYm94LXNoYWRvdzogMCAzcHggNnB4IHJnYmEoMCwwLDAsMC4xNiksIDAgM3B4IDZweCByZ2JhKDAsMCwwLDAuMjMpO1xuICAgIH1cbiAgICAmIHdoZW4gKEBsZXZlbCA9IDMpIHtcbiAgICAgICAgYm94LXNoYWRvdzogMCAxMHB4IDIwcHggcmdiYSgwLDAsMCwwLjE5KSwgMCA2cHggNnB4IHJnYmEoMCwwLDAsMC4yMyk7XG4gICAgfVxuICAgICYgd2hlbiAoQGxldmVsID0gNCkge1xuICAgICAgICBib3gtc2hhZG93OiAwIDE0cHggMjhweCByZ2JhKDAsMCwwLDAuMjUpLCAwIDEwcHggMTBweCByZ2JhKDAsMCwwLDAuMjIpO1xuICAgIH1cbiAgICAmIHdoZW4gKEBsZXZlbCA9IDUpIHtcbiAgICAgICAgYm94LXNoYWRvdzogMCAxOXB4IDM4cHggcmdiYSgwLDAsMCwwLjMwKSwgMCAxNXB4IDEycHggcmdiYSgwLDAsMCwwLjIyKTtcbiAgICB9XG59XG5cbi8vIEhpZ2hsaWdodGVkIExpbmtzXG4uYWN0aXZlLWhpZ2hsaWdodChAY29sb3I6cmdiYSgyNTUsMjU1LDI1NSwwLjE1KSkge1xuICAgICY6YmVmb3JlIHtcbiAgICAgICAgY29udGVudDogJyc7XG4gICAgICAgIHdpZHRoOiAxNTIlO1xuICAgICAgICBoZWlnaHQ6IDE1MiU7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgbGVmdDogLTI2JTtcbiAgICAgICAgdG9wOiAtMjYlO1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiAtd2Via2l0LXJhZGlhbC1ncmFkaWVudChjZW50ZXIsIGNpcmNsZSBjb3ZlciwgQGNvbG9yIDY2JSwgcmdiYShyZWQoQGNvbG9yKSxncmVlbihAY29sb3IpLGJsdWUoQGNvbG9yKSwwKSA2NiUpO1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiByYWRpYWwtZ3JhZGllbnQoY2lyY2xlIGF0IGNlbnRlciwgQGNvbG9yIDY2JSwgcmdiYShyZWQoQGNvbG9yKSxncmVlbihAY29sb3IpLGJsdWUoQGNvbG9yKSwwKSA2NiUpO1xuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7XG4gICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTAwJSAxMDAlO1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgICAgLnRyYW5zaXRpb24oNjAwbXMpO1xuICAgIH1cbiAgICBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZTpiZWZvcmUsICYuYWN0aXZlLXN0YXRlOmJlZm9yZSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIC50cmFuc2l0aW9uKDE1MG1zKTtcbiAgICB9XG59XG4uYWN0aXZlLWhpZ2hsaWdodC1jb2xvcihAY29sb3IpIHtcbiAgICAmOmJlZm9yZSB7XG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtcmFkaWFsLWdyYWRpZW50KGNlbnRlciwgY2lyY2xlIGNvdmVyLCBAY29sb3IgNjYlLCByZ2JhKHJlZChAY29sb3IpLGdyZWVuKEBjb2xvciksYmx1ZShAY29sb3IpLDApIDY2JSk7XG4gICAgICAgIGJhY2tncm91bmQtaW1hZ2U6IHJhZGlhbC1ncmFkaWVudChjaXJjbGUgYXQgY2VudGVyLCBAY29sb3IgNjYlLCByZ2JhKHJlZChAY29sb3IpLGdyZWVuKEBjb2xvciksYmx1ZShAY29sb3IpLDApIDY2JSk7XG4gICAgfVxufVxuXG4vLyBObyBTY3JvbGxiYXJcbi5uby1zY3JvbGxiYXIoKSB7XG4gICAgJjo6LXdlYmtpdC1zY3JvbGxiYXIge1xuICAgICAgICBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG4gICAgICAgIHdpZHRoOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIGhlaWdodDogMCAhaW1wb3J0YW50O1xuICAgICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIG9wYWNpdHk6IDAgIWltcG9ydGFudDtcbiAgICB9XG59XG5cbi8vIEJhcnMgSW5wdXRcbi5iYXJzLWlucHV0KCkge1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAzMnB4O1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgLW1vei1hcHBlYXJhbmNlOiBub25lO1xuICAgIC1tcy1hcHBlYXJhbmNlOiBub25lO1xuICAgIGFwcGVhcmFuY2U6IG5vbmU7XG4gICAgYm9yZGVyLXJhZGl1czogMDtcbiAgICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgICBjb2xvcjogI2ZmZjtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZmZmO1xuICAgICY6Oi13ZWJraXQtaW5wdXQtcGxhY2Vob2xkZXIge1xuICAgICAgICBjb2xvcjogcmdiYSgyNTUsMjU1LDI1NSwxKTtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG59XG4ubm8taGFpcmxpbmVzKCkge1xuICAgICYubm8taGFpcmxpbmVzLCAmLm5vLWhhaXJsaW5lcyB1bCwgJi5uby1oYWlybGluZXMgLmNvbnRlbnQtYmxvY2staW5uZXIge1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICB9XG59XG4ubm8taGFpcmxpbmVzLWJldHdlZW4oKSB7XG4gICAgJi5uby1oYWlybGluZXMtYmV0d2VlbiB7XG4gICAgICAgIC5pdGVtLWlubmVyLCAubGlzdC1idXR0b24sIC5pdGVtLWRpdmlkZXIsIC5saXN0LWdyb3VwLXRpdGxlLCAubGlzdC1ncm91cC10aXRsZSB7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgIH1cbiAgICB9XG59IiwiLyogPT09IFZpZXdzID09PSAqL1xuLnZpZXdzLCAudmlldyB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICB6LWluZGV4OiA1MDAwO1xufVxuLnZpZXdzIHtcbiAgICAuc2Nyb2xsYWJsZSgpO1xufVxuLnZpZXcge1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbn1cbiIsIi8qID09PSBQYWdlcyA9PT0gKi9cblxuLy8gUGFnZXMgYW5pbWF0aW9uc1xuQHBhZ2VEdXJhdGlvbjogMzAwbXM7XG5AbmV3UGFnZU9mZnNldDogNTZweDtcblxuLnBhZ2VzIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG59XG4ucGFnZSB7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAmLmNhY2hlZCB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxufVxuLnBhZ2Utb24tbGVmdCB7XG4gICAgb3BhY2l0eTogMTtcbiAgICAudHJhbnNsYXRlM2QoMCwwLDApO1xufVxuLnBhZ2Utb24tcmlnaHQge1xuICAgIG9wYWNpdHk6IDA7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgLnRyYW5zbGF0ZTNkKDAsIEBuZXdQYWdlT2Zmc2V0LCAwKTtcbn1cbi5wYWdlLWNvbnRlbnQge1xuICAgIC5zY3JvbGxhYmxlKCk7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHotaW5kZXg6IDE7XG59XG5cbi8vQ2xhc3MgdGhhdCB3aWxsIHRyaWdnZXIgdHJhbnNpdGlvbiBkdXJpbmcgcGFnZSBjdXN0b20gdHJhbnNpdGlvbnMgKGxpa2Ugc3dpcGUtYmFjaylcbi5wYWdlLXRyYW5zaXRpb25pbmcge1xuICAgIC50cmFuc2l0aW9uKEBwYWdlRHVyYXRpb24pO1xufVxuLy8gRnJvbS90byBSaWdodCBUby9mcm9tIENlbnRlciBhbmltYXRpb25zXG4ucGFnZS1mcm9tLXJpZ2h0LXRvLWNlbnRlciB7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgLmFuaW1hdGlvbihwYWdlRnJvbVJpZ2h0VG9DZW50ZXIgQHBhZ2VEdXJhdGlvbiBmb3J3YXJkcyk7XG59XG4ucGFnZS1mcm9tLWNlbnRlci10by1yaWdodCB7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgLmFuaW1hdGlvbihwYWdlRnJvbUNlbnRlclRvUmlnaHQgQHBhZ2VEdXJhdGlvbiBmb3J3YXJkcyk7XG59XG5ALXdlYmtpdC1rZXlmcmFtZXMgcGFnZUZyb21SaWdodFRvQ2VudGVyIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsIEBuZXdQYWdlT2Zmc2V0LDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxufVxuQGtleWZyYW1lcyBwYWdlRnJvbVJpZ2h0VG9DZW50ZXIge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsIEBuZXdQYWdlT2Zmc2V0LDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIH1cbn1cbkAtd2Via2l0LWtleWZyYW1lcyBwYWdlRnJvbUNlbnRlclRvUmlnaHQge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLCBAbmV3UGFnZU9mZnNldCwwKTtcbiAgICB9XG59XG5Aa2V5ZnJhbWVzIHBhZ2VGcm9tQ2VudGVyVG9SaWdodCB7XG4gICAgZnJvbSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwgQG5ld1BhZ2VPZmZzZXQsMCk7XG4gICAgfVxufVxuXG5cbi8vIEZyb20vdG8gQ2VudGVyIFRvL2Zyb20gTGVmdCBhbmltYXRpb25zXG4ucGFnZS1mcm9tLWNlbnRlci10by1sZWZ0IHtcbiAgICAuYW5pbWF0aW9uKHBhZ2VGcm9tQ2VudGVyVG9MZWZ0IEBwYWdlRHVyYXRpb24gZm9yd2FyZHMpO1xufVxuLnBhZ2UtZnJvbS1sZWZ0LXRvLWNlbnRlciB7XG4gICAgLmFuaW1hdGlvbihwYWdlRnJvbUxlZnRUb0NlbnRlciBAcGFnZUR1cmF0aW9uIGZvcndhcmRzKTtcbn1cblxuQC13ZWJraXQta2V5ZnJhbWVzIHBhZ2VGcm9tQ2VudGVyVG9MZWZ0IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcGFnZUZyb21DZW50ZXJUb0xlZnQge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIHBhZ2VGcm9tTGVmdFRvQ2VudGVyIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcGFnZUZyb21MZWZ0VG9DZW50ZXIge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxufSIsIi8qID09PSBUb29sYmFycyA9PT0gKi9cblxuLy9Ub29sYmFyL05hdmJhclxuQHRvb2xiYXJCZyA6IEB0aGVtZUNvbG9yO1xuQHRvb2xiYXJDb2xvcjogI2ZmZjtcbkB0b29sYmFyTGlua3NDb2xvcjogI2ZmZjtcbkBuYXZiYXJTaXplOiA1NnB4O1xuQHRvb2xiYXJTaXplOiA0OHB4O1xuXG4vL1RhYiBiYXJcbkB0YWJiYXJTaXplOiA0OHB4O1xuQHRhYmJhckxhYmVsc1NpemU6IDcycHg7XG5AdGFiYmFyTGlua3NDb2xvcjogcmdiYSgyNTUsMjU1LDI1NSwwLjcpO1xuQHRhYmJhckFjdGl2ZUxpbmtzQ29sb3I6IHJnYmEoMjU1LDI1NSwyNTUsMSk7XG5cbi8vIFRvb2xiYXJzIGFuaW1hdGlvbnNcbkB0b29sYmFyRHVyYXRpb246IDMwMG1zO1xuXG4ubmF2YmFyLWlubmVyLCAudG9vbGJhci1pbm5lciB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IDA7XG4gICAgdG9wOiAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgLmZsZXhib3goKTtcbiAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbn1cbi5uYXZiYXItaW5uZXIge1xuICAgIC5qdXN0aWZ5LWNvbnRlbnQoZmxleC1zdGFydCk7XG59XG4udG9vbGJhci1pbm5lciB7XG4gICAgLmp1c3RpZnktY29udGVudChzcGFjZS1iZXR3ZWVuKTsgICBcbn1cbi5uYXZiYXItaW5uZXIuY2FjaGVkIHtcbiAgICBkaXNwbGF5OiBub25lO1xufVxuLm5hdmJhciwgLnRvb2xiYXIge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG1hcmdpbjogMDtcbiAgICB6LWluZGV4OiA1MDA7XG4gICAgLXdlYmtpdC1iYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuO1xuICAgIGNvbG9yOiBAdG9vbGJhckNvbG9yO1xuICAgIGIge1xuICAgICAgICBmb250LXdlaWdodDogNTAwO1xuICAgIH1cbn1cbi5uYXZiYXIgfiAudG9vbGJhciB7XG4gICAgei1pbmRleDogNDk5O1xufVxuLm5hdmJhciwgLnRvb2xiYXIsIC5zdWJuYXZiYXIge1xuICAgIGJhY2tncm91bmQ6IEB0b29sYmFyQmc7XG4gICAgYS5saW5rIHtcbiAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIGNvbG9yOiBAdG9vbGJhckxpbmtzQ29sb3I7XG4gICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC5qdXN0aWZ5LWNvbnRlbnQoY2VudGVyKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgICAgIHBhZGRpbmc6IDAgMTZweDtcbiAgICAgICAgbWluLXdpZHRoOiA0OHB4O1xuICAgICAgICAuYWN0aXZlLWhpZ2hsaWdodCgpO1xuICAgICAgICBpK3NwYW4sIGkraSwgc3BhbitpLCBzcGFuK3NwYW4ge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhLmljb24tb25seSB7XG4gICAgICAgIG1pbi13aWR0aDogMDtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDApO1xuICAgIH1cbiAgICBpLmljb24ge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICB9XG59XG4ubmF2YmFyLCAuc3VibmF2YmFyIHtcbiAgICAuY2VudGVyIHtcbiAgICAgICAgZm9udC1zaXplOiAyMHB4O1xuICAgICAgICBmb250LXdlaWdodDogNTAwO1xuICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICAgIG1hcmdpbjogMCAxNnB4O1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6ZWxsaXBzaXM7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiBAbmF2YmFyU2l6ZTtcbiAgICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgICAgICB0ZXh0LWFsaWduOiBsZWZ0O1xuICAgIH1cbiAgICAubGVmdCwgLnJpZ2h0IHtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDApO1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICAuanVzdGlmeS1jb250ZW50KGZsZXgtc3RhcnQpO1xuICAgICAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG4gICAgLnJpZ2h0IHtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IGF1dG87XG4gICAgfVxuICAgIC5yaWdodDpmaXJzdC1jaGlsZCB7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgcmlnaHQ6IDE2cHg7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICB9XG59XG4ubmF2YmFyIHtcbiAgICBsZWZ0OiAwO1xuICAgIHRvcDogMDtcbiAgICBoZWlnaHQ6IEBuYXZiYXJTaXplO1xuICAgIGZvbnQtc2l6ZTogMjBweDtcbiAgICBhLmxpbmsge1xuICAgICAgICBsaW5lLWhlaWdodDogQG5hdmJhclNpemU7XG4gICAgICAgIGhlaWdodDogQG5hdmJhclNpemU7XG4gICAgfVxuICAgIC5wb3B1cCAmIHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG59XG4uc3VibmF2YmFyIHtcbiAgICBoZWlnaHQ6IEB0b29sYmFyU2l6ZTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDEwMCU7XG4gICAgei1pbmRleDogMjA7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBwYWRkaW5nOiAwIDE2cHg7XG4gICAgLmZsZXhib3goKTtcbiAgICAuanVzdGlmeS1jb250ZW50KHNwYWNlLWJldHdlZW4pO1xuICAgIC5hbGlnbi1pdGVtcyhjZW50ZXIpO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYS5saW5rIHtcbiAgICAgICAgbGluZS1oZWlnaHQ6IEB0b29sYmFyU2l6ZTtcbiAgICAgICAgaGVpZ2h0OiBAdG9vbGJhclNpemU7XG4gICAgfVxuICAgIC5jZW50ZXIge1xuICAgICAgICBsaW5lLWhlaWdodDogQHRvb2xiYXJTaXplO1xuICAgICAgICAmOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiA1NnB4O1xuICAgICAgICB9XG4gICAgfVxuICAgIC5uYXZiYXIubm8tYm9yZGVyICYge1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgIH1cbiAgICAubmF2YmFyLW9uLWxlZnQgJiwgLm5hdmJhci1vbi1yaWdodCAme1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICB9XG4gICAgLm5hdmJhciAmLCAucGFnZSAmIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIH1cbiAgICAucGFnZSA+ICYge1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIG1hcmdpbi10b3A6IDA7XG4gICAgfVxuICAgID4gLmJ1dHRvbnMtcm93IHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgfVxuICAgIC5zZWFyY2hiYXIsICYuc2VhcmNoYmFyIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIH1cbiAgICAmLnNlYXJjaGJhciwgLnNlYXJjaGJhciB7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB9XG4gICAgLnNlYXJjaGJhciB7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICB9XG4gICAgLmNlbnRlciB7XG5cbiAgICB9XG59XG4udG9vbGJhciB7XG4gICAgbGVmdDogMDtcbiAgICBib3R0b206IDA7XG4gICAgaGVpZ2h0OiBAdG9vbGJhclNpemU7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGEubGluayB7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiBAdG9vbGJhclNpemU7XG4gICAgICAgIGhlaWdodDogQHRvb2xiYXJTaXplO1xuICAgIH1cbiAgICBhIHtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDEpO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6ZWxsaXBzaXM7XG4gICAgfVxufVxuXG4vLyBUYWJiYXJcbi50YWJiYXIge1xuICAgIHotaW5kZXg6IDUwMDE7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBib3R0b206IGF1dG87XG4gICAgdG9wOiAwO1xuICAgIC50b29sYmFyLWlubmVyIHtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiAwO1xuICAgICAgICBwYWRkaW5nLXJpZ2h0OiAwO1xuICAgIH1cbiAgICBhLmxpbmsge1xuICAgICAgICBsaW5lLWhlaWdodDogMS40O1xuICAgIH1cbiAgICBhLnRhYi1saW5rLCBhLmxpbmsge1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICBwYWRkaW5nLWxlZnQ6IDA7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IDA7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC5qdXN0aWZ5LWNvbnRlbnQoY2VudGVyKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgICAgIC1tcy1mbGV4OiAxO1xuICAgICAgICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgICAgICAtbW96LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgICAgICAtbXMtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICAgIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gICAgfVxuICAgIGkuaWNvbiB7XG4gICAgICAgIGhlaWdodDogMjRweDtcbiAgICB9XG4gICAgYS50YWItbGluayB7XG4gICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgY29sb3I6IEB0YWJiYXJMaW5rc0NvbG9yO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgICYuYWN0aXZlLCBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZSwgJi5hY3RpdmUtc3RhdGUge1xuICAgICAgICAgICAgY29sb3I6IEB0YWJiYXJBY3RpdmVMaW5rc0NvbG9yO1xuICAgICAgICB9XG4gICAgfVxuICAgIC50YWItbGluay1oaWdobGlnaHQge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIGJvdHRvbTogMDtcbiAgICAgICAgaGVpZ2h0OiAzcHg7XG4gICAgICAgIGJhY2tncm91bmQ6IGRhcmtlbihAdGhlbWVDb2xvciwgMTUlKTtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgyNTUsMjU1LDI1NSwwLjUpO1xuICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgfVxufVxuLnRhYmJhci1sYWJlbHMge1xuICAgIGhlaWdodDogQHRhYmJhckxhYmVsc1NpemU7XG4gICAgYS50YWItbGluaywgYS5saW5rIHtcbiAgICAgICAgcGFkZGluZy10b3A6IDEycHg7XG4gICAgICAgIHBhZGRpbmctYm90dG9tOiAxMnB4O1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIC5qdXN0aWZ5LWNvbnRlbnQoc3BhY2UtYmV0d2Vlbik7XG4gICAgfVxuICAgIHNwYW4udGFiYmFyLWxhYmVsIHtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDE7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIG1hcmdpbi10b3A6IDEwcHg7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIG1heC13aWR0aDogMTAwJTtcbiAgICB9XG59XG4udGFiYmFyLXNjcm9sbGFibGUge1xuICAgIC50b29sYmFyLWlubmVyIHtcbiAgICAgICAgLmp1c3RpZnktY29udGVudChmbGV4LXN0YXJ0KTtcbiAgICAgICAgLm5vLXNjcm9sbGJhcigpO1xuICAgICAgICBvdmVyZmxvdzogYXV0bztcbiAgICB9XG4gICAgYS50YWItbGluaywgYS5saW5rIHtcbiAgICAgICAgd2lkdGg6IGF1dG87XG4gICAgICAgIC5mbGV4LXNocmluaygwKTtcbiAgICAgICAgLW1zLWZsZXg6IDA7XG4gICAgICAgIHBhZGRpbmc6IDAgMTZweDtcbiAgICB9XG59XG4udG9vbGJhci1ib3R0b20ge1xuICAgIGJvdHRvbTogMDtcbiAgICB0b3A6IGF1dG87XG4gICAgLnRhYi1saW5rLWhpZ2hsaWdodCB7XG4gICAgICAgIGJvdHRvbTogYXV0bztcbiAgICAgICAgdG9wOiAwO1xuICAgIH1cbn1cbi5zdWJuYXZiYXIsIC5uYXZiYXIge1xuICAgIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLCBpbnB1dFt0eXBlPVwicGFzc3dvcmRcIl0sIGlucHV0W3R5cGU9XCJzZWFyY2hcIl0sIGlucHV0W3R5cGU9XCJlbWFpbFwiXSwgaW5wdXRbdHlwZT1cInRlbFwiXSwgaW5wdXRbdHlwZT1cInVybFwiXSB7XG4gICAgICAgIC5iYXJzLWlucHV0KCk7XG4gICAgfVxufSIsIi8qID09PSBSZWxhdGlvbiBiZXR3ZWVuIHRvb2xiYXIvbmF2YmFyIHR5cGVzIGFuZCBwYWdlcyA9PT0gKi9cbi5wYWdlLCAudmlldywgLnZpZXdze1xuICAgID4ubmF2YmFyLCA+LnRvb2xiYXIge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgfVxufVxuLnN1Ym5hdmJhciB+IC5wYWdlLWNvbnRlbnQge1xuICAgIHBhZGRpbmctdG9wOiBAdG9vbGJhclNpemU7XG59XG4udG9vbGJhci1maXhlZCwgLnRhYmJhci1maXhlZCB7XG4gICAgLnBhZ2UtY29udGVudCB7XG4gICAgICAgIHBhZGRpbmctdG9wOiBAdG9vbGJhclNpemU7XG4gICAgfVxufVxuLnRhYmJhci1sYWJlbHMtZml4ZWQge1xuICAgIC5wYWdlLWNvbnRlbnQge1xuICAgICAgICBwYWRkaW5nLXRvcDogQHRhYmJhckxhYmVsc1NpemU7XG4gICAgfVxufVxuXG4udG9vbGJhciB+IC5wYWdlLWNvbnRlbnQge1xuICAgIHBhZGRpbmctdG9wOiBAdG9vbGJhclNpemU7XG59XG4udGFiYmFyLWxhYmVscyB+IC5wYWdlLWNvbnRlbnQge1xuICAgIHBhZGRpbmctdG9wOiBAdGFiYmFyTGFiZWxzU2l6ZTtcbn1cbi50b29sYmFyLWJvdHRvbSwgLm1lc3NhZ2ViYXIge1xuICAgIH4gLnBhZ2UtY29udGVudCB7XG4gICAgICAgIHBhZGRpbmctdG9wOiAwO1xuICAgICAgICBwYWRkaW5nLWJvdHRvbTogQHRvb2xiYXJTaXplO1xuICAgIH1cbn1cbi50YWJiYXItbGFiZWxzLnRvb2xiYXItYm90dG9tIH4gLnBhZ2UtY29udGVudCB7XG4gICAgcGFkZGluZy1ib3R0b206IEB0YWJiYXJMYWJlbHNTaXplO1xufVxuLm5hdmJhci1maXhlZCB7XG4gICAgLnBhZ2UtY29udGVudCB7XG4gICAgICAgIHBhZGRpbmctdG9wOiBAbmF2YmFyU2l6ZTtcbiAgICB9XG5cbiAgICAmLnRvb2xiYXItZml4ZWQsICYudGFiYmFyLWZpeGVkLCAudG9vbGJhci1maXhlZCwgLnRhYmJhci1maXhlZCwgLnRvb2xiYXItZml4ZWQgJiwgLnRhYmJhci1maXhlZCAmIHtcbiAgICAgICAgLnBhZ2UtY29udGVudCB7XG4gICAgICAgICAgICBwYWRkaW5nLXRvcDogQG5hdmJhclNpemUgKyBAdG9vbGJhclNpemU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgJi50YWJiYXItbGFiZWxzLWZpeGVkLCAudGFiYmFyLWxhYmVscy1maXhlZCwgLnRhYmJhci1sYWJlbHMtZml4ZWQgJiB7XG4gICAgICAgIC5wYWdlLWNvbnRlbnQge1xuICAgICAgICAgICAgcGFkZGluZy10b3A6IEBuYXZiYXJTaXplICsgQHRhYmJhckxhYmVsc1NpemU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLnRvb2xiYXIgfiAucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy10b3A6IEBuYXZiYXJTaXplICsgQHRvb2xiYXJTaXplO1xuICAgIH1cbiAgICAubWVzc2FnZWJhciB+IC5wYWdlLWNvbnRlbnQsIC50b29sYmFyLWJvdHRvbSB+IC5wYWdlLWNvbnRlbnQge1xuICAgICAgICBwYWRkaW5nLXRvcDogQG5hdmJhclNpemU7XG4gICAgfVxuXG4gICAgLnRhYmJhci1sYWJlbHMgfiAucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy10b3A6IEBuYXZiYXJTaXplICsgQHRhYmJhckxhYmVsc1NpemU7XG4gICAgfVxuICAgIC50YWJiYXItbGFiZWxzLnRvb2xiYXItYm90dG9tIH4gLnBhZ2UtY29udGVudCB7XG4gICAgICAgIHBhZGRpbmctdG9wOiBAbmF2YmFyU2l6ZTtcbiAgICB9XG5cbiAgICAud2l0aC1zdWJuYXZiYXIgLnBhZ2UtY29udGVudCwgLnBhZ2UtY29udGVudC53aXRoLXN1Ym5hdmJhciwgLnN1Ym5hdmJhciB+IC5wYWdlLWNvbnRlbnQge1xuICAgICAgICBwYWRkaW5nLXRvcDogQG5hdmJhclNpemUgKyBAdG9vbGJhclNpemU7XG4gICAgfVxuXG4gICAgLnBhZ2UgLnN1Ym5hdmJhciwgJi5wYWdlIC5zdWJuYXZiYXIge1xuICAgICAgICB0b3A6IEBuYXZiYXJTaXplO1xuICAgIH1cblxuICAgIC50b29sYmFyIHtcbiAgICAgICAgdG9wOiBAbmF2YmFyU2l6ZTtcbiAgICB9XG4gICAgLm1lc3NhZ2ViYXIsIC50b29sYmFyLWJvdHRvbSB7XG4gICAgICAgIHRvcDogYXV0bztcbiAgICB9XG59XG4vLyBQYWdlIEhpZGRlbiBOYXZiYXJcbi5uYXZiYXIge1xuICAgICYubmF2YmFyLWhpZGluZyB7XG4gICAgICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAgICAgJiB+IC5wYWdlLWNvbnRlbnQsICYgfiAucGFnZXMsICYgfiAucGFnZSB7XG4gICAgICAgICAgICAubGlzdC1ncm91cC10aXRsZSB7XG4gICAgICAgICAgICAgICAgLnRyYW5zaXRpb24oNDAwbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLnN1Ym5hdmJhciB7XG4gICAgICAgICAgICAgICAgLnRyYW5zaXRpb24oNDAwbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgICYgfiAuc3VibmF2YmFyLCAmIH4gLnRvb2xiYXIge1xuICAgICAgICAgICAgLnRyYW5zaXRpb24oNDAwbXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgICYubmF2YmFyLWhpZGRlbiB7XG4gICAgICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsLTEwMCUsMCk7XG4gICAgICAgICYgfiAucGFnZS1jb250ZW50LCAmIH4gLnBhZ2VzLCAmIH4gLnBhZ2Uge1xuICAgICAgICAgICAgLmxpc3QtZ3JvdXAtdGl0bGUge1xuICAgICAgICAgICAgICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICAgICAgICAgICAgICB0b3A6LUBuYXZiYXJTaXplO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLnN1Ym5hdmJhciB7XG4gICAgICAgICAgICAgICAgLnRyYW5zbGF0ZTNkKDAsLUBuYXZiYXJTaXplLDApO1xuICAgICAgICAgICAgICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAmIH4gLnN1Ym5hdmJhciwgJiB+IC50b29sYmFyOm5vdCgubWVzc2FnZWJhcik6bm90KC50b29sYmFyLWJvdHRvbSkge1xuICAgICAgICAgICAgLnRyYW5zbGF0ZTNkKDAsLUBuYXZiYXJTaXplLDApO1xuICAgICAgICAgICAgLnRyYW5zaXRpb24oNDAwbXMpO1xuICAgICAgICB9XG4gICAgfVxufVxuLnBhZ2Uubm8tbmF2YmFyIHtcbiAgICAucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy10b3A6IDA7XG4gICAgfVxuICAgICYud2l0aC1zdWJuYXZiYXIgLnBhZ2UtY29udGVudCwgLndpdGgtc3VibmF2YmFyICYgLnBhZ2UtY29udGVudCwgLnBhZ2UtY29udGVudC53aXRoLXN1Ym5hdmJhciB7XG4gICAgICAgIHBhZGRpbmctdG9wOiBAdG9vbGJhclNpemU7XG4gICAgfVxufVxuLy8gUGFnZSBIaWRkZW4gVG9vbGJhclxuLnRvb2xiYXIsIC50YWJiYXIge1xuICAgICYudG9vbGJhci1oaWRpbmcsICYudGFiYmFyLWhpZGluZyB7XG4gICAgICAgIC50cmFuc2l0aW9uKDQwMG1zKTtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG4gICAgJi50b29sYmFyLWhpZGRlbiwgJi50YWJiYXItaGlkZGVuIHtcbiAgICAgICAgLnRyYW5zaXRpb24oNDAwbXMpO1xuICAgIH1cblxuICAgICYudG9vbGJhci1oaWRkZW4sICYudGFiYmFyLWhpZGRlbiB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLC0xMDAlLDApO1xuICAgIH1cbiAgICAubmF2YmFyIH4gJi50b29sYmFyLWhpZGRlbiwgLm5hdmJhciB+ICYudGFiYmFyLWhpZGRlbiB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLC0xMDRweCwwKTtcbiAgICB9XG4gICAgLm5hdmJhciB+ICYudGFiYmFyLWxhYmVscy50b29sYmFyLWhpZGRlbiB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLC0xMjhweCwwKTtcbiAgICB9XG4gICAgJi50b29sYmFyLWhpZGRlbi5tZXNzYWdlYmFyLCAmLnRvb2xiYXItaGlkZGVuLnRvb2xiYXItYm90dG9tIHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsIDEwMCUsMCk7XG4gICAgfVxufVxuLnBhZ2Uubm8tdG9vbGJhciAucGFnZS1jb250ZW50LCAucGFnZS5uby10YWJiYXIgLnBhZ2UtY29udGVudCB7XG4gICAgcGFkZGluZy1ib3R0b206IDA7XG59XG4iLCIvKiA9PT0gU2VhcmNoIEJhciA9PT0gKi9cbkBzZWFyY2hiYXJCb3JkZXJDb2xvcjogI2I0YjRiNDtcbkBzZWFyY2hiYXJTaXplOiBAdG9vbGJhclNpemU7XG4uc2VhcmNoYmFyIHtcbiAgICBoZWlnaHQ6IEBzZWFyY2hiYXJTaXplO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGJhY2tncm91bmQ6IEB0aGVtZUNvbG9yO1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgcGFkZGluZzogMCAxNnB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgY29sb3I6I2ZmZjtcbiAgICBhIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBjb2xvcjojZmZmO1xuICAgICAgICAuYWN0aXZlLWhpZ2hsaWdodCgpO1xuICAgIH1cbiAgICAuc2VhcmNoYmFyLWlucHV0IHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGhlaWdodDogMzJweDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICAuZmxleC1zaHJpbmsoMSk7XG4gICAgfVxuICAgIGlucHV0W3R5cGU9XCJzZWFyY2hcIl0ge1xuICAgICAgICAuYmFycy1pbnB1dCgpO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIHBhZGRpbmc6IDAgMzZweCAwIDI0cHg7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwIGNlbnRlcjtcbiAgICAgICAgb3BhY2l0eTogMC42O1xuICAgICAgICAtd2Via2l0LWJhY2tncm91bmQtc2l6ZTogMjRweCAyNHB4O1xuICAgICAgICBiYWNrZ3JvdW5kLXNpemU6IDI0cHggMjRweDtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgZmlsbD0nI0ZGRkZGRicgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0JyB3aWR0aD0nMjQnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTTE1LjUgMTRoLS43OWwtLjI4LS4yN0MxNS40MSAxMi41OSAxNiAxMS4xMSAxNiA5LjUgMTYgNS45MSAxMy4wOSAzIDkuNSAzUzMgNS45MSAzIDkuNSA1LjkxIDE2IDkuNSAxNmMxLjYxIDAgMy4wOS0uNTkgNC4yMy0xLjU3bC4yNy4yOHYuNzlsNSA0Ljk5TDIwLjQ5IDE5bC00Ljk5LTV6bS02IDBDNy4wMSAxNCA1IDExLjk5IDUgOS41UzcuMDEgNSA5LjUgNSAxNCA3LjAxIDE0IDkuNSAxMS45OSAxNCA5LjUgMTR6Jy8+PHBhdGggZD0nTTAgMGgyNHYyNEgweicgZmlsbD0nbm9uZScvPjwvc3ZnPlwiKTtcbiAgICAgICAgJjo6LXdlYmtpdC1zZWFyY2gtY2FuY2VsLWJ1dHRvbiB7XG4gICAgICAgICAgICAtd2Via2l0LWFwcGVhcmFuY2U6bm9uZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAuc2VhcmNoYmFyLWNsZWFyIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICB3aWR0aDogNTZweDtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICByaWdodDogLTE2cHg7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6bm9uZTtcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogY2VudGVyO1xuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgZmlsbD0nI2ZmZicgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0JyB3aWR0aD0nMjQnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTTE5IDYuNDFMMTcuNTkgNSAxMiAxMC41OSA2LjQxIDUgNSA2LjQxIDEwLjU5IDEyIDUgMTcuNTkgNi40MSAxOSAxMiAxMy40MSAxNy41OSAxOSAxOSAxNy41OSAxMy40MSAxMnonLz48cGF0aCBkPSdNMCAwaDI0djI0SDB6JyBmaWxsPSdub25lJy8+PC9zdmc+XCIpO1xuICAgICAgICAtd2Via2l0LWJhY2tncm91bmQtc2l6ZTogMjRweCAyNHB4O1xuICAgICAgICBiYWNrZ3JvdW5kLXNpemU6IDI0cHggMjRweDtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuICAgIC5zZWFyY2hiYXItY2FuY2VsIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gICAgJi5zZWFyY2hiYXItYWN0aXZlIHtcbiAgICAgICAgaW5wdXRbdHlwZT1cInNlYXJjaFwiXSB7XG4gICAgICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB9XG4gICAgICAgIC5zZWFyY2hiYXItY2xlYXIge1xuICAgICAgICAgICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gICAgICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB9XG4gICAgfVxuICAgICYuc2VhcmNoYmFyLW5vdC1lbXB0eSB7XG4gICAgICAgIC5zZWFyY2hiYXItY2xlYXIge1xuICAgICAgICAgICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gICAgICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB9XG4gICAgfVxufVxuLnNlYXJjaGJhci1vdmVybGF5IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIHotaW5kZXg6IDEwMDtcbiAgICBvcGFjaXR5OiAwO1xuICAgIHBvaW50ZXItZXZlbnRzOm5vbmU7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLDAsMCwwLjI1KTtcbiAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAmLnNlYXJjaGJhci1vdmVybGF5LWFjdGl2ZSB7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBhdXRvO1xuICAgIH1cbn1cbi5zZWFyY2hiYXItbm90LWZvdW5kIHtcbiAgICBkaXNwbGF5OiBub25lO1xufVxuLmhpZGRlbi1ieS1zZWFyY2hiYXIsIC5saXN0LWJsb2NrIC5oaWRkZW4tYnktc2VhcmNoYmFyLCAubGlzdC1ibG9jayBsaS5oaWRkZW4tYnktc2VhcmNoYmFyIHtcbiAgICBkaXNwbGF5OiBub25lO1xufVxuLnBhZ2UgPiAuc2VhcmNoYmFyIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgei1pbmRleDogMjAwO1xuICAgICYgfiAucGFnZS1jb250ZW50IHtcbiAgICAgICAgcGFkZGluZy10b3A6IEBzZWFyY2hiYXJTaXplO1xuICAgIH1cbn1cbi5uYXZiYXItZml4ZWQsIC5uYXZiYXItdGhyb3VnaCB7XG4gICAgLnBhZ2UgPiAuc2VhcmNoYmFyLCA+IC5zZWFyY2hiYXIge1xuICAgICAgICB0b3A6IEBuYXZiYXJTaXplO1xuICAgICAgICAmIH4gLnBhZ2UtY29udGVudCB7XG4gICAgICAgICAgICBwYWRkaW5nLXRvcDogQHNlYXJjaGJhclNpemUgKyBAbmF2YmFyU2l6ZTtcbiAgICAgICAgfVxuICAgIH1cbn0iLCIvKiA9PT0gTWVzc2FnZSBCYXIgPT09ICovXG4udG9vbGJhci5tZXNzYWdlYmFyIHtcbiAgICAudHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgLmhhaXJsaW5lKHRvcCwgI2QxZDFkMSk7XG4gICAgaGVpZ2h0OiA0OHB4O1xuICAgIHRvcDogYXV0bztcbiAgICBib3R0b206IDA7XG4gICAgZm9udC1zaXplOiAxNnB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgdGV4dGFyZWEge1xuICAgICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tb3otYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLW1zLWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIGFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC13ZWJraXQtYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgLW1vei1ib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICBib3JkZXI6IG5vbmU7XG4gICAgICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICBwYWRkaW5nOiAzcHggOHB4IDNweDtcbiAgICAgICAgbWFyZ2luOiAwO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAyOHB4O1xuICAgICAgICBjb2xvcjogIzMzMztcbiAgICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgICAgICBsaW5lLWhlaWdodDogMjJweDtcbiAgICAgICAgZm9udC1mYW1pbHk6IGluaGVyaXQ7XG4gICAgICAgIHJlc2l6ZTpub25lO1xuICAgICAgICAuZmxleC1zaHJpbmsoMSk7XG4gICAgfVxuICAgIGEubGluayB7XG4gICAgICAgIGNvbG9yOiAjMzMzO1xuICAgICAgICAuYWxpZ24tc2VsZihmbGV4LWVuZCk7XG4gICAgICAgIGhlaWdodDogQHRvb2xiYXJTaXplO1xuICAgICAgICBsaW5lLWhlaWdodDogQHRvb2xiYXJTaXplO1xuICAgICAgICAuYWN0aXZlLWhpZ2hsaWdodC1jb2xvcihyZ2JhKDAsMCwwLDAuMSkpO1xuXG4gICAgfVxuICAgIC5saW5rIHtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDApO1xuICAgIH1cbiAgICB+IC5wYWdlLWNvbnRlbnQge1xuICAgICAgICBwYWRkaW5nLWJvdHRvbTogQHRvb2xiYXJTaXplO1xuICAgIH1cbiAgICAucGFnZS5uby10b29sYmFyICYgfi5wYWdlLWNvbnRlbnQge1xuICAgICAgICBwYWRkaW5nLWJvdHRvbTogQHRvb2xiYXJTaXplO1xuICAgIH1cbiAgICAuaGlkZGVuLXRvb2xiYXIgJiB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgICAgIC50cmFuc2l0aW9uKDBtcyk7XG4gICAgfVxufVxuIiwiLyogPT09IEljb25zID09PSAqL1xuaS5pY29uIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgICBiYWNrZ3JvdW5kLXNpemU6IDEwMCUgYXV0bztcbiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7XG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgICBmb250LXN0eWxlOiBub3JtYWw7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIC8qIE1hdGVyaWFsIEljb25zIGh0dHA6Ly9nb29nbGUuZ2l0aHViLmlvL21hdGVyaWFsLWRlc2lnbi1pY29ucy8gKi9cbiAgICAmLmljb24tYmFjayB7XG4gICAgICAgIHdpZHRoOiAyNHB4O1xuICAgICAgICBoZWlnaHQ6IDI0cHg7XG4gICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0Jz48cGF0aCBkPSdNMjAgMTFINy44M2w1LjU5LTUuNTlMMTIgNGwtOCA4IDggOCAxLjQxLTEuNDFMNy44MyAxM0gyMHYtMnonIGZpbGw9JyNmZmZmZmYnLz48L3N2Zz5cIilcbiAgICB9XG4gICAgJi5pY29uLWZvcndhcmQge1xuICAgICAgICB3aWR0aDogMjRweDtcbiAgICAgICAgaGVpZ2h0OiAyNHB4O1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB3aWR0aD0nMjQnIGhlaWdodD0nMjQnIHZpZXdCb3g9JzAgMCAyNCAyNCc+PHBhdGggZD0nTTEyIDRsLTEuNDEgMS40MUwxNi4xNyAxMUg0djJoMTIuMTdsLTUuNTggNS41OUwxMiAyMGw4LTh6JyBmaWxsPScjZmZmZmZmJy8+PC9zdmc+XCIpO1xuICAgIH1cbiAgICAmLmljb24tYmFycyB7XG4gICAgICAgIHdpZHRoOiAyNHB4O1xuICAgICAgICBoZWlnaHQ6IDI0cHg7XG4gICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0Jz48cGF0aCBkPSdNMyAxOGgxOHYtMkgzdjJ6bTAtNWgxOHYtMkgzdjJ6bTAtN3YyaDE4VjZIM3onIGZpbGw9JyNmZmZmZmYnLz48L3N2Zz5cIik7XG4gICAgfVxuICAgICYuaWNvbi1jYW1lcmEge1xuICAgICAgICB3aWR0aDogMjRweDtcbiAgICAgICAgaGVpZ2h0OiAyNHB4O1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgZmlsbD0nIzMzMycgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0JyB3aWR0aD0nMjQnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PGNpcmNsZSBjeD0nMTInIGN5PScxMicgcj0nMy4yJy8+PHBhdGggZD0nTTkgMkw3LjE3IDRINGMtMS4xIDAtMiAuOS0yIDJ2MTJjMCAxLjEuOSAyIDIgMmgxNmMxLjEgMCAyLS45IDItMlY2YzAtMS4xLS45LTItMi0yaC0zLjE3TDE1IDJIOXptMyAxNWMtMi43NiAwLTUtMi4yNC01LTVzMi4yNC01IDUtNSA1IDIuMjQgNSA1LTIuMjQgNS01IDV6Jy8+PHBhdGggZD0nTTAgMGgyNHYyNEgweicgZmlsbD0nbm9uZScvPjwvc3ZnPlwiKTtcbiAgICB9XG4gICAgJi5pY29uLWY3IHtcbiAgICAgICAgd2lkdGg6IDI0cHg7XG4gICAgICAgIGhlaWdodDogMjRweDtcbiAgICAgICAgYmFja2dyb3VuZC1pbWFnZTogdXJsKFwiQHtpbWdCYXNlVXJsfS9pLWY3LW1hdGVyaWFsLnBuZ1wiKTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xuICAgIH1cbiAgICAmLmljb24tbmV4dCwgJi5pY29uLXByZXYge1xuICAgICAgICB3aWR0aDogMjRweDtcbiAgICAgICAgaGVpZ2h0OiAyNHB4O1xuICAgIH1cbiAgICAmLmljb24tbmV4dCB7XG4gICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIGZpbGw9JyNmZmZmZmYnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0Jz48cGF0aCBkPSdNMTAgNkw4LjU5IDcuNDEgMTMuMTcgMTJsLTQuNTggNC41OUwxMCAxOGw2LTZ6Jy8+PHBhdGggZD0nTTAgMGgyNHYyNEgweicgZmlsbD0nbm9uZScvPjwvc3ZnPlwiKTtcbiAgICB9XG4gICAgJi5pY29uLXByZXYge1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyBmaWxsPScjZmZmZmZmJyB3aWR0aD0nMjQnIGhlaWdodD0nMjQnIHZpZXdCb3g9JzAgMCAyNCAyNCc+PHBhdGggZD0nTTE1LjQxIDcuNDFMMTQgNmwtNiA2IDYgNiAxLjQxLTEuNDFMMTAuODMgMTJ6Jy8+PHBhdGggZD0nTTAgMGgyNHYyNEgweicgZmlsbD0nbm9uZScvPjwvc3ZnPlwiKTtcbiAgICB9XG4gICAgJi5pY29uLXBsdXMge1xuICAgICAgICB3aWR0aDogMjRweDtcbiAgICAgICAgaGVpZ2h0OiAyNHB4O1xuICAgICAgICBmb250LXNpemU6IDA7XG4gICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyBmaWxsPScjRkZGRkZGJyBoZWlnaHQ9JzI0JyB2aWV3Qm94PScwIDAgMjQgMjQnIHdpZHRoPScyNCcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJz48cGF0aCBkPSdNMTkgMTNoLTZ2NmgtMnYtNkg1di0yaDZWNWgydjZoNnYyeicvPjxwYXRoIGQ9J00wIDBoMjR2MjRIMHonIGZpbGw9J25vbmUnLz48L3N2Zz5cIik7XG4gICAgfVxuICAgICYuaWNvbi1jbG9zZSB7XG4gICAgICAgIHdpZHRoOiAyNHB4O1xuICAgICAgICBoZWlnaHQ6IDI0cHg7XG4gICAgICAgIGZvbnQtc2l6ZTogMDtcbiAgICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoXCI8c3ZnIGZpbGw9JyNGRkZGRkYnIGhlaWdodD0nMjQnIHZpZXdCb3g9JzAgMCAyNCAyNCcgd2lkdGg9JzI0JyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxwYXRoIGQ9J00xOSA2LjQxTDE3LjU5IDUgMTIgMTAuNTkgNi40MSA1IDUgNi40MSAxMC41OSAxMiA1IDE3LjU5IDYuNDEgMTkgMTIgMTMuNDEgMTcuNTkgMTkgMTkgMTcuNTkgMTMuNDEgMTJ6Jy8+PHBhdGggZD0nTTAgMGgyNHYyNEgweicgZmlsbD0nbm9uZScvPjwvc3ZnPlwiKTtcbiAgICB9XG59XG4iLCIuYmFkZ2Uge1xuICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgY29sb3I6I2ZmZjtcbiAgICBiYWNrZ3JvdW5kOiAjOGU4ZTkzO1xuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICBwYWRkaW5nOiAxcHggNnB4O1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbn1cbi5pY29uIC5iYWRnZSB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IDEwMCU7XG4gICAgbWFyZ2luLWxlZnQ6IC0xMHB4O1xuICAgIHRvcDogLTJweDtcbiAgICBmb250LXNpemU6IDEwcHg7XG4gICAgbGluZS1oZWlnaHQ6IDEuNDtcbiAgICBwYWRkaW5nOiAxcHggNXB4O1xufSIsIi8qID09PSBDb250ZW50IEJsb2NrID09PSAqL1xuQGNvbnRlbnRCbG9ja0JvcmRlckNvbG9yOiByZ2JhKDAsMCwwLDAuMTIpO1xuLmNvbnRlbnQtYmxvY2sge1xuICAgIG1hcmdpbjogMzJweCAwO1xuICAgIHBhZGRpbmc6IDAgMTZweDtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIC5uby1oYWlybGluZXMoKTtcbn1cbi5jb250ZW50LWJsb2NrLXRpdGxlIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBtYXJnaW46IDA7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbGluZS1oZWlnaHQ6IDE7XG4gICAgbWFyZ2luOiAxNnB4IDE2cHggMTZweDtcbiAgICBwYWRkaW5nLXRvcDogMTZweDtcbiAgICBsaW5lLWhlaWdodDogMTZweDtcbiAgICBmb250LXdlaWdodDogNTAwO1xuICAgIGNvbG9yOiByZ2JhKDAsMCwwLDAuNTQpO1xuICAgICsgLmxpc3QtYmxvY2ssICsgLmNvbnRlbnQtYmxvY2ssICsuY2FyZCB7XG4gICAgICAgIG1hcmdpbi10b3A6IDBweDtcbiAgICB9XG5cbn1cbi5jb250ZW50LWJsb2NrLWlubmVyIHtcbiAgICBwYWRkaW5nOiAxNnB4IDE2cHg7XG4gICAgbWFyZ2luLWxlZnQ6IC0xNnB4O1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAuaGFpcmxpbmUodG9wLCBAY29udGVudEJsb2NrQm9yZGVyQ29sb3IpO1xuICAgIC5oYWlybGluZShib3R0b20sIEBjb250ZW50QmxvY2tCb3JkZXJDb2xvcik7XG4gICAgPnA6Zmlyc3QtY2hpbGQge1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgIH1cbiAgICA+cDpsYXN0LWNoaWxkIHtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMDtcbiAgICB9XG59XG4uY29udGVudC1ibG9jay5pbnNldCB7XG4gICAgbWFyZ2luLWxlZnQ6IDE2cHg7XG4gICAgbWFyZ2luLXJpZ2h0OiAxNnB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDdweDtcbiAgICAuY29udGVudC1ibG9jay1pbm5lciB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUodG9wKTtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgfVxufVxuQG1lZGlhIGFsbCBhbmQgKG1pbi13aWR0aDo3NjhweCkge1xuICAgIC5jb250ZW50LWJsb2NrLnRhYmxldC1pbnNldCB7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAxNnB4O1xuICAgICAgICBtYXJnaW4tcmlnaHQ6IDE2cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDRweFxuICAgIH1cbiAgICBcbiAgICAuY29udGVudC1ibG9jay50YWJsZXQtaW5zZXQgLmNvbnRlbnQtYmxvY2staW5uZXIge1xuICAgIFx0LmhhaXJsaW5lLXJlbW92ZSh0b3ApO1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgXHRib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgfVxufVxuIiwiLyogPT09IExpc3RzID09PSAqL1xuQGxpc3RCbG9ja0JvcmRlckNvbG9yOiByZ2JhKDAsMCwwLDAuMTIpO1xuLmxpc3QtYmxvY2sge1xuICAgIG1hcmdpbjogMzJweCAwO1xuICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICB1bCB7XG4gICAgICAgIGxpc3Qtc3R5bGU6IG5vbmU7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICAuaGFpcmxpbmUodG9wLCBAbGlzdEJsb2NrQm9yZGVyQ29sb3IpO1xuICAgICAgICAuaGFpcmxpbmUoYm90dG9tLCBAbGlzdEJsb2NrQm9yZGVyQ29sb3IpO1xuICAgICAgICB1bCB7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDU2cHg7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAuYWxpZ24tdG9wLCAuYWxpZ24tdG9wIC5pdGVtLWNvbnRlbnQsIC5hbGlnbi10b3AgLml0ZW0taW5uZXIge1xuICAgICAgICAuYWxpZ24taXRlbXMoZmxleC1zdGFydCk7XG4gICAgfVxuICAgIFxuICAgIC5pbnNldCgpIHtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDE2cHg7XG4gICAgICAgIG1hcmdpbi1yaWdodDogMTZweDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgICAuY29udGVudC1ibG9jay10aXRsZSB7XG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogMDtcbiAgICAgICAgICAgIG1hcmdpbi1yaWdodDogMDtcbiAgICAgICAgfVxuICAgICAgICB1bCB7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgbGk6Zmlyc3QtY2hpbGQgPiBhe1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogNHB4IDRweCAwIDA7XG4gICAgICAgIH1cbiAgICAgICAgbGk6bGFzdC1jaGlsZCA+IGF7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAwIDAgNHB4IDRweDtcbiAgICAgICAgfVxuICAgICAgICBsaTpmaXJzdC1jaGlsZDpsYXN0LWNoaWxkID4gYSB7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgJi5pbnNldCB7XG4gICAgICAgIC5pbnNldCgpXG4gICAgfVxuICAgICYudGFibGV0LWluc2V0IHtcbiAgICAgICAgQG1lZGlhIGFsbCBhbmQgKG1pbi13aWR0aDo3NjhweCkge1xuICAgICAgICAgICAgLmluc2V0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMaXN0IGl0ZW1zXG4gICAgbGkge1xuICAgICAgICBib3gtc2l6aW5nOmJvcmRlci1ib3g7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB9XG4gICAgXG4gICAgLml0ZW0tbWVkaWEge1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICAuZmxleC1zaHJpbmsoMCk7XG4gICAgICAgIC5mbGV4LXdyYXAobm93cmFwKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgICAgIGJveC1zaXppbmc6Ym9yZGVyLWJveDtcbiAgICAgICAgcGFkZGluZy10b3A6IDhweDtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IDhweDtcbiAgICAgICAgbWluLXdpZHRoOiA0MHB4O1xuICAgICAgICBpICsgaSB7XG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogOHB4O1xuICAgICAgICB9XG4gICAgICAgIGkgKyBpbWcge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAuaXRlbS1tZWRpYSArIC5pdGVtLWlubmVyIHtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDE2cHg7XG4gICAgfVxuICAgIC5pdGVtLWlubmVyIHtcbiAgICAgICAgcGFkZGluZy1yaWdodDogMTZweDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICAuaGFpcmxpbmUoYm90dG9tLCBAbGlzdEJsb2NrQm9yZGVyQ29sb3IpO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgcGFkZGluZy10b3A6IDhweDtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IDhweDtcbiAgICAgICAgbWluLWhlaWdodDogNDhweDtcbiAgICAgICAgYm94LXNpemluZzpib3JkZXItYm94O1xuICAgICAgICAtd2Via2l0LWJveC1mbGV4OjE7XG4gICAgICAgIC1tcy1mbGV4OjE7XG4gICAgICAgIG1pbi13aWR0aDogMDtcbiAgICAgICAgLmZsZXhib3goKTtcbiAgICAgICAgLmp1c3RpZnktY29udGVudChzcGFjZS1iZXR3ZWVuKTtcbiAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgICAgIC5hbGlnbi1zZWxmKHN0cmV0Y2gpO1xuICAgIH1cbiAgICAuaXRlbS10aXRsZSB7XG4gICAgICAgIG1pbi13aWR0aDogMDtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDEpO1xuICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgICAgICBtYXgtd2lkdGg6IDEwMCU7XG4gICAgfVxuXG4gICAgLml0ZW0tYWZ0ZXIge1xuICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgICBjb2xvcjogIzc1NzU3NTtcbiAgICAgICAgLmZsZXgtc2hyaW5rKDApO1xuICAgICAgICBtYXJnaW4tbGVmdDogOHB4O1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICBtYXgtaGVpZ2h0OiAyOHB4O1xuICAgICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgfVxuICAgIC5zbWFydC1zZWxlY3QgLml0ZW0tYWZ0ZXIsIC5hdXRvY29tcGxldGUtb3BlbmVyIC5pdGVtLWFmdGVyIHtcbiAgICAgICAgbWF4LXdpZHRoOiA3MCU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIH1cbiAgICAuaXRlbS1saW5rIHtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgY29sb3I6IGluaGVyaXQ7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgei1pbmRleDogMDtcbiAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgcGFkZGluZy1yaWdodDogNDJweDtcbiAgICAgICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB2aWV3Qm94PScwIDAgNjAgMTIwJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxwYXRoIGQ9J202MCA2MS41LTM4LjI1IDM4LjI1LTkuNzUtOS43NSAyOS4yNS0yOC41LTI5LjI1LTI4LjUgOS43NS05Ljc1eicgZmlsbD0nI2M3YzdjYycvPjwvc3ZnPlwiKTtcbiAgICAgICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTBweCAyMHB4O1xuICAgICAgICAgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgICAgICAgICAgIGJhY2tncm91bmQtcG9zaXRpb246IDk1JSBjZW50ZXI7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAtd2Via2l0LWNhbGMoflwiMTAwJSAtIDE2cHhcIikgY2VudGVyO1xuICAgICAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogY2FsYyh+XCIxMDAlIC0gMTZweFwiKSBjZW50ZXI7XG4gICAgICAgIH1cbiAgICAgICAgaHRtbDpub3QoLndhdGNoLWFjdGl2ZS1zdGF0ZSkgJjphY3RpdmUsICYuYWN0aXZlLXN0YXRlIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwwLDAsMC4xKTtcbiAgICAgICAgfVxuICAgICAgICAmLmxpc3QtYnV0dG9uIHtcbiAgICAgICAgICAgIHBhZGRpbmc6IDAgMTZweDtcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICAgICAgbGluZS1oZWlnaHQ6IDQ4cHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tY29udGVudCB7XG4gICAgICAgIGJveC1zaXppbmc6Ym9yZGVyLWJveDtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiAxNnB4O1xuICAgICAgICBtaW4taGVpZ2h0OiA0OHB4O1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICAuanVzdGlmeS1jb250ZW50KHNwYWNlLWJldHdlZW4pO1xuICAgICAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICB9XG4gICAgLy8gTGFiZWwgYWZ0ZXIgTGlzdCBibG9ja1xuICAgIC5saXN0LWJsb2NrLWxhYmVsIHtcbiAgICAgICAgbWFyZ2luOiAxMHB4IDAgMzVweDtcbiAgICAgICAgcGFkZGluZzogMCAxNnB4O1xuICAgICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICAgIGNvbG9yOiByZ2JhKDAsMCwwLDAuNTQpO1xuICAgIH1cblxuICAgIC8vIFN3aXBlIG91dHNcbiAgICAuc3dpcGVvdXQge1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgICAgIHRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgfVxuICAgIC5zd2lwZW91dC5kZWxldGluZyB7XG4gICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgLnN3aXBlb3V0LWNvbnRlbnQge1xuICAgICAgICAgICAgLnRyYW5zZm9ybSh0cmFuc2xhdGVYKC0xMDAlKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLnN3aXBlb3V0LnRyYW5zaXRpb25pbmcge1xuICAgICAgICAuc3dpcGVvdXQtY29udGVudCwgLnN3aXBlb3V0LWFjdGlvbnMtcmlnaHQgYSwgLnN3aXBlb3V0LWFjdGlvbnMtbGVmdCBhLCAuc3dpcGVvdXQtb3ZlcnN3aXBlIHtcbiAgICAgICAgICAgIC13ZWJraXQtdHJhbnNpdGlvbjogMzAwbXM7XG4gICAgICAgICAgICB0cmFuc2l0aW9uOiAzMDBtcztcbiAgICAgICAgfSAgICBcbiAgICB9XG4gICAgLnN3aXBlb3V0LWNvbnRlbnQge1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIHotaW5kZXg6IDEwO1xuICAgIH1cbiAgICAuc3dpcGVvdXQtb3ZlcnN3aXBlIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2l0aW9uOiAyMDBtcyBsZWZ0O1xuICAgICAgICB0cmFuc2l0aW9uOiAyMDBtcyBsZWZ0O1xuICAgIH1cbiAgICAuc3dpcGVvdXQtYWN0aW9ucy1sZWZ0LCAuc3dpcGVvdXQtYWN0aW9ucy1yaWdodCB7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIGEge1xuICAgICAgICAgICAgcGFkZGluZzogMCAyNHB4O1xuICAgICAgICAgICAgY29sb3I6I2ZmZjtcbiAgICAgICAgICAgIGJhY2tncm91bmQ6ICNjN2M3Y2M7XG4gICAgICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICAgICAgLmFsaWduLWl0ZW1zKGNlbnRlcik7XG4gICAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgICAgICBsZWZ0OiAwO1xuICAgICAgICAgICAgJjphZnRlciB7XG4gICAgICAgICAgICAgICAgY29udGVudDonJztcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICAgICAgdG9wOiAwO1xuICAgICAgICAgICAgICAgIHdpZHRoOiA2MDAlO1xuICAgICAgICAgICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiBpbmhlcml0O1xuICAgICAgICAgICAgICAgIHotaW5kZXg6IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGEuc3dpcGVvdXQtZGVsZXRlIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQ6IEByZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLnN3aXBlb3V0LWFjdGlvbnMtcmlnaHQge1xuICAgICAgICByaWdodDogMCU7XG4gICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlWCgxMDAlKSk7XG4gICAgICAgIGE6YWZ0ZXIge1xuICAgICAgICAgICAgbGVmdDogMTAwJTtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiAtMXB4O1xuICAgICAgICB9XG4gICAgfVxuICAgIC5zd2lwZW91dC1hY3Rpb25zLWxlZnQge1xuICAgICAgICBsZWZ0OiAwJTtcbiAgICAgICAgLnRyYW5zZm9ybSh0cmFuc2xhdGVYKC0xMDAlKSk7XG4gICAgICAgIGE6YWZ0ZXIge1xuICAgICAgICAgICAgcmlnaHQ6IDEwMCU7XG4gICAgICAgICAgICBtYXJnaW4tcmlnaHQ6IC0xcHg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tc3VidGl0bGUge1xuICAgICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgICAgbWF4LXdpZHRoOiAxMDAlO1xuICAgICAgICB0ZXh0LW92ZXJmbG93OmVsbGlwc2lzO1xuICAgIH1cbiAgICAuaXRlbS10ZXh0IHtcbiAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgICBjb2xvcjogIzc1NzU3NTtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDIwcHg7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgbWF4LWhlaWdodDogNDBweDtcbiAgICAgICAgdGV4dC1vdmVyZmxvdzplbGxpcHNpcztcbiAgICAgICAgLXdlYmtpdC1saW5lLWNsYW1wOiAyO1xuICAgICAgICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgICAgICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgICB9XG4gICAgJi5tZWRpYS1saXN0LCBsaS5tZWRpYS1pdGVtIHtcbiAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICBwYWRkaW5nLXRvcDogMTRweDtcbiAgICAgICAgICAgIHBhZGRpbmctYm90dG9tOiAxNHB4O1xuICAgICAgICAgICAgLmFsaWduLXNlbGYoc3RyZXRjaCk7XG4gICAgICAgIH1cbiAgICAgICAgLml0ZW0tbGluayAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgICAgICAgICAgcGFkZGluZy1yaWdodDogMTZweDtcbiAgICAgICAgfVxuICAgICAgICAuaXRlbS1saW5rIC5pdGVtLXRpdGxlLXJvdyB7XG4gICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiAyNnB4O1xuICAgICAgICAgICAgYmFja2dyb3VuZDogbm8tcmVwZWF0IHJpZ2h0IHRvcDtcbiAgICAgICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB2aWV3Qm94PScwIDAgNjAgMTIwJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxwYXRoIGQ9J202MCA2MS41LTM4LjI1IDM4LjI1LTkuNzUtOS43NSAyOS4yNS0yOC41LTI5LjI1LTI4LjUgOS43NS05Ljc1eicgZmlsbD0nI2M3YzdjYycvPjwvc3ZnPlwiKTtcbiAgICAgICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTBweCAyMHB4O1xuICAgICAgICB9XG4gICAgICAgIC5pdGVtLW1lZGlhIHtcbiAgICAgICAgICAgIHBhZGRpbmctdG9wOiAxNHB4O1xuICAgICAgICAgICAgcGFkZGluZy1ib3R0b206IDE0cHg7XG4gICAgICAgICAgICAuYWxpZ24tc2VsZihmbGV4LXN0YXJ0KTtcbiAgICAgICAgICAgIGltZyB7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLml0ZW0tdGl0bGUtcm93IHtcbiAgICAgICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgICAgICAuanVzdGlmeS1jb250ZW50KHNwYWNlLWJldHdlZW4pO1xuICAgICAgICB9XG4gICAgICAgIC5pdGVtLWNvbnRlbnQgPiAuaXRlbS1hZnRlciB7XG4gICAgICAgICAgICBwYWRkaW5nLXRvcDogMTRweDtcbiAgICAgICAgICAgIHBhZGRpbmctYm90dG9tOiAxNHB4O1xuICAgICAgICAgICAgLmFsaWduLXNlbGYoZmxleC1zdGFydCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLmxpc3QtZ3JvdXAge1xuICAgICAgICB1bCB7XG4gICAgICAgICAgICAmOmFmdGVyLCAmOmJlZm9yZSB7XG4gICAgICAgICAgICAgICAgei1pbmRleDogMTE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgKyAubGlzdC1ncm91cCB1bCB7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7ICAgXG4gICAgICAgIH1cbiAgICB9XG4gICAgLml0ZW0tZGl2aWRlciwgLmxpc3QtZ3JvdXAtdGl0bGUge1xuICAgICAgICBiYWNrZ3JvdW5kOiAjZjRmNGY0O1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgICAgIHBhZGRpbmc6IDBweCAxNnB4O1xuICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG1heC13aWR0aDogMTAwJTtcbiAgICAgICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIGNvbG9yOiByZ2JhKDAsMCwwLDAuNTQpO1xuICAgICAgICBoZWlnaHQ6IDQ4cHg7XG4gICAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiA0OHB4O1xuICAgICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgfVxuICAgIC5saXN0LWdyb3VwLXRpdGxlIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBwb3NpdGlvbjogLXdlYmtpdC1zdGlja3k7XG4gICAgICAgIHBvc2l0aW9uOiAtbW96LXN0aWNreTtcbiAgICAgICAgcG9zaXRpb246IHN0aWNreTtcbiAgICAgICAgdG9wOiAwcHg7XG4gICAgICAgIHotaW5kZXg6IDEwO1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgIH1cbiAgICAvLyBTb3J0YWJsZVxuICAgIC5zb3J0YWJsZS1oYW5kbGVyIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICByaWdodDogMDtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICBib3R0b206IDFweDtcbiAgICAgICAgei1pbmRleDogMTA7XG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgICAgIGJhY2tncm91bmQtc2l6ZTogMThweCAxMnB4O1xuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7XG4gICAgICAgIHdpZHRoOiA1MHB4O1xuICAgICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZChcIjxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB2aWV3Qm94PScwIDAgMTggMTInIGZpbGw9JyNjN2M3Y2MnPjxwYXRoIGQ9J00wLDJWMGgyMnYySDB6Jy8+PHBhdGggZD0nTTAsN1Y1aDIydjJIMHonLz48cGF0aCBkPSdNMCwxMnYtMmgyMnYySDB6Jy8+PC9zdmc+XCIpO1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB2aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgIH1cbiAgICAmLnNvcnRhYmxlIHtcbiAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpOyAgICAgICBcbiAgICAgICAgfVxuICAgIH1cbiAgICAmLnNvcnRhYmxlLW9wZW5lZCB7XG4gICAgICAgIC5zb3J0YWJsZS1oYW5kbGVyIHtcbiAgICAgICAgICAgIHZpc2liaWxpdHk6IHZpc2libGU7XG4gICAgICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB9XG4gICAgICAgIC5pdGVtLWlubmVyLCAuaXRlbS1saW5rIC5pdGVtLWlubmVyIHtcbiAgICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDE2cHggKyAxOHB4ICsgMTZweDtcbiAgICAgICAgfVxuICAgICAgICAuaXRlbS1saW5rIC5pdGVtLWlubmVyLCAuaXRlbS1saW5rIC5pdGVtLXRpdGxlLXJvdyB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiBub25lO1xuICAgICAgICB9XG4gICAgfVxuICAgICYuc29ydGFibGUtc29ydGluZyB7XG4gICAgICAgIGxpIHtcbiAgICAgICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsaS5zb3J0aW5nIHtcbiAgICAgICAgei1pbmRleDogNTA7XG4gICAgICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LDI1NSwyNTUsMC44KTtcbiAgICAgICAgLmRlcHRoKDIpO1xuICAgICAgICAudHJhbnNpdGlvbigwbXMpO1xuICAgICAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMYXN0LWNoaWxkc1xuICAgIGxpIHtcbiAgICAgICAgJjpsYXN0LWNoaWxkIHtcbiAgICAgICAgICAgIC5saXN0LWJ1dHRvbiB7XG4gICAgICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgICY6bGFzdC1jaGlsZCwgJjpsYXN0LWNoaWxkIGxpOmxhc3QtY2hpbGQge1xuICAgICAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsaTpsYXN0LWNoaWxkLCAmOmxhc3QtY2hpbGQgbGkge1xuICAgICAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgICAgIC5oYWlybGluZShib3R0b20sIEBsaXN0QmxvY2tCb3JkZXJDb2xvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAubm8taGFpcmxpbmVzKCk7XG4gICAgLm5vLWhhaXJsaW5lcy1iZXR3ZWVuKClcbn1cbiIsIi8qID09PSBGb3JtcyA9PT0gKi9cbi8vIElucHV0c1xuLmxpc3QtYmxvY2sge1xuICAgIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLCBpbnB1dFt0eXBlPVwicGFzc3dvcmRcIl0sIGlucHV0W3R5cGU9XCJzZWFyY2hcIl0sIGlucHV0W3R5cGU9XCJlbWFpbFwiXSwgaW5wdXRbdHlwZT1cInRlbFwiXSwgaW5wdXRbdHlwZT1cInVybFwiXSwgaW5wdXRbdHlwZT1cImRhdGVcIl0sIGlucHV0W3R5cGU9XCJkYXRldGltZS1sb2NhbFwiXSwgaW5wdXRbdHlwZT1cInRpbWVcIl0sIGlucHV0W3R5cGU9XCJudW1iZXJcIl0sIHNlbGVjdCwgdGV4dGFyZWEge1xuICAgICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tb3otYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLW1zLWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIGFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIGJveC1zaXppbmc6Ym9yZGVyLWJveDtcbiAgICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgICAgICBib3JkZXItcmFkaXVzOiAwIDAgMCAwO1xuICAgICAgICBib3gtc2hhZG93OiBub25lO1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgbWFyZ2luOiAwO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAzNnB4O1xuICAgICAgICBjb2xvcjogIzIxMjEyMTtcbiAgICAgICAgZm9udC1zaXplOiAxNnB4O1xuICAgICAgICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgICAgICAgJjo6LXdlYmtpdC1pbnB1dC1wbGFjZWhvbGRlciB7XG4gICAgICAgICAgIGNvbG9yOiByZ2JhKDAsMCwwLDAuMzUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5sYWJlbCwgLmZsb2F0aW5nLWxhYmVsIHtcbiAgICAgICAgdmVydGljYWwtYWxpZ246IHRvcDtcbiAgICAgICAgY29sb3I6cmdiYSgwLDAsMCwwLjY1KTtcbiAgICAgICAgLnRyYW5zaXRpb24oMjAwbXMpO1xuICAgICAgICB3aWR0aDogMzUlO1xuICAgICAgICAuZmxleC1zaHJpbmsoMCk7XG4gICAgfVxuICAgIFxuICAgIGlucHV0W3R5cGU9XCJkYXRlXCJdLCBpbnB1dFt0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIl0ge1xuICAgICAgICBsaW5lLWhlaWdodDogNDRweDtcbiAgICB9XG4gICAgc2VsZWN0IHtcbiAgICAgICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtbW96LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tcy1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgIH1cbiAgICB0ZXh0YXJlYSB7XG4gICAgICAgIHJlc2l6ZTpub25lO1xuICAgICAgICBsaW5lLWhlaWdodDogMS40O1xuICAgICAgICBwYWRkaW5nLXRvcDogOHB4O1xuICAgICAgICBwYWRkaW5nLWJvdHRvbTogN3B4O1xuICAgICAgICBoZWlnaHQ6IDEwMHB4O1xuICAgICAgICAmLnJlc2l6YWJsZSB7XG4gICAgICAgICAgICBoZWlnaHQ6IDM2cHg7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAuaXRlbS1pbnB1dCB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICAtbXMtZmxleDoxO1xuICAgICAgICAuZmxleC1zaHJpbmsoMSk7XG4gICAgICAgIGZvbnQtc2l6ZTogMDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBtYXJnaW4tYm90dG9tOiA0cHg7XG4gICAgICAgIG1pbi1oZWlnaHQ6IDM2cHg7XG4gICAgfVxuXG4gICAgLy8gSW5wdXRzIExpc3RcbiAgICAuaW5wdXQtaXRlbSwgJi5pbnB1dHMtbGlzdCB7XG4gICAgICAgIHVsIHtcbiAgICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUoYm90dG9tKTtcbiAgICAgICAgfVxuICAgICAgICAuaXRlbS1tZWRpYSB7XG4gICAgICAgICAgICAuYWxpZ24tc2VsZihmbGV4LWVuZCk7XG4gICAgICAgICAgICBtaW4taGVpZ2h0OiAzNnB4O1xuICAgICAgICAgICAgbWFyZ2luLWJvdHRvbTogOHB4O1xuICAgICAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgfVxuICAgICAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgICAgIG1hcmdpbi1ib3R0b206IDRweDtcbiAgICAgICAgICAgIHBhZGRpbmctYm90dG9tOiAwO1xuICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICB9XG4gICAgICAgIC5sYWJlbCwgLmZsb2F0aW5nLWxhYmVsIHtcbiAgICAgICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgICB9XG4gICAgICAgIC5mbG9hdGluZy1sYWJlbCB7XG4gICAgICAgICAgICAudHJhbnNmb3JtLW9yaWdpbihsZWZ0KTtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGUoMTYvMTIpIHRyYW5zbGF0ZVkoMjFweCkpO1xuICAgICAgICAgICAgY29sb3I6IHJnYmEoMCwwLDAsMC4zNSk7XG4gICAgICAgICAgICB3aWR0aDogYXV0bztcbiAgICAgICAgICAgIG1heC13aWR0aDogNzUlO1xuICAgICAgICAgICAgfi5pdGVtLWlucHV0IGlucHV0Ojotd2Via2l0LWlucHV0LXBsYWNlaG9sZGVyIHtcbiAgICAgICAgICAgICAgIGNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAuZm9jdXMtc3RhdGUsIC5ub3QtZW1wdHktc3RhdGUge1xuICAgICAgICAuZmxvYXRpbmctbGFiZWwge1xuICAgICAgICAgICAgY29sb3I6cmdiYSgwLDAsMCwwLjY1KTtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGUoMSkgdHJhbnNsYXRlWSgwKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLmZvY3VzLXN0YXRlIHtcbiAgICAgICAgLmxhYmVsLCAuZmxvYXRpbmctbGFiZWwge1xuICAgICAgICAgICAgY29sb3I6IEB0aGVtZUNvbG9yO1xuICAgICAgICB9XG4gICAgfVxufVxuLml0ZW0taW5wdXQtZmllbGQsIC5pbnB1dC1maWVsZCB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIC5oYWlybGluZShib3R0b20sIHJnYmEoMCwgMCwgMCwgMC4xMikpO1xuICAgICY6YWZ0ZXIge1xuICAgICAgICAudHJhbnNpdGlvbigyMDBtcyk7XG4gICAgfVxuICAgICYuZm9jdXMtc3RhdGU6YWZ0ZXIsICYubm90LWVtcHR5LXN0YXRlOmFmdGVyLCAuZm9jdXMtc3RhdGUgJjphZnRlciwgLm5vdC1lbXB0eS1zdGF0ZSAmOmFmdGVye1xuICAgICAgICBiYWNrZ3JvdW5kOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgLnRyYW5zZm9ybShzY2FsZVkoMikpICFpbXBvcnRhbnQ7XG4gICAgfVxufVxudGV4dGFyZWEucmVzaXphYmxlIHtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuLy9Td2l0Y2hcbi5sYWJlbC1zd2l0Y2gge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICAgIHdpZHRoOiAzNnB4O1xuICAgIGhlaWdodDogMTRweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIC5hbGlnbi1zZWxmKGNlbnRlcik7XG4gICAgLmNoZWNrYm94IHtcbiAgICAgICAgd2lkdGg6IDM2cHg7IFxuICAgICAgICBib3JkZXItcmFkaXVzOiAzNnB4O1xuICAgICAgICBib3gtc2l6aW5nOmJvcmRlci1ib3g7XG4gICAgICAgIGhlaWdodDogMTRweDtcbiAgICAgICAgYmFja2dyb3VuZDogI2IwYWZhZjtcbiAgICAgICAgei1pbmRleDogMDtcbiAgICAgICAgbWFyZ2luOiAwO1xuICAgICAgICBwYWRkaW5nOiAwO1xuICAgICAgICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIC1tb3otYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLW1zLWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIGFwcGVhcmFuY2U6IG5vbmU7XG4gICAgICAgIGJvcmRlcjpub25lO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICAmOmFmdGVyIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6JyAnO1xuICAgICAgICAgICAgaGVpZ2h0OiAyMHB4O1xuICAgICAgICAgICAgd2lkdGg6IDIwcHg7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAyMHB4O1xuICAgICAgICAgICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICAgIHotaW5kZXg6IDI7XG4gICAgICAgICAgICB0b3A6IC0zcHg7XG4gICAgICAgICAgICBsZWZ0OiAwcHg7XG4gICAgICAgICAgICBib3gtc2hhZG93OiAwIDJweCA1cHggcmdiYSgwLDAsMCwwLjQpO1xuICAgICAgICAgICAgLnRyYW5zZm9ybSh0cmFuc2xhdGVYKDBweCkpO1xuICAgICAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlucHV0W3R5cGU9XCJjaGVja2JveFwiXSB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICAgICY6Y2hlY2tlZCB7XG4gICAgICAgICAgICAmKyAuY2hlY2tib3gge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6IHJnYmEocmVkKEB0aGVtZUNvbG9yKSwgZ3JlZW4oQHRoZW1lQ29sb3IpLCBibHVlKEB0aGVtZUNvbG9yKSwgMC41KTtcbiAgICAgICAgICAgICAgICAmOmFmdGVyIHtcbiAgICAgICAgICAgICAgICAgICAgLnRyYW5zZm9ybSh0cmFuc2xhdGVYKDE2cHgpKTtcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogQHRoZW1lQ29sb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC5pdGVtLWlucHV0ICYge1xuICAgICAgICB0b3A6ICgzNnB4IC0gMTRweCkgLyAyO1xuICAgIH1cbn1cblxuLy9CdXR0b25zXG4uYnV0dG9uIHtcbiAgICBjb2xvcjpAdGhlbWVDb2xvcjtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICBsaW5lLWhlaWdodDogMzZweDtcbiAgICBib3gtc2l6aW5nOmJvcmRlci1ib3g7XG4gICAgLXdlYmtpdC1hcHBlYXJhbmNlOiBub25lO1xuICAgIC1tb3otYXBwZWFyYW5jZTogbm9uZTtcbiAgICAtbXMtYXBwZWFyYW5jZTogbm9uZTtcbiAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgcGFkZGluZzogMCAxMHB4O1xuICAgIG1hcmdpbjogMDtcbiAgICBoZWlnaHQ6IDM2cHg7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICB0ZXh0LW92ZXJmbG93OmVsbGlwc2lzO1xuICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xuICAgIGZvbnQtZmFtaWx5OiBpbmhlcml0O1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBtaW4td2lkdGg6IDY0cHg7XG4gICAgcGFkZGluZzogMCA4cHg7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgb3V0bGluZTogMDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgaW5wdXRbdHlwZT1cInN1Ym1pdFwiXSYsIGlucHV0W3R5cGU9XCJidXR0b25cIl0me1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICB9XG4gICAgaHRtbDpub3QoLndhdGNoLWFjdGl2ZS1zdGF0ZSkgJjphY3RpdmUsICYuYWN0aXZlLXN0YXRlIHtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgwLDAsMCwwLjEpO1xuICAgIH1cbiAgICAmLmJ1dHRvbi1maWxsIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQHRoZW1lQ29sb3I7XG4gICAgICAgIGNvbG9yOiAjZmZmO1xuICAgICAgICBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZSwgJi5hY3RpdmUtc3RhdGUge1xuICAgICAgICAgICAgYmFja2dyb3VuZDogZGFya2VuKEB0aGVtZUNvbG9yLCA4JSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgJi5idXR0b24tYmlnIHtcbiAgICAgICAgaGVpZ2h0OiA0OHB4O1xuICAgICAgICBsaW5lLWhlaWdodDogNDhweDtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xuICAgIH1cblxuICAgIGkuaWNvbiArIHNwYW4sXG4gICAgc3Bhbjpub3QoLnJpcHBsZS13YXZlKSArIHNwYW4sXG4gICAgc3Bhbjpub3QoLnJpcHBsZS13YXZlKSArIGkuaWNvbixcbiAgICBpLmljb24gKyBpLmljb24ge1xuICAgICAgICBtYXJnaW4tbGVmdDogOHB4O1xuICAgIH1cblxuICAgIC5uYXZiYXIgJiwgLnRvb2xiYXIgJiwgLnN1Ym5hdmJhciAmLCAubm90aWZpY2F0aW9ucyAmIHtcbiAgICAgICAgJjpub3QoLmJ1dHRvbi1maWxsKSB7XG4gICAgICAgICAgICBjb2xvcjojZmZmO1xuICAgICAgICAgICAgaHRtbDpub3QoLndhdGNoLWFjdGl2ZS1zdGF0ZSkgJjphY3RpdmUsICYuYWN0aXZlLXN0YXRlIHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwyNTUsMjU1LDAuMTUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLmJ1dHRvbi1yYWlzZWQge1xuICAgIC5kZXB0aCgxKTtcbiAgICBodG1sOm5vdCgud2F0Y2gtYWN0aXZlLXN0YXRlKSAmOmFjdGl2ZSwgJi5hY3RpdmUtc3RhdGUge1xuICAgICAgICAuZGVwdGgoMik7XG4gICAgfVxufVxuLmJ1dHRvbnMtcm93IHtcbiAgICAuYWxpZ24tc2VsZihjZW50ZXIpO1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmZsZXgtd3JhcChub3dyYXApO1xuICAgIC5idXR0b24ge1xuICAgICAgICBtYXJnaW4tbGVmdDogMTZweDtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIC13ZWJraXQtYm94LWZsZXg6MTtcbiAgICAgICAgLW1zLWZsZXg6MTtcbiAgICB9XG4gICAgLmJ1dHRvbjpmaXJzdC1jaGlsZCB7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAwO1xuICAgIH1cbn1cblxuXG4vLyBTbGlkZXJcbi5yYW5nZS1zbGlkZXIge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIC5hbGlnbi1zZWxmKGNlbnRlcik7XG4gICAgaW5wdXRbdHlwZT1cInJhbmdlXCJdIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBoZWlnaHQ6IDIwcHg7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLW1vei1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtbXMtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgYmFja2dyb3VuZDogLXdlYmtpdC1ncmFkaWVudChsaW5lYXIsIDUwJSAwLCA1MCUgMTAwJSwgY29sb3Itc3RvcCgwLCAjYjliOWI5KSwgY29sb3Itc3RvcCgxMDAlLCAjYjliOWI5KSk7XG4gICAgICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgI2I5YjliOSAwLCAjYjliOWI5IDEwMCUpO1xuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBjZW50ZXI7XG4gICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTAwJSAycHg7XG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgICAgIG91dGxpbmU6IDA7XG4gICAgICAgIC1tcy1iYWNrZ3JvdW5kLXBvc2l0aW9uLXk6IDUwMHB4O1xuICAgICAgICAmOmZvY3VzLCAmOmFjdGl2ZSB7XG4gICAgICAgICAgICBib3JkZXI6IDA7XG4gICAgICAgICAgICBvdXRsaW5lOiAwIG5vbmU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gUmFuZ2UgdGh1bWIgbWl4aW5cbiAgICAucmFuZ2UtdGh1bWIoKSB7XG4gICAgICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgLW1vei1hcHBlYXJhbmNlOiBub25lO1xuICAgICAgICAtbXMtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgICBvdXRsaW5lOiAwO1xuICAgICAgICBoZWlnaHQ6IDIwcHg7XG4gICAgICAgIHdpZHRoOiAyMHB4O1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIGJhY2tncm91bmQ6IEB0aGVtZUNvbG9yO1xuICAgICAgICBib3JkZXItcmFkaXVzOiAyMHB4O1xuICAgIH1cblxuICAgIC8vID09PT09PT0gV2Via2l0ID09PT09PT09XG4gICAgaW5wdXRbdHlwZT1cInJhbmdlXCJdOjotd2Via2l0LXNsaWRlci10aHVtYiB7XG4gICAgICAgIC5yYW5nZS10aHVtYigpO1xuICAgIH1cblxuICAgIGlucHV0W3R5cGU9XCJyYW5nZVwiXTo6LXdlYmtpdC1zbGlkZXItdGh1bWI6YmVmb3JlIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICB0b3A6IDUwJTtcbiAgICAgICAgcmlnaHQ6IDEwMCU7XG4gICAgICAgIHdpZHRoOiAyMDAwcHg7XG4gICAgICAgIGhlaWdodDogMnB4O1xuICAgICAgICBtYXJnaW4tdG9wOiAtMXB4O1xuICAgICAgICB6LWluZGV4OiAxO1xuICAgICAgICBiYWNrZ3JvdW5kOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgY29udGVudDogJyAnO1xuICAgIH1cblxuICAgIC8vID09PT09PT0gRmlyZUZveCA9PT09PT09PVxuICAgIGlucHV0W3R5cGU9XCJyYW5nZVwiXTo6LW1vei1yYW5nZS10cmFjayB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IDJweDtcbiAgICAgICAgYmFja2dyb3VuZDogI2I3YjhiNztcbiAgICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgICBvdXRsaW5lOiAwO1xuICAgIH1cbiAgICBpbnB1dFt0eXBlPVwicmFuZ2VcIl06Oi1tb3otcmFuZ2UtdGh1bWIge1xuICAgICAgICAucmFuZ2UtdGh1bWIoKTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09IElFID09PT09PT09XG4gICAgaW5wdXRbdHlwZT1cInJhbmdlXCJdOjotbXMtdHJhY2sge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAycHg7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICAgIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgICAgIGNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICB9XG4gICAgaW5wdXRbdHlwZT1cInJhbmdlXCJdOjotbXMtdGh1bWIge1xuICAgICAgICAucmFuZ2UtdGh1bWIoKTtcbiAgICB9XG5cbiAgICBpbnB1dFt0eXBlPVwicmFuZ2VcIl06Oi1tcy1maWxsLWxvd2VyIHtcbiAgICAgICAgYmFja2dyb3VuZDogQHRoZW1lQ29sb3I7XG4gICAgfVxuICAgIGlucHV0W3R5cGU9XCJyYW5nZVwiXTo6LW1zLWZpbGwtdXBwZXIge1xuICAgICAgICBiYWNrZ3JvdW5kOiAjYjdiOGI3O1xuICAgIH1cblxuICAgIC5pdGVtLWlucHV0ICYge1xuICAgICAgICB0b3A6ICgzNnB4IC0gMjBweCkgLyAyO1xuICAgIH1cbn1cblxuLy8gQ2hlY2tib3hlc1xubGFiZWwubGFiZWwtY2hlY2tib3gge1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBpLmljb24tZm9ybS1jaGVja2JveCB7XG4gICAgICAgIHdpZHRoOiAxOHB4O1xuICAgICAgICBoZWlnaHQ6IDE4cHg7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMnB4O1xuICAgICAgICBib3JkZXI6IDJweCBzb2xpZCAjNmQ2ZDZkO1xuICAgICAgICBib3gtc2l6aW5nOmJvcmRlci1ib3g7XG4gICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICAgICY6YWZ0ZXIge1xuICAgICAgICAgICAgY29udGVudDonICc7XG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICB3aWR0aDogMThweDtcbiAgICAgICAgICAgIGhlaWdodDogMThweDtcbiAgICAgICAgICAgIGxlZnQ6IC0ycHg7XG4gICAgICAgICAgICB0b3A6IC0ycHg7XG4gICAgICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICAgICAgYmFja2dyb3VuZDogbm8tcmVwZWF0IGNlbnRlcjtcbiAgICAgICAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIGZpbGw9JyNmZmZmZmYnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0Jz48cGF0aCBkPSdNOSAxNi4xN0w0LjgzIDEybC0xLjQyIDEuNDFMOSAxOSAyMSA3bC0xLjQxLTEuNDF6Jy8+PC9zdmc+XCIpO1xuICAgICAgICAgICAgLXdlYmtpdC1iYWNrZ3JvdW5kLXNpemU6IDEwMCUgYXV0bztcbiAgICAgICAgICAgIGJhY2tncm91bmQtc2l6ZTogMTAwJSBhdXRvO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlucHV0W3R5cGU9XCJjaGVja2JveFwiXSwgaW5wdXRbdHlwZT1cInJhZGlvXCJdIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgJjpjaGVja2VkICsgLml0ZW0tbWVkaWEsICY6Y2hlY2tlZCB+IC5pdGVtLWFmdGVyLCAmOmNoZWNrZWQgfiAuaXRlbS1pbm5lcntcbiAgICAgICAgICAgIGkuaWNvbi1mb3JtLWNoZWNrYm94IHtcbiAgICAgICAgICAgICAgICBib3JkZXItY29sb3I6IEB0aGVtZUNvbG9yO1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IEB0aGVtZUNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaS5pY29uLWZvcm0tY2hlY2tib3g6YWZ0ZXIge1xuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5sYWJlbC5sYWJlbC1yYWRpbyB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGkuaWNvbi1mb3JtLXJhZGlvIHtcbiAgICAgICAgd2lkdGg6IDIwcHg7XG4gICAgICAgIGhlaWdodDogMjBweDtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBib3JkZXItcmFkaXVzOiAyMHB4O1xuICAgICAgICBib3JkZXI6IDJweCBzb2xpZCAjNmQ2ZDZkO1xuICAgICAgICBib3gtc2l6aW5nOmJvcmRlci1ib3g7XG4gICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgJjphZnRlciB7XG4gICAgICAgICAgICBjb250ZW50OicgJztcbiAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICAgIHdpZHRoOiAxMHB4O1xuICAgICAgICAgICAgaGVpZ2h0OiAxMHB4O1xuICAgICAgICAgICAgbGVmdDogNTAlO1xuICAgICAgICAgICAgdG9wOiA1MCU7XG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogLTVweDtcbiAgICAgICAgICAgIG1hcmdpbi10b3A6IC01cHg7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDEwMCU7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlKDApKTtcbiAgICAgICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0sIGlucHV0W3R5cGU9XCJyYWRpb1wiXSB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICAgICY6Y2hlY2tlZCArIC5pdGVtLW1lZGlhLCAmOmNoZWNrZWQgfiAuaXRlbS1hZnRlciwgJjpjaGVja2VkIH4gLml0ZW0taW5uZXJ7XG4gICAgICAgICAgICBpLmljb24tZm9ybS1yYWRpbyB7XG4gICAgICAgICAgICAgICAgYm9yZGVyLWNvbG9yOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGkuaWNvbi1mb3JtLXJhZGlvOmFmdGVyIHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlKDEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbmxhYmVsLmxhYmVsLWNoZWNrYm94LCBsYWJlbC5sYWJlbC1yYWRpbyB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgei1pbmRleDogMDtcbiAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgLml0ZW0tYWZ0ZXIge1xuICAgICAgICBpLmljb24tZm9ybS1jaGVja2JveCwgaS5pY29uLWZvcm0tcmFkaW8ge1xuICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICAgICAgICAgIG1hcmdpbi1yaWdodDogMTZweDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAubWVkaWEtbGlzdCAmLCAubWVkaWEtaXRlbSAmIHtcbiAgICAgICAgLml0ZW0tbWVkaWEge1xuICAgICAgICAgICAgaS5pY29uLWZvcm0tY2hlY2tib3gsIGkuaWNvbi1mb3JtLXJhZGlvIHtcbiAgICAgICAgICAgICAgICBtYXJnaW4tdG9wOiA0cHg7XG4gICAgICAgICAgICB9ICAgICAgIFxuICAgICAgICB9XG4gICAgfVxuICAgIGh0bWw6bm90KC53YXRjaC1hY3RpdmUtc3RhdGUpICY6YWN0aXZlLCAmLmFjdGl2ZS1zdGF0ZSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwwLDAsMC4xKTtcbiAgICAgICAgLml0ZW0taW5uZXIge1xuICAgICAgICAgICAgLmhhaXJsaW5lLWNvbG9yKGJvdHRvbSwgdHJhbnNwYXJlbnQpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vLyBTbWFydCBzZWxlY3RzXG4uc21hcnQtc2VsZWN0IHtcbiAgICBzZWxlY3Qge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbn1cbiIsIi8qID09PSBGbG9hdGluZyBBY3Rpb24gQnV0dG9uID09PSAqL1xuLmZsb2F0aW5nLWJ1dHRvbiB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHJpZ2h0OiAxNnB4O1xuICAgIGJvdHRvbTogMTZweDtcbiAgICB3aWR0aDogNTZweDtcbiAgICBoZWlnaHQ6IDU2cHg7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIHotaW5kZXg6IDE1MDA7XG4gICAgLmRlcHRoKDMpO1xuICAgIGJhY2tncm91bmQtY29sb3I6IEB0aGVtZUNvbG9yO1xuICAgIGNvbG9yOiNmZmY7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgLmZsZXhib3goKTtcbiAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbiAgICAuanVzdGlmeS1jb250ZW50KGNlbnRlcik7XG4gICAgaHRtbDpub3QoLndhdGNoLWFjdGl2ZS1zdGF0ZSkgJjphY3RpdmUsICYuYWN0aXZlLXN0YXRlIHtcbiAgICAgICAgYmFja2dyb3VuZDogZGFya2VuKEB0aGVtZUNvbG9yLCA4JSk7XG4gICAgfVxufVxuLmZsb2F0aW5nLWJ1dHRvbi10b29sYmFyLCAuc3BlZWQtZGlhbCB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHJpZ2h0OiAxNnB4O1xuICAgIGJvdHRvbTogMTZweDtcbiAgICB6LWluZGV4OiAxNTAwO1xuICAgIC5mbG9hdGluZy1idXR0b24ge1xuICAgICAgICByaWdodDogMDtcbiAgICAgICAgYm90dG9tOiAwO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgfVxufVxuLy8gU3BlZWQgRGlhbFxuLnNwZWVkLWRpYWwge1xuICAgIC5mbG9hdGluZy1idXR0b24ge1xuICAgICAgICBpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICAgIGxlZnQ6IDUwJTtcbiAgICAgICAgICAgIHRvcDogNTAlO1xuICAgICAgICAgICAgLnRyYW5zZm9ybSh0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKSByb3RhdGUoMGRlZykgc2NhbGUoMSkpO1xuICAgICAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICB9XG4gICAgICAgIGkgKyBpIHtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCkgcm90YXRlKC05MGRlZykgc2NhbGUoMC41KSk7XG4gICAgICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgICYuc3BlZWQtZGlhbC1vcGVuZWQge1xuICAgICAgICAuZmxvYXRpbmctYnV0dG9uIHtcbiAgICAgICAgICAgIGkge1xuICAgICAgICAgICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCkgcm90YXRlKDkwZGVnKSBzY2FsZSgwLjUpKTtcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSArIGkge1xuICAgICAgICAgICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCkgcm90YXRlKDBkZWcpIHNjYWxlKDEpKTtcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLnNwZWVkLWRpYWwtYnV0dG9ucyB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHdpZHRoOiA0MHB4O1xuICAgIGxlZnQ6IDUwJTtcbiAgICBtYXJnaW4tbGVmdDogLTIwcHg7XG4gICAgYm90dG9tOiAxMDAlO1xuICAgIG1hcmdpbi1ib3R0b206IDE2cHg7XG4gICAgLmZsZXhib3goKTtcbiAgICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgIC13ZWJraXQtYm94LWRpcmVjdGlvbjogcmV2ZXJzZTtcbiAgICAtbW96LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgIC1tb3otYm94LWRpcmVjdGlvbjogcmV2ZXJzZTtcbiAgICAtbXMtZmxleC1kaXJlY3Rpb246IGNvbHVtbi1yZXZlcnNlO1xuICAgIC13ZWJraXQtZmxleC1kaXJlY3Rpb246IGNvbHVtbi1yZXZlcnNlO1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW4tcmV2ZXJzZTtcbiAgICB2aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgYSB7XG4gICAgICAgIHdpZHRoOiA0MHB4O1xuICAgICAgICBoZWlnaHQ6IDQwcHg7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgICAgIGNvbG9yOiAjZmZmO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgei1pbmRleDogMTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQHRoZW1lQ29sb3I7XG4gICAgICAgIGh0bWw6bm90KC53YXRjaC1hY3RpdmUtc3RhdGUpICY6YWN0aXZlLCAmLmFjdGl2ZS1zdGF0ZSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiBkYXJrZW4oQHRoZW1lQ29sb3IsIDglKTtcbiAgICAgICAgfVxuICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC5hbGlnbi1pdGVtcyhjZW50ZXIpO1xuICAgICAgICAuanVzdGlmeS1jb250ZW50KGNlbnRlcik7XG4gICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwgOHB4LCAwKSBzY2FsZSgwLjMpKTtcbiAgICAgICAgLnRyYW5zZm9ybS1vcmlnaW4oY2VudGVyIGJvdHRvbSk7XG4gICAgICAgICsgYSB7XG4gICAgICAgICAgICBtYXJnaW4tYm90dG9tOiAxNnB4O1xuICAgICAgICB9XG4gICAgfVxuICAgIC5zcGVlZC1kaWFsLW9wZW5lZCAmIHtcbiAgICAgICAgdmlzaWJpbGl0eTogdmlzaWJsZTtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gICAgICAgIGEge1xuICAgICAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwgMCwgMCkgc2NhbGVZKDEpKTtcbiAgICAgICAgICAgIC5kZXB0aCgzKTtcbiAgICAgICAgICAgICY6bnRoLWNoaWxkKDIpIHtcbiAgICAgICAgICAgICAgICAuZGVsYXkoNTBtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmOm50aC1jaGlsZCgzKSB7XG4gICAgICAgICAgICAgICAgLmRlbGF5KDEwMG1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICY6bnRoLWNoaWxkKDQpIHtcbiAgICAgICAgICAgICAgICAuZGVsYXkoMTUwbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgJjpudGgtY2hpbGQoNSkge1xuICAgICAgICAgICAgICAgIC5kZWxheSgyMDBtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmOm50aC1jaGlsZCg2KSB7XG4gICAgICAgICAgICAgICAgLmRlbGF5KDI1MG1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gUG9wb3ZlIE1vcnBoXG4uZmxvYXRpbmctYnV0dG9uLXRvLXBvcG92ZXIge1xuICAgICYuZmxvYXRpbmctYnV0dG9uLXRvLXBvcG92ZXIge1xuICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgfVxuICAgICYuZmxvYXRpbmctYnV0dG9uLXRvLXBvcG92ZXItaW4ge1xuICAgICAgICAudHJhbnNpdGlvbigxMDBtcyk7XG4gICAgICAgIGkge1xuICAgICAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgICAgIC50cmFuc2l0aW9uKDEwMG1zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAmLmZsb2F0aW5nLWJ1dHRvbi10by1wb3BvdmVyLXNjYWxlIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMDtcbiAgICAgICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgICAgICBib3gtc2hhZG93OiBub25lO1xuICAgIH1cbiAgICAmLmZsb2F0aW5nLWJ1dHRvbi10by1wb3BvdmVyLW91dCB7XG4gICAgICAgIC5kZWxheSgwbXMpO1xuICAgICAgICAudHJhbnNpdGlvbigzMDBtcyk7XG4gICAgICAgIGkge1xuICAgICAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgICAgIC50cmFuc2l0aW9uKDEwMG1zKTtcbiAgICAgICAgICAgIC5kZWxheSgyMDBtcyk7XG4gICAgICAgIH1cbiAgICB9XG59IiwiLyogPT09IE1vZGFscyA9PT0gKi9cbkBtb2RhbEJnQ29sb3I6I2ZmZjtcbkBtb2RhbEJ1dG9uQ29sb3IgOiAjNDI4NWY0O1xuQG1vZGFsQnV0b25CZzogQG1vZGFsQmdDb2xvcjtcbkBtb2RhbER1cmF0aW9uOjQwMG1zO1xuQGFjdGlvbnNNb2RhbER1cmF0aW9uOjMwMG1zO1xuQHBvcG92ZXJEdXJhdGlvbjogMzAwbXM7XG5AcG9wdXBEdXJhdGlvbjogNDAwbXM7XG4ubW9kYWwtb3ZlcmxheSwgLnByZWxvYWRlci1pbmRpY2F0b3Itb3ZlcmxheSwgLnBvcHVwLW92ZXJsYXksIC5waWNrZXItbW9kYWwtb3ZlcmxheSB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IDA7XG4gICAgdG9wOiAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsMCwwLDAuNCk7XG4gICAgei1pbmRleDogMTMwMDA7XG4gICAgdmlzaWJpbGl0eTogaGlkZGVuO1xuICAgIG9wYWNpdHk6IDA7XG4gICAgLnRyYW5zaXRpb24oQG1vZGFsRHVyYXRpb24pO1xuICAgICYubW9kYWwtb3ZlcmxheS12aXNpYmxlIHtcbiAgICAgICAgdmlzaWJpbGl0eTogdmlzaWJsZTtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG59XG4ucG9wdXAtb3ZlcmxheSB7XG4gICAgei1pbmRleDogMTA1MDA7XG59XG4ucGlja2VyLW1vZGFsLW92ZXJsYXkge1xuICAgIHotaW5kZXg6IDEyMDAwO1xufVxuLm1vZGFsIHtcbiAgICB3aWR0aDogMjgwcHg7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHotaW5kZXg6IDEzNTAwO1xuICAgIGxlZnQ6IDUwJTtcbiAgICBtYXJnaW4tbGVmdDogLTE0MHB4O1xuICAgIG1hcmdpbi10b3A6IDA7XG4gICAgdG9wOiA1MCU7XG4gICAgYm9yZGVyLXJhZGl1czogM3B4O1xuICAgIG9wYWNpdHk6IDA7XG4gICAgLnRyYW5zZm9ybSh0cmFuc2xhdGUzZCgwLDAsMCkgc2NhbGUoMS4xODUpKTtcbiAgICAtd2Via2l0LXRyYW5zaXRpb24tcHJvcGVydHk6IC13ZWJraXQtdHJhbnNmb3JtLCBvcGFjaXR5O1xuICAgIC1tb3otdHJhbnNpdGlvbi1wcm9wZXJ0eTogLW1vei10cmFuc2Zvcm0sIG9wYWNpdHk7XG4gICAgLW1zLXRyYW5zaXRpb24tcHJvcGVydHk6IC1tcy10cmFuc2Zvcm0sIG9wYWNpdHk7XG4gICAgLW8tdHJhbnNpdGlvbi1wcm9wZXJ0eTogLW8tdHJhbnNmb3JtLCBvcGFjaXR5O1xuICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybSwgb3BhY2l0eTtcbiAgICBjb2xvcjojNzU3NTc1O1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgLmRlcHRoKDUpO1xuICAgICYubW9kYWwtaW4ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICAudHJhbnNpdGlvbihAbW9kYWxEdXJhdGlvbik7XG4gICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlKDEpKTtcbiAgICB9XG4gICAgJi5tb2RhbC1vdXQge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB6LWluZGV4OiAxMzUwMC0xO1xuICAgICAgICAudHJhbnNpdGlvbihAbW9kYWxEdXJhdGlvbik7XG4gICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlKDAuODE1KSk7XG4gICAgfVxufVxuLm1vZGFsLWlubmVyIHtcbiAgICBwYWRkaW5nOiAyNHB4IDI0cHggMjBweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG4ubW9kYWwtdGl0bGUge1xuICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgZm9udC1zaXplOiAyMHB4O1xuICAgIGNvbG9yOiMyMTIxMjE7XG4gICAgbGluZS1oZWlnaHQ6IDEuMztcbiAgICArLm1vZGFsLXRleHQge1xuICAgICAgICBtYXJnaW4tdG9wOiAyMHB4O1xuICAgIH1cbn1cbi5tb2RhbC10ZXh0IHtcbiAgICBsaW5lLWhlaWdodDogMS41O1xufVxuLm1vZGFsLWJ1dHRvbnMge1xuICAgIGhlaWdodDogNDhweDtcbiAgICBwYWRkaW5nOiA2cHggOHB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYm94LXNpemluZzpib3JkZXItYm94O1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmp1c3RpZnktY29udGVudChmbGV4LWVuZCk7XG4gICAgJi5tb2RhbC1idXR0b25zLXZlcnRpY2FsIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIGhlaWdodDogYXV0bztcbiAgICAgICAgcGFkZGluZzogMCAwIDhweCAwO1xuICAgICAgICAubW9kYWwtYnV0dG9uIHtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiAwO1xuICAgICAgICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgICAgICAgICBoZWlnaHQ6IDQ4cHg7XG4gICAgICAgICAgICBsaW5lLWhlaWdodDogNDhweDtcbiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDE2cHg7XG4gICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiAxNnB4O1xuICAgICAgICB9XG4gICAgfVxufVxuLm1vZGFsLWJ1dHRvbiwgLm1vZGFsLWJ1dHRvbnMgLmJ1dHRvbiB7XG4gICAgLmJ1dHRvbjtcbiAgICAmLm1vZGFsLWJ1dHRvbi1ib2xkIHtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICB9XG4gICAgKyAubW9kYWwtYnV0dG9uIHtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDRweDtcbiAgICB9XG59XG4ubW9kYWwtbm8tYnV0dG9ucyB7XG4gICAgLm1vZGFsLWJ1dHRvbnMge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbn1cbi8vIEFjdGlvbiBzaGVldFxuLmFjdGlvbnMtbW9kYWwge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICB6LWluZGV4OiAxMzUwMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwxMDAlLDApKTtcbiAgICBtYXgtaGVpZ2h0OiAxMDAlO1xuICAgIC5zY3JvbGxhYmxlKCk7XG4gICAgJi5tb2RhbC1pbiB7XG4gICAgICAgIC50cmFuc2l0aW9uKEBhY3Rpb25zTW9kYWxEdXJhdGlvbik7XG4gICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwwLDApKTtcbiAgICB9XG4gICAgJi5tb2RhbC1vdXQge1xuICAgICAgICB6LWluZGV4OiAxMzUwMC0xO1xuICAgICAgICAudHJhbnNpdGlvbihAYWN0aW9uc01vZGFsRHVyYXRpb24pO1xuICAgICAgICAudHJhbnNmb3JtKHRyYW5zbGF0ZTNkKDAsMTAwJSwwKSk7XG4gICAgfVxufVxuLmFjdGlvbnMtbW9kYWwtZ3JvdXAge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAuaGFpcmxpbmUoYm90dG9tLCAjZDJkMmQ2KTtcbiAgICAmOmxhc3QtY2hpbGQge1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgfVxufVxuLmFjdGlvbnMtbW9kYWwtYnV0dG9uLCAuYWN0aW9ucy1tb2RhbC1sYWJlbCB7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgZm9udC13ZWlnaHQ6IG5vcm1hbDtcbiAgICBtYXJnaW46IDA7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgcGFkZGluZzogMCAxNnB4O1xuICAgIGEge1xuICAgICAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgICAgIGNvbG9yOiBpbmhlcml0O1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICB9XG4gICAgYiB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgfVxuICAgICYuYWN0aW9ucy1tb2RhbC1idXR0b24tYm9sZCB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgfVxuICAgICYuYWN0aW9ucy1tb2RhbC1idXR0b24tcmVkIHtcbiAgICAgICAgY29sb3I6IEByZWQ7XG4gICAgfVxuICAgICYuZGlzYWJsZWQge1xuICAgICAgICBvcGFjaXR5OiAwLjk1O1xuICAgICAgICBjb2xvcjpAZ3JheTtcbiAgICB9XG59XG4uYWN0aW9ucy1tb2RhbC1idXR0b24ge1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBsaW5lLWhlaWdodDogNDhweDtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgY29sb3I6IHJnYmEoMCwwLDAsMC44Nyk7XG4gICAgLnRyYW5zaXRpb24oMzAwbXMpO1xuICAgIGEsICYge1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzOyAgICBcbiAgICB9XG4gICAgaHRtbDpub3QoLndhdGNoLWFjdGl2ZS1zdGF0ZSkgJjphY3RpdmUsICYuYWN0aXZlLXN0YXRlIHtcbiAgICAgICAgYmFja2dyb3VuZDogcmdiYSgwLDAsMCwwLjEpO1xuICAgIH1cbn1cbi5hY3Rpb25zLW1vZGFsLWxhYmVsIHtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgY29sb3I6IHJnYmEoMCwwLDAsMC41NCk7XG4gICAgbWluLWhlaWdodDogNTZweDtcbiAgICBsaW5lLWhlaWdodDogMS4zO1xuICAgIHBhZGRpbmctdG9wOiAxMnB4O1xuICAgIHBhZGRpbmctYm90dG9tOiAxMnB4O1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmp1c3RpZnktY29udGVudChmbGV4LXN0YXJ0KTtcbiAgICAuYWxpZ24taXRlbXMoY2VudGVyKTtcbn1cbi8vIFByb21wdFxuaW5wdXQubW9kYWwtdGV4dC1pbnB1dCB7XG4gICAgYm94LXNpemluZzpib3JkZXItYm94O1xuICAgIGhlaWdodDogMzZweDtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgIG1hcmdpbjogMDtcbiAgICBtYXJnaW4tdG9wOiAxNXB4O1xuICAgIHBhZGRpbmc6IDA7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICBmb250LWZhbWlseTogaW5oZXJpdDtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBib3gtc2hhZG93OiBub25lO1xuICAgIC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcbiAgICAtbW96LWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgLW1zLWFwcGVhcmFuY2U6IG5vbmU7XG4gICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICAudHJhbnNpdGlvbigyMDBtcyk7XG4gICAgJjo6LXdlYmtpdC1pbnB1dC1wbGFjZWhvbGRlciB7XG4gICAgICAgY29sb3I6IHJnYmEoMCwwLDAsMC4zNSk7XG4gICAgfVxuICAgICsgaW5wdXQubW9kYWwtdGV4dC1pbnB1dCB7XG4gICAgICAgIG1hcmdpbi10b3A6IDE2cHg7XG4gICAgfVxufVxuLy8gUG9wb3ZlclxuLnBvcG92ZXIge1xuICAgIHdpZHRoOiAzMjBweDtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgIHotaW5kZXg6IDEzNTAwO1xuICAgIG1hcmdpbjogMDtcbiAgICB0b3A6IDA7XG4gICAgb3BhY2l0eTogMDtcbiAgICBsZWZ0OiAwO1xuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICAuZGVwdGgoMik7XG4gICAgLnRyYW5zZm9ybShzY2FsZSgwLjg1LCAwLjYpKTtcbiAgICAtd2Via2l0LXRyYW5zaXRpb24tcHJvcGVydHk6IG9wYWNpdHksIC13ZWJraXQtdHJhbnNmb3JtLCBib3JkZXItcmFkaXVzO1xuICAgIC1tb3otdHJhbnNpdGlvbi1wcm9wZXJ0eTogb3BhY2l0eSwgLW1vei10cmFuc2Zvcm0sIGJvcmRlci1yYWRpdXM7XG4gICAgdHJhbnNpdGlvbi1wcm9wZXJ0eTogb3BhY2l0eSwgdHJhbnNmb3JtLCBib3JkZXItcmFkaXVzO1xuICAgICYucG9wb3Zlci1vbi10b3Age1xuICAgICAgICAudHJhbnNmb3JtLW9yaWdpbihjZW50ZXIgYm90dG9tKTtcbiAgICB9XG4gICAgJi5wb3BvdmVyLW9uLWJvdHRvbSB7XG4gICAgICAgIC50cmFuc2Zvcm0tb3JpZ2luKGNlbnRlciB0b3ApO1xuICAgIH1cbiAgICAmLm1vZGFsLWluIHtcbiAgICAgICAgLnRyYW5zZm9ybShzY2FsZSgxKSk7XG4gICAgICAgIC50cmFuc2l0aW9uKEBwb3BvdmVyRHVyYXRpb24pO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICAmLm1vZGFsLW91dCB7XG4gICAgICAgIC50cmFuc2Zvcm0oc2NhbGUoMSkpO1xuICAgICAgICAudHJhbnNpdGlvbihAcG9wb3ZlckR1cmF0aW9uKTtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG4gICAgLmxpc3QtYmxvY2sge1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgICY6Zmlyc3QtY2hpbGQ6bGFzdC1jaGlsZCB1bCB7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgdWwge1xuICAgICAgICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgICAgICAgIC5oYWlybGluZS1yZW1vdmUodG9wKTtcbiAgICAgICAgfVxuICAgICAgICAmOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgICAgIHVsIHtcbiAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiAzcHggM3B4IDAgMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxpOmZpcnN0LWNoaWxkIGEge1xuICAgICAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDNweCAzcHggMCAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgICY6bGFzdC1jaGlsZCB7XG4gICAgICAgICAgICB1bCB7XG4gICAgICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDAgMCAzcHggM3B4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGk6bGFzdC1jaGlsZCBhIHtcbiAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiAwIDAgM3B4IDNweDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAmOmZpcnN0LWNoaWxkOmxhc3QtY2hpbGQge1xuICAgICAgICAgICAgbGk6Zmlyc3QtY2hpbGQ6bGFzdC1jaGlsZCBhLCB1bDpmaXJzdC1jaGlsZDpsYXN0LWNoaWxkIHtcbiAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiAzcHg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgJi5wb3BvdmVyLWZsb2F0aW5nLWJ1dHRvbiB7XG4gICAgICAgIC50cmFuc2Zvcm0tb3JpZ2luKGNlbnRlciBjZW50ZXIpO1xuICAgICAgICAudHJhbnNmb3JtKHNjYWxlKDAuNykpO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgICAgIC5kZXB0aCgzKTtcbiAgICAgICAgJi5tb2RhbC1pbiB7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAwJTtcbiAgICAgICAgICAgIC50cmFuc2Zvcm0oc2NhbGUoMSkpO1xuICAgICAgICAgICAgLmRlbGF5KDIwMG1zKTtcbiAgICAgICAgICAgIC50cmFuc2l0aW9uKDIwMG1zKTtcbiAgICAgICAgfVxuICAgICAgICAmLm1vZGFsLW91dCB7XG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICAgICAgICAudHJhbnNmb3JtKHNjYWxlKDAuNykpO1xuICAgICAgICAgICAgLmRlbGF5KDBtcyk7XG4gICAgICAgICAgICAudHJhbnNpdGlvbigxMDBtcyk7XG4gICAgICAgIH1cbiAgICAgICAgLmxpc3QtYmxvY2sge1xuICAgICAgICAgICAgbWFyZ2luOiAwO1xuICAgICAgICAgICAgJjpmaXJzdC1jaGlsZCB7XG4gICAgICAgICAgICAgICAgdWwge1xuICAgICAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaTpmaXJzdC1jaGlsZCBhIHtcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmOmxhc3QtY2hpbGQge1xuICAgICAgICAgICAgICAgIHVsIHtcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGk6bGFzdC1jaGlsZCBhIHtcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAmOmZpcnN0LWNoaWxkOmxhc3QtY2hpbGQge1xuICAgICAgICAgICAgICAgIGxpOmZpcnN0LWNoaWxkOmxhc3QtY2hpbGQgYSwgdWw6Zmlyc3QtY2hpbGQ6bGFzdC1jaGlsZCB7XG4gICAgICAgICAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLnBvcG92ZXItaW5uZXIge1xuICAgIC5zY3JvbGxhYmxlKCk7XG59XG4uYWN0aW9ucy1wb3BvdmVyIHtcbiAgICAubGlzdC1ibG9jayB7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICB9XG59XG4uYWN0aW9ucy1wb3BvdmVyLWxhYmVsIHtcbiAgICBwYWRkaW5nOiA4cHggMTZweDtcbiAgICBjb2xvcjpyZ2JhKDAsMCwwLDAuNTQpO1xuICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICBsaW5lLWhlaWdodDogMS4zO1xuICAgIHBhZGRpbmctdG9wOiAxMnB4O1xuICAgIHBhZGRpbmctYm90dG9tOiAxMnB4O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAuaGFpcmxpbmUoYm90dG9tLCAjZDJkMmQ2KTtcbiAgICAmOmxhc3QtY2hpbGQge1xuICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKGJvdHRvbSk7XG4gICAgfVxufVxuLy8gUG9wdXBcbi5wb3B1cCwgLmxvZ2luLXNjcmVlbiB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IDA7XG4gICAgdG9wOiAwO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICB6LWluZGV4OiAxMTAwMDtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgIGJveC1zaXppbmc6Ym9yZGVyLWJveDtcbiAgICBkaXNwbGF5OiBub25lO1xuICAgIC5zY3JvbGxhYmxlKCk7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uLXByb3BlcnR5OiAtd2Via2l0LXRyYW5zZm9ybTtcbiAgICAtbW96LXRyYW5zaXRpb24tcHJvcGVydHk6IC1tb3otdHJhbnNmb3JtO1xuICAgIC1tcy10cmFuc2l0aW9uLXByb3BlcnR5OiAtbXMtdHJhbnNmb3JtO1xuICAgIC1vLXRyYW5zaXRpb24tcHJvcGVydHk6IC1vLXRyYW5zZm9ybTtcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiB0cmFuc2Zvcm07XG4gICAgLnRyYW5zbGF0ZTNkKDAsMTAwJSwwKTtcbiAgICAmLm1vZGFsLWluLCAmLm1vZGFsLW91dCB7XG4gICAgICAgIC50cmFuc2l0aW9uKEBwb3B1cER1cmF0aW9uKTtcbiAgICB9XG4gICAgJi5tb2RhbC1pbiB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxuICAgICYubW9kYWwtb3V0IHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMTAwJSwwKTtcbiAgICB9XG59XG4ubG9naW4tc2NyZWVuLm1vZGFsLWluLCAubG9naW4tc2NyZWVuLm1vZGFsLW91dCB7XG4gICAgZGlzcGxheTogYmxvY2s7XG59XG4vLyBpUGFkIFBvcHVwXG5AbWVkaWEgYWxsIGFuZCAobWluLXdpZHRoOjYzMHB4KSBhbmQgKG1pbi1oZWlnaHQ6NjMwcHgpIHtcbiAgICAucG9wdXA6bm90KC50YWJsZXQtZnVsbHNjcmVlbikge1xuICAgICAgICB3aWR0aDogNjMwcHg7XG4gICAgICAgIGhlaWdodDogNjMwcHg7XG4gICAgICAgIGxlZnQ6IDUwJTtcbiAgICAgICAgdG9wOiA1MCU7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAtMzE1cHg7XG4gICAgICAgIG1hcmdpbi10b3A6IC0zMTVweDtcbiAgICAgICAgYm94LXNoYWRvdzogMHB4IDIwcHggNDRweCByZ2JhKDAsMCwwLDAuNSk7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMTAyNHB4LDApO1xuICAgICAgICAmLm1vZGFsLWluIHtcbiAgICAgICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgICAgIH1cbiAgICAgICAgJi5tb2RhbC1vdXQge1xuICAgICAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMTAyNHB4LDApO1xuICAgICAgICB9XG4gICAgfVxufVxuaHRtbC53aXRoLXN0YXR1c2Jhci1vdmVybGF5IHtcbiAgICAvLyBpUGhvbmUgd2l0aCBzdGF0dXNiYXIgb3ZlcmxheVxuICAgIEBtZWRpYSBhbGwgYW5kIChtYXgtd2lkdGg6NjI5cHgpLCAobWF4LWhlaWdodDo2MjlweCkge1xuICAgICAgICAucG9wdXAge1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCItd2Via2l0LWNhbGMoMTAwJSAtIDIwcHgpXCI7XG4gICAgICAgICAgICBoZWlnaHQ6IH5cImNhbGMoMTAwJSAtIDIwcHgpXCI7XG4gICAgICAgICAgICB0b3A6IDIwcHg7XG4gICAgICAgIH1cbiAgICAgICAgLnBvcHVwLW92ZXJsYXkge1xuICAgICAgICAgICAgei1pbmRleDogOTUwMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAubG9naW4tc2NyZWVuLCAucG9wdXAudGFibGV0LWZ1bGxzY3JlZW4ge1xuICAgICAgICBoZWlnaHQ6IH5cIi13ZWJraXQtY2FsYygxMDAlIC0gMjBweClcIjtcbiAgICAgICAgaGVpZ2h0OiB+XCJjYWxjKDEwMCUgLSAyMHB4KVwiO1xuICAgICAgICB0b3A6IDIwcHg7XG4gICAgfVxufVxuXG4vL1ByZWxvYWRlcnMgbW9kYWxzXG4ubW9kYWwtcHJlbG9hZGVyIHtcbiAgICAubW9kYWwtdGl0bGUsIC5tb2RhbC1pbm5lciB7XG4gICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB9XG59XG4ucHJlbG9hZGVyLWluZGljYXRvci1vdmVybGF5IHtcbiAgICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xuICAgIG9wYWNpdHk6IDA7XG4gICAgYmFja2dyb3VuZDogbm9uZTtcbn1cbi5wcmVsb2FkZXItaW5kaWNhdG9yLW1vZGFsIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgbGVmdDogNTAlO1xuICAgIHRvcDogNTAlO1xuICAgIHBhZGRpbmc6IDhweDtcbiAgICBtYXJnaW4tbGVmdDogLTI0cHg7XG4gICAgbWFyZ2luLXRvcDogLTI0cHg7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLDAsMCwwLjgpO1xuICAgIHotaW5kZXg6IDEzNTAwO1xuICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICAucHJlbG9hZGVyIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgfVxufVxuXG4vLyBQaWNrZXIgTW9kYWxcbi5waWNrZXItbW9kYWwge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDI2MHB4O1xuICAgIHotaW5kZXg6IDEyMDAwO1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uLXByb3BlcnR5OiAtd2Via2l0LXRyYW5zZm9ybTtcbiAgICAtbW96LXRyYW5zaXRpb24tcHJvcGVydHk6IC1tb3otdHJhbnNmb3JtO1xuICAgIC1tcy10cmFuc2l0aW9uLXByb3BlcnR5OiAtbXMtdHJhbnNmb3JtO1xuICAgIC1vLXRyYW5zaXRpb24tcHJvcGVydHk6IC1vLXRyYW5zZm9ybTtcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiB0cmFuc2Zvcm07XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICAudHJhbnNsYXRlM2QoMCwxMDAlLDApO1xuICAgICYubW9kYWwtaW4sICYubW9kYWwtb3V0IHtcbiAgICAgICAgLnRyYW5zaXRpb24oNDAwbXMpO1xuICAgIH1cbiAgICAmLm1vZGFsLWluIHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG4gICAgJi5tb2RhbC1vdXQge1xuICAgICAgICAudHJhbnNsYXRlM2QoMCwxMDAlLDApO1xuICAgIH1cbiAgICAucGlja2VyLW1vZGFsLWlubmVyIHtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgfVxuICAgIC50b29sYmFyIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICArIC5waWNrZXItbW9kYWwtaW5uZXIge1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCItd2Via2l0LWNhbGMoMTAwJSAtIEB7dG9vbGJhclNpemV9KVwiO1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCItbW96LWNhbGMoMTAwJSAtIEB7dG9vbGJhclNpemV9KVwiO1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCJjYWxjKDEwMCUgLSBAe3Rvb2xiYXJTaXplfSlcIjsgICAgXG4gICAgICAgIH1cbiAgICAgICAgYS5saW5rIHtcbiAgICAgICAgICAgIC5mbGV4LXNocmluaygwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAucGlja2VyLWhlYWRlciwgLnBpY2tlci1mb290ZXIge1xuICAgICAgICBoZWlnaHQ6IEB0b29sYmFyU2l6ZTtcbiAgICB9XG4gICAgLnBpY2tlci1oZWFkZXIge1xuICAgICAgICBiYWNrZ3JvdW5kOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgKyAudG9vbGJhciAudG9vbGJhci1pbm5lciB7XG4gICAgICAgICAgICBvdmVyZmxvdzogdmlzaWJsZTtcbiAgICAgICAgfVxuICAgICAgICArIC5waWNrZXItZm9vdGVyICsgLnRvb2xiYXIgKyAucGlja2VyLW1vZGFsLWlubmVyIHtcbiAgICAgICAgICAgIGhlaWdodDogflwiLXdlYmtpdC1jYWxjKDEwMCUgLSBAe3Rvb2xiYXJTaXplfSAqIDMpXCI7XG4gICAgICAgICAgICBoZWlnaHQ6IH5cIi1tb3otY2FsYygxMDAlIC0gQHt0b29sYmFyU2l6ZX0gKiAzKVwiO1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCJjYWxjKDEwMCUgLSBAe3Rvb2xiYXJTaXplfSAqIDMpXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLnBpY2tlci1mb290ZXIge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIGJvdHRvbTogMDtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIC5tb2RhbC1idXR0b25zO1xuICAgICAgICBcbiAgICB9XG4gICAgLnBpY2tlci1oZWFkZXIsIC5waWNrZXItZm9vdGVyIHtcbiAgICAgICAgKyAucGlja2VyLW1vZGFsLWlubmVyIHtcbiAgICAgICAgICAgIGhlaWdodDogflwiLXdlYmtpdC1jYWxjKDEwMCUgLSBAe3Rvb2xiYXJTaXplfSlcIjtcbiAgICAgICAgICAgIGhlaWdodDogflwiLW1vei1jYWxjKDEwMCUgLSBAe3Rvb2xiYXJTaXplfSlcIjtcbiAgICAgICAgICAgIGhlaWdodDogflwiY2FsYygxMDAlIC0gQHt0b29sYmFyU2l6ZX0pXCI7ICAgIFxuICAgICAgICB9XG4gICAgICAgICsgLnRvb2xiYXIgKyAucGlja2VyLW1vZGFsLWlubmVyIHtcbiAgICAgICAgICAgIGhlaWdodDogflwiLXdlYmtpdC1jYWxjKDEwMCUgLSBAe3Rvb2xiYXJTaXplfSAqIDIpXCI7XG4gICAgICAgICAgICBoZWlnaHQ6IH5cIi1tb3otY2FsYygxMDAlIC0gQHt0b29sYmFyU2l6ZX0gKiAyKVwiO1xuICAgICAgICAgICAgaGVpZ2h0OiB+XCJjYWxjKDEwMCUgLSBAe3Rvb2xiYXJTaXplfSAqIDIpXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgJi5waWNrZXItbW9kYWwtaW5saW5lLCAucG9wb3ZlciAmIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgICAgei1pbmRleDogaW5oZXJpdDtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICAgICAgLnRvb2xiYXIge1xuICAgICAgICAgICAgdG9wOiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC5wb3BvdmVyICYge1xuICAgICAgICB3aWR0aDogYXV0bztcbiAgICAgICAgLnRvb2xiYXI6Zmlyc3QtY2hpbGQsIC5waWNrZXItaGVhZGVyOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDJweCAycHggMCAwO1xuICAgICAgICB9XG4gICAgfVxuICAgICYuc21hcnQtc2VsZWN0LXBpY2tlciB7XG4gICAgICAgIC5saXN0LWJsb2NrIHtcbiAgICAgICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgICAgIHVsIHtcbiAgICAgICAgICAgICAgICAuaGFpcmxpbmUtcmVtb3ZlKHRvcCk7XG4gICAgICAgICAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufSIsIi8qID09PSBUb3VjaCByaXBwbGUgPT09ICovXG4vLyBSaXBwbGUgRWxlbWVudHNcbi5yaXBwbGUsIGEuZmxvYXRpbmctYnV0dG9uLCAuZmxvYXRpbmctYnV0dG9uID4gYSwgYS5saW5rLCBhLml0ZW0tbGluaywgLmJ1dHRvbiwgLm1vZGFsLWJ1dHRvbiwgLnRhYi1saW5rLCAubGFiZWwtcmFkaW8sIC5sYWJlbC1jaGVja2JveCwgLmFjdGlvbnMtbW9kYWwtYnV0dG9uLCAuc3BlZWQtZGlhbC1idXR0b25zIGEge1xuICAgIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG4vLyBSaXBwbGVcbi5yaXBwbGUtd2F2ZSB7XG4gICAgbGVmdDogMDtcbiAgICB0b3A6IDA7XG4gICAgcG9zaXRpb246IGFic29sdXRlICFpbXBvcnRhbnQ7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIHotaW5kZXg6LTE7XG4gICAgYmFja2dyb3VuZDpyZ2JhKDAsMCwwLDAuMSk7XG4gICAgcGFkZGluZzogMDtcbiAgICBtYXJnaW46IDA7XG4gICAgZm9udC1zaXplOiAwO1xuICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMHB4LCAwcHgsIDApIHNjYWxlKDApKTtcbiAgICAudHJhbnNpdGlvbigxNDAwbXMpO1xuICAgICYucmlwcGxlLXdhdmUtZmlsbCB7XG4gICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgb3BhY2l0eTogMC4zNTtcbiAgICB9XG4gICAgJi5yaXBwbGUtd2F2ZS1vdXQge1xuICAgICAgICAudHJhbnNpdGlvbig2MDBtcyk7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxuICAgIC5idXR0b24tZmlsbCAmLCAgLnBpY2tlci1jYWxlbmRhci1kYXkgJntcbiAgICAgICAgei1pbmRleDogMTtcbiAgICB9XG59XG4uYnV0dG9uLWZpbGwsIC5uYXZiYXIsIC50b29sYmFyLCAuc3VibmF2YmFyLCAuc2VhcmNoYmFyLCAubm90aWZpY2F0aW9ucywgLmZsb2F0aW5nLWJ1dHRvbiwgLnNwZWVkLWRpYWwtYnV0dG9ucyBhIHtcbiAgICAucmlwcGxlLXdhdmUge1xuICAgICAgICBiYWNrZ3JvdW5kOnJnYmEoMjU1LDI1NSwyNTUsMC4zKTtcbiAgICB9XG59XG4ubWVzc2FnZWJhciB7XG4gICAgLnJpcHBsZS13YXZlIHtcbiAgICAgICAgYmFja2dyb3VuZDpyZ2JhKDAsMCwwLDAuMSk7XG4gICAgfVxufVxuIiwiLy8gQWN0aXZlIGJ1dHRvbiBpY29uIGNvbG9yXG5cbi5idXR0b24ge1xuICAmLmFjdGl2ZSB7XG4gICAgaS5pY29uIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gICAgfVxuICB9XG59XG4iLCIvKiA9PT0gUGFuZWxzID09PSAqL1xuQHBhbmVsV2lkdGg6MjYwcHg7XG5AcGFuZWxzRHVyYXRpb246IDMwMG1zO1xuLnBhbmVsLW92ZXJsYXkge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIHRvcDogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLDAsMCwwLjIpO1xuICAgIG9wYWNpdHk6IDA7XG4gICAgei1pbmRleDogNTk5OTtcbiAgICBkaXNwbGF5OiBub25lO1xuICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwwLDApKTtcbiAgICAudHJhbnNpdGlvbihAcGFuZWxzRHVyYXRpb24pO1xufVxuLnBhbmVsIHtcbiAgICB6LWluZGV4OiAxMDAwO1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIC5zY3JvbGxhYmxlKCk7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHdpZHRoOiBAcGFuZWxXaWR0aDtcbiAgICB0b3A6IDA7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIC50cmFuc2xhdGUzZCgwKTtcbiAgICAudHJhbnNpdGlvbihAcGFuZWxzRHVyYXRpb24pO1xuXG4gICAgJi5wYW5lbC1sZWZ0IHtcblxuICAgICAgICAmLnBhbmVsLWNvdmVyIHtcbiAgICAgICAgICAgIHotaW5kZXg6IDYwMDA7XG4gICAgICAgICAgICBsZWZ0OiAtQHBhbmVsV2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgJi5wYW5lbC1yZXZlYWwge1xuICAgICAgICAgICAgbGVmdDogMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAmLnBhbmVsLXJpZ2h0IHtcbiAgICAgICAgJi5wYW5lbC1jb3ZlciB7XG4gICAgICAgICAgICB6LWluZGV4OiA2MDAwO1xuICAgICAgICAgICAgcmlnaHQ6IC1AcGFuZWxXaWR0aDtcbiAgICAgICAgfVxuICAgICAgICAmLnBhbmVsLXJldmVhbCB7XG4gICAgICAgICAgICByaWdodDogMDtcbiAgICAgICAgfVxuICAgIH1cbn1cbmJvZHkud2l0aC1wYW5lbC1sZWZ0LWNvdmVyLCBib2R5LndpdGgtcGFuZWwtcmlnaHQtY292ZXIge1xuICAgIC5wYW5lbCB7XG4gICAgICAgIGJveC1zaGFkb3c6IDBweCAwcHggMjBweCByZ2JhKDAsMCwwLDAuNSk7XG4gICAgfVxuICAgIC52aWV3cyB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwKTtcbiAgICB9XG4gICAgLnBhbmVsLW92ZXJsYXkge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG59XG5ib2R5LndpdGgtcGFuZWwtbGVmdC1yZXZlYWwsIGJvZHkud2l0aC1wYW5lbC1yaWdodC1yZXZlYWwge1xuICAgIC52aWV3cyB7XG4gICAgICAgIGJveC1zaGFkb3c6IDBweCAwcHggMjBweCByZ2JhKDAsMCwwLDAuNSk7XG4gICAgICAgIC50cmFuc2l0aW9uKEBwYW5lbHNEdXJhdGlvbik7XG4gICAgICAgIC13ZWJraXQtdHJhbnNpdGlvbi1wcm9wZXJ0eTogLXdlYmtpdC10cmFuc2Zvcm0sIGJveC1zaGFkb3c7XG4gICAgICAgIC1tb3otdHJhbnNpdGlvbi1wcm9wZXJ0eTogLW1vei10cmFuc2Zvcm0sIGJveC1zaGFkb3c7XG4gICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybSwgYm94LXNoYWRvdztcbiAgICB9XG4gICAgLnBhbmVsLW92ZXJsYXkge1xuICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsMCwwLDApO1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG59XG5ib2R5LndpdGgtcGFuZWwtbGVmdC1yZXZlYWwge1xuICAgIC52aWV3cyB7XG4gICAgICAgIC50cmFuc2xhdGUzZChAcGFuZWxXaWR0aCk7XG4gICAgfVxuICAgIC5wYW5lbC1vdmVybGF5IHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKEBwYW5lbFdpZHRoKTtcbiAgICB9XG59XG5ib2R5LndpdGgtcGFuZWwtbGVmdC1jb3ZlciB7XG4gICAgLnBhbmVsLWxlZnQge1xuICAgICAgICAudHJhbnNsYXRlM2QoQHBhbmVsV2lkdGgpO1xuICAgIH1cbn1cbmJvZHkud2l0aC1wYW5lbC1yaWdodC1yZXZlYWwge1xuICAgIC52aWV3cyB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgtQHBhbmVsV2lkdGgpO1xuICAgIH1cbiAgICAucGFuZWwtb3ZlcmxheSB7XG4gICAgICAgIC50cmFuc2xhdGUzZCgtQHBhbmVsV2lkdGgpO1xuICAgIH1cbn1cbmJvZHkud2l0aC1wYW5lbC1yaWdodC1jb3ZlciB7XG4gICAgLnBhbmVsLXJpZ2h0IHtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKC1AcGFuZWxXaWR0aCk7XG4gICAgfVxufVxuYm9keS5wYW5lbC1jbG9zaW5nIHtcbiAgICAucGFuZWwtb3ZlcmxheSB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIH1cbiAgICAudmlld3Mge1xuICAgICAgICAudHJhbnNpdGlvbihAcGFuZWxzRHVyYXRpb24pO1xuICAgICAgICAtd2Via2l0LXRyYW5zaXRpb24tcHJvcGVydHk6IC13ZWJraXQtdHJhbnNmb3JtLCBib3gtc2hhZG93O1xuICAgICAgICAtbW96LXRyYW5zaXRpb24tcHJvcGVydHk6IC1tb3otdHJhbnNmb3JtLCBib3gtc2hhZG93O1xuICAgICAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiB0cmFuc2Zvcm0sIGJveC1zaGFkb3c7XG4gICAgfVxufSIsIi8qID09PSBUYWJzID09PSAqL1xuLnRhYnMge1xuICAgIC50YWIge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbiAgICAudGFiLmFjdGl2ZSB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIH1cbn1cbi50YWJzLWFuaW1hdGVkLXdyYXAge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICA+LnRhYnMge1xuICAgICAgICAuZmxleGJveCgpO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAgICAgPi50YWIge1xuICAgICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgICAgIC5mbGV4LXNocmluaygwKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi50YWJzLXN3aXBlYWJsZS13cmFwIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgPiAudGFicyA+IC50YWIge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICB9XG59IiwiLyogPT09IE1lc3NhZ2VzID09PSAqL1xuQG1lc3NhZ2VzQXZhdGFyU2l6ZTogNDhweDtcbi5tZXNzYWdlcy1jb250ZW50IHtcbiAgICBiYWNrZ3JvdW5kOiAjZWVlO1xufVxuLm1lc3NhZ2VzIHtcbiAgICAuZmxleGJveCgpO1xuICAgIC13ZWJraXQtYm94LW9yaWVudDogdmVydGljYWw7XG4gICAgLW1vei1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcbiAgICAtbXMtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbn1cbi5tZXNzYWdlcy1kYXRlIHtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICBmb250LXNpemU6IDEycHg7XG4gICAgbGluZS1oZWlnaHQ6IDE7XG4gICAgbWFyZ2luOiAxMHB4IDE1cHg7XG4gICAgc3BhbiB7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA0MDA7XG4gICAgfVxufVxuLm1lc3NhZ2Uge1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgbWFyZ2luOiAwcHggOHB4IDhweCA4cHg7XG4gICAgbWF4LXdpZHRoOiA4MCU7XG4gICAgLmZsZXhib3goKTtcbiAgICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgIC1tb3otYm94LW9yaWVudDogdmVydGljYWw7XG4gICAgLW1zLWZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgJjpmaXJzdC1jaGlsZCB7XG4gICAgICAgIG1hcmdpbi10b3A6IDhweDtcbiAgICB9XG4gICAgJi5tZXNzYWdlLXBpYyB7XG4gICAgICAgIGltZyB7XG4gICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgfVxuICAgIH1cbn1cbi5tZXNzYWdlLW5hbWUsIC5tZXNzYWdlLWxhYmVsLCAubWVzc2FnZS1kYXRlLCAubWVzc2FnZXMtZGF0ZSB7XG4gICAgY29sb3I6cmdiYSgwLDAsMCwwLjUxKTtcbn1cbi5tZXNzYWdlLW5hbWUge1xuICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICBsaW5lLWhlaWdodDogMTtcbiAgICBtYXJnaW4tYm90dG9tOiAycHg7XG4gICAgbWFyZ2luLXRvcDogN3B4O1xuICAgIC5tZXNzYWdlLWhpZGUtbmFtZSAmIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG59XG4ubWVzc2FnZS1sYWJlbCB7XG4gICAgZm9udC1zaXplOiAxMnB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxO1xuICAgIG1hcmdpbi10b3A6IDRweDtcbiAgICAubWVzc2FnZS1oaWRlLWxhYmVsICYge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbn1cbi5tZXNzYWdlLWF2YXRhciB7XG4gICAgd2lkdGg6IEBtZXNzYWdlc0F2YXRhclNpemU7XG4gICAgaGVpZ2h0OiBAbWVzc2FnZXNBdmF0YXJTaXplO1xuICAgIGJvcmRlci1yYWRpdXM6IDEwMCU7XG4gICAgbWFyZ2luLXRvcDogLUBtZXNzYWdlc0F2YXRhclNpemU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHRvcDogMXB4O1xuICAgIGJhY2tncm91bmQtc2l6ZTogY292ZXI7XG4gICAgb3BhY2l0eTogMTtcbiAgICAudHJhbnNpdGlvbig0MDBtcyk7XG4gICAgLm1lc3NhZ2UtaGlkZS1hdmF0YXIgJiB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxufVxuLm1lc3NhZ2UtdGV4dCB7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBib3JkZXItcmFkaXVzOiAycHg7XG4gICAgcGFkZGluZzogNnB4IDhweDtcbiAgICBtaW4td2lkdGg6IDQ4cHg7XG4gICAgZm9udC1zaXplOiAxNnB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxLjI7XG4gICAgd29yZC1icmVhazogYnJlYWstd29yZDtcbiAgICBjb2xvcjojMzMzO1xuICAgIG1pbi1oZWlnaHQ6IEBtZXNzYWdlc0F2YXRhclNpemU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgaW1nIHtcbiAgICAgICAgbWF4LXdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IGF1dG87XG4gICAgfVxuICAgIC5tZXNzYWdlLXBpYyAmIHtcbiAgICAgICAgcGFkZGluZzogOHB4O1xuICAgIH1cbn1cbi5tZXNzYWdlLWRhdGUge1xuICAgIGZvbnQtc2l6ZTogMTJweDtcbiAgICBtYXJnaW4tdG9wOiA0cHg7XG4gICAgLm1lc3NhZ2UtcGljIGltZyArICYge1xuICAgICAgICBtYXJnaW4tdG9wOiA4cHg7XG4gICAgfVxufVxuLm1lc3NhZ2Utc2VudCB7XG4gICAgLW1zLWZsZXgtaXRlbS1hbGlnbjogZW5kO1xuICAgIC13ZWJraXQtYWxpZ24tc2VsZjogZmxleC1lbmQ7XG4gICAgYWxpZ24tc2VsZjogZmxleC1lbmQ7XG4gICAgLmFsaWduLWl0ZW1zKGZsZXgtZW5kKTtcbiAgICAubWVzc2FnZS1uYW1lLCAubWVzc2FnZS1sYWJlbCB7XG4gICAgICAgIG1hcmdpbi1yaWdodDogOHB4O1xuICAgIH1cbiAgICAubWVzc2FnZS10ZXh0IHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI0M4RTZDOTtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IGF1dG87XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDJweCAycHggMCAycHg7XG4gICAgICAgIG1hcmdpbi1yaWdodDogOHB4O1xuICAgICAgICAmOmJlZm9yZSB7XG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICBjb250ZW50OiAnJztcbiAgICAgICAgICAgIGJvcmRlci1sZWZ0OiAwcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gICAgICAgICAgICBib3JkZXItcmlnaHQ6IDhweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgICAgICAgICAgIGJvcmRlci1ib3R0b206IDhweCBzb2xpZCAjQzhFNkM5O1xuICAgICAgICAgICAgbGVmdDogMTAwJTtcbiAgICAgICAgICAgIGJvdHRvbTogMDtcbiAgICAgICAgICAgIHdpZHRoOiAwO1xuICAgICAgICAgICAgaGVpZ2h0OiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgICYubWVzc2FnZS13aXRoLWF2YXRhciB7XG4gICAgICAgIC5tZXNzYWdlLXRleHQsIC5tZXNzYWdlLW5hbWUsIC5tZXNzYWdlLWxhYmVsIHtcbiAgICAgICAgICAgIG1hcmdpbi1yaWdodDogQG1lc3NhZ2VzQXZhdGFyU2l6ZSArIDhweDtcbiAgICAgICAgfVxuICAgIH1cbn1cbi5tZXNzYWdlLXJlY2VpdmVkIHtcbiAgICAtbXMtZmxleC1pdGVtLWFsaWduOiBzdGFydDtcbiAgICAtd2Via2l0LWFsaWduLXNlbGY6IGZsZXgtc3RhcnQ7XG4gICAgYWxpZ24tc2VsZjogZmxleC1zdGFydDtcbiAgICAuYWxpZ24taXRlbXMoZmxleC1zdGFydCk7XG4gICAgLm1lc3NhZ2UtdGV4dCB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDJweCAycHggMnB4IDBweDtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICAgICAgJjpiZWZvcmUge1xuICAgICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgICAgY29udGVudDogJyc7XG4gICAgICAgICAgICBib3JkZXItbGVmdDogOHB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgICAgICAgICAgYm9yZGVyLXJpZ2h0OiAwcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gICAgICAgICAgICBib3JkZXItYm90dG9tOiA4cHggc29saWQgI2ZmZjtcbiAgICAgICAgICAgIHJpZ2h0OiAxMDAlO1xuICAgICAgICAgICAgYm90dG9tOiAwO1xuICAgICAgICAgICAgd2lkdGg6IDA7XG4gICAgICAgICAgICBoZWlnaHQ6IDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLm1lc3NhZ2UtbmFtZSwgLm1lc3NhZ2UtbGFiZWwge1xuICAgICAgICBtYXJnaW4tbGVmdDogOHB4O1xuICAgIH1cbiAgICAmLm1lc3NhZ2Utd2l0aC1hdmF0YXIge1xuICAgICAgICAubWVzc2FnZS10ZXh0LCAubWVzc2FnZS1uYW1lLCAubWVzc2FnZS1sYWJlbCB7XG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogQG1lc3NhZ2VzQXZhdGFyU2l6ZSArIDhweDtcbiAgICAgICAgfVxuICAgIH0gICAgXG59XG5cbi5tZXNzYWdlLWFwcGVhci1mcm9tLWJvdHRvbSB7XG4gICAgLXdlYmtpdC1hbmltYXRpb246IG1lc3NhZ2VBcHBlYXJGcm9tQm90dG9tIDQwMG1zO1xuICAgIGFuaW1hdGlvbjogbWVzc2FnZUFwcGVhckZyb21Cb3R0b20gNDAwbXM7XG59XG4ubWVzc2FnZS1hcHBlYXItZnJvbS10b3Age1xuICAgIC13ZWJraXQtYW5pbWF0aW9uOiBtZXNzYWdlQXBwZWFyRnJvbVRvcCA0MDBtcztcbiAgICBhbmltYXRpb246IG1lc3NhZ2VBcHBlYXJGcm9tVG9wIDQwMG1zOyAgIFxufVxuXG5ALXdlYmtpdC1rZXlmcmFtZXMgbWVzc2FnZUFwcGVhckZyb21Cb3R0b20ge1xuICAgIGZyb20ge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwxMDAlLDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxufVxuQGtleWZyYW1lcyBtZXNzYWdlQXBwZWFyRnJvbUJvdHRvbSB7XG4gICAgZnJvbSB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwxMDAlLDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwwLDApO1xuICAgIH1cbn1cbkAtd2Via2l0LWtleWZyYW1lcyBtZXNzYWdlQXBwZWFyRnJvbVRvcCB7XG4gICAgZnJvbSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLC0xMDAlLDApO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxufVxuQGtleWZyYW1lcyBtZXNzYWdlQXBwZWFyRnJvbVRvcCB7XG4gICAgZnJvbSB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoMCwtMTAwJSwwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKDAsMCwwKTtcbiAgICB9XG59XG4iLCIvKiA9PT0gU3RhdHVzYmFyIG92ZXJsYXkgPT09ICovXG5odG1sLndpdGgtc3RhdHVzYmFyLW92ZXJsYXkgYm9keXtcbiAgICBwYWRkaW5nLXRvcDogMjBweDtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIC5zdGF0dXNiYXItb3ZlcmxheSB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIH1cbiAgICAucGFuZWwge1xuICAgICAgICBwYWRkaW5nLXRvcDogMjBweDtcbiAgICB9XG59XG4uc3RhdHVzYmFyLW92ZXJsYXkge1xuICAgIGJhY2tncm91bmQ6IEB0aGVtZUNvbG9yO1xuICAgIHotaW5kZXg6IDEwMDAwOyAvLyBBIGJpdCBsb3dlciB0aGFuIC5tb2RhbHMtb3ZlcmxheVxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIHRvcDogMDtcbiAgICBoZWlnaHQ6IDIwcHg7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICAudHJhbnNpdGlvbihAcGFuZWxzRHVyYXRpb24pO1xufSIsIi8qID09PVxuICAgIFByZWxvYWRlclxuICAgIEJ5IFJ1ZGkgVGhldW5pc3NlbiAoaHR0cHM6Ly9naXRodWIuY29tL3J0aGV1bmlzc2VuL21kLXByZWxvYWRlcilcbj09PSAqL1xuLnByZWxvYWRlciB7XG4gICAgQGVhc2luZzogICAgICBjdWJpYy1iZXppZXIoLjgsLjAsLjQsLjgpO1xuXG4gICAgQHNwZWVkOiAgICAgIDEzMjBtczsgICAgICAgLy8gYW5pbWF0aW9uIHRpbWUgZm9yIGVhY2ggbG9vcFxuICAgIEBjb2xvcjogICAgICAjNzU3NTc1OyAgICAgIC8vIEJsdWUgQTIwMCBpbiB0aGUgTWF0ZXJpYWwgRGVzaWduIGNvbG9yIHBhbGV0dGVcbiAgICBAbGluZWNhcDogICAgc3F1YXJlOyAgICAgICAvLyBjb3VsZCBiZSAncm91bmQnLCBidXQgdGhlIG9mZmljaWFsIG9uZSBpcyBzcXVhcmVcbiAgICBAbG9vcHM6ICAgICAgNTsgICAgICAgICAgICAvLyBudW1iZXIgb2YgcG9pbnRzIHdoZXJlIHRoZSBhcmMgbWVldHNcbiAgICBAYXJjOiAgICAgICAgMC43MjsgICAgICAgICAvLyBmcmFjdGlvbiBvZiB0aGUgY2lyY3VtZmVyZW5jZSB0aGF0IHRoZSBhcmMgZ3Jvd3MgdG9cbiAgICBAcGVyaW1ldGVyOiAgNjdweCAqIHBpKCk7ICAvLyBjaXJjdW1mZXJlbmNlIG9mIHRoZSByYXcgc3ZnIGlubmVyIGNyaWNsZVxuXG4gICAgZm9udC1zaXplOiAwO1xuXG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHdpZHRoOiAzMnB4O1xuICAgIGhlaWdodDogMzJweDtcbiAgICAtd2Via2l0LWFuaW1hdGlvbjogcHJlbG9hZGVyLW91dGVyIEBzcGVlZCAqIEBsb29wcyAvIDIgbGluZWFyIGluZmluaXRlO1xuICAgIGFuaW1hdGlvbjogcHJlbG9hZGVyLW91dGVyIEBzcGVlZCAqIEBsb29wcyAvIDIgbGluZWFyIGluZmluaXRlO1xuXG4gICAgc3ZnIHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgLXdlYmtpdC1hbmltYXRpb246IHByZWxvYWRlci1pbm5lciBAc3BlZWQgbGluZWFyIGluZmluaXRlO1xuICAgICAgICBhbmltYXRpb246IHByZWxvYWRlci1pbm5lciBAc3BlZWQgbGluZWFyIGluZmluaXRlO1xuXG4gICAgICAgIGNpcmNsZSB7XG4gICAgICAgICAgICBmaWxsOiBub25lO1xuICAgICAgICAgICAgc3Ryb2tlOiBAY29sb3I7XG4gICAgICAgICAgICBzdHJva2UtbGluZWNhcDogQGxpbmVjYXA7XG4gICAgICAgICAgICAtd2Via2l0LWFuaW1hdGlvbjogcHJlbG9hZGVyLWFyYyBAc3BlZWQgQGVhc2luZyBpbmZpbml0ZTtcbiAgICAgICAgICAgIGFuaW1hdGlvbjogcHJlbG9hZGVyLWFyYyBAc3BlZWQgQGVhc2luZyBpbmZpbml0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBALXdlYmtpdC1rZXlmcmFtZXMgcHJlbG9hZGVyLW91dGVyIHtcbiAgICAgICAgMCUge1xuICAgICAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHJvdGF0ZSgwKTtcbiAgICAgICAgfVxuICAgICAgICAxMDAlIHtcbiAgICAgICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBAa2V5ZnJhbWVzIHByZWxvYWRlci1vdXRlciB7XG4gICAgICAgIDAlIHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDApO1xuICAgICAgICB9XG4gICAgICAgIDEwMCUge1xuICAgICAgICAgICAgdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEAtd2Via2l0LWtleWZyYW1lcyBwcmVsb2FkZXItaW5uZXIge1xuICAgICAgICAwJSB7XG4gICAgICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKC0zNjBkZWcgKiAoMSAtIEBhcmMpKTtcbiAgICAgICAgfVxuICAgICAgICAxMDAlIHtcbiAgICAgICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgQGtleWZyYW1lcyBwcmVsb2FkZXItaW5uZXIge1xuICAgICAgICAwJSB7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgtMzYwZGVnICogKDEgLSBAYXJjKSk7XG4gICAgICAgIH1cbiAgICAgICAgMTAwJSB7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBALXdlYmtpdC1rZXlmcmFtZXMgcHJlbG9hZGVyLWFyYyB7XG4gICAgICAgIDAlIHtcbiAgICAgICAgICAgIHN0cm9rZS1kYXNoYXJyYXk6IDEgQHBlcmltZXRlcjtcbiAgICAgICAgICAgIHN0cm9rZS1kYXNob2Zmc2V0OiAwO1xuICAgICAgICB9XG4gICAgICAgIDQwJSB7XG4gICAgICAgICAgICBzdHJva2UtZGFzaGFycmF5OiBAYXJjICogQHBlcmltZXRlciwgQHBlcmltZXRlcjtcbiAgICAgICAgICAgIHN0cm9rZS1kYXNob2Zmc2V0OiAwO1xuICAgICAgICB9XG4gICAgICAgIDEwMCUge1xuICAgICAgICAgICAgc3Ryb2tlLWRhc2hhcnJheTogMSBAcGVyaW1ldGVyO1xuICAgICAgICAgICAgc3Ryb2tlLWRhc2hvZmZzZXQ6IC1AYXJjICogQHBlcmltZXRlcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBAa2V5ZnJhbWVzIHByZWxvYWRlci1hcmMge1xuICAgICAgICAwJSB7XG4gICAgICAgICAgICBzdHJva2UtZGFzaGFycmF5OiAxIEBwZXJpbWV0ZXI7XG4gICAgICAgICAgICBzdHJva2UtZGFzaG9mZnNldDogMDtcbiAgICAgICAgfVxuICAgICAgICA0MCUge1xuICAgICAgICAgICAgc3Ryb2tlLWRhc2hhcnJheTogQGFyYyAqIEBwZXJpbWV0ZXIsIEBwZXJpbWV0ZXI7XG4gICAgICAgICAgICBzdHJva2UtZGFzaG9mZnNldDogMDtcbiAgICAgICAgfVxuICAgICAgICAxMDAlIHtcbiAgICAgICAgICAgIHN0cm9rZS1kYXNoYXJyYXk6IDEgQHBlcmltZXRlcjtcbiAgICAgICAgICAgIHN0cm9rZS1kYXNob2Zmc2V0OiAtQGFyYyAqIEBwZXJpbWV0ZXI7XG4gICAgICAgIH1cbiAgICB9XG59XG4ucHJlbG9hZGVyLWlubmVyIHtcbiAgICBAcHJlbG9hZGVyLWlubmVyLWVhc2U6IGN1YmljLWJlemllcigwLjM1LCAwLCAwLjI1LCAxKTtcbiAgICBAcHJlbG9hZGVyLWlubmVyLWR1cmF0aW9uOiA1LjI1cztcbiAgICBAcHJlbG9hZGVyLWlubmVyLWNpcmNsZS1kdXJhdGlvbjogQHByZWxvYWRlci1pbm5lci1kdXJhdGlvbiAqIDAuMjU7XG4gICAgQHByZWxvYWRlci1pbm5lci1vdXRlci1kdXJhdGlvbjogQHByZWxvYWRlci1pbm5lci1kdXJhdGlvbiAqICg1LzkpO1xuXG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICAtd2Via2l0LWFuaW1hdGlvbjogcHJlbG9hZGVyLWlubmVyLXJvdGF0ZSBAcHJlbG9hZGVyLWlubmVyLWR1cmF0aW9uIEBwcmVsb2FkZXItaW5uZXItZWFzZSBpbmZpbml0ZTtcbiAgICBhbmltYXRpb246IHByZWxvYWRlci1pbm5lci1yb3RhdGUgQHByZWxvYWRlci1pbm5lci1kdXJhdGlvbiBAcHJlbG9hZGVyLWlubmVyLWVhc2UgaW5maW5pdGU7XG4gICAgLnByZWxvYWRlci1pbm5lci1nYXAge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHdpZHRoOiAycHg7XG4gICAgICAgIGxlZnQ6IDUwJTtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IC0xcHg7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgYm90dG9tOiAwO1xuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICBib3JkZXItdG9wOiA0cHggc29saWQgIzc1NzU3NTtcbiAgICB9XG4gICAgLnByZWxvYWRlci1pbm5lci1sZWZ0LCAucHJlbG9hZGVyLWlubmVyLXJpZ2h0IHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgd2lkdGg6IDUwJTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICB9XG4gICAgLnByZWxvYWRlci1pbm5lci1oYWxmLWNpcmNsZSB7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIHdpZHRoOiAyMDAlO1xuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICBib3JkZXI6IDRweCBzb2xpZCAjNzU3NTc1O1xuICAgICAgICBib3JkZXItYm90dG9tLWNvbG9yOiB0cmFuc3BhcmVudCAhaW1wb3J0YW50O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICAgIC13ZWJraXQtYW5pbWF0aW9uLWl0ZXJhdGlvbi1jb3VudDogaW5maW5pdGU7XG4gICAgICAgIC13ZWJraXQtYW5pbWF0aW9uLWR1cmF0aW9uOiAoQHByZWxvYWRlci1pbm5lci1kdXJhdGlvbiAqIDAuMjUpO1xuICAgICAgICAtd2Via2l0LWFuaW1hdGlvbi10aW1pbmctZnVuY3Rpb246IEBwcmVsb2FkZXItaW5uZXItZWFzZTtcbiAgICAgICAgYW5pbWF0aW9uLWl0ZXJhdGlvbi1jb3VudDogaW5maW5pdGU7XG4gICAgICAgIGFuaW1hdGlvbi1kdXJhdGlvbjogKEBwcmVsb2FkZXItaW5uZXItZHVyYXRpb24gKiAwLjI1KTtcbiAgICAgICAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogQHByZWxvYWRlci1pbm5lci1lYXNlO1xuICAgIH1cbiAgICAucHJlbG9hZGVyLXdoaXRlICYge1xuICAgICAgICAucHJlbG9hZGVyLWlubmVyLWdhcCwgLnByZWxvYWRlci1pbm5lci1oYWxmLWNpcmNsZSB7XG4gICAgICAgICAgICBib3JkZXItY29sb3I6ICNmZmY7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLnByZWxvYWRlci1pbm5lci1sZWZ0IHtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgLnByZWxvYWRlci1pbm5lci1oYWxmLWNpcmNsZSB7XG4gICAgICAgICAgICBsZWZ0OiAwO1xuICAgICAgICAgICAgYm9yZGVyLXJpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudCAhaW1wb3J0YW50O1xuICAgICAgICAgICAgLXdlYmtpdC1hbmltYXRpb24tbmFtZTogcHJlbG9hZGVyLWxlZnQtcm90YXRlO1xuICAgICAgICAgICAgYW5pbWF0aW9uLW5hbWU6IHByZWxvYWRlci1sZWZ0LXJvdGF0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAucHJlbG9hZGVyLWlubmVyLXJpZ2h0IHtcbiAgICAgICAgcmlnaHQ6IDA7XG4gICAgICAgIC5wcmVsb2FkZXItaW5uZXItaGFsZi1jaXJjbGUge1xuICAgICAgICAgICAgcmlnaHQ6IDA7XG4gICAgICAgICAgICBib3JkZXItbGVmdC1jb2xvcjogdHJhbnNwYXJlbnQgIWltcG9ydGFudDtcbiAgICAgICAgICAgIC13ZWJraXQtYW5pbWF0aW9uLW5hbWU6IHByZWxvYWRlci1yaWdodC1yb3RhdGU7XG4gICAgICAgICAgICBhbmltYXRpb24tbmFtZTogcHJlbG9hZGVyLXJpZ2h0LXJvdGF0ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgLmNvbG9yLW11bHRpICYge1xuICAgICAgICAucHJlbG9hZGVyLWlubmVyLWxlZnQge1xuICAgICAgICAgICAgLnByZWxvYWRlci1pbm5lci1oYWxmLWNpcmNsZSB7XG4gICAgICAgICAgICAgICAgLXdlYmtpdC1hbmltYXRpb24tbmFtZTogcHJlbG9hZGVyLWxlZnQtcm90YXRlLW11bHRpY29sb3I7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uLW5hbWU6IHByZWxvYWRlci1sZWZ0LXJvdGF0ZS1tdWx0aWNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC5wcmVsb2FkZXItaW5uZXItcmlnaHQge1xuICAgICAgICAgICAgLnByZWxvYWRlci1pbm5lci1oYWxmLWNpcmNsZSB7XG4gICAgICAgICAgICAgICAgLXdlYmtpdC1hbmltYXRpb24tbmFtZTogcHJlbG9hZGVyLXJpZ2h0LXJvdGF0ZS1tdWx0aWNvbG9yO1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbi1uYW1lOiBwcmVsb2FkZXItcmlnaHQtcm90YXRlLW11bHRpY29sb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIHByZWxvYWRlci1sZWZ0LXJvdGF0ZSB7XG4gICAgMCUsIDEwMCUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDEzMGRlZyk7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoLTVkZWcpO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcHJlbG9hZGVyLWxlZnQtcm90YXRlIHtcbiAgICAwJSwgMTAwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDEzMGRlZyk7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogcm90YXRlKC01ZGVnKTtcbiAgICB9XG59XG5ALXdlYmtpdC1rZXlmcmFtZXMgcHJlbG9hZGVyLXJpZ2h0LXJvdGF0ZSB7XG4gICAgMCUsIDEwMCUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKC0xMzBkZWcpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDVkZWcpO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcHJlbG9hZGVyLXJpZ2h0LXJvdGF0ZSB7XG4gICAgMCUsIDEwMCUge1xuICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgtMTMwZGVnKTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiByb3RhdGUoNWRlZyk7XG4gICAgfVxufVxuXG5ALXdlYmtpdC1rZXlmcmFtZXMgcHJlbG9hZGVyLWlubmVyLXJvdGF0ZSB7XG4gICAgMTIuNSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDEzNWRlZyk7XG4gICAgfVxuICAgIDI1JSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMjcwZGVnKTtcbiAgICB9XG4gICAgMzcuNSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDQwNWRlZyk7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoNTQwZGVnKTtcbiAgICB9XG4gICAgNjIuNSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDY3NWRlZyk7XG4gICAgfVxuICAgIDc1JSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoODEwZGVnKTtcbiAgICB9XG4gICAgODcuNSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDk0NWRlZyk7XG4gICAgfVxuICAgIDEwMCUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDEwODBkZWcpO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcHJlbG9hZGVyLWlubmVyLXJvdGF0ZSB7XG4gICAgMTIuNSUge1xuICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgxMzVkZWcpO1xuICAgIH1cbiAgICAyNSUge1xuICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgyNzBkZWcpO1xuICAgIH1cbiAgICAzNy41JSB7XG4gICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDQwNWRlZyk7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDU0MGRlZyk7XG4gICAgfVxuICAgIDYyLjUlIHtcbiAgICAgICAgdHJhbnNmb3JtOiByb3RhdGUoNjc1ZGVnKTtcbiAgICB9XG4gICAgNzUlIHtcbiAgICAgICAgdHJhbnNmb3JtOiByb3RhdGUoODEwZGVnKTtcbiAgICB9XG4gICAgODcuNSUge1xuICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSg5NDVkZWcpO1xuICAgIH1cbiAgICAxMDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiByb3RhdGUoMTA4MGRlZyk7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIHByZWxvYWRlci1sZWZ0LXJvdGF0ZS1tdWx0aWNvbG9yIHtcbiAgICAwJSxcbiAgICAxMDAlIHtcbiAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6ICM0Mjg1RjQ7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMTMwZGVnKTtcbiAgICB9XG4gICAgNzUlIHtcbiAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6ICMxQjlBNTk7XG4gICAgICAgIGJvcmRlci10b3AtY29sb3I6ICMxQjlBNTk7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIGJvcmRlci1sZWZ0LWNvbG9yOiAjRjdDMjIzO1xuICAgICAgICBib3JkZXItdG9wLWNvbG9yOiAjRjdDMjIzO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKC01ZGVnKTtcbiAgICB9XG4gICAgMjUlIHtcbiAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6ICNERTNFMzU7XG4gICAgICAgIGJvcmRlci10b3AtY29sb3I6ICNERTNFMzU7XG4gICAgfVxufVxuQGtleWZyYW1lcyBwcmVsb2FkZXItbGVmdC1yb3RhdGUtbXVsdGljb2xvciB7XG4gICAgMCUsXG4gICAgMTAwJSB7XG4gICAgICAgIGJvcmRlci1sZWZ0LWNvbG9yOiAjNDI4NUY0O1xuICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSgxMzBkZWcpO1xuICAgIH1cbiAgICA3NSUge1xuICAgICAgICBib3JkZXItbGVmdC1jb2xvcjogIzFCOUE1OTtcbiAgICAgICAgYm9yZGVyLXRvcC1jb2xvcjogIzFCOUE1OTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6ICNGN0MyMjM7XG4gICAgICAgIGJvcmRlci10b3AtY29sb3I6ICNGN0MyMjM7XG4gICAgICAgIHRyYW5zZm9ybTogcm90YXRlKC01ZGVnKTtcbiAgICB9XG4gICAgMjUlIHtcbiAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6ICNERTNFMzU7XG4gICAgICAgIGJvcmRlci10b3AtY29sb3I6ICNERTNFMzU7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIHByZWxvYWRlci1yaWdodC1yb3RhdGUtbXVsdGljb2xvciB7XG4gICAgMCUsXG4gICAgMTAwJSB7XG4gICAgICAgIGJvcmRlci1yaWdodC1jb2xvcjogIzQyODVGNDtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHJvdGF0ZSgtMTMwZGVnKTtcbiAgICB9XG4gICAgNzUlIHtcbiAgICAgICAgYm9yZGVyLXJpZ2h0LWNvbG9yOiAjMUI5QTU5O1xuICAgICAgICBib3JkZXItdG9wLWNvbG9yOiAjMUI5QTU5O1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICBib3JkZXItcmlnaHQtY29sb3I6ICNGN0MyMjM7XG4gICAgICAgIGJvcmRlci10b3AtY29sb3I6ICNGN0MyMjM7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoNWRlZyk7XG4gICAgfVxuICAgIDI1JSB7XG4gICAgICAgIGJvcmRlci10b3AtY29sb3I6ICNERTNFMzU7XG4gICAgICAgIGJvcmRlci1yaWdodC1jb2xvcjogI0RFM0UzNTtcbiAgICB9XG59XG5Aa2V5ZnJhbWVzIHByZWxvYWRlci1yaWdodC1yb3RhdGUtbXVsdGljb2xvciB7XG4gICAgMCUsXG4gICAgMTAwJSB7XG4gICAgICAgIGJvcmRlci1yaWdodC1jb2xvcjogIzQyODVGNDtcbiAgICAgICAgdHJhbnNmb3JtOiByb3RhdGUoLTEzMGRlZyk7XG4gICAgfVxuICAgIDc1JSB7XG4gICAgICAgIGJvcmRlci1yaWdodC1jb2xvcjogIzFCOUE1OTtcbiAgICAgICAgYm9yZGVyLXRvcC1jb2xvcjogIzFCOUE1OTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgYm9yZGVyLXJpZ2h0LWNvbG9yOiAjRjdDMjIzO1xuICAgICAgICBib3JkZXItdG9wLWNvbG9yOiAjRjdDMjIzO1xuICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZSg1ZGVnKTtcbiAgICB9XG4gICAgMjUlIHtcbiAgICAgICAgYm9yZGVyLXRvcC1jb2xvcjogI0RFM0UzNTtcbiAgICAgICAgYm9yZGVyLXJpZ2h0LWNvbG9yOiAjREUzRTM1O1xuICAgIH1cbn0iLCIvKiA9PT0gUHJvZ3Jlc3MgQmFyID09PSAqL1xuLnByb2dyZXNzYmFyLCAucHJvZ3Jlc3NiYXItaW5maW5pdGUge1xuICAgIGhlaWdodDogNHB4O1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIC50cmFuc2Zvcm0tb3JpZ2luKGNlbnRlciBib3R0b20pO1xuICAgIGJhY2tncm91bmQ6IHJnYmEocmVkKEB0aGVtZUNvbG9yKSwgZ3JlZW4oQHRoZW1lQ29sb3IpLCBibHVlKEB0aGVtZUNvbG9yKSwgMC41KTtcbn1cbi8vIERldGVybWluZWRcbi5wcm9ncmVzc2JhciB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgICAtd2Via2l0LXRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgdHJhbnNmb3JtLXN0eWxlOiBwcmVzZXJ2ZS0zZDtcbiAgICBzcGFuIHtcbiAgICAgICAgY29udGVudDogJyc7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgLnRyYW5zbGF0ZTNkKC0xMDAlLCAwLCAwKTtcbiAgICAgICAgLnRyYW5zaXRpb24oMTUwbXMpO1xuICAgIH1cbn1cbi8vIEluZmluaXRlXG4ucHJvZ3Jlc3NiYXItaW5maW5pdGUge1xuICAgIHotaW5kZXg6IDE1MDAwO1xuICAgICY6YmVmb3JlLCAmOmFmdGVyIHtcbiAgICAgICAgY29udGVudDogJyc7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgdG9wOiAwO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBiYWNrZ3JvdW5kOiBAdGhlbWVDb2xvcjtcbiAgICAgICAgLnRyYW5zZm9ybS1vcmlnaW4obGVmdCBjZW50ZXIpO1xuICAgIH1cbiAgICAmOmJlZm9yZSB7XG4gICAgICAgIC5hbmltYXRpb24ocHJvZ3Jlc3NiYXItaW5maW5pdGUtMSAycyBsaW5lYXIgaW5maW5pdGUpO1xuICAgIH1cbiAgICAmOmFmdGVyIHtcbiAgICAgICAgLmFuaW1hdGlvbihwcm9ncmVzc2Jhci1pbmZpbml0ZS0yIDJzIGxpbmVhciBpbmZpbml0ZSk7XG4gICAgfVxuICAgIGh0bWwud2l0aC1zdGF0dXNiYXItb3ZlcmxheSBib2R5ID4gJiwgaHRtbC53aXRoLXN0YXR1c2Jhci1vdmVybGF5IC5mcmFtZXdvcms3LXJvb3QgPiAmIHtcbiAgICAgICAgdG9wOiAyMHB4O1xuICAgIH1cbn1cblxuXG4vLyBNdWx0aWNvbG9yXG4ucHJvZ3Jlc3NiYXItaW5maW5pdGUuY29sb3ItbXVsdGkge1xuICAgIGJhY2tncm91bmQ6IG5vbmUgIWltcG9ydGFudDtcbiAgICAmOmJlZm9yZSwgJjphZnRlciB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBhbmltYXRpb246IG5vbmU7XG4gICAgfVxuICAgICY6YmVmb3JlIHtcbiAgICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgICAgLmFuaW1hdGlvbihwcm9ncmVzc2Jhci1pbmZpbml0ZS1tdWx0aWNvbG9yLWJnIDNzIHN0ZXAtZW5kIGluZmluaXRlKTtcbiAgICB9XG4gICAgJjphZnRlciB7XG4gICAgICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgICAgIC5hbmltYXRpb24ocHJvZ3Jlc3NiYXItaW5maW5pdGUtbXVsdGljb2xvci1maWxsIDNzIGxpbmVhciBpbmZpbml0ZSk7XG4gICAgICAgIC50cmFuc2Zvcm0tb3JpZ2luKGNlbnRlciBjZW50ZXIpO1xuICAgIH1cbn1cblxuYm9keSwgLnZpZXcsIC52aWV3cywgLnBhZ2UsIC5wYW5lbCwgLnBvcHVwLCAuZnJhbWV3b3JrNy1yb290IHtcbiAgICA+IC5wcm9ncmVzc2JhciwgPiAucHJvZ3Jlc3NiYXItaW5maW5pdGUge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgei1pbmRleDogMTUwMDA7XG4gICAgICAgIC50cmFuc2Zvcm0tb3JpZ2luKGNlbnRlciB0b3ApO1xuICAgIH1cbn1cbi8vIEFuaW1hdGlvbnNcbi5wcm9ncmVzc2Jhci1pbiB7XG4gICAgLmFuaW1hdGlvbihwcm9ncmVzc2Jhci1pbiAzMDBtcyBmb3J3YXJkcyk7XG59XG4ucHJvZ3Jlc3NiYXItb3V0IHtcbiAgICAuYW5pbWF0aW9uKHByb2dyZXNzYmFyLW91dCAzMDBtcyBmb3J3YXJkcyk7XG59XG5cbmh0bWwud2l0aC1zdGF0dXNiYXItb3ZlcmxheSBib2R5ID4gLnByb2dyZXNzYmFyLCBodG1sLndpdGgtc3RhdHVzYmFyLW92ZXJsYXkgLmZyYW1ld29yazctcm9vdCA+IC5wcm9ncmVzc2JhciB7XG4gICAgdG9wOiAyMHB4O1xufVxuQC13ZWJraXQta2V5ZnJhbWVzIHByb2dyZXNzYmFyLWluIHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlWSgwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVZKDEpO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcHJvZ3Jlc3NiYXItaW4ge1xuICAgIGZyb20ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWSgwKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWSgxKTtcbiAgICB9XG59XG5ALXdlYmtpdC1rZXlmcmFtZXMgcHJvZ3Jlc3NiYXItb3V0IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlWSgxKTtcbiAgICB9XG4gICAgdG8ge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVZKDApO1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcHJvZ3Jlc3NiYXItb3V0IHtcbiAgICBmcm9tIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZVkoMSk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZVkoMCk7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIHByb2dyZXNzYmFyLWluZmluaXRlLTEge1xuICAgIDAlIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTEwJSkgc2NhbGVYKDAuMSk7XG4gICAgfVxuICAgIDI1JSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDMwJSkgc2NhbGVYKDAuNik7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpIHNjYWxlWCgxKTtcbiAgICB9XG4gICAgMTAwJSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpIHNjYWxlWCgxKTtcbiAgICB9XG59XG5Aa2V5ZnJhbWVzIHByb2dyZXNzYmFyLWluZmluaXRlLTEge1xuICAgIDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC0xMCUpIHNjYWxlWCgwLjEpO1xuICAgIH1cbiAgICAyNSUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMzAlKSBzY2FsZVgoMC42KTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpIHNjYWxlWCgxKTtcbiAgICB9XG4gICAgMTAwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgxMDAlKSBzY2FsZVgoMSk7XG4gICAgfVxufVxuQC13ZWJraXQta2V5ZnJhbWVzIHByb2dyZXNzYmFyLWluZmluaXRlLTIge1xuICAgIDAlIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTEwMCUpIHNjYWxlWCgxKTtcbiAgICB9XG4gICAgNDAlIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTEwMCUpIHNjYWxlWCgxKTtcbiAgICB9XG4gICAgNzUlIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZVgoNjAlKSBzY2FsZVgoMC4zNSk7XG4gICAgfVxuICAgIDkwJSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpIHNjYWxlWCgwLjEpO1xuICAgIH1cbiAgICAxMDAlIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMTAwJSkgc2NhbGVYKDAuMSk7XG4gICAgfVxufVxuQGtleWZyYW1lcyBwcm9ncmVzc2Jhci1pbmZpbml0ZS0yIHtcbiAgICAwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtMTAwJSkgc2NhbGVYKDEpO1xuICAgIH1cbiAgICA0MCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTEwMCUpIHNjYWxlWCgxKTtcbiAgICB9XG4gICAgNzUlIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDYwJSkgc2NhbGVYKDAuMzUpO1xuICAgIH1cbiAgICA5MCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMTAwJSkgc2NhbGVYKDAuMSk7XG4gICAgfVxuICAgIDEwMCUge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMTAwJSkgc2NhbGVYKDAuMSk7XG4gICAgfVxufVxuXG5ALXdlYmtpdC1rZXlmcmFtZXMgcHJvZ3Jlc3NiYXItaW5maW5pdGUtbXVsdGljb2xvci1iZyB7XG4gICAgMCUge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAZ3JlZW47XG4gICAgfVxuICAgIDI1JSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IEByZWQ7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IEBibHVlO1xuICAgIH1cbiAgICA3NSUge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAeWVsbG93O1xuICAgIH1cbn1cbkBrZXlmcmFtZXMgcHJvZ3Jlc3NiYXItaW5maW5pdGUtbXVsdGljb2xvci1iZyB7XG4gICAgMCUge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAZ3JlZW47XG4gICAgfVxuICAgIDI1JSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IEByZWQ7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IEBibHVlO1xuICAgIH1cbiAgICA3NSUge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAeWVsbG93O1xuICAgIH1cbn1cbkAtd2Via2l0LWtleWZyYW1lcyBwcm9ncmVzc2Jhci1pbmZpbml0ZS1tdWx0aWNvbG9yLWZpbGwge1xuICAgIDAlIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlWCgwKTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQHJlZDtcbiAgICB9XG4gICAgMjQuOSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVYKDEpO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAcmVkO1xuICAgIH1cbiAgICAyNSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVYKDApO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAYmx1ZTtcbiAgICB9XG4gICAgNDkuOSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVYKDEpO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAYmx1ZTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlWCgwKTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQHllbGxvdztcbiAgICB9XG4gICAgNzQuOSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVYKDEpO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAeWVsbG93O1xuICAgIH1cbiAgICA3NSUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVYKDApO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAZ3JlZW47XG4gICAgfVxuICAgIDEwMCUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGVYKDEpO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAZ3JlZW47XG4gICAgfVxufVxuQGtleWZyYW1lcyBwcm9ncmVzc2Jhci1pbmZpbml0ZS1tdWx0aWNvbG9yLWZpbGwge1xuICAgIDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZVgoMCk7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IEByZWQ7XG4gICAgfVxuICAgIDI0LjklIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZVgoMSk7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IEByZWQ7XG4gICAgfVxuICAgIDI1JSB7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGVYKDApO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAYmx1ZTtcbiAgICB9XG4gICAgNDkuOSUge1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWCgxKTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQGJsdWU7XG4gICAgfVxuICAgIDUwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGVYKDApO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAeWVsbG93O1xuICAgIH1cbiAgICA3NC45JSB7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGVYKDEpO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAeWVsbG93O1xuICAgIH1cbiAgICA3NSUge1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWCgwKTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQGdyZWVuO1xuICAgIH1cbiAgICAxMDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZVgoMSk7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IEBncmVlbjtcbiAgICB9XG59IiwiLyogPT09IENvbHVtbnMgUGlja2VyID09PSAqL1xuLnBpY2tlci1jb2x1bW5zIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDI2MHB4O1xuICAgIHotaW5kZXg6IDExNTAwO1xuICAgICYucGlja2VyLW1vZGFsLWlubGluZSB7XG4gICAgICAgIGhlaWdodDogMjAwcHg7XG4gICAgfVxuICAgIEBtZWRpYSAob3JpZW50YXRpb246IGxhbmRzY2FwZSkgYW5kIChtYXgtaGVpZ2h0OiA0MTVweCkge1xuICAgICAgICAmOm5vdCgucGlja2VyLW1vZGFsLWlubGluZSkge1xuICAgICAgICAgICAgaGVpZ2h0OiAyMDBweDtcbiAgICAgICAgfVxuICAgIH1cbn1cbi5wb3BvdmVyLnBvcG92ZXItcGlja2VyLWNvbHVtbnMge1xuICAgIHdpZHRoOiAyODBweDtcbiAgICAudG9vbGJhciB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDJweCAycHggMCAwO1xuICAgIH1cbn1cbi5waWNrZXItaXRlbXMge1xuICAgIC5mbGV4Ym94KCk7XG4gICAgLmp1c3RpZnktY29udGVudChjZW50ZXIpO1xuICAgIHBhZGRpbmc6IDA7XG4gICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgZm9udC1zaXplOiAyMHB4O1xuICAgIC13ZWJraXQtbWFzay1ib3gtaW1hZ2U6IC13ZWJraXQtbGluZWFyLWdyYWRpZW50KGJvdHRvbSwgdHJhbnNwYXJlbnQsIHRyYW5zcGFyZW50IDUlLCB3aGl0ZSAyMCUsIHdoaXRlIDgwJSwgdHJhbnNwYXJlbnQgOTUlLCB0cmFuc3BhcmVudCk7XG4gICAgLXdlYmtpdC1tYXNrLWJveC1pbWFnZTogbGluZWFyLWdyYWRpZW50KHRvIHRvcCwgdHJhbnNwYXJlbnQsIHRyYW5zcGFyZW50IDUlLCB3aGl0ZSAyMCUsIHdoaXRlIDgwJSwgdHJhbnNwYXJlbnQgOTUlLCB0cmFuc3BhcmVudCk7XG59XG4ucGlja2VyLWl0ZW1zLWNvbCB7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgbWF4LWhlaWdodDogMTAwJTtcblxuICAgICYucGlja2VyLWl0ZW1zLWNvbC1sZWZ0IHtcbiAgICAgICAgdGV4dC1hbGlnbjogbGVmdDtcbiAgICB9XG4gICAgJi5waWNrZXItaXRlbXMtY29sLWNlbnRlciB7XG4gICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB9XG4gICAgJi5waWNrZXItaXRlbXMtY29sLXJpZ2h0IHtcbiAgICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gICAgfVxuICAgICYucGlja2VyLWl0ZW1zLWNvbC1kaXZpZGVyIHtcbiAgICAgICAgY29sb3I6IHJnYmEoMCwwLDAsMC44Nyk7XG4gICAgICAgIC5mbGV4Ym94KCk7XG4gICAgICAgIC5hbGlnbi1pdGVtcyhjZW50ZXIpO1xuICAgIH1cbn1cbi5waWNrZXItaXRlbXMtY29sLXdyYXBwZXIge1xuICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICBcbiAgICAtd2Via2l0LXRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbiAgICB0cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvbjogZWFzZS1vdXQ7XG59XG4ucGlja2VyLWl0ZW0ge1xuICAgIGhlaWdodDogMzZweDtcbiAgICBsaW5lLWhlaWdodDogMzZweDtcbiAgICBwYWRkaW5nOiAwIDEwcHg7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICBjb2xvcjogcmdiYSgwLDAsMCwwLjU0KTtcbiAgICBsZWZ0OiAwO1xuICAgIHRvcDogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIC50cmFuc2l0aW9uKDMwMG1zKTtcbiAgICAucGlja2VyLWl0ZW1zLWNvbC1hYnNvbHV0ZSAme1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgfVxuICAgICYucGlja2VyLWl0ZW0tZmFyIHtcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgfVxuICAgICYucGlja2VyLXNlbGVjdGVkIHtcbiAgICAgICAgY29sb3I6IHJnYmEoMCwwLDAsMC44Nyk7XG4gICAgICAgIC50cmFuc2Zvcm0odHJhbnNsYXRlM2QoMCwwLDApIHJvdGF0ZVgoMGRlZykpO1xuICAgIH1cbn1cbi5waWNrZXItY2VudGVyLWhpZ2hsaWdodCB7XG4gICAgaGVpZ2h0OiAzNnB4O1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgdG9wOiA1MCU7XG4gICAgbWFyZ2luLXRvcDogLTE4cHg7XG4gICAgLmhhaXJsaW5lKHRvcCwgcmdiYSgwLDAsMCwwLjE1KSk7XG4gICAgLmhhaXJsaW5lKGJvdHRvbSwgcmdiYSgwLDAsMCwwLjE1KSk7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG4vLyAzRCBQaWNrZXJcbi5waWNrZXItM2Qge1xuICAgIC5waWNrZXItaXRlbXMge1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICAtd2Via2l0LXBlcnNwZWN0aXZlOiAxMjAwcHg7XG4gICAgICAgIHBlcnNwZWN0aXZlOiAxMjAwcHg7XG4gICAgfVxuICAgIC5waWNrZXItaXRlbXMtY29sLCAucGlja2VyLWl0ZW1zLWNvbC13cmFwcGVyLCAucGlja2VyLWl0ZW0ge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgICAgIHRyYW5zZm9ybS1zdHlsZTogcHJlc2VydmUtM2Q7XG4gICAgfVxuICAgIC5waWNrZXItaXRlbXMtY29sIHtcbiAgICAgICAgb3ZlcmZsb3c6IHZpc2libGU7XG4gICAgfVxuICAgIC5waWNrZXItaXRlbSB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogY2VudGVyIGNlbnRlciAtMTEwcHg7XG4gICAgICAgIHRyYW5zZm9ybS1vcmlnaW46IGNlbnRlciBjZW50ZXIgLTExMHB4O1xuICAgICAgICAtd2Via2l0LWJhY2tmYWNlLXZpc2liaWxpdHk6IGhpZGRlbjtcbiAgICAgICAgYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuO1xuICAgICAgICAtd2Via2l0LXRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBlYXNlLW91dDtcbiAgICAgICAgdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGVhc2Utb3V0O1xuICAgIH1cbn0iLCIvKiA9PT0gTm90aWZpY2F0aW9ucyA9PT0gKi9cbkBub3RpZmljYXRpb25zRHVyYXRpb246IDQ1MG1zO1xuLm5vdGlmaWNhdGlvbnMge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBsZWZ0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICB6LWluZGV4OiAxMDkwMDtcbiAgICBjb2xvcjogI2ZmZjtcbiAgICBmb250LXNpemU6IDE0cHg7XG4gICAgbWFyZ2luOiAwO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBkaXNwbGF5OiBub25lO1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgbWF4LWhlaWdodDogMTAwJTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIC13ZWJraXQtb3ZlcmZsb3ctc2Nyb2xsaW5nOiB0b3VjaDtcbiAgICAudHJhbnNpdGlvbihAbm90aWZpY2F0aW9uc0R1cmF0aW9uKTtcbiAgICAtd2Via2l0LXBlcnNwZWN0aXZlOjEyMDBweDtcbiAgICBwZXJzcGVjdGl2ZToxMjAwcHg7XG5cbiAgICAmLmxpc3QtYmxvY2sgPiB1bCB7XG4gICAgICAgIC5oYWlybGluZS1yZW1vdmUodG9wKTtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgICAgICBtYXgtd2lkdGg6IDU2OHB4O1xuICAgICAgICBiYWNrZ3JvdW5kOiAjMzIzMjMyO1xuICAgICAgICBtYXJnaW46IDAgYXV0bztcbiAgICB9XG4gICAgLml0ZW0tY29udGVudCB7XG4gICAgICAgIC5hbGlnbi1pdGVtcyhmbGV4LXN0YXJ0KTtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiAyNHB4O1xuICAgIH1cbiAgICAuaXRlbS10aXRsZSB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgZm9udC13ZWlnaHQ6IG5vcm1hbDtcbiAgICAgICAgd2hpdGUtc3BhY2U6IG5vcm1hbDtcbiAgICAgICAgcGFkZGluZy10b3A6IDE0cHg7XG4gICAgICAgIHBhZGRpbmctYm90dG9tOiAxNHB4O1xuICAgIH1cbiAgICAuaXRlbS1pbm5lciB7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IDI0cHg7XG4gICAgICAgIHBhZGRpbmctdG9wOiAwO1xuICAgICAgICBwYWRkaW5nLWJvdHRvbTogMDtcbiAgICAgICAgLmhhaXJsaW5lLXJlbW92ZShib3R0b20pO1xuICAgIH1cbiAgICAuaXRlbS1hZnRlciB7XG4gICAgICAgIG1heC1oZWlnaHQ6IG5vbmU7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAxNnB4O1xuICAgIH1cbiAgICAuYnV0dG9uLmNsb3NlLW5vdGlmaWNhdGlvbiB7XG4gICAgICAgIGNvbG9yOiBsaWdodGVuKHNhdHVyYXRlKEB0aGVtZUNvbG9yLCAxMCUpLCAxMCUpO1xuICAgIH1cbiAgICAubm90aWZpY2F0aW9uLWl0ZW0ge1xuICAgICAgICBtYXJnaW46IDAgYXV0bztcbiAgICAgICAgLnRyYW5zaXRpb24oQG5vdGlmaWNhdGlvbnNEdXJhdGlvbik7XG4gICAgICAgIC5kZWxheSgxMDBtcyk7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxuICAgIC5ub3RpZmljYXRpb24taGlkZGVuIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgICAgLmRlbGF5KDBtcyk7XG4gICAgICAgIC50cmFuc2xhdGUzZCgwLDAsMCk7XG4gICAgfVxuICAgIC5ub3RpZmljYXRpb24taXRlbS1yZW1vdmluZyB7XG4gICAgICAgIC5kZWxheSgwbXMpO1xuICAgIH1cbiAgICBAbWVkaWEgKG1pbi13aWR0aDogNTY5cHgpIHtcbiAgICAgICAgJi5saXN0LWJsb2NrID4gdWwge1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMnB4O1xuICAgICAgICAgICAgd2lkdGg6IGF1dG87XG4gICAgICAgICAgICBtaW4td2lkdGg6IDI4OHB4O1xuICAgICAgICB9XG4gICAgfVxufSIsIi8qID09PSBEaXNhYmxlZCBlbGVtZW50cyA9PT0gKi9cbi5kaXNhYmxlZCwgW2Rpc2FibGVkXSB7XG4gICAgb3BhY2l0eTogMC41NTtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAuZGlzYWJsZWQgJiwgW2Rpc2FibGVkXSAmIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG59IiwiLy8gQ29udGFpbmVyXG5cbi5waG9uZS5hbmRyb2lkIHtcbiAgLmNvbnRhaW5lci1lZGl0IHtcblxuICAgIC5wYWdlLWNvbnRlbnQge1xuICAgICAgLmxpc3QtYmxvY2s6Zmlyc3QtY2hpbGQge1xuICAgICAgICBtYXJnaW4tdG9wOiAtMXB4O1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4uY29udGFpbmVyLWVkaXQsXG4uY29udGFpbmVyLWFkZCxcbi5jb250YWluZXItc2V0dGluZ3Mge1xuICAmLnBvcG92ZXIge1xuICAgIHdpZHRoOiAzNjBweDtcbiAgfVxufVxuXG4uc2V0dGluZ3Mge1xuICAmLnBvcHVwLFxuICAmLnBvcG92ZXIge1xuICAgIC5saXN0LWJsb2NrIHtcbiAgICAgIG1hcmdpbjogMzJweCAwO1xuXG4gICAgICB1bCB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgICB9XG5cbiAgICAgICY6Zmlyc3QtY2hpbGQge1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuXG4gICAgICAgIGxpOmZpcnN0LWNoaWxkIGEge1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAmLFxuICAgIC5wb3BvdmVyLWlubmVyIHtcbiAgICAgID4gLmNvbnRlbnQtYmxvY2sge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBtYXJnaW46IDA7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLnBvcG92ZXItdmlldyB7XG4gICAgICBib3JkZXItcmFkaXVzOiAzcHg7XG5cbiAgICAgID4gLnBhZ2VzIHtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC5jYXRlZ29yaWVzIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgbWFyZ2luOiAwO1xuICAgIHBhZGRpbmc6IDA7XG5cbiAgICA+IC50b29sYmFyIHtcbiAgICAgIHRvcDogMDtcbiAgICAgIGhlaWdodDogMTAwJTtcbiAgICB9XG4gIH1cbiAgLnBvcG92ZXItaW5uZXIge1xuICAgIGhlaWdodDogNDAwcHg7XG4gIH1cbn0iLCIvLyBEYXRhIHZpZXdcblxuLmRhdGF2aWV3IHtcbiAgLnJvdyB7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1hcm91bmQ7XG4gIH1cblxuICB1bCB7XG4gICAgcGFkZGluZzogMCAxMHB4O1xuICAgIGxpc3Qtc3R5bGU6IG5vbmU7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1hcm91bmQ7XG5cbiAgICBsaSB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgfVxuICB9XG5cbiAgLmFjdGl2ZSB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHotaW5kZXg6IDE7XG5cbiAgICAmOjphZnRlciB7XG4gICAgICBjb250ZW50OiAnJztcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIHdpZHRoOiAyMnB4O1xuICAgICAgaGVpZ2h0OiAyMnB4O1xuICAgICAgcmlnaHQ6IC01cHg7XG4gICAgICBib3R0b206IC01cHg7XG4gICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxjaXJjbGUgZmlsbD1cIiNmZmZcIiBjeD1cIjExXCIgY3k9XCIxMVwiIHI9XCIxMVwiLz48cGF0aCBkPVwiTTExLDIxQTEwLDEwLDAsMSwxLDIxLDExLDEwLDEwLDAsMCwxLDExLDIxaDBaTTE3LjQsNy4zMkwxNy4wNiw3YTAuNDgsMC40OCwwLDAsMC0uNjcsMGwtNyw2Ljg0TDYuOTUsMTEuMjRhMC41MSwwLjUxLDAsMCwwLS41OS4wOEw2LDExLjY2YTAuNTgsMC41OCwwLDAsMCwwLC42NWwzLjE5LDMuMzVhMC4zOCwwLjM4LDAsMCwwLC4zOSwwTDE3LjQsOGEwLjQ4LDAuNDgsMCwwLDAsMC0uNjdoMFpcIi8+PC9nPjwvc3ZnPicpO1xuICAgIH1cbiAgfVxufSIsIi8vIExpc3QgZXh0ZW5kXG5cbi5pdGVtLWNvbnRlbnR7XG4gIC5pdGVtLWFmdGVyIHtcbiAgICAmLnNwbGl0dGVyIHtcbiAgICAgIGxhYmVsIHtcbiAgICAgICAgY29sb3I6ICMwMDA7XG4gICAgICAgIG1hcmdpbjowIDVweDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDM2cHg7XG4gICAgICB9XG5cbiAgICAgIC5idXR0b24ge1xuICAgICAgICBtaW4td2lkdGg6IDQwcHg7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiAwO1xuICAgICAgfVxuICAgIH1cblxuICAgICYudmFsdWUge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBtaW4td2lkdGg6IDUwcHg7XG4gICAgICBjb2xvcjogQGJsYWNrO1xuICAgICAgbWFyZ2luLWxlZnQ6IDEwcHg7XG4gICAgICB0ZXh0LWFsaWduOiByaWdodDtcbiAgICB9XG4gIH1cblxuICAmLmJ1dHRvbnMge1xuICAgIC5pdGVtLWlubmVyIHtcbiAgICAgIHBhZGRpbmctdG9wOiAwO1xuICAgICAgcGFkZGluZy1ib3R0b206IDA7XG5cbiAgICAgID4gLnJvdyB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuXG4gICAgICAgIC5idXR0b24ge1xuICAgICAgICAgIGZsZXg6IDE7XG4gICAgICAgICAgZm9udC1zaXplOiAxN3B4O1xuICAgICAgICAgIG1hcmdpbi1sZWZ0OiA1cHg7XG5cbiAgICAgICAgICAmOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgICAgIG1hcmdpbi1sZWZ0OiAwO1xuICAgICAgICAgIH1cblxuICAgICAgICAgICYuYWN0aXZlIHtcbiAgICAgICAgICAgIGNvbG9yOiAjZmZmO1xuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogQHRoZW1lQ29sb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLmNvbG9yLXByZXZpZXcge1xuICAgIHdpZHRoOiAzMHB4O1xuICAgIGhlaWdodDogMzBweDtcbiAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICAgIG1hcmdpbi10b3A6IC0zcHg7XG4gICAgYm94LXNoYWRvdzogMCAwIDAgMXB4IHJnYmEoMCwwLDAsMC4xNSkgaW5zZXQ7XG4gIH1cbn1cblxuLml0ZW0tbGluayB7XG4gICYubm8taW5kaWNhdG9yIHtcbiAgICAuaXRlbS1pbm5lciB7XG4gICAgICBiYWNrZ3JvdW5kLWltYWdlOiBub25lO1xuICAgICAgcGFkZGluZy1yaWdodDogMTZweDtcbiAgICB9XG4gIH1cbn1cblxuLnBvcG92ZXIgLmxpc3QtYmxvY2s6bGFzdC1jaGlsZCBsaTpsYXN0LWNoaWxkIC5idXR0b25zIGEge1xuICBib3JkZXItcmFkaXVzOiAzcHg7XG59IiwiLy8gQ29udGV4dCBtZW51XG5cbi5kb2N1bWVudC1tZW51IHtcbiAgd2lkdGg6IGF1dG87XG4gIGxpbmUtaGVpZ2h0OiAxICFpbXBvcnRhbnQ7XG4gIHotaW5kZXg6IDEyNTAwO1xuXG4gIC5wb3BvdmVyLWlubmVyIHtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICB9XG5cbiAgLmxpc3QtYmxvY2sge1xuICAgIHdoaXRlLXNwYWNlOiBwcmU7XG5cbiAgICB1bCB7XG4gICAgICBoZWlnaHQ6IDQ4cHg7XG4gICAgfVxuXG4gICAgbGkge1xuICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIH1cblxuICAgIC5pdGVtLWxpbmsge1xuICAgICAgaHRtbC5waG9uZSAmIHtcbiAgICAgICAgcGFkZGluZzogMCAxMHB4O1xuICAgICAgfVxuICAgIH1cbiAgfVxufSIsIi8vIENvbG9yIHBhbGV0dGVcblxuLmNvbG9yLXBhbGV0dGUge1xuICBhIHtcbiAgICBmbGV4LWdyb3c6IDE7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG1pbi13aWR0aDogMTBweDtcbiAgICBtaW4taGVpZ2h0OiAyNnB4O1xuICAgIG1hcmdpbjogMXB4IDFweCAwIDA7XG4gICAgYm94LXNoYWRvdzogMCAwIDAgMXB4IHJnYmEoMCwwLDAsMC4xNSkgaW5zZXQ7XG5cbiAgICAmLmFjdGl2ZSB7XG4gICAgICAmOmFmdGVyIHtcbiAgICAgICAgY29udGVudDonICc7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgYm94LXNoYWRvdzogMCAwIDAgMXB4IHdoaXRlLCAwIDAgMCA0cHggQHRoZW1lQ29sb3I7XG4gICAgICAgIHotaW5kZXg6IDE7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDFweDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAmLnRyYW5zcGFyZW50IHtcbiAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgICBiYWNrZ3JvdW5kLXNpemU6IDEwMCUgMTAwJTtcbiAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKFwiPHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHg9JzBweCcgeT0nMHB4JyB2aWV3Qm94PScwIDAgMjIgMjInIHhtbDpzcGFjZT0ncHJlc2VydmUnPjxsaW5lIHN0cm9rZT0nI2ZmMDAwMCcgc3Ryb2tlLWxpbmVjYXA9J3VuZGVmaW5lZCcgc3Ryb2tlLWxpbmVqb2luPSd1bmRlZmluZWQnIGlkPSdzdmdfMScgeTI9JzAnIHgyPScyMicgeTE9JzIyJyB4MT0nMCcgc3Ryb2tlLXdpZHRoPScyJyBmaWxsPSdub25lJy8+PC9zdmc+XCIpO1xuICAgIH1cbiAgfVxuXG4gIC50aGVtZS1jb2xvcnMge1xuICAgIC5pdGVtLWlubmVyIHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIH1cbiAgfVxuXG4gIC5zdGFuZGFydC1jb2xvcnMge1xuICAgIC5pdGVtLWlubmVyIHtcbiAgICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIH1cbiAgfVxuXG4gICYubGlzdC1ibG9jazpsYXN0LWNoaWxkIGxpOmxhc3QtY2hpbGQgYSB7XG4gICAgYm9yZGVyLXJhZGl1czogMDtcbiAgfVxufSIsIi8vIEFib3V0XG5cbi5hYm91dCB7XG4gIC5wYWdlLWNvbnRlbnQge1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgfVxuXG4gIC5jb250ZW50LWJsb2NrOmZpcnN0LWNoaWxkIHtcbiAgICBtYXJnaW46IDE1cHggMDtcbiAgfVxuXG4gIC5jb250ZW50LWJsb2NrIHtcbiAgICBtYXJnaW46IDAgYXV0byAxNXB4O1xuXG4gICAgYSB7XG4gICAgICBjb2xvcjogIzAwMDtcbiAgICB9XG4gIH1cblxuICBoMyB7XG4gICAgZm9udC13ZWlnaHQ6IG5vcm1hbDtcbiAgICBtYXJnaW46IDA7XG5cbiAgICAmLnZlbmRvciB7XG4gICAgICBjb2xvcjogIzAwMDtcbiAgICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xuICAgICAgbWFyZ2luLXRvcDogMTVweDtcbiAgICB9XG4gIH1cblxuICBwID4gbGFiZWwge1xuICAgIG1hcmdpbi1yaWdodDogNXB4O1xuICB9XG5cbiAgLmxvZ28ge1xuICAgIGJhY2tncm91bmQ6IHVybCgnLi4vLi4vLi4vLi4vY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvaW1nL2Fib3V0L29ubHlvZmZpY2Uuc3ZnJykgbm8tcmVwZWF0IGNlbnRlcjtcbiAgfVxufSIsIi8vIFNlYXJjaFxuXG4udGFibGV0IHtcbiAgLnNlYXJjaGJhci5kb2N1bWVudCB7XG4gICAgLmxlZnQge1xuICAgICAgbWluLXdpZHRoOiAxNXB4O1xuICAgIH1cblxuICAgIC5jZW50ZXIge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgbWFyZ2luOiAwO1xuICAgICAgb3ZlcmZsb3c6IHZpc2libGU7XG5cbiAgICAgIC5zZWFyY2hiYXIge1xuICAgICAgICBvdmVyZmxvdzogdmlzaWJsZTtcblxuICAgICAgICAmLnNlYXJjaCB7XG4gICAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5AcGhvbmVTZWFyY2hIZWlnaHQ6IDQ4cHg7XG5cbi5waG9uZSB7XG4gIC5zZWFyY2hiYXIuZG9jdW1lbnQge1xuICAgIC5sZWZ0LFxuICAgIC5jZW50ZXIsXG4gICAgLnJpZ2h0IHtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuXG4gICAgLmxlZnQge1xuICAgICAgbWluLXdpZHRoOiAxNXB4O1xuICAgIH1cblxuICAgIC5jZW50ZXIge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBtYXJnaW46IDA7XG4gICAgICBvdmVyZmxvdzogdmlzaWJsZTtcblxuICAgICAgLnNlYXJjaGJhciB7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLnJpZ2h0IHtcbiAgICAgID4gcCB7XG4gICAgICAgIG1hcmdpbjogMDtcblxuICAgICAgICBhLmxpbmsge1xuICAgICAgICAgIGhlaWdodDogQHBob25lU2VhcmNoSGVpZ2h0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59IiwiLy8gSWNvbnNcbmkuaWNvbiB7XG4gICYuaWNvbi1leHBhbmQtdXAge1xuICAgIHdpZHRoOiAxN3B4O1xuICAgIGhlaWdodDogMTdweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe2JsYWNrfVwiPjxnPjxwb2x5Z29uIHBvaW50cz1cIjEwLjksNS4xIDIsMTMuOSA0LjEsMTYgMTEuMSw5LjIgMTcuOSwxNiAyMCwxMy45IDExLjIsNS4xIDExLjEsNSBcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1leHBhbmQtZG93biB7XG4gICAgd2lkdGg6IDE3cHg7XG4gICAgaGVpZ2h0OiAxN3B4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7YmxhY2t9XCI+PGc+PHBvbHlnb24gcG9pbnRzPVwiMTAuOSwxNi45IDIsOC4xIDQuMSw2IDExLjEsMTIuOCAxNy45LDYgMjAsOC4xIDExLjIsMTYuOSAxMS4xLDE3IFwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXNlYXJjaCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTE5LjUsMTYuOEwxNiwxMy4zYzAuNy0xLjEsMS4xLTIuNCwxLjEtMy44QzE3LDUuNCwxMy42LDIsOS41LDJTMiw1LjQsMiw5LjVTNS40LDE3LDkuNSwxN2MxLjQsMCwyLjctMC40LDMuOC0xLjFsMy41LDMuNWMwLjcsMC43LDEuOSwwLjcsMi42LDBDMjAuMiwxOC43LDIwLjIsMTcuNiwxOS41LDE2Ljh6IE05LjUsMTUuM2MtMy4yLDAtNS44LTIuNi01LjgtNS44czIuNi01LjgsNS44LTUuOHM1LjgsMi42LDUuOCw1LjhTMTIuNywxNS4zLDkuNSwxNS4zelwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLWVkaXQge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0wLDIwaDIydjFIMFYyMHpcIi8+PHBvbHlnb24gcG9pbnRzPVwiMTcuMSwzLjEgMy41LDE2LjcgMywyMCA2LjMsMTkuNSAxOS45LDUuOSBcdFwiLz48cGF0aCBkPVwiTTIwLjUsNS4zTDIyLDMuOGMwLDAtMC4yLTEuMi0wLjktMS45QzIwLjQsMS4xLDE5LjIsMSwxOS4yLDFsLTEuNSwxLjVMMjAuNSw1LjN6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tcGxheSB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTQuMDQ2NDM2MywyLjk4ODQ1NTNjMC4wMDY1MjYsMC4wMDI5NiwwLjAxNDIzNDUsMC4wMDY4MzUsMC4wMjMxNDM4LDAuMDExOTAyMSBjMC41OTA4NjA0LDAuMzM1NzYzNywxMi43MTE4Mzk3LDcuMjkyNDQzMywxMy44OTc3NDg5LDguMDI2ODQwMmMtMC41ODMxNTg1LDAuMzQxNzc1OS0xMy4wMTM3NTg3LDcuNDg3OTI3NC0xMy45MzQ2NTksNy45ODI2NzI3IEw0LjA0NjQzNjMsMi45ODg0NTUzIE0zLjk4ODkzNTcsMkMzLjQ0Mjc3OTUsMi4wMDAwNTc3LDMuMDAwNTI1LDIuNDUzMzU3NSwzLjAwMDUyNSwzLjAxNTM0OFx0YzAsMC41NzM0ODcsMCwxNS4xNjMyOTU3LDAsMTUuOTk0NTIyMUMzLjAwMDUyNSwxOS42MjI5NjMsMy40Nzk2MTA0LDIwLDMuOTk0MDU4OCwyMCBjMC4xNzI5MzcyLDAsMC4zNDk5MTkxLTAuMDQyNjMxMSwwLjUxMzk3NjMtMC4xMzMyMjI2YzAuODkwNTYwMi0wLjQ5MTA0NSwxMy4xODgwODk0LTcuNTU4MzM3MiwxMy45NDA3Mzg3LTcuOTk5NDQ1OSBjMC42NzUxMjEzLTAuMzk1NTIwMiwwLjY4NjczMTMtMS4zMzc1MTIsMC0xLjczMjY2MDNDMTcuNDAzMTc1NCw5LjUzMzMyNzEsNS4xNTIzODUyLDIuNTAxODUyLDQuNTM5Mzk1MywyLjE1MzUxNjUgQzQuMzUyNjIwMSwyLjA0NzI3OTQsNC4xNjU0MDEsMS45OTk5ODEzLDMuOTg4OTM1NywyTDMuOTg4OTM1NywyelwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXJlYWRlciB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTE3LDIxSDFWOWg2VjJsMCwwaDEwdjVoMVYxSDYuMkwwLDcuNlYyMmgxOHYtM2gtMVYyMXogTTYsMi44VjhIMS4xTDYsMi44eiBNMTMsOGMtNS4xLDAtOSw1LTksNXM0LjEsNSw5LDVjNSwwLDktNSw5LTVTMTgsOCwxMyw4eiBNOC43LDE1LjVDNi44LDE0LjQsNi40LDEzLDYuNCwxM3MwLjQtMS41LDIuNC0yLjZDOC4zLDExLjIsOCwxMiw4LDEzQzgsMTMuOSw4LjMsMTQuOCw4LjcsMTUuNXogTTEzLDE2LjdjLTIuMSwwLTMuNy0xLjctMy43LTMuN2MwLTIuMSwxLjctMy43LDMuNy0zLjdjMi4xLDAsMy43LDEuNywzLjcsMy43QzE2LjcsMTUuMSwxNS4xLDE2LjcsMTMsMTYuN3ogTTE3LjMsMTUuNWMwLjQtMC43LDAuNy0xLjYsMC43LTIuNWMwLTEtMC4zLTEuOC0wLjctMi42YzIsMS4xLDMuNCwyLjYsMy40LDIuNlMxOS4yLDE0LjQsMTcuMywxNS41eiBNMTMsMTEuN2MtMC43LDAtMS4zLDAuNi0xLjMsMS4zczAuNiwxLjMsMS4zLDEuM3MxLjMtMC42LDEuMy0xLjNTMTMuNywxMS43LDEzLDExLjd6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tZG93bmxvYWQge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIi0xIDMgMjIgMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwb2x5Z29uIGlkPVwiWE1MSURfM19cIiBwb2ludHM9XCIxMCw1LjYgMTAsMjEuMiAxMSwyMS4yIDExLDUuNiAxNC42LDkuMyAxNS4zLDguNSAxMC41LDMuNiA1LjcsOC41IDYuNCw5LjMgXHRcIi8+PHBvbHlnb24gaWQ9XCJYTUxJRF82X1wiIHBvaW50cz1cIjEzLDEyIDEzLDEzIDE5LDEzIDE5LDMwIDIsMzAgMiwxMyA4LDEzIDgsMTIgMSwxMiAxLDEzIDEsMzAgMSwzMSAyMCwzMSAyMCwzMCAyMCwxMyAyMCwxMiBcdFwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLWluZm8ge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xMCwxN2gyVjhoLTJWMTd6IE0xMSwxQzUuNSwxLDEsNS41LDEsMTFzNC41LDEwLDEwLDEwczEwLTQuNSwxMC0xMFMxNi41LDEsMTEsMXogTTExLDIwYy01LDAtOS00LTktOXM0LTksOS05czksNCw5LDlTMTYsMjAsMTEsMjB6IE0xMCw3aDJWNWgtMlY3elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLWFib3V0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCItMSA3IDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTIxLDE4LjVjMC0wLjMtMC4xLTAuNi0wLjctMC45bC0yLjYtMS4ybDIuNi0xLjJjMC42LTAuMywwLjctMC42LDAuNy0wLjljMC0wLjMtMC4xLTAuNi0wLjctMC45bC04LjktNC4xYy0wLjctMC40LTEuOS0wLjQtMi44LDBsLTguOSw0LjFDLTAuOSwxMy44LTEsMTQuMS0xLDE0LjNzMC4xLDAuNiwwLjcsMC45bDIuNiwxLjJsLTIuNiwxLjJDLTAuOSwxOC0xLDE4LjQtMSwxOC41YzAsMC4yLDAuMSwwLjYsMC43LDAuOWwyLjUsMS4ybC0yLjUsMS4yQy0wLjksMjIuMS0xLDIyLjUtMSwyMi43YzAsMC4zLDAuMSwwLjYsMC43LDAuOWw4LjksNC4xYzAuNSwwLjIsMC44LDAuMywxLjQsMC4zczEtMC4xLDEuNC0wLjNsOC45LTQuMWMwLjYtMC40LDAuNy0wLjYsMC43LTAuOWMwLTAuMy0wLjEtMC42LTAuNy0wLjlsLTIuNS0xLjJsMi41LTEuMkMyMC45LDE5LjIsMjEsMTguOCwyMSwxOC41eiBNLTAuMiwxNC4zTC0wLjIsMTQuM2MwLDAsMC4xLTAuMSwwLjMtMC4yTDksMTBjMC42LTAuMywxLjUtMC4zLDIsMGw4LjksNC4xYzAuMiwwLjEsMC4zLDAuMiwwLjMsMC4ybDAsMGMwLDAtMC4xLDAuMS0wLjMsMC4yTDExLDE4LjZjLTAuNiwwLjMtMS41LDAuMy0yLDBsLTguOS00LjFDLTAuMSwxNC40LTAuMiwxNC4zLTAuMiwxNC4zeiBNMjAuMiwyMi43TDIwLjIsMjIuN2MwLDAtMC4xLDAuMS0wLjMsMC4yTDExLDI3LjFjLTAuNiwwLjMtMS41LDAuMy0yLDBsLTguOS00LjFjLTAuMi0wLjEtMC4zLTAuMi0wLjMtMC4ybDAsMGMwLDAsMC4xLTAuMSwwLjMtMC4ybDMtMS41bDUuNSwyLjZjMC43LDAuNCwxLjksMC40LDIuOCwwbDUuNS0yLjZsMywxLjVDMjAuMSwyMi43LDIwLjIsMjIuNywyMC4yLDIyLjd6IE0xOS45LDE4LjdMMTEsMjIuOGMtMC42LDAuMy0xLjUsMC4zLTIsMGwtOC45LTQuMWMtMC4yLTAuMS0wLjMtMC4yLTAuMy0wLjJsMCwwYzAsMCwwLjEtMC4xLDAuMy0wLjJsMy0xLjVsNS41LDIuNmMwLjcsMC40LDEuOSwwLjQsMi44LDBsNS41LTIuNmwzLDEuNWMwLjIsMC4xLDAuMywwLjIsMC4zLDAuMmwwLDBDMjAuMiwxOC41LDIwLjEsMTguNiwxOS45LDE4Ljd6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24taGVscCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTExLjYsMS4zYy0zLjMsMC02LDIuOC02LDYuMmMwLjMsMCwwLjcsMCwwLjksMGMwLTIuOSwyLjMtNS4yLDUuMS01LjJzNS4xLDIuMyw1LjEsNS4yYzAsMS43LTEuOSwzLjItMyw0LjNDMTIuOSwxMi42LDExLDE0LjIsMTEsMTZjMCwxLjIsMCwyLjIsMCwyLjdjMC4zLDAsMC42LDAsMC45LDBjMC0wLjYsMC0xLjYsMC0yLjVjMC0xLjQsMS4xLTIuNCwyLjItMy41YzEuNy0xLjUsMy41LTMuMSwzLjUtNS4yQzE3LjYsNC4xLDE0LjksMS4zLDExLjYsMS4zeiBNMTEuNSwyMC4yYy0wLjMsMC0wLjUsMC4yLTAuNSwwLjV2MC44YzAsMC4zLDAuMiwwLjUsMC41LDAuNXMwLjUtMC4yLDAuNS0wLjV2LTAuOEMxMS45LDIwLjQsMTEuNywyMC4yLDExLjUsMjAuMnpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1zZXR1cCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTAsM3YxNmgyMlYzSDB6IE0yMSwxN0gxVjVoMjBWMTd6IE0xNi41LDUuOWwtNy4yLDcuMkw4LjgsMTVINHYxYzAsMCwzLjIsMCw1LDBjMC40LDAsMC4yLDAsMC4yLTAuMmwyLjItMC42TDE4LjcsOEwxNi41LDUuOXogTTkuOSwxMy4xbDYuNS02LjRMMTgsOGwtNi41LDYuNEw5LjksMTMuMXpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi12ZXJzaW9ucyB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiLTEgNyAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xOSwxMmMwLTEuMS0wLjktMi0yLTJjMC0xLjEtMC45LTItMi0ySDVjLTEuMSwwLTIsMC45LTIsMmMtMS4xLDAtMiwwLjktMiwyYy0xLjEsMC0yLDAuOS0yLDJ2MTJjMCwxLjEsMC45LDIsMiwyaDE4YzEuMSwwLDItMC45LDItMlYxNEMyMSwxMi45LDIwLjEsMTIsMTksMTJ6IE01LDloMTBjMC42LDAsMSwwLjQsMSwxSDRDNCw5LjQsNC40LDksNSw5eiBNMywxMWgxNGMwLjYsMCwxLDAuNCwxLDFIMkMyLDExLjQsMi40LDExLDMsMTF6IE0yMCwyNmMwLDAuNi0wLjQsMS0xLDFIMWMtMC42LDAtMS0wLjQtMS0xVjE0YzAtMC42LDAuNC0xLDEtMWgxOGMwLjYsMCwxLDAuNCwxLDFWMjZ6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAvLyYuaWNvbi10ZXh0LWFkZGl0aW9uYWwge1xuICAvLyAgd2lkdGg6IDIycHg7XG4gIC8vICBoZWlnaHQ6IDIycHg7XG4gIC8vICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xOC41LDE1LjVjLTEuMSwwLTIsMC45LTIsMnMwLjksMiwyLDJzMi0wLjksMi0yUzE5LjYsMTUuNSwxOC41LDE1LjV6IE0xOC41LDE4LjVjLTAuNiwwLTEtMC40LTEtMWMwLTAuNiwwLjQtMSwxLTFzMSwwLjQsMSwxQzE5LjUsMTguMSwxOS4xLDE4LjUsMTguNSwxOC41eiBNMTguNSw3LjVjMS4xLDAsMi0wLjksMi0yYzAtMS4xLTAuOS0yLTItMnMtMiwwLjktMiwyQzE2LjUsNi42LDE3LjQsNy41LDE4LjUsNy41eiBNMTguNSw0LjVjMC42LDAsMSwwLjQsMSwxcy0wLjQsMS0xLDFzLTEtMC40LTEtMVMxNy45LDQuNSwxOC41LDQuNXogTTE4LjUsOS41Yy0xLjEsMC0yLDAuOS0yLDJzMC45LDIsMiwyczItMC45LDItMlMxOS42LDkuNSwxOC41LDkuNXogTTE4LjUsMTIuNWMtMC42LDAtMS0wLjQtMS0xYzAtMC42LDAuNC0xLDEtMXMxLDAuNCwxLDFDMTkuNSwxMi4xLDE5LjEsMTIuNSwxOC41LDEyLjV6IE02LjksMy44TDEsMTguOWgxLjVsMS44LTQuN2g2LjlsMS43LDQuN2gxLjVMOC42LDMuOEg2Ljl6IE00LjcsMTIuOWwzLTcuOWwzLDcuOUg0Ljd6XCIvPjwvZz48L3N2Zz4nKTtcbiAgLy99XG4gIC8vJi5pY29uLXRleHQtY29sb3Ige1xuICAvLyAgd2lkdGg6IDIycHg7XG4gIC8vICBoZWlnaHQ6IDIycHg7XG4gIC8vICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk04LjksMTJsMi4zLTYuM2wyLjIsNi4zSDguOXogTTQuNywxNy44aDJsMS42LTQuM2g1LjZsMS41LDQuM2gyLjFMMTIuMywzLjVoLTIuMkw0LjcsMTcuOHpcIi8+PC9nPjwvc3ZnPicpO1xuICAvL31cbiAgLy8mLmljb24tdGV4dC1zZWxlY3Rpb24ge1xuICAvLyAgd2lkdGg6IDIycHg7XG4gIC8vICBoZWlnaHQ6IDIycHg7XG4gIC8vICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk03LjYsMTAuM2MwLjIsMC4zLDAuNCwwLjQsMC41LDAuNWMwLjMsMC4yLDAuNiwwLjMsMSwwLjNjMC43LDAsMS4zLTAuMywxLjctMC44YzAuNC0wLjUsMC42LTEuMiwwLjYtMi4xYzAtMC45LTAuMi0xLjUtMC42LTJjLTAuNC0wLjQtMC45LTAuNy0xLjYtMC43Yy0wLjMsMC0wLjYsMC4xLTAuOSwwLjJDOCw2LDcuOCw2LjIsNy42LDYuNFYzLjhINi44VjExaDAuOFYxMC4zeiBNOCw2LjljMC4zLTAuMywwLjctMC40LDEuMS0wLjRjMC41LDAsMC44LDAuMiwxLDAuNWMwLjIsMC40LDAuNCwwLjgsMC40LDEuNGMwLDAuNi0wLjEsMS4xLTAuNCwxLjVjLTAuMiwwLjQtMC42LDAuNi0xLjEsMC42Yy0wLjYsMC0xLjEtMC4zLTEuMy0wLjlDNy42LDkuMiw3LjYsOC44LDcuNiw4LjNDNy42LDcuNyw3LjcsNy4yLDgsNi45eiBNNS43LDEwLjRjLTAuMSwwLTAuMiwwLTAuMi0wLjFjMC0wLjEtMC4xLTAuMS0wLjEtMC4ydi0zYzAtMC41LTAuMi0wLjktMC42LTEuMUM0LjQsNS44LDQsNS42LDMuMyw1LjZjLTAuNSwwLTEsMC4xLTEuNCwwLjRDMS41LDYuMywxLjMsNi43LDEuMyw3LjRoMC44YzAtMC4zLDAuMS0wLjUsMC4yLTAuNmMwLjItMC4yLDAuNS0wLjQsMS0wLjRjMC40LDAsMC43LDAuMSwwLjksMC4yYzAuMiwwLjEsMC4zLDAuNCwwLjMsMC43YzAsMC4xLDAsMC4zLTAuMSwwLjNDNC40LDcuNyw0LjMsNy44LDQuMSw3LjhMMi43LDhDMi4yLDguMSwxLjgsOC4yLDEuNSw4LjVDMS4yLDguOCwxLDkuMSwxLDkuNmMwLDAuNCwwLjIsMC44LDAuNSwxLjFjMC4zLDAuMywwLjcsMC40LDEuMiwwLjRjMC40LDAsMC44LTAuMSwxLjEtMC4zYzAuMy0wLjIsMC42LTAuNCwwLjgtMC42YzAsMC4yLDAuMSwwLjQsMC4yLDAuNWMwLjEsMC4yLDAuNCwwLjMsMC43LDAuM2MwLjEsMCwwLjIsMCwwLjMsMGMwLjEsMCwwLjIsMCwwLjMtMC4xdi0wLjZjLTAuMSwwLTAuMSwwLTAuMiwwQzUuOCwxMC40LDUuNywxMC40LDUuNywxMC40eiBNNC41LDkuMWMwLDAuNS0wLjIsMC45LTAuNywxLjJjLTAuMywwLjEtMC42LDAuMi0wLjksMC4yYy0wLjMsMC0wLjUtMC4xLTAuNy0wLjJDMiwxMC4xLDIsOS45LDIsOS42QzIsOS4zLDIuMSw5LDIuNCw4LjljMC4yLTAuMSwwLjQtMC4yLDAuNy0wLjJsMC41LTAuMWMwLjIsMCwwLjMtMC4xLDAuNS0wLjFjMC4yLDAsMC4zLTAuMSwwLjQtMC4yVjkuMXogTTE4LjUsNUw4LjMsMTUuM2wtMC41LDJjLTAuNiwwLjQtMS4zLDAuMy0xLjUsMC42Yy0wLjMsMC40LDAuOSwwLjQsMS41LDAuM2MwLjQsMCwwLjUsMCwwLjUtMC4ybDIuMi0wLjZMMjAuNyw3LjFMMTguNSw1eiBNOSwxNS4zbDkuNS05LjVMMjAsNy4xbC05LjUsOS41TDksMTUuM3pcIi8+PC9nPjwvc3ZnPicpO1xuICAvL31cbiAgLy8mLmljb24tYnVsbGV0cyB7XG4gIC8vICB3aWR0aDogMjJweDtcbiAgLy8gIGhlaWdodDogMjJweDtcbiAgLy8gIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTcsNHYxaDE1VjRIN3ogTTEsNmgzVjNIMVY2eiBNNywxMmgxNXYtMUg3VjEyeiBNMSwxM2gzdi0zSDFWMTN6IE03LDE5aDE1di0xSDdWMTl6IE0xLDIwaDN2LTNIMVYyMHpcIi8+PC9nPjwvc3ZnPicpO1xuICAvL31cbiAgLy8mLmljb24tbnVtYmVycyB7XG4gIC8vICB3aWR0aDogMjJweDtcbiAgLy8gIGhlaWdodDogMjJweDtcbiAgLy8gIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTcsMy44djFoMTV2LTFIN3ogTTcsMTEuOGgxNXYtMUg3VjExLjh6IE03LDE4LjhoMTV2LTFIN1YxOC44eiBNMy4xLDYuOWgwLjdWMkgzLjNDMy4yLDIuNCwzLjEsMi42LDIuOSwyLjdDMi43LDIuOCwyLjQsMi45LDIsMi45djAuNWgxLjJWNi45eiBNMy4zLDlDMi42LDksMi4xLDkuMiwxLjksOS43Yy0wLjIsMC4zLTAuMiwwLjYtMC4yLDFoMC42YzAtMC4zLDAuMS0wLjUsMC4xLTAuN2MwLjItMC4zLDAuNS0wLjUsMC45LTAuNWMwLjMsMCwwLjUsMC4xLDAuNywwLjNzMC4zLDAuNCwwLjMsMC43YzAsMC4yLTAuMSwwLjUtMC4zLDAuN2MtMC4xLDAuMS0wLjMsMC4zLTAuNiwwLjRsLTAuNywwLjRjLTAuNCwwLjMtMC43LDAuNS0wLjksMC45Yy0wLjIsMC4zLTAuMiwwLjctMC4zLDEuMWgzLjR2LTAuNkgyLjJjMC4xLTAuMiwwLjItMC41LDAuNC0wLjdjMC4xLTAuMSwwLjMtMC4yLDAuNS0wLjRMMy42LDEyYzAuNC0wLjIsMC43LTAuNCwwLjktMC42YzAuMy0wLjMsMC40LTAuNiwwLjQtMWMwLTAuNC0wLjEtMC43LTAuNC0xQzQuMyw5LjEsMy45LDksMy4zLDl6IE00LjEsMTguM2MwLjItMC4xLDAuMy0wLjIsMC40LTAuM2MwLjItMC4yLDAuMi0wLjQsMC4yLTAuN2MwLTAuNC0wLjEtMC43LTAuNC0xQzQsMTYuMSwzLjYsMTYsMy4xLDE2Yy0wLjYsMC0xLjEsMC4yLTEuMywwLjdjLTAuMSwwLjMtMC4yLDAuNi0wLjIsMC45aDAuNmMwLTAuMywwLjEtMC41LDAuMS0wLjZjMC4yLTAuMywwLjQtMC40LDAuOS0wLjRjMC4yLDAsMC40LDAuMSwwLjYsMC4yQzQsMTYuOSw0LjEsMTcsNC4xLDE3LjNjMCwwLjMtMC4xLDAuNi0wLjQsMC43Yy0wLjEsMC4xLTAuMywwLjEtMC42LDAuMWMtMC4xLDAtMC4xLDAtMC4xLDBjMCwwLTAuMSwwLTAuMiwwdjAuNWMwLDAsMC4xLDAsMC4xLDBjMCwwLDAuMSwwLDAuMSwwYzAuNCwwLDAuNywwLjEsMC45LDAuMmMwLjIsMC4xLDAuMywwLjQsMC4zLDAuN2MwLDAuMy0wLjEsMC41LTAuMywwLjdjLTAuMiwwLjItMC41LDAuMy0wLjgsMC4zYy0wLjQsMC0wLjctMC4xLTAuOS0wLjRjLTAuMS0wLjEtMC4yLTAuNC0wLjItMC43SDEuNWMwLDAuNSwwLjEsMC44LDAuNCwxLjJDMi4xLDIwLjgsMi41LDIxLDMuMSwyMWMwLjYsMCwxLTAuMSwxLjMtMC40YzAuMy0wLjMsMC41LTAuNywwLjUtMS4xYzAtMC4zLTAuMS0wLjUtMC4yLTAuN0M0LjUsMTguNSw0LjMsMTguMyw0LjEsMTguM3pcIi8+PC9nPjwvc3ZnPicpO1xuICAvL31cbiAgLy8mLmljb24tbGluZXNwYWNpbmcge1xuICAvLyAgd2lkdGg6IDIycHg7XG4gIC8vICBoZWlnaHQ6IDIycHg7XG4gIC8vICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBvbHlnb24gaWQ9XCJYTUxJRF83X1wiIHBvaW50cz1cIjIyLDQgMjIsMyAxMiwzIDExLDMgMSwzIDEsNCAxMSw0IDExLDQuMyA4LDcuNCA4LjcsOC4xIDExLDUuNyAxMSwxNy4zIDguNywxNC45IDgsMTUuNiAxMSwxOC43IDExLDE5IDEsMTkgMSwyMCAxMSwyMCAxMiwyMCAyMiwyMCAyMiwxOSAxMiwxOSAxMiwxOC42IDE1LDE1LjYgMTQuMywxNC45IDEyLDE3LjIgMTIsNS44IDE0LjMsOC4xIDE1LDcuNCAxMiw0LjQgMTIsNCBcdFwiLz48L2c+PC9zdmc+Jyk7XG4gIC8vfVxuICAmLmljb24tdGV4dC1hbGlnbi1jZW50ZXIge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctbWFzaygnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xLDN2MWgyMVYzSDF6IE00LDd2MWgxNFY3SDR6IE0xLDEyaDIxdi0xSDFWMTJ6IE00LDE1djFoMTR2LTFINHogTTEsMjBoMjF2LTFIMVYyMHpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10ZXh0LWFsaWduLWphc3Qge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctbWFzaygnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xLDN2MWgyMVYzSDF6IE0xLDhoMjFWN0gxVjh6IE0xLDEyaDIxdi0xSDFWMTJ6IE0xLDE2aDIxdi0xSDFWMTZ6IE0xLDIwaDIxdi0xSDFWMjB6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGV4dC1hbGlnbi1sZWZ0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLW1hc2soJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMSwzdjFoMjFWM0gxeiBNMTUsN0gxdjFoMTRWN3ogTTEsMTJoMjF2LTFIMVYxMnogTTE1LDE1SDF2MWgxNFYxNXogTTEsMjBoMjF2LTFIMVYyMHpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10ZXh0LWFsaWduLXJpZ2h0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLW1hc2soJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMSwzdjFoMjFWM0gxeiBNOCw4aDE0VjdIOFY4eiBNMjIsMTFIMXYxaDIxVjExeiBNOCwxNmgxNHYtMUg4VjE2eiBNMjIsMTlIMXYxaDIxVjE5elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLWRlLWluZGVudCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1tYXNrKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTEsMjB2LTFoMjF2MUgxeiBNMTEsMTVoMTF2MUgxMVYxNXogTTExLDExaDExdjFIMTFWMTF6IE0xMSw3aDExdjFIMTFWN3ogTTYuMyw3TDcsNy43bC0zLjgsMy44TDcsMTUuM0w2LjMsMTZMMiwxMS44bC0wLjItMC4zTDIsMTEuMkw2LjMsN3ogTTEsM2gyMXYxSDFWM3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1pbi1pbmRlbnQge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctbWFzaygnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xLDIwdi0xaDIxdjFIMXogTTEyLDE2SDF2LTFoMTFWMTZ6IE0xMiwxMkgxdi0xaDExVjEyeiBNMTIsOEgxVjdoMTFWOHogTTIxLDExLjJsMC4yLDAuM0wyMSwxMS44TDE2LjcsMTZMMTYsMTUuM2wzLjgtMy44TDE2LDcuN0wxNi43LDdMMjEsMTEuMnogTTIyLDRIMVYzaDIxVjR6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGFibGUtYWRkLWNvbHVtbi1sZWZ0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMTUsMTloLTFIOEg3di0xdi0zSDBWMmg3aDFoMTR2NHYxdjN2MXYzdjF2M3YxSDE1eiBNMTUsMThoNnYtM2gtNlYxOHogTTE1LDE0aDZ2LTNoLTZWMTR6IE04LDE4aDZ2LTNIOFYxOHogTTgsMTRoNnYtM0g4VjE0eiBNMTQsMTBWN0g4djNIMTR6IE04LDN2M2g2VjNIOHogTTIxLDNoLTZ2M2g2VjN6IE0xNSw3djNoNlY3SDE1eiBNMywxNmgxdjJoMnYxSDR2Mkgzdi0ySDF2LTFoMlYxNnpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1hZGQtY29sdW1uLXJpZ2h0IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMCwxOWwwLTFsMC0zbDAtMWwwLTNsMC0xbDAtM2wwLTFsMC00aDE0aDFoN3YxM2gtN3YzdjFoLTFIOEg3SDB6IE03LDE1SDF2M2g2VjE1eiBNNywxMUgxdjNoNlYxMXogTTE0LDE1SDh2M2g2VjE1eiBNMTQsMTFIOHYzaDZWMTF6IE0xNCwxMFY3SDh2M0gxNHogTTgsM3YzaDZWM0g4eiBNMSw2aDZWM0gxVjZ6IE0xLDd2M2g2VjdIMXogTTE5LDE4aDJ2MWgtMnYyaC0xdi0yaC0ydi0xaDJ2LTJoMVYxOHpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1hZGQtcm93LWFib3ZlIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMjEsMjBoLTZoLTFIOEg3SDB2LTF2LTN2LTF2LTN2LTFWOFY3VjFoMTV2Nmg2aDF2MXYzdjF2M3YxdjN2MUgyMXogTTcsOEgxdjNoNlY4eiBNNywxMkgxdjNoNlYxMnogTTcsMTZIMXYzaDZWMTZ6IE04LDE5aDZ2LTNIOFYxOXogTTgsMTVoNnYtM0g4VjE1eiBNOCwxMWg2VjhIOFYxMXogTTIxLDhoLTZ2M2g2Vjh6IE0yMSwxMmgtNnYzaDZWMTJ6IE0yMSwxNmgtNnYzaDZWMTZ6IE0xOSw2aC0xVjRoLTJWM2gyVjFoMXYyaDJ2MWgtMlY2elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWFkZC1yb3ctYmVsb3cge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0yMiwxdjF2M3YxdjN2MXYzdjFoLTFoLTZ2Nkgwdi02di0xdi0zVjlWNlY1VjJWMWg3aDFoNmgxaDZIMjJ6IE03LDEwSDF2M2g2VjEweiBNNyw2SDF2M2g2VjZ6IE03LDJIMXYzaDZWMnogTTgsNWg2VjJIOFY1eiBNOCw5aDZWNkg4Vjl6IE04LDEzaDZ2LTNIOFYxM3ogTTIxLDEwaC02djNoNlYxMHogTTIxLDZoLTZ2M2g2VjZ6IE0yMSwyaC02djNoNlYyeiBNMTksMTdoMnYxaC0ydjJoLTF2LTJoLTJ2LTFoMnYtMmgxVjE3elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLXJlbW92ZS1jb2x1bW4ge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0yMSwxOWgtNmgtMWgtMS42Yy0wLjksMS44LTIuNywzLTQuOSwzcy00LTEuMi00LjktM0gxSDB2LTF2LTN2LTF2LTN2LTFWN1Y2VjNWMmg3aDFoNmgxaDZoMXYxdjN2MXYzdjF2M3YxdjN2MUgyMXogTTcuNSwxMkM1LDEyLDMsMTQsMywxNi41UzUsMjEsNy41LDIxczQuNS0yLDQuNS00LjVTMTAsMTIsNy41LDEyeiBNMTQsM0g4djNoNlYzeiBNMTQsN0g4djNoNlY3eiBNMTQsMTFIOHYwLjFjMS45LDAuMiwzLjUsMS4zLDQuNCwyLjlIMTRWMTF6IE0xNCwxNWgtMS4yYzAuMSwwLjUsMC4yLDEsMC4yLDEuNWMwLDAuNS0wLjEsMS0wLjIsMS41SDE0VjE1eiBNMjEsM2gtNnYzaDZWM3ogTTIxLDdoLTZ2M2g2Vjd6IE0yMSwxMWgtNnYzaDZWMTF6IE0yMSwxNWgtNnYzaDZWMTV6IE05LjYsMTkuM2wtMi4xLTIuMWwtMi4xLDIuMWwtMC43LTAuN2wyLjEtMi4xbC0yLjEtMi4xbDAuNy0wLjdsMi4xLDIuMWwyLjEtMi4xbDAuNywwLjdsLTIuMSwyLjFsMi4xLDIuMUw5LjYsMTkuM3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1yZW1vdmUtcm93IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMjEsMTloLTZoLTFoLTEuNmMtMC45LDEuOC0yLjcsMy00LjksM3MtNC0xLjItNC45LTNIMUgwdi0xdi0zdi0xdi0zdi0xVjdWNlYzVjJoN2gxaDZoMWg2aDF2MXYzdjF2M3YxdjN2MXYzdjFIMjF6IE0xLDE4aDEuMkMyLjEsMTcuNSwyLDE3LDIsMTYuNWMwLTAuNSwwLjEtMSwwLjItMS41SDFWMTh6IE03LDNIMXYzaDZWM3ogTTcsN0gxdjNoNlY3eiBNNy41LDEyQzUsMTIsMywxNCwzLDE2LjVTNSwyMSw3LjUsMjFzNC41LTIsNC41LTQuNVMxMCwxMiw3LjUsMTJ6IE0xNCwzSDh2M2g2VjN6IE0xNCw3SDh2M2g2Vjd6IE0xNCwxNWgtMS4yYzAuMSwwLjUsMC4yLDEsMC4yLDEuNWMwLDAuNS0wLjEsMS0wLjIsMS41SDE0VjE1eiBNMjEsM2gtNnYzaDZWM3ogTTIxLDdoLTZ2M2g2Vjd6IE0yMSwxNWgtNnYzaDZWMTV6IE05LjYsMTkuM2wtMi4xLTIuMWwtMi4xLDIuMWwtMC43LTAuN2wyLjEtMi4xbC0yLjEtMi4xbDAuNy0wLjdsMi4xLDIuMWwyLjEtMi4xbDAuNywwLjdsLTIuMSwyLjFsMi4xLDIuMUw5LjYsMTkuM3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1wYWdlYnJlYWsge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk04LDE0djFoMXYtMUg4eiBNNiwxNHYxaDF2LTFINnogTTE4LDIxSDN2LTZIMnY3aDE3di03aC0xVjIxeiBNNCwxNHYxaDF2LTFINHogTTE0LDE0djFoMXYtMUgxNHogTTEwLDE0djFoMXYtMUgxMHogTTguMiwxTDIsNy42VjE0aDFWOWg2VjJsMCwwaDl2MTJoMVYxSDguMnogTTgsOEgzLjFMOCwyLjhWOHogTTEyLDE0djFoMXYtMUgxMnogTTE2LDE0djFoMXYtMUgxNnpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1zZWN0aW9uYnJlYWsge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0yMCwxNFYySDN2MTJIMlYxaDE5djEzSDIweiBNNSwxNHYxSDR2LTFINXogTTcsMTR2MUg2di0xSDd6IE05LDE0djFIOHYtMUg5eiBNMTEsMTR2MWgtMXYtMUgxMXogTTEzLDE0djFoLTF2LTFIMTN6IE0xNSwxNHYxaC0xdi0xSDE1eiBNMTcsMTR2MWgtMXYtMUgxN3ogTTE4LDE0aDF2MWgtMVYxNHogTTMsMjFoMTd2LTZoMXY3SDJ2LTdoMVYyMXpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1zdHJpbmdicmVhayB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTE4LDEySDUuMUw5LDE1LjlsLTAuNywwLjdsLTQuNS00LjVsLTAuNi0wLjZsMC42LTAuNmw0LjUtNC41TDksNy4xTDUuMSwxMUgxOFY1aDF2NnYxSDE4elwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXBhZ2VudW1iZXIge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggZD1cIk04LjIsMUwyLDcuNlYyMmgxN1YxSDguMnogTTgsMi44VjhIMy4xTDgsMi44eiBNMTgsMjFIM1Y5aDZWMmwwLDBoOVYyMXogTTEyLDE5aDF2LTRoLTAuN2MwLDAuMi0wLjEtMC4xLTAuMSwwYy0wLjEsMC4xLTAuMiwwLTAuMywwYy0wLjEsMC4xLTAuMiwwLjEtMC40LDAuMWMtMC4xLDAtMC4zLDAtMC40LDBWMTZIMTJWMTl6IE0xNS4zLDE3LjNDMTUsMTcuOSwxNS4xLDE4LjQsMTUsMTloMC45YzAtMC4zLDAtMC42LDAuMS0wLjljMC4xLTAuMywwLjEtMC42LDAuMy0wLjljMC4xLTAuMywwLjMtMC42LDAuNC0wLjljMC4yLTAuMywwLjEtMC4zLDAuMy0wLjVWMTVoLTN2MWgxLjlDMTUuNiwxNi40LDE1LjUsMTYuNywxNS4zLDE3LjN6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tbGluayB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTEyLjQsOS44YzAsMC0yLjEtMC4xLTMuOCwxLjJjLTIuOCwyLTMuMyw0LjMtMy4zLDQuM3MxLjYtMS43LDMuNS0yLjVjMS43LTAuNywzLjctMC40LDMuNy0wLjR2MS45bDQuOC0zLjNWMTFsLTQuOC0zLjNWOS44eiBNMTEsMUM1LjUsMSwxLDUuNSwxLDExYzAsNS41LDQuNSwxMCwxMCwxMHMxMC00LjUsMTAtMTBDMjEsNS41LDE2LjUsMSwxMSwxeiBNMTEsMjBjLTUsMC05LTQuMS05LTlDMiw2LDYsMiwxMSwyczksNC4xLDksOUMyMCwxNiwxNiwyMCwxMSwyMHpcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1pbWFnZS1saWJyYXJ5IHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIj48ZGVmcz48c3R5bGU+LmNscy0xe2lzb2xhdGlvbjppc29sYXRlO30uY2xzLTJ7b3BhY2l0eTowLjI7fS5jbHMtM3tmaWxsOiNmZmY7fS5jbHMtMTAsLmNscy0xMSwuY2xzLTQsLmNscy02LC5jbHMtNywuY2xzLTgsLmNscy05e21peC1ibGVuZC1tb2RlOm11bHRpcGx5O30uY2xzLTR7ZmlsbDp1cmwoI2dyYWRfOCk7fS5jbHMtNXtmaWxsOnVybCgjZ3JhZF8xMCk7fS5jbHMtNntmaWxsOnVybCgjZ3JhZF8xMik7fS5jbHMtN3tmaWxsOnVybCgjZ3JhZF8xNCk7fS5jbHMtOHtmaWxsOnVybCgjZ3JhZF83OSk7fS5jbHMtOXtmaWxsOnVybCgjZ3JhZF83Nyk7fS5jbHMtMTB7ZmlsbDp1cmwoI2dyYWRfNzUpO30uY2xzLTExe2ZpbGw6dXJsKCNncmFkXzgxKTt9PC9zdHlsZT48bGluZWFyR3JhZGllbnQgaWQ9XCJncmFkXzhcIiB4MT1cIjExLjA4XCIgeTE9XCIxMC4yNlwiIHgyPVwiMTEuMDhcIiB5Mj1cIjEuMjZcIiBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIj48c3RvcCBvZmZzZXQ9XCIwXCIgc3RvcC1jb2xvcj1cIiNmM2U5MTZcIi8+PHN0b3Agb2Zmc2V0PVwiMVwiIHN0b3AtY29sb3I9XCIjZjg5ZDM0XCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPVwiZ3JhZF8xMFwiIHgxPVwiMTEuMDhcIiB5MT1cIjIwLjQ0XCIgeDI9XCIxMS4wOFwiIHkyPVwiMTEuODhcIiBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIj48c3RvcCBvZmZzZXQ9XCIwXCIgc3RvcC1jb2xvcj1cIiM1ZWI2ZThcIi8+PHN0b3Agb2Zmc2V0PVwiMVwiIHN0b3AtY29sb3I9XCIjOTU4Y2MzXCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPVwiZ3JhZF8xMlwiIHgxPVwiMS40NlwiIHkxPVwiMTEuMDVcIiB4Mj1cIjEwLjQ2XCIgeTI9XCIxMS4wNVwiIGdyYWRpZW50VHJhbnNmb3JtPVwidHJhbnNsYXRlKDE3IDUuMDkpIHJvdGF0ZSg5MClcIiBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIj48c3RvcCBvZmZzZXQ9XCIwXCIgc3RvcC1jb2xvcj1cIiNjYzhkYmFcIi8+PHN0b3Agb2Zmc2V0PVwiMVwiIHN0b3AtY29sb3I9XCIjZjg2ODY3XCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPVwiZ3JhZF8xNFwiIHgxPVwiMTEuNzNcIiB5MT1cIjExLjA1XCIgeDI9XCIyMC43M1wiIHkyPVwiMTEuMDVcIiBncmFkaWVudFRyYW5zZm9ybT1cInRyYW5zbGF0ZSgyNy4yOCAtNS4xOCkgcm90YXRlKDkwKVwiIGdyYWRpZW50VW5pdHM9XCJ1c2VyU3BhY2VPblVzZVwiPjxzdG9wIG9mZnNldD1cIjBcIiBzdG9wLWNvbG9yPVwiIzZhYzA3ZlwiLz48c3RvcCBvZmZzZXQ9XCIxXCIgc3RvcC1jb2xvcj1cIiNjNWRhM2RcIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9XCJncmFkXzc5XCIgeDE9XCIxMS43NFwiIHkxPVwiMTAuNDJcIiB4Mj1cIjE3LjUyXCIgeTI9XCI0LjYzXCIgZ3JhZGllbnRUcmFuc2Zvcm09XCJ0cmFuc2xhdGUoMzAuMjkgMi41MSkgcm90YXRlKDEzNSlcIiBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIj48c3RvcCBvZmZzZXQ9XCIwXCIgc3RvcC1jb2xvcj1cIiNjNWRhM2RcIi8+PHN0b3Agb2Zmc2V0PVwiMVwiIHN0b3AtY29sb3I9XCIjZjNlOTE2XCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPVwiZ3JhZF83N1wiIHgxPVwiNC43XCIgeTE9XCIxNy40OVwiIHgyPVwiMTAuNDhcIiB5Mj1cIjExLjcxXCIgZ3JhZGllbnRUcmFuc2Zvcm09XCJ0cmFuc2xhdGUoMjMuMjQgMTkuNjUpIHJvdGF0ZSgxMzUpXCIgZ3JhZGllbnRVbml0cz1cInVzZXJTcGFjZU9uVXNlXCI+PHN0b3Agb2Zmc2V0PVwiMFwiIHN0b3AtY29sb3I9XCIjOTU5NWMzXCIvPjxzdG9wIG9mZnNldD1cIjFcIiBzdG9wLWNvbG9yPVwiI2NjOGRiYVwiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD1cImdyYWRfNzVcIiB4MT1cIjQuNjlcIiB5MT1cIjQuNjRcIiB4Mj1cIjEwLjQ3XCIgeTI9XCIxMC40MlwiIGdyYWRpZW50VHJhbnNmb3JtPVwidHJhbnNsYXRlKDcuNTQgLTMuMTUpIHJvdGF0ZSg0NSlcIiBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIj48c3RvcCBvZmZzZXQ9XCIwXCIgc3RvcC1jb2xvcj1cIiNmODY4NjdcIi8+PHN0b3Agb2Zmc2V0PVwiMVwiIHN0b3AtY29sb3I9XCIjZjg5ZDM0XCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPVwiZ3JhZF84MVwiIHgxPVwiMTEuNzdcIiB5MT1cIjExLjc4XCIgeDI9XCIxNy41NVwiIHkyPVwiMTcuNTZcIiBncmFkaWVudFRyYW5zZm9ybT1cInRyYW5zbGF0ZSgxNC42MyAtNi4wNSkgcm90YXRlKDQ1KVwiIGdyYWRpZW50VW5pdHM9XCJ1c2VyU3BhY2VPblVzZVwiPjxzdG9wIG9mZnNldD1cIjBcIiBzdG9wLWNvbG9yPVwiIzVlYzBlOFwiLz48c3RvcCBvZmZzZXQ9XCIxXCIgc3RvcC1jb2xvcj1cIiM2YWMwN2ZcIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHRpdGxlPmljb25zX2Zvcl9zdmc8L3RpdGxlPjxnIGNsYXNzPVwiY2xzLTFcIj48ZyBpZD1cItCh0LvQvtC5XzFcIiBkYXRhLW5hbWU9XCLQodC70L7QuSAxXCI+PHJlY3QgY2xhc3M9XCJjbHMtMlwiIHg9XCIwLjA5XCIgeT1cIjAuMDFcIiB3aWR0aD1cIjIyXCIgaGVpZ2h0PVwiMjJcIiByeD1cIjRcIiByeT1cIjRcIi8+PHJlY3QgY2xhc3M9XCJjbHMtM1wiIHg9XCIwLjU3XCIgeT1cIjAuNDlcIiB3aWR0aD1cIjIxLjA0XCIgaGVpZ2h0PVwiMjEuMDRcIiByeD1cIjMuNlwiIHJ5PVwiMy42XCIvPjxyZWN0IGNsYXNzPVwiY2xzLTRcIiB4PVwiOC4zM1wiIHk9XCIxLjI2XCIgd2lkdGg9XCI1LjVcIiBoZWlnaHQ9XCI5XCIgcng9XCIyLjVcIiByeT1cIjIuNVwiLz48cmVjdCBjbGFzcz1cImNscy01XCIgeD1cIjguMzNcIiB5PVwiMTEuNzZcIiB3aWR0aD1cIjUuNVwiIGhlaWdodD1cIjlcIiByeD1cIjIuNVwiIHJ5PVwiMi41XCIvPjxyZWN0IGNsYXNzPVwiY2xzLTZcIiB4PVwiMy4yMVwiIHk9XCI2LjU1XCIgd2lkdGg9XCI1LjVcIiBoZWlnaHQ9XCI5XCIgcng9XCIyLjVcIiByeT1cIjIuNVwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtNS4wOSAxNykgcm90YXRlKC05MClcIi8+PHJlY3QgY2xhc3M9XCJjbHMtN1wiIHg9XCIxMy40OFwiIHk9XCI2LjU1XCIgd2lkdGg9XCI1LjVcIiBoZWlnaHQ9XCI5XCIgcng9XCIyLjVcIiByeT1cIjIuNVwiIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSg1LjE4IDI3LjI4KSByb3RhdGUoLTkwKVwiLz48cmVjdCBjbGFzcz1cImNscy04XCIgeD1cIjExLjg3XCIgeT1cIjMuMDNcIiB3aWR0aD1cIjUuNVwiIGhlaWdodD1cIjlcIiByeD1cIjIuNVwiIHJ5PVwiMi41XCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKDE5LjY0IDIzLjE5KSByb3RhdGUoLTEzNSlcIi8+PHJlY3QgY2xhc3M9XCJjbHMtOVwiIHg9XCI0LjhcIiB5PVwiMTAuMTRcIiB3aWR0aD1cIjUuNVwiIGhlaWdodD1cIjlcIiByeD1cIjIuNVwiIHJ5PVwiMi41XCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKDIuNTQgMzAuMzMpIHJvdGF0ZSgtMTM1KVwiLz48cmVjdCBjbGFzcz1cImNscy0xMFwiIHg9XCI0LjgzXCIgeT1cIjMuMDNcIiB3aWR0aD1cIjUuNVwiIGhlaWdodD1cIjlcIiByeD1cIjIuNVwiIHJ5PVwiMi41XCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC0zLjEgNy41Nikgcm90YXRlKC00NSlcIi8+PHJlY3QgY2xhc3M9XCJjbHMtMTFcIiB4PVwiMTEuODdcIiB5PVwiMTAuMTRcIiB3aWR0aD1cIjUuNVwiIGhlaWdodD1cIjlcIiByeD1cIjIuNVwiIHJ5PVwiMi41XCIgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC02LjA3IDE0LjYzKSByb3RhdGUoLTQ1KVwiLz48L2c+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgJi5pY29uLXRleHQtdmFsaWduLXRvcCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1tYXNrKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cmVjdCBjbGFzcz1cImNscy0xXCIgeD1cIjJcIiB5PVwiMlwiIHdpZHRoPVwiMTlcIiBoZWlnaHQ9XCIxXCIvPjxyZWN0IGNsYXNzPVwiY2xzLTFcIiB4PVwiMlwiIHk9XCI0XCIgd2lkdGg9XCIxOVwiIGhlaWdodD1cIjFcIi8+PHBvbHlnb24gY2xhc3M9XCJjbHMtMVwiIHBvaW50cz1cIjEyIDE4IDExIDE4IDExIDcuODMgOC42NSA5LjggOCA4Ljk0IDExLjUgNiAxNSA5IDE0LjM1IDkuOCAxMiA3LjgzIDEyIDE4XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGV4dC12YWxpZ24tbWlkZGxlIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLW1hc2soJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxyZWN0IGNsYXNzPVwiY2xzLTFcIiB4PVwiMlwiIHk9XCIxMFwiIHdpZHRoPVwiMTlcIiBoZWlnaHQ9XCIxXCIvPjxyZWN0IGNsYXNzPVwiY2xzLTFcIiB4PVwiMlwiIHk9XCIxMlwiIHdpZHRoPVwiMTlcIiBoZWlnaHQ9XCIxXCIvPjxwb2x5Z29uIGNsYXNzPVwiY2xzLTFcIiBwb2ludHM9XCIxMSAyIDEyIDIgMTIgNy4xNyAxNC4zNSA1LjIgMTUgNi4wNiAxMS41IDkgOCA2IDguNjUgNS4yIDExIDcuMTcgMTEgMlwiLz48cG9seWdvbiBjbGFzcz1cImNscy0xXCIgcG9pbnRzPVwiMTIgMjEgMTEgMjEgMTEgMTUuODMgOC42NSAxNy44IDggMTYuOTQgMTEuNSAxNCAxNSAxNyAxNC4zNSAxNy44IDEyIDE1LjgzIDEyIDIxXCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGV4dC12YWxpZ24tYm90dG9tIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLW1hc2soJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxyZWN0IGNsYXNzPVwiY2xzLTFcIiB4PVwiMlwiIHk9XCIxOFwiIHdpZHRoPVwiMTlcIiBoZWlnaHQ9XCIxXCIvPjxyZWN0IGNsYXNzPVwiY2xzLTFcIiB4PVwiMlwiIHk9XCIyMFwiIHdpZHRoPVwiMTlcIiBoZWlnaHQ9XCIxXCIvPjxwb2x5Z29uIGNsYXNzPVwiY2xzLTFcIiBwb2ludHM9XCIxMSA0IDEyIDQgMTIgMTUuMTcgMTQuMzUgMTMuMiAxNSAxNC4wNiAxMS41IDE3IDggMTQgOC42NSAxMy4yIDExIDE1LjE3IDExIDRcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgLy8gUHJlc2V0cyBvZiB0YWJsZSBib3JkZXJzXG5cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtYWxsIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBkPVwiTTI2LjksMEgwVjI3SDI3VjBIMjYuOVpNMTMsMjZIMVYxNEgxM1YyNlptMC0xM0gxVjFIMTNWMTNaTTI2LDI2SDE0VjE0SDI2VjI2Wm0wLTEzSDE0VjFIMjZWMTNaXCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGFibGUtYm9yZGVycy1ub25lIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBvcGFjaXR5PVwiMC4zXCIgZD1cIk0yNi45LDBIMFYyN0gyN1YwSDI2LjlaTTEzLDI2SDFWMTRIMTNWMjZabTAtMTNIMVYxSDEzVjEzWk0yNiwyNkgxNFYxNEgyNlYyNlptMC0xM0gxNFYxSDI2VjEzWlwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtaW5uZXIge1xuICAgIHdpZHRoOiAyOHB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwb2x5Z29uIHBvaW50cz1cIjI2IDEzIDE0IDEzIDE0IDEgMTMgMSAxMyAxMyAxIDEzIDEgMTQgMTMgMTQgMTMgMjYgMTQgMjYgMTQgMTQgMjYgMTQgMjYgMTNcIi8+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMjcsMEgwVjI3SDI3VjBaTTEsMjZWMUgyNlYyNkgxWlwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtb3V0ZXIge1xuICAgIHdpZHRoOiAyOHB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMjcsMEgwVjI3SDI3VjBaTTEsMjZWMUgyNlYyNkgxWlwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtbGVmdCB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMjcsMEgwVjI3SDI3VjBaTTEsMjZWMUgyNlYyNkgxWlwiLz48cmVjdCB3aWR0aD1cIjFcIiBoZWlnaHQ9XCIyN1wiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtY2VudGVyIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBvcGFjaXR5PVwiMC4zXCIgZD1cIk0yNywwSDBWMjdIMjdWMFpNMSwyNlYxSDI2VjI2SDFaXCIvPjxyZWN0IHg9XCIxM1wiIHdpZHRoPVwiMVwiIGhlaWdodD1cIjI3XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGFibGUtYm9yZGVycy1yaWdodCB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMjcsMEgwVjI3SDI3VjBaTTEsMjZWMUgyNlYyNkgxWlwiLz48cmVjdCB4PVwiMjZcIiB3aWR0aD1cIjFcIiBoZWlnaHQ9XCIyN1wiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLXRhYmxlLWJvcmRlcnMtdG9wIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBvcGFjaXR5PVwiMC4zXCIgZD1cIk0yNywwSDBWMjdIMjdWMFpNMSwyNlYxSDI2VjI2SDFaXCIvPjxyZWN0IHdpZHRoPVwiMjdcIiBoZWlnaHQ9XCIxXCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tdGFibGUtYm9yZGVycy1taWRkbGUge1xuICAgIHdpZHRoOiAyOHB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxwYXRoIG9wYWNpdHk9XCIwLjNcIiBkPVwiTTI3LDBIMFYyN0gyN1YwWk0xLDI2VjFIMjZWMjZIMVpcIi8+PHJlY3QgeT1cIjEzXCIgd2lkdGg9XCIyN1wiIGhlaWdodD1cIjFcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi10YWJsZS1ib3JkZXJzLWJvdHRvbSB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMjcsMEgwVjI3SDI3VjBaTTEsMjZWMUgyNlYyNkgxWlwiLz48cmVjdCB5PVwiMjZcIiB3aWR0aD1cIjI3XCIgaGVpZ2h0PVwiMVwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cblxuICAvLyBSZW9yZGVyXG5cbiAgJi5pY29uLW1vdmUtYmFja3dhcmQge1xuICAgIHdpZHRoOiAyOHB4O1xuICAgIGhlaWdodDogMjhweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHZpZXdCb3g9XCIwIDAgMjggMjhcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxyZWN0IG9wYWNpdHk9XCIwLjNcIiB4PVwiMVwiIHk9XCIxXCIgd2lkdGg9XCIxN1wiIGhlaWdodD1cIjE3XCIvPjxwYXRoIGQ9XCJNMTAsMTBWMjdIMjdWMTBIMTBaTTI2LDI2SDExVjExSDI2VjI2WlwiLz48L2c+PC9zdmc+Jyk7XG4gIH1cbiAgJi5pY29uLW1vdmUtZm9yd2FyZCB7XG4gICAgd2lkdGg6IDI4cHg7XG4gICAgaGVpZ2h0OiAyOHB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmlld0JveD1cIjAgMCAyOCAyOFwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggb3BhY2l0eT1cIjAuM1wiIGQ9XCJNMTAsMTBWMjdIMjdWMTBIMTBaTTI2LDI2SDExVjExSDI2VjI2WlwiLz48cmVjdCB4PVwiMVwiIHk9XCIxXCIgd2lkdGg9XCIxN1wiIGhlaWdodD1cIjE3XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tbW92ZS1iYWNrZ3JvdW5kIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cmVjdCBvcGFjaXR5PVwiMC4zXCIgeD1cIjhcIiB5PVwiOFwiIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxM1wiLz48cGF0aCBkPVwiTTEsMVYxM0gxM1YxSDFaTTEyLDEySDJWMkgxMlYxMlpcIi8+PHBhdGggZD1cIk0xNSwxNVYyN0gyN1YxNUgxNVpNMjYsMjZIMTZWMTZIMjZWMjZaXCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxuICAmLmljb24tbW92ZS1mb3JlZ3JvdW5kIHtcbiAgICB3aWR0aDogMjhweDtcbiAgICBoZWlnaHQ6IDI4cHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2aWV3Qm94PVwiMCAwIDI4IDI4XCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBvcGFjaXR5PVwiMC4zXCIgZD1cIk0xLDFWMTNIMTNWMUgxWk0xMiwxMkgyVjJIMTJWMTJaXCIvPjxwYXRoIG9wYWNpdHk9XCIwLjNcIiBkPVwiTTE1LDE1VjI3SDI3VjE1SDE1Wk0yNiwyNkgxNlYxNkgyNlYyNlpcIi8+PHJlY3QgeD1cIjhcIiB5PVwiOFwiIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxM1wiLz48L2c+PC9zdmc+Jyk7XG4gIH1cblxuICAmLmljb24tYWxpZ24tbGVmdCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgc3R5bGU9XCJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDIyIDIyO1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48c3R5bGUgdHlwZT1cInRleHQvY3NzXCI+LnN0MHtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDt9PC9zdHlsZT48Zz48ZyBpZD1cIlhNTElEXzM1X1wiPjxwYXRoIGlkPVwiWE1MSURfMzZfXCIgY2xhc3M9XCJzdDBcIiBkPVwiTTEsMjFoMVYxSDFWMjF6IE00LDEzdjRoMTZ2LTRINHogTTEyLDVINHY0aDhWNXpcIi8+PC9nPjwvZz48L3N2Zz4nKTtcbiAgfVxuXG4gICYuaWNvbi1hbGlnbi1jZW50ZXIge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIHN0eWxlPVwiZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMiAyMjtcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PHN0eWxlIHR5cGU9XCJ0ZXh0L2Nzc1wiPi5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7fTwvc3R5bGU+PGcgaWQ9XCJYTUxJRF81X1wiPjxnIGlkPVwiWE1MSURfMjRfXCI+PHBvbHlnb24gaWQ9XCJYTUxJRF8yNV9cIiBjbGFzcz1cInN0MFwiIHBvaW50cz1cIjE5LDEzIDExLDEzIDExLDkgMTUsOSAxNSw1IDExLDUgMTEsMSAxMCwxIDEwLDUgNiw1IDYsOSAxMCw5IDEwLDEzIDIsMTMgMiwxNyAxMCwxNyAxMCwyMSAxMSwyMSAxMSwxNyAxOSwxNyBcdFx0XCIvPjwvZz48L2c+PC9zdmc+Jyk7XG4gIH1cblxuICAmLmljb24tYWxpZ24tcmlnaHQge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIHN0eWxlPVwiZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMiAyMjtcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PHN0eWxlIHR5cGU9XCJ0ZXh0L2Nzc1wiPi5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7fTwvc3R5bGU+PGcgaWQ9XCJYTUxJRF81X1wiPjxnIGlkPVwiWE1MSURfNDJfXCI+PHBhdGggaWQ9XCJYTUxJRF80NF9cIiBjbGFzcz1cInN0MFwiIGQ9XCJNMjAsMXYyMGgxVjFIMjB6IE0yLDE3aDE2di00SDJWMTd6IE0xMCw5aDhWNWgtOFY5elwiLz48L2c+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgJi5pY29uLWFsaWduLXRvcCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgc3R5bGU9XCJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDIyIDIyO1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48ZyBpZD1cIlhNTElEXzM1X1wiPjxwYXRoIGlkPVwiWE1MSURfMzZfXCIgZD1cIk0xLDF2MWgyMFYxSDF6IE05LDRINXYxNmg0VjR6IE0xNywxMlY0aC00djhIMTd6XCIvPjwvZz48L2c+PC9zdmc+Jyk7XG4gIH1cblxuICAmLmljb24tYWxpZ24tbWlkZGxlIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBzdHlsZT1cImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjIgMjI7XCIgeG1sOnNwYWNlPVwicHJlc2VydmVcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxzdHlsZSB0eXBlPVwidGV4dC9jc3NcIj4uc3Qwe2ZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO308L3N0eWxlPjxnIGlkPVwiWE1MSURfNV9cIj48ZyBpZD1cIlhNTElEXzI0X1wiPjxwb2x5Z29uIGlkPVwiWE1MSURfMjVfXCIgY2xhc3M9XCJzdDBcIiBwb2ludHM9XCIxMywyIDEzLDEwIDksMTAgOSw2IDUsNiA1LDEwIDEsMTAgMSwxMSA1LDExIDUsMTUgOSwxNSA5LDExIDEzLDExIDEzLDE5IDE3LDE5IDE3LDExIDIxLDExIDIxLDEwIDE3LDEwIDE3LDIgXHRcdFwiLz48L2c+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgJi5pY29uLWFsaWduLWJvdHRvbSB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgc3R5bGU9XCJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDIyIDIyO1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48ZyBpZD1cIlhNTElEXzM1X1wiPjxwYXRoIGlkPVwiWE1MSURfMzZfXCIgZD1cIk0yMSwyMHYtMUgxdjFIMjF6IE05LDFINXYxNmg0VjF6IE0xMyw5djhoNFY5SDEzelwiLz48L2c+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgJi5pY29uLWFsaWduLWhvcml6b250YWwge1xuICAgIHdpZHRoOiAyMnB4O1xuICAgIGhlaWdodDogMjJweDtcbiAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIHN0eWxlPVwiZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyMiAyMjtcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PGcgaWQ9XCJYTUxJRF8zNV9cIj48cGF0aCBpZD1cIlhNTElEXzM2X1wiIGQ9XCJNMSwxdjFoMjBWMUgxeiBNMC45OTk5OTksMTkuMDAwMDA3NlYyMGgyMHYtMC45OTk5OTI0SDAuOTk5OTk5eiBNOS4wMDAwMDEsMi45OTk5OTk1aC00djE1aDRWMi45OTk5OTk1eiBNMTcsMTMuOTk5OTk5VjYuOTk5OTk4NmgtMy45OTk5OTl2Ny4wMDAwMDA1SDE3elwiLz48L2c+PC9nPjwvc3ZnPicpO1xuICB9XG5cbiAgJi5pY29uLWFsaWduLXZlcnRpY2FsIHtcbiAgICB3aWR0aDogMjJweDtcbiAgICBoZWlnaHQ6IDIycHg7XG4gICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBzdHlsZT1cImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjIgMjI7XCIgeG1sOnNwYWNlPVwicHJlc2VydmVcIiBmaWxsPVwiQHt0aGVtZUNvbG9yfVwiPjxnPjxnIGlkPVwiWE1MSURfMzVfXCI+PHBhdGggaWQ9XCJYTUxJRF8zNl9cIiBkPVwiTTAuOTk5OTk5OCwyMWgxdi0yMGgtMVYyMXogTTE5LjAwMDAwNzYsMjFIMjB2LTIwaC0wLjk5OTk5MjRWMjF6IE0yLjk5OTk5OTUsMTIuOTk5OTk5djMuOTk5OTk5aDE1IHYtMy45OTk5OTlIMi45OTk5OTk1eiBNMTMuOTk5OTk5LDQuOTk5OTk5SDYuOTk5OTk4NnY0aDcuMDAwMDAwNVY0Ljk5OTk5OXpcIi8+PC9nPjwvZz48L3N2Zz4nKTtcbiAgfVxuXG4gIC8vIEZvcm1hdHNcblxuICAmLmljb24tZm9ybWF0LXBkZiB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgc3R5bGU9XCJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDIyIDIyO1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCIgZmlsbD1cIkB7dGhlbWVDb2xvcn1cIj48Zz48cGF0aCBpZD1cIlhNTElEXzJfXCIgZD1cIk0yLDIxaDE4VjRsLTMuOTc5MTY2LTRMMiwwVjIxeiBNMTksOHYxMkgzVjFoMTJsNCw0Vjh6XCIvPjwvZz48Zz48cGF0aCBkPVwiTTkuOTk5NjMyOCw3LjI5OTQxMjNMOS45OTk2MzI4LDcuMjk5NDEyM0MxMC4wOTg4MjQ1LDcuMjk5NDEyMywxMC4wOTg4MjQ1LDcuMjk5NDEyMyw5Ljk5OTYzMjgsNy4yOTk0MTIzXHRjMC4wOTkxOTE3LTAuNDAwNDQwNywwLjIwMDIyMDEtMC42MDA2NjE4LDAuMjAwMjIwMS0wLjkwMDA3MzVWNi4xOTkxMTgxYzAuMDk5MTkxNy0wLjQ5OTYzMjQsMC4wOTkxOTE3LTAuOTAwMDczNSwwLTAuOTk5MjY1MiBjMCwwLDAsMCwwLTAuMDk5MTkxN2wtMC4wOTkxOTE3LTAuMDk5MTkxN2wwLDBsMCwwYzAsMCwwLDAuMDk5MTkxNy0wLjA5OTE5MTcsMC4wOTkxOTE3IEM5Ljc5OTQxMTgsNS42OTk0ODU4LDkuNzk5NDExOCw2LjM5OTMzODcsOS45OTk2MzI4LDcuMjk5NDEyM0w5Ljk5OTYzMjgsNy4yOTk0MTIzeiBNNywxNC4yMDA1ODczXHRjLTAuMjAwMjIwMSwwLjA5OTE5MjYtMC40MDA0NDA3LDAuMjAwMjIxMS0wLjQ5OTYzMjgsMC4yOTk0MTE4Yy0wLjY5OTg1MjksMC42MDA2NjEzLTEuMTk5NDg1OCwxLjMwMDUxNDItMS4zMDA1MTQyLDEuNTk5OTI2OWwwLDAgbDAsMGwwLDBDNS43OTg2Nzc0LDE2LjAwMDczNDMsNi4zOTkzMzg3LDE1LjQwMDA3NCw3LDE0LjIwMDU4NzNDNy4wOTkxOTE3LDE0LjIwMDU4NzMsNy4wOTkxOTE3LDE0LjIwMDU4NzMsNywxNC4yMDA1ODczIEM3LjA5OTE5MTcsMTQuMjAwNTg3Myw3LDE0LjIwMDU4NzMsNywxNC4yMDA1ODczeiBNMTYuMTk5MTE5NiwxMi42OTk4NTM5XHRjLTAuMDk5MTkzNi0wLjA5OTE5MjYtMC40OTk2MzM4LTAuNDAwNDQxMi0xLjg5OTMzOTctMC40MDA0NDEyYy0wLjA5OTE5MjYsMC0wLjA5OTE5MjYsMC0wLjIwMDIyMTEsMGwwLDBjMCwwLDAsMCwwLDAuMDk5MTkyNiBjMC42OTk4NTI5LDAuMjk5NDExOCwxLjM5OTcwNTksMC40OTk2MzI4LDEuODk5MzM4NywwLjQ5OTYzMjhjMC4wOTkxOTE3LDAsMC4wOTkxOTE3LDAsMC4yMDAyMjIsMGwwLDBoMC4wOTkxOTE3IGMwLDAsMCwwLDAtMC4wOTkxOTI2bDAsMEMxNi4zMDAxNDgsMTIuNzk5MDQ0NiwxNi4xOTkxMTk2LDEyLjc5OTA0NDYsMTYuMTk5MTE5NiwxMi42OTk4NTM5eiBNMTYuNTk5NTU5OCwxMy40OTg4OTg1IGMtMC4yMDAyMjIsMC4wOTkxOTE3LTAuNDk5NjMzOCwwLjIwMDIyMTEtMC45MDAwNzQsMC4yMDAyMjExYy0wLjgwMDg4MTQsMC0yLjAwMDM2ODEtMC4yMDAyMjExLTIuOTk5NjMxOS0wLjY5OTg1MjkgYy0xLjcwMDk1NTQsMC4yMDAyMjExLTIuOTk5NjMyOCwwLjQwMDQ0MDItNC4wMDA3MzUzLDAuODAwODgxNGMtMC4wOTkxOTE3LDAtMC4wOTkxOTE3LDAtMC4yMDAyMjAxLDAuMDk5MTkxNyBDNy4yOTk0MTIzLDE2LjAwMDczNDMsNi4yOTgzMDk4LDE3LDUuNDk5MjY1MiwxN2MtMC4yMDAyMjA2LDAtMC4yOTk0MTIzLDAtMC40MDA0NDEyLTAuMDk5MTkxN2wtMC40OTk2MzI0LTAuMjk5NDExOFYxNi41MDIyMDNcdEM0LjUsMTYuMzAxOTgyOSw0LjUsMTYuMjAyNzkxMiw0LjUsMTYuMDAyNTcxMWMwLjA5OTE5MTctMC40OTk2MzI4LDAuNjk5ODUyOS0xLjM5OTcwNjgsMS44OTkzMzg3LTIuMDk5NTU5OCBjMC4yMDAyMjAxLTAuMDk5MTkxNywwLjQ5OTYzMjgtMC4yOTk0MTE4LDAuOTAwMDczNS0wLjQ5OTYzMjhjMC4yOTk0MTE4LTAuNDk5NjMyOCwwLjYwMDY2MTMtMS4xMDAyOTQxLDAuOTk5MjY1Mi0xLjgwMDE0NjEgYzAuNDk5NjMyOC0wLjk5OTI2NTcsMC44MDA4ODE0LTIuMDAwMzY4MSwxLjEwMDI5MzItMi45MDA0NDEybDAsMEM4Ljk5ODUzMDQsNy41MDMzMDU0LDguNzk4MzA5Myw2LjgwMzQ1MjUsOS4xOTg3NTA1LDUuNDAxOTA5NEM5LjI5Nzk0MjIsNS4wMDE0Njg3LDkuNTk5MTkxNyw0LjYwMTAyOCw5Ljk5OTYzMjgsNC42MDEwMjhoMC4yMDAyMjAxYzAuMjAwMjIwMSwwLDAuNDAwNDQwMiwwLjA5OTE5MTcsMC42MDA2NjEzLDAuMjAwMjIwNiBjMC42OTk4NTI5LDAuNjk5ODUyOSwwLjQwMDQ0MTIsMi4yOTk3Nzk0LDAsMy42MDAyOTQxYzAsMC4wOTkxOTE3LDAsMC4wOTkxOTE3LDAsMC4wOTkxOTE3IGMwLjQwMDQ0MTIsMS4xMDAyOTMyLDAuOTk5MjY1NywyLjAwMDM2NzIsMS41OTk5MjYsMi42MDEwMjg0YzAuMjk5NDExOCwwLjIwMDIyMTEsMC40OTk2MzI4LDAuNDAwNDQwMiwwLjkwMDA3NCwwLjYwMDY2MTMgYzAuNDk5NjMyOCwwLDAuOTAwMDczMS0wLjA5OTE5MTcsMS4zMDA1MTQyLTAuMDk5MTkxN2MxLjE5OTQ4NDgsMCwyLjAwMDM2ODEsMC4yMDAyMjAxLDIuMjk5Nzc5OSwwLjY5OTg1Mlx0QzE3LDEyLjUwMzMwNTQsMTcsMTIuNzAzNTI1NSwxNywxMi45MDM3NDU3QzE2LjkwMDgwODMsMTIuOTk5MjY1NywxNi43OTk3Nzk5LDEzLjMwMDUxNDIsMTYuNTk5NTU5OCwxMy40OTg4OTg1eiBNMTAuMDk4ODI0NSw5LjU5OTE5MTdDOS44OTg2MDM0LDEwLjI5OTA0NDYsOS40OTgxNjIzLDExLjA5OTkyNiw5LjA5OTU1ODgsMTIgYy0wLjIwMDIyMDEsMC40MDA0NDAyLTAuNDAwNDQwMiwwLjY5OTg1Mi0wLjYwMDY2MTMsMS4xMDAyOTQxaDAuMDk5MTkxN2gwLjA5OTE5MTdsMCwwIGMxLjMwMDUxNDItMC40OTk2MzI4LDIuNS0wLjgwMDg4MTQsMy4zMDA4ODE0LTAuOTAwMDczMUMxMS43OTc5NDEyLDEyLjEwMTAyODQsMTEuNjk4NzUwNSwxMiwxMS41OTc3MjIxLDExLjkwMDgwODMgQzExLjA5OTkyNiwxMS4zMDAxNDcxLDEwLjQ5OTI2NTcsMTAuNDk5MjY1NywxMC4wOTg4MjQ1LDkuNTk5MTkxN3pcIi8+PC9nPjwvc3ZnPicpO1xuICB9XG4gICYuaWNvbi1mb3JtYXQtcHB0eCB7XG4gICAgd2lkdGg6IDIycHg7XG4gICAgaGVpZ2h0OiAyMnB4O1xuICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiLTIzOCAyNDAgMjIgMjJcIiBzdHlsZT1cImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAtMjM4IDI0MCAyMiAyMjtcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiIGZpbGw9XCJAe3RoZW1lQ29sb3J9XCI+PGc+PHBhdGggaWQ9XCJYTUxJRF8yX1wiIGQ9XCJNLTIzNiwyNjFoMTh2LTE3bC0zLjk3OTE3MTgtNEgtMjM2VjI2MXogTS0yMTksMjQ4djEyaC0xNnYtMTloMTJsNCw0VjI0OHpcIi8+PC9nPjxnPjxwYXRoIGQ9XCJNLTIyOC44MjI2OTI5LDI1MC44NjQ2ODUxYzAuMTM3MDg1LTAuMDYwNzkxLDAuMjM0MTkxOS0wLjIzMDIyNDYsMC4zMTMxMTA0LTAuMzY0NzQ2MVx0YzAuMDc5Mjg0Ny0wLjEzNTE5MjksMC4wODYxODE2LTAuMjkzNTE4MSwwLjA4NjE4MTYtMC40NzM5MzhjMC0wLjIyMjEwNjktMC4wNjEzNDAzLTAuNDE4NjQwMS0wLjE3MjM2MzMtMC41NjAxODA3XHRjLTAuMTEwMjkwNS0wLjE0MDUwMjktMC4yOTY4NzUtMC4yNjI4Nzg0LTAuNDYyODkwNi0wLjI5MzE1MTljLTAuMTIxMDkzOC0wLjAyMzMxNTQtMC4yMzk2ODUxLTAuMDAxMjgxNy0wLjQ1MzU1MjIsMC4wMDkwOTQyIGwtMC4zMTE1MjM0LDAuMDEwMzc2djEuNzkyNTQxNWgwLjQ1MjM5MjZDLTIyOC45ODE1MDYzLDI1MC45OTI3MzY4LTIyOC45NTg2MTgyLDI1MC45MjQ5ODc4LTIyOC44MjI2OTI5LDI1MC44NjQ2ODUxelwiLz48cGF0aCBkPVwiTS0yMzMsMjU2LjExNDEzNTdsNy4zMzMzMTMsMS4zNTUzNDY3VjI0NUwtMjMzLDI0Ni4zMjY4NDMzVjI1Ni4xMTQxMzU3eiBNLTIzMC44NjYwODg5LDI0OC4yODE4NjA0bDEuNDk2ODg3Mi0wLjA5Nzc3ODMgYzAuNjA3Nzg4MS0wLjAzOTczMzksMC45MDc1MzE3LTAuMDU1NzI1MSwxLjEwMTgwNjYtMC4wMDcxNDExYzAuMzAzMjIyNywwLjA3MzYwODQsMC42MzcyMDcsMC4yMzQ5ODU0LDAuODQ4MzI3NiwwLjUzODE0N1x0YzAuMjEzODY3MiwwLjMwNzA2NzksMC4zNTU1OTA4LDAuNzU5MjE2MywwLjM1NTU5MDgsMS4yNjIwODVjMCwwLjM4Nzg3ODQtMC4wNjIzMTY5LDAuNzEzMDczNy0wLjE4NjI3OTMsMC45NzQxMjExXHRjLTAuMTIzMDQ2OSwwLjI1OTA5NDItMC4yNzgwMTUxLDAuNDU5MTA2NC0wLjQ2NDA1MDMsMC42MDAxNTg3Yy0wLjE4Mzk2LDAuMTM5NDY1My0wLjM5OTEwODksMC4yNzAwMTk1LTAuNTU4Nzc2OSwwLjMyNzI3MDUgYy0wLjMxNDU3NTIsMC4wNzc0NTM2LTAuNTI4Njg2NSwwLjE3NDc0MzctMC45ODAyODU2LDAuMTUwODE3OWgtMC41NzA4NjE4djEuOTU2MjM3OGwtMS4wNDIzNTg0LTAuMTA4MTU0M1YyNDguMjgxODYwNHpcIi8+PHBhdGggZD1cIk0tMjIxLjcyNjY4NDYsMjQ3SC0yMjV2OWgzLjI3MzMxNTRDLTIyMS4zMjUzNDc5LDI1Ni0yMjEsMjU1LjY3NDY1MjEtMjIxLDI1NS4yNzMzMTU0di03LjU0NjYzMDlcdEMtMjIxLDI0Ny4zMjUzNDc5LTIyMS4zMjUzNDc5LDI0Ny0yMjEuNzI2Njg0NiwyNDd6XCIvPjwvZz48L3N2Zz4nKTtcbiAgfVxufVxuXG4vLyBPdmVyd3JpdGUgY29sb3IgZm9yIHRvb2xiYXJcbi5uYXZiYXIge1xuICBpLmljb24ge1xuICAgICYuaWNvbi11bmRvIHtcbiAgICAgIHdpZHRoOiAyMnB4O1xuICAgICAgaGVpZ2h0OiAyMnB4O1xuICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHtuYXZCYXJJY29uQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0yMCwxN3YtMmMwLTEuNy0xLjMtMy0zLTNIMy43bDMuNCwzLjRsLTEuNCwxLjRsLTUuMi01LjJMMCwxMWwwLjUtMC42bDUuMi01LjJsMS40LDEuNEwzLjcsMTBIMTdjMi44LDAsNSwyLjIsNSw1djJIMjB6XCIvPjwvZz48L3N2Zz4nKTtcbiAgICB9XG4gICAgJi5pY29uLXJlZG8ge1xuICAgICAgd2lkdGg6IDIycHg7XG4gICAgICBoZWlnaHQ6IDIycHg7XG4gICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe25hdkJhckljb25Db2xvcn1cIj48Zz48cGF0aCBkPVwiTTAsMTd2LTJjMC0yLjgsMi4yLTUsNS01aDEzLjNsLTMuNC0zLjRsMS40LTEuNGw1LjIsNS4yTDIyLDExbC0wLjUsMC42bC01LjIsNS4ybC0xLjQtMS40bDMuNC0zLjRINWMtMS43LDAtMywxLjMtMywzdjJIMHpcIi8+PC9nPjwvc3ZnPicpO1xuICAgIH1cbiAgICAmLmljb24tc2VhcmNoIHtcbiAgICAgIHdpZHRoOiAyMnB4O1xuICAgICAgaGVpZ2h0OiAyMnB4O1xuICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHtuYXZCYXJJY29uQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0xOS41LDE2LjhMMTYsMTMuM2MwLjctMS4xLDEuMS0yLjQsMS4xLTMuOEMxNyw1LjQsMTMuNiwyLDkuNSwyUzIsNS40LDIsOS41UzUuNCwxNyw5LjUsMTdjMS40LDAsMi43LTAuNCwzLjgtMS4xbDMuNSwzLjVjMC43LDAuNywxLjksMC43LDIuNiwwQzIwLjIsMTguNywyMC4yLDE3LjYsMTkuNSwxNi44eiBNOS41LDE1LjNjLTMuMiwwLTUuOC0yLjYtNS44LTUuOHMyLjYtNS44LDUuOC01LjhzNS44LDIuNiw1LjgsNS44UzEyLjcsMTUuMyw5LjUsMTUuM3pcIi8+PC9nPjwvc3ZnPicpO1xuICAgIH1cbiAgICAmLmljb24tYnVyZ2VyIHtcbiAgICAgIHdpZHRoOiAyMnB4O1xuICAgICAgaGVpZ2h0OiAyMnB4O1xuICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCItOCAxIDIyIDIyXCIgZmlsbD1cIkB7bmF2QmFySWNvbkNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNLTYsNnYyaDE4VjZILTZ6IE0tNiwxM2gxOHYtMkgtNlYxM3ogTS02LDE4aDE4di0ySC02VjE4elwiLz48L2c+PC9zdmc+Jyk7XG4gICAgfVxuICAgICYuaWNvbi1wbHVzIHtcbiAgICAgIHdpZHRoOiAyMnB4O1xuICAgICAgaGVpZ2h0OiAyMnB4O1xuICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHtuYXZCYXJJY29uQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0yMSwxMmgtOXY5aC0ydi05SDF2LTJoOVYxaDJ2OWg5VjEyelwiLz48L2c+PC9zdmc+Jyk7XG4gICAgfVxuICAgICYuaWNvbi1lZGl0IHtcbiAgICAgIHdpZHRoOiAyMnB4O1xuICAgICAgaGVpZ2h0OiAyMnB4O1xuICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHtuYXZCYXJJY29uQ29sb3J9XCI+PGc+PHBhdGggZD1cIk0wLDIwaDIydjFIMFYyMHpcIi8+PHBvbHlnb24gcG9pbnRzPVwiMTcuMSwzLjEgMy41LDE2LjcgMywyMCA2LjMsMTkuNSAxOS45LDUuOSBcdFwiLz48cGF0aCBkPVwiTTIwLjUsNS4zTDIyLDMuOGMwLDAtMC4yLTEuMi0wLjktMS45QzIwLjQsMS4xLDE5LjIsMSwxOS4yLDFsLTEuNSwxLjVMMjAuNSw1LjN6XCIvPjwvZz48L3N2Zz4nKTtcbiAgICB9XG4gICAgJi5pY29uLXBsYXkge1xuICAgICAgd2lkdGg6IDIycHg7XG4gICAgICBoZWlnaHQ6IDIycHg7XG4gICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe25hdkJhckljb25Db2xvcn1cIj48Zz48cGF0aCBkPVwiTTQuMDQ2NDM2MywyLjk4ODQ1NTNjMC4wMDY1MjYsMC4wMDI5NiwwLjAxNDIzNDUsMC4wMDY4MzUsMC4wMjMxNDM4LDAuMDExOTAyMSBjMC41OTA4NjA0LDAuMzM1NzYzNywxMi43MTE4Mzk3LDcuMjkyNDQzMywxMy44OTc3NDg5LDguMDI2ODQwMmMtMC41ODMxNTg1LDAuMzQxNzc1OS0xMy4wMTM3NTg3LDcuNDg3OTI3NC0xMy45MzQ2NTksNy45ODI2NzI3IEw0LjA0NjQzNjMsMi45ODg0NTUzIE0zLjk4ODkzNTcsMkMzLjQ0Mjc3OTUsMi4wMDAwNTc3LDMuMDAwNTI1LDIuNDUzMzU3NSwzLjAwMDUyNSwzLjAxNTM0OFx0YzAsMC41NzM0ODcsMCwxNS4xNjMyOTU3LDAsMTUuOTk0NTIyMUMzLjAwMDUyNSwxOS42MjI5NjMsMy40Nzk2MTA0LDIwLDMuOTk0MDU4OCwyMCBjMC4xNzI5MzcyLDAsMC4zNDk5MTkxLTAuMDQyNjMxMSwwLjUxMzk3NjMtMC4xMzMyMjI2YzAuODkwNTYwMi0wLjQ5MTA0NSwxMy4xODgwODk0LTcuNTU4MzM3MiwxMy45NDA3Mzg3LTcuOTk5NDQ1OSBjMC42NzUxMjEzLTAuMzk1NTIwMiwwLjY4NjczMTMtMS4zMzc1MTIsMC0xLjczMjY2MDNDMTcuNDAzMTc1NCw5LjUzMzMyNzEsNS4xNTIzODUyLDIuNTAxODUyLDQuNTM5Mzk1MywyLjE1MzUxNjUgQzQuMzUyNjIwMSwyLjA0NzI3OTQsNC4xNjU0MDEsMS45OTk5ODEzLDMuOTg4OTM1NywyTDMuOTg4OTM1NywyelwiLz48L2c+PC9zdmc+Jyk7XG4gICAgfVxuICAgICYuaWNvbi1zZXR0aW5ncyB7XG4gICAgICB3aWR0aDogMjJweDtcbiAgICAgIGhlaWdodDogMjJweDtcbiAgICAgIC5lbmNvZGVkLXN2Zy1iYWNrZ3JvdW5kKCc8c3ZnIHZlcnNpb249XCIxLjFcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgeD1cIjBweFwiIHk9XCIwcHhcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIkB7bmF2QmFySWNvbkNvbG9yfVwiPjxnPjxwYXRoIGQ9XCJNMTIuMSwySDkuOUM5LjYsMiw5LjQsMi4yLDkuMywyLjVMOC44LDQuOWMwLDAuMi0wLjIsMC4zLTAuMywwLjNzLTAuMSwwLTAuMi0wLjFMNi4yLDMuOEM2LjEsMy43LDYsMy43LDUuOCwzLjdjLTAuMSwwLTAuMywwLTAuNCwwLjFMMy44LDUuNGMtMC4xLDAuMi0wLjIsMC41LDAsMC44bDEuMywyLjFjMC4xLDAuMiwwLjEsMC40LTAuMiwwLjVMMi41LDkuM0MyLjIsOS40LDIsOS42LDIsOS45djIuMmMwLDAuMywwLjIsMC41LDAuNSwwLjZsMi40LDAuNWMwLjMsMC4xLDAuNCwwLjMsMC4yLDAuNWwtMS4zLDIuMWMtMC4yLDAuMi0wLjEsMC42LDAuMSwwLjhsMS42LDEuNmMwLjEsMC4xLDAuMywwLjIsMC40LDAuMnMwLjIsMCwwLjMtMC4xTDguMywxN2MwLjEtMC4xLDAuMS0wLjEsMC4yLTAuMXMwLjMsMC4xLDAuMywwLjNsMC41LDIuM0M5LjQsMTkuOCw5LjYsMjAsOS45LDIwaDIuMmMwLjMsMCwwLjUtMC4yLDAuNi0wLjVsMC41LTIuNGMwLTAuMiwwLjEtMC4zLDAuMy0wLjNjMC4xLDAsMC4xLDAsMC4yLDAuMWwyLjEsMS4zYzAuMSwwLjEsMC4yLDAuMSwwLjMsMC4xYzAuMiwwLDAuMy0wLjEsMC40LTAuMmwxLjYtMS42YzAuMi0wLjIsMC4yLTAuNSwwLjEtMC44bC0xLjMtMi4xYy0wLjItMC4yLTAuMS0wLjUsMC4yLTAuNWwyLjQtMC41YzAuMy0wLjEsMC41LTAuMywwLjUtMC42VjkuOGMwLTAuMy0wLjItMC41LTAuNS0wLjZsLTIuNC0wLjVjLTAuMy0wLjEtMC40LTAuMy0wLjItMC41bDEuMy0yLjFjMC4yLTAuMiwwLjEtMC42LTAuMS0wLjhsLTEuNi0xLjZjLTAuMS0wLjEtMC4zLTAuMi0wLjQtMC4ycy0wLjIsMC0wLjMsMC4xbC0yLjEsMS4zQzEzLjYsNSwxMy42LDUsMTMuNSw1cy0wLjMtMC4xLTAuMy0wLjNsLTAuNS0yLjJDMTIuNiwyLjIsMTIuNCwyLDEyLjEsMkwxMi4xLDJ6IE0xMSwxNC41Yy0xLjksMC0zLjUtMS42LTMuNS0zLjVTOS4xLDcuNSwxMSw3LjVzMy41LDEuNiwzLjUsMy41UzEyLjksMTQuNSwxMSwxNC41TDExLDE0LjV6XCIvPjwvZz48L3N2Zz4nKTtcbiAgICB9XG4gICAgJi5pY29uLXByZXYge1xuICAgICAgd2lkdGg6IDIwcHg7XG4gICAgICBoZWlnaHQ6IDIwcHg7XG4gICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe25hdkJhckljb25Db2xvcn1cIj48Zz48cG9seWdvbiBwb2ludHM9XCI1LjEsMTAuOSAxMy45LDIgMTYsNC4xIDkuMiwxMS4xIDE2LDE3LjkgMTMuOSwyMCA1LjEsMTEuMiA1LDExLjEgXCIvPjwvZz48L3N2Zz4nKTtcbiAgICB9XG4gICAgJi5pY29uLW5leHQge1xuICAgICAgd2lkdGg6IDIwcHg7XG4gICAgICBoZWlnaHQ6IDIwcHg7XG4gICAgICAuZW5jb2RlZC1zdmctYmFja2dyb3VuZCgnPHN2ZyB2ZXJzaW9uPVwiMS4xXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiIHg9XCIwcHhcIiB5PVwiMHB4XCIgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJAe25hdkJhckljb25Db2xvcn1cIj48Zz48cG9seWdvbiBwb2ludHM9XCIxNi45LDEwLjkgOC4xLDIgNiw0LjEgMTIuOCwxMS4xIDYsMTcuOSA4LjEsMjAgMTYuOSwxMS4yIDE3LDExLjEgXCIvPjwvZz48L3N2Zz4nKTtcbiAgICB9XG4gICAgJi5pY29uLWV4cGFuZC1kb3duIHtcbiAgICAgIHdpZHRoOiAyMnB4O1xuICAgICAgaGVpZ2h0OiAyMnB4O1xuICAgICAgLmVuY29kZWQtc3ZnLWJhY2tncm91bmQoJzxzdmcgdmVyc2lvbj1cIjEuMVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB4PVwiMHB4XCIgeT1cIjBweFwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIiBmaWxsPVwiQHtuYXZCYXJJY29uQ29sb3J9XCI+PGc+PHBvbHlnb24gcG9pbnRzPVwiMTAuOSwxNi45IDIsOC4xIDQuMSw2IDExLjEsMTIuOCAxNy45LDYgMjAsOC4xIDExLjIsMTYuOSAxMS4xLDE3IFwiLz48L2c+PC9zdmc+Jyk7XG4gICAgfVxuICB9XG59IiwiLy8gRW5jb2RlZCBTVkcgQmFja2dyb3VuZFxuLmVuY29kZWQtc3ZnLW1hc2soQHN2Zykge1xuICBAdXJsOiBgZW5jb2RlVVJJQ29tcG9uZW50KEB7c3ZnfSlgO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiBAdGhlbWVDb2xvcjtcbiAgLXdlYmtpdC1tYXNrLWltYWdlOiB1cmwoXCJkYXRhOmltYWdlL3N2Zyt4bWw7Y2hhcnNldD11dGYtOCxAe3VybH1cIik7XG59IiwiQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL19taXhpbnMubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL19jb2xvcnMtdmFycy5sZXNzJyk7XG5cbi8vIENvbG9yc1xuQHRoZW1lQ29sb3I6ICNERjY3Mzc7IC8vICgyMjMsMTAzLDU1KVxuQG5hdkJhckljb25Db2xvcjogI2ZmZjtcblxuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2ludHJvLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9ncmlkLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC92aWV3cy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcGFnZXMubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3Rvb2xiYXJzLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC90b29sYmFycy1wYWdlcy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvc2VhcmNoYmFyLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9tZXNzYWdlYmFyLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9pY29ucy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvYmFkZ2VzLmxlc3MnKTtcbi8vQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2NoaXBzLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9jb250ZW50LWJsb2NrLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9saXN0cy5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9jb250YWN0cy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvZm9ybXMubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2Zsb2F0aW5nLWJ1dHRvbi5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9hY2NvcmRpb24ubGVzcycpO1xuLy9AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvY2FyZHMubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL21vZGFscy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcGFuZWxzLmxlc3MnKTtcbi8vQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2xhenktbG9hZC5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvdGFicy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvbWVzc2FnZXMubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL3N0YXR1c2Jhci5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcHJlbG9hZGVyLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9wcm9ncmVzc2Jhci5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9wdWxsLXRvLXJlZnJlc2gubGVzcycpO1xuLy9AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvaW5maW5pdGUtc2Nyb2xsLmxlc3MnKTtcbi8vQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2F1dG9jb21wbGV0ZS5sZXNzJyk7XG4vL0BpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9zd2lwZXIubGVzcycpO1xuLy9AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcGhvdG8tYnJvd3Nlci5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcGlja2VyLmxlc3MnKTtcbi8vQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2NhbGVuZGFyLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9ub3RpZmljYXRpb25zLmxlc3MnKTtcbi8vQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uLy4uL3ZlbmRvci9mcmFtZXdvcms3L3NyYy9sZXNzL21hdGVyaWFsL2xvZ2luLXNjcmVlbi5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vLi4vdmVuZG9yL2ZyYW1ld29yazcvc3JjL2xlc3MvbWF0ZXJpYWwvcmlwcGxlLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi8uLi92ZW5kb3IvZnJhbWV3b3JrNy9zcmMvbGVzcy9tYXRlcmlhbC9kaXNhYmxlZC5sZXNzJyk7XG5cblxuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvX21peGlucy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9tYXRlcmlhbC9fY29udGFpbmVyLmxlc3MnKTtcbkBpbXBvcnQgdXJsKCcuLi8uLi8uLi8uLi9jb21tb24vbW9iaWxlL3Jlc291cmNlcy9sZXNzL21hdGVyaWFsL19kYXRhdmlldy5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9tYXRlcmlhbC9fbGlzdHZpZXcubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvbWF0ZXJpYWwvX2J1dHRvbi5sZXNzJyk7XG5AaW1wb3J0IHVybCgnLi4vLi4vLi4vLi4vY29tbW9uL21vYmlsZS9yZXNvdXJjZXMvbGVzcy9tYXRlcmlhbC9fY29udGV4dG1lbnUubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvbWF0ZXJpYWwvX2NvbG9yLXBhbGV0dGUubGVzcycpO1xuQGltcG9ydCB1cmwoJy4uLy4uLy4uLy4uL2NvbW1vbi9tb2JpbGUvcmVzb3VyY2VzL2xlc3MvbWF0ZXJpYWwvX2Fib3V0Lmxlc3MnKTtcblxuQGltcG9ydCB1cmwoJ21hdGVyaWFsL19zZWFyY2gubGVzcycpO1xuQGltcG9ydCB1cmwoJ21hdGVyaWFsL19pY29ucy5sZXNzJyk7XG5cbi8vIFRvcCBvZmZzZXRcblxuI2VkaXRvcl9zZGsge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGxlZnQ6IDA7XG4gIHJpZ2h0OiAwO1xuICB0b3A6IEB0b29sYmFyU2l6ZTtcbiAgYm90dG9tOiAwO1xuICBoZWlnaHQ6IGF1dG87XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIC50cmFuc2l0aW9uKDMwMG1zKTtcbn1cblxuLy8gRGlzYWJsZSB0ZXh0IHNlbGVjdFxuKiB7XG4gIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XG4gIHVzZXItc2VsZWN0OiBub25lO1xufVxuXG5pbnB1dCwgdGV4dGFyZWEge1xuICAtd2Via2l0LXRvdWNoLWNhbGxvdXQ6ZGVmYXVsdDtcbiAgLXdlYmtpdC11c2VyLXNlbGVjdDp0ZXh0O1xuICB1c2VyLXNlbGVjdDp0ZXh0O1xufVxuXG4vLyBBZGQgQ29udGFpbmVyXG5cbiNhZGQtdGFibGUsXG4jYWRkLXNoYXBlIHtcbiAgLnBhZ2Uge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gIH1cbn1cblxuLy8gVGFibGUgc3R5bGVzXG5cbi50YWJsZS1zdHlsZXMge1xuICAucm93IHtcbiAgICAmLCBsaSB7XG4gICAgICBtYXJnaW4tYm90dG9tOiAxMnB4O1xuICAgIH1cbiAgfVxuXG4gIGxpIHtcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMXB4O1xuXG4gICAgaW1nIHtcbiAgICAgIHdpZHRoOiA3MHB4O1xuICAgICAgaGVpZ2h0OiA1MHB4O1xuICAgIH1cbiAgfVxufVxuXG4vLyBTaGFwZXNcblxuLnNoYXBlcyB7XG4gIGxpIHtcbiAgICB3aWR0aDogNzBweDtcbiAgICBoZWlnaHQ6IDcwcHg7XG4gICAgbWFyZ2luOiAwIDFweDtcblxuICAgIC50aHVtYiB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IEB0aGVtZUNvbG9yO1xuICAgIH1cbiAgfVxufVxuXG4vLyBCdWxsZXRzIGFuZCBudW1iZXJzXG5cbi5idWxsZXRzLFxuLm51bWJlcnMge1xuICB1bCB7XG4gICAgbWFyZ2luLXRvcDogMTBweDtcbiAgfVxuXG4gIGxpIHtcbiAgICB3aWR0aDogNzBweDtcbiAgICBoZWlnaHQ6IDcwcHg7XG4gICAgbWFyZ2luLXJpZ2h0OiAxcHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2M0YzRjNDtcbiAgICBodG1sLnBpeGVsLXJhdGlvLTIgJiB7XG4gICAgICBib3JkZXI6IDAuNXB4IHNvbGlkICNjNGM0YzQ7XG4gICAgfVxuICAgIGh0bWwucGl4ZWwtcmF0aW8tMyAmIHtcbiAgICAgIGJvcmRlcjogMC4zM3B4IHNvbGlkICNjNGM0YzQ7XG4gICAgfVxuXG4gICAgJi5hY3RpdmUge1xuICAgICAgLy9cbiAgICB9XG5cbiAgICAudGh1bWIge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBAd2hpdGU7XG4gICAgICBiYWNrZ3JvdW5kLXNpemU6IGNvdmVyO1xuXG4gICAgICBsYWJlbCB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgdG9wOiAzNCU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIFNsaWRlIGxheW91dFxuXG4uc2xpZGUtbGF5b3V0IHtcbiAgLnJvdyB7XG4gICAgICBtYXJnaW4tYm90dG9tOiAxMnB4O1xuICB9XG5cbiAgbGkge1xuICAgIG1hcmdpbjogMDtcbiAgICBwYWRkaW5nOiAxcHg7XG5cbiAgICBpbWcge1xuICAgICAgYm94LXNoYWRvdzogMCAwIDAgMXB4IHJnYmEoMCwwLDAsMC4xNSk7XG4gICAgfVxuICB9XG59XG5cbi8vIFNsaWRlIHRoZW1lXG5cbi5zbGlkZS10aGVtZSB7XG4gIC5yb3cge1xuICAgIG1hcmdpbi10b3A6IDE0cHg7XG4gICAgbWFyZ2luLWJvdHRvbTogMTJweDtcblxuICAgIGRpdiB7XG4gICAgICBtYXJnaW46IDA7XG4gICAgICBwYWRkaW5nOiAzcHg7XG4gICAgICBib3gtc2hhZG93OiAwIDAgMCAxcHggcmdiYSgwLDAsMCwwLjE1KTtcbiAgICAgIHdpZHRoOiA4NXB4O1xuICAgICAgaGVpZ2h0OiAzOHB4O1xuICAgIH1cbiAgfVxufVxuXG4vLyBDaGFydHNcblxuLmNoYXJ0LXR5cGVzIHtcbiAgbGkge1xuICAgIHdpZHRoOiA2MHB4O1xuICAgIGhlaWdodDogNjBweDtcbiAgICBtYXJnaW46IDZweDtcblxuICAgIC50aHVtYiB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgIGJhY2tncm91bmQtc2l6ZTogY29udGFpbjtcbiAgICB9XG4gIH1cbn0iXX0= */ \ No newline at end of file diff --git a/apps/presentationeditor/mobile/resources/less/ios/_icons.less b/apps/presentationeditor/mobile/resources/less/ios/_icons.less index 2fe1ae30e..c0379093b 100644 --- a/apps/presentationeditor/mobile/resources/less/ios/_icons.less +++ b/apps/presentationeditor/mobile/resources/less/ios/_icons.less @@ -363,4 +363,9 @@ i.icon { height: 22px; .encoded-svg-background(''); } + &.icon-format-odp { + width: 22px; + height: 22px; + .encoded-svg-background(''); + } } \ No newline at end of file diff --git a/apps/presentationeditor/mobile/resources/less/material/_icons.less b/apps/presentationeditor/mobile/resources/less/material/_icons.less index 890ab0ca9..ce6367503 100644 --- a/apps/presentationeditor/mobile/resources/less/material/_icons.less +++ b/apps/presentationeditor/mobile/resources/less/material/_icons.less @@ -333,6 +333,11 @@ i.icon { height: 22px; .encoded-svg-background(''); } + &.icon-format-odp { + width: 22px; + height: 22px; + .encoded-svg-background(''); + } } // Overwrite color for toolbar diff --git a/apps/presentationeditor/sdk_dev_scripts.js b/apps/presentationeditor/sdk_dev_scripts.js index 5805ba034..b28e390be 100644 --- a/apps/presentationeditor/sdk_dev_scripts.js +++ b/apps/presentationeditor/sdk_dev_scripts.js @@ -77,6 +77,8 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/cell/model/CellInfo.js", "../../../../sdkjs/cell/view/DrawingObjectsController.js", "../../../../sdkjs/slide/Drawing/ThemeLoader.js", + "../../../../sdkjs/word/Editor/DocumentContentElementBase.js", + "../../../../sdkjs/word/Editor/StructuredDocumentTags/BlockLevel.js", "../../../../sdkjs/word/Editor/Serialize2.js", "../../../../sdkjs/word/Editor/Numbering.js", "../../../../sdkjs/word/Editor/NumberingChanges.js", @@ -96,6 +98,7 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/word/Editor/SectionsChanges.js", "../../../../sdkjs/word/Editor/Styles.js", "../../../../sdkjs/word/Editor/StylesChanges.js", + "../../../../sdkjs/word/Editor/RevisionsChange.js", "../../../../sdkjs/slide/Editor/Format/StylesPrototype.js", "../../../../sdkjs/word/Drawing/Graphics.js", "../../../../sdkjs/word/Drawing/ShapeDrawer.js", @@ -108,6 +111,8 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/slide/Editor/Format/SlideMaster.js", "../../../../sdkjs/slide/Editor/Format/Layout.js", "../../../../sdkjs/slide/Editor/Format/Comments.js", + "../../../../sdkjs/slide/Editor/Format/NotesMaster.js", + "../../../../sdkjs/slide/Editor/Format/Notes.js", "../../../../sdkjs/word/Editor/ParagraphContent.js", "../../../../sdkjs/word/Editor/Paragraph/ParaTextPr.js", "../../../../sdkjs/word/Editor/Paragraph/ParaTextPrChanges.js", diff --git a/apps/spreadsheeteditor/embed/index.html b/apps/spreadsheeteditor/embed/index.html index 0695c7f3d..99a46ebed 100644 --- a/apps/spreadsheeteditor/embed/index.html +++ b/apps/spreadsheeteditor/embed/index.html @@ -324,7 +324,6 @@ - - diff --git a/apps/spreadsheeteditor/main/app.js b/apps/spreadsheeteditor/main/app.js index db740f9e6..c397378b5 100644 --- a/apps/spreadsheeteditor/main/app.js +++ b/apps/spreadsheeteditor/main/app.js @@ -55,7 +55,6 @@ require.config({ xregexp : '../vendor/xregexp/xregexp-all-min', sockjs : '../vendor/sockjs/sockjs.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', allfonts : '../../sdkjs/common/AllFonts', sdk : '../../sdkjs/cell/sdk-all-min', api : 'api/documents/api', @@ -109,8 +108,7 @@ require.config({ 'allfonts', 'xregexp', 'sockjs', - 'jsziputils', - 'jsrsasign' + 'jsziputils' ] }, gateway: { diff --git a/apps/spreadsheeteditor/main/app/controller/Main.js b/apps/spreadsheeteditor/main/app/controller/Main.js index 8f778c613..2448521e6 100644 --- a/apps/spreadsheeteditor/main/app/controller/Main.js +++ b/apps/spreadsheeteditor/main/app/controller/Main.js @@ -1047,6 +1047,16 @@ define([ config.closable = true; break; + case Asc.c_oAscError.ID.FrmlOperandExpected: + config.msg = this.errorOperandExpected; + config.closable = true; + break; + + case Asc.c_oAscError.ID.FrmlWrongReferences: + config.msg = this.errorFrmlWrongReferences; + config.closable = true; + break; + case Asc.c_oAscError.ID.UnexpectedGuid: config.msg = this.errorUnexpectedGuid; break; @@ -1071,10 +1081,6 @@ define([ config.msg = this.errorDataRange; break; - case Asc.c_oAscError.ID.FrmlOperandExpected: - config.msg = this.errorOperandExpected; - break; - case Asc.c_oAscError.ID.VKeyEncrypt: config.msg = this.errorToken; break; @@ -1160,10 +1166,6 @@ define([ config.msg = this.errorOpenWarning; break; - case Asc.c_oAscError.ID.FrmlWrongReferences: - config.msg = this.errorFrmlWrongReferences; - break; - case Asc.c_oAscError.ID.CopyMultiselectAreaError: config.msg = this.errorCopyMultiselectArea; break; @@ -2057,7 +2059,7 @@ define([ errorFileVKey: 'External error.
    Incorrect securety key. Please, contact support.', errorStockChart: 'Incorrect row order. To build a stock chart place the data on the sheet in the following order:
    opening price, max price, min price, closing price.', errorDataRange: 'Incorrect data range.', - errorOperandExpected: 'Operand expected', + errorOperandExpected: 'The entered function syntax is not correct. Please check if you are missing one of the parentheses - \'(\' or \')\'.', errorKeyEncrypt: 'Unknown key descriptor', errorKeyExpire: 'Key descriptor expired', errorUsersExceed: 'Count of users was exceed', diff --git a/apps/spreadsheeteditor/main/app/controller/Toolbar.js b/apps/spreadsheeteditor/main/app/controller/Toolbar.js index c04c20e1c..2e7dc6f1b 100644 --- a/apps/spreadsheeteditor/main/app/controller/Toolbar.js +++ b/apps/spreadsheeteditor/main/app/controller/Toolbar.js @@ -1436,7 +1436,7 @@ define([ restoreHeight: 300, style: 'max-height: 300px;', store: me.getCollection('TableTemplates'), - itemTemplate: _.template('
    ') + itemTemplate: _.template('
    ') }); picker.on('item:click', function(picker, item, record) { @@ -2222,7 +2222,7 @@ define([ store: this.getApplication().getCollection('Common.Collections.TextArt'), parentMenu: this.toolbar.mnuInsertTextArt.menu, showLast: false, - itemTemplate: _.template('
    ') + itemTemplate: _.template('
    ') }); this.toolbar.mnuTextArtPicker.on('item:click', function(picker, item, record, e) { @@ -2569,8 +2569,23 @@ define([ if (me._state.tablename) me.api.asc_changeAutoFilter(me._state.tablename, Asc.c_oAscChangeFilterOptions.style, fmtname); - else - me.api.asc_addAutoFilter(fmtname, dlg.getSettings()); + else { + var settings = dlg.getSettings(); + if (settings.selectionType == Asc.c_oAscSelectionType.RangeMax || settings.selectionType == Asc.c_oAscSelectionType.RangeRow || + settings.selectionType == Asc.c_oAscSelectionType.RangeCol) + Common.UI.warning({ + title: me.textLongOperation, + msg: me.warnLongOperation, + buttons: ['ok', 'cancel'], + callback: function(btn) { + if (btn == 'ok') + setTimeout(function() { me.api.asc_addAutoFilter(fmtname, settings.range)}, 1); + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + } + }); + else + me.api.asc_addAutoFilter(fmtname, settings.range); + } } Common.NotificationCenter.trigger('edit:complete', me.toolbar); @@ -2582,14 +2597,30 @@ define([ win.show(); win.setSettings({ - api : me.api + api : me.api, + selectionType: me.api.asc_getCellInfo().asc_getFlags().asc_getSelectionType() }); } else { me._state.filter = undefined; if (me._state.tablename) me.api.asc_changeAutoFilter(me._state.tablename, Asc.c_oAscChangeFilterOptions.style, fmtname); - else - me.api.asc_addAutoFilter(fmtname); + else { + var selectionType = me.api.asc_getCellInfo().asc_getFlags().asc_getSelectionType(); + if (selectionType == Asc.c_oAscSelectionType.RangeMax || selectionType == Asc.c_oAscSelectionType.RangeRow || + selectionType == Asc.c_oAscSelectionType.RangeCol) + Common.UI.warning({ + title: me.textLongOperation, + msg: me.warnLongOperation, + buttons: ['ok', 'cancel'], + callback: function(btn) { + if (btn == 'ok') + setTimeout(function() { me.api.asc_addAutoFilter(fmtname)}, 1); + Common.NotificationCenter.trigger('edit:complete', me.toolbar); + } + }); + else + me.api.asc_addAutoFilter(fmtname); + } } } }, @@ -3022,7 +3053,9 @@ define([ txtExpandSort: 'The data next to the selection will not be sorted. Do you want to expand the selection to include the adjacent data or continue with sorting the currently selected cells only?', txtExpand: 'Expand and sort', txtSorting: 'Sorting', - txtSortSelected: 'Sort selected' + txtSortSelected: 'Sort selected', + textLongOperation: 'Long operation', + warnLongOperation: 'The operation you are about to perform might take rather much time to complete.
    Are you sure you want to continue?' }, SSE.Controllers.Toolbar || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/AutoFilterDialog.js b/apps/spreadsheeteditor/main/app/view/AutoFilterDialog.js index c0c2fa909..e1500b78b 100644 --- a/apps/spreadsheeteditor/main/app/view/AutoFilterDialog.js +++ b/apps/spreadsheeteditor/main/app/view/AutoFilterDialog.js @@ -93,7 +93,7 @@ define([ this.handler = options.handler; this.type = options.type || 'number'; - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); Common.UI.Window.prototype.initialize.call(this, _options); }, @@ -342,7 +342,7 @@ define([ this.api = options.api; this.handler = options.handler; - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); Common.UI.Window.prototype.initialize.call(this, _options); }, @@ -516,7 +516,7 @@ define([ this.throughIndexes = []; this.filteredIndexes = []; - _options.tpl = _.template(this.template, _options); + _options.tpl = _.template(this.template)(_options); Common.UI.Window.prototype.initialize.call(this, _options); }, diff --git a/apps/spreadsheeteditor/main/app/view/CellRangeDialog.js b/apps/spreadsheeteditor/main/app/view/CellRangeDialog.js index d68518186..b8a91cb4e 100644 --- a/apps/spreadsheeteditor/main/app/view/CellRangeDialog.js +++ b/apps/spreadsheeteditor/main/app/view/CellRangeDialog.js @@ -69,7 +69,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, @@ -136,7 +136,7 @@ define([ }, onApiRangeChanged: function(info) { - this.inputRange.setValue(info); + this.inputRange.setValue(info.asc_getName()); if (this.inputRange.cmpEl.hasClass('error')) this.inputRange.cmpEl.removeClass('error'); }, diff --git a/apps/spreadsheeteditor/main/app/view/ChartSettings.js b/apps/spreadsheeteditor/main/app/view/ChartSettings.js index 57bc7883b..9f353da74 100644 --- a/apps/spreadsheeteditor/main/app/view/ChartSettings.js +++ b/apps/spreadsheeteditor/main/app/view/ChartSettings.js @@ -925,6 +925,7 @@ define([ { chartSettings: props, imageSettings: (me.isChart) ? me._originalProps : null, + sparklineStyles: me.sparklineStyles, isChart: me.isChart, api: me.api, handler: function(result, value) { @@ -1109,6 +1110,7 @@ define([ if (styles && styles.length>1){ var stylesStore = this.cmbSparkStyle.menuPicker.store, selectedIdx = styles[styles.length-1]; + this.sparklineStyles = styles; if (stylesStore.length == styles.length-1) { var data = stylesStore.models; for (var i=0; i' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.api = this.options.api; Common.UI.Window.prototype.initialize.call(this, this.options); diff --git a/apps/spreadsheeteditor/main/app/view/SetValueDialog.js b/apps/spreadsheeteditor/main/app/view/SetValueDialog.js index 94aac612e..50fdfe928 100644 --- a/apps/spreadsheeteditor/main/app/view/SetValueDialog.js +++ b/apps/spreadsheeteditor/main/app/view/SetValueDialog.js @@ -67,7 +67,7 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.startvalue = this.options.startvalue; this.maxvalue = this.options.maxvalue; this.defaultUnit = this.options.defaultUnit; diff --git a/apps/spreadsheeteditor/main/app/view/ShapeSettings.js b/apps/spreadsheeteditor/main/app/view/ShapeSettings.js index a43b106db..f11030b49 100644 --- a/apps/spreadsheeteditor/main/app/view/ShapeSettings.js +++ b/apps/spreadsheeteditor/main/app/view/ShapeSettings.js @@ -1258,6 +1258,18 @@ define([ this.sldrGradient.on('thumbdblclick', function(cmp){ me.btnGradColor.cmpEl.find('button').dropdown('toggle'); }); + this.sldrGradient.on('sortthumbs', function(cmp, recalc_indexes){ + var colors = [], + currentIdx; + _.each (recalc_indexes, function(recalc_index, index) { + colors.push(me.GradColor.colors[recalc_index]); + if (me.GradColor.currentIdx == recalc_index) + currentIdx = index; + }); + me.OriginalFillType = null; + me.GradColor.colors = colors; + me.GradColor.currentIdx = currentIdx; + }); this.fillControls.push(this.sldrGradient); this.cmbBorderSize = new Common.UI.ComboBorderSizeEditable({ diff --git a/apps/spreadsheeteditor/main/app/view/Statusbar.js b/apps/spreadsheeteditor/main/app/view/Statusbar.js index c9a0223f4..4086b3e9a 100644 --- a/apps/spreadsheeteditor/main/app/view/Statusbar.js +++ b/apps/spreadsheeteditor/main/app/view/Statusbar.js @@ -68,7 +68,7 @@ define([ templateUserList: _.template(''), @@ -489,7 +489,7 @@ define([ _onAddUser: function(m, c, opts) { if (this.panelUsersList) { - this.panelUsersList.find('ul').append(_.template(this.tplUser, {user: m, scope: this})); + this.panelUsersList.find('ul').append(_.template(this.tplUser)({user: m, scope: this})); this.panelUsersList.scroller.update({minScrollbarLength : 40, alwaysVisibleY: true}); } }, @@ -706,7 +706,7 @@ define([ label: this.labelSheetName, btns: {ok: this.okButtonText, cancel: this.cancelButtonText} }); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, @@ -823,7 +823,7 @@ define([ label: options.ismove ? this.textMoveBefore : this.textCopyBefore, btns: {ok: this.okButtonText, cancel: this.cancelButtonText} }); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); Common.UI.Window.prototype.initialize.call(this, this.options); }, diff --git a/apps/spreadsheeteditor/main/app/view/TableOptionsDialog.js b/apps/spreadsheeteditor/main/app/view/TableOptionsDialog.js index 0c1712e57..023fd5bc3 100644 --- a/apps/spreadsheeteditor/main/app/view/TableOptionsDialog.js +++ b/apps/spreadsheeteditor/main/app/view/TableOptionsDialog.js @@ -72,8 +72,9 @@ define([ '' ].join(''); - this.options.tpl = _.template(this.template, this.options); + this.options.tpl = _.template(this.template)(this.options); this.checkRangeType = Asc.c_oAscSelectionDialogType.FormatTable; + this.selectionType = Asc.c_oAscSelectionType.RangeCells; Common.UI.Window.prototype.initialize.call(this, this.options); }, @@ -129,6 +130,8 @@ define([ } if (settings.title) me.setTitle(settings.title); + if (settings.selectionType) + me.selectionType = settings.selectionType; me.api.asc_unregisterCallback('asc_onSelectionRangeChanged', _.bind(me.onApiRangeChanged, me)); me.api.asc_registerCallback('asc_onSelectionRangeChanged', _.bind(me.onApiRangeChanged, me)); @@ -145,15 +148,16 @@ define([ if (this.checkRangeType == Asc.c_oAscSelectionDialogType.FormatTable) { var options = this.api.asc_getAddFormatTableOptions(this.inputRange.getValue()); options.asc_setIsTitle(this.cbTitle.checked); - return options; + return { selectionType: this.selectionType, range: options}; } else - return this.inputRange.getValue(); + return { selectionType: this.selectionType, range: this.inputRange.getValue()}; }, onApiRangeChanged: function(info) { - this.inputRange.setValue(info); + this.inputRange.setValue(info.asc_getName()); if (this.inputRange.cmpEl.hasClass('error')) this.inputRange.cmpEl.removeClass('error'); + this.selectionType = info.asc_getType(); }, isRangeValid: function() { diff --git a/apps/spreadsheeteditor/main/app/view/TableSettings.js b/apps/spreadsheeteditor/main/app/view/TableSettings.js index 53b39fed8..88be21d07 100644 --- a/apps/spreadsheeteditor/main/app/view/TableSettings.js +++ b/apps/spreadsheeteditor/main/app/view/TableSettings.js @@ -478,10 +478,25 @@ define([ var handlerDlg = function(dlg, result) { if (result == 'ok') { me.api.asc_setSelectionDialogMode(Asc.c_oAscSelectionDialogType.None); - me.api.asc_changeTableRange(me._state.TableName, dlg.getSettings()); + + var settings = dlg.getSettings(); + if (settings.selectionType == Asc.c_oAscSelectionType.RangeMax || settings.selectionType == Asc.c_oAscSelectionType.RangeRow || + settings.selectionType == Asc.c_oAscSelectionType.RangeCol) + Common.UI.warning({ + title: me.textLongOperation, + msg: me.warnLongOperation, + buttons: ['ok', 'cancel'], + callback: function(btn) { + if (btn == 'ok') + setTimeout(function() { me.api.asc_changeTableRange(me._state.TableName, settings.range)}, 1); + Common.NotificationCenter.trigger('edit:complete', me); + } + }); + else + me.api.asc_changeTableRange(me._state.TableName, settings.range); } - Common.NotificationCenter.trigger('edit:complete', me.toolbar); + Common.NotificationCenter.trigger('edit:complete', me); }; var win = new SSE.Views.TableOptionsDialog({ handler: handlerDlg @@ -545,7 +560,9 @@ define([ notcriticalErrorTitle : 'Warning', textReservedName : 'The name you are trying to use is already referenced in cell formulas. Please use some other name.', textAdvanced: 'Show advanced settings', - textConvertRange: 'Convert to range' + textConvertRange: 'Convert to range', + textLongOperation: 'Long operation', + warnLongOperation: 'The operation you are about to perform might take rather much time to complete.
    Are you sure you want to continue?' }, SSE.Views.TableSettings || {})); }); \ No newline at end of file diff --git a/apps/spreadsheeteditor/main/app/view/TextArtSettings.js b/apps/spreadsheeteditor/main/app/view/TextArtSettings.js index 4a26f7699..f31ebef90 100644 --- a/apps/spreadsheeteditor/main/app/view/TextArtSettings.js +++ b/apps/spreadsheeteditor/main/app/view/TextArtSettings.js @@ -1228,6 +1228,18 @@ define([ this.sldrGradient.on('thumbdblclick', function(cmp){ me.btnGradColor.cmpEl.find('button').dropdown('toggle'); }); + this.sldrGradient.on('sortthumbs', function(cmp, recalc_indexes){ + var colors = [], + currentIdx; + _.each (recalc_indexes, function(recalc_index, index) { + colors.push(me.GradColor.colors[recalc_index]); + if (me.GradColor.currentIdx == recalc_index) + currentIdx = index; + }); + me.OriginalFillType = null; + me.GradColor.colors = colors; + me.GradColor.currentIdx = currentIdx; + }); this.lockedControls.push(this.sldrGradient); this.cmbBorderSize = new Common.UI.ComboBorderSizeEditable({ diff --git a/apps/spreadsheeteditor/main/app_dev.js b/apps/spreadsheeteditor/main/app_dev.js index 3d8301bbb..2caaafbfe 100644 --- a/apps/spreadsheeteditor/main/app_dev.js +++ b/apps/spreadsheeteditor/main/app_dev.js @@ -55,7 +55,6 @@ require.config({ xregexp : '../vendor/xregexp/xregexp-all-min', sockjs : '../vendor/sockjs/sockjs.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', api : 'api/documents/api', core : 'common/main/lib/core/application', notification : 'common/main/lib/core/NotificationCenter', @@ -122,7 +121,6 @@ require([ 'gateway', 'locale', 'jsziputils', - 'jsrsasign', 'sockjs', 'underscore' ], function (Backbone, Bootstrap, Core) { diff --git a/apps/spreadsheeteditor/main/locale/en.json b/apps/spreadsheeteditor/main/locale/en.json index cea0fad83..8cb9d4962 100644 --- a/apps/spreadsheeteditor/main/locale/en.json +++ b/apps/spreadsheeteditor/main/locale/en.json @@ -701,6 +701,8 @@ "SSE.Controllers.Toolbar.txtSymbol_xsi": "Xi", "SSE.Controllers.Toolbar.txtSymbol_zeta": "Zeta", "SSE.Controllers.Toolbar.warnMergeLostData": "Only the data from the upper-left cell will remain in the merged cell.
    Are you sure you want to continue?", + "SSE.Controllers.Toolbar.textLongOperation": "Long operation", + "SSE.Controllers.Toolbar.warnLongOperation": "The operation you are about to perform might take rather much time to complete.
    Are you sure you want to continue?", "SSE.Views.AutoFilterDialog.btnCustomFilter": "Custom Filter", "SSE.Views.AutoFilterDialog.cancelButtonText": "Cancel", "SSE.Views.AutoFilterDialog.okButtonText": "OK", @@ -1482,6 +1484,9 @@ "SSE.Views.TableSettings.textTableName": "Table Name", "SSE.Views.TableSettings.textTemplate": "Select From Template", "SSE.Views.TableSettings.textTotal": "Total", + "SSE.Views.TableSettings.textConvertRange": "Convert to range", + "SSE.Views.TableSettings.textLongOperation": "Long operation", + "SSE.Views.TableSettings.warnLongOperation": "The operation you are about to perform might take rather much time to complete.
    Are you sure you want to continue?", "SSE.Views.TableSettingsAdvanced.cancelButtonText": "Cancel", "SSE.Views.TableSettingsAdvanced.okButtonText": "Ok", "SSE.Views.TableSettingsAdvanced.textAlt": "Alternative Text", diff --git a/apps/spreadsheeteditor/mobile/app-dev.js b/apps/spreadsheeteditor/mobile/app-dev.js index 70e500048..d3a031a77 100644 --- a/apps/spreadsheeteditor/mobile/app-dev.js +++ b/apps/spreadsheeteditor/mobile/app-dev.js @@ -53,7 +53,6 @@ require.config({ sockjs : '../vendor/sockjs/sockjs.min', jszip : '../vendor/jszip/jszip.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', api : 'api/documents/api', core : 'common/main/lib/core/application', extendes : 'common/mobile/utils/extendes', @@ -102,7 +101,6 @@ require([ 'locale', 'jszip', 'jsziputils', - 'jsrsasign', 'sockjs' ], function (Backbone, Framework7) { Backbone.history.start(); diff --git a/apps/spreadsheeteditor/mobile/app.js b/apps/spreadsheeteditor/mobile/app.js index 518035953..f87754175 100644 --- a/apps/spreadsheeteditor/mobile/app.js +++ b/apps/spreadsheeteditor/mobile/app.js @@ -53,7 +53,6 @@ require.config({ sockjs : '../vendor/sockjs/sockjs.min', jszip : '../vendor/jszip/jszip.min', jsziputils : '../vendor/jszip-utils/jszip-utils.min', - jsrsasign : '../vendor/jsrsasign/jsrsasign-latest-all-min', allfonts : '../../sdkjs/common/AllFonts', sdk : '../../sdkjs/cell/sdk-all-min', api : 'api/documents/api', @@ -82,8 +81,7 @@ require.config({ 'xregexp', 'sockjs', 'jszip', - 'jsziputils', - 'jsrsasign' + 'jsziputils' ] }, backbone: { diff --git a/apps/spreadsheeteditor/mobile/app/controller/Main.js b/apps/spreadsheeteditor/mobile/app/controller/Main.js index 82d129827..eb04ec058 100644 --- a/apps/spreadsheeteditor/mobile/app/controller/Main.js +++ b/apps/spreadsheeteditor/mobile/app/controller/Main.js @@ -786,6 +786,7 @@ define([ case Asc.c_oAscError.ID.FrmlOperandExpected: config.msg = this.errorOperandExpected; + config.closable = true; break; case Asc.c_oAscError.ID.VKeyEncrypt: @@ -875,6 +876,7 @@ define([ case Asc.c_oAscError.ID.FrmlWrongReferences: config.msg = this.errorFrmlWrongReferences; + config.closable = true; break; case Asc.c_oAscError.ID.CopyMultiselectAreaError: diff --git a/apps/spreadsheeteditor/mobile/app/controller/add/AddFunction.js b/apps/spreadsheeteditor/mobile/app/controller/add/AddFunction.js index e44925767..97dccd5a6 100644 --- a/apps/spreadsheeteditor/mobile/app/controller/add/AddFunction.js +++ b/apps/spreadsheeteditor/mobile/app/controller/add/AddFunction.js @@ -87,6 +87,7 @@ define([ _.defer(function () { var editorLang = SSE.getController("Main").editorConfig.lang; + editorLang = (editorLang ? editorLang : 'en').split("-")[0].toLowerCase(); var localizationFunctions = function(data) { fc = data; diff --git a/apps/spreadsheeteditor/mobile/app/template/AddOther.template b/apps/spreadsheeteditor/mobile/app/template/AddOther.template index b3f467468..f20d083e8 100644 --- a/apps/spreadsheeteditor/mobile/app/template/AddOther.template +++ b/apps/spreadsheeteditor/mobile/app/template/AddOther.template @@ -82,12 +82,13 @@
    -
    <%= scope.textAddress %>
    + <% if (!android) { %>
    <%= scope.textAddress %>
    <% } %>
    ', '<% }); %>' - ].join(''), { + ].join(''))({ styles: styles, styleSize: styleSize }); diff --git a/apps/spreadsheeteditor/mobile/app/view/edit/EditChart.js b/apps/spreadsheeteditor/mobile/app/view/edit/EditChart.js index dadda1dc3..e1ed91813 100644 --- a/apps/spreadsheeteditor/mobile/app/view/edit/EditChart.js +++ b/apps/spreadsheeteditor/mobile/app/view/edit/EditChart.js @@ -160,7 +160,7 @@ define([ '<% }); %>', '', '<% }); %>' - ].join(''), { + ].join(''))({ styles: styles }); diff --git a/apps/spreadsheeteditor/sdk_dev_scripts.js b/apps/spreadsheeteditor/sdk_dev_scripts.js index 731ff6002..4fbd9869e 100644 --- a/apps/spreadsheeteditor/sdk_dev_scripts.js +++ b/apps/spreadsheeteditor/sdk_dev_scripts.js @@ -118,10 +118,13 @@ var sdk_dev_scrpipts = [ "../../../../sdkjs/common/Private/license.js", "../../../../sdkjs/cell/Private/comments.js", "../../../../sdkjs/word/Editor/Common.js", + "../../../../sdkjs/word/Editor/DocumentContentElementBase.js", + "../../../../sdkjs/word/Editor/StructuredDocumentTags/BlockLevel.js", "../../../../sdkjs/word/Editor/Comments.js", "../../../../sdkjs/word/Editor/CommentsChanges.js", "../../../../sdkjs/word/Editor/Styles.js", "../../../../sdkjs/word/Editor/StylesChanges.js", + "../../../../sdkjs/word/Editor/RevisionsChange.js", "../../../../sdkjs/word/Editor/ParagraphContent.js", "../../../../sdkjs/word/Editor/Paragraph/ParaTextPr.js", "../../../../sdkjs/word/Editor/Paragraph/ParaTextPrChanges.js", diff --git a/build/Gruntfile.js b/build/Gruntfile.js index 05a499ce5..e4021d4b2 100644 --- a/build/Gruntfile.js +++ b/build/Gruntfile.js @@ -114,7 +114,6 @@ module.exports = function(grunt) { doRegisterTask('bootstrap'); doRegisterTask('jszip'); doRegisterTask('jsziputils'); - doRegisterTask('jsrsasign'); doRegisterTask('requirejs', function(defaultConfig, packageFile) { return { uglify: { @@ -374,7 +373,6 @@ module.exports = function(grunt) { grunt.registerTask('deploy-bootstrap', ['bootstrap-init', 'clean', 'copy']); grunt.registerTask('deploy-jszip', ['jszip-init', 'clean', 'copy']); grunt.registerTask('deploy-jsziputils', ['jsziputils-init', 'clean', 'copy']); - grunt.registerTask('deploy-jsrsasign', ['jsrsasign-init', 'clean', 'copy']); grunt.registerTask('deploy-requirejs', ['requirejs-init', 'clean', 'uglify']); grunt.registerTask('deploy-app-main', ['main-app-init', 'clean', 'imagemin', 'less', 'requirejs', 'concat', diff --git a/build/common.json b/build/common.json index c5fc67f31..0a7255f78 100644 --- a/build/common.json +++ b/build/common.json @@ -162,17 +162,6 @@ } } }, - "jsrsasign": { - "clean": [ - "../deploy/web-apps/vendor/jsrsasign" - ], - "copy": { - "script": { - "src": "../vendor/jsrsasign/jsrsasign-latest-all-min.js", - "dest": "../deploy/web-apps/vendor/jsrsasign/jsrsasign-latest-all-min.js" - } - } - }, "underscore": { "clean": [ "../deploy/web-apps/vendor/underscore" @@ -206,8 +195,7 @@ "deploy-underscore", "deploy-bootstrap", "deploy-jszip", - "deploy-jsziputils", - "deploy-jsrsasign" + "deploy-jsziputils" ] } } \ No newline at end of file diff --git a/build/documenteditor.json b/build/documenteditor.json index a9ee525c2..ac7be5be4 100644 --- a/build/documenteditor.json +++ b/build/documenteditor.json @@ -30,7 +30,6 @@ "sockjs": "empty:", "jszip": "empty:", "jszip-utils": "empty:", - "jsrsasign": "empty:", "coapisettings": "empty:", "allfonts": "empty:", "sdk": "empty:", @@ -85,8 +84,7 @@ "xregexp", "sockjs", "jszip", - "jszip-utils", - "jsrsasign" + "jszip-utils" ] }, "gateway": { @@ -197,7 +195,6 @@ "sockjs": "empty:", "jszip": "empty:", "jszip-utils": "empty:", - "jsrsasign": "empty:", "coapisettings": "empty:", "allfonts": "empty:", "sdk": "empty:", @@ -255,8 +252,7 @@ "xregexp", "sockjs", "jszip", - "jszip-utils", - "jsrsasign" + "jszip-utils" ] }, "gateway": { diff --git a/build/presentationeditor.json b/build/presentationeditor.json index 7073edbb6..b3512c847 100644 --- a/build/presentationeditor.json +++ b/build/presentationeditor.json @@ -30,7 +30,6 @@ "sockjs": "empty:", "jszip": "empty:", "jszip-utils": "empty:", - "jsrsasign": "empty:", "coapisettings": "empty:", "allfonts": "empty:", "sdk": "empty:", @@ -85,8 +84,7 @@ "xregexp", "sockjs", "jszip", - "jszip-utils", - "jsrsasign" + "jszip-utils" ] }, "gateway": { @@ -197,7 +195,6 @@ "sockjs": "empty:", "jszip": "empty:", "jszip-utils": "empty:", - "jsrsasign": "empty:", "coapisettings": "empty:", "allfonts": "empty:", "sdk": "empty:", @@ -255,8 +252,7 @@ "xregexp", "sockjs", "jszip", - "jszip-utils", - "jsrsasign" + "jszip-utils" ] }, "gateway": { diff --git a/build/spreadsheeteditor.json b/build/spreadsheeteditor.json index e3655845b..2ff9bd594 100644 --- a/build/spreadsheeteditor.json +++ b/build/spreadsheeteditor.json @@ -30,7 +30,6 @@ "sockjs": "empty:", "jszip": "empty:", "jszip-utils": "empty:", - "jsrsasign": "empty:", "coapisettings": "empty:", "allfonts": "empty:", "sdk": "empty:", @@ -85,8 +84,7 @@ "xregexp", "sockjs", "jszip", - "jszip-utils", - "jsrsasign" + "jszip-utils" ] }, "gateway": { @@ -208,7 +206,6 @@ "sockjs": "empty:", "jszip": "empty:", "jszip-utils": "empty:", - "jsrsasign": "empty:", "coapisettings": "empty:", "allfonts": "empty:", "sdk": "empty:", @@ -266,8 +263,7 @@ "xregexp", "sockjs", "jszip", - "jszip-utils", - "jsrsasign" + "jszip-utils" ] }, "gateway": { diff --git a/vendor/jszip/jszip.js b/vendor/jszip/jszip.js index 1546d7fcb..6d8dcc9d9 100644 --- a/vendor/jszip/jszip.js +++ b/vendor/jszip/jszip.js @@ -1,60 +1,98 @@ /*! -JSZip - A Javascript class for generating and reading zip files +JSZip v3.1.3 - A Javascript class for generating and reading zip files -(c) 2009-2014 Stuart Knightley +(c) 2009-2016 Stuart Knightley Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. JSZip uses the library pako released under the MIT license : https://github.com/nodeca/pako/blob/master/LICENSE */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.JSZip=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; + enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64; + enc4 = remainingBytes > 2 ? (chr3 & 63) : 64; - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } - else if (isNaN(chr3)) { - enc4 = 64; - } - - output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); + output.push(_keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4)); } - return output; + return output.join(""); }; // public method for decoding -exports.decode = function(input, utf8) { - var output = ""; +exports.decode = function(input) { var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; - var i = 0; + var i = 0, resultIndex = 0; + + var dataUrlPrefix = "data:"; + + if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) { + // This is a common error: people give a data url + // (data:image/png;base64,iVBOR...) with a {base64: true} and + // wonders why things don't work. + // We can detect that the string input looks like a data url but we + // *can't* be sure it is one: removing everything up to the comma would + // be too dangerous. + throw new Error("Invalid base64 input, it looks like a data url."); + } input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + var totalLength = input.length * 3 / 4; + if(input.charAt(input.length - 1) === _keyStr.charAt(64)) { + totalLength--; + } + if(input.charAt(input.length - 2) === _keyStr.charAt(64)) { + totalLength--; + } + if (totalLength % 1 !== 0) { + // totalLength is not an integer, the length does not match a valid + // base64 content. That can happen if: + // - the input is not a base64 content + // - the input is *almost* a base64 content, with a extra chars at the + // beginning or at the end + // - the input uses a base64 variant (base64url for example) + throw new Error("Invalid base64 input, bad content length."); + } + var output; + if (support.uint8array) { + output = new Uint8Array(totalLength|0); + } else { + output = new Array(totalLength|0); + } + while (i < input.length) { enc1 = _keyStr.indexOf(input.charAt(i++)); @@ -66,178 +104,1662 @@ exports.decode = function(input, utf8) { chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; - output = output + String.fromCharCode(chr1); + output[resultIndex++] = chr1; - if (enc3 != 64) { - output = output + String.fromCharCode(chr2); + if (enc3 !== 64) { + output[resultIndex++] = chr2; } - if (enc4 != 64) { - output = output + String.fromCharCode(chr3); + if (enc4 !== 64) { + output[resultIndex++] = chr3; } } return output; - }; -},{}],2:[function(_dereq_,module,exports){ +},{"./support":30,"./utils":32}],2:[function(require,module,exports){ 'use strict'; -function CompressedObject() { - this.compressedSize = 0; - this.uncompressedSize = 0; - this.crc32 = 0; - this.compressionMethod = null; - this.compressedContent = null; + +var external = require("./external"); +var DataWorker = require('./stream/DataWorker'); +var DataLengthProbe = require('./stream/DataLengthProbe'); +var Crc32Probe = require('./stream/Crc32Probe'); +var DataLengthProbe = require('./stream/DataLengthProbe'); + +/** + * Represent a compressed object, with everything needed to decompress it. + * @constructor + * @param {number} compressedSize the size of the data compressed. + * @param {number} uncompressedSize the size of the data after decompression. + * @param {number} crc32 the crc32 of the decompressed file. + * @param {object} compression the type of compression, see lib/compressions.js. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the compressed data. + */ +function CompressedObject(compressedSize, uncompressedSize, crc32, compression, data) { + this.compressedSize = compressedSize; + this.uncompressedSize = uncompressedSize; + this.crc32 = crc32; + this.compression = compression; + this.compressedContent = data; } CompressedObject.prototype = { /** - * Return the decompressed content in an unspecified format. - * The format will depend on the decompressor. - * @return {Object} the decompressed content. + * Create a worker to get the uncompressed content. + * @return {GenericWorker} the worker. */ - getContent: function() { - return null; // see implementation + getContentWorker : function () { + var worker = new DataWorker(external.Promise.resolve(this.compressedContent)) + .pipe(this.compression.uncompressWorker()) + .pipe(new DataLengthProbe("data_length")); + + var that = this; + worker.on("end", function () { + if(this.streamInfo['data_length'] !== that.uncompressedSize) { + throw new Error("Bug : uncompressed data size mismatch"); + } + }); + return worker; }, /** - * Return the compressed content in an unspecified format. - * The format will depend on the compressed conten source. - * @return {Object} the compressed content. + * Create a worker to get the compressed content. + * @return {GenericWorker} the worker. */ - getCompressedContent: function() { - return null; // see implementation + getCompressedWorker : function () { + return new DataWorker(external.Promise.resolve(this.compressedContent)) + .withStreamInfo("compressedSize", this.compressedSize) + .withStreamInfo("uncompressedSize", this.uncompressedSize) + .withStreamInfo("crc32", this.crc32) + .withStreamInfo("compression", this.compression) + ; } }; -module.exports = CompressedObject; - -},{}],3:[function(_dereq_,module,exports){ -'use strict'; -exports.STORE = { - magic: "\x00\x00", - compress: function(content, compressionOptions) { - return content; // no compression - }, - uncompress: function(content) { - return content; // no compression - }, - compressInputType: null, - uncompressInputType: null -}; -exports.DEFLATE = _dereq_('./flate'); - -},{"./flate":8}],4:[function(_dereq_,module,exports){ -'use strict'; - -var utils = _dereq_('./utils'); - -var table = [ - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -]; /** - * - * Javascript crc32 - * http://www.webtoolkit.info/ - * + * Chain the given worker with other workers to compress the content with the + * given compresion. + * @param {GenericWorker} uncompressedWorker the worker to pipe. + * @param {Object} compression the compression object. + * @param {Object} compressionOptions the options to use when compressing. + * @return {GenericWorker} the new worker compressing the content. */ -module.exports = function crc32(input, crc) { +CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions) { + return uncompressedWorker + .pipe(new Crc32Probe()) + .pipe(new DataLengthProbe("uncompressedSize")) + .pipe(compression.compressWorker(compressionOptions)) + .pipe(new DataLengthProbe("compressedSize")) + .withStreamInfo("compression", compression); +}; + +module.exports = CompressedObject; + +},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(require,module,exports){ +'use strict'; + +var GenericWorker = require("./stream/GenericWorker"); + +exports.STORE = { + magic: "\x00\x00", + compressWorker : function (compressionOptions) { + return new GenericWorker("STORE compression"); + }, + uncompressWorker : function () { + return new GenericWorker("STORE decompression"); + } +}; +exports.DEFLATE = require('./flate'); + +},{"./flate":7,"./stream/GenericWorker":28}],4:[function(require,module,exports){ +'use strict'; + +var utils = require('./utils'); + +/** + * The following functions come from pako, from pako/lib/zlib/crc32.js + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for(var n =0; n < 256; n++){ + c = n; + for(var k =0; k < 8; k++){ + c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable, end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + +// That's all for the pako functions. + +/** + * Compute the crc32 of a string. + * This is almost the same as the function crc32, but for strings. Using the + * same function for the two use cases leads to horrible performances. + * @param {Number} crc the starting value of the crc. + * @param {String} str the string to use. + * @param {Number} len the length of the string. + * @param {Number} pos the starting position for the crc32 computation. + * @return {Number} the computed crc32. + */ +function crc32str(crc, str, len, pos) { + var t = crcTable, end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ str.charCodeAt(i)) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + +module.exports = function crc32wrapper(input, crc) { if (typeof input === "undefined" || !input.length) { return 0; } var isArray = utils.getTypeOf(input) !== "string"; - if (typeof(crc) == "undefined") { - crc = 0; + if(isArray) { + return crc32(crc|0, input, input.length, 0); + } else { + return crc32str(crc|0, input, input.length, 0); } - var x = 0; - var y = 0; - var b = 0; - - crc = crc ^ (-1); - for (var i = 0, iTop = input.length; i < iTop; i++) { - b = isArray ? input[i] : input.charCodeAt(i); - y = (crc ^ b) & 0xFF; - x = table[y]; - crc = (crc >>> 8) ^ x; - } - - return crc ^ (-1); }; // vim: set shiftwidth=4 softtabstop=4: -},{"./utils":21}],5:[function(_dereq_,module,exports){ +},{"./utils":32}],5:[function(require,module,exports){ 'use strict'; -var utils = _dereq_('./utils'); +exports.base64 = false; +exports.binary = false; +exports.dir = false; +exports.createFolders = true; +exports.date = null; +exports.compression = null; +exports.compressionOptions = null; +exports.comment = null; +exports.unixPermissions = null; +exports.dosPermissions = null; + +},{}],6:[function(require,module,exports){ +/* global Promise */ +'use strict'; + +// load the global object first: +// - it should be better integrated in the system (unhandledRejection in node) +// - the environment may have a custom Promise implementation (see zone.js) +var ES6Promise = null; +if (typeof Promise !== "undefined") { + ES6Promise = Promise; +} else { + ES6Promise = require("lie"); +} + +/** + * Let the user use/change some implementations. + */ +module.exports = { + Promise: ES6Promise +}; + +},{"lie":58}],7:[function(require,module,exports){ +'use strict'; +var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); + +var pako = require("pako"); +var utils = require("./utils"); +var GenericWorker = require("./stream/GenericWorker"); + +var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array"; + +exports.magic = "\x08\x00"; + +/** + * Create a worker that uses pako to inflate/deflate. + * @constructor + * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate". + * @param {Object} options the options to use when (de)compressing. + */ +function FlateWorker(action, options) { + GenericWorker.call(this, "FlateWorker/" + action); + + this._pako = new pako[action]({ + raw:true, + level : options.level || -1 // default compression + }); + // the `meta` object from the last chunk received + // this allow this worker to pass around metadata + this.meta = {}; + + var self = this; + this._pako.onData = function(data) { + self.push({ + data : data, + meta : self.meta + }); + }; +} + +utils.inherits(FlateWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +FlateWorker.prototype.processChunk = function (chunk) { + this.meta = chunk.meta; + this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false); +}; + +/** + * @see GenericWorker.flush + */ +FlateWorker.prototype.flush = function () { + GenericWorker.prototype.flush.call(this); + this._pako.push([], true); +}; +/** + * @see GenericWorker.cleanUp + */ +FlateWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this._pako = null; +}; + +exports.compressWorker = function (compressionOptions) { + return new FlateWorker("Deflate", compressionOptions); +}; +exports.uncompressWorker = function () { + return new FlateWorker("Inflate", {}); +}; + +},{"./stream/GenericWorker":28,"./utils":32,"pako":59}],8:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var GenericWorker = require('../stream/GenericWorker'); +var utf8 = require('../utf8'); +var crc32 = require('../crc32'); +var signature = require('../signature'); + +/** + * Transform an integer into a string in hexadecimal. + * @private + * @param {number} dec the number to convert. + * @param {number} bytes the number of bytes to generate. + * @returns {string} the result. + */ +var decToHex = function(dec, bytes) { + var hex = "", i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 0xff); + dec = dec >>> 8; + } + return hex; +}; + +/** + * Generate the UNIX part of the external file attributes. + * @param {Object} unixPermissions the unix permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : + * + * TTTTsstrwxrwxrwx0000000000ADVSHR + * ^^^^____________________________ file type, see zipinfo.c (UNX_*) + * ^^^_________________________ setuid, setgid, sticky + * ^^^^^^^^^________________ permissions + * ^^^^^^^^^^______ not used ? + * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only + */ +var generateUnixExternalFileAttr = function (unixPermissions, isDir) { + + var result = unixPermissions; + if (!unixPermissions) { + // I can't use octal values in strict mode, hence the hexa. + // 040775 => 0x41fd + // 0100664 => 0x81b4 + result = isDir ? 0x41fd : 0x81b4; + } + return (result & 0xFFFF) << 16; +}; + +/** + * Generate the DOS part of the external file attributes. + * @param {Object} dosPermissions the dos permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * Bit 0 Read-Only + * Bit 1 Hidden + * Bit 2 System + * Bit 3 Volume Label + * Bit 4 Directory + * Bit 5 Archive + */ +var generateDosExternalFileAttr = function (dosPermissions, isDir) { + + // the dir flag is already set for compatibility + return (dosPermissions || 0) & 0x3F; +}; + +/** + * Generate the various parts used in the construction of the final zip file. + * @param {Object} streamInfo the hash with informations about the compressed file. + * @param {Boolean} streamedContent is the content streamed ? + * @param {Boolean} streamingEnded is the stream finished ? + * @param {number} offset the current offset from the start of the zip file. + * @param {String} platform let's pretend we are this platform (change platform dependents fields) + * @param {Function} encodeFileName the function to encode the file name / comment. + * @return {Object} the zip parts. + */ +var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) { + var file = streamInfo['file'], + compression = streamInfo['compression'], + useCustomEncoding = encodeFileName !== utf8.utf8encode, + encodedFileName = utils.transformTo("string", encodeFileName(file.name)), + utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), + comment = file.comment, + encodedComment = utils.transformTo("string", encodeFileName(comment)), + utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), + useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, + useUTF8ForComment = utfEncodedComment.length !== comment.length, + dosTime, + dosDate, + extraFields = "", + unicodePathExtraField = "", + unicodeCommentExtraField = "", + dir = file.dir, + date = file.date; + + + var dataInfo = { + crc32 : 0, + compressedSize : 0, + uncompressedSize : 0 + }; + + // if the content is streamed, the sizes/crc32 are only available AFTER + // the end of the stream. + if (!streamedContent || streamingEnded) { + dataInfo.crc32 = streamInfo['crc32']; + dataInfo.compressedSize = streamInfo['compressedSize']; + dataInfo.uncompressedSize = streamInfo['uncompressedSize']; + } + + var bitflag = 0; + if (streamedContent) { + // Bit 3: the sizes/crc32 are set to zero in the local header. + // The correct values are put in the data descriptor immediately + // following the compressed data. + bitflag |= 0x0008; + } + if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) { + // Bit 11: Language encoding flag (EFS). + bitflag |= 0x0800; + } + + + var extFileAttr = 0; + var versionMadeBy = 0; + if (dir) { + // dos or unix, we set the dos dir flag + extFileAttr |= 0x00010; + } + if(platform === "UNIX") { + versionMadeBy = 0x031E; // UNIX, version 3.0 + extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); + } else { // DOS or other, fallback to DOS + versionMadeBy = 0x0014; // DOS, version 2.0 + extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); + } + + // date + // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html + + dosTime = date.getUTCHours(); + dosTime = dosTime << 6; + dosTime = dosTime | date.getUTCMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | date.getUTCSeconds() / 2; + + dosDate = date.getUTCFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | (date.getUTCMonth() + 1); + dosDate = dosDate << 5; + dosDate = dosDate | date.getUTCDate(); + + if (useUTF8ForFileName) { + // set the unicode path extra field. unzip needs at least one extra + // field to correctly handle unicode path, so using the path is as good + // as any other information. This could improve the situation with + // other archive managers too. + // This field is usually used without the utf8 flag, with a non + // unicode path in the header (winrar, winzip). This helps (a bit) + // with the messy Windows' default compressed folders feature but + // breaks on p7zip which doesn't seek the unicode path extra field. + // So for now, UTF-8 everywhere ! + unicodePathExtraField = + // Version + decToHex(1, 1) + + // NameCRC32 + decToHex(crc32(encodedFileName), 4) + + // UnicodeName + utfEncodedFileName; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x70" + + // size + decToHex(unicodePathExtraField.length, 2) + + // content + unicodePathExtraField; + } + + if(useUTF8ForComment) { + + unicodeCommentExtraField = + // Version + decToHex(1, 1) + + // CommentCRC32 + decToHex(crc32(encodedComment), 4) + + // UnicodeName + utfEncodedComment; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x63" + + // size + decToHex(unicodeCommentExtraField.length, 2) + + // content + unicodeCommentExtraField; + } + + var header = ""; + + // version needed to extract + header += "\x0A\x00"; + // general purpose bit flag + header += decToHex(bitflag, 2); + // compression method + header += compression.magic; + // last mod file time + header += decToHex(dosTime, 2); + // last mod file date + header += decToHex(dosDate, 2); + // crc-32 + header += decToHex(dataInfo.crc32, 4); + // compressed size + header += decToHex(dataInfo.compressedSize, 4); + // uncompressed size + header += decToHex(dataInfo.uncompressedSize, 4); + // file name length + header += decToHex(encodedFileName.length, 2); + // extra field length + header += decToHex(extraFields.length, 2); + + + var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields; + + var dirRecord = signature.CENTRAL_FILE_HEADER + + // version made by (00: DOS) + decToHex(versionMadeBy, 2) + + // file header (common to file and central directory) + header + + // file comment length + decToHex(encodedComment.length, 2) + + // disk number start + "\x00\x00" + + // internal file attributes TODO + "\x00\x00" + + // external file attributes + decToHex(extFileAttr, 4) + + // relative offset of local header + decToHex(offset, 4) + + // file name + encodedFileName + + // extra field + extraFields + + // file comment + encodedComment; + + return { + fileRecord: fileRecord, + dirRecord: dirRecord + }; +}; + +/** + * Generate the EOCD record. + * @param {Number} entriesCount the number of entries in the zip file. + * @param {Number} centralDirLength the length (in bytes) of the central dir. + * @param {Number} localDirLength the length (in bytes) of the local dir. + * @param {String} comment the zip file comment as a binary string. + * @param {Function} encodeFileName the function to encode the comment. + * @return {String} the EOCD record. + */ +var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) { + var dirEnd = ""; + var encodedComment = utils.transformTo("string", encodeFileName(comment)); + + // end of central dir signature + dirEnd = signature.CENTRAL_DIRECTORY_END + + // number of this disk + "\x00\x00" + + // number of the disk with the start of the central directory + "\x00\x00" + + // total number of entries in the central directory on this disk + decToHex(entriesCount, 2) + + // total number of entries in the central directory + decToHex(entriesCount, 2) + + // size of the central directory 4 bytes + decToHex(centralDirLength, 4) + + // offset of start of central directory with respect to the starting disk number + decToHex(localDirLength, 4) + + // .ZIP file comment length + decToHex(encodedComment.length, 2) + + // .ZIP file comment + encodedComment; + + return dirEnd; +}; + +/** + * Generate data descriptors for a file entry. + * @param {Object} streamInfo the hash generated by a worker, containing informations + * on the file entry. + * @return {String} the data descriptors. + */ +var generateDataDescriptors = function (streamInfo) { + var descriptor = ""; + descriptor = signature.DATA_DESCRIPTOR + + // crc-32 4 bytes + decToHex(streamInfo['crc32'], 4) + + // compressed size 4 bytes + decToHex(streamInfo['compressedSize'], 4) + + // uncompressed size 4 bytes + decToHex(streamInfo['uncompressedSize'], 4); + + return descriptor; +}; + + +/** + * A worker to concatenate other workers to create a zip file. + * @param {Boolean} streamFiles `true` to stream the content of the files, + * `false` to accumulate it. + * @param {String} comment the comment to use. + * @param {String} platform the platform to use, "UNIX" or "DOS". + * @param {Function} encodeFileName the function to encode file names and comments. + */ +function ZipFileWorker(streamFiles, comment, platform, encodeFileName) { + GenericWorker.call(this, "ZipFileWorker"); + // The number of bytes written so far. This doesn't count accumulated chunks. + this.bytesWritten = 0; + // The comment of the zip file + this.zipComment = comment; + // The platform "generating" the zip file. + this.zipPlatform = platform; + // the function to encode file names and comments. + this.encodeFileName = encodeFileName; + // Should we stream the content of the files ? + this.streamFiles = streamFiles; + // If `streamFiles` is false, we will need to accumulate the content of the + // files to calculate sizes / crc32 (and write them *before* the content). + // This boolean indicates if we are accumulating chunks (it will change a lot + // during the lifetime of this worker). + this.accumulate = false; + // The buffer receiving chunks when accumulating content. + this.contentBuffer = []; + // The list of generated directory records. + this.dirRecords = []; + // The offset (in bytes) from the beginning of the zip file for the current source. + this.currentSourceOffset = 0; + // The total number of entries in this zip file. + this.entriesCount = 0; + // the name of the file currently being added, null when handling the end of the zip file. + // Used for the emited metadata. + this.currentFile = null; + + + + this._sources = []; +} +utils.inherits(ZipFileWorker, GenericWorker); + +/** + * @see GenericWorker.push + */ +ZipFileWorker.prototype.push = function (chunk) { + + var currentFilePercent = chunk.meta.percent || 0; + var entriesCount = this.entriesCount; + var remainingFiles = this._sources.length; + + if(this.accumulate) { + this.contentBuffer.push(chunk); + } else { + this.bytesWritten += chunk.data.length; + + GenericWorker.prototype.push.call(this, { + data : chunk.data, + meta : { + currentFile : this.currentFile, + percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100 + } + }); + } +}; + +/** + * The worker started a new source (an other worker). + * @param {Object} streamInfo the streamInfo object from the new source. + */ +ZipFileWorker.prototype.openedSource = function (streamInfo) { + this.currentSourceOffset = this.bytesWritten; + this.currentFile = streamInfo['file'].name; + + var streamedContent = this.streamFiles && !streamInfo['file'].dir; + + // don't stream folders (because they don't have any content) + if(streamedContent) { + var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); + this.push({ + data : record.fileRecord, + meta : {percent:0} + }); + } else { + // we need to wait for the whole file before pushing anything + this.accumulate = true; + } +}; + +/** + * The worker finished a source (an other worker). + * @param {Object} streamInfo the streamInfo object from the finished source. + */ +ZipFileWorker.prototype.closedSource = function (streamInfo) { + this.accumulate = false; + var streamedContent = this.streamFiles && !streamInfo['file'].dir; + var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); + + this.dirRecords.push(record.dirRecord); + if(streamedContent) { + // after the streamed file, we put data descriptors + this.push({ + data : generateDataDescriptors(streamInfo), + meta : {percent:100} + }); + } else { + // the content wasn't streamed, we need to push everything now + // first the file record, then the content + this.push({ + data : record.fileRecord, + meta : {percent:0} + }); + while(this.contentBuffer.length) { + this.push(this.contentBuffer.shift()); + } + } + this.currentFile = null; +}; + +/** + * @see GenericWorker.flush + */ +ZipFileWorker.prototype.flush = function () { + + var localDirLength = this.bytesWritten; + for(var i = 0; i < this.dirRecords.length; i++) { + this.push({ + data : this.dirRecords[i], + meta : {percent:100} + }); + } + var centralDirLength = this.bytesWritten - localDirLength; + + var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName); + + this.push({ + data : dirEnd, + meta : {percent:100} + }); +}; + +/** + * Prepare the next source to be read. + */ +ZipFileWorker.prototype.prepareNextSource = function () { + this.previous = this._sources.shift(); + this.openedSource(this.previous.streamInfo); + if (this.isPaused) { + this.previous.pause(); + } else { + this.previous.resume(); + } +}; + +/** + * @see GenericWorker.registerPrevious + */ +ZipFileWorker.prototype.registerPrevious = function (previous) { + this._sources.push(previous); + var self = this; + + previous.on('data', function (chunk) { + self.processChunk(chunk); + }); + previous.on('end', function () { + self.closedSource(self.previous.streamInfo); + if(self._sources.length) { + self.prepareNextSource(); + } else { + self.end(); + } + }); + previous.on('error', function (e) { + self.error(e); + }); + return this; +}; + +/** + * @see GenericWorker.resume + */ +ZipFileWorker.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if (!this.previous && this._sources.length) { + this.prepareNextSource(); + return true; + } + if (!this.previous && !this._sources.length && !this.generatedError) { + this.end(); + return true; + } +}; + +/** + * @see GenericWorker.error + */ +ZipFileWorker.prototype.error = function (e) { + var sources = this._sources; + if(!GenericWorker.prototype.error.call(this, e)) { + return false; + } + for(var i = 0; i < sources.length; i++) { + try { + sources[i].error(e); + } catch(e) { + // the `error` exploded, nothing to do + } + } + return true; +}; + +/** + * @see GenericWorker.lock + */ +ZipFileWorker.prototype.lock = function () { + GenericWorker.prototype.lock.call(this); + var sources = this._sources; + for(var i = 0; i < sources.length; i++) { + sources[i].lock(); + } +}; + +module.exports = ZipFileWorker; + +},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(require,module,exports){ +'use strict'; + +var compressions = require('../compressions'); +var ZipFileWorker = require('./ZipFileWorker'); + +/** + * Find the compression to use. + * @param {String} fileCompression the compression defined at the file level, if any. + * @param {String} zipCompression the compression defined at the load() level. + * @return {Object} the compression object to use. + */ +var getCompression = function (fileCompression, zipCompression) { + + var compressionName = fileCompression || zipCompression; + var compression = compressions[compressionName]; + if (!compression) { + throw new Error(compressionName + " is not a valid compression method !"); + } + return compression; +}; + +/** + * Create a worker to generate a zip file. + * @param {JSZip} zip the JSZip instance at the right root level. + * @param {Object} options to generate the zip file. + * @param {String} comment the comment to use. + */ +exports.generateWorker = function (zip, options, comment) { + + var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName); + var entriesCount = 0; + try { + + zip.forEach(function (relativePath, file) { + entriesCount++; + var compression = getCompression(file.options.compression, options.compression); + var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; + var dir = file.dir, date = file.date; + + file._compressWorker(compression, compressionOptions) + .withStreamInfo("file", { + name : relativePath, + dir : dir, + date : date, + comment : file.comment || "", + unixPermissions : file.unixPermissions, + dosPermissions : file.dosPermissions + }) + .pipe(zipFileWorker); + }); + zipFileWorker.entriesCount = entriesCount; + } catch (e) { + zipFileWorker.error(e); + } + + return zipFileWorker; +}; + +},{"../compressions":3,"./ZipFileWorker":8}],10:[function(require,module,exports){ +'use strict'; + +/** + * Representation a of zip file in js + * @constructor + */ +function JSZip() { + // if this constructor is used without `new`, it adds `new` before itself: + if(!(this instanceof JSZip)) { + return new JSZip(); + } + + if(arguments.length) { + throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide."); + } + + // object containing the files : + // { + // "folder/" : {...}, + // "folder/data.txt" : {...} + // } + this.files = {}; + + this.comment = null; + + // Where we are in the hierarchy + this.root = ""; + this.clone = function() { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }; +} +JSZip.prototype = require('./object'); +JSZip.prototype.loadAsync = require('./load'); +JSZip.support = require('./support'); +JSZip.defaults = require('./defaults'); + +// TODO find a better way to handle this version, +// a require('package.json').version doesn't work with webpack, see #327 +JSZip.version = "3.1.3"; + +JSZip.loadAsync = function (content, options) { + return new JSZip().loadAsync(content, options); +}; + +JSZip.external = require("./external"); +module.exports = JSZip; + +},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(require,module,exports){ +'use strict'; +var utils = require('./utils'); +var external = require("./external"); +var utf8 = require('./utf8'); +var utils = require('./utils'); +var ZipEntries = require('./zipEntries'); +var Crc32Probe = require('./stream/Crc32Probe'); +var nodejsUtils = require("./nodejsUtils"); + +/** + * Check the CRC32 of an entry. + * @param {ZipEntry} zipEntry the zip entry to check. + * @return {Promise} the result. + */ +function checkEntryCRC32(zipEntry) { + return new external.Promise(function (resolve, reject) { + var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe()); + worker.on("error", function (e) { + reject(e); + }) + .on("end", function () { + if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) { + reject(new Error("Corrupted zip : CRC32 mismatch")); + } else { + resolve(); + } + }) + .resume(); + }); +} + +module.exports = function(data, options) { + var zip = this; + options = utils.extend(options || {}, { + base64: false, + checkCRC32: false, + optimizedBinaryString: false, + createFolders: false, + decodeFileName: utf8.utf8decode + }); + + if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { + return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")); + } + + return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64) + .then(function(data) { + var zipEntries = new ZipEntries(options); + zipEntries.load(data); + return zipEntries; + }).then(function checkCRC32(zipEntries) { + var promises = [external.Promise.resolve(zipEntries)]; + var files = zipEntries.files; + if (options.checkCRC32) { + for (var i = 0; i < files.length; i++) { + promises.push(checkEntryCRC32(files[i])); + } + } + return external.Promise.all(promises); + }).then(function addFiles(results) { + var zipEntries = results.shift(); + var files = zipEntries.files; + for (var i = 0; i < files.length; i++) { + var input = files[i]; + zip.file(input.fileNameStr, input.decompressed, { + binary: true, + optimizedBinaryString: true, + date: input.date, + dir: input.dir, + comment : input.fileCommentStr.length ? input.fileCommentStr : null, + unixPermissions : input.unixPermissions, + dosPermissions : input.dosPermissions, + createFolders: options.createFolders + }); + } + if (zipEntries.zipComment.length) { + zip.comment = zipEntries.zipComment; + } + + return zip; + }); +}; + +},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(require,module,exports){ +"use strict"; + +var utils = require('../utils'); +var GenericWorker = require('../stream/GenericWorker'); + +/** + * A worker that use a nodejs stream as source. + * @constructor + * @param {String} filename the name of the file entry for this stream. + * @param {Readable} stream the nodejs stream. + */ +function NodejsStreamInputAdapter(filename, stream) { + GenericWorker.call(this, "Nodejs stream input adapter for " + filename); + this._upstreamEnded = false; + this._bindStream(stream); +} + +utils.inherits(NodejsStreamInputAdapter, GenericWorker); + +/** + * Prepare the stream and bind the callbacks on it. + * Do this ASAP on node 0.10 ! A lazy binding doesn't always work. + * @param {Stream} stream the nodejs stream to use. + */ +NodejsStreamInputAdapter.prototype._bindStream = function (stream) { + var self = this; + this._stream = stream; + stream.pause(); + stream + .on("data", function (chunk) { + self.push({ + data: chunk, + meta : { + percent : 0 + } + }); + }) + .on("error", function (e) { + if(self.isPaused) { + this.generatedError = e; + } else { + self.error(e); + } + }) + .on("end", function () { + if(self.isPaused) { + self._upstreamEnded = true; + } else { + self.end(); + } + }); +}; +NodejsStreamInputAdapter.prototype.pause = function () { + if(!GenericWorker.prototype.pause.call(this)) { + return false; + } + this._stream.pause(); + return true; +}; +NodejsStreamInputAdapter.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if(this._upstreamEnded) { + this.end(); + } else { + this._stream.resume(); + } + + return true; +}; + +module.exports = NodejsStreamInputAdapter; + +},{"../stream/GenericWorker":28,"../utils":32}],13:[function(require,module,exports){ +'use strict'; + +var Readable = require('readable-stream').Readable; + +var util = require('util'); +util.inherits(NodejsStreamOutputAdapter, Readable); + +/** +* A nodejs stream using a worker as source. +* @see the SourceWrapper in http://nodejs.org/api/stream.html +* @constructor +* @param {StreamHelper} helper the helper wrapping the worker +* @param {Object} options the nodejs stream options +* @param {Function} updateCb the update callback. +*/ +function NodejsStreamOutputAdapter(helper, options, updateCb) { + Readable.call(this, options); + this._helper = helper; + + var self = this; + helper.on("data", function (data, meta) { + if (!self.push(data)) { + self._helper.pause(); + } + if(updateCb) { + updateCb(meta); + } + }) + .on("error", function(e) { + self.emit('error', e); + }) + .on("end", function () { + self.push(null); + }); +} + + +NodejsStreamOutputAdapter.prototype._read = function() { + this._helper.resume(); +}; + +module.exports = NodejsStreamOutputAdapter; + +},{"readable-stream":16,"util":undefined}],14:[function(require,module,exports){ +'use strict'; + +module.exports = { + /** + * True if this is running in Nodejs, will be undefined in a browser. + * In a browser, browserify won't include this file and the whole module + * will be resolved an empty object. + */ + isNode : typeof Buffer !== "undefined", + /** + * Create a new nodejs Buffer. + * @param {Object} data the data to pass to the constructor. + * @param {String} encoding the encoding to use. + * @return {Buffer} a new Buffer. + */ + newBuffer : function(data, encoding){ + return new Buffer(data, encoding); + }, + /** + * Find out if an object is a Buffer. + * @param {Object} b the object to test. + * @return {Boolean} true if the object is a Buffer, false otherwise. + */ + isBuffer : function(b){ + return Buffer.isBuffer(b); + }, + + isStream : function (obj) { + return obj && + typeof obj.on === "function" && + typeof obj.pause === "function" && + typeof obj.resume === "function"; + } +}; + +},{}],15:[function(require,module,exports){ +'use strict'; +var utf8 = require('./utf8'); +var utils = require('./utils'); +var GenericWorker = require('./stream/GenericWorker'); +var StreamHelper = require('./stream/StreamHelper'); +var defaults = require('./defaults'); +var CompressedObject = require('./compressedObject'); +var ZipObject = require('./zipObject'); +var generate = require("./generate"); +var nodejsUtils = require("./nodejsUtils"); +var NodejsStreamInputAdapter = require("./nodejs/NodejsStreamInputAdapter"); + + +/** + * Add a file in the current folder. + * @private + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file + * @param {Object} originalOptions the options of the file + * @return {Object} the new file. + */ +var fileAdd = function(name, data, originalOptions) { + // be sure sub folders exist + var dataType = utils.getTypeOf(data), + parent; + + + /* + * Correct options. + */ + + var o = utils.extend(originalOptions || {}, defaults); + o.date = o.date || new Date(); + if (o.compression !== null) { + o.compression = o.compression.toUpperCase(); + } + + if (typeof o.unixPermissions === "string") { + o.unixPermissions = parseInt(o.unixPermissions, 8); + } + + // UNX_IFDIR 0040000 see zipinfo.c + if (o.unixPermissions && (o.unixPermissions & 0x4000)) { + o.dir = true; + } + // Bit 4 Directory + if (o.dosPermissions && (o.dosPermissions & 0x0010)) { + o.dir = true; + } + + if (o.dir) { + name = forceTrailingSlash(name); + } + if (o.createFolders && (parent = parentFolder(name))) { + folderAdd.call(this, parent, true); + } + + var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false; + if (!originalOptions || typeof originalOptions.binary === "undefined") { + o.binary = !isUnicodeString; + } + + + var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0; + + if (isCompressedEmpty || o.dir || !data || data.length === 0) { + o.base64 = false; + o.binary = true; + data = ""; + o.compression = "STORE"; + dataType = "string"; + } + + /* + * Convert content to fit. + */ + + var zipObjectContent = null; + if (data instanceof CompressedObject || data instanceof GenericWorker) { + zipObjectContent = data; + } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { + zipObjectContent = new NodejsStreamInputAdapter(name, data); + } else { + zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64); + } + + var object = new ZipObject(name, zipObjectContent, o); + this.files[name] = object; + /* + TODO: we can't throw an exception because we have async promises + (we can have a promise of a Date() for example) but returning a + promise is useless because file(name, data) returns the JSZip + object for chaining. Should we break that to allow the user + to catch the error ? + + return external.Promise.resolve(zipObjectContent) + .then(function () { + return object; + }); + */ +}; + +/** + * Find the parent folder of the path. + * @private + * @param {string} path the path to use + * @return {string} the parent folder, or "" + */ +var parentFolder = function (path) { + if (path.slice(-1) === '/') { + path = path.substring(0, path.length - 1); + } + var lastSlash = path.lastIndexOf('/'); + return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; +}; + +/** + * Returns the path with a slash at the end. + * @private + * @param {String} path the path to check. + * @return {String} the path with a trailing slash. + */ +var forceTrailingSlash = function(path) { + // Check the name ends with a / + if (path.slice(-1) !== "/") { + path += "/"; // IE doesn't like substr(-1) + } + return path; +}; + +/** + * Add a (sub) folder in the current folder. + * @private + * @param {string} name the folder's name + * @param {boolean=} [createFolders] If true, automatically create sub + * folders. Defaults to false. + * @return {Object} the new folder. + */ +var folderAdd = function(name, createFolders) { + createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders; + + name = forceTrailingSlash(name); + + // Does this folder already exist? + if (!this.files[name]) { + fileAdd.call(this, name, null, { + dir: true, + createFolders: createFolders + }); + } + return this.files[name]; +}; + +/** +* Cross-window, cross-Node-context regular expression detection +* @param {Object} object Anything +* @return {Boolean} true if the object is a regular expression, +* false otherwise +*/ +function isRegExp(object) { + return Object.prototype.toString.call(object) === "[object RegExp]"; +} + +// return the actual prototype of JSZip +var out = { + /** + * @see loadAsync + */ + load: function() { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); + }, + + + /** + * Call a callback function for each entry at this folder level. + * @param {Function} cb the callback function: + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + */ + forEach: function(cb) { + var filename, relativePath, file; + for (filename in this.files) { + if (!this.files.hasOwnProperty(filename)) { + continue; + } + file = this.files[filename]; + relativePath = filename.slice(this.root.length, filename.length); + if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root + cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn... + } + } + }, + + /** + * Filter nested files/folders with the specified function. + * @param {Function} search the predicate to use : + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + * @return {Array} An array of matching elements. + */ + filter: function(search) { + var result = []; + this.forEach(function (relativePath, entry) { + if (search(relativePath, entry)) { // the file matches the function + result.push(entry); + } + + }); + return result; + }, + + /** + * Add a file to the zip file, or search a file. + * @param {string|RegExp} name The name of the file to add (if data is defined), + * the name of the file to find (if no data) or a regex to match files. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded + * @param {Object} o File options + * @return {JSZip|Object|Array} this JSZip object (when adding a file), + * a file (when searching by string) or an array of files (when searching by regex). + */ + file: function(name, data, o) { + if (arguments.length === 1) { + if (isRegExp(name)) { + var regexp = name; + return this.filter(function(relativePath, file) { + return !file.dir && regexp.test(relativePath); + }); + } + else { // text + var obj = this.files[this.root + name]; + if (obj && !obj.dir) { + return obj; + } else { + return null; + } + } + } + else { // more than one argument : we have data ! + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, + + /** + * Add a directory to the zip file, or search. + * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. + * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. + */ + folder: function(arg) { + if (!arg) { + return this; + } + + if (isRegExp(arg)) { + return this.filter(function(relativePath, file) { + return file.dir && arg.test(relativePath); + }); + } + + // else, name is a new folder + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + + // Allow chaining by returning a new object with this folder as the root + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, + + /** + * Delete a file, or a directory and all sub-files, from the zip + * @param {string} name the name of the file to delete + * @return {JSZip} this JSZip object + */ + remove: function(name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + // Look for any folders + if (name.slice(-1) !== "/") { + name += "/"; + } + file = this.files[name]; + } + + if (file && !file.dir) { + // file + delete this.files[name]; + } else { + // maybe a folder, delete recursively + var kids = this.filter(function(relativePath, file) { + return file.name.slice(0, name.length) === name; + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } + } + + return this; + }, + + /** + * Generate the complete zip file + * @param {Object} options the options to generate the zip file : + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file + */ + generate: function(options) { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); + }, + + /** + * Generate the complete zip file as an internal stream. + * @param {Object} options the options to generate the zip file : + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {StreamHelper} the streamed zip file. + */ + generateInternalStream: function(options) { + var worker, opts = {}; + try { + opts = utils.extend(options || {}, { + streamFiles: false, + compression: "STORE", + compressionOptions : null, + type: "", + platform: "DOS", + comment: null, + mimeType: 'application/zip', + encodeFileName: utf8.utf8encode + }); + + opts.type = opts.type.toLowerCase(); + opts.compression = opts.compression.toUpperCase(); + + // "binarystring" is prefered but the internals use "string". + if(opts.type === "binarystring") { + opts.type = "string"; + } + + if (!opts.type) { + throw new Error("No output type specified."); + } + + utils.checkSupport(opts.type); + + // accept nodejs `process.platform` + if( + opts.platform === 'darwin' || + opts.platform === 'freebsd' || + opts.platform === 'linux' || + opts.platform === 'sunos' + ) { + opts.platform = "UNIX"; + } + if (opts.platform === 'win32') { + opts.platform = "DOS"; + } + + var comment = opts.comment || this.comment || ""; + worker = generate.generateWorker(this, opts, comment); + } catch (e) { + worker = new GenericWorker("error"); + worker.error(e); + } + return new StreamHelper(worker, opts.type || "string", opts.mimeType); + }, + /** + * Generate the complete zip file asynchronously. + * @see generateInternalStream + */ + generateAsync: function(options, onUpdate) { + return this.generateInternalStream(options).accumulate(onUpdate); + }, + /** + * Generate the complete zip file asynchronously. + * @see generateInternalStream + */ + generateNodeStream: function(options, onUpdate) { + options = options || {}; + if (!options.type) { + options.type = "nodebuffer"; + } + return this.generateInternalStream(options).toNodejsStream(onUpdate); + } +}; +module.exports = out; + +},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(require,module,exports){ +/* + * This file is used by module bundlers (browserify/webpack/etc) when + * including a stream implementation. We use "readable-stream" to get a + * consistent behavior between nodejs versions but bundlers often have a shim + * for "stream". Using this shim greatly improve the compatibility and greatly + * reduce the final size of the bundle (only one stream implementation, not + * two). + */ +module.exports = require("stream"); + +},{"stream":undefined}],17:[function(require,module,exports){ +'use strict'; +var DataReader = require('./DataReader'); +var utils = require('../utils'); + +function ArrayReader(data) { + DataReader.call(this, data); + for(var i = 0; i < this.data.length; i++) { + data[i] = data[i] & 0xFF; + } +} +utils.inherits(ArrayReader, DataReader); +/** + * @see DataReader.byteAt + */ +ArrayReader.prototype.byteAt = function(i) { + return this.data[this.zero + i]; +}; +/** + * @see DataReader.lastIndexOfSignature + */ +ArrayReader.prototype.lastIndexOfSignature = function(sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3); + for (var i = this.length - 4; i >= 0; --i) { + if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { + return i - this.zero; + } + } + + return -1; +}; +/** + * @see DataReader.readAndCheckSignature + */ +ArrayReader.prototype.readAndCheckSignature = function (sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3), + data = this.readData(4); + return sig0 === data[0] && sig1 === data[1] && sig2 === data[2] && sig3 === data[3]; +}; +/** + * @see DataReader.readData + */ +ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + return []; + } + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = ArrayReader; + +},{"../utils":32,"./DataReader":18}],18:[function(require,module,exports){ +'use strict'; +var utils = require('../utils'); function DataReader(data) { - this.data = null; // type : see implementation - this.length = 0; + this.data = data; // type : see implementation + this.length = data.length; this.index = 0; + this.zero = 0; } DataReader.prototype = { /** @@ -254,7 +1776,7 @@ DataReader.prototype = { * @throws {Error} an Error if the index is out of bounds. */ checkIndex: function(newIndex) { - if (this.length < newIndex || newIndex < 0) { + if (this.length < this.zero + newIndex || newIndex < 0) { throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); } }, @@ -322,1194 +1844,149 @@ DataReader.prototype = { lastIndexOfSignature: function(sig) { // see implementations }, + /** + * Read the signature (4 bytes) at the current position and compare it with sig. + * @param {string} sig the expected signature + * @return {boolean} true if the signature matches, false otherwise. + */ + readAndCheckSignature: function(sig) { + // see implementations + }, /** * Get the next date. * @return {Date} the date. */ readDate: function() { var dostime = this.readInt(4); - return new Date( + return new Date(Date.UTC( ((dostime >> 25) & 0x7f) + 1980, // year ((dostime >> 21) & 0x0f) - 1, // month (dostime >> 16) & 0x1f, // day (dostime >> 11) & 0x1f, // hour (dostime >> 5) & 0x3f, // minute - (dostime & 0x1f) << 1); // second + (dostime & 0x1f) << 1)); // second } }; module.exports = DataReader; -},{"./utils":21}],6:[function(_dereq_,module,exports){ +},{"../utils":32}],19:[function(require,module,exports){ 'use strict'; -exports.base64 = false; -exports.binary = false; -exports.dir = false; -exports.createFolders = false; -exports.date = null; -exports.compression = null; -exports.compressionOptions = null; -exports.comment = null; -exports.unixPermissions = null; -exports.dosPermissions = null; - -},{}],7:[function(_dereq_,module,exports){ -'use strict'; -var utils = _dereq_('./utils'); - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.string2binary = function(str) { - return utils.string2binary(str); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.string2Uint8Array = function(str) { - return utils.transformTo("uint8array", str); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.uint8Array2String = function(array) { - return utils.transformTo("string", array); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.string2Blob = function(str) { - var buffer = utils.transformTo("arraybuffer", str); - return utils.arrayBuffer2Blob(buffer); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.arrayBuffer2Blob = function(buffer) { - return utils.arrayBuffer2Blob(buffer); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.transformTo = function(outputType, input) { - return utils.transformTo(outputType, input); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.getTypeOf = function(input) { - return utils.getTypeOf(input); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.checkSupport = function(type) { - return utils.checkSupport(type); -}; - -/** - * @deprecated - * This value will be removed in a future version without replacement. - */ -exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS; - -/** - * @deprecated - * This value will be removed in a future version without replacement. - */ -exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS; - - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.pretty = function(str) { - return utils.pretty(str); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.findCompression = function(compressionMethod) { - return utils.findCompression(compressionMethod); -}; - -/** - * @deprecated - * This function will be removed in a future version without replacement. - */ -exports.isRegExp = function (object) { - return utils.isRegExp(object); -}; - - -},{"./utils":21}],8:[function(_dereq_,module,exports){ -'use strict'; -var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); - -var pako = _dereq_("pako"); -exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; -exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; - -exports.magic = "\x08\x00"; -exports.compress = function(input, compressionOptions) { - return pako.deflateRaw(input, { - level : compressionOptions.level || -1 // default compression - }); -}; -exports.uncompress = function(input) { - return pako.inflateRaw(input); -}; - -},{"pako":24}],9:[function(_dereq_,module,exports){ -'use strict'; - -var base64 = _dereq_('./base64'); - -/** -Usage: - zip = new JSZip(); - zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing"); - zip.folder("images").file("smile.gif", base64Data, {base64: true}); - zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); - zip.remove("tempfile"); - - base64zip = zip.generate(); - -**/ - -/** - * Representation a of zip file in js - * @constructor - * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). - * @param {Object=} options the options for creating this objects (optional). - */ -function JSZip(data, options) { - // if this constructor is used without `new`, it adds `new` before itself: - if(!(this instanceof JSZip)) return new JSZip(data, options); - - // object containing the files : - // { - // "folder/" : {...}, - // "folder/data.txt" : {...} - // } - this.files = {}; - - this.comment = null; - - // Where we are in the hierarchy - this.root = ""; - if (data) { - this.load(data, options); - } - this.clone = function() { - var newObj = new JSZip(); - for (var i in this) { - if (typeof this[i] !== "function") { - newObj[i] = this[i]; - } - } - return newObj; - }; -} -JSZip.prototype = _dereq_('./object'); -JSZip.prototype.load = _dereq_('./load'); -JSZip.support = _dereq_('./support'); -JSZip.defaults = _dereq_('./defaults'); - -/** - * @deprecated - * This namespace will be removed in a future version without replacement. - */ -JSZip.utils = _dereq_('./deprecatedPublicUtils'); - -JSZip.base64 = { - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - encode : function(input) { - return base64.encode(input); - }, - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - decode : function(input) { - return base64.decode(input); - } -}; -JSZip.compressions = _dereq_('./compressions'); -module.exports = JSZip; - -},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(_dereq_,module,exports){ -'use strict'; -var base64 = _dereq_('./base64'); -var ZipEntries = _dereq_('./zipEntries'); -module.exports = function(data, options) { - var files, zipEntries, i, input; - options = options || {}; - if (options.base64) { - data = base64.decode(data); - } - - zipEntries = new ZipEntries(data, options); - files = zipEntries.files; - for (i = 0; i < files.length; i++) { - input = files[i]; - this.file(input.fileName, input.decompressed, { - binary: true, - optimizedBinaryString: true, - date: input.date, - dir: input.dir, - comment : input.fileComment.length ? input.fileComment : null, - unixPermissions : input.unixPermissions, - dosPermissions : input.dosPermissions, - createFolders: options.createFolders - }); - } - if (zipEntries.zipComment.length) { - this.comment = zipEntries.zipComment; - } - - return this; -}; - -},{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){ -(function (Buffer){ -'use strict'; -module.exports = function(data, encoding){ - return new Buffer(data, encoding); -}; -module.exports.test = function(b){ - return Buffer.isBuffer(b); -}; - -}).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined)) -},{}],12:[function(_dereq_,module,exports){ -'use strict'; -var Uint8ArrayReader = _dereq_('./uint8ArrayReader'); +var Uint8ArrayReader = require('./Uint8ArrayReader'); +var utils = require('../utils'); function NodeBufferReader(data) { - this.data = data; - this.length = this.data.length; - this.index = 0; + Uint8ArrayReader.call(this, data); } -NodeBufferReader.prototype = new Uint8ArrayReader(); +utils.inherits(NodeBufferReader, Uint8ArrayReader); /** * @see DataReader.readData */ NodeBufferReader.prototype.readData = function(size) { this.checkOffset(size); - var result = this.data.slice(this.index, this.index + size); + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); this.index += size; return result; }; module.exports = NodeBufferReader; -},{"./uint8ArrayReader":18}],13:[function(_dereq_,module,exports){ +},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(require,module,exports){ 'use strict'; -var support = _dereq_('./support'); -var utils = _dereq_('./utils'); -var crc32 = _dereq_('./crc32'); -var signature = _dereq_('./signature'); -var defaults = _dereq_('./defaults'); -var base64 = _dereq_('./base64'); -var compressions = _dereq_('./compressions'); -var CompressedObject = _dereq_('./compressedObject'); -var nodeBuffer = _dereq_('./nodeBuffer'); -var utf8 = _dereq_('./utf8'); -var StringWriter = _dereq_('./stringWriter'); -var Uint8ArrayWriter = _dereq_('./uint8ArrayWriter'); +var DataReader = require('./DataReader'); +var utils = require('../utils'); +function StringReader(data) { + DataReader.call(this, data); +} +utils.inherits(StringReader, DataReader); /** - * Returns the raw data of a ZipObject, decompress the content if necessary. - * @param {ZipObject} file the file to use. - * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + * @see DataReader.byteAt */ -var getRawData = function(file) { - if (file._data instanceof CompressedObject) { - file._data = file._data.getContent(); - file.options.binary = true; - file.options.base64 = false; - - if (utils.getTypeOf(file._data) === "uint8array") { - var copy = file._data; - // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array. - // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file). - file._data = new Uint8Array(copy.length); - // with an empty Uint8Array, Opera fails with a "Offset larger than array size" - if (copy.length !== 0) { - file._data.set(copy, 0); - } - } - } - return file._data; +StringReader.prototype.byteAt = function(i) { + return this.data.charCodeAt(this.zero + i); }; - /** - * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it. - * @param {ZipObject} file the file to use. - * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + * @see DataReader.lastIndexOfSignature */ -var getBinaryData = function(file) { - var result = getRawData(file), - type = utils.getTypeOf(result); - if (type === "string") { - if (!file.options.binary) { - // unicode text ! - // unicode string => binary string is a painful process, check if we can avoid it. - if (support.nodebuffer) { - return nodeBuffer(result, "utf-8"); - } - } - return file.asBinary(); - } +StringReader.prototype.lastIndexOfSignature = function(sig) { + return this.data.lastIndexOf(sig) - this.zero; +}; +/** + * @see DataReader.readAndCheckSignature + */ +StringReader.prototype.readAndCheckSignature = function (sig) { + var data = this.readData(4); + return sig === data; +}; +/** + * @see DataReader.readData + */ +StringReader.prototype.readData = function(size) { + this.checkOffset(size); + // this will work because the constructor applied the "& 0xff" mask. + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; return result; }; +module.exports = StringReader; +},{"../utils":32,"./DataReader":18}],21:[function(require,module,exports){ +'use strict'; +var ArrayReader = require('./ArrayReader'); +var utils = require('../utils'); + +function Uint8ArrayReader(data) { + ArrayReader.call(this, data); +} +utils.inherits(Uint8ArrayReader, ArrayReader); /** - * Transform this._data into a string. - * @param {function} filter a function String -> String, applied if not null on the result. - * @return {String} the string representing this._data. + * @see DataReader.readData */ -var dataToString = function(asUTF8) { - var result = getRawData(this); - if (result === null || typeof result === "undefined") { - return ""; - } - // if the data is a base64 string, we decode it before checking the encoding ! - if (this.options.base64) { - result = base64.decode(result); - } - if (asUTF8 && this.options.binary) { - // JSZip.prototype.utf8decode supports arrays as input - // skip to array => string step, utf8decode will do it. - result = out.utf8decode(result); - } - else { - // no utf8 transformation, do the array => string step. - result = utils.transformTo("string", result); - } - - if (!asUTF8 && !this.options.binary) { - result = utils.transformTo("string", out.utf8encode(result)); +Uint8ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. + return new Uint8Array(0); } + var result = this.data.subarray(this.zero + this.index, this.zero + this.index + size); + this.index += size; return result; }; -/** - * A simple object representing a file in the zip file. - * @constructor - * @param {string} name the name of the file - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data - * @param {Object} options the options of the file - */ -var ZipObject = function(name, data, options) { - this.name = name; - this.dir = options.dir; - this.date = options.date; - this.comment = options.comment; - this.unixPermissions = options.unixPermissions; - this.dosPermissions = options.dosPermissions; +module.exports = Uint8ArrayReader; - this._data = data; - this.options = options; +},{"../utils":32,"./ArrayReader":17}],22:[function(require,module,exports){ +'use strict'; - /* - * This object contains initial values for dir and date. - * With them, we can check if the user changed the deprecated metadata in - * `ZipObject#options` or not. - */ - this._initialMetadata = { - dir : options.dir, - date : options.date - }; -}; - -ZipObject.prototype = { - /** - * Return the content as UTF8 string. - * @return {string} the UTF8 string. - */ - asText: function() { - return dataToString.call(this, true); - }, - /** - * Returns the binary content. - * @return {string} the content as binary. - */ - asBinary: function() { - return dataToString.call(this, false); - }, - /** - * Returns the content as a nodejs Buffer. - * @return {Buffer} the content as a Buffer. - */ - asNodeBuffer: function() { - var result = getBinaryData(this); - return utils.transformTo("nodebuffer", result); - }, - /** - * Returns the content as an Uint8Array. - * @return {Uint8Array} the content as an Uint8Array. - */ - asUint8Array: function() { - var result = getBinaryData(this); - return utils.transformTo("uint8array", result); - }, - /** - * Returns the content as an ArrayBuffer. - * @return {ArrayBuffer} the content as an ArrayBufer. - */ - asArrayBuffer: function() { - return this.asUint8Array().buffer; - } -}; +var utils = require('../utils'); +var support = require('../support'); +var ArrayReader = require('./ArrayReader'); +var StringReader = require('./StringReader'); +var NodeBufferReader = require('./NodeBufferReader'); +var Uint8ArrayReader = require('./Uint8ArrayReader'); /** - * Transform an integer into a string in hexadecimal. - * @private - * @param {number} dec the number to convert. - * @param {number} bytes the number of bytes to generate. - * @returns {string} the result. + * Create a reader adapted to the data. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read. + * @return {DataReader} the data reader. */ -var decToHex = function(dec, bytes) { - var hex = "", - i; - for (i = 0; i < bytes; i++) { - hex += String.fromCharCode(dec & 0xff); - dec = dec >>> 8; +module.exports = function (data) { + var type = utils.getTypeOf(data); + utils.checkSupport(type); + if (type === "string" && !support.uint8array) { + return new StringReader(data); } - return hex; + if (type === "nodebuffer") { + return new NodeBufferReader(data); + } + if (support.uint8array) { + return new Uint8ArrayReader(utils.transformTo("uint8array", data)); + } + return new ArrayReader(utils.transformTo("array", data)); }; -/** - * Merge the objects passed as parameters into a new one. - * @private - * @param {...Object} var_args All objects to merge. - * @return {Object} a new object with the data of the others. - */ -var extend = function() { - var result = {}, i, attr; - for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers - for (attr in arguments[i]) { - if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { - result[attr] = arguments[i][attr]; - } - } - } - return result; -}; +// vim: set shiftwidth=4 softtabstop=4: -/** - * Transforms the (incomplete) options from the user into the complete - * set of options to create a file. - * @private - * @param {Object} o the options from the user. - * @return {Object} the complete set of options. - */ -var prepareFileAttrs = function(o) { - o = o || {}; - if (o.base64 === true && (o.binary === null || o.binary === undefined)) { - o.binary = true; - } - o = extend(o, defaults); - o.date = o.date || new Date(); - if (o.compression !== null) o.compression = o.compression.toUpperCase(); - - return o; -}; - -/** - * Add a file in the current folder. - * @private - * @param {string} name the name of the file - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file - * @param {Object} o the options of the file - * @return {Object} the new file. - */ -var fileAdd = function(name, data, o) { - // be sure sub folders exist - var dataType = utils.getTypeOf(data), - parent; - - o = prepareFileAttrs(o); - - if (typeof o.unixPermissions === "string") { - o.unixPermissions = parseInt(o.unixPermissions, 8); - } - - // UNX_IFDIR 0040000 see zipinfo.c - if (o.unixPermissions && (o.unixPermissions & 0x4000)) { - o.dir = true; - } - // Bit 4 Directory - if (o.dosPermissions && (o.dosPermissions & 0x0010)) { - o.dir = true; - } - - if (o.dir) { - name = forceTrailingSlash(name); - } - - if (o.createFolders && (parent = parentFolder(name))) { - folderAdd.call(this, parent, true); - } - - if (o.dir || data === null || typeof data === "undefined") { - o.base64 = false; - o.binary = false; - data = null; - dataType = null; - } - else if (dataType === "string") { - if (o.binary && !o.base64) { - // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask - if (o.optimizedBinaryString !== true) { - // this is a string, not in a base64 format. - // Be sure that this is a correct "binary string" - data = utils.string2binary(data); - } - } - } - else { // arraybuffer, uint8array, ... - o.base64 = false; - o.binary = true; - - if (!dataType && !(data instanceof CompressedObject)) { - throw new Error("The data of '" + name + "' is in an unsupported format !"); - } - - // special case : it's way easier to work with Uint8Array than with ArrayBuffer - if (dataType === "arraybuffer") { - data = utils.transformTo("uint8array", data); - } - } - - var object = new ZipObject(name, data, o); - this.files[name] = object; - return object; -}; - -/** - * Find the parent folder of the path. - * @private - * @param {string} path the path to use - * @return {string} the parent folder, or "" - */ -var parentFolder = function (path) { - if (path.slice(-1) == '/') { - path = path.substring(0, path.length - 1); - } - var lastSlash = path.lastIndexOf('/'); - return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; -}; - - -/** - * Returns the path with a slash at the end. - * @private - * @param {String} path the path to check. - * @return {String} the path with a trailing slash. - */ -var forceTrailingSlash = function(path) { - // Check the name ends with a / - if (path.slice(-1) != "/") { - path += "/"; // IE doesn't like substr(-1) - } - return path; -}; -/** - * Add a (sub) folder in the current folder. - * @private - * @param {string} name the folder's name - * @param {boolean=} [createFolders] If true, automatically create sub - * folders. Defaults to false. - * @return {Object} the new folder. - */ -var folderAdd = function(name, createFolders) { - createFolders = (typeof createFolders !== 'undefined') ? createFolders : false; - - name = forceTrailingSlash(name); - - // Does this folder already exist? - if (!this.files[name]) { - fileAdd.call(this, name, null, { - dir: true, - createFolders: createFolders - }); - } - return this.files[name]; -}; - -/** - * Generate a JSZip.CompressedObject for a given zipOject. - * @param {ZipObject} file the object to read. - * @param {JSZip.compression} compression the compression to use. - * @param {Object} compressionOptions the options to use when compressing. - * @return {JSZip.CompressedObject} the compressed result. - */ -var generateCompressedObjectFrom = function(file, compression, compressionOptions) { - var result = new CompressedObject(), - content; - - // the data has not been decompressed, we might reuse things ! - if (file._data instanceof CompressedObject) { - result.uncompressedSize = file._data.uncompressedSize; - result.crc32 = file._data.crc32; - - if (result.uncompressedSize === 0 || file.dir) { - compression = compressions['STORE']; - result.compressedContent = ""; - result.crc32 = 0; - } - else if (file._data.compressionMethod === compression.magic) { - result.compressedContent = file._data.getCompressedContent(); - } - else { - content = file._data.getContent(); - // need to decompress / recompress - result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); - } - } - else { - // have uncompressed data - content = getBinaryData(file); - if (!content || content.length === 0 || file.dir) { - compression = compressions['STORE']; - content = ""; - } - result.uncompressedSize = content.length; - result.crc32 = crc32(content); - result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); - } - - result.compressedSize = result.compressedContent.length; - result.compressionMethod = compression.magic; - - return result; -}; - - - - -/** - * Generate the UNIX part of the external file attributes. - * @param {Object} unixPermissions the unix permissions or null. - * @param {Boolean} isDir true if the entry is a directory, false otherwise. - * @return {Number} a 32 bit integer. - * - * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : - * - * TTTTsstrwxrwxrwx0000000000ADVSHR - * ^^^^____________________________ file type, see zipinfo.c (UNX_*) - * ^^^_________________________ setuid, setgid, sticky - * ^^^^^^^^^________________ permissions - * ^^^^^^^^^^______ not used ? - * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only - */ -var generateUnixExternalFileAttr = function (unixPermissions, isDir) { - - var result = unixPermissions; - if (!unixPermissions) { - // I can't use octal values in strict mode, hence the hexa. - // 040775 => 0x41fd - // 0100664 => 0x81b4 - result = isDir ? 0x41fd : 0x81b4; - } - - return (result & 0xFFFF) << 16; -}; - -/** - * Generate the DOS part of the external file attributes. - * @param {Object} dosPermissions the dos permissions or null. - * @param {Boolean} isDir true if the entry is a directory, false otherwise. - * @return {Number} a 32 bit integer. - * - * Bit 0 Read-Only - * Bit 1 Hidden - * Bit 2 System - * Bit 3 Volume Label - * Bit 4 Directory - * Bit 5 Archive - */ -var generateDosExternalFileAttr = function (dosPermissions, isDir) { - - // the dir flag is already set for compatibility - - return (dosPermissions || 0) & 0x3F; -}; - -/** - * Generate the various parts used in the construction of the final zip file. - * @param {string} name the file name. - * @param {ZipObject} file the file content. - * @param {JSZip.CompressedObject} compressedObject the compressed object. - * @param {number} offset the current offset from the start of the zip file. - * @param {String} platform let's pretend we are this platform (change platform dependents fields) - * @return {object} the zip parts. - */ -var generateZipParts = function(name, file, compressedObject, offset, platform) { - var data = compressedObject.compressedContent, - utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), - comment = file.comment || "", - utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), - useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, - useUTF8ForComment = utfEncodedComment.length !== comment.length, - o = file.options, - dosTime, - dosDate, - extraFields = "", - unicodePathExtraField = "", - unicodeCommentExtraField = "", - dir, date; - - - // handle the deprecated options.dir - if (file._initialMetadata.dir !== file.dir) { - dir = file.dir; - } else { - dir = o.dir; - } - - // handle the deprecated options.date - if(file._initialMetadata.date !== file.date) { - date = file.date; - } else { - date = o.date; - } - - var extFileAttr = 0; - var versionMadeBy = 0; - if (dir) { - // dos or unix, we set the dos dir flag - extFileAttr |= 0x00010; - } - if(platform === "UNIX") { - versionMadeBy = 0x031E; // UNIX, version 3.0 - extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); - } else { // DOS or other, fallback to DOS - versionMadeBy = 0x0014; // DOS, version 2.0 - extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); - } - - // date - // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html - // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html - // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html - - dosTime = date.getHours(); - dosTime = dosTime << 6; - dosTime = dosTime | date.getMinutes(); - dosTime = dosTime << 5; - dosTime = dosTime | date.getSeconds() / 2; - - dosDate = date.getFullYear() - 1980; - dosDate = dosDate << 4; - dosDate = dosDate | (date.getMonth() + 1); - dosDate = dosDate << 5; - dosDate = dosDate | date.getDate(); - - if (useUTF8ForFileName) { - // set the unicode path extra field. unzip needs at least one extra - // field to correctly handle unicode path, so using the path is as good - // as any other information. This could improve the situation with - // other archive managers too. - // This field is usually used without the utf8 flag, with a non - // unicode path in the header (winrar, winzip). This helps (a bit) - // with the messy Windows' default compressed folders feature but - // breaks on p7zip which doesn't seek the unicode path extra field. - // So for now, UTF-8 everywhere ! - unicodePathExtraField = - // Version - decToHex(1, 1) + - // NameCRC32 - decToHex(crc32(utfEncodedFileName), 4) + - // UnicodeName - utfEncodedFileName; - - extraFields += - // Info-ZIP Unicode Path Extra Field - "\x75\x70" + - // size - decToHex(unicodePathExtraField.length, 2) + - // content - unicodePathExtraField; - } - - if(useUTF8ForComment) { - - unicodeCommentExtraField = - // Version - decToHex(1, 1) + - // CommentCRC32 - decToHex(this.crc32(utfEncodedComment), 4) + - // UnicodeName - utfEncodedComment; - - extraFields += - // Info-ZIP Unicode Path Extra Field - "\x75\x63" + - // size - decToHex(unicodeCommentExtraField.length, 2) + - // content - unicodeCommentExtraField; - } - - var header = ""; - - // version needed to extract - header += "\x0A\x00"; - // general purpose bit flag - // set bit 11 if utf8 - header += (useUTF8ForFileName || useUTF8ForComment) ? "\x00\x08" : "\x00\x00"; - // compression method - header += compressedObject.compressionMethod; - // last mod file time - header += decToHex(dosTime, 2); - // last mod file date - header += decToHex(dosDate, 2); - // crc-32 - header += decToHex(compressedObject.crc32, 4); - // compressed size - header += decToHex(compressedObject.compressedSize, 4); - // uncompressed size - header += decToHex(compressedObject.uncompressedSize, 4); - // file name length - header += decToHex(utfEncodedFileName.length, 2); - // extra field length - header += decToHex(extraFields.length, 2); - - - var fileRecord = signature.LOCAL_FILE_HEADER + header + utfEncodedFileName + extraFields; - - var dirRecord = signature.CENTRAL_FILE_HEADER + - // version made by (00: DOS) - decToHex(versionMadeBy, 2) + - // file header (common to file and central directory) - header + - // file comment length - decToHex(utfEncodedComment.length, 2) + - // disk number start - "\x00\x00" + - // internal file attributes TODO - "\x00\x00" + - // external file attributes - decToHex(extFileAttr, 4) + - // relative offset of local header - decToHex(offset, 4) + - // file name - utfEncodedFileName + - // extra field - extraFields + - // file comment - utfEncodedComment; - - return { - fileRecord: fileRecord, - dirRecord: dirRecord, - compressedObject: compressedObject - }; -}; - - -// return the actual prototype of JSZip -var out = { - /** - * Read an existing zip and merge the data in the current JSZip object. - * The implementation is in jszip-load.js, don't forget to include it. - * @param {String|ArrayBuffer|Uint8Array|Buffer} stream The stream to load - * @param {Object} options Options for loading the stream. - * options.base64 : is the stream in base64 ? default : false - * @return {JSZip} the current JSZip object - */ - load: function(stream, options) { - throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); - }, - - /** - * Filter nested files/folders with the specified function. - * @param {Function} search the predicate to use : - * function (relativePath, file) {...} - * It takes 2 arguments : the relative path and the file. - * @return {Array} An array of matching elements. - */ - filter: function(search) { - var result = [], - filename, relativePath, file, fileClone; - for (filename in this.files) { - if (!this.files.hasOwnProperty(filename)) { - continue; - } - file = this.files[filename]; - // return a new object, don't let the user mess with our internal objects :) - fileClone = new ZipObject(file.name, file._data, extend(file.options)); - relativePath = filename.slice(this.root.length, filename.length); - if (filename.slice(0, this.root.length) === this.root && // the file is in the current root - search(relativePath, fileClone)) { // and the file matches the function - result.push(fileClone); - } - } - return result; - }, - - /** - * Add a file to the zip file, or search a file. - * @param {string|RegExp} name The name of the file to add (if data is defined), - * the name of the file to find (if no data) or a regex to match files. - * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded - * @param {Object} o File options - * @return {JSZip|Object|Array} this JSZip object (when adding a file), - * a file (when searching by string) or an array of files (when searching by regex). - */ - file: function(name, data, o) { - if (arguments.length === 1) { - if (utils.isRegExp(name)) { - var regexp = name; - return this.filter(function(relativePath, file) { - return !file.dir && regexp.test(relativePath); - }); - } - else { // text - return this.filter(function(relativePath, file) { - return !file.dir && relativePath === name; - })[0] || null; - } - } - else { // more than one argument : we have data ! - name = this.root + name; - fileAdd.call(this, name, data, o); - } - return this; - }, - - /** - * Add a directory to the zip file, or search. - * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. - * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. - */ - folder: function(arg) { - if (!arg) { - return this; - } - - if (utils.isRegExp(arg)) { - return this.filter(function(relativePath, file) { - return file.dir && arg.test(relativePath); - }); - } - - // else, name is a new folder - var name = this.root + arg; - var newFolder = folderAdd.call(this, name); - - // Allow chaining by returning a new object with this folder as the root - var ret = this.clone(); - ret.root = newFolder.name; - return ret; - }, - - /** - * Delete a file, or a directory and all sub-files, from the zip - * @param {string} name the name of the file to delete - * @return {JSZip} this JSZip object - */ - remove: function(name) { - name = this.root + name; - var file = this.files[name]; - if (!file) { - // Look for any folders - if (name.slice(-1) != "/") { - name += "/"; - } - file = this.files[name]; - } - - if (file && !file.dir) { - // file - delete this.files[name]; - } else { - // maybe a folder, delete recursively - var kids = this.filter(function(relativePath, file) { - return file.name.slice(0, name.length) === name; - }); - for (var i = 0; i < kids.length; i++) { - delete this.files[kids[i].name]; - } - } - - return this; - }, - - /** - * Generate the complete zip file - * @param {Object} options the options to generate the zip file : - * - base64, (deprecated, use type instead) true to generate base64. - * - compression, "STORE" by default. - * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. - * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file - */ - generate: function(options) { - options = extend(options || {}, { - base64: true, - compression: "STORE", - compressionOptions : null, - type: "base64", - platform: "DOS", - comment: null, - mimeType: 'application/zip' - }); - - utils.checkSupport(options.type); - - // accept nodejs `process.platform` - if( - options.platform === 'darwin' || - options.platform === 'freebsd' || - options.platform === 'linux' || - options.platform === 'sunos' - ) { - options.platform = "UNIX"; - } - if (options.platform === 'win32') { - options.platform = "DOS"; - } - - var zipData = [], - localDirLength = 0, - centralDirLength = 0, - writer, i, - utfEncodedComment = utils.transformTo("string", this.utf8encode(options.comment || this.comment || "")); - - // first, generate all the zip parts. - for (var name in this.files) { - if (!this.files.hasOwnProperty(name)) { - continue; - } - var file = this.files[name]; - - var compressionName = file.options.compression || options.compression.toUpperCase(); - var compression = compressions[compressionName]; - if (!compression) { - throw new Error(compressionName + " is not a valid compression method !"); - } - var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; - - var compressedObject = generateCompressedObjectFrom.call(this, file, compression, compressionOptions); - - var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength, options.platform); - localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize; - centralDirLength += zipPart.dirRecord.length; - zipData.push(zipPart); - } - - var dirEnd = ""; - - // end of central dir signature - dirEnd = signature.CENTRAL_DIRECTORY_END + - // number of this disk - "\x00\x00" + - // number of the disk with the start of the central directory - "\x00\x00" + - // total number of entries in the central directory on this disk - decToHex(zipData.length, 2) + - // total number of entries in the central directory - decToHex(zipData.length, 2) + - // size of the central directory 4 bytes - decToHex(centralDirLength, 4) + - // offset of start of central directory with respect to the starting disk number - decToHex(localDirLength, 4) + - // .ZIP file comment length - decToHex(utfEncodedComment.length, 2) + - // .ZIP file comment - utfEncodedComment; - - - // we have all the parts (and the total length) - // time to create a writer ! - var typeName = options.type.toLowerCase(); - if(typeName==="uint8array"||typeName==="arraybuffer"||typeName==="blob"||typeName==="nodebuffer") { - writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length); - }else{ - writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length); - } - - for (i = 0; i < zipData.length; i++) { - writer.append(zipData[i].fileRecord); - writer.append(zipData[i].compressedObject.compressedContent); - } - for (i = 0; i < zipData.length; i++) { - writer.append(zipData[i].dirRecord); - } - - writer.append(dirEnd); - - var zip = writer.finalize(); - - - - switch(options.type.toLowerCase()) { - // case "zip is an Uint8Array" - case "uint8array" : - case "arraybuffer" : - case "nodebuffer" : - return utils.transformTo(options.type.toLowerCase(), zip); - case "blob" : - return utils.arrayBuffer2Blob(utils.transformTo("arraybuffer", zip), options.mimeType); - // case "zip is a string" - case "base64" : - return (options.base64) ? base64.encode(zip) : zip; - default : // case "string" : - return zip; - } - - }, - - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - crc32: function (input, crc) { - return crc32(input, crc); - }, - - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - utf8encode: function (string) { - return utils.transformTo("string", utf8.utf8encode(string)); - }, - - /** - * @deprecated - * This method will be removed in a future version without replacement. - */ - utf8decode: function (input) { - return utf8.utf8decode(input); - } -}; -module.exports = out; - -},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(_dereq_,module,exports){ +},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(require,module,exports){ 'use strict'; exports.LOCAL_FILE_HEADER = "PK\x03\x04"; exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; @@ -1518,86 +1995,702 @@ exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; exports.DATA_DESCRIPTOR = "PK\x07\x08"; -},{}],15:[function(_dereq_,module,exports){ +},{}],24:[function(require,module,exports){ 'use strict'; -var DataReader = _dereq_('./dataReader'); -var utils = _dereq_('./utils'); -function StringReader(data, optimizedBinaryString) { - this.data = data; - if (!optimizedBinaryString) { - this.data = utils.string2binary(this.data); - } - this.length = this.data.length; - this.index = 0; +var GenericWorker = require('./GenericWorker'); +var utils = require('../utils'); + +/** + * A worker which convert chunks to a specified type. + * @constructor + * @param {String} destType the destination type. + */ +function ConvertWorker(destType) { + GenericWorker.call(this, "ConvertWorker to " + destType); + this.destType = destType; } -StringReader.prototype = new DataReader(); -/** - * @see DataReader.byteAt - */ -StringReader.prototype.byteAt = function(i) { - return this.data.charCodeAt(i); -}; -/** - * @see DataReader.lastIndexOfSignature - */ -StringReader.prototype.lastIndexOfSignature = function(sig) { - return this.data.lastIndexOf(sig); -}; -/** - * @see DataReader.readData - */ -StringReader.prototype.readData = function(size) { - this.checkOffset(size); - // this will work because the constructor applied the "& 0xff" mask. - var result = this.data.slice(this.index, this.index + size); - this.index += size; - return result; -}; -module.exports = StringReader; +utils.inherits(ConvertWorker, GenericWorker); -},{"./dataReader":5,"./utils":21}],16:[function(_dereq_,module,exports){ +/** + * @see GenericWorker.processChunk + */ +ConvertWorker.prototype.processChunk = function (chunk) { + this.push({ + data : utils.transformTo(this.destType, chunk.data), + meta : chunk.meta + }); +}; +module.exports = ConvertWorker; + +},{"../utils":32,"./GenericWorker":28}],25:[function(require,module,exports){ 'use strict'; -var utils = _dereq_('./utils'); +var GenericWorker = require('./GenericWorker'); +var crc32 = require('../crc32'); +var utils = require('../utils'); /** - * An object to write any content to a string. + * A worker which calculate the crc32 of the data flowing through. * @constructor */ -var StringWriter = function() { - this.data = []; +function Crc32Probe() { + GenericWorker.call(this, "Crc32Probe"); + this.withStreamInfo("crc32", 0); +} +utils.inherits(Crc32Probe, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Crc32Probe.prototype.processChunk = function (chunk) { + this.streamInfo.crc32 = crc32(chunk.data, this.streamInfo.crc32 || 0); + this.push(chunk); }; -StringWriter.prototype = { - /** - * Append any content to the current string. - * @param {Object} input the content to add. - */ - append: function(input) { - input = utils.transformTo("string", input); - this.data.push(input); - }, - /** - * Finalize the construction an return the result. - * @return {string} the generated string. - */ - finalize: function() { - return this.data.join(""); +module.exports = Crc32Probe; + +},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var GenericWorker = require('./GenericWorker'); + +/** + * A worker which calculate the total length of the data flowing through. + * @constructor + * @param {String} propName the name used to expose the length + */ +function DataLengthProbe(propName) { + GenericWorker.call(this, "DataLengthProbe for " + propName); + this.propName = propName; + this.withStreamInfo(propName, 0); +} +utils.inherits(DataLengthProbe, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +DataLengthProbe.prototype.processChunk = function (chunk) { + if(chunk) { + var length = this.streamInfo[this.propName] || 0; + this.streamInfo[this.propName] = length + chunk.data.length; + } + GenericWorker.prototype.processChunk.call(this, chunk); +}; +module.exports = DataLengthProbe; + + +},{"../utils":32,"./GenericWorker":28}],27:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var GenericWorker = require('./GenericWorker'); + +// the size of the generated chunks +// TODO expose this as a public variable +var DEFAULT_BLOCK_SIZE = 16 * 1024; + +/** + * A worker that reads a content and emits chunks. + * @constructor + * @param {Promise} dataP the promise of the data to split + */ +function DataWorker(dataP) { + GenericWorker.call(this, "DataWorker"); + var self = this; + this.dataIsReady = false; + this.index = 0; + this.max = 0; + this.data = null; + this.type = ""; + + this._tickScheduled = false; + + dataP.then(function (data) { + self.dataIsReady = true; + self.data = data; + self.max = data && data.length || 0; + self.type = utils.getTypeOf(data); + if(!self.isPaused) { + self._tickAndRepeat(); + } + }, function (e) { + self.error(e); + }); +} + +utils.inherits(DataWorker, GenericWorker); + +/** + * @see GenericWorker.cleanUp + */ +DataWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this.data = null; +}; + +/** + * @see GenericWorker.resume + */ +DataWorker.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if (!this._tickScheduled && this.dataIsReady) { + this._tickScheduled = true; + utils.delay(this._tickAndRepeat, [], this); + } + return true; +}; + +/** + * Trigger a tick a schedule an other call to this function. + */ +DataWorker.prototype._tickAndRepeat = function() { + this._tickScheduled = false; + if(this.isPaused || this.isFinished) { + return; + } + this._tick(); + if(!this.isFinished) { + utils.delay(this._tickAndRepeat, [], this); + this._tickScheduled = true; } }; -module.exports = StringWriter; +/** + * Read and push a chunk. + */ +DataWorker.prototype._tick = function() { -},{"./utils":21}],17:[function(_dereq_,module,exports){ -(function (Buffer){ + if(this.isPaused || this.isFinished) { + return false; + } + + var size = DEFAULT_BLOCK_SIZE; + var data = null, nextIndex = Math.min(this.max, this.index + size); + if (this.index >= this.max) { + // EOF + return this.end(); + } else { + switch(this.type) { + case "string": + data = this.data.substring(this.index, nextIndex); + break; + case "uint8array": + data = this.data.subarray(this.index, nextIndex); + break; + case "array": + case "nodebuffer": + data = this.data.slice(this.index, nextIndex); + break; + } + this.index = nextIndex; + return this.push({ + data : data, + meta : { + percent : this.max ? this.index / this.max * 100 : 0 + } + }); + } +}; + +module.exports = DataWorker; + +},{"../utils":32,"./GenericWorker":28}],28:[function(require,module,exports){ 'use strict'; + +/** + * A worker that does nothing but passing chunks to the next one. This is like + * a nodejs stream but with some differences. On the good side : + * - it works on IE 6-9 without any issue / polyfill + * - it weights less than the full dependencies bundled with browserify + * - it forwards errors (no need to declare an error handler EVERYWHERE) + * + * A chunk is an object with 2 attributes : `meta` and `data`. The former is an + * object containing anything (`percent` for example), see each worker for more + * details. The latter is the real data (String, Uint8Array, etc). + * + * @constructor + * @param {String} name the name of the stream (mainly used for debugging purposes) + */ +function GenericWorker(name) { + // the name of the worker + this.name = name || "default"; + // an object containing metadata about the workers chain + this.streamInfo = {}; + // an error which happened when the worker was paused + this.generatedError = null; + // an object containing metadata to be merged by this worker into the general metadata + this.extraStreamInfo = {}; + // true if the stream is paused (and should not do anything), false otherwise + this.isPaused = true; + // true if the stream is finished (and should not do anything), false otherwise + this.isFinished = false; + // true if the stream is locked to prevent further structure updates (pipe), false otherwise + this.isLocked = false; + // the event listeners + this._listeners = { + 'data':[], + 'end':[], + 'error':[] + }; + // the previous worker, if any + this.previous = null; +} + +GenericWorker.prototype = { + /** + * Push a chunk to the next workers. + * @param {Object} chunk the chunk to push + */ + push : function (chunk) { + this.emit("data", chunk); + }, + /** + * End the stream. + * @return {Boolean} true if this call ended the worker, false otherwise. + */ + end : function () { + if (this.isFinished) { + return false; + } + + this.flush(); + try { + this.emit("end"); + this.cleanUp(); + this.isFinished = true; + } catch (e) { + this.emit("error", e); + } + return true; + }, + /** + * End the stream with an error. + * @param {Error} e the error which caused the premature end. + * @return {Boolean} true if this call ended the worker with an error, false otherwise. + */ + error : function (e) { + if (this.isFinished) { + return false; + } + + if(this.isPaused) { + this.generatedError = e; + } else { + this.isFinished = true; + + this.emit("error", e); + + // in the workers chain exploded in the middle of the chain, + // the error event will go downward but we also need to notify + // workers upward that there has been an error. + if(this.previous) { + this.previous.error(e); + } + + this.cleanUp(); + } + return true; + }, + /** + * Add a callback on an event. + * @param {String} name the name of the event (data, end, error) + * @param {Function} listener the function to call when the event is triggered + * @return {GenericWorker} the current object for chainability + */ + on : function (name, listener) { + this._listeners[name].push(listener); + return this; + }, + /** + * Clean any references when a worker is ending. + */ + cleanUp : function () { + this.streamInfo = this.generatedError = this.extraStreamInfo = null; + this._listeners = []; + }, + /** + * Trigger an event. This will call registered callback with the provided arg. + * @param {String} name the name of the event (data, end, error) + * @param {Object} arg the argument to call the callback with. + */ + emit : function (name, arg) { + if (this._listeners[name]) { + for(var i = 0; i < this._listeners[name].length; i++) { + this._listeners[name][i].call(this, arg); + } + } + }, + /** + * Chain a worker with an other. + * @param {Worker} next the worker receiving events from the current one. + * @return {worker} the next worker for chainability + */ + pipe : function (next) { + return next.registerPrevious(this); + }, + /** + * Same as `pipe` in the other direction. + * Using an API with `pipe(next)` is very easy. + * Implementing the API with the point of view of the next one registering + * a source is easier, see the ZipFileWorker. + * @param {Worker} previous the previous worker, sending events to this one + * @return {Worker} the current worker for chainability + */ + registerPrevious : function (previous) { + if (this.isLocked) { + throw new Error("The stream '" + this + "' has already been used."); + } + + // sharing the streamInfo... + this.streamInfo = previous.streamInfo; + // ... and adding our own bits + this.mergeStreamInfo(); + this.previous = previous; + var self = this; + previous.on('data', function (chunk) { + self.processChunk(chunk); + }); + previous.on('end', function () { + self.end(); + }); + previous.on('error', function (e) { + self.error(e); + }); + return this; + }, + /** + * Pause the stream so it doesn't send events anymore. + * @return {Boolean} true if this call paused the worker, false otherwise. + */ + pause : function () { + if(this.isPaused || this.isFinished) { + return false; + } + this.isPaused = true; + + if(this.previous) { + this.previous.pause(); + } + return true; + }, + /** + * Resume a paused stream. + * @return {Boolean} true if this call resumed the worker, false otherwise. + */ + resume : function () { + if(!this.isPaused || this.isFinished) { + return false; + } + this.isPaused = false; + + // if true, the worker tried to resume but failed + var withError = false; + if(this.generatedError) { + this.error(this.generatedError); + withError = true; + } + if(this.previous) { + this.previous.resume(); + } + + return !withError; + }, + /** + * Flush any remaining bytes as the stream is ending. + */ + flush : function () {}, + /** + * Process a chunk. This is usually the method overridden. + * @param {Object} chunk the chunk to process. + */ + processChunk : function(chunk) { + this.push(chunk); + }, + /** + * Add a key/value to be added in the workers chain streamInfo once activated. + * @param {String} key the key to use + * @param {Object} value the associated value + * @return {Worker} the current worker for chainability + */ + withStreamInfo : function (key, value) { + this.extraStreamInfo[key] = value; + this.mergeStreamInfo(); + return this; + }, + /** + * Merge this worker's streamInfo into the chain's streamInfo. + */ + mergeStreamInfo : function () { + for(var key in this.extraStreamInfo) { + if (!this.extraStreamInfo.hasOwnProperty(key)) { + continue; + } + this.streamInfo[key] = this.extraStreamInfo[key]; + } + }, + + /** + * Lock the stream to prevent further updates on the workers chain. + * After calling this method, all calls to pipe will fail. + */ + lock: function () { + if (this.isLocked) { + throw new Error("The stream '" + this + "' has already been used."); + } + this.isLocked = true; + if (this.previous) { + this.previous.lock(); + } + }, + + /** + * + * Pretty print the workers chain. + */ + toString : function () { + var me = "Worker " + this.name; + if (this.previous) { + return this.previous + " -> " + me; + } else { + return me; + } + } +}; + +module.exports = GenericWorker; + +},{}],29:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var ConvertWorker = require('./ConvertWorker'); +var GenericWorker = require('./GenericWorker'); +var base64 = require('../base64'); +var support = require("../support"); +var external = require("../external"); + +var NodejsStreamOutputAdapter = null; +if (support.nodestream) { + try { + NodejsStreamOutputAdapter = require('../nodejs/NodejsStreamOutputAdapter'); + } catch(e) {} +} + +/** + * Apply the final transformation of the data. If the user wants a Blob for + * example, it's easier to work with an U8intArray and finally do the + * ArrayBuffer/Blob conversion. + * @param {String} resultType the name of the final type + * @param {String} chunkType the type of the data in the given array. + * @param {Array} dataArray the array containing the data chunks to concatenate + * @param {String|Uint8Array|Buffer} content the content to transform + * @param {String} mimeType the mime type of the content, if applicable. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the content in the right format. + */ +function transformZipOutput(resultType, chunkType, dataArray, mimeType) { + var content = null; + switch(resultType) { + case "blob" : + return utils.newBlob(dataArray, mimeType); + case "base64" : + content = concat(chunkType, dataArray); + return base64.encode(content); + default : + content = concat(chunkType, dataArray); + return utils.transformTo(resultType, content); + } +} + +/** + * Concatenate an array of data of the given type. + * @param {String} type the type of the data in the given array. + * @param {Array} dataArray the array containing the data chunks to concatenate + * @return {String|Uint8Array|Buffer} the concatenated data + * @throws Error if the asked type is unsupported + */ +function concat (type, dataArray) { + var i, index = 0, res = null, totalLength = 0; + for(i = 0; i < dataArray.length; i++) { + totalLength += dataArray[i].length; + } + switch(type) { + case "string": + return dataArray.join(""); + case "array": + return Array.prototype.concat.apply([], dataArray); + case "uint8array": + res = new Uint8Array(totalLength); + for(i = 0; i < dataArray.length; i++) { + res.set(dataArray[i], index); + index += dataArray[i].length; + } + return res; + case "nodebuffer": + return Buffer.concat(dataArray); + default: + throw new Error("concat : unsupported type '" + type + "'"); + } +} + +/** + * Listen a StreamHelper, accumulate its content and concatenate it into a + * complete block. + * @param {StreamHelper} helper the helper to use. + * @param {Function} updateCallback a callback called on each update. Called + * with one arg : + * - the metadata linked to the update received. + * @return Promise the promise for the accumulation. + */ +function accumulate(helper, updateCallback) { + return new external.Promise(function (resolve, reject){ + var dataArray = []; + var chunkType = helper._internalType, + resultType = helper._outputType, + mimeType = helper._mimeType; + helper + .on('data', function (data, meta) { + dataArray.push(data); + if(updateCallback) { + updateCallback(meta); + } + }) + .on('error', function(err) { + dataArray = []; + reject(err); + }) + .on('end', function (){ + try { + var result = transformZipOutput(resultType, chunkType, dataArray, mimeType); + resolve(result); + } catch (e) { + reject(e); + } + dataArray = []; + }) + .resume(); + }); +} + +/** + * An helper to easily use workers outside of JSZip. + * @constructor + * @param {Worker} worker the worker to wrap + * @param {String} outputType the type of data expected by the use + * @param {String} mimeType the mime type of the content, if applicable. + */ +function StreamHelper(worker, outputType, mimeType) { + var internalType = outputType; + switch(outputType) { + case "blob": + internalType = "arraybuffer"; + break; + case "arraybuffer": + internalType = "uint8array"; + break; + case "base64": + internalType = "string"; + break; + } + + try { + // the type used internally + this._internalType = internalType; + // the type used to output results + this._outputType = outputType; + // the mime type + this._mimeType = mimeType; + utils.checkSupport(internalType); + this._worker = worker.pipe(new ConvertWorker(internalType)); + // the last workers can be rewired without issues but we need to + // prevent any updates on previous workers. + worker.lock(); + } catch(e) { + this._worker = new GenericWorker("error"); + this._worker.error(e); + } +} + +StreamHelper.prototype = { + /** + * Listen a StreamHelper, accumulate its content and concatenate it into a + * complete block. + * @param {Function} updateCb the update callback. + * @return Promise the promise for the accumulation. + */ + accumulate : function (updateCb) { + return accumulate(this, updateCb); + }, + /** + * Add a listener on an event triggered on a stream. + * @param {String} evt the name of the event + * @param {Function} fn the listener + * @return {StreamHelper} the current helper. + */ + on : function (evt, fn) { + var self = this; + + if(evt === "data") { + this._worker.on(evt, function (chunk) { + fn.call(self, chunk.data, chunk.meta); + }); + } else { + this._worker.on(evt, function () { + utils.delay(fn, arguments, self); + }); + } + return this; + }, + /** + * Resume the flow of chunks. + * @return {StreamHelper} the current helper. + */ + resume : function () { + utils.delay(this._worker.resume, [], this._worker); + return this; + }, + /** + * Pause the flow of chunks. + * @return {StreamHelper} the current helper. + */ + pause : function () { + this._worker.pause(); + return this; + }, + /** + * Return a nodejs stream for this helper. + * @param {Function} updateCb the update callback. + * @return {NodejsStreamOutputAdapter} the nodejs stream. + */ + toNodejsStream : function (updateCb) { + utils.checkSupport("nodestream"); + if (this._outputType !== "nodebuffer") { + // an object stream containing blob/arraybuffer/uint8array/string + // is strange and I don't know if it would be useful. + // I you find this comment and have a good usecase, please open a + // bug report ! + throw new Error(this._outputType + " is not supported by this method"); + } + + return new NodejsStreamOutputAdapter(this, { + objectMode : this._outputType !== "nodebuffer" + }, updateCb); + } +}; + + +module.exports = StreamHelper; + +},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(require,module,exports){ +'use strict'; + exports.base64 = true; exports.array = true; exports.string = true; exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; -// contains true if JSZip can read/generate nodejs Buffer, false otherwise. -// Browserify will provide a Buffer implementation for browsers, which is -// an augmented Uint8Array (i.e., can be used as either Buffer or U8). exports.nodebuffer = typeof Buffer !== "undefined"; // contains true if JSZip can read/generate Uint8Array, false otherwise. exports.uint8array = typeof Uint8Array !== "undefined"; @@ -1625,100 +2718,19 @@ else { } } -}).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined)) -},{}],18:[function(_dereq_,module,exports){ -'use strict'; -var DataReader = _dereq_('./dataReader'); - -function Uint8ArrayReader(data) { - if (data) { - this.data = data; - this.length = this.data.length; - this.index = 0; - } +try { + exports.nodestream = !!require('readable-stream').Readable; +} catch(e) { + exports.nodestream = false; } -Uint8ArrayReader.prototype = new DataReader(); -/** - * @see DataReader.byteAt - */ -Uint8ArrayReader.prototype.byteAt = function(i) { - return this.data[i]; -}; -/** - * @see DataReader.lastIndexOfSignature - */ -Uint8ArrayReader.prototype.lastIndexOfSignature = function(sig) { - var sig0 = sig.charCodeAt(0), - sig1 = sig.charCodeAt(1), - sig2 = sig.charCodeAt(2), - sig3 = sig.charCodeAt(3); - for (var i = this.length - 4; i >= 0; --i) { - if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { - return i; - } - } - return -1; -}; -/** - * @see DataReader.readData - */ -Uint8ArrayReader.prototype.readData = function(size) { - this.checkOffset(size); - if(size === 0) { - // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. - return new Uint8Array(0); - } - var result = this.data.subarray(this.index, this.index + size); - this.index += size; - return result; -}; -module.exports = Uint8ArrayReader; - -},{"./dataReader":5}],19:[function(_dereq_,module,exports){ +},{"readable-stream":16}],31:[function(require,module,exports){ 'use strict'; -var utils = _dereq_('./utils'); - -/** - * An object to write any content to an Uint8Array. - * @constructor - * @param {number} length The length of the array. - */ -var Uint8ArrayWriter = function(length) { - this.data = new Uint8Array(length); - this.index = 0; -}; -Uint8ArrayWriter.prototype = { - /** - * Append any content to the current array. - * @param {Object} input the content to add. - */ - append: function(input) { - if (input.length !== 0) { - // with an empty Uint8Array, Opera fails with a "Offset larger than array size" - input = utils.transformTo("uint8array", input); - this.data.set(input, this.index); - this.index += input.length; - } - }, - /** - * Finalize the construction an return the result. - * @return {Uint8Array} the generated array. - */ - finalize: function() { - return this.data; - } -}; - -module.exports = Uint8ArrayWriter; - -},{"./utils":21}],20:[function(_dereq_,module,exports){ -'use strict'; - -var utils = _dereq_('./utils'); -var support = _dereq_('./support'); -var nodeBuffer = _dereq_('./nodeBuffer'); +var utils = require('./utils'); +var support = require('./support'); +var nodejsUtils = require('./nodejsUtils'); +var GenericWorker = require('./stream/GenericWorker'); /** * The following functions come from pako, from pako/lib/utils/strings @@ -1883,7 +2895,7 @@ var buf2string = function (buf) { */ exports.utf8encode = function utf8encode(str) { if (support.nodebuffer) { - return nodeBuffer(str, "utf-8"); + return nodejsUtils.newBuffer(str, "utf-8"); } return string2buf(str); @@ -1903,50 +2915,134 @@ exports.utf8decode = function utf8decode(buf) { buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); - // return buf2string(buf); - // Chrome prefers to work with "small" chunks of data - // for the method buf2string. - // Firefox and Chrome has their own shortcut, IE doesn't seem to really care. - var result = [], k = 0, len = buf.length, chunk = 65536; - while (k < len) { - var nextBoundary = utf8border(buf, Math.min(k + chunk, len)); - if (support.uint8array) { - result.push(buf2string(buf.subarray(k, nextBoundary))); - } else { - result.push(buf2string(buf.slice(k, nextBoundary))); - } - k = nextBoundary; - } - return result.join(""); - + return buf2string(buf); }; -// vim: set shiftwidth=4 softtabstop=4: -},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(_dereq_,module,exports){ -'use strict'; -var support = _dereq_('./support'); -var compressions = _dereq_('./compressions'); -var nodeBuffer = _dereq_('./nodeBuffer'); /** - * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. - * @param {string} str the string to transform. - * @return {String} the binary string. + * A worker to decode utf8 encoded binary chunks into string chunks. + * @constructor */ -exports.string2binary = function(str) { - var result = ""; - for (var i = 0; i < str.length; i++) { - result += String.fromCharCode(str.charCodeAt(i) & 0xff); +function Utf8DecodeWorker() { + GenericWorker.call(this, "utf-8 decode"); + // the last bytes if a chunk didn't end with a complete codepoint. + this.leftOver = null; +} +utils.inherits(Utf8DecodeWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Utf8DecodeWorker.prototype.processChunk = function (chunk) { + + var data = utils.transformTo(support.uint8array ? "uint8array" : "array", chunk.data); + + // 1st step, re-use what's left of the previous chunk + if (this.leftOver && this.leftOver.length) { + if(support.uint8array) { + var previousData = data; + data = new Uint8Array(previousData.length + this.leftOver.length); + data.set(this.leftOver, 0); + data.set(previousData, this.leftOver.length); + } else { + data = this.leftOver.concat(data); + } + this.leftOver = null; } - return result; + + var nextBoundary = utf8border(data); + var usableData = data; + if (nextBoundary !== data.length) { + if (support.uint8array) { + usableData = data.subarray(0, nextBoundary); + this.leftOver = data.subarray(nextBoundary, data.length); + } else { + usableData = data.slice(0, nextBoundary); + this.leftOver = data.slice(nextBoundary, data.length); + } + } + + this.push({ + data : exports.utf8decode(usableData), + meta : chunk.meta + }); }; -exports.arrayBuffer2Blob = function(buffer, mimeType) { + +/** + * @see GenericWorker.flush + */ +Utf8DecodeWorker.prototype.flush = function () { + if(this.leftOver && this.leftOver.length) { + this.push({ + data : exports.utf8decode(this.leftOver), + meta : {} + }); + this.leftOver = null; + } +}; +exports.Utf8DecodeWorker = Utf8DecodeWorker; + +/** + * A worker to endcode string chunks into utf8 encoded binary chunks. + * @constructor + */ +function Utf8EncodeWorker() { + GenericWorker.call(this, "utf-8 encode"); +} +utils.inherits(Utf8EncodeWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Utf8EncodeWorker.prototype.processChunk = function (chunk) { + this.push({ + data : exports.utf8encode(chunk.data), + meta : chunk.meta + }); +}; +exports.Utf8EncodeWorker = Utf8EncodeWorker; + +},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(require,module,exports){ +'use strict'; + +var support = require('./support'); +var base64 = require('./base64'); +var nodejsUtils = require('./nodejsUtils'); +var setImmediate = require('core-js/library/fn/set-immediate'); +var external = require("./external"); + + +/** + * Convert a string that pass as a "binary string": it should represent a byte + * array but may have > 255 char codes. Be sure to take only the first byte + * and returns the byte array. + * @param {String} str the string to transform. + * @return {Array|Uint8Array} the string in a binary format. + */ +function string2binary(str) { + var result = null; + if (support.uint8array) { + result = new Uint8Array(str.length); + } else { + result = new Array(str.length); + } + return stringToArrayLike(str, result); +} + +/** + * Create a new blob with the given content and the given type. + * @param {Array[String|ArrayBuffer]} parts the content to put in the blob. DO NOT use + * an Uint8Array because the stock browser of android 4 won't accept it (it + * will be silently converted to a string, "[object Uint8Array]"). + * @param {String} type the mime type of the blob. + * @return {Blob} the created blob. + */ +exports.newBlob = function(parts, type) { exports.checkSupport("blob"); - mimeType = mimeType || 'application/zip'; try { // Blob constructor - return new Blob([buffer], { - type: mimeType + return new Blob(parts, { + type: type }); } catch (e) { @@ -1955,8 +3051,10 @@ exports.arrayBuffer2Blob = function(buffer, mimeType) { // deprecated, browser only, old way var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; var builder = new Builder(); - builder.append(buffer); - return builder.getBlob(mimeType); + for (var i = 0; i < parts.length; i++) { + builder.append(parts[i]); + } + return builder.getBlob(type); } catch (e) { @@ -1989,6 +3087,76 @@ function stringToArrayLike(str, array) { return array; } +/** + * An helper for the function arrayLikeToString. + * This contains static informations and functions that + * can be optimized by the browser JIT compiler. + */ +var arrayToStringHelper = { + /** + * Transform an array of int into a string, chunk by chunk. + * See the performances notes on arrayLikeToString. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @param {String} type the type of the array. + * @param {Integer} chunk the chunk size. + * @return {String} the resulting string. + * @throws Error if the chunk is too big for the stack. + */ + stringifyByChunk: function(array, type, chunk) { + var result = [], k = 0, len = array.length; + // shortcut + if (len <= chunk) { + return String.fromCharCode.apply(null, array); + } + while (k < len) { + if (type === "array" || type === "nodebuffer") { + result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); + } + else { + result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); + } + k += chunk; + } + return result.join(""); + }, + /** + * Call String.fromCharCode on every item in the array. + * This is the naive implementation, which generate A LOT of intermediate string. + * This should be used when everything else fail. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ + stringifyByChar: function(array){ + var resultStr = ""; + for(var i = 0; i < array.length; i++) { + resultStr += String.fromCharCode(array[i]); + } + return resultStr; + }, + applyCanBeUsed : { + /** + * true if the browser accepts to use String.fromCharCode on Uint8Array + */ + uint8array : (function () { + try { + return support.uint8array && String.fromCharCode.apply(null, new Uint8Array(1)).length === 1; + } catch (e) { + return false; + } + })(), + /** + * true if the browser accepts to use String.fromCharCode on nodejs Buffer. + */ + nodebuffer : (function () { + try { + return support.nodebuffer && String.fromCharCode.apply(null, nodejsUtils.newBuffer(1)).length === 1; + } catch (e) { + return false; + } + })() + } +}; + /** * Transform an array-like object to a string. * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. @@ -2004,49 +3172,29 @@ function arrayLikeToString(array) { // result += String.fromCharCode(array[i]); generate too many strings ! // // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 - var chunk = 65536; - var result = [], - len = array.length, + // TODO : we now have workers that split the work. Do we still need that ? + var chunk = 65536, type = exports.getTypeOf(array), - k = 0, canUseApply = true; - try { - switch(type) { - case "uint8array": - String.fromCharCode.apply(null, new Uint8Array(0)); - break; - case "nodebuffer": - String.fromCharCode.apply(null, nodeBuffer(0)); - break; - } - } catch(e) { - canUseApply = false; - } + if (type === "uint8array") { + canUseApply = arrayToStringHelper.applyCanBeUsed.uint8array; + } else if (type === "nodebuffer") { + canUseApply = arrayToStringHelper.applyCanBeUsed.nodebuffer; + } - // no apply : slow and painful algorithm - // default browser on android 4.* - if (!canUseApply) { - var resultStr = ""; - for(var i = 0; i < array.length;i++) { - resultStr += String.fromCharCode(array[i]); - } - return resultStr; - } - while (k < len && chunk > 1) { - try { - if (type === "array" || type === "nodebuffer") { - result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); + if (canUseApply) { + while (chunk > 1) { + try { + return arrayToStringHelper.stringifyByChunk(array, type, chunk); + } catch (e) { + chunk = Math.floor(chunk / 2); } - else { - result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); - } - k += chunk; - } - catch (e) { - chunk = Math.floor(chunk / 2); } } - return result.join(""); + + // no apply or chunk error : slow and painful algorithm + // default browser on android 4.* + return arrayToStringHelper.stringifyByChar(array); } exports.applyFromCharCode = arrayLikeToString; @@ -2081,7 +3229,7 @@ transform["string"] = { return stringToArrayLike(input, new Uint8Array(input.length)); }, "nodebuffer": function(input) { - return stringToArrayLike(input, nodeBuffer(input.length)); + return stringToArrayLike(input, nodejsUtils.newBuffer(input.length)); } }; @@ -2096,7 +3244,7 @@ transform["array"] = { return new Uint8Array(input); }, "nodebuffer": function(input) { - return nodeBuffer(input); + return nodejsUtils.newBuffer(input); } }; @@ -2113,7 +3261,7 @@ transform["arraybuffer"] = { return new Uint8Array(input); }, "nodebuffer": function(input) { - return nodeBuffer(new Uint8Array(input)); + return nodejsUtils.newBuffer(new Uint8Array(input)); } }; @@ -2124,11 +3272,17 @@ transform["uint8array"] = { return arrayLikeToArrayLike(input, new Array(input.length)); }, "arraybuffer": function(input) { - return input.buffer; + // copy the uint8array: DO NOT propagate the original ArrayBuffer, it + // can be way larger (the whole zip file for example). + var copy = new Uint8Array(input.length); + if (input.length) { + copy.set(input, 0); + } + return copy.buffer; }, "uint8array": identity, "nodebuffer": function(input) { - return nodeBuffer(input); + return nodejsUtils.newBuffer(input); } }; @@ -2183,7 +3337,7 @@ exports.getTypeOf = function(input) { if (Object.prototype.toString.call(input) === "[object Array]") { return "array"; } - if (support.nodebuffer && nodeBuffer.test(input)) { + if (support.nodebuffer && nodejsUtils.isBuffer(input)) { return "nodebuffer"; } if (support.uint8array && input instanceof Uint8Array) { @@ -2202,9 +3356,10 @@ exports.getTypeOf = function(input) { exports.checkSupport = function(type) { var supported = support[type.toLowerCase()]; if (!supported) { - throw new Error(type + " is not supported by this browser"); + throw new Error(type + " is not supported by this platform"); } }; + exports.MAX_VALUE_16BITS = 65535; exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 @@ -2224,55 +3379,125 @@ exports.pretty = function(str) { }; /** - * Find a compression registered in JSZip. - * @param {string} compressionMethod the method magic to find. - * @return {Object|null} the JSZip compression object, null if none found. + * Defer the call of a function. + * @param {Function} callback the function to call asynchronously. + * @param {Array} args the arguments to give to the callback. */ -exports.findCompression = function(compressionMethod) { - for (var method in compressions) { - if (!compressions.hasOwnProperty(method)) { - continue; - } - if (compressions[method].magic === compressionMethod) { - return compressions[method]; +exports.delay = function(callback, args, self) { + setImmediate(function () { + callback.apply(self || null, args || []); + }); +}; + +/** + * Extends a prototype with an other, without calling a constructor with + * side effects. Inspired by nodejs' `utils.inherits` + * @param {Function} ctor the constructor to augment + * @param {Function} superCtor the parent constructor to use + */ +exports.inherits = function (ctor, superCtor) { + var Obj = function() {}; + Obj.prototype = superCtor.prototype; + ctor.prototype = new Obj(); +}; + +/** + * Merge the objects passed as parameters into a new one. + * @private + * @param {...Object} var_args All objects to merge. + * @return {Object} a new object with the data of the others. + */ +exports.extend = function() { + var result = {}, i, attr; + for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers + for (attr in arguments[i]) { + if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { + result[attr] = arguments[i][attr]; + } } } - return null; + return result; }; + /** -* Cross-window, cross-Node-context regular expression detection -* @param {Object} object Anything -* @return {Boolean} true if the object is a regular expression, -* false otherwise -*/ -exports.isRegExp = function (object) { - return Object.prototype.toString.call(object) === "[object RegExp]"; + * Transform arbitrary content into a Promise. + * @param {String} name a name for the content being processed. + * @param {Object} inputData the content to process. + * @param {Boolean} isBinary true if the content is not an unicode string + * @param {Boolean} isOptimizedBinaryString true if the string content only has one byte per character. + * @param {Boolean} isBase64 true if the string content is encoded with base64. + * @return {Promise} a promise in a format usable by JSZip. + */ +exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinaryString, isBase64) { + + // if inputData is already a promise, this flatten it. + var promise = external.Promise.resolve(inputData).then(function(data) { + + + var isBlob = support.blob && (data instanceof Blob || ['[object File]', '[object Blob]'].indexOf(Object.prototype.toString.call(data)) !== -1); + + if (isBlob && typeof FileReader !== "undefined") { + return new external.Promise(function (resolve, reject) { + var reader = new FileReader(); + + reader.onload = function(e) { + resolve(e.target.result); + }; + reader.onerror = function(e) { + reject(e.target.error); + }; + reader.readAsArrayBuffer(data); + }); + } else { + return data; + } + }); + + return promise.then(function(data) { + var dataType = exports.getTypeOf(data); + + if (!dataType) { + return external.Promise.reject( + new Error("The data of '" + name + "' is in an unsupported format !") + ); + } + // special case : it's way easier to work with Uint8Array than with ArrayBuffer + if (dataType === "arraybuffer") { + data = exports.transformTo("uint8array", data); + } else if (dataType === "string") { + if (isBase64) { + data = base64.decode(data); + } + else if (isBinary) { + // optimizedBinaryString === true means that the file has already been filtered with a 0xFF mask + if (isOptimizedBinaryString !== true) { + // this is a string, not in a base64 format. + // Be sure that this is a correct "binary string" + data = string2binary(data); + } + } + } + return data; + }); }; - -},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(_dereq_,module,exports){ +},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"core-js/library/fn/set-immediate":36}],33:[function(require,module,exports){ 'use strict'; -var StringReader = _dereq_('./stringReader'); -var NodeBufferReader = _dereq_('./nodeBufferReader'); -var Uint8ArrayReader = _dereq_('./uint8ArrayReader'); -var utils = _dereq_('./utils'); -var sig = _dereq_('./signature'); -var ZipEntry = _dereq_('./zipEntry'); -var support = _dereq_('./support'); -var jszipProto = _dereq_('./object'); +var readerFor = require('./reader/readerFor'); +var utils = require('./utils'); +var sig = require('./signature'); +var ZipEntry = require('./zipEntry'); +var utf8 = require('./utf8'); +var support = require('./support'); // class ZipEntries {{{ /** * All the entries in the zip file. * @constructor - * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. * @param {Object} loadOptions Options for loading the stream. */ -function ZipEntries(data, loadOptions) { +function ZipEntries(loadOptions) { this.files = []; this.loadOptions = loadOptions; - if (data) { - this.load(data); - } } ZipEntries.prototype = { /** @@ -2281,11 +3506,26 @@ ZipEntries.prototype = { * @throws {Error} if it is an other signature. */ checkSignature: function(expectedSignature) { - var signature = this.reader.readString(4); - if (signature !== expectedSignature) { + if (!this.reader.readAndCheckSignature(expectedSignature)) { + this.reader.index -= 4; + var signature = this.reader.readString(4); throw new Error("Corrupted zip or bug : unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); } }, + /** + * Check if the given signature is at the given index. + * @param {number} askedIndex the index to check. + * @param {string} expectedSignature the signature to expect. + * @return {boolean} true if the signature is here, false otherwise. + */ + isSignature: function(askedIndex, expectedSignature) { + var currentIndex = this.reader.index; + this.reader.setIndex(askedIndex); + var signature = this.reader.readString(4); + var result = signature === expectedSignature; + this.reader.setIndex(currentIndex); + return result; + }, /** * Read the end of the central directory. */ @@ -2301,10 +3541,12 @@ ZipEntries.prototype = { // warning : the encoding depends of the system locale // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. // On a windows machine, this field is encoded with the localized windows code page. - this.zipComment = this.reader.readString(this.zipCommentLength); + var zipComment = this.reader.readData(this.zipCommentLength); + var decodeParamType = support.uint8array ? "uint8array" : "array"; // To get consistent behavior with the generation part, we will assume that - // this is utf8 encoded. - this.zipComment = jszipProto.utf8decode(this.zipComment); + // this is utf8 encoded unless specified otherwise. + var decodeContent = utils.transformTo(decodeParamType, zipComment); + this.zipComment = this.loadOptions.decodeFileName(decodeContent); }, /** * Read the end of the Zip 64 central directory. @@ -2314,8 +3556,9 @@ ZipEntries.prototype = { */ readBlockZip64EndOfCentral: function() { this.zip64EndOfCentralSize = this.reader.readInt(8); - this.versionMadeBy = this.reader.readString(2); - this.versionNeeded = this.reader.readInt(2); + this.reader.skip(4); + // this.versionMadeBy = this.reader.readString(2); + // this.versionNeeded = this.reader.readInt(2); this.diskNumber = this.reader.readInt(4); this.diskWithCentralDirStart = this.reader.readInt(4); this.centralDirRecordsOnThisDisk = this.reader.readInt(8); @@ -2332,7 +3575,7 @@ ZipEntries.prototype = { while (index < extraDataSize) { extraFieldId = this.reader.readInt(2); extraFieldLength = this.reader.readInt(4); - extraFieldValue = this.reader.readString(extraFieldLength); + extraFieldValue = this.reader.readData(extraFieldLength); this.zip64ExtensibleData[extraFieldId] = { id: extraFieldId, length: extraFieldLength, @@ -2372,31 +3615,38 @@ ZipEntries.prototype = { var file; this.reader.setIndex(this.centralDirOffset); - while (this.reader.readString(4) === sig.CENTRAL_FILE_HEADER) { + while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) { file = new ZipEntry({ zip64: this.zip64 }, this.loadOptions); file.readCentralPart(this.reader); this.files.push(file); } + + if (this.centralDirRecords !== this.files.length) { + if (this.centralDirRecords !== 0 && this.files.length === 0) { + // We expected some records but couldn't find ANY. + // This is really suspicious, as if something went wrong. + throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length); + } else { + // We found some records but not all. + // Something is wrong but we got something for the user: no error here. + // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length); + } + } }, /** * Read the end of central directory. */ readEndOfCentral: function() { var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); - if (offset === -1) { + if (offset < 0) { // Check if the content is a truncated zip or complete garbage. // A "LOCAL_FILE_HEADER" is not required at the beginning (auto // extractible zip for example) but it can give a good hint. // If an ajax request was used without responseType, we will also // get unreadable data. - var isGarbage = true; - try { - this.reader.setIndex(0); - this.checkSignature(sig.LOCAL_FILE_HEADER); - isGarbage = false; - } catch (e) {} + var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER); if (isGarbage) { throw new Error("Can't find end of central directory : is this a zip file ? " + @@ -2404,8 +3654,10 @@ ZipEntries.prototype = { } else { throw new Error("Corrupted zip : can't find end of central directory"); } + } this.reader.setIndex(offset); + var endOfCentralDirOffset = offset; this.checkSignature(sig.CENTRAL_DIRECTORY_END); this.readBlockEndOfCentral(); @@ -2434,7 +3686,7 @@ ZipEntries.prototype = { // should look for a zip64 EOCD locator offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); - if (offset === -1) { + if (offset < 0) { throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); } this.reader.setIndex(offset); @@ -2442,22 +3694,42 @@ ZipEntries.prototype = { this.readBlockZip64EndOfCentralLocator(); // now the zip64 EOCD record + if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) { + // console.warn("ZIP64 end of central directory not where expected."); + this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + if (this.relativeOffsetEndOfZip64CentralDir < 0) { + throw new Error("Corrupted zip : can't find the ZIP64 end of central directory"); + } + } this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); this.readBlockZip64EndOfCentral(); } + + var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize; + if (this.zip64) { + expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator + expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize; + } + + var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset; + + if (extraBytes > 0) { + // console.warn(extraBytes, "extra bytes at beginning or within zipfile"); + if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) { + // The offsets seem wrong, but we have something at the specified offset. + // So… we keep it. + } else { + // the offset is wrong, update the "zero" of the reader + // this happens if data has been prepended (crx files for example) + this.reader.zero = extraBytes; + } + } else if (extraBytes < 0) { + throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes."); + } }, prepareReader: function(data) { - var type = utils.getTypeOf(data); - if (type === "string" && !support.uint8array) { - this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString); - } - else if (type === "nodebuffer") { - this.reader = new NodeBufferReader(data); - } - else { - this.reader = new Uint8ArrayReader(utils.transformTo("uint8array", data)); - } + this.reader = readerFor(data); }, /** * Read a zip file and create ZipEntries. @@ -2473,16 +3745,36 @@ ZipEntries.prototype = { // }}} end of ZipEntries module.exports = ZipEntries; -},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(_dereq_,module,exports){ +},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utf8":31,"./utils":32,"./zipEntry":34}],34:[function(require,module,exports){ 'use strict'; -var StringReader = _dereq_('./stringReader'); -var utils = _dereq_('./utils'); -var CompressedObject = _dereq_('./compressedObject'); -var jszipProto = _dereq_('./object'); +var readerFor = require('./reader/readerFor'); +var utils = require('./utils'); +var CompressedObject = require('./compressedObject'); +var crc32fn = require('./crc32'); +var utf8 = require('./utf8'); +var compressions = require('./compressions'); +var support = require('./support'); var MADE_BY_DOS = 0x00; var MADE_BY_UNIX = 0x03; +/** + * Find a compression registered in JSZip. + * @param {string} compressionMethod the method magic to find. + * @return {Object|null} the JSZip compression object, null if none found. + */ +var findCompression = function(compressionMethod) { + for (var method in compressions) { + if (!compressions.hasOwnProperty(method)) { + continue; + } + if (compressions[method].magic === compressionMethod) { + return compressions[method]; + } + } + return null; +}; + // class ZipEntry {{{ /** * An entry in the zip file. @@ -2511,45 +3803,6 @@ ZipEntry.prototype = { // bit 11 is set return (this.bitFlag & 0x0800) === 0x0800; }, - /** - * Prepare the function used to generate the compressed content from this ZipFile. - * @param {DataReader} reader the reader to use. - * @param {number} from the offset from where we should read the data. - * @param {number} length the length of the data to read. - * @return {Function} the callback to get the compressed content (the type depends of the DataReader class). - */ - prepareCompressedContent: function(reader, from, length) { - return function() { - var previousIndex = reader.index; - reader.setIndex(from); - var compressedFileData = reader.readData(length); - reader.setIndex(previousIndex); - - return compressedFileData; - }; - }, - /** - * Prepare the function used to generate the uncompressed content from this ZipFile. - * @param {DataReader} reader the reader to use. - * @param {number} from the offset from where we should read the data. - * @param {number} length the length of the data to read. - * @param {JSZip.compression} compression the compression used on this file. - * @param {number} uncompressedSize the uncompressed size to expect. - * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class). - */ - prepareContent: function(reader, from, length, compression, uncompressedSize) { - return function() { - - var compressedFileData = utils.transformTo(compression.uncompressInputType, this.getCompressedContent()); - var uncompressedFileData = compression.uncompress(compressedFileData); - - if (uncompressedFileData.length !== uncompressedSize) { - throw new Error("Bug : uncompressed data size mismatch"); - } - - return uncompressedFileData; - }; - }, /** * Read the local part of a zip file and add the info in this object. * @param {DataReader} reader the reader to use. @@ -2576,32 +3829,19 @@ ZipEntry.prototype = { // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 this.fileNameLength = reader.readInt(2); localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir - this.fileName = reader.readString(this.fileNameLength); + // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding. + this.fileName = reader.readData(this.fileNameLength); reader.skip(localExtraFieldsLength); - if (this.compressedSize == -1 || this.uncompressedSize == -1) { - throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize == -1 || uncompressedSize == -1)"); + if (this.compressedSize === -1 || this.uncompressedSize === -1) { + throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)"); } - compression = utils.findCompression(this.compressionMethod); + compression = findCompression(this.compressionMethod); if (compression === null) { // no compression found - throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + this.fileName + ")"); - } - this.decompressed = new CompressedObject(); - this.decompressed.compressedSize = this.compressedSize; - this.decompressed.uncompressedSize = this.uncompressedSize; - this.decompressed.crc32 = this.crc32; - this.decompressed.compressionMethod = this.compressionMethod; - this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression); - this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize); - - // we need to compute the crc32... - if (this.loadOptions.checkCRC32) { - this.decompressed = utils.transformTo("string", this.decompressed.getContent()); - if (jszipProto.crc32(this.decompressed) !== this.crc32) { - throw new Error("Corrupted zip : CRC32 mismatch"); - } + throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")"); } + this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize)); }, /** @@ -2610,14 +3850,15 @@ ZipEntry.prototype = { */ readCentralPart: function(reader) { this.versionMadeBy = reader.readInt(2); - this.versionNeeded = reader.readInt(2); + reader.skip(2); + // this.versionNeeded = reader.readInt(2); this.bitFlag = reader.readInt(2); this.compressionMethod = reader.readString(2); this.date = reader.readDate(); this.crc32 = reader.readInt(4); this.compressedSize = reader.readInt(4); this.uncompressedSize = reader.readInt(4); - this.fileNameLength = reader.readInt(2); + var fileNameLength = reader.readInt(2); this.extraFieldsLength = reader.readInt(2); this.fileCommentLength = reader.readInt(2); this.diskNumberStart = reader.readInt(2); @@ -2629,10 +3870,11 @@ ZipEntry.prototype = { throw new Error("Encrypted zip are not supported"); } - this.fileName = reader.readString(this.fileNameLength); + // will be read in the local part, see the comments there + reader.skip(fileNameLength); this.readExtraFields(reader); this.parseZIP64ExtraField(reader); - this.fileComment = reader.readString(this.fileCommentLength); + this.fileComment = reader.readData(this.fileCommentLength); }, /** @@ -2659,7 +3901,7 @@ ZipEntry.prototype = { } // fail safe : if the name ends with a / it probably means a folder - if (!this.dir && this.fileName.slice(-1) === '/') { + if (!this.dir && this.fileNameStr.slice(-1) === '/') { this.dir = true; } }, @@ -2675,7 +3917,7 @@ ZipEntry.prototype = { } // should be something, preparing the extra reader - var extraReader = new StringReader(this.extraFields[0x0001].value); + var extraReader = readerFor(this.extraFields[0x0001].value); // I really hope that these 64bits integer can fit in 32 bits integer, because js // won't let us have more. @@ -2697,17 +3939,19 @@ ZipEntry.prototype = { * @param {DataReader} reader the reader to use. */ readExtraFields: function(reader) { - var start = reader.index, + var end = reader.index + this.extraFieldsLength, extraFieldId, extraFieldLength, extraFieldValue; - this.extraFields = this.extraFields || {}; + if (!this.extraFields) { + this.extraFields = {}; + } - while (reader.index < start + this.extraFieldsLength) { + while (reader.index < end) { extraFieldId = reader.readInt(2); extraFieldLength = reader.readInt(2); - extraFieldValue = reader.readString(extraFieldLength); + extraFieldValue = reader.readData(extraFieldLength); this.extraFields[extraFieldId] = { id: extraFieldId, @@ -2720,17 +3964,27 @@ ZipEntry.prototype = { * Apply an UTF8 transformation if needed. */ handleUTF8: function() { + var decodeParamType = support.uint8array ? "uint8array" : "array"; if (this.useUTF8()) { - this.fileName = jszipProto.utf8decode(this.fileName); - this.fileComment = jszipProto.utf8decode(this.fileComment); + this.fileNameStr = utf8.utf8decode(this.fileName); + this.fileCommentStr = utf8.utf8decode(this.fileComment); } else { var upath = this.findExtraFieldUnicodePath(); if (upath !== null) { - this.fileName = upath; + this.fileNameStr = upath; + } else { + // ASCII text or unsupported code page + var fileNameByteArray = utils.transformTo(decodeParamType, this.fileName); + this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray); } + var ucomment = this.findExtraFieldUnicodeComment(); if (ucomment !== null) { - this.fileComment = ucomment; + this.fileCommentStr = ucomment; + } else { + // ASCII text or unsupported code page + var commentByteArray = utils.transformTo(decodeParamType, this.fileComment); + this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray); } } }, @@ -2742,7 +3996,7 @@ ZipEntry.prototype = { findExtraFieldUnicodePath: function() { var upathField = this.extraFields[0x7075]; if (upathField) { - var extraReader = new StringReader(upathField.value); + var extraReader = readerFor(upathField.value); // wrong version if (extraReader.readInt(1) !== 1) { @@ -2750,11 +4004,11 @@ ZipEntry.prototype = { } // the crc of the filename changed, this field is out of date. - if (jszipProto.crc32(this.fileName) !== extraReader.readInt(4)) { + if (crc32fn(this.fileName) !== extraReader.readInt(4)) { return null; } - return jszipProto.utf8decode(extraReader.readString(upathField.length - 5)); + return utf8.utf8decode(extraReader.readData(upathField.length - 5)); } return null; }, @@ -2766,7 +4020,7 @@ ZipEntry.prototype = { findExtraFieldUnicodeComment: function() { var ucommentField = this.extraFields[0x6375]; if (ucommentField) { - var extraReader = new StringReader(ucommentField.value); + var extraReader = readerFor(ucommentField.value); // wrong version if (extraReader.readInt(1) !== 1) { @@ -2774,42 +4028,788 @@ ZipEntry.prototype = { } // the crc of the comment changed, this field is out of date. - if (jszipProto.crc32(this.fileComment) !== extraReader.readInt(4)) { + if (crc32fn(this.fileComment) !== extraReader.readInt(4)) { return null; } - return jszipProto.utf8decode(extraReader.readString(ucommentField.length - 5)); + return utf8.utf8decode(extraReader.readData(ucommentField.length - 5)); } return null; } }; module.exports = ZipEntry; -},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(_dereq_,module,exports){ +},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(require,module,exports){ +'use strict'; + +var StreamHelper = require('./stream/StreamHelper'); +var DataWorker = require('./stream/DataWorker'); +var utf8 = require('./utf8'); +var CompressedObject = require('./compressedObject'); +var GenericWorker = require('./stream/GenericWorker'); + +/** + * A simple object representing a file in the zip file. + * @constructor + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data + * @param {Object} options the options of the file + */ +var ZipObject = function(name, data, options) { + this.name = name; + this.dir = options.dir; + this.date = options.date; + this.comment = options.comment; + this.unixPermissions = options.unixPermissions; + this.dosPermissions = options.dosPermissions; + + this._data = data; + this._dataBinary = options.binary; + // keep only the compression + this.options = { + compression : options.compression, + compressionOptions : options.compressionOptions + }; +}; + +ZipObject.prototype = { + /** + * Create an internal stream for the content of this object. + * @param {String} type the type of each chunk. + * @return StreamHelper the stream. + */ + internalStream: function (type) { + var outputType = type.toLowerCase(); + var askUnicodeString = outputType === "string" || outputType === "text"; + if (outputType === "binarystring" || outputType === "text") { + outputType = "string"; + } + var result = this._decompressWorker(); + + var isUnicodeString = !this._dataBinary; + + if (isUnicodeString && !askUnicodeString) { + result = result.pipe(new utf8.Utf8EncodeWorker()); + } + if (!isUnicodeString && askUnicodeString) { + result = result.pipe(new utf8.Utf8DecodeWorker()); + } + + return new StreamHelper(result, outputType, ""); + }, + + /** + * Prepare the content in the asked type. + * @param {String} type the type of the result. + * @param {Function} onUpdate a function to call on each internal update. + * @return Promise the promise of the result. + */ + async: function (type, onUpdate) { + return this.internalStream(type).accumulate(onUpdate); + }, + + /** + * Prepare the content as a nodejs stream. + * @param {String} type the type of each chunk. + * @param {Function} onUpdate a function to call on each internal update. + * @return Stream the stream. + */ + nodeStream: function (type, onUpdate) { + return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate); + }, + + /** + * Return a worker for the compressed content. + * @private + * @param {Object} compression the compression object to use. + * @param {Object} compressionOptions the options to use when compressing. + * @return Worker the worker. + */ + _compressWorker: function (compression, compressionOptions) { + if ( + this._data instanceof CompressedObject && + this._data.compression.magic === compression.magic + ) { + return this._data.getCompressedWorker(); + } else { + var result = this._decompressWorker(); + if(!this._dataBinary) { + result = result.pipe(new utf8.Utf8EncodeWorker()); + } + return CompressedObject.createWorkerFrom(result, compression, compressionOptions); + } + }, + /** + * Return a worker for the decompressed content. + * @private + * @return Worker the worker. + */ + _decompressWorker : function () { + if (this._data instanceof CompressedObject) { + return this._data.getContentWorker(); + } else if (this._data instanceof GenericWorker) { + return this._data; + } else { + return new DataWorker(this._data); + } + } +}; + +var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"]; +var removedFn = function () { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); +}; + +for(var i = 0; i < removedMethods.length; i++) { + ZipObject.prototype[removedMethods[i]] = removedFn; +} +module.exports = ZipObject; + +},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(require,module,exports){ +require('../modules/web.immediate'); +module.exports = require('../modules/_core').setImmediate; +},{"../modules/_core":40,"../modules/web.immediate":56}],37:[function(require,module,exports){ +module.exports = function(it){ + if(typeof it != 'function')throw TypeError(it + ' is not a function!'); + return it; +}; +},{}],38:[function(require,module,exports){ +var isObject = require('./_is-object'); +module.exports = function(it){ + if(!isObject(it))throw TypeError(it + ' is not an object!'); + return it; +}; +},{"./_is-object":51}],39:[function(require,module,exports){ +var toString = {}.toString; + +module.exports = function(it){ + return toString.call(it).slice(8, -1); +}; +},{}],40:[function(require,module,exports){ +var core = module.exports = {version: '2.3.0'}; +if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef +},{}],41:[function(require,module,exports){ +// optional / simple context binding +var aFunction = require('./_a-function'); +module.exports = function(fn, that, length){ + aFunction(fn); + if(that === undefined)return fn; + switch(length){ + case 1: return function(a){ + return fn.call(that, a); + }; + case 2: return function(a, b){ + return fn.call(that, a, b); + }; + case 3: return function(a, b, c){ + return fn.call(that, a, b, c); + }; + } + return function(/* ...args */){ + return fn.apply(that, arguments); + }; +}; +},{"./_a-function":37}],42:[function(require,module,exports){ +// Thank's IE8 for his funny defineProperty +module.exports = !require('./_fails')(function(){ + return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; +}); +},{"./_fails":45}],43:[function(require,module,exports){ +var isObject = require('./_is-object') + , document = require('./_global').document + // in old IE typeof document.createElement is 'object' + , is = isObject(document) && isObject(document.createElement); +module.exports = function(it){ + return is ? document.createElement(it) : {}; +}; +},{"./_global":46,"./_is-object":51}],44:[function(require,module,exports){ +var global = require('./_global') + , core = require('./_core') + , ctx = require('./_ctx') + , hide = require('./_hide') + , PROTOTYPE = 'prototype'; + +var $export = function(type, name, source){ + var IS_FORCED = type & $export.F + , IS_GLOBAL = type & $export.G + , IS_STATIC = type & $export.S + , IS_PROTO = type & $export.P + , IS_BIND = type & $export.B + , IS_WRAP = type & $export.W + , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) + , expProto = exports[PROTOTYPE] + , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] + , key, own, out; + if(IS_GLOBAL)source = name; + for(key in source){ + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + if(own && key in exports)continue; + // export native or passed + out = own ? target[key] : source[key]; + // prevent global pollution for namespaces + exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] + // bind timers to global for call from export context + : IS_BIND && own ? ctx(out, global) + // wrap global constructors for prevent change them in library + : IS_WRAP && target[key] == out ? (function(C){ + var F = function(a, b, c){ + if(this instanceof C){ + switch(arguments.length){ + case 0: return new C; + case 1: return new C(a); + case 2: return new C(a, b); + } return new C(a, b, c); + } return C.apply(this, arguments); + }; + F[PROTOTYPE] = C[PROTOTYPE]; + return F; + // make static versions for prototype methods + })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; + // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% + if(IS_PROTO){ + (exports.virtual || (exports.virtual = {}))[key] = out; + // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% + if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); + } + } +}; +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +module.exports = $export; +},{"./_core":40,"./_ctx":41,"./_global":46,"./_hide":47}],45:[function(require,module,exports){ +module.exports = function(exec){ + try { + return !!exec(); + } catch(e){ + return true; + } +}; +},{}],46:[function(require,module,exports){ +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); +if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef +},{}],47:[function(require,module,exports){ +var dP = require('./_object-dp') + , createDesc = require('./_property-desc'); +module.exports = require('./_descriptors') ? function(object, key, value){ + return dP.f(object, key, createDesc(1, value)); +} : function(object, key, value){ + object[key] = value; + return object; +}; +},{"./_descriptors":42,"./_object-dp":52,"./_property-desc":53}],48:[function(require,module,exports){ +module.exports = require('./_global').document && document.documentElement; +},{"./_global":46}],49:[function(require,module,exports){ +module.exports = !require('./_descriptors') && !require('./_fails')(function(){ + return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7; +}); +},{"./_descriptors":42,"./_dom-create":43,"./_fails":45}],50:[function(require,module,exports){ +// fast apply, http://jsperf.lnkit.com/fast-apply/5 +module.exports = function(fn, args, that){ + var un = that === undefined; + switch(args.length){ + case 0: return un ? fn() + : fn.call(that); + case 1: return un ? fn(args[0]) + : fn.call(that, args[0]); + case 2: return un ? fn(args[0], args[1]) + : fn.call(that, args[0], args[1]); + case 3: return un ? fn(args[0], args[1], args[2]) + : fn.call(that, args[0], args[1], args[2]); + case 4: return un ? fn(args[0], args[1], args[2], args[3]) + : fn.call(that, args[0], args[1], args[2], args[3]); + } return fn.apply(that, args); +}; +},{}],51:[function(require,module,exports){ +module.exports = function(it){ + return typeof it === 'object' ? it !== null : typeof it === 'function'; +}; +},{}],52:[function(require,module,exports){ +var anObject = require('./_an-object') + , IE8_DOM_DEFINE = require('./_ie8-dom-define') + , toPrimitive = require('./_to-primitive') + , dP = Object.defineProperty; + +exports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){ + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if(IE8_DOM_DEFINE)try { + return dP(O, P, Attributes); + } catch(e){ /* empty */ } + if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); + if('value' in Attributes)O[P] = Attributes.value; + return O; +}; +},{"./_an-object":38,"./_descriptors":42,"./_ie8-dom-define":49,"./_to-primitive":55}],53:[function(require,module,exports){ +module.exports = function(bitmap, value){ + return { + enumerable : !(bitmap & 1), + configurable: !(bitmap & 2), + writable : !(bitmap & 4), + value : value + }; +}; +},{}],54:[function(require,module,exports){ +var ctx = require('./_ctx') + , invoke = require('./_invoke') + , html = require('./_html') + , cel = require('./_dom-create') + , global = require('./_global') + , process = global.process + , setTask = global.setImmediate + , clearTask = global.clearImmediate + , MessageChannel = global.MessageChannel + , counter = 0 + , queue = {} + , ONREADYSTATECHANGE = 'onreadystatechange' + , defer, channel, port; +var run = function(){ + var id = +this; + if(queue.hasOwnProperty(id)){ + var fn = queue[id]; + delete queue[id]; + fn(); + } +}; +var listener = function(event){ + run.call(event.data); +}; +// Node.js 0.9+ & IE10+ has setImmediate, otherwise: +if(!setTask || !clearTask){ + setTask = function setImmediate(fn){ + var args = [], i = 1; + while(arguments.length > i)args.push(arguments[i++]); + queue[++counter] = function(){ + invoke(typeof fn == 'function' ? fn : Function(fn), args); + }; + defer(counter); + return counter; + }; + clearTask = function clearImmediate(id){ + delete queue[id]; + }; + // Node.js 0.8- + if(require('./_cof')(process) == 'process'){ + defer = function(id){ + process.nextTick(ctx(run, id, 1)); + }; + // Browsers with MessageChannel, includes WebWorkers + } else if(MessageChannel){ + channel = new MessageChannel; + port = channel.port2; + channel.port1.onmessage = listener; + defer = ctx(port.postMessage, port, 1); + // Browsers with postMessage, skip WebWorkers + // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' + } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ + defer = function(id){ + global.postMessage(id + '', '*'); + }; + global.addEventListener('message', listener, false); + // IE8- + } else if(ONREADYSTATECHANGE in cel('script')){ + defer = function(id){ + html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ + html.removeChild(this); + run.call(id); + }; + }; + // Rest old browsers + } else { + defer = function(id){ + setTimeout(ctx(run, id, 1), 0); + }; + } +} +module.exports = { + set: setTask, + clear: clearTask +}; +},{"./_cof":39,"./_ctx":41,"./_dom-create":43,"./_global":46,"./_html":48,"./_invoke":50}],55:[function(require,module,exports){ +// 7.1.1 ToPrimitive(input [, PreferredType]) +var isObject = require('./_is-object'); +// instead of the ES6 spec version, we didn't implement @@toPrimitive case +// and the second argument - flag - preferred type is a string +module.exports = function(it, S){ + if(!isObject(it))return it; + var fn, val; + if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; + if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val; + if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; + throw TypeError("Can't convert object to primitive value"); +}; +},{"./_is-object":51}],56:[function(require,module,exports){ +var $export = require('./_export') + , $task = require('./_task'); +$export($export.G + $export.B, { + setImmediate: $task.set, + clearImmediate: $task.clear +}); +},{"./_export":44,"./_task":54}],57:[function(require,module,exports){ +(function (global){ +'use strict'; +var Mutation = global.MutationObserver || global.WebKitMutationObserver; + +var scheduleDrain; + +{ + if (Mutation) { + var called = 0; + var observer = new Mutation(nextTick); + var element = global.document.createTextNode(''); + observer.observe(element, { + characterData: true + }); + scheduleDrain = function () { + element.data = (called = ++called % 2); + }; + } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') { + var channel = new global.MessageChannel(); + channel.port1.onmessage = nextTick; + scheduleDrain = function () { + channel.port2.postMessage(0); + }; + } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) { + scheduleDrain = function () { + + // Create a + diff --git a/vendor/underscore/karma.conf-sauce.js b/vendor/underscore/karma.conf-sauce.js new file mode 100644 index 000000000..7cf946ecd --- /dev/null +++ b/vendor/underscore/karma.conf-sauce.js @@ -0,0 +1,93 @@ +var _ = require('./'); + +// Browsers to run on Sauce Labs platforms +var sauceBrowsers = _.reduce([ + ['firefox', '35'], + ['firefox', '30'], + ['firefox', '21'], + ['firefox', '11'], + ['firefox', '4'], + + ['chrome', '40'], + ['chrome', '39'], + ['chrome', '31'], + ['chrome', '26'], + + ['microsoftedge', '20.10240', 'Windows 10'], + ['internet explorer', '11', 'Windows 10'], + ['internet explorer', '10', 'Windows 8'], + ['internet explorer', '9', 'Windows 7'], + // Currently disabled due to karma-sauce issues + // ['internet explorer', '8'], + // ['internet explorer', '7'], + // ['internet explorer', '6'], + + ['opera', '12'], + ['opera', '11'], + + ['android', '5'], + ['android', '4.4'], + ['android', '4.3'], + ['android', '4.0'], + + ['safari', '8.0', 'OS X 10.10'], + ['safari', '7'], + ['safari', '6'], + ['safari', '5'] +], function(memo, platform) { + // internet explorer -> ie + var label = platform[0].split(' '); + if (label.length > 1) { + label = _.invoke(label, 'charAt', 0) + } + label = (label.join("") + '_v' + platform[1]).replace(' ', '_').toUpperCase(); + memo[label] = _.pick({ + 'base': 'SauceLabs', + 'browserName': platform[0], + 'version': platform[1], + 'platform': platform[2] + }, Boolean); + return memo; +}, {}); + +module.exports = function(config) { + if ( !process.env.SAUCE_USERNAME || !process.env.SAUCE_ACCESS_KEY ) { + console.log('Sauce environments not set --- Skipping'); + return process.exit(0); + } + + config.set({ + basePath: '', + frameworks: ['qunit'], + singleRun: true, + + // list of files / patterns to load in the browser + files: [ + 'test/vendor/qunit-extras.js', + 'test/qunit-setup.js', + 'underscore.js', + 'test/*.js' + ], + + // Number of sauce tests to start in parallel + concurrency: 9, + + // test results reporter to use + reporters: ['dots', 'saucelabs'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + sauceLabs: { + build: 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')', + startConnect: true, + tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER + }, + + captureTimeout: 120000, + customLaunchers: sauceBrowsers, + + // Browsers to launch, commented out to prevent karma from starting + // too many concurrent browsers and timing sauce out. + browsers: _.keys(sauceBrowsers) + }); +}; diff --git a/vendor/underscore/karma.conf.js b/vendor/underscore/karma.conf.js new file mode 100644 index 000000000..d01f24ee0 --- /dev/null +++ b/vendor/underscore/karma.conf.js @@ -0,0 +1,35 @@ +// Note some browser launchers should be installed before using karma start. + +// For example: +// $ npm install karma-firefox-launcher +// $ karma start --browser=Firefox + +// See http://karma-runner.github.io/0.8/config/configuration-file.html +module.exports = function(config) { + config.set({ + basePath: '', + frameworks: ['qunit'], + logLevel: config.LOG_INFO, + port: 9876, + + // list of files / patterns to load in the browser + files: [ + 'test/vendor/qunit-extras.js', + 'test/qunit-setup.js', + 'underscore.js', + 'test/*.js' + ], + + // Test results reporter to use + // https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress'], + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['PhantomJS'], + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: true + }); +}; \ No newline at end of file diff --git a/vendor/underscore/package.json b/vendor/underscore/package.json index baf11b2eb..eff9fca51 100644 --- a/vendor/underscore/package.json +++ b/vendor/underscore/package.json @@ -1,23 +1,50 @@ { - "name" : "underscore", - "description" : "JavaScript's functional programming helper library.", - "homepage" : "http://underscorejs.org", - "keywords" : ["util", "functional", "server", "client", "browser"], - "author" : "Jeremy Ashkenas ", - "repository" : {"type": "git", "url": "git://github.com/jashkenas/underscore.git"}, - "main" : "underscore.js", - "version" : "1.5.2", + "name": "underscore", + "description": "JavaScript's functional programming helper library.", + "homepage": "http://underscorejs.org", + "keywords": [ + "util", + "functional", + "server", + "client", + "browser" + ], + "author": "Jeremy Ashkenas ", + "repository": { + "type": "git", + "url": "git://github.com/jashkenas/underscore.git" + }, + "main": "underscore.js", + "version": "1.8.3", "devDependencies": { - "phantomjs": "1.9.0-1" + "coveralls": "^2.11.2", + "docco": "*", + "eslint": "1.10.x", + "gzip-size-cli": "^1.0.0", + "karma": "^0.13.13", + "karma-qunit": "~0.1.4", + "nyc": "^2.1.3", + "pretty-bytes-cli": "^1.0.0", + "qunit-cli": "~0.2.0", + "qunitjs": "^1.18.0", + "uglify-js": "2.4.x" }, "scripts": { - "test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true" + "test": "npm run test-node && npm run lint", + "coverage": "nyc npm run test-node && nyc report", + "coveralls": "nyc npm run test-node && nyc report --reporter=text-lcov | coveralls", + "lint": "eslint underscore.js test/*.js", + "test-node": "qunit-cli test/*.js", + "test-browser": "npm i karma-phantomjs-launcher && karma start", + "minify": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m", + "build": "npm run minify -- --source-map underscore-min.map --source-map-url \" \" -o underscore-min.js", + "doc": "docco underscore.js", + "weight": "npm run minify | gzip-size | pretty-bytes" }, - "licenses": [ - { - "type": "MIT", - "url": "https://raw.github.com/jashkenas/underscore/master/LICENSE" - } - ], - "files" : ["underscore.js", "underscore-min.js", "LICENSE"] + "license": "MIT", + "files": [ + "underscore.js", + "underscore-min.js", + "underscore-min.map" + ] } diff --git a/vendor/underscore/test/.eslintrc b/vendor/underscore/test/.eslintrc new file mode 100644 index 000000000..fe75e810a --- /dev/null +++ b/vendor/underscore/test/.eslintrc @@ -0,0 +1,13 @@ +{ + "env": { + "browser": true + }, + "globals": { + "QUnit": false + }, + "rules": { + "brace-style": 0, + "no-new-wrappers": 0, + "no-extend-native": 0 + } +} diff --git a/vendor/underscore/test/arrays.js b/vendor/underscore/test/arrays.js index f9ed13294..4e359d1f7 100644 --- a/vendor/underscore/test/arrays.js +++ b/vendor/underscore/test/arrays.js @@ -1,224 +1,563 @@ -$(document).ready(function() { +(function() { + var _ = typeof require == 'function' ? require('..') : window._; - module("Arrays"); + QUnit.module('Arrays'); - test("first", function() { - equal(_.first([1,2,3]), 1, 'can pull out the first element of an array'); - equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); - equal(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); - equal(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); - equal(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first'); - var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); - equal(result, 4, 'works on an arguments object.'); - result = _.map([[1,2,3],[1,2,3]], _.first); - equal(result.join(','), '1,1', 'works well with _.map'); - result = (function() { return _.take([1,2,3], 2); })(); - equal(result.join(','), '1,2', 'aliased as take'); + QUnit.test('first', function(assert) { + assert.strictEqual(_.first([1, 2, 3]), 1, 'can pull out the first element of an array'); + assert.strictEqual(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); + assert.deepEqual(_.first([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)'); + assert.deepEqual(_.first([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)'); + assert.deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can fetch the first n elements'); + assert.deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length'); + var result = (function(){ return _.first(arguments); }(4, 3, 2, 1)); + assert.strictEqual(result, 4, 'works on an arguments object'); + result = _.map([[1, 2, 3], [1, 2, 3]], _.first); + assert.deepEqual(result, [1, 1], 'works well with _.map'); + assert.strictEqual(_.first(null), void 0, 'returns undefined when called on null'); - equal(_.first(null), undefined, 'handles nulls'); + Array.prototype[0] = 'boo'; + assert.strictEqual(_.first([]), void 0, 'return undefined when called on a empty array'); + delete Array.prototype[0]; }); - test("rest", function() { + QUnit.test('head', function(assert) { + assert.strictEqual(_.head, _.first, 'is an alias for first'); + }); + + QUnit.test('take', function(assert) { + assert.strictEqual(_.take, _.first, 'is an alias for first'); + }); + + QUnit.test('rest', function(assert) { var numbers = [1, 2, 3, 4]; - equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); - equal(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); - equal(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); - var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); - equal(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.rest); - equal(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); - result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4); - equal(result.join(', '), '2, 3, 4', 'aliased as drop and works on arguments object'); + assert.deepEqual(_.rest(numbers), [2, 3, 4], 'fetches all but the first element'); + assert.deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'returns the whole array when index is 0'); + assert.deepEqual(_.rest(numbers, 2), [3, 4], 'returns elements starting at the given index'); + var result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4)); + assert.deepEqual(result, [2, 3, 4], 'works on an arguments object'); + result = _.map([[1, 2, 3], [1, 2, 3]], _.rest); + assert.deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map'); }); - test("initial", function() { - equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()'); - equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index'); - var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4); - equal(result.join(", "), "1, 2, 3", 'initial works on arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.initial); - equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map'); + QUnit.test('tail', function(assert) { + assert.strictEqual(_.tail, _.rest, 'is an alias for rest'); }); - test("last", function() { - equal(_.last([1,2,3]), 3, 'can pull out the last element of an array'); - equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last'); - equal(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last'); - equal(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last'); - var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); - equal(result, 4, 'works on an arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.last); - equal(result.join(','), '3,3', 'works well with _.map'); - - equal(_.last(null), undefined, 'handles nulls'); + QUnit.test('drop', function(assert) { + assert.strictEqual(_.drop, _.rest, 'is an alias for rest'); }); - test("compact", function() { - equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); - var result = (function(){ return _.compact(arguments).length; })(0, 1, false, 2, false, 3); - equal(result, 3, 'works on an arguments object'); + QUnit.test('initial', function(assert) { + assert.deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'returns all but the last element'); + assert.deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'returns all but the last n elements'); + assert.deepEqual(_.initial([1, 2, 3, 4], 6), [], 'returns an empty array when n > length'); + var result = (function(){ return _(arguments).initial(); }(1, 2, 3, 4)); + assert.deepEqual(result, [1, 2, 3], 'works on an arguments object'); + result = _.map([[1, 2, 3], [1, 2, 3]], _.initial); + assert.deepEqual(_.flatten(result), [1, 2, 1, 2], 'works well with _.map'); }); - test("flatten", function() { + QUnit.test('last', function(assert) { + assert.strictEqual(_.last([1, 2, 3]), 3, 'can pull out the last element of an array'); + assert.strictEqual(_([1, 2, 3]).last(), 3, 'can perform OO-style "last()"'); + assert.deepEqual(_.last([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)'); + assert.deepEqual(_.last([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)'); + assert.deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can fetch the last n elements'); + assert.deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length'); + var result = (function(){ return _(arguments).last(); }(1, 2, 3, 4)); + assert.strictEqual(result, 4, 'works on an arguments object'); + result = _.map([[1, 2, 3], [1, 2, 3]], _.last); + assert.deepEqual(result, [3, 3], 'works well with _.map'); + assert.strictEqual(_.last(null), void 0, 'returns undefined when called on null'); + + var arr = []; + arr[-1] = 'boo'; + assert.strictEqual(_.last(arr), void 0, 'return undefined when called on a empty array'); + }); + + QUnit.test('compact', function(assert) { + assert.deepEqual(_.compact([1, false, null, 0, '', void 0, NaN, 2]), [1, 2], 'removes all falsy values'); + var result = (function(){ return _.compact(arguments); }(0, 1, false, 2, false, 3)); + assert.deepEqual(result, [1, 2, 3], 'works on an arguments object'); + result = _.map([[1, false, false], [false, false, 3]], _.compact); + assert.deepEqual(result, [[1], [3]], 'works well with _.map'); + }); + + QUnit.test('flatten', function(assert) { + assert.deepEqual(_.flatten(null), [], 'supports null'); + assert.deepEqual(_.flatten(void 0), [], 'supports undefined'); + + assert.deepEqual(_.flatten([[], [[]], []]), [], 'supports empty arrays'); + assert.deepEqual(_.flatten([[], [[]], []], true), [[]], 'can shallowly flatten empty arrays'); + var list = [1, [2], [3, [[[4]]]]]; - deepEqual(_.flatten(list), [1,2,3,4], 'can flatten nested arrays'); - deepEqual(_.flatten(list, true), [1,2,3,[[[4]]]], 'can shallowly flatten nested arrays'); - var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); - deepEqual(result, [1,2,3,4], 'works on an arguments object'); + assert.deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays'); + assert.deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays'); + var result = (function(){ return _.flatten(arguments); }(1, [2], [3, [[[4]]]])); + assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object'); list = [[1], [2], [3], [[4]]]; - deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays'); + assert.deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays'); + + assert.strictEqual(_.flatten([_.range(10), _.range(10), 5, 1, 3], true).length, 23, 'can flatten medium length arrays'); + assert.strictEqual(_.flatten([_.range(10), _.range(10), 5, 1, 3]).length, 23, 'can shallowly flatten medium length arrays'); + assert.strictEqual(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3]).length, 1056003, 'can handle massive arrays'); + assert.strictEqual(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3], true).length, 1056003, 'can handle massive arrays in shallow mode'); + + var x = _.range(100000); + for (var i = 0; i < 1000; i++) x = [x]; + assert.deepEqual(_.flatten(x), _.range(100000), 'can handle very deep arrays'); + assert.deepEqual(_.flatten(x, true), x[0], 'can handle very deep arrays in shallow mode'); }); - test("without", function() { + QUnit.test('without', function(assert) { var list = [1, 2, 1, 0, 3, 1, 4]; - equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); - var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); - equal(result.join(', '), '2, 3, 4', 'works on an arguments object'); + assert.deepEqual(_.without(list, 0, 1), [2, 3, 4], 'removes all instances of the given values'); + var result = (function(){ return _.without(arguments, 0, 1); }(1, 2, 1, 0, 3, 1, 4)); + assert.deepEqual(result, [2, 3, 4], 'works on an arguments object'); - list = [{one : 1}, {two : 2}]; - ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); - ok(_.without(list, list[0]).length == 1, 'ditto.'); + list = [{one: 1}, {two: 2}]; + assert.deepEqual(_.without(list, {one: 1}), list, 'compares objects by reference (value case)'); + assert.deepEqual(_.without(list, list[0]), [{two: 2}], 'compares objects by reference (reference case)'); }); - test("uniq", function() { + QUnit.test('sortedIndex', function(assert) { + var numbers = [10, 20, 30, 40, 50]; + var indexFor35 = _.sortedIndex(numbers, 35); + assert.strictEqual(indexFor35, 3, 'finds the index at which a value should be inserted to retain order'); + var indexFor30 = _.sortedIndex(numbers, 30); + assert.strictEqual(indexFor30, 2, 'finds the smallest index at which a value could be inserted to retain order'); + + var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; + var iterator = function(obj){ return obj.x; }; + assert.strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2, 'uses the result of `iterator` for order comparisons'); + assert.strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3, 'when `iterator` is a string, uses that key for order comparisons'); + + var context = {1: 2, 2: 3, 3: 4}; + iterator = function(obj){ return this[obj]; }; + assert.strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1, 'can execute its iterator in the given context'); + + var values = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, + 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647]; + var largeArray = Array(Math.pow(2, 32) - 1); + var length = values.length; + // Sparsely populate `array` + while (length--) { + largeArray[values[length]] = values[length]; + } + assert.strictEqual(_.sortedIndex(largeArray, 2147483648), 2147483648, 'works with large indexes'); + }); + + QUnit.test('uniq', function(assert) { var list = [1, 2, 1, 3, 1, 4]; - equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); - + assert.deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array'); list = [1, 1, 1, 2, 2, 3]; - equal(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); + assert.deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster'); - list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}]; - var iterator = function(value) { return value.name; }; - equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator'); + list = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}, {name: 'Curly'}]; + var expected = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}]; + var iterator = function(stooge) { return stooge.name; }; + assert.deepEqual(_.uniq(list, false, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (unsorted case)'); + assert.deepEqual(_.uniq(list, iterator), expected, '`sorted` argument defaults to false when omitted'); + assert.deepEqual(_.uniq(list, 'name'), expected, 'when `iterator` is a string, uses that key for comparisons (unsorted case)'); - equal(_.map(_.uniq(list, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator without specifying whether array is sorted'); + list = [{score: 8}, {score: 10}, {score: 10}]; + expected = [{score: 8}, {score: 10}]; + iterator = function(item) { return item.score; }; + assert.deepEqual(_.uniq(list, true, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (sorted case)'); + assert.deepEqual(_.uniq(list, true, 'score'), expected, 'when `iterator` is a string, uses that key for comparisons (sorted case)'); - iterator = function(value) { return value +1; }; - list = [1, 2, 2, 3, 4, 4]; - equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array'); + assert.deepEqual(_.uniq([{0: 1}, {0: 1}, {0: 1}, {0: 2}], 0), [{0: 1}, {0: 2}], 'can use falsy pluck like iterator'); + + var result = (function(){ return _.uniq(arguments); }(1, 2, 1, 3, 1, 4)); + assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object'); + + var a = {}, b = {}, c = {}; + assert.deepEqual(_.uniq([a, b, a, b, c]), [a, b, c], 'works on values that can be tested for equivalency but not ordered'); + + assert.deepEqual(_.uniq(null), [], 'returns an empty array when `array` is not iterable'); + + var context = {}; + list = [3]; + _.uniq(list, function(value, index, array) { + assert.strictEqual(this, context, 'executes its iterator in the given context'); + assert.strictEqual(value, 3, 'passes its iterator the value'); + assert.strictEqual(index, 0, 'passes its iterator the index'); + assert.strictEqual(array, list, 'passes its iterator the entire array'); + }, context); - var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); - equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); }); - test("intersection", function() { + QUnit.test('unique', function(assert) { + assert.strictEqual(_.unique, _.uniq, 'is an alias for uniq'); + }); + + QUnit.test('intersection', function(assert) { var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; - equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); - equal(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection'); - var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry'); - equal(result.join(''), 'moe', 'works on an arguments object'); + assert.deepEqual(_.intersection(stooges, leaders), ['moe'], 'can find the set intersection of two arrays'); + assert.deepEqual(_(stooges).intersection(leaders), ['moe'], 'can perform an OO-style intersection'); + var result = (function(){ return _.intersection(arguments, leaders); }('moe', 'curly', 'larry')); + assert.deepEqual(result, ['moe'], 'works on an arguments object'); var theSixStooges = ['moe', 'moe', 'curly', 'curly', 'larry', 'larry']; - equal(_.intersection(theSixStooges, leaders).join(''), 'moe', 'returns a duplicate-free array'); + assert.deepEqual(_.intersection(theSixStooges, leaders), ['moe'], 'returns a duplicate-free array'); + result = _.intersection([2, 4, 3, 1], [1, 2, 3]); + assert.deepEqual(result, [2, 3, 1], 'preserves the order of the first array'); + result = _.intersection(null, [1, 2, 3]); + assert.deepEqual(result, [], 'returns an empty array when passed null as the first argument'); + result = _.intersection([1, 2, 3], null); + assert.deepEqual(result, [], 'returns an empty array when passed null as an argument beyond the first'); }); - test("union", function() { + QUnit.test('union', function(assert) { var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); - equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); + assert.deepEqual(result, [1, 2, 3, 30, 40], 'can find the union of a list of arrays'); + + result = _([1, 2, 3]).union([2, 30, 1], [1, 40]); + assert.deepEqual(result, [1, 2, 3, 30, 40], 'can perform an OO-style union'); result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); - equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays'); + assert.deepEqual(result, [1, 2, 3, 30, 40, [1]], 'can find the union of a list of nested arrays'); - var args = null; - (function(){ args = arguments; })(1, 2, 3); - result = _.union(args, [2, 30, 1], [1, 40]); - equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); + result = _.union([10, 20], [1, 30, 10], [0, 40]); + assert.deepEqual(result, [10, 20, 1, 30, 0, 40], 'orders values by their first encounter'); - result = _.union(null, [1, 2, 3]); - deepEqual(result, [null, 1, 2, 3]); + result = (function(){ return _.union(arguments, [2, 30, 1], [1, 40]); }(1, 2, 3)); + assert.deepEqual(result, [1, 2, 3, 30, 40], 'works on an arguments object'); + + assert.deepEqual(_.union([1, 2, 3], 4), [1, 2, 3], 'restricts the union to arrays only'); }); - test("difference", function() { + QUnit.test('difference', function(assert) { var result = _.difference([1, 2, 3], [2, 30, 40]); - equal(result.join(' '), '1 3', 'takes the difference of two arrays'); + assert.deepEqual(result, [1, 3], 'can find the difference of two arrays'); + + result = _([1, 2, 3]).difference([2, 30, 40]); + assert.deepEqual(result, [1, 3], 'can perform an OO-style difference'); result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); - equal(result.join(' '), '3 4', 'takes the difference of three arrays'); + assert.deepEqual(result, [3, 4], 'can find the difference of three arrays'); + + result = _.difference([8, 9, 3, 1], [3, 8]); + assert.deepEqual(result, [9, 1], 'preserves the order of the first array'); + + result = (function(){ return _.difference(arguments, [2, 30, 40]); }(1, 2, 3)); + assert.deepEqual(result, [1, 3], 'works on an arguments object'); + + result = _.difference([1, 2, 3], 1); + assert.deepEqual(result, [1, 2, 3], 'restrict the difference to arrays only'); }); - test('zip', function() { + QUnit.test('zip', function(assert) { var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; - var stooges = _.zip(names, ages, leaders); - equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); + assert.deepEqual(_.zip(names, ages, leaders), [ + ['moe', 30, true], + ['larry', 40, void 0], + ['curly', 50, void 0] + ], 'zipped together arrays of different lengths'); - stooges = _.zip(['moe',30, 'stooge 1'],['larry',40, 'stooge 2'],['curly',50, 'stooge 3']); - deepEqual(stooges, [['moe','larry','curly'],[30,40,50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs'); + var stooges = _.zip(['moe', 30, 'stooge 1'], ['larry', 40, 'stooge 2'], ['curly', 50, 'stooge 3']); + assert.deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs'); - // In the case of difference lengths of the tuples undefineds + // In the case of different lengths of the tuples, undefined values // should be used as placeholder - stooges = _.zip(['moe',30],['larry',40],['curly',50, 'extra data']); - deepEqual(stooges, [['moe','larry','curly'],[30,40,50], [undefined, undefined, 'extra data']], 'zipped pairs with empties'); + stooges = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']); + assert.deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], [void 0, void 0, 'extra data']], 'zipped pairs with empties'); var empty = _.zip([]); - deepEqual(empty, [], 'unzipped empty'); + assert.deepEqual(empty, [], 'unzipped empty'); + + assert.deepEqual(_.zip(null), [], 'handles null'); + assert.deepEqual(_.zip(), [], '_.zip() returns []'); }); - test('object', function() { + QUnit.test('unzip', function(assert) { + assert.deepEqual(_.unzip(null), [], 'handles null'); + + assert.deepEqual(_.unzip([['a', 'b'], [1, 2]]), [['a', 1], ['b', 2]]); + + // complements zip + var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + assert.deepEqual(_.unzip(zipped), [['fred', 'barney'], [30, 40], [true, false]]); + + zipped = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']); + assert.deepEqual(_.unzip(zipped), [['moe', 30, void 0], ['larry', 40, void 0], ['curly', 50, 'extra data']], 'Uses length of largest array'); + }); + + QUnit.test('object', function(assert) { var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]); var shouldBe = {moe: 30, larry: 40, curly: 50}; - ok(_.isEqual(result, shouldBe), 'two arrays zipped together into an object'); + assert.deepEqual(result, shouldBe, 'two arrays zipped together into an object'); result = _.object([['one', 1], ['two', 2], ['three', 3]]); shouldBe = {one: 1, two: 2, three: 3}; - ok(_.isEqual(result, shouldBe), 'an array of pairs zipped together into an object'); + assert.deepEqual(result, shouldBe, 'an array of pairs zipped together into an object'); var stooges = {moe: 30, larry: 40, curly: 50}; - ok(_.isEqual(_.object(_.pairs(stooges)), stooges), 'an object converted to pairs and back to an object'); + assert.deepEqual(_.object(_.pairs(stooges)), stooges, 'an object converted to pairs and back to an object'); - ok(_.isEqual(_.object(null), {}), 'handles nulls'); + assert.deepEqual(_.object(null), {}, 'handles nulls'); }); - test("indexOf", function() { + QUnit.test('indexOf', function(assert) { var numbers = [1, 2, 3]; - numbers.indexOf = null; - equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); - var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); - equal(result, 1, 'works on an arguments object'); - equal(_.indexOf(null, 2), -1, 'handles nulls properly'); + assert.strictEqual(_.indexOf(numbers, 2), 1, 'can compute indexOf'); + var result = (function(){ return _.indexOf(arguments, 2); }(1, 2, 3)); + assert.strictEqual(result, 1, 'works on an arguments object'); + + _.each([null, void 0, [], false], function(val) { + var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val); + assert.strictEqual(_.indexOf(val, 2), -1, msg); + assert.strictEqual(_.indexOf(val, 2, -1), -1, msg); + assert.strictEqual(_.indexOf(val, 2, -20), -1, msg); + assert.strictEqual(_.indexOf(val, 2, 15), -1, msg); + }); var num = 35; numbers = [10, 20, 30, 40, 50]; var index = _.indexOf(numbers, num, true); - equal(index, -1, '35 is not in the list'); + assert.strictEqual(index, -1, '35 is not in the list'); numbers = [10, 20, 30, 40, 50]; num = 40; index = _.indexOf(numbers, num, true); - equal(index, 3, '40 is in the list'); + assert.strictEqual(index, 3, '40 is in the list'); numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; - index = _.indexOf(numbers, num, true); - equal(index, 1, '40 is in the list'); + assert.strictEqual(_.indexOf(numbers, num, true), 1, '40 is in the list'); + assert.strictEqual(_.indexOf(numbers, 6, true), -1, '6 isnt in the list'); + assert.strictEqual(_.indexOf([1, 2, 5, 4, 6, 7], 5, true), -1, 'sorted indexOf doesn\'t use binary search'); + assert.ok(_.every(['1', [], {}, null], function() { + return _.indexOf(numbers, num, {}) === 1; + }), 'non-nums as fromIndex make indexOf assume sorted'); numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; index = _.indexOf(numbers, 2, 5); - equal(index, 7, 'supports the fromIndex argument'); + assert.strictEqual(index, 7, 'supports the fromIndex argument'); + + index = _.indexOf([,,, 0], void 0); + assert.strictEqual(index, 0, 'treats sparse arrays as if they were dense'); + + var array = [1, 2, 3, 1, 2, 3]; + assert.strictEqual(_.indexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index'); + assert.strictEqual(_.indexOf(array, 1, -2), -1, 'neg `fromIndex` starts at the right index'); + assert.strictEqual(_.indexOf(array, 2, -3), 4); + _.each([-6, -8, -Infinity], function(fromIndex) { + assert.strictEqual(_.indexOf(array, 1, fromIndex), 0); + }); + assert.strictEqual(_.indexOf([1, 2, 3], 1, true), 0); + + index = _.indexOf([], void 0, true); + assert.strictEqual(index, -1, 'empty array with truthy `isSorted` returns -1'); }); - test("lastIndexOf", function() { + QUnit.test('indexOf with NaN', function(assert) { + assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN), 2, 'Expected [1, 2, NaN] to contain NaN'); + assert.strictEqual(_.indexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN'); + + assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, 1), 2, 'startIndex does not affect result'); + assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, -2), 2, 'startIndex does not affect result'); + + (function() { + assert.strictEqual(_.indexOf(arguments, NaN), 2, 'Expected arguments [1, 2, NaN] to contain NaN'); + }(1, 2, NaN, NaN)); + }); + + QUnit.test('indexOf with +- 0', function(assert) { + _.each([-0, +0], function(val) { + assert.strictEqual(_.indexOf([1, 2, val, val], val), 2); + assert.strictEqual(_.indexOf([1, 2, val, val], -val), 2); + }); + }); + + QUnit.test('lastIndexOf', function(assert) { var numbers = [1, 0, 1]; - equal(_.lastIndexOf(numbers, 1), 2); + var falsy = [void 0, '', 0, false, NaN, null, void 0]; + assert.strictEqual(_.lastIndexOf(numbers, 1), 2); numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; numbers.lastIndexOf = null; - equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); - equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); - var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); - equal(result, 5, 'works on an arguments object'); - equal(_.lastIndexOf(null, 2), -1, 'handles nulls properly'); + assert.strictEqual(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); + assert.strictEqual(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); + var result = (function(){ return _.lastIndexOf(arguments, 1); }(1, 0, 1, 0, 0, 1, 0, 0, 0)); + assert.strictEqual(result, 5, 'works on an arguments object'); + + _.each([null, void 0, [], false], function(val) { + var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val); + assert.strictEqual(_.lastIndexOf(val, 2), -1, msg); + assert.strictEqual(_.lastIndexOf(val, 2, -1), -1, msg); + assert.strictEqual(_.lastIndexOf(val, 2, -20), -1, msg); + assert.strictEqual(_.lastIndexOf(val, 2, 15), -1, msg); + }); numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; var index = _.lastIndexOf(numbers, 2, 2); - equal(index, 1, 'supports the fromIndex argument'); + assert.strictEqual(index, 1, 'supports the fromIndex argument'); + + var array = [1, 2, 3, 1, 2, 3]; + + assert.strictEqual(_.lastIndexOf(array, 1, 0), 0, 'starts at the correct from idx'); + assert.strictEqual(_.lastIndexOf(array, 3), 5, 'should return the index of the last matched value'); + assert.strictEqual(_.lastIndexOf(array, 4), -1, 'should return `-1` for an unmatched value'); + + assert.strictEqual(_.lastIndexOf(array, 1, 2), 0, 'should work with a positive `fromIndex`'); + + _.each([6, 8, Math.pow(2, 32), Infinity], function(fromIndex) { + assert.strictEqual(_.lastIndexOf(array, void 0, fromIndex), -1); + assert.strictEqual(_.lastIndexOf(array, 1, fromIndex), 3); + assert.strictEqual(_.lastIndexOf(array, '', fromIndex), -1); + }); + + var expected = _.map(falsy, function(value) { + return typeof value == 'number' ? -1 : 5; + }); + + var actual = _.map(falsy, function(fromIndex) { + return _.lastIndexOf(array, 3, fromIndex); + }); + + assert.deepEqual(actual, expected, 'should treat falsy `fromIndex` values, except `0` and `NaN`, as `array.length`'); + assert.strictEqual(_.lastIndexOf(array, 3, '1'), 5, 'should treat non-number `fromIndex` values as `array.length`'); + assert.strictEqual(_.lastIndexOf(array, 3, true), 5, 'should treat non-number `fromIndex` values as `array.length`'); + + assert.strictEqual(_.lastIndexOf(array, 2, -3), 1, 'should work with a negative `fromIndex`'); + assert.strictEqual(_.lastIndexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index'); + + assert.deepEqual(_.map([-6, -8, -Infinity], function(fromIndex) { + return _.lastIndexOf(array, 1, fromIndex); + }), [0, -1, -1]); }); - test("range", function() { - equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); - equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); - equal(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); - equal(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); - equal(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); - equal(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); - equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); - equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); + QUnit.test('lastIndexOf with NaN', function(assert) { + assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN), 3, 'Expected [1, 2, NaN] to contain NaN'); + assert.strictEqual(_.lastIndexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN'); + + assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, 2), 2, 'fromIndex does not affect result'); + assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, -2), 2, 'fromIndex does not affect result'); + + (function() { + assert.strictEqual(_.lastIndexOf(arguments, NaN), 3, 'Expected arguments [1, 2, NaN] to contain NaN'); + }(1, 2, NaN, NaN)); }); -}); + QUnit.test('lastIndexOf with +- 0', function(assert) { + _.each([-0, +0], function(val) { + assert.strictEqual(_.lastIndexOf([1, 2, val, val], val), 3); + assert.strictEqual(_.lastIndexOf([1, 2, val, val], -val), 3); + assert.strictEqual(_.lastIndexOf([-1, 1, 2], -val), -1); + }); + }); + + QUnit.test('findIndex', function(assert) { + var objects = [ + {a: 0, b: 0}, + {a: 1, b: 1}, + {a: 2, b: 2}, + {a: 0, b: 0} + ]; + + assert.strictEqual(_.findIndex(objects, function(obj) { + return obj.a === 0; + }), 0); + + assert.strictEqual(_.findIndex(objects, function(obj) { + return obj.b * obj.a === 4; + }), 2); + + assert.strictEqual(_.findIndex(objects, 'a'), 1, 'Uses lookupIterator'); + + assert.strictEqual(_.findIndex(objects, function(obj) { + return obj.b * obj.a === 5; + }), -1); + + assert.strictEqual(_.findIndex(null, _.noop), -1); + assert.strictEqual(_.findIndex(objects, function(a) { + return a.foo === null; + }), -1); + _.findIndex([{a: 1}], function(a, key, obj) { + assert.strictEqual(key, 0); + assert.deepEqual(obj, [{a: 1}]); + assert.strictEqual(this, objects, 'called with context'); + }, objects); + + var sparse = []; + sparse[20] = {a: 2, b: 2}; + assert.strictEqual(_.findIndex(sparse, function(obj) { + return obj && obj.b * obj.a === 4; + }), 20, 'Works with sparse arrays'); + + var array = [1, 2, 3, 4]; + array.match = 55; + assert.strictEqual(_.findIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys'); + }); + + QUnit.test('findLastIndex', function(assert) { + var objects = [ + {a: 0, b: 0}, + {a: 1, b: 1}, + {a: 2, b: 2}, + {a: 0, b: 0} + ]; + + assert.strictEqual(_.findLastIndex(objects, function(obj) { + return obj.a === 0; + }), 3); + + assert.strictEqual(_.findLastIndex(objects, function(obj) { + return obj.b * obj.a === 4; + }), 2); + + assert.strictEqual(_.findLastIndex(objects, 'a'), 2, 'Uses lookupIterator'); + + assert.strictEqual(_.findLastIndex(objects, function(obj) { + return obj.b * obj.a === 5; + }), -1); + + assert.strictEqual(_.findLastIndex(null, _.noop), -1); + assert.strictEqual(_.findLastIndex(objects, function(a) { + return a.foo === null; + }), -1); + _.findLastIndex([{a: 1}], function(a, key, obj) { + assert.strictEqual(key, 0); + assert.deepEqual(obj, [{a: 1}]); + assert.strictEqual(this, objects, 'called with context'); + }, objects); + + var sparse = []; + sparse[20] = {a: 2, b: 2}; + assert.strictEqual(_.findLastIndex(sparse, function(obj) { + return obj && obj.b * obj.a === 4; + }), 20, 'Works with sparse arrays'); + + var array = [1, 2, 3, 4]; + array.match = 55; + assert.strictEqual(_.findLastIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys'); + }); + + QUnit.test('range', function(assert) { + assert.deepEqual(_.range(0), [], 'range with 0 as a first argument generates an empty array'); + assert.deepEqual(_.range(4), [0, 1, 2, 3], 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); + assert.deepEqual(_.range(5, 8), [5, 6, 7], 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); + assert.deepEqual(_.range(3, 10, 3), [3, 6, 9], 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); + assert.deepEqual(_.range(3, 10, 15), [3], 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); + assert.deepEqual(_.range(12, 7, -2), [12, 10, 8], 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); + assert.deepEqual(_.range(0, -10, -1), [0, -1, -2, -3, -4, -5, -6, -7, -8, -9], 'final example in the Python docs'); + assert.strictEqual(1 / _.range(-0, 1)[0], -Infinity, 'should preserve -0'); + assert.deepEqual(_.range(8, 5), [8, 7, 6], 'negative range generates descending array'); + assert.deepEqual(_.range(-3), [0, -1, -2], 'negative range generates descending array'); + }); + + QUnit.test('chunk', function(assert) { + assert.deepEqual(_.chunk([], 2), [], 'chunk for empty array returns an empty array'); + + assert.deepEqual(_.chunk([1, 2, 3], 0), [], 'chunk into parts of 0 elements returns empty array'); + assert.deepEqual(_.chunk([1, 2, 3], -1), [], 'chunk into parts of negative amount of elements returns an empty array'); + assert.deepEqual(_.chunk([1, 2, 3]), [], 'defaults to empty array (chunk size 0)'); + + assert.deepEqual(_.chunk([1, 2, 3], 1), [[1], [2], [3]], 'chunk into parts of 1 elements returns original array'); + + assert.deepEqual(_.chunk([1, 2, 3], 3), [[1, 2, 3]], 'chunk into parts of current array length elements returns the original array'); + assert.deepEqual(_.chunk([1, 2, 3], 5), [[1, 2, 3]], 'chunk into parts of more then current array length elements returns the original array'); + + assert.deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 2), [[10, 20], [30, 40], [50, 60], [70]], 'chunk into parts of less then current array length elements'); + assert.deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 3), [[10, 20, 30], [40, 50, 60], [70]], 'chunk into parts of less then current array length elements'); + }); +}()); diff --git a/vendor/underscore/test/chaining.js b/vendor/underscore/test/chaining.js index 6eeef0f87..5d7595cdc 100644 --- a/vendor/underscore/test/chaining.js +++ b/vendor/underscore/test/chaining.js @@ -1,13 +1,14 @@ -$(document).ready(function() { +(function() { + var _ = typeof require == 'function' ? require('..') : window._; - module("Chaining"); + QUnit.module('Chaining'); - test("map/flatten/reduce", function() { + QUnit.test('map/flatten/reduce', function(assert) { var lyrics = [ - "I'm a lumberjack and I'm okay", - "I sleep all night and I work all day", - "He's a lumberjack and he's okay", - "He sleeps all night and he works all day" + 'I\'m a lumberjack and I\'m okay', + 'I sleep all night and I work all day', + 'He\'s a lumberjack and he\'s okay', + 'He sleeps all night and he works all day' ]; var counts = _(lyrics).chain() .map(function(line) { return line.split(''); }) @@ -16,12 +17,14 @@ $(document).ready(function() { hash[l] = hash[l] || 0; hash[l]++; return hash; - }, {}).value(); - ok(counts.a == 16 && counts.e == 10, 'counted all the letters in the song'); + }, {}) + .value(); + assert.strictEqual(counts.a, 16, 'counted all the letters in the song'); + assert.strictEqual(counts.e, 10, 'counted all the letters in the song'); }); - test("select/reject/sortBy", function() { - var numbers = [1,2,3,4,5,6,7,8,9,10]; + QUnit.test('select/reject/sortBy', function(assert) { + var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; numbers = _(numbers).chain().select(function(n) { return n % 2 === 0; }).reject(function(n) { @@ -29,11 +32,11 @@ $(document).ready(function() { }).sortBy(function(n) { return -n; }).value(); - equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + assert.deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers'); }); - test("select/reject/sortBy in functional style", function() { - var numbers = [1,2,3,4,5,6,7,8,9,10]; + QUnit.test('select/reject/sortBy in functional style', function(assert) { + var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; numbers = _.chain(numbers).select(function(n) { return n % 2 === 0; }).reject(function(n) { @@ -41,11 +44,11 @@ $(document).ready(function() { }).sortBy(function(n) { return -n; }).value(); - equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + assert.deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers'); }); - test("reverse/concat/unshift/pop/map", function() { - var numbers = [1,2,3,4,5]; + QUnit.test('reverse/concat/unshift/pop/map', function(assert) { + var numbers = [1, 2, 3, 4, 5]; numbers = _(numbers).chain() .reverse() .concat([5, 5, 5]) @@ -53,13 +56,44 @@ $(document).ready(function() { .pop() .map(function(n){ return n * 2; }) .value(); - equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); + assert.deepEqual(numbers, [34, 10, 8, 6, 4, 2, 10, 10], 'can chain together array functions.'); }); - test("chaining works in small stages", function() { + QUnit.test('splice', function(assert) { + var instance = _([1, 2, 3, 4, 5]).chain(); + assert.deepEqual(instance.splice(1, 3).value(), [1, 5]); + assert.deepEqual(instance.splice(1, 0).value(), [1, 5]); + assert.deepEqual(instance.splice(1, 1).value(), [1]); + assert.deepEqual(instance.splice(0, 1).value(), [], '#397 Can create empty array'); + }); + + QUnit.test('shift', function(assert) { + var instance = _([1, 2, 3]).chain(); + assert.deepEqual(instance.shift().value(), [2, 3]); + assert.deepEqual(instance.shift().value(), [3]); + assert.deepEqual(instance.shift().value(), [], '#397 Can create empty array'); + }); + + QUnit.test('pop', function(assert) { + var instance = _([1, 2, 3]).chain(); + assert.deepEqual(instance.pop().value(), [1, 2]); + assert.deepEqual(instance.pop().value(), [1]); + assert.deepEqual(instance.pop().value(), [], '#397 Can create empty array'); + }); + + QUnit.test('chaining works in small stages', function(assert) { var o = _([1, 2, 3, 4]).chain(); - deepEqual(o.filter(function(i) { return i < 3; }).value(), [1, 2]); - deepEqual(o.filter(function(i) { return i > 2; }).value(), [3, 4]); + assert.deepEqual(o.filter(function(i) { return i < 3; }).value(), [1, 2]); + assert.deepEqual(o.filter(function(i) { return i > 2; }).value(), [3, 4]); }); -}); + QUnit.test('#1562: Engine proxies for chained functions', function(assert) { + var wrapped = _(512); + assert.strictEqual(wrapped.toJSON(), 512); + assert.strictEqual(wrapped.valueOf(), 512); + assert.strictEqual(+wrapped, 512); + assert.strictEqual(wrapped.toString(), '512'); + assert.strictEqual('' + wrapped, '512'); + }); + +}()); diff --git a/vendor/underscore/test/collections.js b/vendor/underscore/test/collections.js index 82176ad01..ce780f873 100644 --- a/vendor/underscore/test/collections.js +++ b/vendor/underscore/test/collections.js @@ -1,508 +1,939 @@ -$(document).ready(function() { +(function() { + var _ = typeof require == 'function' ? require('..') : window._; - module("Collections"); + QUnit.module('Collections'); - test("each", function() { + QUnit.test('each', function(assert) { _.each([1, 2, 3], function(num, i) { - equal(num, i + 1, 'each iterators provide value and iteration count'); + assert.strictEqual(num, i + 1, 'each iterators provide value and iteration count'); }); var answers = []; - _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); - equal(answers.join(', '), '5, 10, 15', 'context object property accessed'); + _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier); }, {multiplier: 5}); + assert.deepEqual(answers, [5, 10, 15], 'context object property accessed'); answers = []; - _.forEach([1, 2, 3], function(num){ answers.push(num); }); - equal(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); + _.each([1, 2, 3], function(num){ answers.push(num); }); + assert.deepEqual(answers, [1, 2, 3], 'can iterate a simple array'); answers = []; - var obj = {one : 1, two : 2, three : 3}; + var obj = {one: 1, two: 2, three: 3}; obj.constructor.prototype.four = 4; _.each(obj, function(value, key){ answers.push(key); }); - equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); + assert.deepEqual(answers, ['one', 'two', 'three'], 'iterating over objects works, and ignores the object prototype.'); delete obj.constructor.prototype.four; + // ensure the each function is JITed + _(1000).times(function() { _.each([], function(){}); }); + var count = 0; + obj = {1: 'foo', 2: 'bar', 3: 'baz'}; + _.each(obj, function(){ count++; }); + assert.strictEqual(count, 3, 'the fun should be called only 3 times'); + var answer = null; _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); - ok(answer, 'can reference the original collection from inside the iterator'); + assert.ok(answer, 'can reference the original collection from inside the iterator'); answers = 0; _.each(null, function(){ ++answers; }); - equal(answers, 0, 'handles a null properly'); + assert.strictEqual(answers, 0, 'handles a null properly'); + + _.each(false, function(){}); + + var a = [1, 2, 3]; + assert.strictEqual(_.each(a, function(){}), a); + assert.strictEqual(_.each(null, function(){}), null); }); - test('map', function() { + QUnit.test('forEach', function(assert) { + assert.strictEqual(_.forEach, _.each, 'is an alias for each'); + }); + + QUnit.test('lookupIterator with contexts', function(assert) { + _.each([true, false, 'yes', '', 0, 1, {}], function(context) { + _.each([1], function() { + assert.strictEqual(typeof this, 'object', 'context is a wrapped primitive'); + assert.strictEqual(this.valueOf(), context, 'the unwrapped context is the specified primitive'); + assert.equal(this, context, 'context can be coerced to the specified primitive'); + }, context); + }); + }); + + QUnit.test('Iterating objects with sketchy length properties', function(assert) { + var functions = [ + 'each', 'map', 'filter', 'find', + 'some', 'every', 'max', 'min', + 'groupBy', 'countBy', 'partition', 'indexBy' + ]; + var reducers = ['reduce', 'reduceRight']; + + var tricks = [ + {length: '5'}, + {length: {valueOf: _.constant(5)}}, + {length: Math.pow(2, 53) + 1}, + {length: Math.pow(2, 53)}, + {length: null}, + {length: -2}, + {length: new Number(15)} + ]; + + assert.expect(tricks.length * (functions.length + reducers.length + 4)); + + _.each(tricks, function(trick) { + var length = trick.length; + assert.strictEqual(_.size(trick), 1, 'size on obj with length: ' + length); + assert.deepEqual(_.toArray(trick), [length], 'toArray on obj with length: ' + length); + assert.deepEqual(_.shuffle(trick), [length], 'shuffle on obj with length: ' + length); + assert.deepEqual(_.sample(trick), length, 'sample on obj with length: ' + length); + + + _.each(functions, function(method) { + _[method](trick, function(val, key) { + assert.strictEqual(key, 'length', method + ': ran with length = ' + val); + }); + }); + + _.each(reducers, function(method) { + assert.strictEqual(_[method](trick), trick.length, method); + }); + }); + }); + + QUnit.test('Resistant to collection length and properties changing while iterating', function(assert) { + + var collection = [ + 'each', 'map', 'filter', 'find', + 'some', 'every', 'max', 'min', 'reject', + 'groupBy', 'countBy', 'partition', 'indexBy', + 'reduce', 'reduceRight' + ]; + var array = [ + 'findIndex', 'findLastIndex' + ]; + var object = [ + 'mapObject', 'findKey', 'pick', 'omit' + ]; + + _.each(collection.concat(array), function(method) { + var sparseArray = [1, 2, 3]; + sparseArray.length = 100; + var answers = 0; + _[method](sparseArray, function(){ + ++answers; + return method === 'every' ? true : null; + }, {}); + assert.strictEqual(answers, 100, method + ' enumerates [0, length)'); + + var growingCollection = [1, 2, 3], count = 0; + _[method](growingCollection, function() { + if (count < 10) growingCollection.push(count++); + return method === 'every' ? true : null; + }, {}); + assert.strictEqual(count, 3, method + ' is resistant to length changes'); + }); + + _.each(collection.concat(object), function(method) { + var changingObject = {0: 0, 1: 1}, count = 0; + _[method](changingObject, function(val) { + if (count < 10) changingObject[++count] = val + 1; + return method === 'every' ? true : null; + }, {}); + + assert.strictEqual(count, 2, method + ' is resistant to property changes'); + }); + }); + + QUnit.test('map', function(assert) { var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'doubled numbers'); + assert.deepEqual(doubled, [2, 4, 6], 'doubled numbers'); - doubled = _.collect([1, 2, 3], function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'aliased as "collect"'); + var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier: 3}); + assert.deepEqual(tripled, [3, 6, 9], 'tripled numbers with context'); - var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); - equal(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); + doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); + assert.deepEqual(doubled, [2, 4, 6], 'OO-style doubled numbers'); - var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); + var ids = _.map({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){ + return n.id; + }); + assert.deepEqual(ids, ['1', '2'], 'Can use collection methods on Array-likes.'); - if (document.querySelectorAll) { - var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; }); - deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.'); - } + assert.deepEqual(_.map(null, _.noop), [], 'handles a null properly'); - var ids = _.map($('#map-test').children(), function(n){ return n.id; }); - deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.'); + assert.deepEqual(_.map([1], function() { + return this.length; + }, [5]), [1], 'called with context'); - var ids = _.map(document.images, function(n){ return n.id; }); - ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); - - var ifnull = _.map(null, function(){}); - ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); + // Passing a property name like _.pluck. + var people = [{name: 'moe', age: 30}, {name: 'curly', age: 50}]; + assert.deepEqual(_.map(people, 'name'), ['moe', 'curly'], 'predicate string map to object properties'); }); - test('reduce', function() { - var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'can sum up an array'); - - var context = {multiplier : 3}; - sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); - equal(sum, 18, 'can reduce with a context object'); - - sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'aliased as "inject"'); - - sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'OO-style reduce'); - - var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); - equal(sum, 6, 'default initial value'); - - var prod = _.reduce([1, 2, 3, 4], function(prod, num){ return prod * num; }); - equal(prod, 24, 'can reduce via multiplication'); - - var ifnull; - try { - _.reduce(null, function(){}); - } catch (ex) { - ifnull = ex; - } - ok(ifnull instanceof TypeError, 'handles a null (without initial value) properly'); - - ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); - equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); - raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + QUnit.test('collect', function(assert) { + assert.strictEqual(_.collect, _.map, 'is an alias for map'); }); - test('reduceRight', function() { - var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); - equal(list, 'bazbarfoo', 'can perform right folds'); + QUnit.test('reduce', function(assert) { + var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0); + assert.strictEqual(sum, 6, 'can sum up an array'); - var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); - equal(list, 'bazbarfoo', 'aliased as "foldr"'); + var context = {multiplier: 3}; + sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num * this.multiplier; }, 0, context); + assert.strictEqual(sum, 18, 'can reduce with a context object'); - var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); - equal(list, 'bazbarfoo', 'default initial value'); + sum = _([1, 2, 3]).reduce(function(memo, num){ return memo + num; }, 0); + assert.strictEqual(sum, 6, 'OO-style reduce'); - var ifnull; - try { - _.reduceRight(null, function(){}); - } catch (ex) { - ifnull = ex; - } - ok(ifnull instanceof TypeError, 'handles a null (without initial value) properly'); + sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }); + assert.strictEqual(sum, 6, 'default initial value'); - var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; }); - equal(sum, 6, 'default initial value on object'); + var prod = _.reduce([1, 2, 3, 4], function(memo, num){ return memo * num; }); + assert.strictEqual(prod, 24, 'can reduce via multiplication'); - ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + assert.strictEqual(_.reduce(null, _.noop, 138), 138, 'handles a null (with initial value) properly'); + assert.strictEqual(_.reduce([], _.noop, void 0), void 0, 'undefined can be passed as a special case'); + assert.strictEqual(_.reduce([_], _.noop), _, 'collection of length one with no initial value returns the first item'); + assert.strictEqual(_.reduce([], _.noop), void 0, 'returns undefined when collection is empty and no initial value'); + }); - equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); - raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + QUnit.test('foldl', function(assert) { + assert.strictEqual(_.foldl, _.reduce, 'is an alias for reduce'); + }); + + QUnit.test('inject', function(assert) { + assert.strictEqual(_.inject, _.reduce, 'is an alias for reduce'); + }); + + QUnit.test('reduceRight', function(assert) { + var list = _.reduceRight(['foo', 'bar', 'baz'], function(memo, str){ return memo + str; }, ''); + assert.strictEqual(list, 'bazbarfoo', 'can perform right folds'); + + list = _.reduceRight(['foo', 'bar', 'baz'], function(memo, str){ return memo + str; }); + assert.strictEqual(list, 'bazbarfoo', 'default initial value'); + + var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(memo, num){ return memo + num; }); + assert.strictEqual(sum, 6, 'default initial value on object'); + + assert.strictEqual(_.reduceRight(null, _.noop, 138), 138, 'handles a null (with initial value) properly'); + assert.strictEqual(_.reduceRight([_], _.noop), _, 'collection of length one with no initial value returns the first item'); + + assert.strictEqual(_.reduceRight([], _.noop, void 0), void 0, 'undefined can be passed as a special case'); + assert.strictEqual(_.reduceRight([], _.noop), void 0, 'returns undefined when collection is empty and no initial value'); // Assert that the correct arguments are being passed. var args, - memo = {}, + init = {}, object = {a: 1, b: 2}, lastKey = _.keys(object).pop(); - var expected = lastKey == 'a' - ? [memo, 1, 'a', object] - : [memo, 2, 'b', object]; + var expected = lastKey === 'a' + ? [init, 1, 'a', object] + : [init, 2, 'b', object]; _.reduceRight(object, function() { - args || (args = _.toArray(arguments)); - }, memo); + if (!args) args = _.toArray(arguments); + }, init); - deepEqual(args, expected); + assert.deepEqual(args, expected); // And again, with numeric keys. - object = {'2': 'a', '1': 'b'}; + object = {2: 'a', 1: 'b'}; lastKey = _.keys(object).pop(); args = null; - expected = lastKey == '2' - ? [memo, 'a', '2', object] - : [memo, 'b', '1', object]; + expected = lastKey === '2' + ? [init, 'a', '2', object] + : [init, 'b', '1', object]; _.reduceRight(object, function() { - args || (args = _.toArray(arguments)); - }, memo); + if (!args) args = _.toArray(arguments); + }, init); - deepEqual(args, expected); + assert.deepEqual(args, expected); }); - test('find', function() { + QUnit.test('foldr', function(assert) { + assert.strictEqual(_.foldr, _.reduceRight, 'is an alias for reduceRight'); + }); + + QUnit.test('find', function(assert) { var array = [1, 2, 3, 4]; - strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`'); - strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found'); + assert.strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`'); + assert.strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found'); + + array.dontmatch = 55; + assert.strictEqual(_.find(array, function(x) { return x === 55; }), void 0, 'iterates array-likes correctly'); + + // Matching an object like _.findWhere. + var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}]; + assert.deepEqual(_.find(list, {a: 1}), {a: 1, b: 2}, 'can be used as findWhere'); + assert.deepEqual(_.find(list, {b: 4}), {a: 1, b: 4}); + assert.notOk(_.find(list, {c: 1}), 'undefined when not found'); + assert.notOk(_.find([], {c: 1}), 'undefined when searching empty list'); + + var result = _.find([1, 2, 3], function(num){ return num * 2 === 4; }); + assert.strictEqual(result, 2, 'found the first "2" and broke the loop'); + + var obj = { + a: {x: 1, z: 3}, + b: {x: 2, z: 2}, + c: {x: 3, z: 4}, + d: {x: 4, z: 1} + }; + + assert.deepEqual(_.find(obj, {x: 2}), {x: 2, z: 2}, 'works on objects'); + assert.deepEqual(_.find(obj, {x: 2, z: 1}), void 0); + assert.deepEqual(_.find(obj, function(x) { + return x.x === 4; + }), {x: 4, z: 1}); + + _.findIndex([{a: 1}], function(a, key, o) { + assert.strictEqual(key, 0); + assert.deepEqual(o, [{a: 1}]); + assert.strictEqual(this, _, 'called with context'); + }, _); }); - test('detect', function() { - var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); - equal(result, 2, 'found the first "2" and broke the loop'); + QUnit.test('detect', function(assert) { + assert.strictEqual(_.detect, _.find, 'is an alias for find'); }); - test('select', function() { - var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(evens.join(', '), '2, 4, 6', 'selected each even number'); + QUnit.test('filter', function(assert) { + var evenArray = [1, 2, 3, 4, 5, 6]; + var evenObject = {one: 1, two: 2, three: 3}; + var isEven = function(num){ return num % 2 === 0; }; - evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); + assert.deepEqual(_.filter(evenArray, isEven), [2, 4, 6]); + assert.deepEqual(_.filter(evenObject, isEven), [2], 'can filter objects'); + assert.deepEqual(_.filter([{}, evenObject, []], 'two'), [evenObject], 'predicate string map to object properties'); + + _.filter([1], function() { + assert.strictEqual(this, evenObject, 'given context'); + }, evenObject); + + // Can be used like _.where. + var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; + assert.deepEqual(_.filter(list, {a: 1}), [{a: 1, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]); + assert.deepEqual(_.filter(list, {b: 2}), [{a: 1, b: 2}, {a: 2, b: 2}]); + assert.deepEqual(_.filter(list, {}), list, 'Empty object accepts all items'); + assert.deepEqual(_(list).filter({}), list, 'OO-filter'); }); - test('reject', function() { - var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(odds.join(', '), '1, 3, 5', 'rejected each even number'); + QUnit.test('select', function(assert) { + assert.strictEqual(_.select, _.filter, 'is an alias for filter'); + }); - var context = "obj"; + QUnit.test('reject', function(assert) { + var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 === 0; }); + assert.deepEqual(odds, [1, 3, 5], 'rejected each even number'); + + var context = 'obj'; var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){ - equal(context, "obj"); - return num % 2 != 0; + assert.strictEqual(context, 'obj'); + return num % 2 !== 0; }, context); - equal(evens.join(', '), '2, 4, 6', 'rejected each odd number'); + assert.deepEqual(evens, [2, 4, 6], 'rejected each odd number'); + + assert.deepEqual(_.reject([odds, {one: 1, two: 2, three: 3}], 'two'), [odds], 'predicate string map to object properties'); + + // Can be used like _.where. + var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; + assert.deepEqual(_.reject(list, {a: 1}), [{a: 2, b: 2}]); + assert.deepEqual(_.reject(list, {b: 2}), [{a: 1, b: 3}, {a: 1, b: 4}]); + assert.deepEqual(_.reject(list, {}), [], 'Returns empty list given empty object'); }); - test('all', function() { - ok(_.all([], _.identity), 'the empty set'); - ok(_.all([true, true, true], _.identity), 'all true values'); - ok(!_.all([true, false, true], _.identity), 'one false value'); - ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); - ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); - ok(_.all([1], _.identity) === true, 'cast to boolean - true'); - ok(_.all([0], _.identity) === false, 'cast to boolean - false'); - ok(_.every([true, true, true], _.identity), 'aliased as "every"'); - ok(!_.all([undefined, undefined, undefined], _.identity), 'works with arrays of undefined'); + QUnit.test('every', function(assert) { + assert.ok(_.every([], _.identity), 'the empty set'); + assert.ok(_.every([true, true, true], _.identity), 'every true values'); + assert.notOk(_.every([true, false, true], _.identity), 'one false value'); + assert.ok(_.every([0, 10, 28], function(num){ return num % 2 === 0; }), 'even numbers'); + assert.notOk(_.every([0, 11, 28], function(num){ return num % 2 === 0; }), 'an odd number'); + assert.strictEqual(_.every([1], _.identity), true, 'cast to boolean - true'); + assert.strictEqual(_.every([0], _.identity), false, 'cast to boolean - false'); + assert.notOk(_.every([void 0, void 0, void 0], _.identity), 'works with arrays of undefined'); + + var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; + assert.notOk(_.every(list, {a: 1, b: 2}), 'Can be called with object'); + assert.ok(_.every(list, 'a'), 'String mapped to object property'); + + list = [{a: 1, b: 2}, {a: 2, b: 2, c: true}]; + assert.ok(_.every(list, {b: 2}), 'Can be called with object'); + assert.notOk(_.every(list, 'c'), 'String mapped to object property'); + + assert.ok(_.every({a: 1, b: 2, c: 3, d: 4}, _.isNumber), 'takes objects'); + assert.notOk(_.every({a: 1, b: 2, c: 3, d: 4}, _.isObject), 'takes objects'); + assert.ok(_.every(['a', 'b', 'c', 'd'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works'); + assert.notOk(_.every(['a', 'b', 'c', 'd', 'f'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works'); }); - test('any', function() { - var nativeSome = Array.prototype.some; - Array.prototype.some = null; - ok(!_.any([]), 'the empty set'); - ok(!_.any([false, false, false]), 'all false values'); - ok(_.any([false, false, true]), 'one true value'); - ok(_.any([null, 0, 'yes', false]), 'a string'); - ok(!_.any([null, 0, '', false]), 'falsy values'); - ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); - ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); - ok(_.any([1], _.identity) === true, 'cast to boolean - true'); - ok(_.any([0], _.identity) === false, 'cast to boolean - false'); - ok(_.some([false, false, true]), 'aliased as "some"'); - Array.prototype.some = nativeSome; + QUnit.test('all', function(assert) { + assert.strictEqual(_.all, _.every, 'is an alias for every'); }); - test('include', function() { - ok(_.include([1,2,3], 2), 'two is in the array'); - ok(!_.include([1,3,9], 2), 'two is not in the array'); - ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); - ok(_([1,2,3]).include(2), 'OO-style include'); + QUnit.test('some', function(assert) { + assert.notOk(_.some([]), 'the empty set'); + assert.notOk(_.some([false, false, false]), 'all false values'); + assert.ok(_.some([false, false, true]), 'one true value'); + assert.ok(_.some([null, 0, 'yes', false]), 'a string'); + assert.notOk(_.some([null, 0, '', false]), 'falsy values'); + assert.notOk(_.some([1, 11, 29], function(num){ return num % 2 === 0; }), 'all odd numbers'); + assert.ok(_.some([1, 10, 29], function(num){ return num % 2 === 0; }), 'an even number'); + assert.strictEqual(_.some([1], _.identity), true, 'cast to boolean - true'); + assert.strictEqual(_.some([0], _.identity), false, 'cast to boolean - false'); + assert.ok(_.some([false, false, true])); + + var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; + assert.notOk(_.some(list, {a: 5, b: 2}), 'Can be called with object'); + assert.ok(_.some(list, 'a'), 'String mapped to object property'); + + list = [{a: 1, b: 2}, {a: 2, b: 2, c: true}]; + assert.ok(_.some(list, {b: 2}), 'Can be called with object'); + assert.notOk(_.some(list, 'd'), 'String mapped to object property'); + + assert.ok(_.some({a: '1', b: '2', c: '3', d: '4', e: 6}, _.isNumber), 'takes objects'); + assert.notOk(_.some({a: 1, b: 2, c: 3, d: 4}, _.isObject), 'takes objects'); + assert.ok(_.some(['a', 'b', 'c', 'd'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works'); + assert.notOk(_.some(['x', 'y', 'z'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works'); }); - test('invoke', function() { + QUnit.test('any', function(assert) { + assert.strictEqual(_.any, _.some, 'is an alias for some'); + }); + + QUnit.test('includes', function(assert) { + _.each([null, void 0, 0, 1, NaN, {}, []], function(val) { + assert.strictEqual(_.includes(val, 'hasOwnProperty'), false); + }); + assert.strictEqual(_.includes([1, 2, 3], 2), true, 'two is in the array'); + assert.notOk(_.includes([1, 3, 9], 2), 'two is not in the array'); + + assert.strictEqual(_.includes([5, 4, 3, 2, 1], 5, true), true, 'doesn\'t delegate to binary search'); + + assert.strictEqual(_.includes({moe: 1, larry: 3, curly: 9}, 3), true, '_.includes on objects checks their values'); + assert.ok(_([1, 2, 3]).includes(2), 'OO-style includes'); + + var numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; + assert.strictEqual(_.includes(numbers, 1, 1), true, 'takes a fromIndex'); + assert.strictEqual(_.includes(numbers, 1, -1), false, 'takes a fromIndex'); + assert.strictEqual(_.includes(numbers, 1, -2), false, 'takes a fromIndex'); + assert.strictEqual(_.includes(numbers, 1, -3), true, 'takes a fromIndex'); + assert.strictEqual(_.includes(numbers, 1, 6), true, 'takes a fromIndex'); + assert.strictEqual(_.includes(numbers, 1, 7), false, 'takes a fromIndex'); + + assert.ok(_.every([1, 2, 3], _.partial(_.includes, numbers)), 'fromIndex is guarded'); + }); + + QUnit.test('include', function(assert) { + assert.strictEqual(_.include, _.includes, 'is an alias for includes'); + }); + + QUnit.test('contains', function(assert) { + assert.strictEqual(_.contains, _.includes, 'is an alias for includes'); + + }); + + QUnit.test('includes with NaN', function(assert) { + assert.strictEqual(_.includes([1, 2, NaN, NaN], NaN), true, 'Expected [1, 2, NaN] to contain NaN'); + assert.strictEqual(_.includes([1, 2, Infinity], NaN), false, 'Expected [1, 2, NaN] to contain NaN'); + }); + + QUnit.test('includes with +- 0', function(assert) { + _.each([-0, +0], function(val) { + assert.strictEqual(_.includes([1, 2, val, val], val), true); + assert.strictEqual(_.includes([1, 2, val, val], -val), true); + assert.strictEqual(_.includes([-1, 1, 2], -val), false); + }); + }); + + + QUnit.test('invoke', function(assert) { + assert.expect(13); var list = [[5, 1, 7], [3, 2, 1]]; var result = _.invoke(list, 'sort'); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + assert.deepEqual(result[0], [1, 5, 7], 'first array sorted'); + assert.deepEqual(result[1], [1, 2, 3], 'second array sorted'); + + _.invoke([{ + method: function() { + assert.deepEqual(_.toArray(arguments), [1, 2, 3], 'called with arguments'); + } + }], 'method', 1, 2, 3); + + assert.deepEqual(_.invoke([{a: null}, {}, {a: _.constant(1)}], 'a'), [null, void 0, 1], 'handles null & undefined'); + + assert.raises(function() { + _.invoke([{a: 1}], 'a'); + }, TypeError, 'throws for non-functions'); + + var getFoo = _.constant('foo'); + var getThis = function() { return this; }; + var item = { + a: { + b: getFoo, + c: getThis, + d: null + }, + e: getFoo, + f: getThis, + g: function() { + return { + h: getFoo + }; + } + }; + var arr = [item]; + assert.deepEqual(_.invoke(arr, ['a', 'b']), ['foo'], 'supports deep method access via an array syntax'); + assert.deepEqual(_.invoke(arr, ['a', 'c']), [item.a], 'executes deep methods on their direct parent'); + assert.deepEqual(_.invoke(arr, ['a', 'd', 'z']), [void 0], 'does not try to access attributes of non-objects'); + assert.deepEqual(_.invoke(arr, ['a', 'd']), [null], 'handles deep null values'); + assert.deepEqual(_.invoke(arr, ['e']), ['foo'], 'handles path arrays of length one'); + assert.deepEqual(_.invoke(arr, ['f']), [item], 'correct uses parent context with shallow array syntax'); + assert.deepEqual(_.invoke(arr, ['g', 'h']), [void 0], 'does not execute intermediate functions'); + + arr = [{ + a: function() { return 'foo'; } + }, { + a: function() { return 'bar'; } + }]; + assert.deepEqual(_.invoke(arr, 'a'), ['foo', 'bar'], 'can handle different methods on subsequent objects'); }); - test('invoke w/ function reference', function() { + QUnit.test('invoke w/ function reference', function(assert) { var list = [[5, 1, 7], [3, 2, 1]]; var result = _.invoke(list, Array.prototype.sort); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + assert.deepEqual(result[0], [1, 5, 7], 'first array sorted'); + assert.deepEqual(result[1], [1, 2, 3], 'second array sorted'); + + assert.deepEqual(_.invoke([1, 2, 3], function(a) { + return a + this; + }, 5), [6, 7, 8], 'receives params from invoke'); }); // Relevant when using ClojureScript - test('invoke when strings have a call method', function() { + QUnit.test('invoke when strings have a call method', function(assert) { String.prototype.call = function() { return 42; }; var list = [[5, 1, 7], [3, 2, 1]]; - var s = "foo"; - equal(s.call(), 42, "call function exists"); + var s = 'foo'; + assert.strictEqual(s.call(), 42, 'call function exists'); var result = _.invoke(list, 'sort'); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + assert.deepEqual(result[0], [1, 5, 7], 'first array sorted'); + assert.deepEqual(result[1], [1, 2, 3], 'second array sorted'); delete String.prototype.call; - equal(s.call, undefined, "call function removed"); + assert.strictEqual(s.call, void 0, 'call function removed'); }); - test('pluck', function() { - var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; - equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); + QUnit.test('pluck', function(assert) { + var people = [{name: 'moe', age: 30}, {name: 'curly', age: 50}]; + assert.deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'pulls names out of objects'); + assert.deepEqual(_.pluck(people, 'address'), [void 0, void 0], 'missing properties are returned as undefined'); + //compat: most flexible handling of edge cases + assert.deepEqual(_.pluck([{'[object Object]': 1}], {}), [1]); }); - test('where', function() { + QUnit.test('where', function(assert) { var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; var result = _.where(list, {a: 1}); - equal(result.length, 3); - equal(result[result.length - 1].b, 4); + assert.strictEqual(result.length, 3); + assert.strictEqual(result[result.length - 1].b, 4); result = _.where(list, {b: 2}); - equal(result.length, 2); - equal(result[0].a, 1); + assert.strictEqual(result.length, 2); + assert.strictEqual(result[0].a, 1); + result = _.where(list, {}); + assert.strictEqual(result.length, list.length); - result = _.where(list, {a: 1}, true); - equal(result.b, 2, "Only get the first object matched.") - result = _.where(list, {a: 1}, false); - equal(result.length, 3); + function test() {} + test.map = _.map; + assert.deepEqual(_.where([_, {a: 1, b: 2}, _], test), [_, _], 'checks properties given function'); }); - test('findWhere', function() { + QUnit.test('findWhere', function(assert) { var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}]; var result = _.findWhere(list, {a: 1}); - deepEqual(result, {a: 1, b: 2}); + assert.deepEqual(result, {a: 1, b: 2}); result = _.findWhere(list, {b: 4}); - deepEqual(result, {a: 1, b: 4}); + assert.deepEqual(result, {a: 1, b: 4}); - result = _.findWhere(list, {c:1}) - ok(_.isUndefined(result), "undefined when not found"); + result = _.findWhere(list, {c: 1}); + assert.ok(_.isUndefined(result), 'undefined when not found'); - result = _.findWhere([], {c:1}); - ok(_.isUndefined(result), "undefined when searching empty list"); + result = _.findWhere([], {c: 1}); + assert.ok(_.isUndefined(result), 'undefined when searching empty list'); + + function test() {} + test.map = _.map; + assert.strictEqual(_.findWhere([_, {a: 1, b: 2}, _], test), _, 'checks properties given function'); + + function TestClass() { + this.y = 5; + this.x = 'foo'; + } + var expect = {c: 1, x: 'foo', y: 5}; + assert.deepEqual(_.findWhere([{y: 5, b: 6}, expect], new TestClass()), expect, 'uses class instance properties'); }); - test('max', function() { - equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); + QUnit.test('max', function(assert) { + assert.strictEqual(-Infinity, _.max(null), 'can handle null/undefined'); + assert.strictEqual(-Infinity, _.max(void 0), 'can handle null/undefined'); + assert.strictEqual(-Infinity, _.max(null, _.identity), 'can handle null/undefined'); + + assert.strictEqual(_.max([1, 2, 3]), 3, 'can perform a regular Math.max'); var neg = _.max([1, 2, 3], function(num){ return -num; }); - equal(neg, 1, 'can perform a computation-based max'); + assert.strictEqual(neg, 1, 'can perform a computation-based max'); - equal(-Infinity, _.max({}), 'Maximum value of an empty object'); - equal(-Infinity, _.max([]), 'Maximum value of an empty array'); - equal(_.max({'a': 'a'}), -Infinity, 'Maximum value of a non-numeric collection'); + assert.strictEqual(-Infinity, _.max({}), 'Maximum value of an empty object'); + assert.strictEqual(-Infinity, _.max([]), 'Maximum value of an empty array'); + assert.strictEqual(_.max({a: 'a'}), -Infinity, 'Maximum value of a non-numeric collection'); - equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array"); + assert.strictEqual(_.max(_.range(1, 300000)), 299999, 'Maximum value of a too-big array'); + + assert.strictEqual(_.max([1, 2, 3, 'test']), 3, 'Finds correct max in array starting with num and containing a NaN'); + assert.strictEqual(_.max(['test', 1, 2, 3]), 3, 'Finds correct max in array starting with NaN'); + + assert.strictEqual(_.max([1, 2, 3, null]), 3, 'Finds correct max in array starting with num and containing a `null`'); + assert.strictEqual(_.max([null, 1, 2, 3]), 3, 'Finds correct max in array starting with a `null`'); + + assert.strictEqual(_.max([1, 2, 3, '']), 3, 'Finds correct max in array starting with num and containing an empty string'); + assert.strictEqual(_.max(['', 1, 2, 3]), 3, 'Finds correct max in array starting with an empty string'); + + assert.strictEqual(_.max([1, 2, 3, false]), 3, 'Finds correct max in array starting with num and containing a false'); + assert.strictEqual(_.max([false, 1, 2, 3]), 3, 'Finds correct max in array starting with a false'); + + assert.strictEqual(_.max([0, 1, 2, 3, 4]), 4, 'Finds correct max in array containing a zero'); + assert.strictEqual(_.max([-3, -2, -1, 0]), 0, 'Finds correct max in array containing negative numbers'); + + assert.deepEqual(_.map([[1, 2, 3], [4, 5, 6]], _.max), [3, 6], 'Finds correct max in array when mapping through multiple arrays'); + + var a = {x: -Infinity}; + var b = {x: -Infinity}; + var iterator = function(o){ return o.x; }; + assert.strictEqual(_.max([a, b], iterator), a, 'Respects iterator return value of -Infinity'); + + assert.deepEqual(_.max([{a: 1}, {a: 0, b: 3}, {a: 4}, {a: 2}], 'a'), {a: 4}, 'String keys use property iterator'); + + assert.deepEqual(_.max([0, 2], function(c){ return c * this.x; }, {x: 1}), 2, 'Iterator context'); + assert.deepEqual(_.max([[1], [2, 3], [-1, 4], [5]], 0), [5], 'Lookup falsy iterator'); + assert.deepEqual(_.max([{0: 1}, {0: 2}, {0: -1}, {a: 1}], 0), {0: 2}, 'Lookup falsy iterator'); }); - test('min', function() { - equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); + QUnit.test('min', function(assert) { + assert.strictEqual(_.min(null), Infinity, 'can handle null/undefined'); + assert.strictEqual(_.min(void 0), Infinity, 'can handle null/undefined'); + assert.strictEqual(_.min(null, _.identity), Infinity, 'can handle null/undefined'); + + assert.strictEqual(_.min([1, 2, 3]), 1, 'can perform a regular Math.min'); var neg = _.min([1, 2, 3], function(num){ return -num; }); - equal(neg, 3, 'can perform a computation-based min'); + assert.strictEqual(neg, 3, 'can perform a computation-based min'); - equal(Infinity, _.min({}), 'Minimum value of an empty object'); - equal(Infinity, _.min([]), 'Minimum value of an empty array'); - equal(_.min({'a': 'a'}), Infinity, 'Minimum value of a non-numeric collection'); + assert.strictEqual(_.min({}), Infinity, 'Minimum value of an empty object'); + assert.strictEqual(_.min([]), Infinity, 'Minimum value of an empty array'); + assert.strictEqual(_.min({a: 'a'}), Infinity, 'Minimum value of a non-numeric collection'); + + assert.deepEqual(_.map([[1, 2, 3], [4, 5, 6]], _.min), [1, 4], 'Finds correct min in array when mapping through multiple arrays'); var now = new Date(9999999999); var then = new Date(0); - equal(_.min([now, then]), then); + assert.strictEqual(_.min([now, then]), then); - equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array"); + assert.strictEqual(_.min(_.range(1, 300000)), 1, 'Minimum value of a too-big array'); + + assert.strictEqual(_.min([1, 2, 3, 'test']), 1, 'Finds correct min in array starting with num and containing a NaN'); + assert.strictEqual(_.min(['test', 1, 2, 3]), 1, 'Finds correct min in array starting with NaN'); + + assert.strictEqual(_.min([1, 2, 3, null]), 1, 'Finds correct min in array starting with num and containing a `null`'); + assert.strictEqual(_.min([null, 1, 2, 3]), 1, 'Finds correct min in array starting with a `null`'); + + assert.strictEqual(_.min([0, 1, 2, 3, 4]), 0, 'Finds correct min in array containing a zero'); + assert.strictEqual(_.min([-3, -2, -1, 0]), -3, 'Finds correct min in array containing negative numbers'); + + var a = {x: Infinity}; + var b = {x: Infinity}; + var iterator = function(o){ return o.x; }; + assert.strictEqual(_.min([a, b], iterator), a, 'Respects iterator return value of Infinity'); + + assert.deepEqual(_.min([{a: 1}, {a: 0, b: 3}, {a: 4}, {a: 2}], 'a'), {a: 0, b: 3}, 'String keys use property iterator'); + + assert.deepEqual(_.min([0, 2], function(c){ return c * this.x; }, {x: -1}), 2, 'Iterator context'); + assert.deepEqual(_.min([[1], [2, 3], [-1, 4], [5]], 0), [-1, 4], 'Lookup falsy iterator'); + assert.deepEqual(_.min([{0: 1}, {0: 2}, {0: -1}, {a: 1}], 0), {0: -1}, 'Lookup falsy iterator'); }); - test('sortBy', function() { - var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; + QUnit.test('sortBy', function(assert) { + var people = [{name: 'curly', age: 50}, {name: 'moe', age: 30}]; people = _.sortBy(people, function(person){ return person.age; }); - equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); + assert.deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'stooges sorted by age'); - var list = [undefined, 4, 1, undefined, 3, 2]; - equal(_.sortBy(list, _.identity).join(','), '1,2,3,4,,', 'sortBy with undefined values'); + var list = [void 0, 4, 1, void 0, 3, 2]; + assert.deepEqual(_.sortBy(list, _.identity), [1, 2, 3, 4, void 0, void 0], 'sortBy with undefined values'); - var list = ["one", "two", "three", "four", "five"]; + list = ['one', 'two', 'three', 'four', 'five']; var sorted = _.sortBy(list, 'length'); - equal(sorted.join(' '), 'one two four five three', 'sorted by length'); + assert.deepEqual(sorted, ['one', 'two', 'four', 'five', 'three'], 'sorted by length'); function Pair(x, y) { this.x = x; this.y = y; } - var collection = [ + var stableArray = [ new Pair(1, 1), new Pair(1, 2), new Pair(1, 3), new Pair(1, 4), new Pair(1, 5), new Pair(1, 6), new Pair(2, 1), new Pair(2, 2), new Pair(2, 3), new Pair(2, 4), new Pair(2, 5), new Pair(2, 6), - new Pair(undefined, 1), new Pair(undefined, 2), - new Pair(undefined, 3), new Pair(undefined, 4), - new Pair(undefined, 5), new Pair(undefined, 6) + new Pair(void 0, 1), new Pair(void 0, 2), + new Pair(void 0, 3), new Pair(void 0, 4), + new Pair(void 0, 5), new Pair(void 0, 6) ]; - var actual = _.sortBy(collection, function(pair) { + var stableObject = _.object('abcdefghijklmnopqr'.split(''), stableArray); + + var actual = _.sortBy(stableArray, function(pair) { return pair.x; }); - deepEqual(actual, collection, 'sortBy should be stable'); + assert.deepEqual(actual, stableArray, 'sortBy should be stable for arrays'); + assert.deepEqual(_.sortBy(stableArray, 'x'), stableArray, 'sortBy accepts property string'); + + actual = _.sortBy(stableObject, function(pair) { + return pair.x; + }); + + assert.deepEqual(actual, stableArray, 'sortBy should be stable for objects'); + + list = ['q', 'w', 'e', 'r', 't', 'y']; + assert.deepEqual(_.sortBy(list), ['e', 'q', 'r', 't', 'w', 'y'], 'uses _.identity if iterator is not specified'); }); - test('groupBy', function() { + QUnit.test('groupBy', function(assert) { var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); - ok('0' in parity && '1' in parity, 'created a group for each value'); - equal(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); + assert.ok('0' in parity && '1' in parity, 'created a group for each value'); + assert.deepEqual(parity[0], [2, 4, 6], 'put each even number in the right group'); - var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']; var grouped = _.groupBy(list, 'length'); - equal(grouped['3'].join(' '), 'one two six ten'); - equal(grouped['4'].join(' '), 'four five nine'); - equal(grouped['5'].join(' '), 'three seven eight'); + assert.deepEqual(grouped['3'], ['one', 'two', 'six', 'ten']); + assert.deepEqual(grouped['4'], ['four', 'five', 'nine']); + assert.deepEqual(grouped['5'], ['three', 'seven', 'eight']); var context = {}; - _.groupBy([{}], function(){ ok(this === context); }, context); + _.groupBy([{}], function(){ assert.strictEqual(this, context); }, context); grouped = _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; }); - equal(grouped.constructor.length, 1); - equal(grouped.hasOwnProperty.length, 2); + assert.strictEqual(grouped.constructor.length, 1); + assert.strictEqual(grouped.hasOwnProperty.length, 2); var array = [{}]; - _.groupBy(array, function(value, index, obj){ ok(obj === array); }); + _.groupBy(array, function(value, index, obj){ assert.strictEqual(obj, array); }); - var array = [1, 2, 1, 2, 3]; - var grouped = _.groupBy(array); - equal(grouped['1'].length, 2); - equal(grouped['3'].length, 1); + array = [1, 2, 1, 2, 3]; + grouped = _.groupBy(array); + assert.strictEqual(grouped['1'].length, 2); + assert.strictEqual(grouped['3'].length, 1); var matrix = [ - [1,2], - [1,3], - [2,3] + [1, 2], + [1, 3], + [2, 3] ]; - deepEqual(_.groupBy(matrix, 0), {1: [[1,2], [1,3]], 2: [[2,3]]}) - deepEqual(_.groupBy(matrix, 1), {2: [[1,2]], 3: [[1,3], [2,3]]}) + assert.deepEqual(_.groupBy(matrix, 0), {1: [[1, 2], [1, 3]], 2: [[2, 3]]}); + assert.deepEqual(_.groupBy(matrix, 1), {2: [[1, 2]], 3: [[1, 3], [2, 3]]}); + + var liz = {name: 'Liz', stats: {power: 10}}; + var chelsea = {name: 'Chelsea', stats: {power: 10}}; + var jordan = {name: 'Jordan', stats: {power: 6}}; + var collection = [liz, chelsea, jordan]; + var expected = { + 10: [liz, chelsea], + 6: [jordan] + }; + assert.deepEqual(_.groupBy(collection, ['stats', 'power']), expected, 'can group by deep properties'); }); - test('indexBy', function() { - var parity = _.indexBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; }); - equal(parity['true'], 4); - equal(parity['false'], 5); + QUnit.test('indexBy', function(assert) { + var parity = _.indexBy([1, 2, 3, 4, 5], function(num){ return num % 2 === 0; }); + assert.strictEqual(parity['true'], 4); + assert.strictEqual(parity['false'], 5); - var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']; var grouped = _.indexBy(list, 'length'); - equal(grouped['3'], 'ten'); - equal(grouped['4'], 'nine'); - equal(grouped['5'], 'eight'); + assert.strictEqual(grouped['3'], 'ten'); + assert.strictEqual(grouped['4'], 'nine'); + assert.strictEqual(grouped['5'], 'eight'); var array = [1, 2, 1, 2, 3]; - var grouped = _.indexBy(array); - equal(grouped['1'], 1); - equal(grouped['2'], 2); - equal(grouped['3'], 3); + grouped = _.indexBy(array); + assert.strictEqual(grouped['1'], 1); + assert.strictEqual(grouped['2'], 2); + assert.strictEqual(grouped['3'], 3); }); - test('countBy', function() { - var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; }); - equal(parity['true'], 2); - equal(parity['false'], 3); + QUnit.test('countBy', function(assert) { + var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 === 0; }); + assert.strictEqual(parity['true'], 2); + assert.strictEqual(parity['false'], 3); - var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']; var grouped = _.countBy(list, 'length'); - equal(grouped['3'], 4); - equal(grouped['4'], 3); - equal(grouped['5'], 3); + assert.strictEqual(grouped['3'], 4); + assert.strictEqual(grouped['4'], 3); + assert.strictEqual(grouped['5'], 3); var context = {}; - _.countBy([{}], function(){ ok(this === context); }, context); + _.countBy([{}], function(){ assert.strictEqual(this, context); }, context); grouped = _.countBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; }); - equal(grouped.constructor, 1); - equal(grouped.hasOwnProperty, 2); + assert.strictEqual(grouped.constructor, 1); + assert.strictEqual(grouped.hasOwnProperty, 2); var array = [{}]; - _.countBy(array, function(value, index, obj){ ok(obj === array); }); + _.countBy(array, function(value, index, obj){ assert.strictEqual(obj, array); }); - var array = [1, 2, 1, 2, 3]; - var grouped = _.countBy(array); - equal(grouped['1'], 2); - equal(grouped['3'], 1); + array = [1, 2, 1, 2, 3]; + grouped = _.countBy(array); + assert.strictEqual(grouped['1'], 2); + assert.strictEqual(grouped['3'], 1); }); - test('sortedIndex', function() { - var numbers = [10, 20, 30, 40, 50], num = 35; - var indexForNum = _.sortedIndex(numbers, num); - equal(indexForNum, 3, '35 should be inserted at index 3'); + QUnit.test('shuffle', function(assert) { + assert.deepEqual(_.shuffle([1]), [1], 'behaves correctly on size 1 arrays'); + var numbers = _.range(20); + var shuffled = _.shuffle(numbers); + assert.notDeepEqual(numbers, shuffled, 'does change the order'); // Chance of false negative: 1 in ~2.4*10^18 + assert.notStrictEqual(numbers, shuffled, 'original object is unmodified'); + assert.deepEqual(numbers, _.sortBy(shuffled), 'contains the same members before and after shuffle'); - var indexFor30 = _.sortedIndex(numbers, 30); - equal(indexFor30, 2, '30 should be inserted at index 2'); - - var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; - var iterator = function(obj){ return obj.x; }; - strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2); - strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3); - - var context = {1: 2, 2: 3, 3: 4}; - iterator = function(obj){ return this[obj]; }; - strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1); + shuffled = _.shuffle({a: 1, b: 2, c: 3, d: 4}); + assert.strictEqual(shuffled.length, 4); + assert.deepEqual(shuffled.sort(), [1, 2, 3, 4], 'works on objects'); }); - test('shuffle', function() { + QUnit.test('sample', function(assert) { + assert.strictEqual(_.sample([1]), 1, 'behaves correctly when no second parameter is given'); + assert.deepEqual(_.sample([1, 2, 3], -2), [], 'behaves correctly on negative n'); var numbers = _.range(10); - var shuffled = _.shuffle(numbers).sort(); - notStrictEqual(numbers, shuffled, 'original object is unmodified'); - equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle'); + var allSampled = _.sample(numbers, 10).sort(); + assert.deepEqual(allSampled, numbers, 'contains the same members before and after sample'); + allSampled = _.sample(numbers, 20).sort(); + assert.deepEqual(allSampled, numbers, 'also works when sampling more objects than are present'); + assert.ok(_.contains(numbers, _.sample(numbers)), 'sampling a single element returns something from the array'); + assert.strictEqual(_.sample([]), void 0, 'sampling empty array with no number returns undefined'); + assert.notStrictEqual(_.sample([], 5), [], 'sampling empty array with a number returns an empty array'); + assert.notStrictEqual(_.sample([1, 2, 3], 0), [], 'sampling an array with 0 picks returns an empty array'); + assert.deepEqual(_.sample([1, 2], -1), [], 'sampling a negative number of picks returns an empty array'); + assert.ok(_.contains([1, 2, 3], _.sample({a: 1, b: 2, c: 3})), 'sample one value from an object'); + var partialSample = _.sample(_.range(1000), 10); + var partialSampleSorted = partialSample.sort(); + assert.notDeepEqual(partialSampleSorted, _.range(10), 'samples from the whole array, not just the beginning'); }); - test('sample', function() { - var numbers = _.range(10); - var all_sampled = _.sample(numbers, 10).sort(); - equal(all_sampled.join(','), numbers.join(','), 'contains the same members before and after sample'); - all_sampled = _.sample(numbers, 20).sort(); - equal(all_sampled.join(','), numbers.join(','), 'also works when sampling more objects than are present'); - ok(_.contains(numbers, _.sample(numbers)), 'sampling a single element returns something from the array'); - strictEqual(_.sample([]), undefined, 'sampling empty array with no number returns undefined'); - notStrictEqual(_.sample([], 5), [], 'sampling empty array with a number returns an empty array'); - notStrictEqual(_.sample([1, 2, 3], 0), [], 'sampling an array with 0 picks returns an empty array'); - deepEqual(_.sample([1, 2], -1), [], 'sampling a negative number of picks returns an empty array'); + QUnit.test('toArray', function(assert) { + assert.notOk(_.isArray(arguments), 'arguments object is not an array'); + assert.ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); + var a = [1, 2, 3]; + assert.notStrictEqual(_.toArray(a), a, 'array is cloned'); + assert.deepEqual(_.toArray(a), [1, 2, 3], 'cloned array contains same elements'); + + var numbers = _.toArray({one: 1, two: 2, three: 3}); + assert.deepEqual(numbers, [1, 2, 3], 'object flattened into array'); + + var hearts = '\uD83D\uDC95'; + var pair = hearts.split(''); + var expected = [pair[0], hearts, '&', hearts, pair[1]]; + assert.deepEqual(_.toArray(expected.join('')), expected, 'maintains astral characters'); + assert.deepEqual(_.toArray(''), [], 'empty string into empty array'); + + if (typeof document != 'undefined') { + // test in IE < 9 + var actual; + try { + actual = _.toArray(document.childNodes); + } catch (e) { /* ignored */ } + assert.deepEqual(actual, _.map(document.childNodes, _.identity), 'works on NodeList'); + } }); - test('toArray', function() { - ok(!_.isArray(arguments), 'arguments object is not an array'); - ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); - var a = [1,2,3]; - ok(_.toArray(a) !== a, 'array is cloned'); - equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements'); - - var numbers = _.toArray({one : 1, two : 2, three : 3}); - equal(numbers.join(', '), '1, 2, 3', 'object flattened into array'); - - // test in IE < 9 - try { - var actual = _.toArray(document.childNodes); - } catch(ex) { } - - ok(_.isArray(actual), 'should not throw converting a node list'); - }); - - test('size', function() { - equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); - equal(_.size([1, 2, 3]), 3, 'can compute the size of an array'); - equal(_.size($('
    ').add('').add('')), 3, 'can compute the size of jQuery objects'); + QUnit.test('size', function(assert) { + assert.strictEqual(_.size({one: 1, two: 2, three: 3}), 3, 'can compute the size of an object'); + assert.strictEqual(_.size([1, 2, 3]), 3, 'can compute the size of an array'); + assert.strictEqual(_.size({length: 3, 0: 0, 1: 0, 2: 0}), 3, 'can compute the size of Array-likes'); var func = function() { return _.size(arguments); }; - equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object'); + assert.strictEqual(func(1, 2, 3, 4), 4, 'can test the size of the arguments object'); - equal(_.size('hello'), 5, 'can compute the size of a string literal'); - equal(_.size(new String('hello')), 5, 'can compute the size of string object'); + assert.strictEqual(_.size('hello'), 5, 'can compute the size of a string literal'); + assert.strictEqual(_.size(new String('hello')), 5, 'can compute the size of string object'); - equal(_.size(null), 0, 'handles nulls'); + assert.strictEqual(_.size(null), 0, 'handles nulls'); + assert.strictEqual(_.size(0), 0, 'handles numbers'); }); -}); + QUnit.test('partition', function(assert) { + var list = [0, 1, 2, 3, 4, 5]; + assert.deepEqual(_.partition(list, function(x) { return x < 4; }), [[0, 1, 2, 3], [4, 5]], 'handles bool return values'); + assert.deepEqual(_.partition(list, function(x) { return x & 1; }), [[1, 3, 5], [0, 2, 4]], 'handles 0 and 1 return values'); + assert.deepEqual(_.partition(list, function(x) { return x - 3; }), [[0, 1, 2, 4, 5], [3]], 'handles other numeric return values'); + assert.deepEqual(_.partition(list, function(x) { return x > 1 ? null : true; }), [[0, 1], [2, 3, 4, 5]], 'handles null return values'); + assert.deepEqual(_.partition(list, function(x) { if (x < 2) return true; }), [[0, 1], [2, 3, 4, 5]], 'handles undefined return values'); + assert.deepEqual(_.partition({a: 1, b: 2, c: 3}, function(x) { return x > 1; }), [[2, 3], [1]], 'handles objects'); + + assert.deepEqual(_.partition(list, function(x, index) { return index % 2; }), [[1, 3, 5], [0, 2, 4]], 'can reference the array index'); + assert.deepEqual(_.partition(list, function(x, index, arr) { return x === arr.length - 1; }), [[5], [0, 1, 2, 3, 4]], 'can reference the collection'); + + // Default iterator + assert.deepEqual(_.partition([1, false, true, '']), [[1, true], [false, '']], 'Default iterator'); + assert.deepEqual(_.partition([{x: 1}, {x: 0}, {x: 1}], 'x'), [[{x: 1}, {x: 1}], [{x: 0}]], 'Takes a string'); + + // Context + var predicate = function(x){ return x === this.x; }; + assert.deepEqual(_.partition([1, 2, 3], predicate, {x: 2}), [[2], [1, 3]], 'partition takes a context argument'); + + assert.deepEqual(_.partition([{a: 1}, {b: 2}, {a: 1, b: 2}], {a: 1}), [[{a: 1}, {a: 1, b: 2}], [{b: 2}]], 'predicate can be object'); + + var object = {a: 1}; + _.partition(object, function(val, key, obj) { + assert.strictEqual(val, 1); + assert.strictEqual(key, 'a'); + assert.strictEqual(obj, object); + assert.strictEqual(this, predicate); + }, predicate); + }); + + if (typeof document != 'undefined') { + QUnit.test('Can use various collection methods on NodeLists', function(assert) { + var parent = document.createElement('div'); + parent.innerHTML = 'textnode'; + + var elementChildren = _.filter(parent.childNodes, _.isElement); + assert.strictEqual(elementChildren.length, 2); + + assert.deepEqual(_.map(elementChildren, 'id'), ['id1', 'id2']); + assert.deepEqual(_.map(parent.childNodes, 'nodeType'), [1, 3, 1]); + + assert.notOk(_.every(parent.childNodes, _.isElement)); + assert.ok(_.some(parent.childNodes, _.isElement)); + + function compareNode(node) { + return _.isElement(node) ? node.id.charAt(2) : void 0; + } + assert.strictEqual(_.max(parent.childNodes, compareNode), _.last(parent.childNodes)); + assert.strictEqual(_.min(parent.childNodes, compareNode), _.first(parent.childNodes)); + }); + } + +}()); diff --git a/vendor/underscore/test/cross-document.js b/vendor/underscore/test/cross-document.js new file mode 100644 index 000000000..89642760b --- /dev/null +++ b/vendor/underscore/test/cross-document.js @@ -0,0 +1,142 @@ +(function() { + if (typeof document == 'undefined') return; + + var _ = typeof require == 'function' ? require('..') : window._; + + QUnit.module('Cross Document'); + /* global iObject, iElement, iArguments, iFunction, iArray, iError, iString, iNumber, iBoolean, iDate, iRegExp, iNaN, iNull, iUndefined, ActiveXObject */ + + // Setup remote variables for iFrame tests. + var iframe = document.createElement('iframe'); + iframe.frameBorder = iframe.height = iframe.width = 0; + document.body.appendChild(iframe); + var iframeContent = iframe.contentDocument || iframe.contentWindow; + var iDoc = iframeContent.document || iframeContent; + iDoc.write( + [ + '' + ].join('\n') + ); + iDoc.close(); + + QUnit.test('isEqual', function(assert) { + + assert.notOk(_.isEqual(iNumber, 101)); + assert.ok(_.isEqual(iNumber, 100)); + + // Objects from another frame. + assert.ok(_.isEqual({}, iObject), 'Objects with equivalent members created in different documents are equal'); + + // Array from another frame. + assert.ok(_.isEqual([1, 2, 3], iArray), 'Arrays with equivalent elements created in different documents are equal'); + }); + + QUnit.test('isEmpty', function(assert) { + assert.notOk(_([iNumber]).isEmpty(), '[1] is not empty'); + assert.notOk(_.isEmpty(iArray), '[] is empty'); + assert.ok(_.isEmpty(iObject), '{} is empty'); + }); + + QUnit.test('isElement', function(assert) { + assert.notOk(_.isElement('div'), 'strings are not dom elements'); + assert.ok(_.isElement(document.body), 'the body tag is a DOM element'); + assert.ok(_.isElement(iElement), 'even from another frame'); + }); + + QUnit.test('isArguments', function(assert) { + assert.ok(_.isArguments(iArguments), 'even from another frame'); + }); + + QUnit.test('isObject', function(assert) { + assert.ok(_.isObject(iElement), 'even from another frame'); + assert.ok(_.isObject(iFunction), 'even from another frame'); + }); + + QUnit.test('isArray', function(assert) { + assert.ok(_.isArray(iArray), 'even from another frame'); + }); + + QUnit.test('isString', function(assert) { + assert.ok(_.isString(iString), 'even from another frame'); + }); + + QUnit.test('isNumber', function(assert) { + assert.ok(_.isNumber(iNumber), 'even from another frame'); + }); + + QUnit.test('isBoolean', function(assert) { + assert.ok(_.isBoolean(iBoolean), 'even from another frame'); + }); + + QUnit.test('isFunction', function(assert) { + assert.ok(_.isFunction(iFunction), 'even from another frame'); + }); + + QUnit.test('isDate', function(assert) { + assert.ok(_.isDate(iDate), 'even from another frame'); + }); + + QUnit.test('isRegExp', function(assert) { + assert.ok(_.isRegExp(iRegExp), 'even from another frame'); + }); + + QUnit.test('isNaN', function(assert) { + assert.ok(_.isNaN(iNaN), 'even from another frame'); + }); + + QUnit.test('isNull', function(assert) { + assert.ok(_.isNull(iNull), 'even from another frame'); + }); + + QUnit.test('isUndefined', function(assert) { + assert.ok(_.isUndefined(iUndefined), 'even from another frame'); + }); + + QUnit.test('isError', function(assert) { + assert.ok(_.isError(iError), 'even from another frame'); + }); + + if (typeof ActiveXObject != 'undefined') { + QUnit.test('IE host objects', function(assert) { + var xml = new ActiveXObject('Msxml2.DOMDocument.3.0'); + assert.notOk(_.isNumber(xml)); + assert.notOk(_.isBoolean(xml)); + assert.notOk(_.isNaN(xml)); + assert.notOk(_.isFunction(xml)); + assert.notOk(_.isNull(xml)); + assert.notOk(_.isUndefined(xml)); + }); + + QUnit.test('#1621 IE 11 compat mode DOM elements are not functions', function(assert) { + var fn = function() {}; + var xml = new ActiveXObject('Msxml2.DOMDocument.3.0'); + var div = document.createElement('div'); + + // JIT the function + var count = 200; + while (count--) { + _.isFunction(fn); + } + + assert.strictEqual(_.isFunction(xml), false); + assert.strictEqual(_.isFunction(div), false); + assert.strictEqual(_.isFunction(fn), true); + }); + } + +}()); diff --git a/vendor/underscore/test/functions.js b/vendor/underscore/test/functions.js index 7a773f32e..522a99e48 100644 --- a/vendor/underscore/test/functions.js +++ b/vendor/underscore/test/functions.js @@ -1,162 +1,265 @@ -$(document).ready(function() { +(function() { + var _ = typeof require == 'function' ? require('..') : window._; - module("Functions"); + QUnit.module('Functions'); + QUnit.config.asyncRetries = 3; - test("bind", function() { - var context = {name : 'moe'}; - var func = function(arg) { return "name: " + (this.name || arg); }; + QUnit.test('bind', function(assert) { + var context = {name: 'moe'}; + var func = function(arg) { return 'name: ' + (this.name || arg); }; var bound = _.bind(func, context); - equal(bound(), 'name: moe', 'can bind a function to a context'); + assert.strictEqual(bound(), 'name: moe', 'can bind a function to a context'); bound = _(func).bind(context); - equal(bound(), 'name: moe', 'can do OO-style binding'); + assert.strictEqual(bound(), 'name: moe', 'can do OO-style binding'); bound = _.bind(func, null, 'curly'); - equal(bound(), 'name: curly', 'can bind without specifying a context'); + var result = bound(); + // Work around a PhantomJS bug when applying a function with null|undefined. + assert.ok(result === 'name: curly' || result === 'name: ' + window.name, 'can bind without specifying a context'); func = function(salutation, name) { return salutation + ': ' + name; }; func = _.bind(func, this, 'hello'); - equal(func('moe'), 'hello: moe', 'the function was partially applied in advance'); + assert.strictEqual(func('moe'), 'hello: moe', 'the function was partially applied in advance'); func = _.bind(func, this, 'curly'); - equal(func(), 'hello: curly', 'the function was completely applied in advance'); + assert.strictEqual(func(), 'hello: curly', 'the function was completely applied in advance'); func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; func = _.bind(func, this, 'hello', 'moe', 'curly'); - equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); + assert.strictEqual(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); - func = function(context, message) { equal(this, context, message); }; - _.bind(func, 0, 0, 'can bind a function to `0`')(); - _.bind(func, '', '', 'can bind a function to an empty string')(); - _.bind(func, false, false, 'can bind a function to `false`')(); + func = function() { return this; }; + assert.strictEqual(typeof _.bind(func, 0)(), 'object', 'binding a primitive to `this` returns a wrapped primitive'); + + assert.strictEqual(_.bind(func, 0)().valueOf(), 0, 'can bind a function to `0`'); + assert.strictEqual(_.bind(func, '')().valueOf(), '', 'can bind a function to an empty string'); + assert.strictEqual(_.bind(func, false)().valueOf(), false, 'can bind a function to `false`'); // These tests are only meaningful when using a browser without a native bind function // To test this with a modern browser, set underscore's nativeBind to undefined - var F = function () { return this; }; - var Boundf = _.bind(F, {hello: "moe curly"}); + var F = function() { return this; }; + var boundf = _.bind(F, {hello: 'moe curly'}); + var Boundf = boundf; // make eslint happy. var newBoundf = new Boundf(); - equal(newBoundf.hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5"); - equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context"); - ok(newBoundf instanceof F, "a bound instance is an instance of the original function"); + assert.strictEqual(newBoundf.hello, void 0, 'function should not be bound to the context, to comply with ECMAScript 5'); + assert.strictEqual(boundf().hello, 'moe curly', "When called without the new operator, it's OK to be bound to the context"); + assert.ok(newBoundf instanceof F, 'a bound instance is an instance of the original function'); + + assert.raises(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function'); }); - test("partial", function() { + QUnit.test('partial', function(assert) { var obj = {name: 'moe'}; var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); }; obj.func = _.partial(func, 'a', 'b'); - equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply'); + assert.strictEqual(obj.func('c', 'd'), 'moe a b c d', 'can partially apply'); + + obj.func = _.partial(func, _, 'b', _, 'd'); + assert.strictEqual(obj.func('a', 'c'), 'moe a b c d', 'can partially apply with placeholders'); + + func = _.partial(function() { return arguments.length; }, _, 'b', _, 'd'); + assert.strictEqual(func('a', 'c', 'e'), 5, 'accepts more arguments than the number of placeholders'); + assert.strictEqual(func('a'), 4, 'accepts fewer arguments than the number of placeholders'); + + func = _.partial(function() { return typeof arguments[2]; }, _, 'b', _, 'd'); + assert.strictEqual(func('a'), 'undefined', 'unfilled placeholders are undefined'); + + // passes context + function MyWidget(name, options) { + this.name = name; + this.options = options; + } + MyWidget.prototype.get = function() { + return this.name; + }; + var MyWidgetWithCoolOpts = _.partial(MyWidget, _, {a: 1}); + var widget = new MyWidgetWithCoolOpts('foo'); + assert.ok(widget instanceof MyWidget, 'Can partially bind a constructor'); + assert.strictEqual(widget.get(), 'foo', 'keeps prototype'); + assert.deepEqual(widget.options, {a: 1}); + + _.partial.placeholder = obj; + func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd'); + assert.strictEqual(func('a'), 4, 'allows the placeholder to be swapped out'); + + _.partial.placeholder = {}; + func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd'); + assert.strictEqual(func('a'), 5, 'swapping the placeholder preserves previously bound arguments'); + + _.partial.placeholder = _; }); - test("bindAll", function() { - var curly = {name : 'curly'}, moe = { - name : 'moe', - getName : function() { return 'name: ' + this.name; }, - sayHi : function() { return 'hi: ' + this.name; } + QUnit.test('bindAll', function(assert) { + var curly = {name: 'curly'}; + var moe = { + name: 'moe', + getName: function() { return 'name: ' + this.name; }, + sayHi: function() { return 'hi: ' + this.name; } }; curly.getName = moe.getName; _.bindAll(moe, 'getName', 'sayHi'); curly.sayHi = moe.sayHi; - equal(curly.getName(), 'name: curly', 'unbound function is bound to current object'); - equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); + assert.strictEqual(curly.getName(), 'name: curly', 'unbound function is bound to current object'); + assert.strictEqual(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); - curly = {name : 'curly'}; + curly = {name: 'curly'}; moe = { - name : 'moe', - getName : function() { return 'name: ' + this.name; }, - sayHi : function() { return 'hi: ' + this.name; } + name: 'moe', + getName: function() { return 'name: ' + this.name; }, + sayHi: function() { return 'hi: ' + this.name; }, + sayLast: function() { return this.sayHi(_.last(arguments)); } }; - raises(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named'); + assert.raises(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named'); + assert.raises(function() { _.bindAll(moe, 'sayBye'); }, TypeError, 'throws an error for bindAll if the given key is undefined'); + assert.raises(function() { _.bindAll(moe, 'name'); }, TypeError, 'throws an error for bindAll if the given key is not a function'); - _.bindAll(moe, 'sayHi'); + _.bindAll(moe, 'sayHi', 'sayLast'); curly.sayHi = moe.sayHi; - equal(curly.sayHi(), 'hi: moe'); + assert.strictEqual(curly.sayHi(), 'hi: moe'); + + var sayLast = moe.sayLast; + assert.strictEqual(sayLast(1, 2, 3, 4, 5, 6, 7, 'Tom'), 'hi: moe', 'createCallback works with any number of arguments'); + + _.bindAll(moe, ['getName']); + var getName = moe.getName; + assert.strictEqual(getName(), 'name: moe', 'flattens arguments into a single list'); }); - test("memoize", function() { + QUnit.test('memoize', function(assert) { var fib = function(n) { return n < 2 ? n : fib(n - 1) + fib(n - 2); }; - equal(fib(10), 55, 'a memoized version of fibonacci produces identical results'); + assert.strictEqual(fib(10), 55, 'a memoized version of fibonacci produces identical results'); fib = _.memoize(fib); // Redefine `fib` for memoization - equal(fib(10), 55, 'a memoized version of fibonacci produces identical results'); + assert.strictEqual(fib(10), 55, 'a memoized version of fibonacci produces identical results'); var o = function(str) { return str; }; var fastO = _.memoize(o); - equal(o('toString'), 'toString', 'checks hasOwnProperty'); - equal(fastO('toString'), 'toString', 'checks hasOwnProperty'); + assert.strictEqual(o('toString'), 'toString', 'checks hasOwnProperty'); + assert.strictEqual(fastO('toString'), 'toString', 'checks hasOwnProperty'); + + // Expose the cache. + var upper = _.memoize(function(s) { + return s.toUpperCase(); + }); + assert.strictEqual(upper('foo'), 'FOO'); + assert.strictEqual(upper('bar'), 'BAR'); + assert.deepEqual(upper.cache, {foo: 'FOO', bar: 'BAR'}); + upper.cache = {foo: 'BAR', bar: 'FOO'}; + assert.strictEqual(upper('foo'), 'BAR'); + assert.strictEqual(upper('bar'), 'FOO'); + + var hashed = _.memoize(function(key) { + //https://github.com/jashkenas/underscore/pull/1679#discussion_r13736209 + assert.ok(/[a-z]+/.test(key), 'hasher doesn\'t change keys'); + return key; + }, function(key) { + return key.toUpperCase(); + }); + hashed('yep'); + assert.deepEqual(hashed.cache, {YEP: 'yep'}, 'takes a hasher'); + + // Test that the hash function can be used to swizzle the key. + var objCacher = _.memoize(function(value, key) { + return {key: key, value: value}; + }, function(value, key) { + return key; + }); + var myObj = objCacher('a', 'alpha'); + var myObjAlias = objCacher('b', 'alpha'); + assert.notStrictEqual(myObj, void 0, 'object is created if second argument used as key'); + assert.strictEqual(myObj, myObjAlias, 'object is cached if second argument used as key'); + assert.strictEqual(myObj.value, 'a', 'object is not modified if second argument used as key'); }); - asyncTest("delay", 2, function() { + QUnit.test('delay', function(assert) { + assert.expect(2); + var done = assert.async(); var delayed = false; _.delay(function(){ delayed = true; }, 100); - setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); - setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150); + setTimeout(function(){ assert.notOk(delayed, "didn't delay the function quite yet"); }, 50); + setTimeout(function(){ assert.ok(delayed, 'delayed the function'); done(); }, 150); }); - asyncTest("defer", 1, function() { + QUnit.test('defer', function(assert) { + assert.expect(1); + var done = assert.async(); var deferred = false; _.defer(function(bool){ deferred = bool; }, true); - _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); + _.delay(function(){ assert.ok(deferred, 'deferred the function'); done(); }, 50); }); - asyncTest("throttle", 2, function() { + QUnit.test('throttle', function(assert) { + assert.expect(2); + var done = assert.async(); var counter = 0; var incr = function(){ counter++; }; var throttledIncr = _.throttle(incr, 32); throttledIncr(); throttledIncr(); - equal(counter, 1, "incr was called immediately"); - _.delay(function(){ equal(counter, 2, "incr was throttled"); start(); }, 64); + assert.strictEqual(counter, 1, 'incr was called immediately'); + _.delay(function(){ assert.strictEqual(counter, 2, 'incr was throttled'); done(); }, 64); }); - asyncTest("throttle arguments", 2, function() { + QUnit.test('throttle arguments', function(assert) { + assert.expect(2); + var done = assert.async(); var value = 0; var update = function(val){ value = val; }; var throttledUpdate = _.throttle(update, 32); throttledUpdate(1); throttledUpdate(2); _.delay(function(){ throttledUpdate(3); }, 64); - equal(value, 1, "updated to latest value"); - _.delay(function(){ equal(value, 3, "updated to latest value"); start(); }, 96); + assert.strictEqual(value, 1, 'updated to latest value'); + _.delay(function(){ assert.strictEqual(value, 3, 'updated to latest value'); done(); }, 96); }); - asyncTest("throttle once", 2, function() { + QUnit.test('throttle once', function(assert) { + assert.expect(2); + var done = assert.async(); var counter = 0; var incr = function(){ return ++counter; }; var throttledIncr = _.throttle(incr, 32); var result = throttledIncr(); _.delay(function(){ - equal(result, 1, "throttled functions return their value"); - equal(counter, 1, "incr was called once"); start(); + assert.strictEqual(result, 1, 'throttled functions return their value'); + assert.strictEqual(counter, 1, 'incr was called once'); done(); }, 64); }); - asyncTest("throttle twice", 1, function() { + QUnit.test('throttle twice', function(assert) { + assert.expect(1); + var done = assert.async(); var counter = 0; var incr = function(){ counter++; }; var throttledIncr = _.throttle(incr, 32); throttledIncr(); throttledIncr(); - _.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 64); + _.delay(function(){ assert.strictEqual(counter, 2, 'incr was called twice'); done(); }, 64); }); - asyncTest("more throttling", 3, function() { + QUnit.test('more throttling', function(assert) { + assert.expect(3); + var done = assert.async(); var counter = 0; var incr = function(){ counter++; }; var throttledIncr = _.throttle(incr, 30); throttledIncr(); throttledIncr(); - ok(counter == 1); + assert.strictEqual(counter, 1); _.delay(function(){ - ok(counter == 2); + assert.strictEqual(counter, 2); throttledIncr(); - ok(counter == 3); - start(); + assert.strictEqual(counter, 3); + done(); }, 85); }); - asyncTest("throttle repeatedly with results", 6, function() { + QUnit.test('throttle repeatedly with results', function(assert) { + assert.expect(6); + var done = assert.async(); var counter = 0; var incr = function(){ return ++counter; }; var throttledIncr = _.throttle(incr, 100); @@ -168,50 +271,56 @@ $(document).ready(function() { _.delay(saveResult, 160); _.delay(saveResult, 230); _.delay(function() { - equal(results[0], 1, "incr was called once"); - equal(results[1], 1, "incr was throttled"); - equal(results[2], 1, "incr was throttled"); - equal(results[3], 2, "incr was called twice"); - equal(results[4], 2, "incr was throttled"); - equal(results[5], 3, "incr was called trailing"); - start(); + assert.strictEqual(results[0], 1, 'incr was called once'); + assert.strictEqual(results[1], 1, 'incr was throttled'); + assert.strictEqual(results[2], 1, 'incr was throttled'); + assert.strictEqual(results[3], 2, 'incr was called twice'); + assert.strictEqual(results[4], 2, 'incr was throttled'); + assert.strictEqual(results[5], 3, 'incr was called trailing'); + done(); }, 300); }); - asyncTest("throttle triggers trailing call when invoked repeatedly", 2, function() { + QUnit.test('throttle triggers trailing call when invoked repeatedly', function(assert) { + assert.expect(2); + var done = assert.async(); var counter = 0; var limit = 48; var incr = function(){ counter++; }; var throttledIncr = _.throttle(incr, 32); var stamp = new Date; - while ((new Date - stamp) < limit) { + while (new Date - stamp < limit) { throttledIncr(); } var lastCount = counter; - ok(counter > 1); + assert.ok(counter > 1); _.delay(function() { - ok(counter > lastCount); - start(); + assert.ok(counter > lastCount); + done(); }, 96); }); - asyncTest("throttle does not trigger leading call when leading is set to false", 2, function() { + QUnit.test('throttle does not trigger leading call when leading is set to false', function(assert) { + assert.expect(2); + var done = assert.async(); var counter = 0; var incr = function(){ counter++; }; var throttledIncr = _.throttle(incr, 60, {leading: false}); throttledIncr(); throttledIncr(); - ok(counter === 0); + assert.strictEqual(counter, 0); _.delay(function() { - ok(counter == 1); - start(); + assert.strictEqual(counter, 1); + done(); }, 96); }); - asyncTest("more throttle does not trigger leading call when leading is set to false", 3, function() { + QUnit.test('more throttle does not trigger leading call when leading is set to false', function(assert) { + assert.expect(3); + var done = assert.async(); var counter = 0; var incr = function(){ counter++; }; var throttledIncr = _.throttle(incr, 100, {leading: false}); @@ -220,133 +329,325 @@ $(document).ready(function() { _.delay(throttledIncr, 50); _.delay(throttledIncr, 60); _.delay(throttledIncr, 200); - ok(counter === 0); + assert.strictEqual(counter, 0); _.delay(function() { - ok(counter == 1); + assert.strictEqual(counter, 1); }, 250); _.delay(function() { - ok(counter == 2); - start(); + assert.strictEqual(counter, 2); + done(); }, 350); }); - asyncTest("one more throttle with leading: false test", 2, function() { + QUnit.test('one more throttle with leading: false test', function(assert) { + assert.expect(2); + var done = assert.async(); var counter = 0; var incr = function(){ counter++; }; var throttledIncr = _.throttle(incr, 100, {leading: false}); var time = new Date; while (new Date - time < 350) throttledIncr(); - ok(counter <= 3); + assert.ok(counter <= 3); _.delay(function() { - ok(counter <= 4); - start(); + assert.ok(counter <= 4); + done(); }, 200); }); - asyncTest("throttle does not trigger trailing call when trailing is set to false", 4, function() { + QUnit.test('throttle does not trigger trailing call when trailing is set to false', function(assert) { + assert.expect(4); + var done = assert.async(); var counter = 0; var incr = function(){ counter++; }; var throttledIncr = _.throttle(incr, 60, {trailing: false}); throttledIncr(); throttledIncr(); throttledIncr(); - ok(counter === 1); + assert.strictEqual(counter, 1); _.delay(function() { - ok(counter == 1); + assert.strictEqual(counter, 1); throttledIncr(); throttledIncr(); - ok(counter == 2); + assert.strictEqual(counter, 2); _.delay(function() { - ok(counter == 2); - start(); + assert.strictEqual(counter, 2); + done(); }, 96); }, 96); }); - asyncTest("debounce", 1, function() { + QUnit.test('throttle continues to function after system time is set backwards', function(assert) { + assert.expect(2); + var done = assert.async(); + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + var origNowFunc = _.now; + + throttledIncr(); + assert.strictEqual(counter, 1); + _.now = function() { + return new Date(2013, 0, 1, 1, 1, 1); + }; + + _.delay(function() { + throttledIncr(); + assert.strictEqual(counter, 2); + done(); + _.now = origNowFunc; + }, 200); + }); + + QUnit.test('throttle re-entrant', function(assert) { + assert.expect(2); + var done = assert.async(); + var sequence = [ + ['b1', 'b2'], + ['c1', 'c2'] + ]; + var value = ''; + var throttledAppend; + var append = function(arg){ + value += this + arg; + var args = sequence.pop(); + if (args) { + throttledAppend.call(args[0], args[1]); + } + }; + throttledAppend = _.throttle(append, 32); + throttledAppend.call('a1', 'a2'); + assert.strictEqual(value, 'a1a2'); + _.delay(function(){ + assert.strictEqual(value, 'a1a2c1c2b1b2', 'append was throttled successfully'); + done(); + }, 100); + }); + + QUnit.test('throttle cancel', function(assert) { + var done = assert.async(); + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 32); + throttledIncr(); + throttledIncr.cancel(); + throttledIncr(); + throttledIncr(); + + assert.strictEqual(counter, 2, 'incr was called immediately'); + _.delay(function(){ assert.strictEqual(counter, 3, 'incr was throttled'); done(); }, 64); + }); + + QUnit.test('throttle cancel with leading: false', function(assert) { + var done = assert.async(); + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 32, {leading: false}); + throttledIncr(); + throttledIncr.cancel(); + + assert.strictEqual(counter, 0, 'incr was throttled'); + _.delay(function(){ assert.strictEqual(counter, 0, 'incr was throttled'); done(); }, 64); + }); + + QUnit.test('debounce', function(assert) { + assert.expect(1); + var done = assert.async(); var counter = 0; var incr = function(){ counter++; }; var debouncedIncr = _.debounce(incr, 32); debouncedIncr(); debouncedIncr(); _.delay(debouncedIncr, 16); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 96); + _.delay(function(){ assert.strictEqual(counter, 1, 'incr was debounced'); done(); }, 96); }); - asyncTest("debounce asap", 4, function() { - var a, b; + QUnit.test('debounce cancel', function(assert) { + assert.expect(1); + var done = assert.async(); + var counter = 0; + var incr = function(){ counter++; }; + var debouncedIncr = _.debounce(incr, 32); + debouncedIncr(); + debouncedIncr.cancel(); + _.delay(function(){ assert.strictEqual(counter, 0, 'incr was not called'); done(); }, 96); + }); + + QUnit.test('debounce asap', function(assert) { + assert.expect(6); + var done = assert.async(); + var a, b, c; var counter = 0; var incr = function(){ return ++counter; }; var debouncedIncr = _.debounce(incr, 64, true); a = debouncedIncr(); b = debouncedIncr(); - equal(a, 1); - equal(b, 1); - equal(counter, 1, 'incr was called immediately'); + assert.strictEqual(a, 1); + assert.strictEqual(b, 1); + assert.strictEqual(counter, 1, 'incr was called immediately'); _.delay(debouncedIncr, 16); _.delay(debouncedIncr, 32); _.delay(debouncedIncr, 48); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 128); + _.delay(function(){ + assert.strictEqual(counter, 1, 'incr was debounced'); + c = debouncedIncr(); + assert.strictEqual(c, 2); + assert.strictEqual(counter, 2, 'incr was called again'); + done(); + }, 128); }); - asyncTest("debounce asap recursively", 2, function() { + QUnit.test('debounce asap cancel', function(assert) { + assert.expect(4); + var done = assert.async(); + var a, b; + var counter = 0; + var incr = function(){ return ++counter; }; + var debouncedIncr = _.debounce(incr, 64, true); + a = debouncedIncr(); + debouncedIncr.cancel(); + b = debouncedIncr(); + assert.strictEqual(a, 1); + assert.strictEqual(b, 2); + assert.strictEqual(counter, 2, 'incr was called immediately'); + _.delay(debouncedIncr, 16); + _.delay(debouncedIncr, 32); + _.delay(debouncedIncr, 48); + _.delay(function(){ assert.strictEqual(counter, 2, 'incr was debounced'); done(); }, 128); + }); + + QUnit.test('debounce asap recursively', function(assert) { + assert.expect(2); + var done = assert.async(); var counter = 0; var debouncedIncr = _.debounce(function(){ counter++; if (counter < 10) debouncedIncr(); }, 32, true); debouncedIncr(); - equal(counter, 1, "incr was called immediately"); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 96); + assert.strictEqual(counter, 1, 'incr was called immediately'); + _.delay(function(){ assert.strictEqual(counter, 1, 'incr was debounced'); done(); }, 96); }); - test("once", function() { + QUnit.test('debounce after system time is set backwards', function(assert) { + assert.expect(2); + var done = assert.async(); + var counter = 0; + var origNowFunc = _.now; + var debouncedIncr = _.debounce(function(){ + counter++; + }, 100, true); + + debouncedIncr(); + assert.strictEqual(counter, 1, 'incr was called immediately'); + + _.now = function() { + return new Date(2013, 0, 1, 1, 1, 1); + }; + + _.delay(function() { + debouncedIncr(); + assert.strictEqual(counter, 2, 'incr was debounced successfully'); + done(); + _.now = origNowFunc; + }, 200); + }); + + QUnit.test('debounce re-entrant', function(assert) { + assert.expect(2); + var done = assert.async(); + var sequence = [ + ['b1', 'b2'] + ]; + var value = ''; + var debouncedAppend; + var append = function(arg){ + value += this + arg; + var args = sequence.pop(); + if (args) { + debouncedAppend.call(args[0], args[1]); + } + }; + debouncedAppend = _.debounce(append, 32); + debouncedAppend.call('a1', 'a2'); + assert.strictEqual(value, ''); + _.delay(function(){ + assert.strictEqual(value, 'a1a2b1b2', 'append was debounced successfully'); + done(); + }, 100); + }); + + QUnit.test('once', function(assert) { var num = 0; - var increment = _.once(function(){ num++; }); + var increment = _.once(function(){ return ++num; }); increment(); increment(); - equal(num, 1); + assert.strictEqual(num, 1); + + assert.strictEqual(increment(), 1, 'stores a memo to the last value'); }); - test("Recursive onced function.", 1, function() { + QUnit.test('Recursive onced function.', function(assert) { + assert.expect(1); var f = _.once(function(){ - ok(true); + assert.ok(true); f(); }); f(); }); - test("wrap", function() { - var greet = function(name){ return "hi: " + name; }; + QUnit.test('wrap', function(assert) { + var greet = function(name){ return 'hi: ' + name; }; var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); - equal(backwards('moe'), 'hi: moe eom', 'wrapped the salutation function'); + assert.strictEqual(backwards('moe'), 'hi: moe eom', 'wrapped the salutation function'); - var inner = function(){ return "Hello "; }; - var obj = {name : "Moe"}; - obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); - equal(obj.hi(), "Hello Moe"); + var inner = function(){ return 'Hello '; }; + var obj = {name: 'Moe'}; + obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); + assert.strictEqual(obj.hi(), 'Hello Moe'); - var noop = function(){}; - var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); }); - var ret = wrapped(['whats', 'your'], 'vector', 'victor'); - deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']); + var noop = function(){}; + var wrapped = _.wrap(noop, function(){ return Array.prototype.slice.call(arguments, 0); }); + var ret = wrapped(['whats', 'your'], 'vector', 'victor'); + assert.deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']); }); - test("compose", function() { - var greet = function(name){ return "hi: " + name; }; + QUnit.test('negate', function(assert) { + var isOdd = function(n){ return n & 1; }; + assert.strictEqual(_.negate(isOdd)(2), true, 'should return the complement of the given function'); + assert.strictEqual(_.negate(isOdd)(3), false, 'should return the complement of the given function'); + }); + + QUnit.test('compose', function(assert) { + var greet = function(name){ return 'hi: ' + name; }; var exclaim = function(sentence){ return sentence + '!'; }; var composed = _.compose(exclaim, greet); - equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); + assert.strictEqual(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); composed = _.compose(greet, exclaim); - equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); + assert.strictEqual(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); + + // f(g(h(x, y, z))) + function h(x, y, z) { + assert.strictEqual(arguments.length, 3, 'First function called with multiple args'); + return z * y; + } + function g(x) { + assert.strictEqual(arguments.length, 1, 'Composed function is called with 1 argument'); + return x; + } + function f(x) { + assert.strictEqual(arguments.length, 1, 'Composed function is called with 1 argument'); + return x * 2; + } + composed = _.compose(f, g, h); + assert.strictEqual(composed(1, 2, 3), 12); }); - test("after", function() { + QUnit.test('after', function(assert) { var testAfter = function(afterAmount, timesCalled) { var afterCalled = 0; var after = _.after(afterAmount, function() { @@ -356,10 +657,114 @@ $(document).ready(function() { return afterCalled; }; - equal(testAfter(5, 5), 1, "after(N) should fire after being called N times"); - equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); - equal(testAfter(0, 0), 0, "after(0) should not fire immediately"); - equal(testAfter(0, 1), 1, "after(0) should fire when first invoked"); + assert.strictEqual(testAfter(5, 5), 1, 'after(N) should fire after being called N times'); + assert.strictEqual(testAfter(5, 4), 0, 'after(N) should not fire unless called N times'); + assert.strictEqual(testAfter(0, 0), 0, 'after(0) should not fire immediately'); + assert.strictEqual(testAfter(0, 1), 1, 'after(0) should fire when first invoked'); }); -}); + QUnit.test('before', function(assert) { + var testBefore = function(beforeAmount, timesCalled) { + var beforeCalled = 0; + var before = _.before(beforeAmount, function() { beforeCalled++; }); + while (timesCalled--) before(); + return beforeCalled; + }; + + assert.strictEqual(testBefore(5, 5), 4, 'before(N) should not fire after being called N times'); + assert.strictEqual(testBefore(5, 4), 4, 'before(N) should fire before being called N times'); + assert.strictEqual(testBefore(0, 0), 0, 'before(0) should not fire immediately'); + assert.strictEqual(testBefore(0, 1), 0, 'before(0) should not fire when first invoked'); + + var context = {num: 0}; + var increment = _.before(3, function(){ return ++this.num; }); + _.times(10, increment, context); + assert.strictEqual(increment(), 2, 'stores a memo to the last value'); + assert.strictEqual(context.num, 2, 'provides context'); + }); + + QUnit.test('iteratee', function(assert) { + var identity = _.iteratee(); + assert.strictEqual(identity, _.identity, '_.iteratee is exposed as an external function.'); + + function fn() { + return arguments; + } + _.each([_.iteratee(fn), _.iteratee(fn, {})], function(cb) { + assert.strictEqual(cb().length, 0); + assert.deepEqual(_.toArray(cb(1, 2, 3)), _.range(1, 4)); + assert.deepEqual(_.toArray(cb(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), _.range(1, 11)); + }); + + var deepProperty = _.iteratee(['a', 'b']); + assert.strictEqual(deepProperty({a: {b: 2}}), 2, 'treats an array as a deep property accessor'); + + // Test custom iteratee + var builtinIteratee = _.iteratee; + _.iteratee = function(value) { + // RegEx values return a function that returns the number of matches + if (_.isRegExp(value)) return function(obj) { + return (obj.match(value) || []).length; + }; + return value; + }; + + var collection = ['foo', 'bar', 'bbiz']; + + // Test all methods that claim to be transformed through `_.iteratee` + assert.deepEqual(_.countBy(collection, /b/g), {0: 1, 1: 1, 2: 1}); + assert.strictEqual(_.every(collection, /b/g), false); + assert.deepEqual(_.filter(collection, /b/g), ['bar', 'bbiz']); + assert.strictEqual(_.find(collection, /b/g), 'bar'); + assert.strictEqual(_.findIndex(collection, /b/g), 1); + assert.strictEqual(_.findKey(collection, /b/g), '1'); + assert.strictEqual(_.findLastIndex(collection, /b/g), 2); + assert.deepEqual(_.groupBy(collection, /b/g), {0: ['foo'], 1: ['bar'], 2: ['bbiz']}); + assert.deepEqual(_.indexBy(collection, /b/g), {0: 'foo', 1: 'bar', 2: 'bbiz'}); + assert.deepEqual(_.map(collection, /b/g), [0, 1, 2]); + assert.strictEqual(_.max(collection, /b/g), 'bbiz'); + assert.strictEqual(_.min(collection, /b/g), 'foo'); + assert.deepEqual(_.partition(collection, /b/g), [['bar', 'bbiz'], ['foo']]); + assert.deepEqual(_.reject(collection, /b/g), ['foo']); + assert.strictEqual(_.some(collection, /b/g), true); + assert.deepEqual(_.sortBy(collection, /b/g), ['foo', 'bar', 'bbiz']); + assert.strictEqual(_.sortedIndex(collection, 'blah', /b/g), 1); + assert.deepEqual(_.uniq(collection, /b/g), ['foo', 'bar', 'bbiz']); + + var objCollection = {a: 'foo', b: 'bar', c: 'bbiz'}; + assert.deepEqual(_.mapObject(objCollection, /b/g), {a: 0, b: 1, c: 2}); + + // Restore the builtin iteratee + _.iteratee = builtinIteratee; + }); + + QUnit.test('restArgs', function(assert) { + assert.expect(10); + _.restArgs(function(a, args) { + assert.strictEqual(a, 1); + assert.deepEqual(args, [2, 3], 'collects rest arguments into an array'); + })(1, 2, 3); + + _.restArgs(function(a, args) { + assert.strictEqual(a, void 0); + assert.deepEqual(args, [], 'passes empty array if there are not enough arguments'); + })(); + + _.restArgs(function(a, b, c, args) { + assert.strictEqual(arguments.length, 4); + assert.deepEqual(args, [4, 5], 'works on functions with many named parameters'); + })(1, 2, 3, 4, 5); + + var obj = {}; + _.restArgs(function() { + assert.strictEqual(this, obj, 'invokes function with this context'); + }).call(obj); + + _.restArgs(function(array, iteratee, context) { + assert.deepEqual(array, [1, 2, 3, 4], 'startIndex can be used manually specify index of rest parameter'); + assert.strictEqual(iteratee, void 0); + assert.strictEqual(context, void 0); + }, 0)(1, 2, 3, 4); + }); + +}()); diff --git a/vendor/underscore/test/index.html b/vendor/underscore/test/index.html index ea7a13603..ab523afe4 100644 --- a/vendor/underscore/test/index.html +++ b/vendor/underscore/test/index.html @@ -3,42 +3,21 @@ Underscore Test Suite - + + + +
    + - + - + + - - - -
    -
    -
    -
    -
    -
    -
    -
    -

    Underscore Speed Suite

    -

    - A representative sample of the functions are benchmarked here, to provide - a sense of how fast they might run in different browsers. - Each iteration runs on an array of 1000 elements.

    - For example, the 'intersection' test measures the number of times you can - find the intersection of two thousand-element arrays in one second. -

    -
    - diff --git a/vendor/underscore/test/objects.js b/vendor/underscore/test/objects.js index 492171e06..1abdce21f 100644 --- a/vendor/underscore/test/objects.js +++ b/vendor/underscore/test/objects.js @@ -1,135 +1,318 @@ -$(document).ready(function() { +(function() { + var _ = typeof require == 'function' ? require('..') : window._; - module("Objects"); + QUnit.module('Objects'); - test("keys", function() { - equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); + var testElement = typeof document === 'object' ? document.createElement('div') : void 0; + + QUnit.test('keys', function(assert) { + assert.deepEqual(_.keys({one: 1, two: 2}), ['one', 'two'], 'can extract the keys from an object'); // the test above is not safe because it relies on for-in enumeration order var a = []; a[1] = 0; - equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); - raises(function() { _.keys(null); }, TypeError, 'throws an error for `null` values'); - raises(function() { _.keys(void 0); }, TypeError, 'throws an error for `undefined` values'); - raises(function() { _.keys(1); }, TypeError, 'throws an error for number primitives'); - raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives'); - raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives'); + assert.deepEqual(_.keys(a), ['1'], 'is not fooled by sparse arrays; see issue #95'); + assert.deepEqual(_.keys(null), []); + assert.deepEqual(_.keys(void 0), []); + assert.deepEqual(_.keys(1), []); + assert.deepEqual(_.keys('a'), []); + assert.deepEqual(_.keys(true), []); + + // keys that may be missed if the implementation isn't careful + var trouble = { + constructor: Object, + valueOf: _.noop, + hasOwnProperty: null, + toString: 5, + toLocaleString: void 0, + propertyIsEnumerable: /a/, + isPrototypeOf: this, + __defineGetter__: Boolean, + __defineSetter__: {}, + __lookupSetter__: false, + __lookupGetter__: [] + }; + var troubleKeys = ['constructor', 'valueOf', 'hasOwnProperty', 'toString', 'toLocaleString', 'propertyIsEnumerable', + 'isPrototypeOf', '__defineGetter__', '__defineSetter__', '__lookupSetter__', '__lookupGetter__'].sort(); + assert.deepEqual(_.keys(trouble).sort(), troubleKeys, 'matches non-enumerable properties'); }); - test("values", function() { - equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object'); - equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"'); + QUnit.test('allKeys', function(assert) { + assert.deepEqual(_.allKeys({one: 1, two: 2}), ['one', 'two'], 'can extract the allKeys from an object'); + // the test above is not safe because it relies on for-in enumeration order + var a = []; a[1] = 0; + assert.deepEqual(_.allKeys(a), ['1'], 'is not fooled by sparse arrays; see issue #95'); + + a.a = a; + assert.deepEqual(_.allKeys(a), ['1', 'a'], 'is not fooled by sparse arrays with additional properties'); + + _.each([null, void 0, 1, 'a', true, NaN, {}, [], new Number(5), new Date(0)], function(val) { + assert.deepEqual(_.allKeys(val), []); + }); + + // allKeys that may be missed if the implementation isn't careful + var trouble = { + constructor: Object, + valueOf: _.noop, + hasOwnProperty: null, + toString: 5, + toLocaleString: void 0, + propertyIsEnumerable: /a/, + isPrototypeOf: this + }; + var troubleKeys = ['constructor', 'valueOf', 'hasOwnProperty', 'toString', 'toLocaleString', 'propertyIsEnumerable', + 'isPrototypeOf'].sort(); + assert.deepEqual(_.allKeys(trouble).sort(), troubleKeys, 'matches non-enumerable properties'); + + function A() {} + A.prototype.foo = 'foo'; + var b = new A(); + b.bar = 'bar'; + assert.deepEqual(_.allKeys(b).sort(), ['bar', 'foo'], 'should include inherited keys'); + + function y() {} + y.x = 'z'; + assert.deepEqual(_.allKeys(y), ['x'], 'should get keys from constructor'); }); - test("pairs", function() { - deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs'); - deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"'); + QUnit.test('values', function(assert) { + assert.deepEqual(_.values({one: 1, two: 2}), [1, 2], 'can extract the values from an object'); + assert.deepEqual(_.values({one: 1, two: 2, length: 3}), [1, 2, 3], '... even when one of them is "length"'); }); - test("invert", function() { + QUnit.test('pairs', function(assert) { + assert.deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs'); + assert.deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"'); + }); + + QUnit.test('invert', function(assert) { var obj = {first: 'Moe', second: 'Larry', third: 'Curly'}; - equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object'); - ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started'); + assert.deepEqual(_.keys(_.invert(obj)), ['Moe', 'Larry', 'Curly'], 'can invert an object'); + assert.deepEqual(_.invert(_.invert(obj)), obj, 'two inverts gets you back where you started'); - var obj = {length: 3}; - ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"') + obj = {length: 3}; + assert.strictEqual(_.invert(obj)['3'], 'length', 'can invert an object with "length"'); }); - test("functions", function() { - var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; - ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); + QUnit.test('functions', function(assert) { + var obj = {a: 'dash', b: _.map, c: /yo/, d: _.reduce}; + assert.deepEqual(['b', 'd'], _.functions(obj), 'can grab the function names of any passed-in object'); var Animal = function(){}; Animal.prototype.run = function(){}; - equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype'); + assert.deepEqual(_.functions(new Animal), ['run'], 'also looks up functions on the prototype'); }); - test("extend", function() { + QUnit.test('methods', function(assert) { + assert.strictEqual(_.methods, _.functions, 'is an alias for functions'); + }); + + QUnit.test('extend', function(assert) { var result; - equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); - equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); - equal(_.extend({x:'x'}, {a:'b'}).x, 'x', "properties not in source don't get overriden"); - result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); - ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); - result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); - ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); + assert.strictEqual(_.extend({}, {a: 'b'}).a, 'b', 'can extend an object with the attributes of another'); + assert.strictEqual(_.extend({a: 'x'}, {a: 'b'}).a, 'b', 'properties in source override destination'); + assert.strictEqual(_.extend({x: 'x'}, {a: 'b'}).x, 'x', "properties not in source don't get overridden"); + result = _.extend({x: 'x'}, {a: 'a'}, {b: 'b'}); + assert.deepEqual(result, {x: 'x', a: 'a', b: 'b'}, 'can extend from multiple source objects'); + result = _.extend({x: 'x'}, {a: 'a', x: 2}, {a: 'b'}); + assert.deepEqual(result, {x: 2, a: 'b'}, 'extending from multiple source objects last property trumps'); result = _.extend({}, {a: void 0, b: null}); - equal(_.keys(result).join(''), 'ab', 'extend copies undefined values'); + assert.deepEqual(_.keys(result), ['a', 'b'], 'extend copies undefined values'); + + var F = function() {}; + F.prototype = {a: 'b'}; + var subObj = new F(); + subObj.c = 'd'; + assert.deepEqual(_.extend({}, subObj), {a: 'b', c: 'd'}, 'extend copies all properties from source'); + _.extend(subObj, {}); + assert.notOk(subObj.hasOwnProperty('a'), "extend does not convert destination object's 'in' properties to 'own' properties"); try { result = {}; - _.extend(result, null, undefined, {a:1}); - } catch(ex) {} + _.extend(result, null, void 0, {a: 1}); + } catch (e) { /* ignored */ } - equal(result.a, 1, 'should not error on `null` or `undefined` sources'); + assert.strictEqual(result.a, 1, 'should not error on `null` or `undefined` sources'); + + assert.strictEqual(_.extend(null, {a: 1}), null, 'extending null results in null'); + assert.strictEqual(_.extend(void 0, {a: 1}), void 0, 'extending undefined results in undefined'); }); - test("pick", function() { + QUnit.test('extendOwn', function(assert) { var result; - result = _.pick({a:1, b:2, c:3}, 'a', 'c'); - ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named'); - result = _.pick({a:1, b:2, c:3}, ['b', 'c']); - ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array'); - result = _.pick({a:1, b:2, c:3}, ['a'], 'b'); - ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args'); + assert.strictEqual(_.extendOwn({}, {a: 'b'}).a, 'b', 'can extend an object with the attributes of another'); + assert.strictEqual(_.extendOwn({a: 'x'}, {a: 'b'}).a, 'b', 'properties in source override destination'); + assert.strictEqual(_.extendOwn({x: 'x'}, {a: 'b'}).x, 'x', "properties not in source don't get overridden"); + result = _.extendOwn({x: 'x'}, {a: 'a'}, {b: 'b'}); + assert.deepEqual(result, {x: 'x', a: 'a', b: 'b'}, 'can extend from multiple source objects'); + result = _.extendOwn({x: 'x'}, {a: 'a', x: 2}, {a: 'b'}); + assert.deepEqual(result, {x: 2, a: 'b'}, 'extending from multiple source objects last property trumps'); + assert.deepEqual(_.extendOwn({}, {a: void 0, b: null}), {a: void 0, b: null}, 'copies undefined values'); + + var F = function() {}; + F.prototype = {a: 'b'}; + var subObj = new F(); + subObj.c = 'd'; + assert.deepEqual(_.extendOwn({}, subObj), {c: 'd'}, 'copies own properties from source'); + + result = {}; + assert.deepEqual(_.extendOwn(result, null, void 0, {a: 1}), {a: 1}, 'should not error on `null` or `undefined` sources'); + + _.each(['a', 5, null, false], function(val) { + assert.strictEqual(_.extendOwn(val, {a: 1}), val, 'extending non-objects results in returning the non-object value'); + }); + + assert.strictEqual(_.extendOwn(void 0, {a: 1}), void 0, 'extending undefined results in undefined'); + + result = _.extendOwn({a: 1, 0: 2, 1: '5', length: 6}, {0: 1, 1: 2, length: 2}); + assert.deepEqual(result, {a: 1, 0: 1, 1: 2, length: 2}, 'should treat array-like objects like normal objects'); + }); + + QUnit.test('assign', function(assert) { + assert.strictEqual(_.assign, _.extendOwn, 'is an alias for extendOwn'); + }); + + QUnit.test('pick', function(assert) { + var result; + result = _.pick({a: 1, b: 2, c: 3}, 'a', 'c'); + assert.deepEqual(result, {a: 1, c: 3}, 'can restrict properties to those named'); + result = _.pick({a: 1, b: 2, c: 3}, ['b', 'c']); + assert.deepEqual(result, {b: 2, c: 3}, 'can restrict properties to those named in an array'); + result = _.pick({a: 1, b: 2, c: 3}, ['a'], 'b'); + assert.deepEqual(result, {a: 1, b: 2}, 'can restrict properties to those named in mixed args'); + result = _.pick(['a', 'b'], 1); + assert.deepEqual(result, {1: 'b'}, 'can pick numeric properties'); + + _.each([null, void 0], function(val) { + assert.deepEqual(_.pick(val, 'hasOwnProperty'), {}, 'Called with null/undefined'); + assert.deepEqual(_.pick(val, _.constant(true)), {}); + }); + assert.deepEqual(_.pick(5, 'toString', 'b'), {toString: Number.prototype.toString}, 'can iterate primitives'); + + var data = {a: 1, b: 2, c: 3}; + var callback = function(value, key, object) { + assert.strictEqual(key, {1: 'a', 2: 'b', 3: 'c'}[value]); + assert.strictEqual(object, data); + return value !== this.value; + }; + result = _.pick(data, callback, {value: 2}); + assert.deepEqual(result, {a: 1, c: 3}, 'can accept a predicate and context'); var Obj = function(){}; Obj.prototype = {a: 1, b: 2, c: 3}; - ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props'); + var instance = new Obj(); + assert.deepEqual(_.pick(instance, 'a', 'c'), {a: 1, c: 3}, 'include prototype props'); + + assert.deepEqual(_.pick(data, function(val, key) { + return this[key] === 3 && this === instance; + }, instance), {c: 3}, 'function is given context'); + + assert.notOk(_.has(_.pick({}, 'foo'), 'foo'), 'does not set own property if property not in object'); + _.pick(data, function(value, key, obj) { + assert.strictEqual(obj, data, 'passes same object as third parameter of iteratee'); + }); }); - test("omit", function() { + QUnit.test('omit', function(assert) { var result; - result = _.omit({a:1, b:2, c:3}, 'b'); - ok(_.isEqual(result, {a:1, c:3}), 'can omit a single named property'); - result = _.omit({a:1, b:2, c:3}, 'a', 'c'); - ok(_.isEqual(result, {b:2}), 'can omit several named properties'); - result = _.omit({a:1, b:2, c:3}, ['b', 'c']); - ok(_.isEqual(result, {a:1}), 'can omit properties named in an array'); + result = _.omit({a: 1, b: 2, c: 3}, 'b'); + assert.deepEqual(result, {a: 1, c: 3}, 'can omit a single named property'); + result = _.omit({a: 1, b: 2, c: 3}, 'a', 'c'); + assert.deepEqual(result, {b: 2}, 'can omit several named properties'); + result = _.omit({a: 1, b: 2, c: 3}, ['b', 'c']); + assert.deepEqual(result, {a: 1}, 'can omit properties named in an array'); + result = _.omit(['a', 'b'], 0); + assert.deepEqual(result, {1: 'b'}, 'can omit numeric properties'); + + assert.deepEqual(_.omit(null, 'a', 'b'), {}, 'non objects return empty object'); + assert.deepEqual(_.omit(void 0, 'toString'), {}, 'null/undefined return empty object'); + assert.deepEqual(_.omit(5, 'toString', 'b'), {}, 'returns empty object for primitives'); + + var data = {a: 1, b: 2, c: 3}; + var callback = function(value, key, object) { + assert.strictEqual(key, {1: 'a', 2: 'b', 3: 'c'}[value]); + assert.strictEqual(object, data); + return value !== this.value; + }; + result = _.omit(data, callback, {value: 2}); + assert.deepEqual(result, {b: 2}, 'can accept a predicate'); var Obj = function(){}; Obj.prototype = {a: 1, b: 2, c: 3}; - ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props'); + var instance = new Obj(); + assert.deepEqual(_.omit(instance, 'b'), {a: 1, c: 3}, 'include prototype props'); + + assert.deepEqual(_.omit(data, function(val, key) { + return this[key] === 3 && this === instance; + }, instance), {a: 1, b: 2}, 'function is given context'); }); - test("defaults", function() { - var result; - var options = {zero: 0, one: 1, empty: "", nan: NaN, nothing: null}; + QUnit.test('defaults', function(assert) { + var options = {zero: 0, one: 1, empty: '', nan: NaN, nothing: null}; _.defaults(options, {zero: 1, one: 10, twenty: 20, nothing: 'str'}); - equal(options.zero, 0, 'value exists'); - equal(options.one, 1, 'value exists'); - equal(options.twenty, 20, 'default applied'); - equal(options.nothing, null, "null isn't overridden"); + assert.strictEqual(options.zero, 0, 'value exists'); + assert.strictEqual(options.one, 1, 'value exists'); + assert.strictEqual(options.twenty, 20, 'default applied'); + assert.strictEqual(options.nothing, null, "null isn't overridden"); - _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); - equal(options.empty, "", 'value exists'); - ok(_.isNaN(options.nan), "NaN isn't overridden"); - equal(options.word, "word", 'new value is added, first one wins'); + _.defaults(options, {empty: 'full'}, {nan: 'nan'}, {word: 'word'}, {word: 'dog'}); + assert.strictEqual(options.empty, '', 'value exists'); + assert.ok(_.isNaN(options.nan), "NaN isn't overridden"); + assert.strictEqual(options.word, 'word', 'new value is added, first one wins'); try { options = {}; - _.defaults(options, null, undefined, {a:1}); - } catch(ex) {} + _.defaults(options, null, void 0, {a: 1}); + } catch (e) { /* ignored */ } - equal(options.a, 1, 'should not error on `null` or `undefined` sources'); + assert.strictEqual(options.a, 1, 'should not error on `null` or `undefined` sources'); + + assert.deepEqual(_.defaults(null, {a: 1}), {a: 1}, 'defaults skips nulls'); + assert.deepEqual(_.defaults(void 0, {a: 1}), {a: 1}, 'defaults skips undefined'); }); - test("clone", function() { - var moe = {name : 'moe', lucky : [13, 27, 34]}; + QUnit.test('clone', function(assert) { + var moe = {name: 'moe', lucky: [13, 27, 34]}; var clone = _.clone(moe); - equal(clone.name, 'moe', 'the clone as the attributes of the original'); + assert.strictEqual(clone.name, 'moe', 'the clone as the attributes of the original'); clone.name = 'curly'; - ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); + assert.ok(clone.name === 'curly' && moe.name === 'moe', 'clones can change shallow attributes without affecting the original'); clone.lucky.push(101); - equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); + assert.strictEqual(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); - equal(_.clone(undefined), void 0, 'non objects should not be changed by clone'); - equal(_.clone(1), 1, 'non objects should not be changed by clone'); - equal(_.clone(null), null, 'non objects should not be changed by clone'); + assert.strictEqual(_.clone(void 0), void 0, 'non objects should not be changed by clone'); + assert.strictEqual(_.clone(1), 1, 'non objects should not be changed by clone'); + assert.strictEqual(_.clone(null), null, 'non objects should not be changed by clone'); }); - test("isEqual", function() { + QUnit.test('create', function(assert) { + var Parent = function() {}; + Parent.prototype = {foo: function() {}, bar: 2}; + + _.each(['foo', null, void 0, 1], function(val) { + assert.deepEqual(_.create(val), {}, 'should return empty object when a non-object is provided'); + }); + + assert.ok(_.create([]) instanceof Array, 'should return new instance of array when array is provided'); + + var Child = function() {}; + Child.prototype = _.create(Parent.prototype); + assert.ok(new Child instanceof Parent, 'object should inherit prototype'); + + var func = function() {}; + Child.prototype = _.create(Parent.prototype, {func: func}); + assert.strictEqual(Child.prototype.func, func, 'properties should be added to object'); + + Child.prototype = _.create(Parent.prototype, {constructor: Child}); + assert.strictEqual(Child.prototype.constructor, Child); + + Child.prototype.foo = 'foo'; + var created = _.create(Child.prototype, new Child); + assert.notOk(created.hasOwnProperty('foo'), 'should only add own properties'); + }); + + QUnit.test('isEqual', function(assert) { function First() { this.value = 1; } @@ -140,133 +323,139 @@ $(document).ready(function() { Second.prototype.value = 2; // Basic equality and identity comparisons. - ok(_.isEqual(null, null), "`null` is equal to `null`"); - ok(_.isEqual(), "`undefined` is equal to `undefined`"); + assert.ok(_.isEqual(null, null), '`null` is equal to `null`'); + assert.ok(_.isEqual(), '`undefined` is equal to `undefined`'); - ok(!_.isEqual(0, -0), "`0` is not equal to `-0`"); - ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`"); - ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`"); - ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`"); + assert.notOk(_.isEqual(0, -0), '`0` is not equal to `-0`'); + assert.notOk(_.isEqual(-0, 0), 'Commutative equality is implemented for `0` and `-0`'); + assert.notOk(_.isEqual(null, void 0), '`null` is not equal to `undefined`'); + assert.notOk(_.isEqual(void 0, null), 'Commutative equality is implemented for `null` and `undefined`'); // String object and primitive comparisons. - ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal"); - ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal"); - ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal"); - ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives"); + assert.ok(_.isEqual('Curly', 'Curly'), 'Identical string primitives are equal'); + assert.ok(_.isEqual(new String('Curly'), new String('Curly')), 'String objects with identical primitive values are equal'); + assert.ok(_.isEqual(new String('Curly'), 'Curly'), 'String primitives and their corresponding object wrappers are equal'); + assert.ok(_.isEqual('Curly', new String('Curly')), 'Commutative equality is implemented for string objects and primitives'); - ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal"); - ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal"); - ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal"); + assert.notOk(_.isEqual('Curly', 'Larry'), 'String primitives with different values are not equal'); + assert.notOk(_.isEqual(new String('Curly'), new String('Larry')), 'String objects with different primitive values are not equal'); + assert.notOk(_.isEqual(new String('Curly'), {toString: function(){ return 'Curly'; }}), 'String objects and objects with a custom `toString` method are not equal'); // Number object and primitive comparisons. - ok(_.isEqual(75, 75), "Identical number primitives are equal"); - ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal"); - ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal"); - ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives"); - ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal"); - ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`"); + assert.ok(_.isEqual(75, 75), 'Identical number primitives are equal'); + assert.ok(_.isEqual(new Number(75), new Number(75)), 'Number objects with identical primitive values are equal'); + assert.ok(_.isEqual(75, new Number(75)), 'Number primitives and their corresponding object wrappers are equal'); + assert.ok(_.isEqual(new Number(75), 75), 'Commutative equality is implemented for number objects and primitives'); + assert.notOk(_.isEqual(new Number(0), -0), '`new Number(0)` and `-0` are not equal'); + assert.notOk(_.isEqual(0, new Number(-0)), 'Commutative equality is implemented for `new Number(0)` and `-0`'); - ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal"); - ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal"); + assert.notOk(_.isEqual(new Number(75), new Number(63)), 'Number objects with different primitive values are not equal'); + assert.notOk(_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), 'Number objects and objects with a `valueOf` method are not equal'); // Comparisons involving `NaN`. - ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`"); - ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`"); - ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`"); - ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`"); + assert.ok(_.isEqual(NaN, NaN), '`NaN` is equal to `NaN`'); + assert.ok(_.isEqual(new Number(NaN), NaN), 'Object(`NaN`) is equal to `NaN`'); + assert.notOk(_.isEqual(61, NaN), 'A number primitive is not equal to `NaN`'); + assert.notOk(_.isEqual(new Number(79), NaN), 'A number object is not equal to `NaN`'); + assert.notOk(_.isEqual(Infinity, NaN), '`Infinity` is not equal to `NaN`'); // Boolean object and primitive comparisons. - ok(_.isEqual(true, true), "Identical boolean primitives are equal"); - ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal"); - ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal"); - ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans"); - ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal"); + assert.ok(_.isEqual(true, true), 'Identical boolean primitives are equal'); + assert.ok(_.isEqual(new Boolean, new Boolean), 'Boolean objects with identical primitive values are equal'); + assert.ok(_.isEqual(true, new Boolean(true)), 'Boolean primitives and their corresponding object wrappers are equal'); + assert.ok(_.isEqual(new Boolean(true), true), 'Commutative equality is implemented for booleans'); + assert.notOk(_.isEqual(new Boolean(true), new Boolean), 'Boolean objects with different primitive values are not equal'); // Common type coercions. - ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`"); - ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal"); - ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal"); - ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values"); - ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal"); - ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal"); - ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal"); - ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal"); - ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal"); + assert.notOk(_.isEqual(new Boolean(false), true), '`new Boolean(false)` is not equal to `true`'); + assert.notOk(_.isEqual('75', 75), 'String and number primitives with like values are not equal'); + assert.notOk(_.isEqual(new Number(63), new String(63)), 'String and number objects with like values are not equal'); + assert.notOk(_.isEqual(75, '75'), 'Commutative equality is implemented for like string and number values'); + assert.notOk(_.isEqual(0, ''), 'Number and string primitives with like values are not equal'); + assert.notOk(_.isEqual(1, true), 'Number and boolean primitives with like values are not equal'); + assert.notOk(_.isEqual(new Boolean(false), new Number(0)), 'Boolean and number objects with like values are not equal'); + assert.notOk(_.isEqual(false, new String('')), 'Boolean primitives and string objects with like values are not equal'); + assert.notOk(_.isEqual(12564504e5, new Date(2009, 9, 25)), 'Dates and their corresponding numeric primitive values are not equal'); // Dates. - ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal"); - ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal"); - ok(!_.isEqual(new Date(2009, 11, 13), { + assert.ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), 'Date objects referencing identical times are equal'); + assert.notOk(_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), 'Date objects referencing different times are not equal'); + assert.notOk(_.isEqual(new Date(2009, 11, 13), { getTime: function(){ return 12606876e5; } - }), "Date objects and objects with a `getTime` method are not equal"); - ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal"); + }), 'Date objects and objects with a `getTime` method are not equal'); + assert.notOk(_.isEqual(new Date('Curly'), new Date('Curly')), 'Invalid dates are not equal'); // Functions. - ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal"); + assert.notOk(_.isEqual(First, Second), 'Different functions with identical bodies and source code representations are not equal'); // RegExps. - ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal"); - ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal"); - ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal"); - ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps"); - ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal"); + assert.ok(_.isEqual(/(?:)/gim, /(?:)/gim), 'RegExps with equivalent patterns and flags are equal'); + assert.ok(_.isEqual(/(?:)/gi, /(?:)/ig), 'Flag order is not significant'); + assert.notOk(_.isEqual(/(?:)/g, /(?:)/gi), 'RegExps with equivalent patterns and different flags are not equal'); + assert.notOk(_.isEqual(/Moe/gim, /Curly/gim), 'RegExps with different patterns and equivalent flags are not equal'); + assert.notOk(_.isEqual(/(?:)/gi, /(?:)/g), 'Commutative equality is implemented for RegExps'); + assert.notOk(_.isEqual(/Curly/g, {source: 'Larry', global: true, ignoreCase: false, multiline: false}), 'RegExps and RegExp-like objects are not equal'); // Empty arrays, array-like objects, and object literals. - ok(_.isEqual({}, {}), "Empty object literals are equal"); - ok(_.isEqual([], []), "Empty array literals are equal"); - ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal"); - ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal."); - ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects"); + assert.ok(_.isEqual({}, {}), 'Empty object literals are equal'); + assert.ok(_.isEqual([], []), 'Empty array literals are equal'); + assert.ok(_.isEqual([{}], [{}]), 'Empty nested arrays and objects are equal'); + assert.notOk(_.isEqual({length: 0}, []), 'Array-like objects and arrays are not equal.'); + assert.notOk(_.isEqual([], {length: 0}), 'Commutative equality is implemented for array-like objects'); - ok(!_.isEqual({}, []), "Object literals and array literals are not equal"); - ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays"); + assert.notOk(_.isEqual({}, []), 'Object literals and array literals are not equal'); + assert.notOk(_.isEqual([], {}), 'Commutative equality is implemented for objects and arrays'); // Arrays with primitive and object values. - ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal"); - ok(_.isEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g), new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal"); + assert.ok(_.isEqual([1, 'Larry', true], [1, 'Larry', true]), 'Arrays containing identical primitives are equal'); + assert.ok(_.isEqual([/Moe/g, new Date(2009, 9, 25)], [/Moe/g, new Date(2009, 9, 25)]), 'Arrays containing equivalent elements are equal'); // Multi-dimensional arrays. - var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; - var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; - ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared"); + var a = [new Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + var b = [new Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + assert.ok(_.isEqual(a, b), 'Arrays containing nested arrays and objects are recursively compared'); // Overwrite the methods defined in ES 5.1 section 15.4.4. a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null; b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null; // Array elements and properties. - ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal"); - a.push("White Rocks"); - ok(!_.isEqual(a, b), "Arrays of different lengths are not equal"); - a.push("East Boulder"); - b.push("Gunbarrel Ranch", "Teller Farm"); - ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal"); + assert.ok(_.isEqual(a, b), 'Arrays containing equivalent elements and different non-numeric properties are equal'); + a.push('White Rocks'); + assert.notOk(_.isEqual(a, b), 'Arrays of different lengths are not equal'); + a.push('East Boulder'); + b.push('Gunbarrel Ranch', 'Teller Farm'); + assert.notOk(_.isEqual(a, b), 'Arrays of identical lengths containing different elements are not equal'); // Sparse arrays. - ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal"); - ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty"); + assert.ok(_.isEqual(Array(3), Array(3)), 'Sparse arrays of identical lengths are equal'); + assert.notOk(_.isEqual(Array(3), Array(6)), 'Sparse arrays of different lengths are not equal when both are empty'); + + var sparse = []; + sparse[1] = 5; + assert.ok(_.isEqual(sparse, [void 0, 5]), 'Handles sparse arrays as dense'); // Simple objects. - ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal"); - ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal"); - ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal"); - ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal"); - ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal"); - ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects"); - ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent"); + assert.ok(_.isEqual({a: 'Curly', b: 1, c: true}, {a: 'Curly', b: 1, c: true}), 'Objects containing identical primitives are equal'); + assert.ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), 'Objects containing equivalent members are equal'); + assert.notOk(_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), 'Objects of identical sizes with different values are not equal'); + assert.notOk(_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), 'Objects of identical sizes with different property names are not equal'); + assert.notOk(_.isEqual({a: 1, b: 2}, {a: 1}), 'Objects of different sizes are not equal'); + assert.notOk(_.isEqual({a: 1}, {a: 1, b: 2}), 'Commutative equality is implemented for objects'); + assert.notOk(_.isEqual({x: 1, y: void 0}, {x: 1, z: 2}), 'Objects with identical keys and different values are not equivalent'); // `A` contains nested objects and arrays. a = { - name: new String("Moe Howard"), + name: new String('Moe Howard'), age: new Number(77), stooge: true, - hobbies: ["acting"], + hobbies: ['acting'], film: { - name: "Sing a Song of Six Pants", + name: 'Sing a Song of Six Pants', release: new Date(1947, 9, 30), - stars: [new String("Larry Fine"), "Shemp Howard"], + stars: [new String('Larry Fine'), 'Shemp Howard'], minutes: new Number(16), seconds: 54 } @@ -274,304 +463,692 @@ $(document).ready(function() { // `B` contains equivalent nested objects and arrays. b = { - name: new String("Moe Howard"), + name: new String('Moe Howard'), age: new Number(77), stooge: true, - hobbies: ["acting"], + hobbies: ['acting'], film: { - name: "Sing a Song of Six Pants", + name: 'Sing a Song of Six Pants', release: new Date(1947, 9, 30), - stars: [new String("Larry Fine"), "Shemp Howard"], + stars: [new String('Larry Fine'), 'Shemp Howard'], minutes: new Number(16), seconds: 54 } }; - ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared"); + assert.ok(_.isEqual(a, b), 'Objects with nested equivalent members are recursively compared'); // Instances. - ok(_.isEqual(new First, new First), "Object instances are equal"); - ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal"); - ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal"); - ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined"); + assert.ok(_.isEqual(new First, new First), 'Object instances are equal'); + assert.notOk(_.isEqual(new First, new Second), 'Objects with different constructors and identical own properties are not equal'); + assert.notOk(_.isEqual({value: 1}, new First), 'Object instances and objects sharing equivalent properties are not equal'); + assert.notOk(_.isEqual({value: 2}, new Second), 'The prototype chain of objects should not be examined'); // Circular Arrays. (a = []).push(a); (b = []).push(b); - ok(_.isEqual(a, b), "Arrays containing circular references are equal"); - a.push(new String("Larry")); - b.push(new String("Larry")); - ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal"); - a.push("Shemp"); - b.push("Curly"); - ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal"); + assert.ok(_.isEqual(a, b), 'Arrays containing circular references are equal'); + a.push(new String('Larry')); + b.push(new String('Larry')); + assert.ok(_.isEqual(a, b), 'Arrays containing circular references and equivalent properties are equal'); + a.push('Shemp'); + b.push('Curly'); + assert.notOk(_.isEqual(a, b), 'Arrays containing circular references and different properties are not equal'); // More circular arrays #767. - a = ["everything is checked but", "this", "is not"]; + a = ['everything is checked but', 'this', 'is not']; a[1] = a; - b = ["everything is checked but", ["this", "array"], "is not"]; - ok(!_.isEqual(a, b), "Comparison of circular references with non-circular references are not equal"); + b = ['everything is checked but', ['this', 'array'], 'is not']; + assert.notOk(_.isEqual(a, b), 'Comparison of circular references with non-circular references are not equal'); // Circular Objects. a = {abc: null}; b = {abc: null}; a.abc = a; b.abc = b; - ok(_.isEqual(a, b), "Objects containing circular references are equal"); + assert.ok(_.isEqual(a, b), 'Objects containing circular references are equal'); a.def = 75; b.def = 75; - ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal"); + assert.ok(_.isEqual(a, b), 'Objects containing circular references and equivalent properties are equal'); a.def = new Number(75); b.def = new Number(63); - ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal"); + assert.notOk(_.isEqual(a, b), 'Objects containing circular references and different properties are not equal'); // More circular objects #767. - a = {everything: "is checked", but: "this", is: "not"}; + a = {everything: 'is checked', but: 'this', is: 'not'}; a.but = a; - b = {everything: "is checked", but: {that:"object"}, is: "not"}; - ok(!_.isEqual(a, b), "Comparison of circular references with non-circular object references are not equal"); + b = {everything: 'is checked', but: {that: 'object'}, is: 'not'}; + assert.notOk(_.isEqual(a, b), 'Comparison of circular references with non-circular object references are not equal'); // Cyclic Structures. a = [{abc: null}]; b = [{abc: null}]; (a[0].abc = a).push(a); (b[0].abc = b).push(b); - ok(_.isEqual(a, b), "Cyclic structures are equal"); - a[0].def = "Larry"; - b[0].def = "Larry"; - ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal"); - a[0].def = new String("Larry"); - b[0].def = new String("Curly"); - ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal"); + assert.ok(_.isEqual(a, b), 'Cyclic structures are equal'); + a[0].def = 'Larry'; + b[0].def = 'Larry'; + assert.ok(_.isEqual(a, b), 'Cyclic structures containing equivalent properties are equal'); + a[0].def = new String('Larry'); + b[0].def = new String('Curly'); + assert.notOk(_.isEqual(a, b), 'Cyclic structures containing different properties are not equal'); // Complex Circular References. a = {foo: {b: {foo: {c: {foo: null}}}}}; b = {foo: {b: {foo: {c: {foo: null}}}}}; a.foo.b.foo.c.foo = a; b.foo.b.foo.c.foo = b; - ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal"); + assert.ok(_.isEqual(a, b), 'Cyclic structures with nested and identically-named properties are equal'); // Chaining. - ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); + assert.notOk(_.isEqual(_({x: 1, y: void 0}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); a = _({x: 1, y: 2}).chain(); b = _({x: 1, y: 2}).chain(); - equal(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained'); + assert.strictEqual(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained'); - // Objects from another frame. - ok(_.isEqual({}, iObject)); + // Objects without a `constructor` property + if (Object.create) { + a = Object.create(null, {x: {value: 1, enumerable: true}}); + b = {x: 1}; + assert.ok(_.isEqual(a, b), 'Handles objects without a constructor (e.g. from Object.create'); + } + + function Foo() { this.a = 1; } + Foo.prototype.constructor = null; + + var other = {a: 1}; + assert.strictEqual(_.isEqual(new Foo, other), false, 'Objects from different constructors are not equal'); + + + // Tricky object cases val comparisons + assert.strictEqual(_.isEqual([0], [-0]), false); + assert.strictEqual(_.isEqual({a: 0}, {a: -0}), false); + assert.strictEqual(_.isEqual([NaN], [NaN]), true); + assert.strictEqual(_.isEqual({a: NaN}, {a: NaN}), true); + + if (typeof Symbol !== 'undefined') { + var symbol = Symbol('x'); + assert.strictEqual(_.isEqual(symbol, symbol), true, 'A symbol is equal to itself'); + assert.strictEqual(_.isEqual(symbol, Object(symbol)), true, 'Even when wrapped in Object()'); + assert.strictEqual(_.isEqual(symbol, null), false, 'Different types are not equal'); + + var symbolY = Symbol('y'); + assert.strictEqual(_.isEqual(symbol, symbolY), false, 'Different symbols are not equal'); + + var sameStringSymbol = Symbol('x'); + assert.strictEqual(_.isEqual(symbol, sameStringSymbol), false, 'Different symbols of same string are not equal'); + } }); - test("isEmpty", function() { - ok(!_([1]).isEmpty(), '[1] is not empty'); - ok(_.isEmpty([]), '[] is empty'); - ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); - ok(_.isEmpty({}), '{} is empty'); - ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); - ok(_.isEmpty(null), 'null is empty'); - ok(_.isEmpty(), 'undefined is empty'); - ok(_.isEmpty(''), 'the empty string is empty'); - ok(!_.isEmpty('moe'), 'but other strings are not'); + QUnit.test('isEmpty', function(assert) { + assert.notOk(_([1]).isEmpty(), '[1] is not empty'); + assert.ok(_.isEmpty([]), '[] is empty'); + assert.notOk(_.isEmpty({one: 1}), '{one: 1} is not empty'); + assert.ok(_.isEmpty({}), '{} is empty'); + assert.ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); + assert.ok(_.isEmpty(null), 'null is empty'); + assert.ok(_.isEmpty(), 'undefined is empty'); + assert.ok(_.isEmpty(''), 'the empty string is empty'); + assert.notOk(_.isEmpty('moe'), 'but other strings are not'); - var obj = {one : 1}; + var obj = {one: 1}; delete obj.one; - ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); + assert.ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); + + var args = function(){ return arguments; }; + assert.ok(_.isEmpty(args()), 'empty arguments object is empty'); + assert.notOk(_.isEmpty(args('')), 'non-empty arguments object is not empty'); + + // covers collecting non-enumerable properties in IE < 9 + var nonEnumProp = {toString: 5}; + assert.notOk(_.isEmpty(nonEnumProp), 'non-enumerable property is not empty'); }); - // Setup remote variables for iFrame tests. - var iframe = document.createElement('iframe'); - jQuery(iframe).appendTo(document.body); - var iDoc = iframe.contentDocument || iframe.contentWindow.document; - iDoc.write( - "" - ); - iDoc.close(); - - test("isElement", function() { - ok(!_.isElement('div'), 'strings are not dom elements'); - ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); - ok(_.isElement(iElement), 'even from another frame'); - }); - - test("isArguments", function() { - var args = (function(){ return arguments; })(1, 2, 3); - ok(!_.isArguments('string'), 'a string is not an arguments object'); - ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); - ok(_.isArguments(args), 'but the arguments object is an arguments object'); - ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); - ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); - ok(_.isArguments(iArguments), 'even from another frame'); - }); - - test("isObject", function() { - ok(_.isObject(arguments), 'the arguments object is object'); - ok(_.isObject([1, 2, 3]), 'and arrays'); - ok(_.isObject($('html')[0]), 'and DOM element'); - ok(_.isObject(iElement), 'even from another frame'); - ok(_.isObject(function () {}), 'and functions'); - ok(_.isObject(iFunction), 'even from another frame'); - ok(!_.isObject(null), 'but not null'); - ok(!_.isObject(undefined), 'and not undefined'); - ok(!_.isObject('string'), 'and not string'); - ok(!_.isObject(12), 'and not number'); - ok(!_.isObject(true), 'and not boolean'); - ok(_.isObject(new String('string')), 'but new String()'); - }); - - test("isArray", function() { - ok(!_.isArray(undefined), 'undefined vars are not arrays'); - ok(!_.isArray(arguments), 'the arguments object is not an array'); - ok(_.isArray([1, 2, 3]), 'but arrays are'); - ok(_.isArray(iArray), 'even from another frame'); - }); - - test("isString", function() { - var obj = new String("I am a string object"); - ok(!_.isString(document.body), 'the document body is not a string'); - ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); - ok(_.isString(iString), 'even from another frame'); - ok(_.isString("I am a string literal"), 'string literals are'); - ok(_.isString(obj), 'so are String objects'); - }); - - test("isNumber", function() { - ok(!_.isNumber('string'), 'a string is not a number'); - ok(!_.isNumber(arguments), 'the arguments object is not a number'); - ok(!_.isNumber(undefined), 'undefined is not a number'); - ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); - ok(_.isNumber(NaN), 'NaN *is* a number'); - ok(_.isNumber(Infinity), 'Infinity is a number'); - ok(_.isNumber(iNumber), 'even from another frame'); - ok(!_.isNumber('1'), 'numeric strings are not numbers'); - }); - - test("isBoolean", function() { - ok(!_.isBoolean(2), 'a number is not a boolean'); - ok(!_.isBoolean("string"), 'a string is not a boolean'); - ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); - ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); - ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); - ok(!_.isBoolean(undefined), 'undefined is not a boolean'); - ok(!_.isBoolean(NaN), 'NaN is not a boolean'); - ok(!_.isBoolean(null), 'null is not a boolean'); - ok(_.isBoolean(true), 'but true is'); - ok(_.isBoolean(false), 'and so is false'); - ok(_.isBoolean(iBoolean), 'even from another frame'); - }); - - test("isFunction", function() { - ok(!_.isFunction(undefined), 'undefined vars are not functions'); - ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); - ok(!_.isFunction('moe'), 'strings are not functions'); - ok(_.isFunction(_.isFunction), 'but functions are'); - ok(_.isFunction(iFunction), 'even from another frame'); - ok(_.isFunction(function(){}), 'even anonymous ones'); - }); - - test("isDate", function() { - ok(!_.isDate(100), 'numbers are not dates'); - ok(!_.isDate({}), 'objects are not dates'); - ok(_.isDate(new Date()), 'but dates are'); - ok(_.isDate(iDate), 'even from another frame'); - }); - - test("isRegExp", function() { - ok(!_.isRegExp(_.identity), 'functions are not RegExps'); - ok(_.isRegExp(/identity/), 'but RegExps are'); - ok(_.isRegExp(iRegExp), 'even from another frame'); - }); - - test("isFinite", function() { - ok(!_.isFinite(undefined), 'undefined is not Finite'); - ok(!_.isFinite(null), 'null is not Finite'); - ok(!_.isFinite(NaN), 'NaN is not Finite'); - ok(!_.isFinite(Infinity), 'Infinity is not Finite'); - ok(!_.isFinite(-Infinity), '-Infinity is not Finite'); - ok(_.isFinite('12'), 'Numeric strings are numbers'); - ok(!_.isFinite('1a'), 'Non numeric strings are not numbers'); - ok(!_.isFinite(''), 'Empty strings are not numbers'); - var obj = new Number(5); - ok(_.isFinite(obj), 'Number instances can be finite'); - ok(_.isFinite(0), '0 is Finite'); - ok(_.isFinite(123), 'Ints are Finite'); - ok(_.isFinite(-12.44), 'Floats are Finite'); - }); - - test("isNaN", function() { - ok(!_.isNaN(undefined), 'undefined is not NaN'); - ok(!_.isNaN(null), 'null is not NaN'); - ok(!_.isNaN(0), '0 is not NaN'); - ok(_.isNaN(NaN), 'but NaN is'); - ok(_.isNaN(iNaN), 'even from another frame'); - ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN'); - }); - - test("isNull", function() { - ok(!_.isNull(undefined), 'undefined is not null'); - ok(!_.isNull(NaN), 'NaN is not null'); - ok(_.isNull(null), 'but null is'); - ok(_.isNull(iNull), 'even from another frame'); - }); - - test("isUndefined", function() { - ok(!_.isUndefined(1), 'numbers are defined'); - ok(!_.isUndefined(null), 'null is defined'); - ok(!_.isUndefined(false), 'false is defined'); - ok(!_.isUndefined(NaN), 'NaN is defined'); - ok(_.isUndefined(), 'nothing is undefined'); - ok(_.isUndefined(undefined), 'undefined is undefined'); - ok(_.isUndefined(iUndefined), 'even from another frame'); - }); - - if (window.ActiveXObject) { - test("IE host objects", function() { - var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); - ok(!_.isNumber(xml)); - ok(!_.isBoolean(xml)); - ok(!_.isNaN(xml)); - ok(!_.isFunction(xml)); - ok(!_.isNull(xml)); - ok(!_.isUndefined(xml)); + if (typeof document === 'object') { + QUnit.test('isElement', function(assert) { + assert.notOk(_.isElement('div'), 'strings are not dom elements'); + assert.ok(_.isElement(testElement), 'an element is a DOM element'); }); } - test("tap", function() { + QUnit.test('isArguments', function(assert) { + var args = (function(){ return arguments; }(1, 2, 3)); + assert.notOk(_.isArguments('string'), 'a string is not an arguments object'); + assert.notOk(_.isArguments(_.isArguments), 'a function is not an arguments object'); + assert.ok(_.isArguments(args), 'but the arguments object is an arguments object'); + assert.notOk(_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); + assert.notOk(_.isArguments([1, 2, 3]), 'and not vanilla arrays.'); + }); + + QUnit.test('isObject', function(assert) { + assert.ok(_.isObject(arguments), 'the arguments object is object'); + assert.ok(_.isObject([1, 2, 3]), 'and arrays'); + if (testElement) { + assert.ok(_.isObject(testElement), 'and DOM element'); + } + assert.ok(_.isObject(function() {}), 'and functions'); + assert.notOk(_.isObject(null), 'but not null'); + assert.notOk(_.isObject(void 0), 'and not undefined'); + assert.notOk(_.isObject('string'), 'and not string'); + assert.notOk(_.isObject(12), 'and not number'); + assert.notOk(_.isObject(true), 'and not boolean'); + assert.ok(_.isObject(new String('string')), 'but new String()'); + }); + + QUnit.test('isArray', function(assert) { + assert.notOk(_.isArray(void 0), 'undefined vars are not arrays'); + assert.notOk(_.isArray(arguments), 'the arguments object is not an array'); + assert.ok(_.isArray([1, 2, 3]), 'but arrays are'); + }); + + QUnit.test('isString', function(assert) { + var obj = new String('I am a string object'); + if (testElement) { + assert.notOk(_.isString(testElement), 'an element is not a string'); + } + assert.ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); + assert.strictEqual(_.isString('I am a string literal'), true, 'string literals are'); + assert.ok(_.isString(obj), 'so are String objects'); + assert.strictEqual(_.isString(1), false); + }); + + QUnit.test('isSymbol', function(assert) { + assert.notOk(_.isSymbol(0), 'numbers are not symbols'); + assert.notOk(_.isSymbol(''), 'strings are not symbols'); + assert.notOk(_.isSymbol(_.isSymbol), 'functions are not symbols'); + if (typeof Symbol === 'function') { + assert.ok(_.isSymbol(Symbol()), 'symbols are symbols'); + assert.ok(_.isSymbol(Symbol('description')), 'described symbols are symbols'); + assert.ok(_.isSymbol(Object(Symbol())), 'boxed symbols are symbols'); + } + }); + + QUnit.test('isNumber', function(assert) { + assert.notOk(_.isNumber('string'), 'a string is not a number'); + assert.notOk(_.isNumber(arguments), 'the arguments object is not a number'); + assert.notOk(_.isNumber(void 0), 'undefined is not a number'); + assert.ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); + assert.ok(_.isNumber(NaN), 'NaN *is* a number'); + assert.ok(_.isNumber(Infinity), 'Infinity is a number'); + assert.notOk(_.isNumber('1'), 'numeric strings are not numbers'); + }); + + QUnit.test('isBoolean', function(assert) { + assert.notOk(_.isBoolean(2), 'a number is not a boolean'); + assert.notOk(_.isBoolean('string'), 'a string is not a boolean'); + assert.notOk(_.isBoolean('false'), 'the string "false" is not a boolean'); + assert.notOk(_.isBoolean('true'), 'the string "true" is not a boolean'); + assert.notOk(_.isBoolean(arguments), 'the arguments object is not a boolean'); + assert.notOk(_.isBoolean(void 0), 'undefined is not a boolean'); + assert.notOk(_.isBoolean(NaN), 'NaN is not a boolean'); + assert.notOk(_.isBoolean(null), 'null is not a boolean'); + assert.ok(_.isBoolean(true), 'but true is'); + assert.ok(_.isBoolean(false), 'and so is false'); + }); + + QUnit.test('isMap', function(assert) { + assert.notOk(_.isMap('string'), 'a string is not a map'); + assert.notOk(_.isMap(2), 'a number is not a map'); + assert.notOk(_.isMap({}), 'an object is not a map'); + assert.notOk(_.isMap(false), 'a boolean is not a map'); + assert.notOk(_.isMap(void 0), 'undefined is not a map'); + assert.notOk(_.isMap([1, 2, 3]), 'an array is not a map'); + if (typeof Set === 'function') { + assert.notOk(_.isMap(new Set()), 'a set is not a map'); + } + if (typeof WeakSet === 'function') { + assert.notOk(_.isMap(new WeakSet()), 'a weakset is not a map'); + } + if (typeof WeakMap === 'function') { + assert.notOk(_.isMap(new WeakMap()), 'a weakmap is not a map'); + } + if (typeof Map === 'function') { + var keyString = 'a string'; + var obj = new Map(); + obj.set(keyString, 'value'); + assert.ok(_.isMap(obj), 'but a map is'); + } + }); + + QUnit.test('isWeakMap', function(assert) { + assert.notOk(_.isWeakMap('string'), 'a string is not a weakmap'); + assert.notOk(_.isWeakMap(2), 'a number is not a weakmap'); + assert.notOk(_.isWeakMap({}), 'an object is not a weakmap'); + assert.notOk(_.isWeakMap(false), 'a boolean is not a weakmap'); + assert.notOk(_.isWeakMap(void 0), 'undefined is not a weakmap'); + assert.notOk(_.isWeakMap([1, 2, 3]), 'an array is not a weakmap'); + if (typeof Set === 'function') { + assert.notOk(_.isWeakMap(new Set()), 'a set is not a weakmap'); + } + if (typeof WeakSet === 'function') { + assert.notOk(_.isWeakMap(new WeakSet()), 'a weakset is not a weakmap'); + } + if (typeof Map === 'function') { + assert.notOk(_.isWeakMap(new Map()), 'a map is not a weakmap'); + } + if (typeof WeakMap === 'function') { + var keyObj = {}, obj = new WeakMap(); + obj.set(keyObj, 'value'); + assert.ok(_.isWeakMap(obj), 'but a weakmap is'); + } + }); + + QUnit.test('isSet', function(assert) { + assert.notOk(_.isSet('string'), 'a string is not a set'); + assert.notOk(_.isSet(2), 'a number is not a set'); + assert.notOk(_.isSet({}), 'an object is not a set'); + assert.notOk(_.isSet(false), 'a boolean is not a set'); + assert.notOk(_.isSet(void 0), 'undefined is not a set'); + assert.notOk(_.isSet([1, 2, 3]), 'an array is not a set'); + if (typeof Map === 'function') { + assert.notOk(_.isSet(new Map()), 'a map is not a set'); + } + if (typeof WeakMap === 'function') { + assert.notOk(_.isSet(new WeakMap()), 'a weakmap is not a set'); + } + if (typeof WeakSet === 'function') { + assert.notOk(_.isSet(new WeakSet()), 'a weakset is not a set'); + } + if (typeof Set === 'function') { + var obj = new Set(); + obj.add(1).add('string').add(false).add({}); + assert.ok(_.isSet(obj), 'but a set is'); + } + }); + + QUnit.test('isWeakSet', function(assert) { + + assert.notOk(_.isWeakSet('string'), 'a string is not a weakset'); + assert.notOk(_.isWeakSet(2), 'a number is not a weakset'); + assert.notOk(_.isWeakSet({}), 'an object is not a weakset'); + assert.notOk(_.isWeakSet(false), 'a boolean is not a weakset'); + assert.notOk(_.isWeakSet(void 0), 'undefined is not a weakset'); + assert.notOk(_.isWeakSet([1, 2, 3]), 'an array is not a weakset'); + if (typeof Map === 'function') { + assert.notOk(_.isWeakSet(new Map()), 'a map is not a weakset'); + } + if (typeof WeakMap === 'function') { + assert.notOk(_.isWeakSet(new WeakMap()), 'a weakmap is not a weakset'); + } + if (typeof Set === 'function') { + assert.notOk(_.isWeakSet(new Set()), 'a set is not a weakset'); + } + if (typeof WeakSet === 'function') { + var obj = new WeakSet(); + obj.add({x: 1}, {y: 'string'}).add({y: 'string'}).add({z: [1, 2, 3]}); + assert.ok(_.isWeakSet(obj), 'but a weakset is'); + } + }); + + QUnit.test('isFunction', function(assert) { + assert.notOk(_.isFunction(void 0), 'undefined vars are not functions'); + assert.notOk(_.isFunction([1, 2, 3]), 'arrays are not functions'); + assert.notOk(_.isFunction('moe'), 'strings are not functions'); + assert.ok(_.isFunction(_.isFunction), 'but functions are'); + assert.ok(_.isFunction(function(){}), 'even anonymous ones'); + + if (testElement) { + assert.notOk(_.isFunction(testElement), 'elements are not functions'); + } + + var nodelist = typeof document != 'undefined' && document.childNodes; + if (nodelist) { + assert.notOk(_.isFunction(nodelist)); + } + }); + + if (typeof Int8Array !== 'undefined') { + QUnit.test('#1929 Typed Array constructors are functions', function(assert) { + _.chain(['Float32Array', 'Float64Array', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array']) + .map(_.propertyOf(typeof GLOBAL != 'undefined' ? GLOBAL : window)) + .compact() + .each(function(TypedArray) { + // PhantomJS reports `typeof UInt8Array == 'object'` and doesn't report toString TypeArray + // as a function + assert.strictEqual(_.isFunction(TypedArray), Object.prototype.toString.call(TypedArray) === '[object Function]'); + }); + }); + } + + QUnit.test('isDate', function(assert) { + assert.notOk(_.isDate(100), 'numbers are not dates'); + assert.notOk(_.isDate({}), 'objects are not dates'); + assert.ok(_.isDate(new Date()), 'but dates are'); + }); + + QUnit.test('isRegExp', function(assert) { + assert.notOk(_.isRegExp(_.identity), 'functions are not RegExps'); + assert.ok(_.isRegExp(/identity/), 'but RegExps are'); + }); + + QUnit.test('isFinite', function(assert) { + assert.notOk(_.isFinite(void 0), 'undefined is not finite'); + assert.notOk(_.isFinite(null), 'null is not finite'); + assert.notOk(_.isFinite(NaN), 'NaN is not finite'); + assert.notOk(_.isFinite(Infinity), 'Infinity is not finite'); + assert.notOk(_.isFinite(-Infinity), '-Infinity is not finite'); + assert.ok(_.isFinite('12'), 'Numeric strings are numbers'); + assert.notOk(_.isFinite('1a'), 'Non numeric strings are not numbers'); + assert.notOk(_.isFinite(''), 'Empty strings are not numbers'); + var obj = new Number(5); + assert.ok(_.isFinite(obj), 'Number instances can be finite'); + assert.ok(_.isFinite(0), '0 is finite'); + assert.ok(_.isFinite(123), 'Ints are finite'); + assert.ok(_.isFinite(-12.44), 'Floats are finite'); + if (typeof Symbol === 'function') { + assert.notOk(_.isFinite(Symbol()), 'symbols are not numbers'); + assert.notOk(_.isFinite(Symbol('description')), 'described symbols are not numbers'); + assert.notOk(_.isFinite(Object(Symbol())), 'boxed symbols are not numbers'); + } + }); + + QUnit.test('isNaN', function(assert) { + assert.notOk(_.isNaN(void 0), 'undefined is not NaN'); + assert.notOk(_.isNaN(null), 'null is not NaN'); + assert.notOk(_.isNaN(0), '0 is not NaN'); + assert.notOk(_.isNaN(new Number(0)), 'wrapped 0 is not NaN'); + assert.ok(_.isNaN(NaN), 'but NaN is'); + assert.ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN'); + if (typeof Symbol !== 'undefined'){ + assert.notOk(_.isNaN(Symbol()), 'symbol is not NaN'); + } + }); + + QUnit.test('isNull', function(assert) { + assert.notOk(_.isNull(void 0), 'undefined is not null'); + assert.notOk(_.isNull(NaN), 'NaN is not null'); + assert.ok(_.isNull(null), 'but null is'); + }); + + QUnit.test('isUndefined', function(assert) { + assert.notOk(_.isUndefined(1), 'numbers are defined'); + assert.notOk(_.isUndefined(null), 'null is defined'); + assert.notOk(_.isUndefined(false), 'false is defined'); + assert.notOk(_.isUndefined(NaN), 'NaN is defined'); + assert.ok(_.isUndefined(), 'nothing is undefined'); + assert.ok(_.isUndefined(void 0), 'undefined is undefined'); + }); + + QUnit.test('isError', function(assert) { + assert.notOk(_.isError(1), 'numbers are not Errors'); + assert.notOk(_.isError(null), 'null is not an Error'); + assert.notOk(_.isError(Error), 'functions are not Errors'); + assert.ok(_.isError(new Error()), 'Errors are Errors'); + assert.ok(_.isError(new EvalError()), 'EvalErrors are Errors'); + assert.ok(_.isError(new RangeError()), 'RangeErrors are Errors'); + assert.ok(_.isError(new ReferenceError()), 'ReferenceErrors are Errors'); + assert.ok(_.isError(new SyntaxError()), 'SyntaxErrors are Errors'); + assert.ok(_.isError(new TypeError()), 'TypeErrors are Errors'); + assert.ok(_.isError(new URIError()), 'URIErrors are Errors'); + }); + + QUnit.test('tap', function(assert) { var intercepted = null; var interceptor = function(obj) { intercepted = obj; }; var returned = _.tap(1, interceptor); - equal(intercepted, 1, "passes tapped object to interceptor"); - equal(returned, 1, "returns tapped object"); + assert.strictEqual(intercepted, 1, 'passes tapped object to interceptor'); + assert.strictEqual(returned, 1, 'returns tapped object'); - returned = _([1,2,3]).chain(). + returned = _([1, 2, 3]).chain(). map(function(n){ return n * 2; }). max(). tap(interceptor). value(); - ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); + assert.strictEqual(returned, 6, 'can use tapped objects in a chain'); + assert.strictEqual(intercepted, returned, 'can use tapped objects in a chain'); }); - test("has", function () { - var obj = {foo: "bar", func: function () {} }; - ok (_.has(obj, "foo"), "has() checks that the object has a property."); - ok (_.has(obj, "baz") == false, "has() returns false if the object doesn't have the property."); - ok (_.has(obj, "func"), "has() works for functions too."); - obj.hasOwnProperty = null; - ok (_.has(obj, "foo"), "has() works even when the hasOwnProperty method is deleted."); - var child = {}; - child.prototype = obj; - ok (_.has(child, "foo") == false, "has() does not check the prototype chain for a property.") + QUnit.test('has', function(assert) { + var obj = {foo: 'bar', func: function(){}}; + assert.ok(_.has(obj, 'foo'), 'checks that the object has a property.'); + assert.notOk(_.has(obj, 'baz'), "returns false if the object doesn't have the property."); + assert.ok(_.has(obj, 'func'), 'works for functions too.'); + obj.hasOwnProperty = null; + assert.ok(_.has(obj, 'foo'), 'works even when the hasOwnProperty method is deleted.'); + var child = {}; + child.prototype = obj; + assert.notOk(_.has(child, 'foo'), 'does not check the prototype chain for a property.'); + assert.strictEqual(_.has(null, 'foo'), false, 'returns false for null'); + assert.strictEqual(_.has(void 0, 'foo'), false, 'returns false for undefined'); + + assert.ok(_.has({a: {b: 'foo'}}, ['a', 'b']), 'can check for nested properties.'); + assert.notOk(_.has({a: child}, ['a', 'foo']), 'does not check the prototype of nested props.'); }); -}); + + QUnit.test('property', function(assert) { + var stooge = {name: 'moe'}; + assert.strictEqual(_.property('name')(stooge), 'moe', 'should return the property with the given name'); + assert.strictEqual(_.property('name')(null), void 0, 'should return undefined for null values'); + assert.strictEqual(_.property('name')(void 0), void 0, 'should return undefined for undefined values'); + assert.strictEqual(_.property(null)('foo'), void 0, 'should return undefined for null object'); + assert.strictEqual(_.property('x')({x: null}), null, 'can fetch null values'); + assert.strictEqual(_.property('length')(null), void 0, 'does not crash on property access of non-objects'); + + // Deep property access + assert.strictEqual(_.property('a')({a: 1}), 1, 'can get a direct property'); + assert.strictEqual(_.property(['a', 'b'])({a: {b: 2}}), 2, 'can get a nested property'); + assert.strictEqual(_.property(['a'])({a: false}), false, 'can fetch falsy values'); + assert.strictEqual(_.property(['x', 'y'])({x: {y: null}}), null, 'can fetch null values deeply'); + assert.strictEqual(_.property(['x', 'y'])({x: null}), void 0, 'does not crash on property access of nested non-objects'); + assert.strictEqual(_.property([])({x: 'y'}), void 0, 'returns `undefined` for a path that is an empty array'); + }); + + QUnit.test('propertyOf', function(assert) { + var stoogeRanks = _.propertyOf({curly: 2, moe: 1, larry: 3}); + assert.strictEqual(stoogeRanks('curly'), 2, 'should return the property with the given name'); + assert.strictEqual(stoogeRanks(null), void 0, 'should return undefined for null values'); + assert.strictEqual(stoogeRanks(void 0), void 0, 'should return undefined for undefined values'); + assert.strictEqual(_.propertyOf({a: null})('a'), null, 'can fetch null values'); + + function MoreStooges() { this.shemp = 87; } + MoreStooges.prototype = {curly: 2, moe: 1, larry: 3}; + var moreStoogeRanks = _.propertyOf(new MoreStooges()); + assert.strictEqual(moreStoogeRanks('curly'), 2, 'should return properties from further up the prototype chain'); + + var nullPropertyOf = _.propertyOf(null); + assert.strictEqual(nullPropertyOf('curly'), void 0, 'should return undefined when obj is null'); + + var undefPropertyOf = _.propertyOf(void 0); + assert.strictEqual(undefPropertyOf('curly'), void 0, 'should return undefined when obj is undefined'); + + var deepPropertyOf = _.propertyOf({curly: {number: 2}, joe: {number: null}}); + assert.strictEqual(deepPropertyOf(['curly', 'number']), 2, 'can fetch nested properties of obj'); + assert.strictEqual(deepPropertyOf(['joe', 'number']), null, 'can fetch nested null properties of obj'); + }); + + QUnit.test('isMatch', function(assert) { + var moe = {name: 'Moe Howard', hair: true}; + var curly = {name: 'Curly Howard', hair: false}; + + assert.strictEqual(_.isMatch(moe, {hair: true}), true, 'Returns a boolean'); + assert.strictEqual(_.isMatch(curly, {hair: true}), false, 'Returns a boolean'); + + assert.strictEqual(_.isMatch(5, {__x__: void 0}), false, 'can match undefined props on primitives'); + assert.strictEqual(_.isMatch({__x__: void 0}, {__x__: void 0}), true, 'can match undefined props'); + + assert.strictEqual(_.isMatch(null, {}), true, 'Empty spec called with null object returns true'); + assert.strictEqual(_.isMatch(null, {a: 1}), false, 'Non-empty spec called with null object returns false'); + + _.each([null, void 0], function(item) { assert.strictEqual(_.isMatch(item, null), true, 'null matches null'); }); + _.each([null, void 0], function(item) { assert.strictEqual(_.isMatch(item, null), true, 'null matches {}'); }); + assert.strictEqual(_.isMatch({b: 1}, {a: void 0}), false, 'handles undefined values (1683)'); + + _.each([true, 5, NaN, null, void 0], function(item) { + assert.strictEqual(_.isMatch({a: 1}, item), true, 'treats primitives as empty'); + }); + + function Prototest() {} + Prototest.prototype.x = 1; + var specObj = new Prototest; + assert.strictEqual(_.isMatch({x: 2}, specObj), true, 'spec is restricted to own properties'); + + specObj.y = 5; + assert.strictEqual(_.isMatch({x: 1, y: 5}, specObj), true); + assert.strictEqual(_.isMatch({x: 1, y: 4}, specObj), false); + + assert.ok(_.isMatch(specObj, {x: 1, y: 5}), 'inherited and own properties are checked on the test object'); + + Prototest.x = 5; + assert.ok(_.isMatch({x: 5, y: 1}, Prototest), 'spec can be a function'); + + //null edge cases + var oCon = {constructor: Object}; + assert.deepEqual(_.map([null, void 0, 5, {}], _.partial(_.isMatch, _, oCon)), [false, false, false, true], 'doesnt falsy match constructor on undefined/null'); + }); + + QUnit.test('matcher', function(assert) { + var moe = {name: 'Moe Howard', hair: true}; + var curly = {name: 'Curly Howard', hair: false}; + var stooges = [moe, curly]; + + assert.strictEqual(_.matcher({hair: true})(moe), true, 'Returns a boolean'); + assert.strictEqual(_.matcher({hair: true})(curly), false, 'Returns a boolean'); + + assert.strictEqual(_.matcher({__x__: void 0})(5), false, 'can match undefined props on primitives'); + assert.strictEqual(_.matcher({__x__: void 0})({__x__: void 0}), true, 'can match undefined props'); + + assert.strictEqual(_.matcher({})(null), true, 'Empty spec called with null object returns true'); + assert.strictEqual(_.matcher({a: 1})(null), false, 'Non-empty spec called with null object returns false'); + + assert.strictEqual(_.find(stooges, _.matcher({hair: false})), curly, 'returns a predicate that can be used by finding functions.'); + assert.strictEqual(_.find(stooges, _.matcher(moe)), moe, 'can be used to locate an object exists in a collection.'); + assert.deepEqual(_.filter([null, void 0], _.matcher({a: 1})), [], 'Do not throw on null values.'); + + assert.deepEqual(_.filter([null, void 0], _.matcher(null)), [null, void 0], 'null matches null'); + assert.deepEqual(_.filter([null, void 0], _.matcher({})), [null, void 0], 'null matches {}'); + assert.deepEqual(_.filter([{b: 1}], _.matcher({a: void 0})), [], 'handles undefined values (1683)'); + + _.each([true, 5, NaN, null, void 0], function(item) { + assert.strictEqual(_.matcher(item)({a: 1}), true, 'treats primitives as empty'); + }); + + function Prototest() {} + Prototest.prototype.x = 1; + var specObj = new Prototest; + var protospec = _.matcher(specObj); + assert.strictEqual(protospec({x: 2}), true, 'spec is restricted to own properties'); + + specObj.y = 5; + protospec = _.matcher(specObj); + assert.strictEqual(protospec({x: 1, y: 5}), true); + assert.strictEqual(protospec({x: 1, y: 4}), false); + + assert.ok(_.matcher({x: 1, y: 5})(specObj), 'inherited and own properties are checked on the test object'); + + Prototest.x = 5; + assert.ok(_.matcher(Prototest)({x: 5, y: 1}), 'spec can be a function'); + + // #1729 + var o = {b: 1}; + var m = _.matcher(o); + + assert.strictEqual(m({b: 1}), true); + o.b = 2; + o.a = 1; + assert.strictEqual(m({b: 1}), true, 'changing spec object doesnt change matches result'); + + + //null edge cases + var oCon = _.matcher({constructor: Object}); + assert.deepEqual(_.map([null, void 0, 5, {}], oCon), [false, false, false, true], 'doesnt falsy match constructor on undefined/null'); + }); + + QUnit.test('matches', function(assert) { + assert.strictEqual(_.matches, _.matcher, 'is an alias for matcher'); + }); + + QUnit.test('findKey', function(assert) { + var objects = { + a: {a: 0, b: 0}, + b: {a: 1, b: 1}, + c: {a: 2, b: 2} + }; + + assert.strictEqual(_.findKey(objects, function(obj) { + return obj.a === 0; + }), 'a'); + + assert.strictEqual(_.findKey(objects, function(obj) { + return obj.b * obj.a === 4; + }), 'c'); + + assert.strictEqual(_.findKey(objects, 'a'), 'b', 'Uses lookupIterator'); + + assert.strictEqual(_.findKey(objects, function(obj) { + return obj.b * obj.a === 5; + }), void 0); + + assert.strictEqual(_.findKey([1, 2, 3, 4, 5, 6], function(obj) { + return obj === 3; + }), '2', 'Keys are strings'); + + assert.strictEqual(_.findKey(objects, function(a) { + return a.foo === null; + }), void 0); + + _.findKey({a: {a: 1}}, function(a, key, obj) { + assert.strictEqual(key, 'a'); + assert.deepEqual(obj, {a: {a: 1}}); + assert.strictEqual(this, objects, 'called with context'); + }, objects); + + var array = [1, 2, 3, 4]; + array.match = 55; + assert.strictEqual(_.findKey(array, function(x) { return x === 55; }), 'match', 'matches array-likes keys'); + }); + + + QUnit.test('mapObject', function(assert) { + var obj = {a: 1, b: 2}; + var objects = { + a: {a: 0, b: 0}, + b: {a: 1, b: 1}, + c: {a: 2, b: 2} + }; + + assert.deepEqual(_.mapObject(obj, function(val) { + return val * 2; + }), {a: 2, b: 4}, 'simple objects'); + + assert.deepEqual(_.mapObject(objects, function(val) { + return _.reduce(val, function(memo, v){ + return memo + v; + }, 0); + }), {a: 0, b: 2, c: 4}, 'nested objects'); + + assert.deepEqual(_.mapObject(obj, function(val, key, o) { + return o[key] * 2; + }), {a: 2, b: 4}, 'correct keys'); + + assert.deepEqual(_.mapObject([1, 2], function(val) { + return val * 2; + }), {0: 2, 1: 4}, 'check behavior for arrays'); + + assert.deepEqual(_.mapObject(obj, function(val) { + return val * this.multiplier; + }, {multiplier: 3}), {a: 3, b: 6}, 'keep context'); + + assert.deepEqual(_.mapObject({a: 1}, function() { + return this.length; + }, [1, 2]), {a: 2}, 'called with context'); + + var ids = _.mapObject({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){ + return n.id; + }); + assert.deepEqual(ids, {length: void 0, 0: '1', 1: '2'}, 'Check with array-like objects'); + + // Passing a property name like _.pluck. + var people = {a: {name: 'moe', age: 30}, b: {name: 'curly', age: 50}}; + assert.deepEqual(_.mapObject(people, 'name'), {a: 'moe', b: 'curly'}, 'predicate string map to object properties'); + + _.each([null, void 0, 1, 'abc', [], {}, void 0], function(val){ + assert.deepEqual(_.mapObject(val, _.identity), {}, 'mapValue identity'); + }); + + var Proto = function(){ this.a = 1; }; + Proto.prototype.b = 1; + var protoObj = new Proto(); + assert.deepEqual(_.mapObject(protoObj, _.identity), {a: 1}, 'ignore inherited values from prototypes'); + + }); +}()); diff --git a/vendor/underscore/test/qunit-setup.js b/vendor/underscore/test/qunit-setup.js new file mode 100644 index 000000000..ad1e8cd8c --- /dev/null +++ b/vendor/underscore/test/qunit-setup.js @@ -0,0 +1,3 @@ +(function() { + QUnit.config.noglobals = true; +}()); diff --git a/vendor/underscore/test/utility.js b/vendor/underscore/test/utility.js index 52c5495fb..23289afd9 100644 --- a/vendor/underscore/test/utility.js +++ b/vendor/underscore/test/utility.js @@ -1,272 +1,452 @@ -$(document).ready(function() { - +(function() { + var _ = typeof require == 'function' ? require('..') : window._; var templateSettings; - module("Utility", { + QUnit.module('Utility', { - setup: function() { + beforeEach: function() { templateSettings = _.clone(_.templateSettings); }, - teardown: function() { + afterEach: function() { _.templateSettings = templateSettings; } }); - test("#750 - Return _ instance.", 2, function() { + if (typeof this == 'object') { + QUnit.test('noConflict', function(assert) { + var underscore = _.noConflict(); + assert.strictEqual(underscore.identity(1), 1); + if (typeof require != 'function') { + assert.strictEqual(this._, void 0, 'global underscore is removed'); + this._ = underscore; + } else if (typeof global !== 'undefined') { + delete global._; + } + }); + } + + if (typeof require == 'function') { + QUnit.test('noConflict (node vm)', function(assert) { + assert.expect(2); + var done = assert.async(); + var fs = require('fs'); + var vm = require('vm'); + var filename = __dirname + '/../underscore.js'; + fs.readFile(filename, function(err, content){ + var sandbox = vm.createScript( + content + 'this.underscore = this._.noConflict();', + filename + ); + var context = {_: 'oldvalue'}; + sandbox.runInNewContext(context); + assert.strictEqual(context._, 'oldvalue'); + assert.strictEqual(context.underscore.VERSION, _.VERSION); + + done(); + }); + }); + } + + QUnit.test('#750 - Return _ instance.', function(assert) { + assert.expect(2); var instance = _([]); - ok(_(instance) === instance); - ok(new _(instance) === instance); + assert.strictEqual(_(instance), instance); + assert.strictEqual(new _(instance), instance); }); - test("identity", function() { - var moe = {name : 'moe'}; - equal(_.identity(moe), moe, 'moe is the same as his identity'); + QUnit.test('identity', function(assert) { + var stooge = {name: 'moe'}; + assert.strictEqual(_.identity(stooge), stooge, 'stooge is the same as his identity'); }); - test("random", function() { + QUnit.test('constant', function(assert) { + var stooge = {name: 'moe'}; + assert.strictEqual(_.constant(stooge)(), stooge, 'should create a function that returns stooge'); + }); + + QUnit.test('noop', function(assert) { + assert.strictEqual(_.noop('curly', 'larry', 'moe'), void 0, 'should always return undefined'); + }); + + QUnit.test('random', function(assert) { var array = _.range(1000); var min = Math.pow(2, 31); var max = Math.pow(2, 62); - ok(_.every(array, function() { + assert.ok(_.every(array, function() { return _.random(min, max) >= min; - }), "should produce a random number greater than or equal to the minimum number"); + }), 'should produce a random number greater than or equal to the minimum number'); - ok(_.some(array, function() { + assert.ok(_.some(array, function() { return _.random(Number.MAX_VALUE) > 0; - }), "should produce a random number when passed `Number.MAX_VALUE`"); + }), 'should produce a random number when passed `Number.MAX_VALUE`'); }); - test("uniqueId", function() { + QUnit.test('now', function(assert) { + var diff = _.now() - new Date().getTime(); + assert.ok(diff <= 0 && diff > -5, 'Produces the correct time in milliseconds');//within 5ms + }); + + QUnit.test('uniqueId', function(assert) { var ids = [], i = 0; - while(i++ < 100) ids.push(_.uniqueId()); - equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); + while (i++ < 100) ids.push(_.uniqueId()); + assert.strictEqual(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); }); - test("times", function() { + QUnit.test('times', function(assert) { var vals = []; - _.times(3, function (i) { vals.push(i); }); - ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); + _.times(3, function(i) { vals.push(i); }); + assert.deepEqual(vals, [0, 1, 2], 'is 0 indexed'); // vals = []; _(3).times(function(i) { vals.push(i); }); - ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); + assert.deepEqual(vals, [0, 1, 2], 'works as a wrapper'); // collects return values - ok(_.isEqual([0, 1, 2], _.times(3, function(i) { return i; })), "collects return values"); + assert.deepEqual([0, 1, 2], _.times(3, function(i) { return i; }), 'collects return values'); - deepEqual(_.times(0, _.identity), []); - deepEqual(_.times(-1, _.identity), []); - deepEqual(_.times(parseFloat('-Infinity'), _.identity), []); + assert.deepEqual(_.times(0, _.identity), []); + assert.deepEqual(_.times(-1, _.identity), []); + assert.deepEqual(_.times(parseFloat('-Infinity'), _.identity), []); }); - test("mixin", function() { - _.mixin({ + QUnit.test('mixin', function(assert) { + var ret = _.mixin({ myReverse: function(string) { return string.split('').reverse().join(''); } }); - equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); - equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); + assert.strictEqual(ret, _, 'returns the _ object to facilitate chaining'); + assert.strictEqual(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); + assert.strictEqual(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); }); - test("_.escape", function() { - equal(_.escape("Curly & Moe"), "Curly & Moe"); - equal(_.escape('Curly & Moe\'s'), '<a href="http://moe.com">Curly & Moe's</a>'); - equal(_.escape("Curly & Moe"), "Curly &amp; Moe"); - equal(_.escape(null), ''); + QUnit.test('_.escape', function(assert) { + assert.strictEqual(_.escape(null), ''); }); - test("_.unescape", function() { - var string = "Curly & Moe"; - equal(_.unescape("Curly & Moe"), string); - equal(_.unescape('<a href="http://moe.com">Curly & Moe's</a>'), 'Curly & Moe\'s'); - equal(_.unescape("Curly &amp; Moe"), "Curly & Moe"); - equal(_.unescape(null), ''); - equal(_.unescape(_.escape(string)), string); + QUnit.test('_.unescape', function(assert) { + var string = 'Curly & Moe'; + assert.strictEqual(_.unescape(null), ''); + assert.strictEqual(_.unescape(_.escape(string)), string); + assert.strictEqual(_.unescape(string), string, 'don\'t unescape unnecessarily'); }); - test("template", function() { + // Don't care what they escape them to just that they're escaped and can be unescaped + QUnit.test('_.escape & unescape', function(assert) { + // test & (&) separately obviously + var escapeCharacters = ['<', '>', '"', '\'', '`']; + + _.each(escapeCharacters, function(escapeChar) { + var s = 'a ' + escapeChar + ' string escaped'; + var e = _.escape(s); + assert.notEqual(s, e, escapeChar + ' is escaped'); + assert.strictEqual(s, _.unescape(e), escapeChar + ' can be unescaped'); + + s = 'a ' + escapeChar + escapeChar + escapeChar + 'some more string' + escapeChar; + e = _.escape(s); + + assert.strictEqual(e.indexOf(escapeChar), -1, 'can escape multiple occurrences of ' + escapeChar); + assert.strictEqual(_.unescape(e), s, 'multiple occurrences of ' + escapeChar + ' can be unescaped'); + }); + + // handles multiple escape characters at once + var joiner = ' other stuff '; + var allEscaped = escapeCharacters.join(joiner); + allEscaped += allEscaped; + assert.ok(_.every(escapeCharacters, function(escapeChar) { + return allEscaped.indexOf(escapeChar) !== -1; + }), 'handles multiple characters'); + assert.ok(allEscaped.indexOf(joiner) >= 0, 'can escape multiple escape characters at the same time'); + + // test & -> & + var str = 'some string & another string & yet another'; + var escaped = _.escape(str); + + assert.notStrictEqual(escaped.indexOf('&'), -1, 'handles & aka &'); + assert.strictEqual(_.unescape(str), str, 'can unescape &'); + }); + + QUnit.test('template', function(assert) { var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); - var result = basicTemplate({thing : 'This'}); - equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); + var result = basicTemplate({thing: 'This'}); + assert.strictEqual(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); - var sansSemicolonTemplate = _.template("A <% this %> B"); - equal(sansSemicolonTemplate(), "A B"); + var sansSemicolonTemplate = _.template('A <% this %> B'); + assert.strictEqual(sansSemicolonTemplate(), 'A B'); - var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); - equal(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); + var backslashTemplate = _.template('<%= thing %> is \\ridanculous'); + assert.strictEqual(backslashTemplate({thing: 'This'}), 'This is \\ridanculous'); var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); - equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); + assert.strictEqual(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); - var fancyTemplate = _.template("
      <% \ - for (var key in people) { \ - %>
    • <%= people[key] %>
    • <% } %>
    "); - result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); - equal(result, "
    • Moe
    • Larry
    • Curly
    ", 'can run arbitrary javascript in templates'); + var fancyTemplate = _.template('
      <% ' + + ' for (var key in people) { ' + + '%>
    • <%= people[key] %>
    • <% } %>
    '); + result = fancyTemplate({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}}); + assert.strictEqual(result, '
    • Moe
    • Larry
    • Curly
    ', 'can run arbitrary javascript in templates'); - var escapedCharsInJavascriptTemplate = _.template("
      <% _.each(numbers.split('\\n'), function(item) { %>
    • <%= item %>
    • <% }) %>
    "); - result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"}); - equal(result, "
    • one
    • two
    • three
    • four
    ", 'Can use escaped characters (e.g. \\n) in Javascript'); + var escapedCharsInJavaScriptTemplate = _.template('
      <% _.each(numbers.split("\\n"), function(item) { %>
    • <%= item %>
    • <% }) %>
    '); + result = escapedCharsInJavaScriptTemplate({numbers: 'one\ntwo\nthree\nfour'}); + assert.strictEqual(result, '
    • one
    • two
    • three
    • four
    ', 'Can use escaped characters (e.g. \\n) in JavaScript'); - var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
    \">
    <% }); %>"); + var namespaceCollisionTemplate = _.template('<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
    <% }); %>'); result = namespaceCollisionTemplate({ pageCount: 3, thumbnails: { - 1: "p1-thumbnail.gif", - 2: "p2-thumbnail.gif", - 3: "p3-thumbnail.gif" + 1: 'p1-thumbnail.gif', + 2: 'p2-thumbnail.gif', + 3: 'p3-thumbnail.gif' } }); - equal(result, "3 p3-thumbnail.gif
    "); + assert.strictEqual(result, '3 p3-thumbnail.gif
    '); - var noInterpolateTemplate = _.template("

    Just some text. Hey, I know this is silly but it aids consistency.

    "); + var noInterpolateTemplate = _.template('

    Just some text. Hey, I know this is silly but it aids consistency.

    '); result = noInterpolateTemplate(); - equal(result, "

    Just some text. Hey, I know this is silly but it aids consistency.

    "); + assert.strictEqual(result, '

    Just some text. Hey, I know this is silly but it aids consistency.

    '); var quoteTemplate = _.template("It's its, not it's"); - equal(quoteTemplate({}), "It's its, not it's"); + assert.strictEqual(quoteTemplate({}), "It's its, not it's"); - var quoteInStatementAndBody = _.template("<%\ - if(foo == 'bar'){ \ - %>Statement quotes and 'quotes'.<% } %>"); - equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); + var quoteInStatementAndBody = _.template('<% ' + + " if(foo == 'bar'){ " + + "%>Statement quotes and 'quotes'.<% } %>"); + assert.strictEqual(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'."); var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); - equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); + assert.strictEqual(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); - var template = _.template("<%- value %>"); - var result = template({value: "