From f021e7fb767f39fb7fe0b614960ca097d11422dc Mon Sep 17 00:00:00 2001 From: "Deployment Bot (from Travis CI)" Date: Fri, 2 Oct 2020 15:31:46 +0000 Subject: [PATCH] Deploy angular-ui/ui-scroll to github.com/angular-ui/ui-scroll.git:gh-pages --- .babelrc | 15 + .gitignore | 4 + .jshintrc | 24 + .npmignore | 11 + .travis.yml | 28 + LICENSE | 21 + README.md | 593 + bower.json | 38 + demo/adapter/adapter.html | 76 + demo/adapter/adapter.js | 98 + demo/adapterSync/adapterSync.html | 104 + demo/adapterSync/adapterSync.js | 119 + demo/adapterSync/server.js | 161 + demo/animation/animation.html | 34 + demo/animation/animation.js | 68 + demo/append/append.html | 53 + demo/append/append.js | 34 + demo/append/server.js | 86 + demo/bottomVisible/bottomVisibleAdapter.html | 42 + demo/bottomVisible/bottomVisibleAdapter.js | 20 + demo/bufferItems/bufferItems.html | 52 + demo/bufferItems/bufferItems.js | 20 + demo/cache/cache.html | 50 + demo/cache/cache.js | 84 + demo/chat/chat.html | 42 + demo/chat/chat.js | 70 + demo/controllerAs/controllerAs.html | 49 + demo/controllerAs/controllerAs.js | 29 + demo/css/bootstrap.css | 6760 +++++++++++ demo/css/style.css | 345 + demo/css/style.less | 455 + .../differentItemHeights.html | 30 + .../differentItemHeights.js | 43 + demo/disabled/disabled.html | 44 + demo/disabled/disabled.js | 18 + demo/grid-dnd-sort-2/angular-dnd.js | 3462 ++++++ demo/grid-dnd-sort-2/grid-dnd-sort.html | 52 + demo/grid-dnd-sort-2/grid-dnd-sort.js | 45 + demo/grid-dnd-sort-2/grid.css | 28 + demo/grid-dnd-sort/grid-dnd-sort.html | 56 + demo/grid-dnd-sort/grid-dnd-sort.js | 56 + demo/grid-dnd-sort/grid.css | 28 + demo/grid-dnd-widths/grid-dnd-widths.html | 55 + demo/grid-dnd-widths/grid-dnd-widths.js | 57 + demo/grid-dnd-widths/grid.css | 40 + demo/grid-layout-apply/grid-layout-apply.html | 46 + demo/grid-layout-apply/grid-layout-apply.js | 43 + demo/grid-layout-apply/grid.css | 31 + .../grid-layout-manipulations.html | 66 + .../grid-layout-manipulations.js | 65 + demo/grid-layout-manipulations/grid.css | 31 + .../grid-scopes-wrapping.html | 39 + .../grid-scopes-wrapping.js | 45 + demo/grid-scopes-wrapping/grid.css | 31 + demo/index.html | 195 + demo/insideComponent/insideComponent.html | 32 + demo/insideComponent/insideComponent.js | 45 + demo/insideDirective/insideDirective.html | 33 + demo/insideDirective/insideDirective.js | 40 + demo/isLoading/isLoading.html | 43 + demo/isLoading/isLoading.js | 19 + demo/isLoading/isLoadingAdapter.html | 44 + demo/isLoading/isLoadingAdapter.js | 20 + demo/jquery/jquery.html | 37 + demo/jquery/jquery.js | 21 + demo/listScroller/listScroller.html | 40 + demo/listScroller/listScroller.js | 19 + demo/multipleLists/multipleLists.html | 49 + demo/multipleLists/multipleLists.js | 19 + demo/multipleReloadTest/multipleReload.html | 32 + demo/multipleReloadTest/multipleReload.js | 33 + demo/outOfBuffer/outOfBuffer.html | 49 + demo/outOfBuffer/outOfBuffer.js | 217 + demo/persistentScroll/persistentScroll.html | 38 + demo/persistentScroll/persistentScroll.js | 35 + demo/positionedList/positionedList.html | 38 + demo/positionedList/positionedList.js | 47 + demo/rebuilding/rebuilding.html | 40 + demo/rebuilding/rebuilding.js | 20 + demo/reload100/reload100.html | 43 + demo/reload100/reload100.js | 32 + demo/remote/remote.html | 34 + demo/remote/remote.js | 69 + demo/scopeDatasource/scopeDatasource.html | 49 + demo/scopeDatasource/scopeDatasource.js | 18 + .../scrollBubblingPrevent.html | 33 + .../scrollBubblingPrevent.js | 25 + demo/serviceDatasource/serviceDatasource.html | 48 + demo/serviceDatasource/serviceDatasource.js | 19 + demo/tableScroller/tableScroller.html | 54 + demo/tableScroller/tableScroller.js | 19 + demo/topVisible/topVisible.html | 41 + demo/topVisible/topVisible.js | 19 + demo/topVisible/topVisibleAdapter.html | 42 + demo/topVisible/topVisibleAdapter.js | 20 + demo/ui-scroll-demo.gif | Bin 0 -> 579557 bytes demo/userIndexes/userIndexes.html | 57 + demo/userIndexes/userIndexes.js | 42 + demo/visibility/visibility.html | 41 + demo/visibility/visibility.js | 19 + .../windowViewport/windowViewport-iframe.html | 39 + demo/windowViewport/windowViewport.html | 37 + demo/windowViewport/windowViewport.js | 19 + .../windowviewportInline.html | 94 + .../windowviewportInline.js | 35 + dist/ui-scroll-grid.js | 419 + dist/ui-scroll-grid.js.map | 1 + dist/ui-scroll-grid.min.js | 2 + dist/ui-scroll-grid.min.js.map | 1 + dist/ui-scroll-jqlite.js | 12 + dist/ui-scroll-jqlite.min.js | 1 + dist/ui-scroll.js | 1900 ++++ dist/ui-scroll.js.map | 1 + dist/ui-scroll.min.js | 2 + dist/ui-scroll.min.js.map | 1 + package-lock.json | 9909 +++++++++++++++++ package.json | 79 + src/modules/adapter.js | 232 + src/modules/buffer.js | 180 + src/modules/elementRoutines.js | 82 + src/modules/jqLiteExtras.js | 270 + src/modules/padding.js | 84 + src/modules/utils.js | 7 + src/modules/viewport.js | 219 + src/ui-scroll-grid.js | 267 + src/ui-scroll-jqlite.js | 12 + src/ui-scroll.js | 548 + test/.jshintrc | 33 + test/AdapterTestsSpec.js | 1233 ++ test/AssigningSpec.js | 234 + test/BasicSetupSpec.js | 112 + test/BasicTestsSpec.js | 756 ++ test/BufferCleanupSpec.js | 209 + test/GridTestsSpec.js | 406 + test/PaddingsSpec.js | 402 + test/UserIndicesSpec.js | 178 + test/VisibilitySwitchingSpec.js | 129 + test/config/karma.conf.files.js | 31 + test/config/karma.conf.js | 48 + test/jqliteExtrasSpec.js | 180 + test/misc/datasources.js | 228 + test/misc/helpers.js | 42 + test/misc/scaffolding.js | 87 + test/misc/scaffoldingGrid.js | 68 + test/misc/test.css | 6 + webpack.config.js | 162 + 146 files changed, 34922 insertions(+) create mode 100644 .babelrc create mode 100644 .gitignore create mode 100644 .jshintrc create mode 100644 .npmignore create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 bower.json create mode 100644 demo/adapter/adapter.html create mode 100644 demo/adapter/adapter.js create mode 100644 demo/adapterSync/adapterSync.html create mode 100644 demo/adapterSync/adapterSync.js create mode 100644 demo/adapterSync/server.js create mode 100644 demo/animation/animation.html create mode 100644 demo/animation/animation.js create mode 100644 demo/append/append.html create mode 100644 demo/append/append.js create mode 100644 demo/append/server.js create mode 100644 demo/bottomVisible/bottomVisibleAdapter.html create mode 100644 demo/bottomVisible/bottomVisibleAdapter.js create mode 100644 demo/bufferItems/bufferItems.html create mode 100644 demo/bufferItems/bufferItems.js create mode 100644 demo/cache/cache.html create mode 100644 demo/cache/cache.js create mode 100644 demo/chat/chat.html create mode 100644 demo/chat/chat.js create mode 100644 demo/controllerAs/controllerAs.html create mode 100644 demo/controllerAs/controllerAs.js create mode 100644 demo/css/bootstrap.css create mode 100644 demo/css/style.css create mode 100644 demo/css/style.less create mode 100644 demo/differentItemHeights/differentItemHeights.html create mode 100644 demo/differentItemHeights/differentItemHeights.js create mode 100644 demo/disabled/disabled.html create mode 100644 demo/disabled/disabled.js create mode 100644 demo/grid-dnd-sort-2/angular-dnd.js create mode 100644 demo/grid-dnd-sort-2/grid-dnd-sort.html create mode 100644 demo/grid-dnd-sort-2/grid-dnd-sort.js create mode 100644 demo/grid-dnd-sort-2/grid.css create mode 100644 demo/grid-dnd-sort/grid-dnd-sort.html create mode 100644 demo/grid-dnd-sort/grid-dnd-sort.js create mode 100644 demo/grid-dnd-sort/grid.css create mode 100644 demo/grid-dnd-widths/grid-dnd-widths.html create mode 100644 demo/grid-dnd-widths/grid-dnd-widths.js create mode 100644 demo/grid-dnd-widths/grid.css create mode 100644 demo/grid-layout-apply/grid-layout-apply.html create mode 100644 demo/grid-layout-apply/grid-layout-apply.js create mode 100644 demo/grid-layout-apply/grid.css create mode 100644 demo/grid-layout-manipulations/grid-layout-manipulations.html create mode 100644 demo/grid-layout-manipulations/grid-layout-manipulations.js create mode 100644 demo/grid-layout-manipulations/grid.css create mode 100644 demo/grid-scopes-wrapping/grid-scopes-wrapping.html create mode 100644 demo/grid-scopes-wrapping/grid-scopes-wrapping.js create mode 100644 demo/grid-scopes-wrapping/grid.css create mode 100644 demo/index.html create mode 100644 demo/insideComponent/insideComponent.html create mode 100644 demo/insideComponent/insideComponent.js create mode 100644 demo/insideDirective/insideDirective.html create mode 100644 demo/insideDirective/insideDirective.js create mode 100644 demo/isLoading/isLoading.html create mode 100644 demo/isLoading/isLoading.js create mode 100644 demo/isLoading/isLoadingAdapter.html create mode 100644 demo/isLoading/isLoadingAdapter.js create mode 100644 demo/jquery/jquery.html create mode 100644 demo/jquery/jquery.js create mode 100644 demo/listScroller/listScroller.html create mode 100644 demo/listScroller/listScroller.js create mode 100644 demo/multipleLists/multipleLists.html create mode 100644 demo/multipleLists/multipleLists.js create mode 100644 demo/multipleReloadTest/multipleReload.html create mode 100644 demo/multipleReloadTest/multipleReload.js create mode 100644 demo/outOfBuffer/outOfBuffer.html create mode 100644 demo/outOfBuffer/outOfBuffer.js create mode 100644 demo/persistentScroll/persistentScroll.html create mode 100644 demo/persistentScroll/persistentScroll.js create mode 100644 demo/positionedList/positionedList.html create mode 100644 demo/positionedList/positionedList.js create mode 100644 demo/rebuilding/rebuilding.html create mode 100644 demo/rebuilding/rebuilding.js create mode 100644 demo/reload100/reload100.html create mode 100644 demo/reload100/reload100.js create mode 100644 demo/remote/remote.html create mode 100644 demo/remote/remote.js create mode 100644 demo/scopeDatasource/scopeDatasource.html create mode 100644 demo/scopeDatasource/scopeDatasource.js create mode 100644 demo/scrollBubblingPrevent/scrollBubblingPrevent.html create mode 100644 demo/scrollBubblingPrevent/scrollBubblingPrevent.js create mode 100644 demo/serviceDatasource/serviceDatasource.html create mode 100644 demo/serviceDatasource/serviceDatasource.js create mode 100644 demo/tableScroller/tableScroller.html create mode 100644 demo/tableScroller/tableScroller.js create mode 100644 demo/topVisible/topVisible.html create mode 100644 demo/topVisible/topVisible.js create mode 100644 demo/topVisible/topVisibleAdapter.html create mode 100644 demo/topVisible/topVisibleAdapter.js create mode 100644 demo/ui-scroll-demo.gif create mode 100644 demo/userIndexes/userIndexes.html create mode 100644 demo/userIndexes/userIndexes.js create mode 100644 demo/visibility/visibility.html create mode 100644 demo/visibility/visibility.js create mode 100644 demo/windowViewport/windowViewport-iframe.html create mode 100644 demo/windowViewport/windowViewport.html create mode 100644 demo/windowViewport/windowViewport.js create mode 100644 demo/windowviewportInline/windowviewportInline.html create mode 100644 demo/windowviewportInline/windowviewportInline.js create mode 100644 dist/ui-scroll-grid.js create mode 100644 dist/ui-scroll-grid.js.map create mode 100644 dist/ui-scroll-grid.min.js create mode 100644 dist/ui-scroll-grid.min.js.map create mode 100644 dist/ui-scroll-jqlite.js create mode 100644 dist/ui-scroll-jqlite.min.js create mode 100644 dist/ui-scroll.js create mode 100644 dist/ui-scroll.js.map create mode 100644 dist/ui-scroll.min.js create mode 100644 dist/ui-scroll.min.js.map create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/modules/adapter.js create mode 100644 src/modules/buffer.js create mode 100644 src/modules/elementRoutines.js create mode 100644 src/modules/jqLiteExtras.js create mode 100644 src/modules/padding.js create mode 100644 src/modules/utils.js create mode 100644 src/modules/viewport.js create mode 100644 src/ui-scroll-grid.js create mode 100644 src/ui-scroll-jqlite.js create mode 100644 src/ui-scroll.js create mode 100644 test/.jshintrc create mode 100644 test/AdapterTestsSpec.js create mode 100644 test/AssigningSpec.js create mode 100644 test/BasicSetupSpec.js create mode 100644 test/BasicTestsSpec.js create mode 100644 test/BufferCleanupSpec.js create mode 100644 test/GridTestsSpec.js create mode 100644 test/PaddingsSpec.js create mode 100644 test/UserIndicesSpec.js create mode 100644 test/VisibilitySwitchingSpec.js create mode 100644 test/config/karma.conf.files.js create mode 100644 test/config/karma.conf.js create mode 100644 test/jqliteExtrasSpec.js create mode 100644 test/misc/datasources.js create mode 100644 test/misc/helpers.js create mode 100644 test/misc/scaffolding.js create mode 100644 test/misc/scaffoldingGrid.js create mode 100644 test/misc/test.css create mode 100644 webpack.config.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..026dc9b8 --- /dev/null +++ b/.babelrc @@ -0,0 +1,15 @@ +{ + "presets": [ + [ + "@babel/env", + { + "targets": { + "browsers": [ + "last 2 versions", + "IE >= 9" + ] + } + } + ] + ] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d714480e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules +temp +*.log +.idea \ No newline at end of file diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 00000000..42f00ed9 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,24 @@ +{ + "boss": true, + "browser": true, + "eqnull": true, + "expr": true, + "esversion": 6, + "immed": true, + "laxbreak": true, + "loopfunc": true, + "newcap": true, + "noarg": true, + "noempty": true, + "nonew": true, + "quotmark": true, + "smarttabs": true, + "strict": false, + "sub": true, + "trailing": true, + "undef": true, + "unused": true, + "globals": { + "angular": false + } +} diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..c8a70c46 --- /dev/null +++ b/.npmignore @@ -0,0 +1,11 @@ +.idea +/node_modules/ +/src +/temp +/test +.babelrc +.gitignore +.jshintrc +.npmignore +.travis.yml +webpack.config.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..9256c373 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +language: node_js + +node_js: +- "stable" + +install: +- npm install + +cache: + directories: + - "node_modules" + +addons: + firefox: latest + +services: +- xvfb + +script: +- npm run build + +deploy: + provider: pages + skip_cleanup: true + github_token: $github_token + local_dir: ./ + on: + branch: master diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..b27d53e7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2017 Hill30 INC, https://github.com/Hill30 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..64ca8dd5 --- /dev/null +++ b/README.md @@ -0,0 +1,593 @@ +### UI Scroll - [AngularJS](http://angularjs.org/) directive to provide infinite scroll over a limited element buffer + +[![Build Status](https://travis-ci.org/angular-ui/ui-scroll.svg?branch=master)](https://travis-ci.org/angular-ui/ui-scroll) +[![npm version](https://badge.fury.io/js/angular-ui-scroll.svg)](http://badge.fury.io/js/angular-ui-scroll) +[![Bower version](https://badge.fury.io/bo/angular-ui-scroll.svg)](http://badge.fury.io/bo/angular-ui-scroll) +[![Join the chat at https://gitter.im/angular-ui/ui-scroll](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/angular-ui/ui-scroll?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +

+looking for next Angular version? try ngx-ui-scroll +

+ +### Quick links + +- [Introduction](#introduction) + - [Why?](#why) + - [How it works](#how-it-works) + - [Basic usage](#basic-usage) + - [Examples](#examples) + - [Install and connect](#install-and-connect) +- [uiScroll directive](#uiscroll-directive) + - [Parameters](#parameters) + - [Datasource](#datasource) + - [Adapter](#adapter) +- [uiScrollViewport directive](#uiscrollviewport-directive) +- [jqLiteExtras service](#jqliteextras-service) +- [uiScrollTh and uiScrollTd](#uiscrollth-and-uiscrolltd-directives) + - [GridAdapter](#gridadapter) +- [Development](#development) +- [Change log](#change-log) + + +------------------- + + +## Introduction + + +### Why? + +The common way to present to the user a list of data elements of undefined length is to start with a small portion at the top of +the list - just enough to fill the space on the page. Additional rows are appended to the bottom of the list as the user scrolls +down the list. + +The problem with this approach is that even though rows at the top of the list become invisible as they scroll out of the view, +they are still a part of the page and still consume resources. As the user scrolls down the list grows and the web app slows down. + +This becomes a real problem if the html representing a row has event handlers and/or angular watchers attached. A web app of an average +complexity can easily introduce 20 watchers per row. Which for a list of 100 rows gives you total of 2000 watchers and a sluggish app. + + +### How it works + +The uiScroll directive solves the problem just described by dynamically destroying elements as they become invisible and recreating +them if they become visible again. + +The uiScroll directive is similar to the ngRepeat. Like the ngRepeat, uiScroll directive instantiates a template once per item from a +collection. Each template instance gets its own scope, where the given loop variable is set to the current collection item. The +collection content is provided by the datasource. + +The directive is asking the datasource for data to build and render elements until it has enough elements to fill out the viewport. +It will start retrieving new data for new elements again if the user scrolls up/down to the edge of visible element list. + + +![](https://raw.githubusercontent.com/angular-ui/ui-scroll/master/demo/ui-scroll-demo.gif) + + +### Basic usage + +```html + + + ... + + +``` +Listing `ANY` for the tag, the directive can be applied to, stretches the truth - a little bit. The directive works well with majority +of the 'usual' tags - divs, spans, a, inputs, etc. For all of them the viewport should be a div (unless it is the window). Some other +tags require special treatment. If the repeated tag is a li, it is best to use ul or ol as a viewport. For a tr as a repeated tag the +viewport has to be the table or tbody. dl as a repeated tag is not supported. + +The viewport is an element representing the space where the items from the collection are to be shown. Unless specified explicitly with +the [uiScrollViewport](#uiscrollviewport-directive) directive, browser window will be used as the viewport. + +_Important!_ The viewport height must be constrained. If the height of the viewport is not constrained +(style="height:auto") it will pull the entire content of the datasource and may throw an Error depending on the number of items +in the datasource. Even if it does not, using the directive this way does not provide any advantages over using ng-repeat, because +item template will be always instantiated for every item in the datasource. + +_Important!_ There is a Scroll Anchoring feature enforced by some browsers (e.g Google Chrome since v56) which makes scroller behavior incorrect. +The ui-scroll-viewport directive eliminates this effect by disabling the 'overflow-anchor' css-property on its element. +But if the ui-scroll-viewport is not presented in the template, you should take care of this manually by switching it off on the body/html container. + + +### Examples + +We have built pull of examples covering a number of use-cases, showing various ways to use the ui-scroll directive. Each demo is +absolutely independent and has its own html-page and the javascript file with the same name and .js extension. + +To run the examples use __[this link](http://rawgithub.com/angular-ui/ui-scroll/master/demo/index.html)__. + + +### Install and connect + +To install the package via __npm__ use + +``` +npm install --save angular-ui-scroll +``` + +After installation via npm, the ui-scroll distributive files will be available as + +``` + + + + + + + +
+ + browse other examples + +

Adapter (updatable scroller)

+ +
+
    +
  • This is a simple demo which demonstrates some basic Adapter usage.
  • +
  • For all operations presented here the only one Adapter method is being used: applyUpdates.
  • +
  • In this demo we have single datasource defined on the Main Controller .
  • +
  • And two different viewports with two different processing Adapters (on the First and the Second Controllers).
  • +
+
+ +
+

1st list

+ +
+ ...data loading... + 1st list is loaded +
+ +
+ + + +
+ +
+
{{item.content}}
+
+
+ +
+ +
+

2st list

+ +
+ ...data loading... + 2nd list is loaded +
+ +
+ + + +
+ +
+
{{item.content}}
+
+ +
+ +
+ + \ No newline at end of file diff --git a/demo/adapter/adapter.js b/demo/adapter/adapter.js new file mode 100644 index 00000000..f19d03e9 --- /dev/null +++ b/demo/adapter/adapter.js @@ -0,0 +1,98 @@ +angular.module('application', ['ui.scroll']) + + .controller('mainController', [ + '$scope', '$timeout', + function ($scope, $timeout) { + + $scope.title = 'Main Controller'; + + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + id: i, + content: "item #" + i + }); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + } + ]) + + .controller('firstController', ['$scope', function ($scope) { + $scope.title = 'First Controller'; + + $scope.firstListAdapter = { + remain: true + }; + + $scope.updateList1 = function () { + return $scope.firstListAdapter.applyUpdates(function (item, scope) { + return item.content += ' *'; + }); + }; + + $scope.removeFromList1 = function () { + return $scope.firstListAdapter.applyUpdates(function (item, scope) { + if (scope.$index % 2 === 0) { + return []; + } + }); + }; + + var idList1 = 1000; + $scope.addToList1 = function () { + return $scope.firstListAdapter.applyUpdates(function (item, scope) { + var newItem; + newItem = void 0; + if (scope.$index === 2) { + newItem = { + id: idList1, + content: 'a new one #' + idList1 + }; + idList1++; + return [item, newItem]; + } + }); + }; + }]) + + .controller('secondController', ['$scope', function ($scope) { + $scope.title = 'Second Controller'; + + $scope.updateList2 = function () { + return $scope.second.list.adapter.applyUpdates(function (item, scope) { + return item.content += ' *'; + }); + }; + + $scope.removeFromList2 = function () { + return $scope.second.list.adapter.applyUpdates(function (item, scope) { + if (scope.$index % 2 !== 0) { + return []; + } + }); + }; + + var idList2 = 2000; + $scope.addToList2 = function () { + return $scope.second.list.adapter.applyUpdates(function (item, scope) { + var newItem; + newItem = void 0; + if (scope.$index === 4) { + newItem = { + id: idList2, + content: 'a new one #' + idList2 + }; + idList2++; + return [item, newItem]; + } + }); + }; + }]); diff --git a/demo/adapterSync/adapterSync.html b/demo/adapterSync/adapterSync.html new file mode 100644 index 00000000..8444515c --- /dev/null +++ b/demo/adapterSync/adapterSync.html @@ -0,0 +1,104 @@ + + + + + Adapter sync + + + + + + + + + +
+ + browse other examples + +

Adapter: append, prepend and remove sync

+ +
+

+ This demo had been created to show Adapter 'append', 'prepend' and 'applyUpdates' methods in action. + The main point here is that all changes made on the front end have to be synced with the back end. + For this purpose a special Server module was introduced to emulate the remote server. + The following public methods are implemented by this Server factory:
+

    +
  • + request(index, count) just to fetch a bunch of items for the viewport (used by ui-scroll datasource.get); +
  • +
  • + appendItem(params) to add one new item (based on params) to the end of the remote data set; +
  • +
  • + prependItem(params) to add one new item (based on params) to the beginning of the remote data; +
  • +
  • + insertAfterIndex(index, params) to add one new item (based on params) after the item with given index; +
  • +
  • + removeFirst() remove first item; +
  • +
  • + removeLast() remove last item; +
  • +
  • + removeItemById(id) remove one item (based on id). +
  • +
+ The initial data set consists of 40 items and can be extended/reduced unlimitedly. +

+

+ The implementation of the Server factory is not trivial, it is based on indices variations. + Also you may see that new items would not be appended (via 'Append one item' or + 'Insert some after index' buttons) to the viewport immediately if the EOF (end of file) is not reached. + The same is true for prepend operations ('Prepend one item'): BOF (begin of file) must be reached, + otherwise your new items will be rendered only after scrolling to the very top... +

+
+ +
+ + + + + +
+ + +
+
+ +
+ + + +
+ + \ No newline at end of file diff --git a/demo/adapterSync/adapterSync.js b/demo/adapterSync/adapterSync.js new file mode 100644 index 00000000..388a52b2 --- /dev/null +++ b/demo/adapterSync/adapterSync.js @@ -0,0 +1,119 @@ +var app = angular.module('application', ['ui.scroll', 'server']); + +app.controller('mainController', [ + '$scope', 'Server', function ($scope, Server) { + + var ctrl = this; + + ctrl.datasource = { + get: function (index, count, success) { + console.log('request by index = ' + index + ', count = ' + count); + Server.request(index, count).then(function (result) { + if (result.items) { + console.log('resolved ' + result.items.length + ' items'); + } + success(result.items); + }); + } + }; + + $scope.$watch('adapter', (prev, next) => { + console.log('The adapter has been initialized'); + }); + + ctrl.prepend = function () { + Server.prependItem(' ***').then(function (newItem) { + if (ctrl.adapter.isBOF()) { + ctrl.adapter.prepend([newItem]); + } + }); + }; + + ctrl.append = function () { + Server.appendItem(' ***').then(function (newItem) { + if (ctrl.adapter.isEOF()) { + ctrl.adapter.append([newItem]); + } + }); + }; + + // todo dhilt : need to implement it properly + ctrl.removeAll = function () { + ctrl.adapter.applyUpdates(function (item) { + if (item.id) { + Server.removeItemById(item.id); + return []; + } + }); + }; + + ctrl.remove = function (itemRemove) { + Server.removeItemById(itemRemove.id).then(function (result) { + if (result !== false) { + ctrl.adapter.applyUpdates(function (item) { + if (item.id === itemRemove.id) { + return []; + } + }); + } + }); + }; + + ctrl.removeFirst = function () { + Server.removeFirst().then(function (indexRemoved) { + if (indexRemoved !== false) { + ctrl.adapter.applyUpdates(indexRemoved, []); + } + }); + }; + + ctrl.removeLast = function () { + Server.removeLast().then(function (indexRemoved) { + if (indexRemoved !== false) { + ctrl.adapter.applyUpdates(indexRemoved, []); + } + }); + }; + + ctrl.insertSome = function (indexToInsert) { + indexToInsert = parseInt(indexToInsert, 10); + var promises = [ + Server.insertAfterIndex(indexToInsert, ' *** (1)'), + Server.insertAfterIndex(indexToInsert + 1, ' *** (2)'), + Server.insertAfterIndex(indexToInsert + 2, ' *** (3)') + ]; + Promise.all(promises).then(function (result) { + if (result && result.length) { + // need to protect from null + var _result = []; + for(var i = 0; i < result.length; i++) { + if(result[i]) { + _result.push(result[i]); + } + } + if(_result.length) { + var item = getItemByIndex(indexToInsert); + if(item) { + _result.unshift(item); + } + ctrl.adapter.applyUpdates(indexToInsert, _result); + } + } + }); + }; + + function getItemByIndex(index) { + var foundItem = null; + // use Adapter.applyUpdates to get indexed item from Buffer + ctrl.adapter.applyUpdates(function (item) { + if (item.index === index) { + foundItem = item; + } + }); + return foundItem; + } + + ctrl.datasource.minIndex = Server.firstIndex; + ctrl.datasource.maxIndex = Server.lastIndex; + } +]); diff --git a/demo/adapterSync/server.js b/demo/adapterSync/server.js new file mode 100644 index 00000000..2d2ce191 --- /dev/null +++ b/demo/adapterSync/server.js @@ -0,0 +1,161 @@ +angular.module('server', []).factory('Server', + ['$timeout', '$q', function ($timeout, $q) { + + var ServerFactory = { + + firstIndex: 1, + + lastIndex: 40, + + delay: 100, + + data: [], + + absIndex: 1, + + generateId: function () { + var d = '-'; + function S4() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); + } + return (S4() + S4() + d + S4() + d + S4() + d + S4() + d + S4() + S4() + S4()); + }, + + generateItem: function (index) { + return { + index: index, + id: this.generateId(), + content: 'Item #' + this.absIndex++ + } + }, + + init: function () { + for (var i = this.firstIndex; i <= this.lastIndex; i++) { + this.data.push(this.generateItem(i)); + } + }, + + getItem: function (index) { + for (var i = this.data.length - 1; i >= 0; i--) { + if (this.data[i].index === index) { + return this.data[i]; + } + } + }, + + returnDeferredResult: function (result) { + var deferred = $q.defer(); + $timeout(function () { + deferred.resolve(result); + }, this.delay); + return deferred.promise; + }, + + request: function (index, count) { + var start = index; + var end = index + count - 1; + var item, result = { + items: [] + }; + if (start <= end) { + for (var i = start; i <= end; i++) { + if (item = this.getItem(i)) { + result.items.push(item); + } + } + } + return this.returnDeferredResult(result); + }, + + prependItem: function (params) { + var newItem = this.generateItem(--this.firstIndex); + newItem.content += params; + this.data.unshift(newItem); + return this.returnDeferredResult(newItem); + }, + + appendItem: function (params) { + var newItem = this.generateItem(++this.lastIndex); + newItem.content += params; + this.data.push(newItem); + return this.returnDeferredResult(newItem); + }, + + removeFirst: function () { + var firstItem = this.data.find(i => i.index === this.firstIndex); + if(!firstItem) { + return $q.reject(); + } + return this.removeItemById(firstItem.id); + }, + + removeLast: function () { + var lastItem = this.data.find(i => i.index === this.lastIndex); + if(!lastItem) { + return $q.reject(); + } + return this.removeItemById(lastItem.id); + }, + + removeItemById: function (itemId) { + var length = this.data.length; + for (var i = 0; i < length; i++) { + if (this.data[i].id === itemId) { + var indexRemoved = this.data[i].index; + if(indexRemoved > this.firstIndex) { + for (var j = i; j < length; j++) { + this.data[j].index--; + } + } + this.data.splice(i, 1); + this.setIndices(); + return this.returnDeferredResult(indexRemoved); + } + } + return this.returnDeferredResult(false); + }, + + insertAfterIndex: function (index, params) { + if(index < this.firstIndex || index > this.lastIndex) { + return this.returnDeferredResult(null); + } + var length = this.data.length, item; + for (var i = 0; i < length; i++) { + if (this.data[i].index === index) { + for (var j = i + 1; j < length; j++) { + this.data[j].index++; + } + item = this.generateItem(index + 1); + item.content += params; + this.data.splice(i + 1, 0, item); + this.setIndices(); + return this.returnDeferredResult(item); + } + } + return this.returnDeferredResult(null); + }, + + setIndices: function () { + if(!this.data.length) { + this.firstIndex = 1; + this.lastIndex = 1; + return; + } + this.firstIndex = this.data[0].index; + this.lastIndex = this.data[0].index; + for (var i = this.data.length - 1; i >= 0; i--) { + if(this.data[i].index > this.lastIndex) { + this.lastIndex = this.data[i].index; + } + if(this.data[i].index < this.firstIndex) { + this.firstIndex = this.data[i].index; + } + } + } + }; + + ServerFactory.init(); + + return ServerFactory; + } +]); diff --git a/demo/animation/animation.html b/demo/animation/animation.html new file mode 100644 index 00000000..13d3f8c0 --- /dev/null +++ b/demo/animation/animation.html @@ -0,0 +1,34 @@ + + + + + Scroller Demo (animation) + + + + + + + +
+ browse other examples +

Animation demo

+ +
+ + + + +
+ +
+
+ {{$index}}) {{item.content}} +
+
+
+ + \ No newline at end of file diff --git a/demo/animation/animation.js b/demo/animation/animation.js new file mode 100644 index 00000000..56b2f1e7 --- /dev/null +++ b/demo/animation/animation.js @@ -0,0 +1,68 @@ +angular.module('application', ['ui.scroll', 'ngAnimate']).controller('mainController', [ + '$scope', '$log', '$timeout', function($scope, console, $timeout) { + var datasource, idList; + datasource = {}; + datasource.get = function(index, count, success) { + return $timeout(function() { + var i, item, j, ref, ref1, result; + result = []; + for (i = j = ref = index, ref1 = index + count - 1; ref <= ref1 ? j <= ref1 : j >= ref1; i = ref <= ref1 ? ++j : --j) { + if (i <= 0 || i > 14) { + continue; + } + item = {}; + item.id = i; + item.content = "item #" + i; + result.push(item); + } + return success(result); + }, 100); + }; + $scope.datasource = datasource; + $scope.adapterContainer = { + adapter: { + remain: true + } + }; + $scope.updateList = function() { + return $scope.adapterContainer.adapter.applyUpdates(function(item, scope) { + return item.content += ' *'; + }); + }; + $scope.removeFromList = function() { + return $scope.adapterContainer.adapter.applyUpdates(function(item, scope) { + if (scope.$index % 2 === 0) { + return []; + } + }); + }; + $scope.refresh = function() { + return $scope.adapterContainer.adapter.reload(); + }; + idList = 1000; + return $scope.addToList = function() { + return $scope.adapterContainer.adapter.applyUpdates(function(item, scope) { + var newItem; + newItem = void 0; + if (scope.$index === 2) { + newItem = { + id: idList, + content: 'a new one #' + idList + }; + idList++; + return [item, newItem]; + } + }); + }; + } +]); + + + + +/* +//# sourceURL=src/animation.js + */ + +// --- +// generated by coffee-script 1.9.2 \ No newline at end of file diff --git a/demo/append/append.html b/demo/append/append.html new file mode 100644 index 00000000..23f3fdda --- /dev/null +++ b/demo/append/append.html @@ -0,0 +1,53 @@ + + + + + Append and prepend + + + + + + + + +
+ + browse other examples + +

Adapter: append and prepend sync

+ +
+

+ This sample demonstrates an ability to append and prepend new items to the initial data set via adapter. + New appended and prepended items have to be synced with the real data source. + For this purpose a special Server module was implemented to emulate the remote. + The Server hides all indices magic, so the front-end controller logic (ui-scroll datasource implementation) looks very simple. +

+

+ Two methods are implemented on the controller's scope: prepend and append. + They work with two Server methods: prependItem and appendItem. + The additional point is that new items would not be appended to the viewport if the EOF (end of file) is not reached. + Also new items would not be prepended to the viewport if the BOF (begin of file) is not reached. +

+

+ For more complex and powerful sample you may follow this demo. +

+
+ +
+ + +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/demo/append/append.js b/demo/append/append.js new file mode 100644 index 00000000..636602f8 --- /dev/null +++ b/demo/append/append.js @@ -0,0 +1,34 @@ +var app = angular.module('application', ['ui.scroll', 'server']); + +app.controller('mainController', [ + '$scope', 'Server', + function($scope, Server) { + + $scope.datasource = { + get: function(index, count, success) { + console.log('request by index = ' + index + ', count = ' + count); + Server.request(index, count).then(function(result) { + if (result.items.length) { + console.log('resolved ' + result.items.length + ' items'); + } + success(result.items); + }); + } + }; + + $scope.prepend = function() { + var newItem = Server.prependItem(' (new)*'); + if ($scope.adapter.isBOF()) { + $scope.adapter.prepend([newItem]); + } + }; + + $scope.append = function() { + var newItem = Server.appendItem(' (new)*'); + if ($scope.adapter.isEOF()) { + $scope.adapter.append([newItem]); + } + }; + + } +]); \ No newline at end of file diff --git a/demo/append/server.js b/demo/append/server.js new file mode 100644 index 00000000..51a90a86 --- /dev/null +++ b/demo/append/server.js @@ -0,0 +1,86 @@ +angular.module('server', []).factory('Server', + ['$timeout', '$q', function($timeout, $q) { + + var ServerFactory = { + + max: 50, + + first: 1, + + delay: 100, + + data: [], + + prependedData: [], + + appendedData: [], + + generateItem: function(number) { + return { + number: number, + content: 'Item #' + number + } + }, + + init: function() { + for (var i = this.first - 1; i <= this.max; i++) { + this.data.push(this.generateItem(i)); + } + }, + + getItem: function(index) { + if (index < this.first) { + return this.prependedData[(-1) * index]; + } else if (index > this.max) { + return this.appendedData[index - this.max - 1]; + } else { + return this.data[index]; + } + }, + + request: function(index, count) { + var self = this; + var deferred = $q.defer(); + + var start = index; + var end = index + count - 1; + + $timeout(function() { + var item, result = { + items: [] + }; + if (start <= end) { + for (var i = start; i <= end; i++) { + if (item = self.getItem(i)) { + result.items.push(item); + } + } + } + deferred.resolve(result); + }, self.delay); + + return deferred.promise; + }, + + prependItem: function(params) { + var prependedDataIndex = this.first - this.prependedData.length - 1; + var newItem = this.generateItem(prependedDataIndex); + newItem.content += params; + this.prependedData.push(newItem); + return newItem; + }, + + appendItem: function(params) { + var appendedDataIndex = this.max + this.appendedData.length + 1; + var newItem = this.generateItem(appendedDataIndex); + newItem.content += params; + this.appendedData.push(newItem); + return newItem; + } + }; + + ServerFactory.init(); + + return ServerFactory; + } +]); diff --git a/demo/bottomVisible/bottomVisibleAdapter.html b/demo/bottomVisible/bottomVisibleAdapter.html new file mode 100644 index 00000000..e55187b7 --- /dev/null +++ b/demo/bottomVisible/bottomVisibleAdapter.html @@ -0,0 +1,42 @@ + + + + + Bottom visible (Adapter) + + + + + + + +
+ + browse other examples + +

Bottom visible (Adapter)

+ +
+ The Adapter implements bottomVisible property which is a reference to the item currently in the very bottom visible position. + +
+
<li ui-scroll="item in datasource" adapter="adapter">*{{item}}*</li>
+
+ +
+
bottom visible: {{adapter.bottomVisible}}
+
+
+ +
+
bottom visible: {{adapter.bottomVisible}}
+
+ +
+
*{{item}}*
+
+ +
+ + + \ No newline at end of file diff --git a/demo/bottomVisible/bottomVisibleAdapter.js b/demo/bottomVisible/bottomVisibleAdapter.js new file mode 100644 index 00000000..8f2e18f5 --- /dev/null +++ b/demo/bottomVisible/bottomVisibleAdapter.js @@ -0,0 +1,20 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + + $scope.adapter = {}; + + $scope.datasource = {}; + + $scope.datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + } + ]); diff --git a/demo/bufferItems/bufferItems.html b/demo/bufferItems/bufferItems.html new file mode 100644 index 00000000..6b3ac7b5 --- /dev/null +++ b/demo/bufferItems/bufferItems.html @@ -0,0 +1,52 @@ + + + + + + Buffer first, last, length + + + + + + + + +
+ + browse other examples + +

Buffer first, last, length

+ +
+ The ui-scroll Adapter has 3 read-only properties which provide information of current ui-scroll Buffer state. + The buffer contains some visible items and some items that are out of visible part of the viewport. + So with these properties we can get the topmost and the bottommost items that the ui-scroll is dealing with at the moment. + At the template's layer it may look like + +
+
{{adapter.bufferFirst}}
+{{adapter.bufferLast}}
+{{adapter.bufferLength}}
+
+<li ui-scroll="item in datasource" adapter="adapter">{{item}}</li>
+
+
+ +
+
First buffer {{adapter.bufferFirst}}
+
Last buffer {{adapter.bufferLast}}
+
Buffer length: {{adapter.bufferLength}}
+
+ +
+
    +
  • {{item}}
  • +
+
+ +
+ + + + \ No newline at end of file diff --git a/demo/bufferItems/bufferItems.js b/demo/bufferItems/bufferItems.js new file mode 100644 index 00000000..5fbd1302 --- /dev/null +++ b/demo/bufferItems/bufferItems.js @@ -0,0 +1,20 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + + $scope.adapter = {}; + + $scope.datasource = {}; + + $scope.datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 0); + }; + + } + ]); diff --git a/demo/cache/cache.html b/demo/cache/cache.html new file mode 100644 index 00000000..c1fb5238 --- /dev/null +++ b/demo/cache/cache.html @@ -0,0 +1,50 @@ + + + + + Scroller Demo (cache option) + + + + + + + +
+ + browse other examples + +

Cache within datasource implementation

+ +
+

+ The cache that is implemented here is a facade over standard datasource. + So all you need here is to initialize Cache: +

+
datasource.cache.initialize();
+
+ Base data retrieving method datasource.get() isn't changed. + It may has any implementation like no any cache is presented. +

+

+ You may disable/enable Cache programmatically: +

+
datasource.cache.isEnabled = true;
+
+ Toggle-link demonstrates this ability. You can see the difference between cache and no-cache modes because of $timeout back-end delay emulation on datasource.get. +

+
+ +
+ Cache is {{datasource.cache.isEnabled ? 'enabled' : 'disabled'}} + [toggle] +
+ +
+
*{{item.content}}*
+
+ +
+ + + \ No newline at end of file diff --git a/demo/cache/cache.js b/demo/cache/cache.js new file mode 100644 index 00000000..d79a6b88 --- /dev/null +++ b/demo/cache/cache.js @@ -0,0 +1,84 @@ +angular.module('application', ['ui.scroll']).controller('mainController', [ + '$scope', '$log', '$timeout', function($scope, console, $timeout) { + + var datasource = {}; + + datasource.cache = { + initialize: function() { + this.isEnabled = true; + this.items = {}; + this.getPure = datasource.get; + return datasource.get = this.getCached; + }, + + getCached: function(index, count, successCallback) { + var self; + self = datasource.cache; + if (self.isEnabled) { + if (self.getItems(index, count, successCallback)) { + return; + } + return self.getPure(index, count, function(result) { + self.saveItems(index, count, result); + return successCallback(result); + }); + } + return self.getPure(index, count, successCallback); + }, + + toggle: function() { + this.isEnabled = !this.isEnabled; + return this.items = {}; + }, + + saveItems: function(index, count, resultItems) { + var i, item, j, len, results; + results = []; + for (i = j = 0, len = resultItems.length; j < len; i = ++j) { + item = resultItems[i]; + if (!this.items.hasOwnProperty(index + i)) { + results.push(this.items[index + i] = item); + } else { + results.push(void 0); + } + } + return results; + }, + + getItems: function(index, count, successCallback) { + var i, isCached, j, ref, ref1, result; + result = []; + isCached = true; + for (i = j = ref = index, ref1 = index + count - 1; j <= ref1; i = j += 1) { + if (!this.items.hasOwnProperty(i)) { + isCached = false; + return; + } + result.push(this.items[i]); + } + successCallback(result); + return true; + } + }; + + datasource.get = function(index, count, success) { + return $timeout(function() { + var i, item, j, ref, ref1, result; + result = []; + for (i = j = ref = index, ref1 = index + count - 1; ref <= ref1 ? j <= ref1 : j >= ref1; i = ref <= ref1 ? ++j : --j) { + item = {}; + item.content = "item #" + i; + item.data = { + some: false + }; + result.push(item); + } + return success(result); + }, 100); + }; + + $scope.datasource = datasource; + + datasource.cache.initialize(); + } +]); \ No newline at end of file diff --git a/demo/chat/chat.html b/demo/chat/chat.html new file mode 100644 index 00000000..e684b906 --- /dev/null +++ b/demo/chat/chat.html @@ -0,0 +1,42 @@ + + + + + Chat demo + + + + + + + +
+ + browse other examples + +

Chat demo

+ +
+ Chat demo provides: +
- initial position at the bottom of the dataset
+
- scroll up to retrieve new items with positive indexes
+
- special Server service to emulate the remote
+
+ +
+
{{adapter.topVisible.title}} -- top visible item
+
{{adapter.bottomVisible.title}} -- bottom visible item
+
+ + + +
+ + + \ No newline at end of file diff --git a/demo/chat/chat.js b/demo/chat/chat.js new file mode 100644 index 00000000..6433f25a --- /dev/null +++ b/demo/chat/chat.js @@ -0,0 +1,70 @@ +var app = angular.module('application', ['ui.scroll']); + +app.factory('Server', [ + '$timeout', '$q', function ($timeout, $q) { + + return { + + max: 99, + + first: 1, + + delay: 100, + + data: [], + + init: function () { + for (var i = this.first; i <= this.max; i++) { + this.data.push({ + number: i, + title: 'Message #' + i, + text: Math.random().toString(36).substring(7) + }); + } + }, + + request: function (start, end) { + var self = this; + var deferred = $q.defer(); + + $timeout(function () { + var result = []; + if (start <= end) { + for (var i = start; i <= end; i++) { + var serverDataIndex = (-1) * i + self.first; + var item = self.data[serverDataIndex]; + if (item) { + result.push(item); + } + } + } + deferred.resolve(result); + }, self.delay); + + return deferred.promise; + } + }; + + } +]); + + +app.controller('mainController', [ + '$scope', 'Server', function ($scope, Server) { + var datasource = {}; + + Server.init(); + + datasource.get = function (index, count, success) { + console.log('index = ' + index + '; count = ' + count); + + var start = index; + var end = Math.min(index + count - 1, Server.first); + + Server.request(start, end).then(success); + }; + + $scope.datasource = datasource; + + } +]); diff --git a/demo/controllerAs/controllerAs.html b/demo/controllerAs/controllerAs.html new file mode 100644 index 00000000..9c3c4f2f --- /dev/null +++ b/demo/controllerAs/controllerAs.html @@ -0,0 +1,49 @@ + + + + + Scroller Demo (controller as) + + + + + + + +
+ browse other examples +

Controller as syntax for the Datasource and the Adapter

+
+ If you have defined your controller in such way +
+
<div ng-controller="mainController as mainCtrl">
+
+ then you just shouldn't miss it when you define your datasource or adapter: +
+
<div ui-scroll="item in mainCtrl.datasource" adapter="mainCtrl.adapter">{{item}}</div>
+
+ "Hide/Show" button provides a nested scope between mainController and the Viewport via ng-if directive. +
+ +
+ + +
+ +
+ data has been loaded + data loading... +
+ +
+
+
{{item.content}} +
+
+
+
+ + + \ No newline at end of file diff --git a/demo/controllerAs/controllerAs.js b/demo/controllerAs/controllerAs.js new file mode 100644 index 00000000..a18158a6 --- /dev/null +++ b/demo/controllerAs/controllerAs.js @@ -0,0 +1,29 @@ +angular.module('application', ['ui.scroll']).controller('mainController', [ + '$timeout', function($timeout) { + + var datasource = {}; + + datasource.get = function(index, count, success) { + return $timeout(function() { + var i, item, j, ref, ref1, result; + result = []; + for (i = j = ref = index, ref1 = index + count - 1; ref <= ref1 ? j <= ref1 : j >= ref1; i = ref <= ref1 ? ++j : --j) { + item = {}; + item.id = i; + item.content = "item #" + i; + result.push(item); + } + return success(result); + }, 100); + }; + + this.datasource = datasource; + + this.updateList = function() { + this.adapter.applyUpdates(function(item, scope) { + item.content += ' *'; + }); + }; + + } +]); diff --git a/demo/css/bootstrap.css b/demo/css/bootstrap.css new file mode 100644 index 00000000..42c79d6e --- /dev/null +++ b/demo/css/bootstrap.css @@ -0,0 +1,6760 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\002a"; +} +.glyphicon-plus:before { + content: "\002b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +[role="button"] { + cursor: pointer; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover, +a.text-primary:focus { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover, +a.text-success:focus { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover, +a.text-info:focus { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover, +a.text-warning:focus { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover, +a.text-danger:focus { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover, +a.bg-primary:focus { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover, +a.bg-success:focus { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover, +a.bg-warning:focus { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover, +a.bg-danger:focus { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + min-height: .01%; + overflow-x: auto; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #eee; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + min-height: 34px; + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-right: 0; + padding-left: 0; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 11px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #fff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #fff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #337ab7; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group .form-control:focus { + z-index: 3; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #9d9d9d; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #9d9d9d; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 2; + color: #23527c; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 3; + color: #fff; + cursor: default; + background-color: #337ab7; + border-color: #337ab7; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: #777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge, +.btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #fff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron, +.container-fluid .jumbotron { + padding-right: 15px; + padding-left: 15px; + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-object.img-thumbnail { + max-width: none; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item, +button.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + color: #777; + cursor: not-allowed; + background-color: #eee; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success, +button.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info, +button.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-right: 15px; + padding-left: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #337ab7; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; +} +.panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + filter: alpha(opacity=0); + opacity: 0; + + line-break: auto; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + right: 5px; + bottom: 0; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + + line-break: auto; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + background-color: rgba(0, 0, 0, 0); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + margin-top: -10px; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + font-family: serif; + line-height: 1; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -10px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -10px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -10px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-header:before, +.modal-header:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-header:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/demo/css/style.css b/demo/css/style.css new file mode 100644 index 00000000..71b32929 --- /dev/null +++ b/demo/css/style.css @@ -0,0 +1,345 @@ +@import "../css/bootstrap.css"; +.global { + padding: 20px 0; +} +.cont { + width: 970px; + margin: 0 auto; + padding: 0 10px; +} +.cont.cont-global { + padding-top: 20px; + padding-bottom: 20px; +} +.cont-in-frame { + width: 930px; + margin: 0 auto; +} +.example-list { + padding: 0 0 0 15px; +} +.example-list li { + list-style: none; + margin: .7em 0; +} +.example-list li a { + position: relative; +} +.example-list li a:before { + content: "\2022"; + position: absolute; + left: -15px; + font-size: 20px; + top: -2px; + line-height: 1em; +} +.more-wrap { + border-top: 1px solid #eee; + margin-top: 20px; + padding: 10px 0; +} +.back:before { + content: "<< "; +} +.page-header { + margin-top: .1em; +} +.page-header.page-header-exapmle { + margin-top: .2em; + margin-bottom: .2em; +} +.description { + margin: 15px 0; + border-left: 5px #e6e6e6 solid; + padding-left: 15px; +} +.description ul { + padding-left: 20px; +} +.code { + margin-top: 10px; +} +/*info*/ +.info, +.info-if-frame { + border-radius: 5px; + padding: 10px; + font-family: monospace, monospace; +} +.info { + background: #f2f2f2; + margin: 10px 0; +} +.info-if-frame-wrap { + position: fixed; + top: 5px; + left: 0; + right: 0; +} +.info-if-frame { + float: right; + position: relative; + z-index: 100; + margin-right: 10px; + background: #fff; + min-width: 150px; + border: 1px #d9d9d9 solid; + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.1); + opacity: .6; +} +.info-if-frame:hover { + opacity: 1; +} +/*!info*/ +.actions { + margin: 10px 0; + border-radius: 5px; + padding: 10px; + border: 1px #f2f2f2 solid; +} +.actions label { + font-weight: normal; +} +.viewport-iframe, +.viewport { + border: 1px #cccccc solid; + border-radius: 5px; +} +/*iframe*/ +.iframe-wrap { + margin-top: 15px; +} +.iframe-wrap .iframe-top > * { + display: inline-block; + vertical-align: middle; + padding: 3px 10px 7px 12px; +} +.iframe-wrap .iframe-top .iframe-title { + background: #b3b3b3; + border-radius: 5px 5px 0 0; + color: #fff; + line-height: 20px; + margin: 0; + font-size: 14px; + font-weight: normal; +} +.iframe-wrap .viewport-iframe { + width: 100%; + height: 300px; + margin-top: -5px; +} +@media screen and (min-height: 500px) { + .iframe-wrap .viewport-iframe { + height: calc(100vh - 225px); + /*custom*/ + /*!custom*/ + } +} +/*!iframe*/ +/*viewport*/ +.viewport-group { + border: 1px #b3b3b3 solid; + border-radius: 5px; + padding: 10px; + margin: 30px 0; +} +.viewport-group .viewport-group-tilte { + float: left; + margin: -1.2em 0 0 6px; + font-weight: bold; + font-size: 15px; + background: #fff; + padding: 0 8px; +} +.viewport-group .actions { + border: none; + padding: 0; +} +.viewport-wrap { + margin-top: 15px; +} +.viewport-wrap .viewport-title { + display: inline-block; + padding: 3px 10px 7px 12px; + background: #b3b3b3; + border-radius: 5px 5px 0 0; + color: #fff; + line-height: 20px; + margin: 0; + font-size: 14px; + font-weight: normal; +} +.viewport2 { + height: 300px; + list-style: none; + padding: 0; + width: 400px; +} +.viewport2 .uid { + font-size: small; + color: #aaa; +} +.viewport { + margin-top: 15px; + height: 300px; + overflow: auto; + /*custom*/ + /*!custom*/ +} +.viewport-wrap .viewport { + margin-top: -5px; + position: relative; + background: #fff; +} +.viewport .item { + padding: 3px 5px; +} +.viewport .item:nth-child(odd) { + background-color: #e6e6e6; +} +.viewport table { + width: 100%; +} +.viewport table td { + border: 1px #d9d9d9 solid; + padding: 5px; +} +.viewport table td:first-child { + border-left: none; +} +.viewport table td:last-child { + border-right: none; +} +@media screen and (min-height: 500px) { + .viewport:not(.viewport-height-fixed) { + height: calc(100vh - 200px); + /*custom*/ + /*!custom*/ + } + .viewport:not(.viewport-height-fixed)#viewport-persistentScroll { + height: calc(100vh - 300px); + } + .viewport:not(.viewport-height-fixed)#viewport-positionedList { + height: calc(100vh - 320px); + } + .viewport:not(.viewport-height-fixed)#viewport-listScroller { + height: calc(100vh - 280px); + } + .viewport:not(.viewport-height-fixed)#viewport-windowviewportInline { + height: calc(100vh - 230px); + } + .viewport:not(.viewport-height-fixed)#viewport-cache { + height: calc(100vh - 300px); + } +} +.viewport#viewport-multipleList-2 .item { + background-color: transparent; + border-top: 1px #d9d9d9 dotted; +} +.viewport#viewport-multipleList-2 .item:first-child { + border-top: none; +} +.viewport#viewport-multipleList-2 .item ul { + margin-bottom: 0; + padding-left: 20px; +} +.viewport#viewport-tableScroller table td:first-child { + width: 1%; + text-align: center; +} +.viewport#viewport-windowviewportInline .item-inline { + display: inline-block; +} +.viewport#viewport-windowviewportInline .item-inline .item-inline-inn { + display: inline-block; +} +.viewport#viewport-listScroller ul { + padding-left: 20px; +} +.viewport#viewport-listScroller ul li { + margin: 7px 0; +} +.viewport#viewport-animation { + height: auto; + max-height: 300px; +} +.viewport#viewport-animation .item.ng-leave, +.viewport#viewport-animation .item.ng-enter { + -webkit-transition: 0.75s linear all; + transition: 0.75s linear all; +} +.viewport#viewport-animation .item.ng-enter { + opacity: 0; + color: yellow; + height: 0; +} +.viewport#viewport-animation .item.ng-enter.ng-enter-active { + opacity: 1; + color: black; + height: 18px; +} +.viewport#viewport-animation .item.ng-leave { + opacity: 1; + color: black; + height: 18px; +} +.viewport#viewport-animation .item.ng-leave.ng-leave-active { + opacity: 0; + color: red; + height: 0; +} +#viewport-scrollBubblingPrevent-wrap { + background-color: rgba(255, 249, 0, 0.28); + padding: 300px 0; + position: relative; +} +#viewport-scrollBubblingPrevent-wrap:before, +#viewport-scrollBubblingPrevent-wrap:after { + content: "wrapper"; + position: absolute; + width: 100%; + text-align: center; + font-size: 50px; + opacity: .2; + vertical-align: middle; + line-height: 1; +} +#viewport-scrollBubblingPrevent-wrap:before { + top: 120px; +} +#viewport-scrollBubblingPrevent-wrap:after { + bottom: 120px; +} +.toggler { + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} +.viewport-in-frame .item { + padding: 3px 5px; +} +.viewport-in-frame .item:nth-child(odd) { + background-color: #e6e6e6; +} +/*!viewport*/ +.chat { + height: 300px; + padding-left: 10px; +} +.chat .item { + height: 50px; + list-style-type: none; + border: 0 dotted #ddd; + border-bottom-width: 1px; +} +.chat .item .number { + font-weight: bolder; +} +.chat .item .text { + margin-left: 10px; + font-style: italic; +} +.chat .item:last-child { + border-bottom-width: 0; +} diff --git a/demo/css/style.less b/demo/css/style.less new file mode 100644 index 00000000..c29ef0ee --- /dev/null +++ b/demo/css/style.less @@ -0,0 +1,455 @@ +@import "../css/bootstrap.css"; + +.global { + padding: 20px 0; +} + +.cont { + width: 970px; + margin: 0 auto; + padding: 0 10px; + + &.cont-global { + padding-top: 20px; + padding-bottom: 20px; + } +} + +.cont-in-frame { + width: 930px; + margin: 0 auto; +} + +.example-list { + padding: 0 0 0 15px; + + li { + list-style: none; + margin: .7em 0; + + a { + position: relative; + + &:before { + content: "\2022"; + position: absolute; + left: -15px; + font-size: 20px; + top: -2px; + line-height: 1em; + } + } + } + +} + +.more-wrap { + border-top: 1px solid #eee; + margin-top: 20px; + padding: 10px 0; +} + +.back:before { + content: "<< "; +} + +.page-header { + margin-top: .1em; + + &.page-header-exapmle { + margin-top: .2em; + margin-bottom: .2em; + } +} + +.description { + margin: 15px 0; + border-left: 5px hsl(0,0%,90%) solid; + padding-left: 15px; + + ul { + padding-left: 20px; + } +} + +.code { + margin-top: 10px; +} + + +/*info*/ +.info, .info-if-frame { + border-radius: 5px; + padding: 10px; + font-family: monospace, monospace; +} + + + +.info { + background: hsl(0,0%,95%); + margin: 10px 0; +} + +.info-if-frame-wrap { + position: fixed; + top: 5px; + left: 0; + right: 0; +} + + +.info-if-frame { + float: right; + position: relative; + z-index: 100; + margin-right: 10px; + background: #fff; + min-width: 150px; + border: 1px hsl(0,0%,85%) solid; + box-shadow: 2px 2px 2px hsla(0,0%,0%,.1); + opacity: .6; + + &:hover { + opacity: 1; + } +} + + +/*!info*/ + +.actions { + margin: 10px 0; + border-radius: 5px; + padding: 10px; + border: 1px hsl(0,0%,95%) solid; + + label { + font-weight: normal; + } +} + +.item() { + padding: 3px 5px; + + &:nth-child(odd) { + background-color: hsl(0,0%,90%); + } +} + + +.viewport-iframe, +.viewport { + border: 1px hsl(0,0%,80%) solid; + border-radius: 5px; +} + +/*iframe*/ +.iframe-wrap { + margin-top: 15px; + + .iframe-top { + + > * { + display: inline-block; + vertical-align: middle; + padding: 3px 10px 7px 12px; + } + + .iframe-title { + background: hsl(0,0%,70%); + border-radius: 5px 5px 0 0; + color: #fff; + line-height: 20px; + margin: 0; + font-size: 14px; + font-weight: normal; + } + } + + .viewport-iframe { + width: 100%; + height: 300px; + margin-top: -5px; + + + @media screen and (min-height: 500px) { + height: calc(~"100vh - 225px"); + + /*custom*/ + &#windowviewport { + + } + /*!custom*/ + } + + } +} + + +/*!iframe*/ + +/*viewport*/ +.viewport-group { + border: 1px hsl(0,0%,70%) solid; + border-radius: 5px; + padding: 10px; + margin: 30px 0; + + + .viewport-group-tilte { + float: left; + margin: -1.2em 0 0 6px; + font-weight: bold; + font-size: 15px; + background: #fff; + padding: 0 8px; + } + + .actions { + border: none; + padding: 0; + } +} + + + + + + +.viewport-wrap { + margin-top: 15px; + + .viewport-title { + display: inline-block; + padding: 3px 10px 7px 12px; + background: hsl(0,0%,70%); + border-radius: 5px 5px 0 0; + color: #fff; + line-height: 20px; + margin: 0; + font-size: 14px; + font-weight: normal; + } +} + +.viewport2 { + height: 300px; + list-style: none; + padding: 0; + width: 400px; + .uid { + font-size: small; + color: #aaa; + } +} + +.viewport { + margin-top: 15px; + height: 300px; + overflow: auto; + + .viewport-wrap & { + margin-top: -5px; + position: relative; + background: #fff; + } + + .item { + .item; + } + + table { + width: 100%; + + + td { + border: 1px hsl(0,0%,85%) solid; + padding: 5px; + + &:first-child { + border-left: none; + } + + &:last-child { + border-right: none; + } + } + } + + &:not(.viewport-height-fixed) { + + @media screen and (min-height: 500px) { + height: calc(~"100vh - 200px"); + + /*custom*/ + &#viewport-persistentScroll { + height: calc(~"100vh - 300px"); + } + + &#viewport-positionedList { + height: calc(~"100vh - 320px"); + } + + &#viewport-listScroller { + height: calc(~"100vh - 280px"); + } + + &#viewport-windowviewportInline { + height: calc(~"100vh - 230px"); + } + + &#viewport-cache { + height: calc(~"100vh - 300px"); + } + /*!custom*/ + + } + + } + + + + /*custom*/ + &#viewport-multipleList-2 { + .item { + background-color: transparent; + border-top: 1px hsl(0,0%,85%) dotted; + + &:first-child { + border-top: none; + } + + ul { + margin-bottom: 0; + padding-left: 20px; + } + } + } + + &#viewport-tableScroller { + table { + td:first-child { + width: 1%; + text-align: center; + } + } + + } + + &#viewport-windowviewportInline { + .item-inline { + display: inline-block; + + .item-inline-inn { + display: inline-block; + } + } + } + + + + &#viewport-listScroller { + ul { + padding-left: 20px; + + li { + margin: 7px 0; + } + } + } + + &#viewport-animation { + height: auto; + max-height: 300px; + + .item.ng-leave, .item.ng-enter { + -webkit-transition: 0.75s linear all; + transition: 0.75s linear all; + } + + .item.ng-enter { opacity: 0; color: yellow; height: 0; } + .item.ng-enter.ng-enter-active { opacity: 1; color: black; height: 18px; } + + .item.ng-leave { opacity: 1; color: black; height: 18px; } + .item.ng-leave.ng-leave-active { opacity: 0; color: red; height: 0; } + } + /*!custom*/ + + + +} + + +#viewport-scrollBubblingPrevent-wrap { + background-color: rgba(255, 249, 0, 0.28); + padding: 300px 0; + position: relative; + + &:before, + &:after { + content: "wrapper"; + position: absolute; + width: 100%; + text-align: center; + font-size: 50px; + opacity: .2; + vertical-align: middle; + line-height: 1; + } + + &:before { + top: 120px; + } + + &:after { + bottom: 120px; + } +} + +.toggler { + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + + +.viewport-in-frame { + + .item { + .item; + } + +} + +/*!viewport*/ + +.chat { + height: 300px; + padding-left: 10px; + + .item { + height: 50px; + list-style-type: none; + border: 0 dotted #ddd; + border-bottom-width: 1px; + + .number { + font-weight: bolder; + } + + .text { + margin-left: 10px; + font-style: italic; + + } + } + + .item:last-child { + border-bottom-width: 0; + } +} + + + diff --git a/demo/differentItemHeights/differentItemHeights.html b/demo/differentItemHeights/differentItemHeights.html new file mode 100644 index 00000000..f3216cf1 --- /dev/null +++ b/demo/differentItemHeights/differentItemHeights.html @@ -0,0 +1,30 @@ + + + + + Different Item Heights + + + + + + + +
+ + browse other examples + +

Different Item Heights (Interpolation)

+ +
+
+
+
+ {{"item #" + item.index + ' (h = ' + item.height + ')'}} +
+
+
+
+ + + diff --git a/demo/differentItemHeights/differentItemHeights.js b/demo/differentItemHeights/differentItemHeights.js new file mode 100644 index 00000000..7fe54172 --- /dev/null +++ b/demo/differentItemHeights/differentItemHeights.js @@ -0,0 +1,43 @@ +angular.module('application', ['ui.scroll']) + +.run(function($rootScope) { + $rootScope.doReload = function () { + $rootScope.$broadcast('DO_RELOAD'); + }; +}) + +.controller('MainCtrl', function($scope) { + $scope.hello = 'Hello Main Controller!'; + + var reloadListener = $scope.$on('DO_RELOAD', function() { + if ($scope.adapter) { + $scope.adapter.reload(); + } + }); + + $scope.$on("$destroy", function() { + reloadListener(); + }); + + var min = -50, max = 100, delay = 0; + + $scope.datasource = { + get: function(index, count, success) { + console.log('Getting ' + count + ' items started from ' + index + '...'); + setTimeout(function() { + var result = []; + var start = Math.max(min, index); + var end = Math.min(index + count - 1, max); + if (start <= end) { + for (var i = start; i <= end; i++) { + height = 50 + (i + 1); + result.push({ index: i, height: height }); + } + } + console.log('Got ' + result.length + ' items [' + start + '..' + end + ']'); + success(result); + }, delay); + } + }; + +}); diff --git a/demo/disabled/disabled.html b/demo/disabled/disabled.html new file mode 100644 index 00000000..c9b4a3b4 --- /dev/null +++ b/demo/disabled/disabled.html @@ -0,0 +1,44 @@ + + + + + Disabling + + + + + + + +
+ + browse other examples + +

Disabled attribute

+ +
+ There is an property "disabled" on the ui-scroll adapter which allows to ignore user scroll/resize events: + +
+
<div ui-scroll="item in datasource" adapter="myAdapter">{{item}}</div>
+
+ Here we have two-way binding, so just set the property in appropriate time: +
+
$scope.myAdapter.disabled = true;
+
+ Since "disabled" is true no user scroll is being processed by ui-scroll engine. + +
+ +
+ User scroll processing is {{myAdapter.disabled ? "disabled" : "enabled"}} now
+ +
+ +
+
{{item}}
+
+ +
+ + \ No newline at end of file diff --git a/demo/disabled/disabled.js b/demo/disabled/disabled.js new file mode 100644 index 00000000..30219f1a --- /dev/null +++ b/demo/disabled/disabled.js @@ -0,0 +1,18 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + } + ]); diff --git a/demo/grid-dnd-sort-2/angular-dnd.js b/demo/grid-dnd-sort-2/angular-dnd.js new file mode 100644 index 00000000..e9df0819 --- /dev/null +++ b/demo/grid-dnd-sort-2/angular-dnd.js @@ -0,0 +1,3462 @@ +;(function(angular, undefined, window, document){ + + + /** + * @license AngularJS-DND v0.1.23 + * (c) 2014-2015 Alexander Afonin (toafonin@gmail.com, http://github.com/Tuch) + * License: MIT + */ + + 'use strict'; + + /* + + ================= + ANGULAR DND: + ================= + + */ + + /* ENVIRONMENT VARIABLES */ + + var version = '0.1.23', + $ = angular.element, $window = $(window), $document = $(document), body = 'body', TRANSFORM, TRANSFORMORIGIN, MATCHES_SELECTOR, + debug = { + mode: false, + helpers: {} + }, + forEach = angular.forEach, + extend = angular.extend; + + (function () { + window.console = window.console || { + log: noop, + info: noop, + warn: noop, + error: noop + }; + })(); + + (function() { + var agent = navigator.userAgent; + + if ( /webkit\//i.test(agent) ) { + TRANSFORM = '-webkit-transform'; + TRANSFORMORIGIN = '-webkit-transform-origin'; + MATCHES_SELECTOR = 'webkitMatchesSelector'; + } else if (/gecko\//i.test(agent)) { + TRANSFORM = '-moz-transform'; + TRANSFORMORIGIN = '-moz-transform-origin'; + MATCHES_SELECTOR = 'mozMatchesSelector'; + } else if (/trident\//i.test(agent)) { + TRANSFORM = '-ms-transform'; + TRANSFORMORIGIN = 'ms-transform-origin'; + MATCHES_SELECTOR = 'msMatchesSelector'; + } else if (/presto\//i.test(agent)) { + TRANSFORM = '-o-transform'; + TRANSFORMORIGIN = '-o-transform-origin'; + MATCHES_SELECTOR = 'oMatchesSelector'; + } else { + TRANSFORM = 'transform'; + TRANSFORMORIGIN = 'transform-origin'; + MATCHES_SELECTOR = 'matches'; + } + + })(); + + + + /* SOME HELPERS */ + + function noop() {} + + function doFalse() { + return false; + } + + function doTrue() { + return true; + } + + function proxy(context, fn) { + return function() { + fn.apply(context, arguments); + }; + } + + function degToRad(d) { + return (d * (Math.PI / 180)); + } + + function radToDeg(r) { + return (r * (180 / Math.PI)); + } + + function getNumFromSegment(min, curr, max) { + return curr max ? max : curr; + } + + function findEvents(element) { + + var events = element.data('events'); + if (events !== undefined) { + return events; + } + + events = $.data(element, 'events'); + if (events !== undefined) { + return events; + } + + events = $._data(element, 'events'); + if (events !== undefined) { + return events; + } + + events = $._data(element[0], 'events'); + if (events !== undefined) { + return events; + } + + return undefined; + } + + function debounce(fn, timeout, invokeAsap, context) { + if (arguments.length === 3 && typeof invokeAsap !== 'boolean') { + context = invokeAsap; + invokeAsap = false; + } + + var timer; + + return function() { + var args = arguments; + context = context || this; + + if (invokeAsap && !timer) { + fn.apply(context, args); + } + + clearTimeout(timer); + + timer = setTimeout(function() { + if (!invokeAsap) { + fn.apply(context, args); + } + + timer = null; + + }, timeout); + + }; + } + + function throttle(fn, timeout, context) { + var timer, args; + + return function() { + if (timer) { + return; + } + + args = arguments; + context = context || this; + fn.apply(context, args); + timer = setTimeout(function() { timer = null; }, timeout); + }; + } + + + /* parsing like: ' a = fn1(), b = fn2()' into {a: 'fn1()', b: 'fn2()'} */ + + function parseStringAsVars(str) { + if (!str) { + return undefined; + } + + var a = str.replace(/\s/g,'').split(','), ret = {}; + + for( var i = 0; i < a.length; i++ ) { + a[i] = a[i].split('='); + ret[a[i][0]] = a[i][1]; + } + + return ret; + } + + function avgPerf (fn1, timeout, context, callback) { + context = context || this; + timeout = timeout || 1000; + callback = callback || function(val) { + console.log(val); + }; + + var time = []; + + var fn2 = debounce(function() { + var sum = 0; + + for(var i=0; i < time.length; i++) { + sum += time[i]; + } + + callback( Math.round(sum / time.length) ); + + time = []; + + }, timeout); + + return function() { + var start = Date.now(); + + fn1.apply(context, arguments); + + time.push(Date.now() - start); + + fn2(); + + }; + } + + function roundNumber(number, n) { + if (isNaN(n)) { + n=0; + } + + var m = Math.pow(10,n); + return Math.round(number * m) / m; + } + + + /* POINT OBJECT */ + + var Point = (function() { + function Point(x, y) { + if (typeof x === 'object') { + y = x.y || x.top; + x = x.x || x.left; + } + + this.x = x || 0; + this.y = y || 0; + } + + Point.prototype = { + equal: function(other) { + if (!(other instanceof Point)) { + other = new Point(other); + } + + return this.x === other.x && this.y === other.y; + }, + plus: function(other) { + if (!(other instanceof Point)) { + other = new Point(other); + } + + return new Point(this.x + other.x, this.y + other.y); + }, + minus: function(other) { + if (!(other instanceof Point)) { + other = new Point(other); + } + + return new Point(this.x - other.x, this.y - other.y); + }, + scale: function(scalar) { + return new Point(this.x * scalar, this.y * scalar); + }, + magnitude: function() { + return this.distance(new Point(0, 0), this); + }, + distance: function(other) { + if (!(other instanceof Point)) { + other = new Point(other); + } + + return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2)); + }, + angle: function (other, isdegree) { + var ret = Math.atan2( + other.y - this.y, + other.x - this.x + ); + + if (isdegree===true) { + ret *= 180/Math.PI; + } + + return ret; + }, + deltaAngle: function(other, aboutPoint, isdegree) { + aboutPoint = aboutPoint === undefined ? {x:0,y:0} : aboutPoint; + var ret = this.angle(aboutPoint) - other.angle(aboutPoint); + + if (ret < 0) { + ret = Math.PI*2 + ret; + } + + if (isdegree===true) { + ret *= 180/Math.PI; + } + + return ret; + }, + transform: function(matrix) { + return matrix.transformPoint(this); + }, + deltaTransform: function(matrix) { + return matrix.deltaTransformPoint(this); + }, + rotate: function(rads, aboutPoint) { + var matrix = (new Matrix()).rotate(rads, aboutPoint); + + return this.transform(matrix); + }, + getAsCss: function() { + return { + top: this.y, + left: this.x + }; + } + }; + + return function(x,y) { + return new Point(x,y); + }; + })(); + + + + /* MATRIX OBJECT */ + + var Matrix = (function() { + function Matrix(a, b, c, d, tx, ty) { + this.a = a !== undefined ? a : 1; + this.b = b || 0; + this.c = c || 0; + this.d = d !== undefined ? d : 1; + this.tx = tx || 0; + this.ty = ty || 0; + } + + Matrix.prototype = { + concat: function(other) { + return new Matrix( + this.a * other.a + this.c * other.b, + this.b * other.a + this.d * other.b, + this.a * other.c + this.c * other.d, + this.b * other.c + this.d * other.d, + this.a * other.tx + this.c * other.ty + this.tx, + this.b * other.tx + this.d * other.ty + this.ty + ); + }, + inverse: function() { + var determinant = this.a * this.d - this.b * this.c; + + return new Matrix( + this.d / determinant, + -this.b / determinant, + -this.c / determinant, + this.a / determinant, + (this.c * this.ty - this.d * this.tx) / determinant, + (this.b * this.tx - this.a * this.ty) / determinant + ); + }, + rotate: function(theta, aboutPoint) { + var rotationMatrix = new Matrix( + Math.cos(theta), + Math.sin(theta), + -Math.sin(theta), + Math.cos(theta) + ); + + if (aboutPoint) { + rotationMatrix = this.translate(aboutPoint.x, aboutPoint.y).concat(rotationMatrix).translate(-aboutPoint.x, -aboutPoint.y); + } + + return this.concat(rotationMatrix); + }, + scale: function(sx, sy, aboutPoint) { + sy = sy || sx; + + var scaleMatrix = new Matrix(sx, 0, 0, sy); + + if (aboutPoint) { + scaleMatrix = scaleMatrix.translate(aboutPoint.x, aboutPoint.y).translate(-aboutPoint.x, -aboutPoint.y); + } + + return scaleMatrix; + }, + translate: function(tx, ty) { + var translateMatrix = new Matrix(1, 0, 0, 1, tx, ty); + + return this.concat(translateMatrix); + }, + + transformPoint: function(point) { + return new Point( + this.a * point.x + this.c * point.y + this.tx, + this.b * point.x + this.d * point.y + this.ty + ); + }, + deltaTransformPoint: function(point) { + return new Point( + this.a * point.x + this.c * point.y, + this.b * point.x + this.d * point.y + ); + }, + toStyle: function() { + var a = roundNumber(this.a, 3), + b = roundNumber(this.b, 3), + c = roundNumber(this.c, 3), + d = roundNumber(this.d, 3), + tx = roundNumber(this.tx, 3), + ty = roundNumber(this.ty, 3), + result = 'matrix(' + a + ', ' + b + ', ' + c + ', ' + d + ', ' + tx +', ' + ty + ')'; + + return result === 'matrix(1, 0, 0, 1, 0, 0)' ? 'none' : result; + } + }; + + var fn = function(a, b, c, d, tx, ty) { + return new Matrix(a, b, c, d, tx, ty); + }; + + fn.IDENTITY = new Matrix(); + fn.HORIZONTAL_FLIP = new Matrix(-1, 0, 0, 1); + fn.VERTICAL_FLIP = new Matrix(1, 0, 0, -1); + + return fn; + }()); + + /* RECT OBJECT */ + + var Rect = (function() { + function Rect(tl, tr, bl, br) { + this.tl = tl; + this.tr = tr; + this.bl = bl; + this.br = br; + } + + Rect.prototype = { + applyMatrix: function(matrix, aboutPoint) { + var tl, tr, bl, br, + translateIn = new Matrix(1,0,0,1,aboutPoint.x,aboutPoint.y), + translateOut = new Matrix(1,0,0,1,-aboutPoint.x,-aboutPoint.y); + + if (aboutPoint !== undefined) { + tl = this.tl.transform(translateOut).transform(matrix).transform(translateIn); + tr = this.tr.transform(translateOut).transform(matrix).transform(translateIn); + bl = this.bl.transform(translateOut).transform(matrix).transform(translateIn); + br = this.br.transform(translateOut).transform(matrix).transform(translateIn); + } else { + tl = this.tl.transform(matrix); + tr = this.tr.transform(matrix); + bl = this.bl.transform(matrix); + br = this.br.transform(matrix); + } + + return new Rect(tl, tr, bl, br); + }, + width: function() { + var dx = this.tl.x - this.tr.x; + var dy = this.tl.y - this.tr.y; + return Math.sqrt(dx*dx+dy*dy); + }, + height: function() { + var dx = this.tl.x - this.bl.x; + var dy = this.tl.y - this.bl.y; + return Math.sqrt(dx*dx+dy*dy); + }, + client: function() { + var top = Math.min(this.tl.y, this.tr.y, this.bl.y, this.br.y); + var left = Math.min(this.tl.x, this.tr.x, this.bl.x, this.br.x); + var height = Math.max(this.tl.y, this.tr.y, this.bl.y, this.br.y)-top; + var width = Math.max(this.tl.x, this.tr.x, this.bl.x, this.br.x)-left; + + return { + top: roundNumber(top,1), + left: roundNumber(left,1), + height: roundNumber(height,1), + width: roundNumber(width,1), + bottom: roundNumber(top+height, 1), + right: roundNumber(left+width, 1) + }; + }, + getAngle: function(degs) { + var y = this.tl.y-this.tr.y; + var x = this.tl.x-this.tr.x; + + return Math.tan(x/y)*180/Math.PI; + } + }; + + var fn = function(left, top, width, height) { + var args = arguments; + + if (typeof args[0] === 'object') { + top = args[0].top; + left = args[0].left; + width = args[0].width; + height = args[0].height; + } + + return new Rect( + new Point(left,top), + new Point(left+width,top), + new Point(left,top+height), + new Point(left+width,top+height) + ); + }; + + fn.fromPoints = function(tl,tr,bl,br) { + return new Rect( tl,tr,bl,br ); + }; + + return fn; + })(); + + /* JQLITE EXTENDING */ + + extend($.prototype, { + + dndDisableSelection: function() { + this.on('dragstart selectstart', doFalse ).dndCss({ + '-moz-user-select': 'none', + '-khtml-user-select': 'none', + '-webkit-user-select': 'none', + '-o-user-select': 'none', + '-ms-user-select': 'none', + 'user-select': 'none' + }); + }, + + dndEnableSelection: function() { + this.off('dragstart selectstart', doFalse ).dndCss({ + '-moz-user-select': 'auto', + '-khtml-user-select': 'auto', + '-webkit-user-select': 'auto', + '-o-user-select': 'auto', + '-ms-user-select': 'auto', + 'user-select': 'auto' + }); + }, + + dndClientRect: function() { + if (!this[0]) { + return; + } + + var DOMRect = this[0] === window ? {top:0,bottom:0,left:0,right:0,width:0,height:0} : this[0].getBoundingClientRect(); + + return { + bottom: DOMRect.bottom, + height: DOMRect.height, + left: DOMRect.left, + right: DOMRect.right, + top: DOMRect.top, + width: DOMRect.width, + }; + }, + + dndStyleRect: function() { + var styles = this.dndCss(['width','height','top','left']); + + var width = parseFloat(styles.width); + var height = parseFloat(styles.height); + + var top = styles.top === 'auto' ? 0 : parseFloat(styles.top); + var left = styles.left === 'auto' ? 0 : parseFloat(styles.left); + + return {top: top, right: left+width, bottom: top+height, left: left, width: width, height: height}; + }, + + dndGetParentScrollArea: function() { + var ret = [], parents = this.dndClosest(), scrollX, clientX, scrollY, clientY, paddingX, paddingY, paddings, htmlEl = document.documentElement; + + forEach(parents, function(element) { + + paddings = $(element).dndCss(['padding-top', 'padding-right', 'padding-bottom', 'padding-left']); + + scrollX = element.scrollWidth; + clientX = element.clientWidth; + scrollY = element.scrollHeight; + clientY = element.clientHeight; + + paddingY = parseFloat(paddings['padding-top']) + parseFloat(paddings['padding-bottom']); + paddingX = parseFloat(paddings['padding-left']) + parseFloat(paddings['padding-right']); + + if ( scrollX - paddingX !== clientX || scrollY - paddingY !== clientY ) { + ret.push(element); + } + }); + + ret.push(window); + + return $(ret); + }, + + dndGetFirstNotStaticParent: function() { + var ret, position, parents = this.dndClosest(); + + forEach(parents, function(element) { + + position = $(element).dndCss('position'); + + if ( position === 'absolute' || position === 'relative' || position === 'fixed' ) { + ret = element; + return false; + } + }); + + if (!ret) { + ret = document.documentElement; + } + + return $(ret); + }, + + dndClosest: function(selector) { + selector = selector || '*'; + var parent = this[0], ret = []; + + while(parent) { + parent[MATCHES_SELECTOR](selector) && ret.push(parent); + parent = parent.parentElement; + } + + return $(ret); + }, + dndGetAngle: function (degs) { + var matrix = this.dndCss(TRANSFORM); + + if (matrix === 'none' || matrix === '') { + return 0; + } + + var values = matrix.split('(')[1].split(')')[0].split(','), + a = values[0], b = values[1], rads = Math.atan2(b, a); + + rads = rads < 0 ? rads +=Math.PI*2 : rads; + + return degs ? Math.round(rads * 180/Math.PI) : rads; + }, + + dndCloneByStyles: function () { + var ret = []; + + for (var i = 0, length = this.length; i < length; i++) { + var node = this[i].cloneNode(); + var childNodes = angular.element(this[i].childNodes).dndCloneByStyles(); + + angular.element(node).append(childNodes); + + if (node.nodeType === 1) { + node.style.cssText = window.getComputedStyle(this[i], "").cssText; + } + + ret.push(node); + } + + return angular.element(ret); + }, + + dndCss: (function() { + var SPECIAL_CHARS_REGEXP = /([\:\-\_\.]+(.))/g, + MOZ_HACK_REGEXP = /^moz([A-Z])/, hooks = {}; + + function toCamelCase(string) { + return string.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) { + return offset ? letter.toUpperCase() : letter; + }).replace(MOZ_HACK_REGEXP, 'Moz$1'); + } + + (function() { + var arr = { + width: ['paddingLeft','paddingRight','borderLeftWidth', 'borderRightWidth'], + height: ['paddingTop','paddingBottom','borderTopWidth', 'borderBottomWidth'] + }; + + forEach(arr, function(styles, prop) { + + hooks[prop] = { + get: function(element) { + var computed = window.getComputedStyle(element); + var ret = computed[prop]; + + if ( computed.boxSizing !== 'border-box' || ret[ret.length-1] === '%') { + return ret; + } + + ret = parseFloat(ret); + + for(var i = 0; i < styles.length; i++) { + ret -= parseFloat(computed[ styles[i] ]); + } + + return ret + 'px'; + } + }; + + }); + + })(); + + var cssNumber = { + 'columnCount': true, + 'fillOpacity': true, + 'fontWeight': true, + 'lineHeight': true, + 'opacity': true, + 'order': true, + 'orphans': true, + 'widows': true, + 'zIndex': true, + 'zoom': true + }; + + var setCss = function($element, obj) { + var styles = {}; + + for(var key in obj) { + var val = obj[key]; + + if ( typeof val === 'number' && !cssNumber[key] ) { + val += 'px'; + } + + styles[toCamelCase(key)] = val; + } + + $element.css(styles); + + return $element; + }; + + var getCss = function($element, arg) { + var ret = {}; + + if (!$element[0]) { + return undefined; + } + + var style = $element[0].style; + var computed = window.getComputedStyle( $element[0], null ); + + if (typeof arg === 'string') { + if (style[arg]) { + return style[arg]; + } else { + return hooks[arg] && 'get' in hooks[arg] ? hooks[arg].get($element[0]) : computed.getPropertyValue( arg ); + } + } + + for(var i=0; i < arg.length; i++) { + if (style[arg[i]]) { + ret[arg[i]] = style[ arg[i] ]; + } else { + ret[arg[i]] = hooks[arg[i]] && 'get' in hooks[arg[i]] ? hooks[arg[i]].get($element[0]) : computed.getPropertyValue( arg[i] ); + } + } + + return ret; + }; + + function css() { + var a = arguments; + + if ( (a.length === 1) && ((a[0] instanceof Array) || (typeof a[0] === 'string')) ) { + return getCss(this, a[0]); + } else if ( (a.length === 1) && (typeof a[0] === 'object') ) { + return setCss(this, a[0]); + } else if ( a.length === 2 ) { + var obj = {}; + + obj[a[0]] = a[1]; + + return setCss(this, obj); + } + + return this; + + } + + return css; + })() + }); + + /* INIT ANGULAR MODULE */ + + var module = angular.module('dnd', []); + + /* ANGULAR.ELEMENT DND PLUGIN - CORE OF ANGULAR-DND */ + + (function() { + + var Regions = (function() { + var list = {}; + + function Regions(layer) { + if (!list[layer]) { + list[layer] = []; + } + + this.layer = function() { + return layer; + }; + } + + Regions.prototype = { + get: function() { + return list[this.layer()]; + }, + + remove: function(el) { + var index = this.get().indexOf(el); + + if (index > -1) { + this.get().splice(index,1); + } + }, + + has: function(el) { + return this.get().indexOf(el) > -1; + }, + + add: function(el) { + if (this.has(el)) { + return; + } + + this.get().push(el); + + var self = this; + + $(el).on('$destroy', function() { self.remove(el); }); + }, + + }; + + return Regions; + })(); + + var Dnd = (function() { + + var events = [ 'dragstart', 'drag', 'dragend', 'dragenter', 'dragover', 'dragleave', 'drop' ]; + var draggables = [ 'dragstart', 'drag', 'dragend' ]; + var droppables = [ 'dragenter', 'dragover', 'dragleave', 'drop' ]; + var handled = false; + + draggables.has = droppables.has = function(event) { + return this.indexOf(event) > -1; + }; + + var touchevents; + if ('ontouchstart' in document.documentElement) { + touchevents = {start: 'touchstart', move: 'touchmove', end: 'touchend', cancel: 'touchcancel'}; + } else if ('pointerEnabled' in window.navigator) { + touchevents = {start: 'pointerdown', move: 'pointermove', end: 'pointerup', cancel: 'pointercancel'}; + } else if ('msPointerEnabled' in window.navigator) { + touchevents = {start: 'MSPointerDown', move: 'MSPointerMove', end: 'MSPointerUp', cancel: 'MSPointerCancel'}; + } else { + touchevents = {start: 'touchstart', move: 'touchmove', end: 'touchend', cancel: 'touchcancel'}; + } + + function Dnd(el, layer) { + this.el = el; + this.$el = $(el); + this.listeners = { 'dragstart':[], 'drag':[], 'dragend':[], 'dragenter':[], 'dragover':[], 'dragleave':[], 'drop':[] }; + this.regions = new Regions(layer); + this.layer = function() { + return layer; + }; + this.setCurrentManipulator(null); + } + + Dnd.prototype = { + _isEmptyListeners: function(event) { + if (event instanceof Array) { + + for(var i=0; i < event.length; i++ ) { + if (!this._isEmptyListeners(event[i])) { + return false; + } + } + + } else if (this.listeners[event].length > 0) { + return false; + } + + return true; + }, + + addListener: function(event, handler) { + if (events.indexOf(event) === -1) { + console.error('jquery.dnd: invalid event name - ', event); + return this; + } + this.listeners[event].push( handler); + + if ( droppables.has(event) ) { + this.regions.add(this.el); + } else if (draggables.has(event) && !this.mouse && !this.touch) { + if ('onmousedown' in window) { + this.mouse = new Mouse(this); + } + if ( ('ontouchstart' in window) || ('onmsgesturechange' in window) ) { + this.touch = new Touch(this, touchevents); + } + + } + + return this; + }, + + removeListener: function(event, handler) { + var args = arguments; + + if (args.length === 0) { + for( var key in this.listeners ) { + this.listeners[key].length = 0; + } + } else if (args.length === 1) { + this.listeners[event].length = 0; + } else { + var listeners = this.listeners[event]; + + for(var i=0; i < listeners.length; i++) { + if ( listeners[i] === handler ) listeners[event].splice(i,1); + } + + } + + if ( this._isEmptyListeners(droppables) ) this.regions.remove(this.el); + else if ( this._isEmptyListeners(draggables)) this.destroy(); + + return this; + }, + + trigger: function(event, api, el) { + for(var i=0; i < this.listeners[event].length; i++) { + this.listeners[event][i].call(this.$el, api, el); + } + + return this; + }, + + destroy: function() { + if ( this.mouse ) { + this.mouse.destroy(); + delete this.mouse; + } + + if ( this.touch ) { + this.touch.destroy(); + delete this.touch; + } + + return this; + }, + + setCurrentManipulator: function (manipulator) { + this._manipulator = manipulator; + + return this; + }, + + getCurrentManipulator: function () { + return this._manipulator; + } + }; + + + return Dnd; + })(); + + var Api = (function() { + + function Api(manipulator) { + this._manipulator = manipulator; + } + + Api.prototype = { + getAxis: function() { + return this._manipulator.getClientAxis.apply(this._manipulator, arguments); + }, + getBorderedAxis: function() { + return this._manipulator.getBorderedAxis.apply(this._manipulator, arguments); + }, + getRelBorderedAxis: function() { + return this._manipulator.getRelBorderedAxis.apply(this._manipulator, arguments); + }, + getDragTarget: function() { + return this._manipulator.dnd.el; + }, + getDropTarget: function() { + return this._manipulator.target; + }, + getEvent: function() { + return this._manipulator.event; + }, + isTarget: function() { + return this._manipulator.isTarget.apply(this._manipulator, arguments); + }, + unTarget: function() { + this._manipulator.removeFromTargets(); + }, + useAsPoint: function(value) { + return this._manipulator.asPoint = !(value === false); + }, + setBounderElement: function(node) { + this._manipulator.$bounder = angular.element(node); + this.clearCache(); + }, + setReferenceElement: function(node) { + this._manipulator.$reference = angular.element(node); + }, + getBorders: function() { + return this._manipulator.getBorders.apply(this._manipulator, arguments); + }, + getReferencePoint: function() { + return this._manipulator.getReferencePoint.apply(this._manipulator, arguments); + }, + clearCache: function() { + this._manipulator.clearCache.apply(this._manipulator, arguments); + } + }; + + return Api; + + })(); + + var Manipulator = (function() { + var targets = []; + + function Manipulator(dnd) { + this.dnd = dnd; + this.onscroll = proxy(this, this.onscroll); + } + + Manipulator.prototype = { + + getBorders: function(offset) { + if (!this.$bounder) { + return; + } + + var borders = this.getCache('borders'); + + if (!borders) { + var rect = this.$bounder.dndClientRect(); + + borders = this.setCache('borders', { + top: rect.top, + left: rect.left, + right: rect.right, + bottom: rect.bottom + }); + } + + return { + top: borders.top + (offset ? offset.top : 0), + left: borders.left + (offset ? offset.left : 0), + right: borders.right + (offset ? offset.right : 0), + bottom: borders.bottom + (offset ? offset.bottom : 0) + }; + }, + + getReferencePoint: function() { + var referencePoint = this.getCache('referencePoint'); + + if (!referencePoint) { + var rect = this.$reference.dndClientRect(); + + referencePoint = this.setCache('referencePoint', new Point(rect.left, rect.top)); + } + + return referencePoint; + }, + + getBorderedAxis: function(borderOffset, axisOffset) { + var axis = this.getClientAxis(axisOffset); + var borders = this.getBorders(borderOffset); + + var result = borders ? new Point( + getNumFromSegment(borders.left, axis.x, borders.right), + getNumFromSegment(borders.top, axis.y, borders.bottom) + ) : axis; + + return result; + }, + + getRelBorderedAxis: function(borderOffset, axisOffset) { + return this.getBorderedAxis(borderOffset, axisOffset).minus( this.getReferencePoint() ); + }, + + addToTargets: function() { + targets.push(this); + }, + + removeFromTargets: function() { + var index; + + while(index !== -1) { + index = targets.indexOf(this); + if (index > -1) { + targets.splice(index, 1); + } + } + }, + + getTarget: function() { + return targets[0]; + }, + + isTarget: function() { + return this.getTarget() === this; + }, + + start: function() { + this.started = true; + this.targets = []; + this.asPoint = false; + this.api = new Api(this); + this.$scrollareas = this.dnd.$el.dndGetParentScrollArea(); + this.$reference = this.dnd.$el.dndGetFirstNotStaticParent(); + this.$scrollareas.on('scroll', this.onscroll); + this.dnd.trigger('dragstart', this.api); + }, + + onscroll: function() { + this.clearCache(); + this.dnd.trigger('drag', this.api); + }, + + getCache: function(key) { + return this.cache[key]; + }, + + setCache: function(key, value) { + return this.cache[key] = value; + }, + + clearCache: function() { + this.cache = {}; + }, + + stop: function() { + this.$scrollareas.off ('scroll', this.onscroll); + + if (this.targets.length) { + for(var i = 0, length = this.targets.length; i < length; i++) { + $(this.targets[i]).data('dnd')[this.dnd.layer()].trigger('drop', this.api, this.dnd.el); + } + } + + this.dnd.trigger('dragend', this.api, this.targets); + }, + + + prepareRegions: function() { + var regions = this.dnd.regions.get(); + + var ret = []; + + for(var key in regions) { + var dnd = $( regions[key] ).data('dnd')[this.dnd.layer()]; + var rect = dnd.$el.dndClientRect(); + + if (this.dnd === dnd) { + continue; + } + + ret.push({ + dnd: dnd, + rect: rect + }); + } + + return ret; + + }, + + begin: function (event) { + if (this.dnd.getCurrentManipulator() || + $(event.target).dndClosest('[dnd-pointer-none]').length) { + return false; + } + + this.dnd.setCurrentManipulator(this); + + this.addToTargets(); + this.event = event; + this.started = false; + this.clearCache(); + angular.element(document.body).dndDisableSelection(); + + return true; + }, + + _isTriggerByPoint: function (p, r) { + return (p.x > r.left) && (p.x < r.right) && (p.y > r.top) && (p.y < r.bottom); + }, + + _isTriggerByRect: function (a, b) { + return a.top <= b.top && b.top <= a.bottom && ( a.left <= b.left && b.left <= a.right || a.left <= b.right && b.right <= a.right ) || + a.top <= b.bottom && b.bottom <= a.bottom && ( a.left <= b.left && b.left <= a.right || a.left <= b.right && b.right <= a.right ) || + a.left >= b.left && a.right <= b.right && ( b.top <= a.bottom && a.bottom <= b.bottom || b.bottom >= a.top && a.top >= b.top || a.top <= b.top && a.bottom >= b.bottom) || + a.top >= b.top && a.bottom <= b.bottom && ( b.left <= a.right && a.right <= b.right || b.right >= a.left && a.left >= b.left || a.left <= b.left && a.right >= b.right) || + a.top >= b.top && a.right <= b.right && a.bottom <= b.bottom && a.left >= b.left + }, + + progress: function (event) { + this.event = event; + + if (!this.started) { + this.start(); + } + + var regions = this.getCache('regions'); + + if (!regions) { + regions = this.setCache('regions', this.prepareRegions()); + if (debug.mode) { + this.showRegioins(); + } + } + + this.dnd.trigger('drag', this.api); + + var isTrigger = this.asPoint ? this._isTriggerByPoint.bind(this, this.getBorderedAxis()) : + this._isTriggerByRect.bind(this, angular.element(this.dnd.el).dndClientRect()); + var dragenter = []; + var dragover = []; + var dragleave = []; + + for(var i = 0; i < regions.length; i++) { + var region = regions[i], + trigger = isTrigger(region.rect), + targetIndex = this.targets.indexOf(region.dnd.el); + + if ( trigger ) { + if (targetIndex === -1) { + this.targets.push(region.dnd.el); + dragenter.push(region.dnd); + } else { + dragover.push(region.dnd); + } + } else if (targetIndex !== -1) { + dragleave.push($(this.targets[targetIndex]).data('dnd')[this.dnd.layer()]); + this.targets.splice(targetIndex, 1); + } + } + + this._triggerArray(dragleave, 'dragleave'); + this._triggerArray(dragenter, 'dragenter'); + this._triggerArray(dragover, 'dragover'); + }, + + _triggerArray: function (arr, event) { + for (var i = 0; i < arr.length; i++) { + arr[i].trigger(event, this.api, this.dnd.el); + } + }, + + end: function (event) { + this.event = event; + + if (this.started) { + this.stop(); + } + + angular.element(document.body).dndEnableSelection(); + + this.removeFromTargets(); + + debug.mode && this.hideRegions(); + + this.dnd.setCurrentManipulator(null); + }, + + showRegioins: function () { + this.hideRegions(); + + var regions = this.getCache('regions'), + bodyElement = angular.element(document.body), + bodyClientRect = bodyElement.dndClientRect(); + + for (var i = 0, length = regions.length; i < length; i++) { + var region = regions[i]; + + debug.helpers.renderRect( + region.rect.left - bodyClientRect.left, + region.rect.top - bodyClientRect.top, + region.rect.width, + region.rect.height + ); + } + }, + + hideRegions: function () { + var nodes = document.querySelectorAll('.dnd-debug-rect'); + + for (var i = 0, length = nodes.length; i < length; i++) { + nodes[i].remove(); + } + } + }; + + return Manipulator; + })(); + + function Mouse(dnd) { + this.dnd = dnd; + this.manipulator = new Manipulator(dnd); + this.mousedown = proxy(this, this.mousedown); + this.mousemove = proxy(this, this.mousemove); + this.mouseup = proxy(this, this.mouseup); + this.manipulator.getClientAxis = this.getClientAxis; + + dnd.$el.on('mousedown', this.mousedown); + } + + Mouse.prototype = { + + getClientAxis: function(offset) { + return new Point(this.event.clientX + (offset ? offset.x : 0), this.event.clientY + (offset ? offset.y : 0)); + }, + + mousedown: function (event) { + if (!this.manipulator.begin(event)) { + return; + } + + $document.on('mousemove', this.mousemove ); + $document.on('mouseup', this.mouseup ); + }, + + mousemove: function(event) { + this.manipulator.progress(event); + }, + + mouseup: function(event) { + this.manipulator.end(event); + + $document.off('mousemove', this.mousemove ); + $document.off('mouseup', this.mouseup ); + + this.dnd.setCurrentManipulator(null); + }, + + destroy: function() { + this.dnd.$el.off('mousedown', this.mousedown); + }, + }; + + + function Touch(dnd, te) { + this.dnd = dnd; + this.te = te; + this.manipulator = new Manipulator(dnd); + this.touchstart = proxy(this, this.touchstart); + this.touchmove = proxy(this, this.touchmove); + this.touchend = proxy(this, this.touchend); + this.manipulator.getClientAxis = this.getClientAxis; + + dnd.$el.on(this.te.start, this.touchstart); + } + + Touch.prototype = { + + getClientAxis: function(offset) { + var event = this.event.originalEvent || this.event; + + return event.changedTouches ? + Point(event.changedTouches[0].clientX + (offset ? offset.x : 0), event.changedTouches[0].clientY + (offset ? offset.y : 0)) : + Point(event.clientX + (offset ? offset.x : 0), event.clientY + (offset ? offset.y : 0)); + }, + + touchstart: function (event) { + if (!this.manipulator.begin(event)) { + return; + } + + $document.on(this.te.move, this.touchmove ); + $document.on(this.te.end + ' ' + this.te.cancel, this.touchend ); + }, + + touchmove: function(event) { + if (this.manipulator.isTarget()) { + event.preventDefault(); + } + + this.manipulator.progress(event); + }, + + touchend: function(event) { + this.manipulator.end(event); + + $document.off(this.te.move, this.touchmove ); + $document.off(this.te.end + ' ' + this.te.cancel, this.touchend ); + this.dnd.setCurrentManipulator(null); + }, + + destroy: function() { + this.dnd.$el.off(this.te.start, this.touchstart); + } + }; + + /** + * @name angular.element.dndBind + * + * @description + * Àíàëîã jQuery.fn.bind(), òîëüêî äëÿ drag and drop ñîáûòèé + * + * Ñîáûòèÿ òàêæå ìîãóò áûòü â ôîðìàòå , + * íî â îòëè÷èå îò jQuery.fn.bind() â íàøåì ñëó÷àå layer ïîçâîëÿåò íå òîëüêî ãðóïèðîâàòü îáðàáîò÷èêè, + * íî òàêæå è îòäåëÿòü îáëàñòè äëÿ droppable è draggable ýëåìåíòîâ. Ïîÿñíèì. + * Äåëî â òîì, ÷òî ïðè îïðåäåëåíèè ñîáûòèé ýëåìåíò íå ÿâíûì îáðàçîì ïðèïèñûâàåòñÿ ê îïðåäåëåííîé îáëàñòè âèäèìîñòè (layer), + * ïðè÷åì îäèí ýëåìåíò ìîæåò îäíîâðåìåííî íàõîäèòñÿ â íåñêîëüêèõ îáëàñòÿõ. + * Ýòî îçíà÷àåò, ÷òî äëÿ òîãî, ÷òîáû íà ýëåìåíò ñðàáàòûâàëè droppable ñîáûòèÿ, îí äîëæåí íàõîäèòñÿ â layer draggable ýëåìåíòà. + * Ïî óìîë÷àíèþ, åñëè layer íå çàäàí â íàèìåíîâàíèè îáàáîò÷èêà ñîáûòèÿ, òî ýòà îáëàñòü èìåíóåòñÿ 'common', + * ò.å. ñîáûòèÿ drop è common.drop èäåíòè÷íû è íàõîäÿòñÿ â îäíîé è òîé æå îáëàñòè + * + * ! Ýëåìåíò íå ÿâíûì îáðàçîì ñ÷èòàåòñÿ draggable-ýëåìåíòîì, åñëè ó íåãî çàäàíî îäíî èëè íåñêîëüêî ñîáûòèé dragstart, drag èëè dragend + * ! Ýëåìåíò íå ÿâíûì îáðàçîì ñ÷èòàåòñÿ droppable-ýëåìåíòîì, åñëè ó íåãî çàäàíî îäíî èëè íåñêîëüêî ñîáûòèé dragenter, dragover, dragleave èëè drop + * + * @param {object|string} event + * Åñëè object, òî íåîáõîäèìî îïèñàòü ïàðû :. + * Åñëè string, òî îïðåäåëÿåòñÿ òîëüêî ïðè÷åì âîçìîæíî çàäàòü íåñêîëüêî ñîáûòèé ÷åðåç ïðîáåë, íàïðèìåð + * @param {function} handler + * Åñëè arg1 ýòî string, òî arg2 ýòî callback, êîòîðûé áóäåò âûçâàí ïîñëå íàñòóïëåíèÿ ñîáûòèÿ. + * @returns {object} angular.element object. + */ + + $.prototype.dndBind = function ( event, handler ) { + + if (!this.length) { + return this; + } + + var opts = [], events, obj, layer, self = this; + + if (typeof event === 'object') { + obj = event; + + for(var key in obj) { + events = key.replace(/\s+/g, ' ').split(' '); + + for(var i=0; i < events.length; i++) { + opts.push({ + event: events[i], + handler: obj[key] + }); + } + } + + } else if (typeof event === 'string' && typeof handler === 'function') { + events = event.trim().replace(/\s+/g, ' ').split(' '); + + for(var i=0; i < events.length; i++) { + opts.push({ + event: events[i], + handler: handler + }); + } + + } else { + return this; + } + + if (!opts.length) { + return this; + } + + forEach(this, function(element) { + var data = $(element).data(); + + if (!data.dnd) { + data.dnd = {}; + } + + for(var i=0; i < opts.length; i++) { + event = opts[i].event; + handler = opts[i].handler; + + event = event.split('.'); + + if (event[1] === undefined) { + event[1] = event[0]; + event[0] = 'common'; + } + + layer = event[0]; + event = event[1]; + + if (!data.dnd[layer]) { + data.dnd[layer] = new Dnd(element, layer); + } + + data.dnd[layer].addListener(event, handler); + } + }); + + return this; + }; + + + /** + * @name angular.element.dndUnbind + * + * @description + * Àíàëîã jQuery.fn.unbind(), òîëüêî äëÿ drag and drop ñîáûòèé + * + * @param {(object=|string=)} arg1 Åñëè íå object è íå string, òî óäàëÿþòñÿ âñå îáðàáîò÷èêè ñ êàæäîãî ñëîÿ + * Åñëè object, òî áóäóò óäàëåíû callbacks ñîáûòèÿ êîòîðûå çàäàíû â âèäå êëþ÷à è + * @param {(function=|string=)} arg2 + * Åñëè arg1 ýòî string, òî arg2 ýòî callback, êîòîðûé áóäåò âûçâàí ïîñëå íàñòóïëåíèÿ ñîáûòèÿ. + * Åñëè arg1 ýòî object, òî arg2 ýòî string êîòîðàÿ îïðåäåëÿåò èìÿ èñïîëüçóåìîãî ñëîÿ. + * @param {string=} arg3 + * Åñëè çàäàí arg1 è arg2, òî arg3 ýòî string êîòîðàÿ îïðåäåëÿåò èìÿ èñïîëüçóåìîãî ñëîÿ + * @returns {object} angular.element object. + */ + + $.prototype.dndUnbind = function() { + + var args = arguments, events = [], default_layer = 'common'; + + if (!this.length) { + return this; + } + + if (typeof args[0] === 'string') { + + args[0] = args[0].trim().replace(/\s+/g, ' ').split(' '); + + if (typeof args[1] === 'function') { + + for(var i = 0; i < args[0].length; i++) { + events.push({ + event: args[0][i], + handler: args[1] + }); + } + + } else { + for(var i = 0; i < args[0].length; i++) { + events.push({ + event: args[0][i] + }); + } + } + + } else if ( typeof args[0] === 'object') { + + for(var key in args[0]) { + if (args[0].hasOwnProperty(key)) { + + events.push({ + event: key.trim(), + handler: args[0][key] + }); + + } + } + + } else if (args.length !== 0) { + return this; + } + + forEach(this, function(element) { + var data = $(element).data(); + + if (!data.dnd) { + return; + } + + if (args.length === 0) { + + for(var key in data.dnd) { + data.dnd[key].removeListener(); + } + + } else { + + for(var i = 0; i < events.length; i++) { + var obj = events[i]; + + obj.event = obj.event.split('.'); + + if (obj.event[1] === undefined) { + obj.event[1] = obj.event[0]; + obj.event[0] = default_layer; + } + + if (obj.event[0] === '*') { + for(var key in data.dnd) { + data.dnd[key].removeListener( obj.event[1] ); + } + + } else if (data.dnd[ obj.event[0] ]) { + obj.handler ? data.dnd[ obj.event[0] ].removeListener( obj.event[1], obj.handler ) : data.dnd[ obj.event[0] ].removeListener( obj.event[1] ); + } + } + } + }); + + return this; + }; + + })(); + + /* DEBUG HELPERS */ + + debug.helpers.renderPoint = function (point) { + var element = angular.element(document.createElement('div')); + + element.dndCss({ + position: 'absolute', + left: point.x, + top: point.y, + height: 3, + width: 3, + background: 'rgba(0, 0, 0, 0.5)', + 'pointer-events': 'none', + 'z-index': 100000 + }); + + element.addClass('dnd-debug-point'); + + angular.element(document.body).append(element); + }; + + debug.helpers.renderRect = function (left, top, width, height) { + var element = angular.element(document.createElement('div')); + + element.dndCss({ + position: 'absolute', + left: left, + top: top, + height: height, + width: width, + background: 'rgba(249, 255, 0, 0.1)', + 'pointer-events': 'none', + 'z-index': 100000, + 'box-sizing': 'border-box', + 'border': '2px dotted #000' + }); + + element.addClass('dnd-debug-rect'); + + angular.element(document.body).append(element); + }; + + angular.dnd = { + version: version, + noop: noop, + doTrue: doTrue, + doFalse: doFalse, + proxy: proxy, + radToDeg: radToDeg, + degToRad: degToRad, + getNumFromSegment: getNumFromSegment, + findEvents: findEvents, + throttle: throttle, + debounce: debounce, + debug: debug + }; + + + + ; + + module.directive('dndDraggable', ['$timeout', '$parse', '$http', '$compile', '$q', '$templateCache', 'EventEmitter', + function ($timeout, $parse, $http, $compile, $q, $templateCache, EventEmitter) { + + var ElementTarget = (function () { + + function ElementTarget(element, rect) { + + var cssPosition = element.dndCss('position'); + + if (cssPosition !== 'fixed' && cssPosition !== 'absolute' && cssPosition !== 'relative') { + cssPosition = 'relative'; + element.dndCss('position', cssPosition); + } + + this.element = element; + + this.rect = rect; + } + + ElementTarget.prototype = { + initBorderOffset: function () { + var axis = this.api.getBorderedAxis(); + var crect = this.element.dndClientRect(); + + this.borderOffset = { + top: axis.y - crect.top, + left: axis.x - crect.left, + bottom: axis.y - crect.top - crect.height, + right: axis.x - crect.left - crect.width + }; + }, + + init: function (api) { + this.api = api; + delete this.start; + this.initBorderOffset(); + }, + + updatePosition: function () { + var axis = this.api.getRelBorderedAxis(this.borderOffset); + + if (!this.start) { + this.start = new Point(this.element.dndStyleRect()).minus(axis); + } + + var position = new Point(this.start).plus(axis); + + this.rect ? this.rect.update( position.getAsCss() ) : this.element.dndCss( position.getAsCss() ); + }, + + destroy: function () {}, + }; + + return ElementTarget; + })(); + + var HelperTarget = (function () { + var wrapper = $('
').dndCss({position: 'absolute'}); + + function HelperTarget(mainNode, templateUrl, scope) { + this.mainElement = angular.element(mainNode); + this.scope = scope; + this.templateUrl = templateUrl; + + if (templateUrl !== 'clone') { + this.createTemplateByUrl(templateUrl); + } else { + this.ready = true; + } + } + + HelperTarget.prototype = { + + init: function (api) { + delete this.start; + delete this.element; + this.api = api; + this.ready = false; + + this.templateUrl === 'clone' ? this.createElementByClone() : this.createElementByTemplate(); + + this.wrap().appendTo($(document.body)); + + if (!this.scope.$root || !this.scope.$root.$$phase) { + this.scope.$apply(); + } + + api.setReferenceElement(document.body); + this.initBorderOffset(); + + return this; + }, + + createTemplateByUrl: function (templateUrl) { + templateUrl = angular.isFunction (templateUrl) ? templateUrl() : templateUrl; + + return $http.get(templateUrl, {cache: $templateCache}).then(function (result) { + this.template = result.data; + this._offset = Point(); + this.ready = true; + }.bind(this)); + }, + + createElementByClone: function () { + this.element = this.mainElement.dndCloneByStyles().dndCss('position', 'static'); + this._offset = Point(this.mainElement.dndClientRect()).minus(this.api.getBorderedAxis()); + this.ready = true; + + return this; + }, + + createElementByTemplate: function () { + this.element = $compile(this.template)(this.scope); + + return this; + }, + + wrap: function () { + wrapper.html(''); + wrapper.append(this.element); + + return this; + }, + + appendTo: function (element) { + element.append(wrapper); + + return this; + }, + + initBorderOffset: function () { + var axis = this.api.getBorderedAxis(); + + if (this.templateUrl === 'clone') { + var crect = this.mainElement.dndClientRect(); + + this.borderOffset = { + top: axis.y - crect.top, + left: axis.x - crect.left, + bottom: axis.y - crect.top - crect.height, + right: axis.x - crect.left - crect.width + }; + } else { + var crect = wrapper.dndClientRect(); + + this.borderOffset = { + top: 0, + left: 0, + bottom: -crect.height, + right: -crect.width + }; + } + }, + + updatePosition: function () { + var position = this.api.getRelBorderedAxis(this.borderOffset).plus(this._offset); + + wrapper.dndCss(position.getAsCss()); + }, + + + destroy: function () { + this.element.remove(); + }, + }; + + return HelperTarget; + })(); + + function link (scope, element, attrs, ctrls) { + var rect = ctrls[0], + model = ctrls[1], + containment = ctrls[2]; + + var defaults = { + layer: 'common', + useAsPoint: true, + helper: null, + handle: '' + }; + + var getterDraggable = $parse(attrs.dndDraggable); + var opts = extend({}, defaults, $parse(attrs.dndDraggableOpts)(scope) || {}); + var dragstartCallback = $parse(attrs.dndOnDragstart); + var dragCallback = $parse(attrs.dndOnDrag); + var dragendCallback = $parse(attrs.dndOnDragend); + var draggable = opts.helper ? new HelperTarget(element, opts.helper, scope) : new ElementTarget(element, rect); + var started, handle = opts.handle ? element[0].querySelector(opts.handle) : ''; + + function dragstart(api) { + started = false; + + // îïðåäåëÿåì âêëþ÷åí ëè draggable ýëåìåíò + var enabled = getterDraggable(scope); + enabled = enabled === undefined || enabled; + + // åñëè draggable ýëåìåíò âûêëþ÷åí - îòìå÷àåì ýëåìåíò êàê "íå öåëü êóðñîðà" + if (!enabled || (handle && handle !== api.getEvent().target)) { + api.unTarget(); + } + + // åñëè ýëåìåíò íå ÿâëÿåòñÿ öåëüþ êóðñîðà (âîçìîæíî åñòü äðóãèå draggable ýëåìåíòû âíóòðè) - íèêàê íå ðåàãèðóåì íà ñîáûòèå + if (!api.isTarget()) { + return; + } + + draggable.init(api); + + // ñòàâèì ôëàã, ÷òî ýëåìåíò íà÷àë äâèãàòüñÿ + started = true; + + // ñòàâèì ôëàã useAsPoint, ÷òî áû îïðåäåëèòü, ÿâëÿåòñÿ ëè ýëåìåíò ïîëíîðàçìåðíûì èëè òî÷êîé. + //  çàâèñèìîñòè îò ýòîãî ôëàãà ïî ðàçíîìó ðåàãèðóþò droppable çîíû íà ýòîò ýëåìåíò + api.useAsPoint(opts.useAsPoint); + + // çàäàåì ìîäåëü äàííîìó ýëåìåíòó + api.dragmodel = model ? model.get() : null; + + api.setBounderElement( containment ? containment.get() : angular.element(document.body) ); + + // ñòàâèì ôëàã, ÷òî ïðîöåññ ïåðåìåùåíèÿ ýëåìåíòà íà÷àëñÿ + scope.$dragged = true; + + // ïðèìåíÿåì ïîëüçîâàòåëüñêèé callback + dragstartCallback(scope, {'$dragmodel':api.dragmodel, '$dropmodel': api.dropmodel, '$api': api}); + + // çàïóñêàåì dirty-checking öèêë + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function drag(api) { + if (!started) { + return; + } + + draggable.updatePosition(); + dragCallback(scope, {'$dragmodel':api.dragmodel, '$dropmodel': api.dropmodel, '$api': api}); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply() + } + } + + function dragend(api) { + if (!started) { + return; + } + + draggable.destroy(); + + dragendCallback(scope, {'$dragmodel':api.dragmodel, '$dropmodel': api.dropmodel, '$api': api}); + + $timeout(function () { + scope.$dragged = false; + }); + } + + var bindings = {}; + + opts.layer = opts.layer || defaults.layer; + + bindings[opts.layer+'.dragstart'] = dragstart; + bindings[opts.layer+'.drag'] = drag; + bindings[opts.layer+'.dragend'] = dragend; + + element.dndBind(bindings); + + scope.$dragged = false; + } + + return { + require: ['?dndRect', '?dndModel', '?dndContainment'], + scope: true, + link: link + }; + }]); + ; + + module.directive('dndDroppable', ['$parse', '$timeout', function( $parse, $timeout ){ + return { + require: '?dndModel', + scope: true, + link: function(scope, $el, attrs, model){ + + var defaults = { + layer: 'common' + }; + + var getterDroppable = $parse(attrs.dndDroppable); + var opts = extend({}, defaults, $parse(attrs.dndDroppableOpts)(scope) || {}); + var dragenterCallback = $parse(attrs.dndOnDragenter); + var dragoverCallback = $parse(attrs.dndOnDragover); + var dragleaveCallback = $parse(attrs.dndOnDragleave); + var dropCallback = $parse(attrs.dndOnDrop); + + function dragenter(api){ + var local = api.droplocal = {}; + + api.dropmodel = model ? model.get() : model; + + local.droppable = getterDroppable(scope, {'$dragmodel': api.dragmodel, '$dropmodel': api.dropmodel, '$api': api}); + local.droppable = local.droppable === undefined ? true : local.droppable; + + if(!local.droppable) { + return; + } + + dragenterCallback(scope, {'$dragmodel':api.dragmodel, '$dropmodel': api.dropmodel, '$api': api}); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function dragover(api){ + var local = api.droplocal; + + if(!local.droppable) { + return; + } + + dragoverCallback(scope, {'$dragmodel':api.dragmodel, '$dropmodel': api.dropmodel, '$api': api}); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function dragleave(api){ + var local = api.droplocal; + + if(!local.droppable) { + return; + } + + dragleaveCallback(scope, {'$dragmodel':api.dragmodel, '$dropmodel': api.dropmodel, '$api': api}); + api.dropmodel = undefined; + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function drop(api){ + var local = api.droplocal; + + if(!local.droppable) { + return; + } + + dropCallback(scope, {'$dragmodel':api.dragmodel, '$dropmodel': api.dropmodel, '$api': api}); + } + + + var bindings = {}; + + opts.layer = opts.layer || defaults.layer; + + bindings[opts.layer+'.dragenter'] = dragenter; + bindings[opts.layer+'.dragover'] = dragover; + bindings[opts.layer+'.dragleave'] = dragleave; + bindings[opts.layer+'.drop'] = drop; + + $el.dndBind( bindings ); + + } + }; + }]); + ; + + module.directive('dndRotatable', ['$parse', '$timeout', function($parse, $timeout){ + + function link (scope, element, attrs, ctrls) { + var rect = ctrls[0], + containment = ctrls[1]; + + var defaults = { + step: 5 + }; + + var getterRotatable = $parse(attrs.dndRotatable); + var opts = extend({}, defaults, $parse(attrs.dndRotatableOpts)(scope) || {}); + var dragstartCallback = $parse(attrs.dndOnRotatestart); + var dragCallback = $parse(attrs.dndOnRotate); + var dragendCallback = $parse(attrs.dndOnRotateend); + + var cssPosition = element.dndCss('position'); + + if(cssPosition != 'fixed' && cssPosition != 'absolute' && cssPosition != 'relative') { + cssPosition = 'relative'; + element.dndCss('position', cssPosition); + } + + var handle = angular.element('
'); + + element.append(handle); + + function dragstart(api) { + var local = api.local = {}; + + local.rotatable = getterRotatable(scope); + local.rotatable = local.rotatable === undefined ? true : local.rotatable; + + if( !local.rotatable ) { + api.unTarget(); + } + + if(!api.isTarget()) { + return; + } + + local.started = true; + + api.setBounderElement( containment ? containment.get() : angular.element(document.body) ); + + var axis = api.getRelBorderedAxis(); + + local.srect = element.dndStyleRect(); + + local.currAngle = element.dndGetAngle(); + + local.startPoint = Point(axis); + + local.borders = api.getBorders(); + + local.center = Point(local.srect).plus(Point(local.srect.width / 2, local.srect.height / 2)); + + scope.$rotated = true; + + dragstartCallback(scope); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function drag(api){ + var local = api.local; + + if(!local.started) { + return; + } + + var axis = api.getRelBorderedAxis(); + var angle = Point(axis).deltaAngle(local.startPoint, local.center); + var degs = radToDeg(local.currAngle+angle); + + degs = Math.round(degs/opts.step)*opts.step; + var rads = degToRad(degs); + var matrix = Matrix().rotate(rads); + + var compute = Rect( local.center.x - local.srect.width/2, local.center.y - local.srect.height/2, local.srect.width, local.srect.height).applyMatrix( matrix, local.center ).client(); + var rPoint = api.getReferencePoint(); + + if(local.borders && (compute.left + rPoint.x < local.borders.left-1 || compute.top + rPoint.y < local.borders.top-1 || (compute.left + rPoint.x + compute.width) > local.borders.right+1 || (compute.top + rPoint.y + compute.height) > local.borders.bottom+1)) { + return; + } + + if(rect) { + rect.update('transform', matrix.toStyle()); + } else { + element.dndCss('transform', matrix.toStyle()); + } + + dragCallback(scope); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function dragend(api){ + var local = api.local; + + if(!local.started) { + return; + } + + dragendCallback(scope); + + $timeout(function(){ + scope.$rotated = false; + }); + } + + scope.$rotated = false; + + var bindings = { + '$$rotatable.dragstart': dragstart, + '$$rotatable.drag': drag, + '$$rotatable.dragend': dragend + }; + + handle.dndBind( bindings ); + + } + + return { + require: ['?dndRect', '?dndContainment'], + scope: true, + link: link + }; + }]) + ; + + module.directive('dndResizable', ['$parse', '$timeout', function($parse, $timeout) { + + function createHandleElement(side) { + return angular.element('
').addClass('angular-dnd-resizable-handle angular-dnd-resizable-handle-' + side); + } + + function getCenterPoint(rect, scale) { + scale = typeof scale === 'object' ? scale : {x:1,y:1}; + + return new Point(rect.left + rect.width*scale.x/2, rect.top + rect.height*scale.y/2); + } + + function link (scope, $el, attrs, ctrls) { + var rect = ctrls[0], + containment = ctrls[1]; + + var defaults = { + handles: 'ne, se, sw, nw, n, e, s, w', + minWidth: 20, + minHeight: 20, + maxWidth: 10000, + maxHeight: 10000 + }; + + var getterResizable = $parse(attrs.dndResizable); + var opts = extend({}, defaults, $parse(attrs.dndResizableOpts)(scope) || {}); + var dragstartCallback = $parse(attrs.dndOnResizestart); + var dragCallback = $parse(attrs.dndOnResize); + var dragendCallback = $parse(attrs.dndOnResizeend); + + function getBindings(side) { + + function dragstart(api) { + var local = api.local = {}; + + local.resizable = getterResizable(scope); + local.resizable = local.resizable === undefined ? true : local.resizable; + + if ( !local.resizable ) { + api.unTarget(); + } + + if ( !api.isTarget() ) { + return; + } + + api.setBounderElement( containment ? containment.get() : angular.element(document.body) ); + local.started = true; + local.$parent = $el.parent(); + local.rads = $el.dndGetAngle(); + local.rotateMatrix = Matrix.IDENTITY.rotate(local.rads); + local.inverseRotateMatrix = local.rotateMatrix.inverse(); + local.parentRect = local.$parent.dndClientRect(); + + var axis = api.getBorderedAxis(), crect = $el.dndClientRect(), srect = local.rect = $el.dndStyleRect(); + + local.borders = api.getBorders(); + local.startAxis = axis; + + local.minScaleX = opts.minWidth / srect.width; + local.minScaleY = opts.minHeight / srect.height; + local.maxScaleX = opts.maxWidth / srect.width; + local.maxScaleY = opts.maxHeight / srect.height; + + local.deltaX = crect.left - srect.left + crect.width / 2 - srect.width / 2; + local.deltaY = crect.top - srect.top + crect.height / 2 - srect.height / 2; + + scope.$resized = true; + + dragstartCallback(scope); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function drag(api) { + var local = api.local; + + if (!local.started) return; + + var axis = api.getBorderedAxis(); + var vector = Point(axis).minus(local.startAxis).transform(local.inverseRotateMatrix); + + var scale = {x:1,y:1}; + + var width = local.rect.width, + height = local.rect.height, + top = local.rect.top, + left = local.rect.left; + + switch(side) { + case 'n': scale.y = (height - vector.y) / height; break; + case 'e': scale.x = (width + vector.x) / width; break; + case 's': scale.y = (height + vector.y) / height; break; + case 'w': scale.x = (width - vector.x) / width; break; + case 'ne': scale.x = (width + vector.x) / width; scale.y = (height - vector.y) / height; break; + case 'se': scale.x = (width + vector.x) / width; scale.y = (height + vector.y) / height; break; + case 'sw': scale.x = (width - vector.x) / width; scale.y = (height + vector.y) / height; break; + case 'nw': scale.x = (width - vector.x) / width; scale.y = (height - vector.y) / height; break; + } + + scale.x = getNumFromSegment(local.minScaleX, scale.x, local.maxScaleX); + scale.y = getNumFromSegment(local.minScaleY, scale.y, local.maxScaleY); + + var offset; + var center = getCenterPoint(local.rect); + var scaledCenter = getCenterPoint(local.rect, scale); + + switch(side) { + case 'n': offset = Point(left,top+height*scale.y).rotate(local.rads, scaledCenter).minus( Point(left,top+height).rotate(local.rads, center) ); break; + case 'e': offset = Point(left,top).rotate(local.rads, scaledCenter).minus( Point(left,top).rotate(local.rads, center) ); break; + case 's': offset = Point(left,top).rotate(local.rads, scaledCenter).minus( Point(left,top).rotate(local.rads, center) ); break; + case 'w': offset = Point(left+width*scale.x,top).rotate(local.rads, scaledCenter).minus( Point(left+width,top).rotate(local.rads, center) ); break; + case 'ne': offset = Point(left,top+height*scale.y).rotate(local.rads, scaledCenter).minus( Point(left,top+height).rotate(local.rads, center) ); break; + case 'se': offset = Point(left,top).rotate(local.rads, scaledCenter).minus( Point(left,top).rotate(local.rads, center) ); break; + case 'sw': offset = Point(left+width*scale.x,top).rotate(local.rads, scaledCenter).minus( Point(left+width,top).rotate(local.rads, center) ); break; + case 'nw': offset = Point(left+width*scale.x,top+height*scale.y).rotate(local.rads, scaledCenter).minus( Point(left+width,top+height).rotate(local.rads, center) ); break; + }; + + var styles = {}; + styles.width = width * scale.x; + styles.height = height * scale.y; + styles.left = left - offset.x; + styles.top = top - offset.y; + + var realCenter = Point(styles.left+local.deltaX+styles.width/2, styles.top+local.deltaY+styles.height/2); + var boundedRect = Rect(styles.left+local.deltaX, styles.top+local.deltaY, styles.width, styles.height).applyMatrix( local.rotateMatrix, realCenter ).client(); + + if (local.borders && (boundedRect.left+1 < local.borders.left || boundedRect.top+1 < local.borders.top || boundedRect.right-1 > local.borders.right || boundedRect.bottom-1 > local.borders.bottom)) { + return; + } + + if (rect) { + rect.update(styles); + } else { + $el.dndCss(styles); + } + + dragCallback(scope); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function dragend(api) { + var local = api.local; + + if (!local.started) { + return; + } + + dragendCallback(scope); + + + $timeout(function() { scope.$resized = false; }); + } + + return { + '$$resizable.dragstart': dragstart, + '$$resizable.drag': drag, + '$$resizable.dragend': dragend + }; + + } + + var cssPosition = $el.dndCss('position'); + + if (cssPosition !== 'fixed' && cssPosition !== 'absolute' && cssPosition !== 'relative') { + cssPosition = 'relative'; + $el.dndCss('position', cssPosition); + } + + var sides = opts.handles.replace(/\s/g,'').split(','); + + for(var i=0; i < sides.length; i++) { + $el.append( createHandleElement( sides[i] ).dndBind( getBindings( sides[i] ) ) ); + } + + scope.$resized = false; + } + + return { + require: ['?dndRect', '?dndContainment'], + scope: true, + link: link + }; + }]); + ; + + module.directive('dndSortableList', ['$parse', '$compile', function($parse, $compile) { + function link(scope, element, attrs, ctrl) { + var defaults = { + layer: 'common' + }; + var opts = ctrl.options = extend({}, defaults, $parse(attrs.dndSortableOpts)(scope) || {}); + var getter = ctrl.getter = $parse(attrs.dndSortableList) || angular.noop; + var bindings = {}; + + bindings[opts.layer+'.dragover'] = function(api) { + if(getter(scope).length > 0) { + return; + } + + api.$sortable.model = {list: getter(scope)}; + api.$sortable.insertBefore = true; + element.append(api.placeholder[0]); + }; + + element.dndBind(bindings); + } + + controller.$inject = ['$scope', '$element', '$attrs']; + function controller (scope, element, attrs) { } + + return { + scope: true, + link: link, + controller: controller + }; + }]); + + module.directive('dndSortable', ['$parse', '$compile', function($parse, $compile) { + var placeholder, ngRepeatRegExp = /^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/; + var defaults = { + layer: 'common' + }; + + + + function join(obj, sep1, sep2) { + return Object.getOwnPropertyNames(obj).map(function(key) { + return [key, obj[key]].join(sep1); + }).join(sep2); + } + + function joinObj (obj) { + return '{' + join(obj, ':', ',') + '}'; + } + + function joinAttrs (attrs) { + return join(attrs, '="', '" ') + '"'; + } + + function template(element, tAttrs) { + var tag = element[0].nodeName.toLowerCase(); + var ngRepeat = tAttrs.ngRepeat || ''; + var match = ngRepeat.match(ngRepeatRegExp); + + if(!match) { + throw 'dnd-sortable-item requires ng-repeat as dependence'; + } + + var lhs = match[1]; + var rhs = match[2]; + + lhs = lhs.match(/^(?:(\s*[\$\w]+)|\(\s*([\$\w]+)\s*,\s*([\$\w]+)\s*\))$/); + + var model = { + item: 'item: ' + (lhs[3] || lhs[1]) + ', ', + list: 'list: ' + rhs.replace(/\s\|(.)+$/g,'') + ', ', + index: 'index: ' + '$index' + }; + + var opts = angular.extend({ + layer: "'common'", + handle: "''" + }, $parse(tAttrs.dndSortableOpts)()); + + var attrs = { + 'ng-transclude': '', + 'dnd-draggable': '', + 'dnd-draggable-opts': joinObj({ + helper: "'clone'", + useAsPoint: true, + layer: opts.layer, + handle: opts.handle + }), + 'dnd-droppable': '', + 'dnd-droppable-opts': joinObj({ + layer: opts.layer + }), + 'dnd-on-dragstart': '$$onDragStart($api, $dropmodel, $dragmodel)', + 'dnd-on-dragend': '$$onDragEnd($api, $dropmodel, $dragmodel)', + 'dnd-on-dragover': '$$onDragOver($api, $dropmodel, $dragmodel)', + 'dnd-on-drag': '$$onDrag($api, $dropmodel, $dragmodel)', + 'dnd-model': '{' + model.item + model.list + model.index +'}' + }; + + return '<' + tag + ' ' + joinAttrs(attrs) + '>'; + } + + function link(scope, element, attrs, ctrls) { + var listCtrl = ctrls[0]; + var css = element.dndCss(['float', 'display']); + var parentNode = element[0].parentNode; + var floating = /left|right|inline/.test(css.float + css.display); + var getter = $parse(attrs.dndModel) || noop; + var sortstartCallback = $parse(attrs.dndOnSortstart); + var sortCallback = $parse(attrs.dndOnSort); + var sortchangeCallback = $parse(attrs.dndOnSortchange); + var sortendCallback = $parse(attrs.dndOnSortend); + var sortenterCallback = $parse(attrs.dndOnSortenter); + var sortleaveCallback = $parse(attrs.dndOnSortleave); + + + function isHalfway(dragTarget, axis, dropmodel) { + var rect = element.dndClientRect(); + + return (floating ? (axis.x - rect.left) / rect.width : (axis.y - rect.top) / rect.height) > 0.5; + } + + function moveValue(fromIndex, fromList, toIndex, toList) { + toList = toList || fromList; + toList.splice(toIndex, 0, fromList.splice(fromIndex, 1)[0]); + } + + scope.$$onDragStart = function(api) { + sortstartCallback(scope); + + api.placeholder = element.clone(); + element.addClass('ng-hide'); + api.placeholder.addClass('angular-dnd-placeholder'); + parentNode.insertBefore(api.placeholder[0], element[0]); + api.$sortable = {}; + api.clearCache(); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + }; + + scope.$$onDragOver = function(api, dropmodel, dragmodel) { + var isDraggingNow = angular.isDefined(api.$sortable); + if (!isDraggingNow) { + return; + } + var halfway = isHalfway(api.getDragTarget(), api.getBorderedAxis()); + + halfway ? parentNode.insertBefore(api.placeholder[0], element[0].nextSibling) : parentNode.insertBefore(api.placeholder[0], element[0]); + + var model = getter(scope); + + if (sortchangeCallback !== angular.noop && (!api.$sortable.model || api.$sortable.model.index !== model.index)) { + sortchangeCallback(scope); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + api.$sortable.model = model; + api.$sortable.insertBefore = !halfway; + + api.clearCache(); + }; + + scope.$$onDragEnd = function(api) { + element.removeClass('ng-hide'); + api.placeholder.remove(); + + if(!api.$sortable.model) { + return; + } + + var fromIndex = scope.$index, + toIndex = api.$sortable.model.index, + fromList = getter(scope).list, + toList = api.$sortable.model.list; + + if(toList === fromList) { + if(toIndex < fromIndex) { + if(!api.$sortable.insertBefore) toIndex++; + } else { + if(api.$sortable.insertBefore) toIndex--; + } + } else if(!api.$sortable.insertBefore) toIndex++; + + moveValue(fromIndex, fromList, toIndex, toList); + + api.clearCache(); + + sortendCallback(scope); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + }; + + (sortCallback !== angular.noop) && (scope.$$onDrag = function(api) { + sortCallback(scope); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + }); + } + + return { + scope: true, + transclude: true, + template: template, + replace: true, + link: link, + require: ['^dndSortableList'] + }; + }]); +//TODO: +//create - âûçûâàåòñÿ ïðè ñîçäàíèè ñïèñêà + +//activate - íà÷àò ïðîöåññ ñîðòèðîâêè (âûçûâàåòñÿ ó âñåõ ñâÿçàííûõ ñïèñêîâ) +//start - íà÷àò ïðîöåññ ñîðòèðîâêè (âûçûâàåòñÿ òîëüêî ó ñïèñêà èíèöèàòîðà) + +//sort - âûçûâàåòñÿ ïðè ëþáîì äâèæåíèè ìàíèïóëÿòîðà ïðè ñîðòèðîâêå +//change - ñîðòèðîâêà ñïèñêà èçìåíèëàñü +//out - ìàíèïóëÿòîð ñ ýëåìåíòîì âûíåñåí çà ïðåäåëû ñïèñêà (à òàêæå, åñëè áûëî ñîáûòèå over è íåáûëî out òî è ïðè îêîí÷àíèè ñîðòèðîâêè) +//over - ìàíèïóëÿòîð ñ ýëåìåíòîì âíåñåí â ïðåäåëû ñïèñêà + +//beforeStop - áóäåò âûçâàíî ó ñïèñêà èíèöèàòîðà +//update - áóäåò âûçâàíî åñëè ñïèñîê èçìåíèëñÿ +//deactivate - âûçûâàåòñÿ ó âñåõ ñâÿçàííûõ ñïèñêîâ +//stop - âûçûâàåòñÿ ñàìûì ïîñëåäíèì ó ñïèñêà èíèöèàòîðà + +//receive - ýëåìåíò äðîïíóëñÿ ÈÇ äðóãîãî ñïèñêà +//remove - ýëìåíò äðîïíóëñÿ  äðóãîé ñïèñîê + +//example: http://jsfiddle.net/UAcC7/1441/ + ; + + module.directive('dndSelectable', ['$parse', function($parse){ + + var defaults = {}; + + Controller.$inject = ['$scope', '$attrs', '$element']; + function Controller($scope, $attrs, $element) { + var getterSelecting = $parse($attrs.dndModelSelecting), setterSelecting = getterSelecting.assign || noop; + var getterSelected = $parse($attrs.dndModelSelected), setterSelected = getterSelected.assign || noop; + var getterSelectable = $parse($attrs.dndSelectable), setterSelectable = getterSelectable.assign || noop; + var onSelected = $parse($attrs.dndOnSelected); + var onUnselected = $parse($attrs.dndOnUnselected); + var onSelecting = $parse($attrs.dndOnSelecting); + var onUnselecting = $parse($attrs.dndOnUnselecting); + + setterSelected($scope, false); + setterSelecting($scope, false); + + this.getElement = function(){ + return $element; + }; + + this.isSelected = function(){ + return getterSelected($scope); + }; + + this.isSelecting = function(){ + return getterSelecting($scope); + }; + + this.isSelectable = function(){ + var selectable = getterSelectable($scope); + return selectable === undefined || selectable; + }; + + this.toggleSelected = function(val){ + val = val === undefined ? !this.isSelected() : val; + + return val ? this.selected() : this.unselected(); + }; + + this.selecting = function(){ + if (!this.isSelectable()) { + return this; + } + + setterSelecting($scope, true); + onSelecting($scope); + + return this; + }; + + this.unselecting = function(){ + setterSelecting($scope, false); + onUnselecting($scope); + + return this; + }; + + this.selected = function(){ + if (!this.isSelectable()) { + return this; + } + + setterSelected($scope, true); + onSelected($scope); + + return this; + }; + + this.unselected = function(){ + setterSelected($scope, false); + onUnselected($scope); + + return this; + }; + + this.hit = function(a){ + var b = this.rectCtrl.getClient(); + + for(var key in b) { + b[key] = parseFloat(b[key]); + } + + b.bottom = b.bottom == undefined ? b.top + b.height : b.bottom; + b.right = b.right == undefined ? b.left + b.width : b.right; + a.bottom = a.bottom == undefined ? a.top + a.height : a.bottom; + a.right = a.right == undefined ? a.left + a.width : a.right; + + return ( + a.top <= b.top && b.top <= a.bottom && ( a.left <= b.left && b.left <= a.right || a.left <= b.right && b.right <= a.right ) || + a.top <= b.bottom && b.bottom <= a.bottom && ( a.left <= b.left && b.left <= a.right || a.left <= b.right && b.right <= a.right ) || + a.left >= b.left && a.right <= b.right && ( b.top <= a.bottom && a.bottom <= b.bottom || b.bottom >= a.top && a.top >= b.top || a.top <= b.top && a.bottom >= b.bottom) || + a.top >= b.top && a.bottom <= b.bottom && ( b.left <= a.right && a.right <= b.right || b.right >= a.left && a.left >= b.left || a.left <= b.left && a.right >= b.right) || + a.top >= b.top && a.right <= b.right && a.bottom <= b.bottom && a.left >= b.left + ); + }; + + } + + function LikeRectCtrl($element){ + this.$element = $element; + } + + LikeRectCtrl.prototype = { + getClient: function(){ + return this.$element.dndClientRect(); + } + }; + + return { + restrict: 'A', + require: ['dndSelectable', '^dndLassoArea', '?dndRect'], + controller: Controller, + scope: true, + link: function(scope, $el, attrs, ctrls) { + scope.$dndSelectable = ctrls[0]; + + var rectCtrl = ctrls[2]; + + ctrls[0].rectCtrl = rectCtrl ? rectCtrl : new LikeRectCtrl($el); + + ctrls[1].add(ctrls[0]); + + function ondestroy() { + ctrls[1].remove(ctrls[0]); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + $el.on('$destroy', ondestroy); + } + }; + }]); + ; + + module.directive('dndRect', ['$parse', function($parse){ + var setStyles = ['top','left','width','height', 'transform']; + var getStyles = ['top','left','width','height', TRANSFORM]; + + setStyles.has = function(val){ + return this.indexOf(val) > -1; + } + + Controller.$inject = ['$scope', '$attrs', '$element']; + function Controller( $scope, $attrs, $element ){ + var getter = $parse($attrs.dndRect), setter = getter.assign || noop, lastRect; + + this.update = function(prop, value) { + var values, rect = getter($scope) || {}; + + if (typeof prop != 'object') { + values = {}; + values[prop] = value; + } else values = prop; + + for(var i = 0; i < setStyles.length; i++){ + var style = setStyles[i]; + + if(values[style] !== undefined) rect[style] = values[style]; + } + + setter($scope, rect); + }; + + this.get = function(){ + return getter($scope); + }; + + this.getClient = function(){ + return $element.dndClientRect(); + }; + + function sanitize(rect){ + var css; + + rect = typeof rect == 'object' ? rect : {}; + + for(var i = 0; i < setStyles.length; i++){ + + var style = setStyles[i]; + + if(rect[style] !== undefined) continue; + + if(!css) css = $element.dndCss(getStyles); + + rect[style] = (style === 'transform') ? css[TRANSFORM] : css[style]; + } + + for(var key in rect){ + rect[key.toLowerCase()] = rect[key]; + } + + for(var key in rect) { + if(setStyles.has(key)) { + if(typeof rect[key] === 'number') rect[key] = rect[key]+'px'; + } else delete rect[key]; + } + + return rect; + }; + + $scope.$parent.$watch(function(){ + var rect = getter($scope.$parent); + + if(rect !== lastRect) setter($scope, rect); + }); + + $scope.$watch($attrs.dndRect, function(n, o){ + if(!n || typeof n != 'object') return; + if(o == undefined) o = {}; + + var lastRect = n = sanitize(n); + + var css = {}; + + for(var val, i=0; i < setStyles.length; i++ ){ + val = setStyles[i]; + + if(n[val] == undefined && o[val] != undefined) { + css[val] = ''; + } else if(n[val] != undefined) { + css[val] = n[val]; + } + } + + if(css.transform) { + css[TRANSFORM] = css.transform; + } + + $element.dndCss(css); + + }, true); + } + + return { + restrict: 'A', + controller: Controller + }; + }]) + ; + + module.directive('dndModel', ['$parse', function($parse){ + + Controller.$inject = ['$scope', '$attrs']; + function Controller( $scope, $attrs ){ + var getter = $parse($attrs.dndModel), setter = getter.assign + + this.set = function(value){ + setter($scope, value); + }; + + this.get = function(){ + return getter($scope); + }; + } + + return { + restrict: 'A', + controller: Controller + } + }]) + ; + + module.directive('dndLassoArea', ['DndLasso', '$parse', '$timeout', 'dndKey', function(DndLasso, $parse, $timeout, dndKey){ + + Controller.$inject = []; + function Controller(){ + var ctrls = [], data = {}; + + this.data = function(){ + return data; + }; + + this.add = function(ctrl){ + ctrls.push(ctrl); + }; + + this.remove = function(ctrl){ + for(var i = 0; i < ctrls.length; i++){ + if(ctrls[i] === ctrl) { + ctrls.splice(i,1); + return true; + } + } + + return false; + }; + + this.getSelectable = function(element){ + for(var i = 0; i < ctrls.length; i++){ + if(ctrls[i].getElement()[0] == element) return ctrls[i]; + } + + return undefined; + }; + + this.empty = function(){ + return !ctrls.length; + }; + + this.get = function(i){ + return i === undefined ? ctrls : ctrls[i]; + } + } + + var ctrls = []; + + ctrls.remove = function (ctrl){ + for(var i = 0; i < this.length; i++){ + if(this[i] === ctrl) { + this.splice(i,1); + return true; + } + } + + return false; + } + + return { + restrict: 'A', + controller: Controller, + require: 'dndLassoArea', + /* îòðèöàòåëüíûé ïðèîðèòåò íåîáõîäèì äëÿ òîãî, ÷òî áû post link function dnd-lasso-area çàïóñêàëñÿ ðàíüøå post link function ng-click */ + priority: -1, + link: function(scope, $el, attrs, ctrl){ + var defaults = { + selectAdditionals: true + }; + + var getterLassoArea = $parse(attrs.dndLassoArea); + var opts = extend({}, defaults, $parse(attrs.dndLassoAreaOpts)(scope) || {}); + var dragstartCallback = $parse(attrs.dndOnLassostart); + var dragCallback = $parse(attrs.dndOnLasso); + var dragendCallback = $parse(attrs.dndOnLassoend); + var clickCallback = $parse(attrs.dndLassoOnclick); + var lasso = new DndLasso({ $el:$el }), selectable, keyPressed; + + ctrls.push(ctrl); + + function onClick(event){ + if(!ctrl.empty()) { + + if(keyPressed) { + selectable.toggleSelected(); + return + } + + var s = ctrl.get(); + + for(var i = 0; i < s.length; i++){ + s[i].unselected().unselecting(); + } + + if(selectable) selectable.selected(); + + } + + clickCallback( scope, {$event: event}); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function onStart(handler) { + scope.$dragged = true; + + if(!handler.isActive()) return; + + dragstartCallback( scope ); + + if(!ctrl.empty() && !keyPressed) { + + var s = ctrl.get(); + + for(var i = 0; i < s.length; i++){ + s[i].unselected().unselecting(); + } + + } + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function onDrag(handler) { + scope.$dragged = true; + + if(!handler.isActive()) return; + + if(!ctrl.empty()) { + var s = ctrl.get(), rect = handler.getClientRect(); + + for(var i = 0; i < s.length; i++) { + s[i].hit(rect) ? s[i].selecting() : s[i].unselecting(); + } + } + + dragCallback(scope, { $rect: handler.getRect() }); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + } + + function onEnd(handler) { + + if(!handler.isActive()) return; + + var s = ctrl.get(); + + if(!ctrl.empty()) { + + for(var i = 0; i < s.length; i++){ + if(s[i].isSelecting()) s[i].toggleSelected(); + } + + for(var i = 0; i < s.length; i++){ + s[i].unselecting(); + } + } + + dragendCallback(scope, { $rect: handler.getRect() }); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + + /* ÷òî áû ñîáûòèÿ click/dblclick ïîëó÷èëè ôëàã $dragged === true, ïåðåêëþ÷åíèå ôëàãà ïðîèñõîäèò ïîñëå èõ âûïîëíåíèÿ */ + $timeout(function(){ scope.$dragged = false; }); + } + + $el.on('mousedown touchstart', throttle(function (event){ + + scope.$dragged = false; + + //scope.$keypressed = keyPressed = ( dndKey.isset(16) || dndKey.isset(17) || dndKey.isset(18) ); + scope.$keypressed = keyPressed = opts.selectAdditionals ? ( event.shiftKey || event.ctrlKey || event.metaKey ) : false; + + if(!ctrl.empty()) { + selectable = ctrl.getSelectable(event.target); + } + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + + }, 300) ); + + $el.on('click', function(event){ + + if(!scope.$dragged) onClick(event); + + /* ÷òî áû ñîáûòèÿ dnd-on-* ïîëó÷èëè ôëàã $keypressed, ïåðåêëþ÷åíèå ôëàãà ïðîèñõîäèò ïîñëå èõ âûïîëíåíèÿ */ + if(scope.$keypressed) $timeout(function(){ scope.$keypressed = false; }); + } ); + + lasso.on('start', onStart); + lasso.on('drag', onDrag); + lasso.on('end', onEnd); + + $el.on('$destroy', function(){ + ctrls.remove(ctrl); + + if (!scope.$root || !scope.$root.$$phase) { + scope.$apply(); + } + }); + + scope.$dragged = false; + } + }; + }]) + ; + + /** + * @name dnd.fittext + * + * @description + * Îòëè÷íàÿ ôóíêöèÿ äëÿ ïîäãîíêè òåêñòà ïîä ðàçìåð áëîêà, â êîòîðîì ýòîò òåêñò íàõîäèòñÿ. + * çà åäèíñòâåííûé àðãóìåíò ôóíêöèÿ ïðèíèìàåò îáúåêò rect, ñîäåðæàùèé â ñåáå øèðèíó (width) è âûñîòó (height) ýëåìåíòà. + * Íà îñíîâå ýòèõ ïàðàìåòðîâ èäåò ðàñ÷åò âûñîòû øðèôòà. + * Òàêæå ó äèðåêòâû åñòü äîïîëíèòåëüíûå àòðèáóòû-íàñòðîéêè: dnd-fittext-max è dnd-fittext-min, + * êîòîðûå ïîçâîëÿþò çàäàòü ìàêñèìàëüíîå è ìèíèìàëüíîå ñîîòâåòñòâåííî çíà÷åíèå øðèôòà. + * + */ + + module.directive('dndFittext', ['$timeout', '$window', function( $timeout, $window ){ + var $span = $('').dndCss({'position':'absolute','left':-99999, 'top':-99999, 'opacity':0, 'z-index': -9999}); + + $(document.body).append( $span ); + + function encodeStr(val) { + var val = $span.text(val).html().replace(/\s+/g, ' ') + if($span[0].tagName == 'INPUT' || $span[0].tagName == 'TEXTAREA') val = val.replace(/\s/g,' '); + + return val; + } + + function getRealSize(text, font) { + $span.html( encodeStr(text) ).dndCss(font); + var rect = $span[0].getBoundingClientRect(); + + return { + width: parseFloat(rect.width), + height: parseFloat(rect.height) + } + } + + function getCurrSize($el, offsetWidthPrct, offsetHeightPrct){ + var rect = $el[0].getBoundingClientRect(); + + return { + width: parseFloat(rect.width)*(100-offsetWidthPrct)/100, + height: parseFloat(rect.height)*(100-offsetHeightPrct)/100 + } + } + + return { + restrict: 'A', + link: function(scope, $el, attrs) { + + function updateSize(opts) { + opts = opts === undefined ? {} : opts; + var font = $el.dndCss( + ['font-size','font-family','font-weight','text-transform','border-top','border-right','border-bottom','border-left','padding-top','padding-right','padding-bottom','padding-left'] + ), text = opts.text == undefined ? $el.text() || $el.val() : opts.text; + + var sizes = []; + if(opts.width === undefined) sizes.push('width'); + if(opts.height === undefined) sizes.push('height'); + + if(sizes.length) sizes = $el.dndCss(sizes); + + for(var key in sizes){ + var val = sizes[key]; + + if(val[val.length-1] == '%') return; + opts[key] = sizes[key]; + } + + var realSize = getRealSize(text, font), currSize = getCurrSize($el,0,0); + if(!realSize.width || !realSize.height) { + $el.dndCss('font-size', ''); + return + } + + currSize.width = parseFloat(opts.width); + currSize.height = parseFloat(opts.height); + + var kof1 = currSize.height / realSize.height; + var kof2 = currSize.width / realSize.width; + + var max = scope.$eval(attrs.dndFittextMax); + var min = scope.$eval(attrs.dndFittextMin); + + if(min == undefined) min = 0; + if(max == undefined) max = Number.POSITIVE_INFINITY; + + var kof = (kof1 < kof2 ? kof1 : kof2); + + //Êîððåêòèðîâêà ïëàâíîñòè + kof *= 0.85; + if((kof > 0.95 && kof <= 1) || (kof >= 1 && kof < 1.05) ) return; + + var n = kof * parseFloat(font['font-size']); + + n = getNumFromSegment(min, n, max); + + $el.dndCss('font-size', n+'px'); + } + + scope.$watch( attrs.dndFittext, throttle(function(opts){ + updateSize(opts); + }), true); + + $($window).on('resize', function(){ + updateSize(); + }); + } + }; + }]) + ; + + module.directive('dndKeyModel', ['$parse', 'dndKey', function($parse, dndKey){ + return { + restrict: 'A', + link: function(scope, $el, attrs) { + var getter = $parse(attrs.dndKeyModel), setter = getter.assign; + + scope.$watch(function(){ return dndKey.get() }, function(n,o){ + if(n === undefined) return; + setter(scope, n); + }); + } + } + }]) + ; + + module.directive('dndContainment', ['$parse', function($parse){ + + Controller.$inject = ['$element', '$attrs', '$scope']; + function Controller( $element, $attrs, $scope){ + var getterSelector = $parse($attrs.dndContainment); + + this.get = function () { + var selector = getterSelector($scope); + + return selector ? $element.dndClosest(selector).eq(0) : $element.parent(); + } + } + + return { + restrict: 'EAC', + controller: Controller, + } + }]) + ; + + module.factory('dndKey', ['$rootScope', function ($rootScope) { + var keys = []; + + function DndKey(){ + + }; + + DndKey.prototype = { + get: function(){ + return keys; + }, + isset: function(code){ + var index = keys.indexOf(code); + return (index !== -1); + } + }; + + function keydown(event){ + var code = event.keyCode; + debounceKeyup(event); + if(keys.indexOf(code) > -1) return; + + keys.push(code); + $rootScope.$digest(); + } + + function keyup(event){ + var code = event.keyCode, index = keys.indexOf(code); + if(index === -1) return; + + keys.splice(index,1); + $rootScope.$digest(); + }; + + + + var debounceKeyup = debounce(keyup, 1000); + $document.on('keydown', keydown); + $document.on('keyup', keyup); + + return new DndKey; + }]) + ; + + module.factory('DndLasso', [function () { + var $div = $('
').dndCss({position: 'absolute'}); + + var defaults = { + className: 'angular-dnd-lasso', + offsetX: 0, + offsetY: 0 + }; + + function Handler(local){ + + this.getRect = function(){ + return this.isActive ? local.rect : undefined; + } + + this.getClientRect = function(){ + return this.isActive ? $div.dndClientRect() : undefined; + } + + this.isActive = function(){ + return local.active; + } + } + + function Local(api){ + var isTarget = api.isTarget(), handler = new Handler(this); + + this.isTarget = function(){ + return isTarget; + } + + this.handler = function(){ + return handler; + } + + this.getEvent = function(){ + return api.getEvent(); + } + } + + function Lasso(opts){ + + var self = this; + + opts = extend( {}, defaults, opts ); + + function dragstart(api) { + var local = api.local = new Local(api); + + if( !local.isTarget() ) { + self.trigger('start', local.handler() ); + return; + } + + local.active = true; + + self.trigger('start', local.handler() ); + + api.setReferenceElement(opts.$el); + api.setBounderElement(opts.$el); + + local.startAxis = api.getRelBorderedAxis(); + + $div.removeAttr('class style').removeClass('ng-hide').addClass(opts.className); + + opts.$el.append( $div ); + + }; + + function drag(api) { + var local = api.local; + + if( !local.active ) { + self.trigger('drag', local.handler()); + return; + } + + var change = api.getRelBorderedAxis().minus(local.startAxis); + + var rect = { + top: local.startAxis.y, + left: local.startAxis.x, + width: change.x, + height: change.y + }; + + if(rect.width < 0) { + rect.width = - rect.width; + rect.left = rect.left - rect.width; + } + + if(rect.height < 0) { + rect.height = - rect.height; + rect.top = rect.top - rect.height; + } + + local.rect = rect; + + rect.top += opts.offsetY; + rect.left += opts.offsetX; + + $div.dndCss(rect); + + self.trigger('drag', local.handler() ); + }; + + function dragend(api) { + var local = api.local; + + if( !local.active ) { + self.trigger('end', local.handler()); + return; + } + + $div.addClass('ng-hide'); + + $(document.body).append( $div ); + + self.trigger('end', local.handler() ); + }; + + var bindings = { + '$$lasso.dragstart': dragstart, + '$$lasso.drag': drag, + '$$lasso.dragend': dragend + }; + + opts.$el.dndBind(bindings); + + this.destroy = function(){ + opts.$el.dndUnbind(); + }; + + var events = {}; + + this.on = function(name, fn) { + events[name] = events[name] || []; + events[name].push(fn); + }; + + this.trigger = function(name, args) { + events[name] = events[name] || []; + args = args || typeof args === 'string' ? [args] : []; + events[name].forEach(function(fn) { + fn.apply(this, args); + }); + } + } + + return Lasso; + }]) + ; + + module.factory('EventEmitter', [function () { + + function EventEmitter() { + var events = {}; + + this.on = function(name, fn) { + events[name] = events[name] || []; + events[name].push(fn); + }; + + this.off = function(name, fn) { + if(!events[name]) return; + + for(var i = 0, length = events[name].length; i < length; i++){ + if(events[name][i] === fn) events[name].splice(i, 1); + } + }; + + this.trigger = function(name, args) { + events[name] = events[name] || []; + args = args || typeof args === 'string' ? [args] : []; + events[name].forEach(function(fn) { + fn.apply(this, args); + }); + } + } + + return EventEmitter; + }]) + + +})(angular, undefined, window, document); \ No newline at end of file diff --git a/demo/grid-dnd-sort-2/grid-dnd-sort.html b/demo/grid-dnd-sort-2/grid-dnd-sort.html new file mode 100644 index 00000000..de234b1f --- /dev/null +++ b/demo/grid-dnd-sort-2/grid-dnd-sort.html @@ -0,0 +1,52 @@ + + + + + Grid dnd sort (applyLayout) + + + + + + + + + +
+ + browse other examples + +

Grid drag and drop sort, applyLayout

+ +
+ Here is the implementation sample of drag and drop grid columns sorting through the applyLayout method call.
+ Also this demo demonstrates an option of an integration with some external components.
+ And here is being used angular-dnd component to provide + columns drag and drop functionality. +
+ + + + + + + + + + + + + + +
+ {{item.name}} +
{{item.col1}}{{item.col2}}{{item.col3}}
+ +
+ + \ No newline at end of file diff --git a/demo/grid-dnd-sort-2/grid-dnd-sort.js b/demo/grid-dnd-sort-2/grid-dnd-sort.js new file mode 100644 index 00000000..b7b6d421 --- /dev/null +++ b/demo/grid-dnd-sort-2/grid-dnd-sort.js @@ -0,0 +1,45 @@ +angular.module('application', ['ui.scroll', 'ui.scroll.grid', 'dnd']) + .controller('gridController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + col1: i, + col2: 'item #' + i, + col3: (Math.random() < 0.5) + }); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + $scope.headers = [{ + index: 0, + name: 'col1', + sortable: true + }, { + index: 1, + name: 'col2', + sortable: true + }, { + index: 2, + name: 'col3', + sortable: true + }]; + + $scope.onSortEnd = function () { + var layout = $scope.adapter.gridAdapter.getLayout(); + for (var i = 0; i < $scope.headers.length; i++) { + layout[$scope.headers[i].index].mapTo = i; + } + $scope.adapter.gridAdapter.applyLayout(layout) + }; + + } + ]); \ No newline at end of file diff --git a/demo/grid-dnd-sort-2/grid.css b/demo/grid-dnd-sort-2/grid.css new file mode 100644 index 00000000..eb0c9dcd --- /dev/null +++ b/demo/grid-dnd-sort-2/grid.css @@ -0,0 +1,28 @@ +.grid { + height: 300px; +} + +.col1 { + width: 80px; + font-style: italic; +} + +.col2 { + width: 200px; +} + +.col3 { + width: 80px; +} + +.grid th { + cursor: pointer; +} + +.angular-dnd-placeholder { + background: #ddd; +} + +.active { + border: 1px dashed red; +} \ No newline at end of file diff --git a/demo/grid-dnd-sort/grid-dnd-sort.html b/demo/grid-dnd-sort/grid-dnd-sort.html new file mode 100644 index 00000000..e950e1ea --- /dev/null +++ b/demo/grid-dnd-sort/grid-dnd-sort.html @@ -0,0 +1,56 @@ + + + + + Grid dnd sort + + + + + + + + +
+ + browse other examples + +

Grid drag and drop sort, moveBefore

+ +
+
+ Here two methods are being demonstrated. columnFromPoint() which allows you to get the appropriate ColumnAdapter object by coordinates: +
+target = $scope.adapter.gridAdapter.columnFromPoint(evt.clientX, evt.clientY)
+ Another method is moveBefore() which provides an ability to move one column in front of another: +
+column.moveBefore(target)
+
+
+ + + + + + + + + + + + + + +
+ {{item.name}} +
{{item.col1}}{{item.col2}}{{item.col3}}
+ +
+ + \ No newline at end of file diff --git a/demo/grid-dnd-sort/grid-dnd-sort.js b/demo/grid-dnd-sort/grid-dnd-sort.js new file mode 100644 index 00000000..71f32f75 --- /dev/null +++ b/demo/grid-dnd-sort/grid-dnd-sort.js @@ -0,0 +1,56 @@ +angular.module('application', ['ui.scroll', 'ui.scroll.grid']) + .controller('gridController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + col1: i, + col2: 'item #' + i, + col3: (Math.random() < 0.5) + }); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + $scope.headers = [{ + index: 0, + name: 'col1', + sortable: true + }, { + index: 1, + name: 'col2', + sortable: true + }, { + index: 2, + name: 'col3', + sortable: true + }]; + + $scope.dragStart = function (evt) { + var column = $scope.adapter.gridAdapter.columnFromPoint(evt.clientX, evt.clientY); + evt.dataTransfer.setData('application/x-data', + $scope.adapter.gridAdapter.columns.findIndex((c) => c.columnId === column.columnId) + ); + } + + $scope.dragOver = function (evt) { + evt.preventDefault(); + return false; + } + + $scope.dragDrop = function (evt) { + var target = $scope.adapter.gridAdapter.columnFromPoint(evt.clientX, evt.clientY); + var column = $scope.adapter.gridAdapter.columns[evt.dataTransfer.getData('application/x-data')]; + column.moveBefore(target); + console.log(evt.dataTransfer); + } + + } + ]); diff --git a/demo/grid-dnd-sort/grid.css b/demo/grid-dnd-sort/grid.css new file mode 100644 index 00000000..eb0c9dcd --- /dev/null +++ b/demo/grid-dnd-sort/grid.css @@ -0,0 +1,28 @@ +.grid { + height: 300px; +} + +.col1 { + width: 80px; + font-style: italic; +} + +.col2 { + width: 200px; +} + +.col3 { + width: 80px; +} + +.grid th { + cursor: pointer; +} + +.angular-dnd-placeholder { + background: #ddd; +} + +.active { + border: 1px dashed red; +} \ No newline at end of file diff --git a/demo/grid-dnd-widths/grid-dnd-widths.html b/demo/grid-dnd-widths/grid-dnd-widths.html new file mode 100644 index 00000000..06f05182 --- /dev/null +++ b/demo/grid-dnd-widths/grid-dnd-widths.html @@ -0,0 +1,55 @@ + + + + + Grid dnd widths + + + + + + + + +
+ + browse other examples + +

Grid drag and drop widths

+ +
+ To manipulate grid columns widths .css method on gridAdapter column is available: +
+
+$scope.adapter.gridAdapter.columns[0].css('width', '200px');
+
+ You also can set any css property this way. +
+ + + + + + + + + + + + + + +
+ num + + text
{{item.col1}}{{item.col2}}
+ +
+ + \ No newline at end of file diff --git a/demo/grid-dnd-widths/grid-dnd-widths.js b/demo/grid-dnd-widths/grid-dnd-widths.js new file mode 100644 index 00000000..9404aeca --- /dev/null +++ b/demo/grid-dnd-widths/grid-dnd-widths.js @@ -0,0 +1,57 @@ +angular.module('application', ['ui.scroll', 'ui.scroll.grid']) + .controller('gridController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + col1: i, + col2: 'item #' + i + }); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + var splitter = angular.element(document.getElementById('splitter')); + var startX = 0; + var right = 0; + var startDrag = false; + + $scope.dragStart = function (evt) { + if(startDrag) { + return false; + } + splitter.addClass('active'); + startDrag = true; + startX = right + evt.clientX; + }; + + $scope.dragOver = function (evt) { + if(!startDrag) { + return false; + } + + right = startX - evt.clientX; + $scope.adapter.gridAdapter.columns[1].css('width', (200 + right) + 'px'); + $scope.adapter.gridAdapter.columns[0].css('width', (80 - right) + 'px'); + splitter.css('right', '0'); + + return false; + }; + + $scope.dragDrop = function (evt) { + startDrag = false; + splitter.removeClass('active'); + } + + + } + ]); + + diff --git a/demo/grid-dnd-widths/grid.css b/demo/grid-dnd-widths/grid.css new file mode 100644 index 00000000..1fe6cc7b --- /dev/null +++ b/demo/grid-dnd-widths/grid.css @@ -0,0 +1,40 @@ +.grid { + height: 300px; +} + +.grid tbody { + width: 300px; + } + +.col1 { + width: 80px; +} + +td.col1 { + font-style: italic; +} + +.col2 { + width: 200px; +} + +.splitter{ + cursor: e-resize; + float: right; + border: 2px solid black; + height: 20px; + position: relative; + right: 0; +} + +td, th { + border: 0 dashed #999; + border-left-width: 1px; +} +th { + border-bottom-width: 1px; +} + +.active { + border: 2px solid red; +} \ No newline at end of file diff --git a/demo/grid-layout-apply/grid-layout-apply.html b/demo/grid-layout-apply/grid-layout-apply.html new file mode 100644 index 00000000..ee13f49d --- /dev/null +++ b/demo/grid-layout-apply/grid-layout-apply.html @@ -0,0 +1,46 @@ + + + + + Grid layout apply + + + + + + + + +
+ + browse other examples + +

Grid layout apply

+ +
+ - should apply bg-colors and a new columns order +
+ - just should clear +
+
+ + + + + + + + + + + + + + + + +
numbercontentbool
{{item.col1}}{{item.col2}}{{item.col3}}
+ +
+ + \ No newline at end of file diff --git a/demo/grid-layout-apply/grid-layout-apply.js b/demo/grid-layout-apply/grid-layout-apply.js new file mode 100644 index 00000000..11c13b2f --- /dev/null +++ b/demo/grid-layout-apply/grid-layout-apply.js @@ -0,0 +1,43 @@ +angular.module('application', ['ui.scroll', 'ui.scroll.grid']) + .controller('gridController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + col1: i, + col2: 'item #' + i, + col3: (Math.random() < 0.5) + }); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + var clearLayout = [ + {index: 0, mapTo: 0, css: {backgroundColor: ''}}, + {index: 1, mapTo: 1, css: {backgroundColor: ''}}, + {index: 2, mapTo: 2, css: {backgroundColor: ''}} + ]; + + var someLayout = [ + {index: 0, mapTo: 2, css: {backgroundColor: '#ccc'}}, + {index: 1, mapTo: 1, css: {backgroundColor: '#ddd'}}, + {index: 2, mapTo: 0, css: {backgroundColor: '#eee'}} + ]; + + $scope.applyLayout = function () { + $scope.adapter.gridAdapter.applyLayout(someLayout); + }; + + $scope.clearLayout = function () { + $scope.adapter.gridAdapter.applyLayout(clearLayout); + }; + + } + ]); diff --git a/demo/grid-layout-apply/grid.css b/demo/grid-layout-apply/grid.css new file mode 100644 index 00000000..662fa528 --- /dev/null +++ b/demo/grid-layout-apply/grid.css @@ -0,0 +1,31 @@ +.grid { + height: 300px; +} + +.grid tbody { + width: 380px; +} + +hr { + margin: 5px; +} + +.col1 { + width: 80px; +} + +td.col1 { + font-style: italic; +} + +.col2 { + width: 200px; +} + +.col3 { + width: 80px; +} + +input { + margin-bottom: 5px; +} diff --git a/demo/grid-layout-manipulations/grid-layout-manipulations.html b/demo/grid-layout-manipulations/grid-layout-manipulations.html new file mode 100644 index 00000000..15c53765 --- /dev/null +++ b/demo/grid-layout-manipulations/grid-layout-manipulations.html @@ -0,0 +1,66 @@ + + + + + Grid layout manipulations + + + + + + + + +
+ + browse other examples + +

Grid layout manipulations

+ +
+

+ Here we have a demo on grid layout manipulations. + The layout can be updated out of the components core, saved and applied. + To apply some layout you may call applyLayout method on gridAdapter: +

+
+$scope.adapter.gridAdapter.applyLayout(layout)
+ The "layout" variable must have an appropriate format which exactly matches the format of getLayout() method call result. +
+
+layout = $scope.adapter.gridAdapter.getLayout()
+ Note that saving via cookie requires web-server. +

+
+ +
+ 1 column bg-color
+ 2 column bg-color
+ 3 column bg-color
+ + +
+ + +
+ + + + + + + + + + + + + + + + +
numbercontentbool
{{item.col1}}{{item.col2}}{{item.col3}}
+ +
+ + \ No newline at end of file diff --git a/demo/grid-layout-manipulations/grid-layout-manipulations.js b/demo/grid-layout-manipulations/grid-layout-manipulations.js new file mode 100644 index 00000000..8a137feb --- /dev/null +++ b/demo/grid-layout-manipulations/grid-layout-manipulations.js @@ -0,0 +1,65 @@ +angular.module('application', ['ui.scroll', 'ui.scroll.grid']) + .controller('gridController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + col1: i, + col2: 'item #' + i, + col3: (Math.random() < 0.5) + }); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + var cookieName = 'ui-scroll-grid-layout'; + + var clearLayout = [ + {index: 0, mapTo: 0, css: {backgroundColor: ''}}, + {index: 1, mapTo: 1, css: {backgroundColor: ''}}, + {index: 2, mapTo: 2, css: {backgroundColor: ''}} + ]; + + $scope.layout = [ + {index: 0, mapTo: 0, css: {backgroundColor: '#eee'}}, + {index: 1, mapTo: 1, css: {backgroundColor: '#ddd'}}, + {index: 2, mapTo: 2, css: {backgroundColor: '#ccc'}} + ]; + + $scope.applyLayout = function () { + $scope.adapter.gridAdapter.applyLayout($scope.layout); + }; + + $scope.clearLayout = function () { + $scope.adapter.gridAdapter.applyLayout(clearLayout); + }; + + $scope.saveLayout = function () { + var layout = $scope.adapter.gridAdapter.getLayout(); + + var date = new Date(); + date.setTime(date.getTime() + 30 * 24 * 3600 * 1000); // 30 days + document.cookie = cookieName + "=" + JSON.stringify(layout) + "; path=/;expires = " + date.toGMTString(); + }; + + $scope.restoreLayout = function () { + var value = "; " + document.cookie; + var parts = value.split("; " + cookieName + "="); + var result; + if (parts.length != 2 || !(result = parts.pop().split(";").shift())) { + alert('Nothing to apply'); + return; + } + $scope.layout = JSON.parse(result); + $scope.applyLayout(); + }; + + } + ]); diff --git a/demo/grid-layout-manipulations/grid.css b/demo/grid-layout-manipulations/grid.css new file mode 100644 index 00000000..662fa528 --- /dev/null +++ b/demo/grid-layout-manipulations/grid.css @@ -0,0 +1,31 @@ +.grid { + height: 300px; +} + +.grid tbody { + width: 380px; +} + +hr { + margin: 5px; +} + +.col1 { + width: 80px; +} + +td.col1 { + font-style: italic; +} + +.col2 { + width: 200px; +} + +.col3 { + width: 80px; +} + +input { + margin-bottom: 5px; +} diff --git a/demo/grid-scopes-wrapping/grid-scopes-wrapping.html b/demo/grid-scopes-wrapping/grid-scopes-wrapping.html new file mode 100644 index 00000000..6dc8a525 --- /dev/null +++ b/demo/grid-scopes-wrapping/grid-scopes-wrapping.html @@ -0,0 +1,39 @@ + + + + + Grid scopes wrapping + + + + + + + + +
+ + browse other examples + +

Grid scopes wrapping

+ +
+

Here we have ng-repeat wrapping ui-scroll-td directive!

+

+ + + + + + + + + + + + +
{{col}}
{{item[col]}}
+ +
+ + \ No newline at end of file diff --git a/demo/grid-scopes-wrapping/grid-scopes-wrapping.js b/demo/grid-scopes-wrapping/grid-scopes-wrapping.js new file mode 100644 index 00000000..d1480562 --- /dev/null +++ b/demo/grid-scopes-wrapping/grid-scopes-wrapping.js @@ -0,0 +1,45 @@ +angular.module('application', ['ui.scroll', 'ui.scroll.grid']) + .controller('gridController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + $scope.columns = ['col1','col2','col3']; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + col1: i, + col2: 'item #' + i, + col3: (Math.random() < 0.5) + }); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + var clearLayout = [ + {index: 0, mapTo: 0, css: {backgroundColor: ''}}, + {index: 1, mapTo: 1, css: {backgroundColor: ''}}, + {index: 2, mapTo: 2, css: {backgroundColor: ''}} + ]; + + var someLayout = [ + {index: 0, mapTo: 2, css: {backgroundColor: '#ccc'}}, + {index: 1, mapTo: 1, css: {backgroundColor: '#ddd'}}, + {index: 2, mapTo: 0, css: {backgroundColor: '#eee'}} + ]; + + $scope.applyLayout = function () { + $scope.adapter.gridAdapter.applyLayout(someLayout); + }; + + $scope.clearLayout = function () { + $scope.adapter.gridAdapter.applyLayout(clearLayout); + }; + + } + ]); diff --git a/demo/grid-scopes-wrapping/grid.css b/demo/grid-scopes-wrapping/grid.css new file mode 100644 index 00000000..662fa528 --- /dev/null +++ b/demo/grid-scopes-wrapping/grid.css @@ -0,0 +1,31 @@ +.grid { + height: 300px; +} + +.grid tbody { + width: 380px; +} + +hr { + margin: 5px; +} + +.col1 { + width: 80px; +} + +td.col1 { + font-style: italic; +} + +.col2 { + width: 200px; +} + +.col3 { + width: 80px; +} + +input { + margin-bottom: 5px; +} diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 00000000..3f853c6e --- /dev/null +++ b/demo/index.html @@ -0,0 +1,195 @@ + + + + + Scroller Demo + + + + + + diff --git a/demo/insideComponent/insideComponent.html b/demo/insideComponent/insideComponent.html new file mode 100644 index 00000000..01dc6c92 --- /dev/null +++ b/demo/insideComponent/insideComponent.html @@ -0,0 +1,32 @@ + + + + + Inside Angular 1.5+ component + + + + + + + +
+ + browse other examples + +

Scroller inside Angular 1.5+ Component

+ +
+ This sample demonstrates encapsulation of the ui-scroll directive inside some custom component (Angular 1.5+). + + To demonstrate the work of the Adapter, click on any row. The text of the item should change after click. + + The controller of this Component is implemented as ES6 class. Note that this demo might not work in old browsers which don't support ES6 classes. +
+ + + +
+ + + diff --git a/demo/insideComponent/insideComponent.js b/demo/insideComponent/insideComponent.js new file mode 100644 index 00000000..24c7ce6b --- /dev/null +++ b/demo/insideComponent/insideComponent.js @@ -0,0 +1,45 @@ +(function (angular) { + + class Ctrl { + constructor($timeout, $scope) { + this.timeout = $timeout; + this.show = true; + this.$scope = $scope; + } + + get(index, count, success) { + this.timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + id: i, + name: "item #" + i + }); + } + success(result); + }, 100); + } + + update(id) { + return this.scrollAdapter.applyUpdates(function (item) { + if (item.id === id) { + item.name += " *"; + } + }); + } + } + + angular + .module('application', ['ui.scroll']) + .component('myComponent', { + controllerAs: 'ctrl', + template: + '
' + + '
' + + '
{{item.name}}
' + + '
' + + '
', + controller: Ctrl + }); + +})(angular); diff --git a/demo/insideDirective/insideDirective.html b/demo/insideDirective/insideDirective.html new file mode 100644 index 00000000..da5021ee --- /dev/null +++ b/demo/insideDirective/insideDirective.html @@ -0,0 +1,33 @@ + + + + + Inside directive + + + + + + + +
+ + browse other examples + +

Scroller inside the directive

+ +
+ This sample demonstrates encapsulation of the ui-scroll directive inside another custom directive wich has it's own controller and wich uses "Controller As" syntax in it's template. + To demonstrate the work of the Adapter, click on any row. The text of the item should change after click. +
+ +
+
+ +
+
+ +
+ + + \ No newline at end of file diff --git a/demo/insideDirective/insideDirective.js b/demo/insideDirective/insideDirective.js new file mode 100644 index 00000000..35ec6953 --- /dev/null +++ b/demo/insideDirective/insideDirective.js @@ -0,0 +1,40 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', ['$scope', function($scope) { + $scope.show = true; + }]) + .directive('myDir', function() { + return { + restrict: 'E', + controllerAs: 'ctrl', + template: + '
' + + '
' + + '
{{item.name}}
' + + '
' + + '
', + controller: function ($timeout) { + var ctrl = this; + ctrl.show = true; + ctrl.get = function(index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push({ + id: i, + name: "item #" + i + }); + } + success(result); + }, 100); + } + ctrl.update = function(id) { + return ctrl.scrollAdapter.applyUpdates(function(item) { + if (item.id === id) { + item.name += " *"; + } + }); + } + } + } + } +); diff --git a/demo/isLoading/isLoading.html b/demo/isLoading/isLoading.html new file mode 100644 index 00000000..4089f7e9 --- /dev/null +++ b/demo/isLoading/isLoading.html @@ -0,0 +1,43 @@ + + + + + Is loading + + + + + + + +
+ + browse other examples + +

Is loading

+ +
+ There is an optional parameter of ui-scroll directive which allows us to know whether there are any pending load requests. + +
+
<li ui-scroll="item in datasource" is-loading="loading">*{{item}}*</li>
+
+ + We recommend to use isLoading property on adapter. + Please follow this demo. +
+ +
+
is loading: {{loading}}
+
+ +
+
    +
  • *{{item}}*
  • +
+
+ +
+ + + \ No newline at end of file diff --git a/demo/isLoading/isLoading.js b/demo/isLoading/isLoading.js new file mode 100644 index 00000000..6372d32d --- /dev/null +++ b/demo/isLoading/isLoading.js @@ -0,0 +1,19 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', ['$log', '$timeout', + function (console, $timeout) { + + var get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + return { + get: get + }; + } + ]); \ No newline at end of file diff --git a/demo/isLoading/isLoadingAdapter.html b/demo/isLoading/isLoadingAdapter.html new file mode 100644 index 00000000..68dcf14d --- /dev/null +++ b/demo/isLoading/isLoadingAdapter.html @@ -0,0 +1,44 @@ + + + + + Is loading (Adapter) + + + + + + + +
+ + browse other examples + +

Is loading (Adapter)

+ +
+ As it follows from documentation Adapter implements isLoading property to make us know whether there are any pending load requests. + +
+
<li ui-scroll="item in datasource" adapter="adapter">*{{item}}*</li>
+
+ +
+
is loading: {{adapter.isLoading}}
+
+
+ +
+
is loading: {{adapter.isLoading}}
+
+ +
+
    +
  • *{{item}}*
  • +
+
+ +
+ + + \ No newline at end of file diff --git a/demo/isLoading/isLoadingAdapter.js b/demo/isLoading/isLoadingAdapter.js new file mode 100644 index 00000000..8f2e18f5 --- /dev/null +++ b/demo/isLoading/isLoadingAdapter.js @@ -0,0 +1,20 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + + $scope.adapter = {}; + + $scope.datasource = {}; + + $scope.datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + } + ]); diff --git a/demo/jquery/jquery.html b/demo/jquery/jquery.html new file mode 100644 index 00000000..390b9360 --- /dev/null +++ b/demo/jquery/jquery.html @@ -0,0 +1,37 @@ + + + + + jQuery + + + + + + + + +
+ + browse other examples + +

jQuery

+ +
+ In case the Angular App works with jQuery, the ui-scroll should use jQuery. + Otherwise, the ui-scroll should use jqLiteExtras. +
+ +
+ jQuery version is {{jqueryVersion}} + jQuery is not loaded +
+ +
+
{{item}}
+
+ +
+ + + \ No newline at end of file diff --git a/demo/jquery/jquery.js b/demo/jquery/jquery.js new file mode 100644 index 00000000..de5167d2 --- /dev/null +++ b/demo/jquery/jquery.js @@ -0,0 +1,21 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + $scope.jqueryVersion = window.jQuery && angular.element.fn && angular.element.fn.jquery; + + } + ]); diff --git a/demo/listScroller/listScroller.html b/demo/listScroller/listScroller.html new file mode 100644 index 00000000..0fbb7437 --- /dev/null +++ b/demo/listScroller/listScroller.html @@ -0,0 +1,40 @@ + + + + + li based scrollable list + + + + + + + +
+ + browse other examples + +

li based scrollable list

+ +
+ Since html container with ui-scroll attribute is repeatable there are some ways to build a template. + This sample demonstrates list based (<li>) template usage. + +
+
+<ul ui-scroll-viewport>
+	<li ui-scroll="item in datasource">*{{item}}*</li>
+</ul>
+
+
+ +
+
    +
  • *{{item}}*
  • +
+
+ +
+ + + \ No newline at end of file diff --git a/demo/listScroller/listScroller.js b/demo/listScroller/listScroller.js new file mode 100644 index 00000000..6372d32d --- /dev/null +++ b/demo/listScroller/listScroller.js @@ -0,0 +1,19 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', ['$log', '$timeout', + function (console, $timeout) { + + var get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + return { + get: get + }; + } + ]); \ No newline at end of file diff --git a/demo/multipleLists/multipleLists.html b/demo/multipleLists/multipleLists.html new file mode 100644 index 00000000..4f7d5df0 --- /dev/null +++ b/demo/multipleLists/multipleLists.html @@ -0,0 +1,49 @@ + + + + + Independent scrollable lists + + + + + + + +
+ + browse other examples + +

Independent scrollable lists

+ +
+ Here we have two different viewports but single datasource. +
+ +
+
is loading (1): {{adapter.isLoading}}
+
is loading (2): {{adapter2.isLoading}}
+
+ +
+

The List

+
+
*one {{item}}*
+
+
+ +
+

One more list

+
+
+ *two {{item}}* +
    +
  • {{line}}
  • +
+
+
+ +
+ + + \ No newline at end of file diff --git a/demo/multipleLists/multipleLists.js b/demo/multipleLists/multipleLists.js new file mode 100644 index 00000000..612fa584 --- /dev/null +++ b/demo/multipleLists/multipleLists.js @@ -0,0 +1,19 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + $scope.adapter = {}; + } + ]); diff --git a/demo/multipleReloadTest/multipleReload.html b/demo/multipleReloadTest/multipleReload.html new file mode 100644 index 00000000..964df9ac --- /dev/null +++ b/demo/multipleReloadTest/multipleReload.html @@ -0,0 +1,32 @@ + + + + + Multiple reload test + + + + + + + +
+ + browse other examples + +

Multiple reload test

+ +
+ + + Loading: {{adapter.isLoading}} +
+ +
+
{{item}}
+
+ +
+ + + \ No newline at end of file diff --git a/demo/multipleReloadTest/multipleReload.js b/demo/multipleReloadTest/multipleReload.js new file mode 100644 index 00000000..70950d03 --- /dev/null +++ b/demo/multipleReloadTest/multipleReload.js @@ -0,0 +1,33 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + $scope.doSingleReload = function () { + $scope.adapter.reload(); + }; + + $scope.doMultipleReload = function () { + $scope.adapter.reload(); + $timeout(function () { + $scope.adapter.reload(); + }); + $timeout(function () { + $scope.adapter.reload(); + }); + }; + + } + ]); diff --git a/demo/outOfBuffer/outOfBuffer.html b/demo/outOfBuffer/outOfBuffer.html new file mode 100644 index 00000000..3c639946 --- /dev/null +++ b/demo/outOfBuffer/outOfBuffer.html @@ -0,0 +1,49 @@ + + + + + Adapter sync + + + + + + + + +
+ +
+ + + + + +
+ +
+ +
    +
  • +
    + {{$index}}: {{item.content}} ({{item.id}}) + [x] +
    +
  • +
+ +
+ + \ No newline at end of file diff --git a/demo/outOfBuffer/outOfBuffer.js b/demo/outOfBuffer/outOfBuffer.js new file mode 100644 index 00000000..bc932b22 --- /dev/null +++ b/demo/outOfBuffer/outOfBuffer.js @@ -0,0 +1,217 @@ +var app = angular.module('application', ['ui.scroll']); + +app.factory('Server', [ + '$timeout', '$q', function ($timeout, $q) { + + var ServerFactory = { + + firstIndex: 1, + + lastIndex: 40, + + delay: 100, + + data: [], + + absIndex: 1, + + generateId: function () { + var d = '-'; + function S4() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); + } + return (S4() + S4() + d + S4() + d + S4() + d + S4() + d + S4() + S4() + S4()); + }, + + generateItem: function (index) { + return { + index: index, + id: this.generateId(), + content: 'Item #' + this.absIndex++ + } + }, + + init: function () { + for (var i = this.firstIndex; i <= this.lastIndex; i++) { + this.data.push(this.generateItem(i)); + } + }, + + getItem: function (index) { + for (var i = this.data.length - 1; i >= 0; i--) { + if (this.data[i].index === index) { + return this.data[i]; + } + } + }, + + returnDeferredResult: function (result) { + var deferred = $q.defer(); + $timeout(function () { + deferred.resolve(result); + }, this.delay); + return deferred.promise; + }, + + request: function (index, count) { + var start = index; + var end = index + count - 1; + var item, result = { + items: [] + }; + if (start <= end) { + for (var i = start; i <= end; i++) { + if (item = this.getItem(i)) { + result.items.push(item); + } + } + } + return this.returnDeferredResult(result); + }, + + prependItem: function (params) { + var newItem = this.generateItem(--this.firstIndex); + newItem.content += params; + this.data.unshift(newItem); + return this.returnDeferredResult(newItem); + }, + + appendItem: function (params) { + var newItem = this.generateItem(++this.lastIndex); + newItem.content += params; + this.data.push(newItem); + return this.returnDeferredResult(newItem); + }, + + removeFirst: function () { + var firstItem = this.data.find(i => i.index === this.firstIndex); + if(!firstItem) { + return; + } + return this.removeItemById(firstItem.id); + }, + + removeLast: function () { + var lastItem = this.data.find(i => i.index === this.lastIndex); + if(!lastItem) { + return; + } + return this.removeItemById(lastItem.id); + }, + + removeItemById: function (itemId) { + var length = this.data.length; + for (var i = 0; i < length; i++) { + if (this.data[i].id === itemId) { + var indexRemoved = this.data[i].index; + this.data.splice(i, 1); + this.setIndices(); + return this.returnDeferredResult(indexRemoved); + } + } + return this.returnDeferredResult(false); + }, + + setIndices: function() { + if(!this.data.length) { + this.firstIndex = 1; + this.lastIndex = 1; + return; + } + this.firstIndex = this.data[0].index; + this.lastIndex = this.data[0].index; + for (var i = this.data.length - 1; i >= 0; i--) { + if(this.data[i].index > this.lastIndex) { + this.lastIndex = this.data[i].index; + } + if(this.data[i].index < this.firstIndex) { + this.firstIndex = this.data[i].index; + } + } + } + }; + + ServerFactory.init(); + + return ServerFactory; + + } +]); + + +app.controller('mainController', [ + '$scope', 'Server', function ($scope, Server) { + + var ctrl = this; + + ctrl.datasource = { + get: function (index, count, success) { + console.log('request by index = ' + index + ', count = ' + count); + Server.request(index, count).then(function (result) { + if (result.items) { + console.log('resolved ' + result.items.length + ' items'); + } + success(result.items); + }); + } + }; + + $scope.$watch('adapter', (prev, next) => { + console.log('The adapter has been initialized'); + }); + + ctrl.prepend = function () { + Server.prependItem(' ***').then(function (newItem) { + if (ctrl.adapter.isBOF()) { + ctrl.adapter.prepend([newItem]); + } + }); + }; + + ctrl.append = function () { + Server.appendItem(' ***').then(function (newItem) { + if (ctrl.adapter.isEOF()) { + ctrl.adapter.append([newItem]); + } + }); + }; + + // todo dhilt : need to implement it properly + ctrl.removeAll = function () { + ctrl.adapter.applyUpdates(function (item) { + if (item.id) { + Server.removeItemById(item.id); + return []; + } + }); + }; + + ctrl.remove = function (itemRemove) { + Server.removeItemById(itemRemove.id).then(function (result) { + if (result !== false) { + ctrl.adapter.applyUpdates(function (item) { + if (item.id === itemRemove.id) { + return []; + } + }); + } + }); + }; + + ctrl.removeFirst = function () { + Server.removeFirst().then(function (indexRemoved) { + if (indexRemoved !== false) { + ctrl.adapter.applyUpdates(indexRemoved, []); + } + }); + }; + + ctrl.removeLast = function () { + Server.removeLast().then(function (indexRemoved) { + if (indexRemoved !== false) { + ctrl.adapter.applyUpdates(indexRemoved, []); + } + }); + }; + } +]); diff --git a/demo/persistentScroll/persistentScroll.html b/demo/persistentScroll/persistentScroll.html new file mode 100644 index 00000000..a7904e72 --- /dev/null +++ b/demo/persistentScroll/persistentScroll.html @@ -0,0 +1,38 @@ + + + + + Preserves the scroll position on refresh + + + + + + + +
+ + browse other examples + +

Preserves the scroll position on refresh

+ +
+ This sample demonstrates a functionality of top item position persistence. + This persistence is based on topVisible element's index (offset) which is stored in URL ($location). + So when you do some scrolls you see that 'offset' param is persisted via URL hash. + Then you refresh the page and after that the $index value (and leftmost column in the example) changes, + but the item which used to be on top stays on top. +
+ +
+
top visible: {{topVisible.$index}}
+
+ +
+
{{$index}}: {{item}}
+
+ +
+ + + \ No newline at end of file diff --git a/demo/persistentScroll/persistentScroll.js b/demo/persistentScroll/persistentScroll.js new file mode 100644 index 00000000..14d0d5d7 --- /dev/null +++ b/demo/persistentScroll/persistentScroll.js @@ -0,0 +1,35 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', [ '$log', '$timeout', '$rootScope', '$location', + function (console, $timeout, $rootScope, $location) { + + var offset = parseInt($location.search().offset || '0', 10); + + var get = function (index, count, success) { + $timeout(function () { + var actualIndex = index + offset; + var result = []; + var start = Math.max(-40, actualIndex); + var end = Math.min(actualIndex + count - 1, 100); + if (start <= end) { + for (var i = start; i <= end; i++) { + result.push("item " + i); + } + } + success(result); + }, 100); + }; + + $rootScope.$watch((function () { + return $rootScope.topVisible; + }), function () { + if ($rootScope.topVisible) { + $location.search('offset', $rootScope.topVisible.$index + offset-1); + $location.replace(); + } + }); + + return { + get: get + }; + } + ]); \ No newline at end of file diff --git a/demo/positionedList/positionedList.html b/demo/positionedList/positionedList.html new file mode 100644 index 00000000..993e141d --- /dev/null +++ b/demo/positionedList/positionedList.html @@ -0,0 +1,38 @@ + + + + + Scroller Demo (list based) + + + + + + + +
+ + browse other examples + +

Positions the list based on element data

+ +
+ This sample demonstrates a functionality of list positioning based on element data. + There is no persistence, just enter key value in textinput (from 'aa' to 'zz') and get the key-offset positioned list. +
+ +
+
+
+ +
+
+
+ +
+
{{$index}}: {{item}}
+
+
+ + + \ No newline at end of file diff --git a/demo/positionedList/positionedList.js b/demo/positionedList/positionedList.js new file mode 100644 index 00000000..b350b67c --- /dev/null +++ b/demo/positionedList/positionedList.js @@ -0,0 +1,47 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', ['$log', '$timeout', '$rootScope', + function (console, $timeout, $rootScope) { + + $rootScope.key = ""; + var position = 0; + var data = []; + var ref1 = 'abcdefghijklmnopqrstuvwxyz'; + var ref2 = 'abcdefghijklmnopqrstuvwxyz'; + + for (var j = 0; j < ref1.length; j++) + for (var k = 0, letter1 = ref1[j]; k < ref2.length; k++) + for (var i = 0, letter2 = ref2[k]; i <= 9; i++) + data.push("" + letter1 + letter2 + ": 0" + i); + + var get = function (index, count, success) { + return $timeout(function () { + var actualIndex = index + position; + var start = Math.max(0 - position, actualIndex); + var end = Math.min(actualIndex + count - 1, data.length); + + if (start > end) { + success([]); + } else { + success(data.slice(start, end + 1)); + } + }, 100); + }; + + $rootScope.$watch((function () { + return $rootScope.key; + }), function () { + position = 0; + for (var m = 0; m < data.length; m++) { + if ($rootScope.key > data[m]) { + position++; + } + } + if ($rootScope.key) + $rootScope.adapter.reload(); + }); + + return { + get: get, + }; + } + ]); diff --git a/demo/rebuilding/rebuilding.html b/demo/rebuilding/rebuilding.html new file mode 100644 index 00000000..91e831cd --- /dev/null +++ b/demo/rebuilding/rebuilding.html @@ -0,0 +1,40 @@ + + + + + Rebuilding + + + + + + + +
+ + browse other examples + +

Multiple component rebuild

+ +
+ This demo allows to trace memory leaks during destroy and rebuild ui-scroll component. +
+ +
+
+ +
+
+ +
+
+
{{item}}
+
+
+ +
+ + + \ No newline at end of file diff --git a/demo/rebuilding/rebuilding.js b/demo/rebuilding/rebuilding.js new file mode 100644 index 00000000..ddada8cf --- /dev/null +++ b/demo/rebuilding/rebuilding.js @@ -0,0 +1,20 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + $scope.switch = false; + } + ]); diff --git a/demo/reload100/reload100.html b/demo/reload100/reload100.html new file mode 100644 index 00000000..2d3534ec --- /dev/null +++ b/demo/reload100/reload100.html @@ -0,0 +1,43 @@ + + + + + Reload 100 + + + + + + + +
+ + browse other examples + +

Reload with parameter

+ +
+ Here we provide an ability to reload the datasource to some specified position. First you need an adapter defined on your scope: +
+
<div ui-scroll="item in datasource" adapter="myAdapter">{{item}}</div>
+
+ Then just call the reload method on the adapter with index parameter: +
+
$scope.myAdapter.reload(100);
+
+
+ +
+ - index to reload
+ +
+ + +
+
{{item}}
+
+ +
+ + + \ No newline at end of file diff --git a/demo/reload100/reload100.js b/demo/reload100/reload100.js new file mode 100644 index 00000000..dd3977c9 --- /dev/null +++ b/demo/reload100/reload100.js @@ -0,0 +1,32 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + + $scope.doReload = function () { + if (angular.isFunction($scope.adapter.reload)) { + var reloadIndex = parseInt($scope.reloadIndex, 10); + reloadIndex = isNaN(reloadIndex) ? 1 : reloadIndex; + $scope.adapter.reload(reloadIndex); + } + }; +/* + $scope.delay = false; + $timeout(function() { + $scope.delay = true; + }, 500); +*/ + } + ]); diff --git a/demo/remote/remote.html b/demo/remote/remote.html new file mode 100644 index 00000000..d589fb11 --- /dev/null +++ b/demo/remote/remote.html @@ -0,0 +1,34 @@ + + + + + + Remote server emulation + + + + + + + +
+ browse other examples +

Remote server emulation

+
+ This demo implements Remote server emulation factory, so the datasource get method looks like +
+
+datasource.get = function(index, count, success) {
+  Server.request(index, count).then(success);
+};
+
+
+
+
+ {{item.content}} +
+
+
+ + + \ No newline at end of file diff --git a/demo/remote/remote.js b/demo/remote/remote.js new file mode 100644 index 00000000..acf218c1 --- /dev/null +++ b/demo/remote/remote.js @@ -0,0 +1,69 @@ +angular.module('application', ['ui.scroll']) + + .factory('Server', function($timeout, $q) { + return { + + default: { + first: 0, + max: 99, + delay: 100 + }, + + data: [], + + init: function(settings = {}) { + this.first = settings.hasOwnProperty('first') ? settings.first : this.default.first; + this.max = settings.hasOwnProperty('max') ? settings.max : this.default.max; + this.delay = settings.hasOwnProperty('delay') ? settings.delay : this.default.delay; + for (var i = this.first; i <= this.max; i++) { + this.data[i] = { + index: i, + content: 'Item #' + i + }; + } + }, + + request: function(index, count) { + var self = this; + var deferred = $q.defer(); + + var start = index; + var end = index + count - 1; + + $timeout(function() { + var item, result = []; + if (start <= end) { + for (var i = start; i <= end; i++) { + if (item = self.data[i]) { + result.push(item); + } + } + } + deferred.resolve(result); + }, self.delay); + + return deferred.promise; + } + }; + }) + + .controller('mainController', function($scope, Server) { + + $scope.firstIndex = 1; + + Server.init({ + first: $scope.firstIndex, + max: 100, + delay: 40 + }); + + $scope.datasource = { + get: function(index, count, success) { + console.log('requested index = ' + index + ', count = ' + count); + Server.request(index, count).then(function(result) { + console.log('resolved ' + result.length + ' items'); + success(result); + }); + } + }; + }); \ No newline at end of file diff --git a/demo/scopeDatasource/scopeDatasource.html b/demo/scopeDatasource/scopeDatasource.html new file mode 100644 index 00000000..2ed4a6ed --- /dev/null +++ b/demo/scopeDatasource/scopeDatasource.html @@ -0,0 +1,49 @@ + + + + + Datasource on scope (not as service) + + + + + + + +
+ + browse other examples + +

Datasource on scope (not as service)

+ +
+ Per documentation the datasource object can be defined in two different ways. + +
+
<li ui-scroll="item in datasource">{{item}}</li>
+
+ + And the directive will first look for a property with the given name (datasource) on its $scope. + So to use scope-approach you need to declare datasource object on scope of your controller and define method get on it. + +
+
+angular.module('application', ['ui.scroll'])
+  .controller('mainController', ...
+
+    var get = function(index, count, success) { ... };
+
+    $scope.datasource = { get: get };
+
+  );
+
+
+ +
+
{{item}}
+
+ +
+ + + \ No newline at end of file diff --git a/demo/scopeDatasource/scopeDatasource.js b/demo/scopeDatasource/scopeDatasource.js new file mode 100644 index 00000000..7c873bc8 --- /dev/null +++ b/demo/scopeDatasource/scopeDatasource.js @@ -0,0 +1,18 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + } + ]); diff --git a/demo/scrollBubblingPrevent/scrollBubblingPrevent.html b/demo/scrollBubblingPrevent/scrollBubblingPrevent.html new file mode 100644 index 00000000..594c24a1 --- /dev/null +++ b/demo/scrollBubblingPrevent/scrollBubblingPrevent.html @@ -0,0 +1,33 @@ + + + + + Scroller Demo (scroll bubbles up only after eof/bof) + + + + + + + +
+ + browse other examples + +

Scroll bubbles up only after eof/bof

+ +
+ There are 100 elements in datasource (from -50 to +50). + Scrolling of the document begins only after bof/eof is reached. +
+ +
+
+
{{item}}
+
+
+ +
+ + + diff --git a/demo/scrollBubblingPrevent/scrollBubblingPrevent.js b/demo/scrollBubblingPrevent/scrollBubblingPrevent.js new file mode 100644 index 00000000..a9216917 --- /dev/null +++ b/demo/scrollBubblingPrevent/scrollBubblingPrevent.js @@ -0,0 +1,25 @@ +angular.module('application', ['ui.scroll']).factory('datasource', [ + '$log', '$timeout', function(console, $timeout) { + var get, max, min; + min = -50; + max = 50; + + get = function(index, count, success) { + $timeout(function() { + var result = []; + var start = Math.max(min, index); + var end = Math.min(index + count - 1, max); + if (start <= end) { + for (var i = start; i <= end; i++) { + result.push("item #" + i); + } + } + success(result); + }, 50); + }; + + return { + get: get + }; + } +]); \ No newline at end of file diff --git a/demo/serviceDatasource/serviceDatasource.html b/demo/serviceDatasource/serviceDatasource.html new file mode 100644 index 00000000..030ac514 --- /dev/null +++ b/demo/serviceDatasource/serviceDatasource.html @@ -0,0 +1,48 @@ + + + + + Datasource as service + + + + + + + +
+ + browse other examples + +

Datasource as service

+ +
+ Per documentation the datasource object can be defined in two different ways. + +
+
<li ui-scroll="item in datasource">{{item}}</li>
+
+ + In this sample we use service-approach. Here you need to define angular service and declare method get on it. + +
+
+angular.module('application', ['ui.scroll'])
+  .factory('datasource', function() { ...
+
+    var get = function(index, count, success) { ... };
+
+    return { get: get };
+  });
+
+ +
+ +
+
{{item}}
+
+ +
+ + + \ No newline at end of file diff --git a/demo/serviceDatasource/serviceDatasource.js b/demo/serviceDatasource/serviceDatasource.js new file mode 100644 index 00000000..b8eab711 --- /dev/null +++ b/demo/serviceDatasource/serviceDatasource.js @@ -0,0 +1,19 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', ['$log', '$timeout', + function (console, $timeout) { + + var get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + return { + get: get + }; + } + ]); diff --git a/demo/tableScroller/tableScroller.html b/demo/tableScroller/tableScroller.html new file mode 100644 index 00000000..8bf71353 --- /dev/null +++ b/demo/tableScroller/tableScroller.html @@ -0,0 +1,54 @@ + + + + + Table based scrollable list + + + + + + + +
+ + browse other examples + +

Table based scrollable list

+ +
+ Since html container with ui-scroll attribute is repeatable there are some ways to build a template. + This sample demonstrates table based (<tr>) template usage. + +
+
+<table ui-scroll-viewport>
+	<tr ui-scroll="item in datasource">
+		<td>{{$index}}</td>
+		<td>{{item}}</td>
+	</tr>
+</table>
+
+ + And it needed to be said that we have special logic within ui-scroll sources to support table markup. +
+ +
+ + + + + + + +
+ {{$index}} + + {{item}} +
+
+ +
+ + + \ No newline at end of file diff --git a/demo/tableScroller/tableScroller.js b/demo/tableScroller/tableScroller.js new file mode 100644 index 00000000..b8eab711 --- /dev/null +++ b/demo/tableScroller/tableScroller.js @@ -0,0 +1,19 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', ['$log', '$timeout', + function (console, $timeout) { + + var get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + return { + get: get + }; + } + ]); diff --git a/demo/topVisible/topVisible.html b/demo/topVisible/topVisible.html new file mode 100644 index 00000000..b9f954b6 --- /dev/null +++ b/demo/topVisible/topVisible.html @@ -0,0 +1,41 @@ + + + + + Top visible + + + + + + + +
+ + browse other examples + +

Top visible

+ +
+ There is an optional parameter of ui-scroll directive which gives us a reference to the item currently in the topmost visible position. + +
+
<li ui-scroll="item in datasource" top-visible="topItem">*{{item}}*</li>
+
+ + We recommend to use topVisible property on adapter. + Please follow this demo. +
+ +
+
top visible: {{topVisible}}
+
+ +
+
{{$index}}: {{item}}
+
+ +
+ + + \ No newline at end of file diff --git a/demo/topVisible/topVisible.js b/demo/topVisible/topVisible.js new file mode 100644 index 00000000..6372d32d --- /dev/null +++ b/demo/topVisible/topVisible.js @@ -0,0 +1,19 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', ['$log', '$timeout', + function (console, $timeout) { + + var get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + return { + get: get + }; + } + ]); \ No newline at end of file diff --git a/demo/topVisible/topVisibleAdapter.html b/demo/topVisible/topVisibleAdapter.html new file mode 100644 index 00000000..97b0a1f5 --- /dev/null +++ b/demo/topVisible/topVisibleAdapter.html @@ -0,0 +1,42 @@ + + + + + Top visible (Adapter) + + + + + + + +
+ + browse other examples + +

Top visible (Adapter)

+ +
+ As it follows from documentation Adapter implements topVisible property which is a reference to the item currently in the topmost visible position. + +
+
<li ui-scroll="item in datasource" adapter="adapter">*{{item}}*</li>
+
+ +
+
top visible: {{adapter.topVisible}}
+
+
+ +
+
top visible: {{adapter.topVisible}}
+
+ +
+
*{{item}}*
+
+ +
+ + + \ No newline at end of file diff --git a/demo/topVisible/topVisibleAdapter.js b/demo/topVisible/topVisibleAdapter.js new file mode 100644 index 00000000..8f2e18f5 --- /dev/null +++ b/demo/topVisible/topVisibleAdapter.js @@ -0,0 +1,20 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + + $scope.adapter = {}; + + $scope.datasource = {}; + + $scope.datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + } + ]); diff --git a/demo/ui-scroll-demo.gif b/demo/ui-scroll-demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..3cf917d0c1ac08748180ba527280386e107007a6 GIT binary patch literal 579557 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 z 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%0A$4lDW3x#VR^;b`U5J} z^?DsHa}-QK(AT`{&2VfCm~}X=4wvm<1>Gn(Sbbe$0D>a(1RN%tP2*lAgqiyw=cT^) zenEYn8w^I2wKojxa+&LKRp1xE5+(t3CyV_$=5CSkFxCOUe5T-W)?bY1eU5k@sCH*_i;!2_mcMSCGG#LCGFw=b$NQ04gyVh zB|sBikMeXNmLey|?`i?#l)CbsCS;heq_U6lG%bR=%19KeP=63K;U(+(LMt>1!30Cr z*>-!>W@eZ7%>w!UQ~~yFZo|!G$4uVqM|GNgwk?OY$vW)Ey7khdIz4vjyw~3*^Fr+z zXSHqMc&z>Gb&G4~ez;z9-Q86nkGUeLjmv! z?`O=v_38gsp8gvkfA#e*`&khm^YQ5$bb-Ii)6)hel{(<}$7fkIUXSW@H=*4i9rIu1 zXkPl)bmTu#cNhd-**jQ=1{|Ju$%8Ae}C=<3~kn|}*cr)La4 zo!Bi}JgU=lHvgnfb0k_lgxjwB@W{Dr1ksiqZ-n5FxNOn=D|I^KIicIIxd8t!aoX)o zUU|Cp5lz`|b^1TVX^hWvr&mqWGb=5$Jri!pvo&*mwGKZ(=7wdswm zxi@amiUI2KpR4n#?QI2L+M(h!-Bi2v-PP}k0jM?&K+Cu~r4_pKz^&uF^K;#(c#Be+HB_~Du3nlNuYdZC33Clz?mFy;>UOWxp9La=- zXUWzAG5b2B8xXr-YQMl5!{-ZX=T#&R=LyPS-9bJ?kb?pPtP91yO9R2b%in(vaKC~! z2XRTfWLJ5NZgabEiR1P z9oB1{)&p%6GR_(@&Ypqx3fWcfedxXRd-)PtDg=#v`%3>umr$}P=kG3|YAd!1TV8)z zWoW5Tys=1{jaG@CY?hueG!$N7tXJTu4lNj}f))&!oBvLSCrHL+OQmJ2rspYS7Hj6V zL0&>2PE8Q$CO?hF5TnK@>(-BMf8@n`Vx)%B)S;>It|&8T>ku?MKAhn>UhO`cYr0rw z1I>|d)wn>TveTo`Mm`}L)T$bN6;vF+R!dEOj+eK+A@DLpz5P2mX>NAM2=H?JAk?t=;MMhgK2&j+j5prtFSq{VpVWSS$I}MpXYh zZr(lD4Q(Tu+nIy*5RDu?KttyL2bi>a@SR&l(L$|K>h(Li;`5SBicGxSL&c z`hEqtTV3H$$z&T&*V`Wh+_KXZzXIF=gAGvgnJqLu^;h#*vF_+E^VukDBI&<0pG5-L zr|=T*8ipU;XPvGe)6kB@$9^z0`vT#xnxRB^(tyg1*a%4 zPm1#!lPAbx7~%p&Q>6V*#J2cx$_qGJEu$+@M~~9mwiivTa}FqL%0lj@%>Cpp@JK$> z{3p&c+uj#ROGo9+2`!>RF!gyh!i*w$C9T-C%TXglwZyR_Y_Gqa{cW-%Nt|5BHO0tI z-%~b=JyIpmJEm#h8f^pAW{lRmJn46`6e6y zCP*-NGbffGAKOE1(nSYLLHA}{tEOUbCq-Mi8zn`<&KH>b9pm~yNi{tA5FZ?g-3BCF zyWV0+jqbL3HZ2doPhnFgiDp6v5JZUZu!hQ$M#4SBDGuOPQZyUrk79&<`SHW4JVFU~ zNJ30N^84_3%XZvcx(G^KhbWl50yw}$jun#F3E1=wrUO+NM8S<)vFuf_)L?oMcr0lk zvV$;CdVC8+B<};VpFzT+$cKj3MED(9{NRuLU|EGxafJ~g3!=z5NF;$^N?zWRamR-g zkRSYXJ~I3Oj9s}qEW(M6P$1zZY+QpV=HY3D%zOs|;RxkYMOI)e6P2HM^#F!rHn#v; zPZ-i*rbu5(7T5M}@;yfGcUPs=v&Z7hONuJCapSnUu!D!!VW ziqK?0jy%Rd*6%IUPS+`Cv*8_&wmW;e*&mRq7?%moWt0F$`^MYFv+^R7p;yT&@Y$0; zRiPmHLC2vn76DLk&|rFBIH0LZiEKA7idQjEA+wwTdx)LK>mLx$E65N_IhdPwo;OIS zRx}wlR7~><+h&xZ1DsJ5wo8g#B^QA47Uk750xHEoTbdUiH%A1i zSXkjtacvOE6L)yk7ptpSO36vIg=fk%qXG;+v$Ca0zKTwY^3(Ej;h&Kd&KG=U+@_ow zz2ryE8W{9sBmmZdPG9-m&7>IOBrJlcFed^q9lx~6t2qGt3B z@lh#w$={Lh6G(-^oVYK|@LR2PUX>Dc%$_^eZeJq6+kpc_Xi$(>NW zI5Kz=R;MAA`wS+|v(P+0W^vPLl(|AD$e78n+HV9;g+6I9%T1$ZjVK4Rgp}Dfd{`$V z7tspA{EJ}6Qpvf~b{%RVk)_NVE#GBG)#8k%^WJdv;H8lALTSR=npe>W%zmx2q>^4+ zjJUT%^F}VwDt72q>%l=EUuA{I318c2!ba;KpoxhLDg>$Dk>D?B7_#6gLri2Jj5e09`!R-D!`x)IivTwR!n+F5AGOz? zK5!0F8dk;S%Yw5NZ-z7i6qKf_7M{f(b%$5K&}wRV{yelt2nXinR*%&#`*S}`I+|xG zg)wVuZL=?V*#{f)#H;tP{92Nu@kXzBaoOB^LUl<7WblbM1V=R)ENBMoM9%dgfJJK8 zbV89$T;>7?8S+nkLGOS*t4g6-)MgIH3^}u#$*5%qj=F^e z+_a@m$lWO4_G^~s)U2%+%DC9{eFd$ac3W$}rl(~aN{Dr$1v`i{%Mo~@b2BUl3{?pU zn{{6@Orq_Ics)?R3m0|A{_MrkQp|T$^vp)1F^#ZZ_0qF?nQDKI9Ok+aZ_`hM=f?ta z{(L7iiUFxv8U?Ap%KPMtH;F3rwCZgv={JezNm~ z*wAfK0j^=~T$n zuUhB5P8yL9#Ga+6JSnr(KBUv*>UJ$Vr+n|pcgI}SL9Jupo62`&qi37FH5SF)thVGU z#Un9vUlM%n+L8ly7|~EO3(T>ohZSE~Ibghe{brC7beHiJGATfcDm zyz}@-wd~V)SJUB%x9H4II`i1E2QgoR*81fTATF?(K4iNt!jr&M8y|5xh;y`C6tvzc(1T&pZAgOQ zb)~Dak#8oFTUMY&*>_j%I8V$>2=WGYG62qc0?56NsK<)@WE~h*0TaItOeRMFC<07v z{G1AKZ8m+BII*}IoU8W0o(1G25O+#2j!95}?gj$$I?%r&AiV;P%6uJ|BnW3^6PQqd zb4Bf8l4k`n^n$mwYTSFu#~Sc11FpI<$QGHKPSGzJ1ZOD-2hfL!B8LY|02~20;w(t% zEQp~E$jCOK>G}u}F2OxPK8~!O+oo9Z^FHPE9*UJ=O4aZE@I4>m+4>&(L57k6f%`y{ z0odgr1WV2UOhsT43*7oPP@N^r1{n?u9&p%z%nLy3<&5N3!`})7J#)c_(AhyMBhAj< zlNq>gnuZTbf~Yt{7F`0uIAPw?1;0>4GSUd{+z;|S1&GaKhfctxW&ovGfV`7HaT@@+ zP4uNk%uiY$)yzPqm~i8QC?gh0dzOG8GlbB6pr3v;zY-$tI*?E*h8K*;X&yrp98*P$3S)vb?Rs@;=!;%5;ScHhw zfREJlA07H*(ghK}AP0Vi1K^MYkLVH<2^0NUU}F;D(WR0ALMoZkaf4S5v_m3H?E~Vu!1%%1nl93Yvv9g# zvHHex5c%wdAwg1*D}4h^*@g}nLAI&u2e?wmV0{ADeqqsOU@E8iKKA@-I(Enl9`qRi2;RJa6prt zk06GoY$f*8&8trgUD?7z)ckHltRX}q3^`)l4pKweG7JuKP1y<|_DV%ruiflble6kv zbK$!n+{wAPO}WN(UTYsewQ3sc7iDON822XS{YXj;srOl;&3Z%N3!+FPmnN8T_5DVO zyXdO3Oqeg!kjGS{-JvGUv5n@sxksc^r@F_Fq z1}npyHN#sYgIFl&KK&4k-4yH*@+2MEGWj}(@Gy&bh|rzx`A9y4dZ+UhmyN|$*0pnF zjYYBjV&n=3h{ue4Vb{t3P)jAY$Ofrsg1eN-E~i2$XF9p`WHK9{m4-H}bp4QsHaJgK znT7+aY+ss)FoudX@6%Hs>I0(k+{vf%Rb}i`*;`G9x(wyrmE|~#*fNxqCU#Giu1Zbz zQsxXw&y4e6H_GX>%7tH4WX)46c9r816ZB3$wNNgjSB}Kt(Owx$?UBys)F^aD0lRV& zxZh@c-p>y}DhS@Q2o1~w6jPl_SAOHBdNQmjO@}2Hlul<`jIdF_4pTU8>UMUJuBB0x z=;o#y^eJt{4Wvd{VQN>7Mf?GlQRfXT{-7%Q7{s)zJzn+S!A&By0Gnis2DLqN_)CE5%nE<9C1!(nWPo{YBHbCPc~ zhl`jtYVntl6WkjU-5aBi>Qi{IlYTTNEH!4i6KDKr%yw_8P-;pFZ7LZiDhh2ZC2lS_ zYf9!ZL1t{O+^7f_Y0k84mb>tRT_|jlag?7mgzan&_ioK|@a2Um4y;m0u+ z%39_#`c=Jh@h5X@O}ee(BPe*mnE!w|*)o;_7_h|UlQ9oQF+3nF0t(fQ_i#K_B0L~A zI2G;QAje+2UfwY{z9|vDSzo@zZoX9`WsIl%+eZ8tPZ1PBeTLc`Z#~pk9e@wmf^bx- zNO6Lw(}I|yGRFflXit#|^pX5sQu||S`>l55ghfTg+2m#3s-~PuD&xp2Qz1p%sYV^M z$B?M6_NcB1Ns{@?Bri**poyVj^Hg69WVeXLstz@s zbiia|57m+k`ehD}DYX{A&g*h-M%s{b0?2pBs+L&E@8`%L`wdmI0uE|M>cWOC9=cmv zMg;JU;RtJi#4}2-#pKBmgeb+7ZI)SvWXE>2@u!NrUw0O-G>b3Fq@5ms0O8mlh}u|} zw6=-64@y)39V+t1NlLXtJKHQi-l`!Ps-W2MTPyahn|A)Cw#lG3bi6gMIYFuF?X&Lf z(mbDTQAZJPYS23?n(rn9cRtCYwNp`i=4HY*_|a^I)6jLotsVZf)A5JKtYY>aiu%tH7@MiOlG{D?6pj*xk)A!8q z&MLnf^EhIXlbw6}Zcayz+^u!aW0dnlt2(5W*H=f~pJ_f&PCb~9Gjw#Go2&|voMIuI z6dZZ4wk5Ox%vb<-E~K0+;J_?mRw8CSc=mogQFDX=GAJ!#2`!RsEHc9^HFzwVi{Y27 zfKxq}&@vZcDV7L3m*8NQTXn!qe9L`&pj@V9M4^RVInYQNXcT<~n6YdvzGN1US46r( zu(1S7v0T!MSd_LhR=SdXvJi8!lESz6d1VC&vf6n9+SCEJkgg)wt`Z5Yn3${>h)x5BFG1r-Vx3ZjCWdf$|Od(+vQ3&!q%3A5$la0->zKazny$b=QH+o)#S z(Uf#h!B($P>~%RRb7HkBUiyK&KIW&*hF8(wO8q?&E z?P7d}JAu(ggJZ* zhZBrF9KAEV-`zph?Ppx9tt1a;*T8d11+WeKIgJ2Tkhqul%Y9mf-LiB*0CSby$~oJo z!&e_JMA0u!d(Sx|ajlax>}{=qm2Zw_FJjIv?p&e&IWJQom+wPxar-Z8H!e5mzgY@@ zTQ~n^;Pb7Y5Db&?O=##_C-BNm-!LeT{;Egv%D5f+cna6e46xb{NRL8BnjlpTzCtOu z()BrZTl;RUcJ5XF%{c=e=*<@OQOAYs+W-DMga*`P$LL?g$X{@c^Zv6y;&q(fZo&t) zq_y2RF-@x2OtQ5bb=enjuwUS9BLT9vxg_689&TYPZ!13F!NB}YzyAlo|NA!UZ@|yv z^c(Oi{t58Ae$e}G89(%9>t7hZl~v0l;13=BF95%3THoIQf6gP|x2@TS0)GF0yz3ex z&zYvh_6OjH-gy0Q0e`i}>l!n&KLG!qq5eO!{HYk_KXCpZEPubs{4Xs3FBCs<=Epx$ z{4Y?7{|}sgCh5Q6^w6*%6xGlF1=ZjED^!2~aP#d5it7KJZ~K4BdRFJO`E zsrCO9FaJxt?N90Q_f)uYxq5u>eiTb-~E@bf31YDrLt`t#kLfDVa zJ*WP#0F8?NkBAutQ52$y(H*!S>LvjnfevRKiLOo|v}g#pF(N2F1j?fDK*5`iC(a`* z0HOdk$f2NOoj5@PoJD0}eoG9{I2pE;6(-M_JgTo8mI-2<(u~E1gy@4a1xE}-zRp8u zzASoYPAWRXB&?K`6oglYLT(-h!`vzC{f>=i0*{93{5Wxz9Y)xDY1jR8J^YzvY&!wW zNL&XTL^`U>2aOKY6kIS|)(q^>XS7i(2`O)T0rrS$UvtVh6MXW<-$+b6>{w+0(KYpa zi2VD}xiAUi!zJqww7*e#L~RyiM(|jMOMA95;Z}31{yOCZFQP|&*Aq+oAW>zg@*T+ha38&fjZ?buKZ ztnEyE_`?Q(OOzz307$Kq2o)RNMJTw%R*2G>yi?qJyRNTeJgnTWs>9r!%=tjpl{ET- zL+I<(o~gP5_ioB-_=@v1o*a*X<#v*vmoFl%xrGp5TdxIYVVM+veBENK?dttnbH5l* z8|SDo^~7mfK=|RQBtT5L>E3bNBk48a&D*|~i}*;l&Fm!+q9As^90h{|`%kwM5*gQ0 zrC#WS>k?J8ou@b;pIH$Dpg~_95@p3ZjJRcZ_5H43vk@)MWBnh@hyveFCIrc;P!J5B z3PT?&AB1Ygz{547wT^FtIZt6-OfVw(Xt8pCHr0^pM{ypW)qD{ z<^YP-SU$7q{TlHicm;(0;?^hm4o;IJeQ@0C*8bB~&bR=Q^n?%5Wd;IzfiV8iL;&|?CMdi>w7CjdO!hL1 zQ3xJwr~;WZ&fuxdwIJ+y2Sf;ZpIIIt2-D#`nSha#{bU9iuZkKennoXqO0t8(j0N%I zRBp;xC5k%R=_-bGSmw{pp!G{pGl_DObP|r_ATGs@9PW4+ zVz$N4@ZPHAHs0Q1K%YPiI#{qYvY#M9B{T9D-ys!mv?4Q*;$)kP-5!hmg09W zfHU*p8(@Rs;Mh_CTGrFn3vwNH__pxuEIuekf@LIBEXW#8--@PG>1_0Dlu4ol!C^Mt z@UjdwR_JdV0~Nc-2P{`(VKXa%bTD>X!-|TmS*U<(z*7*I4xj=6)xv%KfYgP|73K{N zloWQ4mN5Vz3nE+_p9&8z=xE?=*D+h4`EVR<5_EI+G1Sq98q;qPe|G8PtE-H%FHzJY za!q)VcNPg$HX^A`98ipaBL3rHTV*KXr-^(YZ?y8PeR^2m$?RjdEXVE({I|pPLe)ug zXoQDVH={NY)v0^3d)!MmV=iOW>EB28c*7gVy)hiLr#(^yOp_+A*lIGA3ZL(b@!Tc_ zrOV|!kvk}D;CdN9R+GmudLZw9`#A%nwm?GeP&wsxy1?W#$MLfnL%B5fOa;yBVk5p$ zO_|G?^3GSK&aE*r7q@dA7s@b$>Ia@byXk3t&A@G7bYU=YVvg`Opp8*=f~>m z%-^2m&NnTs%h#5@yLfm<7uh_!LG!lpeO8V`;JLb46;?uxA3emuz{QQ%+5GY()1^3A z&N^!b?exU@?3(-O(dt0@Exfk?E~O$2fl3jYKb;uskP-qUE{9GGM9TtMN8rewSY<0x zPGeAI(NKkIN5z`J9JM;FS>hKH0q`C89Bu=RW6ot4QTYg(aA3U3Fa!roo2WiWL!!>Sg0g1UyG<=ry$Cc>j_hgvup)V3ciPzbLIRMm=QK7?hilK zG25^E6@H$lJlyRod=$vI&-fWw^@Qr{6UjUK7auaF+wb`s+odlfL01Kb)IlVQ^w&H-NA;Ag~)BfM9Qe0dEilf_aTaPJrdb;v;F` z12lu6KzwjJeJBQSnCCyBHsG)}K=71&pIrNhKz!LDzPx520nQKjE+BydUvU>d$wWWt z20z((Kly7vT15hXWlnz;4SzK=F{5}-^@68b4gR{<{`v#~hMWO!H3Cdr0?ZNvG%Okd ztmXr(uLFbv6zw1p06W`2{I@y95P6@2@rl1!*XS zxzPF`ye6ksrZQG`vH=tss850ck%{0Ky4P&RuXWe;(%#IIi5jZ_yjAFN0Wyxt@(8NR zVybF80-Cj|uu2GCs?gk>Yn7{1sLzC0hk+CcWlZif1&+arJL&EWW3Z^j?Hnbk{I*OylAFKvEXupT!w zHV7A2%s(5kthoH;@)AVe9 z8MM^@!Jy@&0X1m-d4G$OiiNfu6lwf}HLE4g@qciUTdT5y`m%OvoqqeWLPIBhTeE6w zHy<~;!S8?gvi`EswQTR!{%ZVy?sY@)eb6&6^W9ay7reWn$F7fundHALct7`k^?vmC z|2AU%vE2>+GGfjD*@$&C^3P=;|Gqu)m=X9(Ea(A%|37hi z^Y&t_vt`GUnZL>MOSH87s! z=7At1@N>c!m9%7COnu84ww`$C<*z4=m%lH6Ju#v>RFpypp&)?Y3xaj$q}IUuf`Fx` z8sgzSNF#Y|Fhe7>uDAv@UtOz-M%&;Se)x5IB>i4J-e)$qlMDd6o=N^%Gs9`#SEUd} z)2~;lwiihDn0|E-V#_j-$SQbDzuv@#9H`Qgd+@P;!wF~Sp3ioB-h?DgxDJMfUxy%c zS+UUY>uxf(kh!tZxll|E_cUc+j49|PXTkbgPW&l#lMzdFLsB-%irJs$I z#4gch*H0`5%NTT8S*2`(Bh|CmO@`FC#)q>a#?t{R#-{h3l>Vvj8&TekfO^owkuSOk zhuy#kKYf9;`8Bm;+~M$_l(bIE0%NeSY5!@GMrpYs~_&*ZEsd13r&$TFqos81E{htrtzgQw%1q`%H| ziRX`JY)kL-O1{m7xAT7AjDca&qdCp#IHSIhd!q>xvqeI&d#vSjpSk?y$@E97=Du?i z=)JE`ojUj5OLZTr6e0GH=f2j^e%_iMg^au3LhpUGi@R69|8Pw^UjFd&&eZGSA;?be z0a3C8_Nvz%Agk{QZ`OgxeG1urodLfRFM#~$sFq!T=isbBF@ZX&(I|pAC53NVifMnH z9nrw1s{9W_^`oEqA_UPV0yR{_Q^2}P_F%fQJQ}JI0yTPQih2X3j~8Nw@}F?- z2Zl@;WMS94;LRXVgyi8d)MU2=ccVb83^C+kRLGPFT?1?}XVK`LZ-u6U#3Dou!y{9- z1w{$t6wikurIfa*!B~SqoKxh{B=F}Lcw$nJo=8(1KXSYb8OX71q~&q02(lDN7<56| zFB(Mm(MWyqem>|hjIf&;~o zUxfI}uCXBHx7lV6#yn3J2izBPW9i>zO8|&u^|&2j)aj6AXQ)0S5UA!{I?#$jniQc` zHc_~x^v^^r6wRd1lle}HL=YL`M0Mli_es_iqmrky&n?N_mvdDRs$`zc+eR)F7b$!o zQj!%{u2AR8*AUv0RK-ZhBp;-C>wB&g(dL*F*;*o!XVKJ@98{KW{8}TpOZ6fbS1bel zWKV^1crhxjuJ)QYXh%PVa&hshPS!#N|CJA6(KG$}26Qc(K$(Z-yXB$!mRyN+O%P7eE7YqmpXmy;{2Cg3iCTq9e-k?l!;^l_W63GauT^78S=zZldkNdsqUKM9-4}?^|UdXJ} zI>(CR1dHEz*|`-?=1r~b(iWM6>(pCEe}p8?*3a6z#k*Use<5;nzHzM1Cgo0#`O!zy zd6|&L_dZC{HBpm&Hx@})&r88^bYrZJ`|F9B-P#YjEj9blwbsQfG}y>Aev( zD81-cS}v1>v5L+-R8B^HyG8!ZX^faR3WD8p2(R$Mvl7ETP-XV;Ge$7^j*PLaOzVt@ zoc$t&;YHS`ds?gyUnY%szLU3Ub7Ov0SQX0JY?@p8>Wz8VgPSkZ;R&_Yao=b+7Zp`mc2C<2PgOKQA&cTlXatZl_XyUKS{{9;%Pu&c^=Cfg8Ji zS5E$8q?{hBY`pc0^Z1X|A3wjh1hy)hJ;={hJ)`uDJ0uQ%|KoCl?0O=y?J{5Cejjzs zR?AuSiGZ?O<_kYE| z4L22i>w@dG_rh!6*&8|08->8_Fc9mwA2g^ACUthc+k2hppcq=`NjM<)z77N!0J$Q( z_C586AD}^O@TN=jVKDPtkAIS_3JSdPF+-HHaD<4fYMIQKL_9c&*PnlALsSH7_^jFa zFlzWgx3c^>Z$}s}Dl?EaE$9Uun6$x3r2v8pfp8IkpX@6LB!cAV{OW1lvOp-3(50-v zN7@Ce5gtM$1mUl@FPnaM&F;wQ462>;(nb!5vh(>=0q0DPB4&fs=8R0kf)d37o5X_h zspHY2Wor`0H{7iC@%Jlum56hyyIFl;KU_aL!2RDL%45T2Rd3Vz& zxa=roe@+zf4%qBRVDE@Y6-}lgm8=SBY1VPz=pjW36 z`ieoGoG?l2Kz>2M>@~t>K@iU=C14^l(gxmDFaojBd$%A0g;3zQAf&tiCRihs4}k0$ z6q*f+NO4BS77R%Hj!XqY`J|8VvBNcs90AE2mc%uR!PN`c7{zSPkA4tgbxH}_f#lf` zqN^X4?Tt));A#zk%U+MBA9OXJh-Gw*o0*Gw-WYd|73(vAC_d=Q0gT`tjHO=)1S~`b zBm!oG;&cang8JeNH3j7xV=-7_(m3MrHRF|TB3|o<8|g;}E5d*m!q=|jT@Ku(gRw?9 z61<&Vi6FsPThNaR;?4*X>41H!flL?$v`C6gF^x~#13sul0kcjMQoaLa^`p%vU|nyL zI_G@cCO=+pFfGo3_mSDQjfJ*_#WJW9tArE1I8ok#qCyIYpw~GP)+0Fw6GW1b85KiS zLDBWVr!QIJGLlk@>OaE0O&)Xhz=TgEh4K2CnK~OBH*x^R-1n;B(mAhzydQ8X5tjl^ z$`$8;3NEFPa*`;^}Iyz~YV?b_A}d8%$H?pi{@Us2L6bNxwPGj2OCP z@yWE0E`jm0vSkU7czBgl_;jjxc@8nB<^hNhLH%4Rvl-bqlQS8t(D0V$FgyBHRswE19W^O4 zcjC+2921RfflfcVm`}X%7KB><0^hT@1_}3rAWvaFX@-EQ7Nz1PeBe=XEkdG@EpRLw zKqw*LV^^%RLC;SvkV~n+3^Qe_TabMbemsu2()VDS9kY8N*b+Vieo|s7DbMn@V4pUZ zSSi@1h=z_kuV~huZ^q0qD3gvghbttVjKa>1D93N6Pza*JvZMYUuCT1g+e8GL;qW88 zLm}Z=rsEJz&Vxo;`C{=isaI7^Sv4X2d%-w$M4}Og#Y06OJGil{xl1MvJ%+hUr|^r% z7)mCSOA#bXmv7x?8L-ETN;jKISG3BSzL&Cs%eI=z+6>FSEV}KZU>^?Q=M0v8b1VQU zmH#|1yGwREyT!U_!oMXV9ZSORA99{J5G)O@z^W`pV6Axmxg6__+ruFiOsFV=JAYtE z`H#-ZAB`%k+?AB5Zn#TW`0hAMnxL;pq_;jfnTx@0ZlAb=l(07fJ`7o+()vRq83ZOK zmp7R&j^w%PE9`o~1=Be#H4YyBc@#WV^3AT)!&tO$aBPQU&=x^4PSrjrnZif*$m;2M z(sCRHnTCst_@r7N2yE*RcdDLD%7L{$*##PkzF}lmt;P7krjSyv)Qt7ISc{`5m%BLI z`%R89swo?412Ig|vU*PLEm+^e-^}TQaS;a`jNj$wBG;oD_hKy1W_%SlN;T;`4U}}3 zqD-A8LOr(%oB4(}ZbhU9dAjzsC*Sj!VjGi}O4dV4C4`!F&9JnH^E^X}Al#Zp!`U9v zIPI4B-8`>-QL>zi*k7Y$R}6Y#8#O;|Zft#-EL99rEq+pDS@gBAF!RW^^r(4+`|wk!{o!e0f{!Zq%QnT@UK)w!Y|B;~glH1!e6G`9IUql-2%l)W;$- zm?qs2Ka!gj(m(`hQ--zyxaa7TG#S35gcJ9oSP2kn8t-H%A}evs67lS*UXR0|e-uRcW0IvTA2sV$&OG>eU`I z3L7?F9yV=BHy^3yS?b#fm4iXAY0#dcmmZ33MNa;Z~Gu(f1NG2Vob#S`1F5eTJ;gL1LSkDy}*!lxhV8w2yvPv4ze9*LzsXAQk zIaX3C)pVRqtCIy^I%PvQ@?{ttiP{!L-AE5(Mqb*DWwZ+4_NKd(a6y}L$-_UJ$8qg0 zopChNDu1TLeGp~E^C27*lDhtY@_L=Dj0q_M=h*5qmBB>B(RiG86SVoIp9hD=y5wYK z{mbYS+x&zOh0iOwO{P4tCu1V>ON}Bz?Hl1VudFP%hVxPRr7v`{s14Q(!lsz+w^Qk+ zBz26GyVZXtZ82E3S50jp{M2d-LN#h{|ItFxIN=)t%0u(>@!pelaDahlM2m&{#^L_S%+Za4o z_mh88O$!m_L5NZ^h+sO1R-v5|ti-hj464z@&6C8cod{a`2Or4<_nFEK_&q{e4(_UV z;lT@Vy0kWSqzjd#D`%t+8?0nIwq%a5QC|#@$wA0f{6}wN4xs+B)thaW2nSH=!iT`I ze6$6Al6_cVazr2Uv@UX2ScZ&_r#Qm2DN*q5fRkCu6C>dhN8^P>-vyN71<2=xO@7?Z zRb;GoUq%dZxvRclb>YM?f4%ggyGqA*YpJ=$>R;d+VJ59EN^=rqP%LBO9_aJ5B5BA| zTgsIyXyB{8JLs{FgI*SJ>7=9vlz)N$^ySTYq)rwxl|CNY+UYmlBY^wS(f52s9+K%{$!KZ*oF<01&5U`^R$0ECcQVsnls(fBzHpzS z{eVRW^PUK9ot9UDiV9Oe`n^YAH~zh~h|&OeGB z^kXFhdLeK6j12lzLs}QRr>dLCS;7oO^0+(?S0Y&7(>piZKCVG5^Am5^`9e;xe#+YD zLh#1c{U2^Qbif(Uc{(sqx?%D9U;zWdSLudVDjUxxUR(u&Pg1{9q`$|1Y7Nr4lPmPw z^gkS!;+q&4CPDVhEgQdlwYu`=bt9%uAz0_mZKsXcHmbkv9`WV#@noE#o`Yj zPrWlOxgxyw?}chRD___pgg^Tbo&hQa*L@^2(8xp+6*q(f&`J6I2$VKOLvWdNd#)Ar zsUk@EoR&EiwO+Cy(6KbFX2&;{v!y|0+{AdG4v znyhl5oF|vYuyU2!pX3Ivd7p1&P>h47>=Rr6xkKN$CA8Hv`V z*;KCFCyWuzZx*vQeB%h=T31$!weQy07qz}yuj1<|gv;FwkuUd#KjDyfJU>nR=q?cW z^R9k+eK;6jJze>Dt;(Z1`#xgX$|Y{wHd&p1ze#GBB~2pm$%l)}$eCUVaRIv@o+&qt zw|ie10N;o}dEdm{6!;PFJwo}LkYi+{qA|1uK|o8!sGKjNiwe0IeDJn8=wd!ZN+p<5 zVZoq}qDjHL8D1zyIrw_8M?Ennm*ze34%74{_gBLp;dq~CgS;sC1lwIGv?PPVF%vRT zLiG85A>_S+Sm&(N>dIdkaAgc9pAmO1nu{m+ym$?5ET0|}C&Ry3V z^dh}?=^#x&Ktxao5JJYkk;B>Nv%aqs>RvQ|S_2bCW5f<^KATid+e*m1ubUc;wI;Ddk;f(sSKHzOFbU zb(=6TW4p)c^P~LfMNM_en2ztQGEcSxP1Blx*Y+DWiR&4r*e=AIrKZFLmpXVgJy_y0 z2}rZ>=b-hVc{HW|)AsizyHrT#o3Okc2d+Qt>VMFRs% z>3UjobbxIvi;%QkoTk<58vb{RWtR8861To#G`O;~x}DFm#BZ8xrfqGhN@F?y;^)NJ zbfj;WiIGj{;Sbi}Jz}iV%;gzV)^T`=LLUZE@*u+dVsV2X~J= zD!LxEdw~jGgdSE6b9Z<*{B~OLYBD2Qb+4O3%lo!{n&kc5^mVB6bKHlw9S^&&K?-9% zpI%(L-zdHc{(~bM!TzVD7C%o$R~~f+jD7Z86BxA{y*gWkzqSt8f@)Ot6nD(FS4=*% z4)@J;PbwQrm3mkfH04f|>ooJQ#e1&Trvwtx8q*RV!l@^g_j4xT)2fg-R%Wtj-lsAzS@whcV&%j}vei+4ugwwZEm;@qzw6sL zmlH0jv@aKEy$H%fkBT-*&Lv{Q);&zm>giq1=F2j5{kZ1?9E|=(_slDnDX@~0>u9}K zO1ZlAOR=eQcEYhzVeqjlvo6YKZ(`VsAg~V>ovGLtT!sRLS~MxCT&!wI z_go4sau{yM6mZ7N+{W3#G4;0>Pr~lbV@n4@QWebKI>_GU%&wQl)8-k%-71}j827YN zT46jsz(J-h2F>bmn3$wZ#zK3B;0HF5sIzv~5uJr}7GqJ@Z{KFOX?yoa>7BlCZjDe* zh`6PEGBSqeS`}$%Y!B%P0oZbm<9U+Xbk`Eac#76I#93CY?ah zZ4@5w5lM0Eji>s>KqmBEKQ?;7Iq>g1I)zTIZJSGZkWbS*=@2u%JVpCTa?)3PSGNi^ zvLQ_IX<;8(Iz)f0leDV2-e`L5F`M#qq7eS*8^3Lb?JNCo$%heb?=>~@h*LUtxq?Vm z?Poh*bK@F|5ckbTJ>uySK5~3{m}4coWp?IoRrI+soaDAy-(gC0T$5nbT)7in$v|TW zY60_*K5lJcX-Im=|3y%zGwaW#;k(b`qHGe!{SWsBw~9|+rgyqU6*R^J3U@=n;-MNkNHzWjYqkj3eo~-d8@7y*Vw23%L{@NbqOPyl!qNQmTuR#}tAe zJDjoUijZn0!l{cq1_%JPhejqV3o*?SZ(Uj3H1o&iaQ0`n14QE08doT!LxO54SdOgd zpW?GNB3a^VJsqB-$ZpUba`rzE*6A%0zzKjW2M__ia&$7@>_;pCj*YNvxB4`s^W%KH zgInmAbN`+r6zqteL^;l9=OMWjwulHrev?&6y?<+==m*F^(wKPk5D>znv`SXD-0UBB zaNS*e{2}W-qs(`N!VD48yPfjmnM%bi(MWXu5sVW&$W!SDN&33EQzSD$#(MXgkY?Dn zbnJt{oe2=?CW{)jBvIXk^i`Y1D%kl(^dj`_15!BvP>EQ%S3WNum0Os8!nsAw%+Lm6 zsqK!6pdnKPtbVK^@`vv3XY&>Bf}`xiX)u0(v6jh$>gRW=xx@A!dxs3XewY1~ zRsCiSCKyqfMf3_Fzs~zL=q-;EF=LI&kmgJr*RM5DA<4VfvhJbVEs8gkiu6H3cUUz0 zhl?8XyWie?ZL?PTa2fvM+5PgBjn4+xN*)W{&wlOXgePPszcWwvf9@b=^$=40d!vQs z*PzmK%&q*GBW)$j#Y#t7M)#i+X{L*!Zh|$jGjTGS)Jl0Vq0D{4$kIxlHcIAYVbb5V z#%F1NmITvJl(?*JZR4;+y@Y@@1_I6=sxUF4^LTtY^qXoN2`7a9Sm^Tux-f|7A0{xU zyf75nrW!n{_5umtc1k+sIp#oiDDvsOZR5 zR^iI*=PIn?D#3BWDV9i)(^@iqVX2Ys+LJg-QEc=wUnD46w9f`n?;N(D*K}sWR|4=6 zE`z8X$(vDGi1y9IGv3HWOE()Y7SJ88)`MXlj(3rG(TF#k)k-?YYmAW@l8>a$^ZGMu zr@3fb3B*}?k7T6XyhnSTgJld#&QP}*$=uaW$K+(UYOhC*yf_{yEbvb38W~aJh{Gjj zIIU_I35*t#>%{vrWps*`4vhMb7vJ9+tv(;E0glzujMZ_D)k};uL?_vdjyAcBDRjgK zdXKfH4gI77^2_9P=+ay!k98?%U$Dio9xL;-rL&&jdnYlTDlwuKiSKvO6(yqU)Ea;8 zJwDPYfmXm0wPC-LYL4!XABK+q;f*JQsZ-C5O-kscbjITqCKeLM23;ny|2qv#3iyBc z8IqFXGU_)0CTTf8gg@U+eMwhF+*;iAk+{!)=pRPLw>OH$4FJT+Stc!ACu^H5e!oz{ zv+RccxhXMeYBt}XKj!A02Hxq~o~5dOh5sg*te+PC?^UKpkGkybdptY_LPAEBB9!&x z4eqBqxMaG9ybTqPtiDk?BoiiY*dWv7k$+(zx7=aZ8+)T-$?t#Wnb6`MHvmwk20@gz zc+7pJTx;!>qEvTtCtm|LZqb*YVpMF!^|FPe6 z<9zfaIrm}R@!6064LOY#x{l()Zv2mhBDb5C)BlPMy=Z!QQ*BbNa^B# zho3rk{u?mrL3Q@zy&El#nW;#ct4>~Q%Mo>-~m*f>8f*NF%d1uF25Q!HsURvU2)Q9BTKU zIMn~jBpt6!Zx3xAEbV{X9s8#ebu@mmyLx>weEoOspH|f24TFAk`1ktz@uzP`Xa9Di zZX%xl|D}Pi|8M;a9^cjfS3l$by8x3rI^$;jZ{ob+pY^{TuA2apS6=x)>wmvL9<8W~+OeDUzq`NNz8~q8^#f~XT998>`V-PLFn`k)fr$1POEQn*zR$#m zZ9c=}ZDwkwH)~KT!!1#9OcvVJWR9I-`M@PRj8c70n6UQ%nDCuE5a@>z?ItN&GMylDs$(f*u;f_Wl%XEMq?1_BVhMW*y z&kE&Mszyv9mJ?8h?58A4t^>1?8CN7zc|qBS{uO-?1l^%jL|xT9^{Fo0yWkWe!YY~ z^089nJ~oDxK*ca`!X0CpxOyV(G5=~};tJ^SZL-EAmFsa80qiIlg#vbr!iFZUsx?#r z#?Eu++<#bhhxfCpNJ}M@mHMJ`zXh7Ei^Y=&7M?4w*Ed$TixlvC5IVU~4$hcu(Lba!3PpuJZUpICjOCzc{!8GL`hWp6x>M zte(h~KUy98B}t~WMdu5@Izhg~_cxy@fx(M5Wb;8w5G)^*KQm!KY88 zGRT7-)83c(wc2dch}mmB8kbQv@}LPLY-X=`Ty4NZ^Ia#~X62$gvX39#{WBmdg0A@4 zA6{+c#{=!Bla%vUDjhGf!Flm_p8wj0CEXEK!96l${&oDZ{rU7I!|yEd)@%NJRr5XQ zg;BJTUn>4WgASRcR%7s72l?)bt2Z)-&%Thu><7M2j!14dXsR7ki1ZM0gc!of)Zl-& z-IHaH_1QI57r|SfV0$rGGvTnciOZi@$6W77sIr9)E54*nWQTpLD0LYe&`pR^d)~D5 z!40#--Q-Y!(qT>@;UXLqaEp%jJ}bPjGpIze;%@AW>m7}8OK!>b((8NLkF-Y)hdtK-y#@8O5B zJ$$)=S`gsKZ57s%WDBDx?xI2+Y@-;svqXJ?KOfHX@bW=%Wgv4H^%L&IA@L@!z4U*yf5zfe@7- z3mx=hiVN7&!q#LUVpEYJbJm16Ip>(~qEyEXSrGi5;B8vH2*%=9m?a+N^0s?1A5Gws z3n;yg+#Ud7m~h+ryCiVPaCK}@X&t5xgImb5PO7MtITTQzpDp6Vm#Tdro$bh&FMhM? zy!;M19{1}!=YuY%>FvJv7`d}l@6Vpf>^9Js0cx=+rbN;QWs@kGCN^y|4CgHy=xls* z1O3G@iK^__BKH6eP_<{rbg^{vt8Ic99x1EHj-vBuZCiaX-t;R^QX2C zg6nE5FTAw%K9$}NQ_j9cz~jlHa{d0JTuX9wdIb{k)Mh;x*i^pftrkzeqFen9p78xR zm|BEP!uv-y=yr)w#VAw_*iyI=^I4h8X7THaB%A0Pt%nnG_M220Z2hi6D%O|QZQLR3 z4T|6=!%th>!9?v3cvpo-rPd=YTc9y`jN2a5B<9y+m&r~yByY9_AVE5R-3%X2eP)F_ zGfh4C!`mC;J%1H+=C{We` z$crUd^#L=v?&oIPX5HlY=(lcek*> zZ~wF7+Yhl1R`rAXntZ=y^%A>#GFpT*|EQjvx7~6OF7B|m#|us*c*X2KnPPm>PeC>9 zj@s`diMcBgE;CV#$gvg?4uZ5O$tC+u4NN8>R33U`0qzO}H{M<(E~qXFi2wkYPGYD4 zh7r09ySEKm)d&xJzC`8}kS{L=KOL$%d3`L$N&XPuKWs}azhgD^SxAKfdrFSbg%bql zAw{bdBXkw|$?x33w0c@d+ON}Vjx8T(4%jgkS%J=M3lgV zrkIWei55?B*bnAWrWSkHK2f3{bhyd96Y9_g5F$7SVhc9aq~(-4+)I()jQIzu-5y@rhQnD0Ho7{Lk3IUlpRO7i^gSLA?iFaCD|sN?TR&@5r+KpMp|^*ix`?#qw41VBo76yuXp zB#!{=6DHkv`!C)TgX2%hd0bS^jh=V?LjWDxTwhkwk1u#C{mv@B8Led+;}gO+ef7Wo zku##W+whmrbJOV>(lr9$DOC>h)UrRtD=7%dAg}o(?w-%Yh7-y}04*bcrQznvyqlV; z>iw|p2)nEl3M&(+-3~N3MQ-1M9@HAiy!20fX|{wem`d_n3ZVB~QIkfPrcv*9vdC$W z(7>5s7ol3}91{OcnZ;SGB|z3t75bhKK|n;t4<_Tu03dGidT<1NMr1Sr>c-2s(K41E z)AKXP6{VnnqR;4*k))@n9yD~MLFrSGfD}H8L|Hm$2b#vNW|126!95z?KMvPYAShS`E}2qZ^2n*YaXc1v`UP71GcfPB8O9@<7W- zjg?<$lnk^SAe?I%8{8UOY#IMnCMK8w1BAt2p791^JSieEiCS@V-(#9FF#Vz^i4drl z2h^uDE(;v{hCQ-ShM^=R5ucG*!h_-&lsu))gYe@V(3R@UY=tTLqv@$pmMRC&?Rarn?O~dkyrq= z!VZI*I|G*NG~ySH@B&8CsfaYc{^g|#^d7^@K%tYU zwahf>+fUaYrzy9g$P3bpFH*pG-sYCu#LHB?2Wfl-Y~TV(0+VFJHmHf!D^9C)=5rYT zNIHj6viT|L!%{^Cu;jYat6-~_<60;}qi6^g^@k94-3p5=6LnyKHT6sXF;gM2N&qcm z6fscyRtyt?Al0cLg<9rrVHD-5ID13-$5dz+DszK@+WtZ01R@F0&x6-9UJ|KalJSIy{ULfm;V9Adh~HI49MUTRD9e;l&0&co z5mJ@7zAYLBfk!b!=1vjEjf}u1<5cibJb6~MkM?Erw_inog?)LUO&57@mtsrWc+YPq zo!?G*-k{bNB_$b+Z3M~Q5*50`flGRT#l8DMo}j2>y9)up4uie zq56^h?1((tDCypQL0&3FjSQ4CtJpZ>^<*pQbZItKpdy8~5-GUs7CLrZniQ;w$kn*=8EaG>)Qq8t=18h)-=_OOwB1poCFn2DHQ|p z@l`7oc)pi|?Ui#a75mAR({l9Va#huzDxXnREydH#w^xJ`ewC|5)7NB((fzWb z6_P8vY^Ta%q@Lo4%uKB%djbW@*Mg3yje6g5;a@+KebtpoMV2iQ1A)bkM10763wR>^ zDa!7g80H)*@WnZ^r9Ua_Nlp)Y9_c`7;gg2d0yKy%I|6YcMo=Yjq?~T2Svn)-`(% z`r&tRrA(5EXWeo~)#_8)U#%t2iq;G1m2ssM0p4&M)#*FIHeXrJcpU zn*vh1w@BIp;-EQ~FnW~k)e@FOfiFz1{MuZy2bcpGUa8IL?WJX_;7MSl>41soRuSv= zC!bbGIQBzk`{yqEkvRjBjsxTI13Fg&BE17+hXaPTgZylRgF1ueorBzwg9GJ*mc7-s zVIEG*F#DVe2L;-5#+z~QJ}%_}=W(d9O};BR%ssK)8*<>5~nBig9Kb=$T*GQ>w~X%91Av_b{5p~awj$!N*pjVYp*!Yj*4R z<(_AJIae1w`EBEU_eO|9i>7kgayr{sX4+tv&DJ(lMfZB4SIH+GHOzJGfvuA@tCO>s zNzUGB-uA+;iGuI4-xVjqE_bA7#0uzaN8FM-x$49Ts%8TH1$_`RL`GdT`}NRVo^Q+D zTTE|uY-Xroqe)}1QQK~t_IJtmrvF~N6N;RZR_;!H(482H^iX8G&- z1{<>@b>EPOyb41Du zRLdn-TnnL!145Dg-F3rHS(c312E=<8P~l4$7M2x1in#S9TUiP@2gr&8@Kr6W5kLg# zA!EmqL$G8ZhdUXcmkRZCQtg%*9Z6(P0t)_+lqs%MQ)prBAR5z5Wr`H;fQJ%2OLMhE zsV77?MCiaY5CA2}^Me}ILLk#5RV*YKfWe@v75nowYJ%kyy=5O~;PG1upNM6wBEblp z;;sl_Z~{~y2*q|i7Qs;%*8*;)LnV8bw%Uhs>gG8dmkh%C!VYWBu9IN%b}Pb<3374) zvpq!lfaNqe)C;=OC_-?e2<<=;z89ge@*^j#CL;M8;7b3&O?e!7(|bCt6%oZ#GpSL| zd{|s3v2KCPCv8@BZBht9pNkMdPBw*wpdAr_{LS)2Z&cG&U2-KA^Rw>ZBdF~7#Mt;K zq`VEhRiED}W+gvbVmq3`uoss#iW(hNytgNq+)e}=p7&vlFQeT(fAz(6f?OOOwO%NV=5MQy_)C+r;OfGa=MR`H+@zW$!2|^bfyHQa8ehR^b%p4oC6?6em0Y zX}}3V_gm3F^N(2K%4l zBF@QrzZs>JT;Tg43a?k#>!0~f3~e+yP|Q->9YWV9P3eDVX$~6xL|K z;ZdgEP4@em!`5t#FRsSZvPOR6h88v-159-|&`MsNd z`?M-2)0z@(&U&E0uiEK|e{;Dv_pou{D|G7CpJ2yNZNCpxuWy!`_F z)U%=f*1F3L4(vI1VptV3r=5m#G;{Bofsu~{ z=AZuy0E%I<_+r~0^tm}E%i?RlH)MdSQBLFpSsg(m$TnIlXl;9e_DP7 z^ZC{6)1lwOmcfyxG(xrMWn;5cFD5`SPyfi zrC=ki;fc;6H4=XNqk*CnjVyeLqcL(aP>Iz@gWaWlI9H>X&uU#hw0}k92PYFH*H@)f zOgvELdhJrL%@rOkc5^gas#gF(55W985`3p!R2>TCgJ-);h~y0~pyHVP@2UPr@ zrLMO7VTw!eENZ@&=SN;+(E&{0=|!O4zAz_QR=rMN{Tdbyrw$M^*5-LbQ-ct`9+WWA zliq7INm@&T&BqykYc$1RqH2uIEL^`Uo7|6)G`Di^nlDl)ph-8k^YU)8xc|J$%fd01 ztJ%`|rMi?=NrY>&mHU{nl=Xv>H_g^wHF{@OJ}qXnHV?arrEUF(_0nw~P1&W`2EBJ} zv3p#mE^YrL-%FZF(BX;n{qUcAKM_w)!#(XINtzSZdjEcYjI)uPkaUc_qrYDfP5F+V z4<$UbWbALGNH<;*5G}JC{yUMjmtycl99h7sDCGS5{>G3sDP-jZ{+NovkG8U>e|~3p zz%~PJ{B$%~T>9Xiwvx1-z6V`_M=?1JORY1ZSe84A*r!hQv@9r+W|}fpxntpU`&BN5 zZqLWafV=WG86Q{~)*7lfkNYDzKZ*%Q(#T;tety}3a1_X}3lGYwha$>orB}wga4}hB z+@sIhF_WE${FQ?Dbg>5hs8?BnR%KeP{`A?Da<;w4!=Nqb zbc*=3+#F=w_bK#I>}YU7U-evBq1|@QPv+d0O6cJ&ZyA>@?tMd zrLm`yhBib8>Od|TWylxOUG>4+>5kvy|Y>HL7EIrc-nUdLz7!em>7Jr#@-QJ-+r* zFTWg?QzIXa7UYwgt%jC_r}Lz1jHd zVKweC-$JA-Ym!ipT}OSR7KJHrGU?f$n)(dDp4wu$*_=HR-4Ei zZg%G0T2Dlz^GhFec6JD1mKW$DEyclq<(|N7xTj(2Z zxSajK5-+{}N7(Nrhb^EhSmtL)bphW4X0KxEHsGeCM4HXUR0v^z0Vb|oO4QRNgM9=6 z^9-~Yi3im<&0*T-D?K6~5W5E{e`)%z!+6Q+gv{tHfl3sV`y))nhC5@-H9{!NvQ9Un zIwP0N*o-Flja`9VMU<2^_vh!ea#OlC2K1x+&9r_^wl8NWi>D5WIjlo7?zT0*44;7< zc$CU14NARI{FzO6{gI=nTgsqmslLGVK~@jZcWi^3UIp*Z1A5e^VWZqJ^p;o4>s(S( z{l!LV(t94V@4rkww_wqGl(5&g`jJ@aew6Rq02|v$KG;Dklc_K28JX==->juiCsmR0 zM`(Xua9h<@x#4gI_o_}^JE_$G?PE?3!O=3kSx2Aq%MNw=2gSM1`7kc|^%IiZz;{}S z8C1W&VZYb6r1jakW0uqJmpM@sB&L;MOfDSt%9jS;ql(M4uACUV69y&!MSvc!XACQW z0v~ltbC}kJgQNBmfkJ7=cG61xV1Nx*fg#MF&TLa z7(H{&V@niu7a!~^uTfd8+$MQ_n2X3>8ol-|Bx8};zOC-3=4E_}0c=XB^=f4^j^!pi^sSci#E+&L4xiPNwhz-CRXir+*DJ|w&p2s= zsRIB2Z|pt~01gmEHVOqp!NdRuqIZUb08%U@Mqvl?S_{bn(oZ1r*j`TNuJ)ZuSoSvQ zc<0ak)47h{Qh=MThS2=P%jV1V*&_5u@MsbBCLPmP^T$4WPurUG5FK69?}CCUG9N1c zI{xG!Uj&v!4vFJLB7rAQ2nVNQZh^3I?irDXz^z9;gOm~U$I670e_MP1ItQK?+%!dH zpBUJzu3xFWUs#A~GkC*gBf6^ivFXct)6lB6VPQ)FZ-v|o(?;l;|Lv!l`2cw=H1E4)zocRDT^0l)JVLYn~7BJy#e~Zvz z0Qtr5VlL{a?<^>s?%}1W&vkcJeCVf#QLCws4eyoqRBf@N{^ULFVaoU@H!lL_z~HFk zCCWwA3Q}%jV3D|zXoq(Wb3|t*?RT>kj_wgdD&<&0?$#$DQLV&y{%$Bu@7QwMUBY7h zQ1MY5n%1_LBoOGS6+^HOr1S2*YtwsZ(@UlXVhjXvPXj&uh?p&vt*0YciqW^Olo?I? zxLo?U1N(TQ`w(e;yv2QdjeYzsy|8(epB?fB2l9+2eIzt0?f^o{rCx>72z|?Trp8F- zP6ft!VkiRb?uXK~RF?COre#**80fou-me54K+>r3uJx%%3|K-`ndXV=i$J!PsE9`r zo|dYfJ<1GWs&vKI#FW?pzKmYlKs1j?1OU;c%sFT*F=(PNsA@WBHcw+3ICz8oSf&l$ zbs4lC;C5pm5}qEk+a0t&AG{CLxK9&xo|0@OG32Z^9K5^nazB2^)iW3v$ zt(hdlH-Zb(^d1>WT+@odYKE>2DtpAZcWOGg#3& zLO0Vpvqu-;9f8X3OtP=N*SV{muMpo2q{nxTC5@v^mZ%&8bxIR;?&s*3)Q;K#iOd~h zQ2R0R2_@Ch5KkOWecHrwj$WoH5NJfqmq921*Rse!@j7HjdVoYcz(bwdHV$B$5G`XZ zd^92kUOJM!hW=EE&yXcDikLKJ0LzAG`9+VRGRE51K>cfI2L}Ks1XwRJ_00u9R*Lq) z0LelCG^J=qnMi7pNcD(_moE74x>LYX5RFzeNo|B9mcs*bJxv0i{;3xI&1Kjz0`Mam zK;&Zxau|-s82$uKQ#$~_m}nn{(X%v+1Cl^3B!W!O@VpXyQ9K1ij00tejkAgO8@1!S zby2txRvDsbhw(jT@L}Z)I$|6sG7e+_l|2F6d~2yL2BXXvO)VgKNJQeMA%&zdrrG7VMXZXKOr6!+7{GlX zp9C`KgJYxmgZ_PW5;!037g5Dh#*(-H_yil*+t zB-0H0=@~$qB5h{CB-;?pZi#N`T!_Xn8yiY95u2lAh`nf|&CM{5wSWX9K`vrg%V7x}5>2S6{jO0L zOKXM0TBI>!9&%yQC@i_EK-3Q6Lx<#PG@y{isbB>HDK9Y1=2#>Y6d{OtCTScIWc4sR zDT8YT9ifd{8#FJ~d=jQ(r*J)?0w5}323870+l$29`=hR=K3}<@K7Wpil!=)+7&QaL zL}C`03m1GZV~~Ov)4kPql0)y?CX_uvk(^rfoAHy3T1|oD(X9)%K3euk=KIn3(5xu8 zKa&fxQLX@81ZK%+X<>{7{9v!PWew!RMdtg);)e@B4Qx%r0Gji;7sN#tnT}Z^HcIPU z4^9M1SFPtozgkzET2Tj5?=P-Z@%X-32QpZu4y@0+POZ4&8?*q%08Rg#B_K2=_L$(K zDToahl_&`w`wYoydY^z;POX|2Sul@g!Msvj&bzwzvuZgxa6M<;s^St~K)wQ$iM&#r zOSYXWoL>BqzKj81gU)C{Xmx@G#T7IFl++nv~;J;(gT#J$-VJKw5hb&-UJ6w~k3EmptV?bz9`Cf!e~1d&5Q zu&R>Y96NE1on^bZi1cM2q6#wh9DPB??owf&ICUI{p@tn5hS%Quef%o4GphK(P@A11RK-1UGp<8Bi%e} zOz8>`bM0_1X7tua_4zAZifUKVQEPJ#Vi6A;1}^w}g)M6RyDaALE-nm%`A65cgPtSk z9zB4eUyM&Hl$jf|$ge+{gl7Nch}YAKNsGb=5F>EOoQrEIX+%a#XdiRXbdouObsZ~U z_i7CU(^+w}ToOdDPo~(3pzXa`mN9-)&#Ta>m3FD$&4VR8BL3p3Yca)w`_y1dat0%m zoppZar=r>zb_}{FX9>B8c0~|AGzW!j=zGLq)P*!@JoYrDjN`aBb)J1l2a)nOx%dRx z-P3>=RHMzFH3a}iQGWZt2#+(0eRUZt48weJqHEP>2Vrp3%`;eJN!{k-=Kan+tHo;v zP1u$jobrK?u$P7q<*0V7!^Z{TukAoRFA|@k~=raY%73}@_4`pL05L8|AJly10;2hCggZF=& zVmiHlkfV2r$5Y5b;1iQfJ0PK6>T2%XVsnHY?xA0}&{_|zv z+(Osx<%G{Fh$F8WB%M2pJ~3Vu+SJ5P2hV#)NzQ_kzD|Th$V~`La)O1mR!qszo|VTj z>VhXFjh@y&237D5rMs@>e_g?H$gM!H)^{mw)khs|N0AW|v06tko>N-yAwhv12?`H1 z#02#sj@s0o+Jhn&9Y5W8>QTHx6P8Hz>9pbQsi3#dD)-$|nUQNst86W65}yZMxYH8s zJX36daOsfl!71O%tvka3W_^Q*muHTR8vG>ROefAndA_|T|0Z5CA!hMNb0t8i+h4dO zK;recI@@n@ABuP$e=E%i(9QgI_gd4p_-)krq`uJzdLO?p6R6L7u21S&fEW$7(rKD_ z6gEy4ew_$W8b0@7rWc+|@Ih*QFxGwLgn#$q-rn6~A}&nPns&Wb;8n7HGEIDakMkS9 z*+z0F({75_(b@yi;4JdlMZ=)RKvEM{j7BVYEG*Cq@&k}~r^V;OF39sHT%{rLh0Gi#SHrsY_Yi1dSwY;g|o9XH&8&t%Hg0+z=m6U0wx?S?O5LsfKP7@{7%V$W~ub?l2v9b~&wCG~| zH3n@;nb$}a^0|~aoG-U%@cn!#dAwBbK36@FCGcgf{qeV$9cRs(R^lbU|DbZfTYoYsB zMVjX@w#0!=B_fQ783k$ot~4v^*Fj6tz1dTXSv_fW!rtdsKB@Pg(}4C_*tvlm_ED>F zs&T#E6L+U@X^P!D5x2f*j3UNvOJEW2zt`r8sZ7I?gV(;JQ}x**IgRx(S0$!|4575f zgnX2#CeL6}O{V(VVpf|5$`tC07(G@=oQZ&$bMJFqq55QP-DZhBi~%Vpxi$iT?=f{D z-~dbd(!Qm$4R|7IDIEDDg`PkBFKvcR6a|REHimrm9s<(nq@_Jxsf>&P*#0 zh<#>j)O#{e$OGj)iX&k~olv-FsfR4`uskIRIC4sHaE&I61POWEY2T2-ut)2)nNooI zy!)$D^oHbXV#xC{XN|U#TEE0$pcRGs+wVw=5^;PcYHBl-E@QAjnx~adsLcY6w0*64 zsbb8N-|Vuh$wKxxjNhr<)W~Ug4JA}YUogo6~e<=U7g{jrx=hVH>1m6}i!phcBW;Q2f$$p2;ImoRSocW(yKONZ{l5nYETgEB6!>;oJz#?7o)^l9SzaCWLx5=)#UDiW5JjKW@n$Vkm^453`AWzrrgA zbIN~4mVcNLVf;k*%?Nqjs-@Mt_F@{sOj~oROJ~Hj1|X6k6wR_ZDSRc;h@y4$yEjKp zEU9)|M=0jkJ%%hPtTsjQ?IuFvjatLo?=C3(3JOh)Hs1Ep)?e4g@Z~U(JC`yEBDqCh z@s9FcYP|AEV<%9<5d~`b=K>vK{S%ll%*PycBX2a}#0SdI(2NM#B?Ne^^hFXb6(<c?Tnik;;_ zmYb^Dp#TtFvO@G`GJ!5BNA5FI(jzDV(-It&go9(n&v9UP%UiTh;nBwqbtD15jDD%q zg8@$}IUNODQt^SDX+8oB4-=g~OEj`^IYNl8{cpb>2u$@^8`0~Cldt~v(sT(ZLvIs)Mr_}bQ;f+u@ukM@`%`KEEoTQ6a|IuZ0)>&go8`~>` zpaylUQ=pYP1)p)Mb&9OUoSV*fW67C;?D8ufdp;J2wJVyrssPDc=a6!}Ail-AlprYw zMSknK^2Mh5rYhfXe%}mHboFd{g%jA;c&z+=*IBxR-yePlBL1abs^(g>qW6933d{G=((f? z&T<ulY9!s6#qGDvF>e##W`cdl>mMfT%AWtr)Qv0*faP3B!`t_Nb5@XL{MBxNJwd z#t1;w#EHKdlKgOmzMGH$NEYC1OB?clL zI8#2(7?#%XCG-xn)duhO$?Hd?T#JT%06EJvS(u9@G1+c&k0mwn3yEYw5;rBYTWZPN zULr9CsE<_l`ufX7@D4C-WF=HYKHC{`?DoZLoaGykgBN@=XE|S-kya*q zMB^Ce>XOohwQ@f?K7TziG$iQwf!y6|{I=aJ0r2TgnDeGwCO`m(c=LO0|H4U@xO`AT zqjBAXGiqfw<1TgHv*sdZC+eD&Iol!sw5}v6Q%%{n zrp0<(9r+RH>+e>`9ZVV|;`+V_nM{8lx73jG)8nLs#fbyEoSXw)$3d2v!n8a!Y~A>0 zU}6@-rUs^!*4{Pr5!0-aaZ9i;^Xl)R)eqme1A;!=QT-_lZB28Ngrfw`4J%%4ez`0C zx~n5F^Oo8t2*r(7fX<@?GrxW2LkDmReV+z}d{~8mC)^?w-uo8R0Lcvqud$@! zm2R1!h99hzKK&wSDKph^^v!(kYR2l0XngkXtvfZ=#6o#NrPN;%7#bEku$q!PPXsQg zZ|!~+llZo%I%QRpnpcz5W#Bj1uyKl~FYQ!3d}M|V6i`~GKb8`G7A3fyF}Ja@VOEbB zK0curznr6RZ%l_^op-{lf3GRlw5~kVy};es7%B4+inW1$+~Bd8T(s|vA3pv?e@7Z` zJb5+$^v=g!dL?rLI>jqqo6Cz-+Ir0-rN7^5t|jKWuVvSj03aNIa?|P}pMa5ufE!0B z1ScArAh?So>(v3wn{rFwi0$DZIy#{5CRv*qu^SwW#(}Tt;3ThbE1e4@FL0#QaI$6` z8On_GuBns?V zV^CHVk7>>KB9?2M`o5N96%iWzx@SlcW=JU^t!^aPCyIZUS{yUXw`)i! z5#>e`BM2s-u}coJjinVG<_?OzLj`0+&IoLRJg(E`B)Cw-3IHQD6$#W92WAEtvh{p_ zh67FrVlWXI*Zv(sY|a+_XBr5K9+O7Je6}6bB98{Z=-=e@aWbN~2!~7IK!Hv6Y6s=J z2crV|1SLHx{w}KYR~iI=vJgU?swnolwC!mBk%8K&fEYu+0sSkrsZ9rkR|c8_ zeMVQiIv5~3blmXc&>|Q};y>Xmp-Rs@z~}9>u|`4?`eyqoKjfGlO_ z54h*=9p&u7>4u4Y8%An{A%x*jyVuBsAK+-g9An;$V&ty^DH>&3$zl-L<$CT4;+Eic4^J*W&K(1S#%TXn~?FP@t4T`Lfn}_j~qv z&;G_Z-_5x?8M&D^xl88Ae?HIe5vWrP-QCr-QPOw`xug0V$62V*210TxF_;!qtylvQ z$|cEa6i%N@AtCGwbf1{|a#(E)OG}-swq^FovolIOHH(eqM_pYfh;wAZ775gA;td*{v`3@i=OD zAU+37J_|H`%viE6X?w7&bjOG2DF@*A&Wl7U>W*CMmoj`aNfHIabi4CJC-ZjBwzU@8 zghAtkMhS3n8JPIsb4+V|_$Z;kP8=EYs6|nN^Oy5G0)JH&)tfnCZ3iVUdhW+#{^Ik0 z5DSsw0Qx@zOboJ*Ut*d^^b>^yvL7hNAI)3$Nt24pv&@y{KdShnw+)T8QY#qPDQNOrIF~N1VMXnYF;2y)?`MG7#UumCTh+U{Wrt3k#K(J5n{)D=j^e#sK}RCx-K% zoAq*h0;tV;Ct)!Ul&>l)%x8pp^Sye-_wwJ$s)$I$GZdwum&5n`1HWw{pL2txYmIzwFdy)JVNo!eE-bTSGr1~7V7KW#1l1j zVpZQ{yiotQms;j&^w%)`-(G4mXH2MSUY=?wYM8#+rM?4Yo_hafp8lhq{y(PJh4hg%2#wN^iz^j~ZBf9J?nD)v{p z{$+`x8qOEJ$Wi1!YxUFHGb?*5{~?Ed9{xuQ9sl~b7W(iD`7bB*&%^EYUs1CEf3yC7 z+^i@5KiRCO{eQVx-&FoT^u)@Q2P3IfTB=r2oAvs4<1PPe*1K1>{A;s5%cJH~ZvZ+j z=49(XJu!Llw)!ul@sv;h+N|H3NavA^oNPzs#Pk>?2gF4G_EnEJAsx-f%RzEU`f8mm zr|Z&2gIgavf9kJ#s(eBDs%>twJxLtTw}{%zc1BUYYOIOSkK>hRVzszA1!vzB&=7C1 zXj8>qek9G(>eA*&C>^hUnTW%i?Kb=kJlDZD*M4}{{O9y1q2Jj@dsNGQQ79{bjhbZJ zpI8Es8bYLX5Fd(f*#->+dmI!PtfP6+D^n2gQvjgyOj~f)pi499qLhQ22(Z-8LMbwj z4@E{oiDl%`O1~aREdps#!m18^>0`!t9Q~%x2)Xj*FJa&Jep-iMta{BR3bPN{##q=n z&ZhC%=~9F%l$JBID(QO>1ip*-Sqv1zVPXNCj3KsSb`u=;;M;p5+Bxo#tEE|N1L=(U z5r0-~GTz3nK6cgl+_qmLM>GD#I}G^vaZ!RgyLP_i?doA(C?+|xR&k`$UWR6v=xnZ9 zVZ>oIrjv1M`CbnDi>gLt5Qp}ANea%GUgl0m#U>}m+_T)D?q?X^MUHO1fAIjS2*!ZIr=VuL7ao4*OR)yCbz%1`^c+{99Q zAk0-~1HruZCw2V`k8aL}hz!Ju21ts+>J=#MPtHe&-{ZUdO4QrUI9M+O(R>)uN$& z_0^K8=jqk*gCXf<1m0W31v)h)v2+kH);Aym7)3?*6|9QY{ASbZt4pT0T~YNcDL<<# z0t}3y58m=%thxD2;wf}Z^$g*8!-8rY1>maqzYeAp1=RI3$pN+jv{;W5!hx1lH2_i% z?mu=)n&Qb3P-?xCPlBwS!&;63Wd5Z0dRazx&wgT-21H?%};<(V5b9do@Lj$Pf z%!+5EP!Ov!w*?&Vl=D=yaTk}UQ>Iaj>Q1X9$5NjzslRsN)|`F22Y&HY-*?p>*ROva z=M41dmRnE+JcRRB2TspK*AvJO1Qp!K5^}=elw_KLoMg{`i6=h$LCoZ#LZ--!DJ>Rs z7fAmA4?xfnG)M;(yE5rP6>%j7FryZr^g>Kq8s>(1k3^B-zGDUQFUb%-O3`%IUuf3` zQ26pLeFTy)lfzk6BcGZ2iC$OWp_2d+$*18Y6e=e+9~Nhp@!0bY_AL$NWSv7ujct@0Q) zKq$egwGl-`f;s~M)5r$>g`oCmDANyNarihNUvaM%yB1oQ0|2AiNZC13n{I>ga+BnV z7XlMd2P0nD=MWmGeDv)i6=SCasLTqrc!ZVYl~Jm6frR-Qb7Euc6g*R#Q+j`N_HN|2 z6dutTHchdGV{jdSIlm0Rp?IE!W&>m%V2jrP?F3n9Zi$M_sRwOe_-YClz~zOZEXkT_ zb1CkPt9J>R&gcUpd)%q6UTDwMZ9% zs~r?n*5)#=o66LxoeU<{mO8GR>td>%?JJED*uy2yd@7AAwu7hrPGC)VHK@({jn5Q6 z+lHE}l_udD8^%nT-S>)g3`$kJAjMXu2FL+O(=;lNbPL`+-{RyXA?k zOLkAYYs)8|WfPJYu_ZVkqrbf$&Vt=7h4<_ctNCE5ZUZU3`o7~~(+w$#`J~R|0^Ov& zFbY3u+t85-~^yNYy?ZdZ> zF-|I0dG(mV1$tCpD0~ci9a=7uo=5L-e)vU~RQgtKMs-Jo4|n>nl$dR$ecV|_uJTg7 z?1rJGvdS-B{ThC0VF{?Brx871@omYlcs!SVCcUdOKLStM+I;j^T(02vvb2vUc2O-0 z)M%Fknra$>`Dl3edo?lm-DD>tYqO2aKcd&W_MiH+;aHhl61PkqGvx7C&6Oco}1;U+gPeRy7i}u*Ni>!BGM0ZP0JHZEQvnBC+1GStDo)M z_xk6a|NgW)tUwYK?pK|rU2OoXXQA^O_2f*!4o>l#81<+B;ZKA#-&=;ML-pHaHEf#w zU_1(rj|t`t2!1HQE`DHPd8x1u2NDQV?-&GfqX@Gb9!3XWE=4b%^x$EEU>2QVp$A37 zr)9y?tTqdmsFE0;lyHc$p|QAEh`JZ0Qd@|&Fpk8qF z4eZU=&~yP?qMbk^f-q-f2$~{^uR)mq2Y`z`iDWwL73t%4biNX;@U8)x-3DmoS0B>3 zurTD?SHdK}706GMcs&;pPthZW(89tM1Faok=qp~F7~T=|^qz`A*a_bJDFNu`e)GKK z>7?%$usC&JN8-Q`WITwkgEp@nR6ts?DJx-V>0#(R2q^MBLxJ7LQ4L&}Kk0b{#8NdY zB%0Pz3AhuDV;PN}5IJwC3giizEYk^+g=Vnu-pxg(3qyZ;`UxaPIk!a-Hc7>9+DDxr zVMB%_s|V0=MNL+i^>;$Q)^V)Mn$2*WoFU^OHtMNs@;g^_y0eD%n%A=$>}h}!;QHHc_2qKC|FK^ zv4uwBFe$8=DVAkAz&Fa-5uCs?FL|MH3^)rccajVOt9Do_#x z`9KpA)0M~<91{4(BKygCaA7H!JO)-N5iKI}w1qQ1hg+c&kU=}HTv=;~lEsx7gi^d5|B}9vvNr#?`WV^UWFQ>yCj1(Uq zWW-26EqM)X(oODpScz|Qq*;o{p(wyGEy+Qh^*+r9WY1vWpXIn^kl&VVEa54ecB4&)0-!oJULD?=${M3v*LBpEP$WJz(R0L zTmXOqfNi7)@U(ztyMo;F0p|JQApxk2t8=4w(Q!NJ`JpJ|ZOMjWHgQtI9f4N`TRhWH z{s-ZlMem&LRrIH>*x3OfqI|$SIa+cbScDtk*@vy;`T?CMXB8blk8-m53f>52)fgmJ zcqcNUWtY|`+9;DeC71Q=&oW^ka_Gp7Wsi+_$`@14!LI;>SfEjjgRuj!Ua~{A>vC|m zv0$#)7{Y;IDp%|*I*?C3z{0ic^*mbStx+^ZvJAGqTm&U21&KMEH`0bzy}cZ>;K=~2 z0#+KRB%hqKocR#*xwHfaQ%x7Ex&ok0r`@1j2|~l<$Op72S6a{koX(;fjm@Kt)0Gmc z#@VLuI4u5iV{JXeP9h}HnLYJMA+g|nA!v{zgx*ZR5FrefFKMdtXy0i8JYQ1-g| z+ge~fwrqTf5jQ$e3QTTM6Oms>JzmG^Ls4{FO4o@kR)==tgysXS+pVbgI?Bnm0BJ-P z$e-18iK6YZSFwpT#W~h@IhEn$gN@{J_mvvaUo?i)p?P(Hh;efj&LsNY<;r$8A4=8! z7;m;Xj`aA|j394uziN(%$o5id$%#lv%g{*l7GwX>@Ux)dS!V!<_jT>Uq=xgwwIbwM0;H3;?tL=D95pMMA`@DLF)4!91FWw^ZxuI z1d5hs9cQ8yL9sKdyO}ymJLy4u-DC97nu!kOepGm^7RpmNex!4W9m!Hq=vG36yeaJA z?V#c@Sou&Yf>Wr?_H;q4x6`t_@~T6jpqqKOglJ6Pa;~hVXS}@4oEp z%eU;6zHUYbckjzo)6W9cQSN?tdz-v2qm8-$BDBJ``6!ARFFo_k!~J9p8otz3ko4 zrCWDQ))0HS0T6xIaFXPglz^h@u(>a-5!Hxm{V?C`z;oXbErt=Ns^PZ-s7bsLQ=j1% z;-eO`BeomEuGym=GNZoH#5SCScH$(Cm7_AjE$SPi2-8sk81mOdYwBz`6;-R(2KQTs zwiHNgrY%b`$DpZc9Lp-&{PYY;O}F7;l;+@~0w< z7AK1Lkx%5vOp7AP`#oWP4JG01K+LuiN67H8w^T+wNgvBj`jFMpeHXK$JyGC0!JRN6 z1?xQas-oS=#oXym1N8x%y3i&&?RGkc6{l#$^Ihe-2F3Ddsk%V#xF)ioA18cpMLW%{ zJ}!%ox0#O17WC4u!9JVTZg+Mv7{={%6@KDKVnHi{)Q>edLr;DBm?mR`NLl|t##inL z)*wW;#~(ccJ0pMeB2y=UrllnMeGJjF1gdinsdKZ4yV)nOIcZq`rgH$R5fxe2T&nS; z&1^q;)g;{=A*Qo*o@hU__yqsvsNg1n@I9f#WKee15dR(Fq?4jh)u6~^$Nakhz5Bu1 z(KZddML^C+pc*o=eu)3g_`vHWU#dk;o<(N~URepA*PP3;s>>Xf%bwIL)&t9LPL|ox zR)TU?kWwp7&MOVYEAbNS(VHudcylkPSJTaClek7=V^(B##xgd?-O<*J8dfbgR@2Og zTz(@xOh~=okHxL5F`|#9t7>CN&HAishdZxnMz8r-^3;g8i88gho3#Cq`B;Akwfnf< zZMG_uv$k%Ul`s(zDA(=*n_T*6*_+YjHJ~&t7c{vxyx<7%o|H!O+5&YUX-j}6cp#3R^H>%W)*j?mQ>xhRogXF?^U2# z+ms-xH6wTJUU7f<_4%J=%h<2Djb9;+%l@%!p6UnDJ?jyY-BDWyiMjM~lD!F%hv{3> zDUS{V{Z@i=594DFviz9RUXm8$9ZA%Xe8_E8xY_EZwv?;Zf78>0U`ZFg?lqy9FtgCnQ<367GEp6pHaPRI78*!Fd^=_sx3 zuN$9ss#`{=sy(qk8b0}We9t*ebK-EmjZH;xeJXvEGxvyVnmYE>reJC|{S))i)I~&$ zV{DgL4M#Pw>Fs8v2Fo->2M9Nhql@ zmd(zwGZsEj&Wm?HRVtDT_Pns?*)QXmZ?Zg))*9Te+83VO+`ieD#vas}9-DfpHd+L8 z8WenK4PNB~)Pxvn#vOU@Eb-2N9X7ZoM-vXRmUvPOjJdjYrPa|l6^~~Wf#`{(C5dFs zi{ufC7U_t7ND|e%1nBQwpZximn#Za1R(z~c{G&DcG@-`=k*vu8kh_yfpB3M(1);QP{uN$RK=U=2W1e`Q!XeVg>{c6mtF^Rq0GtyXD> zR*%1&k#3|oR5;e;*AV{E2)^=E@116-X30}%Q~A05}_hw(dwPOZk&GF2|>^_Pq$m(56~-y}Q6?e3?_#XbgKRC)-} z*&K_NbOXr%j7~IY0Dw$MrcexnUVbuLzYGhJmvKSk_lZNTwT%5;qimp4 za0d8~n|Ft^X*kr@zA1;hb##*u!;%Oi@!F-T#YaW_kLzcY(UU=ILw^2rUv1`6*_5+I@G2X~J{0R3# zGZ2O?${}BM^hT?Ho+f*yztb!KX(i1m#p^-_EzucSyxPxo%}3(VZt@sTO?B;5wL^1_ z#QnTa6uc0KP5fS?wPxa+J56c=6hk|fsQPbQwc~QsM_dNzPlD6!kPUR&o zDZ*u99Y&7Tt@{+_rOOzi!(_ERsZ7t%dMXMlW_f*%_Qp9ATn@7J9VYATk7z_+b^m1c ztmW$$$e?T4*wSg~0>_yI_G>Xs==2f4d+^}wVfjGi*jwB6NH?e{IL2vfW+>St?sF1i zZlYQZx*Qtjyf~yET0$tnqc?AgHZ@wzbv*9*)$Gf>j_T9tVCTii%V1R&MYYJYb(~X# zmkrXp39K7%8@i&)dSxaTzA$mczLCD-FZcZU>G_Q(QLibjhFGh% zq{885RdvlhDR55eVpQTx@w@+vibNTUpMv&}nFuw463)KaGhXyh2a#5#-Kop=YCb-a zc|Sn&S(*W2*T9fl9tFnUHtSibwdj9Lk1MWU zSkuNCv``VqmSII@Zzu;_s&}v!FQjI?5Ux5V_1cy7Tjo-#?t+=&^J5xI z1oj0?wolv-3w3(t(t1I5M2Mdx#%puwtb>muku55A(gZ1XioxVTA|D+iZ89cA>;&JW zPJZ9uGI9AbPtQisqSnuqxGj$4E6PyjOGd+4@U@GQvmf$-@X zsBFAViAwUFx?7wsy}_e!&3?9_lv7_8aTB&_zHG}BTf^*M=44X6sB=_W7b62##mpJ!<|cTA+#PTiRcE+QmX~G&cXc>P^bbi6i+6 z+ce(TH=Py77$r4Z`gr{-D|C#Q+qVZatzB>Vu<3WM(mxQV0B1`L3UjZP_?H@$!H@Yd zB9uFq^Uf@pQZ7uLWQ#O03tHwO*CEUlXXE2Jw|Xf*Bcyfk6D6Tabw-T!PByTx#c5Yf z`O^Y|KS-wKj{S44&k$>=f!p>ova=`X?Unp_hwARvm$erm)lP9oQ~mP&bq_d*4RnzX zEjC*cp$Thy$ETLFx z3D!G#x%p-5(K$5oDD-SXHnK#(u0AFX&&Y4OXl~}VHrB_Ti{1NZ9{tmN4lve*qmgp< zdntj8m3C1BCu9+yIlTflQs1%CX-e}+e(=qGifrheN+^*omx%mDyT^t#v%RohH`VK8 z9q+9sBEGQ!v)4(@U3;dz`i6`bd;Lx~j5eoiIY`+O6j#WPhE$c{3dzmhOMgsrBOFv)YU>bCYQoxp1s5ySP&)o+x$s zVG!%P=65L#;)mFueWxPnJ)$CtXz_Lwdxw#|#;o*&6g6SFjZ0u}))#xKvw009MNiG0 zpED7NL{*6nRLiUED|b)_7tTcGK6a7s8i)R3{$}jzLa1Up9{+AjCsXXyu{KzA!S^D$ zujSOSyy(z?(%NuU%hm(<)yi34Ls-GM`$V#x*9GIIt{u#?W73PY*|^VI{RrFZW`mu; zSs_btTSr~~*2kjz;;PR-#*PBy^Np3rqfW8eq4PQ7`_!S}aagTNH#KkGe+$r4HF3lge5h-4rvsU7UBo!OT|!LF&40Ht{c+2- zgLwIEvDu}#Ty5hkslnq&JgV!ry(B3?E}qe4HQ&pnC5*Lysy_PBErXw0vi7I&>2j#o zPmcSQo!_U3<(Liwv*!i}RYal`h3)f+(VqRW?w?;h{(f!JzxjkXHGxD;ou~IpwgI{V zRe3kpXP-#1JWXh)2kxY?YZ}GMQUnhPpTFg9WOjD40^2wDPvRL0FJ`r$G?;Mq{yu}` z-Hbk{f32PS`bmRurcuhTBAWL7(K64}M||d-X5IJlYI(muVLhuR9*9s3`DC}R;D2lH z4V7Q9z{@`9r)c;b4rQf-(d35!1$jUKP#-7_OS5+XyAO@&0Uk=xdozKW@q+YdyK+-ml zIvj|j8E_p1P__u6A`1}P4q@vX2y*Bh;+6q`1F@pv>VP1yjdTn_oYGnJV+i)+T^uoS zJaON_gE!JYgQYR(K)A?WPE~+7QYt7ONOKts2Ec>iphs;XYS17FI90H5#f*Fb*Wb~N8y0Tz;8@Vv3w4v&7d>`CsW6+Kf z!6FMs-DObE8byU=G2($jrm|{GVD9`r1rS^w3>2V4JYfx#*p;n{moe><(U%=Irjip$ z9(>FsSH(JN#*Yxv1iZ|a!+^?}zf}k}l=f0ZxIrR3qZNYTquM8O%8WA4AoB8;aB5Zg zAj1)VDtZ3PU@WpBS=J$;N%=QbqdJq3uXRTa-y)*24Q}5@VBEY_>vhpIV0QBwdwiYXovR!u0(gM;YZ;wuZW6|7KH^By{s9pr_rW2Sg zBIZlx49nwrL^;VL+jd%8Fo^_M{h&31ZtmkzRV=|%OKY%}Tf`%-d5Jwz!bP0+7YsMR z2s&yC%1zc&BnVSNhg;HiAwopw**$oYPk_RwC(Knx$Q^ettNpZmc3F`q-7AQDcvk-L zVnU#9`RqdV%)GYkqP`iM0bXwa;9npX{(l3p7#J7?`1$!nP%M^#knjr>izOoOjKZ;G zQ27AKzX}3IeBQQvu5bA4efV5aT-G}iNd*N3BO@aR2L~@NFAN2M9(@p?ED+KENrh z=Rc6Ge`*4@IU|4ZS~Y9V4ac5Mpa0Ekg^K8f@j3pT6#)M4sI6#CoiJV7L?xdz2gMv$ z4RIg0p-9^ONY{x|4r?gEt$_`gA42M@g$4}Brs!%ZzH^lLhOa;|QA zZ#Z;+IO%>o@?kFeVJQ<;2iX4``nubw+TZJX*!#bruVv&CDh+_@0<8R36kzn`VR3(d z_5R^#Z5oAs9jtsk|8%y$`)~Sd?BV|JBEWyO0RCaXCNnZ7GbSf99wsLNlaqXtlXj?! z$-iC?lMjH&2foP%yUB+P)YaqzikABSG#o(te*j{!>QtDHHK5M0xvj^ul^RPwW(ji* zP%t=>5h_tC^?S`k%GF>EtkHqt13FV5G*RrIa&yIErD3DsCAKajH7$M!j_<&ier_@H zSSPcIe}PyzK5i^b%xJ(%c;w@N0CELOVsa3DAGWa$kZQ%ol`K^i|J#XNNdV#IL^|J# zt-nAlgqY7C+3^spT1z8w@s)OZQcfn2Af8FlyX~p2HuS!OBB|4_pZbDvX;C27=!_|C zK28BiD!O_BMg=*A2YPK#mG&6{^WHqV-mp^`O4?hJ?s~=zOS*!;@NJ| z1$-)>v#hX;2A?dS^Yk$S_bknPz|5#{07MW>p)q#uMkjT>gOZ#GYXn1lJI=KzweSr0 zw-HRK4xb}3yRnGaFuWA#HRkrhcl?0ZI-$020Q69H=96V*1S=-nZoDiB_PmcMP7w%a z`4nw{g?K!D$BAQ?cak_d!ySVO!vkKFU||(zl5Uf#r1SP1Zx4sqTcE_!faFL4%FbG~ z9~$LLPY3t5yFUDy7l6rrkRL+gbWng`t}p^n?g>DPBIRq@4~vsKb{$I6?J5pSo%fdF zKV*loAC(oSIvtgll~x>8RJ9yc$XZi?4nH(9fDTJ)_bZNTx~`8Z;iDjqle!_27bo>d z=E{?XNx|cj#u<5z)28u1PN&VfT9v0Q8y?4}t=k?^r)|4yM5z7c(#mfghpETkI=SjO zzIRY(u)RIgVkl? zc$HOSZFDbZ@mKF=rzF0-y`16gcfMMjpVOT{=lk$gMP5STqt+Z(0^aOw#P&iXn`*C3 zi`j&sBCesCG1l;`1^$dBx#<|k2>Khn>KXL+x?Ss&*<-9< zk~6bbEXnQjBRW&$ z$47egxM$|%l|i1@`EcdJ&wJEE;d$10bVB*964uZ!pqqf<6e-sT+{KzuEAHQs9< zI3>jmU@WF42;a*B#A78D9z6i1E6$WcF7+S)ujtyv3QklHpv3I5uc=SArPBBNLPKVt zlvI{d+QJDN-QVBO4(8z6A4r8B6wnDx(%*)(4JASn=$gxDl`j;AyYH*L%)U^3oSG5V z*^RM_w%$fZo$!Q()Y9{+A|Uf#P;%o(!LGjG)m&u!GDdx@m@~c9nu0>u5cgZ*i42T+ zVX0#Qt#FEd8XT^5*KDmdkgxR1% z04Dhaf=@v{B*w+2gyLQ?9zP69pG39(nAl3`^q!m1K6-CI%rU<9F)S{92!W41r)Vk) zN*$I(kPy6{eBObd(Y9_&Lr*a5<$aOGl7zht0z!BSccMU?RNMa^A-9br!ws&AI`w**AxZ*>6|v9di|De zHOpL9#S0nLHR}b+V3W$W(;@mZ8NTwH?S#Y;xu&J(`PjKs8{>2PIEKJiL?t6sk4zpQtca8ma&KPAE zZpwYoP%o56R!HKtc@WVGGuDV=P#%FH2p_HaAX{v(5_M1 zYgQT_e_CF(hnmEi4(TUI)~0-n3%nsbb;{7Mi0rNz^3{&l=&qQ0k?{orr0-iyT!U%h zUrx9TN5pL#1Ie{56uP|Vu&;M=7VQJYpMvUVD{Zo2yh}j~-qT`s%x9Cg+hDOwBkcli zMH%0)pZXN-C1rAK>}FA$yf!^rEjwKJ+S_8sMtQpuPfw9y*1@~0b%bcmo*6AtJO)fb ztJHF@K5*`~v=_t|kRWTYtd0%wK`Z#Is9&MO4XF0pkSY?z@(<&(h2KQhJaYwap=ygd zDkgDl+2`4W11>WDzc<>xcsx6HZqY~AojQ2m)D=fetdx~Fi0poA?-qr*@$MZxCFE0L z@G10V?}PEwXZfG)i;!al-?Ia(Y{r3-!cE(Cqz);o~m8pNWMk%{ZmZQ_TOv^)N9$EU5&SJ z&gb6OlG`nPWud(S(Uy;XTg|KY3STrq46`=Pw*x|v&=*~5ddJ_~#T6V1JVD4*f94dQ z=NmHy6F+ya__u2Z3iDc7qq3%cH{k(@P{$cz4@G9L1BdKH%)mB8^a{d-)hd)M zB2*Fcl>?!lAr9p}BC{=FPQ(44@pmdm2d0# zn>otROTD=+oXW#8qs%gM2{CQ~Zn5CUK#K%fM(3r=p`YU-xS@rHkuz-^AIb=Vhpnu4 zBU{=KO-Q5KmGBHZobNx4N}*PCrAE|C2>d?qXrCakz%LI80l7h<^C2KD9NwX5{IggG zTin@|xa0xwGkqMhGk|3P9HRhkiY`gauft=janTB$mQg-h_Dk`w>@Bm*8IAIJSh4KM zSN>X@(BXx7+| zo~1`y3_*G|F-`k05b$J$4B^bj&~Z)7OV+q&`*FHPtiw7uujG_NkizKa!jFDIAGyn9 zF(uLq#-bHFwi!lc>&4!uTKXs^F*rssVn25^N}$}Ads^;TpPs6+9JB3^G-9X{F$fVy zhXfv`LWGh9#sB*`&j<&b5#F(bCD>KL6cmNa=2(NmXhZG$7;9*#7EE@$Kz z*F%ti0-?Z+uUK%545$NlBp_U#R4ezLQdaI&q{>(G+Fwy_N{MgEP0k~t?2T~lmmF1v z@=AZj3=tc2Vhes;P9LQ z8fJjq`8XF+fc&~*D19-No-&GGiWw{*{;KCZ6tB`82|_E(>K*ZGPl@UxgHt;uIL_p< zI>nKaWc3&&Qh4X}fc<+`-liig9q5u=$Go$Nv&GB(h7Xc{v}Ko^#m_P{B+w_&2~czoNVkjZhg{zYRoM zK&lHYtsjzpsl#Y!G+=|bvB!tz*K$%Dm2m9e>bUTHfpao{OG_iGsdFk zfT~5cnE61<$y#U2AaAmY2tM|xiUaXA#WL<_wWxjYs2VP(! ze^l*z7~pX}uC7W&2yTl`RE0o5{d3p)A4i~doOa-BrL(1u!=MVIw9xN)YrlprTTg-( z062ylt@L+nBXP5^40-*+*UabY4|0sZQiPlQQp7tKIqNLNE$BLAh56d( z_XqdZ&A*TEP-D@RHj>kq6z;pK6vZirruc|cvkT4*N{bMS9|r49{_eZ)lo8eM*T1r7 zO_p3w^10L@Xy%2s1ayOV)ceUZ%vLc>;|nr6vh&E`V-A>k!nhK_(c(rutZperY^4}d z2n0DX^$_?$mqmf2NsN0`c5GL5sn~ygAtdHfAh-le^^L5C&`{4MO#47un=JG>1wRMR zKxvi~&Ujf?L`t5aa-MJw&)tCcj|i=|5Fy_|VN(KSQQ^$ho-jt?Tx^&LMrwnu_V41M zz!T^(W58|ku+Z=jm7DHjx`sCkk}(hol^YV}gV9sLCIKT}gJ8isTi9;?ro{z{b=_{|8 z92;dF{p?F%(cyTiQc7nlAGjOvep2trusC^lJl;w>vPvbSMMp8)p$A>>!Cp^tL18Rf z-x2^u?CNZaEB^UyqSm;-atyWjyeQ&hA;IoP6Qg z64b(xa_Q5%^s~0uK}9s(cTeO?y%Hp`5@NOz_I@SgemT;G5V5%ud%qG-y&BiOlFUVz z_a{|Nwb%FLNyn>?->l(FtyOKV)o`t5(zmC05vEis6;Nv8 zHMB$N=V0gU??10|Cy)m9L7(|{l?kuop0AB}Z%kG%*T;++OZ9r9kKumq;->Gm3);*d zgN@RGCE3uDvE>q8K#`Tu#?6g`oUJ43o|kSt=wky|V?CW*HRtQf0kQ@f2EC%hLAPm> zEsYbcI!L(0_Bd6)pj`}Rbl--1sm+7DEQG4xD`bh1O7{l$nFOB8vdwFuoPOyhokbb( zB}D>yNaQ2{ydxoh6+A$9wRNu`G1TZz>x* zf~e%=Lh^fw1gW;!tZn2h&wEkIkNXAQW`%4z^rx`;nu%naIj?3h4LNB^t^lr0C`PX? z57+s{??VBu1FG0b5w34y)O&)$vQj1e_>dj#RH)o0tTBHKW~o ze(#oU-W8SGm1*3T@xv9_?3GpRMrrpKi|$%(tnMhU3>XJGAD5avD$nZxM^Fs$!WPq==%9oc+2-n&HHpBv~kVP z0S^JUn>&xHhB3`|@Lv56OWPUGI}hW$Q@`5jr@g1QT#!`y$g2K>I<)7kyQdWY%LC^5 zuWj1Zw5=3VKd7iAv4o@(S)PKF`jE`G8~5kCZ$Jk(#k)YMVeFkF-yWDz_9@^Tz778y z!@B89CeejW;G0Rjy9U6a{@9T+58A1iNX#9^qUerByBDGHu6?Fk{**;maJ zaM>El(D|yKEAjph=v~rh%|f{d-U_*yqP`NWv_c-^ndM+cg=qE12))9kG7ve#-P+;{ zEnMIr1!v`q^FZT^MFJO&R13XI{I+okGNEsM-CnDIV%A8jo(G0?V4h8!kcGd-Lg(RE}MfXjI#>izAe)U{#e;Gaq=$?o#mkCK1sV(Q^E;4TB}~v=93} zNK>qfm)}8b;fb?jy%FX+XF3b+`M75f1k#M~K*PT}AOD8Hb zrg6R=XF)GQDi=0Tfkn4RCULm}&tw(VMXq*#s6@ysf$IYya*yi4c9y02#c*{F8T?swXk-L(mlK86|aA@7EZ}Mtbz`#t5=*{Bq zKN|vuCiZ`I1N;eCSuE53>IUS6qPhWlqJMP*-m@8Hm+rOvs~ZqL&|><=dQrd3?eA{D zr_kk|H(yKAM&7za{?!e5Kw(&~jxmI{XTRO^oAPpB30a1c+O;(W4-=p;tU!kJ(w7`Q zH%83M$zX=B7tX@$GBmtLYV+cc$Q6=}^i+X3%+h0BiM+8+R#~s~4UArL;4VvF&?xS< zC7=5M<@({-_rHxzsrk9DrB(vge)#QKChohIC=fQ_ZT7irQCk#rt)l zd4Y8?m2@G|Z-pH1yvi1P&C%P$`!ZfYiGx6U`~K#> zn-;EPaihk7@ydGUG{<qynn<@oPg=%_suh*@nV(_b6+y) z>A%7~3+S%RFD1@mo(lFPPPxLb`{=eH*a*#~Ax!6z>2R!MrrpvS{w zdvDBOkbRJC&mLQ`>O@rGr?%uAoeCE>M=PDA{N%ofg$9k>AC`Hy1Zhn}uU)ek=l6gH z6Q|U&?zBvkDl1=ERpcrXlL-i3Ftw|_^q9~3v=B>szsK&HI-mVj*1j5KJE`@HH|KkZ zz4)Gp#=E6?y1}+kiK})Ezw7xtx}aew6Ay%0kwLIHpda11Kgd)ZPNoA6066qT`Rgwf zk`6ok0Xu2VKg{%F;lmHm!)8Nh5SQ2@NC#!T4((Jwj{JBFX#h}D+tPx*kk5gYGm;w& z25p0y0uImw-849DKBIZEI>JT9!$Vq#a`@jk>6VDHmyOGnQ@XPfdi6zF+VrF2gAXuY zqv0|^EeQV?bAJ)m2Egz8z5x<6#oda#ySux)7AX`jTC7NbV8z|FxVyW%dvT|@mX^a> z@4jpA=iYM%XLhC;B~K=i|L6Pb*X!3sz*I|X;s&tc+scPsL*iB3Gw>O+YlQgYl8oP9 zeDHoe?t-o#CXcqk{wK*#@I8TA+Dy94$8c&GL7_p5Fqvv)Vhb}`8ukJCKyztiFLE%w zuLN1u`v{}em43U-&G%pVWb@fA%E>?;*}6?y$BZ-)WMWD~EzO9<(D>zGv87yJXFI@q z4SqsI?1TFSlO1RdAu%-hEx#r}f(rNvfuMos`)fhg3WWquJx-B}l!2i)-s8~lYO=F| zLN@E|67I3riPK|9w*D)y4bL6J>NYlok>FY>Wz9-G(J^a2 zLa#%Ck~Z?zf?QT;Nz!5KQLP@0kER zQANx`|0#iNOx{%fL*mB+$ak2pD{{ zZxPFh+oMiiaQf$Pzn9Um67m7>t8@{08M}dq1;~8aaOeg~pNaPPhCl3?;)5I-rDUuE z#^}j>zC92BVq#Bnq_Vv+Os5s6A;F0CRN{cICnovuQWPv1Xst^lCQ$%F6jssSIeDXk z)fYyQM54<*CKbCv;=j~ytI-o@33Um{3*tsjT&Xg61KSLtrgL*;suBM>+@IH89h0L0 zqvw3+1@Snq)z&rywjH0(EMDs({UZ{L-j!uYXP`75So@|%CxchXPo5_2C}AuPN{jEo zGQ%mcK4LP~$^}%I1l+XE+ACQkeNFAb;K1QWKn#KjxlK;i~j z3?U{pEvV2w{q?{p%x6Qf(TcO!=(p#vpyKkX%X>BL@;id>Hb~T~4{z%#OxAZ7r`v0Y zck4PP%y*wUhhtb}>xQ*LNcuD0as0Gz?FQDp~*c(For|-e1q-VSbc9aSU_SU!xiu zaUAbU*EL~2VHg)!JOAR{fC&A1J$k>wT8#0pCTHnrqD1_y=4g_O0&(E^Wz~G(o?>_Eu{`C0n~$HP zuR+g@MXLjeZP%b$M5AG`4x`s@s5b`db>k=Y5)}60zh*t{)pFKj?~NysjYr2sqO+!P zwcSQjv~kHrazW?G!=W6%uSv=G8W>TiWco4M=Hpnfk}&cBfY<;Fbj}?H&NSCv5~?>! z{EA*qseUf4{#mRPF+pyL`IgdoQ3uXkn|8jk3@lhF8oOIYc{qu_)Lc+48AGCkgng{& zIr4f2w6*}M9}6%v3zY@{vAM|EyqO6YxG;PJxc3KC?gsALds*A0hQ)aJyj!v~8}fH} zgmwkLL`s~vpr5k$T|!$9^aeQz+Af{*MLLLGBnR^8nu*guOZ0`y*A#4+4eDAk9-Qf_ zZbP3TGD~)%NfuPNrLFIqeVQA5U|Z?PfS{cOOk0AwgZr-OOa#c z17myTW0m^~JQHKpiG^mdS#{*&bzI~1QsWImikgU_nkQq;knu^l@m8*aTCMT+f$@%g zarE%8tyBMTHYGNQ!v=vb){AzsIe(cz;qH`c=)eiAjyRbZLMf|F; zbRz8p)r1C{QXO`PnA$`;6HrM~6F+8*mz!A$adVq#z;G3B|!lD$+2n<^+n?5w0`51QYuj&7DO_hUiz z4NiPvCQ8Fb8JTZF1Dd|JqCk)asG0w3DoR4=(k_$bB^XL=}T@$|2R2}_m0d*H?9IqYHl15yyx05I* z@-HVGbzlfQbI2akIPG6G5J|8kJ{*cR@E}o*PFwBhweK25k_3pPzkt_)o>|+faxpuHI3V#Vr;DxSG%+Yhjok07L6@XaM+}Fm z4LMAl6I;<};8Ip#Run@AjiRe_VGUw?BL@dya8qlm*w0!j znZPKWWHY3(xWqZ3^3AeUYeI$^Th~!*PI7`viu$9A6xUZbT>Y#*{fpGy^SL_WV0vnZ zrShZ|x5_+FUAA(;Q>xWVi_gxI+-GAc7$of@~;BX>ot3XGe#8=o(^k~1V3b#_2DQRNC$mDRq2CMTgQZt~a(DM8t}$pW&&f@d4=RQQ%wGnqRYk9r zPPP|VCKX!Zwhye;GZPVj6soNZk9`1HFzYQJ@M@(D8>|$Y?bkcplRG2QkXrB8JLcDW zj61ujH@x!J+XmO#xp8`}Hs%>Oh8^(gr8oAq*8kXSjNgy>mnx4m3d!EjjY=zZuWY0b zY|PyYZTbexHsXwLeBAn@j<=??*^V~zsx;cP2^v$j{4hF6wD_8xs9Mn+Nt&bkb8|bdY1qh?C4W=qZ=U{G>`OfE_og8{>BB zB||UX>es8qVlbPkiL~lPZ1p{H=0nu#2gr04XV0^n9!0I{^@b=?CMmKJ+nZZWN6YNL zJ-K)$wZ8&0c))Ow!wkaWYF*k4a_0=Va=Bg$_}O@B76_CAtYApj-yBRmQ?dsmnqE6d z68oyZgwKA?Qy1!-rH)1?@iUg-UcRpFyYQ;Zv*{yeo~CfupBIyLYeXY{sHGV+lewSy z=B~y#sKI=o!4N%%kPBdw=4G1@$ETLGcVENBHR54zQU`0d;*SVOOW)XYQOoF~`f`b$ zONvHYbRaHJi+oBR)Z^pPI#gbm8TfQwq$_u?uhjUqkTYm3-J+q;k)`TTpk-*zMZGsJ zy!eGW&aM&7%FaTUd)L)nSEx`srO|>?+X8lOkXSm3abLK5;x!KK_T z?;+zi63f{JUEeINTy7nIW+J9RGcym%_FJ8xr0pQS!y&&E|HM(H7gLQs{zq!L@DC#q z2UMoUBT*r&Vf!m=wyS?&S5fyTvfHQqk_GOq4q!8}V6qN_rzSobw7qhVT1m(&*6J@0 ztfF|REuXI%$ynB78=y7n&-=>T8MGHU2x8I~c6+f{Of{as$60p+j2jl$G9FGUu-CQ7 z*RA3Za!mJhDcIcv1GtF%6>SD{@DIqR7J!es-LwmIvVvYVAYZS_c5na4*g>?EAD^$0i4 z4>&H#-SmQ;Z0kC!WFh35Ijhlu;LU!Kwt>i)K{yfLmF8yGTQ<~648Gexc|WTwJYY-o zpYlIL!kr1`( zPBs=zLPs9GPK!o#2}%@swksO#w@ahSgs9!;Q%YOS+VgmDv}-?yI4ItC6Xjs;wJ3PiHpI{ioo4+35js3dcQ} z-w1ra;|<{X^{&ac15D`PsptTrF>r^Zh`T>(@zp>d_}uhu0HUUM!D1hjXvmd|rFACr z2!9-?4b7WHNK>r27*Qh|E?mD2-F3NIbp%>zzU4q^mrwOf@0pKI*F*2Mem&|udcr+k z*lP1y3N^7~T7)0FW2#N&$$vca>jgdottQ_KL( zQs7{F9_&B6eaRgD;dQ3te&|wpha7Lc&F85)U9Il92erWYD%zLxD<@FQeMIKUC+B9o z%6{{QdsV1Aa<}~^yq<@SwKtPq2&-f0Tkt+%fXcCZU_da>cYyZDQ_vF}i5K9<@{?YR zD>xNGA@?n58KbDPF!je}@Wc_+;n1J7=sQnzUYDe{cac(17dO23 z>#1BsSHj05qEut2?lk>ZDkvxP3Z!~J`Q~&rx$NMt`x21y)vwuZQU*8$&yw0f6WaJ0 zlkj)>+r22hPtfs81cFcPvKMby?f%z?K(7!q#BVLM{(hf6Y35z*o1SIkCWXAYYnKG< ze1F(|c-g4-3)Bl`zPc62eG2M%+GPEAb@?p@=ZlBD-GS`)D*tCS7k_f+Tk4j;SrHJ% zamf0cci@a)5FI@GamYCWq8b`0Hsz<2Kz3#X1P=S-EAjy-Cap$=%{9eP6d~`|^W$sE zkyr}ZcqZE$s%7aG7mSMrC-=~wSCO$@$w!vsRqOlnoB z4Ou}d6rVfaAO6Fm40MW1Yf^2MzzR;2k+a|*%-O-sQFGGfiteB~8s^{PU$tH?b|=F* z-5c+5KBk_^wp!2Mm>lX_AwGz}oozlx<){Ip;xjm!58aQ>it zVwr@hY)dVrFELt_`~im-ISLc>j2WB6(&a!)Z@KDQ3hU3DX;yo z`ZG`VspuO(fH!?GaGuM#>oeIW=i+&4-!IIlq7zZ}=dHT6K4=ydYpg{wOb_0rqr$wK?(2TM zTi?z)d4Ku+`OCW+2JgSEqbSF9tU`J(>#g3ZroN98P=9Gcgjz9##p@fz#u zF?LS7$Oz+@-q%P%ontd7$bA~UU zB#*ke-=;}--o8mk8l>LC5#N)Q3<5n(<~Qf12I()2pz537@K=_Cp{64j>f~<{a1{&5 z?4eZUzH_S+4-#~J81Xd_$^kIj$P6eo5e%-sHj`Sy=1LVdv*Lc89k+xMnU+k1Qpj)0 z?kD}^We)e#WB8PmeAfmgt99i+8;RASkqo^ zAeIY);?TonlM5B*X;Btih+UDXnVJ+#EeV0><)c5_!`#iRF+4@G1@vP7hJnX#$sN() zt_F81sBb9Ijmm4(#Z$lH({Pr`=U=EYp}tU=sbEuDg%89R3sEy@>bEG@)g@U6YT!+O zmFW|LPi!hg0&C}w8Q;{U(6~{v1=B0F-W?=26N6QKODC*2G@bi>X-K&W=#>|^>eH7x zis^oqPC9(8Pg;4U;rq5a=@MU``No7yD=;rF?^Np zHxsC(MMY^fA}`ON7I{3MgQk2UxlJ&aTE<1eSp*d{_nwV(Z1^cMS!_<|Js+3oMn->s zOhw3`6^q)K!{XPY{umyYNr*$CE`1`Md>R+Wut=`OeWKDY(3BI;ofk!ZEbq=R^HT@s zCy&DynTR#?$|3EXFAgWV>~q@HP23c^Nl*iKLXF0Vq%14p3Sm6Svu=%sX4wFdL)61Zh?R^Q}5qbRBj#Pej495BiO1?PLcm&((u=oJ_U4NB*lD8Bt= z`f`MvydHs@Q}p+Ommp$20QHg59>k;<{zboeO{+P*QqIhEef=a9*s@ef<6d9Bd7*LJ zwsk@6+0STl?cdzdPR!~(&uDO4_n3I<$Lj01zV)oa(e=>z=EQqaZi>0v-2Kn*&>ya% z^I+ky8=t-=5UXN4k^!}s(Hu+KmoozB{?*o!U}}dgp6UG>jvUp54Js+5G8i)Gk4pc8 zo~|Mux%-3?AfcYdcaEOu2TjD1FMzsMSm1_$ML01((ksRl#OIA#32)@R;LpJ$BAmhS zz9itY=GW_av%B#X)Ey1n0XXO*5*tUH2k<{duz@W(3%Nki<1_mt^{tcD{6_Sl_jD9z z&|sco3R#(-Rp4eXYrm?S!+#UZqHqQj1;j}GNE*PPi&3Br|| zun1*=!%XAKF-l6Dtf2JoxK$jHqEHfOVs*cY|6S-$^13R8`L?BR{KUm4uct$4Qq$AB z^;qJcPx;ODXEbOUYIwieuz%Kbsq(m&BpkMtUvFDm%8q>Oq3wdks#0bb=i%Jyaym(u zyX$8oRukV?g_71|NU1w@l@;}h(y^Zba+Q}W*`3|iN;^Y5MYxUm7 z*2x-wS60?(16Bq9MXX#Jj^AV05Khi_Tougu`M+@$Otu>44{e^TFCvA;6cwhN<+j}a zsbbf-2)+BN_bT>(a8-cE_y3QtGOhBEEAh~K&tup5{V!q_$QK&LAD_hhBa1sVUMW7( zH=;l`t39|N5%&T)*jhpTz>} zwJPUdbzjdK9p7`BHPzF&)mO1P*myq?dpKQqxb*YA zy8UPUKLD%Yf2!MaBeVYjSjz{?Bm0LFXK()lu(o@)ju(f{H)i&RcTQJMu6|wq|7BRG zx6gOy?%Kqggc`R^Du<-hU&j$xA^ z==>*!&1n}(^j|UTTtU?>rM8BX`4UYc)XD#fVH?YqXa9E$yT!EcJ%;URx!U^Q28-|W zuaN{sT9gi}kBIDxggGjmZTH*b^>)8Z8u=BEm-{1kKdN?dJ>DLF^ATkhhw;jX4Qcw! z-|hV8<-k4Y&El;X@^Vd0ou&E8?EcYLpy=mzP)=ovL7*ha2HXF6R?6HB2N{$Hi}{Hs z*XrZcz`McvcVHGug6VD^%H}Xap+%3n7#7L8rnMW*m+t;a@nTkP)s^Y*_0Gqc4~T&V zBwa^XA@?w)05yd&EwY5WYpTFVm9aacK!sh|{RE-Ov zT7S6#X6Q-7_p-HIGe-NcJ-(9zL%<}Wc#h6d1FpL5OK+fv0qu7@*o^sx);XK%4xpgy zZ&j|Ma+jZHYq*!8_8J{jVI1nuY~32QNG>@s54J}EFq982n(XaVbs3MCjddejf{oYH z)E*s9;~_`_X9*p+bk%OJpq9Fjr6CAg6VK5=Wo^vOX{92ZN@qenPie^2pv&C=j8KsUR$4WxxoYJnYQ>cI&53-Yj(O z2DJcW{o}s%*H3i3_WA12CtR^(DX0(K#0P0|sn%3=Iy-v{qdq-+a(K#U1`KJV;t|;j zy-R*ta2#DaKA5FK4P{(y6d8vNISD|C!r(%V7nFyo8oNtvsuh45+JlKdbwyn|QwYWh zKn7WUO<=g*r`4@fpdO=2U?h+PORmbNZ8&4;gMnmBVlv5k01S3=3Xt~+rj#C87y|+1 zjSVd?fVXTQEkKM$C6ge*rcMg_DQc8~yH%OM|0XfB!b&Nq_TYbsRWUqAcob1Ihe5KS)Ch> zC>syvsof3XQCDHs$-_o|g3w}bhsUu?;ndhN7X*RapGnkO8wO5Hw`IT(G(WWT| z*B(h$7jtbPeyO2A%mL45c2E&WiGA-d>ZF;rp2hU^lj&Pckh{-hOW%I<&LWaN=ebc? z)nf}8?il*(N&Fel%D|Gg*r&lin5grX=pX&9y@w5TQibxUWsO~+JNgN4CSANk`jt$| zEPs;!+^~0NQ(M~MY=dIGcZz61GHmDsU?w;A#^@-Aa8Hf-Mg^}vq3F?+azSN+YN-(( zavDoGaVgaHl@>hzF(RuA$jKQ|}9+T8+>#9+7>vF4%+$S1qATZsw&ZZN# zjXHI*BCZH(nPPce$ndQcHn|s+WW-U3Jkv+lhHu5*UD*6&G>X^#Jg@z)DM#UTuArt5HrRac+wh3=Lyx&_q?~uuJ&7Luv0d_};=k z3CIklU~L`KeRIr6aAG@nPs`z!iQT5JzaDCjz}mmhre?Da9$-VBmFog-^M4tkh`hJ3 z!(i`_kT+>$V(8hTOhA81eNOa#SsJ)y+}KB%WK|w?7%6wmUTt#Z$p8r zpq^BE+eKi(Iw)Vh9c~qcO(UpR^vS#>IO*INK`@pwTtELC$ZYAJB~J{r&Ef;9*#gqo zID&LEVBf^F0$`m#b}KBrg%SNG&&3+{QOy46S0rMXiR{${o7{$Fu%!oMvy54{;LA|! zxqJsyolyn0V2*l9jSl;!4hMJ+tFl2n;h!*HhQC9t{0^uPkHY*W6LqQ8V6PYa7vGuhk=9$7RIQsba&FjZXc$*s;H@r{edjwm z&YN!B(kI6fKv|ggDFWgN0+#%7sH#o)K7xt-2xhQsFynPN3p-?c(3_49tK>L{7C&N| zE8>s}vFvl0Yia}sVn`!-$SgbU$9Ny6*$`trkTDe0tA=cV4lY!4=V90N)(d15_iQMH za$ZN|%0)QqdR5Rx{=|<|OvScoR&YarO2(<;r5elbEB`ADJJSmYYr$PQ_C2)5N~en~ z3G<%3hcJ7EGhTaS4@Yz2N0i}Xk(OYFe~v(uR|}Jk+**nF)e^bd66`D&D`6hi4)vqy zap_3K@1o;oq=@>#Lr@Co7w2~tRG@jpH@v60939f1k~zD9E2 zjNhLJT_`L0cjmZ6v%!Q(h~L5IaHq6LxmCjPYP1&H}UI`>ZcA#EH}p!dqL zpS4@8-l_@esyY5>s*_iWdJAscPeAZ0cpM$9i2&A7N9Ib=$Psg8BUj{XxJN>Jk{`uO z+Cy|efnr4w_`^MiO53Q3r9zbXup|oMPWgWLHD^zGejiy@C>hG(s7*tabD2X7c)1T? z#E1^0!VkENxOgY^;`bbWgTSB?e!`L!9Y@VX~`UxS8FKo+ite2=2P7~ zitV<}WX$uIe)8i93?5F($L{eK`j#_5pH&=}BCP%`=`+z}sj$c@wyIffe{HC{u!WO8|=3iWIi(lFgoBP8;b82K-@Owzzi@Z7htDW z>M&N~r1mo_g8gA0#Zawez@TEtyJ8?6)Ol4-(pnx__EQWUu3ZeQ5(|SoQ%n$mQr!aw zL`NDxhhJ*LbYLjkCj`*4l_n{GCDlqN%BUafi$(~mZv?8P+CUd=ZX>bP&!-hG5#X{O zn3kGqBr>G-^lCF_*ylAQf*O>U^y+eS*mgFsv>DR#8nO^s8ADIahxS_H^;*(DwPZwf z6oPeBhIKSPb#&`Bs>9ghH9isQ71=Z3tvC5Wo)Bd+eZZvqVej`0I-u<6$~37 zMy+N90M8LygVJ8>d<8plRRjKmETx9{Tn5h&Tc?-NXz)(3)*ETs>tuI8#fx=h2iQa} zm@*J4?bs+I!g@|aw?RGE37d*`S)9I_coR7sQ#H`{@GKw3YFozQ+(tRZS_6i-dO<@G z;j`jMZRc}262=t1Y4vBq;Y{LV=b(Q^tvSRDV8yi@j3~9s}o{O#Zd98I@u$JV=#h^`~7VHoB zKHS_CwJ(=eY#V}&1w&`If$dNnYFy8y@~seHM+DYlcXvN)9+JaxT5s06M(QDZf5fU= z7w0<>ICH4T5Wl(aC#YxXW6FLk#I$=gym!x@mCWbWbq~&7l0;69fwZVBc3UiOrDWGCJ2$S}6ih25NwDHPzC&h}s!2=NW?r z9fNvjUHoy%IWta6wg%k3{RRuRu~JAu(R_Qj}Pvz|$GurZlOK}fHuSzmEY6q@cxU3s4gSvFg( zDTBGBWu|RTu?BLF1|xpXh7H(w}kQ*-_O9E=FOkiFSjWgX$;AhPeb`F|EVXbOSE*cFnsw2}rkG&XTdGJ`r zzmF=}O=;-3RlO0pc(lhG(oOsNR*ciloPno1j(wVdYjx3l3lw z<<^HPnw4f+8EE-JP{why$ceHR4LTPM*JpXzCmCFjqOr4=GbhEeCb?mp8Fq%sh_KG= zrwW|=y6s%6{>*0)r&@-E)DnTO6o!q=+~|tt>5b$Hq>)2}FOb&wml>k^ zd{#Sp+cC+7tyXQV)F(0hONW+pJ9L#vjfB?Hut+Z z7rSRXu$(^380g__os6KJgLGg*}D_(P97Og4^gpFx-N^ePWrkq&B2;h(U-Op*p3sJn-!R{AafSt zgmDm-6t*K$iuDqzO`ow1oU*^3{4{y?eUycqijk~cJ zs~;>tIDzQ5g5pxVIS&Hlht2&$DZAVZv)~ai`kY0~o~to3zxy?#MHVI(HPL4x=6jv! zdncB;BjY(ma`P5y2l)d8+HQ+cH*DfG^MwIjJ#KsbAK3O40M|=RRUB>J-V4^HN0B(Y zv1Gql7HkgIF={xvQdsQbVBWS_uwTug>_P|m=965`Bvo`g)9f9y`18`+M6&2T4D}MZ zba$NPl4|HuqcHZn{i^=8{xJSckQT%V#*sO0hzDo};Z3MKQD||U z|2G7S5c^0n9}y2%I$g_lP82rS9A?$3kTi%={HuPb*04Bh^nG zy=uixWGTy?3k@-8<`EJ;Xi$)tJJRmr_;R%ovVZt*lKo}p*%nu%WE?>cvi%W}2^o(l z=h(TSw99`aEl=j=`T028MK!I*CNpwKz)7A!G86+Ihf3m&G8qcxOZIrOp0Cd*Y`z= z_ibr9+w{%<-`~gYmsKJ#2vjvPJyu+5-v}W(wm=1-wotcVwc~a8^5TL;#4MSq?$!3AIns)8%?~S z#21PUQkFvGAD~Q4-pa4&5V$11?GeXtbD==+Wjw{wK>eyo#y721uc63nnb2QM))+BT zAG;+aCIWxiWqS>b=%iY+cP2H$WFVnwQnPz>ODha!TNb#GB)scu!qgm=L{I`Zh z%pl7=V#;-aE=UMNjtV5AVOFFn;u3)(2Ioho=JatdIaf6jnOl1bJC&KWV*{CLv)>xa z!MH=|?3@hc0eggPm6!_J>BhM>pbyc&U@WaoO^d2?MquD=@H>i+>764bg~EEGttss; zag9Hrw=5}tG4@4h<28-InL*hP)u$MdmNCXILE8j>RZQmpGJ8+qs@SVTW`h%(Y+&bu zDq|QpL4v4Xl!B_T3a|NhA2To!tEA9A(x*XK3o3!1M;=SKj3zWhvrwr4TC3O>yV3em zFTR2r&EA40Vd)qs#PVU!_d;fs*%TWeuat)mqa?bJhrInfY|BDb1SIn|6?MJRg95x6 zUF>f+P2{a7CKna-vsnrRpZ-Rh4bMj;$n@NV=&3{|7{HXJ7?#>pAmoE=iPH`{A2TvV zV)X+LGdsM9%rfz>&C6GlJ>$Lkr=D#4*;ay@E$G zXf8P$oVO=L{o}Oe06s;L>v`PHY+}9?EypamT%sH&poBA;O%3J?7zuVW74rjwm}fhs z1w*uz4A9|}UOi1gJM&fyLKo$Ws86ad1I2YNwfcr~JB2!E(K)?u#p+j!xAub{-_0D2 zeH-QD$RTW+AuibHXuK$hk5aiATa)aJfdU=l6X8P3wDE>g@sLVr?Ai<_ee0~L1k-4D z@QOkL|DLvs!t>bvKpnp>O!C>=K#4+7S$I;VgpGvlLjMa}gWnI$W24`aIYBzu$_UXm zGTiSQNz!#9XlutYOagNZ=3Ire(zXiPgcR{jcXBkwwn|n4n(67oMZA+3N_K6U*$)dp z(FbhRR14>Ga2HEtwM*2Jyvg$wY&7IT-UZf+)-cmz*)9 zZi(toCS<*CSGrQ%kV^QVG}saw=|Vn+NF%>-?fdkcimA_DrN{Sh|xxUrulr!(bi z3fO~9nmPwN%BSc2#6h``w^tcuuN8NnhTK)6tEfHo@+UE|c;Z4-d5Z*T=(U#VRiKh}#+x0XkhIqv) zu$rYu@i%PBWs$d)Q#}Zv2mXeeZbeaKHGYo&5N|kWrzV)=8*yln`Z#B0?5HFdQD>u) zwn;y^wFb6_g>~oQRed=uBo+_|eH$tyZ>1)HGcHLVr zw0}CB?f#HV7R6P zy#Zu%LF$`9J2F+&-@i_YKA77#kOwb0$Gs%sv^0C<{a&w)BD=8C){UUyp_mN3$oUCF zbU4pgCYq5nbw+~Qxo^rsEG(|jGs!(3!BE#bteC%KH&b4733TW-5dbua9!4VPQMs); zdRuxcg-giTVe2;T#|vq+CfOg;l;#juK6Bv&*{N?;?BYf%)-onuEKsSBq%M3sBy$hs z!Cu#%{x+Q&`V)(xAhek9_<`W7;&7R7N9r|*D=Ow} zlaEL=qf`xs(Z$va(--gVBDGj~*KlQm{y%wC$JrPC3%$~+3&gd>(_soQzw)3lk1 z#n7c0&GKzu<>)w%8Tl06zSg42@<5Hki4WL@>FXC14Eh!iswLpPo9?VE7fw?z(^px@ zP{169316)vT)F6iizyu(YD{<@(^KRtU-Mf@oU-8;Q3Z(jK^#($Ois(=ph*F=UA>Kg zdGevIeM9&ku_oLb+t`msgD}V>P*3Ad69gYA*R1T?BTzoKu-D4skBi1;KLwHlbh%9t z&o(^jD)(WZt^2OWlC7-&0IX`YZnXaZEC(&G!FPZqY9+%#`jL7l46!<4*!Pfez37^_ zAO43~C_1q^sdlayOf4A^ zD@<<%>KhCoK>9S@jLGz$VBSaJZ!2POphOdxVKP`sASS};aF=jB?~EzYMd>oGPOPvr zQy4bU!_W}&cC7Fi@e8`?*vn~M?s$cv&@V)CAQ@mm6rLRs00V^?6@(|21Ck;F&|5&% zhyf@ykT9klkWwVmoBGM1<`en?GaVM~>JLJIGn)Uc;YK9mnTbD7`StMcVof>)6R`h<^Oux`Fa zo!pR~MO1Z&2|!k=ejxP~p%dieS0}Ku_9-N3xe#D-AwL>K7^DV|##aaCR$~Fv|7eKE zzRj>Et0Pat3D0T<%p?SgaKX*rc7V4*7TYke&>jx9&cG|7H`jsp(`4-)z=x<1AXE(P zRSW~W7kU;8qgfZi$yZ>@0oqFsd*X1#%20=E*wiG_btP)wp+wyyBBqq^#bQ6d$#5}5 z#?}P%!zAGtX5RPKU&Utn5Fv`Va!!n9gV$>XdJDsz*aH#kief=Xu>gQGz!Dv5Wzj^H zkR>ZvqwZVh4J$7E4vp19P`5#b?4iUpz-bGhAvqj&4UYCmfF+{19$la%A3Wnsh&5X% zQ2@l+44zX=N?B?IqBRm?ITGqN5(XK8CXR$-LqqqaesYL2?NNL%AiLUb(OeNiRMSMp zG8}wqKy~nK+T$}KUdQ)1jhZ19M#A~?0Io{eVS`hj2O(s8pR+0!&-#Ng* zCR8L94n)@yXvP)2(eOhE5rIP1heLMO4xZmjYB>WaoG43JGVB8u=MM<9o{{yXQUrAb zNcF%drj9hZjlTn|mc;R}3c1jZ5u{NrrZXOuKe@M04Y6SEWPnVOSe~>2xmkaWh((T$ zV$4?}s3tg4AB$^fL|mIuaN4=m5}U$pzUBhGX@(y9DT9_)08zh&z)(MnQJ`+urKvND zhwW`H3%x=?wnd?aX?Xfn|#S_iQW-f%9%}?tEV!CoLg})xAwZ&xN+#wQUn$x%mlh|4ni1 zrCz|lj1S{4$4H(1q4)&`6dl(JehT3j^#prtDJN#^t+YZ`^K02hzA&asn+o<1D*SFS}&T z!Q?HuY3o{OFDaj^IfUreFfM;9TK4{{!zmu?zPRkCyy)Su=$VCa6uBJumW1x~7lwX$FBA3;(zNaBooP8NZ7hf_@x>1!;deXTMzPgNwpkcbDB$X)>eeGTc7Fv>uLqof zgU*&BcY16PbY9l+^#TGV+`d7b%t&1$gO*rnG(l0Oj=_gf>3AmMz7uI2%|Wxwj~TB& zJ{1yY*`paisIs*pC|{NsZH%3Y43h741m55ENdrhy!1^G>1q9mVHghh5OWPc(#YrxC z9{4=JW&20g_j+Q3$ z5uv?)wx|Y1e8}LAGl5DehiMy*CIl#=pOFMmY6(th+(yE|)lCA0q>z}j8;s2{BIO|LR)Z88=tDqf-S1OfV9f zj`^Y(6~q{???seqU&^WebRMGlr$a{rLV(w;EHX$M+*SNxjL5gm@UZk@ih_4bj_;Mi zBz%%f#|mm}fz2cS*LUw-I9hw-li=XI! zf3gYd;xMZV3<<}S8^&3v`|!k2EL!-)srTlpC;ut7Mm9?AH*Z7QY^$Up8|2^aAI!Rq zqI|0~4}_myve}Pt(O?_cSXnVD)&yt-Y^G=Jf_?y2EB9ke^uH|ayBxrwBp;^XY^hDr z#;(v-SbVN@{ai(4?z&`aEB!eL)FI6rBOQ%~S-X~Byd37WaJO<&B(s$LaMBjsj?}tH z#(r9cyBx)hUcB_h#QpT=!ztU2PC4$GXH`rkkDboNX|>MTXW_FZ+=T{{vlf>48r-uo z8oL+gvyLUTmgKW8`1m$ly9yTcP8xfZ1G_tCy>6ZJOTJYI=sej$FWWt;ulRi5vK_B? zg-;z{0HZvVM>Y1K8BYl<-k2$&(lT+;8iae660INCwYp1diBPL zUf^zVmck zD5WiIqpcQ)Eq=RRZ+|25B8$$&yuk}Y=;}sZFdnUO{T60lKXc!J@kc6qqkKJyN~lps zmeEj|QBguw6e%quaruS~Db`k?WqpY<=0 zNd~nE(l%VuK`<|bXWwsKpaU0Ii25Sg1uAsj+Oh>(PV#>-cb9E(Hf_SLad*0LcXzh{ zjk`MpcPF?6cXtTxZoxxvcXxLUu0dYzXJ(#vX02J@*SG!w*H&9qSDpKzyuNvRyczUl zAcFE$m2O{rko#6}9|_UEUHfZ6-hhBAvM^5llPjXZowzgZ%^%yWnT;)+v#mQqR4{Xi z77{}T%8f&64SN;C?L@zAf$(kmPxQRn5b&rWgmY32JYcvnJcl+S#QrdH&bj`=toFws zHJaj}l)~gd#35cz`8j2a($CS5$&v_p3g*#-Y{}>~=8mZNCyC!Usm3lDRy=vE<&!U~ zl%_wwl{vfSc2J5jUGr}8YDjBw>hQ>&YijG3 z%8mXG-)Q_#w- z*4#9$3KZ9S`Is%~ zQy6ItpK;pd_ga8u3z6?*)bjc{f^B=YIQez?S5DkC>cb54+tL>QBJ8)Nu(#DO@rF;q z%+qfhM{k>tZ(Fc_TaQq$__iy#POB|%``BoTaPNoi??+1?zRQ!=dudMlapzN-@8?Ut zg2#}8{_mF`?`MxFr?u~Ws0rhpzb6itCquttD8Jra{kFo>et_jq+<5=90s8~ee1;6Nso2r7w?QFYz{{NW3vOT$>98ag=pY>TT zrJBs*<9}cI+|x|wiMqazwn_KoWcr7)*`40eDttjG60KgnvQ(+mX>s>4@C@Iljc49; zntlNxhh0+m`4nD<9ulJz2mmLTLv0UWph6INUoK>Uhz#ZtKFJ z@5j?rbE-v}$4g6On5BmdXMl)4gudZKF}6REMKe(~FRK#yIZK1|wdUiA(rEpS#V}`< z(dY<`T4vBV%NOH`9exAV92;okzmi;Bh!Ob^io>ImX}HZ(%HLR(=lB^UmM1YIFhr>0 zXK~CAS}W`-&pFjbly>_nEVQku2JC;1Vd+KCW&#Bv|D7D5QxFKWl5%oG$zvbMj_Rn-sj?8S?6Qe{Kbb)!jE??ed#M_e+~Z z6WlG^6(>e$LcV4d?}T7}bW)ZV1DWP60}&=xb|kvR7UOG*GG(r6@t^b4Kn;AaEdA(H z^U21CFb76GD1=qQw1rUYEHR^e!BxZf)hk6wN;z%7HkkuJamKP2^{qEY$%=CQ5Cjdi z(w+VYlO~puaLv!Qfer?>2&Pqyj@!{6%)w8CW0t>FFK14ua`_r<1_d5guZK{pM-%$Z ze)v9A0d#FEO_23fR;ZJ#*69s$??#nJK!m((^4xoN>ZwhMe=~n}fKMEy9n5q*fIuvT zRa?;@aSu(#qi>C%u&&UyUK3Wk#o%b6)l}V#3QA6G1F2CXn;x(;u61Yc3#ASBpR07M zZD*aoWE*8VRTaN{7^5e|77GFBu#sF$SFP6FC>U=0D%zCq%HALZZ`GfxfNfZ>OSupM zwkP;cyB{#RWA(_rKMp+Jv6HPPEx0pLwiK8JRkJMK{d_;rEuN=WT|2Mm_XS>EP`x{n za()GyF(9*{1>*JRL5~!FQ*xQ_U?_@*T!3bGM;yEoQWg*-KxH4C7op%o1}L;-x}uy8 zYnjOhSnWoTI@d>8!OtM2&X8$t_{oBVBmpU4beTH^=OXN1X{hRUCL$9Rd;RNYd<#pl0 z*=#ByjsjiJV>Y~Hv}PXUoGdRqVuqCb1TQY+;#bTHj?-ZSrU(`+tRLiEk)GfgUTNGjEocJT-evou_cNYBCh4C$` zlviFJ-QV~H?UbO&6JZ&jt8FgxZ9ddr2Vx3TB9nCAe_pO#;GfE2Yrj!bPR(yA(ivnAXEv}P-ricj7AyjRV&RL8qgo*zFj^sn%&sby5bItW5i zo5e;MlMzl#$SvDPgsKA}l)>0um7-GoiU2u|`Pgcwit}83u5e7^>{#d1nP`1jwZH2i zjBQl$cE8#1uPzMw-SCwNGq(bxmA%tf-l5Mt%t$O+H&IiDZdxoIETvN;t`kw&;{Y2&p9aQ8D*Y+ty+0!69Mb z;fxV@h9Dz}Ad%o0(`WMpKxnZ-=<%51*t!kV5q-WZ^2o!$@hc3q_$wCeyKMON7H1eM zi8~S9taX#~X0-LOD(xEfH>Z8BYX$~y_&(AAzxOwVyU33u5g$xC(ZXwqXsVOa4(?7_ zx1;$#>U>QCXo0Uy)1oZUhTz;tI6S*-)|5!*3`gS0n16;d*Q$UV9}*oGcUWa-VYlZZ=Pfrj%YZPa$F z15qSeF4{v)1cQBIYb21+NQLm;2H@FW10eZXNWh5GL(m}%{iSS!apXOMAr|YLp-p$e zXodY7wCllTImCbjdAH4l%XVRMKO=e|Nv|11MZ-Qw6g|Z`>E540<>zQBz4F=&Zb$h5 z%AjKJt*Dsi3LTo(+fXj>qKKDe?9XrnKqhNj$8BG{RCl12(tEEU2b$`s5vYT*#)^h8LEcPikG zXq6DtRfqg*E35sEqA<=5K}g%XKmihAig5JMZGNZ;+V6f~+vD&u$DO3vtzh%o31HG< z`lp=0Z;yS<@BIsP^9?8YfS7W>rVft%rX>WnUE=Q>)cCjxLj$iZwSS+2cA%~=#bC|@ zUkA46g1ecJKEg5-015&Kj1Vp@~`sx^@679F&J*Z6E=wy(nWcjbW zTgWfD=y<&!Mqgj8a-k$h2^aGTH;n+1Buoj0SP%Kc@1*3uJAc}YsL}i(67%shjZnF^ zaR#?oC<35zz>(pM38=bBH;IYN3#jbLsB@B6!N_Pr3)t^_vD5-+bI9mQ3g~Lc=$pyt z%te@`Vo7RNC{*y_;PUVt{VC74$@u!VAtJ$;(E2dMASlWDGM|Ys>x`(G$l19H0c_$6 z5d|Cy=tRr@+ z4lZ7 z`n#0K3m=PRyX%$xQP1*5BWoXnb?q6S|!^u z1*Kz&@sY5}vhW-tsbzU;#y-lrW4b|0@kYyViBj5COQ4>1A4gy6bCIIo`pG>YgAhlI z;DfeU!%cqKV_|rGD@RNce4?Ht3wxoOnw)jkjX}rCY+q5Gtg-l+}@th zRX@HRVYORiXai;w-du)711XzRP#;OzP_iq7K%LKJlV4CgAP6%^Ya?WrRp7N=7eYWA zz3$;gKO9;GYkZ2NuMZca1P`9Pgsg5g95<4#KGweG)_A^Rq^JqVQEessKAr77{-OUg zPxt~*$`7Wk<_g&wKz)NE8s~%FS)h|A$gzPyYlMn)Xf&_5KcADyv9lMGU>!FN7F&-$ zkSxlfW?43;ta3!4qZ=%uh6Bm6QA-W)$NB`D$8SpW;+&QfoiPTT^%ww#i7v_`^&%N| zu`9sZRV8I_4=Hi<_msqve8qldvLY4nbg-rwRZ}a3h^~JnM~YVm$&wpo_=Rc>J;~(wKmxl;Rdy`LJ-hOAE!`{ zHO$Hqmq^O{2ffNV;sab4(-NWylCg8~$rLmR=YREL2_rca;Gy{vZGRaty1F>){ z9=Q6UO95hVvn8A^X=$h(`$>=5ef%%M}f zxuKvKCTvv$%DzLa9T3hU0C?m?b>z%tQHN1M8`x`ZgjK_FB@QNQX%r0ckvGbgh1C;I zo$#lQirEBpF5GK#vGo+o9Bw4On_6tR6r$U@Y>~Pwg$`daBD>M1t^3ChgfJH;1^;)P z9-t-n0hHTCzZ;{ayWmL7igX9pK+e3)6Icw}o>(XrLYDJvEf!sPY8`E2SwsVkgXnT( z#RYArWwgdELawosaWw6Nq{tX}dxUy}7fQvD;%Rr(Va+~0Zs+1L7)G6KE zk!oE!)2~WQO;!zc#ESZg?~80|$+U6#R=>+>4eM#yj}*m9E7YfHIoHbJ_h>gD`f?u1 zxqp!5xg}5`o3mML^JKm04kAvi|SZhdP` z%B{=kG1o&>)GL`JIv;MwMy=_wFQ&BQYF6>RhS^~G2fX2{I6qjMvFKR{&ZKm09Z*hb zMYW>X;KiQsWFtaklyNkvD7%AAg7)*>-I%2az?2Ne@cE()Zw1!C#td(Vt6wv0&jjm;OOU%fLX+Zxw4P zHgqx|3mY+H?yNucfU$aKoNl{_i@KCCJsRtT@vCYwdP9+#^=;mEb)#wy?_sWUW9q^7 z8SG-0c5~YAGQjrrPlIXp{O~^v3jv@%S4ALV^E-^rB*#y~coG%cejB(j9Ke3~Tb3`%+*T(EQ z4+P&%<7YTrI0qlNK?k{e1R)LtNw$XDKp*SOurep!8@GP8=O4UUqjdA^;##BKYtAcL zHP~vgJ6mHF4Wp-8<32nHFIwY=zQ#eeB@lZ8klW&A!IHS!lD_aJX_6)?@}_*i79^hW zBwMs4$$F-^x1|luq?oj&+VG}*Z_CK_#0+_kisQ{t)yLX^$Q*i3sBDY+>6x0=2H*P} zf7}MTdd7c#CIxTL`oPHcZp{Yq<}AhMjZGK0LuGNlTnh6k9X}U<+KayQ7oR~D(+d~d zh?k&x(E`1~zVJ%MxBnPI&;8!6Ue=CT?Ug^?a#s5+XD_*+BR|c6>#?DjlMXZ)v zES%k|a)^%t{jY*vdlCL$RT}Ra&}PSXx5}meSJdB-guk}L?X{J^en0-|V%dZ0O#78R zCsz0ItB1HF5cZYo>{l|jK<}51R(b(>b^%Eqf&Q-@S+cKksshBu9YY@$9fQoT-R{8y z-#bR!J%?@BhWIhQ40?{`3XBi=RChD)1@G&Rk5Cbadw|4^9K_#ILcICh{A{#hEG0Q25zRBzS*(jyJRd$c zf>Av98H|gw-p|Lh{u1X$a>mBvuAmJ!@03;Pi)dx6*)V9OMNCqyLU41J1(1`-Z_7hVOY0NzFflOs%qY9txc$4N%q5fhSyE;nDT!xAL;CgpTz}1pSs8YR!{za(;o2w zajBo_H@PjfrKqU5srYBp&!*3A^1o4!rl#HhD|-BYb(8-kdbI5vHXr?G zI(eo#;a~OSz^SzH+1jb?rp?`!?d86P&y4axfAW81l>aXL`0t9x&1~2IEh!HV_bv4; z4ln$>r2G%$as2n+kjL5DXGwYIWcm1iFDbu$+@9V3|39OQ4o@Iem)8>nhe@Y5T$kS$ zhDI)vB~@QA5QW2Ty*^xDI21<$iX@P3C>lw^!!J{luKXVv<$n<#rBk_IG!g6!E&nIs z@$ZcCzX=aMaf#-tm7kV#75|;^sM%;zkBa<<@Yw3|heZ4r;nCxcNpCRz58)AYOO*3p zgvX`;Zo?Zw0sgC_FQz;DPC`)A2^Dg0&|x=|H>%8ZS7bk&^r*6!m=F> zhjZ>Ee88jp0fXVmbl-l14p4!m3(4_D;yT_ALTeDqLW^YiY%IMZ7mB-bh+!k5`w4)7 zAv7sj_)}V<7eZ4GPxpLvy4{$`^5<9#$5%rPbx$V6Og<`%m8T3(j+bJ@*-4P1D&IH1 zN`Wr)nPsg9G56cBVER`^`BXj0R4{{ptt=dkFcnD;f?V5b90vh*Ib$Fa;WrZd0F`N5V*lsj zgm6?=RNxBmlsxdTQ1ND3IF+fb`ItXaX;cI2f%>UIiKYP@UKOsDTSchKZR1nV$wnqg zT=4(`Y}BA9DjLr;g(Hg@w3O3Wtkk4vPvBLx#Sm8Dk>? zqT)Hjkctm~)aD!_7t>W%!mQNhG+ac=oMU!JD?owdA!fkQfqLx;L*z_nN{=+QtqT4S}JCJxkS_i2%`6MPAeVH;x2xPRZtm0pdi-B30D31Vh~`4G^|;I90l5oww@*xP)buhl#2%>fr6y&Zff2 zCt4gkF*tjg1pU%3WWu2o)aTzx zFQs%BY|f8&$$ibwY^xx?}k?& z2!YXht9=v+5N>Y4b@0p7E%;*y?Px*Jky?qpY_(@|BK4l$oc_%|O{Vq=@cD3dE7LPc_p?glRvEf%K|X{s!K? zOHPNlR9gPmE4ra5IHl?z^Wh>_=u`$V1o9Zo7K_=5L~T8U7XuF|*~8IfkWm4dHUxzU z7G-A1zOjZ{d5@pWmCoM!5#wK81riyvjO=|qf#)_ED?;{km^I}EJg*#Uox1|Nwh~D7 z8!5Qq+klmGb5T+%UIZ-YED89yhN@N|&CP9=x;M^=0d_PsQ}&^(mLJ_GI;ULv>+3XTU&A%M&i(Qtt~+ zkqhD0J)tbC2ExVtVdGg{tY*oGnxNVa{wBEm$FXEqtkSu%d@)%l(Tn!m8P|@?MgrG) z`|?Ch;^1@jf!C7V#DXrumsR$JUX5SJ^0i(G^Bb4#EowV&GE??coA;}aoll(dCp3$j zk1tE|*Aun=uyWfFkB?n&C`$f_NYgJ1A4;J$NYf z;gTJADBe%~x!|l3n&Z1z_=Ej4u}&r!aLIUUPlG&z@HWoldqjVqhJ;ZX;=|TZY)r)P^ zsmM}gWnRESrnyy}T+jPzdVq$k#GwhMkE7x}HWj>#R3^D|G?KnbS80E*D&%xrEy}8C1IU~FhN~tDV}^9Fg!~y0R|`C3v(y1h6GfKdZy%;q zt-v*LMbfrz9Ku9Sz_*9=Iu-e6Voley zc44D91<8gSpv3X2y(8a7RqpSvNXQIpirVC#zi!xtJ}N)NScNY6>;N^Tdt)G6qWE7I zT&X-DC9Vl$=0x`b0~+f>Y?Q+bz|9@}*@nTQo6L|pAP)GXggw|YYD6S?OQ>>Fs$gJRQ;LuQb0cTGfQV01nBwo+ay{7r_hft7Y5IVsG_x;~4?+7CIN^(|0ry;L$0L zd^qOeZj&KompMOmuOHvr{z?-2yhL@p`+XhR>DmD6k)%X#v;a1Q`6Mm@YPtO7z+Is| zfF(=cFEwl~4$W^uy?l=V$?l$=M*!DBXWUj#g#fRoN53zn7?`b48Y0%frElOvo|$QZ zjm~hclD>=FLAC+DGU#sfJH7{{NIOS1`(fs9u)#TKNQG!YtAj3Ki}olUfZMe1q?YcI z!}h)I-(|r)Vqrar(!C3t{oAPlaLXYwGXb(jmNMWTm>z(f4|5;*^pH=)6-o<;3m2#| z>?hR&Eu9}~NaNx;90(2TD^2PftnACdW5!hmSWmM$IkKU1aY29fVSy3W@;j3Z zd!i1L-LZJb4y;P^*a?lufeT?T_4&ySgvIg7u<%zi@;252mce>7nL89oI!U1WYt1<3 z9fe{o1uBt7Nl67N1w`n>`Hxvdwz|89kcJ1Pn}&QIJDc62$}mRjY*n#iOu^h|hut2I z{9Yw}_F~uVA{wLhWwb>g#JPuSJr#KUbjO#`3p6@uh6mW*~ed8$x=h+X!>XT=Q zMBWZVr;S5{bxD@AkX4RgYmH`zK$^h8>fVMAZ^0N!Gt2Dpiq;JIJ`)L95+z#@%@|?K zd;&DlgpoJ~;94b>IwiouNBi|8JvId(Lne!y7=g-@wK7t0B~sLRjWo+s3~^IGAO=(P zGYr2<0}Hp|&FfNaS5ob*U@Y?zjd|0)X|tN~23ha|Ew562PEy&l)BJJMQ$$kTPriE6 z0)1%_npqHhGr}nz;EBuefHdiW(&-^524SAk#$4v2GpTzmsgWb;z9#_LD<>T%xG)xk z1Ph#Y8qNSE&iD~*Yjdci5xazEKocz%cpD%@(#IzCN8?RqZW9m_Hl=e1qKY(hm{%eV z*EUR>KJ`Jy?=YiaCEfNJz!?Dy^M`A!%PfAd4kxkbEyuM5%gR#DQLX=RYn~&G2{-$w zrc$3JN}8J?lB;EuTe6cRTc713kx^5xszYiHO0%_KL1;lk>grDaq)|S^T2l)R5iJa1 zB0b$CMI6pxynn(w_%)k1a0R{$X3s5wJ<$RXU@h<3vY56Z-iDo-gk6}Z9cLk|gO$F? z!8x~Nco8jG?@5FLm+kNoz6THGNE#(1xnKyV=1?oV zKd934iExWzr~$_-#rGN%o~fAHjAs6FY9OQh=KB}hv>_!2sf0;PI#-`k9^Qi1L4;9^0U^w)U>N_h*<85q`x1%@!F zUND@Ig}V>l6z+hUH2NFqQum6G;kGPTNoz*FvM@T}X$D{@&Edn>!Xb~ve(16ICrnY_ zkV_Igf-Ot28;_-*n`H-|&t5Z>FSX4`B%pKINguCxC$(zt0p6`FGakF($5DlqPASW( zvlkD*x9Q=zKA<8@**i*Fvhl+e!SW5au7b5LHd7py-xc1w zJguTU^K-nF)Ti4b#~0haTeBj8NKrR%h~sr;w1QP^+o*16T< zzR2p3sGm+z07iOy+d8O*R0j@3gyxE(0lxB@p=!`soD^c^y>+eZSc}JMlPY@CCSOzG z8bC+4sYLb{31ZD)TdgE`vlU&l=^Bao4;Jokb;*1P@S~{+_?ZO}*-74QU+4idnf?V! zEw@$$Vr#YF?j?7b0Pa;l$7)*vpM8^dn+$7J6TG+WRa@i`OaqOL_^MOlSnz2j;Bu^3 z>ZL**A;L+jsCxWWgNv1xBN!OcJktH z?()X#v0?NpN$)X4j2bCN8qI_M+w6E&%r9BI!Sf?mx8W8hzLBSv?zkpUra%)vL7_fB zNxPw>4TCAGK_K(T&*xs2@je-+>KN?C%ZCIS*`zIv0RGWd$)0@4{NA(X!i14ZESXSz z>jni87q^#K6x*@~gt7`gm(vPI7zW1>gu$B%02pjDVoN{=;?Q&EpjT!$*LoLDR!>%a zkB?FI;tA2(U&EDWY(2E!sDUNlm4_8~hU+tUt_lP!q;40^^*P6Bi7C9=Qp+>oM#N1sGqP%+P6s3xIr? zi!!NYusIB=?G(yJI>J~g>&67MS02@QPfJ}n%uCNT!6XyosHDi`Cs#tJJVU-=jQch- zOEA0eI(5E2Bb%*6d4Y{=I{jUpQNsC%Kq;Cs-h>o>5|4UKn3GyfaJ6M+y@z1R%gTxX(vP z<@X53NIDgr9y`HUeOJaSp*rH}f|+Y}L>&4tC(PK3e3}P~ha~ux2iv}g_&Kg7zt|i< zviO|AxlwMhF&AltD4e~BJTUv` zYnLQlT@GE$JYD2s%*>B~Ar)B1lvzY&Ty4%yCq?T0;Jbj|TUxWcn1&F_=N4SIk*+j$ zw*Up$tvtC2mo?8?CaYS^v`TC|m~EVH>@vOYvJmZkW|WyHH`RKUIVvzVk9>nzw)i>$ zVK4~1BMawLQ8&%sNtcpYCektS){v|bAyG1;thNzG(=8?@%zVd?5%YEJ-J+iJqImNo z%TrO?(_mf}eaZpD7unWJhm*eZUwS&-k}+y)p%tXsVAvCtpe zg6+M2O`E3E%6vFr(&oNk^=X>I$-EVeX3h2@N-y$eYF=zd6JaK%^)?#aA!+oEP4#NO z;I|a5V?LCK#PGVQRF}S-GvBwfm(I)A&C4@=qm^jfC5#Bm&*JX8ucgJV^iKXhOyF6o zJyI@Uj%a&OwwHx*&Aermm|-Vtasqi`Rm<rXU zH6zHsJJj+Q#NuY8x9$x-?vH=pRnGKbYN5{~U98bKT&R9bsDEF>V#?S3=qmH>+!%{T zGW`DN5qD>dO0(AS;P>%p&pYXKnd>rzG(-ZGREMO%0?(F%z|xKMa~h(v8)-n85F!uG zGxs^O>oI8S*FbnyRZr_o_w&A3}z-Z$UHNn7eyW!U-pwqjNyt@BZ_=6{*KGQ3`)#tuReEHk7 z^(N!_H=OxpJnu<><=r9vMRXdx(-28g7;O9!CN6FxOpyr;46>pQeBlcsV)yIn)(2RR z+<#`2J?eTyLy-xYiUy{qL6Ja4gZ^}<{07!S4)fPL<$b9{$`AP*u?&?1nN&vo&yI2u zS#UU;ne&}iqDGI2C>5g%Tf|BQMkf>={cO1fMSz_loZJGbwum-UA|Ya5R7O2%N;;!A zyT7VvgV{um_z#T>oo2ha#Htm;0{QeFE;m!$#6P`?645-b-U*BOh5<}etG^nQjS~X` z2_q|6S;jxJ6<-ID(&~1iI7}3x5k-p1vXC#hx~-h4dvd-6vCTmWH`{`z>u}$bDy7T^ zdO5RH@&S1;z;FrBanCfKoew9nzi9HX{aGK!Lsu5i&;G+4-6+gS@=fdSQ(73FFxBNW z|I^(Cdo5}lUUEY;P!F%5(^1q^rx|aybSnRxjZR)L$L9k=hDOlCWP*DAn@M~|j`@!Z z+CYP6VftgPe-Mw1AX&0UB9%k54=fBbQkL^kcpQMLElE0?*o|y$q-bUpI01g|%pe}~ zu0q}AIHpxSB9Y9#R6^qTF$5*Pa8*8aN_0cML{73ZYgmP;iVQt|_pE@DLeX$CjC0X& zEljG>u_WOX;6@-6zvW|=IFj{`jjW2l!fAEGA!l)xp$0~SE)W6A&#IS7uq%vXnF zGB$!SEi;$~6N6}j3LqXpW@%;*eQ4OD4r08x9~c8kA>+gLXc}Jyn}p+S=ZEDYmnmqa zq#;Gpe#X7q!m*0yn`#P(&_=rFOPrb=8$_XrJCB7N7C(~z8J{@jcch1))OV#N1ITy- zy>Y(AVC=N$x6|1hvWl?Q9M^;6ho7s2THnm0O`)N$6b#eo!vP$y`KniKer~u8+T%7* zE-pBWPe+hY=wAW{#` zWuBs+2gRc}M8uxPYz8lLtTXvb#WtTZ@#g_)9;e4#O1GXEk3m=)Uk%N_G+gd)Cq9ZPwpPfR^MH6G;YK4Fijprez7!hCCd1&^ z>D@54e@Hc|g!P0Tn?mES)TnKR5n7ag_9h5ASrCeu;4K`dqT(fxE=A1XD1=nA#h^ysX#KgrTzEDfnYi}uBnS&0)&CsmyD3xM?M z2`Trm;tWWk1mYq?BFpG;`DBN9#k}&?5|R{iP9|JU|74VtC|`ad@!VqxI~X6De6aDF za4xh>A~)A({i~y#flJlnEGC0-Byc~H_^n|s_ro@o|B+WI5NkdUR@_qb7o<`s*Sz*@ zPqHW_pK|0s9c5qXFNE#Nu{Gj(IM7y7;(RKJld6S;pNL2GGrDc+d@*y#C*pyZlvFWa zLio5)*l96XK6fh_Du1c= zc3pL@8q9Jruyr+H#&eJ&YVzDFWpsqbzemj`6=w05OHUM2(VFDx@lX!@d1X^8q)Rc! zkFUV;)`w1S}$nC;pzXCMK&1qtK+-Lfl%fs$_L0lSp(~ z)!e!&?z(=f{Emm4E`_8~2d7zN6c&VoIub!KTJ69-@5Vb)}VYJYGP_b#N#vsv0(_<%P!LZ>y zzmyKkeO7J$Npk(fB#15;AU| zu#kW>*k4i?I0xcm9LH(nM;niGLErumvEporxdazs-;=+y} zLUspz9xA&?RN5xQ;oU)RqY_pssdAZ1l$3|g1LXu1#rjgj;tDzksW*GAgW(fDf{Ry; z_ZOe+4`$3F^b7YITG~0PBz)knzUQh}b!bdQG}_^rvCU;vd?ZyB5DGn@i0IW>NdA&H zWlUR=VV)p8sT&f%gK(>da{4ze>w#t{+a!zP{uS-rh6l z`~I1keYs`I#Fp6_^G(v?h3Uv||!}5AWei^MOju0$mrWXZ?rtYT_{h0J*=WK$ow>ihH9Mhv~YS z86NWmw{25@EFCYc~2-IHY` z$_%jzkTt4}LMsuDB2pCrPVx!=-AxSvv3WCk;!0f5mrYuTJI)2p;Enua3`qUZR$lcclh#A;_F9BH8V zTuVR^%#b3YP(7&R?Cc=EC>l^KewIpL#IWnnp8`mOAclw`ZS2%;c6?np*}LNB!f^Pj zEG^u|PyB#YbU;po!vazK1ApLVy33}BY3Zhkd`^i%a(+gK^vIDQdfRCbnhkYGf`U`qSh#G&21Ln+5N9*&?-hUb+N%HY4P#+;6Ac zQDyD^^z@98$$|9wL4|q2^dIEewq5-;<+h2fHI=QkdjkaMS#+{Psu&b4xNTYdMPh;Q z`QG?ZWlZTmtMwvzOK*wAtA^H{b7AM(xOR9|Dn`|ltJQ8qR(1H=z@-S+lQMo$>NJ$D zyu_7_g_r+~%Mlw5%M*&9;WKp}IuIBO!51uo6-cYvk;N1?(G4+Xo~&JH-C z$}GA%wocnoxeTSwg!m8H1)9#4q|Uk*q_bbFQ8;~bJ(CXwaF@0be@sI!O%)E26f-O2 z&@jG)Q*{0D=(_L!b(e(oP&oCtR{Vt7np)NsO@RA~U+74IHZnhXK{0db4F^s+4K6qxQ97~OH-kPzcQZ@=)>bQcEfMZN!G)Y8RHijoz6QkG7h*HW*MUJo1_wc?j0vrTO<)I1Pb?F&!|l2Xl2Mrpi&%SJ$a3W-3S zAx(p!Pf$*pL{3)rZAJ%4L`kqq4~b8EUtHtIC?}+ZH>9Xu^iPdqc1QULGl5}qq~@=I z65*{`ZSixE076szhU=gdF&8+Yw>eY7d1Lj(X>X0AsKp0=4iIKxgxr7&$B5^ehK!x0 z*W2Pv#E`Rk%PlYGqjKGo5$7MC1;?1Cezal5i|#p!L0tOb*TycL0fG=8IG9oPmk}XR z)p==pN%D`mj37=83p*_!;e0TQ4$yZwg+=XRc{u-kxccv~4+Y4PUOLC5I$E791GwUb zzaq}SS??Lrx{?Wos6s)sK4ao4ji3g)z{Mi1vNq_%@3ffNEtZ&R znK3R3xvmQP>R7remjq`FHu5m_wwCP|Ht%y)j-ywdgRxv@3nNQ|Z=Muyo;Gcs4Q!q-Y+f8}{<+`0gxs0zytro;|FV+Uw%1cZS>`W+4S zXB)R<2an4T0c(fguoA<5hv;F4m?^~08x@~wmyB!oIs{HfX_wO6n9@xQt#fiq6<%^- zhi(xLlPCn928!g+m`Nex9T0s^38VKp=*G2&r?5+MVu zxK5Xuskl-(71nLcD72%D7NmTQE5NVPvP2or<(yJD{+ zX&OCWNvL_c%*059YG2e~2LuBpENrB5928>30F3N9pSPn2C38i}4*Oah8i8a%9Gd>G4wxUeJX_|x5o1fOHCPywIvoq+?P2wtg_XnHU$wvy%O*1g#81pdVd-|itNNMj&Z0;)Ofk}pfnPHj2#runrK!2L#@Mw^%dH%){JIanHk|_JxAAYq~C3DXO zy}0^n4C4SnPvi&H4=Y=j54aIrfl1WolrUNIc&rB?sX{#y9bjbgq>@K6) zYQlYi2iIc3-HW?hafjmW?!}50iUoqZySuv;cXurXio0t|F7J8IJ@;Jsa`&fX&Fsm_ zUTbIV%slh^>+l6Z)xnyn1n=c+DU@KWJz1!XhA8|vQ0WcmaDszt3+bf2M1m*q$g%X~ zDNxgh8vW6|FFnOoF*xG9u^Jd9vf1nBI~UMi9dMFqKY$} zJ8E9!T#ej{$;np6<6MGtZ%uh;{or_+1x_u0IG|bDA*yo`qHA}u?_@6>+Fo<2V-ldS z?R2aZ?1l!1b_6=Hgu^)knWhD`)i^1pY!TGD?9&Eavs_Y=ZFi;Ycf;q0@ z8cDzB|9o_%I=p+4y5ZKk#4G0cp~O?TXRUolU9BYJa;oPfIMyBDaF1yVupWEh4sZIo z?rEm~>Y@J`XCuo1%$s^;hPx+`<0e|>wobZ-O#YA!;n~UOX~Ha6|H1vWcZqdJ#GMe& z3IDshV~;yUn-hS~djH|t@y+Sj5d^z>r)>Rr^Y@Nc%azJb{vg_bE_0J8emo|VY*KS0 zYh$xosJ*7jko9v?3Y8%$wt}dxTSnnT^CadB4o!8G;j_m`Cwuq_<&pOI&mRU)Ab*-t z7{w7RD|TmFaZ-?ojYV3{Rd&fO%AqYb3v4Q{=^D#{qVD9rVM*yX#X2fl2i|=ZascV& zwY|q3*`voX2|OeI7rv)JM+8gwZ5Ivvzz(O!3cO#QpD)Xr&BQg0r#*=E!;s8zeaW`Y z2jh0~SN2NK53$Q!1Q7$3OzsMP9TaL`;LO6AL3)GgSnlkXEq+f2xwO9YJ{naS?|S`u zu|7Apl~W2Kd>!`Ox#N5Na%dq5vCuAqUSkW?ig|Tvy~F+twf_K}pZe$hc0%a=R)P0t zamA?ri*@y{Pg9{=`R@WZSRp` zE%$Hzchga_x1-O8KY73HxBBPp?i_gfAEmxs@S2~X-+LGA^|Zg;Sc52|11jYjB)ak3IL1tq0QNuT#@&Oe2AiZPf<37(F+TL3;M4V zWg8Vrsjy=C=nNGbYB}~ol?I37d5C4MD(EHd33wbtcX9E*T62!KQC@|M>k(2 zpZXt&$6}dUsamz&J;QP-nXSwDN%HAPaHvqi61Z$oz!zulRma74Bw0he!9yeIgCT9xZ}>kDa=a0DSMbSsv$>Gr zcz;@~(V2;oi%}E-C_`b*!10L+g>7Dm^0d)vViX9`33+0L7%Kpm9&U_HXLy1~%mjq& z2f`FxyLOsXonhKc?Iv!M4M!ph`iPJ4>G4`H!HC+ME{Z80b03#Y7mX#LUH6v7!eDQ# zrBDTuC_M3=bjTQ)PlZWQ$l_Qprz+F)o zmf@pP;aRO`V^}G`HT#(^++|*tUA#m$nn}$n0XDGgE}^D1W^XLA2p@JlOYJ7b3dWvv zuO!Lk#yyT%6C%Ax)B4lrmATb82uVxQEV*3O>6O3JDf3H1r)oArJKVN(2H~J}*Gm0< zUQxB{-euuwI0IXGu(Fh2xC%IvanTxxdagqgouq?A;D8fxzn9)R5?akTt2R3IX zfA;A5R--TnaMvNqq@(P|`(5Y@@RhvrszVRO! zMhMoVSwL9)R6F3k3liy+3GcYf3))aT#lLXkkuNt-yv{CJ=nA;>Tcy6l^^g|&bx2IK zSz2F?dTNvz`x9l=l@UoKVG{W288qwEDEOo2Wyqvyb-ZCJIgfoh5r!^m zB!$BKKfOI0a|@&u3+B%0MsUK@%GqNe%0<$RZ#Opcmx`j=AC==3{K7#Gn6xbx%ZlTJ#a(1T9g4jh>v9AKU zR3Uls#I7`d>+7SP_I^1e@RUI2>SH{*s7P#jvoL5A_O(faS6? zeb{ZQaNd2*>MioCi&cED{HY`NTk@%jX`~phq`9{lCi8Waxl#ssM zMa$DzuGE7lAy@E3%Qrwj{ZEMUE-{Gh>}b-ap)p$_{eWSrdCL1eL-}E`gm^$BcDm*na=;)K~2}ZcuU1rYFfYdz_SR56)tN?2nPgkMlDUFNqQ$fb3_!tZ57H z6cVlQWlDkueEW1+21QcX@K80!kr0K!7=GAx%8od6rNz=U!8QHtg?eTP_fr1qS$Wlz?z8 zy`>xE9mE^rxkfNI=4uw-Lm)4&8coE)30NUMIh@zaOsAY-xD#5w%9&rDb}~bC+VRX> zbf0K<5HYoxYahZRUy02{S9G#M9@t~E4Y!a7pUSc*IE*PioKS}o>aTaWmkgX&E48|g zcc_w_ZX*cNh9^wSjeT`@9^w9(y}n2*!c$3R*}Xs*>%%hiXqaTZ=DmRBW5($M4o;1S zr5DUHL$oGKL7ujz5?J4Lus0mw2Y1vw8lEdWwg3m57?@O|@YV`u#++^9RC*McBZ+j_6>R;lJhx?xk!~j{xM4ht z4fUQ!m}Ci8$H%tGh5hPhA;j!pDJBSoBzEJn2;xiT_gSatM7!Vl;+a`eQto-t8QN^5 z&QX?0{Dg@`(n&xO8-~M6U105#CA8p>Im}c0Cd0EIVS^$qtI&a|gwFiA=XDN5h?y11 zyUXS#<2g&{q^EpV!s^Gpfq>AFIqU11L{nz@XJLV*kF55#9IPt><;?aP+wH^WUYz{ik0a-)_=-T=m2? znXg1X{rTOK_{B&2Pph^9G`pGq^GpuG8{`wTwys3YrQPsUjJ+}BJ z7BX88Qo1IaVKY&mGmiS3^z>m#^Jj5tObC$79WS;xn}8{f1J>xxP!d*e`w)&C_2n1f zKvhdDgWGRSrbrV;{FhEMxgK07iU$rx1vIB+r>rS&zunyUV$C7w@xw&$^qm+&TEytX&NJ9eu+OraT1J={Jvg9JS!78S?= zD+Mzc&Jh;9FROkHt|B2h!gTTz5?j1h8OWQ41@zDg+Brc~1|B{&~Vl_T@pk%ao9s4hBP z@94M6xDKD?=HQ&+Q1k+wmGoVo<9r-m(bM}7|Lz(QqYLK5va%=7yJC9z7R|;i`T6CO6ecoK!nKjgt4EGrIjnl#aQLRbIE--7m zWgC7Oiv?c8Z&+$KbsNIv;dyBGZsM$a`7iwJ+hrWi#`l88_SwV_>Pv*ssq7CLu*LNy znC5Fel==xs`E$U1rv!cPI7rK|4M3)I#I?z2q30x_4Hem9TqDco3E^6o^7A?V{&1L< zVw;+9Y@b2za8a6hFci>Wn@?-U6i!N=oWl(w%T^|R-jT{lu$?=j&v-dZ4=v9#t0>qV z%3nVyjbSL)n!l5(C@KLyxK#LKRpdS#m!y>I44>p#*_Hc9mdUSGUoh0t+7-7{RHL0# zzLZzaSCl^3nI17TurM}ag}(1JXp*jMQf6${s%$o@Y|1&9pY0FusBHCTYzwVyi(za} zscg?+RCU&CtYPfjC2RS?*fo6G#G$E_UD>_G_~W4R#|2{#){(Rw9pfv3iCi;dpB1nv zr;h?VsEdVZK$`JwXiWdEa!{FRNULhd!@h%uj0tDED8nXw(?DF2d<-PXuZ5Mh1rO^K zGFl-8XJj$KFxW@y(1g}cktH^u#i;rrs6Pj4YWb`WH)t{=5UC&!SscP7>3ljwTRqRh zybxnQTtlX%xuxZ}tj%qGbDu|=o;-0vj#(ksJYO}nb=HKXNkPXn1zkNw$u!GQHA^aq zZ8ePzza?d0D#=y-bBlS4=X`;3izINzS8Oa&6UBmHm9Sz*+(5-*te7y+3}tEuYl*^p z^vE?iUExBBY@Q+pzQ7u7H?W#1lG4nAzQC4k*Ud%IjE8bf$qf7!S72b~YPkyzlr45Q za}P8NN)w|Xho(dgA|S82IJua9zs0G~2mt34#Fs`Yj8ktHSK^GT^7gaPL(I@pED>2^ zR|Txlg={65#`xx2{;W@-tUoT!srk*DL<zOlp*3$m@(A&vqE;H8 z*`aGh`rm1b3+%%N#UlyS5)i@Wn82YRVdiJ7(1;y#X@GJQDfFd4?aYJI+D#Q~tz*Bu zb2BAVzj7Uc&==UoYU_s7DOro{dUWJhMZ1VvlpZ$JRGR0lgFBzSrjU3UHq>QHs?>Nr z=N6l@moGos>GoSj6jGRsJIV}sLeM{j4KN`nOMgD=w=i8@d)w7D3{q?oWkgVSUcDK* zv|>|Ta=`n{*nb0u7|Dj$=%`UMp;5vnuCt%0_+fr{n}b>c^{}3l^BlFXxaFsFS$*+K zf<*;p7P>tZ_yfB;i;I!+sL{p7HCKZ)*EPC&L(N?A@)~3c%6`ynOV=fvC5^izQp%Z7 z`wBt9el5t6K*s)p;}W*Ao4{eHMZTUSQ8t7G#Ep%pM$TDdfT3%7r;3w zj`GwGfxBg6ZDhM-=Q?yGTex!CE9q!Q`GR}X`M0D~^Cvp+qddz^oo&GtTj|HJwVs`L zcdSh&&C*cHthcS-{UosTGY)u_j;p&D__+-?2`(Z74NQ%PXK8)D5%900AN{>*Nj}|n zFGFFl4KUz0LP#Wl08vg(7%6>st}jhnZ~Mc(Vj0f@poi=(B*;Q_@XuJ`xB2T zuXN=D=P6W(IbX2gQ+VuCAmjnU`~-myISB==#DF-*E$0Vnj4Ilz-5^i;n*k3#WiGUjO^c|_ZdNDaeRS%h0TE?+J#;V-Xn#jhzZuf;osIWH-^AlFSn)psYF_b;dqXmJl{ zR1ysCZHGdrv7NVRtO0U*Tsb^7jcFQ$+X`;kx6C9``=wAfMIUa^%;nK@smf{p4B=MWe4FDcsmKt9*ZTawbyix*4mvUf3|xQor9-FE(0V^eXky`1&L3 z%~7@=(~O9g=e^b~Cj;l@MTI}2=k-rcEt}mRNg1?uZ{3%NkRfQu@iwh!lpQ&;VjVmJ z0+isY=$a@9g@W`CPJLhLXKZ$st~RD!NiZIbmBY5Gg&a5>D_z5u!*W>qgPyd*Gl#ii z1Q&ZtQ+tB-j3rPk^o&1=ZYEVQQcY68{a8GU*YrlHX;yJbBDf-hz`gk-T>><1!K`6Z zsa>Vpm?DhbVz<^}P)VxcF}mCzf-!~Yz*b@k6O17hjRki-OQ$#auBCOQxtNc{QpltT zrMp^Aq_SHt6Q|QvgF+KRFT#&Z>eykX@QGosA+=>3e(e4nH*>P*Yxp0RW6FFf#z2k1 z>!j(Ktw))7QH(g=P|y96qpH#lZ^Tv#dw3b7AvNljg$EL>TOxFS9>wCCQ$v_Y1v(cl zCDJASZ2f?G$iU9rFlPC=cb~Q>r3R0^I>`qc57RDC7zcyGKEMczLv7F8Hal9sLQT6q&MrLrE+fW=Pu&tUKCUPmNZ=6Xuof{zwL{%H5 z2xpofrK0dbmWxW-qwk=Rs8kuJFRz-HXJAKW8pU@zo1b9qLv5TOL5Kb@&N-*3KE=J} zkVp^NOuEdY{f(`Z#CSca{+SbAKS6;V%I1T{tXLm)BNXSUqQ;yQf#c$w3rn$84 zFsIb2?zDE_vgx@Kt-a+PE~Nd__xf*wq0>)4E<7J7G@b3hzmqH5!S_G4*Zh%qE`Cvx z8PS=keKcy`4P~ERG790pXwv~DTJp_Bu2AzAepiy_+|MDU<=;=H2=XpYA##3}N#~sA zpN|&4SUVg{7^1TvRf@*9CW|%VI!=f&>NqIN< zg-wb=DGf@}96BnD4*)niG;y-uHnXyUh{F`Pqd;ac3v3^k?LR7M;y9GG zsuU5jB|flXiBHlDwEZR;5rbm!M{HE;P&;BqN%0TdusjI#JFo~%;xsI(UKCLa1}Cm@ zA~=JR2;N}27wjkwumw`%Gn`8o9Ts7ODNhN;n1)S$>XAVJEvxruxf1oV(cj0Exd=tgFRy2WKjF?N4l_Vz;pW`qLpGn1z z#Gvk-t2yjSF_~_zy5)tHQ8buE*-k_8E4{#bx)JIrO9L~~ThYHJshChu7R)e9XT#GA zgr-0gBkRWqE0YZ6{UZw_e>|Iu1&WdK#^Qh9`L9faA@zvM_F^V~%EQg=l>~(8R zt=j2c<4p(*#KECl$dl%-iZ5W3YRI`p{F<~!5DTjrgnb#ME;zrl!@pD3S30RlEj9=? zk~Gz??|%C8%#}I&dpuT%UjPUm+;ONaak5{IW%zlHY)N*S#k#c zKcOON*OGssB44=#XN_!c-Kzfu6{V+t4(j?xDN1Npiy70c`t`3*j$~<)bizosE1Cp4c-+iJ8@9;v|>;|Kn2FvPZ`}%f|=6`*njzIa2 z5S{F4@!s1z+=x*^QTesknHh; zg!!kkp^LKRgQ{PU_J2X5-Tw&^g?5h@frcuQN9(fZDx()_;+LD!d-Hq7nv44zJJ&i2 z4!VOT;zpNi7Ps4e?R0Pds}w;dqagE9uS;3~C`Bvf2diEG5=CzZ&5)a((SM1e;r~Vy z?H^1YzKlLWmJSY9|3J1Uw~m&E&o*a|1`m!_4-fXn5BHZKPot2(3kL@WC;uB!1eu%! zOipr6PFhV)rceHJKqeu8NeJg8#A*_f{{C(f0)YSk5CA6xU@>hbE*{tk`92Rb3)RsAnED3tb!HJB!ZO@Va11A~)1F7C7{=tdjND#FCCr%Vf z)ZX}x6A6CaQtW8@2PYyzo9bvjT``pTR4n?A6D_s5z2iig%xAxPgJn{FCIu<}?oMPh zp6=pT*qJRmO9*BgH^>}qW-yW6wKs#2r{P8JUxh0**1%|55AtKxI!k=<;w^m-csz1b>~sAZe-vTE@_7>C6-DQp7~;^3IcS<{q0I$xnS zP&i`9FjF^UL2&?kdRKhf&5FGE13UIbEufr=&TkNFeo*MrG{fsAe4Q0leS5%3Uj4p! zTIgGB&!;aU3Ub$~CLi^V#b^OYt^yqM1Jc?+p5_LiGPOc~$~jiBkg$^A|Y%7(+7{RnlkU6uw%jqSq15RtgHevpg}6p02c%kLDuEPFT&H8M6=(BXyTH$O>N3nIlC-Yb~-T%>;7OJfLQI5nQ1mmFfyQ{^u0EWk}o zNujf|_0&f##2=9z=BOy~63R~?oEjbG>A0r*{H>69jdMg`o$ETrYqHREwroV?W^c?=0`yZHzLcDN!5|bOIvWjRI!1sIp*fP!(-3=( zv%Dd$RN{10377hmN2{W1)vXo&<~4O?_E&Dp$PNrU~jlzfiBT6x!rgok13$^!07 z&$$W1%Y%?E^gNaTdk!N28FcSccKA2VhUHyCPe@;D_PHO~>}E1?8qJ@jOLs%@pC=;Q z9ZXPlHY=|HtdXIbnkI?Q2mqv>3W}T{8YYFaxL^c)t>HLF2R1SkbxK)}hAQ)unjc)q z%eYic72Hw@n(x1MLV2io!cyW&`FjXiP_$Y!Ao-?0fSqwke01^}d4KyQa|`bY8B8~& zd1PRtN83k2BRNkpjKegO)Lx!;H>F-;tCTB#S_2WcFSh*$shi%@Uvt7K?#>b)Z50Dt6U}3y?9?#F+oS*`-t!z_EQ8 z7!F zAnp@jrWgylMU(I#@Qnw^@nrhNeA&a->I-U%e!ZscRdT>EjxP^|$#!!P8ZYoNRQH5e zCe{;sFb_%K+B&TzL{cos8UbgzRjOYGq_7$y>0)tP3j8n%l7_OnTJouT#Maf3f|d@| zI08B0hq>~FO+baYdxd#H(!w%K!}wf~ZB*a`@WDZRU`uEC+|n>`8aRTE%E<*j zV;~}UR!9IULU|4e<3TUX6vRV;%+VKFPsbq}Xw;gfFvb`0zEw_%+oHQbwfra|8xhRg z=OH47xbYji1H9R8YN?@%PNMbYY85|iplaqzCr|-s;E@ypk5zh z$(ZQdN=3=!MfTgk%7|)puVSt1m_df1CJ=#_!%+CcP(;p=XysTyT|_J##Pdh29i1Q! z%s7~16C!VYMhIq{bbh25T^!XIR*J{X4UZ{5q;a_KcNT7t0_P1xFvnCYFHn zQ4b7=XEjBPNePh!2lk`_59okm&rT@MSlHb0pPvC@NG=%s$&5R3nB~4)>?R87$%i@w z-&Qq@`(qeYV@sUjEAYYg-tRBIw>ev~f_s%-6|0m}zR+a8V$uG$G7{(6Kbu{K)BtXpB@Rpe-U+Ine$okTX6i zC>$7Io8cJmWY`>M%%5CIkmA}Gw&J48Xqv(}m*S`k?^vGVkB?fq9nPGej(vdDZ39XP z$1aDA0jKzZAq2p&wKOi%tU5$}p|LcF7X9p5{q^(&7R>DSRjj%8cjymU$Oc%jmMmi$ zIU|=GSe^ka$GUtrY+S=tCCC+1&6SYLbax3SZ-_Y^%B)$*5lgP?%{$9}9O9k)h+TYy)(FkCHGgG)4Hz7MOvJj7R8`DlHcD zVcb2;+W;Mq&yZilCRV@;RdPaagn3e=Xj{S)9~H`$TP0Uw-ccfRopH;b3}tOpKRQ;Z z*nmq@tT&X0nmHQYb`^8Um-QGHEAxVNLzDPn6p8QH1kD51h!FUAoXnh`{4!L+9$3zi zuZpe}7n6~I3Rl8wtG`KLI`rg&&68L(u7Av(NHbd8s+supxPn+$zX2x(%DY0sJJ2Sh zkT<`a>>%~7-Ptg_T$&4hlE}pCeIC4_L5npwM1ni9{{pu3VqZ++rQ*9qA>+4PS zYrJ|pu$p@Zyeu`PR@qKG-G3tp0b%BxC7NU_s@pV!e z^|ZbXA*4vThK@Zh00ww8V86*P*oT6W!ty5&J&@!Z@ zl7WHxq!X*4U@3T*BLA9_lWfAk9?4>ArlO$75U+yHsOO*d&cMg}DG-)ybWOi@%@TFb z3wAH+cQ5;PuV!|ycXn@Pc0Uf_Qd=Rb$htAUKU;R{GSus_=Q|r@hT=S82?=&SrRCYo zW}503*~~Vk_#z{nbOfh$RBn{^hXwP0a#Hy%&u zsXPFlc(to=LjO!)<+OJt&2>{7^wWOpr_1VR_}2f65hrj0OYarH?x2UxIDnU2Q~3x; zTmHfK>KLmJ6cWrrdTGDJM-BAq5lrnFXiupo8pI{)gj}~Z36@3(@(vE=A%R{j?qxgT z_}YCL!#Ur%ura+8`ycT1{ga*jc3r~`o5N0B!^~&>Y*~7o4#UJzv7Dxk2EM4}2<<&6 zJ;IrJ=BGWD)LevUDaF&$??hqE)w>DlGO+p6? z`OpE1sA2H+a9P%PMb~&4@d(SNe}<@buwbKykavm70DC=>12+gg&ao!7I1PUk<*X$H zwa+1awDmO8B|YLnC)z`>sU!d;C907hcQ{1ToQR12tQ1M1 ztUi;DKO3b|RY;0illNX7Kh`Egz)j=5L%ESCI^VvBoy}d@c(=Ybimy+(W=^+zw=vm& ze>!v+%ItG1p0-7u;WAv{`8j-(MO=hYF6dH!&o`zR*?{}Ha5z3S7!KrQTKMg7XMgLzZ-y8l?A?WL+OEc1tE=no#TFYK5B_rn!qa0Z2c132@Irjc!V zWr27eNwX(G#H%IbvMyHR#*Eiah|;EXhLw=FGZP26U#AgquQavHn0DmLR`3^2Gj@hP zEx%k3i~&YKQsr&;lpS2J;HT{QY&YSa0W6qX=7@d?j76*^zn@}-eYDGC6_#6}f_f*_ zZ44J!+roPw<}GQ=AHRKP27G^*rft~mPpDE@6>k=m|1{N4v(DwQi;@18Bb~tv6+Aey z?~mKgZi=8+V*A()w2;B(>o{n@!%46L;u!F=?T`kW5XT3JFyy0Rt8Dnprsd)d>{epQ zD-Vd)=v7I1iYxC${aBG!#@-Y5c2}I>u4>*82L3!~9!f6krb`BsVBEY7Y;O$^O1{eD4L?OmTiu8S~L5%P01|!M- z1K$;YM{k{3|2>MU+1TvfGmjeKoBLtt>-Z3TF2=k6*W1ZOzA6I#qFc}7IOSAa`*a}4BLdo5NzQg=solF@iso}&bIvSxohU{*-we@ z&sS$xNk8SxTcuPWo!Dt)FXvUynXyESHkZy~JH?RC-#cGwATJ(sFLj?@n`Uquj9=Sw zUt5b_yMDczg%fm50Z%SoJuKF~V*VLq6$*!1_w@x17-JVtZBJ-!8rQ6EZ3WBaUwRe& zjlNZ6$wzpv>}Uzt5E}V2hEA??iX~@AIO3P(Ds`hZxakV@(+l?Jhl(ffLR>F4MBX2n zfNRk_Q7#yS0(vWzoqlx`5(bBsvmMEQaU#{<(lI2${;=)NDzXVENIQf!43oiZNJJv! zw6jU{fkTrPTxNSfDHZf6{Ih4bZQ5L6xPv=Mm$V^ObVQfUIyO~==&%Bs7ZJ z7LH9stj~TkP#^k%b{#{PRX>>OgVm9PN>HyDfwXno6HkC)wLuR51yjl=V{ z{SdcqGU0)gvmW-3{AGKCzb*2@ZPK zQT;$6D)-Dkx6M7zIohgNMW%xY1|B@pse>cQ1Ir2 zuI?PLIojW_ZI3Dz89_1F6(;IN*DOZoB^o3y+ccVj$^i&~wuB`Fbq7xZV}&s1ULCsw zAoAP!p zI~DTh(QkB9v24VM$}xLIQMKW{4Yxg@{sOmwND;Y;0wve^<3PC91-9vMp+79|Tc8Y@ zMCf(D0i*)8Zc(}9=^H>n23Z8K=s$y~hk4khe&2Ml4sexI?h*%51^}WIL!$w(t6~Kf zU=!+afZi%iBtWEhkb;%YdmD`^RxuAAuFS1?&APs*MbBQa<3?}V>CBa!6i#42$xPAl zvO8jvYjlcxN|SDioSlJ9Q1-rRR7ARUopWZ854x#9g34kgzc}N>rooT@%mhXNvNL(I z6?0IHD2Yi@z|}l0J-?Xm;8;JzZS6YNn~q?oLARvdshP~qc%LL2;yx=sn z^|6jGBiWs0xhzGr9Q|y?T?hbzGFSBgU&N#~N^19KcR$xRMQ*$oBnNS80xtEJQ&jly zX*9}#vp@;J9mAjN9;~XFGOV3j$_vJR`@GYAyiu0pM)dN_z^zoKhVi-tU}#rET6h`g z`w`W)E?p5}u!%f5HT2XrGOt(^HYEUnku1Iy)E(!_41+Cl;+&o zlL|yLu0dvF`R*QjyLi9&WSOGl0!w-rqr0TC*suYO0CwE>dWsc%d_J^B#s4mTVGK zie|VAX(LsLoZxyzE1re)nGh?k!ZB0}t;UR!CaZsNB2M{*Ovo=-YtD9lWeu~1FpIi5 z8E7eGj~33T2_ZN*SWIP~c~0shcWaSTtLf5o)Ld%aLr;->;anYRN$B}fG0`T>L&L*7 zr2A0`66nv~9Jko!vQomu>0#=KW~hUs!LX7Hf$SQC*vEI)0u&u;^w&UzZpO92EiWDr z7YzpX7!gPAO{?8nQZdmreKac8l)4FdAtC4hUwJM}h>sK9f7WCS*Nh{w?5NCUkS{e?7-G-?s_5spOm53D#gmCg(z6gQE27Bo&du``8MJ)+qiNaROnCt@J18xhu85h7V*U>UR}y{Or9t{h8^!YH@(&Skaj zJgNFNgEwAi=)})MoK{qKJOkq?f7$xx>vJ=O~JNteXs zhnR7`pIWe>p@lCAVFGi#6v|HOoU~dnYqJ?eOkq~DKfl&pk4MhjcPRQi3f4XlT8sjp zwX-+4IAXtPbt9_lm=e#k?Qd&SK%#F_V>7m`^!WPpJu1E+oQ1{Sgj#%|Z5*28`CTS_vH3 zp(x*mu}{$99jSG8Gpi~5JY|W$W=|(a9Nj7y$jWdSJZVElid!Ms@m}j`oJi8(oX3Uh zGXaeFyBqW=E-&?W-1RSi6nxRC8W#%qBt@&|dFkLqJX-U%8xDz=b^6G~vYcg(knH2R zNYdoR$tb%oEm~hN&}zN-81glDs;#^~|2)w?L{B^o)u{QtK%q3~vns6iwLY~QY*)nN zY2!a!(@K(I6(%SfP>-j_5;=&K%+cw-MFR8cet1y{AQdc>TEtkUA z-+2H0rupPO%;|sQ5i6APMu633v~}xLRF=f}<#U|F+b!f`Qs|qSUc$7!b>19jnPO%2 z49JdphbI1L$*neSRv)`C`LImpE6e_VdIX(9EgjAG zY$b7?zTlp;hzgy~z&56vW2QC=l&P2cbfT)%->9v!Rf7?ve-=K4c~wN%<`p#t6!MS)tPr=z z59;wfn|VE3IxKsby$^!Lk1*lK^YQwPpD=vc?T;ZW=AE%u^N2SEc$4B~{Kt*eCah69 zaYyRlr-V4ThFTOTr0U3)*rVFW-X=g|L%~T4j6xk8Fa#ck+d82xlCX~S3`Tu|jX0m> z)QlJXHXg%X{G$UkT~yhCJiDejJ6nF^BYAsNTD=fa%SHJQ-Z?PIMw`%eJ;q|2N)}im z6D-DFY0Vf;9r^zBC(-2HkkH#gzrn>wM9=ifm2Y3dqF%uO4DllD-`N#bm%~xm!{xGP zku{)^iz+)bmv&C)Jnsh|oemno^l~kTN8NI=!#2tIifUN&>JleHh`^GS^@sKCs(a}4 za%t*KOc-}Hab*%_d2EK%Y$mV*&Zk_ef@lI}7_g|lb!qa=eCFIK5N}BvrY_O~?n+%= zP8gu!E4PHbOc)^Z5US$e6zrf{pQ%WquLCjBT0ImlUtU>llz>s@2dT`WPeAlV@ESqadQ~V~3fJx6NSAn80P>xJq z@iV?MCu)6RX7+ey?tbQzCSJgrU8I^_;+kESnqASHT_u`Ll$$CE|3a=%Oim!&{_!SY zvx2&|GP`>`yLbN|ooMgd>;{!`Uo>KGX$CY?$(Ey_6T;kC_}qEg+(q2n0n^+SOwXu= zvaef@ebL-+nE4y5`QI(dKe^`r5Eb8Q&OcbrKVr?^NzFeacWVMNUt8wiM&|#n%>R`F zmAlS=z$`$NDL<#pL&bAzZp_1IEx@8=YPu*xf))Vj3oBTFC9G%;1(8HmS?Ckh#7Y%p zIvF@@HMm~d$C@Yv=|wCpwb|N*HO;7X&4g8GI(i@BuBcwN@XD=WgkKxIRaa{1=n`+5 z)#$q_B5bhY`;}!~!ASdbN0M?O6RL5#i}Ypc5KfCv{%WLdA{>-dTv!a3AC!~+U45T{ z>^0kc8xtxTc`rAWy4d?=1A==Wm% zJE^Ex$QYVheJO}@p{rRXTBuS;xI|GXj`d~55I%^R?B}b-pygQoCG($Q?50cX6Tw`) z!KS@+yePPd6cSr(65?MZ8qMqbHbp@)fJ$HAYk8Z6*u|D+>G) z&(2r%H@Cr@s@3FuQp2wgMPuaaAj_jSci8z_GWF)_-?e#UovNY{t2j>W!LbXlg5Z&y zb4z1Vp{&{rKz)U&C08fEHRo|-p_PHdY#CJ#Mv}ftI)Sb&9cC#UB@^_%VA>0zVOkAJ z*L~Nl7Ru7K91RwtqqihtunKQ>6K>Z2P>V{D-fkIHN19#IE0F>9jKvjhcD#-RDLnbUaM`Kd1Wo_Q$*yIVG2Px1s&B>+ro%rQ&RVD{Z}xq4tskFk*ZYExm%S3wP(u_;^8vtic6+Lpa_ zWtY%1vnpeM7m)ClN}J`%9i|=w6t*Um?pn>9xqr+_{XjiAAkF?lZoW*Wy|A5@Ldat- zJZm<$b3o!L(NaTrLPZIKeMsM?0^gfKId(|@<#5)}oaXV+zgUGK|L~vx0uzq~!mc@v z(>AO15zkx{XM_dd%h8IJ5pUa(6QTwC+L4Pm=vR0mAKdXru0^umks!~peafM*wk0FW zp_r%T1JN-HO)=d`RH3jX%|F#sElcu13xU2F#lY-UVgMd90{)2*fmSVH-Fo=aV$-48 zLu@N)>lm4|t~8H2Rs0(Ahc{bzSuhfvOft1)h-n1pM)$fY+~@NM(y9X8YH2}T5G2wG zwd~_m!5)y!k=MluyYv>WFYKwor==n8vKI?wQ$_%=p$o@X1Dgg0TRa}&tdc1hp6+~G z6wuZ?$`);?7Ihca{HwTfqPJ3Pt67#*BX_+r&Bxy}gs6C;m}ex0tj(`YU5k)rbBV6i z))I?+ysxplAM-3Wm13&{JBXRK>XkRGFRf*W&45=LFLJIG>9K~+vQ{Rc{hj#i(rL|< zSX~3}?2`pG!LhD)i!if>OE!xLg@EQTg|jAuW@Cf4Uk()HUmcJQ#&Cw|z+H zPF`EXx^I+)Zoqfw$6!l=JoZ4sYy4Vp63=NkbtoHRVH$Y$mVqb}MUK;+A7_TGm)nb% zv105Q)CQU924CXXxdxlNJ$8DXuTmdLG&H55Nj}e#VWi8bM2K_>n|_q2HjLBH|bFFU_=KVQ8==x3N2wR4EG^p>_4 zTfBF^y94z2<#Mq#5fD5+2Xd#0xE=UayyiSB0Ga(#2>r+p7MA3Ruw28nK=>8)52yaV=7m5 zI~CV7fV{B1C_yp3UadmO1eQa9Sq@-Cf4*rRY)xEXJnkE58zsx1HA+CU(0p=# zVH#qm<^X86eUHPDkAIj{EwD8349Qt@Vbw-HlYw~UKXk!P^4^FGz-)`d!EieXlMfo z=uk_f;Jg^DEt$wYrCp%(!1xwX)Q}yJwgs>h8({zd1WpI6gD8Z&Zj{A7l$Le_1GEvvTPki;D`^yW10=7qPv^LQ{Q1Y*?AhPBdB29egaH-Lipakctezoa z{voRV6QZx!P;Ys>Pa#=h`R)G5umQ0R$1{;*-~|{VKC^lFfBU#Kv8qS-dw@lqCn!0; zR?&d(Dt||VAS?z#<-H;Jy#1CF11wCTaL9a|L@6}jqIb}u33?T@BCh=HPb34Z8dI&P zf4=|Vg%w-SKUjYgfq;1_KzJF4?p}uxfdB{vD1m)VZ$db2;7Qp8hi6PBtgT5z*sQF{ z$KsG|Q1rgd$S1*%Wwbm$3@Aq{65--&{uwr<2hyO;`3_!X;mG6Z5afbJ#+2eEA~Bfl z|6iOa`&-g-r7V(_l!g++S}lGgKJmu`8Bk49e>{abHhBTM#X8Ryw)>HJrvq-AV@2@ zSoI^ILzRLstCA$t>mdZ5B$$sXf-)iQWU+)k@*o*LIS6uyG9l`EHPajheQuM$Y%4w?X zwrql6D~~}R=C)0HzlEF)8J{FAI8bawzNIm!Og)%nB;7;NXRAv567iv4qe{Ory;t(K z;&<7*L^gWh%fGh@A899Zqww55k4p(C8wT8A2;K)5H7HK%8sow2JIchchsNXYfiD6z z^sR`Bz_bq4h$K#J>3hf4IjN5veD+|W!k<&ympz>GZXQ?H5=RMdV)^j$+DaDklMYzD zSLWe+O9rbOnx$A4R=3sI!+3=wPxw|IY6VzAX+y4t*>0dn6Un z?vr}PTpi_UHR!!+gxq_}cpw|qO?8`921DI#hxT1VKNMOW8&Tlf>A#fpH`Q;XR)1Hp zFY?$Yzo7oRosfCWUO$+lOyiL9p($O!Pc3SsmPmO5--8Epf&y>yEEHGsEyK-X@}x*d zh}>2XV5h`bhgyN(xMT zSs}Ql6GWeKg=o!^ zK^ANK4MH1p-BKE3pCIEmlJZY$Wr)i)jx)w7mWp4ih!$|?F_|4uV8r<<*n5BICJ73R>xr& zTXPaa7BEl*2f1}6K-t8U;ir-DBs_%V8}+Qp+BH>5L@ZzwheRO^vmD*6VH5&67F`J< zNG5Yg)t^VI9hVuVMgkvwRN$EoY7rDC6bxwALkb>qlQbMMzAt$wzWt_xC z74T>!AHjSDjf}_=mK4&A)?k7^U_~QA=U!f2d%^p)x=v!YO1Weivw%TeKfaQMFF%Gs zov2LkG+ zJ)JHFgTX?^em(TcP*E@YW9MOI z3+~1q->6Xiag`!yw9aAV=u&mWIxP(4!OJDN-Z@Ca2tcYrkH$0Q*`Je1atd%+e4CDz z&dn4(9{g%ISlfweF8WmL5W{1@8W3P-;$kk9+fSdi@O-tTL3Z6QMLgy91GbeCx1+(M zSyNBMaks%SzGJO*+Xa`xtT-)xpf2aD`YWPUXHVUrIW<*iSt##GdS-XP8zK6*B5=rK zX4Vg^<%_%20h)Ox`@QRUa-4Hy@awrqcyF^^tU`l4cKVy`a8%~+NP%@?81MIGM9*1s z!CkeN$!-UY-#F$Mvmf%CbY=BT8WDaQCy+HhabWk{_)3*{@Xxt5s+CYV9ojSh`FZXP z<`+3ZTV0$joaa@Xx0nNwXQNSTxFQqjQ2mv^*I$jdUw(w0bBh7n9Pr=`W3w1nDd5{G zLK%D^U~erXk&FGpWDva6lBcfW187xgkQ+38k$z*;xlBofY!A%EpVqvloA4q#8k|TS zl0w;8NN~C4Fbejj(7Rfoo#QE@+?|D~F2>+a9*XB0#j%n|l@EJbH6{k!r8oOCJI(Bf zSp3t7%QA0cUbmh?3;2^K>XxLJ5v#RG_a|U0_l$G)MZ(|lzKm1Yy@^PGjehIfGDV(& zM! Nz#+_U;Io!ViIsVP_ok(jsJQQNgX{`p4Gh-fLUg;fv$qxX$I?U!MJfdw=Sm zdjItP4*U?@hh}{q#O%BA=apLrQ9h1x{^PZE5j>`3eQBwH3^4k7tm(!i>n#A{;9?k1hK)4l3lNDmQ5o&2z zuvNE5SWQBbZ}jB-!^#W>wph_dSj;8_#~*Pd%QwbC1SPedI+R!Ir?aJ-Y$I$38^_L z@m$e^UIEcoC`@+2R=Pa++#LGxfM6^1I=9f^ZTHVst<_Ln3Bhu@<81Di@bUE zv1S~IaxqP@eTPghGr_rJx12yZ0X(-fG&=bjTbasG((O!=2Z`Z=(a@YY6D2R$FmfV*WS$#+h{SL4nE(OXcB(}Zj2_3$M$TN=2F_0r1arM36fyE3-V7QiEI7(*A&Lb6#! zm%w1TGYT8`SeZCS9JN-Nglb3sUYXown}ku7qHrF6S{XBxcS2m1#$%hpQkBj@5+hIr zYO4IIRFyeoot}^%fdf)Ct^(Ij-jkPPSQq^KARo=_qc@1S_^pR}VI~c>m%c4py=_h9 zWHwPJs?e1BF^ORBcUNI$ZTIM8@)Th5EKc^)YAimO=1c;ct6eQOb@6Uh`p;uj2kZ2M zf3p>^KZ$NybZRE8e-7na03BFvDRwEo{{yy~RGq1^Y|Wn1oFOM`U%6}_tBy?d-7b8f z5DW3FVUDaF;RJ=m3RU?GReKd}E7JW}Mlaoh4zU@=npQlWoEpUCS2#ukI~eRGEp^ia zL#G2@Uo-R}IXwGxk2VMF?4r0rvpXgWLbo#i3~{14GvYn7j7u|K9}^C9lc#S5HRi_> z$i+7J=KlC2FUga(o#k~hOn}4cY}I0i4-k=~nk)^&tnrjItps&(Fok9DHeDM^!C|SX z5#la#rW?65qsTgzjL!9hxkkeIy!;6+arNdyG5%kQ7rRh4dn>86in+i=Y_&4oE-bEW zgm|@*LV2bYPqI-Acs@A%u}54mo*n{Z^-mbpQtBEvk@AW1gE|H}c1C`{KO~7G=#G}(54b@Vp#XqpsvdDOR?=cu|DXtGTX?Jp= zg({hzMGea;b+S}#t+bV%e4;op68QcJp%Uy|XPJ8mLff zD;`I?eC4Mkd3$G~2J(q4j^8hQzYVBzoOrhX?#N5*qJ0%PSVL58vl?j=2e=02=uuT{ z`C_|g=K#xdU`Ok9TMahLuhdL!^j8TH@Tp-~L46@M{pl_t9SgWq*v%LRp;c#$BEfzf zM^B5ieXq2?5t+9xXh~jch#5==wM~OX#)AWML#F2Qsm`IZh#-F_Lz*<=Tp@!VXR=Ri zBb?cptQzrHNuteTqZ81J4FVglT0c z!f&E4_;AzE<YA8cI*#V2yO6m!+c|kY+34U`Ky@z!<5-Q0NAzm!Y67 zL&aML8CmUE`~R?_ZL^6E2(d~FFaHr1lop|drTpp6&dNf;$U!MOK+!M7*#k*M=?3_$ zY?6sXIyMuw{DCHOb3TTnnwDUN`6javiX}C~($C2{&dKn?sd4{DKZ`53@LtrxRjj6o zu@r*(ha0*j6vfpYbVIXvg9HHPPGTVxnMsl(>JzsKm(gj$B@0HmX%P&&r;BZAOKQp!uY2=oRikDtD#mC#po+%sIZk_+vlvm!|Jtj#;<$w{SE;ZK|9o2N^Vrasc36t6fcOcO&P1eQ`^h_JyffEiH>XA|ukSW*zB9jsQeX=RK zfMIlu044kQC7-v8=%|42ucY8O13*|QBD-X0T6?KalWpBC z>(4OS-SfTI@;D<_F{SFkdW5}4`4mT1Bc?tms^OU?Yv)oxBfNXjWo3a)DEnML`F*QP zQD{~NP|wB>C4AkvO0VAiGj@8s_XfzDecFHN?oQdIt}ei?!)|pki2uigK>BYc1UEPL ze}ND@0=9gDp8PWZ6A1B*(@ji_>=S{Ila(Z zKB%jwDCyNI+o!0z75oqKLDR3E(?a=Zah6PgyehzxfC2 zh*l-gsCwkMdfbwB-t_+wfpBcP@@d}p>A(9g3L=8j_LG7LSNI=&Q$R`u1xlbupNJaW zvR0?YzHeOvK0SRQoFO5e|0fDU=YOFfE}HC5T0QUjeLg{mq~OHNu>Tu`h%6|LDXB`Y zXo&yb9rhm(qCLH}ysW&T@cX9;5gWVkUk*gkU~$=KQ`1ay*JAho4nkC~|9>Dv&+-2Y zLWK8z3J{|$Z701U3)yo^4Ga6Ndx!1+fgessQvMtKP<*;o|G&TwlM|D}>%*(#E1R2} z%gev!_ZK!!Hm3e(`{8P9?sD?tV*UJ6eKf?$1L8k4!~gG02wVV>Ttnet7yy&OaH64TI1)&ykSo_%JQ|C~ zX}>ekSTdeSCK*E{-&8u8N@`H`e=;FbX(hzz{<{ewfS$Enp<1Glr|>_U5H;E`Q!TZd z&9=+cM$?{78|^MfQ+bN*&O41x|7Ak_=$HL36T)oB8!XQO zM$zo<_CIF}-T!bpUda~LH)?pP5|RWZj;8-(La6ka|2aQjuKE3sm{0om=LG?bN#Cal zaXer1W8UORe7&%9+*sm8-|d8 z3Nnhy?r9x_YDt$C_}+ScXa#F#ljKT6K}Q-%OpvxOMn2b(8S~66MIp&8v0~xqLp-UM z?1)fYD#p}Dcar8l8b$2SwdcK<4*v^4Z6n6>Shp>9Ym92c6>Mhlp zp;Lj{1f*ITxv;TN0>Xx#yN-dTkFhzuvo^>*`NH%94u_Hs1iS6pUj)^*PNt6)+LK9t?BI zYd>tABCsdu7h$6W9K0hZiAPvxHVI)J7XNW_!hB`i5>tDHUP?F-+{A4L#qt#w|naB~sExqqoL zidi9Uz5bM}xdh(?Jcs7}-ESMFAh?Y}qm01F>=-eF35!;ZE5@pj`!peLV{~VVaoQ(F zS$uC})xIt7W3}Zmeq8_dms2VsSbrv_`v(O`z=Ojif*hkuD25#|1tGXBj_`A+C48$b zA%p*q3E>uN&V-OT)4|IlaF^_QrN&qekdvGmgdd?BMa+1PrG_9&8aY3vMU$UW&%R63 zQ=+2MnViz*7>^gTg~6m62~#bHgn(=q#0)|YmjXgUP-MYkLzspr%Aq5rlED$%gXLj5 z$RIb9>@ZMx?kG9OR6u_k zavUHfcB{7q*=?1I0c->Hu7^68_!`4Ah4rqFzSVdn04=dRdq|RUdNF@`HO6Pf%A(J#IOx4v z7k64Wgdp1aOMI1b+kOAbppG_fwKvTLr4lYNKB8^^R_om zmFx@BhBWCMMclQsIi@^4j7(Q|@NXKcu2n5W?{>w`Xh>4(0X+JKthuIWZB;L_e6}ga1H}WxO!dAsbUbkiCg7!j4)PE% z%DsEQ%qU8nY;m?;OknUJ^ycYd&|-TJW&2-4jEw_%r;UOE3L7Px%lNC zY7A%|cH=dmqAkag#%4v&ScIF2BUjG8bOCZKMys^`F8=T8G>XZGOe)YL(dZhe=b%3Y zL(eS^M`RBw?LsRt_7FE0MyD9YpVKC3szbwYw3a+xpCxH(T6Rpa!i1TX>}<|&pLH5f zsGs*NMg#xeHsb(TAftUehSPovF?s)Gj*PT0+5unepe|@R^)SaRJ`;BZdz>@5(iWAF zI-3--o=xW5<|%3Y_p7hq4uvCJhfEi;L&%S93idfz3?`QAQ18wC;r!O|cTKxA+wN^T z75)fHjPnpK9kQPypFPNVhlZtmnB6y0lSa8fWu4N4_rPZf0+Az)3Ig&EExtNQW0!JX zBXWgxz%Z!(tF5Tf1|B<)cyYpgEUO`fw&-I*zoBb|#XI?ivD(!7+~e9^X8&?z5Ru1n!OKJWNF3?lFr26LvY&v&ecK6=3Y4C;11x z?uD~*pTd5(E2Jc$ke7WsR1S-m1aTsmDC$#v4@ebpYg9EDuF>Zv3=n}Ewh09`x5hf$>dx!J!`H6OfD**^3 zp2KOMJr~2! zaiRk(^9DLsMj|H1L6iF;iFrfIB*2o##Ml6x@DhS~5^g%ac0VQ{Hbx>fL@s(JoD3Oj z;aJY{Il+fO(d}C;PQ<~e#fxeu!A1kCbO9gUNyCpOXkhDqww?=5*2L`|q)%~xMJvU% zBuxIGhBnJ%+}IZHlugT6A~iN7$hf@VSbJSBds`3}AkNA(?laddh!4>JNVdqAJmwjN zfewtxXU7SrK=e1zu@QOmROR_?6AlLJO0LM6W`Y5%<)ahnI7iA*9WCVWjTe{Laq4KB9$hjOz)#sp}b(tqBH1Hxpm=mmv(_mnUnZvtZ#RQE?L(zMj)HnTAMS*fI(J!x!CEm8hzRE(Z+O>ohZ; zwCu0SeY(hl6VF?YDB#6Ok&s7^dCrx>&-=@t=ZugC__$3)xXs&^M@MiY7C)ak8xNi?OP5_b-6@)z%(9G5Pc*4sB(2GUYQbK5Nz~+}RbH zmibta#@Ya+?=B#Zir8-5Fc!TqqyrG7t+lv2337#doRc7V?@F z?#eb`P6V4C92Y`64}KGn$224xD7cQGG1iK5&}1^rY{u9|B-e(GZoaXGpx*#td}GVj zZr<$GD8^v*yyk~(;T57^*&){&#?Y#vSjm*pncvVEj);VY6nByh`mmErb*gb5v;~a- zx`XX)L#Mht*7Nl@5G~<4j^W&C+aMOpke~+5GOKLKc!0Zj9dw+Zxst&VIp}%&L8+dN zL1aA)ZRSF9!Qf0Frae$vF^)w(m94Xd(+315tL&8PMyqM7tm)Ep0O!;=b9#dsuVOo% z5r^@bBVxLZ>224yTZv9>kqZ5W2?ttu!=@{HLbrQjUV6|&I$+G&zRC8k2@Zaqyg}~U`H@>gL*C)c^uXLo+fz9A>kM<~ z9djnQ9&9DQ!peb`!5-uuUsQi|45mRbWV8JJ2IR#`s70g?p)&_rFCcMlzvFfnw|8Hz zUqoB%&|m#_Bji5yw;^u)xb~VcuAZEKjGX{vckc1w%Tu>JGUQ*If>Lp$GX5h@nImXD z5Voh^^AeItCs6uJG@wnJBfUDnTtRR$nA!Y(((xHG{n z*0{-Z{#LXcVDR*aA1!jg*$BGf_{=wPJcwORh3|C-!ZtQ`KR%$Z@Fuyc0gT9e{4$6^9Q?$X$!IQ_6V-d5|z%RusT3h02;+M(D?=Fm-*xq+}Rgsy}@+cn1k{17Jb?lDf5;vbeCwH z%;@Tt*o5_%c9*aom)HZA6}gwW-i>*LjiKX~#p2P+i*dzscm!t~5#n($3|DfK3ASK8 z+`^0{YdKU<Z2L9^B+d3wjK+kFXg(p+QRSVn{#WNhn*Ff>ovHuG&>^3c1bW0oLdK$MoWi>Pf)GfC*9it4Ipb4Vk zNLpgTV528HTD@;I`+!3qk1F3tAp9Et-j9R1BE2YSjou42I8A5Wi;J}8$ZoZ(=xG$0 zF#(@cxW0?g{>|#CK&{;lW+GiC(%u3A!@0NAR^KU6)`$Xy#0-k$_cCIS6YbE!HnR>8 z-X7jy^j#irZj%r$7kaSH9CYIdme3Ii9Je6+I&8gwh8zYL>b^4a zD2H|Dwx0ux>#j~@0D)Q*qL<|l;yw93^vkn}6VNeU!XX8D4ORUKQRegqA)9hDJ9aTU zF_qAp(~+(7;N&9l@n}|$K;MxkN4-?YM!4gIL!Y15_=FH|DNw}w;c;S@0AuaZ{>xtA z&pLGfe1~HAbNF%}ioFx}BcS=eLmy$Fq;L;RQ7e?%8F#{2Y#dJ^>KUc$zEaV2-oUib z-|6qvWHRht zQ`kfZWLL5KfkFiM8zsDX1Z=U}0abY1{agN^M}x*c!u^jgw|@|W?r?&j+ZT{@k{}0? zZg9nrs@Y(mfe5|9aGoDn2;a4U{RnAEH+ZDj?y8TrKc1n3*6asY97$Jp=5SI-X`TCT zK5)^Hiw7Xhzat`&Aw>PgvWB>2oPSm|L!@*;>bZf*fWR&x#qKeM5#E1pW5r1_!BGtO zmE*dqO3bSskJa~ebrZA-C_XyT_}po#mFs&Z%Y}*^Cc9VbVMUSZH8^Ms9YAgmrtn115mP>QMG0Ka?NRLhldp@9Pqg&#LFY^N#oJlB=Giy7F{ z3aT%*quQdC6S5!0Z|%EE9+C@7l2~)|3>+Vl#rS_u%ItRtMMEZ2Oz7aq!HdK4-tp{-q%ct zy^`e2OSG`;D2i97O+!EPRb7KSyRbeAYxSN)LInIfWt6I=V{1ATHPgVJz z?fqwhe82c;6o8JEZ2_$q9xg|5kmgVcqwiZqfpI}Va0mCNbVp>odX0IAV3l_l@dA2r6)aLGe+kSJ+KrykW=Xdj z%U18z9tR6;wi$3S$Maak^PYAbfy&dPXZ*hlXp}2uU52;u>>|a)DeLahGg9}QOb!b2 z-#6&XqbRNakpJQF%^D5_=Ve(EFt#pKx_vS|Qh=--zn=}DNgOje%)K~2_?Mmq9qbjq6jTXBN;?Sp|1>+-gaV60cVq-kc^i34M(GtjXQP=&Aeu_>Rde zG0l;E4#qGF{_2kTgOPo5?tOXaV?-jCw(GBRElVfrwtUu?@U7@pFkgD~$U>ovH*F)X z>bq>OarvZENBXP9uP(LEFI&%+NZP*VxK$jm(@CaHpU+uAq=@eYr=hR!l|z@l4_W+K zpWkm2iGRMgxhWy#fhveB1&O2g;>VaN-R@DF!g`x1SoOqN@T&aw?Ta|kvyoXbsNbcTS|}6EPYU*AuOdE<^B~CqxtttPRV$brIZo) zcIk#QRtxLy;;PskY=_%@Y~`PLpUCz>A@Gk0^INREwc)Ef|JZwYR_SzHnXewEh`D6~ zx~ewmAs!qAA4E(5APjnl3=-fSnu>CB1TTyZ`9g%wBMpvcc53F{(Y5FOE@ca}kQX6h zCUa(7KGD#%6BXRNGD$L@UVY5frwL0@UA?i_uJiKtuOorLa@mi(A`+Ls#CKR<7^EBD?_BGTm^+K;;yDx$-gN8z6 zlqehYBq0JT=)ck%z8qI*=;~GTI%#P!X{72%hf9!ZuQu&{)#$IRFTG5xgmJA_&>m%NpdD7Ej$@mV zrgM*r{A8~x3B{}KDzBTD(eln5t^dmryIPcmY{lUBQ>ibaJBPns>99#pS1m`sTiLzU zs+Z2Miq(8i5R6-UmdfhC?XXpStX1%kTjefnyHiBM6P`an>FRMg7=5DLq<=(UqsOz? z@IlPgjr(iQv#z4M<3X9`n_tZCoI(2Al;ziUY21Art&WxyX|c#{%-9f_PX9$*H)>-Y z-fr{Gg{n11qAyp@%Tr(G)&8&-auVNs8&r;iSPSzRs1SIHP6pgGqK$L20T9&o4-wm? z+QaZ8ea^ap&|izwM_sZ7%gq$qHfO(D6DrL<$qO90&~91~X0P^~**4_k5Ex@ChPSom|Xv@Qd-zv{VaAlU#8Vl z%*bB5eQTAdi>v&q*6t!tV71+Ovf8BA!T2egHY$TV4}Vw4;Am^Z4hgLlSx(M`cl%@W z$>9()>|LG#?t9Ysn5XAA;$9Yg!3gJ{wpFv0gtsAYn@sAID#dj=2j-tatNt7!F9>qy zs7u?DGoF1QU2KY9iODF(Rw4evlZyG>tXWETG-x}{(vj*@7~XF5D)JGU|F&su*1X2F zny!yUnEyMvI$|LwkjvBF^F?aXDb?KJ z?*@^Hu_P(M-V>Hp@vjk!oDrRYu)pfNkBAvBK&o2SZ!*0l8SNGemc~DR z?|6PJ-Inv8(5fIDXcVS247lG*r4=|}@>IQ7Ik&TH&WiY^6b6LtI@L0CRx3>Yf*t2V zzm}V1&}rVA{w-`wbm$&L)-Exp<|_Sn!mZn6>xTzqe0vrA+w1y(uX%&G(R0f61p)v# z6dlsxrJ>ZixhlJ+l|~)#ESm8%=^*jVvBJ6i(1UX$(US(}q_-P+)OcNA=1C-@zt~jK zd~?WT+^@ebPlI`f0aL<3uuQD4SAyxhnS;q<08#@7f(%CNrnJC5%U4m@(F}jS=_Bh3 zqkoZ8SQbnTfd1}S#8!}mpS_7NFirTXDm0ALzCGPv%07@^_`M&K5xRP?r>17BI|e4L ziyE^5j;R6Ou^6VARsy0yXddi%R&6^x1{8SHkR+3&fz0g`-ihW?>dcqxC^zMRaN#ft z=731z_y!fsK*@HDQN*kvCOJ}3^x9MbXomI9L8WZ2LuZd`mS`T92*VszlgcC}0^4b{ z2s-rI(|4TgXRHN}zcl3CY)Y@S@5Lw2#v`_4Fgq&!?-cJyxQ`S*q-2b92td`83 zQAC}PHpxEFVKcL@}CcbB3C+TtX*ySux)7k8()yBBTq=XcJ! z=bpRneR1c-td;DUJufmV+1ax{--ooLEpk670cYg9z-YogoXRm3qPM@;6Ho*x2oWiW zZJXBRKDbY4l#P5W|Lt?ybxC!FLhWa|I?2zr!DHp|W2iSm$k-iXyE&}|%>T?%+6PiP z))QXb6uXH;a4h0QqbJSmE1(zJ3ZAZ>iP_zk8@QJnhy;w?14ViZC=- zpieha+_#xAcW0I1FwB1#30FT?EoBN40H@Z1sj^KO0Si4uooRg)RZpm5uf#O!Tw=TX zGJEGE$5JZf2g3zl#a!ML$Cy-9j^RXFdy_PT?-xLr=v`zxGan{@-4XQB4bCJ})YQhS z@|UH}^b@F~DL0%?Kj!zvJ&NGvo?PiKX&R zy0fK|i_-&%g39|D4mdw@e`LO|g$J-JbIG!Kh$4LZvK}GHVZhEQMT5tg*#@G4F&!AL zgAk2tR99vS1gpdR&Kw4_rzsXsJu9Ri%d3D(`XZHqpFu!j`5$xY`)|Wy{whe&*plPQ z!K$`F5HTkU6DKVW{!g^VA3;mD--q!!vvUWRyfvgR^0dSfmYm?V@A8Ij>ZIRBm)xj- zDWNX&zAkxqEPHX|I7%&l%Ua+GT$Zz2_FY{5PQsnJuZ=pk{PWXF0D8Dr=5o-%@YhD| zz@$8X%ayS2+CkDf!BxNFZnVL|W0gzF#uK;AA!aNnDc#A)dt24Y66el8pd5b4cN4}-gU6v{ji=1ulJHF4_`hCJzs9}lgVD7dS4?~BE6i)G@%T;V9+%2 zWu`2GD5<6@T$?;RA!M~dX}voMj*L81O$Vmk5Eg)BXl4UTK#pKc4lDDtzFM@g*0hn{ z1qqqm*jO}V01n^gDa77Q81#=VE{xss@%NFp*X|eB6^?iKrC5&9G%@iuXKLomCuG|v z=3wJ=fD|<}C9^pNTyK$8_~v>+GkuZ2y%i>g943A>syk9n227dAm!P5HggAJlThTknpFW!V8V`JFVo&D=H z_Lg|7Ko!2CE@0nm>ZnrAiW0$z(!fKXT%1`J!Blg>JlQ*vS5Y2+(0q@3K}`BBQ1l!A z`$VDp*o8UD-aiP;#q4|LTHl~10<)S3yjB*+1YN4i=)qRioB_{p!`@le zPlmWUX8jpv!;j$ga`vH66%;k^N6`!RJKkdY zNZO=nD57FIr7rRWwR9Gm>)V$zEfx`qH}J4$;Nv;rnNl`A4#tQxw`tyMEDA!x@t0Sz z=B6`M16Zdt1rd^my8bvqWYJH}3d&4A%IC4`E;{n*wpLz>kl2``zgPRz2%-67eVTTF zFLlgS#g1jKP7-`TpR8UnvP*s;Cq$wawK?xB#3I^cJa!TECDovYecHj5t{9BHpnF*5 zdI(7~&;4VzVpkQE;`H&Tn%05kdRR68{~8@ zCQK{}t!Ntkfoe7)XgT9(Z-%gJGnHWkk)HgnGxYDF2|*S+ za{qAZ*nQHww8!+c%{yb&C$p+H<8NoQgPVN*TOxOGroC+sf{Lz zlk>GJ2b#SS&dq(Pye=TOk626s00ijiINY*0+_8kVDyXC~?csa!XZmKGtlF>2=HUc>CCP%Z7I+ul03&X@ynx&J7!3 z#Xp?K3wp;JcE^`;$M5C#CH1T1$r=0do$%H=$CV+=mpd^sX`Yfh3Eq22=ey+nSfQgk z8L#_{hdX9bx7QsV@fPbG0T zn5-}~+uTt8Z68D*ksdFNU+$#CDp$YBme6)NNOqe!%mRze)(b7;>rou9MBD6-)uUdt z!YUZG!rebU8zVlte|gq>d}6zXGwTVe4ZAbYp5nn<;??#tZ-I3EFt_yFbwt4okRG&q{SEx$h;IRZGO|#rt43`G7NoQGeLaz6Iqkz_*pm zH!kd1%w$HaHAuM^t~upZ+56SFMRSJbQizq7sLbQ*MvikYYmcqA@cp{A zw$|Io^En+0V?ePeKDSNx_{*EYysNIwtg>p@k|Z3&1`n9p{OVWdb+`QJE%M~Kp#8n{ z>1h_~^}Vg-Icp{)zW94*GE=y|ZNl95&6b}9fBtSwdM&t}F2W(1S_quznOu|i8=xkV zI~-qANQHb%lJnESq#Oh2oGPGu!f8xe{l#5X(- z%YoX3J&*SZXA|bYW0}-)V9G=*A2mR5T?arU-%!d)-cPb6s zmSLH*hE4vt)uJB4yRGUu(P8hMM7F7=ILYO4%Y$)@3jDfeoBAZ0CA*8a-TE$nli3bH zvyU+#;!E5=$*4r!cqDcwzDst>X9&m~^$PwWEfXxLRVs{Apko!c%f2-f454>UEK@I4 zE76ixSnLEAolGM795?5&7`X=|vvs($CyRH01CqsSz?LaymZ5$0qqx`P_9R`SkSIchU!Fe4ivKC42#fjF z3IMY)v{5A}2|Vv7Y?&e+cxpt`El26vwNVE#+|p5{nuhb!#7g0=uEfdfy(dCAwm;Kk zx{kHsChM<#qgBa{P2NqhczLGH4Y;*DOtYQ(Mwbs^Xs0WP5_nO~2~-fEFOp=Law(2W zQT{_$lI8P4UmA|0PMck{SxOrbr`66-QH3I76BimPz*yC^=ELYvnBLA9Wq5nSP}_$R zfmca9Hb$q@z1z;zFe#v@f&cSb;6kHl68@xi)lSg1j)>Hkjv$Zv%pt7fo+7@1>Q8`f zm`1X%Q@e6EDrVyxY!XCm!LweL{J|qWN$Xr5LxyHqf@%WaH*hGqkEE=fc@Xn;h1p_j ziomIAjJ;W2{w8^aC9%roysq=}Pij&F&fyYg(loXQR&Bi-3T84H%Y8^aYR*1%y9n#` zjWZO-8l^s6E08)_JjJYTN*DR&foUX=Pg}M>{qvz^ldS{p|BZ3l>z`bxk^P-6s2mYBvuBO7e-{! zfv1Hoxz%kLc6r_~7YqG|JG}zoT4Y%sk_mDJ0X`v|16Y3Qc4Q>=#D2{BTCO8lGOcV_ z<~LxzYe27ohRwc6rPSp|ZB=p!{8G-Woh$P8>qrB_TTvJeOpi)V@>v#KLIjrW0EE6( zmVI8zgOT7s)D^?4&En3B9pE>bS!5LHV@m8U3mTL-BYf@pmX$&q9!6mFhC+il*!v5Y zIC2hJ1jnZ*A?mQ8%uJ2?uZfj7pa_K7kn?UcQObYT0sY5=7cVV?G+#N)zBp*(tQYoz za*ME)DmIP~)RMtWg;JHSq>QEmUD%|ozKaF&3d+EQ=tg#m=(YE9P4{%5^j-`-+5ap} zRg?Q;I>ZpMfbtnaDc_{)>S?2js?U(tNJY8tp7mCYjjSUU(T2>Ko|k2f2Af`ZQ^RNU zmQS>$o5sJ(AvpCs#WaAMd9jbl%i2yV%-oT`px9TK)X%PK_V zmE&(3OGL8fnKlY*@<^#=+ZdyiT+1~SPVW7sU+Fap#^~r_?xc_n6RW}P6$L*W%8Wi~ zsY}u?*2Onfs*)sWm4uXkqJF4wB2m}jwOneOYpVAAuA#q`UcO8|^x)z3m(c`Hu!Jc- zuQpVe$qc(B1W=XjwqS93%5UnVn>Rn5_O+-lU)N*z3I zmdX0&rW}TIG9V_>%v^JGXw#DXt=`(kdrn8dDt%^fE1-JL&d7e@y#2!y)m}TUnq!_3 z#wf=6YJYNjvyub(ziULXUM-A3HV5)fMzCmQBSq%=@4r&eGmMSf=B|*N3p1t+I)>12 zJIW4fd+}z2V{YEhkADqh=JQupjI`@kFH+nQF^$fDJX-PFTg%v;ZXz2ab^nB^PVg_~ zD(1h4lkd=?!L&5~_kosHdy-J1OGY&`d@`>YNW4W8{?77Fdgz|luc_9W+wv-M3_7AV zl_kFPY`Ep|{6He;7u@U*U+!2S2~J2rvlR38>Q%x8dKJAI4pMrjXDF^{-y#a!MNg4G zbWr-zS00LI{b{+4Qa`sk5?k*JX?2GEd^Kn@UV9PuSv=$z|D)ct7?fZJH{d{4?i_>f zur1_sxm~VtWue5Ks$D2N@LPwk4)E8Xk2`7z=2+&vM+L#Y{)J65?Ll6n7b7(VL7OZqio#?kd~EvGNx{y`0`8WdyD z!j3o%LC0f0#uSp&o*An~E1bkX3Hgb!eo6d3|7&>N{a_*ODdg$yE@U%)@49|0!qkSk z&I%hw+^Id~-Xfl@942<_Ry|b=9CaB5z0_>-kfAAkRVq?VzD-0ZD;7h_PuGe+PJ&6H zE@X@r4pr2Plz&7T{LGtvy{pWG#Da{YdI&lqkX~%zH|PE}YzG z1_K6%7PV?_uVDcD%>RPds^U1&nzu4NLuvRQA~sR&1-t4{mS3{lw+&G3^6Ha8 z$S%|UK+Vd}2=L}2?Zrb*`QL{IXie}Z(Kke_UF(zZ z`(}c$OVSD+cZnN!W8Sc&UWVsEc01WZlUa68(?gOl_8c|3a9xcLKum2T9@tMt&L+Pt zG8yKJ%nymRA0kg6Uj0WxaKap$G_(~kxkN^%vpTf&9*-9k@oUIj4exz42g=MPb`FNt}>;sou|lvjeZ@c{&rW2aW(q0KN&7=Bz=Go zeS+XBW-3XgTmCJ>TUa*{zCTe@*UUBV!ZzJBM6ax9LmQZP#ubkd&7+ zNU;8#zThyQkMX-94w%!Wl=nBZpIO#HCH+rlun_Z3q*Bb>Y`mpT2Fiu%uTM~|vTyk# zraRu>(;Y(A%;E@JiiiS3D5YxkDmP+yzJIoT`pB4`#KoXL=?3V??gc+=a#Dvf0thj~?nz4h6=4@pnLx0WPY<@Evg%%O)|02*DjWSs2 z%O1(fq-99E5SJQn%c%GiM@^k8{`5tz92SFEf|ah1Vz5x|Yaj|>fIbllV0NKm?Jbg9 z>I3Qo8Xy##e4sJKJye+5PruHzc{2D^r8ZNQB}pfxhCn1mu4iGUa)(|hs!XI2tzxBR zwXL+lDo?aD`&r2$E7`*k$?o6`9e;JmXjQj}P78b8FhRPXq#}<%zT46OtC;84v%}6Phgm};KP|EiAk*dM*#UxJp>WNZ5)fg`I4?KI0LU&iZ3s=fy5?o%M zU>;$ttFDEBw``Dyyiyf427VwG001}!uw4g!0*C>6#f-`&Fpi-xZ~!r+R#+T>Ka5nM z+@HWtLa=OuFrlzPG{pX>RQ|3`7KE7rUqxtR-ZLQ(tlX0eVw=f|PBM`CbMBLJg4?N$ zFAvavORySYGtr;foV>K1PhifM!n3zh4hiV z%-8+cfZ`NF+9HL(biLCI&+?L6o7lOs(r7zZ{O#-|T)kW5+}i`KJg5IP3pA3h(Y$Bl}q(W$p^+d6syvBhI$%%lfRa>vgx+DQ+-uD_WBHVRWgi8 zKgudNPMiJ|(`WV;IN8;OReR(OJ*P)@Wy#-w%Q9MbzkT zR~qjiFkcyjoI)dCv^EDB-l596GLW`Fritv)yW1x@`^I} z0@vvXcIha*`cC9ZL3v6t@p4lQd5^IAdUx=A*J}DYf?FN@1|-%FJ=y zidCwxis}6FrkVBHGx+MO(^LJ`t&HZK1S|B9vmA|sfA~Zi;k6jA&SNb8-x6zqg=`VzEFV~%BsH$(E34qV zYGqY!WEWgy8lA4=ujCi5u;E-01FtbaF*hrR%o0?t4}o=rHFaq5bwokc1fPSk8rVse z>ny=HL`Upn$&Qj#ke5|TE$$LtiWj>O|P0MvR))~`x9^`D8(DL&tladJ>=LvJO8 zIA{`>$wZ|XLG{!>>#42l>AdWyf>02vZ|H+KU~n-QTk08mIGBFbGfi_aFV{0~eXTSJ z#_oo=tga>?4YWD*kN8rh0pmT=nY*;s=P74Ls zAW0q5-O2tg;f!%RlHg3R(INE2SFGD%l8_SbGiO?qVq`;#9l{^t<9i@#?gmCjmy0 z1lNOyvTM_6z56~@Z3}!{*3aGbh;NV-ZETXlx+paynllsXFqe6=5S>?5oibPP;hHy` zrb+z}9}*g<<8B^LUGab^)xuTw;tHF!Q=@93(4sFmrK4mp$kK()%0XfMZ@6&)61$ie zf_)m;=g-Nv%ys!*9tV`EDB6S^i1lZ7AE&CI=bKccxD+cAv5XCuA8fjUkR>~-8L8H= z99*NM3Z|NuJh!DPee=$nc$0zTHoSs=23;|I)t>njkiD3;p8G(#G+5+lPZoIZNEjDb z|FD+yfpfaayrw=ZwIK;ayH%F3CBC8{H>mH#E#zTMX_dWtzv`l~xarU!$p)Tz|Ft?9 z8LOIid4K#1Trr>KK~QM^^3ZfkP3L&URMT|MkP zzIlFor}q5(@l;f0+}u^Xymg|+A)J=^Tn_czz6~J$NC*Cq|F^l9b1RkisW-MPeK+^M z^6@SjS?}!L!J+dV-19_C8K$Qz2ehe$^jHQos6~vvBYXRlUsi=nE)~o6^{3wdm#q)u z6b+9QOUW!3?Mh=%zOiMIgG{NVaha!X zlaG9ZpL(N>4H(=1f0O!nP(1isSb<#DJE^a?tm<%TZTD>M_3Qd?Ro@mM-yWguR{joNyrTXK!-=`aVmy2xHs$I6~9Zs8F!Xe?Y0WrzJ$tmw! zLw+terzpJezj%FhdvMD;uWwCmDJ(3k%dKfDYHVs~3JRJ8gJ%*Gf2E`>1+}gPbRCuq zl}66Il@48&{XbQG(-E}i7TWt?s=l|Vd$g&jzoBEbJ@1{@Pp3|d6bz3x{hBG7TCAL# zX_{JTU4Ga0d)>SLt?l2&BB67UZ;Kg+)BmOI*SeuwmA7*}hX z0LsY;<+Orwrv2wwPAJq00JY+TT3JD@(*AR*6%?8VfTnRm)2yIrY5(ad4GNtAKqok% z{{{U2)A4_G{odF6$?r$MH@{yB2@3d#{Qn=;6B3pFf5G|&S|tgQ{|)QM8q59z>n{^O z6{>PjMG<;)sFYDJR-%uctDKw+uqKb>OWE}fhb@;g#u2FYDVA?^czeN4jiT_&xx^;y327CmzWfFS-hz;U{9EJbS3RFxk2sjQ(eXC6-JZo@36ks zRH2wtOeRSC3j&&$cv--Ht$CB4QJP)I6_X+BfTNgx%O%>Vx#CfTPy55!N`w8@R9DC2 z%3{xd!TQeUyW@Gh57Rg?pvTj_@tiL`@33BYb#H6Br|13CKxmEs0jGt59RN#Hx*dqd zb4;#^#AC7@grjA%6N0aXpXY%uXOk!IPv#O- z2}8nC*yEnn;>FWOvD0OnSFtjx%0|^wg_Oz?Gv{|)k+Sugmk*TPKS+-x@ZOXeae`^e zkMkpWPLB&>Wf)Eh6SeG4ic+o0Z3~|_7AW$nFgfxR!Z3D8{lf5d4B>rGjyFsBR=>B+ z0jO_v`ryzpZUL1ag)l6_TH{MId?_!3Ve<0-X^6+x?#h*yvmK(8H!#+<<0X(p+nr^Q znVFcBb8FRBDu^cgFevT@DkOx9CZ|@#u;8Y#v@st7$?SZl*2TK_E)`iJ|BBbdT5s|r z2q{SV+ve(6P6TUv&f_y26n%D~sPo16)|EHI#9rq&!&#^IRi*)?AiFB4f{;lc69L0H zpfCU2Y^<&M{!D>2{e_hRrG=|})Uuk`J&S7^=d%iV{xM6c+yytw^xQxF>WLs+L+tYF zsPaZd{zGDmXkjud7tx|&wc0FTZuT1y>I#hOEWEM2K-Zc=Jz`CkUc)x*0XlveXM-ZKyZQG$`=82A+ zqs@usjLJM+Ix-XAs=Gy@(308TUpF{Aq$%kzR2E0O_tmbZNnK)>A921<)?tUYCWW=K zV4pq`<@omR6}>#$dfyfhAM5pZA_!auVC*lXyWBR+9Y<@4 z@$Tr`Xc%0awi?n-MEG#<>T5g?64EA}u=@T3>wmf#4fwfB&ml1x6r^uPY)Z3gq0buc zWI({~aEb4godKMjc>s@sA>W-FjDcO`oxx91j9qpP*k%P!W+jwxwvG}$RO^__&AlGz zRR+YM?K3WZs=BIKdRYvPEbJI?If@y8d(&*SLJA3cD=D6uqd^V6mIj+`?KZh}A`yQJ z$QZB~ndF30%$9*A_PXsz-3BV=NJ%R-+>~-0h%DxMR-1T9g`}-a6ys%m!{OKbn!YWh z#(l6iu4i|bc?=@u9T=VRYNp%dp5yAshsR-PE0yZ76o;gf;K}= zLOV_deNt?z6+?nqO)H?SA#_-NJh2v`Pi0ajdB& zU?t5;(#9klz`*5%Y-G$lHeop_K2DW4RLH?^D?9yTTV55%a zsF$vU;Ysrnb@g{gIJ0rAbBUH#^xiAOx3MjjVRw_=ek|JDj75aRe3+akVBn`tog|DV z908?Tg+Tyzou>pf9)cq%H~=^sii9zZ501^;q;x-kW@Xbi;1hG~q@vm6 z2mT>m$W;RC_l@)03Etxd8)>Hty>q%zLrOlDqcsn5~-%S0x) zaO!niJsWw(wrh2E$pZgm?0~*iKkziO(uYpix<1WK@F8g3w@vTWRZ<$1MJ7aegOz!+ht z{%k(cn|@ICuQuFZG3%%Z8$HpL*zQdI`$#PLs)p~Yn_d$<&J=}mZdt#35JZxx+VkjEUyr~1bQqidp^#<#_c{jp({}C4Pr0rf z+QQyo{6Evsf3L=97Gfy3y#Bx^tOqau$ge*I#Sx&({{O;|;qe3D!TvZ%s@TDJAD)m~ zRZu?2nO2&jR#W(5*-(+wk$#d3Kxt*=;3Dj5thZw1mv=ET%!P7Ptoi(*g>te1;WrHg6dGZrn4Zu=DTw-jrg8VqY2 z0m~n4paZ_}0&9j)^R;5-#zM$=gIHUC5q44)qi%Hq!(+7= zPi#F~LrUlpUXUW1x5Lm@acEW}JW@i1;+(QtwG`p8?V;4Z!UWjAY@!5beO-=&H|fGv zTI09*VrMlYnEHawk7F3v6WH?Ny}?LG1Yic37>u+eX44opie$A>tjniZbhadaB(Um8 zlu28(ptpIre;6789ItM&lROw}^vC<~YsWQ?aW>8@H#Gt|$lM>b;5s#TJAeuqn=&<0 zo&Z~)KGyFzRK+F*LpRCw1WQmCXP(bMbv8i^lFr~7B~_OQBEU`~aDFKbH!O?Yf5JNV zPO&@*D#cIXZ^LSWgz)vn6xb%WjOq{QVta$5t&md`plR`HHnC0+BoUBY~^X}0mo$mZk7sWZ=+7=&5us~N7gIlkXQ3Lr@Mr&!81?|%t1&lhv) zpEC>bQ)lE;n!jZb+F`Gb#;=d2ebmd_Le8G2&HfdfnjZ_vy#~MiO65Qbvav~Hder}k z3^rTMJ1Pw)KTi3;5cA5P%oP{OyOUEjigP&{$#i4WP)4X&uFr;?f=QS~!%(1?R>upMS!Oy(F4_k+M517*+ z)In>l4TzwJ#M7a?YNMoihhETQ$IuiBb;gBgkA(j%P3Gb^p3}@Cwo8KQdNJgcF{%dZ zrx&s3l~;!su~PU-f^$iw^!Z#DY-kST5iK~(kl&3CjqZvTiJx}=2gmmE$Y9I z|GrbrFJ8k+QF9bdaWaOD)>;ik4A?TQ!H2Dpo2}T`sq(5TT+|B_45)p!qj+t{em<)C zi|7B*w+@P*QKyPoN4Q=``dU}fR|il-BbTqE@vW!JsKQ%xnv}cN=ft8G_&3O9G(wMX1YR5P`_aU&k!Ev&F)BFaY;fpe zsB8ca0l?##J$+qwP!TK&H9=-Ig^!;Bc+GUi zR{*$j0mg!;XfDVMaR`a8b$Ms+->9CHvKsWVepp&2H7MR`nl?V#?t{fxzVIzNLj{qk znn`*nabrKjsUb)*Wo>K_a|}pqxJgw6>fe`|q?ey$X$9uFEp4$TQ4Fmd_(2pxWwapE zogyrLZzE>c*1=_ffV3YyZwD)T&#wyd(X&={LEPC|1Rc~Sasb*m8xUc;%kH{+iU=5A zK%_&2+7;W$!j1~MZX+S;u^Yjnq;+J#L>dhH9@}IpXxh%C>HvI0K7EdB^=*NEwePUl zE=8p2r#@@P%k2Bu+A>hv_o@xCxDF&-DaGRHNDPM%(zQgS^&88Wh%DA49eRGSGFb_= zW>H0PKn&xLBohQR#rwh_F*bc5^gW(7raEEnV=GTws@A(U(DF$R|22EZwgFtfR zyiA1s4wT~GSYEMk=&@tXor7AHSnk);Es^8kB<-&AAqW8^Lf^eM9SyqY`EBX}YXme> zX+Qb;IE*wgNvtzTWZ1xe8rMeN5}q_cNj!zmgurh%rD&fRE~LREJ_;V!TyDmSKQ}?) ziDwd;hEbc|t(ak~oBr#tpt3#)cimk(fz{Xx*zA~Tt@I2pGFd^KZGS^%H^3fXauTVV zB}0A>2Zj7CX+K*n_}tY;WV7Uv*$}NavX%*Pc7SXVFQ=_6CD`?y>kbb`7Ovvd9;+d4y2x07CqdWV?s762%9}u;oEbeG@77?(7r)h+!}W@x z#?H3X&E(eAHl1as_2#EoBGg40sO|MV>qW-xiwC2oicJz3G}cLR|6<+n*KssS@m`Nd zf>4kI={|rd5YuQ3>IG2>S#~;jJ9W}WO!9NpLzMgwL%*MNuA~w-siOj?e1Ux14W%Zq zz5WXfJJax8Xodi^WZ^|w=G7@wcwrRrI`_k=EgGWqU_IW>!m>`VRFgBtG3MdSRc-3M*%EC1V9Aw5vd z-rslK*Z6TDLUEwiePFP;uX9PFm5pQndcfbguVaa1n0;u=@;=RS_yhA$;%3`%lh854 zIFiZXQRx$(SXG~o9W^6(0WAKNA@PCLuXZDA4-}hMI=nJGr zM{JmzsheEEapTU9BaaoWXv1e)RtDlXCr(7+RZCbAvA!I2Mvuq(bJXVLJo;-!-)5T( zvk;7+J*6vbd22=gu>Q!{4G!rqcwk$|7~8j9qO|#%9$v;FUMzj`;i0%FExBCr@J&p) zWK=bX{%~TWjE0AC0>gGTxDC%{jx>CYh<^<*a)H6#K2fLWufwBAL3Zeh{ z@Y;gjY!X9!%|?OF&~wYQb;|<1Wh1-e5WV9vzT^3M$Cq;_&~qmwdbdm8qt}ULfHwWI zK5}SuI<>63H|0*NbxHN7XQ~=oBU$6-(|17{D=SZ1bzWDsj~5zv*!rv%S=LU5S{6o2 z_igRiSiCsfk52s7csf?t5x)VTOL&{^{mRSJrpxOh6__HIv(RfmkPA!^-~hGf+N)N9iv&#JSdb4d5^kp0ofrz0%kpUo|J9tWM^(0c}1_YB0P z*u(GayynhOzp`St*GpTCL!%fkY{!^cwg7t&D-MwNL8b1Gvk$iER+O~rBP8chQ5g*z z;{^5kG5iNipFd0pbU*A0e)%UFiSZLU;1jF$d$bn@U13=oLCww)6TU z(S)^r>!?};SyREINOIJZiz_pH@^m4XI{*cc@VHBX8~Q@gIc$~R(rQ!l%+RCXi-VaR zAJ?hjgGs2hV3z01fBxg54$Z?^EcglQ_qV*UoYedm@GDA^3rIDKX_uDYm@#Ebh393e`7WrMIy>WtU*pOnj}rwuc@K|*XeRVNqlE}*&h## z>#ggI-Ik#0N6D9I6?mY`DdX2#D8oMf65j4u0@A6saM*@7T$j0=YuP`bw4e6tcBxS< zG)q%n@u^J36aLa+WD#U@$c_nC?cB} z474J$e*c4z6nV1Xu@sZR07gVH`kkip#SK9#&(6G5}w{d~m{nG_i*@Zh0|0TL~SZ#er%xDgt195%IG zS+02}z&@ZVeAe6_@Q)861+`OZnxS%#Xc~jn<)*(ww39Bhs}qQYE+Ie^Ij%f~rC{F! z0|j!ah$F%`_QHLX=2Df$vusqAB@5x2Tg8gIFS%hE;!;=orH=&dmPLl=)=-s&Uz}0+ zBF(L-scosLhMVT#QKIv4qftwr+b~JP(CeUSd4!77Mawjdx>?6OM%r^lKgBRv(>N!D zM^8dYsaemyW{5}MvE@LE%C-ld*Wg#_MYDn1v^1}weVV10y7f>9uhF+xN^L{mt07+F z?~L{>TOhYAUXy^FD&BRqKhk`rA$T&!r4yBREr#nKKG>N=u;Mmtn{VWg|0brUM4<}B zBsm?Hk|h16nTYqb73NIAmUFl0o^A+3xbchwP{#0Lfzz~Y=f9i7M$>)_!|lY~moxoP zD*-Maq&wLEkgiOX5wAo9sNMF zOp$xm3RROP&06`*ig*)SM6OS4mEmff0(48jCXeg}VD25*Q1nFhr=(OFkY6 zUJ)lT+5w0uHka!fyUn%uN$Nuu2ACM31f#kvSS{QR8of`6H6UfELM=%@rWRk1Q%f>{ z?~`jp&!7_iK5B&tY8CTrm5AiIxW>=Z=>`1j#cgb4mViAmHjsf6%R!c6b!{-lAEHC= z$V1`GHH}z5p9i!=_W9EgkV|E1wFYC%*t!*(JH+l05r!AWa6gYoaN&)tpC87c^A$=c zq+*!f(@BneGgWrME0e>Gr=du+`0D<|Q6gput4m2a$%28##asu`?;8T5VWJ=t@B1NB zgud_<55G0unBNkavz%zlaOU4IKa74cyi^lQ*pH(D)_sPF8g+^Gim68?!|TTeMN_3qAg|Iuzpcn0%7-vmp~PUN?0z~T*j2J*AB3NJ zPapY{knCO;@j`el-F-ZlE4^1laKl6P=b2U1p>qBdBq=t&T?bS3EsDd@ToQk`I9+uw zitD3BCLFFCHI-wpYomv9tU__-7P0(o`GDj(v8CWf8m)Idb!&} zyBt!pK_H+(|08AAA{rjykWx5&v5W;7l#(#BMR6Z28@MNET5MS}kBR1@o`a>Jz7}(S z{1A%%ia^qWOxse+bs)22h~RJ2uG69@JEr!pjGX>|m)d4gSX_$)4Nnj4+y442yEUy> z9BVCiY{5Hw>o*zRUY2+4N;~^35|x=@40K(EIQtz48ox~Ob{q^{HTpLhy)Uopi7R*Z zhZov@M5$JLmcGuN5@gK#yWIEjFxgizPXSiDwI4eH6v+Kn0$(uZD1Mi!poO3gO+Ke} z22Fw~{0QLir227^T{4&qwnTy@us8Y~fTS}d*&a6{V)oY{9w7^WN2{vBT~S-AJhkY* z6gw_ms;_#jW;CCv?C;S-BCUmtg=71_TXDi;6L<+gdGuzfE2NR)7AMF)vz|t}ui3r6 z$k0Avaz@k2WXhzWEz9kYAg9tP zrjT+U=acCv*F)d8r^hBRj=bZ_`UsK=RH3G$$dgwB_al_f{MPy~<|t`F5HS6!LHr5% z!|S0D>)=|KZfFguyJ0vLj|pthNE4of_|`QyG!sA2274mjaHyz?H3G^g2k1H$vu_b% zUlCcz_&a)G+^*^mn|DksoCtD{X*x>AEO`%59BKSPb(|(dr8q8pBJ(1|4I4&IZH=F} z$6!ct_3$*%#3ZFBOU~>w!ZE?aVw{>Kv4{4v7kJ-$X4#>WY+J}r6k&F!)v$EnMT<6J zp1uDQMJlz7*|xRCb|S~wCe6o+8}UTg#iK>zGa0ux+5z*4ncY0~Z#0FnWfbK$JuHfS z(0gfiJdR4iOni(Kw%VZ&EjhRD~gyZ*18kECoqG0zf@I9^~8 z_YiF9L}~VLw?S=$otgX6qmnYG*(1$3wwFx|12{|Moa2DmzF zcpUiY69gK-#xGQop#jmc7lgRlvMicDbH z!DRA*LFK}JJkDT+O39RKD5@hW+?QZBC9dR;dxH*XjlnAHA*n*U9PD(0Y23jBI_`BO z!F41H^#YZ3M1njQ-+GGi{cpa}`OqWTU<64=GT8cuvbhX@;gi;IXVbL!MD@yE%r8dZ z-ud8Dp9bbwPvzj>PiHjmF$N8=ymGuJvQn7wiIO8UU=rH$1zU-MRWaZ>^ki&-pPRmM z*;BDNXnaa@1G^8}EE zK9Rb>#*kVrY zCSzaGCoCSbggO;}=&#$)q2k^E6$~VsSbiG^8IHivr`|wTe*~K+SSF;PZhr(ee*_Lf zxNu$SfJ&CY^P)sXaKd_i;%jrSd3T)9Xa^VlSA9sky^t;!7mh7&ly?hSdvT9nr%y&< zTyM)Z-6*yKMFJD}Yhqq>d1T;Tugo_Qh)V0td^OR5eO?Ot$}bxsMO*)vH70nQ`(F*QV2c^}W)MM3B~DsG$B(&u$3nqh79-v6 z0$of(LV6sz83K73$oXe-5_`%cob73~?XE(|vSW1X{_R74I1}f}$AD?Ln~C}Lc9i4x z8dO2@$eQ|wlIaB@VKf~CDr5&fV350}X38Vs4k=Ot%asy$= z{fV|!bTME>T>N2F0`y%1VZ;D(D&Y4fSsQ=8>qUf-U|=o`e6D(c7#wHsypUz0a1{<< zKeAGS8Cez5{lX9Tf0(YPRsXBHs;dUwvmWl*9_+Q=z24`!uUogLo<9jeeW9@)vw05U^PK^8A%a+l3%#+s z150ebhti7)M99~RM^}kv-aAIuh-+RM)yhurP6QyNtRQM^LO$-DEt{V6Wg)X4Gl8j! zBTPgh4QIq8s!`Og@$?pvf2vG*UDWfk28bQM75d+}^ zX3)3c1egF2NEip+Z+=v0Qy3IM7Hmj2cg+w0OSzdr0NmT8&UrHP`w; zXe@X(TSI5m5r0i`U{G3i4ZRqqj4D7TZjHTF^K(xAXkx2#HU%V1tJ0;-d0ec8fbUt{w?5r553 z4Te@faK#|-dVLNX(L5puVh!NF4%Gjy9N4OF$^f{q*c4^lx^0p+WevTz*m`i=dJNrq zO5S=9g8N3_+I0i^;~30o&SqYk18& zW;#YHWdUM6+awPr4^)Ho2QjvtJE7@2Y9@mi(dDCx6QDhgB{3|67zsMZ0HRHk2e{Dd zXOpKz7-c+IA=Xe;(E=pA(EE2{IH5Rzi1rpIcn02B+KO?;hH{r&DUHGs%Rzn0kxxCz zp8XwZIE+#DE75?9WW>|tuIkF}v>HE3p-dua08M07xr znM0kK6x#@IFgO1h_mTN*e_f1_dnL`sJ~QQts6=lJBj-iss2(@3q%LQiJy$$dOL1YR z@!{TyvTTO6Y_z9rzx{eol2nFkuYZ?p7#@knn(Qx5I1vm)5=W#E=>8sBu6pdJuUXZ;Tn(&z9i@DOqzS!$x;DJpnOpKGNVC^b6CMimMe=B`3|#xSOn z$fwoOcuxwcA+k0K26p?-HhJ8k65M8fpa@{=3G)NA)8WbEy=C8!X};rD0XG}~d#0Oo z1_oQLl$rt_HRGf6!mRufr=r>xYw$ErMJ0q=6jtFl9LEmVA+K&TPlB%$Z!Cg{iE^~R zWbCg>WRGAEfvOC!RGMpUM*e$Bm{r%Iof;lorlXPcl<9!Gk-aoxp8L^Y$`RAW9Lx8; zQR?|-RyEGW^YV`!C%uYkW?@r;1sJ-8+JCm!^6Di1ch27v zx#2N;P_>rhjkWOHwCbZ~(M>K8E0>WwwXmm`snaq4;xLZ(Fhl@)12$+u6H3982W@iN zExL!(b}O;(A-%(s1O?0=b#rEgNLIT;fWVn3fR^JUF)WnKzN;eu7zc2FfM!eu^!N|K zi>_|yucr9vSVyd;4+dp0g=I2DWMM~G2K@J2ed#TK%dNoht>8zl{^(Zt@m2)kP89b} zaJe6u=T25OMN-oh1;=!%%w!br4w8B&TY4wgawlJUCoXa)LfNnFrSF)(Ersj$v}i2V zd#5IIuda2k@!3sr>rQJJ_n!D(hbQ#qJC^3~z5epO!LXZF_`Q*gp&{;r3C)8kjVmkc zgLy8qPN|!U2%Ie2gLUeIjg^~`)`Q)z6lJFe6_$I+{0Aq5M`v_bJF6s_;Rlx*M24j^ zhxaYhaX@DT#-nHIqt_3Yub*QnnQ_Ak}O zrTzuTsYYari|`0X^lo{IPIdQr2MQ`FQ3XQ+^qia(1Vxt~bMq8(y49TIg8e&kNX=R&lb zA!3CG8I1>4v0t!XM`lheJ{ul4`wz+yKAXm7hZbi`1~!#Mq4|#k33a zrl6(2IUc1s2BcS?WKNxAU)n(7UiKLoi2%&rBqHwG(7OXMHf`U1hZ9~;Tl~dJU(@)r zfBu`VH1u9PJ_U(5&BMP5?Ou%GwKr(mQ64M{r`(8=e6FeXd&oJv6a1E3)(*4t))jlA z0*F9Hg;xR`$e`1*6m|x%A6(~`hawa5!@8MZ4T#}NrrR1LF89Qt4q<_9z8crDkwwDU zDxc1eTC!WsRodKAPi66Y{5e0lrJ2bS4+m{{{h?JAhorJQoVwBt|GON6EWaZv=X#Upgp1nj3WmW&WEy!#)=^ zft+U?n0p$Bw}yU7yr?Csg-oDw+ovgbT_2f-$qC=FADg`QsiMi4oa$PEFLb#r_D zPLhg2<5CT=1^t{)QYG}I$DjK$yFZr7;dJ@RcRMX7qGt5MRz$mt8pG2{e-FM+G@2y0 z(c8FCq3jdS_|%&6LOy+Tz`a?*Ousow%04Pi`^*b^Xqp?9OS24dK9Ff%8u z6hDMsMhaaKNIVhcVEo9XWtl?Fv%V`e4KMg8N5PW%*mgbcd&LvC8X@SSHIBfeQi9S_ zjH4p8%v0I056NGI4i3zwm2Kt%9Ef*v0?{*It@PgwqV^AhY)L}XQ?jettki69!XRl1 zd^iboh9T;4bj8PPai1_vSTW#>d#KmKNzr!mZSxc`5^#%+NyT755Y`BYq+@9Uq{pHq z8zPr-w=3EjkhJ%s7fFDzP6VEgvVN4l<3G9jzl@Eua^nl+kqVi(5v#TxOf4Jyt_w7s zB-)H^2N^!qDoKhSOdS{Pf0;XP=9JrUtw&ALKdv8JKgnR?E^A& zvi74gC@B2Gl(!$Fn*;f>4dJ7^RrVA6yt0juMGLZzD%tq5kI_vJd>Lixcx9hp^YB&p zp1b19F~xV*$uTXoB{;@5TOr6f3*ErTG50RZ(8W2QyLisApd$a)Fe9bs*HkML&geLA z;Pb|{GO&6sMXHwR_b|D@wTiXm(1Du0grdcTu}m>-L+k-L!RNLp7)(F6_U$L+Rpm*{ zZYHt5Js&0wr2HpKYUuf;;S-+mHXOBGE+xEL2FpG7aXuK^qqANvnP>E~wAVtRFVN9g z9W&wHsJ`lB26KVBGIdM(gCXa(xYln@fHd*QS2?i+opY=z>6t(7cve35((H_+vcO$x z6Dey_iUbEIZuYRwSdlJSR-PtB2|H~YF4PEB}CVD$sgwFYOqZ9+UX(X(tk0j zb_R`Z4|x>I?I`~FW}11aVmXfh4&OadGq0c5`k%A^dJQ5fGSsD|l753gUdzVlqnI1P~ zP~U)=Aihhik8gvuMF@F9D;%Upg%x$7H;Tei?|nt3#Pku6HP{VKg3X>~`2n0T!pJY> zriKTq(C0z+XCebfOyp=riFGQAE8*Il=t2}y2=>S`64n*aX^C>Kgm)mBJ3C z!Fvmhh5$wAa%z$&a8@J`uGOE3jZWQAgmkJzUI<@1K$YP`^)9-FBd?Q#maB^LL$lRX zbO4cq#qzmWHV7!a)fvw`B7Vqi(9$jD*8mlQQmTejhBrie&Gxic(!i)TQRoa`G+Q)9 zK1eJN?@kYbf9hFC8YQ8cTT$4cR=tx_>iOR30i-V&)+^G}p?9ywm%4<*OB zsj`s|em+BZmE#DISUAZ@8 ztZ(sQ@!dnNvE@7Wc*rJbJ#{B}_|wt_pU4sbBgpREmZbA9cy<2r=XRD3rtX`cbI&@% zHc+j#Prh(9h{K*EPXo1&ggGUIiE$S*v320j3u{z3wkf!wb&xq0CycAp7)^k8ko$5r z%BXUW_;$sHeaSgE*KLpNjCS~G&gn;D<$fIgWxR-H*6&^MeL9}uk@Jr@y?%;lB8Fp( z&_kw4vqCyEi&yn?*6a$&Y5-(2^~-8#)_&~pJZ}kXowI5Qdrq|JfhFB^9&_fgDqwY% zc$k@Go-;0QoX9%y+|lZA!ueVk(&=RijqXXSSE21M6)P-T$AOkvi{9e=!DY)vk#gw8@3a0sldu zw|K}`x)H_Qgd190^{p>#X|(Va=nCYNR8o;<;#d{Vp-f4XC`_^vLNhb70*gC>YkZ@< zIPSdWI>j>1cPDQ>))4iyQU%t+=;&{=XS$c3C|M>Bs9}wQ8k&yX|kkM>fRJT|aPLM1)lhD6upHjm{}?#H(A^AgDNur2d(`ViKMClYP6{iWnN zdHZov@NiPd2)a=MccRgn6@vWocVSl>StUMdv^i;eDTpHICq!Xppiux4kaZIhG+0K; z9sm*fr;_}72n+>x0R{K2Y*s$G5;@h>1YzIK!c1BR;%?wTFFGfHfzlL)RRV<4L(1Jl zd?!l9JWkO}P9eQZKUBatMXocmLqYrAOIAV7k=F~r2tbP?<3J3gz~}{3_AoJ4zrFVxr+Jx~ghzU)SQy&VBGJqvvhete` zQn*M`smO#VlHZV0+H#-2Ia*+sj5Y`G@!sr+y;MZzFhyeI70`&h=8y?-6kZq(*Fctt z5LspkVzdzYZGaTFyd*tJ!Ud(WY8r2BAQ?)KGzpbztXYzfw9MfSF`_w(T##%D6lZmx zT*d(Lz9>v9rTo7=u4YOYeKB!mYWdH7$SH68!x1`BMY?Afcxm_q+qD*R@#(TC7Amo3 zqBeMQG29BK_&#^*<@0tIk1-Rd{Sx!yBc%*iaF*Q(uX4A2clsi zvKf-B%zN5MvO3c8xk84ct-rt8VC7@xJ_W4%k{awD#9ri?8D3HurI_uZ1gRVzkfM~} zZBz4EWCAOz2xITOR};vdTKzXF1*E7Om-EXV3!%yXhY9krIC|N?Z<*HTEmDM~1ezityTmW#*wt}FJY^^{F zv2pN7mN%13N{>)C&NpkJY2&C_=(yfZ4>3LKToU3$U`ZMQr9x0*0$oBzB(4(M>qr0{ z`G=bCkSaW=jCYFKgrHbee6W_P#FGoIn+?b6eQAdnx|fy&>f`&NPXn+jSXj6pu)9LB zN*;YjBj;f4CH*ZX`1L5z)2abLgdz2*ca%)GO7|N{W*=Kts-+=JC&G)l@j!CCd~y6> zGKq<=A<>t0HP0-s&F>^P@t@d!j|O79xti!0jE}>~Y{wLmnIA{}DTzQ6H-6j>@+ z!qE1E@5s?b>8!~W<`)x^36d7@^%u*D(`*f4U+8O9hgZHBQN~#>Z~pzp`PE_=tJJwndJ|CjTt<-j5FoGRz8N8HzH>!Y)hX*1EduB)dO2%_Zt6s%Mrn zqyxPRxlx5}?myceEL-_2_;4(vkZg-$%?dRul-tg3Fl9CcD?6!CyOz#w#js6)nD@k) z_dwu7Q?mD==3_jaZ8Ooa!TAf9)N|nabEM=;pu#K(qs1#@Z?{p84P#3zg9^bZ@9v?! zJELI~gG0{Qa>-A_hg@}hO+eH#pacTdeZD-v*g#AAh1J;8a#~H4w1;^R7Ky>y?If`C zNIQ86z5u8C3u%UZ7-C;aJ->C@Tz=jIR{)YXHga_iGPV6H>@qv*@+RJLGnJO_&|$d0 zUAuc(n18jQZB?uAX{7f>+gDoCgiAwc8kL)Qa7rmwffjZ>(|jw_rVS)V|ZP0EFSUyyJ7aoMRs)cuAMew+W;&E=wDo%-qGbm6==qffS zD>g~G{!_<_@tqki)&Ba0${6Wzx!`z(eb6)m_AVm?;hhx&p$@}}6_IA#+EnM%e(UF( zgKaEbU%9hk>v?ytrAc-n3e1(mp{2?nOG9{Q2WTq@V(IPc7)ELxel8n<)84n$3P5~@ zC(b7?)!DimJ0vZcY1J~5R+=il(8e9zrjy?XXuAFn)Bc;)UN2UCRDZmYXdAE-2GPo@ zl1ZA_%HVA>?Zs#*bC+5)ta~Eu!@PeUJ6cD?T1SRm5nu@j~Y$aT%RdO${=@Xa?DEQgUia< zkexUgSu7vL56dB7usF7v4@#6DTxfP@a=3H`qTG}kFKI-2zQuw>cxzv`{#k@_C4Mj zTHlN~e40$`)OjfeXQyQ6K!~H14<;<<^9k1rQN2UD4iT0Y!x>yF8P-L+mJ0o4hM5jA zc@Ez(jA3S)Y-_kN)|vu)F5)R=Vdkn5)H-=?1YU{l#KW1tlLw=pVf@L;+^=4TwY{}o{L#R%M1D4u=vXVwoSnDSC-!7f%!8(wP#W& zWaYm2PCV!6@s)b;B@1|G9koO5yozf0(;B?%toU?jeP9}28d(08B*N8=KdTsfH_8Z< z3kbL=^EGy~j}N@Jx2E32bRYpjB=gr^L_43o7TQYe_?tQ4YH0p8?zPE^w%5sfyY2sN z6cF#E7|f9nD02~Lvg&B;|110IttKka$MILzQ=pY%vh}kd#(XPm)?d*X{v-TtfI@ByaRzbde=W5F+G)-Q$VlKs&keH_RGGOs_?I;WhR6RiX(N(6@Y zkh`>GejW+b=m|^``aJLn>5}#JG4%aA|AQ}O{%!6|V12n`V(qUAtM9sxUvy~K z&Zq0j#IDsEO@SSrf0rb}`)5wO!JZr|&`=A|djj2u^S1jQ-ET_5`8*P_3(&CU{|zKpBDxL>9hTf#T*J{gyvL{{f{ z0T78RWKoWVAONfg1=_b8tzQXbA`d)XS4YsWM9_~{fzxWg8U$JI6Mo(2zQw* zG_VPb>6ZiU5#SACuZbWS&1cD&RiXzLSzi665vo8Em76t2p)OeYeME-LG)KF!cNR5+ zILL835xhPdgS@M%TdQsu3WvGW^^?`Mf6?K~(Nb5Yhtt-tKzW8ToDzi{2d564h8D5B z)d@Iptdg7Sfi)msICEOpwpqlwfELyy#;a#|mU4LeCV-|lD_CUFL0G`#tSu}JX8Bj{ zw{P$7Q0pIm2~p!0RUyC4e()V3**e7x5S>yMp2i_ol3&-ZO_5!Z^eL0yBF@G1=iur6 zz*{b{B^`W5dNC)1hlx=c!ndiM9on8FXQke7lxG#g0n$q)nd-Y(*LIW34b=w02gl{# zGn$PEUh=Q>^wY9boRdw8W+8S3Ed)okVQGb^u(a8_p#LIVt+k(@10mhqjBQH76Q5?Da5c;#6w6Nky#7crW9HPe$BYu@KI9Xdv|;PgrT+(e z62{>WD))c0Cq)M2l|~%@yL^&i_mTDb_CL!fW$xPlNBJb1EA2x*3HJ&wkj^esEUeTj zt<|rrv#4seukZNqPrUvY|D-L_tS!#5E7kiy5K5wQU!2u+fzei_&WC)m@;}QbQBiRL zKT?8||HGa{h0#{ zy$|ywV)QX)?kr~RJ$vjhZSimU&}IAaZBI~VPjc5%WBPxmP6|G#lfkIIiS*H#?8$|k z+2P`$vF6d)!l}jl`I(04wU*WGj?LZH?Wvxo&A!Uj!KVMkw{^kC;k=g%& zpN#MSulPyN=K1=}$>{Ov%E|TC)dzcW{J*m&=SO#^w=WN8Z*OlC=^PX3mJ{je|KU&4 zKU5OH#01C0gyqM>|4%rScf|h>918LOnL{a^&K3RNI21^gYo97wHD`DrDA>_`;A)tXuqxw(9f0D|Kd<~`Xj&$XmTxQ`d$9F z{!MFhS7u$&9Cn)%Z4F1$c@ohiitUXj^JV|Vp_G0xAM#i1Xueo$bvfId>}a{#>Ip{v zq}17Zvp15+U^La)c6&6FZN^HEK?@JHqM?K?=-08f8r0h``&#JI{FL9&H9x>As{4wR51HLsuka*y*u{;zSM4bq|Pu)ZZ_p;RF zEB+-V*=IQNMH9;}uWY-PG$}2rQS^QhTS|$$HlWU+1q?5+sczxJ^iWhNudO>`AuqgpH|)Mor@iIN%a37{%)$3m znD~2eKj*uZ?TKonPKAz9wrzFDL4sgCKFw$KzNAknjt|eE9ESI)2U1DAGf^u@n#t9{7p8W@w)Lvm;Y;@;Gw{I5mI$aWe*TcI6on; z@v*%pnhQ^oc{j#D;w6|mt~#0G%~My5&_YkG7#>#1HubNInb>V;o3E-ml6)@2azIq5 zlC6h2QJ{X=iousFSk{a&Z<1vc$z;ZJTo$hkM$K;9OX%Uwymd1Hm$}z|xc8!qo;Wsp z*t=uhT0vpC=<7zJk)Kho@q5eV%0gcj*HY$qR{8o6{h0f%EjqvTwvt0zWm?YK{_1!8HI(3_wC) zRH0If*;SNmO<<6VN1+egRirHIO~>e?u?iU_{ry!u+x!cazIr6?7A+V!HpAh5CrhM9 zF3#T_5@XFMM_{os#GN38AE8i0jypOc&HpDpE~bc*Ms`$A_fJCFL=iQ`bCO2aer$Ic zG!2nxq%6^F(#XsQu%`-?Py)n(l9Xj}-H$;a={_j))?!34sG&5^x@a`SFs3hF@(Aa% zX}U?|pY;C7v(<-0Lw5#qGCU=4J`7~Y>J%!~mV+^rZc;hu4q11~CXy8rGgy16d4$vy zG8!AGkMzg*wF)L(mn3n*LdK{cN2mQ?Za+AbGLc19i4`Ij^NYGCwC3ntHv`O8*$YP>m_PGE;Fm&x`|XsGldjx zCCcK_;3YJv0F65;9I>&4mdk-A`d$a6KjqVXFAps}sLYfb1-3ui_(u9zu+IbRsDB|U)dq2#q$__l`3bKiA4pM|CPUqihdfmq zb|b%oM(49a6-_CPh7lh_Mhcx*1PNr<7lSsStRJ9}reqr;1;7GK`+23W!#&>5O=SA; z^6Xjz*%iJ7NrEI0p(E=ObxP)u*)Rhcap>4I9HNMYuRe zkQtZ4kEPWCkXT_*z!C_d+kpT{j{JsvpmGVsz zu7UQTdEj{5W<5@y!pUY#`T(`2bfit54JVe)0MX1KtGjc6ppR}mIXtera$bzay7+*c zk~u?E9-{P`Zf#WL9itEC2|W=!PDEgh$%L{^E}(-m^+3G`H={0BBxTc;VF;v`ac2$1R_h_`xj zp{wqK@Q#S${}%Sh=${S0(raNn-f*{Ec&>OCtzQ zi85i?Q47A4FMf<(0UE!=S9UhB&jkU``IOm5%%t9duPXOk5=GunE|NE4>k z(2}NOzjkmQ_B?AJZZF9G2>iMsx5TVrt_+QQHTCu3BGyAi z?tvyJH`4I&0!HZ%ZNMTI$Ml;i)zz}V0hlE*bb1TQ0@5nC`5s*0@{elg5d8sC0nxb`@d0S_DY6xg{Xc$RBlZco_|F+WjQr!_6OwQ#uZ9-!_va>llu0OmI| zfRUxL6V#J44zDMgCyrbhNWRSZu?6&Q1%A=`_7?#Rv3?JQc!Y|^`-2bziD(J%@UT>9 ze9jTTtgT-vrBM_Eh{>FhO%cA*m3=LlfmY&%n{@Y;<_?FSvE51UD)TcNN$seAv_nyFH8$E9)@|qucdyx%W%WB zej+NNnJv!cWzqdl-a#$VfKqV5)3+D8Ytyo|wo>(KuHwiKLlx5IMOVn?O|E6|e zizim?btFjZhf;X-E3G$C+K)jTp?X)8u>h3r9tXRwJV;i6#ZO6~Haxh57YwBptBe=( zJ_5SeR;z|MbCUh=S&nC{i)Dv0BIa|Zhhe{KAPDjo19P%77$N2 zztLgt6-S#%&tFX`jI_u(NnUwGu8FkB!jRK(_sEEY`w+#{1ldHj(EjsfB|W`L{&@m@us{AExWXQmjZBo>theJ@ZbNv?4}_u>RUVl++p zC8yUb_j3j0HZr#l_yHII-wpsOT#{XRAb2^s$w6>klTLQHCc+aaJJKT~03`;lv?3&X zBGSSr03}0NGJ89COd04AUN|e8L4#zI6o4`k0FmM?$O`a74~@gMEzD*O$-gTNtSB_Z zh-ZV6LtFqQ&FEL|1F9QAsKubMCW-f~I1l09MVI)w_cpmzQN`Uh#ozggAJU8YW^?yX z07K(AL)po6R#=5UgYE~Cyx#%NwP1I;wD*m_mgopx1t?i;|0=< z|C0$StF|JOQLI*_Eth*%x}*JPH&SKZOGH_PiYza9DYOLn6mT@4H|CxH1I}jl**M}3 zIWf&|2`PJJEb%}WZal+c>C_!nr|gSu^+->$YiV^HH8|t<&ph2UbqkFG-I_SWQqlIB z*RhIP@7(vO#=599fKRbTWbHdw;7|HlL=o8duBe)#F>N$G@L&bVia<-auFfb9$a9*l zi<8aj<8ou^H*DB{T8f2x_Z-Hv$BT<<8RJJCc+c7)_(#im)_p+r@_OjalQR zlE?ynLuR! zPn0+=dDPL=CbY8)Ak*3Qa^^M|KsY|Z;%jQ>`yZu_E_(C=>g8EtKeQc zY8gY?UaBK~!AE){vR_6R$eQS(@>tDvdXVHz+x3}mG+?N~c8uT{1#qLbVq~wXRhHgp zIVfq(Q`fbw$zq(NZu~tXU-A54+&-(d(FeB} zFsVp6!77d}sOTSfq&%oP2X?vCHnhA-1~zWNp~ zT2GZ&WtC&S1dGP)pdr3W(3#{VmkEl2JgTCSH9r;w>MSSbQr^98+&KtJYli*+$9x0i zFzJkSFuJgg{LcL5*kKH{1`YMhjgYKA%-7ZLwvNnuF$ygTJE zgZ=azztoN3<5g~8O$kaj(k;6RPBC;1^V+Wod|%^_0j4Xg@tz}aTud>rWuoP+Yj%Lr zP)nzU{D%C-gjGIm$pB02l*1=7t4YZQ-Rr&AOI9Zbc#tu`ma!XF|tIdon%s8yTr!UzwditCOcJJ z1gWokkXO*%d)1z^*s7!>p`a3uG|ET1vp>prKg8t2L>ZOe+!sL`P;%><`Q@_u)wn-69YFs2x}+9e%Dpw17IykR5UE7Wg``=76?O%v;Q5cqBr06sMQ& znuFJZGQ5N;23IsBZE_sjcg*zV$kl$-JZIS7c=K8jYCmgonG7nmwn?o*xzRkId-KSD z6Rc{O<>ZLBNX!}Q3odyR!s`w`U_8;x8O_um^%30+azM!PO^<#?NbA)%&#d8&ZDSIi zDDDQ0OcwpLcc~K0D^j1<>RROcGVXl8=(e!8iw(x?QVK%|81!9&?^<0ICYXrXcxcp{ zL6K~KSDakxWcpOSv%bEzMKsl((|;H9xAKRZ5 z`NpTh1LMlQxE&NHdc%CPFhR2ZbWy9(rIJN#INi9tqNKUPJZGK%N8x6v zM!3%IYTMoci~k*j1bfHCbmGyqC0;C&7u$_Fq@+{%}6EQ#XEb zfE}3>7=*Ducd98fVz^3UoyKCCGpV>1u*Ax9oTCLWB5Bhlcr zm0~Vwcf>xz7Bx|;3BrEIa$#l5?=#dWGY6eU%VEt4CqK{ijTXFD2BJlEg%RsL*#B;F z*c!^#dvx6F@_UCTA$nX*<&69!lcWFq^>ETC!A+RU`)mJVmCk6R$%pwYfKv~-Zb>)&L1dD54D~9kX zWJbvR&smK)vY!ev9}Lfatpqxcq;fB!3}u}p__HM2V2ZGLofNJS(WNk^Mp2zKq0_)D zrMdS_k<6!Wu~C8B+*COLc-27-hdLpYQ^sr{Z1U{h?$grbwv+XePz}1)@w)2z{ms zOYvQus+juTeXNm@U`|a*6jfDS!0;YxQA40@HolfWis;o=jX&%x#8Or2)hbWSkobr1u;PAsu5b*rzrWAxI^4R3lF< zPVJ|s(@!D@#jrZbfuUPp5=R;&uhzw(J1nv-`5Kq4^**;6SRzxOPT_hH00`o_t!O{h zf=dht;<;!I3SwYwH8vn+i6^x~tUkU;K-Rp!G1Ml$ezLN#mMS4P?{p?biWrFriq>ly zS%YHfIU8wO@rR>CY$1X#0YV`eo9Jk|=Iud2Nk$wXLV>i+n~gIdMR;69%!in8>e>Oj z%R`7TX5X#eL?khZnswFheSd5|z6;_i(w1&QVZ3GEJ&dSQQmTp<=P zvEVs)lF#PA7)lEwShGZ_+8gRDc%+;2P=Y)!=87q3em|3fu=M9`?=Awk4^3G1=n; zyodmoU;<7xd#x-N!|sk4(jR0JIWc;=?-la$Z>9<*{N?nA-K+HB~WS-+R_4GD8<7wC9^4o=?Hmx^6&~^ zspw7SYs25JlhL_8Gk#W;MBpqiPr}o=a%|&~TTigia81{)ZcSobDvM?cJk&`7s(uU{ zZ44WAxc)}Scu)4)=WLe{*Ypg3a-09*@RtsH+^gjW_CBebX@msnu9BE(NGj3$&4^I& zK_xc|X96;eglJVpAJO@I7?O}RP;^u-B1J<;!WY==Tmb%HuE|AL7kk1YlM-hbE!V%w z;nyUn(%oQtNmG==jPRUx%Jh_QYdBSso2^4K86EYSXr7Osi2B37GGrr+a{H(#W7B_-Hp$b7m<&HbGyVH@t z%~)*hjW07v?pWV{x{p>f)pBi8uZ_l%qpv}Qb`G2kR>28I{bVfZ;B+RtQKGEVYb<_T z%}-cQvfR}r%j|L>utmqGC9Ij?=pVd4OIf9rJ1iG^1d9GirWTy4~v1^yiL2gBFuUZS# zlooVri>ti0R6WyF6Y5}Zfjno)hr9rz>!K-@tx;t;$b<08MAIn_zmpQd`y=M}1|3}! z#JRL1l=8;BdmCH2o5n5)&uN7WwRuL^)Gn6OrDlrn1hT?Id_naaYV+)a;^j*z*12lK z`Q_eJ<`DF`$Ad6Ls2QqW4b9~GU6(So zgOT9TQW0d#-cvP(n>5p;s{gs81AN0}gq=6iEyC|o>Zy*?~ zr5wi2TX~Z^bnlTP@0hD6$j*kIJM!MdL%YfgL23taEy*EZ~ zWhmYBx2%firqku=`~_USgf2L{f)u5k!W|R-*}J2h@(Kmg3;X}I8a9fsC1J-}g}Ew^ zJo~$G|BW#2IQy}FRAlpS7ag!OPWfk69_;3qpP4hssPvJCKJD%N1S57x8G${g4XnR@ zMR#&#xgiB?u&zLnH7q zd4FYCU`xPP11V_Z0i@k5G4qz~E{Z znY#F|vp(AQiFg{yehzg^dRO#M4dTi`_5)gR$~$rNF%f=2aq0;nYRP^Awtk_z{;kA1 z?xaKlmsoNXQOHZ*2B8G=M8C+sgv}HA z6QasFs3tk6u0E(?E~TEt@KFKI1lz+mFrd@f|4*$?IVA4$!l2Nm| z3VG6?yt=fI{eav;zvSH@!j2R%U7~g4&;h-aTu*=?-jL&+v|0$ecE^x-=1^Q~z3l|M z&Tc(t=MR=dEH*tEDMF68ks$|8DY>*@xhH9jEEpM5Y{gpGi9SHg46Hy80HqaL29ZP! z+_L;mh$KWPBbE8zsJqLixWa~8&RN|o|&ndnUC`e_O9ArcHQ^7)*4Y|5+!A5>%~Y*sq1pIZqju} za?Fkf$P5SildIB`)-j;8nt*lXNa{b~YJ-jXKrlnJ0`2c1ZDsyMo(#R;IpOv=0sF(o^=u?X1W^IAa^G=bC^R!Yb4KNxSfR$diV2uM;I+%EwQ&N<6wjE!KDN(o#HOukTWZ=-#$sWH^QGmK=^uede>7-1wubnV_6O_KJ#YAlvy zVU1ZYkz^u?b0LlB(w6LP%?Ni{XK zz?S&x`mS~@hZtav|Zb_jPp*{-YToz|5H-Hg~EAuV_^$%KEsi_A~;MppA>iUGIm z7agQ#UGm)S=1!Y+cbsc?)Y9AoAI*BFx%IeV5XJmnV=-K@hepIeSh!T9rS*GRkh@S7!u`dxemy<&H9kD6BGf zbs-P1f?KqmSjTZP#UXiVCLI%j|9FAZ?`v|Hx5RdeQWR4NaoP&LFjB4ts>oXD9_WPr zU2JpTYmQlaLAFbKA*tI9*3%s?p0Z-IT#*;35~Q1B&tI`!(p3!ARZZ1ZQj1k)Sq?Zn zcoub_DFD-ElGPwnbQOc)avbV~9vaY1>ZcxR-(f1<2bnA%njRgR-5r`^9hu%~{+aq> zC2;gk?#Np22xfC+<9TEodSvHvL{xd`AReIzI&xY*az29TD-+mb9lMepyRjTU6(!iq zaWwYvI`(`qnZ^)DVYs9o`z*u!#3DY99Q!XH2OJ%{mDr@r>XV-8$KLBdPbKsMDtW)= z6BjXva<%ndJ``=kc$H^s-q#Z>8h`TY8a*QPArFPEnn0a8y6-fJSeBLh4T~r_i99-tx{G=he z)UmN=z7h(G!#ef83yQ3mepE+4s=Ty{#UaiGUC@!ikihnnmIjfS8tF$N|l)B>nYjWNHSit7W5rO9)jxJmqo zDbw@mDbaWZ)o2l>-;vHyY^G}h;J5|Y2-#VLxJ!SkU2LFjLF}>F_W4n)-N=z+IKghZ z^7NPD-lHKQZ07VSvadHR?_q(ba7DAnW;GUvZ8R6>E4&g6vh#M&I2x|1idEF*UkBQf zxI3UZw&2x?+EuRHMNg_-Udff&k^O<%waHzO82tFYn|Jm63ZwZ;9NUpKcj&jHYl5`1 z?=9z%f4+d0ior0)1(tVL0sEx#`@ro>G3%XU4*=#r%LZ|teE|owwXuPgGceJ zp{o&Hnfw_BGOGOl?FGjS3xFtxbFv-+=V+q-O+mO`bDiFFx(IJ?2SsN6d@;LpS7D{k~( z&Lcvt?z8sZ@b7Yjn#7^LaIqfqx1qtfL!PbTSwYazu0O!w!BlMDHQs!mHjBWx*u$K} z6F1cYTmO()n&$KT_@MW$`ecQ``eq;GLOpkS9(vMEaC$&+D$RN;iR}={V$rez=~lCi4A9YL0dj2Htd9mjb!-o1 zbHMVc`)duLW~o=1_(xB!G?PbAfI7kFJ1>{%gUZzn*0^u%`dI9xh+ugPl}{fCW8JG~nnbcfRC4fjwUS&m{t1;X3{Mner3%p2f`JmG_G` zn2^;EFbXVM3nc3sBvLS#M;}XT2adn8p~r^yjvkAn4>Mgo+!BSzdHh8|@vH3E=^+o6 zG_z-H^Q&qG#`5WxO4tX*u;2h*xa_PqOfcBN&Odw?n1?-~8j*_92;I&{+=?@sx@gRjs_KLsP>{+_*guhkmqQS$dgzzJP% zfNzU!(zV|U!rwfsSYwoR#)AHA$G-;11GMeXvOWi8ehP#^ux5AwXRZJKzByXM24SOP z``$nylw@j8MU74;*9=49#FTVdY_oB-B4lqqT(Bj?kH*t|z5mA4P=E@j;4g7H{RW+k z=Xf6YD=|zxH&fuN_uNw-ibkH-w}bZY!^)c3!tcNBQW6=GTjM6UnI)XTiPK`nTRvQ# z{oq)wvl>l&>3GMv-sG^-;H)gbVuFY=`Dbsy&9xn4Pw{R1{O2o+SQb^!s&HQJy`ji` zrRFpGlj+=eR@|2kO((he{82|$?R8gDsu>ho9-Nw~k5$7J`i(A^zCTP7P=AWZ1Qjhv zg9~YIi4`IeCCm+}smR*i9PB2KV&63@cr&3^UKWZJam_!-BARJKslprX2M>mz;%Nll z@e&ua3>BXZ{{2c5@lWl9q-4}y0k-0%3Ofk(r>vB%9Sf>SUBXH28xI> z0A$b%_;Xj6{M3KLq`oLPDf zgy>2be_(Qy6$r)%d=C>8Yb9!kfq8|AeZ6?qsj(Q=9|7>euk&@WmfXJy{y8<0*KKKC;Z z+saeUD7KSLdOYeH#`y7*Uk z{Wgj0dMw;@BNMoa81+gdftAv)-ZYiRy#Cg}zQKOD!SDBq_8t2qdVAz|E3f?=t#=s1 zwyp!;Usm5|12Ix;)VsNA7HxIkn1or1dx(nncyFENlajyKX5D=f9n2G z@k3nf=a%2wj#tSvZ+kAty+8pfQykw#AKE^t3*X)7*Z%$eW8>4?e>Xvgec#^m7X{vS z4D|eQQw_W+e2(_4tPhjRhTOOe9mvGiUkTQ#3nJ^v12)!0t=y^yoa5p?E|2#7^?|~n z*7P{E4c#OSbs=2V3S``DgOu~GLB=~4;CxoGpZPOLu|)<#*?TFHnrkSiehZTH)Q2MJ zN<6+JgI~xt4C(-KFrMZapxa4>db=`+(d-hF8Vtn?o`nnT8%x_HHZK1SVLsdiQ5hGE za0|0C5!&xPV^RQ{yIV$*;yq{e*9@6qkft;*8zApW>KLw1cjJWy-=L~jZpOM;T&kxRlz-m%y zDY#QESd3*6;a8u8Hm#w->59h;&yvQRN?vpyD~2&o2(-<`NEqE_?cmwM4yC4*6;5+w z>u&f(qjag7F%qso2O?@X>N0zFtc&cYF2}bhKP;^fGbhYQ%~Pe9y&5Q1t9+q5t8;H6lnvwnRk4YNKwL;uouNAa!7F(fD{<9 zv&i6swTdfrBd$4udf<#e^R>|z7Q2-O-mvl9vS?HKU~7_#fmc1(x?*REX=H^b)W!TY zVv3wrT)t$X4;3wnfwRGrMMZqr-t($vABw*^mUHLav5Ae{8he%NB=`Jk>G|8_T;#iC zyZ=FVH$aBJuv zOL&J3i~{wDTSlXW51j6#7;DcN(i&KPld%qjG>1&0OwPYmmC&H;c!AkFxD6|0&wg-m z)su&qhU}OO8W|(hq=K4|cJEnHGc|D10wR(!W6F`o%`k9F-zWUyVQ!mkOmqpz^Gp|O zN2Z3#WGC4#QlaEpSTje9FQG2yPTuV{I{s@HIg>;;)8AMq0tUQV>_YO$V*BMI?$CSt zQ+DVusWcy@>c~fD(SgsJa+2~D9CSpkm22;q;<+e30m9+IBEVhq$QUQAQxjMJefadGl@ou|xZ{)VWuH@y zlS<;eex^gCu*x<3g>4>cau4n(w_ zYtw-OO}i;hu+Gq>xt^9azaBKakRhK*Uxt$~ zGvHI|)!Ys&L)y!@|Kf}V{_bQLX2aq{kEL)F0VF4_Q)#>p7#~PaKOlB%#2gmBFkJqY z+AexP7T+Jy_&_{|M}%+R;!h>FCThDQ{%g#f2;uE_(B|`E&7~1!{=NruFg zaJDXm7cE)J89flso@d?sUKOj_`ZJlbq@Ndurvm>9%?dMp$di6k#tVtu4H3}k3FAC} z)inz)1Nlhm^}EVJhvsl$cG9ZHMh&)Z-$1Up-*r~>BIxu4a6dki%lP3dO5LD6d)M@% z^2Y~_6^`}g=+#FCL+2Q+FI@2@H5cU#wbOd#9lG^H&%|vQbY2_H-EXj zCI37;Wi=l^e^Xv-Ccnm1Gil4gC?h-TmH`ydW|hl1HB*?zEIAJwx^xr2-&*}7q->4!Awqw~ryp`1?sRRGB#2VURr3@wkT=LxX1w!S1AkD>O1FOMOH zgl0e;pDZ*vq;E=^?CLmr5TRTbC2)MjU@k3SX*Jh!N8CsD(~>SoFUXl8ShYK05NYx* z{P{34?^n^I#R>raAY=gi)8E(al?r5Fzz3|}UZpr>>E3W{~JAeE7QWsN2copB?|z>rZbq*=R%QZ5_h zQo5)BU#CleqyUox91wV0vCL{TJ~SCWwLLr)Kh@hA$Ph$%9+C0bk7PKD${5q0C|j#y zCYqk3)JIYBt*=QO8ZxVy1AkHGiRtKr5?Ne_XEielmb8wXrls6tU&&;8mTj?rPyu!g zaFR%HmN0eWGcm@h^$=~8^)vmOlme*qada_>|9fYJdS{hwEH;ujidNKGPb0;3@D*q* zIYO<~%46NcUL>PeBx`1kuE{Lt!YuE3aAj8{ANp9N5NoY8Il!rat&muxRKu)HfK<%2 zZr+vUJeg1tmr-qDRy(p5@3B@H8CG?fQa>xwAb?(X6)BG7sSn7iVjap%GHdffWh7wJ z3NRH7sHWVrMOd+(3sm2;SU(VI5L#>y3pISYmdJ$~l^hxfBQ@y`saasUaxiUSxUQUx zsVAY%Hq`3mP?Sr&;WkB#Z~F ztpr&dH4Ytnj^u`dT!n|UrlB87WZXtjN4HOhMdGaPa;ydo#V(mF@32DOUqPj5N+krL z)-70WT%oR9tRFk#-E&!eOG@n;4qbAKIPPqGMviOCSp$|!0}7yiEu|bbiRRX&{{N2A zePG$ZyQ=(MO_2*peSVsO!nG(E||x5Fi#^`WZ+9txh7WA&6kM9|Hsj4Gj>1B+%2# z^suC#F-!53p~aF7GO@vNI3;3Y(J{){6R+$O1%@=QY~IP0=T#6d%AO#DPQs=oxPZaW zTqSs9*sxd8IWGFpIHkD55rt$91SagII1-_91B?`BW9|J|6zrdKE1Vk+BWun)gzYUR zspSUF@>(>KrYmHu<1p&pfxt9o5SsF_C?}1GD{d17jUZKg8J3ICs`VF*nQ4H2TjjP* zPy-f&7I{+f^kfKuurMIWGJT!-T&~TqG4>o+j3anFbissH;3o9F6KyXKGP79uML#|z z2)NO{*z7QN{iunX2pREAFDUwjuy-9`luVF_mRkk`S^p@87!0o_a12RNSEgXA1TfNe zpj;^`m3KgoTa_3pV}m$Mm+e3WODQuUB_TZ^6u2;UJNENNd1$0+C{*T;+r+S1>R&P7 zS4H6H-SfvSTp?OUi*zfq9|LW0$D_K7R+S(r@4eA+&P9QZp=pcO#XQeqI&@(fZvW*e zIOjHvxkB;QrCgomkbWm05Cei4vu34prx(!Wp$;>=(;-Xb~f~pR! zwe@Z{Jwg&$XwF5OU+$$+O-vP}WK2oq#r*oEb51Mw(dlye?u!{kA%G5NRq82ZiCkWM zDe1q*%oaWJvI4|9xhAQgve!~mB4%%~S?vQlaELBA-{$J>zq*~}x)Ly!0Q^r-O#I(K zF)8^APR{?BVlM8t+^@L*S6Qs{M#S}h$YRa^lEo6@5>L4J1D~se1ihb;xT2im6E4

Z;O;lG;(eTQ0QvYx0*tqn+q2pxE*#8NQ6|yT0itAxj&Cc~b?j3#J zT|Eds1j4f&q1b^m=t}l@!o?Fw>i-8WE_6R@agB`lk10+=rv1khhkbrB#pNlbbuqP_ z!EH~bxHYx8w50UO6xZd|wiNw`6(bsFg4+Khi(6aAnw$6X`wNPP8yY4XJLWq7Z+!9b zO<(YTaB*Kn?^?%yaPe&B^jPuecnfN_cxtI?VYYr|wS9S~d3&#QXLYdQKbm+r>Hkp^ zPmE8XQ2)`y%cG0`Lle*J%&s1;j{l!P@xb;e>g06wm&do~|Gxpn(Eksh__=Ah$yh`2L>l+I@odG$lBq1gk7t`>Nvs3nZ2uQf zEQ^rJQEIMOsx)YH*cxx<&@VR|jQrn0F=pj|f#Ut~9A$lujSlbcXIm4k1(iMUw11@D z`bF8ePoOxp(baWlG@eP>=ES=JmJo{@)|D6EI53{}1d9KXy*^za;o|^Sv^5`1*S#&w zRqedfU1)Li6DZ5va|!Fk$2!jGd;-OiZcOAk_ZIJwgJ8Kh{B9l@eOf_|SL>ELU#>Lj z%^v|X$@OEGxP)(N?Y8~pf6&f8yMTQ8D=$<_+CrY4NClzcAC#=m1Y^?0nMQXk~5U) z3DI->CwtN_7@I9Z7|d?>G@^gB6~>d{N5m(PwT~VoFe(-wBoQPQ9eB_Tw3);VOdT6b z3K^}$f2bl_9JRbN1(4Z>&|*R3NQ6<8-uH?U2#x>^4G5+$&LS;l?i{#f{~d^yqjf-?dC*{+h9tn$x_R#jD>stBH@MK{&5 zjGO08H%!9T*H^#UI@fH(xAAUJ*=A=ZUKAjA^bMvu%$JANgEZzYtmfa>wq=0T}zHk{<1lMTAR*X?Tnos>mu**_yt#_B_^j!pE zT@@_hs=3q^a27gqh1cxIw4O}$;4^OEz*@JL%=OzppH&M-K5Rs4#Xwhwl)HpZ3<>^y zlb|L@qc|mIb9uS{_N5?aq->8sjm%q?x95k_OrJl58a^xG{^3<0_r6a#@$Ki)S`O-b zoddDw{xSvYR6CxSj2DWLAO2RRX9S}6&Et=2;s@_sm>_wpW7Le4lnlCkpA1s@x%bh; z=UW@?HY9xw;iW_Poz+P9bX_e&-2izOM2F2wlhAQ(V)qwPpdjhTglIsPLjESnYqs_= z@AcEnZxmMbg;1g}S>`zJ)t_(bWC=ZwDkc|`iwj;#4L!PTpT=!ewaGfYBz)&lXmz*f z&F>w9%_;Fg`%0orYL`AXMCtbV=4+dNBI2u1u;rAihFujYRZU2s%E5=e@XR1~tyfT) za4gCorYz`CLfm8#jN%sssijuZ#|Z04SLQ;x0OI7b3tU!=U^;!a{gk@sVoqDd38VFI zscnTOZXz%`>l<>XQJGTU$>4; zx%ht1+AJzTt5=-eVY%7DU)GUnu|2LEueTzVUv6_J{ODr@$)~tas^q8S%W7A zOQ%|{gpD(w&~aM~M`PoOo(;E_$S0bm!NgCVizGimPZbzG<%mcKMd!4DaHyWi8ILEJ z#qTn7%?2CC))R@|qC-k)qBsC^xT2z%lxDKH1{qemRa($01@=>pV4SHp5J}47cr?z4 z8zeeNmr@gj;0?`3%Ch~a{bhY7_2=CS{UIrIwU7!Obqo+Vz4?_Pt>QaAMC#a!;`%s` zNDf~~$T*p7iJS$H1V;nFz!qGFDFG+cP>N=vmjYvINWQGmfD_6Dr5eMLyn7Z#ZNhn2 z1dtaTjIPG8D$7#1s*4C_XC@{Y^RpP)sz-`kDlBWzLAmKHQo@@E3!$Kkmz~lF73hal zXr(aZQH1+oCvFF2r_p~MM)54t$KMGvcZ8XSGjKMTBX3vOf+MbE_8cLsG{`<2`zj7m zV=_#>RYoj1P!M5|`9II1-i-Swc;Sb=ji=vl2)%;3hc|x#$7U1SUzCx2Z(X5dOaSnz01VXMK9(?Z~=Mom}RU=q97ysFU8+`%P8nOGi2c3f1?oxyI-6eE7<$KJf&TrRQ(FO`0M464qD~DX(3P zYbWzjjJNCyajDp>gEjK!;RO-IF7jc51P^oy9V=T`$un)6*>XIpg!4FiS6N@AT0riY z^SD;Za6Cnp!Ni=&s7EuMR&oo2i`wQ5qOfN}r_T@_8d5co3S-zFE{|(-LJU!*vMyf3{J;wv;YIdJcne3+ z!yCtgekpdL@F@5m%K>09pAEsKr{>l9%$mY%R+jhM^qo#&8;*ZiFag$#N#V5=F+?cz zG(-Jw{J0tVK@Sg4gT(r?O{t?1Tc0g$0(%+-3kp*}*SM|A`zuxe$g5Vob%Z^UDGIUs z%~lCn`uTCziRn1yuRdu32^?quj~0M5HW2|p${-LNok1CkP4O=og2Vvvs22pmD=2sLpQz@*X%bj$=|L~rf~@JmiY!6g;i`F(%FjWFL2C&0J-ogsnBfFL zCJ3iz0CNf=IqYCO-pJ9{!2+Nl{&cvwowDjluqZ{a#66LWH@JQlECX_4YVtL3b5>}B zV(uad(&7AqAwbJeJ5;ci0z$WqFZmth#VXi{&E2pqgkU#>77YZC2m7~>eA>bB&SUl! zBwo=AUzQ`a2!}jvxdh*1TcU`R+JfI0gleIXwB8WP``~Bk%*bZij|O4J=|S@O7N5MI z@*IZG^RZ&?Nvc4^wStb`+#eFkh>}q7tnkoOiXcr8!ZAJc(b*3EKAp&)4FbypH^fI9 zg-17Ngk?f-VHRO>29WBuFs=qW6-`SBA{-YDXG+do;~02H8b!bmi-`y~){8+$vmrPJ zo|Qqu%bX7cZ7l3!r+0M&?ja!>QE9J3l~GY0tHJ8&!F_D;Sm5A6khGLEWS9+-4#7>+ zz;aIydd41O-3OlaCbCL{e5$ieXpVE1G`~BH!RCo0tWQ9fv{|xCB#t*zb#>+x@?=wt zxkbTpnr&B6ag=UR^eBW)TNGwSlqyBM&T0fX1F6?sJi2BADcIe^0INO^tPue=p&+_z z_I1b$MOg;2=x?Rg17|WPnOC?_YET0fh%@bJ& z%Ck(!#-bvg%gCFOCzevk;}nd+6V4|ttj{A6W~mS&W&!2DI0+(u$bbBYUBJqa$7ob= zV4ctM;w7^Jb+>B}%|ihdSyV$9T~F4UZf>l%ppi@B~c{XK`viWs7OU(4KY(*FCuVz?$^VVGRe5fpR5`N}jnnVlX(NyA>NgP#F6bnnn_v`;w;q_~`PY$SE=? zYCNAfqVxk5?u+n{bV&K!ePJvV4KFkYga*R%0(WXa0@opR}bO=0ny!qY| zX3VIe$|x?nCQNkH8@9X!&J z)38(U25`+3MfrSN*_YD-97}5xUC6#{ttCAy3X0Y(SNoF{jRh57 zQBhle+}MJuW!kzbqlN&5lKC6HP9~piM$7^pfMbmG5eB)QCC{PF7tq{X)I___!=&x9| zE0O1@Q`!J$&KBTE>Rv?njI-F~jn&yHH5Zfxxfs=to+TeVl-c9tnsCIR1e@t8?JU8uGgnf;ig3<5K@)vVkMArR3n9IkV4(thSj@@mZcqb z3Q-2~Y3{WX?kmk;>~jOzs7_1GPI{a+284S=t0S>SW4~XeP^HZnmKzokURoMN)v+W2 zH^Fs0$5yF&t24*Cv)S7r=g7F*c(rOLqsqd2yr0z@yaDd1?*n@(q)e_y9~(n*l`NNs zafv&u6IpeyachM|8Zq1|?#@Z?f9F4NP)Sg=%qkc23J*!M4X~*Yop%lfjSmTyb}sA{ z@`X(bbCdi8O;m4wpMwTY0KO?DVBP1_I zT)PIxuW`MzM}50S{WnJgFGc}i7Y|Mr4N+96Kjc$3DzXdZ+vOQ{LE|z>V)=j~3LmX^ zMT7UDGONbOc*fLK#zcHc70$;@^4*M=bS>w6={5EA8~WZ2=$4j2OKB!jqsM%*t-I>R zKB-{mNPyk1aZP^!FeR|xc+RLeh{12@66 z@e>`Jqg|6Wy>Kv1A8t#BUFe%Gx2Q?N{6XbglzTLhj0mJpq*9>MwABIDomY7U>m%JA z|HJ{w&wx~@kc8;XKDw90U|X6W>rUmQwLJ>WzMC^I^O|+;DnAv5^un>xAb{j++^#+} z+O0Wnz&yGn8hi)Wdlrr48j~g-ZM$kTM*@wB7T~Bi-zx#m35gN$t8Ad^YtEc$Kcj!T z!NsGRA>XY9ocAh1|Kg)^-EXHl#v~Esy zbfeYhjXIUA3{H*Gm@c$-&)H%6o&Vk}xZDcQT5}znT)kZDI`6C(-WhW2y5@(R1Q0#z zAvK*^lHGOhHriF5+eXUG>Q~Qs`>(WSqYX_Nx-*4*&89h~abNa~3I`apPvVkm07C!bLK4k~l_9c$2N?PLO8=a% zy4J8VcO+}b^tU0wY9wF$Pa^#xZys}r5#m8HfgeL$h{MHC11?Yqf|EF|0xy-*Y&sOv z!%2GXX+f^uu*O+Q;8|JjSw+uT)%ID-lgV{xq`&a zG*s0P4p``${FqUP1~G$VJ!%Z9wjAK@me;u6h<^Dl9(Q>m-qb~1c}KITqE~0>Or*Lk zPJHQWWI0#XU4yRKD`3A|-R)#cX5pN_OpNw}B61GBdhYk%IR?`OsA?Ts^*rb0JXh~1 zpXq`}%m!C4?(HS6|21G_*;@LGwZX_fIvN(Lu826V@`tbKtJN@($M2E7_tEC(lJAL? z#MTM|*3?bc33-<234Lt>%Dgngrq$l#;}>uYQT9OZS7;<&aHtqviP*teFkk z%MEY9=78#^pVKB_?sTP3jnez?*$^TYXhzJ&fI*@>AQNfrt182Sm4S?=hTbwtC#2DV zbGS6KPbyZ&Q!1k&I7di`awfm?wuwEvT)j4zQ$3Jn!G?w~!Ie%nQ|DBxL^Ve|go^Y~ zr-GgRt~^usT(3qKEx$>S=R!sdpVf1I@!Wdp9r3zn2(|u|jD+{aUPhMwSF@ggzvIro z^@5VRy>3SMli%E!kHpYAUSgi?^_df}d!4ynlh@+cvpqIMW$0rgK1*Ut#AFgbr3|c0 z^A;-gu~pnlza>7()HBJ)Jd+HP^*m*Knss_N9qpT>8gC_x;AMwrA678SCjAE#|Mt8Z z{?^g)(8ePZLCkEQ=vqGE3Wj+kwOglFSPbm7F1LQ}{km8E=lEgeYtOIE0-Rm|VKP7h zNUI%RfYtoqz&OtNuDU7eWEStWs0`E8>!72ZkYGGq;S)x2#*IGCZ)_jp3V4JQ;CS4k z4>1MG0)|mFDv?>!;gZ>Gd4MDMSOEa&a&Mo)be5h6C$Y#c0ASJAv!`>?u#ey$MP?Ks zsA%F{ieFFH)rjytfnwFt9^Ci+J-%p#QOYB2;YAV4Stp6xn+HnV;^n^A>XN%SuWR1@ z$sX^E$dsjUFOZ@R(W#9QP0VXpWP_BE3*&$Qge!va^Z+91i7IJA_5_K7VBviFW~Fy) za5yfoqCzgA<3#FNjPGfX?3V$!TYkxcBQDH!Bto{7S9h1SU+O-guSAtvw)M&ftuxgcwWS<(#i6#dZi zEpNk6A)5@_62sX57@eSPj>i$-uAR9R1;Kk%h*N#9o{eqeOo>WHZmE%=q2Ozqtb?Mo(5$ok-mO$?ZHrZk!}>?h zM#nyE)-KmULitVc&l@bjcbJb_)17WbDI;xHiPi9-GlsoX6TA1-s-o@!tiFcs3+nP> zKYS8SL&#Um!^Aw-Y)iZER@r4;-STo)Y0{xOs}!-sj6%LwKG zeTzSj*cO1+(WoH6o*%Z%&iS8$(o}mG6djr8eLLDve?9ZbNLokFgdtj|P?o#_?8;$0geFL47~+g6H{7V zgD8VA!)e(YScomGw938>VHfZvD4Q@d^&g=;0(iyR6972|)?_M2_RpLcW=(k0mGp5& zQp|Xw1MJ4qAN@%k^5Zl~5WFDlNDZA7UB$AOv>}OMYOvIp(=v0CgU?yAM~pbP&{y*y z5n&2$hMYcWEPxwA#3slSnjoQ+uPD!;##gGtqbNK3QN}nT=}p^rL*W!(67TJy9HeNe z=%}2!f}|GbV82zAl{*n{a(qfYF1tb}@$#eSQKhcsA_A59xf$I-!&~z7T<<{&>>h=l z(I<`X=AgYcrh)FSYyaBsOt@0dTCkJBL4Z;!F^_mO`@)I!*;WL~Q;Me|S?oZ2pM9xX zlV9tOMp^GLn5?;pH}6H|gsC7$S*;ui7bP^=s>nf$UqGg`Ie`7*B2kV4?arg?HuaSk zj)*9Z%S|cQ(6MI9Z=&H5Ho@Iz*4hjci(}%t3Cqn+HuxE9OTJT$y458HnkrmY*@1qlT09$T)(_9jp5 z(Vw{!iDEMS3TX}>o3iJ(YJ}LM)-IIDIu|alL^q0f1;-RWdnN*MgiDh>uy#LqgpInRN@#8k`IXx~5 z%<*^SpSz<5$v@-)D0gIhOQmF(t|AboN@t6Ft>1?gbxUbuvtP*KO8+;e(~@JPyMBvRQJ*7YerWsOH~gq> zo+>wS!#zab*&opDVq zUgkO@7nZ%~OhNsWZ~1o6^)Io90!M6%w*fthcIS+2m$+&j^`^0oHB^CXD6;#AG5Gi~ zGcs(jcfhiD6Swxe0wJj*;V;43d+zE7t53H2ZA$RiRcZ(_iMM9K85_?vzGr+t|0^+M&(A~kr#`kUoWMUFA( zDL)od4R&44*R!7Uto*8{r*2>z>|q`(2kr}phIg1{Hf+>2n2t5vt@1{mG_YppvK>6x z;dT$p9tA{;MkOB@eF!1lE@LgTNGT)EE+fm-^2c>R?zTp@X-EY)WE3?-IWEOBFEeyA zsKGp}h0IWTGQ~qfI@Yol(pYBqNQ2~I!=hoMreWiuVMAbVv;A-{<**rWg#R&k*o1k+ z>b0Ed!LS7h&wPHfv-XJXVy3|+5`QQ7UDJqTvaG!}qn!$$O){l(BVQ)Z8xM>u`Q#|K z%AuD)L3e5X4@EfkMRJBi$X6#orzTn9KA?DBu=)v5{K>eiJ_R*8a905;_eh2poj2dZ zKNSkNbjiGrrVO6=tfei8km?cn*c@J%Y+M!dG{s>wG#YV_^tl~{C(Ek$MY$G*$A2$O z*pC!*SE&9aJE|e1=+I83FU3YS%pm@uT7 z2q-Gi-V1LKsf~~jY2F95L=m-052u@?WjNt=G>Y8+26g{tC2vCYb}IDxO;*+Ql3B40 zQgb|NlMiQ=MQSM}pS+#Q>Wb;;n#CKUP73hif@e!J=Hru424!F>q!0+Q+dz5*0n;VY#{PpBt=$kwmqTll?rS zWq3;B{k26h;KTg^Uqs{O5K|4F+LsHIfeNUlDklC<>1L5^?WXE40cSG#Xa8s@jPg|xPX$E%D~WW(v$5JmrQi#o@TwAF z^Z4vDO)&kO(E-MG(P)CTax00B9CW(8E`_#In)7=~9Dq!WQ%FEpHk@QhXGnXNGdoUa z>D{BKOcuvdira#IitaddmTt4I$sa+bY~8?!CDR|e^*+PKqwnnN^Ffn$aisLT&D37Pap!z9+`ppsakSh(-zR#}cvwE*K>iaD1?g5oUbKd6D&j}3 zyk%b*jaQhn*CVY^P;1bxMj80bD@5*~2%4AT50nyt(_b#&4x2csi}-1qkzCrL8O3Xv z&1+f1YuQU{IfrYxKh{2DuIG`i=R?;E4%g-o>uNFDy7mzDt#p8&ok-J5uCvRLw^2CiNl2hbcx&W7C39{|%lJtu z0A0lwA|TQ@C{(M_nPjRca>TJK>W|7eQ~5aa)L)SFexYuShANwfYFxBxeUU1-PIa?s zc%^zQHQhev7mb>X7eOv`?PrbEM4%5Gf8gZLQLVQh5m=5Pl%}&|5 zw%2nlB*vTGYl;zbk$n<-f;*HYyHqW^g(-l~%{W>qX*9I2h+ebUs3sw(^WN4?yB!eF5rXJ@OssPdxCe=KP8b1%@rJsr>x&gA?R>Yn<3e}^{ zi%MM~^Fr?Vs)s3Rmm%t;WLAdzsz(QEEJpLE!5UdpA_35ie)|C2#rmPJt zcTL9*?vjCKynMtza%e(#XnJ+%TGIR;-^Phkk9T~{K5+95JvxjHlQPfH$~y=>&juEb z!LWMde`Mo*W21#->-My)i`@1WK$n9D(f8Y0JuP0|APiYTnIwQvHUMc^2nQRSFdUe@ zg|6_wvG-PCQHF2Z@60eX=+NEWDN^DL-4aR*h%`udNq5J<(B0h(A>hyyX>ajcDRZ*6?f-hJG4UDwWY9M5x}*RR=5`+D!4I`0_wAJ8tmO8r;Q(ucTx&}#n$%D$O5jWCXm&sP zIuXZs?!8_F5ML+C^!zYR6-RI`6bBm0B#dLAdFUFl4d*-#40Fg=K5jQS&M}|HzMv^8 zw8iJfCYy_jqsC#6jkGe4j5CU;frsis!kU!v4MP99HH8MF3MFiNCBpmfofrYf&4Rlv zi@BZxPIgI$LUR!vdndEWhrVxANA3@mQ$r=GbHSmJb@0$fknlL>sKLT`$pauhv-40P z-seIBgV@kpe5HxPlPs6SfWNu!cT1d&R3S5jva^F*f7jbXmGm_hPIBO2>2v42PAs`O z6^(#TLa~Q32ch39U1Hv-#eNIpP)NBoK^COb3Cl+K@{m6_GjBS zO9rmJKS3{5FJzirtx`c_(O8orN_17u0WE7m^3x&eDV^{h0s883ac)86M*a2cX=goE z*w-4Jue0T`I&UXC0@PO+u2%(kh>{#+;t#R29i(qAH8#$Yry?G7V@Yjb$OVF!l6o^k9Ef{-2S%vp1HXR&# zrTXiX?paUEYs>jo?e9+(PQdvVf?pLpi8!+XKl=5r7@o-uC73YzoZ6mG%X!M-dCH|m zXyinMR~=f#+^AF>66}9_fBDT0*K$|jyfz2DG6nbASQlz8p2ZQ2!`)j8L|A^Q+vvmd zUhU8UlzVH4{=|RkcTjkUH+CJv=}8%_jR>e5T@&Qe3qwQI#QG&9ggt^E(3~|9cExYg9pcmP{s^ z97J_3c$Yx4{aUWzKMH!9k7IY=5wbgaPP6{@_u-iFsL);hY4BFl z{d4hqedQ2it-vwK<2^1kV(|(qE~GLgV7=>p9XF)%+h3FgdX#JAY=8Ir*xSechnM?r zH9)aiFN^}MSKXCHv7%omQn;28|BV{@b+*jt4cb*!zKG~`Ks?@6@7@*DBw&;wf2s|Z# z?`@5zbLlra-(HS)`F(iod6w_{eJs8dLD{MP=*qG_$ME4Bq8}~bmb$dCL)34Hvo)kI zQ{o?`l>Lq2?e#wPXm*Ri$!BbGCthp@Ddqn9?+$-+IIm<*T(PQt@i}`v4!j<2`vNhQ z?FVph@eEY)UGCMXBwLu5xNf*{%+t6mJzxsD^2KMe2x2h|W1y!d6@5+g93pBZYftZS zW$gFLc`0~A$0*x9=9M0EDRwOQq=0=rP_~0>%XotLsu=8ZArkY}d!A*2!55-B#(+Eg zf|&^=&>qK$tAtmk+JZt4vm|IWR&GYCJH$|mhVrY;alBNWQ}V_1Dk6kuLq1Kpwlq?(;tB&9WXu{SNsHqqB>4wjl7 zba7B7Z7x4n=5OYKTj@n@M8%XTCv6$#K2O49wr=d86Y-E$0S9KutdIw`VI>=lunxsl z<>ZsT<$JATJ4RV1qAov2{gtE~H-|JeZkH4P!XdqgbjP@%a3vRv$M|)2jI2~XD$rha zn{*dd^m$l!4!O#>bK2!j%3jsOPF$9}lmqLBG9O)6}v!3tjE$R>)=$LuYE!Ohj*e0; zld9@j!|T7DGSFmyTJwcP(sA?^Klxxxc>%sHxXbH`A`~yv{3CH5n)&V3?Pm&`CJ`Ss5Z`FQcc#m*&NGthy~bjE9j!R!uDcP1k1;vN-AcjtGhVWr(HrQ(OTB;mlUMEdZQSF|RQeEQfJ z$8ttwS0QnevD;J@3Mz7>t*O!UA34U0$CX4|(~^VO+1Vz>KZot5YAdqB0Eam+lh%wv z*EK6v4xUNfbdU6`yB%T?gqoC9Oh#J`G4E@hsRC}jhrt^PJf1aEN|aTaEV&g#K+9CC z=fw~_goOkiJcFR{SA$_dk9%} zzzr7D+=^;cbfl{CrA0bian3)!x)3LARu*w&vhKMEFtF8Hbe^tPf?4`|Qdk4}2(NBCg^4s8_EMEBJQ%HBWmvN0{T$HS>~* zYWz(A#KnJ#Yfdr$!ZE(ji>3S}soRM;nU!P|p11kawi6q&SV%}3%7R{hhY>!hrR?(= z{;h9U0F7ogQOOl+U(Y;n%Kj}CQLSaoDE1QXqlq;8o6H6(4=2uqi}+O5AN&>-d1sD4 zSwuJZTi;37YaL;KMIG%_fMJ$8mAz!ARzJD-jLV%=@@BKeuS%?Sc-d#9W|urD@+~M3 zt)tPVZ5N<79TYXL6u4_v=Uvo|)lg~`Yse0zwXefRx^HGjYvYhk(_7+$aD+TJ4KU{q{Bv)dOZl>DH2DqS`N9L`?aj0I)LUT>~K5o!)Xg z{<{ySmSAMSFBxny#bKC8YgBolY^$)V|9%ON&9mWZqA{N|2*;`9Jk3^IE?K9^b?b9~ z8uWk+jS*;foBFqQmE2E?NW=at5m)@Cf-6d(%n~fE%SizydJt-U8t82zGsJa49)CT|F~k=UC}>A;PZYp>T`h zhq#>u&Gvq~@7(T0_rn7;6e&T20E;<+^C&ShmeY`59ot%&p^w-2!G^N~*Jc+?hRFJ=MK^7H+bXOaF*F zk@RTSBBiYz64l`Nj^8`N=u<(2IbK~y2qK|~v++4;ks44SEHm0c({P_B*D7F(z#_VO zUI|Z|qEvt1WT`4n+EJ%BkaX-rpOLITt&!f*8!|yttO);rOv>;XhqW8=nIn^?# zrW;S67BQ2r*YA}WujH9ov@AXzpA{xDK@&%;l&B|h-)-NIFSZt?rNIUEE;?J1PbGqp z0yNI&h1QZPO4e%)e;KAB%P&`mJP)%j|I!rJ zTaEEvg+EFU_*}%Qlo?apl_-C_j$WVp({e1^}g10DIkvf7q4vNo=H!LYn8`3=ia z>1yW7Mm6eJ7NONk>TMmGI2&4cSWaaFvwxaVEYIhyisgg8@gU;mgq2)k!BKl7rE`RC z%H{(!|3=+S@(&6cJ!YC<)eX{QrJpYd=?zA4XyLb6sLTe7tfcjY;2gMCiGeo_+Z&_D z2+9+ReyLx50divJ)jvWPhj9a)|6U_-$ zw6YSO9#-Eg*A6My=w#PK=CXp7bY|IgtqM3A!$~0W!jeE1XH4%xs7QV|;j;W&AeO#C z1+6#~m=9n-DK`waes;h9Y;~T6T+z4|rIWjByrpPTiDId@(Iv3dGTG9TsE}xdLCD|h z8*q@3hrXm#Aisl(fEDOM0WU&0thB9-^hS(ql?0rz&DK$-_bBUJC7aO-GsX%MqHr>D zC~${E*ct|89wgS;<)w!)XhMPI0Dc`9P#9{sU_&V>FVYP&r+m*Y4keZheHjk|qin5k zs;mU}6vg*+6)SZHZA>dsuSrohM~a@5ie98Bk3z5qr=p3ntv4yk3(bl$Hs6=e-}TYk z*8i@aAAr7lrN2lWh)AqUO>yv-9e#R`)xI_1IUyr|a;;c=7Pg^ks!?~qOl zrauV<^B z>R6OsWn6kFZ)UIC&RenjF)H?5Y4dq9K@S4R`Tixq;K5?cw({-q$X5#+p?~lYQ8Rqne^^J?L1~o?k8BN!5}& zVZcER;5agQ%rMV41bRER2xpSl#2Ee0FW8a4DeJ#o_{_>V5)%VZJ2icyGa;~`(t=C^7}?fa~QTRf#(LH&;`SYu-;WMv5@6Dn8i{J zaL1}B{Jf=TkPvqp$F2m7C+7AQB0|C?!rC7XYZoSK5}}c5Au8HT`FwuT@=ANhjqYzV z3>6Oe!xYajhDUSpJ#~na+2X#Xg~ch2&Q*!;_sTt(R+(f)+kpwjZ$sI&d8Io_#RvYy z8u@EML>{q%uTr*Ap+${af-#8lKGkLYLn&vg#9k@NpC|Ob!-HStf10@Q{x2qOaw=X< zPR{=_af^wH{SP)Y#-^>PposBk>u5aF)6_FDHo@4mZOp74?CgD=ef_=tWBp^0J{@rw zw{l!cb_~2Yp{OFEygI9@C84P|>OWRxL}z7XCB~}Ug0U+9hk%T6DEDpeb?l?xU7`mg z`vz;?O{YvuS5HoNP0f|ft~IRA_0Fy!mo|F7ZT4^cm#27PeDd??KTq+-@cKS#?{wkh z{PXwAV1 zL!iZ`0sq!c+hRD!7_hO}G+GP|z-$#m+lrwPV(4ixH0D;ozmovAwg3bsCQJ~RTmK#W z?`X_fn9XR++`oJNJqTOdXK?Pj6lCO_$F{zrwb!zqmP%CJhxs8v(_K zcO{~_*3C&ob-rXVFm6`K1WSxvN=!W+i;Q0ia;{>BX*2p=*^2lTywGs`pY-B3GE2;7=t@koTSzodWLnz`nd95%he|8YnZ3|MPj1>Wn#Ug~urhk>C_Q`fqAZ^R z9#EjD@Y|0!t4+kG8p>6QtWcV$iMM!7;DC2rzE#un+0)CMJJqF2?vcHF6K@@J#RQ4d zoY(A6f8F?G#yo-M>7y|t?>^9V`b^ZeG2t9*v=UNnll5(|A1_=RRU% zgW+XmbRLvXlpDUD`C++pes}U1A3QdEBR8uf}w`>P70E=zD;=^oVPZc!(k8YbG)Z=&1x7|mdn0)G7Dh_>SI+S#mm--}=%!o|mt!8h=zHBh)zkRGF+3uB zlI#mAxq-tmQrli|Cd z&u<@;_Ywv`L@1sUuE}x3iG~lLAX*lD!{sbYQ@9ad{^UG6^ zii#I|+5@popHKKn#0}zh(;|q~FYcPQX8X%C6}6hlhgT4<#s>P35m26u<$nnEiqnXb z@PI$os(lf@l2yRlk@#o=NKmN$IT!yD!NyYa%)w)-HsHGM*%hnNn7V;|d`G=KTFZ&@ z!x4lo@<)SP5}#RE?ILp3TgLfKtl2N*Qt$8Urs@ekg_~LsWpijVT`ka(>d$k213;2} z=|eN(KL(SR9W3$Kad?V@;a&^uV7zmF1<_v8g`d00#WwYhGFwUtrTFg4L{&EUe-?9Y zblXJ{Y%UlL^2bXhES8rIZepwk;*8d9Al)GX$HBGtf?YT6dM{?0QF~FGZOewt@PdYc*y}$QB?hQ= zvc~vul2qfLmED7fZ`@R@?p{*H?2ORPUi8V57HrFlqV5Xbgc8!tCe$0T;0o?PH@Mp% z`{LIJ85L2~xwA$X<>XT@w!lkFNdG+W?}6=o4=Iz`h|x5fRC938Vyh>i$y*wCT93^g z>)n<9kiroabw>DL3bZF`_|6~4OF74My9E-!@;t;d?1_i{^(f6uLT6j~Q`Y6EIe2Hr zJzlxkjKklJ+lB1Y_G%S|40S$KLvb>nui6ay$RGjrsWG{uJ`i-=b})!tGuzSVJLB}y z*L!hrRHI>H;n<4q&vFl^V{`Tl{FU!cuH3x0cbe9z<5U(qr)_7a`<8Qp&c@Q*C_eKG zoh^-Lc};D>PCdR~?GAXCKFkL<<^(dV#&3A$sR$f({+c;03i`v9h1x}?6r8y|ko|mU zKIFw!_bvRpGy)H=lGs21Vq=?EO8koV-D4O2yjVcB(2TWKkFj+Y(mH47><7`-%vw|z z-Q4$|o}ph(&7Lk<;$*#)L~hr*b^q*ZmMpq0(!Y0s{_5#`U*A2-67s>2pdJ291&V31 z?iC)CzisrkV+_AEyr#AVzINg$s2{E!i6#y1S;!K2yHxP)zLojizMLeXm!M(PJIjL) z4Y2pOn#RIZi@O9dxAPjwsg8>+%&(bZAEit_ix`Af8_yzlG;Gz7_kk5JG0-BBcY67$ zUk?0#w#}|+TMbN6&fz}pTF>I!JDLstpvdU4`t6BpH}6jWwM6X4zfu~bOXS&0pMqel zPj9y#mwzFG?O^~ofK5U$j=&tOQ%&z@M38ys->hTg_p`H;Ho&#;vyPKEq9wF;?|$pE zrzZ+8{YIEVm{Z0cf8zKZc<8%+H2MKu@MK+sd|WgS(dExq0RpL#El~x&p)%Z+2yyfc zzk1^dN{Uc|(9$090Y6Jr%+A#v%FahXPO zaKE_hn^BI>`0R%JvGT~&|R1lfY zvq|!|Xz?5GpVeBNT`7&6DeuR;&8zfgxqJe-$yq}!^&>Oz*i{hhab%XMY0F99#<8dd z<0Swz>>e0MUS6Ik*zaZ+;t0yO~Ulhn9<@-vz&eJP+0PZp+yIhAlaj}qj0EIi*( zH}9A0$+*`a1Gp`|Mi(k*c3*3LDNN2iLmjRpO(P>42XNy_TvyFjm5ST>lq5Bmohg}$ z`F#iKQK20RnyP~5IK0IYfv5SC*&V)BvdP0T3Vl;U4Wx;C$`dDX4v>Jv9o!_Q=j1vB z;b+kr1M3iJ(>x$mwe)yH?*W>KM0^c!>|1&+1THY*Yo_a-RDSIc7MWYNP7S66X+#Jt zd>R16QiZlSw_Yudl_!e^fkgxbkTmCG&ueT-MZDvQuyn9GA9voVDdYnulm3p|z0E=A z-xNcB!^n^&@SKv;?Gm+-64ps9<|7A=fYP?;67F~?+iGd)K?yIi^wD;yIBlG;NxUeM zW^g?I5we7`1VKktW~K&dQKcBjp+%}{_Te$BI6`E26H&{hWCFx) zLIPEX-@{XUE0WYlk}9N1x5iWXQQLei*O$GNyQj$_Mr$1Mmy+3|#k!EVqm%(@s58IWALuB2$~EAoHLIJ%*^EsmV2< z0rKd$C;!qTx2(Fg4p&0H*}<<(a6lv-s!I{5lse?QOJx%~WP{_f18Rx}q~ivU>V)Si zzZ&Hn_|-2U;RNok0Go7qU65^ucf4A|c{W0I2(eSH)QS{ruWcy5P0EYUy`?G0I>;r! z&)olAM0B1g%?uoS4$&Kd{95$qJ+Bfdc>#hoRYsQd-@e88umm4fElpC6Occ5!@}~|f zXD1SIdvmvW6F)g54=-09ECXejLDUX#s5j!n7<^{6Hg&0Z&hy30jvB*eO9Xp4kRsy1 zKb^~z`sA<>m!=3PTy*VUG{@5hUoO(;$);CJ%~3Ckz|W#kZ^0$ShErU7Z=$2CI7IXw z4z-&;>ahM)Cg>RaL7m*I7ZOaUtnJiQAJ!$1s{@W8efvi#jIX;6)=ke#;c*O!n^H=c z>h_W7VJy+PcI>g(!NSEf7^g#)${@>4k(GhSk|`{?X0n{#_PnVc)2p6pncjBO-WonK z!;u!qJQ8Q9*Wh^%ZcA75F=a6!R-JwCcwS%0pR(V$eQ&t?bmq%lcvO006Y^O4f0bj6 znyQS*WKEhPsRlul)mT!gpp;iw#ZFjMsQ~x#mWa=NuaG9zxz8)7K%{QT-(-*uwOCG* zZ3lT+R2x7hd?bNx6(z8%vbGBLA|=?w<1COoYLe=&swSGdF#b~_7@Z2*p#y@+R3wFg z;O0!JVj$TdAS3===@bYbDvTO`H_3yGt5*xx)QYXtLhhQ>!6$>TB~I^d2nShHvA*VH*L4H5CqNZ^SrV40;wg}j8R|5l9-F0U$`SI*=e-eC1KbeN zd6@HliqiKviZ*EE7a>yW9B`iwD4-a?;%%ug9ns?%G0Yz+rhCsTS^gav=*r$S=h$=> z-}IrX>FFB6fE`6Ak9xZ{diQ6PjtHw%L;I%_mY*z=`b6kW;>bbW2$%@bMxKH1-r}6u z0;?Uwn=4==Eac1^wE(I)(Xn`yP+}FZPc1KFR~hF+HNeeiD_@HM+fB(RU|>xb#Qx3d~ahGG4= zY2`f~;n#KdhlS%o&u%9fUern+=wo zR0(<~S6BymR3BKbK2zpXD>L2sgdU!>)>L>nPRTxTj9gMP%hbHfq&-LJ%8rofjAZgp zmdXtGPmd_p)=$%p&gBhesUXgfwf475JPj)G;uERFV;)2wyv>sLHIV_bz~SkYlBqV; zC-2XUAm=9I7PL;0!A+g`!QBqzcaHsP;0eIivVqxz+Fd519+f0GvTvh*s-GUYSO1mAY(%FwGsKi zmY(PBQu$;{^~KMQ*I&)gv}+Aqr~$U7hd|Q9%f!<+49LTie%=!yeYMSg_j=3ec#ennj`sbI=7UlhmmPE9u0hDI(fSVAOY#b>UEQ#q{Ue|;MoC(@qxLdLgZOP{ z?8lFEL%Ab+4J98zBdCYWd#VEk*LA?URN}mT2l{-1@Ehz0ZWxRk~b@`kQ+Jx{IAJ zhBBlyqSiB|n6XIa*q)RgzNcolDg<`FN`nX=XbgY|Lysx^_X`_$sLofWPnI6Cj8?3E zj!o1s$M0 zxln(A1xeN2N}9yeU9TsqJp4P!I<<}~eXapi!(lpmfufVMHjqxr$=#5Xo8mt%|ppKS1W0)0#ZInkW`72I^)QJ4%68B%xv##UP9&e353 z5fC!)mIK~1C&W+)n4@xZx0RC_p8OXVI+01W(2QHYgn%61n|%ig8JY^`H7iD~=tklc z(t2S2X*}niE0l}DxVW!M9*_um%2M2jkHzDOmYY+nUMof8Fw)w`Hp?F^QPt01iKi4~Y{&c9$W@;cf z9N&Xt&mJKossQGtcEuGQJdPK8zyj78tP|X|-qOIv!HyJ`$LIQVCJC0ra^=Odj5rRb zo>mY7eU_wm!fsQ{B#>L&5*;5LWxPsyn*Fm49~sAu5*aJQBTDAPrqdr+VTfUGRb>kc zuj^kZL|V2JjV4&O*UoCBD57g*g`L758X6V%m*zG9(RJQ34$Bym<5?GgLo?sAE>wqN2mV)OBS3W29MdtRdL!5ztWW zb%m$Fs}v;(<0)&m5@WlfC%m-QR3F@<-V3k@quDC zdO##PRy<&Hd#%3yP19*vo@1_BVW@4cn7t1OkNM^?);pmbD9GVODD-=7-V0cGO`VHG zNek2J!?FPg1RcgYge;_!Y^De>5-l_4?JeG=Zc`gR^gCK>Ju&%KEd$P{7&opc8kxi< z)1spR5py=Ht>T+h7r2kvxNL-_xef;j(tV%gYn^&>WMEj~6&R$#M`PrD-KBOF6x=o-+Va zN>Qpmn$PVq~N4$3{g9!_v z|0!Pcx}aNL{krb?MhF-6y-gs?92) zH(w_wE~=IZscU=oT_c=%j2Xm1HC{<0E`FY%v0vCt$;91d-zdAr=9Q0AG!*jJ;SyoE z0GAq=x;0`kw(_r>Xy}&KBrZS)XyyKJ5LYnkvD1ng7?&J?#q3s1v}Q@5LXb;fyDH8n z%L4ob7$zOvj8-Dzd2J!#Ql|f!u1j)^?uAFDyO%Yu;mV}KKvQPS`yI~hZgc7ARFe+=t@e@) z5Kpg1?&o|7x8z%HfDT>)1r(GJyC4dt_>sEqFXHV|A8!8Thq{r6Ewd-{TPIFZ4;)F$ zgLax#5VR3m&eni&)S#DUB*Q%OU4{4KmwQCP{p~xsDz>a*wDSrB09<8z`&)d(Jo%Gj z6+zmgWNVX;`Gx1!(k2qAKUKS7y$fumy!r^~6k9 zljOWoRSwJwJ$5{x6^~S$3sM=cLUFore%L76ePZN&;hl@k-RHzD!(4@&TS>N%@otj2i0~^*9D?y{%f6}{Mgq4+h;RL~ zqnWTk+}o85xrb%gf;*uZ^k3v>0XWNvMnH4+=)Q}j3Rnn<>9^1=0)X_WSfl&I;+;~~ z=N@n21YLi-)OGZv&+Xtva99ME)UE)N2TuK|N4P@4Oxb#puE4@bbf3>Yr>hO&y(Jcx$*A|-twj|=Z%p5FhU z0kT6CZl7M0eH;K05k137j?o`9=WQF18Ps<|x8dI5;p7v^Zf8KhWXtJy`Ghk(AmR~I z5UbIDswDPErMF8}1A`hHOdfcqH{$s!*m{1zfi94cS# z_RiT0 z^=|6m77cd^DAUl1qkX6p57g(2!@04@yPlp}g7>al#eXE|c(( z_0r{>M&d;>C#ae_WcxhosiMSOFY2vEVaI3E-gxF-8fm4!ghULvy~!8`3-74jq>RSe z`vAV7AbqKq;;pGZ9hxUpvUtuojmBZ%s@Che)#io5gFAJjlpO|{OHVa zZiRO-vK^S_!Nber$yei3#p5aD6KPkmsq7OOk%|*B!V{U+6D&iFVuOtn)#H9*1y z0yUA`Txc;5e<{_QH$71dPR!pFDJGvR11FNs#pcpiE|ema6(_3|<0J697La&lnUnS6 z)V1V77)E#lc&bQevdt+pad5I3Jk_E&(55(rsAsHP!|Nz-=`5d$ww^+wG*Ww~`gW!? zzDy0E!PDG-rUuzHY3Qbl-Jo_D_zL^Pdv<(c`sAk(WDl=mB{gFyCF@44HPgJN(;!Nl zI&tFV)Xi=Ek&v0f;pv%Ale3><*<>@=?>f49@aDl15-p8U&0(Fol8QqK<`H2%j`E-R zRTojQ-h2f}&#po4_>Je8$5z0eIOr{n9<;0=c6Y{)LEG8U>2UDbpyRsDf&U7Ur&wiXJPi>VRJ3ov2G@AfbW{gMK zd}^R|lm(A#wXYIWiRNKdgpQ{T0~*GGpJP3V(!IRO7V>9uL(}?ofPK(0>UmYd7b--= z#7)79^Yzc?DTxO{|BFUJ4j}md5Hg7fi98Y){~uZ=m>divXHrxBZ{&orkugTg^xE__ zhBx769`?QJe-?9A!-FD=vm5HcY# zB!!gz!J2`|?9r*Z$?^8Fx$@cN%Eh_P4@=#P8=dPrecS&fVfr{V^4}7s_v^<~hlfiC z=bz4gEL~zGOc>I^e^g8uP0jxnGW~BM(?8W0M&|WTw)P+8)<5mlf5ce-RBZpzSN)S> zO;4kz(P)g!4WmB$&uWY~3p2(;11SF2g-riX8bw>xha%|zi$?K3g-rjUQT(@%Nu#qG z8`u70ZHLZ((S9Ul^~xC3(IIvm2?Tv&SYv8Gs4#+C#$##Z~7(5haTzz&jT54f&Qg+^JXq zTO)>8rU%su+ig976Wpw5j|LmX3HmP_e zaFfCS==L-)K4rEY@i&Lvf)wRN4nt462o;1ODvo<#|hwA6J7bw%wv!_sG6(GM_A#?O~D`kk$$eW#@t0gB%Tsg)AXN4j+b z_Xo+AB3%c9r6wr-D(CNe=bHt62(81wAeywQ%~wVz&P8x(NDZa-j>qKg;v=Edw};CO z$k#Yu%X&*+ow(KgnK3%34|H5x@#u;FXaLGg)oitf~`BO&V6%o$7&5k&JY zj`OR|L}smkuLb3YH@>FdbbYSB2ARI_HDvnLkmK(El<#KK`fvZ|x!A{NH`}Qyg10-F zhAy|eId+Y=d-=X+xBJC0g1-;Svt524R->yLe;?I%o&7#;9!r+4X?=RNby~Frm?vhK z?g%@3wb=~Re*gGIpXR$CUb05*OXehJguw5R@3V$GVcNWsS;6L#WIb=5~5Ru zL7L$mX*@McFh|ZX#o`B?Ycb#htDCHc%CoTpu&r%8$$_ZIxoE=q5-8>PVAvYK4_Wu^ zZVPurP~t4^A+U^!0R#)*X^JN>g7N+JksOuS0*C66l+l@bV3AEc zLx{?man;7EAd|P>=RFF>XVAkh8TeiB}NwLY1Kmubz51sRaF;K|Cr_FRYbqLPat3O zAtBR?1xHC;%@bQ%KWp?;HCUil!Ls&wst$R?qa;Vw?jHS+_4c%4c3UXZ?5 zt@7}1?IK2RHp{5$=S%VF&rHbj7C&)5x<1rOmFLxaOwd1Db7tyoO~)drbbhuK6F1mDJq9s4|7;KO8nQQ> zTE)%;ib~#ZT?^y?qc)#&znf&lU**DK?kA%L(V=3OTE1@p;Q9s>@|b;Cx(Jlcw5_m$&`?nc9*h=-S6-F)!Y?oHh!!dU_X9vndn5cT05JS zWk%U7cg?fCCnpgDa<`4y|6?6iY#GK|*;*KEW%JN?8Jlk~EK}{$3fmbmmU?#??pnKj zsb?@2SI8%_ME~mXYdsb?ihiYA%89A)%xph;Mmw+K!lY22kLfhz&zwZx(fY>YDY{W)szjo`j)Z>)dn{|} zU1LWw9g*6>z2^|#VrSEsvqStEv={RHH7)+|Ft+-$_fyHg%!~+Mxf~m`{~WyzIHo1} zKKbXHiQcK>_R&G$_Lr8=>{y)6K=kbSr1#4D?Cfhweka;)vwHyKUx& zJ>x2Z9!Ys-!R*g^CJoQrKNbdYvxfATOS?qiaEI38yXsNII}1?Mh^$wL9ub3^iQ&D5e_X6*NH0!gjMKfh%LGqd>)f%EUZ z(o`5Cq;-Z?-F1NRkzbk5@1^B0d(VznX~KP%{up}c^pPC^aB)^c9~dn&5A#_9DRM9^ zM=zwqd9wezS|6HX5R?xgq7K09y>N7WQLK(UCcu!q2O|vlG2>Cp z3Z-gi74 ztQ+bp6yOC5oBR+hz8t++6@ey1U(7!jx7f3>k!1dhg$9to5Mvuhmkj=x?=2wek^w9PVQ1t z3F=?R@S4B92=y#3_LKw=8ECO9^autEL{o~F{w1va(!I;gmk#a?nfKYS@S@}ci0r{w zwUz@PpoqkOANFVeepVcP!4Y;rRUMy{jFUfi=58ppmEvj&@84~fMSyAkL zB1f55&{D};9pay%9P$%oZc8+sT`UE4% zaEGP9h!#A^SFp0a>UojWMCY-&$XZ5}%sXHs0IXd1N(BNh@=%pw;s%(=FH7>Ky@0u2 zp=~fX7q~~LIY283oUp6pu%zcUz4#-TGa*bAL z7)u=qoJFtfBGGkoX&qu@N@DU;thiWwBs4yyFy^Q4z0qrtTndZjfdT?GfJ^d*SI9#A z7I_?xNgiuh9!70~kGY=>d-$P367FIyzf?S{Mf`1eJV`oeQ{MNSD0vNDKxbKyTAYnV z;7(PP@T1g?*TdgZ#PF}Yh(J0yT(3~rqfk^44f`s{cejv|E{{Op>up5A&-b41TN54F zlBi3ptk?^M9P*)v;?U55rDlZJLBP9~Xj!G~cQ@G(sU+;_hoJxj3W_jCBLX1_?a>k!3mKX`p7CX`kmW&dqG8xbeeATKNz$K&UyP@fjYJTB zTL{T+shHF!9={2j(yvtFubj55Tx_jej&PhWb6TOOlK4@%Kv6Z!QN;~pM=Mm(>tqpn zWT{VO`P63d(N`z^$P$5OvFw4{%OZC?-1pc61)u=14vO86m@Or_ycWi3gI()+=;(+3 zS%_p}3+xROKV0A= z^CX7yUSavTKFSv-C{En^ylR;*q~}FYo-cNge+Mg|*^MWC7_V#%mO_vP7!NT8Pd{F) zI{G$3Eu{k215ia-yue{$Bu0_2WdT!IF>6{QcY&nsqLVenCmEnVfwAe5quyDmzH}(x zBO)Jr8{wz?! zRMsyX;L@OLtF&t~^5NVboa}|hdPXKN*`cii3c_i@ooaksT2uP1CPE`}Ybg?U8MWC2 zz$YVVQTgklxp7`m6$`a@5cl+R9Kyy33f9REB0dhb_HxK1=&}tUnFNtY0s^p3jv7#Y z9f||hvsMly8+=BSDq{)#9DbAMa9foBqA8Ldu`24ds@$_030#)DZtj8@CP8Rr;4K3{ zC8c*|sgGp2g9OpdQ&Xae)BY+kRHv<3a2eWr-fy4TgR|TLU1!HpSH@QXR0an&MxFb1 zhuDw$Ryn~9WsR5)MK<@Gp&ujt^>AO`7x&X`^*f6Vz4b<`^Bi1_ll9d>>?;YyMSS;&((4aMU4MHquAdP1+7r8UhJ-9UKTifDdpI8=hM3pykWP zq;K^clPnbNmkDc?z8a;K@(w#1I?@BNRk)UD_*NVZjBs^k3|2c-^p)@zK;l46)=9I> zX}ysZ>o)DocVA9#EB=U0f@?cLK9d_>o#-8tn5L7M(UaKYlZ4_^#92i6e!^ zkv>`PzV(bgWvanMLx3GLplK6$Y2F{R6eG6emy27Rm&se8;$39;%}neoYB%4qeZcl^ z!1SnZt9Z_R*+6q8?%w;ZK$moyh|sJ|p*4u(UecO8dEBkMS$LQ%6MQA?0q@4&LeaGVA5!BK0yB%Kb? zPexq?l4A+2BST{oqf`SExZ}a%<9R;Nc^hdvtdy0gGO79CL280c?}ZhEiQTc8gS+KM zyw20HzMsoWYooIZN416*5`COq8xGS&mO%?yr-(qw(2qz_K?eIyb0RH)tN7coT86XAt{3kpA6Z%iiR`-|Sj&x;kDb zGcKU5*%UC|ii7?AMuyB_q0gL5{HprnYbWC}HLx8rmBo(_JoVkMJ_bLV*nq`>XS_GM zkHGiw8nHg<4%Z1Bz5PuYUjqwDu4onX5G=Ff{$jCy+L_P zWIUm(^{3WEZPJm3{%Mt~PAABAqMG>07KJ*1&o}Fky}`Z?@;3&QI+tIs?!dG2?w2zO z-6pi{S4MTkh$}m!$~(BgVH+fI+jf8BVKKndY%ozAm;$klUxQ>vZQPAi7iEJJR(Bsi zIm9ZRU%1=E&Xs4GTIboHSJB^u6oLwT4@>aTL_NRbuOGZr1MWl)DUA=UqBoj5_sBYd zQSrsaamx&@oB;`0`@?pUggJANB9p&s}3cK(A+1pE18y{?%gVKjX zT0{DdOAW)0&^J!v?T+~n0g-B_w3eq7o!hA5;})7NnB?)?m{oq;O8(*sRcgwb%^61R z*`(buY!Vc3azq5BN9~@?Ol-^;9@?Gk5rFqeYCtk$+kF)6KIUt8TtD60(srb~HviyV z?0Ig!$hn}T*_89UP`bY$o48PY{!1&iL*enS7reh-S6Ax9{?dE=)xhs;B4*q8`Gr1B zn8XCJ%&LmlU-{`In4HA#v58~p`)v(;v{#*b&7B~W+i$P=-_NCXQW>wjO?Rkbc9gny zZ2#`G#2jM3*}czC+r?4()%tgr)9-tr?>WB7URc#0}03%?*T3JkT~~@Jm$EGXP-wB2wMe_$9>0)AKX|isL?$c zXZzV3cveia`-O&n3csIS@)&x5`?&h-w#rpw5KJH`1Bx9k%vvlwxU=E-bT}bg^Je>4 z;?{|Fi-_(NcJg!S&3FG3ue{SEkOn;j7e*q%CYcJ|z$3z@X6gI!@Czr5@V~!gN?=ya z)-rk9F9RVVac0I?P zbt4rMrAZ5IT$o8gYFrP4N+=Iat4vq`1Ur-i(fLo1!myQ!vo3mGYGb9<=U6C#$dRhi8P-1fYlX3ZNP{L zA~jnZ$TGOJTkRmx|L2m)ezS);&;Hop+Oek|WBvn;(T(%LjK><=KRpVVK&2nX+Na+! zyBp&<@;S!ha!1Q6U6-B4f4w8?z2ZXE-rW2C{qyG@LtT84xVgF=^jL;Z3PQBG0U@RN z*CkUyjWiCUvwtWAzHKWB{;|a;Lm*!<5sdRvhF=!z4PEVP*>17BNz`eAQ>`3juNM@8 zEv8;8PfO1fUP&2xSAqc|ZjA*9i(W*^UD(ef6r!H-jq|b<-t8%cJ1!GQ6LVbEO5>_r zfdVm}=OVxj&QZDJm=qL>_X=FQ^+O7wo+VO>`(=q=&_rC$&%Z>2eM+Q>P`FOgxa#&1 zkTC)ES3SJnm!Akq@s1Boh@KnP!G#%>qFIQ8wuxT7dRZ9`!CSmr@5Ww^l0+lTjW7Y@ zYgL*AU~}Zs1!Jiq1i><@VFEo>x|8g}P3qs(zXf@!n_!S%EaO3hUcU(AvSF2WZNck| zPS8W4@N|}A7$PvG1L?%3=M7kcwF0pON>D-AoL6--7~!u+mAxNy-Vi13;1Vt;Bj;pP zkZYK~|Ei&*qCt?7c=Ovx>Ih9EA3cl9ZeljX3_9LGUz0I*mtps|Po$6iHU@v5``ci< zN#*rO_%!hs3lhiFdw3X8!hA4^eeN{e@niO(MFFq04iLQ{>s;wa?|d-Hdz@tdTKCuY zxiw$zw+f6B?D`^7qCe08OXH3tc`$&*2{#XG6* zJ^d3E-UekZKdWq5tjl=LIK|Qp3c*v4sc!$R#Oe4YZAJ9q6yUBz*-C;TK5Arw&9bDsy{9Mt=gcFg|I^B=_P{;=)A=YD@Kcf0)Vzgw-{ zqR6`LNhT2(Hl*>F=$H~e=qLSYJyy|}hbVb|Son|P+`Jq$3?wCFb=CV1Fd|T*A*`N3L(r)F#PYA z?2sT1?gGuX#2EP;+AY}Hb$LmZ_Jy3r*BtiU6xy|XbaB1Rob;m!dCe8CYiy?an5|4> zz9zB_ei6j`NOep9Xf?RneO&oH5y!$n>xX^?qrMMVif^}wq1^)Mhvv51hK$T<0>v## zaT>R}LvkM)p37mr_oHI!Q0E(vkxQ_ATE0NQ>QN@&*(WN^sPDWd)T<{q5tAI0K6g_D zsDWdwx;OO;a=(@(Qp+%yjt%6;{nzo(em7LNw!k4adf^(>#jM z8Zqmyt{sYYDAFU^E@5XI?_f$OGc*@dB@}_1MmzJ0Wz}dkjL)c+xby~Of z8(pUhd4nxg?q7k@W~YlV3-(oAT3>0A&=q4|m%i|&(8?yADfxSDsTuC6RrD;$jd^}Z z^YI?2OnU}U>p%FB$niQ!|5uqF#2RQCd9A1|SYh5ksrB*Zb$z2?rCqSKp)9dhPP$B` zW52cWuU4JT-!s*I5E~PS=%{WF>1<7?_`Wo4iEiJsSvjg8)s|_r9#~IJIQqMacY>mM z@39|6W8PHAYO9ZoC(p{NIB&}2?k)TcdS>FNG@+!Kq4#Z8`?D?^5jlweJA}KaKF@#%RhnXd{t(@~+CcOyURr5ZiT_?S$ zn+|4?F`E}SX@rYSENeRyhKud({1(6tQ*@#J`Q-BVrDE0+6=iQm`}^@rdNy4wYp50J zL+Yp7(e^BmSw*P~kBjw?dANen&om17A{twJ< zDr#u_+}PMS@^4Cxz;;x5=Wx=%KzZMA!_Z{@_;lsh$=Zqe2cF%uy4mz!lpNF3gWvw~ zarCb45AFQ}vlmW(&i&)#_`UnJ;y(4lmEr2_H0SuXNzyi zMx+0t+My!qLh!1Uwg;+hghOBXCftSK(W-LuKYEUr_}Q5Lc76R2de&@}mb&+&7TiiS z&BCVUkQ{aq3!Bdf%N*od5wp+v(fh#CH>0E#+V$^3{T>fwkGD0Qt||X%&2IKW+7I{p zbH15q_c)7+jQ@0mlR@V)QNd^)YMe_K1ObzoJ%0nrUJpPOLr4{>&OC4ZPoxaY*Z9sB zj$50yE*13eeFGw;&S>TG9cI%IApD_JzkzP^H~x#Sn+O6xJc%pz=M&?kD?U)!;-%L` zNjkJIF2oB=-m+FD=0!ZJWcw6JKEQ_bw`kehh!XqNkCZDaoHLGH;YZ(6Xz(rag}4lA2!;G9+Mzp)8QJ0Ec#)%1~C zAJq=AlpocNJv%)5JSoR{TtBUCecUkrq5S^1aoP3oxM@9vlc!lK1}6uxXD5SZOoN!= zQ4`^`wEgmJ0Mw52P+Hwjfc9@FFuC`uTnL@Lddo_<{S@Yv zXG)b68@kwJJ6a)KTo*=KuC(6i&qJPWJlFd-!l_$QJo&U1tt9HXf+<857Npr3iDN4F3@%DM!bSxuA`u3w=B%d(2`SDRZcghXRPS62jr(v~*bPahC)?<8&TmZpu%d ztCdYfy{}NjES?_{6xl{Zi4`(hKanTqiVtuXc*D%Q*Y$klX9zv|_j>I4k#GeECO%Lh zi(;LuY5G+3aAu(@$G-o*#wj|!vk7hV9>8+L&-yf~NG@}q%aOw@jRngbCi`~6NwY8U ztGD9)4cQmZMIx4=4A!$$w=aUWwK-!8SrRF3(ujMCi(E|A5^38cGz#1cBs982hBm!E zSfBU}epZPbd_=>i^Ei(#Nwxi12~k)boe#BYsZ!vByfyfuP>+0Hb>u^z?eEh9wvue> zc#ChLjdTG-V>^VyyC|gHg$t=ihO+6%GzYy3AozM;&1+CTJmO0Rk1lX8&@BH~Q7Z-; zp@)kt0)1>@Tgn(1c9TA$oxY7i>wR&!aVIN~-i}+gSx$$}JS1b|i7Fx<`@sAsq8o*s zT$UVV{MM&GR%*2i%+BEL}a;c2lB39aonHv_zr*?`VJ zJ5n_k(0MB!3-pb2Nu_cSDVIxPDc(oLRVD2p?+X?U7rSTTh(X(f-|5qB+aDPtzU5H- zDqhjz!FC>%xpu`39C@XHP0+LQ;D|R%d)ocA^SAa7kyPe&BT53QyVW(=3!hIlT1K%wcZK-q2(GK6K~Evp~0Hf}hwy=)|tJ z-&E|4J+vDdr|@#T$Rc&|yvO%mpLwRlT^p5IbOuv&^|9Fe_1v&daf?I+=hzL{Sw!}rO^>S z%12~YfysZkJ}J`D`+fq&bZnCWk4}kRtm{%V-k13<`f^Mp{acCMj9j6cp@vi9w1{je zPDJMYfxcHMvg*Ol5g4jvaC@q5}9 zOwBi&-qdROXyogQ)i^iu3@}@mTVJ#f@Oc0PzOzDLkgfw*eUb~S2wTR@YMosDpu zH2P2fw+4VAiZqTns*{$Uz)_iUv2J`Rw4(Ar?l9o^0rlt#8YFeTO65`5hjy z+1{h4BB~q_xM8l?R|wm$2*P=5sIEV$yFY9XO4RH>lk86;L`ek;=>P3c$8XQ1Kytcc z%ixY6rT3+^2v7xl?dSukqyp~~1fODj^oM_>bpLp*ZNqj3!prrXc5~885!@~oKHm&r z)g{4pgJH4~y}Y8pb@P4f=1HjQu*Ce4rpBpX8=#0odn50Jg#@P*1>pmhT1{S^p~8w} zB+uALImn0{u1L9?jASsJp2&xo!Fh#>oyu5!o|Cy7@A-=D0+4k+o3Ic?p#bzLd*!Dl z=yT4Muc5A&9;z@)sbX&gYl!Z=%UeuWY&uu7CckQPzbqJ zWFX91$gv?MT-(&U2=2b;;LacCK3QxNEe{MAM~IO{C77exghoE?y zlH#Y1kB#XIa(EOcGiAS5Omi^ko4Dl*27t4axS#N-3v<83EhjW7pag>=b`F}y91E$H zy0_9L^gM^sDJIA%ns7GzGk>y_)=0$JNR%f}%1BMb6CyHqB7AUcXecJVZXtfL57jG8 zdMiw7x=)}ZoUEUQ2CqrBSxC0KPPQjcaokT9(MYBZPu3Jp@oY))zD_2#AS`u?g_@>3 zl1jZq3v_2EwkAh=JC_o3oocfXAQzs>b57y%@S(gwnqQw9-I8jBk!J4!Bsl|c6Es%3 zAc30Xr}n@~ZL&g%AVfPhT$uRPyj>=9aHmEv9Z?EboO|wdavnPruI^`)ntpc4Q>7PT z4vWSlNJJkDQ7|`Qy(CUk^sayt&9soZm4M)q@^DlFx&zt+Y=Z9sD;`e7xlWs<`^j8q zPS(TV$2Hm3SkA*OVUR}|@6p1oSP&?=@Ru0o8ka;1qaIjpGU4m~uR1sC|4iz(cd ziVolcrC7_O5!>gUlIPee=ImNN{k9h}wqVoS_OON%f$pUp<=CrWL8Olv@G}7<5PGU zjmmY-=Mt!7i(80D8Pku9qQw+t#j-LH;^M_J$Lo}GigF2La+QAhFnf7(dU>lAcfD14 zRckqFk*M?Gdv!!!B6$UGciN6{MG;3DlShRjf9@OlN}0D z@bt(97(O4e`Z{cmIb(=|s6i2?F;vwO9@>VLqIyu)J)G57TI}eI28(mRHVu)`ufSq2 z>wT03;nxB4XQ`Q1>hg!i_BrMy7Oi4sTZ&|V_sGVH%l2GMPAe-_X{|j?bN39bIuFPJ zlx1!eUH-ZcyMZFY<LbIw?OMH;ISMsz zlck^L|MY0+y#~36)R{#Xx$8dRpesRFC;^K$llzxA6oVi&CD9{Uv1Oq7xyESaQmx3+ z?|H5Z1kc2<@^VF>6IiXS*3dDl^3v8e6b@m>VOb7k`#>Z?he&&zNBh`P`-B%vB)7e& z4DE|S2L*jcaclXcRR>jV>PkpQ%zg!^r30``8^1LhS zswPWkY2|Jir2S!f7M=in%X3bQ}ms+NN&;R zzIlLDqxpP)Ah9jk+70+gE`S*|cwq&^WfY6tppr*=ABEIO;O1tEBC@SVHsyRpMFxrV z(JIJ6%j8iHS0GQYM-y>Vm`$RNN5KN#U2qiuPzN1*4H>)}U>Na4=N!w&?(Dj5+g6#_ z!A;*^p1>sNI9yJdKAgBP{PH`B=#1)%m++U%<%t`r&Q_()KV#6UtUg@R?%9xT`tuMrI63VR;p1_VrG>0Z>z=3jy`0NEG-o~hxOJx<F@doY>TyZL;vYYik+YX717M$g$$+s9gK85@qgwE$`1BVl$*=BfmzyUylzz zVTlZkGP;*Nv@ta3V-P2>wV6FsM051+a>i|NOG2!D!y}%mxOcU-?U(_1Ie4*eDk;emB-aJ^oR6{O7>Dx=(MXQQMk| zKXP%-+;h@9d}7u1LBx?_G{w60$K={@_2clDSM;g-Sre4P{K3T_B+=UTGbe$XwY!zI zzkk+1H0$7#wLv_hOCxvlQYcmU+J@jd{@-=z-!(ILqF6K=obmO*7ieeu0Ko&)o>;?* zCP>FJCM4leB|E80CYT13PVE$KJVtHYj)RkLHbA}r_11`hx@%(F8pR}I%Uxk~YSo9Q zo8IqA*nG%XjtS*`VH{Z-_eOpX{F^fuppZmM8UbF7ZN0|d6yzSl^Z!Qgu>Pmun_Wq_ zeX8S}M`wF&mcZl|1hh4=!uXnJ3v1HWRt>-hIqRLQvDJVipKP(!>}sv9wMNa*=FceI zf2w1r-}!Md(}m%}rj~Hpvqm|%rarM|RJ=i02JoJMs1PoIaYIt)n*Rh?%#H$T5B|G} zbQQ06<7PugK8TUln$PEBV>V=3*YefSQmQtflZ-eBFonrhUJMw-vqfrkRM5FgC($2E z9UH%5RAFSDwBkWOPQ-CC!Oq;bre*B+r0VF;@s2ontMFv4gFM{uVE6;> zNH6QiGFfx8v9@*Z@m=L?V$7Dl+DY!;ZGMWA_KBlgZjYeANYu(`c|%LDc*%gzDV{kJ zRdqzRzU##E5Vr$85jp9{U#FovC^*?Il4{^KY^YuNv>e^G<$cNo`_4zZvFUmIvzy}l z8Sgrg+Ie^R8hq{i)@WUX_Coq`yV&VD{PD$$=VfvqFNAr^S!34t|86SNp3`TCzoaEz zP$SXvgBqN6vm9)$#2kr#+@e8jiKv~io*hoAnn-m9DXu}4eFKgBpbl?fsx<2zcIRY# z-(UNF_oCU`;pu+X0lhb=nqwr(auz(EkJ-U09iopqW!&1a$7ga<16(FHC=k1zYG=u6 zKbgCZHhh7yiSNHXj93o8Z*cW3?Chmv)W|OrImKFisyZ$Bdn^#Qe>}0Tce}rHvX-}c zd}xOx>jIJ297wf&tID49S^A0b`}egS5_Ny9Y51cT|E#0yRLlCLn-{3!>USaE3N`zLvZ^U$PsU{Q)#Q4Wq z2R5Z4g&YWx|!m?@ZqPZL0jkPJ;SOp%T|ehCJt z(+!BfH=&!HEz%!SfXE~bp&RtRaGrV)e-XZpsj2@OjJuBhvqXrxSqp+q<&Fp>eUiHl zV6(-Uyi!YXL4Yw{4n6C^nMkzC)mZw;h4GsTGR|rGkf9aQd1v#`nbqn2icZM&wPN;V z%Hb~~|KW_EQrL*QXDVd+&64`|FNf9#F$8kggRuM^NljIHefS_)n)XOK89lzbr<&ZY zBUAn^Q9Aw-`~3h048|5GpbtNAd!OY-I%*Ql=%T(LbWhLn32e@tJgJu(x2kLKj@P0) zID7TD#N(0q{ZC&$ZV_a2Da6=ou##Xh4m0A0jI%$dYAJAdB-bXWb5_@VrwNL2H2cDa^&o}!e zgDi8SJfR=+IkWjbzUHx)|`PfzIMt*(EAR&OodFGC)W&XYCfwd4+D}KcPK7O${%g< z0c!8CeD{-GwV$TVHhc}GuE7S;zeQn~B(;N{y`A*0+<$}4x!r<+9|d4&5n`g#1(MO_ z2GF7-4Pi`Dgc25R^jy=o#3&GC2o=Z{WQzM<=*9fdgOv~g;JGyS#zfTw5%xhJ2MftC zG#<-5M}JF@q)Su5Jr#bkpD+-|R>W{Gt`V-``FP3Og@PM9%2p$j@|Zz^M{cA&GJlC;rd_^4&GcQ+eBl!ko?Ia=gIq!qZ8af+-^1|^ zuRfDhVdrsPE)ytr^^om_H9+6dm$seC8ypIZCW@ z`B7{1#-U*8=X;^g8Zw+?wPrk=nDG5SDyFzknfjRI_=}`4-#IF86(Kf30{9ag%rB@$ z>eyA9RJj?6w?7D(Zhhu^gqN5)EIHLmMqgOVla4crDCUXd{-{}Cv+DgK+IDKSLHCT-`ZKNCJZXXf z>t@!5-#N5tTVJb0X8w0f+x@>V?O;;?+NL`Yqg5LnY-6@GNESl89!%s>0e-@%H{q(C z=?xrz5Es?|dccQHNl;1B0xAC5_$&meYHQl^U4PM$sIm5!Wu{fz(&Oyp&-m-M_AmAf zHc021Jr=p%D@!j&8UAkm5^U#OC~9<|J=Z$dZ|B;u(q?qxI@h+=k4+gIE_;^Tl%eX3 zXWY-I?x)HG$z!PY_%5oQd{HkRs;|Jv`u0tEM+#$j#z({-G{wuW9}*~|M-z`kX;dO? zy7|u#=D)*N4PH0XL#B+*=Q&OA&m-t>HdA=-1yk@o6&JJB6krj0Y}lyH$54kj_#Su= zG)tVhh2{C{-+7gjSQo(`#W=)Wz8m(lis50V`4Ya+xJ8ZTkw7k87gu;k8B0O#1|=v( z^GjL7487_R&knxt5Up#qsxI6l(ZkA%%0Glwn-VTx4!x!foKQH5mL~@j3*= z1$ua}pxuB%iAdR5m|2)vpYieV!Jok&c)GldoVwD>SE{cbR^o5on3?^TmH3B`t~Rdj zZte&tzYzD3@bK_|hT@^g4^$l)o%=8pugk10C@5$u{0FI{0@_g(oqd(PBMn2dmER^C zC+1sc*E?4?y8Z#^|3=RTcK@O0Ur#R<&;M--{!fPDq3Q6DT6m~EJftKZ+7S=2h=;_( zLwVt$$?y<-_)on4pY@A>G9&*qNB&g~`Jcq=IRDQ_lb`zf&YX01qAkgQok6)z>-<>eyCrdF#cox;_*ZMg6;oS{X+A9qJEM5-_|b@|EXUL zA^?b)2`ci@`jr9j=s(sk!0aslNBx37?%(PclW48{H8g1dzJ8(i-_0B(w)4lU%qS=KI3}zDW&_cH*cP!$bGoYip zPnqeA`%UsmDby6Z?^CvS5k`!nYK;XdO)&nwV6>(8g0#!Q&cgt3%@md|rA#Yf;o2T2H~w@i@l zW+gHjPJ?q&Zt_yr7#){!mxQFexdn_fxLEtgl+R z-bx>%JSS%PE1ey+g0XBIxTJNumR*<2Fj8qgqlB;~N!Ch|+cLQiAH6Ql)<#$S%pdvW z+2<0~%9m6WS&g#<_4#<^m|}5r$z|FsDIK;}4iWS4uYwTg=wszdeSM#U-_1kfSRaX= zXtj{epxL=tV;+_1EU{d+&NFMM_bbgDd0w`W>k;xuH!m5TrC+u;7_xi36M1#fdVkrG z7g+7RdrR~qp&!DbTkU%}y7u=ZCI14iM(aqF^q%4hg*jV|jXq{l4%KCJSUyzyoiVq` za@7O#wG4!dt>?)Iu})AOIJX#>B13-HGVbs?7c0%}Z3?zBO7bDt-x}gC=`uau8KK9a zdyAW+TgE=i>rB4%b*)va?)lC~z_mTjdWV=nr=vEJJYg%iIk!SES&_q|!XLl6q1j&{j)1xd{A8Sq~#nrVi3>{|ebLpp8ne-(bOIn8F?!N4u9={juf0{8a zc92K-x|-Sb=ciRT^s?{3~-dc~EAGqeWheg-rbt~Ehfu5%KlQyyVSE#F{p4}*N zAGeJus}EE$w(Hd^V;I_g_?POVn)%Nq(bo!9B+7B`aENOUV}y3C5>CJho?oxF`PFu^ z_9d2X`x__VDA~VSYKO#-nFiO&7e-okryjM`nAR-eQBY~3psc4fn3x+KIVkS&zVdI*ZIV>pu&Po2` z9%}ZlTgabLTf)nhBl|BK3wRY)`qfz{EO7oxGOGK_PENNMR~>EZ7__gDw|~xH9s-+W zZ(j93^$q0>Yu{#lc|BtA_h*WqH;rJm+L+hh^V}S9-Dv&C0V%DJy<0{f5<>HKm1k)sm}ZCaUE=aHW?giL&@gs6J3eP z-93qa$R)4>H)I}ja1RocCkG0|VIoRvasi?|1F_nB5JC|*@IcTNh`1R_Ed(9tccRzT zJ7`k$g}5^4!kFCyc;f=%AEvjHe&{HlrArXEWMDEGf`<+eWb*~$KqU5LB$y9m-Bs<; z8(DX!_ZI$&{6UJC1WYgwmOZce6i?h5L_!nuoLjJwkjLdELgflfc}Bc9XlR3JbDk6; zr=S*+>Y#8HVxb|g%;v#e0%o@G_DBW1!h&&i0iCeWcpb1?vr5fHpxIuSmBO2dW{tQZ zvS}TVahTsLmiDAI?;1NDvMXq!$Z+4LNS5wqqi~X)>C8h20eD%V=9p`5ATPg zJ=3n8n2>I-3bNP*q1Zy5Se=a!J0OmXKJK&_dbQ`(hZ)nW>&-qZmtK_ip^jI6tb7qzQ{J5)+<*RxA}NN(mJp+RkUkA35G0Q) z#f|$xLYhkFG#37n~r#M@~ySm++82*P!3-v5suX zwKQ14nhL=g^P!)LgAMn*Y_CD4uw>q0WtVU@Kbe%>q$F!LSLKbQZOmk+umGCj#N7GF zKs^t?c|X>Y#Qv~wdtr-fCd;i4@e{>FFj*BIJ^3PCJ162#Ue~d|=28;(0#f!uJBLD( z-N4ylQEa-2TbE#3L_&19MMh#mu$(Jtutxm!D;PTgS6YU4cRZLa(nvS52@}ye6zO>t z8N}|<14FRwA+9jIRjz{tb<@brQ|>u8)CgU&7E8%*N@6bbT(8n{QfqVeQ&rJl=-y-H zrqJguvXT5AR>z3Qr7BXbzsQAp!gx?%SUQrT6-l*-q`5&-ig-Rud3}LA7SBAk5#$0n zAqh!_ykOoHQyP;JDJ%kvnG3L|=ZmBx?}UiI$djZhl1kk`Ux+ASYvjX6@(I*IqKimk zIxsaK09yob5FmC0l3fyj1R}rd#P4AEgcis5UPRDvfbmfUs;$VE98j(^fFKvZvM=PK zdl(K<8DeKux8$7&X5jf}C}>?phfSs?Le6cin1e}{*;;0C9-cQHft=LaV8Tegh6OZiEFSkesYp_MO zT@>KQfjbwGy=7p6v+~S?(%FcjXmXWU_K(SFVU+X5p?hW12QIY{74;+F59yV8NaWkg z$_pRcR<$}^IBlNX<~w+iC`9BtaW;r^5W8C|ECD6BQq9ty1zaZi z-WessWeqPW3Sa3LI+m4Sos}Ei*t<|xPBm4$yD5BcRc_E$q;gPXFVZ5U1eljWIj}16 z28zjGC8eg#`1EaWrAkz+O3*V(#FzY{4oV(@N-=~=lSYtoUiG`46*uXv8^lRF@FWi_ zf1UlPA0uHWH+4p7O}36M)pP0Xl#%7FoY1z#a)!fdnT%@o(R{+(ioEFxmC*{fYvYLK zs*$h`U5DC!?AFDI&ye*>sZr#XepP=&6%4zW4F&!g*>Za5|2Hf}aKrB0v*RKo;&)`F z?qaoAnKDSU(@>=5!8}8w-r_b=hqIK9bsyhSdQ($h8r4MJ{l~1fE~1tq14(^b3tR4D zG^k^xL^<97ICORD8(75NfAAh~OdRmNZL$*^6r3J##wD@E85F^8 za=VlA|yfAG880vbtxs|HL% z*Ft$0oNUmeGTMs!VUU5js9vUs+Nvm(sueX|^iiapVzC^jw)J?_wCdK3gt9H5%u6_} z0Y~4Igj2L9Mzr79rI+fCmDXn>$xy@3qfmv0W$le-C1v_$N*yqG-$i=g zN3+U4!}97e@T&F0n-vU!b^>k4ZIO!Iit2CPpRr892g)yFhBeyEM&!6El?{dzO(!mI zN3P53?nvd+D zkIBmOvwi2LJQP1plqj}9J2Dg%z3}SClpg&e6k`mlb|KSqI8DqT^JqACEFX{@OR=7+ zYjQ6WQ>;*F$B&zM#o1a{0es^Ef52S_)kPQ2a}7Pwn8FrYER$Nq+E}j1sA&=%>#yiH z$r|fw8%tOm>%$q(u=?Uy27bI=)X!Zuu3Yxzwn{eBXpIY6F_I(;ti+OieeN^a6p?>) zG;wA)+pkj3s5*LUu=e#2O7Ks`eM?2laAiu`AEHOm6S}RHHY=5E<7@bMsIT6IEU4*+ zwfe|PRorzIw{S;0?xGC+T9o`6rQMpT?N_sLWOLhBGM=%=%>_^JH0o_fl2n7(a3?m} zdvGL(T&CB#pwlJ8&#ggO=I zUDo!U&+OLC*nsuq$1JFWkJi-Gj@`-5QS$et?gh4pxwBt8?yLImnRY9rc3C36%Wd$g zCGNV@?0Qd7L?7?IA0^>wl?nR06XLt4FPMd?k#&2qXWzM-5JSN`Im~&spG$L)Cvi|< zd{Bgcz{MAT%!D)v+P9_IZ_Vf=&-Oj2H$H5PIq2Rw@RV?nP};0rCCsq{hj}0N86V}U zbnN(H4@*jvU=tkm{@qW`1P`bk5KHP1*MMLAg0Y?L^U?sEd`nm8dz4eT zl~so|G;R+Uh1I$T^k<;??BhJ1R!+%Q9O%h+V-T{c^(f-xS;Nus2_dzyov!I-$;D_w z=BMv5eiZA+;@5qvGyu9ih@!>>Y7go$I7QNcAMtJF(134wPX78HsmF{@crD)-E9s(F z@9Pivi*QdsRVKi|!AI%a5=ZbGXsTxpN+ z5nwclZ*bpr=}bL8+Lup(T8^l*H!lfYoUdkAd*8pArs0LgJigAS0TUy@Db?r7Z+;U? zp3WWpqLcWplck;W*jb7GtdRE?Jf|K__d@UBJ7?Sm{#9kwJt+41C9(>*Colp3Z>-%_ zRGV$%F8Dx^Kxj#Dic68=1b26LcP&!f+Y&UmyIXO0cPZ{pk)lOPfl_FJ4Db7W`#*cH zHFGd)&2ttx%*slh`}$qifWmL8+H$F><+Z#+FA=@|+STDaoZF92t>jM^+)oF2#Er2} zmu%n11+34upD_MB{lrF;=boOux(29=?T7`Tz9g4QSKE~cdr2k|LZrU;|8l<0d?|LI zkjnJZMvPeVP$~0YH17TlM8FjA&-}%)TA?(o!KXm;MB}rvW=qJQof6Fo?P`qTW^na zbGYtrc9ZoG$Z-w5n9K;)VDH+KM0p94V=}!I4^<7N#6m{=&go`$N<%e&>)B6I@O^Wy z*`4bX^wBpVfvlDRObPgk_iBHF?UElE_Tse`Uf@n3kW??9FJFRvrw2fN$%t~K^Sl&- z9f-rw6%^=DJ%Gi;Oes0Ybr&cMvE5U7v*EHA6a4d4Lrv8$nGlYVM54bD?RjBLDyWzb zxcx}27o30>=n_P4LxE~__5J9YKF^;HU|XQjPpr;5$&k$f6&V)kx9V?ycr?sXUA53Q zDnTI?kXp2eYsOI23n*m>GLL&-2s#`OQ=aChQNQ@ShFM?`o)nyQGQ?!Ujq<8Ys8Kz- zLr7hi1Knb=ijZuWYXN3=!}vvH?V(Bq6GZeXR4^0~sVdI>_;9v}pNhBO|t9!@l~ib^8*6`SI~Z>Pnx)8TDrmWl*qWO zr%>^GqN=!F40>ta0)=yy+b!7MaGPbEFc0f~UCl$=e%LIs80=z)yWKjC`~0~^fExT;73PGXi+?Yj){9PT zSyIP-_CFvzY$b;Ly3&_T29yzLf)26={cwD?@i<&dVHHXraZQ} z%083wH>s;On{rg6E%4Vgstwt=I1T#_>lKY$U=UIg_TLvM^Ynll?0CWrWYF`*Zy0bd z$k+TxvNq|fW!Vu=X0e?#n(xUeaEk)w@$H>`=05s}Lr03yXa7&E+Zt;f{Eg3SD;m* zuKK3~8|_$Ce)zCq0)&T;7Eb8T9dAlZt9Ni^NqxlG1N}T3Ym2vt$F?Iw7kU0-%-jU; zL>DlNq^5&fpmBqOBMxTdWNm&CxLu`7pq@FOqII(MQSYdumS6sZu%E`eb)Ny=NEY){ zDj4RE(T<6mu@{jJV|50^Bf8@yu7O6@&=Oy+9qk2Y+N{s;JG8M;>xC?}MjO7Vu-5nU ztntE3wgOJe+^#LSjuTp?sfEOh|0xbbUZGXRQ|JvaCB z&!eMxwTwT~-r#exwJ;);UC4}&#?a2|O84Qw<;AyL2RR3Rcj<9F73EaEZ|gUU%J_1z zKdCn;{l)S|y8ALCYuQNgbVDzFA0ZZ!TczQ^Bh}ZW@m2@O^;RWbpeP8BGmg1I%c#Ic zh6bZP>49_ewP+a(e9P%bCsjblCI@hp#|T4D*lnk-)XkdIrq!7wx90vEPia$^w9C1N z9xo@~z+a!{K}&JXutPKXDn4#*Vb3PbVlBbUS!s$yQOi1uv8PZyH1Dy3Rvsk#05OYw zfZAZn>;SNL)YY?k8?>3CIyRDKZyS2XnZq&bw7yFuCw!>3bcw7$}Bw5y2#QY&i3H~@&uEg_|QR{6+TJLr;K=fW^%Jv_U>C>@PG0slQzat@s=vu z7W!4Dt^7Tj)18syVnUYY*Z@?!zD&mG>4oz`_cKAC8!($$GU$VY1(bHBSN*Lv(ctMI z{HSMd16<@nVkq*bV|68Ute#{~%xt$AX6Q$D!hkHsq^;1p`l`7_cTnaO%UiD|NZuaLYym)kCODFnk7T0nhY ze`C^miP=f8Okm1AA}(@87L~mp`wIBqJOSSSmL~v$$X|hJXrC{-e&rlS zwRr^W_yoQ9WlTj3{IvwQ+zWP;;j$PcaZl0)V8*v>k>zqGHcUv zFa2ge`NjavCOf-0DmaWUESf(tg(Wr}nwY4R80r(+1B1d~UL7!nju5^1Xy|0L(r~E8 zP@?>Jj{a(%(tM)EK)mf*nc+nKhnYtI z*=b)o?AkwUK0@?fA?B(Ro+}d8ItmZEVRKD02g9LMn#1)T z#CFxyeDC2w*V9om;;Q%G9e~AwmBHoVrRVB|g@udNgO&09!^z{nU+xe~hli_=i0|t& zXH%#DjsyI-Ub{NnA3xq-Mx0I}?#2+03(o2I zp_7v~&krX5xt^=w0h0*mbB+AuKh^QiPdqop0}%hlNuKi~|GfB5aXbJ4g(9Ff2x!JX z@BODo{{Oc;0ptJoJi-57LeJ9Uh8&TOFNYVV&oL0CM~sK(l{xn7Z6vbN&>kgOTVvo- zB|igvy$QEWT$Ik|fK;)iYVDcpS3GllCyiVYSf)jS;!Y(-Mh9j}`C;3StjxCj;%K%=F;Au2Px`BvEDImj=BZ2XaBvvn zi&VeLw~H6y&l$Uwj=yn1cq5-wdwU-Lf_-^Sm?a(a@N+_VUi(zN(UxQ#iiXLHM{o~I z!tSIQc0=%V?93(nTvPFxO!R&s(~qBXo7tmeP)lmqyU1$0WP8#DMG{Ugi$`-U+kK1S zJG7gP7PvkB7AJJ$6vX$BJ`;Ii*8MlpXIuYE0CpWENT9y_4Ry*l<+pH6U?nh3vj&ZAC+R%~mKl?SGNHXVB!(V?WO16!&Ai$*T8^ zT=9J;&=c)_D;dM)St}B~R!xS`fIsja@pyOiUi9(d zw`$%K04pDWo-T|az6_k9%10&~6T73jgn<#+$}i~U`Y{dIo>vJet(eF9U-`}Yyv8a3 z&RzB6WV*oUU@4eXY4N5?Xn1OY65>{Hh*U@jibMUbvIhgMtW`)jID(2n2ze+QZ|)7f zQX$Sy??imMVgejjs^?bk||e>$|W}2<)~_K;<${8CH?Pbg6&eMdP&FhnbyJKf0A>>n~RKCaF&7q z3l-$TWybC}3q60Decm-_@VX;9rn9C!DbJYS8XZK$w^B>h$Gv%{K?71vyw$9Aum)-e zXXsA3Y0;Qyf7kpaKb+{dTt$4sAkNuo5Z;ELXsHah7X_(Jr#3hHeUMYsy;}L&qeXYj zMQ6Uyt}^$Bs|DHov-sZ0;+LnJI@1z>B_n9=fZC%-L)co}$xvZEHl$synpFmEeBDt) zyP(3_K{~e5D2$RfX_ZCZ&vkF(PelS(vyXo_Yj-F=u*e7+fah zFd$5vP(;(J{E77z>rKF(hBoy=e|5-PeKux!v&g$ajB%45&e!4UN6YhZP(vc-PLQ_iP)`o)2Ux7%0-U zcmScw-+vE>STUUirlBcgs(NQGU}H4M$cfJ-+hrg(v$D&32@TeV_;tH}kgF*fH@`?} zT^uvnR?02|>vU!=z*4`|DZ8E8kDjdHi4QsBe>e@J{kySe==J=Cg(-b`{kcgdq_myL zj=?!Ap~1^4VpsWnoCi+P>LfdZgJQf?mtj}5qg-7^rrZh7RSJQ9Es-JdnK!aVI|?BU zbGO2n&$Yo<3oqb+wV{mt*VXU@v9SbPw;yK`#T%99#eUK~io}F#g>P*65ee#o-Ep5%lz|+<57s5n|D{>O7`qYpB31Q<#}WT4Dpu@+e^|?k2eRlnOWa z1veA!K%4U;&X`t@(Qx0UuN_lRkF*Z9&@aiwFJaJCiO<>S_7lclnGI$=?nY4Kg>j#W zCw{%GF}*+MNdxYZ*!v82a-LyQS;>8>z6=pv_!$!NR)z+4{ke#=7K4mVMtwSwyVA4E zp?Pmhm!iA*Z0kpzXom{o^e!kp{fq$Pp7uSl+Z2;XJ8rq(x$xdONp_dTVL+gsV7#Zk8vDXS`LFPRZ_X&{7d?EPn1ov+ev++iVj@gLBB z1{wkN-XS^7(!G0terOX9qnQgey0bGQvQMT9yRr;yMGCithrK$sjc*BqdD%I)g(Cu1 z!$01I2NJ;v>nWG}u?7Oe;py@gU`l`IiFvXjWEv@Psx*?ag7)NbdI0oQw>4noKn5B&ny zw?!W_uuK6V_tHpaIz|F-Ae<=XX54XwC9<#jopH;65p~XoJpLzi9*1GT$2;l1u>hW- zs0}$gEh)P-zUanL;2u4gXCG8MB2CC(hw@YAh!4#FM%r{pHt&VIBp<$yg3U2R_8zB;@!S~kxIhP0`2-M5ljKXn z!B}d$cq&Ofx{?@D`A&+BFDj~9DqcLQm>ALsC2CS%s&hHSees%@+u=Py@W#!9X`h%M?R`x#VQu0|YMt))*kjB?dAFdTvBw<$dbT zajdI7*zH7)jzIl--^WiseT6Run?G9Q#J(GtT-TCR^;uK+9u)23v38fn{3|~M!5>x!Vj&y$*0JkA5GKqvAq}x|33q52AYquFFSF z%g-b!Fh#FN6GsX0-p55b)Ur4XX2DAznf5m354Vzsbg?8t>kAQAAC|0x?GTbSB{XxsW2o4wg`Yr zGb<+Er3hr^#TbC=DUptSE0@gSea{{A3U;w}Ril0>=@FRJb!E|hDZfvu>N~J(19N?L zN+%<0vNMo<74mK)s&_JLJ0KOxfjQa$6ncG3mRZo$TX4ne%8^;L?!KCp*R|HZSY|t= zAHgV66}1FWB%%TptO{s4NH01lD^K3lO^j!Vnq|I=FMTypMVbYW1y`Q5Pb^Pv zB;ZhO#%QVb^s--ZI@1lM*3-#5GSK)8ra6$Cs{{{%0$obIF0CElymUfQSY&}%$W)+> z1_p;0rI6iDn}L!7Rx7OaHMhE-WeYGoq6$;_SBAK5NkSDi(!pw$B}M^7Cl&t9Y<)#W9x%XBti6cEzpX>6zj{=TBZBWG?68F`;JBD3&e zTd;YjAwmD|PzuJdLRY7BBv|e{m|d$+?R#-t)^OmB5jIcnO_VvQxmvoS!nL$Ai;kg? zks(=%#;3p9d_<1GRu|Y}(7mE1F04I>$!$Mnu(Mb#LNG{y?@JJS|3}H8QYHXZAe*8@ z|AnHSOo!=vgHfjbp*Ad98${a#xOk%H0jKz8jDh1ze}HXYz~p$>B;%LKX-Aw%@YKA} z)S}VUa=_GT_SAaU)aK^Y*N3Sc(&;^+>2)LAFAtN)UEuv^gSpb&>Pt!k4rrg7B%HlbCQ0{r$R z-Y@IP>M}fT=GAQxh?Vx2KigBY%!?+*8!9`h1i>}_0xuw)W&R5@68-YoaXWVlA0Jl& zS*FDwA;*=YeTEQ*%>aQ1)e$DEF~hlWf9Z0?r2GD0MV2QxIUyZzaRwGQDUfJex**j>`)lB;&9=hp;x&aEEX?hMJKF zNY%eSV||Rm4_}+ezPgddA==e2!#~Y3n54$^z9Sr&QT}lMa)gp&WI}s{{No5&!N}?< zi>L0ot0tu0Vm-9MkRLxv6JuAP=i3$YF0T3nYQm_3t{kbIu~D~~GRW#$ZtV7Ojha^( zL}VFxW>GXL4`TSztNVoysF)sY5t`kdz1eD~yy=BMP9ZZ{!t7oYGG1Y{;(R_{cXn7T zNI@nxL^6r?@CGdL)sz{5uPpR*6euz+A~GvHKLNR#ttLB;>^WW&Iu7|L%|?Jb5+E3D za*|3u75j9Y>AaQp^#qoCl12UlcjM(1F8hdG(^CRYjd?x)jvM^I2c*0~X| zg%T7Bo@$syA`ZmrHUXm60n<%zhH@`HI-SkzHY1U@xJoRnID)7G&(EsPqs%UvDSi9Thdl^XGF4U@;SDG9Sw`w&O4s%ek&2 z#^oAsr-SOUd&v>xC44mJ2znBk3KF|~DeCZ{`clVq9t#^1TJ7=0#5xs!JIA;S#k0$X ze2aZ^%@O^OE5IhbdJXt<+cwW2k8F?9{1}yL%GU7w7wc3g`%TL%QePdAcos-73#2jw zEmvU$1!DPb->Am@)-WB~eM|?s{z|3TWm1OtPxbRL^=3YR&sp*bRUuf8ZvD!K4``M$ zWq;;{eSY)4pCr32>Fs;hyK2McC`dLHGlO;G{9{M3zoibiPL4e0a<@Er7a4aKi}=w& zalcJga(FEWPJ6zslKl%i;cI{ESHj*6`iEbHFa1{hjgdZXBQXzRn-4xbCgOcrvv>MS zvOBm8Lb$(&_|#r2_x_&T>F#5nx>xxDfH8-#*r2{-#ffJxs0wP~p@fbp%@zjXF`G2q zfxgMak_pP75Nqtq{TJ&$hY47Wd#p~>{|OVYSu`*aYhPrz}`# z#7e~(H0?DNX_b(X@mFM~ATMVa@%p7;=rHQm8(6>RLJgsLSwjjigub~<*J4o=5?&< zr3puwlhVm>#H>!#v zP`K2@(Wf|6C9$QoiiI((o780~LYriSPL-N86wi&gG?aM{nlxo!qF!sL%NlcPlFCO% zv8d`=H!q2TBFoh z?AQ)&l5k8Yi4U?mp$r}k)Q?9F%6!vmBzn)qTl!T$cs+y@tuc<&TAC(8;fbQ!6oj{tCjEfx!}%(aXj$ zq5yXRe$gL8SI!-=Et^-Ok9QlK7IDc-EUVFJI9`aVWT%0*im^4BzKZuD%QZdu-%e{j zr)YkhK8^$91X5WOXfcTMqSWO>YzPYaki{jQ7hd6wSF}aTcp=1wOUj*>>=^(x5P8V0z`}wepm%;F!5rmSx0}dA^mVa*-oiu~m zYXO2F4QJ0O6yPqEYfL z@FxQJjP+l$`verNS_knZ7Y1Akw)!flXCHNScBwImHz=Z$j6Mf$O6cCHW%q}ErmoLrW4USe}5TFU}(B(e+R%*6$9T4)Frsfv5$*w<>Oq=s3Sroe1~vzrDbaE4Pe;x z?R>au2CAveO0O5L8YwcgOC*sg)x@zv@^8(n#j!hfPsJn({?;o?Vzh&o36QBF31#tJ z*V_noiD<)zxhz-AecoaIX&$Er<$O+@Sd(28Iq)E6Jo_|*n;1-cm6DKp-u&NAGrv#4~1hdeJjvQR7DD|9Ng z{D!2hGimbI>g~BLM#bEU6s@*Khs)fxJyJvCjQYnQ;6l7!1tJ9FX(vb@E zHLL;|JqgvxJ+6}G;I*4<-@LL4r))oLx|J^3DCWbDciTrYy0y(N!5)1 z3_M~m(|vphMtM4Wji9zqtOZg*vz#|eqT!B#6_NQE3hG&1NDLQGi=DO@e93`%e_Sz| zuwdnvj$;u~UdssKJrkoCz^hw-Ju- zAu*V6eyQUS53-1+QjQsx^RqpxAlUv%joSzxK5T$yq$eV5$p>FPA3|8PrDGMWO4>0y zwNvP?quQ+eC7u!}oYI`%7pk<1%u>IFj_fAd&DUGao)vM4Ow8M-9a1jd7~z@==>ZDj z>$p$@f#!B04)bqPQ8xiWFY$b9i+yY)Hsf_Qz!|k6lp!HZmZTl7#ntsW^h{kY^Mo!z zT?FmtVZ9D|#E#rAi9~K?hJWie(&4b1O{twORDG(Lu5GZ=yx+z8zS^4GpdH=z6 zG_D66_mL2F+hNCJ@}~TBX#w-6_t5>HsF!w{aFfvhovP|zTz~h!`B)VaDn3b}$*8;8 ziN^HA1WV@}1q9vJL>z}V5Hx}?Zx6h7i5n&Ex|R#C{2qh)$l~C`yj!)!;Gtb(miz9n zt2VxiSh7R8_odFcG{O60-1cr`Q9f~r)S}ij{8wX_vTg}?)$VR(Y4WNnwU18))_XGL z_|iohDPs;5SDZzXpNB?m-(DixUKtFN(L1tcf~)tR_03jv5>LxFFn zm1=fv08oQoR&zBK0IiWP6PN&L2c8eMg%

H}>FJ^~y?S<1c5cUh&aO5s-&)DjjETAIPxG}IV!aEi zgB^Qp=7Fr_FY0)r`;i6fPz>31Pn%Rh;(S9w{5Q#7og6Kl0}6O7N|PLgfBPwDxT%T) zD?kmejsa?lobY-qE45*5t6?3FVcn2nz2ss2;$efPVZ)(eqs3w4{ow`uCO8-{Vum+j zb_O|ZB<8A2kJfAaVc#gI)f9)(%dc2aa3YS99fw#bNnsLGq-hm9jT47*Nm>?5bxP)& zH>JBbiA6QN*pxY9&otsIf@kirCWYe2a{V$F5>%{r${dWu>4MIF?Njp0z} z;&HQy)mWIvSa`@7Jb5hqVc5KB49p-y*5C3&Op;``MKrn-gv>jnE_|CV*q
kzq6 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
l0acuha!* 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�Wy)m_~Sx#K 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

+ + browse other examples + +

Set user min and max indexes

+ +
+ Here we provide an ability of external min and max indexes setting to let the viewport know how many items do we have. +
+
<li ui-scroll="item in datasource">{{item}}</li>
+
+ Then you can play with minIndex and maxIndex properties which are being accessible on your datasource after the ui-scroll directive is linked: +
+
+datasource.minIndex = -100;
+datasource.maxIndex = 100;
+
+ Such setting does not not lead to data fetching but the scroll bar params do match datasource size defined this way. +
+ +
+ + minIndex value to set +
+ + maxIndex value to set +
+ +
+ +
+
{{item}}
+
+ +
+ + + \ No newline at end of file diff --git a/demo/userIndexes/userIndexes.js b/demo/userIndexes/userIndexes.js new file mode 100644 index 00000000..7a1e5720 --- /dev/null +++ b/demo/userIndexes/userIndexes.js @@ -0,0 +1,42 @@ +angular.module('application', ['ui.scroll']) + .controller('mainController', [ + '$scope', '$log', '$timeout', function ($scope, console, $timeout) { + var datasource = {}; + + datasource.get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + $scope.datasource = datasource; + $scope.adapter = {}; + + $scope.setUserMinIndex = function () { + var userMinIndex = parseInt($scope.userMinIndex, 10); + if(!isNaN(userMinIndex)) + $scope.datasource.minIndex = userMinIndex; + }; + + $scope.setUserMaxIndex = function () { + var userMaxIndex = parseInt($scope.userMaxIndex, 10); + if(!isNaN(userMaxIndex)) + $scope.datasource.maxIndex = userMaxIndex; + }; + + $scope.setUserIndexes = function () { + $scope.setUserMinIndex(); + $scope.setUserMaxIndex(); + }; + + $scope.delay = false; + $timeout(function() { + $scope.delay = true; + }, 500); + + } + ]); \ No newline at end of file diff --git a/demo/visibility/visibility.html b/demo/visibility/visibility.html new file mode 100644 index 00000000..dc077792 --- /dev/null +++ b/demo/visibility/visibility.html @@ -0,0 +1,41 @@ + + + + + Visibility + + + + + + + +
+ + browse other examples + +

Visibility

+ +
+ We have an internal mechanism to start data fetching after invisible scroller becomes visible. + So generally you don't need to execute reload method when you play with scroller visibility. +
+ +
+
+ +
+
+ +
+
    +
  • *{{item}}*
  • +
+
+ +
+ + + \ No newline at end of file diff --git a/demo/visibility/visibility.js b/demo/visibility/visibility.js new file mode 100644 index 00000000..6372d32d --- /dev/null +++ b/demo/visibility/visibility.js @@ -0,0 +1,19 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', ['$log', '$timeout', + function (console, $timeout) { + + var get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + return { + get: get + }; + } + ]); \ No newline at end of file diff --git a/demo/windowViewport/windowViewport-iframe.html b/demo/windowViewport/windowViewport-iframe.html new file mode 100644 index 00000000..e4f2785d --- /dev/null +++ b/demo/windowViewport/windowViewport-iframe.html @@ -0,0 +1,39 @@ + + + + + Scroller Demo (entire window) + + + + + + + +
+
+
+
is loading: {{loading}}
+
top visible: {{topItem}}
+
+
+
+ +
+
+
+ {{item}} +
+
+
+ + + + + + \ No newline at end of file diff --git a/demo/windowViewport/windowViewport.html b/demo/windowViewport/windowViewport.html new file mode 100644 index 00000000..e4779dbb --- /dev/null +++ b/demo/windowViewport/windowViewport.html @@ -0,0 +1,37 @@ + + + + + Entire window scrollable + + + + + + + +
+ + browse other examples + +

Entire window scrollable

+ +
+ This sample demonstrates the scroller without viewport defining. + As it follows from documentation: + unless specified explicitly with the uiScrollViewport directive, browser window will be used as viewport. + And this is the reason why this demo is placed in an iframe. You also can open it in a new tab. +
+ +
+
+

Sample in iframe

+ Open example in new tab +
+ +
+ +
+ + + \ No newline at end of file diff --git a/demo/windowViewport/windowViewport.js b/demo/windowViewport/windowViewport.js new file mode 100644 index 00000000..b8eab711 --- /dev/null +++ b/demo/windowViewport/windowViewport.js @@ -0,0 +1,19 @@ +angular.module('application', ['ui.scroll']) + .factory('datasource', ['$log', '$timeout', + function (console, $timeout) { + + var get = function (index, count, success) { + $timeout(function () { + var result = []; + for (var i = index; i <= index + count - 1; i++) { + result.push("item #" + i); + } + success(result); + }, 100); + }; + + return { + get: get + }; + } + ]); diff --git a/demo/windowviewportInline/windowviewportInline.html b/demo/windowviewportInline/windowviewportInline.html new file mode 100644 index 00000000..06861c89 --- /dev/null +++ b/demo/windowviewportInline/windowviewportInline.html @@ -0,0 +1,94 @@ + + + + + Inline blocks demo + + + + + + + + + + +
+ browse other examples +

Inline blocks demo

+ +
+
is loading: {{loading}}
+
top visible: {{topItem}}
+
+ +
+
+
+ *{{item.content}}* +
+
+
+ +
+ + + \ No newline at end of file diff --git a/demo/windowviewportInline/windowviewportInline.js b/demo/windowviewportInline/windowviewportInline.js new file mode 100644 index 00000000..e4d3296f --- /dev/null +++ b/demo/windowviewportInline/windowviewportInline.js @@ -0,0 +1,35 @@ +angular.module('application', ['ui.scroll']).factory('datasource', [ + '$log', '$timeout', function(console, $timeout) { + var get; + get = function(index, count, success) { + return $timeout(function() { + var i, item, j, ref, ref1, result; + result = []; + for (i = j = ref = index, ref1 = index + count - 1; ref <= ref1 ? j <= ref1 : j >= ref1; i = ref <= ref1 ? ++j : --j) { + item = {}; + if (inlineDemo) { + item.width = inlineDemo.getWidth(i); + item.height = inlineDemo.getHeight(i); + item.color = inlineDemo.getColor(i); + } + item.content = "item #" + i; + result.push(item); + } + return success(result); + }, 100); + }; + return { + get: get + }; + } +]); + + + + +/* +//# sourceURL=src/windowviewportInline.js + */ + +// --- +// generated by coffee-script 1.9.2 \ No newline at end of file diff --git a/dist/ui-scroll-grid.js b/dist/ui-scroll-grid.js new file mode 100644 index 00000000..b99d3d9b --- /dev/null +++ b/dist/ui-scroll-grid.js @@ -0,0 +1,419 @@ +/*! + * angular-ui-scroll + * https://github.com/angular-ui/ui-scroll + * Version: 1.8.2 -- 2020-10-02T15:31:19.969Z + * License: MIT + */ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +angular.module('ui.scroll.grid', []).directive('uiScrollTh', ['$log', '$timeout', function (console, $timeout) { + function GridAdapter(controller) { + this.getLayout = function () { + return controller.getLayout(); + }; + + this.applyLayout = function (layout) { + return controller.applyLayout(layout); + }; + + this.columnFromPoint = function (x, y) { + return controller.columnFromPoint(x, y); + }; + + Object.defineProperty(this, 'columns', { + get: function get() { + return controller.getColumns(); + } + }); + } + + function ColumnAdapter(controller, column) { + this.css = function () + /* attr, value */ + { + var attr = arguments[0]; + var value = arguments[1]; + + if (arguments.length == 1) { + return column.header.css(attr); + } + + if (arguments.length == 2) { + column.header.css(attr, value); + controller.forEachRow(function (row) { + return row[column.id].css(attr, value); + }); + column.css[attr] = value; + } + }; + + this.moveBefore = function (index) { + return controller.moveBefore(column, index); + }; + + this.exchangeWith = function (index) { + return controller.exchangeWith(column, index); + }; + + Object.defineProperty(this, 'columnId', { + get: function get() { + return column.id; + } + }); + } + + function ColumnController(controller, columns, header) { + this.header = header; + this.css = {}; + this.mapTo = columns.length; + this.id = columns.length; // controller api methods + + this.applyLayout = function (layout) { + this.css = angular.extend({}, layout.css); + this.mapTo = layout.mapTo; + applyCss(this.header, this.css); + }; + + this.moveBefore = function (target) { + var _this = this; + + if (target) { + moveBefore(header, target.header); + controller.forEachRow(function (row) { + return moveBefore(row[_this.id], row[target.id]); + }); + } else { + moveLast(header); + controller.forEachRow(function (row) { + return moveLast(row[_this.id]); + }); + } + }; + + this.columnFromPoint = function (x, y) { + var _this2 = this; + + if (insidePoint(header, x, y)) { + return this; + } + + var result = null; + controller.forEachRow(function (row) { + return result = insidePoint(row[_this2.id], x, y) ? _this2 : result; + }); + return result; + }; + + this.applyCss = function (target) { + applyCss(target, this.css); + }; // function definitions + + + function insidePoint(element, x, y) { + var offset = element.offset(); + if (x < offset.left || offset.left + element.outerWidth(true) < x) return false; + if (y < offset.top || offset.top + element.outerHeight(true) < y) return false; + return true; + } + + function moveBefore(element, target) { + element.detach(); + target.before(element); + } + + function moveLast(element) { + var parent = element.parent(); + element.detach(); + parent.append(element); + } + + function applyCss(target, css) { + target.removeAttr('style'); + + for (var attr in css) { + if (css.hasOwnProperty(attr)) { + target.css(attr, css[attr]); + } + } + } + } + + function GridController(scrollViewport) { + var _this3 = this; + + var columns = []; + var rowMap = new Map(); + $timeout(function () { + scrollViewport.adapter.publicContext.gridAdapter = new GridAdapter(_this3); + + scrollViewport.adapter.transform = function (scope, item) { + return transform(rowMap.get(scope), item); + }; + }); + + this.registerColumn = function (header) { + columns.push(new ColumnController(this, columns, header)); + }; + + this.registerCell = function (scope, cell) { + var row = rowMap.get(scope); + + if (!row) { + row = []; + rowMap.set(scope, row); + } + + if (row.length >= columns.length) { + return false; + } + + row.push(cell); + return true; + }; + + this.unregisterCell = function (scope, cell) { + var row = rowMap.get(scope); + var i = row.indexOf(cell); + row.splice(i, 1); + + if (!row.length) { + rowMap.delete(scope); + } + }; + + this.forEachRow = function (callback) { + rowMap.forEach(callback); + }; + + this.getColumns = function () { + var _this4 = this; + + var result = []; + columns.slice().sort(function (a, b) { + return a.mapTo - b.mapTo; + }).forEach(function (column) { + return result.push(new ColumnAdapter(_this4, column)); + }); + return result; + }; + + this.getLayout = function () { + var result = []; + columns.forEach(function (column, index) { + return result.push({ + index: index, + css: angular.extend({}, column.css), + mapTo: column.mapTo + }); + }); + return result; + }; + + this.applyLayout = function (layouts) { + if (!layouts || layouts.length != columns.length) { + throw new Error('Failed to apply layout - number of layouts should match number of columns'); + } + + layouts.forEach(function (layout, index) { + return columns[index].applyLayout(layout); + }); + transform(columns.map(function (column) { + return column.header; + })); + rowMap.forEach(function (row) { + return transform(row); + }); + }; + + this.moveBefore = function (selected, target) { + var index = target; + + if (target % 1 !== 0) { + index = target ? columns[target.columnId].mapTo : columns.length; + } + + if (index < 0 || index > columns.length) { + return; // throw an error? + } + + var mapTo = selected.mapTo, + next = null; + index -= mapTo < index ? 1 : 0; + columns.forEach(function (c) { + c.mapTo -= c.mapTo > mapTo ? 1 : 0; + c.mapTo += c.mapTo >= index ? 1 : 0; + next = c.mapTo === index + 1 ? c : next; + }); + selected.mapTo = index; + selected.moveBefore(next); + }; + + this.exchangeWith = function (selected, index) { + if (index < 0 || index >= columns.length) { + return; + } + + columns.find(function (c) { + return c.mapTo === index; + }).mapTo = selected.mapTo; + selected.mapTo = index; + }; + + this.columnFromPoint = function (x, y) { + var column = columns.find(function (col) { + return col.columnFromPoint(x, y); + }); + return column ? new ColumnAdapter(this, column) : undefined; + }; // function definitions + + + function transform(row) { + var parent = row[0].parent(); + var visible = []; + row.forEach(function (cell, index) { + columns[index].applyCss(cell); + visible[columns[index].mapTo] = row[index]; + row[index].detach(); + }); + visible.forEach(function (cell) { + return parent.append(cell); + }); + } + } + + return { + require: ['^^uiScrollViewport'], + restrict: 'A', + link: function link($scope, element, $attr, controllers) { + controllers[0].gridController = controllers[0].gridController || new GridController(controllers[0]); + controllers[0].gridController.registerColumn(element); + } + }; +}]).directive('uiScrollTd', function () { + return { + require: ['?^^uiScrollViewport'], + restrict: 'A', + link: function link($scope, element, $attr, controllers) { + if (!controllers[0]) { + return; + } + + var scope = $scope; + var tdInitializer = $scope.uiScrollTdInitializer; + + if (!tdInitializer) { + tdInitializer = $scope.uiScrollTdInitializer = { + linking: true + }; + } + + if (!tdInitializer.linking) { + scope = tdInitializer.scope; + } + + var gridController = controllers[0].gridController; + + if (gridController.registerCell(scope, element)) { + $scope.$on('$destroy', function () { + return gridController.unregisterCell(scope, element); + }); + } + + if (!tdInitializer.linking) { + tdInitializer.onLink(); + } + } + }; +}); + +/***/ }) +/******/ ]); +//# sourceMappingURL=ui-scroll-grid.js.map \ No newline at end of file diff --git a/dist/ui-scroll-grid.js.map b/dist/ui-scroll-grid.js.map new file mode 100644 index 00000000..e4b95e04 --- /dev/null +++ b/dist/ui-scroll-grid.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/ui-scroll-grid.js"],"names":["angular","module","directive","console","$timeout","GridAdapter","controller","getLayout","applyLayout","layout","columnFromPoint","x","y","Object","defineProperty","get","getColumns","ColumnAdapter","column","css","attr","arguments","value","length","header","forEachRow","row","id","moveBefore","index","exchangeWith","ColumnController","columns","mapTo","extend","applyCss","target","moveLast","insidePoint","result","element","offset","left","outerWidth","top","outerHeight","detach","before","parent","append","removeAttr","hasOwnProperty","GridController","scrollViewport","rowMap","Map","adapter","publicContext","gridAdapter","transform","scope","item","registerColumn","push","registerCell","cell","set","unregisterCell","i","indexOf","splice","delete","callback","forEach","slice","sort","a","b","layouts","Error","map","selected","columnId","next","c","find","col","undefined","visible","require","restrict","link","$scope","$attr","controllers","gridController","tdInitializer","uiScrollTdInitializer","linking","$on","onLink"],"mappings":"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","file":"ui-scroll-grid.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","angular.module('ui.scroll.grid', [])\n .directive('uiScrollTh', ['$log', '$timeout', function(console, $timeout) {\n\n function GridAdapter(controller) {\n\n this.getLayout = () => controller.getLayout();\n\n this.applyLayout = (layout) => controller.applyLayout(layout);\n\n this.columnFromPoint = (x, y) => controller.columnFromPoint(x, y);\n\n Object.defineProperty(this, 'columns', { get: () => controller.getColumns() });\n }\n\n function ColumnAdapter(controller, column) {\n\n this.css = function( /* attr, value */ ) {\n var attr = arguments[0];\n var value = arguments[1];\n if (arguments.length == 1) {\n return column.header.css(attr);\n }\n if (arguments.length == 2) {\n column.header.css(attr, value);\n controller.forEachRow((row) => row[column.id].css(attr, value));\n column.css[attr] = value;\n }\n };\n\n this.moveBefore = (index) => controller.moveBefore(column, index);\n\n this.exchangeWith = (index) => controller.exchangeWith(column, index);\n\n Object.defineProperty(this, 'columnId', { get: () => column.id });\n }\n\n function ColumnController(controller, columns, header) {\n\n this.header = header;\n this.css = {};\n this.mapTo = columns.length;\n this.id = columns.length;\n\n // controller api methods\n\n this.applyLayout = function(layout) {\n this.css = angular.extend({}, layout.css);\n this.mapTo = layout.mapTo;\n applyCss(this.header, this.css);\n };\n\n this.moveBefore = function(target) {\n if (target) {\n moveBefore(header, target.header);\n controller.forEachRow((row) => moveBefore(row[this.id], row[target.id]));\n } else {\n moveLast(header);\n controller.forEachRow((row) => moveLast(row[this.id]));\n }\n };\n\n this.columnFromPoint = function(x, y) {\n if (insidePoint(header, x, y)) {\n return this;\n }\n let result = null;\n controller.forEachRow((row) =>\n result = insidePoint(row[this.id], x, y) ? this : result\n );\n return result;\n };\n\n this.applyCss = function(target) {\n applyCss(target, this.css);\n };\n\n // function definitions\n\n function insidePoint(element, x, y) {\n let offset = element.offset();\n if (x < offset.left || offset.left + element.outerWidth(true) < x)\n return false;\n if (y < offset.top || offset.top + element.outerHeight(true) < y)\n return false;\n return true;\n }\n\n function moveBefore(element, target) {\n element.detach();\n target.before(element);\n }\n\n function moveLast(element) {\n let parent = element.parent();\n element.detach();\n parent.append(element);\n }\n\n function applyCss(target, css) {\n target.removeAttr('style');\n for (let attr in css) {\n if (css.hasOwnProperty(attr)) {\n target.css(attr, css[attr]);\n }\n }\n }\n\n }\n\n function GridController(scrollViewport) {\n let columns = [];\n let rowMap = new Map();\n\n $timeout(() => {\n scrollViewport.adapter.publicContext.gridAdapter = new GridAdapter(this);\n scrollViewport.adapter.transform = (scope, item) => transform(rowMap.get(scope), item);\n });\n\n this.registerColumn = function(header) {\n columns.push(new ColumnController(this, columns, header));\n };\n\n this.registerCell = function(scope, cell) {\n let row = rowMap.get(scope);\n if (!row) {\n row = [];\n rowMap.set(scope, row);\n }\n if (row.length >= columns.length) {\n return false;\n }\n row.push(cell);\n return true;\n };\n\n this.unregisterCell = function(scope, cell) {\n let row = rowMap.get(scope);\n let i = row.indexOf(cell);\n row.splice(i, 1);\n if (!row.length) {\n rowMap.delete(scope);\n }\n };\n\n this.forEachRow = function(callback) {\n rowMap.forEach(callback);\n };\n\n this.getColumns = function() {\n let result = [];\n columns.slice()\n .sort((a, b) => a.mapTo - b.mapTo)\n .forEach((column) => result.push(new ColumnAdapter(this, column)));\n return result;\n };\n\n this.getLayout = function() {\n let result = [];\n columns.forEach((column, index) => result.push({\n index: index,\n css: angular.extend({}, column.css),\n mapTo: column.mapTo\n }));\n return result;\n };\n\n this.applyLayout = function(layouts) {\n if (!layouts || layouts.length != columns.length) {\n throw new Error('Failed to apply layout - number of layouts should match number of columns');\n }\n layouts.forEach((layout, index) => columns[index].applyLayout(layout));\n transform(columns.map((column) => column.header));\n rowMap.forEach((row) => transform(row));\n };\n\n this.moveBefore = function(selected, target) {\n let index = target;\n\n if (target % 1 !== 0) {\n index = target ? columns[target.columnId].mapTo : columns.length;\n }\n if (index < 0 || index > columns.length) {\n return; // throw an error?\n }\n\n let mapTo = selected.mapTo,\n next = null;\n index -= mapTo < index ? 1 : 0;\n\n columns.forEach(c => {\n c.mapTo -= c.mapTo > mapTo ? 1 : 0;\n c.mapTo += c.mapTo >= index ? 1 : 0;\n next = c.mapTo === index + 1 ? c : next;\n });\n\n selected.mapTo = index;\n selected.moveBefore(next);\n };\n\n this.exchangeWith = function(selected, index) {\n if (index < 0 || index >= columns.length) {\n return;\n }\n columns.find(c => c.mapTo === index).mapTo = selected.mapTo;\n selected.mapTo = index;\n };\n\n this.columnFromPoint = function(x, y) {\n let column = columns.find(col => col.columnFromPoint(x, y));\n return column ? new ColumnAdapter(this, column) : undefined;\n };\n\n // function definitions\n\n function transform(row) {\n let parent = row[0].parent();\n let visible = [];\n\n row.forEach((cell, index) => {\n columns[index].applyCss(cell);\n visible[columns[index].mapTo] = row[index];\n row[index].detach();\n });\n\n visible.forEach(cell => parent.append(cell));\n }\n\n }\n\n return {\n require: ['^^uiScrollViewport'],\n restrict: 'A',\n link: ($scope, element, $attr, controllers) => {\n controllers[0].gridController = controllers[0].gridController || new GridController(controllers[0]);\n controllers[0].gridController.registerColumn(element);\n }\n };\n }])\n\n.directive('uiScrollTd', function() {\n return {\n require: ['?^^uiScrollViewport'],\n restrict: 'A',\n link: ($scope, element, $attr, controllers) => {\n if (!controllers[0]) {\n return;\n }\n let scope = $scope;\n let tdInitializer = $scope.uiScrollTdInitializer;\n if (!tdInitializer) {\n tdInitializer = $scope.uiScrollTdInitializer = {\n linking: true\n };\n }\n if (!tdInitializer.linking) {\n scope = tdInitializer.scope;\n }\n let gridController = controllers[0].gridController;\n if (gridController.registerCell(scope, element)) {\n $scope.$on('$destroy', () => gridController.unregisterCell(scope, element));\n }\n if (!tdInitializer.linking) {\n tdInitializer.onLink();\n }\n }\n };\n});\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/ui-scroll-grid.min.js b/dist/ui-scroll-grid.min.js new file mode 100644 index 00000000..da7b9e35 --- /dev/null +++ b/dist/ui-scroll-grid.min.js @@ -0,0 +1,2 @@ +!function(t){var n={};function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{enumerable:!0,get:r})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,n){if(1&n&&(t=e(t)),8&n)return t;if(4&n&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(e.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&n&&"string"!=typeof t)for(var o in t)e.d(r,o,function(n){return t[n]}.bind(null,o));return r},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},e.p="",e(e.s=0)}([function(t,n){angular.module("ui.scroll.grid",[]).directive("uiScrollTh",["$log","$timeout",function(t,n){function e(t){this.getLayout=function(){return t.getLayout()},this.applyLayout=function(n){return t.applyLayout(n)},this.columnFromPoint=function(n,e){return t.columnFromPoint(n,e)},Object.defineProperty(this,"columns",{get:function(){return t.getColumns()}})}function r(t,n){this.css=function(){var e=arguments[0],r=arguments[1];if(1==arguments.length)return n.header.css(e);2==arguments.length&&(n.header.css(e,r),t.forEachRow((function(t){return t[n.id].css(e,r)})),n.css[e]=r)},this.moveBefore=function(e){return t.moveBefore(n,e)},this.exchangeWith=function(e){return t.exchangeWith(n,e)},Object.defineProperty(this,"columnId",{get:function(){return n.id}})}function o(t,n,e){function r(t,n,e){var r=t.offset();return!(n=u.length)&&(e.push(n),!0)},this.unregisterCell=function(t,n){var e=c.get(t),r=e.indexOf(n);e.splice(r,1),e.length||c.delete(t)},this.forEachRow=function(t){c.forEach(t)},this.getColumns=function(){var t=this,n=[];return u.slice().sort((function(t,n){return t.mapTo-n.mapTo})).forEach((function(e){return n.push(new r(t,e))})),n},this.getLayout=function(){var t=[];return u.forEach((function(n,e){return t.push({index:e,css:angular.extend({},n.css),mapTo:n.mapTo})})),t},this.applyLayout=function(t){if(!t||t.length!=u.length)throw new Error("Failed to apply layout - number of layouts should match number of columns");t.forEach((function(t,n){return u[n].applyLayout(t)})),a(u.map((function(t){return t.header}))),c.forEach((function(t){return a(t)}))},this.moveBefore=function(t,n){var e=n;if(n%1!=0&&(e=n?u[n.columnId].mapTo:u.length),!(e<0||e>u.length)){var r=t.mapTo,o=null;e-=rr?1:0,t.mapTo+=t.mapTo>=e?1:0,o=t.mapTo===e+1?t:o})),t.mapTo=e,t.moveBefore(o)}},this.exchangeWith=function(t,n){n<0||n>=u.length||(u.find((function(t){return t.mapTo===n})).mapTo=t.mapTo,t.mapTo=n)},this.columnFromPoint=function(t,n){var e=u.find((function(e){return e.columnFromPoint(t,n)}));return e?new r(this,e):void 0}}return{require:["^^uiScrollViewport"],restrict:"A",link:function(t,n,e,r){r[0].gridController=r[0].gridController||new i(r[0]),r[0].gridController.registerColumn(n)}}}]).directive("uiScrollTd",(function(){return{require:["?^^uiScrollViewport"],restrict:"A",link:function(t,n,e,r){if(r[0]){var o=t,i=t.uiScrollTdInitializer;i||(i=t.uiScrollTdInitializer={linking:!0}),i.linking||(o=i.scope);var u=r[0].gridController;u.registerCell(o,n)&&t.$on("$destroy",(function(){return u.unregisterCell(o,n)})),i.linking||i.onLink()}}}}))}]); +//# sourceMappingURL=ui-scroll-grid.min.js.map \ No newline at end of file diff --git a/dist/ui-scroll-grid.min.js.map b/dist/ui-scroll-grid.min.js.map new file mode 100644 index 00000000..7d351ad4 --- /dev/null +++ b/dist/ui-scroll-grid.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/ui-scroll-grid.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","angular","directive","console","$timeout","GridAdapter","controller","this","getLayout","applyLayout","layout","columnFromPoint","x","y","getColumns","ColumnAdapter","column","css","attr","arguments","length","header","forEachRow","row","id","moveBefore","index","exchangeWith","ColumnController","columns","insidePoint","element","offset","left","outerWidth","top","outerHeight","target","detach","before","moveLast","parent","append","applyCss","removeAttr","mapTo","extend","result","GridController","scrollViewport","rowMap","Map","transform","visible","forEach","cell","adapter","publicContext","gridAdapter","scope","item","registerColumn","push","registerCell","set","unregisterCell","indexOf","splice","delete","callback","slice","sort","a","b","layouts","Error","map","selected","columnId","next","find","col","undefined","require","restrict","link","$scope","$attr","controllers","gridController","tdInitializer","uiScrollTdInitializer","linking","$on","onLink"],"mappings":"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","file":"ui-scroll-grid.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","angular.module('ui.scroll.grid', [])\n .directive('uiScrollTh', ['$log', '$timeout', function(console, $timeout) {\n\n function GridAdapter(controller) {\n\n this.getLayout = () => controller.getLayout();\n\n this.applyLayout = (layout) => controller.applyLayout(layout);\n\n this.columnFromPoint = (x, y) => controller.columnFromPoint(x, y);\n\n Object.defineProperty(this, 'columns', { get: () => controller.getColumns() });\n }\n\n function ColumnAdapter(controller, column) {\n\n this.css = function( /* attr, value */ ) {\n var attr = arguments[0];\n var value = arguments[1];\n if (arguments.length == 1) {\n return column.header.css(attr);\n }\n if (arguments.length == 2) {\n column.header.css(attr, value);\n controller.forEachRow((row) => row[column.id].css(attr, value));\n column.css[attr] = value;\n }\n };\n\n this.moveBefore = (index) => controller.moveBefore(column, index);\n\n this.exchangeWith = (index) => controller.exchangeWith(column, index);\n\n Object.defineProperty(this, 'columnId', { get: () => column.id });\n }\n\n function ColumnController(controller, columns, header) {\n\n this.header = header;\n this.css = {};\n this.mapTo = columns.length;\n this.id = columns.length;\n\n // controller api methods\n\n this.applyLayout = function(layout) {\n this.css = angular.extend({}, layout.css);\n this.mapTo = layout.mapTo;\n applyCss(this.header, this.css);\n };\n\n this.moveBefore = function(target) {\n if (target) {\n moveBefore(header, target.header);\n controller.forEachRow((row) => moveBefore(row[this.id], row[target.id]));\n } else {\n moveLast(header);\n controller.forEachRow((row) => moveLast(row[this.id]));\n }\n };\n\n this.columnFromPoint = function(x, y) {\n if (insidePoint(header, x, y)) {\n return this;\n }\n let result = null;\n controller.forEachRow((row) =>\n result = insidePoint(row[this.id], x, y) ? this : result\n );\n return result;\n };\n\n this.applyCss = function(target) {\n applyCss(target, this.css);\n };\n\n // function definitions\n\n function insidePoint(element, x, y) {\n let offset = element.offset();\n if (x < offset.left || offset.left + element.outerWidth(true) < x)\n return false;\n if (y < offset.top || offset.top + element.outerHeight(true) < y)\n return false;\n return true;\n }\n\n function moveBefore(element, target) {\n element.detach();\n target.before(element);\n }\n\n function moveLast(element) {\n let parent = element.parent();\n element.detach();\n parent.append(element);\n }\n\n function applyCss(target, css) {\n target.removeAttr('style');\n for (let attr in css) {\n if (css.hasOwnProperty(attr)) {\n target.css(attr, css[attr]);\n }\n }\n }\n\n }\n\n function GridController(scrollViewport) {\n let columns = [];\n let rowMap = new Map();\n\n $timeout(() => {\n scrollViewport.adapter.publicContext.gridAdapter = new GridAdapter(this);\n scrollViewport.adapter.transform = (scope, item) => transform(rowMap.get(scope), item);\n });\n\n this.registerColumn = function(header) {\n columns.push(new ColumnController(this, columns, header));\n };\n\n this.registerCell = function(scope, cell) {\n let row = rowMap.get(scope);\n if (!row) {\n row = [];\n rowMap.set(scope, row);\n }\n if (row.length >= columns.length) {\n return false;\n }\n row.push(cell);\n return true;\n };\n\n this.unregisterCell = function(scope, cell) {\n let row = rowMap.get(scope);\n let i = row.indexOf(cell);\n row.splice(i, 1);\n if (!row.length) {\n rowMap.delete(scope);\n }\n };\n\n this.forEachRow = function(callback) {\n rowMap.forEach(callback);\n };\n\n this.getColumns = function() {\n let result = [];\n columns.slice()\n .sort((a, b) => a.mapTo - b.mapTo)\n .forEach((column) => result.push(new ColumnAdapter(this, column)));\n return result;\n };\n\n this.getLayout = function() {\n let result = [];\n columns.forEach((column, index) => result.push({\n index: index,\n css: angular.extend({}, column.css),\n mapTo: column.mapTo\n }));\n return result;\n };\n\n this.applyLayout = function(layouts) {\n if (!layouts || layouts.length != columns.length) {\n throw new Error('Failed to apply layout - number of layouts should match number of columns');\n }\n layouts.forEach((layout, index) => columns[index].applyLayout(layout));\n transform(columns.map((column) => column.header));\n rowMap.forEach((row) => transform(row));\n };\n\n this.moveBefore = function(selected, target) {\n let index = target;\n\n if (target % 1 !== 0) {\n index = target ? columns[target.columnId].mapTo : columns.length;\n }\n if (index < 0 || index > columns.length) {\n return; // throw an error?\n }\n\n let mapTo = selected.mapTo,\n next = null;\n index -= mapTo < index ? 1 : 0;\n\n columns.forEach(c => {\n c.mapTo -= c.mapTo > mapTo ? 1 : 0;\n c.mapTo += c.mapTo >= index ? 1 : 0;\n next = c.mapTo === index + 1 ? c : next;\n });\n\n selected.mapTo = index;\n selected.moveBefore(next);\n };\n\n this.exchangeWith = function(selected, index) {\n if (index < 0 || index >= columns.length) {\n return;\n }\n columns.find(c => c.mapTo === index).mapTo = selected.mapTo;\n selected.mapTo = index;\n };\n\n this.columnFromPoint = function(x, y) {\n let column = columns.find(col => col.columnFromPoint(x, y));\n return column ? new ColumnAdapter(this, column) : undefined;\n };\n\n // function definitions\n\n function transform(row) {\n let parent = row[0].parent();\n let visible = [];\n\n row.forEach((cell, index) => {\n columns[index].applyCss(cell);\n visible[columns[index].mapTo] = row[index];\n row[index].detach();\n });\n\n visible.forEach(cell => parent.append(cell));\n }\n\n }\n\n return {\n require: ['^^uiScrollViewport'],\n restrict: 'A',\n link: ($scope, element, $attr, controllers) => {\n controllers[0].gridController = controllers[0].gridController || new GridController(controllers[0]);\n controllers[0].gridController.registerColumn(element);\n }\n };\n }])\n\n.directive('uiScrollTd', function() {\n return {\n require: ['?^^uiScrollViewport'],\n restrict: 'A',\n link: ($scope, element, $attr, controllers) => {\n if (!controllers[0]) {\n return;\n }\n let scope = $scope;\n let tdInitializer = $scope.uiScrollTdInitializer;\n if (!tdInitializer) {\n tdInitializer = $scope.uiScrollTdInitializer = {\n linking: true\n };\n }\n if (!tdInitializer.linking) {\n scope = tdInitializer.scope;\n }\n let gridController = controllers[0].gridController;\n if (gridController.registerCell(scope, element)) {\n $scope.$on('$destroy', () => gridController.unregisterCell(scope, element));\n }\n if (!tdInitializer.linking) {\n tdInitializer.onLink();\n }\n }\n };\n});\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/ui-scroll-jqlite.js b/dist/ui-scroll-jqlite.js new file mode 100644 index 00000000..c542a1a4 --- /dev/null +++ b/dist/ui-scroll-jqlite.js @@ -0,0 +1,12 @@ +/*! + * angular-ui-scroll + * https://github.com/angular-ui/ui-scroll.git + * This module is deprecated since 1.6.0 and will be removed in future versions! + * License: MIT + */ +(function () { + 'use strict'; + + angular.module('ui.scroll.jqlite', []); + +})(); \ No newline at end of file diff --git a/dist/ui-scroll-jqlite.min.js b/dist/ui-scroll-jqlite.min.js new file mode 100644 index 00000000..af1c87f9 --- /dev/null +++ b/dist/ui-scroll-jqlite.min.js @@ -0,0 +1 @@ +!function(){"use strict";angular.module("ui.scroll.jqlite",[])}(); \ No newline at end of file diff --git a/dist/ui-scroll.js b/dist/ui-scroll.js new file mode 100644 index 00000000..1c2c1afc --- /dev/null +++ b/dist/ui-scroll.js @@ -0,0 +1,1900 @@ +/*! + * angular-ui-scroll + * https://github.com/angular-ui/ui-scroll + * Version: 1.8.2 -- 2020-10-02T15:31:19.969Z + * License: MIT + */ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */, +/* 1 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// CONCATENATED MODULE: ./src/modules/jqLiteExtras.js +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } + +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } + +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +/*! + globals: angular, window + List of used element methods available in JQuery but not in JQuery Lite + element.before(elem) + element.height() + element.outerHeight(true) + element.height(value) = only for Top/Bottom padding elements + element.scrollTop() + element.scrollTop(value) + */ +var jqLiteExtras_JQLiteExtras = +/*#__PURE__*/ +function () { + function JQLiteExtras() { + _classCallCheck(this, JQLiteExtras); + } + + _createClass(JQLiteExtras, [{ + key: "registerFor", + value: function registerFor(element) { + var convertToPx, css, getStyle, isWindow; // angular implementation blows up if elem is the window + + css = angular.element.prototype.css; + + element.prototype.css = function (name, value) { + var self = this; + var elem = self[0]; + + if (!(!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style)) { + return css.call(self, name, value); + } + }; // as defined in angularjs v1.0.5 + + + isWindow = function isWindow(obj) { + return obj && obj.document && obj.location && obj.alert && obj.setInterval; + }; + + function scrollTo(self, direction, value) { + var elem = self[0]; + + var _top$left$direction = _slicedToArray({ + top: ['scrollTop', 'pageYOffset', 'scrollLeft'], + left: ['scrollLeft', 'pageXOffset', 'scrollTop'] + }[direction], 3), + method = _top$left$direction[0], + prop = _top$left$direction[1], + preserve = _top$left$direction[2]; + + var isValueDefined = typeof value !== 'undefined'; + + if (isWindow(elem)) { + if (isValueDefined) { + return elem.scrollTo(self[preserve].call(self), value); + } + + return prop in elem ? elem[prop] : elem.document.documentElement[method]; + } else { + if (isValueDefined) { + elem[method] = value; + } + + return elem[method]; + } + } + + if (window.getComputedStyle) { + getStyle = function getStyle(elem) { + return window.getComputedStyle(elem, null); + }; + + convertToPx = function convertToPx(elem, value) { + return parseFloat(value); + }; + } else { + getStyle = function getStyle(elem) { + return elem.currentStyle; + }; + + convertToPx = function convertToPx(elem, value) { + var left, result, rs, rsLeft, style; + var core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; + var rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i'); + + if (!rnumnonpx.test(value)) { + return parseFloat(value); + } // ported from JQuery + + + style = elem.style; + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + if (rs) { + rs.left = style.left; + } // put in the new values to get a computed style out + + + style.left = value; + result = style.pixelLeft; + style.left = left; + + if (rsLeft) { + rs.left = rsLeft; + } + + return result; + }; + } + + function getMeasurements(elem, measure) { + var base, borderA, borderB, computedMarginA, computedMarginB, computedStyle, dirA, dirB, marginA, marginB, paddingA, paddingB; + + if (isWindow(elem)) { + base = document.documentElement[{ + height: 'clientHeight', + width: 'clientWidth' + }[measure]]; + return { + base: base, + padding: 0, + border: 0, + margin: 0 + }; + } // Start with offset property + + + var _width$height$measure = _slicedToArray({ + width: [elem.offsetWidth, 'Left', 'Right'], + height: [elem.offsetHeight, 'Top', 'Bottom'] + }[measure], 3); + + base = _width$height$measure[0]; + dirA = _width$height$measure[1]; + dirB = _width$height$measure[2]; + computedStyle = getStyle(elem); + paddingA = convertToPx(elem, computedStyle['padding' + dirA]) || 0; + paddingB = convertToPx(elem, computedStyle['padding' + dirB]) || 0; + borderA = convertToPx(elem, computedStyle['border' + dirA + 'Width']) || 0; + borderB = convertToPx(elem, computedStyle['border' + dirB + 'Width']) || 0; + computedMarginA = computedStyle['margin' + dirA]; + computedMarginB = computedStyle['margin' + dirB]; // I do not care for width for now, so this hack is irrelevant + // if ( !supportsPercentMargin ) + // computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA ) + // computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB ) + + marginA = convertToPx(elem, computedMarginA) || 0; + marginB = convertToPx(elem, computedMarginB) || 0; + return { + base: base, + padding: paddingA + paddingB, + border: borderA + borderB, + margin: marginA + marginB + }; + } + + function getWidthHeight(elem, direction, measure) { + var computedStyle, result; + var measurements = getMeasurements(elem, direction); + + if (measurements.base > 0) { + return { + base: measurements.base - measurements.padding - measurements.border, + outer: measurements.base, + outerfull: measurements.base + measurements.margin + }[measure]; + } // Fall back to computed then uncomputed css if necessary + + + computedStyle = getStyle(elem); + result = computedStyle[direction]; + + if (result < 0 || result === null) { + result = elem.style[direction] || 0; + } // Normalize "", auto, and prepare for extra + + + result = parseFloat(result) || 0; + return { + base: result - measurements.padding - measurements.border, + outer: result, + outerfull: result + measurements.padding + measurements.border + measurements.margin + }[measure]; + } // define missing methods + + + return angular.forEach({ + before: function before(newElem) { + var children, elem, i, j, parent, ref, self; + self = this; + elem = self[0]; + parent = self.parent(); + children = parent.contents(); + + if (children[0] === elem) { + return parent.prepend(newElem); + } else { + for (i = j = 1, ref = children.length - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { + if (children[i] === elem) { + angular.element(children[i - 1]).after(newElem); + return; + } + } + + throw new Error('invalid DOM structure ' + elem.outerHTML); + } + }, + height: function height(value) { + var self; + self = this; + + if (typeof value !== 'undefined') { + if (angular.isNumber(value)) { + value = value + 'px'; + } + + return css.call(self, 'height', value); + } else { + return getWidthHeight(this[0], 'height', 'base'); + } + }, + outerHeight: function outerHeight(option) { + return getWidthHeight(this[0], 'height', option ? 'outerfull' : 'outer'); + }, + outerWidth: function outerWidth(option) { + return getWidthHeight(this[0], 'width', option ? 'outerfull' : 'outer'); + }, + + /* + The offset setter method is not implemented + */ + offset: function offset(value) { + var docElem, win; + var self = this; + var box = { + top: 0, + left: 0 + }; + var elem = self[0]; + var doc = elem && elem.ownerDocument; + + if (arguments.length) { + if (value === undefined) { + return self; + } // TODO: implement setter + + + throw new Error('offset setter method is not implemented'); + } + + if (!doc) { + return; + } + + docElem = doc.documentElement; // TODO: Make sure it's not a disconnected DOM node + + if (elem.getBoundingClientRect != null) { + box = elem.getBoundingClientRect(); + } + + win = doc.defaultView || doc.parentWindow; + return { + top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0), + left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0) + }; + }, + scrollTop: function scrollTop(value) { + return scrollTo(this, 'top', value); + }, + scrollLeft: function scrollLeft(value) { + return scrollTo(this, 'left', value); + } + }, function (value, key) { + if (!element.prototype[key]) { + return element.prototype[key] = value; + } + }); + } + }]); + + return JQLiteExtras; +}(); + + +// CONCATENATED MODULE: ./src/modules/elementRoutines.js +function elementRoutines_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function elementRoutines_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function elementRoutines_createClass(Constructor, protoProps, staticProps) { if (protoProps) elementRoutines_defineProperties(Constructor.prototype, protoProps); if (staticProps) elementRoutines_defineProperties(Constructor, staticProps); return Constructor; } + +var hideClassToken = 'ng-ui-scroll-hide'; + +var ElementRoutines = +/*#__PURE__*/ +function () { + elementRoutines_createClass(ElementRoutines, null, [{ + key: "addCSSRules", + value: function addCSSRules() { + var selector = '.' + hideClassToken; + var rules = 'display: none'; + var sheet = document.styleSheets[0]; + var index; + + try { + index = sheet.cssRules.length; + } catch (err) { + index = 0; + } + + if ('insertRule' in sheet) { + sheet.insertRule(selector + '{' + rules + '}', index); + } else if ('addRule' in sheet) { + sheet.addRule(selector, rules, index); + } + } + }]); + + function ElementRoutines($injector, $q) { + elementRoutines_classCallCheck(this, ElementRoutines); + + this.$animate = $injector.has && $injector.has('$animate') ? $injector.get('$animate') : null; + this.isAngularVersionLessThen1_3 = angular.version.major === 1 && angular.version.minor < 3; + this.$q = $q; + } + + elementRoutines_createClass(ElementRoutines, [{ + key: "hideElement", + value: function hideElement(wrapper) { + wrapper.element.addClass(hideClassToken); + } + }, { + key: "showElement", + value: function showElement(wrapper) { + wrapper.element.removeClass(hideClassToken); + } + }, { + key: "insertElement", + value: function insertElement(newElement, previousElement) { + previousElement.after(newElement); + return []; + } + }, { + key: "removeElement", + value: function removeElement(wrapper) { + wrapper.element.remove(); + wrapper.scope.$destroy(); + return []; + } + }, { + key: "insertElementAnimated", + value: function insertElementAnimated(newElement, previousElement) { + if (!this.$animate) { + return this.insertElement(newElement, previousElement); + } + + if (this.isAngularVersionLessThen1_3) { + var deferred = this.$q.defer(); // no need for parent - previous element is never null + + this.$animate.enter(newElement, null, previousElement, function () { + return deferred.resolve(); + }); + return [deferred.promise]; + } // no need for parent - previous element is never null + + + return [this.$animate.enter(newElement, null, previousElement)]; + } + }, { + key: "removeElementAnimated", + value: function removeElementAnimated(wrapper) { + if (!this.$animate) { + return this.removeElement(wrapper); + } + + if (this.isAngularVersionLessThen1_3) { + var deferred = this.$q.defer(); + this.$animate.leave(wrapper.element, function () { + wrapper.scope.$destroy(); + return deferred.resolve(); + }); + return [deferred.promise]; + } + + return [this.$animate.leave(wrapper.element).then(function () { + return wrapper.scope.$destroy(); + })]; + } + }]); + + return ElementRoutines; +}(); + + +// CONCATENATED MODULE: ./src/modules/utils.js +var OPERATIONS = { + PREPEND: 'prepend', + APPEND: 'append', + INSERT: 'insert', + REMOVE: 'remove', + NONE: 'none' +}; +// CONCATENATED MODULE: ./src/modules/buffer.js + +function ScrollBuffer(elementRoutines, bufferSize, startIndex) { + var buffer = Object.create(Array.prototype); + angular.extend(buffer, { + size: bufferSize, + reset: function reset(startIndex) { + buffer.remove(0, buffer.length); + buffer.eof = false; + buffer.bof = false; + buffer.first = startIndex; + buffer.next = startIndex; + buffer.minIndex = startIndex; + buffer.maxIndex = startIndex; + buffer.minIndexUser = null; + buffer.maxIndexUser = null; + }, + append: function append(items) { + items.forEach(function (item) { + ++buffer.next; + buffer.insert(OPERATIONS.APPEND, item); + }); + buffer.maxIndex = buffer.eof ? buffer.next - 1 : Math.max(buffer.next - 1, buffer.maxIndex); + }, + prepend: function prepend(items, immutableTop) { + items.reverse().forEach(function (item) { + if (immutableTop) { + ++buffer.next; + } else { + --buffer.first; + } + + buffer.insert(OPERATIONS.PREPEND, item); + }); + buffer.minIndex = buffer.bof ? buffer.minIndex = buffer.first : Math.min(buffer.first, buffer.minIndex); + }, + + /** + * inserts wrapped element in the buffer + * the first argument is either operation keyword (see below) or a number for operation 'insert' + * for insert the number is the index for the buffer element the new one have to be inserted after + * operations: 'append', 'prepend', 'insert', 'remove', 'none' + */ + insert: function insert(operation, item, shiftTop) { + var wrapper = { + item: item + }; + + if (operation % 1 === 0) { + // it is an insert + wrapper.op = OPERATIONS.INSERT; + buffer.splice(operation, 0, wrapper); + + if (shiftTop) { + buffer.first--; + } else { + buffer.next++; + } + } else { + wrapper.op = operation; + + switch (operation) { + case OPERATIONS.APPEND: + buffer.push(wrapper); + break; + + case OPERATIONS.PREPEND: + buffer.unshift(wrapper); + break; + } + } + }, + // removes elements from buffer + remove: function remove(arg1, arg2) { + if (angular.isNumber(arg1)) { + // removes items from arg1 (including) through arg2 (excluding) + for (var i = arg1; i < arg2; i++) { + elementRoutines.removeElement(buffer[i]); + } + + return buffer.splice(arg1, arg2 - arg1); + } // removes single item (wrapper) from the buffer + + + buffer.splice(buffer.indexOf(arg1), 1); + + if (arg1.shiftTop && buffer.first === this.getAbsMinIndex()) { + this.incrementMinIndex(); + } else { + this.decrementMaxIndex(); + } + + if (arg1.shiftTop) { + buffer.first++; + } else { + buffer.next--; + } + + if (!buffer.length) { + buffer.minIndex = Math.min(buffer.maxIndex, buffer.minIndex); + } + + return elementRoutines.removeElementAnimated(arg1); + }, + incrementMinIndex: function incrementMinIndex() { + if (buffer.minIndexUser !== null) { + if (buffer.minIndex > buffer.minIndexUser) { + buffer.minIndexUser++; + return; + } + + if (buffer.minIndex === buffer.minIndexUser) { + buffer.minIndexUser++; + } + } + + buffer.minIndex++; + }, + decrementMaxIndex: function decrementMaxIndex() { + if (buffer.maxIndexUser !== null && buffer.maxIndex <= buffer.maxIndexUser) { + buffer.maxIndexUser--; + } + + buffer.maxIndex--; + }, + getAbsMinIndex: function getAbsMinIndex() { + if (buffer.minIndexUser !== null) { + return Math.min(buffer.minIndexUser, buffer.minIndex); + } + + return buffer.minIndex; + }, + getAbsMaxIndex: function getAbsMaxIndex() { + if (buffer.maxIndexUser !== null) { + return Math.max(buffer.maxIndexUser, buffer.maxIndex); + } + + return buffer.maxIndex; + }, + effectiveHeight: function effectiveHeight(elements) { + if (!elements.length) { + return 0; + } + + var top = Number.MAX_VALUE; + var bottom = Number.NEGATIVE_INFINITY; + elements.forEach(function (wrapper) { + if (wrapper.element[0].offsetParent) { + // element style is not display:none + top = Math.min(top, wrapper.element.offset().top); + bottom = Math.max(bottom, wrapper.element.offset().top + wrapper.element.outerHeight(true)); + } + }); + return Math.max(0, bottom - top); + }, + getItems: function getItems() { + return buffer.filter(function (item) { + return item.op === OPERATIONS.NONE; + }); + }, + getFirstItem: function getFirstItem() { + var list = buffer.getItems(); + + if (!list.length) { + return null; + } + + return list[0].item; + }, + getLastItem: function getLastItem() { + var list = buffer.getItems(); + + if (!list.length) { + return null; + } + + return list[list.length - 1].item; + } + }); + buffer.reset(startIndex); + return buffer; +} +// CONCATENATED MODULE: ./src/modules/padding.js +function padding_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function padding_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function padding_createClass(Constructor, protoProps, staticProps) { if (protoProps) padding_defineProperties(Constructor.prototype, protoProps); if (staticProps) padding_defineProperties(Constructor, staticProps); return Constructor; } + +// Can't just extend the Array, due to Babel does not support built-in classes extending +// This solution was taken from https://stackoverflow.com/questions/46897414/es6-class-extends-array-workaround-for-es5-babel-transpile +var CacheProto = +/*#__PURE__*/ +function () { + function CacheProto() { + padding_classCallCheck(this, CacheProto); + } + + padding_createClass(CacheProto, [{ + key: "add", + value: function add(item) { + for (var i = this.length - 1; i >= 0; i--) { + if (this[i].index === item.scope.$index) { + this[i].height = item.element.outerHeight(); + return; + } + } + + this.push({ + index: item.scope.$index, + height: item.element.outerHeight() + }); + this.sort(function (a, b) { + return a.index < b.index ? -1 : a.index > b.index ? 1 : 0; + }); + } + }, { + key: "remove", + value: function remove(argument, _shiftTop) { + var index = argument % 1 === 0 ? argument : argument.scope.$index; + var shiftTop = argument % 1 === 0 ? _shiftTop : argument.shiftTop; + + for (var i = this.length - 1; i >= 0; i--) { + if (this[i].index === index) { + this.splice(i, 1); + break; + } + } + + if (!shiftTop) { + for (var _i = this.length - 1; _i >= 0; _i--) { + if (this[_i].index > index) { + this[_i].index--; + } + } + } + } + }, { + key: "clear", + value: function clear() { + this.length = 0; + } + }]); + + return CacheProto; +}(); + +function Cache() { + var instance = []; + instance.push.apply(instance, arguments); + Object.setPrototypeOf(instance, Cache.prototype); + return instance; +} + +Cache.prototype = Object.create(Array.prototype); +Object.getOwnPropertyNames(CacheProto.prototype).forEach(function (methodName) { + return Cache.prototype[methodName] = CacheProto.prototype[methodName]; +}); + +function generateElement(template) { + if (template.nodeType !== Node.ELEMENT_NODE) { + throw new Error('ui-scroll directive requires an Element node for templating the view'); + } + + var element; + + switch (template.tagName.toLowerCase()) { + case 'dl': + throw new Error("ui-scroll directive does not support <".concat(template.tagName, "> as a repeating tag: ").concat(template.outerHTML)); + + case 'tr': + var table = angular.element('
'); + element = table.find('tr'); + break; + + case 'li': + element = angular.element('
  • '); + break; + + default: + element = angular.element('
    '); + } + + return element; +} + +var Padding = +/*#__PURE__*/ +function () { + function Padding(template) { + padding_classCallCheck(this, Padding); + + this.element = generateElement(template); + this.cache = new Cache(); + } + + padding_createClass(Padding, [{ + key: "height", + value: function height() { + return this.element.height.apply(this.element, arguments); + } + }]); + + return Padding; +}(); + +/* harmony default export */ var modules_padding = (Padding); +// CONCATENATED MODULE: ./src/modules/viewport.js + +function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding) { + var topPadding = null; + var bottomPadding = null; + var viewport = viewportController && viewportController.viewport ? viewportController.viewport : angular.element(window); + var container = viewportController && viewportController.container ? viewportController.container : undefined; + var scope = viewportController && viewportController.scope ? viewportController.scope : $rootScope; + viewport.css({ + 'overflow-anchor': 'none', + 'overflow-y': 'auto', + 'display': 'block' + }); + + function bufferPadding() { + return viewport.outerHeight() * padding; // some extra space to initiate preload + } + + angular.extend(viewport, { + getScope: function getScope() { + return scope; + }, + createPaddingElements: function createPaddingElements(template) { + topPadding = new modules_padding(template); + bottomPadding = new modules_padding(template); + element.before(topPadding.element); + element.after(bottomPadding.element); + topPadding.height(0); + bottomPadding.height(0); + }, + applyContainerStyle: function applyContainerStyle() { + if (!container) { + return true; + } + + if (container !== viewport) { + viewport.css('height', window.getComputedStyle(container[0]).height); + } + + return viewport.height() > 0; + }, + bottomDataPos: function bottomDataPos() { + var scrollHeight = viewport[0].scrollHeight; + scrollHeight = scrollHeight != null ? scrollHeight : viewport[0].document.documentElement.scrollHeight; + return scrollHeight - bottomPadding.height(); + }, + topDataPos: function topDataPos() { + return topPadding.height(); + }, + bottomVisiblePos: function bottomVisiblePos() { + return viewport.scrollTop() + viewport.outerHeight(); + }, + topVisiblePos: function topVisiblePos() { + return viewport.scrollTop(); + }, + insertElement: function insertElement(e, sibling) { + return elementRoutines.insertElement(e, sibling || topPadding.element); + }, + insertElementAnimated: function insertElementAnimated(e, sibling) { + return elementRoutines.insertElementAnimated(e, sibling || topPadding.element); + }, + shouldLoadBottom: function shouldLoadBottom() { + return !buffer.eof && viewport.bottomDataPos() < viewport.bottomVisiblePos() + bufferPadding(); + }, + clipBottom: function clipBottom() { + // clip the invisible items off the bottom + var overage = 0; + var overageHeight = 0; + var itemHeight = 0; + var emptySpaceHeight = viewport.bottomDataPos() - viewport.bottomVisiblePos() - bufferPadding(); + + for (var i = buffer.length - 1; i >= 0; i--) { + itemHeight = buffer[i].element.outerHeight(true); + + if (overageHeight + itemHeight > emptySpaceHeight) { + break; + } + + bottomPadding.cache.add(buffer[i]); + overageHeight += itemHeight; + overage++; + } + + if (overage > 0) { + buffer.eof = false; + buffer.remove(buffer.length - overage, buffer.length); + buffer.next -= overage; + viewport.adjustPaddings(); + } + }, + shouldLoadTop: function shouldLoadTop() { + return !buffer.bof && viewport.topDataPos() > viewport.topVisiblePos() - bufferPadding(); + }, + clipTop: function clipTop() { + // clip the invisible items off the top + var overage = 0; + var overageHeight = 0; + var itemHeight = 0; + var emptySpaceHeight = viewport.topVisiblePos() - viewport.topDataPos() - bufferPadding(); + + for (var i = 0; i < buffer.length; i++) { + itemHeight = buffer[i].element.outerHeight(true); + + if (overageHeight + itemHeight > emptySpaceHeight) { + break; + } + + topPadding.cache.add(buffer[i]); + overageHeight += itemHeight; + overage++; + } + + if (overage > 0) { + // we need to adjust top padding element before items are removed from top + // to avoid strange behaviour of scroll bar during remove top items when we are at the very bottom + topPadding.height(topPadding.height() + overageHeight); + buffer.bof = false; + buffer.remove(0, overage); + buffer.first += overage; + } + }, + adjustPaddings: function adjustPaddings() { + if (!buffer.length) { + return; + } // precise heights calculation based on items that are in buffer or that were in buffer once + + + var visibleItemsHeight = buffer.reduce(function (summ, item) { + return summ + item.element.outerHeight(true); + }, 0); + var topPaddingHeight = 0, + topCount = 0; + topPadding.cache.forEach(function (item) { + if (item.index < buffer.first) { + topPaddingHeight += item.height; + topCount++; + } + }); + var bottomPaddingHeight = 0, + bottomCount = 0; + bottomPadding.cache.forEach(function (item) { + if (item.index >= buffer.next) { + bottomPaddingHeight += item.height; + bottomCount++; + } + }); + var totalHeight = visibleItemsHeight + topPaddingHeight + bottomPaddingHeight; + var averageItemHeight = totalHeight / (topCount + bottomCount + buffer.length); // average heights calculation, items that have never been reached + + var adjustTopPadding = buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser; + var adjustBottomPadding = buffer.maxIndexUser !== null && buffer.maxIndex < buffer.maxIndexUser; + var topPaddingHeightAdd = adjustTopPadding ? (buffer.minIndex - buffer.minIndexUser) * averageItemHeight : 0; + var bottomPaddingHeightAdd = adjustBottomPadding ? (buffer.maxIndexUser - buffer.maxIndex) * averageItemHeight : 0; // paddings combine adjustment + + topPadding.height(topPaddingHeight + topPaddingHeightAdd); + bottomPadding.height(bottomPaddingHeight + bottomPaddingHeightAdd); + }, + onAfterMinIndexSet: function onAfterMinIndexSet(topPaddingHeightOld) { + // additional scrollTop adjustment in case of datasource.minIndex external set + if (buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser) { + var diff = topPadding.height() - topPaddingHeightOld; + viewport.scrollTop(viewport.scrollTop() + diff); + + while ((diff -= viewport.scrollTop()) > 0) { + bottomPadding.height(bottomPadding.height() + diff); + viewport.scrollTop(viewport.scrollTop() + diff); + } + } + }, + onAfterPrepend: function onAfterPrepend(updates) { + if (!updates.prepended.length) { + return; + } + + var height = buffer.effectiveHeight(updates.prepended); + var paddingHeight = topPadding.height() - height; + + if (paddingHeight >= 0) { + topPadding.height(paddingHeight); + return; + } + + var position = viewport.scrollTop(); + var newPosition = position - paddingHeight; + viewport.synthetic = { + previous: position, + next: newPosition + }; + topPadding.height(0); + viewport.scrollTop(newPosition); + }, + resetTopPadding: function resetTopPadding() { + topPadding.height(0); + topPadding.cache.clear(); + }, + resetBottomPadding: function resetBottomPadding() { + bottomPadding.height(0); + bottomPadding.cache.clear(); + }, + removeCacheItem: function removeCacheItem(item, shiftTop) { + topPadding.cache.remove(item, shiftTop); + bottomPadding.cache.remove(item, shiftTop); + }, + removeItem: function removeItem(item) { + this.removeCacheItem(item); + return buffer.remove(item); + } + }); + return viewport; +} +// CONCATENATED MODULE: ./src/modules/adapter.js +function adapter_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function adapter_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function adapter_createClass(Constructor, protoProps, staticProps) { if (protoProps) adapter_defineProperties(Constructor.prototype, protoProps); if (staticProps) adapter_defineProperties(Constructor, staticProps); return Constructor; } + + + +var adapter_Adapter = +/*#__PURE__*/ +function () { + function Adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload) { + adapter_classCallCheck(this, Adapter); + + this.$parse = $parse; + this.$attr = $attr; + this.viewport = viewport; + this.buffer = buffer; + this.doAdjust = doAdjust; + this.reload = reload; + this.isLoading = false; + this.disabled = false; + var viewportScope = viewport.getScope(); + this.startScope = viewportScope.$parent ? viewportScope : $scope; + this.publicContext = {}; + this.assignAdapter($attr.adapter); + this.generatePublicContext(); + } + + adapter_createClass(Adapter, [{ + key: "assignAdapter", + value: function assignAdapter(adapterAttr) { + if (!adapterAttr || !(adapterAttr = adapterAttr.replace(/^\s+|\s+$/gm, ''))) { + return; + } + + var adapterOnScope; + + try { + this.$parse(adapterAttr).assign(this.startScope, {}); + adapterOnScope = this.$parse(adapterAttr)(this.startScope); + } catch (error) { + error.message = "Angular ui-scroll Adapter assignment exception.\n" + "Can't parse \"".concat(adapterAttr, "\" expression.\n") + error.message; + throw error; + } + + angular.extend(adapterOnScope, this.publicContext); + this.publicContext = adapterOnScope; + } + }, { + key: "generatePublicContext", + value: function generatePublicContext() { + var _this = this; + + // these methods will be accessible out of ui-scroll via user defined adapter + var publicMethods = ['reload', 'applyUpdates', 'append', 'prepend', 'isBOF', 'isEOF', 'isEmpty']; + + for (var i = publicMethods.length - 1; i >= 0; i--) { + this.publicContext[publicMethods[i]] = this[publicMethods[i]].bind(this); + } // these read-only props will be accessible out of ui-scroll via user defined adapter + + + var publicProps = ['isLoading', 'topVisible', 'topVisibleElement', 'topVisibleScope', 'bottomVisible', 'bottomVisibleElement', 'bottomVisibleScope']; + + var _loop = function _loop(_i) { + var property = void 0, + attr = _this.$attr[publicProps[_i]]; + Object.defineProperty(_this, publicProps[_i], { + get: function get() { + return property; + }, + set: function set(value) { + property = value; + _this.publicContext[publicProps[_i]] = value; + + if (attr) { + _this.$parse(attr).assign(_this.startScope, value); + } + } + }); + }; + + for (var _i = publicProps.length - 1; _i >= 0; _i--) { + _loop(_i); + } // read-only immediately calculated public properties + + + var publicPropsImmediate = ['bufferFirst', 'bufferLast', 'bufferLength']; + + var _loop2 = function _loop2(_i2) { + Object.defineProperty(_this.publicContext, publicPropsImmediate[_i2], { + get: function get() { + return _this[publicPropsImmediate[_i2]]; + } + }); + }; + + for (var _i2 = publicPropsImmediate.length - 1; _i2 >= 0; _i2--) { + _loop2(_i2); + } // non-read-only public property + + + Object.defineProperty(this.publicContext, 'disabled', { + get: function get() { + return _this.disabled; + }, + set: function set(value) { + return !(_this.disabled = value) ? _this.doAdjust() : null; + } + }); + } + }, { + key: "loading", + value: function loading(value) { + this.isLoading = value; + } + }, { + key: "isBOF", + value: function isBOF() { + return this.buffer.bof; + } + }, { + key: "isEOF", + value: function isEOF() { + return this.buffer.eof; + } + }, { + key: "isEmpty", + value: function isEmpty() { + return !this.buffer.length; + } + }, { + key: "append", + value: function append(newItems) { + this.buffer.append(newItems); + this.doAdjust(); + this.viewport.clipTop(); + this.viewport.clipBottom(); + } + }, { + key: "prepend", + value: function prepend(newItems) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + this.buffer.prepend(newItems, options.immutableTop); + this.doAdjust(); + this.viewport.clipTop(); + this.viewport.clipBottom(); + } + }, { + key: "applyUpdates", + value: function applyUpdates(arg1, arg2, arg3) { + if (typeof arg1 === 'function') { + this.applyUpdatesFunc(arg1, arg2); + } else { + this.applyUpdatesIndex(arg1, arg2, arg3); + } + + this.doAdjust(); + } + }, { + key: "applyUpdatesFunc", + value: function applyUpdatesFunc(cb) { + var _this2 = this; + + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + this.buffer.slice(0).forEach(function (wrapper) { + // we need to do it on the buffer clone, because buffer content + // may change as we iterate through + _this2.applyUpdate(wrapper, cb(wrapper.item, wrapper.scope, wrapper.element), options); + }); + } + }, { + key: "applyUpdatesIndex", + value: function applyUpdatesIndex(index, newItems) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + if (index % 1 !== 0) { + throw new Error('applyUpdates - ' + index + ' is not a valid index (should be an integer)'); + } + + var _index = index - this.buffer.first; // apply updates only within buffer + + + if (_index >= 0 && _index < this.buffer.length) { + this.applyUpdate(this.buffer[_index], newItems, options); + } // out-of-buffer case: deletion may affect Paddings + else if (index >= this.buffer.getAbsMinIndex() && index <= this.buffer.getAbsMaxIndex()) { + if (angular.isArray(newItems) && !newItems.length) { + this.viewport.removeCacheItem(index, !options.immutableTop && index === this.buffer.minIndex); + + if (!options.immutableTop && index === this.buffer.getAbsMinIndex()) { + this.buffer.incrementMinIndex(); + } else { + this.buffer.decrementMaxIndex(); + } + } + } + } + }, { + key: "applyUpdate", + value: function applyUpdate(wrapper, newItems) { + var _this3 = this; + + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + if (!angular.isArray(newItems)) { + return; + } + + var position = this.buffer.indexOf(wrapper); + + if (!newItems.reverse().some(function (newItem) { + return newItem === wrapper.item; + })) { + wrapper.op = OPERATIONS.REMOVE; // try to catch "first" edge case on remove + + if (!options.immutableTop && !newItems.length) { + // this is the first item, or the previous one's part of the "shift-top" group + if (position === 0 && this.buffer.bof || position !== 0 && this.buffer[position - 1].shiftTop) { + wrapper.shiftTop = true; + } + } + } + + newItems.forEach(function (newItem) { + if (newItem === wrapper.item) { + position--; + } else { + // 3 parameter (shiftTop) is to catch "first" edge case on insert + _this3.buffer.insert(position + 1, newItem, !options.immutableTop && position === -1); + } + }); + } + }, { + key: "calculateProperties", + value: function calculateProperties() { + var rowTop = null, + topHeight = 0; + var topDone = false, + bottomDone = false; + var length = this.buffer.length; + + for (var i = 0; i < length; i++) { + var item = this.buffer[i]; + var itemTop = item.element.offset().top; + + if (rowTop !== itemTop) { + // a new row condition + var itemHeight = item.element.outerHeight(true); + var top = this.viewport.topDataPos() + topHeight + itemHeight; + + if (!topDone && top > this.viewport.topVisiblePos()) { + topDone = true; + this['topVisible'] = item.item; + this['topVisibleElement'] = item.element; + this['topVisibleScope'] = item.scope; + } + + if (!bottomDone && (top >= this.viewport.bottomVisiblePos() || i === length - 1 && this.isEOF())) { + bottomDone = true; + this['bottomVisible'] = item.item; + this['bottomVisibleElement'] = item.element; + this['bottomVisibleScope'] = item.scope; + } + + topHeight += itemHeight; + } + + rowTop = itemTop; + + if (topDone && bottomDone) { + break; + } + } + } + }, { + key: "bufferLength", + get: function get() { + return this.buffer.getItems().length; + } + }, { + key: "bufferFirst", + get: function get() { + return this.buffer.getFirstItem(); + } + }, { + key: "bufferLast", + get: function get() { + return this.buffer.getLastItem(); + } + }]); + + return Adapter; +}(); + +/* harmony default export */ var modules_adapter = (adapter_Adapter); +// CONCATENATED MODULE: ./src/ui-scroll.js + + + + + + +angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtras).run(['JQLiteExtras', function (JQLiteExtras) { + var elt = angular.element; + !(window.jQuery && elt.fn && elt.fn.jquery) ? new JQLiteExtras().registerFor(elt) : null; + ElementRoutines.addCSSRules(); +}]).directive('uiScrollViewport', function () { + return { + restrict: 'A', + controller: ['$scope', '$element', function (scope, element) { + var _this = this; + + this.container = element; + this.viewport = element; + this.scope = scope; + angular.forEach(element.children(), function (child) { + if (child.tagName.toLowerCase() === 'tbody') { + _this.viewport = angular.element(child); + } + }); + return this; + }] + }; +}).directive('uiScroll', ['$log', '$injector', '$rootScope', '$timeout', '$interval', '$q', '$parse', function (console, $injector, $rootScope, $timeout, $interval, $q, $parse) { + return { + require: ['?^uiScrollViewport'], + restrict: 'A', + transclude: 'element', + priority: 1000, + terminal: true, + link: link + }; + + function link($scope, element, $attr, controllers, linker) { + var match = $attr.uiScroll.match(/^\s*(\w+)\s+in\s+([(\w|\$)\.]+)\s*$/); + + if (!match) { + throw new Error('Expected uiScroll in form of \'_item_ in _datasource_\' but got \'' + $attr.uiScroll + '\''); + } + + function parseNumber(value, defaultValue, isFloat) { + if (!isFloat) { + value = value === null ? defaultValue : Math.floor(value); + } + + return isNaN(value) ? defaultValue : value; + } + + function parseNumericAttr(value, defaultValue, isFloat) { + var result = $parse(value)($scope); + return parseNumber(result, defaultValue, isFloat); + } + + function parseBooleanAttr(value, defaultValue) { + var result = $parse(value)($scope); + return typeof result === 'boolean' ? result : defaultValue; + } + + var BUFFER_MIN = 3; + var BUFFER_DEFAULT = 10; + var PADDING_MIN = 0.3; + var PADDING_DEFAULT = 0.5; + var HANDLE_INERTIA_DEFAULT = true; + var START_INDEX_DEFAULT = 1; + var MAX_VIEWPORT_DELAY = 500; + var VIEWPORT_POLLING_INTERVAL = 50; + var datasource = null; + var itemName = match[1]; + var datasourceName = match[2]; + var viewportController = controllers[0]; + var bufferSize = Math.max(BUFFER_MIN, parseNumericAttr($attr.bufferSize, BUFFER_DEFAULT)); + var padding = Math.max(PADDING_MIN, parseNumericAttr($attr.padding, PADDING_DEFAULT, true)); + var handleInertia = parseBooleanAttr($attr.handleInertia, HANDLE_INERTIA_DEFAULT); + var startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT); + var ridActual = 0; // current data revision id + + var pending = []; + var elementRoutines = new ElementRoutines($injector, $q); + var buffer = new ScrollBuffer(elementRoutines, bufferSize, startIndex); + var viewport = new Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding); + var adapter = new modules_adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload); + + if (viewportController) { + viewportController.adapter = adapter; + } + + var isDatasourceValid = function isDatasourceValid() { + return Object.prototype.toString.call(datasource) === '[object Object]' && typeof datasource.get === 'function'; + }; + + datasource = $parse(datasourceName)($scope); // try to get datasource on scope + + if (!isDatasourceValid()) { + datasource = $injector.get(datasourceName); // try to inject datasource as service + + if (!isDatasourceValid()) { + throw new Error(datasourceName + ' is not a valid datasource'); + } + } + + var onRenderHandlers = []; + + function onRenderHandlersRunner() { + onRenderHandlers.forEach(function (handler) { + return handler.run(); + }); + onRenderHandlers = []; + } + + function persistDatasourceIndex(datasource, propName) { + var getter; // need to postpone min/maxIndexUser processing if the view is empty + + if (angular.isNumber(datasource[propName])) { + getter = datasource[propName]; + + if (angular.isNumber(getter)) { + onRenderHandlers = onRenderHandlers.filter(function (handler) { + return handler.id !== propName; + }); + onRenderHandlers.push({ + id: propName, + run: function run() { + return datasource[propName] = getter; + } + }); + } + } + } + + function defineDatasourceIndex(datasource, propName, propUserName) { + var descriptor = Object.getOwnPropertyDescriptor(datasource, propName); + + if (descriptor && (descriptor.set || descriptor.get)) { + return; + } + + var getter; + persistDatasourceIndex(datasource, propName); + Object.defineProperty(datasource, propName, { + set: function set(value) { + getter = value; + + if (pending.length && !buffer.length) { + persistDatasourceIndex(datasource, propName); + return; + } + + buffer[propUserName] = value; + var topPaddingHeightOld = viewport.topDataPos(); + viewport.adjustPaddings(); + + if (propName === 'minIndex') { + viewport.onAfterMinIndexSet(topPaddingHeightOld); + } + }, + get: function get() { + return getter; + } + }); + } + + defineDatasourceIndex(datasource, 'minIndex', 'minIndexUser'); + defineDatasourceIndex(datasource, 'maxIndex', 'maxIndexUser'); + var fetchNext = datasource.get.length !== 2 ? function (success) { + return datasource.get(buffer.next, bufferSize, success); + } : function (success) { + datasource.get({ + index: buffer.next, + append: buffer.length ? buffer[buffer.length - 1].item : void 0, + count: bufferSize + }, success); + }; + var fetchPrevious = datasource.get.length !== 2 ? function (success) { + return datasource.get(buffer.first - bufferSize, bufferSize, success); + } : function (success) { + datasource.get({ + index: buffer.first - bufferSize, + prepend: buffer.length ? buffer[0].item : void 0, + count: bufferSize + }, success); + }; + + var initialize = function initialize() { + var tryCount = 0; + + if (!viewport.applyContainerStyle()) { + var timer = $interval(function () { + tryCount++; + + if (viewport.applyContainerStyle()) { + $interval.cancel(timer); + doAdjust(); + } + + if (tryCount * VIEWPORT_POLLING_INTERVAL >= MAX_VIEWPORT_DELAY) { + $interval.cancel(timer); + throw Error("ui-scroll directive requires a viewport with non-zero height in ".concat(MAX_VIEWPORT_DELAY, "ms")); + } + }, VIEWPORT_POLLING_INTERVAL); + } else { + doAdjust(); + } + }; + /** + * Build padding elements + * + * Calling linker is the only way I found to get access to the tag name of the template + * to prevent the directive scope from pollution a new scope is created and destroyed + * right after the builder creation is completed + */ + + + linker(function (clone, scope) { + viewport.createPaddingElements(clone[0]); // we do not include the clone in the DOM. It means that the nested directives will not + // be able to reach the parent directives, but in this case it is intentional because we + // created the clone to access the template tag name + + scope.$destroy(); + clone.remove(); + }); + $scope.$on('$destroy', function () { + unbindEvents(); + viewport.off('mousewheel', wheelHandler); + }); + viewport.on('mousewheel', wheelHandler); + initialize(); + /* Private function definitions */ + + function isInvalid(rid) { + return rid && rid !== ridActual || $scope.$$destroyed; + } + + function bindEvents() { + viewport.on('resize', resizeAndScrollHandler); + viewport.on('scroll', resizeAndScrollHandler); + } + + function unbindEvents() { + viewport.off('resize', resizeAndScrollHandler); + viewport.off('scroll', resizeAndScrollHandler); + } + + function reload() { + unbindEvents(); + viewport.resetTopPadding(); + viewport.resetBottomPadding(); + + if (arguments.length) { + startIndex = parseNumber(arguments[0], START_INDEX_DEFAULT, false); + } + + buffer.reset(startIndex); + persistDatasourceIndex(datasource, 'minIndex'); + persistDatasourceIndex(datasource, 'maxIndex'); + doAdjust(); + } + + function isElementVisible(wrapper) { + return wrapper.element.height() && wrapper.element[0].offsetParent; + } + + function visibilityWatcher(wrapper) { + if (isElementVisible(wrapper)) { + buffer.forEach(function (item) { + if (typeof item.unregisterVisibilityWatcher === 'function') { + item.unregisterVisibilityWatcher(); + delete item.unregisterVisibilityWatcher; + } + }); + + if (!pending.length) { + $timeout(function () { + return doAdjust(); + }); + } + } + } + + function insertWrapperContent(wrapper, insertAfter) { + createElement(wrapper, insertAfter, viewport.insertElement); + + if (!isElementVisible(wrapper)) { + wrapper.unregisterVisibilityWatcher = wrapper.scope.$watch(function () { + return visibilityWatcher(wrapper); + }); + } + + elementRoutines.hideElement(wrapper); // hide inserted elements before data binding + } + + function createElement(wrapper, insertAfter, insertElement) { + var promises = null; + var sibling = insertAfter > 0 ? buffer[insertAfter - 1].element : undefined; + linker(function (clone, scope) { + promises = insertElement(clone, sibling); + wrapper.element = clone; + wrapper.scope = scope; + scope[itemName] = wrapper.item; + }); // ui-scroll-grid apply + + if (adapter.transform) { + var tdInitializer = wrapper.scope.uiScrollTdInitializer; + + if (tdInitializer && tdInitializer.linking) { + adapter.transform(wrapper.scope, wrapper.element); + } else { + wrapper.scope.uiScrollTdInitializer = { + onLink: function onLink() { + return adapter.transform(wrapper.scope, wrapper.element); + }, + scope: wrapper.scope + }; + } + } + + return promises; + } + + function updateDOM() { + var promises = []; + var toBePrepended = []; + var toBeRemoved = []; + var inserted = []; + buffer.forEach(function (wrapper, i) { + switch (wrapper.op) { + case OPERATIONS.PREPEND: + toBePrepended.unshift(wrapper); + break; + + case OPERATIONS.APPEND: + insertWrapperContent(wrapper, i); + wrapper.op = OPERATIONS.NONE; + inserted.push(wrapper); + break; + + case OPERATIONS.INSERT: + promises = promises.concat(createElement(wrapper, i, viewport.insertElementAnimated)); + wrapper.op = OPERATIONS.NONE; + inserted.push(wrapper); + break; + + case OPERATIONS.REMOVE: + toBeRemoved.push(wrapper); + } + }); + toBeRemoved.forEach(function (wrapper) { + return promises = promises.concat(viewport.removeItem(wrapper)); + }); + if (toBePrepended.length) toBePrepended.forEach(function (wrapper) { + insertWrapperContent(wrapper); + wrapper.op = OPERATIONS.NONE; + }); + buffer.forEach(function (item, i) { + return item.scope.$index = buffer.first + i; + }); + return { + prepended: toBePrepended, + removed: toBeRemoved, + inserted: inserted, + animated: promises + }; + } + + function updatePaddings(rid, updates) { + // schedule another doAdjust after animation completion + if (updates.animated.length) { + $q.all(updates.animated).then(function () { + viewport.adjustPaddings(); + doAdjust(rid); + }); + } else { + viewport.adjustPaddings(); + } + } + + function enqueueFetch(rid, updates) { + if (viewport.shouldLoadBottom()) { + if (!updates || buffer.effectiveHeight(updates.inserted) > 0) { + // this means that at least one item appended in the last batch has height > 0 + if (pending.push(true) === 1) { + adapter.loading(true); + fetch(rid); + } + } + } else if (viewport.shouldLoadTop()) { + if (!updates || buffer.effectiveHeight(updates.prepended) > 0 || pending[0]) { + // this means that at least one item appended in the last batch has height > 0 + // pending[0] = true means that previous fetch was appending. We need to force at least one prepend + // BTW there will always be at least 1 element in the pending array because bottom is fetched first + if (pending.push(false) === 1) { + adapter.loading(true); + fetch(rid); + } + } + } + } + + function processUpdates() { + var updates = updateDOM(); // We need the item bindings to be processed before we can do adjustments + + !$scope.$$phase && !$rootScope.$$phase && $scope.$digest(); + updates.inserted.forEach(function (w) { + return elementRoutines.showElement(w); + }); + updates.prepended.forEach(function (w) { + return elementRoutines.showElement(w); + }); + return updates; + } + + function doAdjust(rid) { + if (!rid) { + // dismiss pending requests + pending = []; + rid = ++ridActual; + } + + var updates = processUpdates(); + + if (isInvalid(rid)) { + return; + } + + updatePaddings(rid, updates); + enqueueFetch(rid); + + if (!pending.length) { + adapter.calculateProperties(); + } + } + + function doAdjustAfterFetch(rid) { + var updates = processUpdates(); + viewport.onAfterPrepend(updates); + + if (isInvalid(rid)) { + return; + } + + updatePaddings(rid, updates); + onRenderHandlersRunner(); + enqueueFetch(rid, updates); + pending.shift(); + if (pending.length) fetch(rid);else { + adapter.loading(false); + bindEvents(); + adapter.calculateProperties(); + } + } + + function fetch(rid) { + if (pending[0]) { + // scrolling down + if (buffer.length && !viewport.shouldLoadBottom()) { + doAdjustAfterFetch(rid); + } else { + fetchNext(function (result) { + if (isInvalid(rid)) { + return; + } + + if (result.length < bufferSize) { + buffer.eof = true; + } + + if (result.length > 0) { + viewport.clipTop(); + buffer.append(result); + } + + doAdjustAfterFetch(rid); + }); + } + } else { + // scrolling up + if (buffer.length && !viewport.shouldLoadTop()) { + doAdjustAfterFetch(rid); + } else { + fetchPrevious(function (result) { + if (isInvalid(rid)) { + return; + } + + if (result.length < bufferSize) { + buffer.bof = true; // log 'bof is reached' + } + + if (result.length > 0) { + if (buffer.length) { + viewport.clipBottom(); + } + + buffer.prepend(result); + } + + doAdjustAfterFetch(rid); + }); + } + } + } + + function fixInertia() { + if (!viewport.synthetic) { + return; + } + + var oldPosition = viewport.synthetic.previous; + var newPosition = viewport.synthetic.next; + + if (viewport.scrollTop() !== newPosition) { + requestAnimationFrame(function () { + var position = viewport.scrollTop(); + var diff = oldPosition - position; + + if (diff > 0) { + // inertia over synthetic + viewport.scrollTop(newPosition - diff); + } else { + viewport.scrollTop(newPosition); + } + + viewport.synthetic = null; + }); + return true; + } + + viewport.synthetic = null; + } + + function resizeAndScrollHandler() { + if (handleInertia && fixInertia()) { + return; + } + + if (!$rootScope.$$phase && !adapter.isLoading && !adapter.disabled) { + enqueueFetch(ridActual); + + if (pending.length) { + unbindEvents(); + } else { + adapter.calculateProperties(); + !$scope.$$phase && $scope.$digest(); + } + } + } + + function wheelHandler(event) { + if (!adapter.disabled) { + var scrollTop = viewport[0].scrollTop; + var yMax = viewport[0].scrollHeight - viewport[0].clientHeight; + + if (scrollTop === 0 && !buffer.bof || scrollTop === yMax && !buffer.eof) { + event.preventDefault(); + } + } + } + } +}]); + +/***/ }) +/******/ ]); +//# sourceMappingURL=ui-scroll.js.map \ No newline at end of file diff --git a/dist/ui-scroll.js.map b/dist/ui-scroll.js.map new file mode 100644 index 00000000..fdde1b94 --- /dev/null +++ b/dist/ui-scroll.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/modules/jqLiteExtras.js","webpack:///./src/modules/elementRoutines.js","webpack:///./src/modules/utils.js","webpack:///./src/modules/buffer.js","webpack:///./src/modules/padding.js","webpack:///./src/modules/viewport.js","webpack:///./src/modules/adapter.js","webpack:///./src/ui-scroll.js"],"names":["JQLiteExtras","element","convertToPx","css","getStyle","isWindow","angular","prototype","name","value","self","elem","nodeType","style","call","obj","document","location","alert","setInterval","scrollTo","direction","top","left","method","prop","preserve","isValueDefined","documentElement","window","getComputedStyle","parseFloat","currentStyle","result","rs","rsLeft","core_pnum","source","rnumnonpx","RegExp","test","runtimeStyle","pixelLeft","getMeasurements","measure","base","borderA","borderB","computedMarginA","computedMarginB","computedStyle","dirA","dirB","marginA","marginB","paddingA","paddingB","height","width","padding","border","margin","offsetWidth","offsetHeight","getWidthHeight","measurements","outer","outerfull","forEach","before","newElem","children","i","j","parent","ref","contents","prepend","length","after","Error","outerHTML","isNumber","outerHeight","option","outerWidth","offset","docElem","win","box","doc","ownerDocument","arguments","undefined","getBoundingClientRect","defaultView","parentWindow","pageYOffset","scrollTop","clientTop","pageXOffset","scrollLeft","clientLeft","key","hideClassToken","ElementRoutines","selector","rules","sheet","styleSheets","index","cssRules","err","insertRule","addRule","$injector","$q","$animate","has","get","isAngularVersionLessThen1_3","version","major","minor","wrapper","addClass","removeClass","newElement","previousElement","remove","scope","$destroy","insertElement","deferred","defer","enter","resolve","promise","removeElement","leave","then","OPERATIONS","PREPEND","APPEND","INSERT","REMOVE","NONE","ScrollBuffer","elementRoutines","bufferSize","startIndex","buffer","Object","create","Array","extend","size","reset","eof","bof","first","next","minIndex","maxIndex","minIndexUser","maxIndexUser","append","items","item","insert","Math","max","immutableTop","reverse","min","operation","shiftTop","op","splice","push","unshift","arg1","arg2","indexOf","getAbsMinIndex","incrementMinIndex","decrementMaxIndex","removeElementAnimated","getAbsMaxIndex","effectiveHeight","elements","Number","MAX_VALUE","bottom","NEGATIVE_INFINITY","offsetParent","getItems","filter","getFirstItem","list","getLastItem","CacheProto","$index","sort","a","b","argument","_shiftTop","Cache","instance","apply","setPrototypeOf","getOwnPropertyNames","methodName","generateElement","template","Node","ELEMENT_NODE","tagName","toLowerCase","table","find","Padding","cache","Viewport","viewportController","$rootScope","topPadding","bottomPadding","viewport","container","bufferPadding","getScope","createPaddingElements","applyContainerStyle","bottomDataPos","scrollHeight","topDataPos","bottomVisiblePos","topVisiblePos","e","sibling","insertElementAnimated","shouldLoadBottom","clipBottom","overage","overageHeight","itemHeight","emptySpaceHeight","add","adjustPaddings","shouldLoadTop","clipTop","visibleItemsHeight","reduce","summ","topPaddingHeight","topCount","bottomPaddingHeight","bottomCount","totalHeight","averageItemHeight","adjustTopPadding","adjustBottomPadding","topPaddingHeightAdd","bottomPaddingHeightAdd","onAfterMinIndexSet","topPaddingHeightOld","diff","onAfterPrepend","updates","prepended","paddingHeight","position","newPosition","synthetic","previous","resetTopPadding","clear","resetBottomPadding","removeCacheItem","removeItem","Adapter","$scope","$parse","$attr","doAdjust","reload","isLoading","disabled","viewportScope","startScope","$parent","publicContext","assignAdapter","adapter","generatePublicContext","adapterAttr","replace","adapterOnScope","assign","error","message","publicMethods","bind","publicProps","property","attr","defineProperty","set","publicPropsImmediate","newItems","options","arg3","applyUpdatesFunc","applyUpdatesIndex","cb","slice","applyUpdate","_index","isArray","some","newItem","rowTop","topHeight","topDone","bottomDone","itemTop","isEOF","module","constant","run","elt","jQuery","fn","jquery","registerFor","addCSSRules","directive","restrict","controller","child","console","$timeout","$interval","require","transclude","priority","terminal","link","controllers","linker","match","uiScroll","parseNumber","defaultValue","isFloat","floor","isNaN","parseNumericAttr","parseBooleanAttr","BUFFER_MIN","BUFFER_DEFAULT","PADDING_MIN","PADDING_DEFAULT","HANDLE_INERTIA_DEFAULT","START_INDEX_DEFAULT","MAX_VIEWPORT_DELAY","VIEWPORT_POLLING_INTERVAL","datasource","itemName","datasourceName","handleInertia","ridActual","pending","isDatasourceValid","toString","onRenderHandlers","onRenderHandlersRunner","handler","persistDatasourceIndex","propName","getter","id","defineDatasourceIndex","propUserName","descriptor","getOwnPropertyDescriptor","fetchNext","success","count","fetchPrevious","initialize","tryCount","timer","cancel","clone","$on","unbindEvents","off","wheelHandler","on","isInvalid","rid","$$destroyed","bindEvents","resizeAndScrollHandler","isElementVisible","visibilityWatcher","unregisterVisibilityWatcher","insertWrapperContent","insertAfter","createElement","$watch","hideElement","promises","transform","tdInitializer","uiScrollTdInitializer","linking","onLink","updateDOM","toBePrepended","toBeRemoved","inserted","concat","removed","animated","updatePaddings","all","enqueueFetch","loading","fetch","processUpdates","$$phase","$digest","w","showElement","calculateProperties","doAdjustAfterFetch","shift","fixInertia","oldPosition","requestAnimationFrame","event","yMax","clientHeight","preventDefault"],"mappings":"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","file":"ui-scroll.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n","/*!\r\n globals: angular, window\r\n List of used element methods available in JQuery but not in JQuery Lite\r\n element.before(elem)\r\n element.height()\r\n element.outerHeight(true)\r\n element.height(value) = only for Top/Bottom padding elements\r\n element.scrollTop()\r\n element.scrollTop(value)\r\n */\r\n\r\nexport default class JQLiteExtras {\r\n\r\n registerFor(element) {\r\n let convertToPx, css, getStyle, isWindow;\r\n // angular implementation blows up if elem is the window\r\n css = angular.element.prototype.css;\r\n\r\n element.prototype.css = function (name, value) {\r\n let self = this;\r\n let elem = self[0];\r\n if (!(!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style)) {\r\n return css.call(self, name, value);\r\n }\r\n };\r\n\r\n // as defined in angularjs v1.0.5\r\n isWindow = (obj) => obj && obj.document && obj.location && obj.alert && obj.setInterval;\r\n\r\n function scrollTo(self, direction, value) {\r\n let elem = self[0];\r\n let [method, prop, preserve] = {\r\n top: [\r\n 'scrollTop',\r\n 'pageYOffset',\r\n 'scrollLeft'\r\n ],\r\n left: [\r\n 'scrollLeft',\r\n 'pageXOffset',\r\n 'scrollTop'\r\n ]\r\n }[direction];\r\n\r\n const isValueDefined = typeof value !== 'undefined';\r\n if (isWindow(elem)) {\r\n if (isValueDefined) {\r\n return elem.scrollTo(self[preserve].call(self), value);\r\n }\r\n return (prop in elem) ? elem[prop] : elem.document.documentElement[method];\r\n } else {\r\n if (isValueDefined) {\r\n elem[method] = value;\r\n }\r\n return elem[method];\r\n }\r\n }\r\n\r\n if (window.getComputedStyle) {\r\n getStyle = (elem) => window.getComputedStyle(elem, null);\r\n convertToPx = (elem, value) => parseFloat(value);\r\n } else {\r\n getStyle = (elem) => elem.currentStyle;\r\n convertToPx = (elem, value) => {\r\n let left, result, rs, rsLeft, style;\r\n let core_pnum = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source;\r\n let rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i');\r\n\r\n if (!rnumnonpx.test(value)) {\r\n return parseFloat(value);\r\n }\r\n\r\n // ported from JQuery\r\n style = elem.style;\r\n left = style.left;\r\n rs = elem.runtimeStyle;\r\n rsLeft = rs && rs.left;\r\n if (rs) {\r\n rs.left = style.left;\r\n }\r\n // put in the new values to get a computed style out\r\n style.left = value;\r\n result = style.pixelLeft;\r\n style.left = left;\r\n if (rsLeft) {\r\n rs.left = rsLeft;\r\n }\r\n return result;\r\n };\r\n }\r\n\r\n function getMeasurements(elem, measure) {\r\n let base, borderA, borderB, computedMarginA, computedMarginB, computedStyle, dirA, dirB, marginA, marginB, paddingA, paddingB;\r\n\r\n if (isWindow(elem)) {\r\n base = document.documentElement[{height: 'clientHeight', width: 'clientWidth'}[measure]];\r\n\r\n return {\r\n base: base,\r\n padding: 0,\r\n border: 0,\r\n margin: 0\r\n };\r\n }\r\n\r\n // Start with offset property\r\n [\r\n base,\r\n dirA,\r\n dirB\r\n ] = {\r\n width: [\r\n elem.offsetWidth,\r\n 'Left',\r\n 'Right'\r\n ],\r\n height: [\r\n elem.offsetHeight,\r\n 'Top',\r\n 'Bottom'\r\n ]\r\n }[measure];\r\n\r\n computedStyle = getStyle(elem);\r\n paddingA = convertToPx(elem, computedStyle['padding' + dirA]) || 0;\r\n paddingB = convertToPx(elem, computedStyle['padding' + dirB]) || 0;\r\n borderA = convertToPx(elem, computedStyle['border' + dirA + 'Width']) || 0;\r\n borderB = convertToPx(elem, computedStyle['border' + dirB + 'Width']) || 0;\r\n computedMarginA = computedStyle['margin' + dirA];\r\n computedMarginB = computedStyle['margin' + dirB];\r\n\r\n // I do not care for width for now, so this hack is irrelevant\r\n // if ( !supportsPercentMargin )\r\n // computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA )\r\n // computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB )\r\n marginA = convertToPx(elem, computedMarginA) || 0;\r\n marginB = convertToPx(elem, computedMarginB) || 0;\r\n\r\n return {\r\n base: base,\r\n padding: paddingA + paddingB,\r\n border: borderA + borderB,\r\n margin: marginA + marginB\r\n };\r\n }\r\n\r\n function getWidthHeight(elem, direction, measure) {\r\n let computedStyle, result;\r\n\r\n let measurements = getMeasurements(elem, direction);\r\n\r\n if (measurements.base > 0) {\r\n return {\r\n base: measurements.base - measurements.padding - measurements.border,\r\n outer: measurements.base,\r\n outerfull: measurements.base + measurements.margin\r\n }[measure];\r\n }\r\n\r\n // Fall back to computed then uncomputed css if necessary\r\n computedStyle = getStyle(elem);\r\n result = computedStyle[direction];\r\n\r\n if (result < 0 || result === null) {\r\n result = elem.style[direction] || 0;\r\n }\r\n\r\n // Normalize \"\", auto, and prepare for extra\r\n result = parseFloat(result) || 0;\r\n\r\n return {\r\n base: result - measurements.padding - measurements.border,\r\n outer: result,\r\n outerfull: result + measurements.padding + measurements.border + measurements.margin\r\n }[measure];\r\n }\r\n\r\n // define missing methods\r\n return angular.forEach({\r\n before(newElem) {\r\n var children, elem, i, j, parent, ref, self;\r\n self = this;\r\n elem = self[0];\r\n parent = self.parent();\r\n children = parent.contents();\r\n if (children[0] === elem) {\r\n return parent.prepend(newElem);\r\n } else {\r\n for (i = j = 1, ref = children.length - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) {\r\n if (children[i] === elem) {\r\n angular.element(children[i - 1]).after(newElem);\r\n return;\r\n }\r\n }\r\n throw new Error('invalid DOM structure ' + elem.outerHTML);\r\n }\r\n },\r\n height (value){\r\n var self;\r\n self = this;\r\n if (typeof value !== 'undefined') {\r\n if (angular.isNumber(value)) {\r\n value = value + 'px';\r\n }\r\n return css.call(self, 'height', value);\r\n } else {\r\n return getWidthHeight(this[0], 'height', 'base');\r\n }\r\n },\r\n outerHeight(option) {\r\n return getWidthHeight(this[0], 'height', option ? 'outerfull' : 'outer');\r\n },\r\n outerWidth(option) {\r\n return getWidthHeight(this[0], 'width', option ? 'outerfull' : 'outer');\r\n },\r\n\r\n /*\r\n The offset setter method is not implemented\r\n */\r\n offset(value) {\r\n let docElem, win;\r\n let self = this;\r\n let box = {\r\n top: 0,\r\n left: 0\r\n };\r\n let elem = self[0];\r\n let doc = elem && elem.ownerDocument;\r\n\r\n if (arguments.length) {\r\n if (value === undefined) {\r\n return self;\r\n }\r\n // TODO: implement setter\r\n throw new Error('offset setter method is not implemented');\r\n }\r\n\r\n if (!doc) {\r\n return;\r\n }\r\n\r\n docElem = doc.documentElement;\r\n\r\n // TODO: Make sure it's not a disconnected DOM node\r\n\r\n if (elem.getBoundingClientRect != null) {\r\n box = elem.getBoundingClientRect();\r\n }\r\n\r\n win = doc.defaultView || doc.parentWindow;\r\n\r\n return {\r\n top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),\r\n left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)\r\n };\r\n },\r\n scrollTop(value) {\r\n return scrollTo(this, 'top', value);\r\n },\r\n scrollLeft(value) {\r\n return scrollTo(this, 'left', value);\r\n }\r\n }, (value, key) => {\r\n if (!element.prototype[key]) {\r\n return element.prototype[key] = value;\r\n }\r\n });\r\n }\r\n\r\n}\r\n","const hideClassToken = 'ng-ui-scroll-hide';\r\n\r\nexport default class ElementRoutines {\r\n\r\n static addCSSRules() {\r\n const selector = '.' + hideClassToken;\r\n const rules = 'display: none';\r\n const sheet = document.styleSheets[0];\r\n let index;\r\n try {\r\n index = sheet.cssRules.length;\r\n } catch (err) {\r\n index = 0;\r\n }\r\n if('insertRule' in sheet) {\r\n sheet.insertRule(selector + '{' + rules + '}', index);\r\n }\r\n else if('addRule' in sheet) {\r\n sheet.addRule(selector, rules, index);\r\n }\r\n }\r\n\r\n constructor($injector, $q) {\r\n this.$animate = ($injector.has && $injector.has('$animate')) ? $injector.get('$animate') : null;\r\n this.isAngularVersionLessThen1_3 = angular.version.major === 1 && angular.version.minor < 3;\r\n this.$q = $q;\r\n }\r\n\r\n hideElement(wrapper) {\r\n wrapper.element.addClass(hideClassToken);\r\n }\r\n\r\n showElement(wrapper) {\r\n wrapper.element.removeClass(hideClassToken);\r\n }\r\n\r\n insertElement(newElement, previousElement) {\r\n previousElement.after(newElement);\r\n return [];\r\n }\r\n\r\n removeElement(wrapper) {\r\n wrapper.element.remove();\r\n wrapper.scope.$destroy();\r\n return [];\r\n }\r\n\r\n insertElementAnimated(newElement, previousElement) {\r\n if (!this.$animate) {\r\n return this.insertElement(newElement, previousElement);\r\n }\r\n\r\n if (this.isAngularVersionLessThen1_3) {\r\n const deferred = this.$q.defer();\r\n // no need for parent - previous element is never null\r\n this.$animate.enter(newElement, null, previousElement, () => deferred.resolve());\r\n\r\n return [deferred.promise];\r\n }\r\n\r\n // no need for parent - previous element is never null\r\n return [this.$animate.enter(newElement, null, previousElement)];\r\n }\r\n\r\n removeElementAnimated(wrapper) {\r\n if (!this.$animate) {\r\n return this.removeElement(wrapper);\r\n }\r\n\r\n if (this.isAngularVersionLessThen1_3) {\r\n const deferred = this.$q.defer();\r\n this.$animate.leave(wrapper.element, () => {\r\n wrapper.scope.$destroy();\r\n return deferred.resolve();\r\n });\r\n\r\n return [deferred.promise];\r\n }\r\n\r\n return [(this.$animate.leave(wrapper.element)).then(() => wrapper.scope.$destroy())];\r\n }\r\n}","export const OPERATIONS = {\n PREPEND: 'prepend',\n APPEND: 'append',\n INSERT: 'insert',\n REMOVE: 'remove',\n NONE: 'none'\n};\n","import { OPERATIONS } from './utils';\r\n\r\nexport default function ScrollBuffer(elementRoutines, bufferSize, startIndex) {\r\n const buffer = Object.create(Array.prototype);\r\n\r\n angular.extend(buffer, {\r\n size: bufferSize,\r\n\r\n reset(startIndex) {\r\n buffer.remove(0, buffer.length);\r\n buffer.eof = false;\r\n buffer.bof = false;\r\n buffer.first = startIndex;\r\n buffer.next = startIndex;\r\n buffer.minIndex = startIndex;\r\n buffer.maxIndex = startIndex;\r\n buffer.minIndexUser = null;\r\n buffer.maxIndexUser = null;\r\n },\r\n\r\n append(items) {\r\n items.forEach((item) => {\r\n ++buffer.next;\r\n buffer.insert(OPERATIONS.APPEND, item);\r\n });\r\n buffer.maxIndex = buffer.eof ? buffer.next - 1 : Math.max(buffer.next - 1, buffer.maxIndex);\r\n },\r\n\r\n prepend(items, immutableTop) {\r\n items.reverse().forEach((item) => {\r\n if (immutableTop) {\r\n ++buffer.next;\r\n }\r\n else {\r\n --buffer.first;\r\n }\r\n buffer.insert(OPERATIONS.PREPEND, item);\r\n });\r\n buffer.minIndex = buffer.bof ? buffer.minIndex = buffer.first : Math.min(buffer.first, buffer.minIndex);\r\n },\r\n\r\n /**\r\n * inserts wrapped element in the buffer\r\n * the first argument is either operation keyword (see below) or a number for operation 'insert'\r\n * for insert the number is the index for the buffer element the new one have to be inserted after\r\n * operations: 'append', 'prepend', 'insert', 'remove', 'none'\r\n */\r\n insert(operation, item, shiftTop) {\r\n const wrapper = {\r\n item: item\r\n };\r\n\r\n if (operation % 1 === 0) { // it is an insert\r\n wrapper.op = OPERATIONS.INSERT;\r\n buffer.splice(operation, 0, wrapper);\r\n if (shiftTop) {\r\n buffer.first--;\r\n }\r\n else {\r\n buffer.next++;\r\n }\r\n } else {\r\n wrapper.op = operation;\r\n switch (operation) {\r\n case OPERATIONS.APPEND:\r\n buffer.push(wrapper);\r\n break;\r\n case OPERATIONS.PREPEND:\r\n buffer.unshift(wrapper);\r\n break;\r\n }\r\n }\r\n },\r\n\r\n // removes elements from buffer\r\n remove(arg1, arg2) {\r\n if (angular.isNumber(arg1)) {\r\n // removes items from arg1 (including) through arg2 (excluding)\r\n for (let i = arg1; i < arg2; i++) {\r\n elementRoutines.removeElement(buffer[i]);\r\n }\r\n return buffer.splice(arg1, arg2 - arg1);\r\n }\r\n // removes single item (wrapper) from the buffer\r\n buffer.splice(buffer.indexOf(arg1), 1);\r\n if (arg1.shiftTop && buffer.first === this.getAbsMinIndex()) {\r\n this.incrementMinIndex();\r\n }\r\n else {\r\n this.decrementMaxIndex();\r\n }\r\n if (arg1.shiftTop) {\r\n buffer.first++;\r\n }\r\n else {\r\n buffer.next--;\r\n }\r\n if (!buffer.length) {\r\n buffer.minIndex = Math.min(buffer.maxIndex, buffer.minIndex);\r\n }\r\n\r\n return elementRoutines.removeElementAnimated(arg1);\r\n },\r\n\r\n incrementMinIndex() {\r\n if (buffer.minIndexUser !== null) {\r\n if (buffer.minIndex > buffer.minIndexUser) {\r\n buffer.minIndexUser++;\r\n return;\r\n }\r\n if (buffer.minIndex === buffer.minIndexUser) {\r\n buffer.minIndexUser++;\r\n }\r\n }\r\n buffer.minIndex++;\r\n },\r\n\r\n decrementMaxIndex() {\r\n if (buffer.maxIndexUser !== null && buffer.maxIndex <= buffer.maxIndexUser) {\r\n buffer.maxIndexUser--;\r\n }\r\n buffer.maxIndex--;\r\n },\r\n\r\n getAbsMinIndex() {\r\n if (buffer.minIndexUser !== null) {\r\n return Math.min(buffer.minIndexUser, buffer.minIndex);\r\n }\r\n return buffer.minIndex;\r\n },\r\n\r\n getAbsMaxIndex() {\r\n if (buffer.maxIndexUser !== null) {\r\n return Math.max(buffer.maxIndexUser, buffer.maxIndex);\r\n }\r\n return buffer.maxIndex;\r\n },\r\n\r\n effectiveHeight(elements) {\r\n if (!elements.length) {\r\n return 0;\r\n }\r\n let top = Number.MAX_VALUE;\r\n let bottom = Number.NEGATIVE_INFINITY;\r\n elements.forEach((wrapper) => {\r\n if (wrapper.element[0].offsetParent) {\r\n // element style is not display:none\r\n top = Math.min(top, wrapper.element.offset().top);\r\n bottom = Math.max(bottom, wrapper.element.offset().top + wrapper.element.outerHeight(true));\r\n }\r\n });\r\n return Math.max(0, bottom - top);\r\n },\r\n\r\n getItems() {\r\n return buffer.filter(item => item.op === OPERATIONS.NONE);\r\n },\r\n\r\n getFirstItem() {\r\n const list = buffer.getItems();\r\n if (!list.length) {\r\n return null;\r\n }\r\n return list[0].item;\r\n },\r\n\r\n getLastItem() {\r\n const list = buffer.getItems();\r\n if (!list.length) {\r\n return null;\r\n }\r\n return list[list.length - 1].item;\r\n }\r\n\r\n });\r\n\r\n buffer.reset(startIndex);\r\n\r\n return buffer;\r\n}\r\n","// Can't just extend the Array, due to Babel does not support built-in classes extending\r\n// This solution was taken from https://stackoverflow.com/questions/46897414/es6-class-extends-array-workaround-for-es5-babel-transpile\r\nclass CacheProto {\r\n add(item) {\r\n for (let i = this.length - 1; i >= 0; i--) {\r\n if (this[i].index === item.scope.$index) {\r\n this[i].height = item.element.outerHeight();\r\n return;\r\n }\r\n }\r\n this.push({\r\n index: item.scope.$index,\r\n height: item.element.outerHeight()\r\n });\r\n this.sort((a, b) => ((a.index < b.index) ? -1 : ((a.index > b.index) ? 1 : 0)));\r\n }\r\n\r\n remove(argument, _shiftTop) {\r\n const index = argument % 1 === 0 ? argument : argument.scope.$index;\r\n const shiftTop = argument % 1 === 0 ? _shiftTop : argument.shiftTop;\r\n for (let i = this.length - 1; i >= 0; i--) {\r\n if (this[i].index === index) {\r\n this.splice(i, 1);\r\n break;\r\n }\r\n }\r\n if (!shiftTop) {\r\n for (let i = this.length - 1; i >= 0; i--) {\r\n if (this[i].index > index) {\r\n this[i].index--;\r\n }\r\n }\r\n }\r\n }\r\n\r\n clear() {\r\n this.length = 0;\r\n }\r\n}\r\n\r\nfunction Cache() {\r\n const instance = [];\r\n instance.push.apply(instance, arguments);\r\n Object.setPrototypeOf(instance, Cache.prototype);\r\n return instance;\r\n}\r\nCache.prototype = Object.create(Array.prototype);\r\nObject.getOwnPropertyNames(CacheProto.prototype).forEach(methodName =>\r\n Cache.prototype[methodName] = CacheProto.prototype[methodName]\r\n);\r\n\r\nfunction generateElement(template) {\r\n if (template.nodeType !== Node.ELEMENT_NODE) {\r\n throw new Error('ui-scroll directive requires an Element node for templating the view');\r\n }\r\n let element;\r\n switch (template.tagName.toLowerCase()) {\r\n case 'dl':\r\n throw new Error(`ui-scroll directive does not support <${template.tagName}> as a repeating tag: ${template.outerHTML}`);\r\n case 'tr':\r\n let table = angular.element('
    ');\r\n element = table.find('tr');\r\n break;\r\n case 'li':\r\n element = angular.element('
  • ');\r\n break;\r\n default:\r\n element = angular.element('
    ');\r\n }\r\n return element;\r\n}\r\n\r\nclass Padding {\r\n constructor(template) {\r\n this.element = generateElement(template);\r\n this.cache = new Cache();\r\n }\r\n\r\n height() {\r\n return this.element.height.apply(this.element, arguments);\r\n }\r\n}\r\n\r\nexport default Padding;","import Padding from './padding';\r\n\r\nexport default function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding) {\r\n let topPadding = null;\r\n let bottomPadding = null;\r\n const viewport = viewportController && viewportController.viewport ? viewportController.viewport : angular.element(window);\r\n const container = viewportController && viewportController.container ? viewportController.container : undefined;\r\n const scope = viewportController && viewportController.scope ? viewportController.scope : $rootScope;\r\n\r\n viewport.css({\r\n 'overflow-anchor': 'none',\r\n 'overflow-y': 'auto',\r\n 'display': 'block'\r\n });\r\n\r\n function bufferPadding() {\r\n return viewport.outerHeight() * padding; // some extra space to initiate preload\r\n }\r\n\r\n angular.extend(viewport, {\r\n getScope() {\r\n return scope;\r\n },\r\n\r\n createPaddingElements(template) {\r\n topPadding = new Padding(template);\r\n bottomPadding = new Padding(template);\r\n element.before(topPadding.element);\r\n element.after(bottomPadding.element);\r\n topPadding.height(0);\r\n bottomPadding.height(0);\r\n },\r\n\r\n applyContainerStyle() {\r\n if (!container) {\r\n return true;\r\n }\r\n if (container !== viewport) {\r\n viewport.css('height', window.getComputedStyle(container[0]).height);\r\n }\r\n return viewport.height() > 0;\r\n },\r\n\r\n bottomDataPos() {\r\n let scrollHeight = viewport[0].scrollHeight;\r\n scrollHeight = scrollHeight != null ? scrollHeight : viewport[0].document.documentElement.scrollHeight;\r\n return scrollHeight - bottomPadding.height();\r\n },\r\n\r\n topDataPos() {\r\n return topPadding.height();\r\n },\r\n\r\n bottomVisiblePos() {\r\n return viewport.scrollTop() + viewport.outerHeight();\r\n },\r\n\r\n topVisiblePos() {\r\n return viewport.scrollTop();\r\n },\r\n\r\n insertElement(e, sibling) {\r\n return elementRoutines.insertElement(e, sibling || topPadding.element);\r\n },\r\n\r\n insertElementAnimated(e, sibling) {\r\n return elementRoutines.insertElementAnimated(e, sibling || topPadding.element);\r\n },\r\n\r\n shouldLoadBottom() {\r\n return !buffer.eof && viewport.bottomDataPos() < viewport.bottomVisiblePos() + bufferPadding();\r\n },\r\n\r\n clipBottom() {\r\n // clip the invisible items off the bottom\r\n let overage = 0;\r\n let overageHeight = 0;\r\n let itemHeight = 0;\r\n let emptySpaceHeight = viewport.bottomDataPos() - viewport.bottomVisiblePos() - bufferPadding();\r\n\r\n for (let i = buffer.length - 1; i >= 0; i--) {\r\n itemHeight = buffer[i].element.outerHeight(true);\r\n if (overageHeight + itemHeight > emptySpaceHeight) {\r\n break;\r\n }\r\n bottomPadding.cache.add(buffer[i]);\r\n overageHeight += itemHeight;\r\n overage++;\r\n }\r\n\r\n if (overage > 0) {\r\n buffer.eof = false;\r\n buffer.remove(buffer.length - overage, buffer.length);\r\n buffer.next -= overage;\r\n viewport.adjustPaddings();\r\n }\r\n },\r\n\r\n shouldLoadTop() {\r\n return !buffer.bof && (viewport.topDataPos() > viewport.topVisiblePos() - bufferPadding());\r\n },\r\n\r\n clipTop() {\r\n // clip the invisible items off the top\r\n let overage = 0;\r\n let overageHeight = 0;\r\n let itemHeight = 0;\r\n let emptySpaceHeight = viewport.topVisiblePos() - viewport.topDataPos() - bufferPadding();\r\n\r\n for (let i = 0; i < buffer.length; i++) {\r\n itemHeight = buffer[i].element.outerHeight(true);\r\n if (overageHeight + itemHeight > emptySpaceHeight) {\r\n break;\r\n }\r\n topPadding.cache.add(buffer[i]);\r\n overageHeight += itemHeight;\r\n overage++;\r\n }\r\n\r\n if (overage > 0) {\r\n // we need to adjust top padding element before items are removed from top\r\n // to avoid strange behaviour of scroll bar during remove top items when we are at the very bottom\r\n topPadding.height(topPadding.height() + overageHeight);\r\n buffer.bof = false;\r\n buffer.remove(0, overage);\r\n buffer.first += overage;\r\n }\r\n },\r\n\r\n adjustPaddings() {\r\n if (!buffer.length) {\r\n return;\r\n }\r\n\r\n // precise heights calculation based on items that are in buffer or that were in buffer once\r\n const visibleItemsHeight = buffer.reduce((summ, item) => summ + item.element.outerHeight(true), 0);\r\n\r\n let topPaddingHeight = 0, topCount = 0;\r\n topPadding.cache.forEach(item => {\r\n if (item.index < buffer.first) {\r\n topPaddingHeight += item.height;\r\n topCount++;\r\n }\r\n });\r\n\r\n let bottomPaddingHeight = 0, bottomCount = 0;\r\n bottomPadding.cache.forEach(item => {\r\n if (item.index >= buffer.next) {\r\n bottomPaddingHeight += item.height;\r\n bottomCount++;\r\n }\r\n });\r\n\r\n const totalHeight = visibleItemsHeight + topPaddingHeight + bottomPaddingHeight;\r\n const averageItemHeight = totalHeight / (topCount + bottomCount + buffer.length);\r\n\r\n // average heights calculation, items that have never been reached\r\n let adjustTopPadding = buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser;\r\n let adjustBottomPadding = buffer.maxIndexUser !== null && buffer.maxIndex < buffer.maxIndexUser;\r\n let topPaddingHeightAdd = adjustTopPadding ? (buffer.minIndex - buffer.minIndexUser) * averageItemHeight : 0;\r\n let bottomPaddingHeightAdd = adjustBottomPadding ? (buffer.maxIndexUser - buffer.maxIndex) * averageItemHeight : 0;\r\n\r\n // paddings combine adjustment\r\n topPadding.height(topPaddingHeight + topPaddingHeightAdd);\r\n bottomPadding.height(bottomPaddingHeight + bottomPaddingHeightAdd);\r\n },\r\n\r\n onAfterMinIndexSet(topPaddingHeightOld) {\r\n // additional scrollTop adjustment in case of datasource.minIndex external set\r\n if (buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser) {\r\n let diff = topPadding.height() - topPaddingHeightOld;\r\n viewport.scrollTop(viewport.scrollTop() + diff);\r\n while((diff -= viewport.scrollTop()) > 0) {\r\n bottomPadding.height(bottomPadding.height() + diff);\r\n viewport.scrollTop(viewport.scrollTop() + diff);\r\n }\r\n }\r\n },\r\n\r\n onAfterPrepend(updates) {\r\n if (!updates.prepended.length) {\r\n return;\r\n }\r\n const height = buffer.effectiveHeight(updates.prepended);\r\n const paddingHeight = topPadding.height() - height;\r\n if (paddingHeight >= 0) {\r\n topPadding.height(paddingHeight);\r\n return;\r\n }\r\n const position = viewport.scrollTop();\r\n const newPosition = position - paddingHeight;\r\n viewport.synthetic = { previous: position, next: newPosition };\r\n topPadding.height(0);\r\n viewport.scrollTop(newPosition);\r\n },\r\n\r\n resetTopPadding() {\r\n topPadding.height(0);\r\n topPadding.cache.clear();\r\n },\r\n\r\n resetBottomPadding() {\r\n bottomPadding.height(0);\r\n bottomPadding.cache.clear();\r\n },\r\n\r\n removeCacheItem(item, shiftTop) {\r\n topPadding.cache.remove(item, shiftTop);\r\n bottomPadding.cache.remove(item, shiftTop);\r\n },\r\n\r\n removeItem(item) {\r\n this.removeCacheItem(item);\r\n return buffer.remove(item);\r\n }\r\n });\r\n\r\n return viewport;\r\n}\r\n","import { OPERATIONS } from './utils';\r\n\r\nclass Adapter {\r\n\r\n constructor($scope, $parse, $attr, viewport, buffer, doAdjust, reload) {\r\n this.$parse = $parse;\r\n this.$attr = $attr;\r\n this.viewport = viewport;\r\n this.buffer = buffer;\r\n\r\n this.doAdjust = doAdjust;\r\n this.reload = reload;\r\n\r\n this.isLoading = false;\r\n this.disabled = false;\r\n\r\n const viewportScope = viewport.getScope();\r\n this.startScope = viewportScope.$parent ? viewportScope : $scope;\r\n\r\n this.publicContext = {};\r\n this.assignAdapter($attr.adapter);\r\n this.generatePublicContext();\r\n }\r\n\r\n assignAdapter(adapterAttr) {\r\n if (!adapterAttr || !(adapterAttr = adapterAttr.replace(/^\\s+|\\s+$/gm, ''))) {\r\n return;\r\n }\r\n let adapterOnScope;\r\n\r\n try {\r\n this.$parse(adapterAttr).assign(this.startScope, {});\r\n adapterOnScope = this.$parse(adapterAttr)(this.startScope);\r\n }\r\n catch (error) {\r\n error.message = `Angular ui-scroll Adapter assignment exception.\\n` +\r\n `Can't parse \"${adapterAttr}\" expression.\\n` +\r\n error.message;\r\n throw error;\r\n }\r\n\r\n angular.extend(adapterOnScope, this.publicContext);\r\n this.publicContext = adapterOnScope;\r\n }\r\n\r\n generatePublicContext() {\r\n // these methods will be accessible out of ui-scroll via user defined adapter\r\n const publicMethods = ['reload', 'applyUpdates', 'append', 'prepend', 'isBOF', 'isEOF', 'isEmpty'];\r\n for (let i = publicMethods.length - 1; i >= 0; i--) {\r\n this.publicContext[publicMethods[i]] = this[publicMethods[i]].bind(this);\r\n }\r\n\r\n // these read-only props will be accessible out of ui-scroll via user defined adapter\r\n const publicProps = ['isLoading', 'topVisible', 'topVisibleElement', 'topVisibleScope', 'bottomVisible', 'bottomVisibleElement', 'bottomVisibleScope'];\r\n for (let i = publicProps.length - 1; i >= 0; i--) {\r\n let property, attr = this.$attr[publicProps[i]];\r\n Object.defineProperty(this, publicProps[i], {\r\n get: () => property,\r\n set: (value) => {\r\n property = value;\r\n this.publicContext[publicProps[i]] = value;\r\n if (attr) {\r\n this.$parse(attr).assign(this.startScope, value);\r\n }\r\n }\r\n });\r\n }\r\n\r\n // read-only immediately calculated public properties\r\n const publicPropsImmediate = ['bufferFirst', 'bufferLast', 'bufferLength'];\r\n for (let i = publicPropsImmediate.length - 1; i >= 0; i--) {\r\n Object.defineProperty(this.publicContext, publicPropsImmediate[i], {\r\n get: () => this[publicPropsImmediate[i]]\r\n });\r\n }\r\n\r\n // non-read-only public property\r\n Object.defineProperty(this.publicContext, 'disabled', {\r\n get: () => this.disabled,\r\n set: (value) => (!(this.disabled = value)) ? this.doAdjust() : null\r\n });\r\n }\r\n\r\n loading(value) {\r\n this.isLoading = value;\r\n }\r\n\r\n isBOF() {\r\n return this.buffer.bof;\r\n }\r\n\r\n isEOF() {\r\n return this.buffer.eof;\r\n }\r\n\r\n isEmpty() {\r\n return !this.buffer.length;\r\n }\r\n\r\n get bufferLength() {\r\n return this.buffer.getItems().length;\r\n }\r\n\r\n get bufferFirst() {\r\n return this.buffer.getFirstItem();\r\n }\r\n\r\n get bufferLast() {\r\n return this.buffer.getLastItem();\r\n }\r\n\r\n append(newItems) {\r\n this.buffer.append(newItems);\r\n this.doAdjust();\r\n this.viewport.clipTop();\r\n this.viewport.clipBottom();\r\n }\r\n\r\n prepend(newItems, options = {}) {\r\n this.buffer.prepend(newItems, options.immutableTop);\r\n this.doAdjust();\r\n this.viewport.clipTop();\r\n this.viewport.clipBottom();\r\n }\r\n\r\n applyUpdates(arg1, arg2, arg3) {\r\n if (typeof arg1 === 'function') {\r\n this.applyUpdatesFunc(arg1, arg2);\r\n } else {\r\n this.applyUpdatesIndex(arg1, arg2, arg3);\r\n }\r\n this.doAdjust();\r\n }\r\n\r\n applyUpdatesFunc(cb, options = {}) {\r\n this.buffer.slice(0).forEach((wrapper) => {\r\n // we need to do it on the buffer clone, because buffer content\r\n // may change as we iterate through\r\n this.applyUpdate(wrapper, cb(wrapper.item, wrapper.scope, wrapper.element), options);\r\n });\r\n }\r\n\r\n applyUpdatesIndex(index, newItems, options = {}) {\r\n if (index % 1 !== 0) {\r\n throw new Error('applyUpdates - ' + index + ' is not a valid index (should be an integer)');\r\n }\r\n const _index = index - this.buffer.first;\r\n\r\n // apply updates only within buffer\r\n if (_index >= 0 && _index < this.buffer.length) {\r\n this.applyUpdate(this.buffer[_index], newItems, options);\r\n }\r\n // out-of-buffer case: deletion may affect Paddings\r\n else if(index >= this.buffer.getAbsMinIndex() && index <= this.buffer.getAbsMaxIndex()) {\r\n if(angular.isArray(newItems) && !newItems.length) {\r\n this.viewport.removeCacheItem(index, !options.immutableTop && index === this.buffer.minIndex);\r\n if (!options.immutableTop && index === this.buffer.getAbsMinIndex()) {\r\n this.buffer.incrementMinIndex();\r\n }\r\n else {\r\n this.buffer.decrementMaxIndex();\r\n }\r\n }\r\n }\r\n }\r\n\r\n applyUpdate(wrapper, newItems, options = {}) {\r\n if (!angular.isArray(newItems)) {\r\n return;\r\n }\r\n let position = this.buffer.indexOf(wrapper);\r\n if (!newItems.reverse().some(newItem => newItem === wrapper.item)) {\r\n wrapper.op = OPERATIONS.REMOVE;\r\n // try to catch \"first\" edge case on remove\r\n if (!options.immutableTop && !newItems.length) {\r\n // this is the first item, or the previous one's part of the \"shift-top\" group\r\n if (\r\n (position === 0 && this.buffer.bof) ||\r\n (position !== 0 && this.buffer[position - 1].shiftTop)\r\n ) {\r\n wrapper.shiftTop = true;\r\n }\r\n }\r\n }\r\n newItems.forEach((newItem) => {\r\n if (newItem === wrapper.item) {\r\n position--;\r\n } else {\r\n // 3 parameter (shiftTop) is to catch \"first\" edge case on insert\r\n this.buffer.insert(position + 1, newItem, !options.immutableTop && position === -1);\r\n }\r\n });\r\n }\r\n\r\n calculateProperties() {\r\n let rowTop = null, topHeight = 0;\r\n let topDone = false, bottomDone = false;\r\n const length = this.buffer.length;\r\n\r\n for (let i = 0; i < length; i++) {\r\n const item = this.buffer[i];\r\n const itemTop = item.element.offset().top;\r\n\r\n if (rowTop !== itemTop) { // a new row condition\r\n const itemHeight = item.element.outerHeight(true);\r\n const top = this.viewport.topDataPos() + topHeight + itemHeight;\r\n\r\n if (!topDone && top > this.viewport.topVisiblePos()) {\r\n topDone = true;\r\n this['topVisible'] = item.item;\r\n this['topVisibleElement'] = item.element;\r\n this['topVisibleScope'] = item.scope;\r\n }\r\n if (!bottomDone && (top >= this.viewport.bottomVisiblePos() || (i === length - 1 && this.isEOF()))) {\r\n bottomDone = true;\r\n this['bottomVisible'] = item.item;\r\n this['bottomVisibleElement'] = item.element;\r\n this['bottomVisibleScope'] = item.scope;\r\n }\r\n topHeight += itemHeight;\r\n }\r\n rowTop = itemTop;\r\n\r\n if (topDone && bottomDone) {\r\n break;\r\n }\r\n }\r\n }\r\n\r\n}\r\n\r\nexport default Adapter;\r\n","import JQLiteExtras from './modules/jqLiteExtras';\nimport ElementRoutines from './modules/elementRoutines.js';\nimport ScrollBuffer from './modules/buffer.js';\nimport Viewport from './modules/viewport.js';\nimport Adapter from './modules/adapter.js';\nimport { OPERATIONS } from './modules/utils';\n\nangular.module('ui.scroll', [])\n\n .constant('JQLiteExtras', JQLiteExtras)\n .run(['JQLiteExtras', (JQLiteExtras) => {\n const elt = angular.element;\n !(window.jQuery && elt.fn && elt.fn.jquery) ? (new JQLiteExtras()).registerFor(elt) : null;\n ElementRoutines.addCSSRules();\n }])\n\n .directive('uiScrollViewport', function () {\n return {\n restrict: 'A',\n controller: [\n '$scope',\n '$element',\n function (scope, element) {\n this.container = element;\n this.viewport = element;\n this.scope = scope;\n\n angular.forEach(element.children(), child => {\n if (child.tagName.toLowerCase() === 'tbody') {\n this.viewport = angular.element(child);\n }\n });\n\n return this;\n }\n ]\n };\n })\n\n .directive('uiScroll', [\n '$log',\n '$injector',\n '$rootScope',\n '$timeout',\n '$interval',\n '$q',\n '$parse',\n function (console, $injector, $rootScope, $timeout, $interval, $q, $parse) {\n\n return {\n require: ['?^uiScrollViewport'],\n restrict: 'A',\n transclude: 'element',\n priority: 1000,\n terminal: true,\n link: link\n };\n\n function link($scope, element, $attr, controllers, linker) {\n const match = $attr.uiScroll.match(/^\\s*(\\w+)\\s+in\\s+([(\\w|\\$)\\.]+)\\s*$/);\n if (!match) {\n throw new Error('Expected uiScroll in form of \\'_item_ in _datasource_\\' but got \\'' + $attr.uiScroll + '\\'');\n }\n\n function parseNumber(value, defaultValue, isFloat) {\n if (!isFloat) {\n value = value === null ? defaultValue : Math.floor(value);\n }\n return isNaN(value) ? defaultValue : value;\n }\n\n function parseNumericAttr(value, defaultValue, isFloat) {\n const result = $parse(value)($scope);\n return parseNumber(result, defaultValue, isFloat);\n }\n\n function parseBooleanAttr(value, defaultValue) {\n const result = $parse(value)($scope);\n return typeof result === 'boolean' ? result : defaultValue;\n }\n\n const BUFFER_MIN = 3;\n const BUFFER_DEFAULT = 10;\n const PADDING_MIN = 0.3;\n const PADDING_DEFAULT = 0.5;\n const HANDLE_INERTIA_DEFAULT = true;\n const START_INDEX_DEFAULT = 1;\n const MAX_VIEWPORT_DELAY = 500;\n const VIEWPORT_POLLING_INTERVAL = 50;\n\n let datasource = null;\n const itemName = match[1];\n const datasourceName = match[2];\n const viewportController = controllers[0];\n const bufferSize = Math.max(BUFFER_MIN, parseNumericAttr($attr.bufferSize, BUFFER_DEFAULT));\n const padding = Math.max(PADDING_MIN, parseNumericAttr($attr.padding, PADDING_DEFAULT, true));\n const handleInertia = parseBooleanAttr($attr.handleInertia, HANDLE_INERTIA_DEFAULT);\n let startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT);\n let ridActual = 0; // current data revision id\n let pending = [];\n\n const elementRoutines = new ElementRoutines($injector, $q);\n const buffer = new ScrollBuffer(elementRoutines, bufferSize, startIndex);\n const viewport = new Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding);\n const adapter = new Adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload);\n\n if (viewportController) {\n viewportController.adapter = adapter;\n }\n\n const isDatasourceValid = () =>\n Object.prototype.toString.call(datasource) === '[object Object]' && typeof datasource.get === 'function';\n\n datasource = $parse(datasourceName)($scope); // try to get datasource on scope\n if (!isDatasourceValid()) {\n datasource = $injector.get(datasourceName); // try to inject datasource as service\n if (!isDatasourceValid()) {\n throw new Error(datasourceName + ' is not a valid datasource');\n }\n }\n\n let onRenderHandlers = [];\n function onRenderHandlersRunner() {\n onRenderHandlers.forEach(handler => handler.run());\n onRenderHandlers = [];\n }\n function persistDatasourceIndex(datasource, propName) {\n let getter;\n // need to postpone min/maxIndexUser processing if the view is empty\n if(angular.isNumber(datasource[propName])) {\n getter = datasource[propName];\n if(angular.isNumber(getter)) {\n onRenderHandlers = onRenderHandlers.filter(handler => handler.id !== propName);\n onRenderHandlers.push({\n id: propName,\n run: () => datasource[propName] = getter\n });\n }\n }\n }\n\n function defineDatasourceIndex(datasource, propName, propUserName) {\n const descriptor = Object.getOwnPropertyDescriptor(datasource, propName);\n if (descriptor && (descriptor.set || descriptor.get)) {\n return;\n }\n let getter;\n persistDatasourceIndex(datasource, propName);\n Object.defineProperty(datasource, propName, {\n set: (value) => {\n getter = value;\n if(pending.length && !buffer.length) {\n persistDatasourceIndex(datasource, propName);\n return;\n }\n buffer[propUserName] = value;\n const topPaddingHeightOld = viewport.topDataPos();\n viewport.adjustPaddings();\n if (propName === 'minIndex') {\n viewport.onAfterMinIndexSet(topPaddingHeightOld);\n }\n },\n get: () => getter\n });\n }\n\n defineDatasourceIndex(datasource, 'minIndex', 'minIndexUser');\n defineDatasourceIndex(datasource, 'maxIndex', 'maxIndexUser');\n\n const fetchNext = (datasource.get.length !== 2) ?\n (success) => datasource.get(buffer.next, bufferSize, success) :\n (success) => {\n datasource.get({\n index: buffer.next,\n append: buffer.length ? buffer[buffer.length - 1].item : void 0,\n count: bufferSize\n }, success);\n };\n\n const fetchPrevious = (datasource.get.length !== 2) ?\n (success) => datasource.get(buffer.first - bufferSize, bufferSize, success) :\n (success) => {\n datasource.get({\n index: buffer.first - bufferSize,\n prepend: buffer.length ? buffer[0].item : void 0,\n count: bufferSize\n }, success);\n };\n\n const initialize = () => {\n let tryCount = 0;\n if(!viewport.applyContainerStyle()) {\n const timer = $interval(() => {\n tryCount++;\n if(viewport.applyContainerStyle()) {\n $interval.cancel(timer);\n doAdjust();\n }\n if(tryCount * VIEWPORT_POLLING_INTERVAL >= MAX_VIEWPORT_DELAY) {\n $interval.cancel(timer);\n throw Error(`ui-scroll directive requires a viewport with non-zero height in ${MAX_VIEWPORT_DELAY}ms`);\n }\n }, VIEWPORT_POLLING_INTERVAL);\n }\n else {\n doAdjust();\n }\n };\n\n /**\n * Build padding elements\n *\n * Calling linker is the only way I found to get access to the tag name of the template\n * to prevent the directive scope from pollution a new scope is created and destroyed\n * right after the builder creation is completed\n */\n linker((clone, scope) => {\n viewport.createPaddingElements(clone[0]);\n // we do not include the clone in the DOM. It means that the nested directives will not\n // be able to reach the parent directives, but in this case it is intentional because we\n // created the clone to access the template tag name\n scope.$destroy();\n clone.remove();\n });\n\n $scope.$on('$destroy', () => {\n unbindEvents();\n viewport.off('mousewheel', wheelHandler);\n });\n\n viewport.on('mousewheel', wheelHandler);\n\n initialize();\n\n /* Private function definitions */\n\n function isInvalid(rid) {\n return (rid && rid !== ridActual) || $scope.$$destroyed;\n }\n\n function bindEvents() {\n viewport.on('resize', resizeAndScrollHandler);\n viewport.on('scroll', resizeAndScrollHandler);\n }\n\n function unbindEvents() {\n viewport.off('resize', resizeAndScrollHandler);\n viewport.off('scroll', resizeAndScrollHandler);\n }\n\n function reload() {\n unbindEvents();\n viewport.resetTopPadding();\n viewport.resetBottomPadding();\n if (arguments.length) {\n startIndex = parseNumber(arguments[0], START_INDEX_DEFAULT, false);\n }\n buffer.reset(startIndex);\n persistDatasourceIndex(datasource, 'minIndex');\n persistDatasourceIndex(datasource, 'maxIndex');\n doAdjust();\n }\n\n function isElementVisible(wrapper) {\n return wrapper.element.height() && wrapper.element[0].offsetParent;\n }\n\n function visibilityWatcher(wrapper) {\n if (isElementVisible(wrapper)) {\n buffer.forEach((item) => {\n if (typeof item.unregisterVisibilityWatcher === 'function') {\n item.unregisterVisibilityWatcher();\n delete item.unregisterVisibilityWatcher;\n }\n });\n if (!pending.length) {\n $timeout(() => doAdjust());\n }\n }\n }\n\n function insertWrapperContent(wrapper, insertAfter) {\n createElement(wrapper, insertAfter, viewport.insertElement);\n if (!isElementVisible(wrapper)) {\n wrapper.unregisterVisibilityWatcher = wrapper.scope.$watch(() => visibilityWatcher(wrapper));\n }\n elementRoutines.hideElement(wrapper); // hide inserted elements before data binding\n }\n\n function createElement(wrapper, insertAfter, insertElement) {\n let promises = null;\n const sibling = (insertAfter > 0) ? buffer[insertAfter - 1].element : undefined;\n linker((clone, scope) => {\n promises = insertElement(clone, sibling);\n wrapper.element = clone;\n wrapper.scope = scope;\n scope[itemName] = wrapper.item;\n });\n // ui-scroll-grid apply\n if (adapter.transform) {\n const tdInitializer = wrapper.scope.uiScrollTdInitializer;\n if (tdInitializer && tdInitializer.linking) {\n adapter.transform(wrapper.scope, wrapper.element);\n } else {\n wrapper.scope.uiScrollTdInitializer = {\n onLink: () => adapter.transform(wrapper.scope, wrapper.element),\n scope: wrapper.scope\n };\n }\n }\n return promises;\n }\n\n function updateDOM() {\n let promises = [];\n const toBePrepended = [];\n const toBeRemoved = [];\n const inserted = [];\n\n buffer.forEach((wrapper, i) => {\n switch (wrapper.op) {\n case OPERATIONS.PREPEND:\n toBePrepended.unshift(wrapper);\n break;\n case OPERATIONS.APPEND:\n insertWrapperContent(wrapper, i);\n wrapper.op = OPERATIONS.NONE;\n inserted.push(wrapper);\n break;\n case OPERATIONS.INSERT:\n promises = promises.concat(createElement(wrapper, i, viewport.insertElementAnimated));\n wrapper.op = OPERATIONS.NONE;\n inserted.push(wrapper);\n break;\n case OPERATIONS.REMOVE:\n toBeRemoved.push(wrapper);\n }\n });\n\n toBeRemoved.forEach((wrapper) => promises = promises.concat(viewport.removeItem(wrapper)));\n\n if (toBePrepended.length)\n toBePrepended.forEach((wrapper) => {\n insertWrapperContent(wrapper);\n wrapper.op = OPERATIONS.NONE;\n });\n\n buffer.forEach((item, i) => item.scope.$index = buffer.first + i);\n\n return {\n prepended: toBePrepended,\n removed: toBeRemoved,\n inserted: inserted,\n animated: promises\n };\n\n }\n\n function updatePaddings(rid, updates) {\n // schedule another doAdjust after animation completion\n if (updates.animated.length) {\n $q.all(updates.animated).then(() => {\n viewport.adjustPaddings();\n doAdjust(rid);\n });\n } else {\n viewport.adjustPaddings();\n }\n }\n\n function enqueueFetch(rid, updates) {\n if (viewport.shouldLoadBottom()) {\n if (!updates || buffer.effectiveHeight(updates.inserted) > 0) {\n // this means that at least one item appended in the last batch has height > 0\n if (pending.push(true) === 1) {\n adapter.loading(true);\n fetch(rid);\n }\n }\n } else if (viewport.shouldLoadTop()) {\n if ((!updates || buffer.effectiveHeight(updates.prepended) > 0) || pending[0]) {\n // this means that at least one item appended in the last batch has height > 0\n // pending[0] = true means that previous fetch was appending. We need to force at least one prepend\n // BTW there will always be at least 1 element in the pending array because bottom is fetched first\n if (pending.push(false) === 1) {\n adapter.loading(true);\n fetch(rid);\n }\n }\n }\n }\n\n function processUpdates() {\n const updates = updateDOM();\n\n // We need the item bindings to be processed before we can do adjustments\n !$scope.$$phase && !$rootScope.$$phase && $scope.$digest();\n\n updates.inserted.forEach(w => elementRoutines.showElement(w));\n updates.prepended.forEach(w => elementRoutines.showElement(w));\n return updates;\n }\n\n function doAdjust(rid) {\n if (!rid) { // dismiss pending requests\n pending = [];\n rid = ++ridActual;\n }\n\n const updates = processUpdates();\n\n if (isInvalid(rid)) {\n return;\n }\n\n updatePaddings(rid, updates);\n enqueueFetch(rid);\n\n if (!pending.length) {\n adapter.calculateProperties();\n }\n }\n\n function doAdjustAfterFetch(rid) {\n const updates = processUpdates();\n\n viewport.onAfterPrepend(updates);\n\n if (isInvalid(rid)) {\n return;\n }\n\n updatePaddings(rid, updates);\n onRenderHandlersRunner();\n enqueueFetch(rid, updates);\n pending.shift();\n\n if (pending.length)\n fetch(rid);\n else {\n adapter.loading(false);\n bindEvents();\n adapter.calculateProperties();\n }\n }\n\n function fetch(rid) {\n if (pending[0]) {// scrolling down\n if (buffer.length && !viewport.shouldLoadBottom()) {\n doAdjustAfterFetch(rid);\n } else {\n fetchNext((result) => {\n if (isInvalid(rid)) {\n return;\n }\n\n if (result.length < bufferSize) {\n buffer.eof = true;\n }\n\n if (result.length > 0) {\n viewport.clipTop();\n buffer.append(result);\n }\n\n doAdjustAfterFetch(rid);\n });\n }\n } else { // scrolling up\n if (buffer.length && !viewport.shouldLoadTop()) {\n doAdjustAfterFetch(rid);\n } else {\n fetchPrevious((result) => {\n if (isInvalid(rid)) {\n return;\n }\n\n if (result.length < bufferSize) {\n buffer.bof = true;\n // log 'bof is reached'\n }\n\n if (result.length > 0) {\n if (buffer.length) {\n viewport.clipBottom();\n }\n buffer.prepend(result);\n }\n\n doAdjustAfterFetch(rid);\n });\n }\n }\n }\n\n function fixInertia() {\n if (!viewport.synthetic) {\n return;\n }\n const oldPosition = viewport.synthetic.previous;\n const newPosition = viewport.synthetic.next;\n if (viewport.scrollTop() !== newPosition) {\n requestAnimationFrame(() => {\n const position = viewport.scrollTop();\n const diff = oldPosition - position;\n if (diff > 0) { // inertia over synthetic\n viewport.scrollTop(newPosition - diff);\n } else {\n viewport.scrollTop(newPosition);\n }\n viewport.synthetic = null;\n });\n return true;\n }\n viewport.synthetic = null;\n }\n\n function resizeAndScrollHandler() {\n if (handleInertia && fixInertia()) {\n return;\n }\n if (!$rootScope.$$phase && !adapter.isLoading && !adapter.disabled) {\n\n enqueueFetch(ridActual);\n\n if (pending.length) {\n unbindEvents();\n } else {\n adapter.calculateProperties();\n !$scope.$$phase && $scope.$digest();\n }\n }\n }\n\n function wheelHandler(event) {\n if (!adapter.disabled) {\n const scrollTop = viewport[0].scrollTop;\n const yMax = viewport[0].scrollHeight - viewport[0].clientHeight;\n\n if ((scrollTop === 0 && !buffer.bof) || (scrollTop === yMax && !buffer.eof)) {\n event.preventDefault();\n }\n }\n }\n }\n\n }\n ]);\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/ui-scroll.min.js b/dist/ui-scroll.min.js new file mode 100644 index 00000000..1c721cfd --- /dev/null +++ b/dist/ui-scroll.min.js @@ -0,0 +1,2 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([,function(e,t,n){"use strict";function r(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0;try{for(var a,u=e[Symbol.iterator]();!(r=(a=u.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{r||null==u.return||u.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function i(e,t){for(var n=0;n0?{base:s.base-s.padding-s.border,outer:s.base,outerfull:s.base+s.margin}[a]:(((u=i(e)[n])<0||null===u)&&(u=e.style[n]||0),{base:(u=parseFloat(u)||0)-s.padding-s.border,outer:u,outerfull:u+s.padding+s.border+s.margin}[a])}return n=angular.element.prototype.css,e.prototype.css=function(e,t){var r=this[0];if(r&&3!==r.nodeType&&8!==r.nodeType&&r.style)return n.call(this,e,t)},o=function(e){return e&&e.document&&e.location&&e.alert&&e.setInterval},window.getComputedStyle?(i=function(e){return window.getComputedStyle(e,null)},t=function(e,t){return parseFloat(t)}):(i=function(e){return e.currentStyle},t=function(e,t){var n,r,i,o,a;return new RegExp("^("+/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source+")(?!px)[a-z%]+$","i").test(t)?(n=(a=e.style).left,o=(i=e.runtimeStyle)&&i.left,i&&(i.left=a.left),a.left=t,r=a.pixelLeft,a.left=n,o&&(i.left=o),r):parseFloat(t)}),angular.forEach({before:function(e){var t,n,r,i,o,a;if(n=this[0],(t=(o=this.parent()).contents())[0]===n)return o.prepend(e);for(r=i=1,a=t.length-1;1<=a?i<=a:i>=a;r=1<=a?++i:--i)if(t[r]===n)return void angular.element(t[r-1]).after(e);throw new Error("invalid DOM structure "+n.outerHTML)},height:function(e){return void 0!==e?(angular.isNumber(e)&&(e+="px"),n.call(this,"height",e)):u(this[0],"height","base")},outerHeight:function(e){return u(this[0],"height",e?"outerfull":"outer")},outerWidth:function(e){return u(this[0],"width",e?"outerfull":"outer")},offset:function(e){var t,n,r=this,i={top:0,left:0},o=r[0],a=o&&o.ownerDocument;if(arguments.length){if(void 0===e)return r;throw new Error("offset setter method is not implemented")}if(a)return t=a.documentElement,null!=o.getBoundingClientRect&&(i=o.getBoundingClientRect()),n=a.defaultView||a.parentWindow,{top:i.top+(n.pageYOffset||t.scrollTop)-(t.clientTop||0),left:i.left+(n.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}},scrollTop:function(e){return a(this,"top",e)},scrollLeft:function(e){return a(this,"left",e)}},(function(t,n){if(!e.prototype[n])return e.prototype[n]=t}))}}])&&i(t.prototype,n),o&&i(t,o),e}();function a(e,t){for(var n=0;nr.minIndexUser)return void r.minIndexUser++;r.minIndex===r.minIndexUser&&r.minIndexUser++}r.minIndex++},decrementMaxIndex:function(){null!==r.maxIndexUser&&r.maxIndex<=r.maxIndexUser&&r.maxIndexUser--,r.maxIndex--},getAbsMinIndex:function(){return null!==r.minIndexUser?Math.min(r.minIndexUser,r.minIndex):r.minIndex},getAbsMaxIndex:function(){return null!==r.maxIndexUser?Math.max(r.maxIndexUser,r.maxIndex):r.maxIndex},effectiveHeight:function(e){if(!e.length)return 0;var t=Number.MAX_VALUE,n=Number.NEGATIVE_INFINITY;return e.forEach((function(e){e.element[0].offsetParent&&(t=Math.min(t,e.element.offset().top),n=Math.max(n,e.element.offset().top+e.element.outerHeight(!0)))})),Math.max(0,n-t)},getItems:function(){return r.filter((function(e){return e.op===p}))},getFirstItem:function(){var e=r.getItems();return e.length?e[0].item:null},getLastItem:function(){var e=r.getItems();return e.length?e[e.length-1].item:null}}),r.reset(n),r}function g(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function v(e,t){for(var n=0;n=0;t--)if(this[t].index===e.scope.$index)return void(this[t].height=e.element.outerHeight());this.push({index:e.scope.$index,height:e.element.outerHeight()}),this.sort((function(e,t){return e.indext.index?1:0}))}},{key:"remove",value:function(e,t){for(var n=e%1==0?e:e.scope.$index,r=e%1==0?t:e.shiftTop,i=this.length-1;i>=0;i--)if(this[i].index===n){this.splice(i,1);break}if(!r)for(var o=this.length-1;o>=0;o--)this[o].index>n&&this[o].index--}},{key:"clear",value:function(){this.length=0}}]),e}();function y(){var e=[];return e.push.apply(e,arguments),Object.setPrototypeOf(e,y.prototype),e}y.prototype=Object.create(Array.prototype),Object.getOwnPropertyNames(x.prototype).forEach((function(e){return y.prototype[e]=x.prototype[e]}));var I=function(){function e(t){g(this,e),this.element=function(e){if(e.nodeType!==Node.ELEMENT_NODE)throw new Error("ui-scroll directive requires an Element node for templating the view");var t;switch(e.tagName.toLowerCase()){case"dl":throw new Error("ui-scroll directive does not support <".concat(e.tagName,"> as a repeating tag: ").concat(e.outerHTML));case"tr":t=angular.element("
    ").find("tr");break;case"li":t=angular.element("
  • ");break;default:t=angular.element("
    ")}return t}(t),this.cache=new y}return b(e,[{key:"height",value:function(){return this.element.height.apply(this.element,arguments)}}]),e}();function w(e,t,n,r,i,o){var a=null,u=null,s=r&&r.viewport?r.viewport:angular.element(window),l=r&&r.container?r.container:void 0,c=r&&r.scope?r.scope:i;function f(){return s.outerHeight()*o}return s.css({"overflow-anchor":"none","overflow-y":"auto",display:"block"}),angular.extend(s,{getScope:function(){return c},createPaddingElements:function(e){a=new I(e),u=new I(e),n.before(a.element),n.after(u.element),a.height(0),u.height(0)},applyContainerStyle:function(){return!l||(l!==s&&s.css("height",window.getComputedStyle(l[0]).height),s.height()>0)},bottomDataPos:function(){var e=s[0].scrollHeight;return(e=null!=e?e:s[0].document.documentElement.scrollHeight)-u.height()},topDataPos:function(){return a.height()},bottomVisiblePos:function(){return s.scrollTop()+s.outerHeight()},topVisiblePos:function(){return s.scrollTop()},insertElement:function(t,n){return e.insertElement(t,n||a.element)},insertElementAnimated:function(t,n){return e.insertElementAnimated(t,n||a.element)},shouldLoadBottom:function(){return!t.eof&&s.bottomDataPos()=0&&!(n+(r=t[o].element.outerHeight(!0))>i);o--)u.cache.add(t[o]),n+=r,e++;e>0&&(t.eof=!1,t.remove(t.length-e,t.length),t.next-=e,s.adjustPaddings())},shouldLoadTop:function(){return!t.bof&&s.topDataPos()>s.topVisiblePos()-f()},clipTop:function(){for(var e=0,n=0,r=0,i=s.topVisiblePos()-s.topDataPos()-f(),o=0;oi);o++)a.cache.add(t[o]),n+=r,e++;e>0&&(a.height(a.height()+n),t.bof=!1,t.remove(0,e),t.first+=e)},adjustPaddings:function(){if(t.length){var e=t.reduce((function(e,t){return e+t.element.outerHeight(!0)}),0),n=0,r=0;a.cache.forEach((function(e){e.index=t.next&&(i+=e.height,o++)}));var s=(e+n+i)/(r+o+t.length),l=null!==t.minIndexUser&&t.minIndex>t.minIndexUser,c=null!==t.maxIndexUser&&t.maxIndext.minIndexUser){var n=a.height()-e;for(s.scrollTop(s.scrollTop()+n);(n-=s.scrollTop())>0;)u.height(u.height()+n),s.scrollTop(s.scrollTop()+n)}},onAfterPrepend:function(e){if(e.prepended.length){var n=t.effectiveHeight(e.prepended),r=a.height()-n;if(r>=0)a.height(r);else{var i=s.scrollTop(),o=i-r;s.synthetic={previous:i,next:o},a.height(0),s.scrollTop(o)}}},resetTopPadding:function(){a.height(0),a.cache.clear()},resetBottomPadding:function(){u.height(0),u.cache.clear()},removeCacheItem:function(e,t){a.cache.remove(e,t),u.cache.remove(e,t)},removeItem:function(e){return this.removeCacheItem(e),t.remove(e)}}),s}function E(e,t){for(var n=0;n=0;n--)this.publicContext[t[n]]=this[t[n]].bind(this);for(var r=["isLoading","topVisible","topVisibleElement","topVisibleScope","bottomVisible","bottomVisibleElement","bottomVisibleScope"],i=function(t){var n=void 0,i=e.$attr[r[t]];Object.defineProperty(e,r[t],{get:function(){return n},set:function(o){n=o,e.publicContext[r[t]]=o,i&&e.$parse(i).assign(e.startScope,o)}})},o=r.length-1;o>=0;o--)i(o);for(var a=["bufferFirst","bufferLast","bufferLength"],u=function(t){Object.defineProperty(e.publicContext,a[t],{get:function(){return e[a[t]]}})},s=a.length-1;s>=0;s--)u(s);Object.defineProperty(this.publicContext,"disabled",{get:function(){return e.disabled},set:function(t){return(e.disabled=t)?null:e.doAdjust()}})}},{key:"loading",value:function(e){this.isLoading=e}},{key:"isBOF",value:function(){return this.buffer.bof}},{key:"isEOF",value:function(){return this.buffer.eof}},{key:"isEmpty",value:function(){return!this.buffer.length}},{key:"append",value:function(e){this.buffer.append(e),this.doAdjust(),this.viewport.clipTop(),this.viewport.clipBottom()}},{key:"prepend",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.buffer.prepend(e,t.immutableTop),this.doAdjust(),this.viewport.clipTop(),this.viewport.clipBottom()}},{key:"applyUpdates",value:function(e,t,n){"function"==typeof e?this.applyUpdatesFunc(e,t):this.applyUpdatesIndex(e,t,n),this.doAdjust()}},{key:"applyUpdatesFunc",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.buffer.slice(0).forEach((function(r){t.applyUpdate(r,e(r.item,r.scope,r.element),n)}))}},{key:"applyUpdatesIndex",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(e%1!=0)throw new Error("applyUpdates - "+e+" is not a valid index (should be an integer)");var r=e-this.buffer.first;r>=0&&r=this.buffer.getAbsMinIndex()&&e<=this.buffer.getAbsMaxIndex()&&angular.isArray(t)&&!t.length&&(this.viewport.removeCacheItem(e,!n.immutableTop&&e===this.buffer.minIndex),n.immutableTop||e!==this.buffer.getAbsMinIndex()?this.buffer.decrementMaxIndex():this.buffer.incrementMinIndex())}},{key:"applyUpdate",value:function(e,t){var n=this,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(angular.isArray(t)){var i=this.buffer.indexOf(e);t.reverse().some((function(t){return t===e.item}))||(e.op=d,r.immutableTop||t.length||(0===i&&this.buffer.bof||0!==i&&this.buffer[i-1].shiftTop)&&(e.shiftTop=!0)),t.forEach((function(t){t===e.item?i--:n.buffer.insert(i+1,t,!r.immutableTop&&-1===i)}))}}},{key:"calculateProperties",value:function(){for(var e=null,t=0,n=!1,r=!1,i=this.buffer.length,o=0;othis.viewport.topVisiblePos()&&(n=!0,this.topVisible=a.item,this.topVisibleElement=a.element,this.topVisibleScope=a.scope),!r&&(l>=this.viewport.bottomVisiblePos()||o===i-1&&this.isEOF())&&(r=!0,this.bottomVisible=a.item,this.bottomVisibleElement=a.element,this.bottomVisibleScope=a.scope),t+=s}if(e=u,n&&r)break}}},{key:"bufferLength",get:function(){return this.buffer.getItems().length}},{key:"bufferFirst",get:function(){return this.buffer.getFirstItem()}},{key:"bufferLast",get:function(){return this.buffer.getLastItem()}}])&&E(t.prototype,n),r&&E(t,r),e}();angular.module("ui.scroll",[]).constant("JQLiteExtras",o).run(["JQLiteExtras",function(e){var t=angular.element;!(window.jQuery&&t.fn&&t.fn.jquery)&&(new e).registerFor(t),l.addCSSRules()}]).directive("uiScrollViewport",(function(){return{restrict:"A",controller:["$scope","$element",function(e,t){var n=this;return this.container=t,this.viewport=t,this.scope=e,angular.forEach(t.children(),(function(e){"tbody"===e.tagName.toLowerCase()&&(n.viewport=angular.element(e))})),this}]}})).directive("uiScroll",["$log","$injector","$rootScope","$timeout","$interval","$q","$parse",function(e,t,n,r,i,o,a){return{require:["?^uiScrollViewport"],restrict:"A",transclude:"element",priority:1e3,terminal:!0,link:function(e,u,s,g,v){var b=s.uiScroll.match(/^\s*(\w+)\s+in\s+([(\w|\$)\.]+)\s*$/);if(!b)throw new Error("Expected uiScroll in form of '_item_ in _datasource_' but got '"+s.uiScroll+"'");function x(e,t,n){return n||(e=null===e?t:Math.floor(e)),isNaN(e)?t:e}function y(t,n,r){return x(a(t)(e),n,r)}var I=null,E=b[1],$=b[2],P=g[0],k=Math.max(3,y(s.bufferSize,10)),S=Math.max(.3,y(s.padding,.5,!0)),A=(H=s.handleInertia,F=!0,N=a(H)(e),"boolean"==typeof N?N:F),O=y(s.startIndex,1),j=0,L=[],U=new l(t,o),M=new m(U,k,O),V=new w(U,M,u,P,n,S),C=new T(e,a,s,V,M,ee,(function(){Q(),V.resetTopPadding(),V.resetBottomPadding(),arguments.length&&(O=x(arguments[0],1,!1));M.reset(O),D(I,"minIndex"),D(I,"maxIndex"),ee()}));var H,F,N;P&&(P.adapter=C);var _=function(){return"[object Object]"===Object.prototype.toString.call(I)&&"function"==typeof I.get};if(!(I=a($)(e),_()||(I=t.get($),_())))throw new Error($+" is not a valid datasource");var B=[];function D(e,t){var n;angular.isNumber(e[t])&&(n=e[t],angular.isNumber(n)&&(B=B.filter((function(e){return e.id!==t}))).push({id:t,run:function(){return e[t]=n}}))}function R(e,t,n){var r,i=Object.getOwnPropertyDescriptor(e,t);i&&(i.set||i.get)||(D(e,t),Object.defineProperty(e,t,{set:function(i){if(r=i,!L.length||M.length){M[n]=i;var o=V.topDataPos();V.adjustPaddings(),"minIndex"===t&&V.onAfterMinIndexSet(o)}else D(e,t)},get:function(){return r}}))}R(I,"minIndex","minIndexUser"),R(I,"maxIndex","maxIndexUser");var W=2!==I.get.length?function(e){return I.get(M.next,k,e)}:function(e){I.get({index:M.next,append:M.length?M[M.length-1].item:void 0,count:k},e)},q=2!==I.get.length?function(e){return I.get(M.first-k,k,e)}:function(e){I.get({index:M.first-k,prepend:M.length?M[0].item:void 0,count:k},e)};function z(t){return t&&t!==j||e.$$destroyed}function Q(){V.off("resize",re),V.off("scroll",re)}function X(e){return e.element.height()&&e.element[0].offsetParent}function Y(e,t){J(e,t,V.insertElement),X(e)||(e.unregisterVisibilityWatcher=e.scope.$watch((function(){return function(e){X(e)&&(M.forEach((function(e){"function"==typeof e.unregisterVisibilityWatcher&&(e.unregisterVisibilityWatcher(),delete e.unregisterVisibilityWatcher)})),L.length||r((function(){return ee()})))}(e)}))),U.hideElement(e)}function J(e,t,n){var r=null,i=t>0?M[t-1].element:void 0;if(v((function(t,o){r=n(t,i),e.element=t,e.scope=o,o[E]=e.item})),C.transform){var o=e.scope.uiScrollTdInitializer;o&&o.linking?C.transform(e.scope,e.element):e.scope.uiScrollTdInitializer={onLink:function(){return C.transform(e.scope,e.element)},scope:e.scope}}return r}function G(e,t){t.animated.length?o.all(t.animated).then((function(){V.adjustPaddings(),ee(e)})):V.adjustPaddings()}function K(e,t){V.shouldLoadBottom()?(!t||M.effectiveHeight(t.inserted)>0)&&1===L.push(!0)&&(C.loading(!0),ne(e)):V.shouldLoadTop()&&(!t||M.effectiveHeight(t.prepended)>0||L[0])&&1===L.push(!1)&&(C.loading(!0),ne(e))}function Z(){var t,r,i,o,a=(t=[],r=[],i=[],o=[],M.forEach((function(e,n){switch(e.op){case c:r.unshift(e);break;case f:Y(e,n),e.op=p,o.push(e);break;case h:t=t.concat(J(e,n,V.insertElementAnimated)),e.op=p,o.push(e);break;case d:i.push(e)}})),i.forEach((function(e){return t=t.concat(V.removeItem(e))})),r.length&&r.forEach((function(e){Y(e),e.op=p})),M.forEach((function(e,t){return e.scope.$index=M.first+t})),{prepended:r,removed:i,inserted:o,animated:t});return!e.$$phase&&!n.$$phase&&e.$digest(),a.inserted.forEach((function(e){return U.showElement(e)})),a.prepended.forEach((function(e){return U.showElement(e)})),a}function ee(e){e||(L=[],e=++j);var t=Z();z(e)||(G(e,t),K(e),L.length||C.calculateProperties())}function te(e){var t=Z();V.onAfterPrepend(t),z(e)||(G(e,t),B.forEach((function(e){return e.run()})),B=[],K(e,t),L.shift(),L.length?ne(e):(C.loading(!1),V.on("resize",re),V.on("scroll",re),C.calculateProperties()))}function ne(e){L[0]?M.length&&!V.shouldLoadBottom()?te(e):W((function(t){z(e)||(t.length0&&(V.clipTop(),M.append(t)),te(e))})):M.length&&!V.shouldLoadTop()?te(e):q((function(t){z(e)||(t.length0&&(M.length&&V.clipBottom(),M.prepend(t)),te(e))}))}function re(){A&&function(){if(V.synthetic){var e=V.synthetic.previous,t=V.synthetic.next;if(V.scrollTop()!==t)return requestAnimationFrame((function(){var n=V.scrollTop(),r=e-n;r>0?V.scrollTop(t-r):V.scrollTop(t),V.synthetic=null})),!0;V.synthetic=null}}()||n.$$phase||C.isLoading||C.disabled||(K(j),L.length?Q():(C.calculateProperties(),!e.$$phase&&e.$digest()))}function ie(e){if(!C.disabled){var t=V[0].scrollTop,n=V[0].scrollHeight-V[0].clientHeight;(0===t&&!M.bof||t===n&&!M.eof)&&e.preventDefault()}}v((function(e,t){V.createPaddingElements(e[0]),t.$destroy(),e.remove()})),e.$on("$destroy",(function(){Q(),V.off("mousewheel",ie)})),V.on("mousewheel",ie),function(){var e=0;if(V.applyContainerStyle())ee();else var t=i((function(){if(e++,V.applyContainerStyle()&&(i.cancel(t),ee()),50*e>=500)throw i.cancel(t),Error("ui-scroll directive requires a viewport with non-zero height in ".concat(500,"ms"))}),50)}()}}}])}]); +//# sourceMappingURL=ui-scroll.min.js.map \ No newline at end of file diff --git a/dist/ui-scroll.min.js.map b/dist/ui-scroll.min.js.map new file mode 100644 index 00000000..fefad5b7 --- /dev/null +++ b/dist/ui-scroll.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/modules/jqLiteExtras.js","webpack:///./src/modules/elementRoutines.js","webpack:///./src/modules/utils.js","webpack:///./src/modules/buffer.js","webpack:///./src/modules/padding.js","webpack:///./src/modules/viewport.js","webpack:///./src/modules/adapter.js","webpack:///./src/ui-scroll.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","JQLiteExtras","element","convertToPx","css","getStyle","isWindow","scrollTo","self","direction","elem","top","left","method","prop","preserve","isValueDefined","document","documentElement","getWidthHeight","measure","result","measurements","base","borderA","borderB","computedMarginA","computedMarginB","computedStyle","dirA","dirB","paddingA","paddingB","height","width","padding","border","margin","offsetWidth","offsetHeight","getMeasurements","outer","outerfull","style","parseFloat","angular","this","nodeType","obj","location","alert","setInterval","window","getComputedStyle","currentStyle","rs","rsLeft","RegExp","source","test","runtimeStyle","pixelLeft","forEach","before","newElem","children","j","parent","ref","contents","prepend","length","after","Error","outerHTML","isNumber","outerHeight","option","outerWidth","offset","docElem","win","box","doc","ownerDocument","arguments","undefined","getBoundingClientRect","defaultView","parentWindow","pageYOffset","scrollTop","clientTop","pageXOffset","scrollLeft","clientLeft","hideClassToken","ElementRoutines","$injector","$q","$animate","has","isAngularVersionLessThen1_3","version","major","minor","index","selector","rules","sheet","styleSheets","cssRules","err","insertRule","addRule","wrapper","addClass","removeClass","newElement","previousElement","remove","scope","$destroy","insertElement","deferred","defer","enter","resolve","promise","removeElement","leave","then","OPERATIONS","ScrollBuffer","elementRoutines","bufferSize","startIndex","buffer","Array","extend","size","reset","eof","bof","first","next","minIndex","maxIndex","minIndexUser","maxIndexUser","append","items","item","insert","Math","max","immutableTop","reverse","min","operation","shiftTop","op","splice","push","unshift","arg1","arg2","indexOf","getAbsMinIndex","incrementMinIndex","decrementMaxIndex","removeElementAnimated","getAbsMaxIndex","effectiveHeight","elements","Number","MAX_VALUE","bottom","NEGATIVE_INFINITY","offsetParent","getItems","filter","getFirstItem","list","getLastItem","CacheProto","$index","sort","a","b","argument","_shiftTop","Cache","instance","apply","setPrototypeOf","getOwnPropertyNames","methodName","Padding","template","Node","ELEMENT_NODE","tagName","toLowerCase","find","generateElement","cache","Viewport","viewportController","$rootScope","topPadding","bottomPadding","viewport","container","bufferPadding","getScope","createPaddingElements","applyContainerStyle","bottomDataPos","scrollHeight","topDataPos","bottomVisiblePos","topVisiblePos","e","sibling","insertElementAnimated","shouldLoadBottom","clipBottom","overage","overageHeight","itemHeight","emptySpaceHeight","add","adjustPaddings","shouldLoadTop","clipTop","visibleItemsHeight","reduce","summ","topPaddingHeight","topCount","bottomPaddingHeight","bottomCount","averageItemHeight","adjustTopPadding","adjustBottomPadding","topPaddingHeightAdd","bottomPaddingHeightAdd","onAfterMinIndexSet","topPaddingHeightOld","diff","onAfterPrepend","updates","prepended","paddingHeight","position","newPosition","synthetic","previous","resetTopPadding","clear","resetBottomPadding","removeCacheItem","removeItem","Adapter","$scope","$parse","$attr","doAdjust","reload","isLoading","disabled","viewportScope","startScope","$parent","publicContext","assignAdapter","adapter","generatePublicContext","adapterAttr","replace","adapterOnScope","assign","error","message","publicMethods","publicProps","attr","set","publicPropsImmediate","newItems","options","arg3","applyUpdatesFunc","applyUpdatesIndex","cb","slice","applyUpdate","_index","isArray","some","newItem","rowTop","topHeight","topDone","bottomDone","itemTop","isEOF","constant","run","elt","jQuery","fn","jquery","registerFor","addCSSRules","directive","restrict","controller","child","console","$timeout","$interval","require","transclude","priority","terminal","link","controllers","linker","match","uiScroll","parseNumber","defaultValue","isFloat","floor","isNaN","parseNumericAttr","datasource","itemName","datasourceName","handleInertia","ridActual","pending","unbindEvents","persistDatasourceIndex","isDatasourceValid","toString","onRenderHandlers","propName","handler","id","defineDatasourceIndex","propUserName","descriptor","getOwnPropertyDescriptor","fetchNext","success","count","fetchPrevious","isInvalid","rid","$$destroyed","off","resizeAndScrollHandler","isElementVisible","insertWrapperContent","insertAfter","createElement","unregisterVisibilityWatcher","$watch","visibilityWatcher","hideElement","promises","clone","transform","tdInitializer","uiScrollTdInitializer","linking","onLink","updatePaddings","animated","all","enqueueFetch","inserted","loading","fetch","processUpdates","toBePrepended","toBeRemoved","concat","removed","$$phase","$digest","w","showElement","calculateProperties","doAdjustAfterFetch","shift","on","oldPosition","requestAnimationFrame","fixInertia","wheelHandler","event","yMax","clientHeight","preventDefault","$on","tryCount","timer","cancel","initialize"],"mappings":"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","file":"ui-scroll.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n","/*!\r\n globals: angular, window\r\n List of used element methods available in JQuery but not in JQuery Lite\r\n element.before(elem)\r\n element.height()\r\n element.outerHeight(true)\r\n element.height(value) = only for Top/Bottom padding elements\r\n element.scrollTop()\r\n element.scrollTop(value)\r\n */\r\n\r\nexport default class JQLiteExtras {\r\n\r\n registerFor(element) {\r\n let convertToPx, css, getStyle, isWindow;\r\n // angular implementation blows up if elem is the window\r\n css = angular.element.prototype.css;\r\n\r\n element.prototype.css = function (name, value) {\r\n let self = this;\r\n let elem = self[0];\r\n if (!(!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style)) {\r\n return css.call(self, name, value);\r\n }\r\n };\r\n\r\n // as defined in angularjs v1.0.5\r\n isWindow = (obj) => obj && obj.document && obj.location && obj.alert && obj.setInterval;\r\n\r\n function scrollTo(self, direction, value) {\r\n let elem = self[0];\r\n let [method, prop, preserve] = {\r\n top: [\r\n 'scrollTop',\r\n 'pageYOffset',\r\n 'scrollLeft'\r\n ],\r\n left: [\r\n 'scrollLeft',\r\n 'pageXOffset',\r\n 'scrollTop'\r\n ]\r\n }[direction];\r\n\r\n const isValueDefined = typeof value !== 'undefined';\r\n if (isWindow(elem)) {\r\n if (isValueDefined) {\r\n return elem.scrollTo(self[preserve].call(self), value);\r\n }\r\n return (prop in elem) ? elem[prop] : elem.document.documentElement[method];\r\n } else {\r\n if (isValueDefined) {\r\n elem[method] = value;\r\n }\r\n return elem[method];\r\n }\r\n }\r\n\r\n if (window.getComputedStyle) {\r\n getStyle = (elem) => window.getComputedStyle(elem, null);\r\n convertToPx = (elem, value) => parseFloat(value);\r\n } else {\r\n getStyle = (elem) => elem.currentStyle;\r\n convertToPx = (elem, value) => {\r\n let left, result, rs, rsLeft, style;\r\n let core_pnum = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source;\r\n let rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i');\r\n\r\n if (!rnumnonpx.test(value)) {\r\n return parseFloat(value);\r\n }\r\n\r\n // ported from JQuery\r\n style = elem.style;\r\n left = style.left;\r\n rs = elem.runtimeStyle;\r\n rsLeft = rs && rs.left;\r\n if (rs) {\r\n rs.left = style.left;\r\n }\r\n // put in the new values to get a computed style out\r\n style.left = value;\r\n result = style.pixelLeft;\r\n style.left = left;\r\n if (rsLeft) {\r\n rs.left = rsLeft;\r\n }\r\n return result;\r\n };\r\n }\r\n\r\n function getMeasurements(elem, measure) {\r\n let base, borderA, borderB, computedMarginA, computedMarginB, computedStyle, dirA, dirB, marginA, marginB, paddingA, paddingB;\r\n\r\n if (isWindow(elem)) {\r\n base = document.documentElement[{height: 'clientHeight', width: 'clientWidth'}[measure]];\r\n\r\n return {\r\n base: base,\r\n padding: 0,\r\n border: 0,\r\n margin: 0\r\n };\r\n }\r\n\r\n // Start with offset property\r\n [\r\n base,\r\n dirA,\r\n dirB\r\n ] = {\r\n width: [\r\n elem.offsetWidth,\r\n 'Left',\r\n 'Right'\r\n ],\r\n height: [\r\n elem.offsetHeight,\r\n 'Top',\r\n 'Bottom'\r\n ]\r\n }[measure];\r\n\r\n computedStyle = getStyle(elem);\r\n paddingA = convertToPx(elem, computedStyle['padding' + dirA]) || 0;\r\n paddingB = convertToPx(elem, computedStyle['padding' + dirB]) || 0;\r\n borderA = convertToPx(elem, computedStyle['border' + dirA + 'Width']) || 0;\r\n borderB = convertToPx(elem, computedStyle['border' + dirB + 'Width']) || 0;\r\n computedMarginA = computedStyle['margin' + dirA];\r\n computedMarginB = computedStyle['margin' + dirB];\r\n\r\n // I do not care for width for now, so this hack is irrelevant\r\n // if ( !supportsPercentMargin )\r\n // computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA )\r\n // computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB )\r\n marginA = convertToPx(elem, computedMarginA) || 0;\r\n marginB = convertToPx(elem, computedMarginB) || 0;\r\n\r\n return {\r\n base: base,\r\n padding: paddingA + paddingB,\r\n border: borderA + borderB,\r\n margin: marginA + marginB\r\n };\r\n }\r\n\r\n function getWidthHeight(elem, direction, measure) {\r\n let computedStyle, result;\r\n\r\n let measurements = getMeasurements(elem, direction);\r\n\r\n if (measurements.base > 0) {\r\n return {\r\n base: measurements.base - measurements.padding - measurements.border,\r\n outer: measurements.base,\r\n outerfull: measurements.base + measurements.margin\r\n }[measure];\r\n }\r\n\r\n // Fall back to computed then uncomputed css if necessary\r\n computedStyle = getStyle(elem);\r\n result = computedStyle[direction];\r\n\r\n if (result < 0 || result === null) {\r\n result = elem.style[direction] || 0;\r\n }\r\n\r\n // Normalize \"\", auto, and prepare for extra\r\n result = parseFloat(result) || 0;\r\n\r\n return {\r\n base: result - measurements.padding - measurements.border,\r\n outer: result,\r\n outerfull: result + measurements.padding + measurements.border + measurements.margin\r\n }[measure];\r\n }\r\n\r\n // define missing methods\r\n return angular.forEach({\r\n before(newElem) {\r\n var children, elem, i, j, parent, ref, self;\r\n self = this;\r\n elem = self[0];\r\n parent = self.parent();\r\n children = parent.contents();\r\n if (children[0] === elem) {\r\n return parent.prepend(newElem);\r\n } else {\r\n for (i = j = 1, ref = children.length - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) {\r\n if (children[i] === elem) {\r\n angular.element(children[i - 1]).after(newElem);\r\n return;\r\n }\r\n }\r\n throw new Error('invalid DOM structure ' + elem.outerHTML);\r\n }\r\n },\r\n height (value){\r\n var self;\r\n self = this;\r\n if (typeof value !== 'undefined') {\r\n if (angular.isNumber(value)) {\r\n value = value + 'px';\r\n }\r\n return css.call(self, 'height', value);\r\n } else {\r\n return getWidthHeight(this[0], 'height', 'base');\r\n }\r\n },\r\n outerHeight(option) {\r\n return getWidthHeight(this[0], 'height', option ? 'outerfull' : 'outer');\r\n },\r\n outerWidth(option) {\r\n return getWidthHeight(this[0], 'width', option ? 'outerfull' : 'outer');\r\n },\r\n\r\n /*\r\n The offset setter method is not implemented\r\n */\r\n offset(value) {\r\n let docElem, win;\r\n let self = this;\r\n let box = {\r\n top: 0,\r\n left: 0\r\n };\r\n let elem = self[0];\r\n let doc = elem && elem.ownerDocument;\r\n\r\n if (arguments.length) {\r\n if (value === undefined) {\r\n return self;\r\n }\r\n // TODO: implement setter\r\n throw new Error('offset setter method is not implemented');\r\n }\r\n\r\n if (!doc) {\r\n return;\r\n }\r\n\r\n docElem = doc.documentElement;\r\n\r\n // TODO: Make sure it's not a disconnected DOM node\r\n\r\n if (elem.getBoundingClientRect != null) {\r\n box = elem.getBoundingClientRect();\r\n }\r\n\r\n win = doc.defaultView || doc.parentWindow;\r\n\r\n return {\r\n top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),\r\n left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)\r\n };\r\n },\r\n scrollTop(value) {\r\n return scrollTo(this, 'top', value);\r\n },\r\n scrollLeft(value) {\r\n return scrollTo(this, 'left', value);\r\n }\r\n }, (value, key) => {\r\n if (!element.prototype[key]) {\r\n return element.prototype[key] = value;\r\n }\r\n });\r\n }\r\n\r\n}\r\n","const hideClassToken = 'ng-ui-scroll-hide';\r\n\r\nexport default class ElementRoutines {\r\n\r\n static addCSSRules() {\r\n const selector = '.' + hideClassToken;\r\n const rules = 'display: none';\r\n const sheet = document.styleSheets[0];\r\n let index;\r\n try {\r\n index = sheet.cssRules.length;\r\n } catch (err) {\r\n index = 0;\r\n }\r\n if('insertRule' in sheet) {\r\n sheet.insertRule(selector + '{' + rules + '}', index);\r\n }\r\n else if('addRule' in sheet) {\r\n sheet.addRule(selector, rules, index);\r\n }\r\n }\r\n\r\n constructor($injector, $q) {\r\n this.$animate = ($injector.has && $injector.has('$animate')) ? $injector.get('$animate') : null;\r\n this.isAngularVersionLessThen1_3 = angular.version.major === 1 && angular.version.minor < 3;\r\n this.$q = $q;\r\n }\r\n\r\n hideElement(wrapper) {\r\n wrapper.element.addClass(hideClassToken);\r\n }\r\n\r\n showElement(wrapper) {\r\n wrapper.element.removeClass(hideClassToken);\r\n }\r\n\r\n insertElement(newElement, previousElement) {\r\n previousElement.after(newElement);\r\n return [];\r\n }\r\n\r\n removeElement(wrapper) {\r\n wrapper.element.remove();\r\n wrapper.scope.$destroy();\r\n return [];\r\n }\r\n\r\n insertElementAnimated(newElement, previousElement) {\r\n if (!this.$animate) {\r\n return this.insertElement(newElement, previousElement);\r\n }\r\n\r\n if (this.isAngularVersionLessThen1_3) {\r\n const deferred = this.$q.defer();\r\n // no need for parent - previous element is never null\r\n this.$animate.enter(newElement, null, previousElement, () => deferred.resolve());\r\n\r\n return [deferred.promise];\r\n }\r\n\r\n // no need for parent - previous element is never null\r\n return [this.$animate.enter(newElement, null, previousElement)];\r\n }\r\n\r\n removeElementAnimated(wrapper) {\r\n if (!this.$animate) {\r\n return this.removeElement(wrapper);\r\n }\r\n\r\n if (this.isAngularVersionLessThen1_3) {\r\n const deferred = this.$q.defer();\r\n this.$animate.leave(wrapper.element, () => {\r\n wrapper.scope.$destroy();\r\n return deferred.resolve();\r\n });\r\n\r\n return [deferred.promise];\r\n }\r\n\r\n return [(this.$animate.leave(wrapper.element)).then(() => wrapper.scope.$destroy())];\r\n }\r\n}","export const OPERATIONS = {\n PREPEND: 'prepend',\n APPEND: 'append',\n INSERT: 'insert',\n REMOVE: 'remove',\n NONE: 'none'\n};\n","import { OPERATIONS } from './utils';\r\n\r\nexport default function ScrollBuffer(elementRoutines, bufferSize, startIndex) {\r\n const buffer = Object.create(Array.prototype);\r\n\r\n angular.extend(buffer, {\r\n size: bufferSize,\r\n\r\n reset(startIndex) {\r\n buffer.remove(0, buffer.length);\r\n buffer.eof = false;\r\n buffer.bof = false;\r\n buffer.first = startIndex;\r\n buffer.next = startIndex;\r\n buffer.minIndex = startIndex;\r\n buffer.maxIndex = startIndex;\r\n buffer.minIndexUser = null;\r\n buffer.maxIndexUser = null;\r\n },\r\n\r\n append(items) {\r\n items.forEach((item) => {\r\n ++buffer.next;\r\n buffer.insert(OPERATIONS.APPEND, item);\r\n });\r\n buffer.maxIndex = buffer.eof ? buffer.next - 1 : Math.max(buffer.next - 1, buffer.maxIndex);\r\n },\r\n\r\n prepend(items, immutableTop) {\r\n items.reverse().forEach((item) => {\r\n if (immutableTop) {\r\n ++buffer.next;\r\n }\r\n else {\r\n --buffer.first;\r\n }\r\n buffer.insert(OPERATIONS.PREPEND, item);\r\n });\r\n buffer.minIndex = buffer.bof ? buffer.minIndex = buffer.first : Math.min(buffer.first, buffer.minIndex);\r\n },\r\n\r\n /**\r\n * inserts wrapped element in the buffer\r\n * the first argument is either operation keyword (see below) or a number for operation 'insert'\r\n * for insert the number is the index for the buffer element the new one have to be inserted after\r\n * operations: 'append', 'prepend', 'insert', 'remove', 'none'\r\n */\r\n insert(operation, item, shiftTop) {\r\n const wrapper = {\r\n item: item\r\n };\r\n\r\n if (operation % 1 === 0) { // it is an insert\r\n wrapper.op = OPERATIONS.INSERT;\r\n buffer.splice(operation, 0, wrapper);\r\n if (shiftTop) {\r\n buffer.first--;\r\n }\r\n else {\r\n buffer.next++;\r\n }\r\n } else {\r\n wrapper.op = operation;\r\n switch (operation) {\r\n case OPERATIONS.APPEND:\r\n buffer.push(wrapper);\r\n break;\r\n case OPERATIONS.PREPEND:\r\n buffer.unshift(wrapper);\r\n break;\r\n }\r\n }\r\n },\r\n\r\n // removes elements from buffer\r\n remove(arg1, arg2) {\r\n if (angular.isNumber(arg1)) {\r\n // removes items from arg1 (including) through arg2 (excluding)\r\n for (let i = arg1; i < arg2; i++) {\r\n elementRoutines.removeElement(buffer[i]);\r\n }\r\n return buffer.splice(arg1, arg2 - arg1);\r\n }\r\n // removes single item (wrapper) from the buffer\r\n buffer.splice(buffer.indexOf(arg1), 1);\r\n if (arg1.shiftTop && buffer.first === this.getAbsMinIndex()) {\r\n this.incrementMinIndex();\r\n }\r\n else {\r\n this.decrementMaxIndex();\r\n }\r\n if (arg1.shiftTop) {\r\n buffer.first++;\r\n }\r\n else {\r\n buffer.next--;\r\n }\r\n if (!buffer.length) {\r\n buffer.minIndex = Math.min(buffer.maxIndex, buffer.minIndex);\r\n }\r\n\r\n return elementRoutines.removeElementAnimated(arg1);\r\n },\r\n\r\n incrementMinIndex() {\r\n if (buffer.minIndexUser !== null) {\r\n if (buffer.minIndex > buffer.minIndexUser) {\r\n buffer.minIndexUser++;\r\n return;\r\n }\r\n if (buffer.minIndex === buffer.minIndexUser) {\r\n buffer.minIndexUser++;\r\n }\r\n }\r\n buffer.minIndex++;\r\n },\r\n\r\n decrementMaxIndex() {\r\n if (buffer.maxIndexUser !== null && buffer.maxIndex <= buffer.maxIndexUser) {\r\n buffer.maxIndexUser--;\r\n }\r\n buffer.maxIndex--;\r\n },\r\n\r\n getAbsMinIndex() {\r\n if (buffer.minIndexUser !== null) {\r\n return Math.min(buffer.minIndexUser, buffer.minIndex);\r\n }\r\n return buffer.minIndex;\r\n },\r\n\r\n getAbsMaxIndex() {\r\n if (buffer.maxIndexUser !== null) {\r\n return Math.max(buffer.maxIndexUser, buffer.maxIndex);\r\n }\r\n return buffer.maxIndex;\r\n },\r\n\r\n effectiveHeight(elements) {\r\n if (!elements.length) {\r\n return 0;\r\n }\r\n let top = Number.MAX_VALUE;\r\n let bottom = Number.NEGATIVE_INFINITY;\r\n elements.forEach((wrapper) => {\r\n if (wrapper.element[0].offsetParent) {\r\n // element style is not display:none\r\n top = Math.min(top, wrapper.element.offset().top);\r\n bottom = Math.max(bottom, wrapper.element.offset().top + wrapper.element.outerHeight(true));\r\n }\r\n });\r\n return Math.max(0, bottom - top);\r\n },\r\n\r\n getItems() {\r\n return buffer.filter(item => item.op === OPERATIONS.NONE);\r\n },\r\n\r\n getFirstItem() {\r\n const list = buffer.getItems();\r\n if (!list.length) {\r\n return null;\r\n }\r\n return list[0].item;\r\n },\r\n\r\n getLastItem() {\r\n const list = buffer.getItems();\r\n if (!list.length) {\r\n return null;\r\n }\r\n return list[list.length - 1].item;\r\n }\r\n\r\n });\r\n\r\n buffer.reset(startIndex);\r\n\r\n return buffer;\r\n}\r\n","// Can't just extend the Array, due to Babel does not support built-in classes extending\r\n// This solution was taken from https://stackoverflow.com/questions/46897414/es6-class-extends-array-workaround-for-es5-babel-transpile\r\nclass CacheProto {\r\n add(item) {\r\n for (let i = this.length - 1; i >= 0; i--) {\r\n if (this[i].index === item.scope.$index) {\r\n this[i].height = item.element.outerHeight();\r\n return;\r\n }\r\n }\r\n this.push({\r\n index: item.scope.$index,\r\n height: item.element.outerHeight()\r\n });\r\n this.sort((a, b) => ((a.index < b.index) ? -1 : ((a.index > b.index) ? 1 : 0)));\r\n }\r\n\r\n remove(argument, _shiftTop) {\r\n const index = argument % 1 === 0 ? argument : argument.scope.$index;\r\n const shiftTop = argument % 1 === 0 ? _shiftTop : argument.shiftTop;\r\n for (let i = this.length - 1; i >= 0; i--) {\r\n if (this[i].index === index) {\r\n this.splice(i, 1);\r\n break;\r\n }\r\n }\r\n if (!shiftTop) {\r\n for (let i = this.length - 1; i >= 0; i--) {\r\n if (this[i].index > index) {\r\n this[i].index--;\r\n }\r\n }\r\n }\r\n }\r\n\r\n clear() {\r\n this.length = 0;\r\n }\r\n}\r\n\r\nfunction Cache() {\r\n const instance = [];\r\n instance.push.apply(instance, arguments);\r\n Object.setPrototypeOf(instance, Cache.prototype);\r\n return instance;\r\n}\r\nCache.prototype = Object.create(Array.prototype);\r\nObject.getOwnPropertyNames(CacheProto.prototype).forEach(methodName =>\r\n Cache.prototype[methodName] = CacheProto.prototype[methodName]\r\n);\r\n\r\nfunction generateElement(template) {\r\n if (template.nodeType !== Node.ELEMENT_NODE) {\r\n throw new Error('ui-scroll directive requires an Element node for templating the view');\r\n }\r\n let element;\r\n switch (template.tagName.toLowerCase()) {\r\n case 'dl':\r\n throw new Error(`ui-scroll directive does not support <${template.tagName}> as a repeating tag: ${template.outerHTML}`);\r\n case 'tr':\r\n let table = angular.element('
    ');\r\n element = table.find('tr');\r\n break;\r\n case 'li':\r\n element = angular.element('
  • ');\r\n break;\r\n default:\r\n element = angular.element('
    ');\r\n }\r\n return element;\r\n}\r\n\r\nclass Padding {\r\n constructor(template) {\r\n this.element = generateElement(template);\r\n this.cache = new Cache();\r\n }\r\n\r\n height() {\r\n return this.element.height.apply(this.element, arguments);\r\n }\r\n}\r\n\r\nexport default Padding;","import Padding from './padding';\r\n\r\nexport default function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding) {\r\n let topPadding = null;\r\n let bottomPadding = null;\r\n const viewport = viewportController && viewportController.viewport ? viewportController.viewport : angular.element(window);\r\n const container = viewportController && viewportController.container ? viewportController.container : undefined;\r\n const scope = viewportController && viewportController.scope ? viewportController.scope : $rootScope;\r\n\r\n viewport.css({\r\n 'overflow-anchor': 'none',\r\n 'overflow-y': 'auto',\r\n 'display': 'block'\r\n });\r\n\r\n function bufferPadding() {\r\n return viewport.outerHeight() * padding; // some extra space to initiate preload\r\n }\r\n\r\n angular.extend(viewport, {\r\n getScope() {\r\n return scope;\r\n },\r\n\r\n createPaddingElements(template) {\r\n topPadding = new Padding(template);\r\n bottomPadding = new Padding(template);\r\n element.before(topPadding.element);\r\n element.after(bottomPadding.element);\r\n topPadding.height(0);\r\n bottomPadding.height(0);\r\n },\r\n\r\n applyContainerStyle() {\r\n if (!container) {\r\n return true;\r\n }\r\n if (container !== viewport) {\r\n viewport.css('height', window.getComputedStyle(container[0]).height);\r\n }\r\n return viewport.height() > 0;\r\n },\r\n\r\n bottomDataPos() {\r\n let scrollHeight = viewport[0].scrollHeight;\r\n scrollHeight = scrollHeight != null ? scrollHeight : viewport[0].document.documentElement.scrollHeight;\r\n return scrollHeight - bottomPadding.height();\r\n },\r\n\r\n topDataPos() {\r\n return topPadding.height();\r\n },\r\n\r\n bottomVisiblePos() {\r\n return viewport.scrollTop() + viewport.outerHeight();\r\n },\r\n\r\n topVisiblePos() {\r\n return viewport.scrollTop();\r\n },\r\n\r\n insertElement(e, sibling) {\r\n return elementRoutines.insertElement(e, sibling || topPadding.element);\r\n },\r\n\r\n insertElementAnimated(e, sibling) {\r\n return elementRoutines.insertElementAnimated(e, sibling || topPadding.element);\r\n },\r\n\r\n shouldLoadBottom() {\r\n return !buffer.eof && viewport.bottomDataPos() < viewport.bottomVisiblePos() + bufferPadding();\r\n },\r\n\r\n clipBottom() {\r\n // clip the invisible items off the bottom\r\n let overage = 0;\r\n let overageHeight = 0;\r\n let itemHeight = 0;\r\n let emptySpaceHeight = viewport.bottomDataPos() - viewport.bottomVisiblePos() - bufferPadding();\r\n\r\n for (let i = buffer.length - 1; i >= 0; i--) {\r\n itemHeight = buffer[i].element.outerHeight(true);\r\n if (overageHeight + itemHeight > emptySpaceHeight) {\r\n break;\r\n }\r\n bottomPadding.cache.add(buffer[i]);\r\n overageHeight += itemHeight;\r\n overage++;\r\n }\r\n\r\n if (overage > 0) {\r\n buffer.eof = false;\r\n buffer.remove(buffer.length - overage, buffer.length);\r\n buffer.next -= overage;\r\n viewport.adjustPaddings();\r\n }\r\n },\r\n\r\n shouldLoadTop() {\r\n return !buffer.bof && (viewport.topDataPos() > viewport.topVisiblePos() - bufferPadding());\r\n },\r\n\r\n clipTop() {\r\n // clip the invisible items off the top\r\n let overage = 0;\r\n let overageHeight = 0;\r\n let itemHeight = 0;\r\n let emptySpaceHeight = viewport.topVisiblePos() - viewport.topDataPos() - bufferPadding();\r\n\r\n for (let i = 0; i < buffer.length; i++) {\r\n itemHeight = buffer[i].element.outerHeight(true);\r\n if (overageHeight + itemHeight > emptySpaceHeight) {\r\n break;\r\n }\r\n topPadding.cache.add(buffer[i]);\r\n overageHeight += itemHeight;\r\n overage++;\r\n }\r\n\r\n if (overage > 0) {\r\n // we need to adjust top padding element before items are removed from top\r\n // to avoid strange behaviour of scroll bar during remove top items when we are at the very bottom\r\n topPadding.height(topPadding.height() + overageHeight);\r\n buffer.bof = false;\r\n buffer.remove(0, overage);\r\n buffer.first += overage;\r\n }\r\n },\r\n\r\n adjustPaddings() {\r\n if (!buffer.length) {\r\n return;\r\n }\r\n\r\n // precise heights calculation based on items that are in buffer or that were in buffer once\r\n const visibleItemsHeight = buffer.reduce((summ, item) => summ + item.element.outerHeight(true), 0);\r\n\r\n let topPaddingHeight = 0, topCount = 0;\r\n topPadding.cache.forEach(item => {\r\n if (item.index < buffer.first) {\r\n topPaddingHeight += item.height;\r\n topCount++;\r\n }\r\n });\r\n\r\n let bottomPaddingHeight = 0, bottomCount = 0;\r\n bottomPadding.cache.forEach(item => {\r\n if (item.index >= buffer.next) {\r\n bottomPaddingHeight += item.height;\r\n bottomCount++;\r\n }\r\n });\r\n\r\n const totalHeight = visibleItemsHeight + topPaddingHeight + bottomPaddingHeight;\r\n const averageItemHeight = totalHeight / (topCount + bottomCount + buffer.length);\r\n\r\n // average heights calculation, items that have never been reached\r\n let adjustTopPadding = buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser;\r\n let adjustBottomPadding = buffer.maxIndexUser !== null && buffer.maxIndex < buffer.maxIndexUser;\r\n let topPaddingHeightAdd = adjustTopPadding ? (buffer.minIndex - buffer.minIndexUser) * averageItemHeight : 0;\r\n let bottomPaddingHeightAdd = adjustBottomPadding ? (buffer.maxIndexUser - buffer.maxIndex) * averageItemHeight : 0;\r\n\r\n // paddings combine adjustment\r\n topPadding.height(topPaddingHeight + topPaddingHeightAdd);\r\n bottomPadding.height(bottomPaddingHeight + bottomPaddingHeightAdd);\r\n },\r\n\r\n onAfterMinIndexSet(topPaddingHeightOld) {\r\n // additional scrollTop adjustment in case of datasource.minIndex external set\r\n if (buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser) {\r\n let diff = topPadding.height() - topPaddingHeightOld;\r\n viewport.scrollTop(viewport.scrollTop() + diff);\r\n while((diff -= viewport.scrollTop()) > 0) {\r\n bottomPadding.height(bottomPadding.height() + diff);\r\n viewport.scrollTop(viewport.scrollTop() + diff);\r\n }\r\n }\r\n },\r\n\r\n onAfterPrepend(updates) {\r\n if (!updates.prepended.length) {\r\n return;\r\n }\r\n const height = buffer.effectiveHeight(updates.prepended);\r\n const paddingHeight = topPadding.height() - height;\r\n if (paddingHeight >= 0) {\r\n topPadding.height(paddingHeight);\r\n return;\r\n }\r\n const position = viewport.scrollTop();\r\n const newPosition = position - paddingHeight;\r\n viewport.synthetic = { previous: position, next: newPosition };\r\n topPadding.height(0);\r\n viewport.scrollTop(newPosition);\r\n },\r\n\r\n resetTopPadding() {\r\n topPadding.height(0);\r\n topPadding.cache.clear();\r\n },\r\n\r\n resetBottomPadding() {\r\n bottomPadding.height(0);\r\n bottomPadding.cache.clear();\r\n },\r\n\r\n removeCacheItem(item, shiftTop) {\r\n topPadding.cache.remove(item, shiftTop);\r\n bottomPadding.cache.remove(item, shiftTop);\r\n },\r\n\r\n removeItem(item) {\r\n this.removeCacheItem(item);\r\n return buffer.remove(item);\r\n }\r\n });\r\n\r\n return viewport;\r\n}\r\n","import { OPERATIONS } from './utils';\r\n\r\nclass Adapter {\r\n\r\n constructor($scope, $parse, $attr, viewport, buffer, doAdjust, reload) {\r\n this.$parse = $parse;\r\n this.$attr = $attr;\r\n this.viewport = viewport;\r\n this.buffer = buffer;\r\n\r\n this.doAdjust = doAdjust;\r\n this.reload = reload;\r\n\r\n this.isLoading = false;\r\n this.disabled = false;\r\n\r\n const viewportScope = viewport.getScope();\r\n this.startScope = viewportScope.$parent ? viewportScope : $scope;\r\n\r\n this.publicContext = {};\r\n this.assignAdapter($attr.adapter);\r\n this.generatePublicContext();\r\n }\r\n\r\n assignAdapter(adapterAttr) {\r\n if (!adapterAttr || !(adapterAttr = adapterAttr.replace(/^\\s+|\\s+$/gm, ''))) {\r\n return;\r\n }\r\n let adapterOnScope;\r\n\r\n try {\r\n this.$parse(adapterAttr).assign(this.startScope, {});\r\n adapterOnScope = this.$parse(adapterAttr)(this.startScope);\r\n }\r\n catch (error) {\r\n error.message = `Angular ui-scroll Adapter assignment exception.\\n` +\r\n `Can't parse \"${adapterAttr}\" expression.\\n` +\r\n error.message;\r\n throw error;\r\n }\r\n\r\n angular.extend(adapterOnScope, this.publicContext);\r\n this.publicContext = adapterOnScope;\r\n }\r\n\r\n generatePublicContext() {\r\n // these methods will be accessible out of ui-scroll via user defined adapter\r\n const publicMethods = ['reload', 'applyUpdates', 'append', 'prepend', 'isBOF', 'isEOF', 'isEmpty'];\r\n for (let i = publicMethods.length - 1; i >= 0; i--) {\r\n this.publicContext[publicMethods[i]] = this[publicMethods[i]].bind(this);\r\n }\r\n\r\n // these read-only props will be accessible out of ui-scroll via user defined adapter\r\n const publicProps = ['isLoading', 'topVisible', 'topVisibleElement', 'topVisibleScope', 'bottomVisible', 'bottomVisibleElement', 'bottomVisibleScope'];\r\n for (let i = publicProps.length - 1; i >= 0; i--) {\r\n let property, attr = this.$attr[publicProps[i]];\r\n Object.defineProperty(this, publicProps[i], {\r\n get: () => property,\r\n set: (value) => {\r\n property = value;\r\n this.publicContext[publicProps[i]] = value;\r\n if (attr) {\r\n this.$parse(attr).assign(this.startScope, value);\r\n }\r\n }\r\n });\r\n }\r\n\r\n // read-only immediately calculated public properties\r\n const publicPropsImmediate = ['bufferFirst', 'bufferLast', 'bufferLength'];\r\n for (let i = publicPropsImmediate.length - 1; i >= 0; i--) {\r\n Object.defineProperty(this.publicContext, publicPropsImmediate[i], {\r\n get: () => this[publicPropsImmediate[i]]\r\n });\r\n }\r\n\r\n // non-read-only public property\r\n Object.defineProperty(this.publicContext, 'disabled', {\r\n get: () => this.disabled,\r\n set: (value) => (!(this.disabled = value)) ? this.doAdjust() : null\r\n });\r\n }\r\n\r\n loading(value) {\r\n this.isLoading = value;\r\n }\r\n\r\n isBOF() {\r\n return this.buffer.bof;\r\n }\r\n\r\n isEOF() {\r\n return this.buffer.eof;\r\n }\r\n\r\n isEmpty() {\r\n return !this.buffer.length;\r\n }\r\n\r\n get bufferLength() {\r\n return this.buffer.getItems().length;\r\n }\r\n\r\n get bufferFirst() {\r\n return this.buffer.getFirstItem();\r\n }\r\n\r\n get bufferLast() {\r\n return this.buffer.getLastItem();\r\n }\r\n\r\n append(newItems) {\r\n this.buffer.append(newItems);\r\n this.doAdjust();\r\n this.viewport.clipTop();\r\n this.viewport.clipBottom();\r\n }\r\n\r\n prepend(newItems, options = {}) {\r\n this.buffer.prepend(newItems, options.immutableTop);\r\n this.doAdjust();\r\n this.viewport.clipTop();\r\n this.viewport.clipBottom();\r\n }\r\n\r\n applyUpdates(arg1, arg2, arg3) {\r\n if (typeof arg1 === 'function') {\r\n this.applyUpdatesFunc(arg1, arg2);\r\n } else {\r\n this.applyUpdatesIndex(arg1, arg2, arg3);\r\n }\r\n this.doAdjust();\r\n }\r\n\r\n applyUpdatesFunc(cb, options = {}) {\r\n this.buffer.slice(0).forEach((wrapper) => {\r\n // we need to do it on the buffer clone, because buffer content\r\n // may change as we iterate through\r\n this.applyUpdate(wrapper, cb(wrapper.item, wrapper.scope, wrapper.element), options);\r\n });\r\n }\r\n\r\n applyUpdatesIndex(index, newItems, options = {}) {\r\n if (index % 1 !== 0) {\r\n throw new Error('applyUpdates - ' + index + ' is not a valid index (should be an integer)');\r\n }\r\n const _index = index - this.buffer.first;\r\n\r\n // apply updates only within buffer\r\n if (_index >= 0 && _index < this.buffer.length) {\r\n this.applyUpdate(this.buffer[_index], newItems, options);\r\n }\r\n // out-of-buffer case: deletion may affect Paddings\r\n else if(index >= this.buffer.getAbsMinIndex() && index <= this.buffer.getAbsMaxIndex()) {\r\n if(angular.isArray(newItems) && !newItems.length) {\r\n this.viewport.removeCacheItem(index, !options.immutableTop && index === this.buffer.minIndex);\r\n if (!options.immutableTop && index === this.buffer.getAbsMinIndex()) {\r\n this.buffer.incrementMinIndex();\r\n }\r\n else {\r\n this.buffer.decrementMaxIndex();\r\n }\r\n }\r\n }\r\n }\r\n\r\n applyUpdate(wrapper, newItems, options = {}) {\r\n if (!angular.isArray(newItems)) {\r\n return;\r\n }\r\n let position = this.buffer.indexOf(wrapper);\r\n if (!newItems.reverse().some(newItem => newItem === wrapper.item)) {\r\n wrapper.op = OPERATIONS.REMOVE;\r\n // try to catch \"first\" edge case on remove\r\n if (!options.immutableTop && !newItems.length) {\r\n // this is the first item, or the previous one's part of the \"shift-top\" group\r\n if (\r\n (position === 0 && this.buffer.bof) ||\r\n (position !== 0 && this.buffer[position - 1].shiftTop)\r\n ) {\r\n wrapper.shiftTop = true;\r\n }\r\n }\r\n }\r\n newItems.forEach((newItem) => {\r\n if (newItem === wrapper.item) {\r\n position--;\r\n } else {\r\n // 3 parameter (shiftTop) is to catch \"first\" edge case on insert\r\n this.buffer.insert(position + 1, newItem, !options.immutableTop && position === -1);\r\n }\r\n });\r\n }\r\n\r\n calculateProperties() {\r\n let rowTop = null, topHeight = 0;\r\n let topDone = false, bottomDone = false;\r\n const length = this.buffer.length;\r\n\r\n for (let i = 0; i < length; i++) {\r\n const item = this.buffer[i];\r\n const itemTop = item.element.offset().top;\r\n\r\n if (rowTop !== itemTop) { // a new row condition\r\n const itemHeight = item.element.outerHeight(true);\r\n const top = this.viewport.topDataPos() + topHeight + itemHeight;\r\n\r\n if (!topDone && top > this.viewport.topVisiblePos()) {\r\n topDone = true;\r\n this['topVisible'] = item.item;\r\n this['topVisibleElement'] = item.element;\r\n this['topVisibleScope'] = item.scope;\r\n }\r\n if (!bottomDone && (top >= this.viewport.bottomVisiblePos() || (i === length - 1 && this.isEOF()))) {\r\n bottomDone = true;\r\n this['bottomVisible'] = item.item;\r\n this['bottomVisibleElement'] = item.element;\r\n this['bottomVisibleScope'] = item.scope;\r\n }\r\n topHeight += itemHeight;\r\n }\r\n rowTop = itemTop;\r\n\r\n if (topDone && bottomDone) {\r\n break;\r\n }\r\n }\r\n }\r\n\r\n}\r\n\r\nexport default Adapter;\r\n","import JQLiteExtras from './modules/jqLiteExtras';\nimport ElementRoutines from './modules/elementRoutines.js';\nimport ScrollBuffer from './modules/buffer.js';\nimport Viewport from './modules/viewport.js';\nimport Adapter from './modules/adapter.js';\nimport { OPERATIONS } from './modules/utils';\n\nangular.module('ui.scroll', [])\n\n .constant('JQLiteExtras', JQLiteExtras)\n .run(['JQLiteExtras', (JQLiteExtras) => {\n const elt = angular.element;\n !(window.jQuery && elt.fn && elt.fn.jquery) ? (new JQLiteExtras()).registerFor(elt) : null;\n ElementRoutines.addCSSRules();\n }])\n\n .directive('uiScrollViewport', function () {\n return {\n restrict: 'A',\n controller: [\n '$scope',\n '$element',\n function (scope, element) {\n this.container = element;\n this.viewport = element;\n this.scope = scope;\n\n angular.forEach(element.children(), child => {\n if (child.tagName.toLowerCase() === 'tbody') {\n this.viewport = angular.element(child);\n }\n });\n\n return this;\n }\n ]\n };\n })\n\n .directive('uiScroll', [\n '$log',\n '$injector',\n '$rootScope',\n '$timeout',\n '$interval',\n '$q',\n '$parse',\n function (console, $injector, $rootScope, $timeout, $interval, $q, $parse) {\n\n return {\n require: ['?^uiScrollViewport'],\n restrict: 'A',\n transclude: 'element',\n priority: 1000,\n terminal: true,\n link: link\n };\n\n function link($scope, element, $attr, controllers, linker) {\n const match = $attr.uiScroll.match(/^\\s*(\\w+)\\s+in\\s+([(\\w|\\$)\\.]+)\\s*$/);\n if (!match) {\n throw new Error('Expected uiScroll in form of \\'_item_ in _datasource_\\' but got \\'' + $attr.uiScroll + '\\'');\n }\n\n function parseNumber(value, defaultValue, isFloat) {\n if (!isFloat) {\n value = value === null ? defaultValue : Math.floor(value);\n }\n return isNaN(value) ? defaultValue : value;\n }\n\n function parseNumericAttr(value, defaultValue, isFloat) {\n const result = $parse(value)($scope);\n return parseNumber(result, defaultValue, isFloat);\n }\n\n function parseBooleanAttr(value, defaultValue) {\n const result = $parse(value)($scope);\n return typeof result === 'boolean' ? result : defaultValue;\n }\n\n const BUFFER_MIN = 3;\n const BUFFER_DEFAULT = 10;\n const PADDING_MIN = 0.3;\n const PADDING_DEFAULT = 0.5;\n const HANDLE_INERTIA_DEFAULT = true;\n const START_INDEX_DEFAULT = 1;\n const MAX_VIEWPORT_DELAY = 500;\n const VIEWPORT_POLLING_INTERVAL = 50;\n\n let datasource = null;\n const itemName = match[1];\n const datasourceName = match[2];\n const viewportController = controllers[0];\n const bufferSize = Math.max(BUFFER_MIN, parseNumericAttr($attr.bufferSize, BUFFER_DEFAULT));\n const padding = Math.max(PADDING_MIN, parseNumericAttr($attr.padding, PADDING_DEFAULT, true));\n const handleInertia = parseBooleanAttr($attr.handleInertia, HANDLE_INERTIA_DEFAULT);\n let startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT);\n let ridActual = 0; // current data revision id\n let pending = [];\n\n const elementRoutines = new ElementRoutines($injector, $q);\n const buffer = new ScrollBuffer(elementRoutines, bufferSize, startIndex);\n const viewport = new Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding);\n const adapter = new Adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload);\n\n if (viewportController) {\n viewportController.adapter = adapter;\n }\n\n const isDatasourceValid = () =>\n Object.prototype.toString.call(datasource) === '[object Object]' && typeof datasource.get === 'function';\n\n datasource = $parse(datasourceName)($scope); // try to get datasource on scope\n if (!isDatasourceValid()) {\n datasource = $injector.get(datasourceName); // try to inject datasource as service\n if (!isDatasourceValid()) {\n throw new Error(datasourceName + ' is not a valid datasource');\n }\n }\n\n let onRenderHandlers = [];\n function onRenderHandlersRunner() {\n onRenderHandlers.forEach(handler => handler.run());\n onRenderHandlers = [];\n }\n function persistDatasourceIndex(datasource, propName) {\n let getter;\n // need to postpone min/maxIndexUser processing if the view is empty\n if(angular.isNumber(datasource[propName])) {\n getter = datasource[propName];\n if(angular.isNumber(getter)) {\n onRenderHandlers = onRenderHandlers.filter(handler => handler.id !== propName);\n onRenderHandlers.push({\n id: propName,\n run: () => datasource[propName] = getter\n });\n }\n }\n }\n\n function defineDatasourceIndex(datasource, propName, propUserName) {\n const descriptor = Object.getOwnPropertyDescriptor(datasource, propName);\n if (descriptor && (descriptor.set || descriptor.get)) {\n return;\n }\n let getter;\n persistDatasourceIndex(datasource, propName);\n Object.defineProperty(datasource, propName, {\n set: (value) => {\n getter = value;\n if(pending.length && !buffer.length) {\n persistDatasourceIndex(datasource, propName);\n return;\n }\n buffer[propUserName] = value;\n const topPaddingHeightOld = viewport.topDataPos();\n viewport.adjustPaddings();\n if (propName === 'minIndex') {\n viewport.onAfterMinIndexSet(topPaddingHeightOld);\n }\n },\n get: () => getter\n });\n }\n\n defineDatasourceIndex(datasource, 'minIndex', 'minIndexUser');\n defineDatasourceIndex(datasource, 'maxIndex', 'maxIndexUser');\n\n const fetchNext = (datasource.get.length !== 2) ?\n (success) => datasource.get(buffer.next, bufferSize, success) :\n (success) => {\n datasource.get({\n index: buffer.next,\n append: buffer.length ? buffer[buffer.length - 1].item : void 0,\n count: bufferSize\n }, success);\n };\n\n const fetchPrevious = (datasource.get.length !== 2) ?\n (success) => datasource.get(buffer.first - bufferSize, bufferSize, success) :\n (success) => {\n datasource.get({\n index: buffer.first - bufferSize,\n prepend: buffer.length ? buffer[0].item : void 0,\n count: bufferSize\n }, success);\n };\n\n const initialize = () => {\n let tryCount = 0;\n if(!viewport.applyContainerStyle()) {\n const timer = $interval(() => {\n tryCount++;\n if(viewport.applyContainerStyle()) {\n $interval.cancel(timer);\n doAdjust();\n }\n if(tryCount * VIEWPORT_POLLING_INTERVAL >= MAX_VIEWPORT_DELAY) {\n $interval.cancel(timer);\n throw Error(`ui-scroll directive requires a viewport with non-zero height in ${MAX_VIEWPORT_DELAY}ms`);\n }\n }, VIEWPORT_POLLING_INTERVAL);\n }\n else {\n doAdjust();\n }\n };\n\n /**\n * Build padding elements\n *\n * Calling linker is the only way I found to get access to the tag name of the template\n * to prevent the directive scope from pollution a new scope is created and destroyed\n * right after the builder creation is completed\n */\n linker((clone, scope) => {\n viewport.createPaddingElements(clone[0]);\n // we do not include the clone in the DOM. It means that the nested directives will not\n // be able to reach the parent directives, but in this case it is intentional because we\n // created the clone to access the template tag name\n scope.$destroy();\n clone.remove();\n });\n\n $scope.$on('$destroy', () => {\n unbindEvents();\n viewport.off('mousewheel', wheelHandler);\n });\n\n viewport.on('mousewheel', wheelHandler);\n\n initialize();\n\n /* Private function definitions */\n\n function isInvalid(rid) {\n return (rid && rid !== ridActual) || $scope.$$destroyed;\n }\n\n function bindEvents() {\n viewport.on('resize', resizeAndScrollHandler);\n viewport.on('scroll', resizeAndScrollHandler);\n }\n\n function unbindEvents() {\n viewport.off('resize', resizeAndScrollHandler);\n viewport.off('scroll', resizeAndScrollHandler);\n }\n\n function reload() {\n unbindEvents();\n viewport.resetTopPadding();\n viewport.resetBottomPadding();\n if (arguments.length) {\n startIndex = parseNumber(arguments[0], START_INDEX_DEFAULT, false);\n }\n buffer.reset(startIndex);\n persistDatasourceIndex(datasource, 'minIndex');\n persistDatasourceIndex(datasource, 'maxIndex');\n doAdjust();\n }\n\n function isElementVisible(wrapper) {\n return wrapper.element.height() && wrapper.element[0].offsetParent;\n }\n\n function visibilityWatcher(wrapper) {\n if (isElementVisible(wrapper)) {\n buffer.forEach((item) => {\n if (typeof item.unregisterVisibilityWatcher === 'function') {\n item.unregisterVisibilityWatcher();\n delete item.unregisterVisibilityWatcher;\n }\n });\n if (!pending.length) {\n $timeout(() => doAdjust());\n }\n }\n }\n\n function insertWrapperContent(wrapper, insertAfter) {\n createElement(wrapper, insertAfter, viewport.insertElement);\n if (!isElementVisible(wrapper)) {\n wrapper.unregisterVisibilityWatcher = wrapper.scope.$watch(() => visibilityWatcher(wrapper));\n }\n elementRoutines.hideElement(wrapper); // hide inserted elements before data binding\n }\n\n function createElement(wrapper, insertAfter, insertElement) {\n let promises = null;\n const sibling = (insertAfter > 0) ? buffer[insertAfter - 1].element : undefined;\n linker((clone, scope) => {\n promises = insertElement(clone, sibling);\n wrapper.element = clone;\n wrapper.scope = scope;\n scope[itemName] = wrapper.item;\n });\n // ui-scroll-grid apply\n if (adapter.transform) {\n const tdInitializer = wrapper.scope.uiScrollTdInitializer;\n if (tdInitializer && tdInitializer.linking) {\n adapter.transform(wrapper.scope, wrapper.element);\n } else {\n wrapper.scope.uiScrollTdInitializer = {\n onLink: () => adapter.transform(wrapper.scope, wrapper.element),\n scope: wrapper.scope\n };\n }\n }\n return promises;\n }\n\n function updateDOM() {\n let promises = [];\n const toBePrepended = [];\n const toBeRemoved = [];\n const inserted = [];\n\n buffer.forEach((wrapper, i) => {\n switch (wrapper.op) {\n case OPERATIONS.PREPEND:\n toBePrepended.unshift(wrapper);\n break;\n case OPERATIONS.APPEND:\n insertWrapperContent(wrapper, i);\n wrapper.op = OPERATIONS.NONE;\n inserted.push(wrapper);\n break;\n case OPERATIONS.INSERT:\n promises = promises.concat(createElement(wrapper, i, viewport.insertElementAnimated));\n wrapper.op = OPERATIONS.NONE;\n inserted.push(wrapper);\n break;\n case OPERATIONS.REMOVE:\n toBeRemoved.push(wrapper);\n }\n });\n\n toBeRemoved.forEach((wrapper) => promises = promises.concat(viewport.removeItem(wrapper)));\n\n if (toBePrepended.length)\n toBePrepended.forEach((wrapper) => {\n insertWrapperContent(wrapper);\n wrapper.op = OPERATIONS.NONE;\n });\n\n buffer.forEach((item, i) => item.scope.$index = buffer.first + i);\n\n return {\n prepended: toBePrepended,\n removed: toBeRemoved,\n inserted: inserted,\n animated: promises\n };\n\n }\n\n function updatePaddings(rid, updates) {\n // schedule another doAdjust after animation completion\n if (updates.animated.length) {\n $q.all(updates.animated).then(() => {\n viewport.adjustPaddings();\n doAdjust(rid);\n });\n } else {\n viewport.adjustPaddings();\n }\n }\n\n function enqueueFetch(rid, updates) {\n if (viewport.shouldLoadBottom()) {\n if (!updates || buffer.effectiveHeight(updates.inserted) > 0) {\n // this means that at least one item appended in the last batch has height > 0\n if (pending.push(true) === 1) {\n adapter.loading(true);\n fetch(rid);\n }\n }\n } else if (viewport.shouldLoadTop()) {\n if ((!updates || buffer.effectiveHeight(updates.prepended) > 0) || pending[0]) {\n // this means that at least one item appended in the last batch has height > 0\n // pending[0] = true means that previous fetch was appending. We need to force at least one prepend\n // BTW there will always be at least 1 element in the pending array because bottom is fetched first\n if (pending.push(false) === 1) {\n adapter.loading(true);\n fetch(rid);\n }\n }\n }\n }\n\n function processUpdates() {\n const updates = updateDOM();\n\n // We need the item bindings to be processed before we can do adjustments\n !$scope.$$phase && !$rootScope.$$phase && $scope.$digest();\n\n updates.inserted.forEach(w => elementRoutines.showElement(w));\n updates.prepended.forEach(w => elementRoutines.showElement(w));\n return updates;\n }\n\n function doAdjust(rid) {\n if (!rid) { // dismiss pending requests\n pending = [];\n rid = ++ridActual;\n }\n\n const updates = processUpdates();\n\n if (isInvalid(rid)) {\n return;\n }\n\n updatePaddings(rid, updates);\n enqueueFetch(rid);\n\n if (!pending.length) {\n adapter.calculateProperties();\n }\n }\n\n function doAdjustAfterFetch(rid) {\n const updates = processUpdates();\n\n viewport.onAfterPrepend(updates);\n\n if (isInvalid(rid)) {\n return;\n }\n\n updatePaddings(rid, updates);\n onRenderHandlersRunner();\n enqueueFetch(rid, updates);\n pending.shift();\n\n if (pending.length)\n fetch(rid);\n else {\n adapter.loading(false);\n bindEvents();\n adapter.calculateProperties();\n }\n }\n\n function fetch(rid) {\n if (pending[0]) {// scrolling down\n if (buffer.length && !viewport.shouldLoadBottom()) {\n doAdjustAfterFetch(rid);\n } else {\n fetchNext((result) => {\n if (isInvalid(rid)) {\n return;\n }\n\n if (result.length < bufferSize) {\n buffer.eof = true;\n }\n\n if (result.length > 0) {\n viewport.clipTop();\n buffer.append(result);\n }\n\n doAdjustAfterFetch(rid);\n });\n }\n } else { // scrolling up\n if (buffer.length && !viewport.shouldLoadTop()) {\n doAdjustAfterFetch(rid);\n } else {\n fetchPrevious((result) => {\n if (isInvalid(rid)) {\n return;\n }\n\n if (result.length < bufferSize) {\n buffer.bof = true;\n // log 'bof is reached'\n }\n\n if (result.length > 0) {\n if (buffer.length) {\n viewport.clipBottom();\n }\n buffer.prepend(result);\n }\n\n doAdjustAfterFetch(rid);\n });\n }\n }\n }\n\n function fixInertia() {\n if (!viewport.synthetic) {\n return;\n }\n const oldPosition = viewport.synthetic.previous;\n const newPosition = viewport.synthetic.next;\n if (viewport.scrollTop() !== newPosition) {\n requestAnimationFrame(() => {\n const position = viewport.scrollTop();\n const diff = oldPosition - position;\n if (diff > 0) { // inertia over synthetic\n viewport.scrollTop(newPosition - diff);\n } else {\n viewport.scrollTop(newPosition);\n }\n viewport.synthetic = null;\n });\n return true;\n }\n viewport.synthetic = null;\n }\n\n function resizeAndScrollHandler() {\n if (handleInertia && fixInertia()) {\n return;\n }\n if (!$rootScope.$$phase && !adapter.isLoading && !adapter.disabled) {\n\n enqueueFetch(ridActual);\n\n if (pending.length) {\n unbindEvents();\n } else {\n adapter.calculateProperties();\n !$scope.$$phase && $scope.$digest();\n }\n }\n }\n\n function wheelHandler(event) {\n if (!adapter.disabled) {\n const scrollTop = viewport[0].scrollTop;\n const yMax = viewport[0].scrollHeight - viewport[0].clientHeight;\n\n if ((scrollTop === 0 && !buffer.bof) || (scrollTop === yMax && !buffer.eof)) {\n event.preventDefault();\n }\n }\n }\n }\n\n }\n ]);\n"],"sourceRoot":""} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..bebbcc56 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,9909 @@ +{ + "name": "angular-ui-scroll", + "version": "1.8.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.3.tgz", + "integrity": "sha512-w445QGI2qd0E0GlSnq6huRZWPMmQGCp5gd5ZWS4hagn0EiwzxD5QMFkpchyusAyVC1n27OKXzQ0/88aVU9n4xQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.3", + "@babel/helpers": "^7.2.0", + "@babel/parser": "^7.3.3", + "@babel/template": "^7.2.2", + "@babel/traverse": "^7.2.2", + "@babel/types": "^7.3.3", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.3.tgz", + "integrity": "sha512-aEADYwRRZjJyMnKN7llGIlircxTCofm3dtV5pmY6ob18MSIuipHpA2yZWkPlycwu5HJcx/pADS3zssd8eY7/6A==", + "dev": true, + "requires": { + "@babel/types": "^7.3.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz", + "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", + "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.7.0" + }, + "dependencies": { + "@babel/helper-annotate-as-pure": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "dev": true + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + } + } + }, + "@babel/helper-define-map": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz", + "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.0.0", + "lodash": "^4.17.10" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz", + "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", + "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", + "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/template": "^7.2.2", + "@babel/types": "^7.2.2", + "lodash": "^4.17.10" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", + "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz", + "integrity": "sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.2.3", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "dev": true, + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.3.1.tgz", + "integrity": "sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==", + "dev": true, + "requires": { + "@babel/template": "^7.1.2", + "@babel/traverse": "^7.1.5", + "@babel/types": "^7.3.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.3.tgz", + "integrity": "sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", + "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.2.tgz", + "integrity": "sha512-DjeMS+J2+lpANkYLLO+m6GjoTMygYglKmRe6cDTbFv3L9i6mmiE8fe6B8MtCSLZpVXscD5kn7s6SgtHrDoBWoA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz", + "integrity": "sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.2.0" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", + "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz", + "integrity": "sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz", + "integrity": "sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.10" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.3.3.tgz", + "integrity": "sha512-n0CLbsg7KOXsMF4tSTLCApNMoXk0wOPb0DYfsOO1e7SfIb9gOyfbpKI2MZ+AXfqvlfzq2qsflJ1nEns48Caf2w==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.1.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.3.2.tgz", + "integrity": "sha512-Lrj/u53Ufqxl/sGxyjsJ2XNtNuEjDyjpqdhMNh5aZ+XFOdThL46KBj27Uem4ggoezSYBxKWAil6Hu8HtwqesYw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz", + "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", + "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz", + "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz", + "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", + "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", + "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz", + "integrity": "sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", + "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz", + "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", + "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.3.3.tgz", + "integrity": "sha512-IrIP25VvXWu/VlBWTpsjGptpomtIkYrN/3aDp4UKm7xK6UxZY88kcJ1UwETbzHAlwN21MnNfwlar0u8y3KpiXw==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.1.0", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz", + "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==", + "dev": true, + "requires": { + "regenerator-transform": "^0.13.3" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", + "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", + "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz", + "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" + } + }, + "@babel/preset-env": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.1.tgz", + "integrity": "sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.3.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.2.0", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.2.0", + "@babel/plugin-transform-classes": "^7.2.0", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.2.0", + "@babel/plugin-transform-dotall-regex": "^7.2.0", + "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.2.0", + "@babel/plugin-transform-function-name": "^7.2.0", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.2.0", + "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@babel/plugin-transform-modules-systemjs": "^7.2.0", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.3.0", + "@babel/plugin-transform-new-target": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-parameters": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.2.0", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.2.0", + "browserslist": "^4.3.4", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.3.0" + } + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + } + }, + "@babel/types": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.3.tgz", + "integrity": "sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@npmcli/move-file": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", + "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz", + "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", + "dev": true + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } + } + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", + "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000929", + "electron-to-chromium": "^1.3.103", + "node-releases": "^1.1.3" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000938", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000938.tgz", + "integrity": "sha512-ekW8NQ3/FvokviDxhdKLZZAx7PptXNwxKgXtnR5y+PR3hckwuP3yJ1Ir+4/c97dsHNqtAyfKUGdw8P4EYzBNgw==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "clean-webpack-plugin": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-0.1.19.tgz", + "integrity": "sha512-M1Li5yLHECcN2MahoreuODul5LkjohJGFxLPTjl3j1ttKrF5rgjZET1SJduuqxLAuT1gAPOdkhg03qcaaU1KeA==", + "dev": true, + "requires": { + "rimraf": "^2.6.1" + } + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "^7.1.1" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + }, + "dependencies": { + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + } + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-webpack-plugin": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.1.1.tgz", + "integrity": "sha512-4TlkHFYkrZ3WppLA5XkPmBLI5lnEpFsXvpeqxCf5PzkratZiVklNXsvoQkLhUU43q7ZL3AOXtaHAd9jLNJoU0w==", + "dev": true, + "requires": { + "cacache": "^15.0.5", + "fast-glob": "^3.2.4", + "find-cache-dir": "^3.3.1", + "glob-parent": "^5.1.1", + "globby": "^11.0.1", + "loader-utils": "^2.0.0", + "normalize-path": "^3.0.0", + "p-limit": "^3.0.2", + "schema-utils": "^2.7.1", + "serialize-javascript": "^5.0.1", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", + "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "cacache": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", + "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.0", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "ssri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", + "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.113", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz", + "integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "enhanced-resolve": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", + "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "dev": true + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "html-entities": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isbinaryfile": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", + "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jasmine-core": { + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", + "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=", + "dev": true + }, + "jest-worker": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", + "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "jshint": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.10.1.tgz", + "integrity": "sha512-9GpPfKeffYBl7oBDX2lHPG16j0AM7D2bn3aLy9DaWTr6CWa0i/7UGhX8WLZ7V14QQnnr4hXbjauTLYg06F+HYw==", + "dev": true, + "requires": { + "cli": "~1.0.0", + "console-browserify": "1.1.x", + "exit": "0.1.x", + "htmlparser2": "3.8.x", + "lodash": "~4.17.10", + "minimatch": "~3.0.2", + "shelljs": "0.3.x", + "strip-json-comments": "1.0.x" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "karma": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/karma/-/karma-5.0.5.tgz", + "integrity": "sha512-Q4Su7kNwkTgqS+KbSCYgH0p4a/0JIxVLyp7qKNV7vgPNhIF4kIoh0GlUfMKpw67BrR3hgPQSJoxgF7xnzUtPpg==", + "dev": true, + "requires": { + "body-parser": "^1.16.1", + "braces": "^3.0.2", + "chokidar": "^3.0.0", + "colors": "^1.1.0", + "connect": "^3.6.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "flatted": "^2.0.0", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^4.0.2", + "lodash": "^4.17.14", + "log4js": "^4.0.0", + "mime": "^2.3.1", + "minimatch": "^3.0.2", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "socket.io": "2.1.1", + "source-map": "^0.6.1", + "tmp": "0.0.33", + "ua-parser-js": "0.7.21", + "yargs": "^15.3.1" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "^1.0.0", + "which": "^1.2.1" + } + }, + "karma-firefox-launcher": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz", + "integrity": "sha512-LbZ5/XlIXLeQ3cqnCbYLn+rOVhuMIK9aZwlP6eOLGzWdo1UVp7t6CN3DP4SafiRLjexKwHeKHDm0c38Mtd3VxA==", + "dev": true + }, + "karma-jasmine": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-2.0.1.tgz", + "integrity": "sha512-iuC0hmr9b+SNn1DaUD2QEYtUxkS1J+bSJSn7ejdEexs7P8EYvA1CWkEdrDQ+8jVH3AgWlCNwjYsT1chjcNW9lA==", + "dev": true, + "requires": { + "jasmine-core": "^3.3" + }, + "dependencies": { + "jasmine-core": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.3.0.tgz", + "integrity": "sha512-3/xSmG/d35hf80BEN66Y6g9Ca5l/Isdeg/j6zvbTYlTzeKinzmaTM4p9am5kYqOmE05D7s1t8FGjzdSnbUbceA==", + "dev": true + } + } + }, + "karma-sourcemap-loader": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz", + "integrity": "sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "karma-webpack": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-4.0.2.tgz", + "integrity": "sha512-970/okAsdUOmiMOCY8sb17A2I8neS25Ad9uhyK3GHgmRSIFJbDcNEFE8dqqUhNe9OHiCC9k3DMrSmtd/0ymP1A==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.1.0", + "neo-async": "^2.6.1", + "schema-utils": "^1.0.0", + "source-map": "^0.7.3", + "webpack-dev-middleware": "^3.7.0" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "log4js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-4.5.1.tgz", + "integrity": "sha512-EEEgFcE9bLgaYUKuozyFfytQM2wDHtXn4tAN41pkaxpNjAykv11GVdeI4tHtmPWW4Xrgh9R/2d7XYghDVjbKKw==", + "dev": true, + "requires": { + "date-format": "^2.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.0", + "rfdc": "^1.1.4", + "streamroller": "^1.0.6" + } + }, + "loglevel": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", + "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "mime": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", + "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "dev": true + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "requires": { + "mime-db": "~1.38.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz", + "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-releases": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.7.tgz", + "integrity": "sha512-bKdrwaqJUPHqlCzDD7so/R+Nk0jGv9a11ZhLrD9f6i947qGLrGAhU3OxRENa19QQmwzGy/g6zCDEuLGDO8HPvA==", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-is": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", + "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "object-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", + "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pidtree": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz", + "integrity": "sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "portfinder": { + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", + "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + } + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", + "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-transform": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz", + "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "regexpu-core": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.4.0.tgz", + "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^7.0.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.0.2" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rfdc": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", + "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selfsigned": { + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", + "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", + "dev": true, + "requires": { + "node-forge": "^0.10.0" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "socket.io": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", + "dev": true, + "requires": { + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==", + "dev": true + }, + "socket.io-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.2.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "socket.io-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "sockjs": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "sockjs-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "dev": true, + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "dev": true + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "streamroller": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-1.0.6.tgz", + "integrity": "sha512-3QC47Mhv3/aZNFpDDVO44qQb9gwB9QggMEE0sQmkTAwBVYdBRWISdsywlkfm5II1Q5y/pmrHflti/IgmIzdDBg==", + "dev": true, + "requires": { + "async": "^2.6.2", + "date-format": "^2.0.0", + "debug": "^3.2.6", + "fs-extra": "^7.0.1", + "lodash": "^4.17.14" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } + }, + "string.prototype.padend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tar": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", + "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.2.tgz", + "integrity": "sha512-3qAQpykRTD5DReLu5/cwpsg7EZFzP3Q0Hp2XUWJUw2mpq2jfgOKTZr8IZKKnNieRVVo1UauROTdhbQJZveGKtQ==", + "dev": true, + "requires": { + "cacache": "^15.0.5", + "find-cache-dir": "^3.3.1", + "jest-worker": "^26.3.0", + "p-limit": "^3.0.2", + "schema-utils": "^2.7.1", + "serialize-javascript": "^5.0.1", + "source-map": "^0.6.1", + "terser": "^5.3.2", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", + "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "cacache": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", + "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.0", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "ssri": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", + "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "terser": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.3.3.tgz", + "integrity": "sha512-vRQDIlD+2Pg8YMwVK9kMM3yGylG95EIwzBai1Bw7Ot4OBfn3VP1TZn3EWx4ep2jERN/AmnVaTiGuelZSN7ds/A==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "dependencies": { + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + } + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.21", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", + "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==", + "dev": true + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz", + "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz", + "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "watchpack": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", + "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "dev": true, + "requires": { + "chokidar": "^3.4.1", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true, + "optional": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webpack": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", + "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.3.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", + "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + } + } + } + }, + "webpack-cli": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", + "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + } + } + }, + "webpack-dev-server": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.20", + "sockjs-client": "1.4.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "websocket-driver": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "dev": true, + "requires": { + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..f3d21501 --- /dev/null +++ b/package.json @@ -0,0 +1,79 @@ +{ + "name": "angular-ui-scroll", + "description": "AngularJS virtual scrolling module", + "version": "1.8.2", + "src": "./src/", + "public": "./dist/", + "main": "./dist/ui-scroll.js", + "homepage": "https://github.com/angular-ui/ui-scroll", + "author": { + "name": "Michael Feingold", + "email": "mfeingold@hill30.com" + }, + "maintainers": [ + { + "name": "Denis Hilt", + "web": "https://github.com/dhilt" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/angular-ui/ui-scroll.git" + }, + "bugs": { + "url": "https://github.com/angular-ui/ui-scroll/issues" + }, + "license": "MIT", + "scripts": { + "prod-build": "webpack --color", + "prod-test": "karma start test/config/karma.conf.js", + "dev-server": "webpack-dev-server --color", + "dev-test": "karma start test/config/karma.conf.js", + "hint-test": "jshint --verbose test", + "hint-src": "jshint --verbose src", + "build": "npm run hint-src && npm run prod-build && npm run hint-test && npm run prod-test", + "dev": "npm-run-all --parallel dev-server dev-test", + "test": "npm run dev-test", + "start": "npm run dev-server" + }, + "peerDependencies": { + "angular": ">=1.2.0" + }, + "devDependencies": { + "@babel/core": "^7.3.3", + "@babel/preset-env": "^7.3.1", + "babel-loader": "^8.1.0", + "clean-webpack-plugin": "^0.1.17", + "copy-webpack-plugin": "^6.1.1", + "jasmine-core": "^2.8.0", + "jshint": "^2.10.1", + "karma": "^5.0.5", + "karma-chrome-launcher": "^2.2.0", + "karma-firefox-launcher": "^1.1.0", + "karma-jasmine": "^2.0.1", + "karma-sourcemap-loader": "^0.3.7", + "karma-webpack": "^4.0.2", + "npm-run-all": "^4.1.2", + "terser-webpack-plugin": "^4.2.2", + "webpack": "^4.42.0", + "webpack-cli": "^3.3.1", + "webpack-dev-server": "^3.11.0" + }, + "keywords": [ + "angular", + "angularjs", + "angular.ui", + "angular-ui", + "ui.scroll", + "ui-scroll", + "angular-ui-scroll", + "virtual", + "unlimited", + "infinite", + "live", + "perpetual", + "scroll", + "scroller", + "scrolling" + ] +} diff --git a/src/modules/adapter.js b/src/modules/adapter.js new file mode 100644 index 00000000..d0dafceb --- /dev/null +++ b/src/modules/adapter.js @@ -0,0 +1,232 @@ +import { OPERATIONS } from './utils'; + +class Adapter { + + constructor($scope, $parse, $attr, viewport, buffer, doAdjust, reload) { + this.$parse = $parse; + this.$attr = $attr; + this.viewport = viewport; + this.buffer = buffer; + + this.doAdjust = doAdjust; + this.reload = reload; + + this.isLoading = false; + this.disabled = false; + + const viewportScope = viewport.getScope(); + this.startScope = viewportScope.$parent ? viewportScope : $scope; + + this.publicContext = {}; + this.assignAdapter($attr.adapter); + this.generatePublicContext(); + } + + assignAdapter(adapterAttr) { + if (!adapterAttr || !(adapterAttr = adapterAttr.replace(/^\s+|\s+$/gm, ''))) { + return; + } + let adapterOnScope; + + try { + this.$parse(adapterAttr).assign(this.startScope, {}); + adapterOnScope = this.$parse(adapterAttr)(this.startScope); + } + catch (error) { + error.message = `Angular ui-scroll Adapter assignment exception.\n` + + `Can't parse "${adapterAttr}" expression.\n` + + error.message; + throw error; + } + + angular.extend(adapterOnScope, this.publicContext); + this.publicContext = adapterOnScope; + } + + generatePublicContext() { + // these methods will be accessible out of ui-scroll via user defined adapter + const publicMethods = ['reload', 'applyUpdates', 'append', 'prepend', 'isBOF', 'isEOF', 'isEmpty']; + for (let i = publicMethods.length - 1; i >= 0; i--) { + this.publicContext[publicMethods[i]] = this[publicMethods[i]].bind(this); + } + + // these read-only props will be accessible out of ui-scroll via user defined adapter + const publicProps = ['isLoading', 'topVisible', 'topVisibleElement', 'topVisibleScope', 'bottomVisible', 'bottomVisibleElement', 'bottomVisibleScope']; + for (let i = publicProps.length - 1; i >= 0; i--) { + let property, attr = this.$attr[publicProps[i]]; + Object.defineProperty(this, publicProps[i], { + get: () => property, + set: (value) => { + property = value; + this.publicContext[publicProps[i]] = value; + if (attr) { + this.$parse(attr).assign(this.startScope, value); + } + } + }); + } + + // read-only immediately calculated public properties + const publicPropsImmediate = ['bufferFirst', 'bufferLast', 'bufferLength']; + for (let i = publicPropsImmediate.length - 1; i >= 0; i--) { + Object.defineProperty(this.publicContext, publicPropsImmediate[i], { + get: () => this[publicPropsImmediate[i]] + }); + } + + // non-read-only public property + Object.defineProperty(this.publicContext, 'disabled', { + get: () => this.disabled, + set: (value) => (!(this.disabled = value)) ? this.doAdjust() : null + }); + } + + loading(value) { + this.isLoading = value; + } + + isBOF() { + return this.buffer.bof; + } + + isEOF() { + return this.buffer.eof; + } + + isEmpty() { + return !this.buffer.length; + } + + get bufferLength() { + return this.buffer.getItems().length; + } + + get bufferFirst() { + return this.buffer.getFirstItem(); + } + + get bufferLast() { + return this.buffer.getLastItem(); + } + + append(newItems) { + this.buffer.append(newItems); + this.doAdjust(); + this.viewport.clipTop(); + this.viewport.clipBottom(); + } + + prepend(newItems, options = {}) { + this.buffer.prepend(newItems, options.immutableTop); + this.doAdjust(); + this.viewport.clipTop(); + this.viewport.clipBottom(); + } + + applyUpdates(arg1, arg2, arg3) { + if (typeof arg1 === 'function') { + this.applyUpdatesFunc(arg1, arg2); + } else { + this.applyUpdatesIndex(arg1, arg2, arg3); + } + this.doAdjust(); + } + + applyUpdatesFunc(cb, options = {}) { + this.buffer.slice(0).forEach((wrapper) => { + // we need to do it on the buffer clone, because buffer content + // may change as we iterate through + this.applyUpdate(wrapper, cb(wrapper.item, wrapper.scope, wrapper.element), options); + }); + } + + applyUpdatesIndex(index, newItems, options = {}) { + if (index % 1 !== 0) { + throw new Error('applyUpdates - ' + index + ' is not a valid index (should be an integer)'); + } + const _index = index - this.buffer.first; + + // apply updates only within buffer + if (_index >= 0 && _index < this.buffer.length) { + this.applyUpdate(this.buffer[_index], newItems, options); + } + // out-of-buffer case: deletion may affect Paddings + else if(index >= this.buffer.getAbsMinIndex() && index <= this.buffer.getAbsMaxIndex()) { + if(angular.isArray(newItems) && !newItems.length) { + this.viewport.removeCacheItem(index, !options.immutableTop && index === this.buffer.minIndex); + if (!options.immutableTop && index === this.buffer.getAbsMinIndex()) { + this.buffer.incrementMinIndex(); + } + else { + this.buffer.decrementMaxIndex(); + } + } + } + } + + applyUpdate(wrapper, newItems, options = {}) { + if (!angular.isArray(newItems)) { + return; + } + let position = this.buffer.indexOf(wrapper); + if (!newItems.reverse().some(newItem => newItem === wrapper.item)) { + wrapper.op = OPERATIONS.REMOVE; + // try to catch "first" edge case on remove + if (!options.immutableTop && !newItems.length) { + // this is the first item, or the previous one's part of the "shift-top" group + if ( + (position === 0 && this.buffer.bof) || + (position !== 0 && this.buffer[position - 1].shiftTop) + ) { + wrapper.shiftTop = true; + } + } + } + newItems.forEach((newItem) => { + if (newItem === wrapper.item) { + position--; + } else { + // 3 parameter (shiftTop) is to catch "first" edge case on insert + this.buffer.insert(position + 1, newItem, !options.immutableTop && position === -1); + } + }); + } + + calculateProperties() { + let rowTop = null, topHeight = 0; + let topDone = false, bottomDone = false; + const length = this.buffer.length; + + for (let i = 0; i < length; i++) { + const item = this.buffer[i]; + const itemTop = item.element.offset().top; + + if (rowTop !== itemTop) { // a new row condition + const itemHeight = item.element.outerHeight(true); + const top = this.viewport.topDataPos() + topHeight + itemHeight; + + if (!topDone && top > this.viewport.topVisiblePos()) { + topDone = true; + this['topVisible'] = item.item; + this['topVisibleElement'] = item.element; + this['topVisibleScope'] = item.scope; + } + if (!bottomDone && (top >= this.viewport.bottomVisiblePos() || (i === length - 1 && this.isEOF()))) { + bottomDone = true; + this['bottomVisible'] = item.item; + this['bottomVisibleElement'] = item.element; + this['bottomVisibleScope'] = item.scope; + } + topHeight += itemHeight; + } + rowTop = itemTop; + + if (topDone && bottomDone) { + break; + } + } + } + +} + +export default Adapter; diff --git a/src/modules/buffer.js b/src/modules/buffer.js new file mode 100644 index 00000000..13b29101 --- /dev/null +++ b/src/modules/buffer.js @@ -0,0 +1,180 @@ +import { OPERATIONS } from './utils'; + +export default function ScrollBuffer(elementRoutines, bufferSize, startIndex) { + const buffer = Object.create(Array.prototype); + + angular.extend(buffer, { + size: bufferSize, + + reset(startIndex) { + buffer.remove(0, buffer.length); + buffer.eof = false; + buffer.bof = false; + buffer.first = startIndex; + buffer.next = startIndex; + buffer.minIndex = startIndex; + buffer.maxIndex = startIndex; + buffer.minIndexUser = null; + buffer.maxIndexUser = null; + }, + + append(items) { + items.forEach((item) => { + ++buffer.next; + buffer.insert(OPERATIONS.APPEND, item); + }); + buffer.maxIndex = buffer.eof ? buffer.next - 1 : Math.max(buffer.next - 1, buffer.maxIndex); + }, + + prepend(items, immutableTop) { + items.reverse().forEach((item) => { + if (immutableTop) { + ++buffer.next; + } + else { + --buffer.first; + } + buffer.insert(OPERATIONS.PREPEND, item); + }); + buffer.minIndex = buffer.bof ? buffer.minIndex = buffer.first : Math.min(buffer.first, buffer.minIndex); + }, + + /** + * inserts wrapped element in the buffer + * the first argument is either operation keyword (see below) or a number for operation 'insert' + * for insert the number is the index for the buffer element the new one have to be inserted after + * operations: 'append', 'prepend', 'insert', 'remove', 'none' + */ + insert(operation, item, shiftTop) { + const wrapper = { + item: item + }; + + if (operation % 1 === 0) { // it is an insert + wrapper.op = OPERATIONS.INSERT; + buffer.splice(operation, 0, wrapper); + if (shiftTop) { + buffer.first--; + } + else { + buffer.next++; + } + } else { + wrapper.op = operation; + switch (operation) { + case OPERATIONS.APPEND: + buffer.push(wrapper); + break; + case OPERATIONS.PREPEND: + buffer.unshift(wrapper); + break; + } + } + }, + + // removes elements from buffer + remove(arg1, arg2) { + if (angular.isNumber(arg1)) { + // removes items from arg1 (including) through arg2 (excluding) + for (let i = arg1; i < arg2; i++) { + elementRoutines.removeElement(buffer[i]); + } + return buffer.splice(arg1, arg2 - arg1); + } + // removes single item (wrapper) from the buffer + buffer.splice(buffer.indexOf(arg1), 1); + if (arg1.shiftTop && buffer.first === this.getAbsMinIndex()) { + this.incrementMinIndex(); + } + else { + this.decrementMaxIndex(); + } + if (arg1.shiftTop) { + buffer.first++; + } + else { + buffer.next--; + } + if (!buffer.length) { + buffer.minIndex = Math.min(buffer.maxIndex, buffer.minIndex); + } + + return elementRoutines.removeElementAnimated(arg1); + }, + + incrementMinIndex() { + if (buffer.minIndexUser !== null) { + if (buffer.minIndex > buffer.minIndexUser) { + buffer.minIndexUser++; + return; + } + if (buffer.minIndex === buffer.minIndexUser) { + buffer.minIndexUser++; + } + } + buffer.minIndex++; + }, + + decrementMaxIndex() { + if (buffer.maxIndexUser !== null && buffer.maxIndex <= buffer.maxIndexUser) { + buffer.maxIndexUser--; + } + buffer.maxIndex--; + }, + + getAbsMinIndex() { + if (buffer.minIndexUser !== null) { + return Math.min(buffer.minIndexUser, buffer.minIndex); + } + return buffer.minIndex; + }, + + getAbsMaxIndex() { + if (buffer.maxIndexUser !== null) { + return Math.max(buffer.maxIndexUser, buffer.maxIndex); + } + return buffer.maxIndex; + }, + + effectiveHeight(elements) { + if (!elements.length) { + return 0; + } + let top = Number.MAX_VALUE; + let bottom = Number.NEGATIVE_INFINITY; + elements.forEach((wrapper) => { + if (wrapper.element[0].offsetParent) { + // element style is not display:none + top = Math.min(top, wrapper.element.offset().top); + bottom = Math.max(bottom, wrapper.element.offset().top + wrapper.element.outerHeight(true)); + } + }); + return Math.max(0, bottom - top); + }, + + getItems() { + return buffer.filter(item => item.op === OPERATIONS.NONE); + }, + + getFirstItem() { + const list = buffer.getItems(); + if (!list.length) { + return null; + } + return list[0].item; + }, + + getLastItem() { + const list = buffer.getItems(); + if (!list.length) { + return null; + } + return list[list.length - 1].item; + } + + }); + + buffer.reset(startIndex); + + return buffer; +} diff --git a/src/modules/elementRoutines.js b/src/modules/elementRoutines.js new file mode 100644 index 00000000..b4c7dda5 --- /dev/null +++ b/src/modules/elementRoutines.js @@ -0,0 +1,82 @@ +const hideClassToken = 'ng-ui-scroll-hide'; + +export default class ElementRoutines { + + static addCSSRules() { + const selector = '.' + hideClassToken; + const rules = 'display: none'; + const sheet = document.styleSheets[0]; + let index; + try { + index = sheet.cssRules.length; + } catch (err) { + index = 0; + } + if('insertRule' in sheet) { + sheet.insertRule(selector + '{' + rules + '}', index); + } + else if('addRule' in sheet) { + sheet.addRule(selector, rules, index); + } + } + + constructor($injector, $q) { + this.$animate = ($injector.has && $injector.has('$animate')) ? $injector.get('$animate') : null; + this.isAngularVersionLessThen1_3 = angular.version.major === 1 && angular.version.minor < 3; + this.$q = $q; + } + + hideElement(wrapper) { + wrapper.element.addClass(hideClassToken); + } + + showElement(wrapper) { + wrapper.element.removeClass(hideClassToken); + } + + insertElement(newElement, previousElement) { + previousElement.after(newElement); + return []; + } + + removeElement(wrapper) { + wrapper.element.remove(); + wrapper.scope.$destroy(); + return []; + } + + insertElementAnimated(newElement, previousElement) { + if (!this.$animate) { + return this.insertElement(newElement, previousElement); + } + + if (this.isAngularVersionLessThen1_3) { + const deferred = this.$q.defer(); + // no need for parent - previous element is never null + this.$animate.enter(newElement, null, previousElement, () => deferred.resolve()); + + return [deferred.promise]; + } + + // no need for parent - previous element is never null + return [this.$animate.enter(newElement, null, previousElement)]; + } + + removeElementAnimated(wrapper) { + if (!this.$animate) { + return this.removeElement(wrapper); + } + + if (this.isAngularVersionLessThen1_3) { + const deferred = this.$q.defer(); + this.$animate.leave(wrapper.element, () => { + wrapper.scope.$destroy(); + return deferred.resolve(); + }); + + return [deferred.promise]; + } + + return [(this.$animate.leave(wrapper.element)).then(() => wrapper.scope.$destroy())]; + } +} \ No newline at end of file diff --git a/src/modules/jqLiteExtras.js b/src/modules/jqLiteExtras.js new file mode 100644 index 00000000..e730f2ec --- /dev/null +++ b/src/modules/jqLiteExtras.js @@ -0,0 +1,270 @@ +/*! + globals: angular, window + List of used element methods available in JQuery but not in JQuery Lite + element.before(elem) + element.height() + element.outerHeight(true) + element.height(value) = only for Top/Bottom padding elements + element.scrollTop() + element.scrollTop(value) + */ + +export default class JQLiteExtras { + + registerFor(element) { + let convertToPx, css, getStyle, isWindow; + // angular implementation blows up if elem is the window + css = angular.element.prototype.css; + + element.prototype.css = function (name, value) { + let self = this; + let elem = self[0]; + if (!(!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style)) { + return css.call(self, name, value); + } + }; + + // as defined in angularjs v1.0.5 + isWindow = (obj) => obj && obj.document && obj.location && obj.alert && obj.setInterval; + + function scrollTo(self, direction, value) { + let elem = self[0]; + let [method, prop, preserve] = { + top: [ + 'scrollTop', + 'pageYOffset', + 'scrollLeft' + ], + left: [ + 'scrollLeft', + 'pageXOffset', + 'scrollTop' + ] + }[direction]; + + const isValueDefined = typeof value !== 'undefined'; + if (isWindow(elem)) { + if (isValueDefined) { + return elem.scrollTo(self[preserve].call(self), value); + } + return (prop in elem) ? elem[prop] : elem.document.documentElement[method]; + } else { + if (isValueDefined) { + elem[method] = value; + } + return elem[method]; + } + } + + if (window.getComputedStyle) { + getStyle = (elem) => window.getComputedStyle(elem, null); + convertToPx = (elem, value) => parseFloat(value); + } else { + getStyle = (elem) => elem.currentStyle; + convertToPx = (elem, value) => { + let left, result, rs, rsLeft, style; + let core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; + let rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i'); + + if (!rnumnonpx.test(value)) { + return parseFloat(value); + } + + // ported from JQuery + style = elem.style; + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + if (rs) { + rs.left = style.left; + } + // put in the new values to get a computed style out + style.left = value; + result = style.pixelLeft; + style.left = left; + if (rsLeft) { + rs.left = rsLeft; + } + return result; + }; + } + + function getMeasurements(elem, measure) { + let base, borderA, borderB, computedMarginA, computedMarginB, computedStyle, dirA, dirB, marginA, marginB, paddingA, paddingB; + + if (isWindow(elem)) { + base = document.documentElement[{height: 'clientHeight', width: 'clientWidth'}[measure]]; + + return { + base: base, + padding: 0, + border: 0, + margin: 0 + }; + } + + // Start with offset property + [ + base, + dirA, + dirB + ] = { + width: [ + elem.offsetWidth, + 'Left', + 'Right' + ], + height: [ + elem.offsetHeight, + 'Top', + 'Bottom' + ] + }[measure]; + + computedStyle = getStyle(elem); + paddingA = convertToPx(elem, computedStyle['padding' + dirA]) || 0; + paddingB = convertToPx(elem, computedStyle['padding' + dirB]) || 0; + borderA = convertToPx(elem, computedStyle['border' + dirA + 'Width']) || 0; + borderB = convertToPx(elem, computedStyle['border' + dirB + 'Width']) || 0; + computedMarginA = computedStyle['margin' + dirA]; + computedMarginB = computedStyle['margin' + dirB]; + + // I do not care for width for now, so this hack is irrelevant + // if ( !supportsPercentMargin ) + // computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA ) + // computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB ) + marginA = convertToPx(elem, computedMarginA) || 0; + marginB = convertToPx(elem, computedMarginB) || 0; + + return { + base: base, + padding: paddingA + paddingB, + border: borderA + borderB, + margin: marginA + marginB + }; + } + + function getWidthHeight(elem, direction, measure) { + let computedStyle, result; + + let measurements = getMeasurements(elem, direction); + + if (measurements.base > 0) { + return { + base: measurements.base - measurements.padding - measurements.border, + outer: measurements.base, + outerfull: measurements.base + measurements.margin + }[measure]; + } + + // Fall back to computed then uncomputed css if necessary + computedStyle = getStyle(elem); + result = computedStyle[direction]; + + if (result < 0 || result === null) { + result = elem.style[direction] || 0; + } + + // Normalize "", auto, and prepare for extra + result = parseFloat(result) || 0; + + return { + base: result - measurements.padding - measurements.border, + outer: result, + outerfull: result + measurements.padding + measurements.border + measurements.margin + }[measure]; + } + + // define missing methods + return angular.forEach({ + before(newElem) { + var children, elem, i, j, parent, ref, self; + self = this; + elem = self[0]; + parent = self.parent(); + children = parent.contents(); + if (children[0] === elem) { + return parent.prepend(newElem); + } else { + for (i = j = 1, ref = children.length - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { + if (children[i] === elem) { + angular.element(children[i - 1]).after(newElem); + return; + } + } + throw new Error('invalid DOM structure ' + elem.outerHTML); + } + }, + height (value){ + var self; + self = this; + if (typeof value !== 'undefined') { + if (angular.isNumber(value)) { + value = value + 'px'; + } + return css.call(self, 'height', value); + } else { + return getWidthHeight(this[0], 'height', 'base'); + } + }, + outerHeight(option) { + return getWidthHeight(this[0], 'height', option ? 'outerfull' : 'outer'); + }, + outerWidth(option) { + return getWidthHeight(this[0], 'width', option ? 'outerfull' : 'outer'); + }, + + /* + The offset setter method is not implemented + */ + offset(value) { + let docElem, win; + let self = this; + let box = { + top: 0, + left: 0 + }; + let elem = self[0]; + let doc = elem && elem.ownerDocument; + + if (arguments.length) { + if (value === undefined) { + return self; + } + // TODO: implement setter + throw new Error('offset setter method is not implemented'); + } + + if (!doc) { + return; + } + + docElem = doc.documentElement; + + // TODO: Make sure it's not a disconnected DOM node + + if (elem.getBoundingClientRect != null) { + box = elem.getBoundingClientRect(); + } + + win = doc.defaultView || doc.parentWindow; + + return { + top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0), + left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0) + }; + }, + scrollTop(value) { + return scrollTo(this, 'top', value); + }, + scrollLeft(value) { + return scrollTo(this, 'left', value); + } + }, (value, key) => { + if (!element.prototype[key]) { + return element.prototype[key] = value; + } + }); + } + +} diff --git a/src/modules/padding.js b/src/modules/padding.js new file mode 100644 index 00000000..2324537a --- /dev/null +++ b/src/modules/padding.js @@ -0,0 +1,84 @@ +// Can't just extend the Array, due to Babel does not support built-in classes extending +// This solution was taken from https://stackoverflow.com/questions/46897414/es6-class-extends-array-workaround-for-es5-babel-transpile +class CacheProto { + add(item) { + for (let i = this.length - 1; i >= 0; i--) { + if (this[i].index === item.scope.$index) { + this[i].height = item.element.outerHeight(); + return; + } + } + this.push({ + index: item.scope.$index, + height: item.element.outerHeight() + }); + this.sort((a, b) => ((a.index < b.index) ? -1 : ((a.index > b.index) ? 1 : 0))); + } + + remove(argument, _shiftTop) { + const index = argument % 1 === 0 ? argument : argument.scope.$index; + const shiftTop = argument % 1 === 0 ? _shiftTop : argument.shiftTop; + for (let i = this.length - 1; i >= 0; i--) { + if (this[i].index === index) { + this.splice(i, 1); + break; + } + } + if (!shiftTop) { + for (let i = this.length - 1; i >= 0; i--) { + if (this[i].index > index) { + this[i].index--; + } + } + } + } + + clear() { + this.length = 0; + } +} + +function Cache() { + const instance = []; + instance.push.apply(instance, arguments); + Object.setPrototypeOf(instance, Cache.prototype); + return instance; +} +Cache.prototype = Object.create(Array.prototype); +Object.getOwnPropertyNames(CacheProto.prototype).forEach(methodName => + Cache.prototype[methodName] = CacheProto.prototype[methodName] +); + +function generateElement(template) { + if (template.nodeType !== Node.ELEMENT_NODE) { + throw new Error('ui-scroll directive requires an Element node for templating the view'); + } + let element; + switch (template.tagName.toLowerCase()) { + case 'dl': + throw new Error(`ui-scroll directive does not support <${template.tagName}> as a repeating tag: ${template.outerHTML}`); + case 'tr': + let table = angular.element('
    '); + element = table.find('tr'); + break; + case 'li': + element = angular.element('
  • '); + break; + default: + element = angular.element('
    '); + } + return element; +} + +class Padding { + constructor(template) { + this.element = generateElement(template); + this.cache = new Cache(); + } + + height() { + return this.element.height.apply(this.element, arguments); + } +} + +export default Padding; \ No newline at end of file diff --git a/src/modules/utils.js b/src/modules/utils.js new file mode 100644 index 00000000..c0b78476 --- /dev/null +++ b/src/modules/utils.js @@ -0,0 +1,7 @@ +export const OPERATIONS = { + PREPEND: 'prepend', + APPEND: 'append', + INSERT: 'insert', + REMOVE: 'remove', + NONE: 'none' +}; diff --git a/src/modules/viewport.js b/src/modules/viewport.js new file mode 100644 index 00000000..96ecee37 --- /dev/null +++ b/src/modules/viewport.js @@ -0,0 +1,219 @@ +import Padding from './padding'; + +export default function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding) { + let topPadding = null; + let bottomPadding = null; + const viewport = viewportController && viewportController.viewport ? viewportController.viewport : angular.element(window); + const container = viewportController && viewportController.container ? viewportController.container : undefined; + const scope = viewportController && viewportController.scope ? viewportController.scope : $rootScope; + + viewport.css({ + 'overflow-anchor': 'none', + 'overflow-y': 'auto', + 'display': 'block' + }); + + function bufferPadding() { + return viewport.outerHeight() * padding; // some extra space to initiate preload + } + + angular.extend(viewport, { + getScope() { + return scope; + }, + + createPaddingElements(template) { + topPadding = new Padding(template); + bottomPadding = new Padding(template); + element.before(topPadding.element); + element.after(bottomPadding.element); + topPadding.height(0); + bottomPadding.height(0); + }, + + applyContainerStyle() { + if (!container) { + return true; + } + if (container !== viewport) { + viewport.css('height', window.getComputedStyle(container[0]).height); + } + return viewport.height() > 0; + }, + + bottomDataPos() { + let scrollHeight = viewport[0].scrollHeight; + scrollHeight = scrollHeight != null ? scrollHeight : viewport[0].document.documentElement.scrollHeight; + return scrollHeight - bottomPadding.height(); + }, + + topDataPos() { + return topPadding.height(); + }, + + bottomVisiblePos() { + return viewport.scrollTop() + viewport.outerHeight(); + }, + + topVisiblePos() { + return viewport.scrollTop(); + }, + + insertElement(e, sibling) { + return elementRoutines.insertElement(e, sibling || topPadding.element); + }, + + insertElementAnimated(e, sibling) { + return elementRoutines.insertElementAnimated(e, sibling || topPadding.element); + }, + + shouldLoadBottom() { + return !buffer.eof && viewport.bottomDataPos() < viewport.bottomVisiblePos() + bufferPadding(); + }, + + clipBottom() { + // clip the invisible items off the bottom + let overage = 0; + let overageHeight = 0; + let itemHeight = 0; + let emptySpaceHeight = viewport.bottomDataPos() - viewport.bottomVisiblePos() - bufferPadding(); + + for (let i = buffer.length - 1; i >= 0; i--) { + itemHeight = buffer[i].element.outerHeight(true); + if (overageHeight + itemHeight > emptySpaceHeight) { + break; + } + bottomPadding.cache.add(buffer[i]); + overageHeight += itemHeight; + overage++; + } + + if (overage > 0) { + buffer.eof = false; + buffer.remove(buffer.length - overage, buffer.length); + buffer.next -= overage; + viewport.adjustPaddings(); + } + }, + + shouldLoadTop() { + return !buffer.bof && (viewport.topDataPos() > viewport.topVisiblePos() - bufferPadding()); + }, + + clipTop() { + // clip the invisible items off the top + let overage = 0; + let overageHeight = 0; + let itemHeight = 0; + let emptySpaceHeight = viewport.topVisiblePos() - viewport.topDataPos() - bufferPadding(); + + for (let i = 0; i < buffer.length; i++) { + itemHeight = buffer[i].element.outerHeight(true); + if (overageHeight + itemHeight > emptySpaceHeight) { + break; + } + topPadding.cache.add(buffer[i]); + overageHeight += itemHeight; + overage++; + } + + if (overage > 0) { + // we need to adjust top padding element before items are removed from top + // to avoid strange behaviour of scroll bar during remove top items when we are at the very bottom + topPadding.height(topPadding.height() + overageHeight); + buffer.bof = false; + buffer.remove(0, overage); + buffer.first += overage; + } + }, + + adjustPaddings() { + if (!buffer.length) { + return; + } + + // precise heights calculation based on items that are in buffer or that were in buffer once + const visibleItemsHeight = buffer.reduce((summ, item) => summ + item.element.outerHeight(true), 0); + + let topPaddingHeight = 0, topCount = 0; + topPadding.cache.forEach(item => { + if (item.index < buffer.first) { + topPaddingHeight += item.height; + topCount++; + } + }); + + let bottomPaddingHeight = 0, bottomCount = 0; + bottomPadding.cache.forEach(item => { + if (item.index >= buffer.next) { + bottomPaddingHeight += item.height; + bottomCount++; + } + }); + + const totalHeight = visibleItemsHeight + topPaddingHeight + bottomPaddingHeight; + const averageItemHeight = totalHeight / (topCount + bottomCount + buffer.length); + + // average heights calculation, items that have never been reached + let adjustTopPadding = buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser; + let adjustBottomPadding = buffer.maxIndexUser !== null && buffer.maxIndex < buffer.maxIndexUser; + let topPaddingHeightAdd = adjustTopPadding ? (buffer.minIndex - buffer.minIndexUser) * averageItemHeight : 0; + let bottomPaddingHeightAdd = adjustBottomPadding ? (buffer.maxIndexUser - buffer.maxIndex) * averageItemHeight : 0; + + // paddings combine adjustment + topPadding.height(topPaddingHeight + topPaddingHeightAdd); + bottomPadding.height(bottomPaddingHeight + bottomPaddingHeightAdd); + }, + + onAfterMinIndexSet(topPaddingHeightOld) { + // additional scrollTop adjustment in case of datasource.minIndex external set + if (buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser) { + let diff = topPadding.height() - topPaddingHeightOld; + viewport.scrollTop(viewport.scrollTop() + diff); + while((diff -= viewport.scrollTop()) > 0) { + bottomPadding.height(bottomPadding.height() + diff); + viewport.scrollTop(viewport.scrollTop() + diff); + } + } + }, + + onAfterPrepend(updates) { + if (!updates.prepended.length) { + return; + } + const height = buffer.effectiveHeight(updates.prepended); + const paddingHeight = topPadding.height() - height; + if (paddingHeight >= 0) { + topPadding.height(paddingHeight); + return; + } + const position = viewport.scrollTop(); + const newPosition = position - paddingHeight; + viewport.synthetic = { previous: position, next: newPosition }; + topPadding.height(0); + viewport.scrollTop(newPosition); + }, + + resetTopPadding() { + topPadding.height(0); + topPadding.cache.clear(); + }, + + resetBottomPadding() { + bottomPadding.height(0); + bottomPadding.cache.clear(); + }, + + removeCacheItem(item, shiftTop) { + topPadding.cache.remove(item, shiftTop); + bottomPadding.cache.remove(item, shiftTop); + }, + + removeItem(item) { + this.removeCacheItem(item); + return buffer.remove(item); + } + }); + + return viewport; +} diff --git a/src/ui-scroll-grid.js b/src/ui-scroll-grid.js new file mode 100644 index 00000000..2aef2430 --- /dev/null +++ b/src/ui-scroll-grid.js @@ -0,0 +1,267 @@ +angular.module('ui.scroll.grid', []) + .directive('uiScrollTh', ['$log', '$timeout', function(console, $timeout) { + + function GridAdapter(controller) { + + this.getLayout = () => controller.getLayout(); + + this.applyLayout = (layout) => controller.applyLayout(layout); + + this.columnFromPoint = (x, y) => controller.columnFromPoint(x, y); + + Object.defineProperty(this, 'columns', { get: () => controller.getColumns() }); + } + + function ColumnAdapter(controller, column) { + + this.css = function( /* attr, value */ ) { + var attr = arguments[0]; + var value = arguments[1]; + if (arguments.length == 1) { + return column.header.css(attr); + } + if (arguments.length == 2) { + column.header.css(attr, value); + controller.forEachRow((row) => row[column.id].css(attr, value)); + column.css[attr] = value; + } + }; + + this.moveBefore = (index) => controller.moveBefore(column, index); + + this.exchangeWith = (index) => controller.exchangeWith(column, index); + + Object.defineProperty(this, 'columnId', { get: () => column.id }); + } + + function ColumnController(controller, columns, header) { + + this.header = header; + this.css = {}; + this.mapTo = columns.length; + this.id = columns.length; + + // controller api methods + + this.applyLayout = function(layout) { + this.css = angular.extend({}, layout.css); + this.mapTo = layout.mapTo; + applyCss(this.header, this.css); + }; + + this.moveBefore = function(target) { + if (target) { + moveBefore(header, target.header); + controller.forEachRow((row) => moveBefore(row[this.id], row[target.id])); + } else { + moveLast(header); + controller.forEachRow((row) => moveLast(row[this.id])); + } + }; + + this.columnFromPoint = function(x, y) { + if (insidePoint(header, x, y)) { + return this; + } + let result = null; + controller.forEachRow((row) => + result = insidePoint(row[this.id], x, y) ? this : result + ); + return result; + }; + + this.applyCss = function(target) { + applyCss(target, this.css); + }; + + // function definitions + + function insidePoint(element, x, y) { + let offset = element.offset(); + if (x < offset.left || offset.left + element.outerWidth(true) < x) + return false; + if (y < offset.top || offset.top + element.outerHeight(true) < y) + return false; + return true; + } + + function moveBefore(element, target) { + element.detach(); + target.before(element); + } + + function moveLast(element) { + let parent = element.parent(); + element.detach(); + parent.append(element); + } + + function applyCss(target, css) { + target.removeAttr('style'); + for (let attr in css) { + if (css.hasOwnProperty(attr)) { + target.css(attr, css[attr]); + } + } + } + + } + + function GridController(scrollViewport) { + let columns = []; + let rowMap = new Map(); + + $timeout(() => { + scrollViewport.adapter.publicContext.gridAdapter = new GridAdapter(this); + scrollViewport.adapter.transform = (scope, item) => transform(rowMap.get(scope), item); + }); + + this.registerColumn = function(header) { + columns.push(new ColumnController(this, columns, header)); + }; + + this.registerCell = function(scope, cell) { + let row = rowMap.get(scope); + if (!row) { + row = []; + rowMap.set(scope, row); + } + if (row.length >= columns.length) { + return false; + } + row.push(cell); + return true; + }; + + this.unregisterCell = function(scope, cell) { + let row = rowMap.get(scope); + let i = row.indexOf(cell); + row.splice(i, 1); + if (!row.length) { + rowMap.delete(scope); + } + }; + + this.forEachRow = function(callback) { + rowMap.forEach(callback); + }; + + this.getColumns = function() { + let result = []; + columns.slice() + .sort((a, b) => a.mapTo - b.mapTo) + .forEach((column) => result.push(new ColumnAdapter(this, column))); + return result; + }; + + this.getLayout = function() { + let result = []; + columns.forEach((column, index) => result.push({ + index: index, + css: angular.extend({}, column.css), + mapTo: column.mapTo + })); + return result; + }; + + this.applyLayout = function(layouts) { + if (!layouts || layouts.length != columns.length) { + throw new Error('Failed to apply layout - number of layouts should match number of columns'); + } + layouts.forEach((layout, index) => columns[index].applyLayout(layout)); + transform(columns.map((column) => column.header)); + rowMap.forEach((row) => transform(row)); + }; + + this.moveBefore = function(selected, target) { + let index = target; + + if (target % 1 !== 0) { + index = target ? columns[target.columnId].mapTo : columns.length; + } + if (index < 0 || index > columns.length) { + return; // throw an error? + } + + let mapTo = selected.mapTo, + next = null; + index -= mapTo < index ? 1 : 0; + + columns.forEach(c => { + c.mapTo -= c.mapTo > mapTo ? 1 : 0; + c.mapTo += c.mapTo >= index ? 1 : 0; + next = c.mapTo === index + 1 ? c : next; + }); + + selected.mapTo = index; + selected.moveBefore(next); + }; + + this.exchangeWith = function(selected, index) { + if (index < 0 || index >= columns.length) { + return; + } + columns.find(c => c.mapTo === index).mapTo = selected.mapTo; + selected.mapTo = index; + }; + + this.columnFromPoint = function(x, y) { + let column = columns.find(col => col.columnFromPoint(x, y)); + return column ? new ColumnAdapter(this, column) : undefined; + }; + + // function definitions + + function transform(row) { + let parent = row[0].parent(); + let visible = []; + + row.forEach((cell, index) => { + columns[index].applyCss(cell); + visible[columns[index].mapTo] = row[index]; + row[index].detach(); + }); + + visible.forEach(cell => parent.append(cell)); + } + + } + + return { + require: ['^^uiScrollViewport'], + restrict: 'A', + link: ($scope, element, $attr, controllers) => { + controllers[0].gridController = controllers[0].gridController || new GridController(controllers[0]); + controllers[0].gridController.registerColumn(element); + } + }; + }]) + +.directive('uiScrollTd', function() { + return { + require: ['?^^uiScrollViewport'], + restrict: 'A', + link: ($scope, element, $attr, controllers) => { + if (!controllers[0]) { + return; + } + let scope = $scope; + let tdInitializer = $scope.uiScrollTdInitializer; + if (!tdInitializer) { + tdInitializer = $scope.uiScrollTdInitializer = { + linking: true + }; + } + if (!tdInitializer.linking) { + scope = tdInitializer.scope; + } + let gridController = controllers[0].gridController; + if (gridController.registerCell(scope, element)) { + $scope.$on('$destroy', () => gridController.unregisterCell(scope, element)); + } + if (!tdInitializer.linking) { + tdInitializer.onLink(); + } + } + }; +}); diff --git a/src/ui-scroll-jqlite.js b/src/ui-scroll-jqlite.js new file mode 100644 index 00000000..c542a1a4 --- /dev/null +++ b/src/ui-scroll-jqlite.js @@ -0,0 +1,12 @@ +/*! + * angular-ui-scroll + * https://github.com/angular-ui/ui-scroll.git + * This module is deprecated since 1.6.0 and will be removed in future versions! + * License: MIT + */ +(function () { + 'use strict'; + + angular.module('ui.scroll.jqlite', []); + +})(); \ No newline at end of file diff --git a/src/ui-scroll.js b/src/ui-scroll.js new file mode 100644 index 00000000..705f9932 --- /dev/null +++ b/src/ui-scroll.js @@ -0,0 +1,548 @@ +import JQLiteExtras from './modules/jqLiteExtras'; +import ElementRoutines from './modules/elementRoutines.js'; +import ScrollBuffer from './modules/buffer.js'; +import Viewport from './modules/viewport.js'; +import Adapter from './modules/adapter.js'; +import { OPERATIONS } from './modules/utils'; + +angular.module('ui.scroll', []) + + .constant('JQLiteExtras', JQLiteExtras) + .run(['JQLiteExtras', (JQLiteExtras) => { + const elt = angular.element; + !(window.jQuery && elt.fn && elt.fn.jquery) ? (new JQLiteExtras()).registerFor(elt) : null; + ElementRoutines.addCSSRules(); + }]) + + .directive('uiScrollViewport', function () { + return { + restrict: 'A', + controller: [ + '$scope', + '$element', + function (scope, element) { + this.container = element; + this.viewport = element; + this.scope = scope; + + angular.forEach(element.children(), child => { + if (child.tagName.toLowerCase() === 'tbody') { + this.viewport = angular.element(child); + } + }); + + return this; + } + ] + }; + }) + + .directive('uiScroll', [ + '$log', + '$injector', + '$rootScope', + '$timeout', + '$interval', + '$q', + '$parse', + function (console, $injector, $rootScope, $timeout, $interval, $q, $parse) { + + return { + require: ['?^uiScrollViewport'], + restrict: 'A', + transclude: 'element', + priority: 1000, + terminal: true, + link: link + }; + + function link($scope, element, $attr, controllers, linker) { + const match = $attr.uiScroll.match(/^\s*(\w+)\s+in\s+([(\w|\$)\.]+)\s*$/); + if (!match) { + throw new Error('Expected uiScroll in form of \'_item_ in _datasource_\' but got \'' + $attr.uiScroll + '\''); + } + + function parseNumber(value, defaultValue, isFloat) { + if (!isFloat) { + value = value === null ? defaultValue : Math.floor(value); + } + return isNaN(value) ? defaultValue : value; + } + + function parseNumericAttr(value, defaultValue, isFloat) { + const result = $parse(value)($scope); + return parseNumber(result, defaultValue, isFloat); + } + + function parseBooleanAttr(value, defaultValue) { + const result = $parse(value)($scope); + return typeof result === 'boolean' ? result : defaultValue; + } + + const BUFFER_MIN = 3; + const BUFFER_DEFAULT = 10; + const PADDING_MIN = 0.3; + const PADDING_DEFAULT = 0.5; + const HANDLE_INERTIA_DEFAULT = true; + const START_INDEX_DEFAULT = 1; + const MAX_VIEWPORT_DELAY = 500; + const VIEWPORT_POLLING_INTERVAL = 50; + + let datasource = null; + const itemName = match[1]; + const datasourceName = match[2]; + const viewportController = controllers[0]; + const bufferSize = Math.max(BUFFER_MIN, parseNumericAttr($attr.bufferSize, BUFFER_DEFAULT)); + const padding = Math.max(PADDING_MIN, parseNumericAttr($attr.padding, PADDING_DEFAULT, true)); + const handleInertia = parseBooleanAttr($attr.handleInertia, HANDLE_INERTIA_DEFAULT); + let startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT); + let ridActual = 0; // current data revision id + let pending = []; + + const elementRoutines = new ElementRoutines($injector, $q); + const buffer = new ScrollBuffer(elementRoutines, bufferSize, startIndex); + const viewport = new Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding); + const adapter = new Adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload); + + if (viewportController) { + viewportController.adapter = adapter; + } + + const isDatasourceValid = () => + Object.prototype.toString.call(datasource) === '[object Object]' && typeof datasource.get === 'function'; + + datasource = $parse(datasourceName)($scope); // try to get datasource on scope + if (!isDatasourceValid()) { + datasource = $injector.get(datasourceName); // try to inject datasource as service + if (!isDatasourceValid()) { + throw new Error(datasourceName + ' is not a valid datasource'); + } + } + + let onRenderHandlers = []; + function onRenderHandlersRunner() { + onRenderHandlers.forEach(handler => handler.run()); + onRenderHandlers = []; + } + function persistDatasourceIndex(datasource, propName) { + let getter; + // need to postpone min/maxIndexUser processing if the view is empty + if(angular.isNumber(datasource[propName])) { + getter = datasource[propName]; + if(angular.isNumber(getter)) { + onRenderHandlers = onRenderHandlers.filter(handler => handler.id !== propName); + onRenderHandlers.push({ + id: propName, + run: () => datasource[propName] = getter + }); + } + } + } + + function defineDatasourceIndex(datasource, propName, propUserName) { + const descriptor = Object.getOwnPropertyDescriptor(datasource, propName); + if (descriptor && (descriptor.set || descriptor.get)) { + return; + } + let getter; + persistDatasourceIndex(datasource, propName); + Object.defineProperty(datasource, propName, { + set: (value) => { + getter = value; + if(pending.length && !buffer.length) { + persistDatasourceIndex(datasource, propName); + return; + } + buffer[propUserName] = value; + const topPaddingHeightOld = viewport.topDataPos(); + viewport.adjustPaddings(); + if (propName === 'minIndex') { + viewport.onAfterMinIndexSet(topPaddingHeightOld); + } + }, + get: () => getter + }); + } + + defineDatasourceIndex(datasource, 'minIndex', 'minIndexUser'); + defineDatasourceIndex(datasource, 'maxIndex', 'maxIndexUser'); + + const fetchNext = (datasource.get.length !== 2) ? + (success) => datasource.get(buffer.next, bufferSize, success) : + (success) => { + datasource.get({ + index: buffer.next, + append: buffer.length ? buffer[buffer.length - 1].item : void 0, + count: bufferSize + }, success); + }; + + const fetchPrevious = (datasource.get.length !== 2) ? + (success) => datasource.get(buffer.first - bufferSize, bufferSize, success) : + (success) => { + datasource.get({ + index: buffer.first - bufferSize, + prepend: buffer.length ? buffer[0].item : void 0, + count: bufferSize + }, success); + }; + + const initialize = () => { + let tryCount = 0; + if(!viewport.applyContainerStyle()) { + const timer = $interval(() => { + tryCount++; + if(viewport.applyContainerStyle()) { + $interval.cancel(timer); + doAdjust(); + } + if(tryCount * VIEWPORT_POLLING_INTERVAL >= MAX_VIEWPORT_DELAY) { + $interval.cancel(timer); + throw Error(`ui-scroll directive requires a viewport with non-zero height in ${MAX_VIEWPORT_DELAY}ms`); + } + }, VIEWPORT_POLLING_INTERVAL); + } + else { + doAdjust(); + } + }; + + /** + * Build padding elements + * + * Calling linker is the only way I found to get access to the tag name of the template + * to prevent the directive scope from pollution a new scope is created and destroyed + * right after the builder creation is completed + */ + linker((clone, scope) => { + viewport.createPaddingElements(clone[0]); + // we do not include the clone in the DOM. It means that the nested directives will not + // be able to reach the parent directives, but in this case it is intentional because we + // created the clone to access the template tag name + scope.$destroy(); + clone.remove(); + }); + + $scope.$on('$destroy', () => { + unbindEvents(); + viewport.off('mousewheel', wheelHandler); + }); + + viewport.on('mousewheel', wheelHandler); + + initialize(); + + /* Private function definitions */ + + function isInvalid(rid) { + return (rid && rid !== ridActual) || $scope.$$destroyed; + } + + function bindEvents() { + viewport.on('resize', resizeAndScrollHandler); + viewport.on('scroll', resizeAndScrollHandler); + } + + function unbindEvents() { + viewport.off('resize', resizeAndScrollHandler); + viewport.off('scroll', resizeAndScrollHandler); + } + + function reload() { + unbindEvents(); + viewport.resetTopPadding(); + viewport.resetBottomPadding(); + if (arguments.length) { + startIndex = parseNumber(arguments[0], START_INDEX_DEFAULT, false); + } + buffer.reset(startIndex); + persistDatasourceIndex(datasource, 'minIndex'); + persistDatasourceIndex(datasource, 'maxIndex'); + doAdjust(); + } + + function isElementVisible(wrapper) { + return wrapper.element.height() && wrapper.element[0].offsetParent; + } + + function visibilityWatcher(wrapper) { + if (isElementVisible(wrapper)) { + buffer.forEach((item) => { + if (typeof item.unregisterVisibilityWatcher === 'function') { + item.unregisterVisibilityWatcher(); + delete item.unregisterVisibilityWatcher; + } + }); + if (!pending.length) { + $timeout(() => doAdjust()); + } + } + } + + function insertWrapperContent(wrapper, insertAfter) { + createElement(wrapper, insertAfter, viewport.insertElement); + if (!isElementVisible(wrapper)) { + wrapper.unregisterVisibilityWatcher = wrapper.scope.$watch(() => visibilityWatcher(wrapper)); + } + elementRoutines.hideElement(wrapper); // hide inserted elements before data binding + } + + function createElement(wrapper, insertAfter, insertElement) { + let promises = null; + const sibling = (insertAfter > 0) ? buffer[insertAfter - 1].element : undefined; + linker((clone, scope) => { + promises = insertElement(clone, sibling); + wrapper.element = clone; + wrapper.scope = scope; + scope[itemName] = wrapper.item; + }); + // ui-scroll-grid apply + if (adapter.transform) { + const tdInitializer = wrapper.scope.uiScrollTdInitializer; + if (tdInitializer && tdInitializer.linking) { + adapter.transform(wrapper.scope, wrapper.element); + } else { + wrapper.scope.uiScrollTdInitializer = { + onLink: () => adapter.transform(wrapper.scope, wrapper.element), + scope: wrapper.scope + }; + } + } + return promises; + } + + function updateDOM() { + let promises = []; + const toBePrepended = []; + const toBeRemoved = []; + const inserted = []; + + buffer.forEach((wrapper, i) => { + switch (wrapper.op) { + case OPERATIONS.PREPEND: + toBePrepended.unshift(wrapper); + break; + case OPERATIONS.APPEND: + insertWrapperContent(wrapper, i); + wrapper.op = OPERATIONS.NONE; + inserted.push(wrapper); + break; + case OPERATIONS.INSERT: + promises = promises.concat(createElement(wrapper, i, viewport.insertElementAnimated)); + wrapper.op = OPERATIONS.NONE; + inserted.push(wrapper); + break; + case OPERATIONS.REMOVE: + toBeRemoved.push(wrapper); + } + }); + + toBeRemoved.forEach((wrapper) => promises = promises.concat(viewport.removeItem(wrapper))); + + if (toBePrepended.length) + toBePrepended.forEach((wrapper) => { + insertWrapperContent(wrapper); + wrapper.op = OPERATIONS.NONE; + }); + + buffer.forEach((item, i) => item.scope.$index = buffer.first + i); + + return { + prepended: toBePrepended, + removed: toBeRemoved, + inserted: inserted, + animated: promises + }; + + } + + function updatePaddings(rid, updates) { + // schedule another doAdjust after animation completion + if (updates.animated.length) { + $q.all(updates.animated).then(() => { + viewport.adjustPaddings(); + doAdjust(rid); + }); + } else { + viewport.adjustPaddings(); + } + } + + function enqueueFetch(rid, updates) { + if (viewport.shouldLoadBottom()) { + if (!updates || buffer.effectiveHeight(updates.inserted) > 0) { + // this means that at least one item appended in the last batch has height > 0 + if (pending.push(true) === 1) { + adapter.loading(true); + fetch(rid); + } + } + } else if (viewport.shouldLoadTop()) { + if ((!updates || buffer.effectiveHeight(updates.prepended) > 0) || pending[0]) { + // this means that at least one item appended in the last batch has height > 0 + // pending[0] = true means that previous fetch was appending. We need to force at least one prepend + // BTW there will always be at least 1 element in the pending array because bottom is fetched first + if (pending.push(false) === 1) { + adapter.loading(true); + fetch(rid); + } + } + } + } + + function processUpdates() { + const updates = updateDOM(); + + // We need the item bindings to be processed before we can do adjustments + !$scope.$$phase && !$rootScope.$$phase && $scope.$digest(); + + updates.inserted.forEach(w => elementRoutines.showElement(w)); + updates.prepended.forEach(w => elementRoutines.showElement(w)); + return updates; + } + + function doAdjust(rid) { + if (!rid) { // dismiss pending requests + pending = []; + rid = ++ridActual; + } + + const updates = processUpdates(); + + if (isInvalid(rid)) { + return; + } + + updatePaddings(rid, updates); + enqueueFetch(rid); + + if (!pending.length) { + adapter.calculateProperties(); + } + } + + function doAdjustAfterFetch(rid) { + const updates = processUpdates(); + + viewport.onAfterPrepend(updates); + + if (isInvalid(rid)) { + return; + } + + updatePaddings(rid, updates); + onRenderHandlersRunner(); + enqueueFetch(rid, updates); + pending.shift(); + + if (pending.length) + fetch(rid); + else { + adapter.loading(false); + bindEvents(); + adapter.calculateProperties(); + } + } + + function fetch(rid) { + if (pending[0]) {// scrolling down + if (buffer.length && !viewport.shouldLoadBottom()) { + doAdjustAfterFetch(rid); + } else { + fetchNext((result) => { + if (isInvalid(rid)) { + return; + } + + if (result.length < bufferSize) { + buffer.eof = true; + } + + if (result.length > 0) { + viewport.clipTop(); + buffer.append(result); + } + + doAdjustAfterFetch(rid); + }); + } + } else { // scrolling up + if (buffer.length && !viewport.shouldLoadTop()) { + doAdjustAfterFetch(rid); + } else { + fetchPrevious((result) => { + if (isInvalid(rid)) { + return; + } + + if (result.length < bufferSize) { + buffer.bof = true; + // log 'bof is reached' + } + + if (result.length > 0) { + if (buffer.length) { + viewport.clipBottom(); + } + buffer.prepend(result); + } + + doAdjustAfterFetch(rid); + }); + } + } + } + + function fixInertia() { + if (!viewport.synthetic) { + return; + } + const oldPosition = viewport.synthetic.previous; + const newPosition = viewport.synthetic.next; + if (viewport.scrollTop() !== newPosition) { + requestAnimationFrame(() => { + const position = viewport.scrollTop(); + const diff = oldPosition - position; + if (diff > 0) { // inertia over synthetic + viewport.scrollTop(newPosition - diff); + } else { + viewport.scrollTop(newPosition); + } + viewport.synthetic = null; + }); + return true; + } + viewport.synthetic = null; + } + + function resizeAndScrollHandler() { + if (handleInertia && fixInertia()) { + return; + } + if (!$rootScope.$$phase && !adapter.isLoading && !adapter.disabled) { + + enqueueFetch(ridActual); + + if (pending.length) { + unbindEvents(); + } else { + adapter.calculateProperties(); + !$scope.$$phase && $scope.$digest(); + } + } + } + + function wheelHandler(event) { + if (!adapter.disabled) { + const scrollTop = viewport[0].scrollTop; + const yMax = viewport[0].scrollHeight - viewport[0].clientHeight; + + if ((scrollTop === 0 && !buffer.bof) || (scrollTop === yMax && !buffer.eof)) { + event.preventDefault(); + } + } + } + } + + } + ]); diff --git a/test/.jshintrc b/test/.jshintrc new file mode 100644 index 00000000..1cb61f60 --- /dev/null +++ b/test/.jshintrc @@ -0,0 +1,33 @@ +{ + "bitwise": true, + "curly": true, + "browser": true, + "eqeqeq": true, + "expr": true, + "esversion": 9, + "forin": true, + "freeze": true, + "futurehostile": true, + "iterator": true, + "jasmine": true, + "jquery": true, + "latedef": true, + "noarg": true, + "nocomma": true, + "node": true, + "nonbsp": true, + "nonew": true, + "smarttabs": true, + "strict": true, + "sub": true, + "trailing": true, + "undef": true, + "unused": true, + "globals": { + "angular": false, + "inject": false, + "runTest": true, + "runGridTest": false, + "Helper": true + } +} diff --git a/test/AdapterTestsSpec.js b/test/AdapterTestsSpec.js new file mode 100644 index 00000000..dabe02c9 --- /dev/null +++ b/test/AdapterTestsSpec.js @@ -0,0 +1,1233 @@ +describe('uiScroll', function () { + 'use strict'; + + let datasource; + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.test.datasources')); + + const injectDatasource = (datasourceToken) => + beforeEach( + inject([datasourceToken, function (_datasource) { + datasource = _datasource; + }]) + ); + + describe('applyUpdates tests\n', function () { + injectDatasource('myOnePageDatasource'); + var scrollSettings = {datasource: 'myOnePageDatasource', adapter: 'adapter'}; + + it('should create adapter object', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(viewport.children().length).toBe(5); + + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should update rows in place', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function(item, scope){ + return [item + ' *' + scope.$index]; + } + ); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one *1'); + expect(Helper.getRow(viewport, 2)).toBe('2: two *2'); + expect(Helper.getRow(viewport, 3)).toBe('3: three *3'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one *1'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three *3'); + } + ); + }); + + it('should update selected (first) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item, scope) { + if (item === 'one') { + return [item + ' *' + scope.$index]; + } + } + ); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one *1'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one *1'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should update selected (middle) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item, scope) { + if (item === 'two') { + return [item + ' *' + scope.$index]; + } + } + ); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two *2'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should update selected (last) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item, scope) { + if (item === 'three') { + return [item + ' *' + scope.$index]; + } + } + ); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three *3'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three *3'); + } + ); + }); + + it('should delete selected (first) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item) { + if (item === 'one') { + return []; + } + } + ); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('2: two'); + expect(Helper.getRow(viewport, 2)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('2: two'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should delete selected (first) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + + datasource; + + scope.adapter.applyUpdates( + function (item) { + if (item === 'one') { + return []; + } + }, + { immutableTop: true } + ); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('1: two'); + expect(Helper.getRow(viewport, 2)).toBe('2: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: two'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('2: three'); + } + ); + }); + + var deleteMiddleRow = function (viewport, scope, options) { + + scope.adapter.applyUpdates( + function (item) { + if (item === 'two') { + return []; + } + }, + options + ); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('2: three'); + }; + + it('should delete selected (middle) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + deleteMiddleRow(viewport, scope); + } + ); + }); + + it('should delete selected (middle) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + deleteMiddleRow(viewport, scope, { immutableTop: true }); + } + ); + }); + + var deleteLastRow = function (viewport, scope, options) { + scope.adapter.applyUpdates( + function (item) { + if (item === 'three') { + return []; + } + }, + options + ); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('2: two'); + }; + + it('should delete selected (last) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + deleteLastRow(viewport, scope); + } + ); + }); + + it('should delete selected (last) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + deleteLastRow(viewport, scope, { immutableTop: true }); + } + ); + }); + + it('should insert a new element before selected (first) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item) { + if (item === 'one') { + return ['before one', item]; + } + } + ); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('0: before one'); + expect(Helper.getRow(viewport, 2)).toBe('1: one'); + expect(Helper.getRow(viewport, 3)).toBe('2: two'); + expect(Helper.getRow(viewport, 4)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('0: before one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should insert a new element before selected (first) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item) { + if (item === 'one') { + return ['before one', item]; + } + }, + { immutableTop: true } + ); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('1: before one'); + expect(Helper.getRow(viewport, 2)).toBe('2: one'); + expect(Helper.getRow(viewport, 3)).toBe('3: two'); + expect(Helper.getRow(viewport, 4)).toBe('4: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: before one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('4: three'); + } + ); + }); + + var insertAfterFirst = function (viewport, scope, options) { + scope.adapter.applyUpdates( + function (item) { + if (item.text === 'one') { + return [item, { text: 'after one' }]; + } + }, + options + ); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: after one'); + expect(Helper.getRow(viewport, 3)).toBe('3: two'); + expect(Helper.getRow(viewport, 4)).toBe('4: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('4: three'); + }; + + it('should insert a new element after selected (first) row', function () { + var scrollSettings = { datasource: 'myObjectDatasource', adapter: 'adapter', template: '{{$index}}: {{item.text}}' }; + runTest(scrollSettings, + function (viewport, scope) { + insertAfterFirst(viewport, scope); + } + ); + }); + + it('should insert a new element after selected (first) row with immutableTop option', function () { + var scrollSettings = { datasource: 'myObjectDatasource', adapter: 'adapter', template: '{{$index}}: {{item.text}}' }; + runTest(scrollSettings, + function (viewport, scope) { + insertAfterFirst(viewport, scope, { immutableTop: true }); + } + ); + }); + + var insertBeforeSecond = function (viewport, scope, options) { + scope.adapter.applyUpdates( + function (item) { + if (item === 'two') { + return ['before two', item]; + } + }, + options + ); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: before two'); + expect(Helper.getRow(viewport, 3)).toBe('3: two'); + expect(Helper.getRow(viewport, 4)).toBe('4: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('4: three'); + }; + + it('should insert a new element before selected (middle) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + insertBeforeSecond(viewport, scope); + } + ); + }); + + it('should insert a new element before selected (middle) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + insertBeforeSecond(viewport, scope, { immutableTop: true }); + } + ); + }); + + var insertAfterLast = function (viewport, scope, options) { + scope.adapter.applyUpdates( + function (item) { + if (item === 'three') { + return [item, 'after three']; + } + }, + options + ); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + expect(Helper.getRow(viewport, 4)).toBe('4: after three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('4: after three'); + }; + + it('should insert a new element after selected (last) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + insertAfterLast(viewport, scope); + } + ); + }); + + it('should insert a new element after selected (last) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + insertAfterLast(viewport, scope, { immutableTop: true }); + } + ); + }); + }); + + describe('applyUpdates tests (index based)\n', function () { + var scrollSettings = {datasource: 'myOnePageDatasource', adapter: 'adapter'}; + + it('should update selected (first) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates(1, ['one *1']); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one *1'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one *1'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should ignore out of bound indexes', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates(0, ['invalid']); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should ignore out of bound indexes 2', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates(4, ['invalid']); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should update selected (middle) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates(2, ['two *2']); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two *2'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should update selected (last) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates(3, ['three *3']); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three *3'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three *3'); + } + ); + }); + + it('should delete selected (first) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates(1, []); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('2: two'); + expect(Helper.getRow(viewport, 2)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('2: two'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should delete selected (first) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + + expect(viewport.children().length).toBe(5); + + scope.adapter.applyUpdates(1, [], { immutableTop: true }); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('1: two'); + expect(Helper.getRow(viewport, 2)).toBe('2: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: two'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('2: three'); + } + ); + }); + + var deleteMiddleRow = function (viewport, scope, options) { + scope.adapter.applyUpdates(2, [], options); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('2: three'); + }; + + it('should delete selected (middle) row', function () { + runTest(scrollSettings, function (viewport, scope) { + deleteMiddleRow(viewport, scope); + }); + }); + + it('should delete selected (middle) row with immutableTop option', function () { + runTest(scrollSettings, function (viewport, scope) { + deleteMiddleRow(viewport, scope, { immutableTop: true }); + }); + }); + + var deleteLastRow = function (viewport, scope) { + scope.adapter.applyUpdates(3, []); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('2: two'); + }; + + it('should delete selected (last) row', function () { + runTest(scrollSettings, function (viewport, scope) { + deleteLastRow(viewport, scope); + }); + }); + + it('should delete selected (last) row with immutableTop option', function () { + runTest(scrollSettings, function (viewport, scope) { + deleteLastRow(viewport, scope, { immutableTop: true }); + }); + }); + + it('should insert a new element before selected (first) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates(1, ['before one', 'one']); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('0: before one'); + expect(Helper.getRow(viewport, 2)).toBe('1: one'); + expect(Helper.getRow(viewport, 3)).toBe('2: two'); + expect(Helper.getRow(viewport, 4)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('0: before one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should insert a new element before selected (first) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + + expect(viewport.children().length).toBe(5); + + scope.adapter.applyUpdates(1, ['before one', 'one'], { immutableTop: true }); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('1: before one'); + expect(Helper.getRow(viewport, 2)).toBe('2: one'); + expect(Helper.getRow(viewport, 3)).toBe('3: two'); + expect(Helper.getRow(viewport, 4)).toBe('4: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: before one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('4: three'); + } + ); + }); + + var insertAfterFirst = function (viewport, scope, options) { + scope.adapter.applyUpdates(1, ['one', 'after one'], options); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: after one'); + expect(Helper.getRow(viewport, 3)).toBe('3: two'); + expect(Helper.getRow(viewport, 4)).toBe('4: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('4: three'); + }; + + it('should insert a new element after selected (first) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + insertAfterFirst(viewport, scope); + } + ); + }); + + it('should insert a new element after selected (first) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + insertAfterFirst(viewport, scope, { immutableTop: true }); + } + ); + }); + + var insertBeforeSecond = function (viewport, scope, options) { + scope.adapter.applyUpdates(2, ['before two', 'two'], options); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: before two'); + expect(Helper.getRow(viewport, 3)).toBe('3: two'); + expect(Helper.getRow(viewport, 4)).toBe('4: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('4: three'); + }; + + it('should insert a new element before selected (middle) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + insertBeforeSecond(viewport, scope); + } + ); + }); + + it('should insert a new element before selected (middle) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + insertBeforeSecond(viewport, scope, { immutableTop: true }); + } + ); + }); + + var insretAfterLast = function (viewport, scope, options) { + scope.adapter.applyUpdates(3, ['three', 'after three'], options); + + expect(viewport.children().length).toBe(6); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + expect(Helper.getRow(viewport, 4)).toBe('4: after three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('4: after three'); + }; + + it('should insert a new element after selected (last) row', function () { + runTest(scrollSettings, + function (viewport, scope) { + insretAfterLast(viewport, scope); + } + ); + }); + + it('should insert a new element after selected (last) row with immutableTop option', function () { + runTest(scrollSettings, + function (viewport, scope) { + insretAfterLast(viewport, scope, { immutableTop: true }); + } + ); + }); + }); + + describe('applyUpdates tests with object items\n', function () { + var scrollSettings = { + datasource: 'myObjectDatasource', + adapter: 'adapter', + template: '{{$index}}: {{item.text}}' + }; + + it('should update existing item inplace', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item, scope) { + item.text += ' *' + scope.$index; + } + ); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one *1'); + expect(Helper.getRow(viewport, 2)).toBe('2: two *2'); + expect(Helper.getRow(viewport, 3)).toBe('3: three *3'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one *1'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three *3'); + } + ); + }); + + it('should replace existing item with an updated one', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item, scope) { + return [ + { + text: item.text + ' *' + scope.$index + } + ]; + } + ); + + expect(viewport.children().length).toBe(5); + expect(Helper.getRow(viewport, 1)).toBe('1: one *1'); + expect(Helper.getRow(viewport, 2)).toBe('2: two *2'); + expect(Helper.getRow(viewport, 3)).toBe('3: three *3'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one *1'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three *3'); + } + ); + }); + + it('should preserve the order of inserted items', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item, scope) { + if (scope.$index === 1) { + item.text += ' *' + scope.$index; + return [ + {text: item.text + ' before 1'}, + {text: item.text + ' before 2'}, + item, + {text: item.text + ' after 1'}, + {text: item.text + ' after 2'} + ]; + } + } + ); + + expect(viewport.children().length).toBe(9); + expect(Helper.getRow(viewport, 1)).toBe('-1: one *1 before 1'); + expect(Helper.getRow(viewport, 2)).toBe('0: one *1 before 2'); + expect(Helper.getRow(viewport, 3)).toBe('1: one *1'); + expect(Helper.getRow(viewport, 4)).toBe('2: one *1 after 1'); + expect(Helper.getRow(viewport, 5)).toBe('3: one *1 after 2'); + expect(Helper.getRow(viewport, 6)).toBe('4: two'); + expect(Helper.getRow(viewport, 7)).toBe('5: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('-1: one *1 before 1'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('5: three'); + } + ); + }); + + it('should preserve the order of inserted items 2', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.applyUpdates( + function (item, scope) { + if (scope.$index === 2) { + item.text += ' *' + scope.$index; + return [ + {text: item.text + ' before 1'}, + {text: item.text + ' before 2'}, + item, + {text: item.text + ' after 1'}, + {text: item.text + ' after 2'} + ]; + } + } + ); + + expect(viewport.children().length).toBe(9); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two *2 before 1'); + expect(Helper.getRow(viewport, 3)).toBe('3: two *2 before 2'); + expect(Helper.getRow(viewport, 4)).toBe('4: two *2'); + expect(Helper.getRow(viewport, 5)).toBe('5: two *2 after 1'); + expect(Helper.getRow(viewport, 6)).toBe('6: two *2 after 2'); + expect(Helper.getRow(viewport, 7)).toBe('7: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('7: three'); + } + ); + }); + }); + + describe('append tests\n', function () { + + it('should append two rows to the dataset', function () { + runTest({datasource: 'myOnePageDatasource', adapter: 'adapter'}, + function (viewport, scope) { + + scope.adapter.append(['appended one', 'appended two']); + + expect(viewport.children().length).toBe(7); + expect(Helper.getRow(viewport, 1)).toBe('1: one'); + expect(Helper.getRow(viewport, 2)).toBe('2: two'); + expect(Helper.getRow(viewport, 3)).toBe('3: three'); + expect(Helper.getRow(viewport, 4)).toBe('4: appended one'); + expect(Helper.getRow(viewport, 5)).toBe('5: appended two'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('5: appended two'); + } + ); + }); + + it('should append two rows to the empty dataset', function () { + runTest({datasource: 'myEmptyDatasource', adapter: 'adapter'}, + function (viewport, scope) { + + scope.adapter.append(['appended one', 'appended two']); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('1: appended one'); + expect(Helper.getRow(viewport, 2)).toBe('2: appended two'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: appended one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('2: appended two'); + } + ); + }); + + }); + + describe('prepend tests\n', function () { + + it('should prepend two rows to the dataset', function () { + runTest({ datasource: 'myOnePageDatasource', adapter: 'adapter' }, + function (viewport, scope) { + + scope.adapter.prepend(['prepended one', 'prepended two']); + + expect(viewport.children().length).toBe(7); + expect(Helper.getRow(viewport, 1)).toBe('-1: prepended one'); + expect(Helper.getRow(viewport, 2)).toBe('0: prepended two'); + expect(Helper.getRow(viewport, 3)).toBe('1: one'); + expect(Helper.getRow(viewport, 4)).toBe('2: two'); + expect(Helper.getRow(viewport, 5)).toBe('3: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('-1: prepended one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('3: three'); + } + ); + }); + + it('should prepend two rows to the dataset with immutableTop option', function () { + runTest({ datasource: 'myOnePageDatasource', adapter: 'adapter' }, + function (viewport, scope) { + + scope.adapter.prepend(['prepended one', 'prepended two'], { immutableTop: true }); + + expect(viewport.children().length).toBe(7); + expect(Helper.getRow(viewport, 1)).toBe('1: prepended one'); + expect(Helper.getRow(viewport, 2)).toBe('2: prepended two'); + expect(Helper.getRow(viewport, 3)).toBe('3: one'); + expect(Helper.getRow(viewport, 4)).toBe('4: two'); + expect(Helper.getRow(viewport, 5)).toBe('5: three'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: prepended one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('5: three'); + } + ); + }); + + it('should prepend two rows to the empty dataset', function () { + runTest({ datasource: 'myEmptyDatasource', adapter: 'adapter' }, + function (viewport, scope) { + + scope.adapter.prepend(['prepended one', 'prepended two']); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('-1: prepended one'); + expect(Helper.getRow(viewport, 2)).toBe('0: prepended two'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('-1: prepended one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('0: prepended two'); + } + ); + }); + + it('should prepend two rows to the empty dataset with immutableTop option', function () { + runTest({ datasource: 'myEmptyDatasource', adapter: 'adapter' }, + function (viewport, scope) { + + scope.adapter.prepend(['prepended one', 'prepended two'], { immutableTop: true }); + + expect(viewport.children().length).toBe(4); + expect(Helper.getRow(viewport, 1)).toBe('1: prepended one'); + expect(Helper.getRow(viewport, 2)).toBe('2: prepended two'); + + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.topVisibleElement[0].innerHTML).toBe('1: prepended one'); + expect(scope.adapter.bottomVisibleElement[0].innerHTML).toBe('2: prepended two'); + } + ); + }); + + }); + + describe('adapter reload tests', function () { + var scrollSettings = {datasource: 'myInfiniteDatasource', adapter: 'adapter'}; + + it('initial load should be positioned at item#1', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.topVisible).toBe('item1'); + } + ); + }); + + it('reload(100) should position it at item#100', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.topVisible).toBe('item1'); + + scope.adapter.reload(100); + + expect(scope.adapter.topVisible).toBe('item100'); + } + ); + }); + + it('reload() after reload(100) should position it at item#100', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.topVisible).toBe('item1'); + + scope.adapter.reload(100); + + expect(scope.adapter.topVisible).toBe('item100'); + + scope.adapter.reload(); + + expect(scope.adapter.topVisible).toBe('item100'); + } + ); + }); + + it('reload(0) after reload(100) should position it at item#0', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.topVisible).toBe('item1'); + + scope.adapter.reload(100); + + expect(scope.adapter.topVisible).toBe('item100'); + + scope.adapter.reload(0); + + expect(scope.adapter.topVisible).toBe('item0'); + } + ); + }); + + it('should round numbers for startIndex', () => { + runTest(scrollSettings, + function (viewport, scope) { + scope.adapter.reload(23.4); + expect(scope.adapter.topVisible).toBe('item23'); + + scope.adapter.reload(-56.9); + expect(scope.adapter.topVisible).toBe('item-57'); + } + ); + }); + + it('should correctly convert string to number and round', () => { + runTest(scrollSettings, + function (viewport, scope) { + scope.adapter.reload('1001.14'); + expect(scope.adapter.topVisible).toBe('item1001'); + + scope.adapter.reload('0'); + expect(scope.adapter.topVisible).toBe('item0'); + } + ); + }); + + it('should set startIndex to default if number is invalid', () => { + runTest(scrollSettings, + function (viewport, scope) { + scope.adapter.reload('invalid number'); + expect(scope.adapter.topVisible).toBe('item1'); + + scope.adapter.reload({}); + expect(scope.adapter.topVisible).toBe('item1'); + + scope.adapter.reload(null); + expect(scope.adapter.topVisible).toBe('item1'); + } + ); + }); + + }); + + describe('adapter bof/eof/empty', function () { + + it('empty dataset', function () { + runTest({datasource: 'myEmptyDatasource', adapter: 'adapter'}, + function (viewport, scope) { + expect(scope.adapter.isEmpty()).toBe(true); + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(true); + } + ); + }); + + it('one short page dataset', function () { + runTest({datasource: 'myOnePageDatasource', adapter: 'adapter'}, + function (viewport, scope) { + expect(scope.adapter.isEmpty()).toBe(false); + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(true); + } + ); + }); + + it('one big page dataset', function () { + runTest({datasource: 'myOneBigPageDatasource', adapter: 'adapter'}, + function (viewport, scope) { + expect(scope.adapter.isEmpty()).toBe(false); + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(false); + } + ); + }); + + it('one big page dataset after scroll down', function () { + runTest({datasource: 'myOneBigPageDatasource', adapter: 'adapter'}, + function (viewport, scope) { + + expect(scope.adapter.isEmpty()).toBe(false); + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(false); + + viewport.scrollTop(10000); + + expect(scope.adapter.isEOF()).toBe(true); + expect(scope.adapter.bottomVisible).toBe('item99'); + } + ); + }); + + }); + + describe('adapter bottomVisible', function () { + var scrollSettings = {datasource: 'myMultipageDatasource', adapter: 'adapter', viewportHeight: 80, itemHeight: 20}; + + it('scroll down a bit', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.bottomVisible).toBe('item4'); + + viewport.scrollTop(10); + expect(scope.adapter.bottomVisible).toBe('item5'); + + viewport.scrollTop(20); + expect(scope.adapter.bottomVisible).toBe('item5'); + + viewport.scrollTop(30); + expect(scope.adapter.bottomVisible).toBe('item6'); + } + ); + }); + + it('scroll down to the very bottom', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.bottomVisible).toBe('item4'); + + viewport.scrollTop(1000); + expect(scope.adapter.bottomVisible).toBe('item10'); + + viewport.scrollTop(1000); + expect(scope.adapter.bottomVisible).toBe('item20'); + } + ); + }); + + }); + + describe('adapter append/prepend clipping', function () { + var scrollSettings = {datasource: 'myOnePageDatasource', adapter: 'adapter', viewportHeight: 60, itemHeight: 20, bufferSize: 3, padding: 1}; + + it('should not clip after 1 small pack appended', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.isEOF()).toBe(true); + + scope.adapter.append(['item1*', 'item2*', 'item3*']); + expect(scope.adapter.isEOF()).toBe(true); + expect(viewport.children().length).toBe(2 + 3 + 3); + expect(Helper.getLastRow(viewport)).toBe('6: item3*'); + } + ); + }); + + it('should clip 1 bottom item from the 1 big pack appended', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.isEOF()).toBe(true); + + scope.adapter.append(['item1*', 'item2*', 'item3*', 'item4*']); + expect(scope.adapter.isEOF()).toBe(false); + + viewport.scrollTop(10000); + expect(scope.adapter.isEOF()).toBe(true); + expect(viewport.children().length).toBe(2 + 3 + 3); + expect(Helper.getLastRow(viewport)).toBe('6: item3*'); + } + ); + }); + + it('should clip 1 pack from top after 3 packs appended', function () { + runTest(scrollSettings, + function (viewport, scope) { + + scope.adapter.append(['item1*', 'item2*', 'item3*', 'item4*']); + expect(viewport.children().length).toBe(2 + 3 + 3); + + viewport.scrollTop(3 * 20); + scope.adapter.append(['item4*', 'item5*', 'item6*', 'item7*']); + expect(viewport.children().length).toBe(2 + 3 + 3 + 3); + + viewport.scrollTop(3 * 20 * 2); + scope.adapter.append(['item7*', 'item8*', 'item9*', 'item10*']); + expect(viewport.children().length).toBe(2 + 3 + 3 + 3); + + expect(Helper.getFirstRow(viewport)).toBe('4: item1*'); + expect(Helper.getLastRow(viewport)).toBe('12: item9*'); + } + ); + }); + + }); + + describe('adapter bufferFirst, bufferLast, bufferLength', function () { + var scrollSettings = { datasource: 'myMultipageDatasource', adapter: 'adapter', viewportHeight: 80, itemHeight: 20 }; + + it('without scroll', function () { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.adapter.bufferFirst).toBe('item1'); + expect(Helper.getFirstRow(viewport)).toBe('1: item1'); + expect(scope.adapter.bufferLast).toBe('item10'); + expect(Helper.getLastRow(viewport)).toBe('10: item10'); + expect(scope.adapter.bufferLength).toBe(10); + } + ); + }); + + it('scroll to the bottom', function () { + runTest(scrollSettings, + function (viewport, scope) { + viewport.scrollTop(10000); + expect(scope.adapter.bufferFirst).toBe('item5'); + expect(Helper.getFirstRow(viewport)).toBe('5: item5'); + expect(scope.adapter.bufferLast).toBe('item20'); + expect(Helper.getLastRow(viewport)).toBe('20: item20'); + expect(scope.adapter.bufferLength).toBe(16); + } + ); + }); + }); + +}); diff --git a/test/AssigningSpec.js b/test/AssigningSpec.js new file mode 100644 index 00000000..9f08b778 --- /dev/null +++ b/test/AssigningSpec.js @@ -0,0 +1,234 @@ +describe('uiScroll', function () { + 'use strict'; + + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.test.datasources')); + + var myApp = angular.module('myApp',[]); + myApp.controller('MyTopController', function($scope) { + $scope.name = 'MyTopController'; + }); + myApp.controller('MyInnerController', function($scope) { + $scope.name = 'MyInnerController'; + $scope.container = {}; + }); + myApp.controller('MyBottomController', function($scope) { + $scope.name = 'MyBottomController'; + $scope.container = {}; + }); + + beforeEach(module('myApp')); + + var setDirective = function(options) { + return function() { + var directive = { + restrict: 'E', + scope: true, + controller: function($scope) { + this.show = true; + this.container = {}; + $scope.container = {}; + } + }; + if (options.ctrlAs) { + directive.controllerAs = options.ctrlAs; + } + directive.template = options.template; + return directive; + }; + }; + + var executeTest = function(template, scopeSelector, scopeContainer) { + inject(function($rootScope, $compile) { + // build and render + var templateElement = angular.element(template); + var scope = $rootScope.$new(); + angular.element(document).find('body').append(templateElement); + $compile(templateElement)(scope); + scope.$apply(); + + // find adapter element and scope container + var adapterContainer; + if(scopeSelector) { + var adapterElement; + if(typeof scopeSelector === 'string') { + adapterElement = templateElement.find('[ng-controller="' + scopeSelector + '"]'); + } + else { //number + adapterElement = templateElement.find('my-dir' + scopeSelector); + } + adapterContainer = adapterElement.scope(); + } + else { + adapterContainer = $rootScope; + } + if (scopeContainer) { + adapterContainer = adapterContainer[scopeContainer]; + } + + // expectations + expect(!!adapterContainer.adapter).toBe(true); + expect(angular.isString(adapterContainer.adapter.topVisible)).toBe(true); + + // clean up + templateElement.remove(); + }); + }; + + describe('Adapter assigning', function () { + + it('should work in simplest case (viewport)', function () { + var template = +'
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 'MyBottomController'); + }); + + it('should work in simplest case (no viewport)', function () { + var template = +'
    ' + + '
    ' + + '
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 'MyBottomController'); + }); + + it('should work with additional container (viewport)', function () { + var template = +'
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 'MyBottomController', 'ctrl'); + }); + + it('should work with additional container (no viewport)', function () { + var template = +'
    ' + + '
    ' + + '
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 'MyBottomController', 'ctrl'); + }); + + it('should work for "Controller As" syntax (viewport)', function () { + var template = +'
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 'MyInnerController as ctrl', 'ctrl'); + }); + + it('should work for "Controller As" syntax (no viewport)', function () { + var template = +'
    ' + + '
    ' + + '
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 'MyInnerController as ctrl', 'ctrl'); + }); + + it('should work for custom directive with "Controller As" syntax (viewport)', function () { + myApp.directive('myDir1', setDirective({ + ctrlAs: 'ctrl', + template: +'
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + +'
    ' + })); + var template = +'
    ' + + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 1, 'ctrl'); + }); + + it('should work for custom directive with "Controller As" syntax (no viewport)', function () { + myApp.directive('myDir2', setDirective({ + ctrlAs: 'ctrl', + template: +'
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + +'
    ' + })); + var template = +'
    ' + + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 2, 'ctrl'); + }); + + it('should work for custom directive with the adapter defined on some external controller', function () { + myApp.directive('myDir3', setDirective({ + ctrlAs: 'ctrl2', + template: +'
    ' + + '
    ' + + '{{$index}}: {{item}}' + + '
    ' + +'
    ' + })); + var template = +'
    ' + + '
    ' + + '
    ' + + '' + + '
    ' + + '
    ' + +'
    '; + executeTest(template, 'MyInnerController as ctrl', 'ctrl'); + }); + }); + +}); diff --git a/test/BasicSetupSpec.js b/test/BasicSetupSpec.js new file mode 100644 index 00000000..1744aead --- /dev/null +++ b/test/BasicSetupSpec.js @@ -0,0 +1,112 @@ +describe('uiScroll', function() { + 'use strict'; + + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.test.datasources')); + + describe('basic setup', function() { + + it('should throw an error if the template\'s wrong', function() { + runTest({ datasource: 'myEmptyDatasource', extra: 'ng-if="false"' }, null, { + catch: function(error) { + expect(error.message).toBe('ui-scroll directive requires an Element node for templating the view'); + } + } + ); + }); + + var scrollSettings = { datasource: 'myEmptyDatasource' }; + + it('should bind to window scroll and resize events and unbind them after the scope is destroyed', function() { + spyOn($.fn, 'on').and.callThrough(); + spyOn($.fn, 'off').and.callThrough(); + runTest(scrollSettings, + function(viewport) { + expect($.fn.on.calls.all().length).toBe(4); + expect($.fn.on.calls.all()[0].args[0]).toBe('visibilitychange'); + expect($.fn.on.calls.all()[1].args[0]).toBe('mousewheel'); + expect($.fn.on.calls.all()[1].object[0]).toBe(viewport[0]); + expect($.fn.on.calls.all()[2].args[0]).toBe('resize'); + expect($.fn.on.calls.all()[2].object[0]).toBe(viewport[0]); + expect($.fn.on.calls.all()[3].args[0]).toBe('scroll'); + expect($.fn.on.calls.all()[3].object[0]).toBe(viewport[0]); + }, { + cleanupTest: function(viewport, scope, $timeout) { + $timeout(function() { + expect($.fn.off.calls.all().length).toBe(4); + expect($.fn.off.calls.all()[0].args[0]).toBe('visibilitychange'); + expect($.fn.off.calls.all()[1].args[0]).toBe('resize'); + expect($.fn.off.calls.all()[1].object[0]).toBe(viewport[0]); + expect($.fn.off.calls.all()[2].args[0]).toBe('scroll'); + expect($.fn.off.calls.all()[2].object[0]).toBe(viewport[0]); + expect($.fn.off.calls.all()[3].args[0]).toBe('mousewheel'); + expect($.fn.off.calls.all()[3].object[0]).toBe(viewport[0]); + }); + } + } + ); + }); + + it('should create 2 divs of 0 height', function() { + runTest(scrollSettings, + function(viewport) { + expect(viewport.children().length).toBe(2); + + var topPadding = viewport.children()[0]; + expect(topPadding.tagName.toLowerCase()).toBe('div'); + expect(Helper.getTopPadding(viewport)).toBe(0); + + var bottomPadding = viewport.children()[1]; + expect(bottomPadding.tagName.toLowerCase()).toBe('div'); + expect(Helper.getBottomPadding(viewport)).toBe(0); + } + ); + }); + + it('should call get on the datasource 2 times ', function() { + var spy; + inject(function(myEmptyDatasource) { + spy = spyOn(myEmptyDatasource, 'get').and.callThrough(); + }); + runTest(scrollSettings, + function() { + expect(spy.calls.all().length).toBe(2); + expect(spy.calls.all()[0].args.length).toBe(3); + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[0].args[1]).toBe(10); + expect(spy.calls.all()[1].args.length).toBe(3); + expect(spy.calls.all()[1].args[0]).toBe(-9); + expect(spy.calls.all()[1].args[1]).toBe(10); + } + ); + }); + }); + + describe('basic setup (new datasource get signature)', function() { + var scrollSettings = { datasource: 'myDescriptoEmptyDatasource' }; + + it('should call get on the datasource 2 times ', function() { + var spy; + inject(function(myDescriptoEmptyDatasource) { + spy = spyOn(myDescriptoEmptyDatasource, 'get').and.callThrough(); + }); + runTest(scrollSettings, + function() { + expect(spy.calls.all().length).toBe(2); + expect(spy.calls.all()[0].args.length).toBe(2); + expect(spy.calls.all()[0].args[0].index).toBe(1); + expect(spy.calls.all()[0].args[0].count).toBe(10); + expect('append' in spy.calls.all()[0].args[0]).toBe(true); + expect(spy.calls.all()[0].args[0].append).toBeUndefined(); + expect('prepend' in spy.calls.all()[0].args[0]).toBe(false); + expect(spy.calls.all()[1].args.length).toBe(2); + expect(spy.calls.all()[1].args[0].index).toBe(-9); + expect(spy.calls.all()[1].args[0].count).toBe(10); + expect('append' in spy.calls.all()[1].args[0]).toBe(false); + expect('prepend' in spy.calls.all()[1].args[0]).toBe(true); + expect(spy.calls.all()[1].args[0].prepend).toBeUndefined(); + } + ); + }); + }); +}); diff --git a/test/BasicTestsSpec.js b/test/BasicTestsSpec.js new file mode 100644 index 00000000..64884dc9 --- /dev/null +++ b/test/BasicTestsSpec.js @@ -0,0 +1,756 @@ +describe('uiScroll', function () { + 'use strict'; + + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.test.datasources')); + + describe('datasource with only 3 elements', function () { + var scrollSettings = {datasource: 'myOnePageDatasource'}; + + it('should create 3 divs with data (+ 2 padding divs)', function () { + runTest(scrollSettings, + function (viewport) { + expect(viewport.children().length).toBe(5); + + var row1 = viewport.children()[1]; + expect(row1.tagName.toLowerCase()).toBe('div'); + expect(row1.innerHTML).toBe('1: one'); + + var row2 = viewport.children()[2]; + expect(row2.tagName.toLowerCase()).toBe('div'); + expect(row2.innerHTML).toBe('2: two'); + + var row3 = viewport.children()[3]; + expect(row3.tagName.toLowerCase()).toBe('div'); + expect(row3.innerHTML).toBe('3: three'); + } + ); + }); + + it('should call get on the datasource 2 times ', function () { + var spy; + inject(function (myOnePageDatasource) { + spy = spyOn(myOnePageDatasource, 'get').and.callThrough(); + runTest(scrollSettings, + function () { + expect(spy.calls.all().length).toBe(2); + expect(spy.calls.all()[0].args[0]).toBe(1); // gets 3 rows (with eof) + expect(spy.calls.all()[1].args[0]).toBe(-9); // gets 0 rows (and bof) + }); + }); + }); + }); + + describe('datasource with 3 elements and buffersize 3 (new get signature)', function() { + var scrollSettings = { datasource: 'myDescriptorOnePageDatasource', bufferSize: 3 }; + + it('should call get on the datasource 3 times ', function () { + var spy; + inject(function (myDescriptorOnePageDatasource) { + spy = spyOn(myDescriptorOnePageDatasource, 'get').and.callThrough(); + runTest(scrollSettings, + function () { + expect(spy.calls.all().length).toBe(3); + expect(spy.calls.all()[0].args[0].index).toBe(1); // gets 3 rows (no eof) + expect(spy.calls.all()[0].args[0].count).toBe(3); + expect('append' in spy.calls.all()[0].args[0]).toBe(true); + expect(spy.calls.all()[0].args[0].append).toBeUndefined(); + expect('prepend' in spy.calls.all()[0].args[0]).toBe(false); + expect(spy.calls.all()[1].args[0].index).toBe(4); // gets 0 rows (and eof) + expect(spy.calls.all()[1].args[0].count).toBe(3); + expect('append' in spy.calls.all()[1].args[0]).toBe(true); + expect(spy.calls.all()[1].args[0].append).toBe('three'); + expect('prepend' in spy.calls.all()[1].args[0]).toBe(false); + expect(spy.calls.all()[2].args[0].index).toBe(-2); // gets 0 rows (and bof) + expect(spy.calls.all()[2].args[0].count).toBe(3); + expect('append' in spy.calls.all()[2].args[0]).toBe(false); + expect('prepend' in spy.calls.all()[2].args[0]).toBe(true); + expect(spy.calls.all()[2].args[0].prepend).toBe('one'); + }); + }); + }); + }); + + describe('datasource with only 3 elements (negative index)', function () { + var scrollSettings = { datasource: 'anotherDatasource' }; + it('should create 3 divs with data (+ 2 padding divs)', function () { + runTest(scrollSettings, + function (viewport) { + expect(viewport.children().length).toBe(5); + + var row1 = viewport.children()[1]; + expect(row1.tagName.toLowerCase()).toBe('div'); + expect(row1.innerHTML).toBe('-2: item-2'); + + var row2 = viewport.children()[2]; + expect(row2.tagName.toLowerCase()).toBe('div'); + expect(row2.innerHTML).toBe('-1: item-1'); + + var row3 = viewport.children()[3]; + expect(row3.tagName.toLowerCase()).toBe('div'); + expect(row3.innerHTML).toBe('0: item0'); + } + ); + }); + + it('should call get on the datasource 2 times ', function () { + var spy; + inject(function (anotherDatasource) { + spy = spyOn(anotherDatasource, 'get').and.callThrough(); + runTest(scrollSettings, + function () { + expect(spy.calls.all().length).toBe(2); + + expect(spy.calls.all()[0].args[0]).toBe(1); // gets 0 rows (and eof) + expect(spy.calls.all()[1].args[0]).toBe(-9); // gets 3 rows (and bof) + }); + }); + }); + }); + + describe('datasource with 20 elements and buffer size 3 - constrained viewport', function () { + var scrollSettings = { datasource: 'myMultipageDatasource', viewportHeight: 200, itemHeight: 40, bufferSize: 3 }; + + it('should create 9 divs with data (+ 2 padding divs)', function () { + runTest(scrollSettings, + function (viewport) { + var itemsLoaded = 9; + var itemsWithPaddings = itemsLoaded + 2; + expect(viewport.children().length).toBe(itemsWithPaddings); + expect(viewport.scrollTop()).toBe(0); + expect(Helper.getTopPadding(viewport)).toBe(0); + expect(Helper.getBottomPadding(viewport)).toBe(0); + + for (var i = 1; i < itemsLoaded; i++) { + var row = viewport.children()[i]; + expect(row.tagName.toLowerCase()).toBe('div'); + expect(row.innerHTML).toBe(i + ': item' + i); + } + } + ); + }); + + it('should call get on the datasource 4 times ', function () { + var spy; + inject(function (myMultipageDatasource) { + spy = spyOn(myMultipageDatasource, 'get').and.callThrough(); + }); + runTest(scrollSettings, + function () { + // There are 9 loaded items, so there were 3 data calls + // Additional call was for top items resulted with 0 items. + expect(spy.calls.all().length).toBe(4); + + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[1].args[0]).toBe(4); + expect(spy.calls.all()[2].args[0]).toBe(7); + expect(spy.calls.all()[3].args[0]).toBe(-2); + } + ); + }); + + it('should create 3 more divs (12 divs total) with data (+ 2 padding divs)', function () { + var itemsLoaded = 12; + var itemsWithPaddings = itemsLoaded + 2; + runTest(scrollSettings, + function (viewport) { + viewport.scrollTop(100); + inject(function () { + expect(viewport.children().length).toBe(itemsWithPaddings); + expect(viewport.scrollTop()).toBe(100); + expect(Helper.getTopPadding(viewport)).toBe(0); + expect(Helper.getBottomPadding(viewport)).toBe(0); + + for (var i = 1; i < itemsLoaded; i++) { + var row = viewport.children()[i]; + expect(row.tagName.toLowerCase()).toBe('div'); + expect(row.innerHTML).toBe(i + ': item' + i); + } + }); + } + ); + }); + + it('should call get on the datasource 1 extra time (5 total) ', function () { + var spy; + inject(function (myMultipageDatasource) { + spy = spyOn(myMultipageDatasource, 'get').and.callThrough(); + }); + runTest(scrollSettings, + function (viewport) { + viewport.scrollTop(100); + + expect(spy.calls.all().length).toBe(5); + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[1].args[0]).toBe(4); + expect(spy.calls.all()[2].args[0]).toBe(7); + expect(spy.calls.all()[3].args[0]).toBe(-2); + expect(spy.calls.all()[4].args[0]).toBe(10); + } + ); + }); + + it('should clip 4 divs from the top and add 3 more divs to the bottom (11 divs total) (+ 2 padding divs)', function () { + runTest(scrollSettings, + function (viewport) { + var itemsLoaded = 11; + var itemsWithPaddings = itemsLoaded + 2; + var clippedDivs = 4; + + viewport.scrollTop(100); + viewport.scrollTop(400); + + expect(viewport.children().length).toBe(itemsWithPaddings); + expect(viewport.scrollTop()).toBe(280); + expect(Helper.getTopPadding(viewport)).toBe(160); + expect(Helper.getBottomPadding(viewport)).toBe(0); + + for (var i = 1; i <= itemsLoaded; i++) { + var row = viewport.children()[i]; + expect(row.tagName.toLowerCase()).toBe('div'); + expect(row.innerHTML).toBe((i + clippedDivs) + ': item' + (i + clippedDivs)); + } + } + ); + }); + + it('should call get on the datasource 1 more time (6 total) ', function () { + var spy; + inject(function (myMultipageDatasource) { + spy = spyOn(myMultipageDatasource, 'get').and.callThrough(); + }); + runTest(scrollSettings, + function (viewport) { + var calls = 6; + + viewport.scrollTop(100); + viewport.scrollTop(400); + + expect(spy.calls.all().length).toBe(calls); + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[1].args[0]).toBe(4); + expect(spy.calls.all()[2].args[0]).toBe(7); + expect(spy.calls.all()[3].args[0]).toBe(-2); + expect(spy.calls.all()[4].args[0]).toBe(10); + expect(spy.calls.all()[5].args[0]).toBe(13); + } + ); + }); + + it('should re-add 3 divs at the top and clip 2 divs from the bottom (9 divs total) (+ 2 padding divs)', function () { + runTest(scrollSettings, + function (viewport) { + var itemsLoaded = 8; + var itemsWithPaddings = itemsLoaded + 2; + + viewport.scrollTop(100); + viewport.scrollTop(400); + viewport.scrollTop(0); + + expect(viewport.children().length).toBe(itemsWithPaddings); + expect(viewport.scrollTop()).toBe(0); + expect(Helper.getTopPadding(viewport)).toBe(0); + expect(Helper.getBottomPadding(viewport)).toBe(280); + + for (var i = 1; i <= itemsLoaded; i++) { + var row = viewport.children()[i]; + expect(row.tagName.toLowerCase()).toBe('div'); + expect(row.innerHTML).toBe((i) + ': item' + (i)); + } + } + ); + }); + + it('should call get on the datasource 1 more time (8 total) ', function () { + var spy; + inject(function (myMultipageDatasource) { + spy = spyOn(myMultipageDatasource, 'get').and.callThrough(); + }); + + runTest(scrollSettings, + function (viewport) { + var totalCallsNumber = 8; + + viewport.scrollTop(100); + viewport.scrollTop(400); + viewport.scrollTop(0); + + expect(spy.calls.all().length).toBe(totalCallsNumber); + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[1].args[0]).toBe(4); + expect(spy.calls.all()[2].args[0]).toBe(7); + expect(spy.calls.all()[3].args[0]).toBe(-2); + expect(spy.calls.all()[4].args[0]).toBe(10); + expect(spy.calls.all()[5].args[0]).toBe(13); + expect(spy.calls.all()[6].args[0]).toBe(2); + expect(spy.calls.all()[7].args[0]).toBe(-1); + } + ); + }); + }); + + describe('datasource with 12 elements and buffer size 3 (fold/edge cases)', function () { + var itemsCount = 12, buffer = 3, itemHeight = 20; + + it('[full frame] should call get on the datasource 4 (12/3) times + 2 additional times (with empty result)', function () { + var spy; + var viewportHeight = itemsCount * itemHeight; + + inject(function (myEdgeDatasource) { + spy = spyOn(myEdgeDatasource, 'get').and.callThrough(); + }); + + runTest( + { + datasource: 'myEdgeDatasource', + bufferSize: buffer, + viewportHeight: viewportHeight, + itemHeight: itemHeight + }, + function () { + expect(spy.calls.all().length).toBe(parseInt(itemsCount / buffer, 10) + 2); + + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[1].args[0]).toBe(4); + expect(spy.calls.all()[2].args[0]).toBe(7); + expect(spy.calls.all()[3].args[0]).toBe(-2); + expect(spy.calls.all()[4].args[0]).toBe(-5); + expect(spy.calls.all()[5].args[0]).toBe(-8); + } + ); + }); + + it('[fold frame] should call get on the datasource 3 times', function () { + var spy; + var viewportHeight = buffer * itemHeight; + + inject(function (myEdgeDatasource) { + spy = spyOn(myEdgeDatasource, 'get').and.callThrough(); + }); + + runTest( + { + datasource: 'myEdgeDatasource', + bufferSize: buffer, + viewportHeight: viewportHeight, + itemHeight: itemHeight + }, + function () { + expect(spy.calls.all().length).toBe(3); + + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[1].args[0]).toBe(4); + expect(spy.calls.all()[2].args[0]).toBe(-2); + } + ); + }); + + it('[fold frame, scroll down] should call get on the datasource 1 extra time', function () { + var spy; + var viewportHeight = buffer * itemHeight; + + inject(function (myEdgeDatasource) { + spy = spyOn(myEdgeDatasource, 'get').and.callThrough(); + }); + + runTest( + { + datasource: 'myEdgeDatasource', + bufferSize: buffer, + viewportHeight: viewportHeight, + itemHeight: itemHeight + }, + function (viewport) { + viewport.scrollTop(viewportHeight + itemHeight); + viewport.scrollTop(viewportHeight + itemHeight * 2); + + expect(spy.calls.all().length).toBe(4); + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[1].args[0]).toBe(4); //last full + expect(spy.calls.all()[2].args[0]).toBe(-2); + expect(spy.calls.all()[3].args[0]).toBe(6); //empty + + } + ); + }); + + it('[fold frame, scroll up] should call get on the datasource 2 extra times', function () { + var spy; + var viewportHeight = buffer * itemHeight; + + inject(function (myEdgeDatasource) { + spy = spyOn(myEdgeDatasource, 'get').and.callThrough(); + }); + + runTest( + { + datasource: 'myEdgeDatasource', + bufferSize: buffer, + viewportHeight: viewportHeight, + itemHeight: itemHeight + }, + function (viewport) { + viewport.scrollTop(0); //first full, scroll to -2 + viewport.scrollTop(0); //last full, scroll to -5, bof is reached + viewport.scrollTop(0); //empty, no scroll occurred (-8) + + expect(spy.calls.all().length).toBe(5); + expect(spy.calls.all()[0].args[0]).toBe(1); + expect(spy.calls.all()[1].args[0]).toBe(4); + expect(spy.calls.all()[2].args[0]).toBe(-2); //first full + expect(spy.calls.all()[3].args[0]).toBe(-5); //last full + expect(spy.calls.all()[4].args[0]).toBe(-8); //empty + } + ); + }); + }); + + describe('prevent unwanted scroll bubbling', function () { + var scrollSettings = { datasource: 'myDatasourceToPreventScrollBubbling', bufferSize: 3, viewportHeight: 300 }; + var documentScrollBubblingCount = 0; + + var incrementDocumentScrollCount = function (event) { + event = event.originalEvent || event; + if (!event.defaultPrevented) { + documentScrollBubblingCount++; + } + }; + var getNewWheelEvent = function () { + var event = document.createEvent('MouseEvents'); + event.initEvent('mousewheel', true, true); + event.wheelDelta = 120; + return event; + }; + + it('should prevent wheel-event bubbling until bof is reached', function () { + var spy; + + inject(function (myDatasourceToPreventScrollBubbling) { + spy = spyOn(myDatasourceToPreventScrollBubbling, 'get').and.callThrough(); + }); + + runTest(scrollSettings, + function (viewport) { + var wheelEventElement = viewport[0]; + + angular.element(document.body).on('mousewheel', incrementDocumentScrollCount); //spy for wheel-events bubbling + + //simulate multiple wheel-scroll events within viewport + + wheelEventElement.dispatchEvent(getNewWheelEvent()); //preventDefault will not occurred but the document will not scroll because of viewport will be scrolled + expect(documentScrollBubblingCount).toBe(1); + + viewport.scrollTop(0); + + wheelEventElement.dispatchEvent(getNewWheelEvent()); //now we are at the top but preventDefault is occurred because of bof will be reached only after next scroll trigger + expect(documentScrollBubblingCount).toBe(2); //here! the only one prevented wheel-event + + wheelEventElement.dispatchEvent(getNewWheelEvent()); //preventDefault will not occurred but document will not scroll because of viewport will be scrolled + expect(documentScrollBubblingCount).toBe(3); + + viewport.scrollTop(0); //bof will be reached right after that + + wheelEventElement.dispatchEvent(getNewWheelEvent()); //preventDefault will not occurred because of we are at the top and bof is reached + expect(documentScrollBubblingCount).toBe(4); + + wheelEventElement.dispatchEvent(getNewWheelEvent()); //preventDefault will not occurred because of we are at the top and bof is reached + expect(documentScrollBubblingCount).toBe(5); + + }, { + cleanupTest: function () { + angular.element(document.body).off('mousewheel', incrementDocumentScrollCount); + } + } + ); + }); + }); + + describe('calculation of the paddings', function () { + + var viewportHeight = 120; + var itemHeight = 20; + var bufferSize = 3; + + var scrollSettings = { + datasource: 'myInfiniteDatasource', + viewportHeight: viewportHeight, + itemHeight: itemHeight, + bufferSize: bufferSize + }; + + it('should calculate top padding element\'s height during scroll down', function () { + runTest(scrollSettings, + function (viewport) { + // scroll down + expectation + for(var i = 0; i < 6; i++) { + viewport.scrollTop(5000); + expect(Helper.getTopPadding(viewport)).toBe(itemHeight * bufferSize * (i + 1)); + } + } + ); + }); + + it('should calculate bottom padding element\'s height during scroll up', function () { + runTest(scrollSettings, + function (viewport) { + // scroll up + expectation + for(var i = 0; i < 6; i++) { + viewport.scrollTop(-5000); + expect(Helper.getBottomPadding(viewport)).toBe(itemHeight * bufferSize * (i + 1)); + } + + } + ); + }); + + it('should calculate both padding elements heights during scroll down and up', function () { + runTest(scrollSettings, + function (viewport) { + var scrollDelta = itemHeight * bufferSize; + var i, scrollIteration = 7; + + // scroll down + expectation + for(i = 0; i < scrollIteration; i++) { + viewport.scrollTop(viewport.scrollTop() + scrollDelta); + expect(Helper.getTopPadding(viewport)).toBe(itemHeight * bufferSize * (i + 1)); + expect(Helper.getBottomPadding(viewport)).toBe(0); + } + + // scroll up + expectation + for(i = 0; i < scrollIteration; i++) { + viewport.scrollTop(viewport.scrollTop() - scrollDelta); + expect(Helper.getTopPadding(viewport)).toBe(itemHeight * bufferSize * (scrollIteration - i - 1)); + expect(Helper.getBottomPadding(viewport)).toBe(itemHeight * bufferSize * (i + 1)); + } + + // further scroll up + expectation + for(i = scrollIteration; i < 2*scrollIteration; i++) { + viewport.scrollTop(viewport.scrollTop() - scrollDelta); + expect(Helper.getTopPadding(viewport)).toBe(0); + expect(Helper.getBottomPadding(viewport)).toBe(itemHeight * bufferSize * (i + 1)); + } + } + ); + }); + }); + + describe('topVisible property: deep access and sync', function () { + + it('should get topVisible as an adapter property', function () { + runTest({datasource: 'myMultipageDatasource', adapter: 'adapterContainer.innerContainer.adapter'}, + function (viewport, scope) { + expect(!!scope.adapterContainer && !!scope.adapterContainer.innerContainer && !!scope.adapterContainer.innerContainer.adapter).toBe(true); + expect(angular.isString(scope.adapterContainer.innerContainer.adapter.topVisible)).toBe(true); + } + ); + }); + + it('should get topVisible as a scope property', function () { + runTest({datasource: 'myMultipageDatasource', topVisible: 'scopeContainer.innerContainer.topVisible'}, + function (viewport, scope) { + expect(!!scope.scopeContainer && !!scope.scopeContainer.innerContainer).toBe(true); + expect(angular.isString(scope.scopeContainer.innerContainer.topVisible)).toBe(true); + } + ); + }); + + it('should sync scope-topVisible with adapter-topVisible during each fetching', function () { + runTest({ + datasource: 'myMultipageDatasource', + itemHeight: 40, + bufferSize: 3, + adapter: 'container1.adapter', + topVisible: 'container2.topVisible' + }, + function (viewport, scope) { + var topVisibleChangeCount = 0; + + scope.$watch('container1.adapter.topVisible', function(newValue) { + if(newValue === 'item1') { + return; + } + topVisibleChangeCount++; + + expect(scope.container1.adapter.topVisible).toBe(newValue); + expect(scope.container2.topVisible).toBe(newValue); + + if(topVisibleChangeCount === 1) { + expect(newValue).toBe('item3'); + } + else if(topVisibleChangeCount === 2) { + expect(newValue).toBe('item8'); + } + }); + + viewport.scrollTop(100); // 100 : 40 = 2.5 --> item3 + viewport.scrollTop(300); // 300 : 40 = 7.5 --> item8 + + expect(topVisibleChangeCount).toBe(2); + } + ); + }); + + it('should sync scope-topVisible with adapter-topVisible during each scrolling (single fetch case)', function () { + runTest({ + datasource: 'myOneBigPageDatasource', + itemHeight: 40, + bufferSize: 3, + adapter: 'container1.adapter', + topVisible: 'container2.topVisible' + }, + function (viewport, scope) { + var topVisibleChangeCount = 0; + + scope.$watch('container1.adapter.topVisible', function(newValue) { + if(newValue === 'item1') { + return; + } + topVisibleChangeCount++; + + expect(scope.container1.adapter.topVisible).toBe(newValue); + expect(scope.container2.topVisible).toBe(newValue); + + if(topVisibleChangeCount === 1) { + expect(newValue).toBe('item3'); + } + else if(topVisibleChangeCount === 2) { + expect(newValue).toBe('item8'); + } + }); + + viewport.scrollTop(100); // 100 : 40 = 2.5 --> item3 + viewport.scrollTop(300); // 300 : 40 = 7.5 --> item8 + + expect(topVisibleChangeCount).toBe(2); + } + ); + }); + + }); + + describe('disabled property', function () { + + it('should prevent datasource.get call', function () { + var spy; + inject(function (myInfiniteDatasource) { + spy = spyOn(myInfiniteDatasource, 'get').and.callThrough(); + }); + + runTest({datasource: 'myInfiniteDatasource', adapter: 'adapter'}, + function (viewport, scope) { + scope.adapter.disabled = true; + viewport.scrollTop(1000); // scroll to bottom + + expect(spy.calls.all().length).toBe(3); // just three initial requests + } + ); + }); + + it('should fetch new data after disabled = false', function () { + var spy; + inject(function (myInfiniteDatasource) { + spy = spyOn(myInfiniteDatasource, 'get').and.callThrough(); + }); + + runTest({datasource: 'myInfiniteDatasource', adapter: 'adapter'}, + function (viewport, scope) { + + scope.adapter.disabled = true; + viewport.scrollTop(1000); // scroll to bottom + scope.adapter.disabled = false; + + expect(spy.calls.all().length).toBe(4); // 3 initial + 1 new requests + } + ); + }); + + }); + + describe('attributes scope binding', function () { + var calls = 6; + var bufferSize = 5; + + it('bufferSize scope binding should work (1)', function () { + inject(function (myInfiniteDatasource) { + var spy = spyOn(myInfiniteDatasource, 'get').and.callThrough(); + runTest({datasource: 'myInfiniteDatasource', bufferSize: bufferSize}, + function () { + expect(spy.calls.all().length).toBe(calls); + } + ); + }); + }); + + it('bufferSize scope binding should work (2)', function () { + inject(function (myInfiniteDatasource) { + var spy = spyOn(myInfiniteDatasource, 'get').and.callThrough(); + runTest({datasource: 'myInfiniteDatasource', bufferSize: 'start'}, + function () { + expect(spy.calls.all().length).toBe(calls); + }, { + scope: { + 'start': bufferSize + } + } + ); + }); + }); + }); + + describe('interpolation', function() { + var myTemplate = '
    {{$index}}: {{item}}
    '; + var scrollSettings = { + datasource: 'myInfiniteDatasource', + template: myTemplate, + topVisible: 'topVisible', + bufferSize: 10 + }; + + it('should keep 1st item at the top after initial auto fetching is done', function() { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.topVisible).toBe('item1'); + expect(viewport.scrollTop()).toBe(400); // 1 pack (bufferSize * itemHeight) from the top + }, { + scope: { + 'itemHeight': 40 + } + } + ); + }); + + it('should keep (-bufferSize) item at the top after one manual fetching is done', function() { + runTest(scrollSettings, + function (viewport, scope) { + + viewport.scrollTop(0); // scroll to the very top + + expect(scope.topVisible).toBe('item-9'); + expect(viewport.scrollTop()).toBe(400); // 1 pack (bufferSize * itemHeight) from the top + }, { + scope: { + 'itemHeight': 40 + } + } + ); + }); + }); + + describe('effective height', function() { + var scrollSettings = { + datasource: 'myInfiniteDatasource', + topVisible: 'topVisible', + bufferSize: 3, + viewportHeight: 315 + }; + + it('should break through negative value', function() { + runTest(scrollSettings, + function (viewport, scope) { + expect(scope.topVisible).toBe('item1'); + } + ); + }); + }); + +}); diff --git a/test/BufferCleanupSpec.js b/test/BufferCleanupSpec.js new file mode 100644 index 00000000..7130abc6 --- /dev/null +++ b/test/BufferCleanupSpec.js @@ -0,0 +1,209 @@ +describe('uiScroll', () => { + 'use strict'; + + let datasource; + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.test.datasources')); + + const injectDatasource = datasourceToken => + beforeEach( + inject([datasourceToken, _datasource => + datasource = _datasource + ]) + ); + + describe('buffer cleanup', () => { + const settings = { + datasource: 'myEdgeDatasource', // items range is [-5..6] + adapter: 'adapter', + viewportHeight: 60, + itemHeight: 20, + padding: 0.3, + startIndex: 3, + bufferSize: 3 + }; + + injectDatasource('myEdgeDatasource'); + + const cleanBuffer = (scope, applyUpdateOptions) => { + const get = datasource.get; + const removedItems = []; + // sync the datasource + datasource.get = (index, count, success) => { + if (removedItems.indexOf('item' + index) !== -1) { + index += removedItems.length; + } + get(index, count, success); + }; + // clean up the buffer + scope.adapter.applyUpdates(item => { + removedItems.push(item); + return []; + }, applyUpdateOptions); + }; + + const shouldWorkWhenEOF = (viewport, scope, options) => { + expect(scope.adapter.isBOF()).toBe(false); + expect(scope.adapter.isEOF()).toBe(true); + expect(scope.adapter.bufferFirst).toBe('item0'); + expect(scope.adapter.bufferLast).toBe('item6'); + + // remove items 0..6 items form -5..6 datasource + cleanBuffer(scope, options); + + // result [-5..-1] + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(true); + expect(Helper.getRow(viewport, 1)).toBe('-5: item-5'); + expect(Helper.getRow(viewport, 2)).toBe('-4: item-4'); + expect(Helper.getRow(viewport, 3)).toBe('-3: item-3'); + expect(Helper.getRow(viewport, 4)).toBe('-2: item-2'); + expect(Helper.getRow(viewport, 5)).toBe('-1: item-1'); + expect(scope.adapter.bufferLength).toBe(5); + }; + + it('should be consistent on forward direction when eof with immutabeTop', () => + runTest(settings, (viewport, scope) => + shouldWorkWhenEOF(viewport, scope, { immutableTop: true }) + ) + ); + + it('should be consistent on forward direction when eof without immutabeTop', () => + runTest(settings, (viewport, scope) => + shouldWorkWhenEOF(viewport, scope) + ) + ); + + const shouldWorkWhenNotEOF = (viewport, scope, options) => { + expect(scope.adapter.isBOF()).toBe(false); + expect(scope.adapter.isEOF()).toBe(false); + expect(scope.adapter.bufferFirst).toBe('item-4'); + expect(scope.adapter.bufferLast).toBe('item1'); + + // remove items -4..1 items form -5..6 datasource + cleanBuffer(scope, options); + + // result [-5, 2, 3, 4] + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(false); + expect(Helper.getRow(viewport, 1)).toBe('-5: item-5'); + expect(Helper.getRow(viewport, 2)).toBe('-4: item2'); + expect(Helper.getRow(viewport, 3)).toBe('-3: item3'); + expect(Helper.getRow(viewport, 4)).toBe('-2: item4'); + expect(scope.adapter.bufferLength).toBe(4); + }; + + it('should be consistent on forward direction when not eof with immutabeTop', () => + runTest({ + ...settings, + startIndex: -1, + viewportHeight: 40 + }, (viewport, scope) => + shouldWorkWhenNotEOF(viewport, scope, { immutableTop: true }) + ) + ); + + it('should be consistent on forward direction when not eof without immutabeTop', () => + runTest({ + ...settings, + startIndex: -1, + viewportHeight: 40 + }, (viewport, scope) => + shouldWorkWhenNotEOF(viewport, scope) + ) + ); + + it('should be consistent on backward direction when bof with immutableTop', () => + runTest({ + ...settings, + startIndex: -3, + padding: 0.5 + }, (viewport, scope) => { + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(false); + expect(scope.adapter.bufferFirst).toBe('item-5'); + expect(scope.adapter.bufferLast).toBe('item1'); + + // remove items -5..1 items form -5..6 datasource + cleanBuffer(scope, { immutableTop: true }); + + // result [2..6] + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(true); + expect(Helper.getRow(viewport, 1)).toBe('-5: item2'); + expect(Helper.getRow(viewport, 2)).toBe('-4: item3'); + expect(Helper.getRow(viewport, 3)).toBe('-3: item4'); + expect(Helper.getRow(viewport, 4)).toBe('-2: item5'); + expect(Helper.getRow(viewport, 5)).toBe('-1: item6'); + expect(scope.adapter.bufferLength).toBe(5); + }) + ); + + it('should be consistent on backward direction when bof without immutableTop', () => + runTest({ + ...settings, + startIndex: -3, + padding: 0.5 + }, (viewport, scope) => { + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(false); + expect(scope.adapter.bufferFirst).toBe('item-5'); + expect(scope.adapter.bufferLast).toBe('item1'); + + // remove items -5..1 items form -5..6 datasource + cleanBuffer(scope); + + // result [2..6] + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(true); + expect(Helper.getRow(viewport, 1)).toBe('2: item2'); + expect(Helper.getRow(viewport, 2)).toBe('3: item3'); + expect(Helper.getRow(viewport, 3)).toBe('4: item4'); + expect(Helper.getRow(viewport, 4)).toBe('5: item5'); + expect(Helper.getRow(viewport, 5)).toBe('6: item6'); + expect(scope.adapter.bufferLength).toBe(5); + }) + ); + + const shouldWorkWhenNotBOF = (viewport, scope, options) => { + expect(scope.adapter.isBOF()).toBe(false); + expect(scope.adapter.isEOF()).toBe(false); + expect(scope.adapter.bufferFirst).toBe('item-4'); + expect(scope.adapter.bufferLast).toBe('item2'); + + // remove items -4..2 items form -5..6 datasource + cleanBuffer(scope, options); + + // result [-5, 3, 4, 5, 6] + expect(scope.adapter.isBOF()).toBe(true); + expect(scope.adapter.isEOF()).toBe(true); + expect(Helper.getRow(viewport, 1)).toBe('-5: item-5'); + expect(Helper.getRow(viewport, 2)).toBe('-4: item3'); + expect(Helper.getRow(viewport, 3)).toBe('-3: item4'); + expect(Helper.getRow(viewport, 4)).toBe('-2: item5'); + expect(Helper.getRow(viewport, 5)).toBe('-1: item6'); + expect(scope.adapter.bufferLength).toBe(5); + }; + + it('should be consistent on backward direction when not bof with immutableTop', () => + runTest({ + ...settings, + startIndex: -1, + padding: 0.3 + }, (viewport, scope) => + shouldWorkWhenNotBOF(viewport, scope, { immutableTop: true }) + ) + ); + + it('should be consistent on backward direction when not bof without immutableTop', () => + runTest({ + ...settings, + startIndex: -1, + padding: 0.3 + }, (viewport, scope) => + shouldWorkWhenNotBOF(viewport, scope) + ) + ); + }); + +}); diff --git a/test/GridTestsSpec.js b/test/GridTestsSpec.js new file mode 100644 index 00000000..40c36e5e --- /dev/null +++ b/test/GridTestsSpec.js @@ -0,0 +1,406 @@ +describe('uiScroll', function () { + 'use strict'; + + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.grid')); + beforeEach(module('ui.scroll.test.datasources')); + + var scrollSettings = { + datasource: 'myGridDatasource', + viewportHeight: 120, + itemHeight: 20, + bufferSize: 3 + }; + + function expectLayoutMap(scope, map) { + var layout = scope.adapter.gridAdapter.getLayout(); + layout.forEach((column, index) => expect(column.mapTo).toBe(map[index])); + } + + function getHeaderElement(head, index) { + var header = head.children(); + return header.children()[index]; + } + + function getLastRowElement(body, index) { + var rows = body.children(); + var lastRow = angular.element(rows[rows.length - 2]); + return lastRow.children()[index]; + } + + function applyOrderLayout(scope, map) { + var layout = []; + for(var i = 0; i < map.length; i++) { + layout.push({index: i, mapTo: map[i], css: {}}); + } + scope.adapter.gridAdapter.applyLayout(layout); + } + + function expectHeaderContents(head, contents) { + for(var i = 0; i < contents.length; i++) { + expect(getHeaderElement(head, i).innerHTML).toBe(contents[i]); + } + } + + function expectLastRowContents(body, contents) { + for(var i = 0; i < contents.length; i++) { + expect(getLastRowElement(body, i).innerHTML).toBe(contents[i]); + } + } + + + describe('basic setup', function () { + var scrollSettings = {datasource: 'myEmptyDatasource'}; + + it('should create gridAdapter', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + expect(scope.adapter).toBeTruthy(); + expect(scope.adapter.gridAdapter).toBeTruthy(); + expect(Object.prototype.toString.call(scope.adapter.gridAdapter.getLayout()), '[object Array]'); + } + ); + }); + + it('columns should have default mapping', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + expectLayoutMap(scope, [0, 1, 2, 3]); + } + ); + }); + }); + + + describe('moveBefore method logic', function () { + var scrollSettings = {datasource: 'myEmptyDatasource'}; + + it('column mappings should not be affected by 0 -> 0 move', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[0].moveBefore(0); + expectLayoutMap(scope, [0, 1, 2, 3]); + } + ); + }); + + it('column mappings should not be affected by 1 -> 1 move', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[1].moveBefore(1); + expectLayoutMap(scope, [0, 1, 2, 3]); + } + ); + }); + + it('column mappings should not be affected by 3 -> 3 move', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[3].moveBefore(3); + expectLayoutMap(scope, [0, 1, 2, 3]); + } + ); + }); + + it('column mappings should reflect 1 -> 0 move', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[1].moveBefore(0); + expectLayoutMap(scope, [1, 0, 2, 3]); + } + ); + }); + + it('column mappings should reflect 3 -> 0 move', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[3].moveBefore(0); + expectLayoutMap(scope, [1, 2, 3, 0]); + } + ); + }); + + it('column mappings should reflect 2 -> 1 move', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[2].moveBefore(1); + expectLayoutMap(scope, [0, 2, 1, 3]); + } + ); + }); + + it('column mappings should reflect 0 -> 1 move (it is a noop)', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[0].moveBefore(1); + expectLayoutMap(scope, [0, 1, 2, 3]); + } + ); + }); + + it('column mappings should reflect 2 -> 2 move (it is a noop)', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[2].moveBefore(2); + expectLayoutMap(scope, [0, 1, 2, 3]); + } + ); + }); + + it('column mappings should reflect 0 -> 2 move', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[0].moveBefore(2); + expectLayoutMap(scope, [1, 0, 2, 3]); + } + ); + }); + + it('column mappings should reflect 0 -> 4 move', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[0].moveBefore(4); + expectLayoutMap(scope, [3, 0, 1, 2]); + } + ); + }); + + it(' 1 -> 0 move twice should be a noop', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[1].moveBefore(0); + expectLayoutMap(scope, [1, 0, 2, 3]); + + scope.adapter.gridAdapter.columns[1].moveBefore(0); + expectLayoutMap(scope, [0, 1, 2, 3]); + } + ); + }); + + it('multiple moveBefore should work', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + expectLayoutMap(scope, [0, 1, 2, 3]); + + scope.adapter.gridAdapter.columns[2].moveBefore(1); + expectLayoutMap(scope, [0, 2, 1, 3]); + + scope.adapter.gridAdapter.columns[3].moveBefore(0); + expectLayoutMap(scope, [1, 3, 2, 0]); + + scope.adapter.gridAdapter.columns[3].moveBefore(2); + expectLayoutMap(scope, [1, 2, 3, 0]); + + scope.adapter.gridAdapter.columns[1].moveBefore(3); + expectLayoutMap(scope, [2, 1, 3, 0]); + } + ); + }); + }); + + + describe('moveBefore method', function () { + it('should reorder headers', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[2].moveBefore(1); + expectHeaderContents(head, ['col0', 'col2', 'col1', 'col3']); + } + ); + }); + + it('should reorder body columns', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[2].moveBefore(1); + expectLastRowContents(body, ['col0', 'col2', 'col1', 'col3']); + } + ); + }); + + it('should reorder body columns after new rows rendering', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[2].moveBefore(1); + expectLastRowContents(body, ['col0', 'col2', 'col1', 'col3']); + } + ); + }); + }); + + + describe('css method', function () { + var attr = 'backgroundColor', value = 'yellow'; + + it('should apply css right after the call', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + + var headerElement = getHeaderElement(head, 0); + var lastRowElement = getLastRowElement(body, 0); + expect(headerElement.style[attr]).toBe(''); + expect(lastRowElement.style[attr]).toBe(''); + + scope.adapter.gridAdapter.columns[0].css(attr, value); + expect(headerElement.style[attr]).toBe(value); + expect(lastRowElement.style[attr]).toBe(value); + } + ); + }); + + it('should apply css to new elements', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.columns[0].css(attr, value); + var headerElement = getHeaderElement(head, 0); + var lastRowElement = getLastRowElement(body, 0); + expect(headerElement.style[attr]).toBe(value); + expect(lastRowElement.style[attr]).toBe(value); + } + ); + }); + }); + + + describe('get and apply layout', function () { + var layout = [ + {index: 0, mapTo: 3, css: {zIndex: '1'}}, + {index: 1, mapTo: 2, css: {zIndex: '20'}}, + {index: 2, mapTo: 1, css: {zIndex: '300'}}, + {index: 3, mapTo: 0, css: {zIndex: '4000'}} + ]; + var layoutCss = [ + {index: 0, mapTo: 0, css: {zIndex: '1'}}, + {index: 1, mapTo: 1, css: {zIndex: '20'}}, + {index: 2, mapTo: 2, css: {zIndex: '300'}}, + {index: 3, mapTo: 3, css: {zIndex: '4000'}} + ]; + + it('should get empty layout', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.getLayout().forEach((column, index) => { + expect(column.css['zIndex']).toBeFalsy(); + expect(column.mapTo).toBe(index); + }); + } + ); + }); + + it('should apply some layout and then get it', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.applyLayout(layout); + + scope.adapter.gridAdapter.getLayout().forEach((column, index) => { + expect(column.css['zIndex']).toBe(layout[index].css['zIndex']); + expect(column.mapTo).toBe(layout[index].mapTo); + }); + } + ); + }); + + it('should apply css layout to header elements', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.applyLayout(layoutCss); + layoutCss.forEach((column, index) => { + expect(getHeaderElement(head, index).style['zIndex']).toBe(column.css['zIndex']); + }); + } + ); + }); + + it('should apply css layout to existed body elements', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.applyLayout(layoutCss); + layoutCss.forEach((column, index) => { + expect(getLastRowElement(body, index).style['zIndex']).toBe(column.css['zIndex']); + }); + } + ); + }); + + it('should apply css layout to new body elements', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + scope.adapter.gridAdapter.applyLayout(layoutCss); + layoutCss.forEach((column, index) => { + expect(getLastRowElement(body, index).style['zIndex']).toBe(column.css['zIndex']); + }); + } + ); + }); + + it('should apply order layout to header elements', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + applyOrderLayout(scope, [3, 2, 1, 0]); + expectHeaderContents(head, ['col3', 'col2', 'col1', 'col0']); + } + ); + }); + + it('should apply order layout to existed body elements', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + applyOrderLayout(scope, [3, 2, 1, 0]); + expectLastRowContents(body, ['col3', 'col2', 'col1', 'col0']); + } + ); + }); + + it('should apply order layout to new body elements', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + applyOrderLayout(scope, [3, 2, 1, 0]); + expectLastRowContents(body, ['col3', 'col2', 'col1', 'col0']); + } + ); + }); + + it('should apply order layout to existed body elements multiple times', function () { + runGridTest(scrollSettings, + function (head, body, scope) { + applyOrderLayout(scope, [1, 2, 3, 0]); + expectLastRowContents(body, ['col3', 'col0', 'col1', 'col2']); + + applyOrderLayout(scope, [1, 3, 2, 0]); + expectLastRowContents(body, ['col3', 'col0', 'col2', 'col1']); + + applyOrderLayout(scope, [0, 2, 3, 1]); + expectLastRowContents(body, ['col0', 'col3', 'col1', 'col2']); + } + ); + }); + + }); + + describe('scopes wrapping', function () { + var scrollSettings = { + datasource: 'myGridDatasource', + viewportHeight: 120, + itemHeight: 20, + bufferSize: 3, + rowTemplate: '{{item[col]}}' + }; + var columns = ['col0', 'col1', 'col2', 'col3']; + + it('should work', function () { + runGridTest(scrollSettings, + function(head, body) { + for(var i = 0; i < columns.length; i++) { + expect(getLastRowElement(body, i).innerHTML).toBe(columns[i]); + } + }, + { + scope: { + columns: columns + } + } + ); + }); + }); + +}); diff --git a/test/PaddingsSpec.js b/test/PaddingsSpec.js new file mode 100644 index 00000000..04ea66b1 --- /dev/null +++ b/test/PaddingsSpec.js @@ -0,0 +1,402 @@ +describe('uiScroll Paddings spec.', () => { + 'use strict'; + + let datasource; + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.test.datasources')); + beforeEach( + inject(function(myResponsiveDatasource) { + datasource = myResponsiveDatasource; + }) + ); + + const itemsCount = 30; + const itemHeight = 100; + const viewportHeight = 500; + const MAX = 3; // maximum scrolling interations to reach out the EOF/BOF + + const scrollSettings = { + datasource: 'myResponsiveDatasource', + adapter: 'adapter', + itemHeight: itemHeight, + viewportHeight: viewportHeight + }; + + function appendTitle(outside, indices) { + return (outside ? ' outside' : ' inside') + ' the buffer' + (indices ? ' when min/max indices are set': ''); + } + + function setUserIndices() { + datasource.minIndex = datasource.min; + datasource.maxIndex = datasource.max; + } + + function scrollBottom(viewport, count = 1) { + for (var i = 0; i < count; i++) { + viewport.scrollTop(99999); + } + } + + function scrollTop(viewport, count = 1) { + for (var i = 0; i < count; i++) { + viewport.scrollTop(0); + } + } + + function removeItem(datasource, index) { + if(index >= datasource.min && index <= datasource.max) { + const indexRemoved = datasource.data.indexOf(datasource.data[index - datasource.min]); + if(indexRemoved > -1) { + datasource.data.splice(indexRemoved, 1); + if(index === datasource.min) { + datasource.min++; + } + else { + datasource.max--; + } + } + } + } + + function insertItems(datasource, index, items = []) { + if(index >= datasource.min && index <= datasource.max && items.length) { + const indexToInsert = datasource.data.indexOf(datasource.data[index - datasource.min]); + if(indexToInsert > -1) { + datasource.data.splice(indexToInsert, 0, items); + datasource.max += items.length; + } + } + } + + function checkRow(viewport, row, content, tail = false) { + var children = viewport.children(); + if(tail) { + row = children.length - 1 - row; + } + const rowElement = children[row]; + expect(rowElement.innerHTML).toBe(content); + } + + function checkRowBack(viewport, row, content) { + checkRow(viewport, row, content, true); + } + + it('\nshould set up properly', () => { + runTest(scrollSettings, + () => { + expect(datasource.min).toBe(1); + expect(datasource.max).toBe(itemsCount); + } + ); + }); + + describe('Removing items via indexed-based applyUpdates\n', () => { + + [true, false].forEach(outside => + [true, false].forEach(userIndices => + it('should remove last row' + appendTitle(outside, userIndices), () => + runTest(scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + scrollBottom(viewport, MAX); + outside && scrollTop(viewport); + const initialBottomHeight = Helper.getBottomPadding(viewport); + + removeItem(datasource, datasource.max); + scope.adapter.applyUpdates(itemsCount, []); + outside && expect(Helper.getBottomPadding(viewport)).toBe(initialBottomHeight - itemHeight); + + !outside && scrollTop(viewport); + scrollBottom(viewport, MAX); + expect(viewport.scrollTop()).toBe(itemsCount * itemHeight - viewportHeight - itemHeight); + checkRowBack(viewport, 1, (itemsCount - 1) + ': item' + (itemsCount - 1)); + } + ) + ) + ) + ); + + [true, false].forEach(outside => + [true, false].forEach(userIndices => + it('should remove last row and then the next after last' + appendTitle(outside, userIndices), () => + runTest(scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + scrollBottom(viewport, MAX); + outside && scrollTop(viewport); + + const initialBottomHeight = Helper.getBottomPadding(viewport); + removeItem(datasource, datasource.max); + scope.adapter.applyUpdates(itemsCount, []); + removeItem(datasource, datasource.max); + scope.adapter.applyUpdates(itemsCount - 1, []); + outside && expect(Helper.getBottomPadding(viewport)).toBe(initialBottomHeight - itemHeight * 2); + + !outside && scrollTop(viewport); + scrollBottom(viewport, MAX); + expect(viewport.scrollTop()).toBe(itemsCount * itemHeight - viewportHeight - itemHeight * 2); + checkRowBack(viewport, 1, (itemsCount - 2) + ': item' + (itemsCount - 2)); + } + ) + ) + ) + ); + + [true, false].forEach(outside => + [true, false].forEach(userIndices => + it('should remove pre-last row' + appendTitle(outside, userIndices), () => + runTest(scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + scrollBottom(viewport, MAX); + outside && scrollTop(viewport); + + const initialBottomHeight = Helper.getBottomPadding(viewport); + removeItem(datasource, datasource.max - 1); + scope.adapter.applyUpdates(itemsCount - 1, []); + outside && expect(Helper.getBottomPadding(viewport)).toBe(initialBottomHeight - itemHeight); + + !outside && scrollTop(viewport); + scrollBottom(viewport, MAX); + expect(viewport.scrollTop()).toBe(itemsCount * itemHeight - viewportHeight - itemHeight); + checkRowBack(viewport, 1, (itemsCount - 1) + ': item' + itemsCount); + checkRowBack(viewport, 2, (itemsCount - 2) + ': item' + (itemsCount - 2)); + } + ) + ) + ) + ); + + [true, false].forEach(outside => + [true, false].forEach(userIndices => + it('should remove first row' + appendTitle(outside, userIndices), () => + runTest(scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + outside && scrollBottom(viewport, MAX); + + const initialTopHeight = Helper.getTopPadding(viewport); + removeItem(datasource, datasource.min); + scope.adapter.applyUpdates(1, []); + outside && expect(Helper.getTopPadding(viewport)).toBe(initialTopHeight - itemHeight); + + !outside && scrollBottom(viewport, MAX); + expect(Helper.getBottomPadding(viewport)).toBe(0); + + scrollTop(viewport); + expect(Helper.getTopPadding(viewport)).toBe(0); + checkRow(viewport, 1, '2: item2'); + } + ) + ) + ) + ); + + [true, false].forEach(outside => + [true, false].forEach(userIndices => + it('should remove first row and then the next after first' + appendTitle(outside, userIndices), () => + runTest(scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + outside && scrollBottom(viewport, MAX); + + const initialTopHeight = Helper.getTopPadding(viewport); + removeItem(datasource, datasource.min); + scope.adapter.applyUpdates(1, []); + removeItem(datasource, datasource.min); + scope.adapter.applyUpdates(2, []); + outside && expect(Helper.getTopPadding(viewport)).toBe(initialTopHeight - itemHeight * 2); + + !outside && scrollBottom(viewport, MAX); + expect(Helper.getBottomPadding(viewport)).toBe(0); + + scrollTop(viewport); + expect(Helper.getTopPadding(viewport)).toBe(0); + checkRow(viewport, 1, '3: item3'); + } + ) + ) + ) + ); + + [true, false].forEach(outside => + [true, false].forEach(userIndices => + it('should remove second row' + appendTitle(outside, userIndices), () => + runTest(scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + outside && scrollBottom(viewport, MAX); + + const initialTopHeight = Helper.getTopPadding(viewport); + removeItem(datasource, datasource.min + 1); + scope.adapter.applyUpdates(2, []); + outside && expect(Helper.getTopPadding(viewport)).toBe(initialTopHeight - itemHeight * 1); + + !outside && scrollBottom(viewport, MAX); + expect(Helper.getBottomPadding(viewport)).toBe(0); + + scrollTop(viewport); + expect(Helper.getTopPadding(viewport)).toBe(0); + checkRow(viewport, 1, '1: item1'); + checkRow(viewport, 2, '2: item3'); + } + ) + ) + ) + ); + }); + + describe('Appending inside the buffer\n', () => { + + it('should append 3 rows via index-based applyUpdates', () => { + runTest(Object.assign({}, scrollSettings, { startIndex: 28 }), + (viewport, scope) => { + const newItems = [ + 'item' + (datasource.max + 1), + 'item' + (datasource.max + 2), + 'item' + (datasource.max + 3) + ]; + const oldMax = datasource.max; + const _scrollTop = viewport.scrollTop(); + + insertItems(datasource, datasource.max, newItems); + scope.adapter.applyUpdates(oldMax, ['item' + oldMax, ...newItems]); + + scrollBottom(viewport); + expect(viewport.scrollTop()).toBe(_scrollTop + newItems.length * itemHeight); + + checkRowBack(viewport, 1, (datasource.max - 0) + ': ' + newItems[2]); + checkRowBack(viewport, 2, (datasource.max - 1) + ': ' + newItems[1]); + checkRowBack(viewport, 3, (datasource.max - 2) + ': ' + newItems[0]); + checkRowBack(viewport, 4, oldMax + ': item' + oldMax); + } + ); + }); + + it('should append 3 rows via index-based applyUpdates when min/max indices are set', () => { + runTest(Object.assign({}, scrollSettings, { startIndex: 28 }), + (viewport, scope) => { + const newItems = [ + 'item' + (datasource.max + 1), + 'item' + (datasource.max + 2), + 'item' + (datasource.max + 3) + ]; + const oldMax = datasource.max; + + datasource.minIndex = datasource.min; + datasource.maxIndex = datasource.max; + const _scrollTop = viewport.scrollTop(); + + insertItems(datasource, datasource.max, newItems); + scope.adapter.applyUpdates(oldMax, ['item' + oldMax, ...newItems]); + + scrollBottom(viewport); + expect(viewport.scrollTop()).toBe(_scrollTop + newItems.length * itemHeight); + + checkRowBack(viewport, 1, (datasource.max - 0) + ': ' + newItems[2]); + checkRowBack(viewport, 2, (datasource.max - 1) + ': ' + newItems[1]); + checkRowBack(viewport, 3, (datasource.max - 2) + ': ' + newItems[0]); + checkRowBack(viewport, 4, oldMax + ': item' + oldMax); + } + ); + }); + }); + + + describe('Removing items via indexed-based applyUpdates when neither BOF nor EOF are reached\n', () => { + const _scrollSettings = Object.assign({}, scrollSettings, { startIndex: 12 }); + + [true, false].forEach(userIndices => + it('should remove first buffered row' + appendTitle(true, userIndices), () => + runTest(_scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + removeItem(datasource, 2); + scope.adapter.applyUpdates(2, []); + + scrollBottom(viewport, MAX); + expect(Helper.getBottomPadding(viewport)).toBe(0); + checkRowBack(viewport, 1, (itemsCount - 1) + ': item' + itemsCount); + + scrollTop(viewport); + expect(Helper.getTopPadding(viewport)).toBe(0); + checkRow(viewport, 1, '1: item1'); + checkRow(viewport, 2, '2: item3'); + } + ) + ) + ); + + [true, false].forEach(userIndices => + it('should remove last buffered row' + appendTitle(true, userIndices), () => + runTest(_scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + removeItem(datasource, 19); + scope.adapter.applyUpdates(19, []); + + scrollBottom(viewport); + expect(Helper.getBottomPadding(viewport)).toBe(0); + checkRowBack(viewport, 1, (itemsCount - 1) + ': item' + itemsCount); + + scrollTop(viewport); + expect(Helper.getTopPadding(viewport)).toBe(0); + } + ) + ) + ); + + [true, false].forEach(userIndices => + it('should remove absolute first row' + appendTitle(true, userIndices), () => + runTest(_scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + removeItem(datasource, 1); + scope.adapter.applyUpdates(1, []); + + scrollBottom(viewport, MAX); + expect(Helper.getBottomPadding(viewport)).toBe(0); + checkRowBack(viewport, 1, itemsCount + ': item' + itemsCount); + + scrollTop(viewport); + expect(Helper.getTopPadding(viewport)).toBe(0); + checkRow(viewport, 1, '2: item2'); + checkRow(viewport, 2, '3: item3'); + } + ) + ) + ); + + [true, false].forEach(userIndices => + it('should remove absolute last row' + appendTitle(true, userIndices), () => + runTest(_scrollSettings, + (viewport, scope) => { + userIndices && setUserIndices(); + + removeItem(datasource, itemsCount); + scope.adapter.applyUpdates(itemsCount, []); + + scrollBottom(viewport, MAX); + expect(Helper.getBottomPadding(viewport)).toBe(0); + checkRowBack(viewport, 1, (itemsCount - 1) + ': item' + (itemsCount - 1)); + + scrollTop(viewport); + expect(Helper.getTopPadding(viewport)).toBe(0); + checkRow(viewport, 1, '1: item1'); + checkRow(viewport, 2, '2: item2'); + } + ) + ) + ); + }); + +}); diff --git a/test/UserIndicesSpec.js b/test/UserIndicesSpec.js new file mode 100644 index 00000000..e594cc29 --- /dev/null +++ b/test/UserIndicesSpec.js @@ -0,0 +1,178 @@ +/*global describe, beforeEach, module, inject, it, expect, runTest, Helper */ +describe('uiScroll main/max indices', function() { + 'use strict'; + + let datasource; + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.test.datasources')); + + const injectDatasource = (datasourceToken) => + beforeEach( + inject([datasourceToken, function(_datasource) { + datasource = _datasource; + }]) + ); + + const viewportHeight = 120; + const itemHeight = 20; + const bufferSize = 3; + const userMinIndex = -99; // for 100 items + const userMaxIndex = 100; + + const scrollSettings = { + datasource: 'myInfiniteDatasource', + viewportHeight: viewportHeight, + itemHeight: itemHeight, + bufferSize: bufferSize, + adapter: 'adapter' + }; + + describe('Setting\n', () => { + injectDatasource('myInfiniteDatasource'); + + it('should set up bottom padding element\'s height after user max index is set', () => + runTest(scrollSettings, + (viewport) => { + expect(viewport.scrollTop()).toBe(itemHeight * bufferSize); + + datasource.maxIndex = userMaxIndex; + + const virtualItemsAmount = userMaxIndex - (viewportHeight / itemHeight) - bufferSize; + expect(Helper.getBottomPadding(viewport)).toBe(itemHeight * virtualItemsAmount); + expect(viewport.scrollTop()).toBe(itemHeight * bufferSize); + } + ) + ); + + it('should set up top padding element\'s height after user min index is set', () => + runTest(scrollSettings, + (viewport) => { + expect(viewport.scrollTop()).toBe(itemHeight * bufferSize); + + datasource.minIndex = userMinIndex; + + const virtualItemsAmount = (-1) * userMinIndex - bufferSize + 1; + expect(Helper.getTopPadding(viewport)).toBe(itemHeight * virtualItemsAmount); + expect(viewport.scrollTop()).toBe(itemHeight * ((-1) * userMinIndex + 1)); + } + ) + ); + + }); + + describe('Pre-setting\n', () => { + injectDatasource('myInfiniteDatasource'); + + it('should work with maxIndex pre-set on datasource', () => { + datasource.maxIndex = userMaxIndex; + runTest(scrollSettings, + (viewport) => { + const virtualItemsAmount = userMaxIndex - (viewportHeight / itemHeight) - bufferSize; + expect(Helper.getBottomPadding(viewport)).toBe(itemHeight * virtualItemsAmount); + expect(viewport.scrollTop()).toBe(itemHeight * bufferSize); + } + ); + }); + + it('should work with minIndex pre-set on datasource', () => { + datasource.minIndex = userMinIndex; + runTest(scrollSettings, + (viewport) => { + const virtualItemsAmount = (-1) * userMinIndex - bufferSize + 1; + expect(Helper.getTopPadding(viewport)).toBe(itemHeight * virtualItemsAmount); + expect(viewport.scrollTop()).toBe(itemHeight * ((-1) * userMinIndex + 1)); + } + ); + }); + + it('should work when the viewport is big enough to include more than 1 pack of item (last)', () => { + const viewportHeight = 450; + const _topItemsCount = Math.round(viewportHeight * 0.5 / itemHeight); + const _topPackCount = Math.ceil(_topItemsCount / bufferSize); + const _minIndex = (-1) * _topPackCount * bufferSize + 1; // one additinal adjustment should occur + datasource.minIndex = _minIndex; + datasource.maxIndex = userMaxIndex; + runTest(Object.assign({}, scrollSettings, { viewportHeight }), + (viewport) => { + expect(Helper.getTopPadding(viewport)).toBe(0); + expect(viewport.scrollTop()).toBe(_topPackCount * bufferSize * itemHeight); + } + ); + }); + + it('should work when the viewport is big enough to include more than 1 pack of item (first)', () => { + const viewportHeight = 450; + const _topItemsCount = Math.round(viewportHeight * 0.5 / itemHeight); + const _topPackCount = Math.ceil(_topItemsCount / bufferSize); + let _minIndex = -1; // ~9 additinal adjustments should occur + datasource.minIndex = _minIndex; + datasource.maxIndex = userMaxIndex; + runTest(Object.assign({}, scrollSettings, { viewportHeight }), + (viewport) => { + expect(Helper.getTopPadding(viewport)).toBe(0); + expect(viewport.scrollTop()).toBe(_topPackCount * bufferSize * itemHeight); + } + ); + }); + + }); + + describe('Reload\n', () => { + injectDatasource('myResponsiveDatasource'); + beforeEach(() => { + datasource.min = userMinIndex; + datasource.max = userMaxIndex; + datasource.init(); + }); + + it('should persist user maxIndex after reload', () => { + datasource.maxIndex = userMaxIndex; + runTest(Object.assign({}, scrollSettings, { datasource: 'myResponsiveDatasource' }), + (viewport, scope) => { + scope.adapter.reload(); + const virtualItemsAmount = userMaxIndex - (viewportHeight / itemHeight) - bufferSize; + expect(Helper.getBottomPadding(viewport)).toBe(itemHeight * virtualItemsAmount); + expect(viewport.scrollTop()).toBe(itemHeight * bufferSize); + } + ); + }); + + it('should persist user minIndex after reload', () => { + datasource.minIndex = userMinIndex; + runTest(Object.assign({}, scrollSettings, { datasource: 'myResponsiveDatasource' }), + (viewport, scope) => { + scope.adapter.reload(); + const virtualItemsAmount = (-1) * userMinIndex - bufferSize + 1; + expect(Helper.getTopPadding(viewport)).toBe(itemHeight * virtualItemsAmount); + expect(viewport.scrollTop()).toBe(itemHeight * ((-1) * userMinIndex + 1)); + } + ); + }); + + it('should apply new user minIndex and maxIndex after reload', () => { + const startIndex = 10; + const add = 50; + const minIndexNew = userMinIndex - add; + const maxIndexNew = userMaxIndex + add; + datasource.minIndex = userMinIndex; + datasource.maxIndex = userMaxIndex; + runTest(Object.assign({}, scrollSettings, { datasource: 'myResponsiveDatasource', startIndex }), + (viewport, scope) => { + const _scrollTop = viewport.scrollTop(); + + scope.adapter.reload(startIndex); + datasource.min = minIndexNew; + datasource.max = maxIndexNew; + datasource.minIndex = minIndexNew; + datasource.maxIndex = maxIndexNew; + + expect(Helper.getTopPadding(viewport)).toBe(itemHeight * ((-1) * minIndexNew + startIndex - bufferSize)); + expect(Helper.getBottomPadding(viewport)).toBe(itemHeight * (maxIndexNew - startIndex + 1 - (viewportHeight / itemHeight) - bufferSize)); + expect(viewport.scrollTop()).toBe(_scrollTop + itemHeight * add); + } + ); + }); + + }); + +}); diff --git a/test/VisibilitySwitchingSpec.js b/test/VisibilitySwitchingSpec.js new file mode 100644 index 00000000..5774052a --- /dev/null +++ b/test/VisibilitySwitchingSpec.js @@ -0,0 +1,129 @@ +describe('uiScroll visibility.', () => { + 'use strict'; + + beforeEach(module('ui.scroll')); + beforeEach(module('ui.scroll.test.datasources')); + + const scrollSettings = { + datasource: 'myMultipageDatasource', + viewportHeight: 200, + itemHeight: 40, + bufferSize: 3, + adapter: 'adapter' + }; + + const checkContent = (rows, count) => { + expect(rows.length).toBe(count); + for (var i = 1; i < count - 1; i++) { + expect(rows[i].innerHTML).toBe(i + ': item' + i); + } + }; + + const onePackItemsCount = 3 * 1 + 2; + const twoPacksItemsCount = 3 * 2 + 2; + const threePacksItemsCount = 3 * 3 + 2; + + describe('Viewport visibility changing\n', () => { + + it('should create 9 divs with data (+ 2 padding divs)', () => + runTest(scrollSettings, + (viewport) => { + expect(viewport.scrollTop()).toBe(0); + checkContent(viewport.children(), threePacksItemsCount); + } + ) + ); + + it('should preserve elements after visibility switched off (display:none)', () => + runTest(scrollSettings, + (viewport, scope) => { + viewport.css('display', 'none'); + scope.$apply(); + + expect(viewport.scrollTop()).toBe(0); + checkContent(viewport.children(), threePacksItemsCount); + } + ) + ); + + it('should only load one batch with visibility switched off (display:none)', () => + runTest(scrollSettings, + (viewport, scope) => { + viewport.css('display', 'none'); + scope.adapter.reload(); + + expect(viewport.scrollTop()).toBe(0); + checkContent(viewport.children(), onePackItemsCount); + } + ) + ); + + it('should load full set after css-visibility switched back on', () => + runTest(scrollSettings, + (viewport, scope, $timeout) => { + viewport.css('display', 'none'); + scope.adapter.reload(); + + viewport.css('display', 'block'); + scope.$apply(); + $timeout.flush(); + + expect(viewport.scrollTop()).toBe(0); + checkContent(viewport.children(), threePacksItemsCount); + expect(scope.adapter.topVisible).toBe('item1'); + } + ) + ); + + it('should load full set after scope-visibility switched back on', () => + runTest(Object.assign({}, scrollSettings, { + wrapper: { + start: '
    ', + end: '
    ' + } + }), (viewport, scope) => { + scope.show = false; + scope.$apply(); + expect(viewport.children().length).toBe(0); + + scope.show = true; + scope.$apply(); + expect(viewport.scrollTop()).toBe(0); + checkContent(viewport.children().children(), threePacksItemsCount); + }, { + scope: { + show: true + } + } + ) + ); + }); + + describe('Items visibility changing\n', () => { + + it('should load only one batch with items height = 0', () => + runTest(Object.assign({}, scrollSettings, { itemHeight: '0' }), + (viewport) => { + expect(viewport.children().length).toBe(onePackItemsCount); + expect(viewport.scrollTop()).toBe(0); + checkContent(viewport.children(), onePackItemsCount); + } + ) + ); + + it('should load one more batch after the height of some item is set to a positive value', () => + runTest(Object.assign({}, scrollSettings, { itemHeight: '0' }), + (viewport, scope, $timeout) => { + angular.element(viewport.children()[onePackItemsCount - 2]).css('height', 40); + expect(angular.element(viewport.children()[onePackItemsCount - 2]).css('height')).toBe('40px'); + scope.$apply(); + $timeout.flush(); + + expect(viewport.scrollTop()).toBe(0); + checkContent(viewport.children(), twoPacksItemsCount); + } + ) + ); + }); + +}); diff --git a/test/config/karma.conf.files.js b/test/config/karma.conf.files.js new file mode 100644 index 00000000..3570fb61 --- /dev/null +++ b/test/config/karma.conf.files.js @@ -0,0 +1,31 @@ +const files = [ + 'https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js', + 'https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.js', + 'https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular-mocks.js', + '../misc/test.css', + '../misc/datasources.js', + '../misc/scaffolding*.js', + '../misc/helpers.js', + { + pattern: '../*Spec.js', + watched: false, + served: true, + included: true + } +]; + +module.exports.development = [ + ...files, + '../../src/ui-scroll.js', + '../../src/ui-scroll-grid.js' +]; + +module.exports.production = [ + ...files, + '../../dist/ui-scroll.min.js', + '../../dist/ui-scroll-grid.min.js', + { + pattern: '../../dist/*.js.map', + included: false + } +]; diff --git a/test/config/karma.conf.js b/test/config/karma.conf.js new file mode 100644 index 00000000..76ede4b8 --- /dev/null +++ b/test/config/karma.conf.js @@ -0,0 +1,48 @@ +const chrome = process.platform === 'linux' ? 'Chromium' : 'Chrome'; + +const ENV = (process.env.npm_lifecycle_event.indexOf('dev') === 0) ? 'development' : 'production'; + +const webpackSettings = ENV === 'development' ? { + preprocessors: { + '../../src/ui-scroll*.js': ['webpack', 'sourcemap'] + }, + webpack: require('../../webpack.config.js') +} : {}; + +module.exports = function (config) { + 'use strict'; + + config.set(Object.assign({ + + basePath: '', + + frameworks: ['jasmine'], + + files: [ + ...require('./karma.conf.files.js')[ENV] + ], + + exclude: [], + + reporters: ['dots'], + + port: ENV === 'development' ? 9100 : 8082, + + colors: true, + + logLevel: config.LOG_INFO, + + autoWatch: ENV === 'development', + + keepalive: ENV === 'development', + + browsers: process.env.TRAVIS ? + ['Firefox'] : + [chrome], + + captureTimeout: 60000, + + singleRun: ENV !== 'development' + + }, webpackSettings)); +}; diff --git a/test/jqliteExtrasSpec.js b/test/jqliteExtrasSpec.js new file mode 100644 index 00000000..9359538f --- /dev/null +++ b/test/jqliteExtrasSpec.js @@ -0,0 +1,180 @@ +describe('\njqLite: testing against jQuery\n', function () { + 'use strict'; + + var sandbox = angular.element('
    '); + var extras; + + beforeEach(module('ui.scroll')); + beforeEach(function(){ + angular.element(document).find('body').append(sandbox = angular.element('
    ')); + inject(function(JQLiteExtras) { + extras = function(){}; + (new JQLiteExtras()).registerFor(extras); + }); + }); + + afterEach(function() {sandbox.remove();}); + + describe('height() getter for window\n', function() { + it('should work for window element', function() { + var element = angular.element(window); + expect(extras.prototype.height.call(element)).toBe(element.height()); + }); + }); + + describe('getters height() and outerHeight()\n', function () { + + function createElement(element) { + var result = angular.element(element); + sandbox.append(result); + return result; + } + + angular.forEach( + [ + '
    some text
    ', + '
    some text (height in em)
    ', + '
    some text height in px
    ', + '
    some text w border
    ', + '
    some text w border
    ', + '
    some text w padding
    ', + '
    some text w padding
    ', + '
    some text w margin
    ', + '
    some text w margin
    ' + ], function(element) { + + it('should be the same as jQuery height() for ' + element, function() { + (function(element) { + expect(extras.prototype.height.call(element)).toBe(element.height()); + })(createElement(element)); + } + ); + + it ('should be the same as jQuery outerHeight() for ' + element, function() { + (function(element) { + expect(extras.prototype.outerHeight.call(element)).toBe(element.outerHeight()); + })(createElement(element)); + } + ); + + it ('should be the same as jQuery outerHeight(true) for ' + element, function() { + (function(element) { + expect(extras.prototype.outerHeight.call(element, true)).toBe(element.outerHeight(true)); + })(createElement(element)); + } + ); + + } + + ); + }); + + describe('height(value) setter\n', function () { + + function createElement(element) { + var result = angular.element(element); + sandbox.append(result); + return result; + } + + angular.forEach( + [ + '
    some text
    ', + '
    some text (height in em)
    ', + '
    some text height in px
    ', + '
    some text w border
    ', + '
    some text w border
    ', + '
    some text w padding
    ', + '
    some text w padding
    ', + '
    some text w margin
    ', + '
    some text w margin
    ', + '
    some text w margin
    ' + ], function(element) { + + // Since jQuery v3 the .hegth() results don't being rounded (https://github.com/jquery/jquery/pull/2454). + // So the element '
    some text w line height
    ' will cause the error -- + // Expected 18 to be 17.6 + + it('height(value) for ' + element, function() { + (function (element) { + expect(extras.prototype.height.call(element)).toBe(element.height()); + var h = element.height(); + extras.prototype.height.call(element, h*2); + expect(extras.prototype.height.call(element)).toBe(h*2); + })(createElement(element)); + } + ); + + } + + ); + }); + + describe('offset() getter\n', function () { + + function createElement(element) { + var result = angular.element(element); + sandbox.append(result); + return result; + } + + angular.forEach( + [ + '
    some text
    ', + '
    some text (height in em)
    ', +// '
    some text height in px
    ', +// '
    some text w border
    ', +// '
    some text w border
    ', +// '
    some text w padding
    ', +// '
    some text w padding
    ', +// '
    some text w margin
    ', + '

    some text w margin

    ' + ], function(element) { + + it('should be the same as jQuery offset() for ' + element, function() { + (function (element) { + var target = jQuery(element.contents()[0]); + expect(extras.prototype.offset.call(target)).toEqual(element.offset()); + })(createElement(element)); + } + ); + + } + + ); + }); + + describe('scrollTop()\n', function() { + + function createElement(element) { + var result = angular.element(element); + sandbox.append(result); + return result; + } + + it('should be the same as jQuery scrollTop() for window', function() { + + createElement('
    '); + var element = jQuery(window); + expect(extras.prototype.scrollTop.call(element)).toBe(element.scrollTop()); + element.scrollTop(100); + expect(extras.prototype.scrollTop.call(element)).toBe(element.scrollTop()); + extras.prototype.scrollTop.call(element, 200); + expect(extras.prototype.scrollTop.call(element)).toBe(element.scrollTop()); + } + ); + + it('should be the same as jQuery scrollTop() for window', function() { + + var element = createElement('
    '); + expect(extras.prototype.scrollTop.call(element)).toBe(element.scrollTop()); + element.scrollTop(100); + expect(extras.prototype.scrollTop.call(element)).toBe(element.scrollTop()); + extras.prototype.scrollTop.call(element, 200); + expect(extras.prototype.scrollTop.call(element)).toBe(element.scrollTop()); + } + ); + + }); + +}); \ No newline at end of file diff --git a/test/misc/datasources.js b/test/misc/datasources.js new file mode 100644 index 00000000..d983fa6e --- /dev/null +++ b/test/misc/datasources.js @@ -0,0 +1,228 @@ +(function() { + 'use strict'; + + angular.module('ui.scroll.test.datasources', []) + + .factory('myEmptyDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + success([]); + } + }; + } + ]) + + .factory('myDescriptoEmptyDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(descriptor, success) { + success([]); + } + }; + } + ]) + + .factory('myOnePageDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + if (index === 1) { + success(['one', 'two', 'three']); + } else { + success([]); + } + } + }; + } + ]) + + .factory('myOneBigPageDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + if (index === 1) { + var resultList = []; + for (var i = 1; i < 100; i++) { + resultList.push('item' + i); + } + success(resultList); + } else { + success([]); + } + } + }; + } + ]) + + .factory('myDescriptorOnePageDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(descriptor, success) { + if (descriptor.index === 1) { + success(['one', 'two', 'three']); + } else { + success([]); + } + } + }; + } + ]) + + .factory('myObjectDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + if (index === 1) { + success([{ text: 'one' }, { text: 'two' }, { text: 'three' }]); + } else { + success([]); + } + } + }; + } + ]) + + .factory('myMultipageDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + var result = []; + for (var i = index; i < index + count; i++) { + if (i > 0 && i <= 20) { + result.push('item' + i); + } + } + success(result); + } + }; + } + ]) + + .factory('anotherDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + var result = []; + for (var i = index; i < index + count; i++) { + if (i > -3 && i < 1) { + result.push('item' + i); + } + } + success(result); + } + }; + } + ]) + + .factory('myEdgeDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + var result = []; + for (var i = index; i < index + count; i++) { + if (i > -6 && i <= 6) { + result.push('item' + i); + } + } + success(result); + } + }; + } + ]) + + .factory('myDatasourceToPreventScrollBubbling', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + var result = []; + for (var i = index; i < index + count; i++) { + if (i < -6 || i > 20) { + break; + } + result.push('item' + i); + } + success(result); + } + }; + } + ]) + + .factory('myInfiniteDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + var result = []; + for (var i = index; i < index + count; i++) { + result.push('item' + i); + } + success(result); + } + }; + } + ]) + + .factory('myGridDatasource', [ + '$log', '$timeout', '$rootScope', + function() { + return { + get: function(index, count, success) { + var result = []; + for (var i = index; i < index + count; i++) { + result.push({ + col0: 'col0', + col1: 'col1', + col2: 'col2', + col3: 'col3' + }); + } + success(result); + } + }; + } + ]) + + + .factory('myResponsiveDatasource', function() { + var datasource = { + data: [], + min: 1, + max: 30, + init: function() { + this.data = []; + for (var i = this.min; i <= this.max; i++) { + this.data.push('item' + i); + } + }, + getItem: function(index) { + return this.data[index - this.min]; + }, + get: function(index, count, success) { + var result = []; + var start = Math.max(this.min, index); + var end = Math.min(index + count - 1, this.max); + if (start <= end) { + for (var i = start; i <= end; i++) { + result.push(this.getItem(i)); + } + } + success(result); + } + }; + datasource.init(); + return datasource; + } + ); + +})(); \ No newline at end of file diff --git a/test/misc/helpers.js b/test/misc/helpers.js new file mode 100644 index 00000000..ece545ee --- /dev/null +++ b/test/misc/helpers.js @@ -0,0 +1,42 @@ + + +let Helper; + +(function() { + 'use strict'; + + Helper = { + + getTopPadding: (viewport) => { + const viewportChildren = viewport.children(); + const topPadding = viewportChildren[0]; + return parseInt(topPadding.style.height, 10); + }, + + getBottomPadding: (viewport) => { + const viewportChildren = viewport.children(); + const bottomPadding = viewportChildren[viewportChildren.length - 1]; + return parseInt(bottomPadding.style.height, 10); + }, + + getRow: (viewport, number) => { // number is index + 1 + const viewportChildren = viewport.children(); + if (viewportChildren.length < 2 + number) { + return; + } + return viewportChildren[number].innerHTML; + }, + + getFirstRow: (viewport) => Helper.getRow(viewport, 1), + + getLastRow: (viewport) => { + const viewportChildren = viewport.children(); + if (viewportChildren.length < 3) { + return; + } + return viewportChildren[viewportChildren.length - 2].innerHTML; + } + + }; + +})(); diff --git a/test/misc/scaffolding.js b/test/misc/scaffolding.js new file mode 100644 index 00000000..62506bce --- /dev/null +++ b/test/misc/scaffolding.js @@ -0,0 +1,87 @@ +/* exported runTest */ + +function createHtml(settings) { + 'use strict'; + var viewportStyle = ' style="height:' + (settings.viewportHeight || 200) + 'px"'; + var itemStyle = settings.itemHeight ? ' style="height:' + settings.itemHeight + 'px"' : ''; + var bufferSize = settings.bufferSize ? ' buffer-size="' + settings.bufferSize + '"' : ''; + var padding = settings.padding ? ' padding="' + settings.padding + '"' : ''; + var isLoading = settings.isLoading ? ' is-loading="' + settings.isLoading + '"' : ''; + var topVisible = settings.topVisible ? ' top-visible="' + settings.topVisible + '"' : ''; + var disabled = settings.disabled ? ' disabled="' + settings.disabled + '"' : ''; + var adapter = settings.adapter ? ' adapter="' + settings.adapter + '"' : ''; + var template = settings.template ? settings.template : '{{$index}}: {{item}}'; + var startIndex = settings.startIndex ? ' start-index="' + settings.startIndex + '"' : ''; + var inertia = ' handle-inertia="false"'; + var extra = settings.extra || ''; + return '
    ' + + (settings.wrapper ? settings.wrapper.start : '') + + '
    ' + + template + + '
    ' + + (settings.wrapper ? settings.wrapper.end : '') + + '
    '; +} + +function finalize(scroller, options, scope, $timeout) { + 'use strict'; + options = options || {}; + scroller.remove(); + + if (typeof options.cleanupTest === 'function') { + options.cleanupTest(scroller, scope, $timeout); + } +} + +function augmentScroller(scroller) { + 'use strict'; + var scrollTop = scroller.scrollTop; + scroller.scrollTop = function () { + var result = scrollTop.apply(scroller, arguments); + if (arguments.length) { + scroller.trigger('scroll'); + } + return result; + }; +} + +function runTest(scrollSettings, run, options) { + 'use strict'; + options = options || {}; + inject(function ($rootScope, $compile, $window, $timeout) { + var scroller = angular.element(createHtml(scrollSettings)); + var scope = $rootScope.$new(); + augmentScroller(scroller); + + angular.element(document).find('body').append(scroller); + + if (options.scope) { + angular.extend(scope, options.scope); + } + + var compile = function() { + $compile(scroller)(scope); + scope.$apply(); + }; + + if (typeof options.catch === 'function') { + try { + compile(); + } catch (error) { + options.catch(error); + } + } else { + compile(); + } + + if(typeof run === 'function') { + try { + run(scroller, scope, $timeout); + } finally { + finalize(scroller, options, scope, $timeout); + } + } + }); +} \ No newline at end of file diff --git a/test/misc/scaffoldingGrid.js b/test/misc/scaffoldingGrid.js new file mode 100644 index 00000000..5f9a3408 --- /dev/null +++ b/test/misc/scaffoldingGrid.js @@ -0,0 +1,68 @@ +/* exported runGridTest */ + +function createGridHtml (settings) { + 'use strict'; + var viewportStyle = ' style="height:' + (settings.viewportHeight || 200) + 'px"'; + var columns = ['col0', 'col1', 'col2', 'col3']; + + var html = + '' + + '' + + ''; + columns.forEach(col => { html += + ''; + }); html += + '' + + '' + + '' + + ''; + if(settings.rowTemplate) { + html += settings.rowTemplate; + } else { + columns.forEach(col => { html += + ''; + }); + } html += + '' + + '' + + '
    ' + col + '
    {{item.' + col + '}}
    '; + return html; +} + +function finalize(scroller, options, scope, $timeout) { + 'use strict'; + options = options || {}; + scroller.remove(); + + if (typeof options.cleanupTest === 'function') { + options.cleanupTest(scroller, scope, $timeout); + } +} + +function runGridTest(scrollSettings, run, options) { + 'use strict'; + options = options || {}; + inject(function($rootScope, $compile, $window, $timeout) { + var scroller = angular.element(createGridHtml(scrollSettings)); + var scope = $rootScope.$new(); + + angular.element(document).find('body').append(scroller); + var head = angular.element(scroller.children()[0]); + var body = angular.element(scroller.children()[1]); + + if (options.scope) { + angular.extend(scope, options.scope); + } + + $compile(scroller)(scope); + + scope.$apply(); + $timeout.flush(); + + try { + run(head, body, scope, $timeout); + } finally { + finalize(scroller, options, scope, $timeout); + } + }); +} \ No newline at end of file diff --git a/test/misc/test.css b/test/misc/test.css new file mode 100644 index 00000000..d7af5c04 --- /dev/null +++ b/test/misc/test.css @@ -0,0 +1,6 @@ +.grid { width: 250px; } +.col0 { width: 40px; } +.col1 { width: 80px; } +.col2 { width: 40px; } +.col3 { width: 50px; } +.item:nth-child(odd) { background-color: #e6e6e6; } \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 00000000..a3dc1e81 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,162 @@ +'use strict'; + +const path = require('path'); +const glob = require('glob'); +const webpack = require('webpack'); +const CleanWebpackPlugin = require('clean-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); + +const packageJSON = require('./package.json'); + +const getBanner = () => + packageJSON.name + '\n' + + packageJSON.homepage + '\n' + + 'Version: ' + packageJSON.version + ' -- ' + (new Date()).toISOString() + '\n' + + 'License: ' + packageJSON.license; + +const scriptName = process.env.npm_lifecycle_event; +const ENV = scriptName.indexOf('dev') === 0 ? 'development' : 'production'; +const isTest = scriptName.indexOf('test') >= 0; + +console.log('***** webpack runs in ' + ENV + (isTest ? ' (test)' : '') + ' environment\n'); + +const devServerPort = 5005; +const devServerHost = 'localhost'; +let configEnv; + +if (ENV === 'development') { + configEnv = { + entry: isTest ? ({ + 'test': glob.sync(path.resolve(__dirname, 'test/*.js')) + }) : ({}), + + output: { + filename: '[name].js', + publicPath: '/' + }, + + devtool: 'inline-source-map', + + plugins: [], + + optimization: {}, + + devServer: !isTest ? { + historyApiFallback: { + rewrites: [ + { from: /\/*\/*\.html$/, to: (context) => '/demo' + context.parsedUrl.pathname }, + { from: /\/*\/*\.css$/, to: (context) => '/demo' + context.parsedUrl.pathname }, + { from: /\/*\/*\.js$/, to: (context) => '/demo' + context.parsedUrl.pathname }, + { from: /\/ui-scroll-demo\.gif$/, to: '/demo/ui-scroll-demo.gif' }, + { from: /^\/$/, to: '/demo/index.html' } + ] + }, + proxy: { + '/dist': { + target: 'http://' + devServerHost + ':' + devServerPort, + pathRewrite: { '^/dist': '' } + } + }, + inline: true, + quiet: false, + stats: { + modules: false, + errors: true, + warnings: true + }, + port: devServerPort, + host: devServerHost, + publicPath: '/' + } : {}, + + watch: true + } +} + +if (ENV === 'production') { + configEnv = { + entry: { + 'ui-scroll.min': path.resolve(__dirname, 'src/ui-scroll.js'), + 'ui-scroll-grid.min': path.resolve(__dirname, 'src/ui-scroll-grid.js') + }, + + output: { + path: path.join(__dirname, 'dist'), + filename: '[name].js' + }, + + devtool: 'source-map', + + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + sourceMap: true, + parallel: true, + extractComments: false, + terserOptions: { + warnings: true, + compress: { + warnings: true, + }, + output: { + comments: false, + }, + }, + include: /\.min\.js$/ + }) + ], + }, + + plugins: [ + new CleanWebpackPlugin('dist', { + root: __dirname + }), + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/ui-scroll-jqlite.js', to: 'ui-scroll-jqlite.min.js' }, + { from: 'src/ui-scroll-jqlite.js', to: 'ui-scroll-jqlite.js' } + ] + }), + new webpack.BannerPlugin(getBanner()) + ], + + devServer: {}, + + watch: false + } +} + +module.exports = { + entry: Object.assign({ + 'ui-scroll': path.resolve(__dirname, 'src/ui-scroll.js'), + 'ui-scroll-grid': path.resolve(__dirname, 'src/ui-scroll-grid.js') + }, configEnv.entry), + + output: configEnv.output, + + cache: false, + + devtool: configEnv.devtool, + + mode: ENV, + + optimization: configEnv.optimization, + + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader' + } + ] + }, + + plugins: configEnv.plugins, + + devServer: configEnv.devServer, + + watch: configEnv.watch +};

    Zfy`jit%x6TB4X(dOE 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 z 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 + + + + User min and max indexes + + + + + + + + +