diff --git a/README.md b/README.md
index 6fcdaebe..524d609f 100644
--- a/README.md
+++ b/README.md
@@ -475,6 +475,9 @@ Pull Rerquest should include source code (./scr) changes, may include tests (./t
## Change log
+### v1.7.4
+ * Fixed jqLite/jQuery confrontation.
+
### v1.7.3
* Fixed some html-attributes and Adapter.reload argument parsing.
diff --git a/bower.json b/bower.json
index 011c229d..e3d7c603 100644
--- a/bower.json
+++ b/bower.json
@@ -1,7 +1,7 @@
{
"name": "angular-ui-scroll",
"description": "AngularJS infinite scrolling module",
- "version": "1.7.3",
+ "version": "1.7.4",
"main": "./dist/ui-scroll.js",
"homepage": "https://github.com/angular-ui/ui-scroll.git",
"license": "MIT",
diff --git a/demo/adapterSync/server.js b/demo/adapterSync/server.js
index 2d2ce191..23bb6395 100644
--- a/demo/adapterSync/server.js
+++ b/demo/adapterSync/server.js
@@ -1,161 +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;
- }
-]);
+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/append/server.js b/demo/append/server.js
index 51a90a86..649171ad 100644
--- a/demo/append/server.js
+++ b/demo/append/server.js
@@ -1,86 +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;
- }
-]);
+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/disabled/disabled.html b/demo/disabled/disabled.html
index c9b4a3b4..2b41caa4 100644
--- a/demo/disabled/disabled.html
+++ b/demo/disabled/disabled.html
@@ -1,44 +1,44 @@
-
-
-
-
+
+
browse other examples
+
+
+
+
+
+ If the height of all the viewport rows is known and not going to be changed,
+ it might be passed as "row-height" attribute.
+ This reduces inner calculations and browser reflows,
+ which leads to a performance increase.
+
+
+
+
+ performance decrease coefficient (0 - fastest)
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/fixedRowHeight/fixedRowHeight.js b/demo/fixedRowHeight/fixedRowHeight.js
new file mode 100644
index 00000000..93185574
--- /dev/null
+++ b/demo/fixedRowHeight/fixedRowHeight.js
@@ -0,0 +1,74 @@
+angular.module('application', ['ui.scroll'])
+
+ .controller('MainCtrl', ($scope) => {
+ $scope.hello = 'Hello Main Controller!';
+
+ let min = -150, max = 200, delay = 0, inputs = 10;
+
+ const getInput = index => {
+ const result = [];
+ for (let i = 0; i < inputs; i++) {
+ result.push({ value: ((index % 2 === 0 ? -1 : 1) * (i + 1)).toString() });
+ }
+ return result;
+ }
+
+ const data = [];
+ for (let i = min; i <= max; i++) {
+ height = 50 + (i + 1);
+ data.push({
+ index: i,
+ text: 'item #' + i,
+ input: getInput(i)
+ });
+ }
+
+ $scope.datasource = {
+ get: (index, count, success) => {
+ console.log('Getting ' + count + ' items started from ' + index + '...');
+ setTimeout(() => {
+ const result = [];
+ const start = Math.max(min, index);
+ const end = Math.min(index + count - 1, max);
+ if (start <= end) {
+ for (let i = start; i <= end; i++) {
+ const _item = data.find(item => item.index === i);
+ if (_item) {
+ result.push(_item);
+ }
+ }
+ }
+ console.log('Got ' + result.length + ' items [' + start + '..' + end + ']');
+ success(result);
+ }, delay);
+ }
+ };
+
+ $scope.getSum = item =>
+ item.input.reduce((a, i) => a + Number(i.value), 0);
+
+ $scope.getMul = item =>
+ item.input.reduce((a, i) => a * Number(i.value), 1);
+
+ $scope.getText = item => {
+ const num = $scope.getMul(item).toString();
+ const result = [];
+ for (let i = 0; i < item.text.length; i++) {
+ result.push(item.text[i]);
+ result.push(i < num.length ? num[i] : 'x');
+ }
+ return result.join('');
+ }
+
+ const perfSlowCountDefault = 2;
+ $scope.perfSlowCount = perfSlowCountDefault;
+ $scope.perfSlowCountList = [];
+ $scope.$watch('perfSlowCount', () => {
+ let size = Number($scope.perfSlowCount);
+ if (isNaN(size)) {
+ size = perfSlowCountDefault;
+ }
+ $scope.perfSlowCountList = (new Array(size)).fill(0);
+ })
+
+ });
diff --git a/demo/grid-dnd-widths/grid-dnd-widths.html b/demo/grid-dnd-widths/grid-dnd-widths.html
index 06f05182..678a0bb1 100644
--- a/demo/grid-dnd-widths/grid-dnd-widths.html
+++ b/demo/grid-dnd-widths/grid-dnd-widths.html
@@ -1,55 +1,55 @@
-
-
-
-
-
Grid dnd widths
-
-
-
-
-
-
-
-
-
-
-
browse other examples
-
-
-
-
- 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}}
-
-
-
-
-
-
+
+
+
+
+
Grid dnd widths
+
+
+
+
+
+
+
+
+
+
+
browse other examples
+
+
+
+
+ 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
index 9404aeca..629bcd84 100644
--- a/demo/grid-dnd-widths/grid-dnd-widths.js
+++ b/demo/grid-dnd-widths/grid-dnd-widths.js
@@ -1,57 +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');
- }
-
-
- }
- ]);
-
-
+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
index 1fe6cc7b..f5d16e11 100644
--- a/demo/grid-dnd-widths/grid.css
+++ b/demo/grid-dnd-widths/grid.css
@@ -1,40 +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;
+.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/index.html b/demo/index.html
index d2c32b7c..7db6cb35 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -16,6 +16,11 @@
Datasource as service
+
+
+ Datasource as service with a fixed rowHeight
+
+
Datasource on scope (not as service)
@@ -64,6 +69,11 @@
Bottom visible (Adapter)
+
+
+ Fixed row height (higher perfromance)
+
+
Reload datasource to specified index
diff --git a/demo/insideComponent/insideComponent.html b/demo/insideComponent/insideComponent.html
index 01dc6c92..37cdebf4 100644
--- a/demo/insideComponent/insideComponent.html
+++ b/demo/insideComponent/insideComponent.html
@@ -1,32 +1,32 @@
-
-
-
-
- Inside Angular 1.5+ component
-
-
-
-
-
-
-
-
-
-
browse other examples
-
-
-
-
- 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.
-
-
-
-
-
-
-
-
+
+
+
+
+ Inside Angular 1.5+ component
+
+
+
+
+
+
+
+
+
+
browse other examples
+
+
+
+
+ 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
index 24c7ce6b..41a59005 100644
--- a/demo/insideComponent/insideComponent.js
+++ b/demo/insideComponent/insideComponent.js
@@ -1,45 +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);
+(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/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
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
\ 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/outOfBuffer/outOfBuffer.html b/demo/outOfBuffer/outOfBuffer.html
index 3c639946..4fe1f3bf 100644
--- a/demo/outOfBuffer/outOfBuffer.html
+++ b/demo/outOfBuffer/outOfBuffer.html
@@ -1,49 +1,49 @@
-
-
-
-
- Adapter sync
-
-
-
-
-
-
-
-
-
-
-
- Prepend one item
- Append one item
-
- Remove first
- Remove last
-
-
-
-
-
-
-
-
+
+
+
+
+ Adapter sync
+
+
+
+
+
+
+
+
+
+
+
+ Prepend one item
+ Append one item
+
+ Remove first
+ Remove last
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/outOfBuffer/outOfBuffer.js b/demo/outOfBuffer/outOfBuffer.js
index bc932b22..0b946a01 100644
--- a/demo/outOfBuffer/outOfBuffer.js
+++ b/demo/outOfBuffer/outOfBuffer.js
@@ -1,217 +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, []);
- }
- });
- };
- }
-]);
+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/remote/remote.html b/demo/remote/remote.html
index d589fb11..2b3f0079 100644
--- a/demo/remote/remote.html
+++ b/demo/remote/remote.html
@@ -1,34 +1,34 @@
-
-
-
-
-
- Remote server emulation
-
-
-
-
-
-
-
-
-
browse other examples
-
-
- 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);
-};
-
-
-
-
-
-
+
+
+
+
+
+ Remote server emulation
+
+
+
+
+
+
+
+
+
browse other examples
+
+
+ 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);
+};
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/remote/remote.js b/demo/remote/remote.js
index acf218c1..5114b0c2 100644
--- a/demo/remote/remote.js
+++ b/demo/remote/remote.js
@@ -1,69 +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);
- });
- }
- };
+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/serviceDatasourceRowHeight/serviceDatasource.html b/demo/serviceDatasourceRowHeight/serviceDatasource.html
new file mode 100644
index 00000000..e7cab253
--- /dev/null
+++ b/demo/serviceDatasourceRowHeight/serviceDatasource.html
@@ -0,0 +1,41 @@
+
+
+
+
+ Datasource as service
+
+
+
+
+
+
+
+
+
+
browse other examples
+
+
+
+
+
This sample shows the optimizations provided by a fixed row height, in particular when scrolling
+ fast through a large list of items as it uses the scrollTo()
method for a direct jump.
+
+
To see the optimization in action, scroll down to item #500, and then scroll back to top using the scrollbar
+ or by pressing 'Home' or 'cmd+ArrowUp' on your keyboard.
+
+ The page is identical to the standard
Datasource as service
+ demo, with the fixed row-height attribute set for the directive:
+
+
<li ui-scroll="item in datasource" row-height="26">{{item}}</li>
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/serviceDatasourceRowHeight/serviceDatasource.js b/demo/serviceDatasourceRowHeight/serviceDatasource.js
new file mode 100644
index 00000000..b8eab711
--- /dev/null
+++ b/demo/serviceDatasourceRowHeight/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/userIndexes/userIndexes.html b/demo/userIndexes/userIndexes.html
index f6dcdfdc..0d62dfcf 100644
--- a/demo/userIndexes/userIndexes.html
+++ b/demo/userIndexes/userIndexes.html
@@ -1,57 +1,57 @@
-
-
-
-
- User min and max indexes
-
-
-
-
-
-
-
-
-
-
-
browse other examples
-
-
-
-
- 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.
-
-
-
- Set minIndex = {{userMinIndex}}
- minIndex value to set
-
- Set maxIndex = {{userMaxIndex}}
- maxIndex value to set
-
- Set both Indexes
-
-
-
-
-
-
-
+
+
+
+
+ User min and max indexes
+
+
+
+
+
+
+
+
+
+
+
browse other examples
+
+
+
+
+ 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.
+
+
+
+ Set minIndex = {{userMinIndex}}
+ minIndex value to set
+
+ Set maxIndex = {{userMaxIndex}}
+ maxIndex value to set
+
+ Set both Indexes
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/userIndexes/userIndexes.js b/demo/userIndexes/userIndexes.js
index 7a1e5720..93f35c68 100644
--- a/demo/userIndexes/userIndexes.js
+++ b/demo/userIndexes/userIndexes.js
@@ -1,42 +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);
-
- }
+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/dist/ui-scroll-grid.js b/dist/ui-scroll-grid.js
index f69f8807..0199247b 100644
--- a/dist/ui-scroll-grid.js
+++ b/dist/ui-scroll-grid.js
@@ -1,7 +1,7 @@
/*!
* angular-ui-scroll
* https://github.com/angular-ui/ui-scroll
- * Version: 1.7.3 -- 2019-05-27T16:57:07.461Z
+ * Version: 1.7.4 -- 2019-08-26T15:34:13.140Z
* License: MIT
*/
/******/ (function(modules) { // webpackBootstrap
diff --git a/dist/ui-scroll-jqlite.js b/dist/ui-scroll-jqlite.js
index c542a1a4..7fae71e5 100644
--- a/dist/ui-scroll-jqlite.js
+++ b/dist/ui-scroll-jqlite.js
@@ -1,12 +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', []);
-
+/*!
+ * 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
index c542a1a4..7fae71e5 100644
--- a/dist/ui-scroll-jqlite.min.js
+++ b/dist/ui-scroll-jqlite.min.js
@@ -1,12 +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', []);
-
+/*!
+ * 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.js b/dist/ui-scroll.js
index 6a791810..8133dc1b 100644
--- a/dist/ui-scroll.js
+++ b/dist/ui-scroll.js
@@ -1,7 +1,7 @@
/*!
* angular-ui-scroll
* https://github.com/angular-ui/ui-scroll
- * Version: 1.7.3 -- 2019-05-27T16:57:07.461Z
+ * Version: 1.7.4 -- 2019-08-26T15:34:13.140Z
* License: MIT
*/
/******/ (function(modules) { // webpackBootstrap
@@ -113,15 +113,15 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
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)
+/*!
+ 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__*/
@@ -342,8 +342,8 @@ function () {
return getWidthHeight(this[0], 'width', option ? 'outerfull' : 'outer');
},
- /*
- The offset setter method is not implemented
+ /*
+ The offset setter method is not implemented
*/
offset: function offset(value) {
var docElem, win;
@@ -509,7 +509,7 @@ function () {
// CONCATENATED MODULE: ./src/modules/buffer.js
-function ScrollBuffer(elementRoutines, bufferSize, startIndex) {
+function ScrollBuffer(elementRoutines, bufferSize, startIndex, rowHeight) {
var buffer = Object.create(Array.prototype);
angular.extend(buffer, {
size: bufferSize,
@@ -519,11 +519,23 @@ function ScrollBuffer(elementRoutines, bufferSize, startIndex) {
buffer.bof = false;
buffer.first = startIndex;
buffer.next = startIndex;
- buffer.minIndex = startIndex;
+ buffer.minIndex = startIndex; // Calculated when data is effectively accessed
+
buffer.maxIndex = startIndex;
- buffer.minIndexUser = null;
+ buffer.minIndexUser = null; // as set by the user (datasource)
+
buffer.maxIndexUser = null;
},
+ // PHIL: set the new index to be displayed without resettng the sroll and the calculated min/max
+ // Note that this actually make sense with a fixed rowHeight when the scroll value can be calculated
+ // for a # of rows
+ resetStartIndex: function resetStartIndex(startIndex) {
+ buffer.remove(0, buffer.length);
+ buffer.eof = buffer.eof && startIndex == buffer.maxIndex;
+ buffer.bof = buffer.bof && startIndex == buffer.minIndex;
+ buffer.first = startIndex;
+ buffer.next = startIndex;
+ },
append: function append(items) {
items.forEach(function (item) {
++buffer.next;
@@ -539,11 +551,11 @@ function ScrollBuffer(elementRoutines, bufferSize, startIndex) {
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', 'update', 'none'
+ /**
+ * 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', 'update', 'none'
*/
insert: function insert(operation, item, isTop) {
var wrapper = {
@@ -601,8 +613,9 @@ function ScrollBuffer(elementRoutines, bufferSize, startIndex) {
}
if (!buffer.length) {
- buffer.first = 1;
- buffer.next = 1;
+ buffer.first = buffer.minIndex % 1 ? buffer.minIndex : startIndex;
+ buffer.next = buffer.first;
+ buffer.eof = buffer.eof && buffer.first == buffer.maxIndex;
}
return elementRoutines.removeElementAnimated(arg1);
@@ -653,10 +666,33 @@ function ScrollBuffer(elementRoutines, bufferSize, startIndex) {
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));
+ bottom = Math.max(bottom, wrapper.element.offset().top + (rowHeight || wrapper.element.outerHeight(true)));
}
});
return Math.max(0, bottom - top);
+ },
+ getItems: function getItems() {
+ return buffer.filter(function (item) {
+ return item.op === '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);
@@ -764,21 +800,30 @@ function generateElement(template) {
}
return element;
-}
+} //
+// Padding represents the dummy element added to both the top and the bottom of the scrolling container
+// It holds the element, as well as a cache for the items (rows) height. In case of a fixed rowHeight, the
+// cache is not used and thus is not created.
+//
+
var Padding =
/*#__PURE__*/
function () {
- function Padding(template) {
+ function Padding(template, useCache) {
padding_classCallCheck(this, Padding);
this.element = generateElement(template);
- this.cache = new Cache();
+
+ if (useCache) {
+ this.cache = new Cache();
+ }
}
padding_createClass(Padding, [{
key: "height",
value: function height() {
+ // When called with a parameter, this sets the height of the padding
return this.element.height.apply(this.element, arguments);
}
}]);
@@ -789,7 +834,7 @@ function () {
/* harmony default export */ var modules_padding = (Padding);
// CONCATENATED MODULE: ./src/modules/viewport.js
-function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding) {
+function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding, rowHeight) {
var topPadding = null;
var bottomPadding = null;
var viewport = viewportController && viewportController.viewport ? viewportController.viewport : angular.element(window);
@@ -803,15 +848,41 @@ function Viewport(elementRoutines, buffer, element, viewportController, $rootSco
function bufferPadding() {
return viewport.outerHeight() * padding; // some extra space to initiate preload
- }
+ } //
+ // Viewport measurements
+ //
+ // +----------------+ 0
+ // | top |
+ // | padding |
+ // +----------------+ topDataPos() [=topPadding.height]
+ // | not visible |
+ // | items |
+ // +----------------+ topVisiblePos() [=viewport.scrollTop]
+ // | |
+ // | visible |
+ // | items |
+ // | |
+ // +----------------+ bottomVisiblePos() [=viewport.scrollTop+viewport.height]
+ // | not visible |
+ // | items |
+ // +----------------+ bottomDataPos() [=scrollHeight-bottomPadding.height]
+ // | bottom |
+ // | padding |
+ // +----------------+ scrollHeight
+ //
+ // bufferPadding is some extra space we have top & bottom to allow infinite scrolling
+ // bufferPadding = viewport.outerHeight() * padding
+ //
+ // bottomVisiblePos() - topVisiblePos() == viewport.outerHeight()
+
angular.extend(viewport, {
getScope: function getScope() {
return scope;
},
createPaddingElements: function createPaddingElements(template) {
- topPadding = new modules_padding(template);
- bottomPadding = new modules_padding(template);
+ topPadding = new modules_padding(template, !rowHeight);
+ bottomPadding = new modules_padding(template, !rowHeight);
element.before(topPadding.element);
element.after(bottomPadding.element);
topPadding.height(0);
@@ -854,20 +925,25 @@ function Viewport(elementRoutines, buffer, element, viewportController, $rootSco
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 (rowHeight) {
+ overage = Math.min(buffer.length, Math.floor(emptySpaceHeight / rowHeight));
+ } else {
+ var itemHeight = 0;
+ var overageHeight = 0;
- if (overageHeight + itemHeight > emptySpaceHeight) {
- break;
- }
+ 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++;
+ bottomPadding.cache.add(buffer[i]);
+ overageHeight += itemHeight;
+ overage++;
+ }
}
if (overage > 0) {
@@ -884,19 +960,25 @@ function Viewport(elementRoutines, buffer, element, viewportController, $rootSco
// 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 (rowHeight) {
+ overage = Math.min(buffer.length, Math.floor(emptySpaceHeight / rowHeight));
+ overageHeight = overage * rowHeight;
+ } else {
+ var itemHeight = 0;
- if (overageHeight + itemHeight > emptySpaceHeight) {
- break;
- }
+ for (var i = 0; i < buffer.length; i++) {
+ itemHeight = buffer[i].element.outerHeight(true);
- topPadding.cache.add(buffer[i]);
- overageHeight += itemHeight;
- overage++;
+ if (overageHeight + itemHeight > emptySpaceHeight) {
+ break;
+ }
+
+ topPadding.cache.add(buffer[i]);
+ overageHeight += itemHeight;
+ overage++;
+ }
}
if (overage > 0) {
@@ -908,7 +990,36 @@ function Viewport(elementRoutines, buffer, element, viewportController, $rootSco
buffer.first += overage;
}
},
+ // PHIL: remove all the entries in the buffer without changing the scrollbar, nor the scroll position
+ // and update the padding accordingly
+ // It is designed to work with non fixed rowHeight, although it will need more tests in this area...
+ scrollTo: function scrollTo(first) {
+ if (rowHeight) {
+ var min = buffer.getAbsMinIndex();
+ var max = buffer.getAbsMaxIndex();
+ first = Math.min(Math.max(first, min), max); // Adjust the paddings before removing the elements to avoid touching the scroll top position
+
+ topPadding.height((first - min) * rowHeight);
+ bottomPadding.height((max + 1 - first) * rowHeight);
+ buffer.resetStartIndex(first);
+ } else {
+ buffer.resetStartIndex(first);
+ viewport.adjustPaddings();
+ }
+ },
adjustPaddings: function adjustPaddings() {
+ if (rowHeight) {
+ var min = buffer.getAbsMinIndex();
+ var max = buffer.getAbsMaxIndex();
+ topPadding.height((buffer.first - min) * rowHeight); // PHIL: next points to the next possible item, while max is the index of the last one.
+ // In order to make them compatible, we should add one to max
+ // Also, it looks like buffer is not changing maxIndex when an element is inserted/appended
+ // Not sure if this can have a consequence or not....
+
+ bottomPadding.height((max + 1 - buffer.next) * rowHeight);
+ return;
+ }
+
if (!buffer.length) {
return;
} // precise heights calculation based on items that are in buffer or that were in buffer once
@@ -970,15 +1081,26 @@ function Viewport(elementRoutines, buffer, element, viewportController, $rootSco
},
resetTopPadding: function resetTopPadding() {
topPadding.height(0);
- topPadding.cache.clear();
+
+ if (topPadding.cache) {
+ topPadding.cache.clear();
+ }
},
resetBottomPadding: function resetBottomPadding() {
bottomPadding.height(0);
- bottomPadding.cache.clear();
+
+ if (bottomPadding.cache) {
+ bottomPadding.cache.clear();
+ }
},
removeCacheItem: function removeCacheItem(item, isTop) {
- topPadding.cache.remove(item, isTop);
- bottomPadding.cache.remove(item, isTop);
+ if (topPadding.cache) {
+ topPadding.cache.remove(item, isTop);
+ }
+
+ if (bottomPadding.cache) {
+ bottomPadding.cache.remove(item, isTop);
+ }
},
removeItem: function removeItem(item) {
this.removeCacheItem(item);
@@ -1070,6 +1192,21 @@ function () {
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
@@ -1120,29 +1257,33 @@ function () {
}
}, {
key: "applyUpdates",
- value: function applyUpdates(arg1, arg2) {
+ value: function applyUpdates(arg1, arg2, arg3) {
if (typeof arg1 === 'function') {
- this.applyUpdatesFunc(arg1);
+ this.applyUpdatesFunc(arg1, arg2);
+ if (arg2 && arg2.noAdjust) return;
} else {
- this.applyUpdatesIndex(arg1, arg2);
+ this.applyUpdatesIndex(arg1, arg2, arg3);
+ if (arg3 && arg3.noAdjust) return;
}
this.doAdjust();
}
}, {
key: "applyUpdatesFunc",
- value: function applyUpdatesFunc(cb) {
+ value: function applyUpdatesFunc(cb, options) {
var _this2 = this;
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));
+ _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)');
}
@@ -1151,13 +1292,13 @@ function () {
if (_index >= 0 && _index < this.buffer.length) {
- this.applyUpdate(this.buffer[_index], newItems);
+ 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, index === this.buffer.minIndex);
+ this.viewport.removeCacheItem(index, !options.immutableTop && index === this.buffer.minIndex);
- if (index === this.buffer.getAbsMinIndex()) {
+ if (!options.immutableTop && index === this.buffer.getAbsMinIndex()) {
this.buffer.incrementMinIndex();
} else {
this.buffer.decrementMaxIndex();
@@ -1170,6 +1311,8 @@ function () {
value: function applyUpdate(wrapper, newItems) {
var _this3 = this;
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+
if (!angular.isArray(newItems)) {
return;
}
@@ -1181,7 +1324,7 @@ function () {
})) {
wrapper.op = 'remove';
- if (position === 0 && !newItems.length) {
+ if (!options.immutableTop && position === 0 && !newItems.length) {
wrapper._op = 'isTop'; // to catch "first" edge case on remove
}
}
@@ -1191,7 +1334,7 @@ function () {
position--;
} else {
// 3 parameter (isTop) is to catch "first" edge case on insert
- _this3.buffer.insert(position + 1, newItem, position === -1);
+ _this3.buffer.insert(position + 1, newItem, !options.immutableTop && position === -1);
}
});
}
@@ -1237,6 +1380,21 @@ function () {
}
}
}
+ }, {
+ 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;
@@ -1250,7 +1408,8 @@ function () {
angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtras).run(['JQLiteExtras', function (JQLiteExtras) {
- !window.jQuery ? new JQLiteExtras().registerFor(angular.element) : null;
+ var elt = angular.element;
+ !(window.jQuery && elt.fn && elt.fn.jquery) ? new JQLiteExtras().registerFor(elt) : null;
ElementRoutines.addCSSRules();
}]).directive('uiScrollViewport', function () {
return {
@@ -1299,31 +1458,52 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
return parseNumber(result, defaultValue, isFloat);
}
- var BUFFER_MIN = 3;
- var BUFFER_DEFAULT = 10;
- var PADDING_MIN = 0.3;
- var PADDING_DEFAULT = 0.5;
- var START_INDEX_DEFAULT = 1;
- var MAX_VIEWPORT_DELAY = 500;
- var VIEWPORT_POLLING_INTERVAL = 50;
+ var BUFFER_MIN = 3; // Minimum size of the data source request
+
+ var BUFFER_DEFAULT = 10; // Default datasource request size
+
+ var PADDING_MIN = 0.3; // Mininum # of rows in the padding area
+
+ var PADDING_DEFAULT = 0.5; // Default # of rows in the padding area
+
+ var START_INDEX_DEFAULT = 1; // Default start index when requestng the first data block
+
+ var MAX_VIEWPORT_DELAY = 500; // Max time wait (ms) to get the viewport with an height>0
+
+ var VIEWPORT_POLLING_INTERVAL = 50; // Interval used to check the initial viewport height
+
var datasource = null;
- var itemName = match[1];
- var datasourceName = match[2];
- var viewportController = controllers[0];
+ var itemName = match[1]; // Name of the index variable to publish
+
+ var datasourceName = match[2]; // Name of the datasource to request the rows from
+
+ var viewportController = controllers[0]; // ViewportController, as specified in the require option (http://websystique.com/angularjs/angularjs-custom-directives-controllers-require-option-guide/)
+
var bufferSize = Math.max(BUFFER_MIN, parseNumericAttr($attr.bufferSize, BUFFER_DEFAULT));
var padding = Math.max(PADDING_MIN, parseNumericAttr($attr.padding, PADDING_DEFAULT, true));
- var startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT);
+ var startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT); // PHIL: Provide a fixed row height
+ //
+
+ var rowHeight = parseNumericAttr($attr.rowHeight, null, false); // PHIL: Read the visibility watch option, true by default
+
+ var allowVisibilityWatch = $attr.allowVisibilityWatch !== 'false'; // Revision IDs
+ //
+
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 buffer = new ScrollBuffer(elementRoutines, bufferSize, startIndex, rowHeight);
+ var viewport = new Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding, rowHeight);
var adapter = new modules_adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload);
if (viewportController) {
viewportController.adapter = adapter;
- }
+ } // Currently, we only debounce the scroll events when a fixed rowHeight is provided
+ // as the unit tests will have to be adapted to support this feature
+
+
+ var scPreviousScrollTop = -1;
var isDatasourceValid = function isDatasourceValid() {
return Object.prototype.toString.call(datasource) === '[object Object]' && typeof datasource.get === 'function';
@@ -1473,7 +1653,12 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
function bindEvents() {
viewport.bind('resize', resizeAndScrollHandler);
- viewport.bind('scroll', resizeAndScrollHandler);
+ viewport.bind('scroll', resizeAndScrollHandler); // If a scroll event happened while the handler was not bounded, emit the scroll
+
+ if (isPendingScroll()) {
+ // Do it immediately
+ _resizeAndScrollHandler();
+ }
}
function unbindEvents() {
@@ -1482,6 +1667,7 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
}
function reload() {
+ unbindEvents();
viewport.resetTopPadding();
viewport.resetBottomPadding();
@@ -1490,13 +1676,21 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
}
buffer.reset(startIndex);
+ scPreviousScrollTop = -1; // Avoid isScrollPending() to be true
+
persistDatasourceIndex(datasource, 'minIndex');
persistDatasourceIndex(datasource, 'maxIndex');
doAdjust();
}
+ function scrollTo(first) {
+ unbindEvents();
+ viewport.scrollTo(first);
+ doAdjust();
+ }
+
function isElementVisible(wrapper) {
- return wrapper.element.height() && wrapper.element[0].offsetParent;
+ return (rowHeight || wrapper.element.height()) && wrapper.element[0].offsetParent;
}
function visibilityWatcher(wrapper) {
@@ -1519,13 +1713,15 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
function insertWrapperContent(wrapper, insertAfter) {
createElement(wrapper, insertAfter, viewport.insertElement);
- if (!isElementVisible(wrapper)) {
+ if (allowVisibilityWatch && !isElementVisible(wrapper)) {
wrapper.unregisterVisibilityWatcher = wrapper.scope.$watch(function () {
return visibilityWatcher(wrapper);
});
}
- elementRoutines.hideElement(wrapper); // hide inserted elements before data binding
+ if (allowVisibilityWatch) {
+ elementRoutines.hideElement(wrapper); // hide inserted elements before data binding
+ }
}
function createElement(wrapper, insertAfter, insertElement) {
@@ -1599,7 +1795,9 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
inserted: inserted,
animated: promises
};
- }
+ } // Adjust the viewport paddings
+ //
+
function updatePaddings(rid, updates) {
// schedule another doAdjust after animation completion
@@ -1614,6 +1812,17 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
}
function enqueueFetch(rid, updates) {
+ // If there is a scroll pending, we don't enqueue the fetch as the scroll might be an absolute scroll
+ // So we don't need to load top or bottom
+ // This happens when there is a scroll frenzi, and the $digest is slow enough, so it stacks the calls without
+ // giving a chance to the scroll event to be emitted and processed.
+ // We also do that if it leads to an absolute scroll
+ if (isPendingScroll() && calculateAbsoluteScroll() !== undefined) {
+ // Looks like the event is swallowed on some browsers (FF) on some scroll configuration
+ resizeAndScrollHandler();
+ return;
+ }
+
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
@@ -1637,14 +1846,23 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
function processUpdates() {
var updates = updateDOM(); // We need the item bindings to be processed before we can do adjustments
+ // If there are no changes and the row-height is static, then ignore it!
+
+ var changes = updates.animated.length + updates.inserted.length + updates.prepended.length + updates.removed.length;
+
+ if (changes || !rowHeight) {
+ !$scope.$$phase && !$rootScope.$$phase && $scope.$digest();
+ }
+
+ if (allowVisibilityWatch) {
+ updates.inserted.forEach(function (w) {
+ return elementRoutines.showElement(w);
+ });
+ updates.prepended.forEach(function (w) {
+ return elementRoutines.showElement(w);
+ });
+ }
- !$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;
}
@@ -1739,19 +1957,79 @@ angular.module('ui.scroll', []).constant('JQLiteExtras', jqLiteExtras_JQLiteExtr
}
}
+ function isPendingScroll() {
+ if (rowHeight) {
+ // Maybe the scroll changed but the event has *not* yet being dispatched
+ // because of the $digest running and taking to long
+ var sc = viewport.scrollTop();
+
+ if (sc != scPreviousScrollTop && scPreviousScrollTop >= 0) {
+ return true;
+ }
+ }
+
+ return false;
+ } // Deboucing the scroll events avois intermediate $digest when scrolling fast
+
+
+ var scTimer;
+
function resizeAndScrollHandler() {
+ if (rowHeight) {
+ if (scTimer) clearTimeout(scTimer);
+ scTimer = setTimeout(_resizeAndScrollHandler, 50);
+ } else {
+ _resizeAndScrollHandler();
+ }
+ }
+
+ function _resizeAndScrollHandler() {
if (!$rootScope.$$phase && !adapter.isLoading && !adapter.disabled) {
+ // Absolute positioning currently only works when a fixed rowHeight is provided
+ // We might isolate the averegaRowHeight calculation in the viewport to provide an estimate
+ // and provide a reasonable behavior with variable height as well
+ if (rowHeight) {
+ var newFirst = calculateAbsoluteScroll();
+
+ if (newFirst !== undefined) {
+ scrollTo(newFirst);
+ return;
+ }
+ }
+
enqueueFetch(ridActual);
if (pending.length) {
unbindEvents();
} else {
adapter.calculateProperties();
- !$scope.$$phase && $scope.$digest();
+
+ if (!rowHeight) {
+ // The digest is forced to calculate the height, which is not necessary when the height is knowm
+ !$scope.$$phase && $scope.$digest();
+ }
}
}
}
+ function calculateAbsoluteScroll() {
+ if (rowHeight) {
+ scPreviousScrollTop = viewport.scrollTop();
+ var newFirst = Math.floor(viewport.scrollTop() / rowHeight) + buffer.getAbsMinIndex();
+ newFirst = Math.max(buffer.getAbsMinIndex(), Math.min(buffer.getAbsMaxIndex(), newFirst)); // Bound the scroll
+
+ if (newFirst < buffer.first - bufferSize) {
+ return newFirst;
+ }
+
+ if (newFirst > buffer.next + bufferSize) {
+ return newFirst;
+ }
+ }
+
+ return undefined;
+ }
+
function wheelHandler(event) {
if (!adapter.disabled) {
var scrollTop = viewport[0].scrollTop;
diff --git a/dist/ui-scroll.js.map b/dist/ui-scroll.js.map
index ee87c1d0..526bc9b9 100644
--- a/dist/ui-scroll.js.map
+++ b/dist/ui-scroll.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/modules/jqLiteExtras.js","webpack:///./src/modules/elementRoutines.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","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","reverse","min","operation","isTop","op","splice","push","unshift","arg1","arg2","indexOf","_op","getAbsMinIndex","incrementMinIndex","decrementMaxIndex","removeElementAnimated","getAbsMaxIndex","effectiveHeight","elements","Number","MAX_VALUE","bottom","NEGATIVE_INFINITY","offsetParent","CacheProto","$index","sort","a","b","argument","_isTop","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","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","newItems","applyUpdatesFunc","applyUpdatesIndex","cb","slice","applyUpdate","_index","isArray","position","some","newItem","rowTop","topHeight","topDone","bottomDone","itemTop","isEOF","module","constant","run","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","BUFFER_MIN","BUFFER_DEFAULT","PADDING_MIN","PADDING_DEFAULT","START_INDEX_DEFAULT","MAX_VIEWPORT_DELAY","VIEWPORT_POLLING_INTERVAL","datasource","itemName","datasourceName","ridActual","pending","isDatasourceValid","toString","onRenderHandlers","onRenderHandlersRunner","handler","persistDatasourceIndex","propName","getter","filter","id","defineDatasourceIndex","propUserName","descriptor","getOwnPropertyDescriptor","fetchNext","success","count","fetchPrevious","initialize","tryCount","timer","cancel","clone","$on","unbindEvents","unbind","wheelHandler","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","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 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('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) {\r\n items.reverse().forEach((item) => {\r\n --buffer.first;\r\n buffer.insert('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', 'update', 'none'\r\n */\r\n insert(operation, item, isTop) {\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 = 'insert';\r\n buffer.splice(operation, 0, wrapper);\r\n if(isTop) {\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 'append':\r\n buffer.push(wrapper);\r\n break;\r\n case '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._op === 'isTop' && buffer.first === this.getAbsMinIndex()) {\r\n this.incrementMinIndex();\r\n }\r\n else {\r\n this.decrementMaxIndex();\r\n }\r\n if(arg1._op === 'isTop') {\r\n buffer.first++;\r\n }\r\n else {\r\n buffer.next--;\r\n }\r\n if(!buffer.length) {\r\n buffer.first = 1;\r\n buffer.next = 1;\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 });\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, _isTop) {\r\n const index = argument % 1 === 0 ? argument : argument.scope.$index;\r\n const isTop = argument % 1 === 0 ? _isTop : argument._op === 'isTop';\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(!isTop) {\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 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 }\r\n else {\r\n topPadding.height(0);\r\n viewport.scrollTop(viewport.scrollTop() - paddingHeight);\r\n }\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, isTop) {\r\n topPadding.cache.remove(item, isTop);\r\n bottomPadding.cache.remove(item, isTop);\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","class 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 // 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 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) {\r\n this.buffer.prepend(newItems);\r\n this.doAdjust();\r\n this.viewport.clipTop();\r\n this.viewport.clipBottom();\r\n }\r\n\r\n applyUpdates(arg1, arg2) {\r\n if (typeof arg1 === 'function') {\r\n this.applyUpdatesFunc(arg1);\r\n } else {\r\n this.applyUpdatesIndex(arg1, arg2);\r\n }\r\n this.doAdjust();\r\n }\r\n\r\n applyUpdatesFunc(cb) {\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));\r\n });\r\n }\r\n\r\n applyUpdatesIndex(index, newItems) {\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);\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, index === this.buffer.minIndex);\r\n if(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) {\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 = 'remove';\r\n if(position === 0 && !newItems.length) {\r\n wrapper._op = 'isTop'; // to catch \"first\" edge case on remove\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 (isTop) is to catch \"first\" edge case on insert\r\n this.buffer.insert(position + 1, newItem, 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';\n\nangular.module('ui.scroll', [])\n\n .constant('JQLiteExtras', JQLiteExtras)\n .run(['JQLiteExtras', (JQLiteExtras) => {\n !window.jQuery ? (new JQLiteExtras()).registerFor(angular.element) : 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 const BUFFER_MIN = 3;\n const BUFFER_DEFAULT = 10;\n const PADDING_MIN = 0.3;\n const PADDING_DEFAULT = 0.5;\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 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.unbind('mousewheel', wheelHandler);\n });\n\n viewport.bind('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.bind('resize', resizeAndScrollHandler);\n viewport.bind('scroll', resizeAndScrollHandler);\n }\n\n function unbindEvents() {\n viewport.unbind('resize', resizeAndScrollHandler);\n viewport.unbind('scroll', resizeAndScrollHandler);\n }\n\n function reload() {\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 'prepend':\n toBePrepended.unshift(wrapper);\n break;\n case 'append':\n insertWrapperContent(wrapper, i);\n wrapper.op = 'none';\n inserted.push(wrapper);\n break;\n case 'insert':\n promises = promises.concat(createElement(wrapper, i, viewport.insertElementAnimated));\n wrapper.op = 'none';\n inserted.push(wrapper);\n break;\n case '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 = '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 resizeAndScrollHandler() {\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
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/modules/jqLiteExtras.js","webpack:///./src/modules/elementRoutines.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","ScrollBuffer","elementRoutines","bufferSize","startIndex","rowHeight","buffer","Object","create","Array","extend","size","reset","eof","bof","first","next","minIndex","maxIndex","minIndexUser","maxIndexUser","resetStartIndex","append","items","item","insert","Math","max","reverse","min","operation","isTop","op","splice","push","unshift","arg1","arg2","indexOf","_op","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","_isTop","Cache","instance","apply","setPrototypeOf","getOwnPropertyNames","methodName","generateElement","template","Node","ELEMENT_NODE","tagName","toLowerCase","table","find","Padding","useCache","cache","Viewport","viewportController","$rootScope","topPadding","bottomPadding","viewport","container","bufferPadding","getScope","createPaddingElements","applyContainerStyle","bottomDataPos","scrollHeight","topDataPos","bottomVisiblePos","topVisiblePos","e","sibling","insertElementAnimated","shouldLoadBottom","clipBottom","overage","emptySpaceHeight","floor","itemHeight","overageHeight","add","adjustPaddings","shouldLoadTop","clipTop","visibleItemsHeight","reduce","summ","topPaddingHeight","topCount","bottomPaddingHeight","bottomCount","totalHeight","averageItemHeight","adjustTopPadding","adjustBottomPadding","topPaddingHeightAdd","bottomPaddingHeightAdd","onAfterMinIndexSet","topPaddingHeightOld","diff","onAfterPrepend","updates","prepended","paddingHeight","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","arg3","applyUpdatesFunc","noAdjust","applyUpdatesIndex","cb","options","slice","applyUpdate","_index","isArray","immutableTop","position","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","isNaN","parseNumericAttr","BUFFER_MIN","BUFFER_DEFAULT","PADDING_MIN","PADDING_DEFAULT","START_INDEX_DEFAULT","MAX_VIEWPORT_DELAY","VIEWPORT_POLLING_INTERVAL","datasource","itemName","datasourceName","allowVisibilityWatch","ridActual","pending","scPreviousScrollTop","isDatasourceValid","toString","onRenderHandlers","onRenderHandlersRunner","handler","persistDatasourceIndex","propName","getter","id","defineDatasourceIndex","propUserName","descriptor","getOwnPropertyDescriptor","fetchNext","success","count","fetchPrevious","initialize","tryCount","timer","cancel","clone","$on","unbindEvents","unbind","wheelHandler","isInvalid","rid","$$destroyed","bindEvents","resizeAndScrollHandler","isPendingScroll","_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","calculateAbsoluteScroll","loading","fetch","processUpdates","changes","$$phase","$digest","w","showElement","calculateProperties","doAdjustAfterFetch","shift","sc","scTimer","clearTimeout","setTimeout","newFirst","event","yMax","clientHeight","preventDefault"],"mappings":";;;;;;;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AClFA;;;;;;;;;;IAWqBA,yB;;;;;;;;;gCAEPC,O,EAAS;AACnB,UAAIC,WAAJ,EAAiBC,GAAjB,EAAsBC,QAAtB,EAAgCC,QAAhC,CADmB,CAEnB;;AACAF,SAAG,GAAGG,OAAO,CAACL,OAAR,CAAgBM,SAAhB,CAA0BJ,GAAhC;;AAEAF,aAAO,CAACM,SAAR,CAAkBJ,GAAlB,GAAwB,UAAUK,IAAV,EAAgBC,KAAhB,EAAuB;AAC7C,YAAIC,IAAI,GAAG,IAAX;AACA,YAAIC,IAAI,GAAGD,IAAI,CAAC,CAAD,CAAf;;AACA,YAAI,EAAE,CAACC,IAAD,IAASA,IAAI,CAACC,QAAL,KAAkB,CAA3B,IAAgCD,IAAI,CAACC,QAAL,KAAkB,CAAlD,IAAuD,CAACD,IAAI,CAACE,KAA/D,CAAJ,EAA2E;AACzE,iBAAOV,GAAG,CAACW,IAAJ,CAASJ,IAAT,EAAeF,IAAf,EAAqBC,KAArB,CAAP;AACD;AACF,OAND,CALmB,CAanB;;;AACAJ,cAAQ,GAAG,kBAACU,GAAD;AAAA,eAASA,GAAG,IAAIA,GAAG,CAACC,QAAX,IAAuBD,GAAG,CAACE,QAA3B,IAAuCF,GAAG,CAACG,KAA3C,IAAoDH,GAAG,CAACI,WAAjE;AAAA,OAAX;;AAEA,eAASC,QAAT,CAAkBV,IAAlB,EAAwBW,SAAxB,EAAmCZ,KAAnC,EAA0C;AACxC,YAAIE,IAAI,GAAGD,IAAI,CAAC,CAAD,CAAf;;AADwC,iDAET;AAC7BY,aAAG,EAAE,CACH,WADG,EAEH,aAFG,EAGH,YAHG,CADwB;AAM7BC,cAAI,EAAE,CACJ,YADI,EAEJ,aAFI,EAGJ,WAHI;AANuB,UAW7BF,SAX6B,CAFS;AAAA,YAEnCG,MAFmC;AAAA,YAE3BC,IAF2B;AAAA,YAErBC,QAFqB;;AAexC,YAAMC,cAAc,GAAG,OAAOlB,KAAP,KAAiB,WAAxC;;AACA,YAAIJ,QAAQ,CAACM,IAAD,CAAZ,EAAoB;AAClB,cAAIgB,cAAJ,EAAoB;AAClB,mBAAOhB,IAAI,CAACS,QAAL,CAAcV,IAAI,CAACgB,QAAD,CAAJ,CAAeZ,IAAf,CAAoBJ,IAApB,CAAd,EAAyCD,KAAzC,CAAP;AACD;;AACD,iBAAQgB,IAAI,IAAId,IAAT,GAAiBA,IAAI,CAACc,IAAD,CAArB,GAA8Bd,IAAI,CAACK,QAAL,CAAcY,eAAd,CAA8BJ,MAA9B,CAArC;AACD,SALD,MAKO;AACL,cAAIG,cAAJ,EAAoB;AAClBhB,gBAAI,CAACa,MAAD,CAAJ,GAAef,KAAf;AACD;;AACD,iBAAOE,IAAI,CAACa,MAAD,CAAX;AACD;AACF;;AAED,UAAIK,MAAM,CAACC,gBAAX,EAA6B;AAC3B1B,gBAAQ,GAAG,kBAACO,IAAD;AAAA,iBAAUkB,MAAM,CAACC,gBAAP,CAAwBnB,IAAxB,EAA8B,IAA9B,CAAV;AAAA,SAAX;;AACAT,mBAAW,GAAG,qBAACS,IAAD,EAAOF,KAAP;AAAA,iBAAiBsB,UAAU,CAACtB,KAAD,CAA3B;AAAA,SAAd;AACD,OAHD,MAGO;AACLL,gBAAQ,GAAG,kBAACO,IAAD;AAAA,iBAAUA,IAAI,CAACqB,YAAf;AAAA,SAAX;;AACA9B,mBAAW,GAAG,qBAACS,IAAD,EAAOF,KAAP,EAAiB;AAC7B,cAAIc,IAAJ,EAAUU,MAAV,EAAkBC,EAAlB,EAAsBC,MAAtB,EAA8BtB,KAA9B;AACA,cAAIuB,SAAS,GAAG,sCAAsCC,MAAtD;AACA,cAAIC,SAAS,GAAG,IAAIC,MAAJ,CAAW,OAAOH,SAAP,GAAmB,iBAA9B,EAAiD,GAAjD,CAAhB;;AAEA,cAAI,CAACE,SAAS,CAACE,IAAV,CAAe/B,KAAf,CAAL,EAA4B;AAC1B,mBAAOsB,UAAU,CAACtB,KAAD,CAAjB;AACD,WAP4B,CAS7B;;;AACAI,eAAK,GAAGF,IAAI,CAACE,KAAb;AACAU,cAAI,GAAGV,KAAK,CAACU,IAAb;AACAW,YAAE,GAAGvB,IAAI,CAAC8B,YAAV;AACAN,gBAAM,GAAGD,EAAE,IAAIA,EAAE,CAACX,IAAlB;;AACA,cAAIW,EAAJ,EAAQ;AACNA,cAAE,CAACX,IAAH,GAAUV,KAAK,CAACU,IAAhB;AACD,WAhB4B,CAiB7B;;;AACAV,eAAK,CAACU,IAAN,GAAad,KAAb;AACAwB,gBAAM,GAAGpB,KAAK,CAAC6B,SAAf;AACA7B,eAAK,CAACU,IAAN,GAAaA,IAAb;;AACA,cAAIY,MAAJ,EAAY;AACVD,cAAE,CAACX,IAAH,GAAUY,MAAV;AACD;;AACD,iBAAOF,MAAP;AACD,SAzBD;AA0BD;;AAED,eAASU,eAAT,CAAyBhC,IAAzB,EAA+BiC,OAA/B,EAAwC;AACtC,YAAIC,IAAJ,EAAUC,OAAV,EAAmBC,OAAnB,EAA4BC,eAA5B,EAA6CC,eAA7C,EAA8DC,aAA9D,EAA6EC,IAA7E,EAAmFC,IAAnF,EAAyFC,OAAzF,EAAkGC,OAAlG,EAA2GC,QAA3G,EAAqHC,QAArH;;AAEA,YAAInD,QAAQ,CAACM,IAAD,CAAZ,EAAoB;AAClBkC,cAAI,GAAG7B,QAAQ,CAACY,eAAT,CAAyB;AAAC6B,kBAAM,EAAE,cAAT;AAAyBC,iBAAK,EAAE;AAAhC,YAA+Cd,OAA/C,CAAzB,CAAP;AAEA,iBAAO;AACLC,gBAAI,EAAEA,IADD;AAELc,mBAAO,EAAE,CAFJ;AAGLC,kBAAM,EAAE,CAHH;AAILC,kBAAM,EAAE;AAJH,WAAP;AAMD,SAZqC,CActC;;;AAdsC,mDAmBlC;AACFH,eAAK,EAAE,CACL/C,IAAI,CAACmD,WADA,EAEL,MAFK,EAGL,OAHK,CADL;AAMFL,gBAAM,EAAE,CACN9C,IAAI,CAACoD,YADC,EAEN,KAFM,EAGN,QAHM;AANN,UAWFnB,OAXE,CAnBkC;;AAgBpCC,YAhBoC;AAiBpCM,YAjBoC;AAkBpCC,YAlBoC;AAgCtCF,qBAAa,GAAG9C,QAAQ,CAACO,IAAD,CAAxB;AACA4C,gBAAQ,GAAGrD,WAAW,CAACS,IAAD,EAAOuC,aAAa,CAAC,YAAYC,IAAb,CAApB,CAAX,IAAsD,CAAjE;AACAK,gBAAQ,GAAGtD,WAAW,CAACS,IAAD,EAAOuC,aAAa,CAAC,YAAYE,IAAb,CAApB,CAAX,IAAsD,CAAjE;AACAN,eAAO,GAAG5C,WAAW,CAACS,IAAD,EAAOuC,aAAa,CAAC,WAAWC,IAAX,GAAkB,OAAnB,CAApB,CAAX,IAA+D,CAAzE;AACAJ,eAAO,GAAG7C,WAAW,CAACS,IAAD,EAAOuC,aAAa,CAAC,WAAWE,IAAX,GAAkB,OAAnB,CAApB,CAAX,IAA+D,CAAzE;AACAJ,uBAAe,GAAGE,aAAa,CAAC,WAAWC,IAAZ,CAA/B;AACAF,uBAAe,GAAGC,aAAa,CAAC,WAAWE,IAAZ,CAA/B,CAtCsC,CAwCtC;AACA;AACA;AACA;;AACAC,eAAO,GAAGnD,WAAW,CAACS,IAAD,EAAOqC,eAAP,CAAX,IAAsC,CAAhD;AACAM,eAAO,GAAGpD,WAAW,CAACS,IAAD,EAAOsC,eAAP,CAAX,IAAsC,CAAhD;AAEA,eAAO;AACLJ,cAAI,EAAEA,IADD;AAELc,iBAAO,EAAEJ,QAAQ,GAAGC,QAFf;AAGLI,gBAAM,EAAEd,OAAO,GAAGC,OAHb;AAILc,gBAAM,EAAER,OAAO,GAAGC;AAJb,SAAP;AAMD;;AAED,eAASU,cAAT,CAAwBrD,IAAxB,EAA8BU,SAA9B,EAAyCuB,OAAzC,EAAkD;AAChD,YAAIM,aAAJ,EAAmBjB,MAAnB;AAEA,YAAIgC,YAAY,GAAGtB,eAAe,CAAChC,IAAD,EAAOU,SAAP,CAAlC;;AAEA,YAAI4C,YAAY,CAACpB,IAAb,GAAoB,CAAxB,EAA2B;AACzB,iBAAO;AACLA,gBAAI,EAAEoB,YAAY,CAACpB,IAAb,GAAoBoB,YAAY,CAACN,OAAjC,GAA2CM,YAAY,CAACL,MADzD;AAELM,iBAAK,EAAED,YAAY,CAACpB,IAFf;AAGLsB,qBAAS,EAAEF,YAAY,CAACpB,IAAb,GAAoBoB,YAAY,CAACJ;AAHvC,YAILjB,OAJK,CAAP;AAKD,SAX+C,CAahD;;;AACAM,qBAAa,GAAG9C,QAAQ,CAACO,IAAD,CAAxB;AACAsB,cAAM,GAAGiB,aAAa,CAAC7B,SAAD,CAAtB;;AAEA,YAAIY,MAAM,GAAG,CAAT,IAAcA,MAAM,KAAK,IAA7B,EAAmC;AACjCA,gBAAM,GAAGtB,IAAI,CAACE,KAAL,CAAWQ,SAAX,KAAyB,CAAlC;AACD,SAnB+C,CAqBhD;;;AACAY,cAAM,GAAGF,UAAU,CAACE,MAAD,CAAV,IAAsB,CAA/B;AAEA,eAAO;AACLY,cAAI,EAAEZ,MAAM,GAAGgC,YAAY,CAACN,OAAtB,GAAgCM,YAAY,CAACL,MAD9C;AAELM,eAAK,EAAEjC,MAFF;AAGLkC,mBAAS,EAAElC,MAAM,GAAGgC,YAAY,CAACN,OAAtB,GAAgCM,YAAY,CAACL,MAA7C,GAAsDK,YAAY,CAACJ;AAHzE,UAILjB,OAJK,CAAP;AAKD,OAlKkB,CAoKnB;;;AACA,aAAOtC,OAAO,CAAC8D,OAAR,CAAgB;AACrBC,cADqB,kBACdC,OADc,EACL;AACd,cAAIC,QAAJ,EAAc5D,IAAd,EAAoB6D,CAApB,EAAuBC,CAAvB,EAA0BC,MAA1B,EAAkCC,GAAlC,EAAuCjE,IAAvC;AACAA,cAAI,GAAG,IAAP;AACAC,cAAI,GAAGD,IAAI,CAAC,CAAD,CAAX;AACAgE,gBAAM,GAAGhE,IAAI,CAACgE,MAAL,EAAT;AACAH,kBAAQ,GAAGG,MAAM,CAACE,QAAP,EAAX;;AACA,cAAIL,QAAQ,CAAC,CAAD,CAAR,KAAgB5D,IAApB,EAA0B;AACxB,mBAAO+D,MAAM,CAACG,OAAP,CAAeP,OAAf,CAAP;AACD,WAFD,MAEO;AACL,iBAAKE,CAAC,GAAGC,CAAC,GAAG,CAAR,EAAWE,GAAG,GAAGJ,QAAQ,CAACO,MAAT,GAAkB,CAAxC,EAA2C,KAAKH,GAAL,GAAWF,CAAC,IAAIE,GAAhB,GAAsBF,CAAC,IAAIE,GAAtE,EAA2EH,CAAC,GAAG,KAAKG,GAAL,GAAW,EAAEF,CAAb,GAAiB,EAAEA,CAAlG,EAAqG;AACnG,kBAAIF,QAAQ,CAACC,CAAD,CAAR,KAAgB7D,IAApB,EAA0B;AACxBL,uBAAO,CAACL,OAAR,CAAgBsE,QAAQ,CAACC,CAAC,GAAG,CAAL,CAAxB,EAAiCO,KAAjC,CAAuCT,OAAvC;AACA;AACD;AACF;;AACD,kBAAM,IAAIU,KAAJ,CAAU,2BAA2BrE,IAAI,CAACsE,SAA1C,CAAN;AACD;AACF,SAlBoB;AAmBrBxB,cAnBqB,kBAmBbhD,KAnBa,EAmBP;AACZ,cAAIC,IAAJ;AACAA,cAAI,GAAG,IAAP;;AACA,cAAI,OAAOD,KAAP,KAAiB,WAArB,EAAkC;AAChC,gBAAIH,OAAO,CAAC4E,QAAR,CAAiBzE,KAAjB,CAAJ,EAA6B;AAC3BA,mBAAK,GAAGA,KAAK,GAAG,IAAhB;AACD;;AACD,mBAAON,GAAG,CAACW,IAAJ,CAASJ,IAAT,EAAe,QAAf,EAAyBD,KAAzB,CAAP;AACD,WALD,MAKO;AACL,mBAAOuD,cAAc,CAAC,KAAK,CAAL,CAAD,EAAU,QAAV,EAAoB,MAApB,CAArB;AACD;AACF,SA9BoB;AA+BrBmB,mBA/BqB,uBA+BTC,MA/BS,EA+BD;AAClB,iBAAOpB,cAAc,CAAC,KAAK,CAAL,CAAD,EAAU,QAAV,EAAoBoB,MAAM,GAAG,WAAH,GAAiB,OAA3C,CAArB;AACD,SAjCoB;AAkCrBC,kBAlCqB,sBAkCVD,MAlCU,EAkCF;AACjB,iBAAOpB,cAAc,CAAC,KAAK,CAAL,CAAD,EAAU,OAAV,EAAmBoB,MAAM,GAAG,WAAH,GAAiB,OAA1C,CAArB;AACD,SApCoB;;AAsCrB;;;AAGAE,cAzCqB,kBAyCd7E,KAzCc,EAyCP;AACZ,cAAI8E,OAAJ,EAAaC,GAAb;AACA,cAAI9E,IAAI,GAAG,IAAX;AACA,cAAI+E,GAAG,GAAG;AACRnE,eAAG,EAAE,CADG;AAERC,gBAAI,EAAE;AAFE,WAAV;AAIA,cAAIZ,IAAI,GAAGD,IAAI,CAAC,CAAD,CAAf;AACA,cAAIgF,GAAG,GAAG/E,IAAI,IAAIA,IAAI,CAACgF,aAAvB;;AAEA,cAAIC,SAAS,CAACd,MAAd,EAAsB;AACpB,gBAAIrE,KAAK,KAAKoF,SAAd,EAAyB;AACvB,qBAAOnF,IAAP;AACD,aAHmB,CAIpB;;;AACA,kBAAM,IAAIsE,KAAJ,CAAU,yCAAV,CAAN;AACD;;AAED,cAAI,CAACU,GAAL,EAAU;AACR;AACD;;AAEDH,iBAAO,GAAGG,GAAG,CAAC9D,eAAd,CAtBY,CAwBZ;;AAEA,cAAIjB,IAAI,CAACmF,qBAAL,IAA8B,IAAlC,EAAwC;AACtCL,eAAG,GAAG9E,IAAI,CAACmF,qBAAL,EAAN;AACD;;AAEDN,aAAG,GAAGE,GAAG,CAACK,WAAJ,IAAmBL,GAAG,CAACM,YAA7B;AAEA,iBAAO;AACL1E,eAAG,EAAEmE,GAAG,CAACnE,GAAJ,IAAWkE,GAAG,CAACS,WAAJ,IAAmBV,OAAO,CAACW,SAAtC,KAAoDX,OAAO,CAACY,SAAR,IAAqB,CAAzE,CADA;AAEL5E,gBAAI,EAAEkE,GAAG,CAAClE,IAAJ,IAAYiE,GAAG,CAACY,WAAJ,IAAmBb,OAAO,CAACc,UAAvC,KAAsDd,OAAO,CAACe,UAAR,IAAsB,CAA5E;AAFD,WAAP;AAID,SA7EoB;AA8ErBJ,iBA9EqB,qBA8EXzF,KA9EW,EA8EJ;AACf,iBAAOW,QAAQ,CAAC,IAAD,EAAO,KAAP,EAAcX,KAAd,CAAf;AACD,SAhFoB;AAiFrB4F,kBAjFqB,sBAiFV5F,KAjFU,EAiFH;AAChB,iBAAOW,QAAQ,CAAC,IAAD,EAAO,MAAP,EAAeX,KAAf,CAAf;AACD;AAnFoB,OAAhB,EAoFJ,UAACA,KAAD,EAAQ8F,GAAR,EAAgB;AACjB,YAAI,CAACtG,OAAO,CAACM,SAAR,CAAkBgG,GAAlB,CAAL,EAA6B;AAC3B,iBAAOtG,OAAO,CAACM,SAAR,CAAkBgG,GAAlB,IAAyB9F,KAAhC;AACD;AACF,OAxFM,CAAP;AAyFD;;;;;;;;;;;;;;AC3QH,IAAM+F,cAAc,GAAG,mBAAvB;;IAEqBC,e;;;;;kCAEE;AACnB,UAAMC,QAAQ,GAAG,MAAMF,cAAvB;AACA,UAAMG,KAAK,GAAG,eAAd;AACA,UAAMC,KAAK,GAAG5F,QAAQ,CAAC6F,WAAT,CAAqB,CAArB,CAAd;AACA,UAAIC,KAAJ;;AACA,UAAI;AACFA,aAAK,GAAGF,KAAK,CAACG,QAAN,CAAejC,MAAvB;AACD,OAFD,CAEE,OAAOkC,GAAP,EAAY;AACZF,aAAK,GAAG,CAAR;AACD;;AACD,UAAG,gBAAgBF,KAAnB,EAA0B;AACxBA,aAAK,CAACK,UAAN,CAAiBP,QAAQ,GAAG,GAAX,GAAiBC,KAAjB,GAAyB,GAA1C,EAA+CG,KAA/C;AACD,OAFD,MAGK,IAAG,aAAaF,KAAhB,EAAuB;AAC1BA,aAAK,CAACM,OAAN,CAAcR,QAAd,EAAwBC,KAAxB,EAA+BG,KAA/B;AACD;AACF;;;AAED,2BAAYK,SAAZ,EAAuBC,EAAvB,EAA2B;AAAA;;AACzB,SAAKC,QAAL,GAAiBF,SAAS,CAACG,GAAV,IAAiBH,SAAS,CAACG,GAAV,CAAc,UAAd,CAAlB,GAA+CH,SAAS,CAACI,GAAV,CAAc,UAAd,CAA/C,GAA2E,IAA3F;AACA,SAAKC,2BAAL,GAAmClH,OAAO,CAACmH,OAAR,CAAgBC,KAAhB,KAA0B,CAA1B,IAA+BpH,OAAO,CAACmH,OAAR,CAAgBE,KAAhB,GAAwB,CAA1F;AACA,SAAKP,EAAL,GAAUA,EAAV;AACD;;;;gCAEWQ,O,EAAS;AACnBA,aAAO,CAAC3H,OAAR,CAAgB4H,QAAhB,CAAyBrB,cAAzB;AACD;;;gCAEWoB,O,EAAS;AACnBA,aAAO,CAAC3H,OAAR,CAAgB6H,WAAhB,CAA4BtB,cAA5B;AACD;;;kCAEauB,U,EAAYC,e,EAAiB;AACzCA,qBAAe,CAACjD,KAAhB,CAAsBgD,UAAtB;AACA,aAAO,EAAP;AACD;;;kCAEaH,O,EAAS;AACrBA,aAAO,CAAC3H,OAAR,CAAgBgI,MAAhB;AACAL,aAAO,CAACM,KAAR,CAAcC,QAAd;AACA,aAAO,EAAP;AACD;;;0CAEqBJ,U,EAAYC,e,EAAiB;AACjD,UAAI,CAAC,KAAKX,QAAV,EAAoB;AAClB,eAAO,KAAKe,aAAL,CAAmBL,UAAnB,EAA+BC,eAA/B,CAAP;AACD;;AAED,UAAI,KAAKR,2BAAT,EAAsC;AACpC,YAAMa,QAAQ,GAAG,KAAKjB,EAAL,CAAQkB,KAAR,EAAjB,CADoC,CAEpC;;AACA,aAAKjB,QAAL,CAAckB,KAAd,CAAoBR,UAApB,EAAgC,IAAhC,EAAsCC,eAAtC,EAAuD;AAAA,iBAAMK,QAAQ,CAACG,OAAT,EAAN;AAAA,SAAvD;AAEA,eAAO,CAACH,QAAQ,CAACI,OAAV,CAAP;AACD,OAXgD,CAajD;;;AACA,aAAO,CAAC,KAAKpB,QAAL,CAAckB,KAAd,CAAoBR,UAApB,EAAgC,IAAhC,EAAsCC,eAAtC,CAAD,CAAP;AACD;;;0CAEqBJ,O,EAAS;AAC7B,UAAI,CAAC,KAAKP,QAAV,EAAoB;AAClB,eAAO,KAAKqB,aAAL,CAAmBd,OAAnB,CAAP;AACD;;AAED,UAAI,KAAKJ,2BAAT,EAAsC;AACpC,YAAMa,QAAQ,GAAG,KAAKjB,EAAL,CAAQkB,KAAR,EAAjB;AACA,aAAKjB,QAAL,CAAcsB,KAAd,CAAoBf,OAAO,CAAC3H,OAA5B,EAAqC,YAAM;AACzC2H,iBAAO,CAACM,KAAR,CAAcC,QAAd;AACA,iBAAOE,QAAQ,CAACG,OAAT,EAAP;AACD,SAHD;AAKA,eAAO,CAACH,QAAQ,CAACI,OAAV,CAAP;AACD;;AAED,aAAO,CAAE,KAAKpB,QAAL,CAAcsB,KAAd,CAAoBf,OAAO,CAAC3H,OAA5B,CAAD,CAAuC2I,IAAvC,CAA4C;AAAA,eAAMhB,OAAO,CAACM,KAAR,CAAcC,QAAd,EAAN;AAAA,OAA5C,CAAD,CAAP;AACD;;;;;;;;AChFY,SAASU,YAAT,CAAsBC,eAAtB,EAAuCC,UAAvC,EAAmDC,UAAnD,EAA+DC,SAA/D,EAA0E;AACvF,MAAMC,MAAM,GAAGC,MAAM,CAACC,MAAP,CAAcC,KAAK,CAAC9I,SAApB,CAAf;AAEAD,SAAO,CAACgJ,MAAR,CAAeJ,MAAf,EAAuB;AACrBK,QAAI,EAAER,UADe;AAGrBS,SAHqB,iBAGfR,UAHe,EAGH;AAChBE,YAAM,CAACjB,MAAP,CAAc,CAAd,EAAiBiB,MAAM,CAACpE,MAAxB;AACAoE,YAAM,CAACO,GAAP,GAAa,KAAb;AACAP,YAAM,CAACQ,GAAP,GAAa,KAAb;AACAR,YAAM,CAACS,KAAP,GAAeX,UAAf;AACAE,YAAM,CAACU,IAAP,GAAcZ,UAAd;AACAE,YAAM,CAACW,QAAP,GAAkBb,UAAlB,CANgB,CAMc;;AAC9BE,YAAM,CAACY,QAAP,GAAkBd,UAAlB;AACAE,YAAM,CAACa,YAAP,GAAsB,IAAtB,CARgB,CAQY;;AAC5Bb,YAAM,CAACc,YAAP,GAAsB,IAAtB;AACD,KAboB;AAerB;AACA;AACA;AACAC,mBAAe,EAAE,SAASA,eAAT,CAAyBjB,UAAzB,EAAqC;AACpDE,YAAM,CAACjB,MAAP,CAAc,CAAd,EAAiBiB,MAAM,CAACpE,MAAxB;AACAoE,YAAM,CAACO,GAAP,GAAaP,MAAM,CAACO,GAAP,IAAcT,UAAU,IAAEE,MAAM,CAACY,QAA9C;AACAZ,YAAM,CAACQ,GAAP,GAAaR,MAAM,CAACQ,GAAP,IAAcV,UAAU,IAAEE,MAAM,CAACW,QAA9C;AACAX,YAAM,CAACS,KAAP,GAAeX,UAAf;AACAE,YAAM,CAACU,IAAP,GAAcZ,UAAd;AACD,KAxBoB;AA0BrBkB,UA1BqB,kBA0BdC,KA1Bc,EA0BP;AACZA,WAAK,CAAC/F,OAAN,CAAc,UAACgG,IAAD,EAAU;AACtB,UAAElB,MAAM,CAACU,IAAT;AACAV,cAAM,CAACmB,MAAP,CAAc,QAAd,EAAwBD,IAAxB;AACD,OAHD;AAIAlB,YAAM,CAACY,QAAP,GAAkBZ,MAAM,CAACO,GAAP,GAAaP,MAAM,CAACU,IAAP,GAAc,CAA3B,GAA+BU,IAAI,CAACC,GAAL,CAASrB,MAAM,CAACU,IAAP,GAAc,CAAvB,EAA0BV,MAAM,CAACY,QAAjC,CAAjD;AACD,KAhCoB;AAkCrBjF,WAlCqB,mBAkCbsF,KAlCa,EAkCN;AACbA,WAAK,CAACK,OAAN,GAAgBpG,OAAhB,CAAwB,UAACgG,IAAD,EAAU;AAChC,UAAElB,MAAM,CAACS,KAAT;AACAT,cAAM,CAACmB,MAAP,CAAc,SAAd,EAAyBD,IAAzB;AACD,OAHD;AAIAlB,YAAM,CAACW,QAAP,GAAkBX,MAAM,CAACQ,GAAP,GAAaR,MAAM,CAACW,QAAP,GAAkBX,MAAM,CAACS,KAAtC,GAA8CW,IAAI,CAACG,GAAL,CAASvB,MAAM,CAACS,KAAhB,EAAuBT,MAAM,CAACW,QAA9B,CAAhE;AACD,KAxCoB;;AA0CrB;;;;;;AAMAQ,UAhDqB,kBAgDdK,SAhDc,EAgDHN,IAhDG,EAgDGO,KAhDH,EAgDU;AAC7B,UAAM/C,OAAO,GAAG;AACdwC,YAAI,EAAEA;AADQ,OAAhB;;AAIA,UAAIM,SAAS,GAAG,CAAZ,KAAkB,CAAtB,EAAyB;AAAC;AACxB9C,eAAO,CAACgD,EAAR,GAAa,QAAb;AACA1B,cAAM,CAAC2B,MAAP,CAAcH,SAAd,EAAyB,CAAzB,EAA4B9C,OAA5B;;AACA,YAAG+C,KAAH,EAAU;AACRzB,gBAAM,CAACS,KAAP;AACD,SAFD,MAGK;AACHT,gBAAM,CAACU,IAAP;AACD;AACF,OATD,MASO;AACLhC,eAAO,CAACgD,EAAR,GAAaF,SAAb;;AACA,gBAAQA,SAAR;AACE,eAAK,QAAL;AACExB,kBAAM,CAAC4B,IAAP,CAAYlD,OAAZ;AACA;;AACF,eAAK,SAAL;AACEsB,kBAAM,CAAC6B,OAAP,CAAenD,OAAf;AACA;AANJ;AAQD;AACF,KAzEoB;AA2ErB;AACAK,UA5EqB,kBA4Ed+C,IA5Ec,EA4ERC,IA5EQ,EA4EF;AACjB,UAAI3K,OAAO,CAAC4E,QAAR,CAAiB8F,IAAjB,CAAJ,EAA4B;AAC1B;AACA,aAAK,IAAIxG,CAAC,GAAGwG,IAAb,EAAmBxG,CAAC,GAAGyG,IAAvB,EAA6BzG,CAAC,EAA9B,EAAkC;AAChCsE,yBAAe,CAACJ,aAAhB,CAA8BQ,MAAM,CAAC1E,CAAD,CAApC;AACD;;AACD,eAAO0E,MAAM,CAAC2B,MAAP,CAAcG,IAAd,EAAoBC,IAAI,GAAGD,IAA3B,CAAP;AACD,OAPgB,CAQjB;;;AACA9B,YAAM,CAAC2B,MAAP,CAAc3B,MAAM,CAACgC,OAAP,CAAeF,IAAf,CAAd,EAAoC,CAApC;;AACA,UAAGA,IAAI,CAACG,GAAL,KAAa,OAAb,IAAwBjC,MAAM,CAACS,KAAP,KAAiB,KAAKyB,cAAL,EAA5C,EAAmE;AACjE,aAAKC,iBAAL;AACD,OAFD,MAGK;AACH,aAAKC,iBAAL;AACD;;AACD,UAAGN,IAAI,CAACG,GAAL,KAAa,OAAhB,EAAyB;AACvBjC,cAAM,CAACS,KAAP;AACD,OAFD,MAGK;AACHT,cAAM,CAACU,IAAP;AACD;;AACD,UAAG,CAACV,MAAM,CAACpE,MAAX,EAAmB;AACjBoE,cAAM,CAACS,KAAP,GAAeT,MAAM,CAACW,QAAP,GAAgB,CAAhB,GAAoBX,MAAM,CAACW,QAA3B,GAAsCb,UAArD;AACAE,cAAM,CAACU,IAAP,GAAcV,MAAM,CAACS,KAArB;AACAT,cAAM,CAACO,GAAP,GAAaP,MAAM,CAACO,GAAP,IAAcP,MAAM,CAACS,KAAP,IAAcT,MAAM,CAACY,QAAhD;AACD;;AAED,aAAOhB,eAAe,CAACyC,qBAAhB,CAAsCP,IAAtC,CAAP;AACD,KAzGoB;AA2GrBK,qBA3GqB,+BA2GD;AAClB,UAAGnC,MAAM,CAACa,YAAP,KAAwB,IAA3B,EAAiC;AAC/B,YAAGb,MAAM,CAACW,QAAP,GAAkBX,MAAM,CAACa,YAA5B,EAA0C;AACxCb,gBAAM,CAACa,YAAP;AACA;AACD;;AACD,YAAGb,MAAM,CAACW,QAAP,KAAoBX,MAAM,CAACa,YAA9B,EAA4C;AAC1Cb,gBAAM,CAACa,YAAP;AACD;AACF;;AACDb,YAAM,CAACW,QAAP;AACD,KAtHoB;AAwHrByB,qBAxHqB,+BAwHD;AAClB,UAAGpC,MAAM,CAACc,YAAP,KAAwB,IAAxB,IAAgCd,MAAM,CAACY,QAAP,IAAmBZ,MAAM,CAACc,YAA7D,EAA2E;AACzEd,cAAM,CAACc,YAAP;AACD;;AACDd,YAAM,CAACY,QAAP;AACD,KA7HoB;AA+HrBsB,kBA/HqB,4BA+HJ;AACf,UAAGlC,MAAM,CAACa,YAAP,KAAwB,IAA3B,EAAiC;AAC/B,eAAOO,IAAI,CAACG,GAAL,CAASvB,MAAM,CAACa,YAAhB,EAA8Bb,MAAM,CAACW,QAArC,CAAP;AACD;;AACD,aAAOX,MAAM,CAACW,QAAd;AACD,KApIoB;AAsIrB2B,kBAtIqB,4BAsIJ;AACf,UAAGtC,MAAM,CAACc,YAAP,KAAwB,IAA3B,EAAiC;AAC/B,eAAOM,IAAI,CAACC,GAAL,CAASrB,MAAM,CAACc,YAAhB,EAA8Bd,MAAM,CAACY,QAArC,CAAP;AACD;;AACD,aAAOZ,MAAM,CAACY,QAAd;AACD,KA3IoB;AA6IrB2B,mBA7IqB,2BA6ILC,QA7IK,EA6IK;AACxB,UAAI,CAACA,QAAQ,CAAC5G,MAAd,EAAsB;AACpB,eAAO,CAAP;AACD;;AACD,UAAIxD,GAAG,GAAGqK,MAAM,CAACC,SAAjB;AACA,UAAIC,MAAM,GAAGF,MAAM,CAACG,iBAApB;AACAJ,cAAQ,CAACtH,OAAT,CAAiB,UAACwD,OAAD,EAAa;AAC5B,YAAIA,OAAO,CAAC3H,OAAR,CAAgB,CAAhB,EAAmB8L,YAAvB,EAAqC;AACnC;AACAzK,aAAG,GAAGgJ,IAAI,CAACG,GAAL,CAASnJ,GAAT,EAAcsG,OAAO,CAAC3H,OAAR,CAAgBqF,MAAhB,GAAyBhE,GAAvC,CAAN;AACAuK,gBAAM,GAAGvB,IAAI,CAACC,GAAL,CAASsB,MAAT,EAAiBjE,OAAO,CAAC3H,OAAR,CAAgBqF,MAAhB,GAAyBhE,GAAzB,IAAgC2H,SAAS,IAAIrB,OAAO,CAAC3H,OAAR,CAAgBkF,WAAhB,CAA4B,IAA5B,CAA7C,CAAjB,CAAT;AACD;AACF,OAND;AAOA,aAAOmF,IAAI,CAACC,GAAL,CAAS,CAAT,EAAYsB,MAAM,GAAGvK,GAArB,CAAP;AACD,KA3JoB;AA6JrB0K,YA7JqB,sBA6JV;AACT,aAAO9C,MAAM,CAAC+C,MAAP,CAAc,UAAA7B,IAAI;AAAA,eAAIA,IAAI,CAACQ,EAAL,KAAY,MAAhB;AAAA,OAAlB,CAAP;AACD,KA/JoB;AAiKrBsB,gBAjKqB,0BAiKN;AACb,UAAMC,IAAI,GAAGjD,MAAM,CAAC8C,QAAP,EAAb;;AACA,UAAI,CAACG,IAAI,CAACrH,MAAV,EAAkB;AAChB,eAAO,IAAP;AACD;;AACD,aAAOqH,IAAI,CAAC,CAAD,CAAJ,CAAQ/B,IAAf;AACD,KAvKoB;AAyKrBgC,eAzKqB,yBAyKP;AACZ,UAAMD,IAAI,GAAGjD,MAAM,CAAC8C,QAAP,EAAb;;AACA,UAAI,CAACG,IAAI,CAACrH,MAAV,EAAkB;AAChB,eAAO,IAAP;AACD;;AACD,aAAOqH,IAAI,CAACA,IAAI,CAACrH,MAAL,GAAc,CAAf,CAAJ,CAAsBsF,IAA7B;AACD;AA/KoB,GAAvB;AAmLAlB,QAAM,CAACM,KAAP,CAAaR,UAAb;AAEA,SAAOE,MAAP;AACD,C;;;;;;;;ACzLD;AACA;IACMmD,U;;;;;;;;;wBACAjC,I,EAAM;AACR,WAAK,IAAI5F,CAAC,GAAG,KAAKM,MAAL,GAAc,CAA3B,EAA8BN,CAAC,IAAI,CAAnC,EAAsCA,CAAC,EAAvC,EAA2C;AACzC,YAAI,KAAKA,CAAL,EAAQsC,KAAR,KAAkBsD,IAAI,CAAClC,KAAL,CAAWoE,MAAjC,EAAyC;AACvC,eAAK9H,CAAL,EAAQf,MAAR,GAAiB2G,IAAI,CAACnK,OAAL,CAAakF,WAAb,EAAjB;AACA;AACD;AACF;;AACD,WAAK2F,IAAL,CAAU;AACRhE,aAAK,EAAEsD,IAAI,CAAClC,KAAL,CAAWoE,MADV;AAER7I,cAAM,EAAE2G,IAAI,CAACnK,OAAL,CAAakF,WAAb;AAFA,OAAV;AAIA,WAAKoH,IAAL,CAAU,UAACC,CAAD,EAAIC,CAAJ;AAAA,eAAYD,CAAC,CAAC1F,KAAF,GAAU2F,CAAC,CAAC3F,KAAb,GAAsB,CAAC,CAAvB,GAA6B0F,CAAC,CAAC1F,KAAF,GAAU2F,CAAC,CAAC3F,KAAb,GAAsB,CAAtB,GAA0B,CAAjE;AAAA,OAAV;AACD;;;2BAEM4F,Q,EAAUC,M,EAAQ;AACvB,UAAM7F,KAAK,GAAG4F,QAAQ,GAAG,CAAX,KAAiB,CAAjB,GAAqBA,QAArB,GAAgCA,QAAQ,CAACxE,KAAT,CAAeoE,MAA7D;AACA,UAAM3B,KAAK,GAAG+B,QAAQ,GAAG,CAAX,KAAiB,CAAjB,GAAqBC,MAArB,GAA8BD,QAAQ,CAACvB,GAAT,KAAiB,OAA7D;;AACA,WAAK,IAAI3G,CAAC,GAAG,KAAKM,MAAL,GAAc,CAA3B,EAA8BN,CAAC,IAAI,CAAnC,EAAsCA,CAAC,EAAvC,EAA2C;AACzC,YAAI,KAAKA,CAAL,EAAQsC,KAAR,KAAkBA,KAAtB,EAA6B;AAC3B,eAAK+D,MAAL,CAAYrG,CAAZ,EAAe,CAAf;AACA;AACD;AACF;;AACD,UAAG,CAACmG,KAAJ,EAAW;AACT,aAAK,IAAInG,EAAC,GAAG,KAAKM,MAAL,GAAc,CAA3B,EAA8BN,EAAC,IAAI,CAAnC,EAAsCA,EAAC,EAAvC,EAA2C;AACzC,cAAI,KAAKA,EAAL,EAAQsC,KAAR,GAAgBA,KAApB,EAA2B;AACzB,iBAAKtC,EAAL,EAAQsC,KAAR;AACD;AACF;AACF;AACF;;;4BAEO;AACN,WAAKhC,MAAL,GAAc,CAAd;AACD;;;;;;AAGH,SAAS8H,KAAT,GAAiB;AACf,MAAMC,QAAQ,GAAG,EAAjB;AACAA,UAAQ,CAAC/B,IAAT,CAAcgC,KAAd,CAAoBD,QAApB,EAA8BjH,SAA9B;AACAuD,QAAM,CAAC4D,cAAP,CAAsBF,QAAtB,EAAgCD,KAAK,CAACrM,SAAtC;AACA,SAAOsM,QAAP;AACD;;AACDD,KAAK,CAACrM,SAAN,GAAkB4I,MAAM,CAACC,MAAP,CAAcC,KAAK,CAAC9I,SAApB,CAAlB;AACA4I,MAAM,CAAC6D,mBAAP,CAA2BX,UAAU,CAAC9L,SAAtC,EAAiD6D,OAAjD,CAAyD,UAAA6I,UAAU;AAAA,SACjEL,KAAK,CAACrM,SAAN,CAAgB0M,UAAhB,IAA8BZ,UAAU,CAAC9L,SAAX,CAAqB0M,UAArB,CADmC;AAAA,CAAnE;;AAIA,SAASC,eAAT,CAAyBC,QAAzB,EAAmC;AACjC,MAAGA,QAAQ,CAACvM,QAAT,KAAsBwM,IAAI,CAACC,YAA9B,EAA4C;AAC1C,UAAM,IAAIrI,KAAJ,CAAU,sEAAV,CAAN;AACD;;AACD,MAAI/E,OAAJ;;AACA,UAAQkN,QAAQ,CAACG,OAAT,CAAiBC,WAAjB,EAAR;AACE,SAAK,IAAL;AACE,YAAM,IAAIvI,KAAJ,iDAAmDmI,QAAQ,CAACG,OAA5D,mCAA4FH,QAAQ,CAAClI,SAArG,EAAN;;AACF,SAAK,IAAL;AACE,UAAIuI,KAAK,GAAGlN,OAAO,CAACL,OAAR,CAAgB,8CAAhB,CAAZ;AACAA,aAAO,GAAGuN,KAAK,CAACC,IAAN,CAAW,IAAX,CAAV;AACA;;AACF,SAAK,IAAL;AACExN,aAAO,GAAGK,OAAO,CAACL,OAAR,CAAgB,WAAhB,CAAV;AACA;;AACF;AACEA,aAAO,GAAGK,OAAO,CAACL,OAAR,CAAgB,aAAhB,CAAV;AAXJ;;AAaA,SAAOA,OAAP;AACD,C,CAED;AACA;AACA;AACA;AACA;;;IACMyN,O;;;AACJ,mBAAYP,QAAZ,EAAqBQ,QAArB,EAA+B;AAAA;;AAC7B,SAAK1N,OAAL,GAAeiN,eAAe,CAACC,QAAD,CAA9B;;AACA,QAAGQ,QAAH,EAAa;AACX,WAAKC,KAAL,GAAa,IAAIhB,KAAJ,EAAb;AACD;AACF;;;;6BAEQ;AACP;AACA,aAAO,KAAK3M,OAAL,CAAawD,MAAb,CAAoBqJ,KAApB,CAA0B,KAAK7M,OAA/B,EAAwC2F,SAAxC,CAAP;AACD;;;;;;AAGY8H,2DAAf,E;;AC3FA;AAEe,SAASG,QAAT,CAAkB/E,eAAlB,EAAmCI,MAAnC,EAA2CjJ,OAA3C,EAAoD6N,kBAApD,EAAwEC,UAAxE,EAAoFpK,OAApF,EAA6FsF,SAA7F,EAAwG;AACrH,MAAI+E,UAAU,GAAG,IAAjB;AACA,MAAIC,aAAa,GAAG,IAApB;AACA,MAAMC,QAAQ,GAAGJ,kBAAkB,IAAIA,kBAAkB,CAACI,QAAzC,GAAoDJ,kBAAkB,CAACI,QAAvE,GAAkF5N,OAAO,CAACL,OAAR,CAAgB4B,MAAhB,CAAnG;AACA,MAAMsM,SAAS,GAAGL,kBAAkB,IAAIA,kBAAkB,CAACK,SAAzC,GAAqDL,kBAAkB,CAACK,SAAxE,GAAoFtI,SAAtG;AACA,MAAMqC,KAAK,GAAG4F,kBAAkB,IAAIA,kBAAkB,CAAC5F,KAAzC,GAAiD4F,kBAAkB,CAAC5F,KAApE,GAA4E6F,UAA1F;AAEAG,UAAQ,CAAC/N,GAAT,CAAa;AACX,uBAAmB,MADR;AAEX,kBAAc,MAFH;AAGX,eAAW;AAHA,GAAb;;AAMA,WAASiO,aAAT,GAAyB;AACvB,WAAOF,QAAQ,CAAC/I,WAAT,KAAyBxB,OAAhC,CADuB,CACkB;AAC1C,GAfoH,CAiBrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGArD,SAAO,CAACgJ,MAAR,CAAe4E,QAAf,EAAyB;AACvBG,YADuB,sBACZ;AACT,aAAOnG,KAAP;AACD,KAHsB;AAKvBoG,yBALuB,iCAKDnB,QALC,EAKS;AAC9Ba,gBAAU,GAAG,IAAIN,eAAJ,CAAYP,QAAZ,EAAqB,CAAClE,SAAtB,CAAb;AACAgF,mBAAa,GAAG,IAAIP,eAAJ,CAAYP,QAAZ,EAAqB,CAAClE,SAAtB,CAAhB;AACAhJ,aAAO,CAACoE,MAAR,CAAe2J,UAAU,CAAC/N,OAA1B;AACAA,aAAO,CAAC8E,KAAR,CAAckJ,aAAa,CAAChO,OAA5B;AACA+N,gBAAU,CAACvK,MAAX,CAAkB,CAAlB;AACAwK,mBAAa,CAACxK,MAAd,CAAqB,CAArB;AACD,KAZsB;AAcvB8K,uBAduB,iCAcD;AACpB,UAAI,CAACJ,SAAL,EAAgB;AACd,eAAO,IAAP;AACD;;AACD,UAAGA,SAAS,KAAKD,QAAjB,EAA2B;AACzBA,gBAAQ,CAAC/N,GAAT,CAAa,QAAb,EAAuB0B,MAAM,CAACC,gBAAP,CAAwBqM,SAAS,CAAC,CAAD,CAAjC,EAAsC1K,MAA7D;AACD;;AACD,aAAOyK,QAAQ,CAACzK,MAAT,KAAoB,CAA3B;AACD,KAtBsB;AAwBvB+K,iBAxBuB,2BAwBP;AACd,UAAIC,YAAY,GAAGP,QAAQ,CAAC,CAAD,CAAR,CAAYO,YAA/B;AACAA,kBAAY,GAAGA,YAAY,IAAI,IAAhB,GAAuBA,YAAvB,GAAsCP,QAAQ,CAAC,CAAD,CAAR,CAAYlN,QAAZ,CAAqBY,eAArB,CAAqC6M,YAA1F;AACA,aAAOA,YAAY,GAAGR,aAAa,CAACxK,MAAd,EAAtB;AACD,KA5BsB;AA8BvBiL,cA9BuB,wBA8BV;AACX,aAAOV,UAAU,CAACvK,MAAX,EAAP;AACD,KAhCsB;AAkCvBkL,oBAlCuB,8BAkCJ;AACjB,aAAOT,QAAQ,CAAChI,SAAT,KAAuBgI,QAAQ,CAAC/I,WAAT,EAA9B;AACD,KApCsB;AAsCvByJ,iBAtCuB,2BAsCP;AACd,aAAOV,QAAQ,CAAChI,SAAT,EAAP;AACD,KAxCsB;AA0CvBkC,iBA1CuB,yBA0CTyG,CA1CS,EA0CNC,OA1CM,EA0CG;AACxB,aAAOhG,eAAe,CAACV,aAAhB,CAA8ByG,CAA9B,EAAiCC,OAAO,IAAId,UAAU,CAAC/N,OAAvD,CAAP;AACD,KA5CsB;AA8CvB8O,yBA9CuB,iCA8CDF,CA9CC,EA8CEC,OA9CF,EA8CW;AAChC,aAAOhG,eAAe,CAACiG,qBAAhB,CAAsCF,CAAtC,EAAyCC,OAAO,IAAId,UAAU,CAAC/N,OAA/D,CAAP;AACD,KAhDsB;AAkDvB+O,oBAlDuB,8BAkDJ;AACjB,aAAO,CAAC9F,MAAM,CAACO,GAAR,IAAeyE,QAAQ,CAACM,aAAT,KAA2BN,QAAQ,CAACS,gBAAT,KAA8BP,aAAa,EAA5F;AACD,KApDsB;AAsDvBa,cAtDuB,wBAsDV;AACX;AACA,UAAIC,OAAO,GAAG,CAAd;AACA,UAAIC,gBAAgB,GAAGjB,QAAQ,CAACM,aAAT,KAA2BN,QAAQ,CAACS,gBAAT,EAA3B,GAAyDP,aAAa,EAA7F;;AACA,UAAGnF,SAAH,EAAc;AACZiG,eAAO,GAAG5E,IAAI,CAACG,GAAL,CAASvB,MAAM,CAACpE,MAAhB,EAAuBwF,IAAI,CAAC8E,KAAL,CAAWD,gBAAgB,GAAClG,SAA5B,CAAvB,CAAV;AACD,OAFD,MAEO;AACL,YAAIoG,UAAU,GAAG,CAAjB;AACA,YAAIC,aAAa,GAAG,CAApB;;AAEA,aAAK,IAAI9K,CAAC,GAAG0E,MAAM,CAACpE,MAAP,GAAgB,CAA7B,EAAgCN,CAAC,IAAI,CAArC,EAAwCA,CAAC,EAAzC,EAA6C;AAC3C6K,oBAAU,GAAGnG,MAAM,CAAC1E,CAAD,CAAN,CAAUvE,OAAV,CAAkBkF,WAAlB,CAA8B,IAA9B,CAAb;;AACA,cAAImK,aAAa,GAAGD,UAAhB,GAA6BF,gBAAjC,EAAmD;AACjD;AACD;;AACDlB,uBAAa,CAACL,KAAd,CAAoB2B,GAApB,CAAwBrG,MAAM,CAAC1E,CAAD,CAA9B;AACA8K,uBAAa,IAAID,UAAjB;AACAH,iBAAO;AACR;AACF;;AAED,UAAIA,OAAO,GAAG,CAAd,EAAiB;AACfhG,cAAM,CAACO,GAAP,GAAa,KAAb;AACAP,cAAM,CAACjB,MAAP,CAAciB,MAAM,CAACpE,MAAP,GAAgBoK,OAA9B,EAAuChG,MAAM,CAACpE,MAA9C;AACAoE,cAAM,CAACU,IAAP,IAAesF,OAAf;AACAhB,gBAAQ,CAACsB,cAAT;AACD;AACF,KAjFsB;AAmFvBC,iBAnFuB,2BAmFP;AACd,aAAO,CAACvG,MAAM,CAACQ,GAAR,IAAgBwE,QAAQ,CAACQ,UAAT,KAAwBR,QAAQ,CAACU,aAAT,KAA2BR,aAAa,EAAvF;AACD,KArFsB;AAuFvBsB,WAvFuB,qBAuFb;AACR;AACA,UAAIR,OAAO,GAAG,CAAd;AACA,UAAII,aAAa,GAAG,CAApB;AACA,UAAIH,gBAAgB,GAAGjB,QAAQ,CAACU,aAAT,KAA2BV,QAAQ,CAACQ,UAAT,EAA3B,GAAmDN,aAAa,EAAvF;;AACA,UAAGnF,SAAH,EAAc;AACZiG,eAAO,GAAG5E,IAAI,CAACG,GAAL,CAASvB,MAAM,CAACpE,MAAhB,EAAuBwF,IAAI,CAAC8E,KAAL,CAAWD,gBAAgB,GAAClG,SAA5B,CAAvB,CAAV;AACAqG,qBAAa,GAAGJ,OAAO,GAAGjG,SAA1B;AACD,OAHD,MAGO;AACL,YAAIoG,UAAU,GAAG,CAAjB;;AAEA,aAAK,IAAI7K,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG0E,MAAM,CAACpE,MAA3B,EAAmCN,CAAC,EAApC,EAAwC;AACtC6K,oBAAU,GAAGnG,MAAM,CAAC1E,CAAD,CAAN,CAAUvE,OAAV,CAAkBkF,WAAlB,CAA8B,IAA9B,CAAb;;AACA,cAAImK,aAAa,GAAGD,UAAhB,GAA6BF,gBAAjC,EAAmD;AACjD;AACD;;AACDnB,oBAAU,CAACJ,KAAX,CAAiB2B,GAAjB,CAAqBrG,MAAM,CAAC1E,CAAD,CAA3B;AACA8K,uBAAa,IAAID,UAAjB;AACAH,iBAAO;AACR;AACF;;AAED,UAAIA,OAAO,GAAG,CAAd,EAAiB;AACf;AACA;AACAlB,kBAAU,CAACvK,MAAX,CAAkBuK,UAAU,CAACvK,MAAX,KAAsB6L,aAAxC;AACApG,cAAM,CAACQ,GAAP,GAAa,KAAb;AACAR,cAAM,CAACjB,MAAP,CAAc,CAAd,EAAiBiH,OAAjB;AACAhG,cAAM,CAACS,KAAP,IAAgBuF,OAAhB;AACD;AACF,KArHsB;AAuHvB;AACA;AACA;AACA9N,YA1HuB,oBA0HduI,KA1Hc,EA0HP;AACd,UAAGV,SAAH,EAAc;AACZ,YAAMwB,GAAG,GAAGvB,MAAM,CAACkC,cAAP,EAAZ;AACA,YAAMb,GAAG,GAAGrB,MAAM,CAACsC,cAAP,EAAZ;AACA7B,aAAK,GAAGW,IAAI,CAACG,GAAL,CAASH,IAAI,CAACC,GAAL,CAASZ,KAAT,EAAgBc,GAAhB,CAAT,EAA8BF,GAA9B,CAAR,CAHY,CAIZ;;AACAyD,kBAAU,CAACvK,MAAX,CAAkB,CAACkG,KAAK,GAACc,GAAP,IAAYxB,SAA9B;AACAgF,qBAAa,CAACxK,MAAd,CAAqB,CAAE8G,GAAG,GAAC,CAAL,GAAQZ,KAAT,IAAgBV,SAArC;AACAC,cAAM,CAACe,eAAP,CAAuBN,KAAvB;AACD,OARD,MAQO;AACLT,cAAM,CAACe,eAAP,CAAuBN,KAAvB;AACAuE,gBAAQ,CAACsB,cAAT;AACD;AACF,KAvIsB;AAyIvBA,kBAzIuB,4BAyIN;AACf,UAAGvG,SAAH,EAAc;AACZ,YAAMwB,GAAG,GAAGvB,MAAM,CAACkC,cAAP,EAAZ;AACA,YAAMb,GAAG,GAAGrB,MAAM,CAACsC,cAAP,EAAZ;AACAwC,kBAAU,CAACvK,MAAX,CAAkB,CAACyF,MAAM,CAACS,KAAP,GAAac,GAAd,IAAmBxB,SAArC,EAHY,CAIZ;AACA;AACA;AACA;;AACAgF,qBAAa,CAACxK,MAAd,CAAqB,CAAE8G,GAAG,GAAC,CAAL,GAAQrB,MAAM,CAACU,IAAhB,IAAsBX,SAA3C;AACA;AACD;;AAED,UAAI,CAACC,MAAM,CAACpE,MAAZ,EAAoB;AAClB;AACD,OAfc,CAiBf;;;AACA,UAAM6K,kBAAkB,GAAGzG,MAAM,CAAC0G,MAAP,CAAc,UAACC,IAAD,EAAOzF,IAAP;AAAA,eAAgByF,IAAI,GAAGzF,IAAI,CAACnK,OAAL,CAAakF,WAAb,CAAyB,IAAzB,CAAvB;AAAA,OAAd,EAAqE,CAArE,CAA3B;AACA,UAAI2K,gBAAgB,GAAG,CAAvB;AAAA,UAA0BC,QAAQ,GAAG,CAArC;AACA/B,gBAAU,CAACJ,KAAX,CAAiBxJ,OAAjB,CAAyB,UAAAgG,IAAI,EAAI;AAC/B,YAAGA,IAAI,CAACtD,KAAL,GAAaoC,MAAM,CAACS,KAAvB,EAA8B;AAC5BmG,0BAAgB,IAAI1F,IAAI,CAAC3G,MAAzB;AACAsM,kBAAQ;AACT;AACF,OALD;AAOA,UAAIC,mBAAmB,GAAG,CAA1B;AAAA,UAA6BC,WAAW,GAAG,CAA3C;AACAhC,mBAAa,CAACL,KAAd,CAAoBxJ,OAApB,CAA4B,UAAAgG,IAAI,EAAI;AAClC,YAAGA,IAAI,CAACtD,KAAL,IAAcoC,MAAM,CAACU,IAAxB,EAA8B;AAC5BoG,6BAAmB,IAAI5F,IAAI,CAAC3G,MAA5B;AACAwM,qBAAW;AACZ;AACF,OALD;AAOA,UAAMC,WAAW,GAAGP,kBAAkB,GAAGG,gBAArB,GAAwCE,mBAA5D;AACA,UAAMG,iBAAiB,GAAGD,WAAW,IAAIH,QAAQ,GAAGE,WAAX,GAAyB/G,MAAM,CAACpE,MAApC,CAArC,CApCe,CAsCf;;AACA,UAAIsL,gBAAgB,GAAGlH,MAAM,CAACa,YAAP,KAAwB,IAAxB,IAAgCb,MAAM,CAACW,QAAP,GAAkBX,MAAM,CAACa,YAAhF;AACA,UAAIsG,mBAAmB,GAAGnH,MAAM,CAACc,YAAP,KAAwB,IAAxB,IAAgCd,MAAM,CAACY,QAAP,GAAkBZ,MAAM,CAACc,YAAnF;AACA,UAAIsG,mBAAmB,GAAGF,gBAAgB,GAAG,CAAClH,MAAM,CAACW,QAAP,GAAkBX,MAAM,CAACa,YAA1B,IAA0CoG,iBAA7C,GAAiE,CAA3G;AACA,UAAII,sBAAsB,GAAGF,mBAAmB,GAAG,CAACnH,MAAM,CAACc,YAAP,GAAsBd,MAAM,CAACY,QAA9B,IAA0CqG,iBAA7C,GAAiE,CAAjH,CA1Ce,CA4Cf;;AACAnC,gBAAU,CAACvK,MAAX,CAAkBqM,gBAAgB,GAAGQ,mBAArC;AACArC,mBAAa,CAACxK,MAAd,CAAqBuM,mBAAmB,GAAGO,sBAA3C;AACD,KAxLsB;AA0LvBC,sBA1LuB,8BA0LJC,mBA1LI,EA0LiB;AACtC;AACA,UAAIvH,MAAM,CAACa,YAAP,KAAwB,IAAxB,IAAgCb,MAAM,CAACW,QAAP,GAAkBX,MAAM,CAACa,YAA7D,EAA2E;AACzE,YAAI2G,IAAI,GAAG1C,UAAU,CAACvK,MAAX,KAAsBgN,mBAAjC;AACAvC,gBAAQ,CAAChI,SAAT,CAAmBgI,QAAQ,CAAChI,SAAT,KAAuBwK,IAA1C;;AACA,eAAM,CAACA,IAAI,IAAIxC,QAAQ,CAAChI,SAAT,EAAT,IAAiC,CAAvC,EAA0C;AACxC+H,uBAAa,CAACxK,MAAd,CAAqBwK,aAAa,CAACxK,MAAd,KAAyBiN,IAA9C;AACAxC,kBAAQ,CAAChI,SAAT,CAAmBgI,QAAQ,CAAChI,SAAT,KAAuBwK,IAA1C;AACD;AACF;AACF,KApMsB;AAsMvBC,kBAtMuB,0BAsMRC,OAtMQ,EAsMC;AACtB,UAAI,CAACA,OAAO,CAACC,SAAR,CAAkB/L,MAAvB,EACE;AACF,UAAMrB,MAAM,GAAGyF,MAAM,CAACuC,eAAP,CAAuBmF,OAAO,CAACC,SAA/B,CAAf;AACA,UAAMC,aAAa,GAAG9C,UAAU,CAACvK,MAAX,KAAsBA,MAA5C;;AACA,UAAIqN,aAAa,IAAI,CAArB,EAAwB;AACtB9C,kBAAU,CAACvK,MAAX,CAAkBqN,aAAlB;AACD,OAFD,MAGK;AACH9C,kBAAU,CAACvK,MAAX,CAAkB,CAAlB;AACAyK,gBAAQ,CAAChI,SAAT,CAAmBgI,QAAQ,CAAChI,SAAT,KAAuB4K,aAA1C;AACD;AACF,KAlNsB;AAoNvBC,mBApNuB,6BAoNL;AAChB/C,gBAAU,CAACvK,MAAX,CAAkB,CAAlB;;AACA,UAAGuK,UAAU,CAACJ,KAAd,EAAqB;AACnBI,kBAAU,CAACJ,KAAX,CAAiBoD,KAAjB;AACD;AACF,KAzNsB;AA2NvBC,sBA3NuB,gCA2NF;AACnBhD,mBAAa,CAACxK,MAAd,CAAqB,CAArB;;AACA,UAAGwK,aAAa,CAACL,KAAjB,EAAwB;AACtBK,qBAAa,CAACL,KAAd,CAAoBoD,KAApB;AACD;AACF,KAhOsB;AAkOvBE,mBAlOuB,2BAkOP9G,IAlOO,EAkODO,KAlOC,EAkOM;AAC3B,UAAGqD,UAAU,CAACJ,KAAd,EAAqB;AACnBI,kBAAU,CAACJ,KAAX,CAAiB3F,MAAjB,CAAwBmC,IAAxB,EAA8BO,KAA9B;AACD;;AACD,UAAGsD,aAAa,CAACL,KAAjB,EAAwB;AACtBK,qBAAa,CAACL,KAAd,CAAoB3F,MAApB,CAA2BmC,IAA3B,EAAiCO,KAAjC;AACD;AACF,KAzOsB;AA2OvBwG,cA3OuB,sBA2OZ/G,IA3OY,EA2ON;AACf,WAAK8G,eAAL,CAAqB9G,IAArB;AACA,aAAOlB,MAAM,CAACjB,MAAP,CAAcmC,IAAd,CAAP;AACD;AA9OsB,GAAzB;AAiPA,SAAO8D,QAAP;AACD,C;;;;;;;;ICjSKkD,O;;;AAEJ,mBAAYC,MAAZ,EAAoBC,MAApB,EAA4BC,KAA5B,EAAmCrD,QAAnC,EAA6ChF,MAA7C,EAAqDsI,QAArD,EAA+DC,MAA/D,EAAuE;AAAA;;AACrE,SAAKH,MAAL,GAAcA,MAAd;AACA,SAAKC,KAAL,GAAaA,KAAb;AACA,SAAKrD,QAAL,GAAgBA,QAAhB;AACA,SAAKhF,MAAL,GAAcA,MAAd;AAEA,SAAKsI,QAAL,GAAgBA,QAAhB;AACA,SAAKC,MAAL,GAAcA,MAAd;AAEA,SAAKC,SAAL,GAAiB,KAAjB;AACA,SAAKC,QAAL,GAAgB,KAAhB;AAEA,QAAMC,aAAa,GAAG1D,QAAQ,CAACG,QAAT,EAAtB;AACA,SAAKwD,UAAL,GAAkBD,aAAa,CAACE,OAAd,GAAwBF,aAAxB,GAAwCP,MAA1D;AAEA,SAAKU,aAAL,GAAqB,EAArB;AACA,SAAKC,aAAL,CAAmBT,KAAK,CAACU,OAAzB;AACA,SAAKC,qBAAL;AACD;;;;kCAEaC,W,EAAa;AACzB,UAAI,CAACA,WAAD,IAAgB,EAAEA,WAAW,GAAGA,WAAW,CAACC,OAAZ,CAAoB,aAApB,EAAmC,EAAnC,CAAhB,CAApB,EAA6E;AAC3E;AACD;;AACD,UAAIC,cAAJ;;AAEA,UAAI;AACF,aAAKf,MAAL,CAAYa,WAAZ,EAAyBG,MAAzB,CAAgC,KAAKT,UAArC,EAAiD,EAAjD;AACAQ,sBAAc,GAAG,KAAKf,MAAL,CAAYa,WAAZ,EAAyB,KAAKN,UAA9B,CAAjB;AACD,OAHD,CAIA,OAAOU,KAAP,EAAc;AACZA,aAAK,CAACC,OAAN,GAAgB,8EACEL,WADF,wBAEdI,KAAK,CAACC,OAFR;AAGA,cAAMD,KAAN;AACD;;AAEDjS,aAAO,CAACgJ,MAAR,CAAe+I,cAAf,EAA+B,KAAKN,aAApC;AACA,WAAKA,aAAL,GAAqBM,cAArB;AACD;;;4CAEuB;AAAA;;AACtB;AACA,UAAMI,aAAa,GAAG,CAAC,QAAD,EAAW,cAAX,EAA2B,QAA3B,EAAqC,SAArC,EAAgD,OAAhD,EAAyD,OAAzD,EAAkE,SAAlE,CAAtB;;AACA,WAAK,IAAIjO,CAAC,GAAGiO,aAAa,CAAC3N,MAAd,GAAuB,CAApC,EAAuCN,CAAC,IAAI,CAA5C,EAA+CA,CAAC,EAAhD,EAAoD;AAClD,aAAKuN,aAAL,CAAmBU,aAAa,CAACjO,CAAD,CAAhC,IAAuC,KAAKiO,aAAa,CAACjO,CAAD,CAAlB,EAAuBkO,IAAvB,CAA4B,IAA5B,CAAvC;AACD,OALqB,CAOtB;;;AACA,UAAMC,WAAW,GAAG,CAAC,WAAD,EAAc,YAAd,EAA4B,mBAA5B,EAAiD,iBAAjD,EAAoE,eAApE,EAAqF,sBAArF,EAA6G,oBAA7G,CAApB;;AARsB,iCASbnO,EATa;AAUpB,YAAIoO,QAAQ,SAAZ;AAAA,YAAcC,IAAI,GAAG,KAAI,CAACtB,KAAL,CAAWoB,WAAW,CAACnO,EAAD,CAAtB,CAArB;AACA2E,cAAM,CAAC2J,cAAP,CAAsB,KAAtB,EAA4BH,WAAW,CAACnO,EAAD,CAAvC,EAA4C;AAC1C+C,aAAG,EAAE;AAAA,mBAAMqL,QAAN;AAAA,WADqC;AAE1CG,aAAG,EAAE,aAACtS,KAAD,EAAW;AACdmS,oBAAQ,GAAGnS,KAAX;AACA,iBAAI,CAACsR,aAAL,CAAmBY,WAAW,CAACnO,EAAD,CAA9B,IAAqC/D,KAArC;;AACA,gBAAIoS,IAAJ,EAAU;AACR,mBAAI,CAACvB,MAAL,CAAYuB,IAAZ,EAAkBP,MAAlB,CAAyB,KAAI,CAACT,UAA9B,EAA0CpR,KAA1C;AACD;AACF;AARyC,SAA5C;AAXoB;;AAStB,WAAK,IAAI+D,EAAC,GAAGmO,WAAW,CAAC7N,MAAZ,GAAqB,CAAlC,EAAqCN,EAAC,IAAI,CAA1C,EAA6CA,EAAC,EAA9C,EAAkD;AAAA,cAAzCA,EAAyC;AAYjD,OArBqB,CAuBtB;;;AACA,UAAMwO,oBAAoB,GAAG,CAAC,aAAD,EAAgB,YAAhB,EAA8B,cAA9B,CAA7B;;AAxBsB,mCAyBbxO,GAzBa;AA0BpB2E,cAAM,CAAC2J,cAAP,CAAsB,KAAI,CAACf,aAA3B,EAA0CiB,oBAAoB,CAACxO,GAAD,CAA9D,EAAmE;AACjE+C,aAAG,EAAE;AAAA,mBAAM,KAAI,CAACyL,oBAAoB,CAACxO,GAAD,CAArB,CAAV;AAAA;AAD4D,SAAnE;AA1BoB;;AAyBtB,WAAK,IAAIA,GAAC,GAAGwO,oBAAoB,CAAClO,MAArB,GAA8B,CAA3C,EAA8CN,GAAC,IAAI,CAAnD,EAAsDA,GAAC,EAAvD,EAA2D;AAAA,eAAlDA,GAAkD;AAI1D,OA7BqB,CA+BtB;;;AACA2E,YAAM,CAAC2J,cAAP,CAAsB,KAAKf,aAA3B,EAA0C,UAA1C,EAAsD;AACpDxK,WAAG,EAAE;AAAA,iBAAM,KAAI,CAACoK,QAAX;AAAA,SAD+C;AAEpDoB,WAAG,EAAE,aAACtS,KAAD;AAAA,iBAAY,EAAE,KAAI,CAACkR,QAAL,GAAgBlR,KAAlB,CAAD,GAA6B,KAAI,CAAC+Q,QAAL,EAA7B,GAA+C,IAA1D;AAAA;AAF+C,OAAtD;AAID;;;4BAEO/Q,K,EAAO;AACb,WAAKiR,SAAL,GAAiBjR,KAAjB;AACD;;;4BAEO;AACN,aAAO,KAAKyI,MAAL,CAAYQ,GAAnB;AACD;;;4BAEO;AACN,aAAO,KAAKR,MAAL,CAAYO,GAAnB;AACD;;;8BAES;AACR,aAAO,CAAC,KAAKP,MAAL,CAAYpE,MAApB;AACD;;;2BAcMmO,Q,EAAU;AACf,WAAK/J,MAAL,CAAYgB,MAAZ,CAAmB+I,QAAnB;AACA,WAAKzB,QAAL;AACA,WAAKtD,QAAL,CAAcwB,OAAd;AACA,WAAKxB,QAAL,CAAce,UAAd;AACD;;;4BAEOgE,Q,EAAU;AAChB,WAAK/J,MAAL,CAAYrE,OAAZ,CAAoBoO,QAApB;AACA,WAAKzB,QAAL;AACA,WAAKtD,QAAL,CAAcwB,OAAd;AACA,WAAKxB,QAAL,CAAce,UAAd;AACD;;;iCAEYjE,I,EAAMC,I,EAAMiI,I,EAAM;AAC7B,UAAI,OAAOlI,IAAP,KAAgB,UAApB,EAAgC;AAC9B,aAAKmI,gBAAL,CAAsBnI,IAAtB,EAA4BC,IAA5B;AACA,YAAGA,IAAI,IAAIA,IAAI,CAACmI,QAAhB,EAA0B;AAC3B,OAHD,MAGO;AACL,aAAKC,iBAAL,CAAuBrI,IAAvB,EAA6BC,IAA7B,EAAmCiI,IAAnC;AACA,YAAGA,IAAI,IAAIA,IAAI,CAACE,QAAhB,EAA0B;AAC3B;;AACD,WAAK5B,QAAL;AACD;;;qCAEgB8B,E,EAAIC,O,EAAS;AAAA;;AAC5B,WAAKrK,MAAL,CAAYsK,KAAZ,CAAkB,CAAlB,EAAqBpP,OAArB,CAA6B,UAACwD,OAAD,EAAa;AACxC;AACA;AACA,cAAI,CAAC6L,WAAL,CAAiB7L,OAAjB,EAA0B0L,EAAE,CAAC1L,OAAO,CAACwC,IAAT,EAAexC,OAAO,CAACM,KAAvB,EAA8BN,OAAO,CAAC3H,OAAtC,CAA5B,EAA4EsT,OAA5E;AACD,OAJD;AAKD;;;sCAEiBzM,K,EAAOmM,Q,EAAwB;AAAA,UAAdM,OAAc,uEAAJ,EAAI;;AAC/C,UAAIzM,KAAK,GAAG,CAAR,KAAc,CAAlB,EAAqB;AACnB,cAAM,IAAI9B,KAAJ,CAAU,oBAAoB8B,KAApB,GAA4B,8CAAtC,CAAN;AACD;;AACD,UAAM4M,MAAM,GAAG5M,KAAK,GAAG,KAAKoC,MAAL,CAAYS,KAAnC,CAJ+C,CAM/C;;;AACA,UAAI+J,MAAM,IAAI,CAAV,IAAeA,MAAM,GAAG,KAAKxK,MAAL,CAAYpE,MAAxC,EAAgD;AAC9C,aAAK2O,WAAL,CAAiB,KAAKvK,MAAL,CAAYwK,MAAZ,CAAjB,EAAsCT,QAAtC,EAAgDM,OAAhD;AACD,OAFD,CAGA;AAHA,WAIK,IAAGzM,KAAK,IAAI,KAAKoC,MAAL,CAAYkC,cAAZ,EAAT,IAAyCtE,KAAK,IAAI,KAAKoC,MAAL,CAAYsC,cAAZ,EAArD,EAAmF;AACtF,cAAGlL,OAAO,CAACqT,OAAR,CAAgBV,QAAhB,KAA6B,CAACA,QAAQ,CAACnO,MAA1C,EAAkD;AAChD,iBAAKoJ,QAAL,CAAcgD,eAAd,CAA8BpK,KAA9B,EAAqC,CAACyM,OAAO,CAACK,YAAT,IAAyB9M,KAAK,KAAK,KAAKoC,MAAL,CAAYW,QAApF;;AACA,gBAAI,CAAC0J,OAAO,CAACK,YAAT,IAAyB9M,KAAK,KAAK,KAAKoC,MAAL,CAAYkC,cAAZ,EAAvC,EAAqE;AACnE,mBAAKlC,MAAL,CAAYmC,iBAAZ;AACD,aAFD,MAGK;AACH,mBAAKnC,MAAL,CAAYoC,iBAAZ;AACD;AACF;AACF;AACF;;;gCAEW1D,O,EAASqL,Q,EAAwB;AAAA;;AAAA,UAAdM,OAAc,uEAAJ,EAAI;;AAC3C,UAAI,CAACjT,OAAO,CAACqT,OAAR,CAAgBV,QAAhB,CAAL,EAAgC;AAC9B;AACD;;AACD,UAAIY,QAAQ,GAAG,KAAK3K,MAAL,CAAYgC,OAAZ,CAAoBtD,OAApB,CAAf;;AACA,UAAI,CAACqL,QAAQ,CAACzI,OAAT,GAAmBsJ,IAAnB,CAAwB,UAAAC,OAAO;AAAA,eAAIA,OAAO,KAAKnM,OAAO,CAACwC,IAAxB;AAAA,OAA/B,CAAL,EAAmE;AACjExC,eAAO,CAACgD,EAAR,GAAa,QAAb;;AACA,YAAI,CAAC2I,OAAO,CAACK,YAAT,IAAyBC,QAAQ,KAAK,CAAtC,IAA2C,CAACZ,QAAQ,CAACnO,MAAzD,EAAiE;AAC/D8C,iBAAO,CAACuD,GAAR,GAAc,OAAd,CAD+D,CACxC;AACxB;AACF;;AACD8H,cAAQ,CAAC7O,OAAT,CAAiB,UAAC2P,OAAD,EAAa;AAC5B,YAAIA,OAAO,KAAKnM,OAAO,CAACwC,IAAxB,EAA8B;AAC5ByJ,kBAAQ;AACT,SAFD,MAEO;AACL;AACA,gBAAI,CAAC3K,MAAL,CAAYmB,MAAZ,CAAmBwJ,QAAQ,GAAG,CAA9B,EAAiCE,OAAjC,EAA0C,CAACR,OAAO,CAACK,YAAT,IAAyBC,QAAQ,KAAK,CAAC,CAAjF;AACD;AACF,OAPD;AAQD;;;0CAEqB;AACpB,UAAIG,MAAM,GAAG,IAAb;AAAA,UAAmBC,SAAS,GAAG,CAA/B;AACA,UAAIC,OAAO,GAAG,KAAd;AAAA,UAAqBC,UAAU,GAAG,KAAlC;AACA,UAAMrP,MAAM,GAAG,KAAKoE,MAAL,CAAYpE,MAA3B;;AAEA,WAAK,IAAIN,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGM,MAApB,EAA4BN,CAAC,EAA7B,EAAiC;AAC/B,YAAM4F,IAAI,GAAG,KAAKlB,MAAL,CAAY1E,CAAZ,CAAb;AACA,YAAM4P,OAAO,GAAGhK,IAAI,CAACnK,OAAL,CAAaqF,MAAb,GAAsBhE,GAAtC;;AAEA,YAAI0S,MAAM,KAAKI,OAAf,EAAwB;AAAE;AACxB,cAAM/E,UAAU,GAAGjF,IAAI,CAACnK,OAAL,CAAakF,WAAb,CAAyB,IAAzB,CAAnB;AACA,cAAM7D,GAAG,GAAG,KAAK4M,QAAL,CAAcQ,UAAd,KAA6BuF,SAA7B,GAAyC5E,UAArD;;AAEA,cAAI,CAAC6E,OAAD,IAAY5S,GAAG,GAAG,KAAK4M,QAAL,CAAcU,aAAd,EAAtB,EAAqD;AACnDsF,mBAAO,GAAG,IAAV;AACA,iBAAK,YAAL,IAAqB9J,IAAI,CAACA,IAA1B;AACA,iBAAK,mBAAL,IAA4BA,IAAI,CAACnK,OAAjC;AACA,iBAAK,iBAAL,IAA0BmK,IAAI,CAAClC,KAA/B;AACD;;AACD,cAAI,CAACiM,UAAD,KAAgB7S,GAAG,IAAI,KAAK4M,QAAL,CAAcS,gBAAd,EAAP,IAA4CnK,CAAC,KAAKM,MAAM,GAAG,CAAf,IAAoB,KAAKuP,KAAL,EAAhF,CAAJ,EAAoG;AAClGF,sBAAU,GAAG,IAAb;AACA,iBAAK,eAAL,IAAwB/J,IAAI,CAACA,IAA7B;AACA,iBAAK,sBAAL,IAA+BA,IAAI,CAACnK,OAApC;AACA,iBAAK,oBAAL,IAA6BmK,IAAI,CAAClC,KAAlC;AACD;;AACD+L,mBAAS,IAAI5E,UAAb;AACD;;AACD2E,cAAM,GAAGI,OAAT;;AAEA,YAAIF,OAAO,IAAIC,UAAf,EAA2B;AACzB;AACD;AACF;AACF;;;wBA3HkB;AACjB,aAAO,KAAKjL,MAAL,CAAY8C,QAAZ,GAAuBlH,MAA9B;AACD;;;wBAEiB;AAChB,aAAO,KAAKoE,MAAL,CAAYgD,YAAZ,EAAP;AACD;;;wBAEgB;AACf,aAAO,KAAKhD,MAAL,CAAYkD,WAAZ,EAAP;AACD;;;;;;AAqHYgF,2DAAf,E;;AChOA;AACA;AACA;AACA;AACA;AAEA9Q,OAAO,CAACgU,MAAR,CAAe,WAAf,EAA4B,EAA5B,EAEGC,QAFH,CAEY,cAFZ,EAE4BvU,yBAF5B,EAGGwU,GAHH,CAGO,CAAC,cAAD,EAAiB,UAACxU,YAAD,EAAkB;AACtC,MAAMyU,GAAG,GAAGnU,OAAO,CAACL,OAApB;AACA,IAAE4B,MAAM,CAAC6S,MAAP,IAAiBD,GAAG,CAACE,EAArB,IAA2BF,GAAG,CAACE,EAAJ,CAAOC,MAApC,IAA+C,IAAI5U,YAAJ,EAAD,CAAqB6U,WAArB,CAAiCJ,GAAjC,CAA9C,GAAsF,IAAtF;AACAhO,iBAAe,CAACqO,WAAhB;AACD,CAJI,CAHP,EASGC,SATH,CASa,kBATb,EASiC,YAAY;AACzC,SAAO;AACLC,YAAQ,EAAE,GADL;AAELC,cAAU,EAAE,CACV,QADU,EAEV,UAFU,EAGV,UAAU/M,KAAV,EAAiBjI,OAAjB,EAA0B;AAAA;;AACxB,WAAKkO,SAAL,GAAiBlO,OAAjB;AACA,WAAKiO,QAAL,GAAgBjO,OAAhB;AACA,WAAKiI,KAAL,GAAaA,KAAb;AAEA5H,aAAO,CAAC8D,OAAR,CAAgBnE,OAAO,CAACsE,QAAR,EAAhB,EAAoC,UAAA2Q,KAAK,EAAI;AAC3C,YAAIA,KAAK,CAAC5H,OAAN,CAAcC,WAAd,OAAgC,OAApC,EAA6C;AAC3C,eAAI,CAACW,QAAL,GAAgB5N,OAAO,CAACL,OAAR,CAAgBiV,KAAhB,CAAhB;AACD;AACF,OAJD;AAMA,aAAO,IAAP;AACD,KAfS;AAFP,GAAP;AAoBD,CA9BH,EAgCGH,SAhCH,CAgCa,UAhCb,EAgCyB,CACrB,MADqB,EAErB,WAFqB,EAGrB,YAHqB,EAIrB,UAJqB,EAKrB,WALqB,EAMrB,IANqB,EAOrB,QAPqB,EAQrB,UAAUI,OAAV,EAAmBhO,SAAnB,EAA8B4G,UAA9B,EAA0CqH,QAA1C,EAAoDC,SAApD,EAA+DjO,EAA/D,EAAmEkK,MAAnE,EAA2E;AAEzE,SAAO;AACLgE,WAAO,EAAE,CAAC,oBAAD,CADJ;AAELN,YAAQ,EAAE,GAFL;AAGLO,cAAU,EAAE,SAHP;AAILC,YAAQ,EAAE,IAJL;AAKLC,YAAQ,EAAE,IALL;AAMLC,QAAI,EAAEA;AAND,GAAP;;AASA,WAASA,IAAT,CAAcrE,MAAd,EAAsBpR,OAAtB,EAA+BsR,KAA/B,EAAsCoE,WAAtC,EAAmDC,MAAnD,EAA2D;AACzD,QAAMC,KAAK,GAAGtE,KAAK,CAACuE,QAAN,CAAeD,KAAf,CAAqB,qCAArB,CAAd;;AACA,QAAI,CAACA,KAAL,EAAY;AACV,YAAM,IAAI7Q,KAAJ,CAAU,uEAAuEuM,KAAK,CAACuE,QAA7E,GAAwF,IAAlG,CAAN;AACD;;AAED,aAASC,WAAT,CAAqBtV,KAArB,EAA4BuV,YAA5B,EAA0CC,OAA1C,EAAmD;AACjD,UAAI,CAACA,OAAL,EAAc;AACZxV,aAAK,GAAGA,KAAK,KAAK,IAAV,GAAiBuV,YAAjB,GAAgC1L,IAAI,CAAC8E,KAAL,CAAW3O,KAAX,CAAxC;AACD;;AACD,aAAOyV,KAAK,CAACzV,KAAD,CAAL,GAAeuV,YAAf,GAA8BvV,KAArC;AACD;;AAED,aAAS0V,gBAAT,CAA0B1V,KAA1B,EAAiCuV,YAAjC,EAA+CC,OAA/C,EAAwD;AACtD,UAAMhU,MAAM,GAAGqP,MAAM,CAAC7Q,KAAD,CAAN,CAAc4Q,MAAd,CAAf;AACA,aAAO0E,WAAW,CAAC9T,MAAD,EAAS+T,YAAT,EAAuBC,OAAvB,CAAlB;AACD;;AAED,QAAMG,UAAU,GAAG,CAAnB,CAlByD,CAkBnC;;AACtB,QAAMC,cAAc,GAAG,EAAvB,CAnByD,CAmB9B;;AAC3B,QAAMC,WAAW,GAAG,GAApB,CApByD,CAoBhC;;AACzB,QAAMC,eAAe,GAAG,GAAxB,CArByD,CAqB5B;;AAC7B,QAAMC,mBAAmB,GAAG,CAA5B,CAtByD,CAsB1B;;AAC/B,QAAMC,kBAAkB,GAAG,GAA3B,CAvByD,CAuBzB;;AAChC,QAAMC,yBAAyB,GAAG,EAAlC,CAxByD,CAwBnB;;AAEtC,QAAIC,UAAU,GAAG,IAAjB;AACA,QAAMC,QAAQ,GAAGf,KAAK,CAAC,CAAD,CAAtB,CA3ByD,CA2B9B;;AAC3B,QAAMgB,cAAc,GAAGhB,KAAK,CAAC,CAAD,CAA5B,CA5ByD,CA4BxB;;AACjC,QAAM/H,kBAAkB,GAAG6H,WAAW,CAAC,CAAD,CAAtC,CA7ByD,CA6Bd;;AAC3C,QAAM5M,UAAU,GAAGuB,IAAI,CAACC,GAAL,CAAS6L,UAAT,EAAqBD,gBAAgB,CAAC5E,KAAK,CAACxI,UAAP,EAAmBsN,cAAnB,CAArC,CAAnB;AACA,QAAM1S,OAAO,GAAG2G,IAAI,CAACC,GAAL,CAAS+L,WAAT,EAAsBH,gBAAgB,CAAC5E,KAAK,CAAC5N,OAAP,EAAgB4S,eAAhB,EAAiC,IAAjC,CAAtC,CAAhB;AACA,QAAIvN,UAAU,GAAGmN,gBAAgB,CAAC5E,KAAK,CAACvI,UAAP,EAAmBwN,mBAAnB,CAAjC,CAhCyD,CAkCzD;AACA;;AACA,QAAMvN,SAAS,GAAGkN,gBAAgB,CAAC5E,KAAK,CAACtI,SAAP,EAAkB,IAAlB,EAAwB,KAAxB,CAAlC,CApCyD,CAsCzD;;AACA,QAAM6N,oBAAoB,GAAGvF,KAAK,CAACuF,oBAAN,KAA6B,OAA1D,CAvCyD,CAyCzD;AACA;;AACA,QAAIC,SAAS,GAAG,CAAhB,CA3CyD,CA2CtC;;AACnB,QAAIC,OAAO,GAAG,EAAd;AAEA,QAAMlO,eAAe,GAAG,IAAIrC,eAAJ,CAAoBU,SAApB,EAA+BC,EAA/B,CAAxB;AACA,QAAM8B,MAAM,GAAG,IAAIL,YAAJ,CAAiBC,eAAjB,EAAkCC,UAAlC,EAA8CC,UAA9C,EAA0DC,SAA1D,CAAf;AACA,QAAMiF,QAAQ,GAAG,IAAIL,QAAJ,CAAa/E,eAAb,EAA8BI,MAA9B,EAAsCjJ,OAAtC,EAA+C6N,kBAA/C,EAAmEC,UAAnE,EAA+EpK,OAA/E,EAAwFsF,SAAxF,CAAjB;AACA,QAAMgJ,OAAO,GAAG,IAAIb,eAAJ,CAAYC,MAAZ,EAAoBC,MAApB,EAA4BC,KAA5B,EAAmCrD,QAAnC,EAA6ChF,MAA7C,EAAqDsI,QAArD,EAA+DC,MAA/D,CAAhB;;AAEA,QAAI3D,kBAAJ,EAAwB;AACtBA,wBAAkB,CAACmE,OAAnB,GAA6BA,OAA7B;AACD,KArDwD,CAuDzD;AACA;;;AACA,QAAIgF,mBAAmB,GAAC,CAAC,CAAzB;;AAEA,QAAMC,iBAAiB,GAAG,SAApBA,iBAAoB;AAAA,aACxB/N,MAAM,CAAC5I,SAAP,CAAiB4W,QAAjB,CAA0BrW,IAA1B,CAA+B6V,UAA/B,MAA+C,iBAA/C,IAAoE,OAAOA,UAAU,CAACpP,GAAlB,KAA0B,UADtE;AAAA,KAA1B;;AAGAoP,cAAU,GAAGrF,MAAM,CAACuF,cAAD,CAAN,CAAuBxF,MAAvB,CAAb,CA9DyD,CA8DZ;;AAC7C,QAAI,CAAC6F,iBAAiB,EAAtB,EAA0B;AACxBP,gBAAU,GAAGxP,SAAS,CAACI,GAAV,CAAcsP,cAAd,CAAb,CADwB,CACoB;;AAC5C,UAAI,CAACK,iBAAiB,EAAtB,EAA0B;AACxB,cAAM,IAAIlS,KAAJ,CAAU6R,cAAc,GAAG,4BAA3B,CAAN;AACD;AACF;;AAED,QAAIO,gBAAgB,GAAG,EAAvB;;AACA,aAASC,sBAAT,GAAkC;AAChCD,sBAAgB,CAAChT,OAAjB,CAAyB,UAAAkT,OAAO;AAAA,eAAIA,OAAO,CAAC9C,GAAR,EAAJ;AAAA,OAAhC;AACA4C,sBAAgB,GAAG,EAAnB;AACD;;AACD,aAASG,sBAAT,CAAgCZ,UAAhC,EAA4Ca,QAA5C,EAAsD;AACpD,UAAIC,MAAJ,CADoD,CAEpD;;AACA,UAAGnX,OAAO,CAAC4E,QAAR,CAAiByR,UAAU,CAACa,QAAD,CAA3B,CAAH,EAA2C;AACzCC,cAAM,GAAGd,UAAU,CAACa,QAAD,CAAnB;;AACA,YAAGlX,OAAO,CAAC4E,QAAR,CAAiBuS,MAAjB,CAAH,EAA6B;AAC3BL,0BAAgB,GAAGA,gBAAgB,CAACnL,MAAjB,CAAwB,UAAAqL,OAAO;AAAA,mBAAIA,OAAO,CAACI,EAAR,KAAeF,QAAnB;AAAA,WAA/B,CAAnB;AACAJ,0BAAgB,CAACtM,IAAjB,CAAsB;AACpB4M,cAAE,EAAEF,QADgB;AAEpBhD,eAAG,EAAE;AAAA,qBAAMmC,UAAU,CAACa,QAAD,CAAV,GAAuBC,MAA7B;AAAA;AAFe,WAAtB;AAID;AACF;AACF;;AAED,aAASE,qBAAT,CAA+BhB,UAA/B,EAA2Ca,QAA3C,EAAqDI,YAArD,EAAmE;AACjE,UAAMC,UAAU,GAAG1O,MAAM,CAAC2O,wBAAP,CAAgCnB,UAAhC,EAA4Ca,QAA5C,CAAnB;;AACA,UAAIK,UAAU,KAAKA,UAAU,CAAC9E,GAAX,IAAkB8E,UAAU,CAACtQ,GAAlC,CAAd,EAAsD;AACpD;AACD;;AACD,UAAIkQ,MAAJ;AACAF,4BAAsB,CAACZ,UAAD,EAAaa,QAAb,CAAtB;AACArO,YAAM,CAAC2J,cAAP,CAAsB6D,UAAtB,EAAkCa,QAAlC,EAA4C;AAC1CzE,WAAG,EAAE,aAACtS,KAAD,EAAW;AACdgX,gBAAM,GAAGhX,KAAT;;AACA,cAAGuW,OAAO,CAAClS,MAAR,IAAkB,CAACoE,MAAM,CAACpE,MAA7B,EAAqC;AACnCyS,kCAAsB,CAACZ,UAAD,EAAaa,QAAb,CAAtB;AACA;AACD;;AACDtO,gBAAM,CAAC0O,YAAD,CAAN,GAAuBnX,KAAvB;AACA,cAAMgQ,mBAAmB,GAAGvC,QAAQ,CAACQ,UAAT,EAA5B;AACAR,kBAAQ,CAACsB,cAAT;;AACA,cAAIgI,QAAQ,KAAK,UAAjB,EAA6B;AAC3BtJ,oBAAQ,CAACsC,kBAAT,CAA4BC,mBAA5B;AACD;AACF,SAbyC;AAc1ClJ,WAAG,EAAE;AAAA,iBAAMkQ,MAAN;AAAA;AAdqC,OAA5C;AAgBD;;AAEDE,yBAAqB,CAAChB,UAAD,EAAa,UAAb,EAAyB,cAAzB,CAArB;AACAgB,yBAAqB,CAAChB,UAAD,EAAa,UAAb,EAAyB,cAAzB,CAArB;AAEA,QAAMoB,SAAS,GAAIpB,UAAU,CAACpP,GAAX,CAAezC,MAAf,KAA0B,CAA3B,GAChB,UAACkT,OAAD;AAAA,aAAarB,UAAU,CAACpP,GAAX,CAAe2B,MAAM,CAACU,IAAtB,EAA4Bb,UAA5B,EAAwCiP,OAAxC,CAAb;AAAA,KADgB,GAEhB,UAACA,OAAD,EAAa;AACXrB,gBAAU,CAACpP,GAAX,CAAe;AACbT,aAAK,EAAEoC,MAAM,CAACU,IADD;AAEbM,cAAM,EAAEhB,MAAM,CAACpE,MAAP,GAAgBoE,MAAM,CAACA,MAAM,CAACpE,MAAP,GAAgB,CAAjB,CAAN,CAA0BsF,IAA1C,GAAiD,KAAK,CAFjD;AAGb6N,aAAK,EAAElP;AAHM,OAAf,EAIGiP,OAJH;AAKD,KARH;AAUA,QAAME,aAAa,GAAIvB,UAAU,CAACpP,GAAX,CAAezC,MAAf,KAA0B,CAA3B,GACpB,UAACkT,OAAD;AAAA,aAAarB,UAAU,CAACpP,GAAX,CAAe2B,MAAM,CAACS,KAAP,GAAeZ,UAA9B,EAA0CA,UAA1C,EAAsDiP,OAAtD,CAAb;AAAA,KADoB,GAEpB,UAACA,OAAD,EAAa;AACXrB,gBAAU,CAACpP,GAAX,CAAe;AACbT,aAAK,EAAEoC,MAAM,CAACS,KAAP,GAAeZ,UADT;AAEblE,eAAO,EAAEqE,MAAM,CAACpE,MAAP,GAAgBoE,MAAM,CAAC,CAAD,CAAN,CAAUkB,IAA1B,GAAiC,KAAK,CAFlC;AAGb6N,aAAK,EAAElP;AAHM,OAAf,EAIGiP,OAJH;AAKD,KARH;;AAUA,QAAMG,UAAU,GAAG,SAAbA,UAAa,GAAM;AACvB,UAAIC,QAAQ,GAAG,CAAf;;AACA,UAAG,CAAClK,QAAQ,CAACK,mBAAT,EAAJ,EAAoC;AAClC,YAAM8J,KAAK,GAAGhD,SAAS,CAAC,YAAM;AAC5B+C,kBAAQ;;AACR,cAAGlK,QAAQ,CAACK,mBAAT,EAAH,EAAmC;AACjC8G,qBAAS,CAACiD,MAAV,CAAiBD,KAAjB;AACA7G,oBAAQ;AACT;;AACD,cAAG4G,QAAQ,GAAG1B,yBAAX,IAAwCD,kBAA3C,EAA+D;AAC7DpB,qBAAS,CAACiD,MAAV,CAAiBD,KAAjB;AACA,kBAAMrT,KAAK,2EAAoEyR,kBAApE,QAAX;AACD;AACF,SAVsB,EAUpBC,yBAVoB,CAAvB;AAWD,OAZD,MAaK;AACHlF,gBAAQ;AACT;AACF,KAlBD;AAoBA;;;;;;;;;AAOAoE,UAAM,CAAC,UAAC2C,KAAD,EAAQrQ,KAAR,EAAkB;AACvBgG,cAAQ,CAACI,qBAAT,CAA+BiK,KAAK,CAAC,CAAD,CAApC,EADuB,CAEvB;AACA;AACA;;AACArQ,WAAK,CAACC,QAAN;AACAoQ,WAAK,CAACtQ,MAAN;AACD,KAPK,CAAN;AASAoJ,UAAM,CAACmH,GAAP,CAAW,UAAX,EAAuB,YAAM;AAC3BC,kBAAY;AACZvK,cAAQ,CAACwK,MAAT,CAAgB,YAAhB,EAA8BC,YAA9B;AACD,KAHD;AAKAzK,YAAQ,CAACwE,IAAT,CAAc,YAAd,EAA4BiG,YAA5B;AAEAR,cAAU;AAEV;;AAEA,aAASS,SAAT,CAAmBC,GAAnB,EAAwB;AACtB,aAAQA,GAAG,IAAIA,GAAG,KAAK9B,SAAhB,IAA8B1F,MAAM,CAACyH,WAA5C;AACD;;AAED,aAASC,UAAT,GAAsB;AACpB7K,cAAQ,CAACwE,IAAT,CAAc,QAAd,EAAwBsG,sBAAxB;AACA9K,cAAQ,CAACwE,IAAT,CAAc,QAAd,EAAwBsG,sBAAxB,EAFoB,CAGpB;;AACA,UAAGC,eAAe,EAAlB,EAAsB;AACpB;AACAC,+BAAuB;AACxB;AACF;;AAED,aAAST,YAAT,GAAwB;AACtBvK,cAAQ,CAACwK,MAAT,CAAgB,QAAhB,EAA0BM,sBAA1B;AACA9K,cAAQ,CAACwK,MAAT,CAAgB,QAAhB,EAA0BM,sBAA1B;AACD;;AAED,aAASvH,MAAT,GAAkB;AAChBgH,kBAAY;AACZvK,cAAQ,CAAC6C,eAAT;AACA7C,cAAQ,CAAC+C,kBAAT;;AACA,UAAIrL,SAAS,CAACd,MAAd,EAAsB;AACpBkE,kBAAU,GAAG+M,WAAW,CAACnQ,SAAS,CAAC,CAAD,CAAV,EAAe4Q,mBAAf,EAAoC,KAApC,CAAxB;AACD;;AACDtN,YAAM,CAACM,KAAP,CAAaR,UAAb;AACAiO,yBAAmB,GAAG,CAAC,CAAvB,CARgB,CAQU;;AAC1BM,4BAAsB,CAACZ,UAAD,EAAa,UAAb,CAAtB;AACAY,4BAAsB,CAACZ,UAAD,EAAa,UAAb,CAAtB;AACAnF,cAAQ;AACT;;AAED,aAASpQ,QAAT,CAAkBuI,KAAlB,EAAyB;AACvB8O,kBAAY;AACZvK,cAAQ,CAAC9M,QAAT,CAAkBuI,KAAlB;AACA6H,cAAQ;AACT;;AAED,aAAS2H,gBAAT,CAA0BvR,OAA1B,EAAmC;AACjC,aAAO,CAACqB,SAAS,IAAIrB,OAAO,CAAC3H,OAAR,CAAgBwD,MAAhB,EAAd,KAA2CmE,OAAO,CAAC3H,OAAR,CAAgB,CAAhB,EAAmB8L,YAArE;AACD;;AAED,aAASqN,iBAAT,CAA2BxR,OAA3B,EAAoC;AAClC,UAAIuR,gBAAgB,CAACvR,OAAD,CAApB,EAA+B;AAC7BsB,cAAM,CAAC9E,OAAP,CAAe,UAACgG,IAAD,EAAU;AACvB,cAAI,OAAOA,IAAI,CAACiP,2BAAZ,KAA4C,UAAhD,EAA4D;AAC1DjP,gBAAI,CAACiP,2BAAL;AACA,mBAAOjP,IAAI,CAACiP,2BAAZ;AACD;AACF,SALD;;AAMA,YAAI,CAACrC,OAAO,CAAClS,MAAb,EAAqB;AACnBsQ,kBAAQ,CAAC;AAAA,mBAAM5D,QAAQ,EAAd;AAAA,WAAD,CAAR;AACD;AACF;AACF;;AAED,aAAS8H,oBAAT,CAA8B1R,OAA9B,EAAuC2R,WAAvC,EAAoD;AAClDC,mBAAa,CAAC5R,OAAD,EAAU2R,WAAV,EAAuBrL,QAAQ,CAAC9F,aAAhC,CAAb;;AACA,UAAI0O,oBAAoB,IAAI,CAACqC,gBAAgB,CAACvR,OAAD,CAA7C,EAAwD;AACtDA,eAAO,CAACyR,2BAAR,GAAsCzR,OAAO,CAACM,KAAR,CAAcuR,MAAd,CAAqB;AAAA,iBAAML,iBAAiB,CAACxR,OAAD,CAAvB;AAAA,SAArB,CAAtC;AACD;;AACD,UAAIkP,oBAAJ,EAA0B;AACxBhO,uBAAe,CAAC4Q,WAAhB,CAA4B9R,OAA5B,EADwB,CACc;AACvC;AACF;;AAED,aAAS4R,aAAT,CAAuB5R,OAAvB,EAAgC2R,WAAhC,EAA6CnR,aAA7C,EAA4D;AAC1D,UAAIuR,QAAQ,GAAG,IAAf;AACA,UAAM7K,OAAO,GAAIyK,WAAW,GAAG,CAAf,GAAoBrQ,MAAM,CAACqQ,WAAW,GAAG,CAAf,CAAN,CAAwBtZ,OAA5C,GAAsD4F,SAAtE;AACA+P,YAAM,CAAC,UAAC2C,KAAD,EAAQrQ,KAAR,EAAkB;AACvByR,gBAAQ,GAAGvR,aAAa,CAACmQ,KAAD,EAAQzJ,OAAR,CAAxB;AACAlH,eAAO,CAAC3H,OAAR,GAAkBsY,KAAlB;AACA3Q,eAAO,CAACM,KAAR,GAAgBA,KAAhB;AACAA,aAAK,CAAC0O,QAAD,CAAL,GAAkBhP,OAAO,CAACwC,IAA1B;AACD,OALK,CAAN,CAH0D,CAS1D;;AACA,UAAI6H,OAAO,CAAC2H,SAAZ,EAAuB;AACrB,YAAMC,aAAa,GAAGjS,OAAO,CAACM,KAAR,CAAc4R,qBAApC;;AACA,YAAID,aAAa,IAAIA,aAAa,CAACE,OAAnC,EAA4C;AAC1C9H,iBAAO,CAAC2H,SAAR,CAAkBhS,OAAO,CAACM,KAA1B,EAAiCN,OAAO,CAAC3H,OAAzC;AACD,SAFD,MAEO;AACL2H,iBAAO,CAACM,KAAR,CAAc4R,qBAAd,GAAsC;AACpCE,kBAAM,EAAE;AAAA,qBAAM/H,OAAO,CAAC2H,SAAR,CAAkBhS,OAAO,CAACM,KAA1B,EAAiCN,OAAO,CAAC3H,OAAzC,CAAN;AAAA,aAD4B;AAEpCiI,iBAAK,EAAEN,OAAO,CAACM;AAFqB,WAAtC;AAID;AACF;;AACD,aAAOyR,QAAP;AACD;;AAED,aAASM,SAAT,GAAqB;AACnB,UAAIN,QAAQ,GAAG,EAAf;AACA,UAAMO,aAAa,GAAG,EAAtB;AACA,UAAMC,WAAW,GAAG,EAApB;AACA,UAAMC,QAAQ,GAAG,EAAjB;AAEAlR,YAAM,CAAC9E,OAAP,CAAe,UAACwD,OAAD,EAAUpD,CAAV,EAAgB;AAC7B,gBAAQoD,OAAO,CAACgD,EAAhB;AACE,eAAK,SAAL;AACEsP,yBAAa,CAACnP,OAAd,CAAsBnD,OAAtB;AACA;;AACF,eAAK,QAAL;AACE0R,gCAAoB,CAAC1R,OAAD,EAAUpD,CAAV,CAApB;AACAoD,mBAAO,CAACgD,EAAR,GAAa,MAAb;AACAwP,oBAAQ,CAACtP,IAAT,CAAclD,OAAd;AACA;;AACF,eAAK,QAAL;AACE+R,oBAAQ,GAAGA,QAAQ,CAACU,MAAT,CAAgBb,aAAa,CAAC5R,OAAD,EAAUpD,CAAV,EAAa0J,QAAQ,CAACa,qBAAtB,CAA7B,CAAX;AACAnH,mBAAO,CAACgD,EAAR,GAAa,MAAb;AACAwP,oBAAQ,CAACtP,IAAT,CAAclD,OAAd;AACA;;AACF,eAAK,QAAL;AACEuS,uBAAW,CAACrP,IAAZ,CAAiBlD,OAAjB;AAfJ;AAiBD,OAlBD;AAoBAuS,iBAAW,CAAC/V,OAAZ,CAAoB,UAACwD,OAAD;AAAA,eAAa+R,QAAQ,GAAGA,QAAQ,CAACU,MAAT,CAAgBnM,QAAQ,CAACiD,UAAT,CAAoBvJ,OAApB,CAAhB,CAAxB;AAAA,OAApB;AAEA,UAAIsS,aAAa,CAACpV,MAAlB,EACEoV,aAAa,CAAC9V,OAAd,CAAsB,UAACwD,OAAD,EAAa;AACjC0R,4BAAoB,CAAC1R,OAAD,CAApB;AACAA,eAAO,CAACgD,EAAR,GAAa,MAAb;AACD,OAHD;AAKF1B,YAAM,CAAC9E,OAAP,CAAe,UAACgG,IAAD,EAAO5F,CAAP;AAAA,eAAa4F,IAAI,CAAClC,KAAL,CAAWoE,MAAX,GAAoBpD,MAAM,CAACS,KAAP,GAAenF,CAAhD;AAAA,OAAf;AAEA,aAAO;AACLqM,iBAAS,EAAEqJ,aADN;AAELI,eAAO,EAAEH,WAFJ;AAGLC,gBAAQ,EAAEA,QAHL;AAILG,gBAAQ,EAAEZ;AAJL,OAAP;AAOD,KA/TwD,CAiUzD;AACA;;;AACA,aAASa,cAAT,CAAwB3B,GAAxB,EAA6BjI,OAA7B,EAAsC;AACpC;AACA,UAAIA,OAAO,CAAC2J,QAAR,CAAiBzV,MAArB,EAA6B;AAC3BsC,UAAE,CAACqT,GAAH,CAAO7J,OAAO,CAAC2J,QAAf,EAAyB3R,IAAzB,CAA8B,YAAM;AAClCsF,kBAAQ,CAACsB,cAAT;AACAgC,kBAAQ,CAACqH,GAAD,CAAR;AACD,SAHD;AAID,OALD,MAKO;AACL3K,gBAAQ,CAACsB,cAAT;AACD;AACF;;AAED,aAASkL,YAAT,CAAsB7B,GAAtB,EAA2BjI,OAA3B,EAAoC;AAClC;AACA;AACA;AACA;AACA;AACA,UAAGqI,eAAe,MAAM0B,uBAAuB,OAAK9U,SAApD,EAA+D;AAC7D;AACAmT,8BAAsB;AACtB;AACD;;AAED,UAAI9K,QAAQ,CAACc,gBAAT,EAAJ,EAAiC;AAC/B,YAAI,CAAC4B,OAAD,IAAY1H,MAAM,CAACuC,eAAP,CAAuBmF,OAAO,CAACwJ,QAA/B,IAA2C,CAA3D,EAA8D;AAC5D;AACA,cAAIpD,OAAO,CAAClM,IAAR,CAAa,IAAb,MAAuB,CAA3B,EAA8B;AAC5BmH,mBAAO,CAAC2I,OAAR,CAAgB,IAAhB;AACAC,iBAAK,CAAChC,GAAD,CAAL;AACD;AACF;AACF,OARD,MAQO,IAAI3K,QAAQ,CAACuB,aAAT,EAAJ,EAA8B;AACnC,YAAK,CAACmB,OAAD,IAAY1H,MAAM,CAACuC,eAAP,CAAuBmF,OAAO,CAACC,SAA/B,IAA4C,CAAzD,IAA+DmG,OAAO,CAAC,CAAD,CAA1E,EAA+E;AAC7E;AACA;AACA;AACA,cAAIA,OAAO,CAAClM,IAAR,CAAa,KAAb,MAAwB,CAA5B,EAA+B;AAC7BmH,mBAAO,CAAC2I,OAAR,CAAgB,IAAhB;AACAC,iBAAK,CAAChC,GAAD,CAAL;AACD;AACF;AACF;AACF;;AAED,aAASiC,cAAT,GAA0B;AACxB,UAAMlK,OAAO,GAAGqJ,SAAS,EAAzB,CADwB,CAGxB;AACA;;AACA,UAAMc,OAAO,GAAGnK,OAAO,CAAC2J,QAAR,CAAiBzV,MAAjB,GAAwB8L,OAAO,CAACwJ,QAAR,CAAiBtV,MAAzC,GAAgD8L,OAAO,CAACC,SAAR,CAAkB/L,MAAlE,GAAyE8L,OAAO,CAAC0J,OAAR,CAAgBxV,MAAzG;;AACA,UAAGiW,OAAO,IAAI,CAAC9R,SAAf,EAA0B;AACxB,SAACoI,MAAM,CAAC2J,OAAR,IAAmB,CAACjN,UAAU,CAACiN,OAA/B,IAA0C3J,MAAM,CAAC4J,OAAP,EAA1C;AACD;;AAED,UAAInE,oBAAJ,EAA0B;AACxBlG,eAAO,CAACwJ,QAAR,CAAiBhW,OAAjB,CAAyB,UAAA8W,CAAC;AAAA,iBAAIpS,eAAe,CAACqS,WAAhB,CAA4BD,CAA5B,CAAJ;AAAA,SAA1B;AACAtK,eAAO,CAACC,SAAR,CAAkBzM,OAAlB,CAA0B,UAAA8W,CAAC;AAAA,iBAAIpS,eAAe,CAACqS,WAAhB,CAA4BD,CAA5B,CAAJ;AAAA,SAA3B;AACD;;AAED,aAAOtK,OAAP;AACD;;AAED,aAASY,QAAT,CAAkBqH,GAAlB,EAAuB;AACrB,UAAI,CAACA,GAAL,EAAU;AAAE;AACV7B,eAAO,GAAG,EAAV;AACA6B,WAAG,GAAG,EAAE9B,SAAR;AACD;;AAED,UAAMnG,OAAO,GAAGkK,cAAc,EAA9B;;AAEA,UAAIlC,SAAS,CAACC,GAAD,CAAb,EAAoB;AAClB;AACD;;AAED2B,oBAAc,CAAC3B,GAAD,EAAMjI,OAAN,CAAd;AACA8J,kBAAY,CAAC7B,GAAD,CAAZ;;AAEA,UAAI,CAAC7B,OAAO,CAAClS,MAAb,EAAqB;AACnBmN,eAAO,CAACmJ,mBAAR;AACD;AACF;;AAED,aAASC,kBAAT,CAA4BxC,GAA5B,EAAiC;AAC/B,UAAMjI,OAAO,GAAGkK,cAAc,EAA9B;AAEA5M,cAAQ,CAACyC,cAAT,CAAwBC,OAAxB;;AAEA,UAAIgI,SAAS,CAACC,GAAD,CAAb,EAAoB;AAClB;AACD;;AAED2B,oBAAc,CAAC3B,GAAD,EAAMjI,OAAN,CAAd;AACAyG,4BAAsB;AACtBqD,kBAAY,CAAC7B,GAAD,EAAMjI,OAAN,CAAZ;AACAoG,aAAO,CAACsE,KAAR;AAEA,UAAItE,OAAO,CAAClS,MAAZ,EACE+V,KAAK,CAAChC,GAAD,CAAL,CADF,KAEK;AACH5G,eAAO,CAAC2I,OAAR,CAAgB,KAAhB;AACA7B,kBAAU;AACV9G,eAAO,CAACmJ,mBAAR;AACD;AACF;;AAED,aAASP,KAAT,CAAehC,GAAf,EAAoB;AAClB,UAAI7B,OAAO,CAAC,CAAD,CAAX,EAAgB;AAAC;AACf,YAAI9N,MAAM,CAACpE,MAAP,IAAiB,CAACoJ,QAAQ,CAACc,gBAAT,EAAtB,EAAmD;AACjDqM,4BAAkB,CAACxC,GAAD,CAAlB;AACD,SAFD,MAEO;AACLd,mBAAS,CAAC,UAAC9V,MAAD,EAAY;AACpB,gBAAI2W,SAAS,CAACC,GAAD,CAAb,EAAoB;AAClB;AACD;;AAED,gBAAI5W,MAAM,CAAC6C,MAAP,GAAgBiE,UAApB,EAAgC;AAC9BG,oBAAM,CAACO,GAAP,GAAa,IAAb;AACD;;AAED,gBAAIxH,MAAM,CAAC6C,MAAP,GAAgB,CAApB,EAAuB;AACrBoJ,sBAAQ,CAACwB,OAAT;AACAxG,oBAAM,CAACgB,MAAP,CAAcjI,MAAd;AACD;;AAEDoZ,8BAAkB,CAACxC,GAAD,CAAlB;AACD,WAfQ,CAAT;AAgBD;AACF,OArBD,MAqBO;AAAG;AACR,YAAI3P,MAAM,CAACpE,MAAP,IAAiB,CAACoJ,QAAQ,CAACuB,aAAT,EAAtB,EAAgD;AAC9C4L,4BAAkB,CAACxC,GAAD,CAAlB;AACD,SAFD,MAEO;AACLX,uBAAa,CAAC,UAACjW,MAAD,EAAY;AACxB,gBAAI2W,SAAS,CAACC,GAAD,CAAb,EAAoB;AAClB;AACD;;AAED,gBAAI5W,MAAM,CAAC6C,MAAP,GAAgBiE,UAApB,EAAgC;AAC9BG,oBAAM,CAACQ,GAAP,GAAa,IAAb,CAD8B,CAE9B;AACD;;AAED,gBAAIzH,MAAM,CAAC6C,MAAP,GAAgB,CAApB,EAAuB;AACrB,kBAAIoE,MAAM,CAACpE,MAAX,EAAmB;AACjBoJ,wBAAQ,CAACe,UAAT;AACD;;AACD/F,oBAAM,CAACrE,OAAP,CAAe5C,MAAf;AACD;;AAEDoZ,8BAAkB,CAACxC,GAAD,CAAlB;AACD,WAlBY,CAAb;AAmBD;AACF;AACF;;AAED,aAASI,eAAT,GAA2B;AACzB,UAAGhQ,SAAH,EAAc;AACZ;AACA;AACA,YAAIsS,EAAE,GAAGrN,QAAQ,CAAChI,SAAT,EAAT;;AACA,YAAGqV,EAAE,IAAEtE,mBAAJ,IAA2BA,mBAAmB,IAAE,CAAnD,EAAsD;AACpD,iBAAO,IAAP;AACD;AACF;;AACD,aAAO,KAAP;AACD,KAxewD,CA0ezD;;;AACA,QAAIuE,OAAJ;;AACA,aAASxC,sBAAT,GAAkC;AAChC,UAAI/P,SAAJ,EAAe;AACb,YAAIuS,OAAJ,EAAaC,YAAY,CAACD,OAAD,CAAZ;AACbA,eAAO,GAAGE,UAAU,CAACxC,uBAAD,EAA0B,EAA1B,CAApB;AACD,OAHD,MAGO;AACLA,+BAAuB;AACxB;AACF;;AAED,aAASA,uBAAT,GAAmC;AACjC,UAAI,CAACnL,UAAU,CAACiN,OAAZ,IAAuB,CAAC/I,OAAO,CAACP,SAAhC,IAA6C,CAACO,OAAO,CAACN,QAA1D,EAAoE;AAClE;AACA;AACA;AACA,YAAG1I,SAAH,EAAc;AACZ,cAAM0S,QAAQ,GAAGhB,uBAAuB,EAAxC;;AACA,cAAGgB,QAAQ,KAAG9V,SAAd,EAAyB;AACvBzE,oBAAQ,CAACua,QAAD,CAAR;AACA;AACD;AACF;;AAEDjB,oBAAY,CAAC3D,SAAD,CAAZ;;AAEA,YAAIC,OAAO,CAAClS,MAAZ,EAAoB;AAClB2T,sBAAY;AACb,SAFD,MAEO;AACLxG,iBAAO,CAACmJ,mBAAR;;AACA,cAAG,CAACnS,SAAJ,EAAe;AACb;AACA,aAACoI,MAAM,CAAC2J,OAAR,IAAmB3J,MAAM,CAAC4J,OAAP,EAAnB;AACD;AACF;AACF;AACF;;AAED,aAASN,uBAAT,GAAmC;AAC/B,UAAG1R,SAAH,EAAc;AACZgO,2BAAmB,GAAG/I,QAAQ,CAAChI,SAAT,EAAtB;AACA,YAAIyV,QAAQ,GAAGrR,IAAI,CAAC8E,KAAL,CAAWlB,QAAQ,CAAChI,SAAT,KAAuB+C,SAAlC,IAA+CC,MAAM,CAACkC,cAAP,EAA9D;AACAuQ,gBAAQ,GAAGrR,IAAI,CAACC,GAAL,CAASrB,MAAM,CAACkC,cAAP,EAAT,EAAkCd,IAAI,CAACG,GAAL,CAASvB,MAAM,CAACsC,cAAP,EAAT,EAAiCmQ,QAAjC,CAAlC,CAAX,CAHY,CAG8E;;AAC1F,YAAIA,QAAQ,GAACzS,MAAM,CAACS,KAAP,GAAaZ,UAA1B,EAAsC;AACpC,iBAAO4S,QAAP;AACD;;AACD,YAAIA,QAAQ,GAACzS,MAAM,CAACU,IAAP,GAAYb,UAAzB,EAAqC;AACnC,iBAAO4S,QAAP;AACD;AACF;;AACD,aAAO9V,SAAP;AACH;;AAED,aAAS8S,YAAT,CAAsBiD,KAAtB,EAA6B;AAC3B,UAAI,CAAC3J,OAAO,CAACN,QAAb,EAAuB;AACrB,YAAMzL,SAAS,GAAGgI,QAAQ,CAAC,CAAD,CAAR,CAAYhI,SAA9B;AACA,YAAM2V,IAAI,GAAG3N,QAAQ,CAAC,CAAD,CAAR,CAAYO,YAAZ,GAA2BP,QAAQ,CAAC,CAAD,CAAR,CAAY4N,YAApD;;AAEA,YAAK5V,SAAS,KAAK,CAAd,IAAmB,CAACgD,MAAM,CAACQ,GAA5B,IAAqCxD,SAAS,KAAK2V,IAAd,IAAsB,CAAC3S,MAAM,CAACO,GAAvE,EAA6E;AAC3EmS,eAAK,CAACG,cAAN;AACD;AACF;AACF;AACF;AAEF,CA9jBoB,CAhCzB,E","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","/*!\n globals: angular, window\n List of used element methods available in JQuery but not in JQuery Lite\n element.before(elem)\n element.height()\n element.outerHeight(true)\n element.height(value) = only for Top/Bottom padding elements\n element.scrollTop()\n element.scrollTop(value)\n */\n\nexport default class JQLiteExtras {\n\n registerFor(element) {\n let convertToPx, css, getStyle, isWindow;\n // angular implementation blows up if elem is the window\n css = angular.element.prototype.css;\n\n element.prototype.css = function (name, value) {\n let self = this;\n let elem = self[0];\n if (!(!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style)) {\n return css.call(self, name, value);\n }\n };\n\n // as defined in angularjs v1.0.5\n isWindow = (obj) => obj && obj.document && obj.location && obj.alert && obj.setInterval;\n\n function scrollTo(self, direction, value) {\n let elem = self[0];\n let [method, prop, preserve] = {\n top: [\n 'scrollTop',\n 'pageYOffset',\n 'scrollLeft'\n ],\n left: [\n 'scrollLeft',\n 'pageXOffset',\n 'scrollTop'\n ]\n }[direction];\n\n const isValueDefined = typeof value !== 'undefined';\n if (isWindow(elem)) {\n if (isValueDefined) {\n return elem.scrollTo(self[preserve].call(self), value);\n }\n return (prop in elem) ? elem[prop] : elem.document.documentElement[method];\n } else {\n if (isValueDefined) {\n elem[method] = value;\n }\n return elem[method];\n }\n }\n\n if (window.getComputedStyle) {\n getStyle = (elem) => window.getComputedStyle(elem, null);\n convertToPx = (elem, value) => parseFloat(value);\n } else {\n getStyle = (elem) => elem.currentStyle;\n convertToPx = (elem, value) => {\n let left, result, rs, rsLeft, style;\n let core_pnum = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source;\n let rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i');\n\n if (!rnumnonpx.test(value)) {\n return parseFloat(value);\n }\n\n // ported from JQuery\n style = elem.style;\n left = style.left;\n rs = elem.runtimeStyle;\n rsLeft = rs && rs.left;\n if (rs) {\n rs.left = style.left;\n }\n // put in the new values to get a computed style out\n style.left = value;\n result = style.pixelLeft;\n style.left = left;\n if (rsLeft) {\n rs.left = rsLeft;\n }\n return result;\n };\n }\n\n function getMeasurements(elem, measure) {\n let base, borderA, borderB, computedMarginA, computedMarginB, computedStyle, dirA, dirB, marginA, marginB, paddingA, paddingB;\n\n if (isWindow(elem)) {\n base = document.documentElement[{height: 'clientHeight', width: 'clientWidth'}[measure]];\n\n return {\n base: base,\n padding: 0,\n border: 0,\n margin: 0\n };\n }\n\n // Start with offset property\n [\n base,\n dirA,\n dirB\n ] = {\n width: [\n elem.offsetWidth,\n 'Left',\n 'Right'\n ],\n height: [\n elem.offsetHeight,\n 'Top',\n 'Bottom'\n ]\n }[measure];\n\n computedStyle = getStyle(elem);\n paddingA = convertToPx(elem, computedStyle['padding' + dirA]) || 0;\n paddingB = convertToPx(elem, computedStyle['padding' + dirB]) || 0;\n borderA = convertToPx(elem, computedStyle['border' + dirA + 'Width']) || 0;\n borderB = convertToPx(elem, computedStyle['border' + dirB + 'Width']) || 0;\n computedMarginA = computedStyle['margin' + dirA];\n computedMarginB = computedStyle['margin' + dirB];\n\n // I do not care for width for now, so this hack is irrelevant\n // if ( !supportsPercentMargin )\n // computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA )\n // computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB )\n marginA = convertToPx(elem, computedMarginA) || 0;\n marginB = convertToPx(elem, computedMarginB) || 0;\n\n return {\n base: base,\n padding: paddingA + paddingB,\n border: borderA + borderB,\n margin: marginA + marginB\n };\n }\n\n function getWidthHeight(elem, direction, measure) {\n let computedStyle, result;\n\n let measurements = getMeasurements(elem, direction);\n\n if (measurements.base > 0) {\n return {\n base: measurements.base - measurements.padding - measurements.border,\n outer: measurements.base,\n outerfull: measurements.base + measurements.margin\n }[measure];\n }\n\n // Fall back to computed then uncomputed css if necessary\n computedStyle = getStyle(elem);\n result = computedStyle[direction];\n\n if (result < 0 || result === null) {\n result = elem.style[direction] || 0;\n }\n\n // Normalize \"\", auto, and prepare for extra\n result = parseFloat(result) || 0;\n\n return {\n base: result - measurements.padding - measurements.border,\n outer: result,\n outerfull: result + measurements.padding + measurements.border + measurements.margin\n }[measure];\n }\n\n // define missing methods\n return angular.forEach({\n before(newElem) {\n var children, elem, i, j, parent, ref, self;\n self = this;\n elem = self[0];\n parent = self.parent();\n children = parent.contents();\n if (children[0] === elem) {\n return parent.prepend(newElem);\n } else {\n for (i = j = 1, ref = children.length - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) {\n if (children[i] === elem) {\n angular.element(children[i - 1]).after(newElem);\n return;\n }\n }\n throw new Error('invalid DOM structure ' + elem.outerHTML);\n }\n },\n height (value){\n var self;\n self = this;\n if (typeof value !== 'undefined') {\n if (angular.isNumber(value)) {\n value = value + 'px';\n }\n return css.call(self, 'height', value);\n } else {\n return getWidthHeight(this[0], 'height', 'base');\n }\n },\n outerHeight(option) {\n return getWidthHeight(this[0], 'height', option ? 'outerfull' : 'outer');\n },\n outerWidth(option) {\n return getWidthHeight(this[0], 'width', option ? 'outerfull' : 'outer');\n },\n\n /*\n The offset setter method is not implemented\n */\n offset(value) {\n let docElem, win;\n let self = this;\n let box = {\n top: 0,\n left: 0\n };\n let elem = self[0];\n let doc = elem && elem.ownerDocument;\n\n if (arguments.length) {\n if (value === undefined) {\n return self;\n }\n // TODO: implement setter\n throw new Error('offset setter method is not implemented');\n }\n\n if (!doc) {\n return;\n }\n\n docElem = doc.documentElement;\n\n // TODO: Make sure it's not a disconnected DOM node\n\n if (elem.getBoundingClientRect != null) {\n box = elem.getBoundingClientRect();\n }\n\n win = doc.defaultView || doc.parentWindow;\n\n return {\n top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),\n left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)\n };\n },\n scrollTop(value) {\n return scrollTo(this, 'top', value);\n },\n scrollLeft(value) {\n return scrollTo(this, 'left', value);\n }\n }, (value, key) => {\n if (!element.prototype[key]) {\n return element.prototype[key] = value;\n }\n });\n }\n\n}\n","const hideClassToken = 'ng-ui-scroll-hide';\n\nexport default class ElementRoutines {\n\n static addCSSRules() {\n const selector = '.' + hideClassToken;\n const rules = 'display: none';\n const sheet = document.styleSheets[0];\n let index;\n try {\n index = sheet.cssRules.length;\n } catch (err) {\n index = 0;\n }\n if('insertRule' in sheet) {\n sheet.insertRule(selector + '{' + rules + '}', index);\n }\n else if('addRule' in sheet) {\n sheet.addRule(selector, rules, index);\n }\n }\n\n constructor($injector, $q) {\n this.$animate = ($injector.has && $injector.has('$animate')) ? $injector.get('$animate') : null;\n this.isAngularVersionLessThen1_3 = angular.version.major === 1 && angular.version.minor < 3;\n this.$q = $q;\n }\n\n hideElement(wrapper) {\n wrapper.element.addClass(hideClassToken);\n }\n\n showElement(wrapper) {\n wrapper.element.removeClass(hideClassToken);\n }\n\n insertElement(newElement, previousElement) {\n previousElement.after(newElement);\n return [];\n }\n\n removeElement(wrapper) {\n wrapper.element.remove();\n wrapper.scope.$destroy();\n return [];\n }\n\n insertElementAnimated(newElement, previousElement) {\n if (!this.$animate) {\n return this.insertElement(newElement, previousElement);\n }\n\n if (this.isAngularVersionLessThen1_3) {\n const deferred = this.$q.defer();\n // no need for parent - previous element is never null\n this.$animate.enter(newElement, null, previousElement, () => deferred.resolve());\n\n return [deferred.promise];\n }\n\n // no need for parent - previous element is never null\n return [this.$animate.enter(newElement, null, previousElement)];\n }\n\n removeElementAnimated(wrapper) {\n if (!this.$animate) {\n return this.removeElement(wrapper);\n }\n\n if (this.isAngularVersionLessThen1_3) {\n const deferred = this.$q.defer();\n this.$animate.leave(wrapper.element, () => {\n wrapper.scope.$destroy();\n return deferred.resolve();\n });\n\n return [deferred.promise];\n }\n\n return [(this.$animate.leave(wrapper.element)).then(() => wrapper.scope.$destroy())];\n }\n}","export default function ScrollBuffer(elementRoutines, bufferSize, startIndex, rowHeight) {\n const buffer = Object.create(Array.prototype);\n\n angular.extend(buffer, {\n size: bufferSize,\n\n reset(startIndex) {\n buffer.remove(0, buffer.length);\n buffer.eof = false;\n buffer.bof = false;\n buffer.first = startIndex;\n buffer.next = startIndex;\n buffer.minIndex = startIndex; // Calculated when data is effectively accessed\n buffer.maxIndex = startIndex;\n buffer.minIndexUser = null; // as set by the user (datasource)\n buffer.maxIndexUser = null;\n },\n \n // PHIL: set the new index to be displayed without resettng the sroll and the calculated min/max\n // Note that this actually make sense with a fixed rowHeight when the scroll value can be calculated\n // for a # of rows\n resetStartIndex: function resetStartIndex(startIndex) {\n buffer.remove(0, buffer.length);\n buffer.eof = buffer.eof && startIndex==buffer.maxIndex;\n buffer.bof = buffer.bof && startIndex==buffer.minIndex;\n buffer.first = startIndex;\n buffer.next = startIndex;\n },\n\n append(items) {\n items.forEach((item) => {\n ++buffer.next;\n buffer.insert('append', item);\n });\n buffer.maxIndex = buffer.eof ? buffer.next - 1 : Math.max(buffer.next - 1, buffer.maxIndex);\n },\n\n prepend(items) {\n items.reverse().forEach((item) => {\n --buffer.first;\n buffer.insert('prepend', item);\n });\n buffer.minIndex = buffer.bof ? buffer.minIndex = buffer.first : Math.min(buffer.first, buffer.minIndex);\n },\n\n /**\n * inserts wrapped element in the buffer\n * the first argument is either operation keyword (see below) or a number for operation 'insert'\n * for insert the number is the index for the buffer element the new one have to be inserted after\n * operations: 'append', 'prepend', 'insert', 'remove', 'update', 'none'\n */\n insert(operation, item, isTop) {\n const wrapper = {\n item: item\n };\n\n if (operation % 1 === 0) {// it is an insert\n wrapper.op = 'insert';\n buffer.splice(operation, 0, wrapper);\n if(isTop) {\n buffer.first--;\n }\n else {\n buffer.next++;\n }\n } else {\n wrapper.op = operation;\n switch (operation) {\n case 'append':\n buffer.push(wrapper);\n break;\n case 'prepend':\n buffer.unshift(wrapper);\n break;\n }\n }\n },\n\n // removes elements from buffer\n remove(arg1, arg2) {\n if (angular.isNumber(arg1)) {\n // removes items from arg1 (including) through arg2 (excluding)\n for (let i = arg1; i < arg2; i++) {\n elementRoutines.removeElement(buffer[i]);\n }\n return buffer.splice(arg1, arg2 - arg1);\n }\n // removes single item(wrapper) from the buffer\n buffer.splice(buffer.indexOf(arg1), 1);\n if(arg1._op === 'isTop' && buffer.first === this.getAbsMinIndex()) {\n this.incrementMinIndex();\n }\n else {\n this.decrementMaxIndex();\n }\n if(arg1._op === 'isTop') {\n buffer.first++;\n }\n else {\n buffer.next--;\n }\n if(!buffer.length) {\n buffer.first = buffer.minIndex%1 ? buffer.minIndex : startIndex;\n buffer.next = buffer.first;\n buffer.eof = buffer.eof && buffer.first==buffer.maxIndex;\n }\n\n return elementRoutines.removeElementAnimated(arg1);\n },\n\n incrementMinIndex() {\n if(buffer.minIndexUser !== null) {\n if(buffer.minIndex > buffer.minIndexUser) {\n buffer.minIndexUser++;\n return;\n }\n if(buffer.minIndex === buffer.minIndexUser) {\n buffer.minIndexUser++;\n }\n }\n buffer.minIndex++;\n },\n\n decrementMaxIndex() {\n if(buffer.maxIndexUser !== null && buffer.maxIndex <= buffer.maxIndexUser) {\n buffer.maxIndexUser--;\n }\n buffer.maxIndex--;\n },\n\n getAbsMinIndex() {\n if(buffer.minIndexUser !== null) {\n return Math.min(buffer.minIndexUser, buffer.minIndex);\n }\n return buffer.minIndex;\n },\n\n getAbsMaxIndex() {\n if(buffer.maxIndexUser !== null) {\n return Math.max(buffer.maxIndexUser, buffer.maxIndex);\n }\n return buffer.maxIndex;\n },\n\n effectiveHeight(elements) {\n if (!elements.length) {\n return 0;\n }\n let top = Number.MAX_VALUE;\n let bottom = Number.NEGATIVE_INFINITY;\n elements.forEach((wrapper) => {\n if (wrapper.element[0].offsetParent) {\n // element style is not display:none\n top = Math.min(top, wrapper.element.offset().top);\n bottom = Math.max(bottom, wrapper.element.offset().top + (rowHeight || wrapper.element.outerHeight(true)));\n }\n });\n return Math.max(0, bottom - top);\n },\n\n getItems() {\n return buffer.filter(item => item.op === 'none');\n },\n\n getFirstItem() {\n const list = buffer.getItems();\n if (!list.length) {\n return null;\n }\n return list[0].item;\n },\n\n getLastItem() {\n const list = buffer.getItems();\n if (!list.length) {\n return null;\n }\n return list[list.length - 1].item;\n }\n\n });\n\n buffer.reset(startIndex);\n\n return buffer;\n}\n","// Can't just extend the Array, due to Babel does not support built-in classes extending\n// This solution was taken from https://stackoverflow.com/questions/46897414/es6-class-extends-array-workaround-for-es5-babel-transpile\nclass CacheProto {\n add(item) {\n for (let i = this.length - 1; i >= 0; i--) {\n if (this[i].index === item.scope.$index) {\n this[i].height = item.element.outerHeight();\n return;\n }\n }\n this.push({\n index: item.scope.$index,\n height: item.element.outerHeight()\n });\n this.sort((a, b) => ((a.index < b.index) ? -1 : ((a.index > b.index) ? 1 : 0)));\n }\n\n remove(argument, _isTop) {\n const index = argument % 1 === 0 ? argument : argument.scope.$index;\n const isTop = argument % 1 === 0 ? _isTop : argument._op === 'isTop';\n for (let i = this.length - 1; i >= 0; i--) {\n if (this[i].index === index) {\n this.splice(i, 1);\n break;\n }\n }\n if(!isTop) {\n for (let i = this.length - 1; i >= 0; i--) {\n if (this[i].index > index) {\n this[i].index--;\n }\n }\n }\n }\n\n clear() {\n this.length = 0;\n }\n}\n\nfunction Cache() {\n const instance = [];\n instance.push.apply(instance, arguments);\n Object.setPrototypeOf(instance, Cache.prototype);\n return instance;\n}\nCache.prototype = Object.create(Array.prototype);\nObject.getOwnPropertyNames(CacheProto.prototype).forEach(methodName =>\n Cache.prototype[methodName] = CacheProto.prototype[methodName]\n);\n\nfunction generateElement(template) {\n if(template.nodeType !== Node.ELEMENT_NODE) {\n throw new Error('ui-scroll directive requires an Element node for templating the view');\n }\n let element;\n switch (template.tagName.toLowerCase()) {\n case 'dl':\n throw new Error(`ui-scroll directive does not support <${template.tagName}> as a repeating tag: ${template.outerHTML}`);\n case 'tr':\n let table = angular.element('
');\n element = table.find('tr');\n break;\n case 'li':\n element = angular.element('
');\n break;\n default:\n element = angular.element('
');\n }\n return element;\n}\n\n//\n// Padding represents the dummy element added to both the top and the bottom of the scrolling container\n// It holds the element, as well as a cache for the items (rows) height. In case of a fixed rowHeight, the \n// cache is not used and thus is not created.\n//\nclass Padding {\n constructor(template,useCache) {\n this.element = generateElement(template);\n if(useCache) {\n this.cache = new Cache();\n }\n }\n\n height() {\n // When called with a parameter, this sets the height of the padding\n return this.element.height.apply(this.element, arguments);\n }\n}\n\nexport default Padding;","import Padding from './padding';\n\nexport default function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding, rowHeight) {\n let topPadding = null;\n let bottomPadding = null;\n const viewport = viewportController && viewportController.viewport ? viewportController.viewport : angular.element(window);\n const container = viewportController && viewportController.container ? viewportController.container : undefined;\n const scope = viewportController && viewportController.scope ? viewportController.scope : $rootScope;\n\n viewport.css({\n 'overflow-anchor': 'none',\n 'overflow-y': 'auto',\n 'display': 'block'\n });\n\n function bufferPadding() {\n return viewport.outerHeight() * padding; // some extra space to initiate preload\n }\n\n // \n // Viewport measurements\n //\n // +----------------+ 0\n // | top |\n // | padding |\n // +----------------+ topDataPos() [=topPadding.height]\n // | not visible |\n // | items |\n // +----------------+ topVisiblePos() [=viewport.scrollTop]\n // | |\n // | visible |\n // | items |\n // | |\n // +----------------+ bottomVisiblePos() [=viewport.scrollTop+viewport.height]\n // | not visible |\n // | items |\n // +----------------+ bottomDataPos() [=scrollHeight-bottomPadding.height]\n // | bottom |\n // | padding |\n // +----------------+ scrollHeight \n //\n // bufferPadding is some extra space we have top & bottom to allow infinite scrolling\n // bufferPadding = viewport.outerHeight() * padding\n //\n // bottomVisiblePos() - topVisiblePos() == viewport.outerHeight()\n \n\n angular.extend(viewport, {\n getScope() {\n return scope;\n },\n\n createPaddingElements(template) {\n topPadding = new Padding(template,!rowHeight);\n bottomPadding = new Padding(template,!rowHeight);\n element.before(topPadding.element);\n element.after(bottomPadding.element);\n topPadding.height(0);\n bottomPadding.height(0);\n },\n\n applyContainerStyle() {\n if (!container) {\n return true;\n }\n if(container !== viewport) {\n viewport.css('height', window.getComputedStyle(container[0]).height);\n }\n return viewport.height() > 0;\n },\n\n bottomDataPos() {\n let scrollHeight = viewport[0].scrollHeight;\n scrollHeight = scrollHeight != null ? scrollHeight : viewport[0].document.documentElement.scrollHeight;\n return scrollHeight - bottomPadding.height();\n },\n\n topDataPos() {\n return topPadding.height();\n },\n\n bottomVisiblePos() {\n return viewport.scrollTop() + viewport.outerHeight();\n },\n\n topVisiblePos() {\n return viewport.scrollTop();\n },\n\n insertElement(e, sibling) {\n return elementRoutines.insertElement(e, sibling || topPadding.element);\n },\n\n insertElementAnimated(e, sibling) {\n return elementRoutines.insertElementAnimated(e, sibling || topPadding.element);\n },\n\n shouldLoadBottom() {\n return !buffer.eof && viewport.bottomDataPos() < viewport.bottomVisiblePos() + bufferPadding();\n },\n\n clipBottom() {\n // clip the invisible items off the bottom\n let overage = 0;\n let emptySpaceHeight = viewport.bottomDataPos() - viewport.bottomVisiblePos() - bufferPadding();\n if(rowHeight) {\n overage = Math.min(buffer.length,Math.floor(emptySpaceHeight/rowHeight));\n } else {\n let itemHeight = 0;\n let overageHeight = 0;\n\n for (let i = buffer.length - 1; i >= 0; i--) {\n itemHeight = buffer[i].element.outerHeight(true);\n if (overageHeight + itemHeight > emptySpaceHeight) {\n break;\n }\n bottomPadding.cache.add(buffer[i]);\n overageHeight += itemHeight;\n overage++;\n }\n }\n\n if (overage > 0) {\n buffer.eof = false;\n buffer.remove(buffer.length - overage, buffer.length);\n buffer.next -= overage;\n viewport.adjustPaddings();\n }\n },\n\n shouldLoadTop() {\n return !buffer.bof && (viewport.topDataPos() > viewport.topVisiblePos() - bufferPadding());\n },\n\n clipTop() {\n // clip the invisible items off the top\n let overage = 0;\n let overageHeight = 0;\n let emptySpaceHeight = viewport.topVisiblePos() - viewport.topDataPos() - bufferPadding();\n if(rowHeight) {\n overage = Math.min(buffer.length,Math.floor(emptySpaceHeight/rowHeight));\n overageHeight = overage * rowHeight;\n } else {\n let itemHeight = 0;\n\n for (let i = 0; i < buffer.length; i++) {\n itemHeight = buffer[i].element.outerHeight(true);\n if (overageHeight + itemHeight > emptySpaceHeight) {\n break;\n }\n topPadding.cache.add(buffer[i]);\n overageHeight += itemHeight;\n overage++;\n }\n }\n\n if (overage > 0) {\n // we need to adjust top padding element before items are removed from top\n // to avoid strange behaviour of scroll bar during remove top items when we are at the very bottom\n topPadding.height(topPadding.height() + overageHeight);\n buffer.bof = false;\n buffer.remove(0, overage);\n buffer.first += overage;\n }\n },\n\n // PHIL: remove all the entries in the buffer without changing the scrollbar, nor the scroll position\n // and update the padding accordingly\n // It is designed to work with non fixed rowHeight, although it will need more tests in this area...\n scrollTo(first) {\n if(rowHeight) {\n const min = buffer.getAbsMinIndex(); \n const max = buffer.getAbsMaxIndex();\n first = Math.min(Math.max(first, min),max);\n // Adjust the paddings before removing the elements to avoid touching the scroll top position\n topPadding.height((first-min)*rowHeight);\n bottomPadding.height(((max+1)-first)*rowHeight);\n buffer.resetStartIndex(first);\n } else {\n buffer.resetStartIndex(first);\n viewport.adjustPaddings();\n } \n },\n \n adjustPaddings() {\n if(rowHeight) {\n const min = buffer.getAbsMinIndex(); \n const max = buffer.getAbsMaxIndex();\n topPadding.height((buffer.first-min)*rowHeight);\n // PHIL: next points to the next possible item, while max is the index of the last one.\n // In order to make them compatible, we should add one to max\n // Also, it looks like buffer is not changing maxIndex when an element is inserted/appended\n // Not sure if this can have a consequence or not....\n bottomPadding.height(((max+1)-buffer.next)*rowHeight);\n return;\n }\n\n if (!buffer.length) {\n return;\n }\n\n // precise heights calculation based on items that are in buffer or that were in buffer once\n const visibleItemsHeight = buffer.reduce((summ, item) => summ + item.element.outerHeight(true), 0);\n let topPaddingHeight = 0, topCount = 0;\n topPadding.cache.forEach(item => {\n if(item.index < buffer.first) {\n topPaddingHeight += item.height;\n topCount++;\n }\n });\n \n let bottomPaddingHeight = 0, bottomCount = 0;\n bottomPadding.cache.forEach(item => {\n if(item.index >= buffer.next) {\n bottomPaddingHeight += item.height;\n bottomCount++;\n }\n });\n \n const totalHeight = visibleItemsHeight + topPaddingHeight + bottomPaddingHeight;\n const averageItemHeight = totalHeight / (topCount + bottomCount + buffer.length); \n\n // average heights calculation, items that have never been reached\n let adjustTopPadding = buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser;\n let adjustBottomPadding = buffer.maxIndexUser !== null && buffer.maxIndex < buffer.maxIndexUser;\n let topPaddingHeightAdd = adjustTopPadding ? (buffer.minIndex - buffer.minIndexUser) * averageItemHeight : 0;\n let bottomPaddingHeightAdd = adjustBottomPadding ? (buffer.maxIndexUser - buffer.maxIndex) * averageItemHeight : 0;\n\n // paddings combine adjustment\n topPadding.height(topPaddingHeight + topPaddingHeightAdd);\n bottomPadding.height(bottomPaddingHeight + bottomPaddingHeightAdd);\n },\n\n onAfterMinIndexSet(topPaddingHeightOld) {\n // additional scrollTop adjustment in case of datasource.minIndex external set\n if (buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser) {\n let diff = topPadding.height() - topPaddingHeightOld;\n viewport.scrollTop(viewport.scrollTop() + diff);\n while((diff -= viewport.scrollTop()) > 0) {\n bottomPadding.height(bottomPadding.height() + diff);\n viewport.scrollTop(viewport.scrollTop() + diff);\n }\n }\n },\n\n onAfterPrepend(updates) {\n if (!updates.prepended.length)\n return;\n const height = buffer.effectiveHeight(updates.prepended);\n const paddingHeight = topPadding.height() - height;\n if (paddingHeight >= 0) {\n topPadding.height(paddingHeight);\n }\n else {\n topPadding.height(0);\n viewport.scrollTop(viewport.scrollTop() - paddingHeight);\n }\n },\n\n resetTopPadding() {\n topPadding.height(0);\n if(topPadding.cache) {\n topPadding.cache.clear();\n }\n },\n\n resetBottomPadding() {\n bottomPadding.height(0);\n if(bottomPadding.cache) {\n bottomPadding.cache.clear();\n }\n },\n\n removeCacheItem(item, isTop) {\n if(topPadding.cache) {\n topPadding.cache.remove(item, isTop);\n }\n if(bottomPadding.cache) {\n bottomPadding.cache.remove(item, isTop);\n }\n },\n\n removeItem(item) {\n this.removeCacheItem(item);\n return buffer.remove(item);\n }\n });\n\n return viewport;\n}\n","class Adapter {\n\n constructor($scope, $parse, $attr, viewport, buffer, doAdjust, reload) {\n this.$parse = $parse;\n this.$attr = $attr;\n this.viewport = viewport;\n this.buffer = buffer;\n\n this.doAdjust = doAdjust;\n this.reload = reload;\n\n this.isLoading = false;\n this.disabled = false;\n\n const viewportScope = viewport.getScope();\n this.startScope = viewportScope.$parent ? viewportScope : $scope;\n\n this.publicContext = {};\n this.assignAdapter($attr.adapter);\n this.generatePublicContext();\n }\n\n assignAdapter(adapterAttr) {\n if (!adapterAttr || !(adapterAttr = adapterAttr.replace(/^\\s+|\\s+$/gm, ''))) {\n return;\n }\n let adapterOnScope;\n\n try {\n this.$parse(adapterAttr).assign(this.startScope, {});\n adapterOnScope = this.$parse(adapterAttr)(this.startScope);\n }\n catch (error) {\n error.message = `Angular ui-scroll Adapter assignment exception.\\n` +\n `Can't parse \"${adapterAttr}\" expression.\\n` +\n error.message;\n throw error;\n }\n\n angular.extend(adapterOnScope, this.publicContext);\n this.publicContext = adapterOnScope;\n }\n\n generatePublicContext() {\n // these methods will be accessible out of ui-scroll via user defined adapter\n const publicMethods = ['reload', 'applyUpdates', 'append', 'prepend', 'isBOF', 'isEOF', 'isEmpty'];\n for (let i = publicMethods.length - 1; i >= 0; i--) {\n this.publicContext[publicMethods[i]] = this[publicMethods[i]].bind(this);\n }\n\n // these read-only props will be accessible out of ui-scroll via user defined adapter\n const publicProps = ['isLoading', 'topVisible', 'topVisibleElement', 'topVisibleScope', 'bottomVisible', 'bottomVisibleElement', 'bottomVisibleScope'];\n for (let i = publicProps.length - 1; i >= 0; i--) {\n let property, attr = this.$attr[publicProps[i]];\n Object.defineProperty(this, publicProps[i], {\n get: () => property,\n set: (value) => {\n property = value;\n this.publicContext[publicProps[i]] = value;\n if (attr) {\n this.$parse(attr).assign(this.startScope, value);\n }\n }\n });\n }\n\n // read-only immediately calculated public properties\n const publicPropsImmediate = ['bufferFirst', 'bufferLast', 'bufferLength'];\n for (let i = publicPropsImmediate.length - 1; i >= 0; i--) {\n Object.defineProperty(this.publicContext, publicPropsImmediate[i], {\n get: () => this[publicPropsImmediate[i]]\n });\n }\n\n // non-read-only public property\n Object.defineProperty(this.publicContext, 'disabled', {\n get: () => this.disabled,\n set: (value) => (!(this.disabled = value)) ? this.doAdjust() : null\n });\n }\n\n loading(value) {\n this.isLoading = value;\n }\n\n isBOF() {\n return this.buffer.bof;\n }\n\n isEOF() {\n return this.buffer.eof;\n }\n\n isEmpty() {\n return !this.buffer.length;\n }\n\n get bufferLength() {\n return this.buffer.getItems().length;\n }\n\n get bufferFirst() {\n return this.buffer.getFirstItem();\n }\n\n get bufferLast() {\n return this.buffer.getLastItem();\n }\n\n append(newItems) {\n this.buffer.append(newItems);\n this.doAdjust();\n this.viewport.clipTop();\n this.viewport.clipBottom();\n }\n\n prepend(newItems) {\n this.buffer.prepend(newItems);\n this.doAdjust();\n this.viewport.clipTop();\n this.viewport.clipBottom();\n }\n\n applyUpdates(arg1, arg2, arg3) {\n if (typeof arg1 === 'function') {\n this.applyUpdatesFunc(arg1, arg2);\n if(arg2 && arg2.noAdjust) return;\n } else {\n this.applyUpdatesIndex(arg1, arg2, arg3);\n if(arg3 && arg3.noAdjust) return;\n }\n this.doAdjust();\n }\n\n applyUpdatesFunc(cb, options) {\n this.buffer.slice(0).forEach((wrapper) => {\n // we need to do it on the buffer clone, because buffer content\n // may change as we iterate through\n this.applyUpdate(wrapper, cb(wrapper.item, wrapper.scope, wrapper.element), options);\n });\n }\n\n applyUpdatesIndex(index, newItems, options = {}) {\n if (index % 1 !== 0) {\n throw new Error('applyUpdates - ' + index + ' is not a valid index (should be an integer)');\n }\n const _index = index - this.buffer.first;\n\n // apply updates only within buffer\n if (_index >= 0 && _index < this.buffer.length) {\n this.applyUpdate(this.buffer[_index], newItems, options);\n }\n // out-of-buffer case: deletion may affect Paddings\n else if(index >= this.buffer.getAbsMinIndex() && index <= this.buffer.getAbsMaxIndex()) {\n if(angular.isArray(newItems) && !newItems.length) {\n this.viewport.removeCacheItem(index, !options.immutableTop && index === this.buffer.minIndex);\n if (!options.immutableTop && index === this.buffer.getAbsMinIndex()) {\n this.buffer.incrementMinIndex();\n }\n else {\n this.buffer.decrementMaxIndex();\n }\n }\n }\n }\n\n applyUpdate(wrapper, newItems, options = {}) {\n if (!angular.isArray(newItems)) {\n return;\n }\n let position = this.buffer.indexOf(wrapper);\n if (!newItems.reverse().some(newItem => newItem === wrapper.item)) {\n wrapper.op = 'remove';\n if (!options.immutableTop && position === 0 && !newItems.length) {\n wrapper._op = 'isTop'; // to catch \"first\" edge case on remove\n }\n }\n newItems.forEach((newItem) => {\n if (newItem === wrapper.item) {\n position--;\n } else {\n // 3 parameter (isTop) is to catch \"first\" edge case on insert\n this.buffer.insert(position + 1, newItem, !options.immutableTop && position === -1);\n }\n });\n }\n\n calculateProperties() {\n let rowTop = null, topHeight = 0;\n let topDone = false, bottomDone = false;\n const length = this.buffer.length;\n\n for (let i = 0; i < length; i++) {\n const item = this.buffer[i];\n const itemTop = item.element.offset().top;\n\n if (rowTop !== itemTop) { // a new row condition\n const itemHeight = item.element.outerHeight(true);\n const top = this.viewport.topDataPos() + topHeight + itemHeight;\n\n if (!topDone && top > this.viewport.topVisiblePos()) {\n topDone = true;\n this['topVisible'] = item.item;\n this['topVisibleElement'] = item.element;\n this['topVisibleScope'] = item.scope;\n }\n if (!bottomDone && (top >= this.viewport.bottomVisiblePos() || (i === length - 1 && this.isEOF()))) {\n bottomDone = true;\n this['bottomVisible'] = item.item;\n this['bottomVisibleElement'] = item.element;\n this['bottomVisibleScope'] = item.scope;\n }\n topHeight += itemHeight;\n }\n rowTop = itemTop;\n\n if (topDone && bottomDone) {\n break;\n }\n }\n }\n\n}\n\nexport default Adapter;\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';\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 const BUFFER_MIN = 3; // Minimum size of the data source request\n const BUFFER_DEFAULT = 10; // Default datasource request size\n const PADDING_MIN = 0.3; // Mininum # of rows in the padding area\n const PADDING_DEFAULT = 0.5; // Default # of rows in the padding area\n const START_INDEX_DEFAULT = 1; // Default start index when requestng the first data block\n const MAX_VIEWPORT_DELAY = 500; // Max time wait (ms) to get the viewport with an height>0\n const VIEWPORT_POLLING_INTERVAL = 50; // Interval used to check the initial viewport height\n\n let datasource = null;\n const itemName = match[1]; // Name of the index variable to publish\n const datasourceName = match[2]; // Name of the datasource to request the rows from\n const viewportController = controllers[0]; // ViewportController, as specified in the require option (http://websystique.com/angularjs/angularjs-custom-directives-controllers-require-option-guide/)\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 let startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT);\n\n // PHIL: Provide a fixed row height\n // \n const rowHeight = parseNumericAttr($attr.rowHeight, null, false);\n\n // PHIL: Read the visibility watch option, true by default\n const allowVisibilityWatch = $attr.allowVisibilityWatch!=='false';\n\n // Revision IDs\n // \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, rowHeight);\n const viewport = new Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding, rowHeight);\n const adapter = new Adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload);\n\n if (viewportController) {\n viewportController.adapter = adapter;\n }\n\n // Currently, we only debounce the scroll events when a fixed rowHeight is provided\n // as the unit tests will have to be adapted to support this feature\n let scPreviousScrollTop=-1;\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.unbind('mousewheel', wheelHandler);\n });\n\n viewport.bind('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.bind('resize', resizeAndScrollHandler);\n viewport.bind('scroll', resizeAndScrollHandler);\n // If a scroll event happened while the handler was not bounded, emit the scroll\n if(isPendingScroll()) {\n // Do it immediately\n _resizeAndScrollHandler();\n }\n }\n\n function unbindEvents() {\n viewport.unbind('resize', resizeAndScrollHandler);\n viewport.unbind('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 scPreviousScrollTop = -1; // Avoid isScrollPending() to be true\n persistDatasourceIndex(datasource, 'minIndex');\n persistDatasourceIndex(datasource, 'maxIndex');\n doAdjust();\n }\n\n function scrollTo(first) {\n unbindEvents();\n viewport.scrollTo(first);\n doAdjust();\n }\n\n function isElementVisible(wrapper) {\n return (rowHeight || 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 (allowVisibilityWatch && !isElementVisible(wrapper)) {\n wrapper.unregisterVisibilityWatcher = wrapper.scope.$watch(() => visibilityWatcher(wrapper));\n }\n if (allowVisibilityWatch) {\n elementRoutines.hideElement(wrapper); // hide inserted elements before data binding\n }\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 'prepend':\n toBePrepended.unshift(wrapper);\n break;\n case 'append':\n insertWrapperContent(wrapper, i);\n wrapper.op = 'none';\n inserted.push(wrapper);\n break;\n case 'insert':\n promises = promises.concat(createElement(wrapper, i, viewport.insertElementAnimated));\n wrapper.op = 'none';\n inserted.push(wrapper);\n break;\n case '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 = '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 // Adjust the viewport paddings\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 there is a scroll pending, we don't enqueue the fetch as the scroll might be an absolute scroll\n // So we don't need to load top or bottom\n // This happens when there is a scroll frenzi, and the $digest is slow enough, so it stacks the calls without\n // giving a chance to the scroll event to be emitted and processed.\n // We also do that if it leads to an absolute scroll\n if(isPendingScroll() && calculateAbsoluteScroll()!==undefined) {\n // Looks like the event is swallowed on some browsers (FF) on some scroll configuration\n resizeAndScrollHandler();\n return;\n }\n\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 // If there are no changes and the row-height is static, then ignore it!\n const changes = updates.animated.length+updates.inserted.length+updates.prepended.length+updates.removed.length;\n if(changes || !rowHeight) {\n !$scope.$$phase && !$rootScope.$$phase && $scope.$digest();\n }\n\n if (allowVisibilityWatch) {\n updates.inserted.forEach(w => elementRoutines.showElement(w));\n updates.prepended.forEach(w => elementRoutines.showElement(w));\n }\n\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 isPendingScroll() {\n if(rowHeight) {\n // Maybe the scroll changed but the event has *not* yet being dispatched\n // because of the $digest running and taking to long\n var sc = viewport.scrollTop();\n if(sc!=scPreviousScrollTop && scPreviousScrollTop>=0) {\n return true;\n }\n }\n return false;\n }\n\n // Deboucing the scroll events avois intermediate $digest when scrolling fast\n let scTimer;\n function resizeAndScrollHandler() {\n if (rowHeight) {\n if (scTimer) clearTimeout(scTimer);\n scTimer = setTimeout(_resizeAndScrollHandler, 50);\n } else {\n _resizeAndScrollHandler();\n }\n }\n\n function _resizeAndScrollHandler() {\n if (!$rootScope.$$phase && !adapter.isLoading && !adapter.disabled) {\n // Absolute positioning currently only works when a fixed rowHeight is provided\n // We might isolate the averegaRowHeight calculation in the viewport to provide an estimate\n // and provide a reasonable behavior with variable height as well\n if(rowHeight) {\n const newFirst = calculateAbsoluteScroll();\n if(newFirst!==undefined) {\n scrollTo(newFirst);\n return;\n }\n }\n\n enqueueFetch(ridActual);\n\n if (pending.length) {\n unbindEvents();\n } else {\n adapter.calculateProperties();\n if(!rowHeight) {\n // The digest is forced to calculate the height, which is not necessary when the height is knowm\n !$scope.$$phase && $scope.$digest();\n }\n }\n }\n }\n\n function calculateAbsoluteScroll() {\n if(rowHeight) {\n scPreviousScrollTop = viewport.scrollTop();\n let newFirst = Math.floor(viewport.scrollTop() / rowHeight) + buffer.getAbsMinIndex();\n newFirst = Math.max(buffer.getAbsMinIndex(), Math.min(buffer.getAbsMaxIndex(),newFirst)); // Bound the scroll\n if (newFirst
buffer.next+bufferSize) {\n return newFirst;\n } \n }\n return undefined;\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
index b6b5d46e..483f5356 100644
--- a/dist/ui-scroll.min.js
+++ b/dist/ui-scroll.min.js
@@ -1,2 +1,2 @@
-!function(n){var r={};function i(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.m=n,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(n,r,function(e){return t[e]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=1)}([,function(e,t,n){"use strict";function g(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,s=e[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{r||null==s.return||s.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;ni.minIndexUser)return void i.minIndexUser++;i.minIndex===i.minIndexUser&&i.minIndexUser++}i.minIndex++},decrementMaxIndex:function(){null!==i.maxIndexUser&&i.maxIndex<=i.maxIndexUser&&i.maxIndexUser--,i.maxIndex--},getAbsMinIndex:function(){return null!==i.minIndexUser?Math.min(i.minIndexUser,i.minIndex):i.minIndex},getAbsMaxIndex:function(){return null!==i.maxIndexUser?Math.max(i.maxIndexUser,i.maxIndex):i.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)}}),i.reset(t),i}function u(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function l(e,t){for(var n=0;nt.index?1:0})}},{key:"remove",value:function(e,t){for(var n=e%1==0?e:e.scope.$index,r=e%1==0?t:"isTop"===e._op,i=this.length-1;0<=i;i--)if(this[i].index===n){this.splice(i,1);break}if(!r)for(var o=this.length-1;0<=o;o--)this[o].index>n&&this[o].index--}},{key:"clear",value:function(){this.length=0}}]),e}();function d(){var e=[];return e.push.apply(e,arguments),Object.setPrototypeOf(e,d.prototype),e}d.prototype=Object.create(Array.prototype),Object.getOwnPropertyNames(f.prototype).forEach(function(e){return d.prototype[e]=f.prototype[e]});var h=function(){function t(e){u(this,t),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}(e),this.cache=new d}return c(t,[{key:"height",value:function(){return this.element.height.apply(this.element,arguments)}}]),t}();function X(n,c,t,e,r,i){var f=null,d=null,o=e&&e.viewport?e.viewport:angular.element(window),a=e&&e.container?e.container:void 0,s=e&&e.scope?e.scope:r;function u(){return o.outerHeight()*i}return o.css({"overflow-anchor":"none","overflow-y":"auto",display:"block"}),angular.extend(o,{getScope:function(){return s},createPaddingElements:function(e){f=new h(e),d=new h(e),t.before(f.element),t.after(d.element),f.height(0),d.height(0)},applyContainerStyle:function(){return!a||(a!==o&&o.css("height",window.getComputedStyle(a[0]).height),0o.topVisiblePos()-u()},clipTop:function(){for(var e=0,t=0,n=0,r=o.topVisiblePos()-o.topDataPos()-u(),i=0;i=c.next&&(r+=e.height,i++)});var o=(e+t+r)/(n+i+c.length),a=null!==c.minIndexUser&&c.minIndex>c.minIndexUser,s=null!==c.maxIndexUser&&c.maxIndexc.minIndexUser){var t=f.height()-e;for(o.scrollTop(o.scrollTop()+t);0<(t-=o.scrollTop());)d.height(d.height()+t),o.scrollTop(o.scrollTop()+t)}},onAfterPrepend:function(e){if(e.prepended.length){var t=c.effectiveHeight(e.prepended),n=f.height()-t;0<=n?f.height(n):(f.height(0),o.scrollTop(o.scrollTop()-n))}},resetTopPadding:function(){f.height(0),f.cache.clear()},resetBottomPadding:function(){d.height(0),d.cache.clear()},removeCacheItem:function(e,t){f.cache.remove(e,t),d.cache.remove(e,t)},removeItem:function(e){return this.removeCacheItem(e),c.remove(e)}}),o}function p(e,t){for(var n=0;n=this.buffer.getAbsMinIndex()&&e<=this.buffer.getAbsMaxIndex()&&angular.isArray(t)&&!t.length&&(this.viewport.removeCacheItem(e,e===this.buffer.minIndex),e===this.buffer.getAbsMinIndex()?this.buffer.incrementMinIndex():this.buffer.decrementMaxIndex())}},{key:"applyUpdate",value:function(t,e){var n=this;if(angular.isArray(e)){var r=this.buffer.indexOf(t);e.reverse().some(function(e){return e===t.item})||(t.op="remove",0!==r||e.length||(t._op="isTop")),e.forEach(function(e){e===t.item?r--:n.buffer.insert(r+1,e,-1===r)})}}},{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+=u}if(e=s,n&&r)break}}}])&&p(e.prototype,t),n&&p(e,n),u}();angular.module("ui.scroll",[]).constant("JQLiteExtras",r).run(["JQLiteExtras",function(e){!window.jQuery&&(new e).registerFor(angular.element),q.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,B,D,F,R,W,z){return{require:["?^uiScrollViewport"],restrict:"A",transclude:"element",priority:1e3,terminal:!0,link:function(i,e,t,n,a){var r=t.uiScroll.match(/^\s*(\w+)\s+in\s+([(\w|\$)\.]+)\s*$/);if(!r)throw new Error("Expected uiScroll in form of '_item_ in _datasource_' but got '"+t.uiScroll+"'");function o(e,t,n){return n||(e=null===e?t:Math.floor(e)),isNaN(e)?t:e}function s(e,t,n){var r=z(e)(i);return o(r,t,n)}var u=null,l=r[1],c=r[2],f=n[0],d=Math.max(3,s(t.bufferSize,10)),h=Math.max(.3,s(t.padding,.5,!0)),p=s(t.startIndex,1),m=0,g=[],v=new q(B,W),b=new Q(v,d,p),x=new X(v,b,e,f,D,h),y=new Y(i,z,t,x,b,C,function(){x.resetTopPadding(),x.resetBottomPadding(),arguments.length&&(p=o(arguments[0],1,!1));b.reset(p),E(u,"minIndex"),E(u,"maxIndex"),C()});f&&(f.adapter=y);var w=function(){return"[object Object]"===Object.prototype.toString.call(u)&&"function"==typeof u.get};if(u=z(c)(i),!w()&&(u=B.get(c),!w()))throw new Error(c+" is not a valid datasource");var I=[];function E(e,t){var n;angular.isNumber(e[t])&&(n=e[t],angular.isNumber(n)&&(I=I.filter(function(e){return e.id!==t})).push({id:t,run:function(){return e[t]=n}}))}function $(n,r,i){var o,e=Object.getOwnPropertyDescriptor(n,r);e&&(e.set||e.get)||(E(n,r),Object.defineProperty(n,r,{set:function(e){if(o=e,!g.length||b.length){b[i]=e;var t=x.topDataPos();x.adjustPaddings(),"minIndex"===r&&x.onAfterMinIndexSet(t)}else E(n,r)},get:function(){return o}}))}$(u,"minIndex","minIndexUser"),$(u,"maxIndex","maxIndexUser");var P=2!==u.get.length?function(e){return u.get(b.next,d,e)}:function(e){u.get({index:b.next,append:b.length?b[b.length-1].item:void 0,count:d},e)},T=2!==u.get.length?function(e){return u.get(b.first-d,d,e)}:function(e){u.get({index:b.first-d,prepend:b.length?b[0].item:void 0,count:d},e)};function S(e){return e&&e!==m||i.$$destroyed}function k(){x.unbind("resize",_),x.unbind("scroll",_)}function A(e){return e.element.height()&&e.element[0].offsetParent}function O(e,t){j(e,t,x.insertElement),A(e)||(e.unregisterVisibilityWatcher=e.scope.$watch(function(){A(e)&&(b.forEach(function(e){"function"==typeof e.unregisterVisibilityWatcher&&(e.unregisterVisibilityWatcher(),delete e.unregisterVisibilityWatcher)}),g.length||F(function(){return C()}))})),v.hideElement(e)}function j(n,e,r){var i=null,o=0a.minIndexUser)return void a.minIndexUser++;a.minIndex===a.minIndexUser&&a.minIndexUser++}a.minIndex++},decrementMaxIndex:function(){null!==a.maxIndexUser&&a.maxIndex<=a.maxIndexUser&&a.maxIndexUser--,a.maxIndex--},getAbsMinIndex:function(){return null!==a.minIndexUser?Math.min(a.minIndexUser,a.minIndex):a.minIndex},getAbsMaxIndex:function(){return null!==a.maxIndexUser?Math.max(a.maxIndexUser,a.maxIndex):a.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+(o||e.element.outerHeight(!0))))}),Math.max(0,n-t)},getItems:function(){return a.filter(function(e){return"none"===e.op})},getFirstItem:function(){var e=a.getItems();return e.length?e[0].item:null},getLastItem:function(){var e=a.getItems();return e.length?e[e.length-1].item:null}}),a.reset(i),a}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function l(e,t){for(var n=0;nt.index?1:0})}},{key:"remove",value:function(e,t){for(var n=e%1==0?e:e.scope.$index,r=e%1==0?t:"isTop"===e._op,i=this.length-1;0<=i;i--)if(this[i].index===n){this.splice(i,1);break}if(!r)for(var o=this.length-1;0<=o;o--)this[o].index>n&&this[o].index--}},{key:"clear",value:function(){this.length=0}}]),e}();function d(){var e=[];return e.push.apply(e,arguments),Object.setPrototypeOf(e,d.prototype),e}d.prototype=Object.create(Array.prototype),Object.getOwnPropertyNames(c.prototype).forEach(function(e){return d.prototype[e]=c.prototype[e]});var v=function(){function n(e,t){s(this,n),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}(e),t&&(this.cache=new d)}return f(n,[{key:"height",value:function(){return this.element.height.apply(this.element,arguments)}}]),n}();function te(n,d,t,e,r,i,h){var p=null,m=null,o=e&&e.viewport?e.viewport:angular.element(window),a=e&&e.container?e.container:void 0,u=e&&e.scope?e.scope:r;function s(){return o.outerHeight()*i}return o.css({"overflow-anchor":"none","overflow-y":"auto",display:"block"}),angular.extend(o,{getScope:function(){return u},createPaddingElements:function(e){p=new v(e,!h),m=new v(e,!h),t.before(p.element),t.after(m.element),p.height(0),m.height(0)},applyContainerStyle:function(){return!a||(a!==o&&o.css("height",window.getComputedStyle(a[0]).height),0o.topVisiblePos()-s()},clipTop:function(){var e=0,t=0,n=o.topVisiblePos()-o.topDataPos()-s();if(h)t=(e=Math.min(d.length,Math.floor(n/h)))*h;else for(var r=0,i=0;i=d.next&&(o+=e.height,a++)});var u=(n+r+o)/(i+a+d.length),s=null!==d.minIndexUser&&d.minIndex>d.minIndexUser,l=null!==d.maxIndexUser&&d.maxIndexd.minIndexUser){var t=p.height()-e;for(o.scrollTop(o.scrollTop()+t);0<(t-=o.scrollTop());)m.height(m.height()+t),o.scrollTop(o.scrollTop()+t)}},onAfterPrepend:function(e){if(e.prepended.length){var t=d.effectiveHeight(e.prepended),n=p.height()-t;0<=n?p.height(n):(p.height(0),o.scrollTop(o.scrollTop()-n))}},resetTopPadding:function(){p.height(0),p.cache&&p.cache.clear()},resetBottomPadding:function(){m.height(0),m.cache&&m.cache.clear()},removeCacheItem:function(e,t){p.cache&&p.cache.remove(e,t),m.cache&&m.cache.remove(e,t)},removeItem:function(e){return this.removeCacheItem(e),d.remove(e)}}),o}function h(e,t){for(var n=0;n=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(t,e){var n=this,r=2this.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()}}])&&h(e.prototype,t),n&&h(e,n),s}();angular.module("ui.scroll",[]).constant("JQLiteExtras",r).run(["JQLiteExtras",function(e){var t=angular.element;!(window.jQuery&&t.fn&&t.fn.jquery)&&(new e).registerFor(t),Z.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,Q,X,Y,J,G,K){return{require:["?^uiScrollViewport"],restrict:"A",transclude:"element",priority:1e3,terminal:!0,link:function(i,e,t,n,a){var r=t.uiScroll.match(/^\s*(\w+)\s+in\s+([(\w|\$)\.]+)\s*$/);if(!r)throw new Error("Expected uiScroll in form of '_item_ in _datasource_' but got '"+t.uiScroll+"'");function o(e,t,n){return n||(e=null===e?t:Math.floor(e)),isNaN(e)?t:e}function u(e,t,n){var r=K(e)(i);return o(r,t,n)}var s=null,l=r[1],f=r[2],c=n[0],d=Math.max(3,u(t.bufferSize,10)),h=Math.max(.3,u(t.padding,.5,!0)),p=u(t.startIndex,1),m=u(t.rowHeight,null,!1),g="false"!==t.allowVisibilityWatch,v=0,b=[],x=new Z(Q,G),y=new ee(x,d,p,m),I=new te(x,y,e,c,X,h,m),w=new ne(i,K,t,I,y,N,function(){O(),I.resetTopPadding(),I.resetBottomPadding(),arguments.length&&(p=o(arguments[0],1,!1));y.reset(p),E=-1,P(s,"minIndex"),P(s,"maxIndex"),N()});c&&(c.adapter=w);var E=-1,T=function(){return"[object Object]"===Object.prototype.toString.call(s)&&"function"==typeof s.get};if(s=K(f)(i),!T()&&(s=Q.get(f),!T()))throw new Error(f+" is not a valid datasource");var $=[];function P(e,t){var n;angular.isNumber(e[t])&&(n=e[t],angular.isNumber(n)&&($=$.filter(function(e){return e.id!==t})).push({id:t,run:function(){return e[t]=n}}))}function M(n,r,i){var o,e=Object.getOwnPropertyDescriptor(n,r);e&&(e.set||e.get)||(P(n,r),Object.defineProperty(n,r,{set:function(e){if(o=e,!b.length||y.length){y[i]=e;var t=I.topDataPos();I.adjustPaddings(),"minIndex"===r&&I.onAfterMinIndexSet(t)}else P(n,r)},get:function(){return o}}))}M(s,"minIndex","minIndexUser"),M(s,"maxIndex","maxIndexUser");var A,S=2!==s.get.length?function(e){return s.get(y.next,d,e)}:function(e){s.get({index:y.next,append:y.length?y[y.length-1].item:void 0,count:d},e)},k=2!==s.get.length?function(e){return s.get(y.first-d,d,e)}:function(e){s.get({index:y.first-d,prepend:y.length?y[0].item:void 0,count:d},e)};function j(e){return e&&e!==v||i.$$destroyed}function O(){I.unbind("resize",R),I.unbind("scroll",R)}function L(e){return(m||e.element.height())&&e.element[0].offsetParent}function U(e,t){V(e,t,I.insertElement),g&&!L(e)&&(e.unregisterVisibilityWatcher=e.scope.$watch(function(){L(e)&&(y.forEach(function(e){"function"==typeof e.unregisterVisibilityWatcher&&(e.unregisterVisibilityWatcher(),delete e.unregisterVisibilityWatcher)}),b.length||Y(function(){return N()}))})),g&&x.hideElement(e)}function V(n,e,r){var i=null,o=0y.next+d)return e}}function z(e){if(!w.disabled){var t=I[0].scrollTop,n=I[0].scrollHeight-I[0].clientHeight;(0===t&&!y.bof||t===n&&!y.eof)&&e.preventDefault()}}a(function(e,t){I.createPaddingElements(e[0]),t.$destroy(),e.remove()}),i.$on("$destroy",function(){O(),I.unbind("mousewheel",z)}),I.bind("mousewheel",z),function(){var e=0;if(I.applyContainerStyle())N();else var t=J(function(){if(e++,I.applyContainerStyle()&&(J.cancel(t),N()),500<=50*e)throw J.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
index 821f66bf..5c9174da 100644
--- a/dist/ui-scroll.min.js.map
+++ b/dist/ui-scroll.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/modules/jqLiteExtras.js","webpack:///./src/modules/elementRoutines.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$direction","_slicedToArray","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","_width$height$measure","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","elementRoutines_classCallCheck","$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","ScrollBuffer","elementRoutines","bufferSize","startIndex","buffer","Array","extend","size","reset","eof","bof","first","next","minIndex","maxIndex","minIndexUser","maxIndexUser","append","items","item","insert","Math","max","reverse","min","operation","isTop","op","splice","push","unshift","arg1","arg2","indexOf","_op","getAbsMinIndex","incrementMinIndex","decrementMaxIndex","removeElementAnimated","getAbsMaxIndex","effectiveHeight","elements","Number","MAX_VALUE","bottom","NEGATIVE_INFINITY","offsetParent","CacheProto","$index","sort","a","b","argument","_isTop","Cache","instance","apply","setPrototypeOf","getOwnPropertyNames","methodName","Padding","template","padding_classCallCheck","Node","ELEMENT_NODE","tagName","toLowerCase","concat","find","generateElement","cache","Viewport","viewportController","$rootScope","topPadding","bottomPadding","viewport","container","bufferPadding","overflow-anchor","overflow-y","display","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","resetTopPadding","clear","resetBottomPadding","removeCacheItem","removeItem","Adapter","$scope","$parse","$attr","doAdjust","reload","adapter_classCallCheck","isLoading","disabled","viewportScope","startScope","$parent","publicContext","assignAdapter","adapter","generatePublicContext","adapterAttr","replace","adapterOnScope","assign","error","message","_this","publicMethods","publicProps","_loop","attr","set","newItems","applyUpdatesFunc","applyUpdatesIndex","cb","_this2","slice","applyUpdate","_index","isArray","_this3","position","some","newItem","rowTop","topHeight","topDone","bottomDone","itemTop","isEOF","constant","run","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","ridActual","pending","persistDatasourceIndex","isDatasourceValid","toString","onRenderHandlers","propName","filter","handler","id","defineDatasourceIndex","propUserName","descriptor","getOwnPropertyDescriptor","fetchNext","success","count","fetchPrevious","isInvalid","rid","$$destroyed","unbindEvents","unbind","resizeAndScrollHandler","isElementVisible","insertWrapperContent","insertAfter","createElement","unregisterVisibilityWatcher","$watch","hideElement","promises","clone","transform","tdInitializer","uiScrollTdInitializer","linking","onLink","updatePaddings","animated","all","enqueueFetch","inserted","loading","fetch","processUpdates","toBePrepended","toBeRemoved","removed","updateDOM","$$phase","$digest","w","showElement","calculateProperties","doAdjustAfterFetch","shift","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 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('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) {\r\n items.reverse().forEach((item) => {\r\n --buffer.first;\r\n buffer.insert('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', 'update', 'none'\r\n */\r\n insert(operation, item, isTop) {\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 = 'insert';\r\n buffer.splice(operation, 0, wrapper);\r\n if(isTop) {\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 'append':\r\n buffer.push(wrapper);\r\n break;\r\n case '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._op === 'isTop' && buffer.first === this.getAbsMinIndex()) {\r\n this.incrementMinIndex();\r\n }\r\n else {\r\n this.decrementMaxIndex();\r\n }\r\n if(arg1._op === 'isTop') {\r\n buffer.first++;\r\n }\r\n else {\r\n buffer.next--;\r\n }\r\n if(!buffer.length) {\r\n buffer.first = 1;\r\n buffer.next = 1;\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 });\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, _isTop) {\r\n const index = argument % 1 === 0 ? argument : argument.scope.$index;\r\n const isTop = argument % 1 === 0 ? _isTop : argument._op === 'isTop';\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(!isTop) {\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 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 }\r\n else {\r\n topPadding.height(0);\r\n viewport.scrollTop(viewport.scrollTop() - paddingHeight);\r\n }\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, isTop) {\r\n topPadding.cache.remove(item, isTop);\r\n bottomPadding.cache.remove(item, isTop);\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","class 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 // 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 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) {\r\n this.buffer.prepend(newItems);\r\n this.doAdjust();\r\n this.viewport.clipTop();\r\n this.viewport.clipBottom();\r\n }\r\n\r\n applyUpdates(arg1, arg2) {\r\n if (typeof arg1 === 'function') {\r\n this.applyUpdatesFunc(arg1);\r\n } else {\r\n this.applyUpdatesIndex(arg1, arg2);\r\n }\r\n this.doAdjust();\r\n }\r\n\r\n applyUpdatesFunc(cb) {\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));\r\n });\r\n }\r\n\r\n applyUpdatesIndex(index, newItems) {\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);\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, index === this.buffer.minIndex);\r\n if(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) {\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 = 'remove';\r\n if(position === 0 && !newItems.length) {\r\n wrapper._op = 'isTop'; // to catch \"first\" edge case on remove\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 (isTop) is to catch \"first\" edge case on insert\r\n this.buffer.insert(position + 1, newItem, 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';\n\nangular.module('ui.scroll', [])\n\n .constant('JQLiteExtras', JQLiteExtras)\n .run(['JQLiteExtras', (JQLiteExtras) => {\n !window.jQuery ? (new JQLiteExtras()).registerFor(angular.element) : 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 const BUFFER_MIN = 3;\n const BUFFER_DEFAULT = 10;\n const PADDING_MIN = 0.3;\n const PADDING_DEFAULT = 0.5;\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 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.unbind('mousewheel', wheelHandler);\n });\n\n viewport.bind('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.bind('resize', resizeAndScrollHandler);\n viewport.bind('scroll', resizeAndScrollHandler);\n }\n\n function unbindEvents() {\n viewport.unbind('resize', resizeAndScrollHandler);\n viewport.unbind('scroll', resizeAndScrollHandler);\n }\n\n function reload() {\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 'prepend':\n toBePrepended.unshift(wrapper);\n break;\n case 'append':\n insertWrapperContent(wrapper, i);\n wrapper.op = 'none';\n inserted.push(wrapper);\n break;\n case 'insert':\n promises = promises.concat(createElement(wrapper, i, viewport.insertElementAnimated));\n wrapper.op = 'none';\n inserted.push(wrapper);\n break;\n case '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 = '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 resizeAndScrollHandler() {\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
+{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/modules/jqLiteExtras.js","webpack:///./src/modules/elementRoutines.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$direction","_slicedToArray","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","_width$height$measure","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","elementRoutines_classCallCheck","$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","ScrollBuffer","elementRoutines","bufferSize","startIndex","rowHeight","buffer","Array","extend","size","reset","eof","bof","first","next","minIndex","maxIndex","minIndexUser","maxIndexUser","resetStartIndex","append","items","item","insert","Math","max","reverse","min","operation","isTop","op","splice","push","unshift","arg1","arg2","indexOf","_op","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","_isTop","Cache","instance","apply","setPrototypeOf","getOwnPropertyNames","methodName","Padding","template","useCache","padding_classCallCheck","Node","ELEMENT_NODE","tagName","toLowerCase","concat","find","generateElement","cache","Viewport","viewportController","$rootScope","topPadding","bottomPadding","viewport","container","bufferPadding","overflow-anchor","overflow-y","display","getScope","createPaddingElements","applyContainerStyle","bottomDataPos","scrollHeight","topDataPos","bottomVisiblePos","topVisiblePos","e","sibling","insertElementAnimated","shouldLoadBottom","clipBottom","overage","emptySpaceHeight","floor","itemHeight","overageHeight","add","adjustPaddings","shouldLoadTop","clipTop","visibleItemsHeight","reduce","summ","topPaddingHeight","topCount","bottomPaddingHeight","bottomCount","averageItemHeight","adjustTopPadding","adjustBottomPadding","topPaddingHeightAdd","bottomPaddingHeightAdd","onAfterMinIndexSet","topPaddingHeightOld","diff","onAfterPrepend","updates","prepended","paddingHeight","resetTopPadding","clear","resetBottomPadding","removeCacheItem","removeItem","Adapter","$scope","$parse","$attr","doAdjust","reload","adapter_classCallCheck","isLoading","disabled","viewportScope","startScope","$parent","publicContext","assignAdapter","adapter","generatePublicContext","adapterAttr","replace","adapterOnScope","assign","error","message","_this","publicMethods","publicProps","_loop","attr","set","publicPropsImmediate","_loop2","newItems","arg3","applyUpdatesFunc","noAdjust","applyUpdatesIndex","cb","options","_this2","slice","applyUpdate","_index","isArray","immutableTop","_this3","position","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","isNaN","parseNumericAttr","datasource","itemName","datasourceName","allowVisibilityWatch","ridActual","pending","unbindEvents","scPreviousScrollTop","persistDatasourceIndex","isDatasourceValid","toString","onRenderHandlers","propName","handler","id","defineDatasourceIndex","propUserName","descriptor","getOwnPropertyDescriptor","scTimer","fetchNext","success","count","fetchPrevious","isInvalid","rid","$$destroyed","unbind","resizeAndScrollHandler","isElementVisible","insertWrapperContent","insertAfter","createElement","unregisterVisibilityWatcher","$watch","hideElement","promises","clone","transform","tdInitializer","uiScrollTdInitializer","linking","onLink","updatePaddings","animated","all","enqueueFetch","isPendingScroll","calculateAbsoluteScroll","inserted","loading","fetch","processUpdates","toBePrepended","toBeRemoved","removed","updateDOM","changes","$$phase","$digest","w","showElement","calculateProperties","doAdjustAfterFetch","shift","_resizeAndScrollHandler","sc","clearTimeout","setTimeout","newFirst","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","/*!\n globals: angular, window\n List of used element methods available in JQuery but not in JQuery Lite\n element.before(elem)\n element.height()\n element.outerHeight(true)\n element.height(value) = only for Top/Bottom padding elements\n element.scrollTop()\n element.scrollTop(value)\n */\n\nexport default class JQLiteExtras {\n\n registerFor(element) {\n let convertToPx, css, getStyle, isWindow;\n // angular implementation blows up if elem is the window\n css = angular.element.prototype.css;\n\n element.prototype.css = function (name, value) {\n let self = this;\n let elem = self[0];\n if (!(!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style)) {\n return css.call(self, name, value);\n }\n };\n\n // as defined in angularjs v1.0.5\n isWindow = (obj) => obj && obj.document && obj.location && obj.alert && obj.setInterval;\n\n function scrollTo(self, direction, value) {\n let elem = self[0];\n let [method, prop, preserve] = {\n top: [\n 'scrollTop',\n 'pageYOffset',\n 'scrollLeft'\n ],\n left: [\n 'scrollLeft',\n 'pageXOffset',\n 'scrollTop'\n ]\n }[direction];\n\n const isValueDefined = typeof value !== 'undefined';\n if (isWindow(elem)) {\n if (isValueDefined) {\n return elem.scrollTo(self[preserve].call(self), value);\n }\n return (prop in elem) ? elem[prop] : elem.document.documentElement[method];\n } else {\n if (isValueDefined) {\n elem[method] = value;\n }\n return elem[method];\n }\n }\n\n if (window.getComputedStyle) {\n getStyle = (elem) => window.getComputedStyle(elem, null);\n convertToPx = (elem, value) => parseFloat(value);\n } else {\n getStyle = (elem) => elem.currentStyle;\n convertToPx = (elem, value) => {\n let left, result, rs, rsLeft, style;\n let core_pnum = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source;\n let rnumnonpx = new RegExp('^(' + core_pnum + ')(?!px)[a-z%]+$', 'i');\n\n if (!rnumnonpx.test(value)) {\n return parseFloat(value);\n }\n\n // ported from JQuery\n style = elem.style;\n left = style.left;\n rs = elem.runtimeStyle;\n rsLeft = rs && rs.left;\n if (rs) {\n rs.left = style.left;\n }\n // put in the new values to get a computed style out\n style.left = value;\n result = style.pixelLeft;\n style.left = left;\n if (rsLeft) {\n rs.left = rsLeft;\n }\n return result;\n };\n }\n\n function getMeasurements(elem, measure) {\n let base, borderA, borderB, computedMarginA, computedMarginB, computedStyle, dirA, dirB, marginA, marginB, paddingA, paddingB;\n\n if (isWindow(elem)) {\n base = document.documentElement[{height: 'clientHeight', width: 'clientWidth'}[measure]];\n\n return {\n base: base,\n padding: 0,\n border: 0,\n margin: 0\n };\n }\n\n // Start with offset property\n [\n base,\n dirA,\n dirB\n ] = {\n width: [\n elem.offsetWidth,\n 'Left',\n 'Right'\n ],\n height: [\n elem.offsetHeight,\n 'Top',\n 'Bottom'\n ]\n }[measure];\n\n computedStyle = getStyle(elem);\n paddingA = convertToPx(elem, computedStyle['padding' + dirA]) || 0;\n paddingB = convertToPx(elem, computedStyle['padding' + dirB]) || 0;\n borderA = convertToPx(elem, computedStyle['border' + dirA + 'Width']) || 0;\n borderB = convertToPx(elem, computedStyle['border' + dirB + 'Width']) || 0;\n computedMarginA = computedStyle['margin' + dirA];\n computedMarginB = computedStyle['margin' + dirB];\n\n // I do not care for width for now, so this hack is irrelevant\n // if ( !supportsPercentMargin )\n // computedMarginA = hackPercentMargin( elem, computedStyle, computedMarginA )\n // computedMarginB = hackPercentMargin( elem, computedStyle, computedMarginB )\n marginA = convertToPx(elem, computedMarginA) || 0;\n marginB = convertToPx(elem, computedMarginB) || 0;\n\n return {\n base: base,\n padding: paddingA + paddingB,\n border: borderA + borderB,\n margin: marginA + marginB\n };\n }\n\n function getWidthHeight(elem, direction, measure) {\n let computedStyle, result;\n\n let measurements = getMeasurements(elem, direction);\n\n if (measurements.base > 0) {\n return {\n base: measurements.base - measurements.padding - measurements.border,\n outer: measurements.base,\n outerfull: measurements.base + measurements.margin\n }[measure];\n }\n\n // Fall back to computed then uncomputed css if necessary\n computedStyle = getStyle(elem);\n result = computedStyle[direction];\n\n if (result < 0 || result === null) {\n result = elem.style[direction] || 0;\n }\n\n // Normalize \"\", auto, and prepare for extra\n result = parseFloat(result) || 0;\n\n return {\n base: result - measurements.padding - measurements.border,\n outer: result,\n outerfull: result + measurements.padding + measurements.border + measurements.margin\n }[measure];\n }\n\n // define missing methods\n return angular.forEach({\n before(newElem) {\n var children, elem, i, j, parent, ref, self;\n self = this;\n elem = self[0];\n parent = self.parent();\n children = parent.contents();\n if (children[0] === elem) {\n return parent.prepend(newElem);\n } else {\n for (i = j = 1, ref = children.length - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) {\n if (children[i] === elem) {\n angular.element(children[i - 1]).after(newElem);\n return;\n }\n }\n throw new Error('invalid DOM structure ' + elem.outerHTML);\n }\n },\n height (value){\n var self;\n self = this;\n if (typeof value !== 'undefined') {\n if (angular.isNumber(value)) {\n value = value + 'px';\n }\n return css.call(self, 'height', value);\n } else {\n return getWidthHeight(this[0], 'height', 'base');\n }\n },\n outerHeight(option) {\n return getWidthHeight(this[0], 'height', option ? 'outerfull' : 'outer');\n },\n outerWidth(option) {\n return getWidthHeight(this[0], 'width', option ? 'outerfull' : 'outer');\n },\n\n /*\n The offset setter method is not implemented\n */\n offset(value) {\n let docElem, win;\n let self = this;\n let box = {\n top: 0,\n left: 0\n };\n let elem = self[0];\n let doc = elem && elem.ownerDocument;\n\n if (arguments.length) {\n if (value === undefined) {\n return self;\n }\n // TODO: implement setter\n throw new Error('offset setter method is not implemented');\n }\n\n if (!doc) {\n return;\n }\n\n docElem = doc.documentElement;\n\n // TODO: Make sure it's not a disconnected DOM node\n\n if (elem.getBoundingClientRect != null) {\n box = elem.getBoundingClientRect();\n }\n\n win = doc.defaultView || doc.parentWindow;\n\n return {\n top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),\n left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)\n };\n },\n scrollTop(value) {\n return scrollTo(this, 'top', value);\n },\n scrollLeft(value) {\n return scrollTo(this, 'left', value);\n }\n }, (value, key) => {\n if (!element.prototype[key]) {\n return element.prototype[key] = value;\n }\n });\n }\n\n}\n","const hideClassToken = 'ng-ui-scroll-hide';\n\nexport default class ElementRoutines {\n\n static addCSSRules() {\n const selector = '.' + hideClassToken;\n const rules = 'display: none';\n const sheet = document.styleSheets[0];\n let index;\n try {\n index = sheet.cssRules.length;\n } catch (err) {\n index = 0;\n }\n if('insertRule' in sheet) {\n sheet.insertRule(selector + '{' + rules + '}', index);\n }\n else if('addRule' in sheet) {\n sheet.addRule(selector, rules, index);\n }\n }\n\n constructor($injector, $q) {\n this.$animate = ($injector.has && $injector.has('$animate')) ? $injector.get('$animate') : null;\n this.isAngularVersionLessThen1_3 = angular.version.major === 1 && angular.version.minor < 3;\n this.$q = $q;\n }\n\n hideElement(wrapper) {\n wrapper.element.addClass(hideClassToken);\n }\n\n showElement(wrapper) {\n wrapper.element.removeClass(hideClassToken);\n }\n\n insertElement(newElement, previousElement) {\n previousElement.after(newElement);\n return [];\n }\n\n removeElement(wrapper) {\n wrapper.element.remove();\n wrapper.scope.$destroy();\n return [];\n }\n\n insertElementAnimated(newElement, previousElement) {\n if (!this.$animate) {\n return this.insertElement(newElement, previousElement);\n }\n\n if (this.isAngularVersionLessThen1_3) {\n const deferred = this.$q.defer();\n // no need for parent - previous element is never null\n this.$animate.enter(newElement, null, previousElement, () => deferred.resolve());\n\n return [deferred.promise];\n }\n\n // no need for parent - previous element is never null\n return [this.$animate.enter(newElement, null, previousElement)];\n }\n\n removeElementAnimated(wrapper) {\n if (!this.$animate) {\n return this.removeElement(wrapper);\n }\n\n if (this.isAngularVersionLessThen1_3) {\n const deferred = this.$q.defer();\n this.$animate.leave(wrapper.element, () => {\n wrapper.scope.$destroy();\n return deferred.resolve();\n });\n\n return [deferred.promise];\n }\n\n return [(this.$animate.leave(wrapper.element)).then(() => wrapper.scope.$destroy())];\n }\n}","export default function ScrollBuffer(elementRoutines, bufferSize, startIndex, rowHeight) {\n const buffer = Object.create(Array.prototype);\n\n angular.extend(buffer, {\n size: bufferSize,\n\n reset(startIndex) {\n buffer.remove(0, buffer.length);\n buffer.eof = false;\n buffer.bof = false;\n buffer.first = startIndex;\n buffer.next = startIndex;\n buffer.minIndex = startIndex; // Calculated when data is effectively accessed\n buffer.maxIndex = startIndex;\n buffer.minIndexUser = null; // as set by the user (datasource)\n buffer.maxIndexUser = null;\n },\n \n // PHIL: set the new index to be displayed without resettng the sroll and the calculated min/max\n // Note that this actually make sense with a fixed rowHeight when the scroll value can be calculated\n // for a # of rows\n resetStartIndex: function resetStartIndex(startIndex) {\n buffer.remove(0, buffer.length);\n buffer.eof = buffer.eof && startIndex==buffer.maxIndex;\n buffer.bof = buffer.bof && startIndex==buffer.minIndex;\n buffer.first = startIndex;\n buffer.next = startIndex;\n },\n\n append(items) {\n items.forEach((item) => {\n ++buffer.next;\n buffer.insert('append', item);\n });\n buffer.maxIndex = buffer.eof ? buffer.next - 1 : Math.max(buffer.next - 1, buffer.maxIndex);\n },\n\n prepend(items) {\n items.reverse().forEach((item) => {\n --buffer.first;\n buffer.insert('prepend', item);\n });\n buffer.minIndex = buffer.bof ? buffer.minIndex = buffer.first : Math.min(buffer.first, buffer.minIndex);\n },\n\n /**\n * inserts wrapped element in the buffer\n * the first argument is either operation keyword (see below) or a number for operation 'insert'\n * for insert the number is the index for the buffer element the new one have to be inserted after\n * operations: 'append', 'prepend', 'insert', 'remove', 'update', 'none'\n */\n insert(operation, item, isTop) {\n const wrapper = {\n item: item\n };\n\n if (operation % 1 === 0) {// it is an insert\n wrapper.op = 'insert';\n buffer.splice(operation, 0, wrapper);\n if(isTop) {\n buffer.first--;\n }\n else {\n buffer.next++;\n }\n } else {\n wrapper.op = operation;\n switch (operation) {\n case 'append':\n buffer.push(wrapper);\n break;\n case 'prepend':\n buffer.unshift(wrapper);\n break;\n }\n }\n },\n\n // removes elements from buffer\n remove(arg1, arg2) {\n if (angular.isNumber(arg1)) {\n // removes items from arg1 (including) through arg2 (excluding)\n for (let i = arg1; i < arg2; i++) {\n elementRoutines.removeElement(buffer[i]);\n }\n return buffer.splice(arg1, arg2 - arg1);\n }\n // removes single item(wrapper) from the buffer\n buffer.splice(buffer.indexOf(arg1), 1);\n if(arg1._op === 'isTop' && buffer.first === this.getAbsMinIndex()) {\n this.incrementMinIndex();\n }\n else {\n this.decrementMaxIndex();\n }\n if(arg1._op === 'isTop') {\n buffer.first++;\n }\n else {\n buffer.next--;\n }\n if(!buffer.length) {\n buffer.first = buffer.minIndex%1 ? buffer.minIndex : startIndex;\n buffer.next = buffer.first;\n buffer.eof = buffer.eof && buffer.first==buffer.maxIndex;\n }\n\n return elementRoutines.removeElementAnimated(arg1);\n },\n\n incrementMinIndex() {\n if(buffer.minIndexUser !== null) {\n if(buffer.minIndex > buffer.minIndexUser) {\n buffer.minIndexUser++;\n return;\n }\n if(buffer.minIndex === buffer.minIndexUser) {\n buffer.minIndexUser++;\n }\n }\n buffer.minIndex++;\n },\n\n decrementMaxIndex() {\n if(buffer.maxIndexUser !== null && buffer.maxIndex <= buffer.maxIndexUser) {\n buffer.maxIndexUser--;\n }\n buffer.maxIndex--;\n },\n\n getAbsMinIndex() {\n if(buffer.minIndexUser !== null) {\n return Math.min(buffer.minIndexUser, buffer.minIndex);\n }\n return buffer.minIndex;\n },\n\n getAbsMaxIndex() {\n if(buffer.maxIndexUser !== null) {\n return Math.max(buffer.maxIndexUser, buffer.maxIndex);\n }\n return buffer.maxIndex;\n },\n\n effectiveHeight(elements) {\n if (!elements.length) {\n return 0;\n }\n let top = Number.MAX_VALUE;\n let bottom = Number.NEGATIVE_INFINITY;\n elements.forEach((wrapper) => {\n if (wrapper.element[0].offsetParent) {\n // element style is not display:none\n top = Math.min(top, wrapper.element.offset().top);\n bottom = Math.max(bottom, wrapper.element.offset().top + (rowHeight || wrapper.element.outerHeight(true)));\n }\n });\n return Math.max(0, bottom - top);\n },\n\n getItems() {\n return buffer.filter(item => item.op === 'none');\n },\n\n getFirstItem() {\n const list = buffer.getItems();\n if (!list.length) {\n return null;\n }\n return list[0].item;\n },\n\n getLastItem() {\n const list = buffer.getItems();\n if (!list.length) {\n return null;\n }\n return list[list.length - 1].item;\n }\n\n });\n\n buffer.reset(startIndex);\n\n return buffer;\n}\n","// Can't just extend the Array, due to Babel does not support built-in classes extending\n// This solution was taken from https://stackoverflow.com/questions/46897414/es6-class-extends-array-workaround-for-es5-babel-transpile\nclass CacheProto {\n add(item) {\n for (let i = this.length - 1; i >= 0; i--) {\n if (this[i].index === item.scope.$index) {\n this[i].height = item.element.outerHeight();\n return;\n }\n }\n this.push({\n index: item.scope.$index,\n height: item.element.outerHeight()\n });\n this.sort((a, b) => ((a.index < b.index) ? -1 : ((a.index > b.index) ? 1 : 0)));\n }\n\n remove(argument, _isTop) {\n const index = argument % 1 === 0 ? argument : argument.scope.$index;\n const isTop = argument % 1 === 0 ? _isTop : argument._op === 'isTop';\n for (let i = this.length - 1; i >= 0; i--) {\n if (this[i].index === index) {\n this.splice(i, 1);\n break;\n }\n }\n if(!isTop) {\n for (let i = this.length - 1; i >= 0; i--) {\n if (this[i].index > index) {\n this[i].index--;\n }\n }\n }\n }\n\n clear() {\n this.length = 0;\n }\n}\n\nfunction Cache() {\n const instance = [];\n instance.push.apply(instance, arguments);\n Object.setPrototypeOf(instance, Cache.prototype);\n return instance;\n}\nCache.prototype = Object.create(Array.prototype);\nObject.getOwnPropertyNames(CacheProto.prototype).forEach(methodName =>\n Cache.prototype[methodName] = CacheProto.prototype[methodName]\n);\n\nfunction generateElement(template) {\n if(template.nodeType !== Node.ELEMENT_NODE) {\n throw new Error('ui-scroll directive requires an Element node for templating the view');\n }\n let element;\n switch (template.tagName.toLowerCase()) {\n case 'dl':\n throw new Error(`ui-scroll directive does not support <${template.tagName}> as a repeating tag: ${template.outerHTML}`);\n case 'tr':\n let table = angular.element('');\n element = table.find('tr');\n break;\n case 'li':\n element = angular.element(' ');\n break;\n default:\n element = angular.element('
');\n }\n return element;\n}\n\n//\n// Padding represents the dummy element added to both the top and the bottom of the scrolling container\n// It holds the element, as well as a cache for the items (rows) height. In case of a fixed rowHeight, the \n// cache is not used and thus is not created.\n//\nclass Padding {\n constructor(template,useCache) {\n this.element = generateElement(template);\n if(useCache) {\n this.cache = new Cache();\n }\n }\n\n height() {\n // When called with a parameter, this sets the height of the padding\n return this.element.height.apply(this.element, arguments);\n }\n}\n\nexport default Padding;","import Padding from './padding';\n\nexport default function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding, rowHeight) {\n let topPadding = null;\n let bottomPadding = null;\n const viewport = viewportController && viewportController.viewport ? viewportController.viewport : angular.element(window);\n const container = viewportController && viewportController.container ? viewportController.container : undefined;\n const scope = viewportController && viewportController.scope ? viewportController.scope : $rootScope;\n\n viewport.css({\n 'overflow-anchor': 'none',\n 'overflow-y': 'auto',\n 'display': 'block'\n });\n\n function bufferPadding() {\n return viewport.outerHeight() * padding; // some extra space to initiate preload\n }\n\n // \n // Viewport measurements\n //\n // +----------------+ 0\n // | top |\n // | padding |\n // +----------------+ topDataPos() [=topPadding.height]\n // | not visible |\n // | items |\n // +----------------+ topVisiblePos() [=viewport.scrollTop]\n // | |\n // | visible |\n // | items |\n // | |\n // +----------------+ bottomVisiblePos() [=viewport.scrollTop+viewport.height]\n // | not visible |\n // | items |\n // +----------------+ bottomDataPos() [=scrollHeight-bottomPadding.height]\n // | bottom |\n // | padding |\n // +----------------+ scrollHeight \n //\n // bufferPadding is some extra space we have top & bottom to allow infinite scrolling\n // bufferPadding = viewport.outerHeight() * padding\n //\n // bottomVisiblePos() - topVisiblePos() == viewport.outerHeight()\n \n\n angular.extend(viewport, {\n getScope() {\n return scope;\n },\n\n createPaddingElements(template) {\n topPadding = new Padding(template,!rowHeight);\n bottomPadding = new Padding(template,!rowHeight);\n element.before(topPadding.element);\n element.after(bottomPadding.element);\n topPadding.height(0);\n bottomPadding.height(0);\n },\n\n applyContainerStyle() {\n if (!container) {\n return true;\n }\n if(container !== viewport) {\n viewport.css('height', window.getComputedStyle(container[0]).height);\n }\n return viewport.height() > 0;\n },\n\n bottomDataPos() {\n let scrollHeight = viewport[0].scrollHeight;\n scrollHeight = scrollHeight != null ? scrollHeight : viewport[0].document.documentElement.scrollHeight;\n return scrollHeight - bottomPadding.height();\n },\n\n topDataPos() {\n return topPadding.height();\n },\n\n bottomVisiblePos() {\n return viewport.scrollTop() + viewport.outerHeight();\n },\n\n topVisiblePos() {\n return viewport.scrollTop();\n },\n\n insertElement(e, sibling) {\n return elementRoutines.insertElement(e, sibling || topPadding.element);\n },\n\n insertElementAnimated(e, sibling) {\n return elementRoutines.insertElementAnimated(e, sibling || topPadding.element);\n },\n\n shouldLoadBottom() {\n return !buffer.eof && viewport.bottomDataPos() < viewport.bottomVisiblePos() + bufferPadding();\n },\n\n clipBottom() {\n // clip the invisible items off the bottom\n let overage = 0;\n let emptySpaceHeight = viewport.bottomDataPos() - viewport.bottomVisiblePos() - bufferPadding();\n if(rowHeight) {\n overage = Math.min(buffer.length,Math.floor(emptySpaceHeight/rowHeight));\n } else {\n let itemHeight = 0;\n let overageHeight = 0;\n\n for (let i = buffer.length - 1; i >= 0; i--) {\n itemHeight = buffer[i].element.outerHeight(true);\n if (overageHeight + itemHeight > emptySpaceHeight) {\n break;\n }\n bottomPadding.cache.add(buffer[i]);\n overageHeight += itemHeight;\n overage++;\n }\n }\n\n if (overage > 0) {\n buffer.eof = false;\n buffer.remove(buffer.length - overage, buffer.length);\n buffer.next -= overage;\n viewport.adjustPaddings();\n }\n },\n\n shouldLoadTop() {\n return !buffer.bof && (viewport.topDataPos() > viewport.topVisiblePos() - bufferPadding());\n },\n\n clipTop() {\n // clip the invisible items off the top\n let overage = 0;\n let overageHeight = 0;\n let emptySpaceHeight = viewport.topVisiblePos() - viewport.topDataPos() - bufferPadding();\n if(rowHeight) {\n overage = Math.min(buffer.length,Math.floor(emptySpaceHeight/rowHeight));\n overageHeight = overage * rowHeight;\n } else {\n let itemHeight = 0;\n\n for (let i = 0; i < buffer.length; i++) {\n itemHeight = buffer[i].element.outerHeight(true);\n if (overageHeight + itemHeight > emptySpaceHeight) {\n break;\n }\n topPadding.cache.add(buffer[i]);\n overageHeight += itemHeight;\n overage++;\n }\n }\n\n if (overage > 0) {\n // we need to adjust top padding element before items are removed from top\n // to avoid strange behaviour of scroll bar during remove top items when we are at the very bottom\n topPadding.height(topPadding.height() + overageHeight);\n buffer.bof = false;\n buffer.remove(0, overage);\n buffer.first += overage;\n }\n },\n\n // PHIL: remove all the entries in the buffer without changing the scrollbar, nor the scroll position\n // and update the padding accordingly\n // It is designed to work with non fixed rowHeight, although it will need more tests in this area...\n scrollTo(first) {\n if(rowHeight) {\n const min = buffer.getAbsMinIndex(); \n const max = buffer.getAbsMaxIndex();\n first = Math.min(Math.max(first, min),max);\n // Adjust the paddings before removing the elements to avoid touching the scroll top position\n topPadding.height((first-min)*rowHeight);\n bottomPadding.height(((max+1)-first)*rowHeight);\n buffer.resetStartIndex(first);\n } else {\n buffer.resetStartIndex(first);\n viewport.adjustPaddings();\n } \n },\n \n adjustPaddings() {\n if(rowHeight) {\n const min = buffer.getAbsMinIndex(); \n const max = buffer.getAbsMaxIndex();\n topPadding.height((buffer.first-min)*rowHeight);\n // PHIL: next points to the next possible item, while max is the index of the last one.\n // In order to make them compatible, we should add one to max\n // Also, it looks like buffer is not changing maxIndex when an element is inserted/appended\n // Not sure if this can have a consequence or not....\n bottomPadding.height(((max+1)-buffer.next)*rowHeight);\n return;\n }\n\n if (!buffer.length) {\n return;\n }\n\n // precise heights calculation based on items that are in buffer or that were in buffer once\n const visibleItemsHeight = buffer.reduce((summ, item) => summ + item.element.outerHeight(true), 0);\n let topPaddingHeight = 0, topCount = 0;\n topPadding.cache.forEach(item => {\n if(item.index < buffer.first) {\n topPaddingHeight += item.height;\n topCount++;\n }\n });\n \n let bottomPaddingHeight = 0, bottomCount = 0;\n bottomPadding.cache.forEach(item => {\n if(item.index >= buffer.next) {\n bottomPaddingHeight += item.height;\n bottomCount++;\n }\n });\n \n const totalHeight = visibleItemsHeight + topPaddingHeight + bottomPaddingHeight;\n const averageItemHeight = totalHeight / (topCount + bottomCount + buffer.length); \n\n // average heights calculation, items that have never been reached\n let adjustTopPadding = buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser;\n let adjustBottomPadding = buffer.maxIndexUser !== null && buffer.maxIndex < buffer.maxIndexUser;\n let topPaddingHeightAdd = adjustTopPadding ? (buffer.minIndex - buffer.minIndexUser) * averageItemHeight : 0;\n let bottomPaddingHeightAdd = adjustBottomPadding ? (buffer.maxIndexUser - buffer.maxIndex) * averageItemHeight : 0;\n\n // paddings combine adjustment\n topPadding.height(topPaddingHeight + topPaddingHeightAdd);\n bottomPadding.height(bottomPaddingHeight + bottomPaddingHeightAdd);\n },\n\n onAfterMinIndexSet(topPaddingHeightOld) {\n // additional scrollTop adjustment in case of datasource.minIndex external set\n if (buffer.minIndexUser !== null && buffer.minIndex > buffer.minIndexUser) {\n let diff = topPadding.height() - topPaddingHeightOld;\n viewport.scrollTop(viewport.scrollTop() + diff);\n while((diff -= viewport.scrollTop()) > 0) {\n bottomPadding.height(bottomPadding.height() + diff);\n viewport.scrollTop(viewport.scrollTop() + diff);\n }\n }\n },\n\n onAfterPrepend(updates) {\n if (!updates.prepended.length)\n return;\n const height = buffer.effectiveHeight(updates.prepended);\n const paddingHeight = topPadding.height() - height;\n if (paddingHeight >= 0) {\n topPadding.height(paddingHeight);\n }\n else {\n topPadding.height(0);\n viewport.scrollTop(viewport.scrollTop() - paddingHeight);\n }\n },\n\n resetTopPadding() {\n topPadding.height(0);\n if(topPadding.cache) {\n topPadding.cache.clear();\n }\n },\n\n resetBottomPadding() {\n bottomPadding.height(0);\n if(bottomPadding.cache) {\n bottomPadding.cache.clear();\n }\n },\n\n removeCacheItem(item, isTop) {\n if(topPadding.cache) {\n topPadding.cache.remove(item, isTop);\n }\n if(bottomPadding.cache) {\n bottomPadding.cache.remove(item, isTop);\n }\n },\n\n removeItem(item) {\n this.removeCacheItem(item);\n return buffer.remove(item);\n }\n });\n\n return viewport;\n}\n","class Adapter {\n\n constructor($scope, $parse, $attr, viewport, buffer, doAdjust, reload) {\n this.$parse = $parse;\n this.$attr = $attr;\n this.viewport = viewport;\n this.buffer = buffer;\n\n this.doAdjust = doAdjust;\n this.reload = reload;\n\n this.isLoading = false;\n this.disabled = false;\n\n const viewportScope = viewport.getScope();\n this.startScope = viewportScope.$parent ? viewportScope : $scope;\n\n this.publicContext = {};\n this.assignAdapter($attr.adapter);\n this.generatePublicContext();\n }\n\n assignAdapter(adapterAttr) {\n if (!adapterAttr || !(adapterAttr = adapterAttr.replace(/^\\s+|\\s+$/gm, ''))) {\n return;\n }\n let adapterOnScope;\n\n try {\n this.$parse(adapterAttr).assign(this.startScope, {});\n adapterOnScope = this.$parse(adapterAttr)(this.startScope);\n }\n catch (error) {\n error.message = `Angular ui-scroll Adapter assignment exception.\\n` +\n `Can't parse \"${adapterAttr}\" expression.\\n` +\n error.message;\n throw error;\n }\n\n angular.extend(adapterOnScope, this.publicContext);\n this.publicContext = adapterOnScope;\n }\n\n generatePublicContext() {\n // these methods will be accessible out of ui-scroll via user defined adapter\n const publicMethods = ['reload', 'applyUpdates', 'append', 'prepend', 'isBOF', 'isEOF', 'isEmpty'];\n for (let i = publicMethods.length - 1; i >= 0; i--) {\n this.publicContext[publicMethods[i]] = this[publicMethods[i]].bind(this);\n }\n\n // these read-only props will be accessible out of ui-scroll via user defined adapter\n const publicProps = ['isLoading', 'topVisible', 'topVisibleElement', 'topVisibleScope', 'bottomVisible', 'bottomVisibleElement', 'bottomVisibleScope'];\n for (let i = publicProps.length - 1; i >= 0; i--) {\n let property, attr = this.$attr[publicProps[i]];\n Object.defineProperty(this, publicProps[i], {\n get: () => property,\n set: (value) => {\n property = value;\n this.publicContext[publicProps[i]] = value;\n if (attr) {\n this.$parse(attr).assign(this.startScope, value);\n }\n }\n });\n }\n\n // read-only immediately calculated public properties\n const publicPropsImmediate = ['bufferFirst', 'bufferLast', 'bufferLength'];\n for (let i = publicPropsImmediate.length - 1; i >= 0; i--) {\n Object.defineProperty(this.publicContext, publicPropsImmediate[i], {\n get: () => this[publicPropsImmediate[i]]\n });\n }\n\n // non-read-only public property\n Object.defineProperty(this.publicContext, 'disabled', {\n get: () => this.disabled,\n set: (value) => (!(this.disabled = value)) ? this.doAdjust() : null\n });\n }\n\n loading(value) {\n this.isLoading = value;\n }\n\n isBOF() {\n return this.buffer.bof;\n }\n\n isEOF() {\n return this.buffer.eof;\n }\n\n isEmpty() {\n return !this.buffer.length;\n }\n\n get bufferLength() {\n return this.buffer.getItems().length;\n }\n\n get bufferFirst() {\n return this.buffer.getFirstItem();\n }\n\n get bufferLast() {\n return this.buffer.getLastItem();\n }\n\n append(newItems) {\n this.buffer.append(newItems);\n this.doAdjust();\n this.viewport.clipTop();\n this.viewport.clipBottom();\n }\n\n prepend(newItems) {\n this.buffer.prepend(newItems);\n this.doAdjust();\n this.viewport.clipTop();\n this.viewport.clipBottom();\n }\n\n applyUpdates(arg1, arg2, arg3) {\n if (typeof arg1 === 'function') {\n this.applyUpdatesFunc(arg1, arg2);\n if(arg2 && arg2.noAdjust) return;\n } else {\n this.applyUpdatesIndex(arg1, arg2, arg3);\n if(arg3 && arg3.noAdjust) return;\n }\n this.doAdjust();\n }\n\n applyUpdatesFunc(cb, options) {\n this.buffer.slice(0).forEach((wrapper) => {\n // we need to do it on the buffer clone, because buffer content\n // may change as we iterate through\n this.applyUpdate(wrapper, cb(wrapper.item, wrapper.scope, wrapper.element), options);\n });\n }\n\n applyUpdatesIndex(index, newItems, options = {}) {\n if (index % 1 !== 0) {\n throw new Error('applyUpdates - ' + index + ' is not a valid index (should be an integer)');\n }\n const _index = index - this.buffer.first;\n\n // apply updates only within buffer\n if (_index >= 0 && _index < this.buffer.length) {\n this.applyUpdate(this.buffer[_index], newItems, options);\n }\n // out-of-buffer case: deletion may affect Paddings\n else if(index >= this.buffer.getAbsMinIndex() && index <= this.buffer.getAbsMaxIndex()) {\n if(angular.isArray(newItems) && !newItems.length) {\n this.viewport.removeCacheItem(index, !options.immutableTop && index === this.buffer.minIndex);\n if (!options.immutableTop && index === this.buffer.getAbsMinIndex()) {\n this.buffer.incrementMinIndex();\n }\n else {\n this.buffer.decrementMaxIndex();\n }\n }\n }\n }\n\n applyUpdate(wrapper, newItems, options = {}) {\n if (!angular.isArray(newItems)) {\n return;\n }\n let position = this.buffer.indexOf(wrapper);\n if (!newItems.reverse().some(newItem => newItem === wrapper.item)) {\n wrapper.op = 'remove';\n if (!options.immutableTop && position === 0 && !newItems.length) {\n wrapper._op = 'isTop'; // to catch \"first\" edge case on remove\n }\n }\n newItems.forEach((newItem) => {\n if (newItem === wrapper.item) {\n position--;\n } else {\n // 3 parameter (isTop) is to catch \"first\" edge case on insert\n this.buffer.insert(position + 1, newItem, !options.immutableTop && position === -1);\n }\n });\n }\n\n calculateProperties() {\n let rowTop = null, topHeight = 0;\n let topDone = false, bottomDone = false;\n const length = this.buffer.length;\n\n for (let i = 0; i < length; i++) {\n const item = this.buffer[i];\n const itemTop = item.element.offset().top;\n\n if (rowTop !== itemTop) { // a new row condition\n const itemHeight = item.element.outerHeight(true);\n const top = this.viewport.topDataPos() + topHeight + itemHeight;\n\n if (!topDone && top > this.viewport.topVisiblePos()) {\n topDone = true;\n this['topVisible'] = item.item;\n this['topVisibleElement'] = item.element;\n this['topVisibleScope'] = item.scope;\n }\n if (!bottomDone && (top >= this.viewport.bottomVisiblePos() || (i === length - 1 && this.isEOF()))) {\n bottomDone = true;\n this['bottomVisible'] = item.item;\n this['bottomVisibleElement'] = item.element;\n this['bottomVisibleScope'] = item.scope;\n }\n topHeight += itemHeight;\n }\n rowTop = itemTop;\n\n if (topDone && bottomDone) {\n break;\n }\n }\n }\n\n}\n\nexport default Adapter;\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';\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 const BUFFER_MIN = 3; // Minimum size of the data source request\n const BUFFER_DEFAULT = 10; // Default datasource request size\n const PADDING_MIN = 0.3; // Mininum # of rows in the padding area\n const PADDING_DEFAULT = 0.5; // Default # of rows in the padding area\n const START_INDEX_DEFAULT = 1; // Default start index when requestng the first data block\n const MAX_VIEWPORT_DELAY = 500; // Max time wait (ms) to get the viewport with an height>0\n const VIEWPORT_POLLING_INTERVAL = 50; // Interval used to check the initial viewport height\n\n let datasource = null;\n const itemName = match[1]; // Name of the index variable to publish\n const datasourceName = match[2]; // Name of the datasource to request the rows from\n const viewportController = controllers[0]; // ViewportController, as specified in the require option (http://websystique.com/angularjs/angularjs-custom-directives-controllers-require-option-guide/)\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 let startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT);\n\n // PHIL: Provide a fixed row height\n // \n const rowHeight = parseNumericAttr($attr.rowHeight, null, false);\n\n // PHIL: Read the visibility watch option, true by default\n const allowVisibilityWatch = $attr.allowVisibilityWatch!=='false';\n\n // Revision IDs\n // \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, rowHeight);\n const viewport = new Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding, rowHeight);\n const adapter = new Adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload);\n\n if (viewportController) {\n viewportController.adapter = adapter;\n }\n\n // Currently, we only debounce the scroll events when a fixed rowHeight is provided\n // as the unit tests will have to be adapted to support this feature\n let scPreviousScrollTop=-1;\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.unbind('mousewheel', wheelHandler);\n });\n\n viewport.bind('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.bind('resize', resizeAndScrollHandler);\n viewport.bind('scroll', resizeAndScrollHandler);\n // If a scroll event happened while the handler was not bounded, emit the scroll\n if(isPendingScroll()) {\n // Do it immediately\n _resizeAndScrollHandler();\n }\n }\n\n function unbindEvents() {\n viewport.unbind('resize', resizeAndScrollHandler);\n viewport.unbind('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 scPreviousScrollTop = -1; // Avoid isScrollPending() to be true\n persistDatasourceIndex(datasource, 'minIndex');\n persistDatasourceIndex(datasource, 'maxIndex');\n doAdjust();\n }\n\n function scrollTo(first) {\n unbindEvents();\n viewport.scrollTo(first);\n doAdjust();\n }\n\n function isElementVisible(wrapper) {\n return (rowHeight || 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 (allowVisibilityWatch && !isElementVisible(wrapper)) {\n wrapper.unregisterVisibilityWatcher = wrapper.scope.$watch(() => visibilityWatcher(wrapper));\n }\n if (allowVisibilityWatch) {\n elementRoutines.hideElement(wrapper); // hide inserted elements before data binding\n }\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 'prepend':\n toBePrepended.unshift(wrapper);\n break;\n case 'append':\n insertWrapperContent(wrapper, i);\n wrapper.op = 'none';\n inserted.push(wrapper);\n break;\n case 'insert':\n promises = promises.concat(createElement(wrapper, i, viewport.insertElementAnimated));\n wrapper.op = 'none';\n inserted.push(wrapper);\n break;\n case '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 = '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 // Adjust the viewport paddings\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 there is a scroll pending, we don't enqueue the fetch as the scroll might be an absolute scroll\n // So we don't need to load top or bottom\n // This happens when there is a scroll frenzi, and the $digest is slow enough, so it stacks the calls without\n // giving a chance to the scroll event to be emitted and processed.\n // We also do that if it leads to an absolute scroll\n if(isPendingScroll() && calculateAbsoluteScroll()!==undefined) {\n // Looks like the event is swallowed on some browsers (FF) on some scroll configuration\n resizeAndScrollHandler();\n return;\n }\n\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 // If there are no changes and the row-height is static, then ignore it!\n const changes = updates.animated.length+updates.inserted.length+updates.prepended.length+updates.removed.length;\n if(changes || !rowHeight) {\n !$scope.$$phase && !$rootScope.$$phase && $scope.$digest();\n }\n\n if (allowVisibilityWatch) {\n updates.inserted.forEach(w => elementRoutines.showElement(w));\n updates.prepended.forEach(w => elementRoutines.showElement(w));\n }\n\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 isPendingScroll() {\n if(rowHeight) {\n // Maybe the scroll changed but the event has *not* yet being dispatched\n // because of the $digest running and taking to long\n var sc = viewport.scrollTop();\n if(sc!=scPreviousScrollTop && scPreviousScrollTop>=0) {\n return true;\n }\n }\n return false;\n }\n\n // Deboucing the scroll events avois intermediate $digest when scrolling fast\n let scTimer;\n function resizeAndScrollHandler() {\n if (rowHeight) {\n if (scTimer) clearTimeout(scTimer);\n scTimer = setTimeout(_resizeAndScrollHandler, 50);\n } else {\n _resizeAndScrollHandler();\n }\n }\n\n function _resizeAndScrollHandler() {\n if (!$rootScope.$$phase && !adapter.isLoading && !adapter.disabled) {\n // Absolute positioning currently only works when a fixed rowHeight is provided\n // We might isolate the averegaRowHeight calculation in the viewport to provide an estimate\n // and provide a reasonable behavior with variable height as well\n if(rowHeight) {\n const newFirst = calculateAbsoluteScroll();\n if(newFirst!==undefined) {\n scrollTo(newFirst);\n return;\n }\n }\n\n enqueueFetch(ridActual);\n\n if (pending.length) {\n unbindEvents();\n } else {\n adapter.calculateProperties();\n if(!rowHeight) {\n // The digest is forced to calculate the height, which is not necessary when the height is knowm\n !$scope.$$phase && $scope.$digest();\n }\n }\n }\n }\n\n function calculateAbsoluteScroll() {\n if(rowHeight) {\n scPreviousScrollTop = viewport.scrollTop();\n let newFirst = Math.floor(viewport.scrollTop() / rowHeight) + buffer.getAbsMinIndex();\n newFirst = Math.max(buffer.getAbsMinIndex(), Math.min(buffer.getAbsMaxIndex(),newFirst)); // Bound the scroll\n if (newFirstbuffer.next+bufferSize) {\n return newFirst;\n } \n }\n return undefined;\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
index 5cac9765..d7cda5ec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "angular-ui-scroll",
- "version": "1.7.3",
+ "version": "1.7.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -3288,8 +3288,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -3313,15 +3312,13 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
- "dev": true,
- "optional": true
+ "dev": true
},
"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,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -3338,22 +3335,19 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
- "dev": true,
- "optional": true
+ "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,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -3484,8 +3478,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -3499,7 +3492,6 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -3516,7 +3508,6 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -3525,15 +3516,13 @@
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -3554,7 +3543,6 @@
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -3643,8 +3631,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -3658,7 +3645,6 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -3754,8 +3740,7 @@
"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,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -3797,7 +3782,6 @@
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -3819,7 +3803,6 @@
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -3868,15 +3851,13 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
diff --git a/package.json b/package.json
index 90f7b02e..fa219e3a 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "angular-ui-scroll",
"description": "AngularJS infinite scrolling module",
- "version": "1.7.3",
+ "version": "1.7.4",
"src": "./src/",
"public": "./dist/",
"main": "./dist/ui-scroll.js",
@@ -26,6 +26,7 @@
"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",
+ "build-dev": "npm run hint-src && npm run prod-build",
"dev": "npm-run-all --parallel dev-server dev-test",
"test": "npm run dev-test",
"start": "npm run dev-server"
diff --git a/src/modules/adapter.js b/src/modules/adapter.js
index 09e8767a..d37115f8 100644
--- a/src/modules/adapter.js
+++ b/src/modules/adapter.js
@@ -1,203 +1,225 @@
-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);
- }
- }
- });
- }
-
- // 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;
- }
-
- append(newItems) {
- this.buffer.append(newItems);
- this.doAdjust();
- this.viewport.clipTop();
- this.viewport.clipBottom();
- }
-
- prepend(newItems) {
- this.buffer.prepend(newItems);
- this.doAdjust();
- this.viewport.clipTop();
- this.viewport.clipBottom();
- }
-
- applyUpdates(arg1, arg2) {
- if (typeof arg1 === 'function') {
- this.applyUpdatesFunc(arg1);
- } else {
- this.applyUpdatesIndex(arg1, arg2);
- }
- this.doAdjust();
- }
-
- applyUpdatesFunc(cb) {
- 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));
- });
- }
-
- applyUpdatesIndex(index, newItems) {
- 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);
- }
- // 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, index === this.buffer.minIndex);
- if(index === this.buffer.getAbsMinIndex()) {
- this.buffer.incrementMinIndex();
- }
- else {
- this.buffer.decrementMaxIndex();
- }
- }
- }
- }
-
- applyUpdate(wrapper, newItems) {
- if (!angular.isArray(newItems)) {
- return;
- }
- let position = this.buffer.indexOf(wrapper);
- if (!newItems.reverse().some(newItem => newItem === wrapper.item)) {
- wrapper.op = 'remove';
- if(position === 0 && !newItems.length) {
- wrapper._op = 'isTop'; // to catch "first" edge case on remove
- }
- }
- newItems.forEach((newItem) => {
- if (newItem === wrapper.item) {
- position--;
- } else {
- // 3 parameter (isTop) is to catch "first" edge case on insert
- this.buffer.insert(position + 1, newItem, 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;
+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) {
+ this.buffer.prepend(newItems);
+ this.doAdjust();
+ this.viewport.clipTop();
+ this.viewport.clipBottom();
+ }
+
+ applyUpdates(arg1, arg2, arg3) {
+ if (typeof arg1 === 'function') {
+ this.applyUpdatesFunc(arg1, arg2);
+ if(arg2 && arg2.noAdjust) return;
+ } else {
+ this.applyUpdatesIndex(arg1, arg2, arg3);
+ if(arg3 && arg3.noAdjust) return;
+ }
+ 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 = 'remove';
+ if (!options.immutableTop && position === 0 && !newItems.length) {
+ wrapper._op = 'isTop'; // to catch "first" edge case on remove
+ }
+ }
+ newItems.forEach((newItem) => {
+ if (newItem === wrapper.item) {
+ position--;
+ } else {
+ // 3 parameter (isTop) 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
index 866afe17..71c7b875 100644
--- a/src/modules/buffer.js
+++ b/src/modules/buffer.js
@@ -1,154 +1,186 @@
-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('append', item);
- });
- buffer.maxIndex = buffer.eof ? buffer.next - 1 : Math.max(buffer.next - 1, buffer.maxIndex);
- },
-
- prepend(items) {
- items.reverse().forEach((item) => {
- --buffer.first;
- buffer.insert('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', 'update', 'none'
- */
- insert(operation, item, isTop) {
- const wrapper = {
- item: item
- };
-
- if (operation % 1 === 0) {// it is an insert
- wrapper.op = 'insert';
- buffer.splice(operation, 0, wrapper);
- if(isTop) {
- buffer.first--;
- }
- else {
- buffer.next++;
- }
- } else {
- wrapper.op = operation;
- switch (operation) {
- case 'append':
- buffer.push(wrapper);
- break;
- case '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._op === 'isTop' && buffer.first === this.getAbsMinIndex()) {
- this.incrementMinIndex();
- }
- else {
- this.decrementMaxIndex();
- }
- if(arg1._op === 'isTop') {
- buffer.first++;
- }
- else {
- buffer.next--;
- }
- if(!buffer.length) {
- buffer.first = 1;
- buffer.next = 1;
- }
-
- 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);
- }
-
- });
-
- buffer.reset(startIndex);
-
- return buffer;
-}
+export default function ScrollBuffer(elementRoutines, bufferSize, startIndex, rowHeight) {
+ 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; // Calculated when data is effectively accessed
+ buffer.maxIndex = startIndex;
+ buffer.minIndexUser = null; // as set by the user (datasource)
+ buffer.maxIndexUser = null;
+ },
+
+ // PHIL: set the new index to be displayed without resettng the sroll and the calculated min/max
+ // Note that this actually make sense with a fixed rowHeight when the scroll value can be calculated
+ // for a # of rows
+ resetStartIndex: function resetStartIndex(startIndex) {
+ buffer.remove(0, buffer.length);
+ buffer.eof = buffer.eof && startIndex==buffer.maxIndex;
+ buffer.bof = buffer.bof && startIndex==buffer.minIndex;
+ buffer.first = startIndex;
+ buffer.next = startIndex;
+ },
+
+ append(items) {
+ items.forEach((item) => {
+ ++buffer.next;
+ buffer.insert('append', item);
+ });
+ buffer.maxIndex = buffer.eof ? buffer.next - 1 : Math.max(buffer.next - 1, buffer.maxIndex);
+ },
+
+ prepend(items) {
+ items.reverse().forEach((item) => {
+ --buffer.first;
+ buffer.insert('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', 'update', 'none'
+ */
+ insert(operation, item, isTop) {
+ const wrapper = {
+ item: item
+ };
+
+ if (operation % 1 === 0) {// it is an insert
+ wrapper.op = 'insert';
+ buffer.splice(operation, 0, wrapper);
+ if(isTop) {
+ buffer.first--;
+ }
+ else {
+ buffer.next++;
+ }
+ } else {
+ wrapper.op = operation;
+ switch (operation) {
+ case 'append':
+ buffer.push(wrapper);
+ break;
+ case '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._op === 'isTop' && buffer.first === this.getAbsMinIndex()) {
+ this.incrementMinIndex();
+ }
+ else {
+ this.decrementMaxIndex();
+ }
+ if(arg1._op === 'isTop') {
+ buffer.first++;
+ }
+ else {
+ buffer.next--;
+ }
+ if(!buffer.length) {
+ buffer.first = buffer.minIndex%1 ? buffer.minIndex : startIndex;
+ buffer.next = buffer.first;
+ buffer.eof = buffer.eof && buffer.first==buffer.maxIndex;
+ }
+
+ 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 + (rowHeight || wrapper.element.outerHeight(true)));
+ }
+ });
+ return Math.max(0, bottom - top);
+ },
+
+ getItems() {
+ return buffer.filter(item => item.op === '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
index b4c7dda5..a9c877f6 100644
--- a/src/modules/elementRoutines.js
+++ b/src/modules/elementRoutines.js
@@ -1,82 +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())];
- }
+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
index e730f2ec..bba9b7f7 100644
--- a/src/modules/jqLiteExtras.js
+++ b/src/modules/jqLiteExtras.js
@@ -1,270 +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;
- }
- });
- }
-
-}
+/*!
+ 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
index ce66e22d..6b9766dd 100644
--- a/src/modules/padding.js
+++ b/src/modules/padding.js
@@ -1,84 +1,92 @@
-// 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, _isTop) {
- const index = argument % 1 === 0 ? argument : argument.scope.$index;
- const isTop = argument % 1 === 0 ? _isTop : argument._op === 'isTop';
- for (let i = this.length - 1; i >= 0; i--) {
- if (this[i].index === index) {
- this.splice(i, 1);
- break;
- }
- }
- if(!isTop) {
- 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);
- }
-}
-
+// 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, _isTop) {
+ const index = argument % 1 === 0 ? argument : argument.scope.$index;
+ const isTop = argument % 1 === 0 ? _isTop : argument._op === 'isTop';
+ for (let i = this.length - 1; i >= 0; i--) {
+ if (this[i].index === index) {
+ this.splice(i, 1);
+ break;
+ }
+ }
+ if(!isTop) {
+ 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;
+}
+
+//
+// Padding represents the dummy element added to both the top and the bottom of the scrolling container
+// It holds the element, as well as a cache for the items (rows) height. In case of a fixed rowHeight, the
+// cache is not used and thus is not created.
+//
+class Padding {
+ constructor(template,useCache) {
+ this.element = generateElement(template);
+ if(useCache) {
+ this.cache = new Cache();
+ }
+ }
+
+ height() {
+ // When called with a parameter, this sets the height of the padding
+ return this.element.height.apply(this.element, arguments);
+ }
+}
+
export default Padding;
\ No newline at end of file
diff --git a/src/modules/viewport.js b/src/modules/viewport.js
index 4f64acb9..c6744e41 100644
--- a/src/modules/viewport.js
+++ b/src/modules/viewport.js
@@ -1,216 +1,290 @@
-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);
- }
- else {
- topPadding.height(0);
- viewport.scrollTop(viewport.scrollTop() - paddingHeight);
- }
- },
-
- resetTopPadding() {
- topPadding.height(0);
- topPadding.cache.clear();
- },
-
- resetBottomPadding() {
- bottomPadding.height(0);
- bottomPadding.cache.clear();
- },
-
- removeCacheItem(item, isTop) {
- topPadding.cache.remove(item, isTop);
- bottomPadding.cache.remove(item, isTop);
- },
-
- removeItem(item) {
- this.removeCacheItem(item);
- return buffer.remove(item);
- }
- });
-
- return viewport;
-}
+import Padding from './padding';
+
+export default function Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding, rowHeight) {
+ 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
+ }
+
+ //
+ // Viewport measurements
+ //
+ // +----------------+ 0
+ // | top |
+ // | padding |
+ // +----------------+ topDataPos() [=topPadding.height]
+ // | not visible |
+ // | items |
+ // +----------------+ topVisiblePos() [=viewport.scrollTop]
+ // | |
+ // | visible |
+ // | items |
+ // | |
+ // +----------------+ bottomVisiblePos() [=viewport.scrollTop+viewport.height]
+ // | not visible |
+ // | items |
+ // +----------------+ bottomDataPos() [=scrollHeight-bottomPadding.height]
+ // | bottom |
+ // | padding |
+ // +----------------+ scrollHeight
+ //
+ // bufferPadding is some extra space we have top & bottom to allow infinite scrolling
+ // bufferPadding = viewport.outerHeight() * padding
+ //
+ // bottomVisiblePos() - topVisiblePos() == viewport.outerHeight()
+
+
+ angular.extend(viewport, {
+ getScope() {
+ return scope;
+ },
+
+ createPaddingElements(template) {
+ topPadding = new Padding(template,!rowHeight);
+ bottomPadding = new Padding(template,!rowHeight);
+ 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 emptySpaceHeight = viewport.bottomDataPos() - viewport.bottomVisiblePos() - bufferPadding();
+ if(rowHeight) {
+ overage = Math.min(buffer.length,Math.floor(emptySpaceHeight/rowHeight));
+ } else {
+ let itemHeight = 0;
+ let overageHeight = 0;
+
+ 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 emptySpaceHeight = viewport.topVisiblePos() - viewport.topDataPos() - bufferPadding();
+ if(rowHeight) {
+ overage = Math.min(buffer.length,Math.floor(emptySpaceHeight/rowHeight));
+ overageHeight = overage * rowHeight;
+ } else {
+ let itemHeight = 0;
+
+ 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;
+ }
+ },
+
+ // PHIL: remove all the entries in the buffer without changing the scrollbar, nor the scroll position
+ // and update the padding accordingly
+ // It is designed to work with non fixed rowHeight, although it will need more tests in this area...
+ scrollTo(first) {
+ if(rowHeight) {
+ const min = buffer.getAbsMinIndex();
+ const max = buffer.getAbsMaxIndex();
+ first = Math.min(Math.max(first, min),max);
+ // Adjust the paddings before removing the elements to avoid touching the scroll top position
+ topPadding.height((first-min)*rowHeight);
+ bottomPadding.height(((max+1)-first)*rowHeight);
+ buffer.resetStartIndex(first);
+ } else {
+ buffer.resetStartIndex(first);
+ viewport.adjustPaddings();
+ }
+ },
+
+ adjustPaddings() {
+ if(rowHeight) {
+ const min = buffer.getAbsMinIndex();
+ const max = buffer.getAbsMaxIndex();
+ topPadding.height((buffer.first-min)*rowHeight);
+ // PHIL: next points to the next possible item, while max is the index of the last one.
+ // In order to make them compatible, we should add one to max
+ // Also, it looks like buffer is not changing maxIndex when an element is inserted/appended
+ // Not sure if this can have a consequence or not....
+ bottomPadding.height(((max+1)-buffer.next)*rowHeight);
+ return;
+ }
+
+ 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);
+ }
+ else {
+ topPadding.height(0);
+ viewport.scrollTop(viewport.scrollTop() - paddingHeight);
+ }
+ },
+
+ resetTopPadding() {
+ topPadding.height(0);
+ if(topPadding.cache) {
+ topPadding.cache.clear();
+ }
+ },
+
+ resetBottomPadding() {
+ bottomPadding.height(0);
+ if(bottomPadding.cache) {
+ bottomPadding.cache.clear();
+ }
+ },
+
+ removeCacheItem(item, isTop) {
+ if(topPadding.cache) {
+ topPadding.cache.remove(item, isTop);
+ }
+ if(bottomPadding.cache) {
+ bottomPadding.cache.remove(item, isTop);
+ }
+ },
+
+ removeItem(item) {
+ this.removeCacheItem(item);
+ return buffer.remove(item);
+ }
+ });
+
+ return viewport;
+}
diff --git a/src/ui-scroll-jqlite.js b/src/ui-scroll-jqlite.js
index c542a1a4..7fae71e5 100644
--- a/src/ui-scroll-jqlite.js
+++ b/src/ui-scroll-jqlite.js
@@ -1,12 +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', []);
-
+/*!
+ * 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
index edb83dea..73284808 100644
--- a/src/ui-scroll.js
+++ b/src/ui-scroll.js
@@ -8,7 +8,8 @@ angular.module('ui.scroll', [])
.constant('JQLiteExtras', JQLiteExtras)
.run(['JQLiteExtras', (JQLiteExtras) => {
- !window.jQuery ? (new JQLiteExtras()).registerFor(angular.element) : null;
+ const elt = angular.element;
+ !(window.jQuery && elt.fn && elt.fn.jquery) ? (new JQLiteExtras()).registerFor(elt) : null;
ElementRoutines.addCSSRules();
}])
@@ -72,33 +73,47 @@ angular.module('ui.scroll', [])
return parseNumber(result, defaultValue, isFloat);
}
- const BUFFER_MIN = 3;
- const BUFFER_DEFAULT = 10;
- const PADDING_MIN = 0.3;
- const PADDING_DEFAULT = 0.5;
- const START_INDEX_DEFAULT = 1;
- const MAX_VIEWPORT_DELAY = 500;
- const VIEWPORT_POLLING_INTERVAL = 50;
+ const BUFFER_MIN = 3; // Minimum size of the data source request
+ const BUFFER_DEFAULT = 10; // Default datasource request size
+ const PADDING_MIN = 0.3; // Mininum # of rows in the padding area
+ const PADDING_DEFAULT = 0.5; // Default # of rows in the padding area
+ const START_INDEX_DEFAULT = 1; // Default start index when requestng the first data block
+ const MAX_VIEWPORT_DELAY = 500; // Max time wait (ms) to get the viewport with an height>0
+ const VIEWPORT_POLLING_INTERVAL = 50; // Interval used to check the initial viewport height
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 itemName = match[1]; // Name of the index variable to publish
+ const datasourceName = match[2]; // Name of the datasource to request the rows from
+ const viewportController = controllers[0]; // ViewportController, as specified in the require option (http://websystique.com/angularjs/angularjs-custom-directives-controllers-require-option-guide/)
+ const bufferSize = Math.max(BUFFER_MIN, parseNumericAttr($attr.bufferSize, BUFFER_DEFAULT));
const padding = Math.max(PADDING_MIN, parseNumericAttr($attr.padding, PADDING_DEFAULT, true));
let startIndex = parseNumericAttr($attr.startIndex, START_INDEX_DEFAULT);
+
+ // PHIL: Provide a fixed row height
+ //
+ const rowHeight = parseNumericAttr($attr.rowHeight, null, false);
+
+ // PHIL: Read the visibility watch option, true by default
+ const allowVisibilityWatch = $attr.allowVisibilityWatch!=='false';
+
+ // Revision IDs
+ //
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 buffer = new ScrollBuffer(elementRoutines, bufferSize, startIndex, rowHeight);
+ const viewport = new Viewport(elementRoutines, buffer, element, viewportController, $rootScope, padding, rowHeight);
const adapter = new Adapter($scope, $parse, $attr, viewport, buffer, doAdjust, reload);
if (viewportController) {
viewportController.adapter = adapter;
}
+ // Currently, we only debounce the scroll events when a fixed rowHeight is provided
+ // as the unit tests will have to be adapted to support this feature
+ let scPreviousScrollTop=-1;
+
const isDatasourceValid = () =>
Object.prototype.toString.call(datasource) === '[object Object]' && typeof datasource.get === 'function';
@@ -232,6 +247,11 @@ angular.module('ui.scroll', [])
function bindEvents() {
viewport.bind('resize', resizeAndScrollHandler);
viewport.bind('scroll', resizeAndScrollHandler);
+ // If a scroll event happened while the handler was not bounded, emit the scroll
+ if(isPendingScroll()) {
+ // Do it immediately
+ _resizeAndScrollHandler();
+ }
}
function unbindEvents() {
@@ -240,19 +260,27 @@ angular.module('ui.scroll', [])
}
function reload() {
+ unbindEvents();
viewport.resetTopPadding();
viewport.resetBottomPadding();
if (arguments.length) {
startIndex = parseNumber(arguments[0], START_INDEX_DEFAULT, false);
}
buffer.reset(startIndex);
+ scPreviousScrollTop = -1; // Avoid isScrollPending() to be true
persistDatasourceIndex(datasource, 'minIndex');
persistDatasourceIndex(datasource, 'maxIndex');
doAdjust();
}
+ function scrollTo(first) {
+ unbindEvents();
+ viewport.scrollTo(first);
+ doAdjust();
+ }
+
function isElementVisible(wrapper) {
- return wrapper.element.height() && wrapper.element[0].offsetParent;
+ return (rowHeight || wrapper.element.height()) && wrapper.element[0].offsetParent;
}
function visibilityWatcher(wrapper) {
@@ -271,10 +299,12 @@ angular.module('ui.scroll', [])
function insertWrapperContent(wrapper, insertAfter) {
createElement(wrapper, insertAfter, viewport.insertElement);
- if (!isElementVisible(wrapper)) {
+ if (allowVisibilityWatch && !isElementVisible(wrapper)) {
wrapper.unregisterVisibilityWatcher = wrapper.scope.$watch(() => visibilityWatcher(wrapper));
}
- elementRoutines.hideElement(wrapper); // hide inserted elements before data binding
+ if (allowVisibilityWatch) {
+ elementRoutines.hideElement(wrapper); // hide inserted elements before data binding
+ }
}
function createElement(wrapper, insertAfter, insertElement) {
@@ -346,6 +376,8 @@ angular.module('ui.scroll', [])
}
+ // Adjust the viewport paddings
+ //
function updatePaddings(rid, updates) {
// schedule another doAdjust after animation completion
if (updates.animated.length) {
@@ -359,6 +391,17 @@ angular.module('ui.scroll', [])
}
function enqueueFetch(rid, updates) {
+ // If there is a scroll pending, we don't enqueue the fetch as the scroll might be an absolute scroll
+ // So we don't need to load top or bottom
+ // This happens when there is a scroll frenzi, and the $digest is slow enough, so it stacks the calls without
+ // giving a chance to the scroll event to be emitted and processed.
+ // We also do that if it leads to an absolute scroll
+ if(isPendingScroll() && calculateAbsoluteScroll()!==undefined) {
+ // Looks like the event is swallowed on some browsers (FF) on some scroll configuration
+ resizeAndScrollHandler();
+ return;
+ }
+
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
@@ -384,10 +427,17 @@ angular.module('ui.scroll', [])
const updates = updateDOM();
// We need the item bindings to be processed before we can do adjustments
- !$scope.$$phase && !$rootScope.$$phase && $scope.$digest();
+ // If there are no changes and the row-height is static, then ignore it!
+ const changes = updates.animated.length+updates.inserted.length+updates.prepended.length+updates.removed.length;
+ if(changes || !rowHeight) {
+ !$scope.$$phase && !$rootScope.$$phase && $scope.$digest();
+ }
+
+ if (allowVisibilityWatch) {
+ updates.inserted.forEach(w => elementRoutines.showElement(w));
+ updates.prepended.forEach(w => elementRoutines.showElement(w));
+ }
- updates.inserted.forEach(w => elementRoutines.showElement(w));
- updates.prepended.forEach(w => elementRoutines.showElement(w));
return updates;
}
@@ -483,8 +533,41 @@ angular.module('ui.scroll', [])
}
}
+ function isPendingScroll() {
+ if(rowHeight) {
+ // Maybe the scroll changed but the event has *not* yet being dispatched
+ // because of the $digest running and taking to long
+ var sc = viewport.scrollTop();
+ if(sc!=scPreviousScrollTop && scPreviousScrollTop>=0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Deboucing the scroll events avois intermediate $digest when scrolling fast
+ let scTimer;
function resizeAndScrollHandler() {
+ if (rowHeight) {
+ if (scTimer) clearTimeout(scTimer);
+ scTimer = setTimeout(_resizeAndScrollHandler, 50);
+ } else {
+ _resizeAndScrollHandler();
+ }
+ }
+
+ function _resizeAndScrollHandler() {
if (!$rootScope.$$phase && !adapter.isLoading && !adapter.disabled) {
+ // Absolute positioning currently only works when a fixed rowHeight is provided
+ // We might isolate the averegaRowHeight calculation in the viewport to provide an estimate
+ // and provide a reasonable behavior with variable height as well
+ if(rowHeight) {
+ const newFirst = calculateAbsoluteScroll();
+ if(newFirst!==undefined) {
+ scrollTo(newFirst);
+ return;
+ }
+ }
enqueueFetch(ridActual);
@@ -492,11 +575,29 @@ angular.module('ui.scroll', [])
unbindEvents();
} else {
adapter.calculateProperties();
- !$scope.$$phase && $scope.$digest();
+ if(!rowHeight) {
+ // The digest is forced to calculate the height, which is not necessary when the height is knowm
+ !$scope.$$phase && $scope.$digest();
+ }
}
}
}
+ function calculateAbsoluteScroll() {
+ if(rowHeight) {
+ scPreviousScrollTop = viewport.scrollTop();
+ let newFirst = Math.floor(viewport.scrollTop() / rowHeight) + buffer.getAbsMinIndex();
+ newFirst = Math.max(buffer.getAbsMinIndex(), Math.min(buffer.getAbsMaxIndex(),newFirst)); // Bound the scroll
+ if (newFirstbuffer.next+bufferSize) {
+ return newFirst;
+ }
+ }
+ return undefined;
+ }
+
function wheelHandler(event) {
if (!adapter.disabled) {
const scrollTop = viewport[0].scrollTop;
diff --git a/test/PaddingsSpec.js b/test/PaddingsSpec.js
index df80b4b1..362d881b 100644
--- a/test/PaddingsSpec.js
+++ b/test/PaddingsSpec.js
@@ -1,404 +1,404 @@
-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);
- viewport.trigger('scroll');
- }
- }
-
- function scrollTop(viewport, count = 1) {
- for (var i = 0; i < count; i++) {
- viewport.scrollTop(0);
- viewport.trigger('scroll');
- }
- }
-
- 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');
- }
- )
- )
- );
- });
-
-});
+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);
+ viewport.trigger('scroll');
+ }
+ }
+
+ function scrollTop(viewport, count = 1) {
+ for (var i = 0; i < count; i++) {
+ viewport.scrollTop(0);
+ viewport.trigger('scroll');
+ }
+ }
+
+ 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/config/karma.conf.files.js b/test/config/karma.conf.files.js
index 3570fb61..905af763 100644
--- a/test/config/karma.conf.files.js
+++ b/test/config/karma.conf.files.js
@@ -1,31 +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
- }
-];
+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/misc/scaffoldingGrid.js b/test/misc/scaffoldingGrid.js
index 5f9a3408..04475533 100644
--- a/test/misc/scaffoldingGrid.js
+++ b/test/misc/scaffoldingGrid.js
@@ -1,68 +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 +=
- '' + col + ' ';
- }); html +=
- ' ' +
- ' ' +
- '' +
- '';
- if(settings.rowTemplate) {
- html += settings.rowTemplate;
- } else {
- columns.forEach(col => { html +=
- '{{item.' + col + '}} ';
- });
- } html +=
- ' ' +
- ' ' +
- '
';
- 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);
- }
- });
+/* 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 +=
+ '' + col + ' ';
+ }); html +=
+ ' ' +
+ ' ' +
+ '' +
+ '';
+ if(settings.rowTemplate) {
+ html += settings.rowTemplate;
+ } else {
+ columns.forEach(col => { html +=
+ '{{item.' + col + '}} ';
+ });
+ } html +=
+ ' ' +
+ ' ' +
+ '
';
+ 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
index d7af5c04..70657749 100644
--- a/test/misc/test.css
+++ b/test/misc/test.css
@@ -1,6 +1,6 @@
-.grid { width: 250px; }
-.col0 { width: 40px; }
-.col1 { width: 80px; }
-.col2 { width: 40px; }
-.col3 { width: 50px; }
+.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