@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
7,023 lines • 224 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('./kendo.core.js');
require('./kendo.data.odata.js');
require('./kendo.data.xml.js');
require('./kendo.licensing.js');
require('@progress/kendo-licensing');
/*
This code is copied/inspired by the internal @progress/kendo-data-query repo:
https://github.com/telerik/kendo-data-query/tree/develop/src/filtering
!!!
1. If updates are to be synced consider the accentFoldingFiltering,
which at the moment is not present as a feature in the data-query-package.
2. Double-check available operators as well.
3. Make sure objs are strings -> i.e., replace (a || "") to (a + '')
!!!
In future, if we consider reusing the code directly we should revise the above omissions.
*/
const logic = {
"or": {
concat: (acc, fn) => a => acc(a) || fn(a),
identity: () => false
},
"and": {
concat: (acc, fn) => a => acc(a) && fn(a),
identity: () => true
}
};
const operatorsMap = {
isnullorempty: (a) => kendo.isBlank(a) || a === '',
isnotnullorempty: (a) => kendo.isPresent(a) && a !== '',
contains: (a, b) => (a + '').indexOf(b) >= 0,
doesnotcontain: (a, b) => (a + '').indexOf(b) === -1,
doesnotendwith: (a, b) => (a + '').indexOf(b, (a || "").length - (b || "").length) < 0,
doesnotstartwith: (a, b) => (a + '').lastIndexOf(b, 0) === -1,
endswith: (a, b) => (a + '').indexOf(b, (a || "").length - (b || "").length) >= 0,
eq: (a, b) => a === b,
gt: (a, b) => a > b,
gte: (a, b) => a >= b,
isempty: (a) => a === '',
isnotempty: (a) => a !== '',
isnotnull: (a) => kendo.isPresent(a),
isnull: (a) => kendo.isBlank(a),
lt: (a, b) => a < b,
lte: (a, b) => a <= b,
neq: (a, b) => a != b,
startswith: (a, b) => (a + '').lastIndexOf(b, 0) === 0
};
const dateRegExp = /^\/Date\((.*?)\)\/$/;
const convertValue = (value, ignoreCase, accentFoldingFiltering) => {
if (value != null && kendo.isString(value)) {
const date = dateRegExp.exec(value);
if (date) {
return new Date(+date[1]).getTime();
} else if (ignoreCase) {
return accentFoldingFiltering ? value.toLocaleLowerCase(accentFoldingFiltering) : value.toLowerCase();
}
} else if (value != null && kendo.isDate(value)) {
return value.getTime();
}
return value;
};
const typedGetter = (prop, value, ignoreCase, accentFoldingFiltering) => {
if (!kendo.isPresent(value)) {
return prop;
}
let acc = prop;
if (kendo.isString(value)) {
const date = dateRegExp.exec(value);
if (date) {
value = new Date(+date[1]);
} else {
acc = a => {
const x = prop(a);
if (typeof x === 'string' && ignoreCase) {
return accentFoldingFiltering ? x.toLocaleLowerCase(accentFoldingFiltering) : x.toLowerCase();
} else {
return kendo.isNumeric(x) ? x + "" : x;
}
};
}
}
if (kendo.isDate(value)) {
return a => {
const x = acc(a);
return kendo.isDate(x) ? x.getTime() : x;
};
}
return acc;
};
const transformFilter = ({ field, ignoreCase, value, operator = 'eq', accentFoldingFiltering }) => {
field = !kendo.isPresent(field) ? a => a : field;
ignoreCase = kendo.isPresent(ignoreCase) ? ignoreCase : true;
const itemProp = typedGetter(
kendo.isFunction(field) ? field : kendo.getter(field, true),
value,
ignoreCase,
accentFoldingFiltering
);
value = convertValue(value, ignoreCase, accentFoldingFiltering);
const op = kendo.isFunction(operator) ? operator : operatorsMap[operator];
return a => op(itemProp(a), value, ignoreCase);
};
const isCompositeFilterDescriptor = (source) => kendo.isPresent(source.filters);
const transformCompositeFilter = (filter) => {
const accentFoldingFiltering = filter.accentFoldingFiltering;
const combiner = logic[filter.logic || 'and'];
return filter.filters
.filter(kendo.isPresent)
.map(x => (isCompositeFilterDescriptor(x) ? transformCompositeFilter(extendAccentFolding(x, accentFoldingFiltering)) : transformFilter(extendAccentFolding(x, accentFoldingFiltering))))
.reduce(combiner.concat, combiner.identity);
};
const extendAccentFolding = (filter, accentFoldingFiltering) => (kendo.isPresent(accentFoldingFiltering) ? Object.assign(filter, { accentFoldingFiltering }) : filter);
const filterExprNoEval = function(expr) {
return transformCompositeFilter(expr);
};
const __meta__ = {
id: "data",
name: "Data source",
category: "framework",
description: "Powerful component for using local and remote data.Fully supports CRUD, Sorting, Paging, Filtering, Grouping, and Aggregates.",
depends: [ "core" ],
features: [ {
id: "data-odata",
name: "OData",
description: "Support for accessing Open Data Protocol (OData) services.",
depends: [ "data.odata" ]
}, {
id: "data-signalr",
name: "SignalR",
description: "Support for binding to SignalR hubs.",
depends: [ "data.signalr" ]
}, {
id: "data-XML",
name: "XML",
description: "Support for binding to XML.",
depends: [ "data.xml" ]
}]
};
(function($, undefined$1) {
var extend = $.extend,
isPlainObject = $.isPlainObject,
isEmptyObject = $.isEmptyObject,
isArray = Array.isArray,
grep = $.grep,
ajax = $.ajax,
map,
each = $.each,
noop = $.noop,
kendo = window.kendo,
isFunction = kendo.isFunction,
Observable = kendo.Observable,
Class = kendo.Class,
STRING = "string",
FUNCTION = "function",
ASCENDING = "asc",
CREATE = "create",
READ = "read",
UPDATE = "update",
DESTROY = "destroy",
CHANGE = "change",
SYNC = "sync",
GET = "get",
ERROR = "error",
REQUESTSTART = "requestStart",
PROGRESS = "progress",
REQUESTEND = "requestEnd",
ITEMSLOADED = "itemsLoaded",
ITEMLOAD = "itemLoad",
crud = [CREATE, READ, UPDATE, DESTROY],
identity = function(o) { return o; },
getter = kendo.getter,
stringify = kendo.stringify,
math = Math,
push = [].push,
join = [].join,
pop = [].pop,
splice = [].splice,
shift = [].shift,
slice = [].slice,
unshift = [].unshift,
toString = {}.toString,
stableSort = kendo.support.stableSort,
dateRegExp = /^\/Date\((.*?)\)\/$/,
objectKeys = [];
var ObservableArray = Observable.extend({
init: function(array, type) {
var that = this;
that.type = type || ObservableObject;
Observable.fn.init.call(that);
that.length = array.length;
that.wrapAll(array, that);
that._loadPromises = [];
that._loadedNodes = [];
},
at: function(index) {
return this[index];
},
toJSON: function(serializeFunctions) {
var idx, length = this.length, value, json = new Array(length);
for (idx = 0; idx < length; idx++) {
value = this[idx];
if (value instanceof ObservableObject) {
value = value.toJSON(serializeFunctions);
}
json[idx] = value;
}
return json;
},
parent: noop,
wrapAll: function(source, target) {
var that = this,
idx,
length,
parent = function() {
return that;
};
target = target || [];
for (idx = 0, length = source.length; idx < length; idx++) {
target[idx] = that.wrap(source[idx], parent);
}
return target;
},
wrap: function(object, parent) {
var that = this,
observable;
if (object !== null && toString.call(object) === "[object Object]") {
observable = object instanceof that.type || object instanceof Model;
if (!observable) {
object = object instanceof ObservableObject ? object.toJSON() : object;
object = new that.type(object);
}
object.parent = parent;
object.bind(CHANGE, function(e) {
var isGroup = object.hasOwnProperty("hasSubgroups");
that.trigger(CHANGE, {
field: e.field,
node: e.node,
index: e.index,
items: e.items || [this],
action: e.node || isGroup ? (e.action || "itemloaded") : "itemchange"
});
});
object.bind(ITEMLOAD, function(e) {
that._loadPromises.push(e.promise);
that._loading = true;
e.promise.done(function() {
that._loadedNodes.push(e.node);
var index = that._loadPromises.indexOf(e.promise);
that._loadPromises.splice(index, 1);
if (!that._loadPromises.length) {
that._loading = false;
that.trigger(ITEMSLOADED, { collection: that, nodes: that._loadedNodes });
that._loadedNodes = [];
}
});
});
}
return object;
},
loading: function() {
return this._loading;
},
push: function() {
var index = this.length,
items = this.wrapAll(arguments),
result;
result = push.apply(this, items);
if (!this.omitChangeEvent) {
this.trigger(CHANGE, {
action: "add",
index: index,
items: items
});
}
return result;
},
slice: slice,
sort: [].sort,
join: join,
pop: function() {
var length = this.length, result = pop.apply(this);
if (length) {
this.trigger(CHANGE, {
action: "remove",
index: length - 1,
items: [result]
});
}
return result;
},
splice: function(index, howMany, item) {
var items = this.wrapAll(slice.call(arguments, 2)),
result, i, len;
result = splice.apply(this, [index, howMany].concat(items));
if (result.length) {
if (!this.omitChangeEvent) {
this.trigger(CHANGE, {
action: "remove",
index: index,
items: this.omitCache && this.omitCache.length ? result.concat(this.omitCache) : result
});
this.omitCache = [];
}
for (i = 0, len = result.length; i < len; i++) {
if (result[i] && result[i].children) {
result[i].unbind(CHANGE);
}
}
}
if (item) {
if (!this.omitChangeEvent) {
this.trigger(CHANGE, {
action: "add",
index: index,
items: items
});
}
}
return result;
},
shift: function() {
var length = this.length, result = shift.apply(this);
if (length) {
this.trigger(CHANGE, {
action: "remove",
index: 0,
items: [result]
});
}
return result;
},
unshift: function() {
var items = this.wrapAll(arguments),
result;
result = unshift.apply(this, items);
this.trigger(CHANGE, {
action: "add",
index: 0,
items: items
});
return result;
},
indexOf: function(item) {
var that = this,
idx,
length;
for (idx = 0, length = that.length; idx < length; idx++) {
if (that[idx] === item) {
return idx;
}
}
return -1;
},
forEach: function(callback, thisArg) {
var idx = 0;
var length = this.length;
var context = thisArg || window;
for (; idx < length; idx++) {
callback.call(context, this[idx], idx, this);
}
},
map: function(callback, thisArg) {
var idx = 0;
var result = [];
var length = this.length;
var context = thisArg || window;
for (; idx < length; idx++) {
result[idx] = callback.call(context, this[idx], idx, this);
}
return result;
},
reduce: function(callback) {
var idx = 0,
result,
length = this.length;
if (arguments.length == 2) {
result = arguments[1];
} else if (idx < length) {
result = this[idx++];
}
for (; idx < length; idx++) {
result = callback(result, this[idx], idx, this);
}
return result;
},
reduceRight: function(callback) {
var idx = this.length - 1,
result;
if (arguments.length == 2) {
result = arguments[1];
} else if (idx > 0) {
result = this[idx--];
}
for (; idx >= 0; idx--) {
result = callback(result, this[idx], idx, this);
}
return result;
},
filter: function(callback, thisArg) {
var idx = 0;
var result = [];
var item;
var length = this.length;
var context = thisArg || window;
for (; idx < length; idx++) {
item = this[idx];
if (callback.call(context, item, idx, this)) {
result[result.length] = item;
}
}
return result;
},
find: function(callback, thisArg) {
var idx = 0;
var item;
var length = this.length;
var context = thisArg || window;
for (; idx < length; idx++) {
item = this[idx];
if (callback.call(context, item, idx, this)) {
return item;
}
}
},
every: function(callback, thisArg) {
var idx = 0;
var item;
var length = this.length;
var context = thisArg || window;
for (; idx < length; idx++) {
item = this[idx];
if (!callback.call(context, item, idx, this)) {
return false;
}
}
return true;
},
some: function(callback, thisArg) {
var idx = 0;
var item;
var length = this.length;
var context = thisArg || window;
for (; idx < length; idx++) {
item = this[idx];
if (callback.call(context, item, idx, this)) {
return true;
}
}
return false;
},
// non-standard collection methods
remove: function(item) {
var idx = this.indexOf(item);
if (idx !== -1) {
this.splice(idx, 1);
}
},
empty: function() {
this.splice(0, this.length);
}
});
// Polyfill for Symbol.iterator
if (typeof Symbol !== "undefined" && Symbol.iterator && !ObservableArray.prototype[Symbol.iterator]) {
ObservableArray.prototype[Symbol.iterator] = [][Symbol.iterator];
}
var LazyObservableArray = ObservableArray.extend({
init: function(data, type, events) {
var parentFn = function() { return this; };
Observable.fn.init.call(this);
this.type = type || ObservableObject;
if (events) {
this._events = events;
}
for (var idx = 0; idx < data.length; idx++) {
this[idx] = data[idx];
}
this.length = idx;
this._parent = parentFn.bind(this);
this._loadPromises = [];
this._loadedNodes = [];
},
at: function(index) {
var item = this[index];
if (!(item instanceof this.type)) {
item = this[index] = this.wrap(item, this._parent);
} else {
item.parent = this._parent;
}
return item;
}
});
function eventHandler(context, type, field, prefix) {
return function(e) {
var event = {}, key;
for (key in e) {
event[key] = e[key];
}
if (prefix) {
event.field = field + "." + e.field;
} else {
event.field = field;
}
if (type == CHANGE && context._notifyChange) {
context._notifyChange(event);
}
context.trigger(type, event);
};
}
function isPrimitiveType(value) {
return (typeof value === "object" && Object.getPrototypeOf(value) === Object.getPrototypeOf({}))
|| Object.getPrototypeOf(value) === Object.getPrototypeOf(new Date())
|| typeof value !== "object";
}
function ownKeys(value, ignoreObjectKeys) {
var props = [];
var protoKeys = [];
var keys, filteredObjectKeys;
value = value || {};
if (!isPrimitiveType(value)) {
protoKeys = Object.getOwnPropertyNames(Object.getPrototypeOf(value)).filter(f => f.indexOf("__") !== 0);
}
keys = Object.getOwnPropertyNames(value).concat(protoKeys);
filteredObjectKeys = objectKeys.filter(function(key) {
return keys.indexOf(key) < 0;
});
while (value) {
Object.getOwnPropertyNames(value).forEach(function(prop) {
if (props.indexOf(prop) === -1 && (!ignoreObjectKeys || filteredObjectKeys.indexOf(prop) < 0)) {
props.push(prop);
}
});
value = Object.getPrototypeOf(value);
}
return props;
}
objectKeys = ownKeys({}, false);
var ObservableObject = Observable.extend({
init: function(value) {
var that = this,
member,
keys = ownKeys(value, true),
parent = function() {
return that;
};
Observable.fn.init.call(this);
this._handlers = {};
keys.forEach(function(field) {
member = value[field];
if (typeof member === "object" && member && !member.getTime && field.charAt(0) != "_") {
member = that.wrap(member, field, parent);
}
that[field] = member;
});
that.uid = kendo.guid();
},
shouldSerialize: function(field, serializeFunctions) {
// This way we cover both if the serializeFunctions parameter is an object OR a boolean.
if (typeof serializeFunctions === "object") {
serializeFunctions = (serializeFunctions && serializeFunctions[field]);
}
return this.hasOwnProperty(field) && field !== "_handlers" && field !== "_events" && (serializeFunctions || typeof this[field] !== FUNCTION) && field !== "uid";
},
forEach: function(f) {
for (var i in this) {
if (this.shouldSerialize(i)) {
f(this[i], i);
}
}
},
toJSON: function(serializeFunctions) {
var result = {}, value, field;
for (field in this) {
if (this.shouldSerialize(field, serializeFunctions)) {
value = this[field];
if (value instanceof ObservableObject || value instanceof ObservableArray) {
value = value.toJSON(serializeFunctions);
}
result[field] = value;
}
}
return result;
},
get: function(field) {
var that = this, result;
that.trigger(GET, { field: field });
if (field === "this") {
result = that;
} else {
result = kendo.getter(field, true)(that);
}
return result;
},
_set: function(field, value) {
var that = this;
var composite = field.indexOf(".") >= 0;
if (composite) {
var paths = field.split("."),
path = "";
while (paths.length > 1) {
path += paths.shift();
var obj = kendo.getter(path, true)(that);
if (obj instanceof ObservableObject) {
obj.set(paths.join("."), value);
return composite;
}
path += ".";
}
}
kendo.setter(field)(that, value);
return composite;
},
set: function(field, value) {
var that = this,
isSetPrevented = false,
composite = field.indexOf(".") >= 0,
current = kendo.getter(field, true)(that);
if (current !== value) {
if (current instanceof Observable && this._handlers[field]) {
if (this._handlers[field].get) {
current.unbind(GET, this._handlers[field].get);
}
current.unbind(CHANGE, this._handlers[field].change);
}
isSetPrevented = that.trigger("set", { field: field, value: value });
if (!isSetPrevented) {
if (!composite) {
value = that.wrap(value, field, function() { return that; });
}
if ((!that._set(field, value) || field.indexOf("(") >= 0 || field.indexOf("[") >= 0)) {
that.trigger(CHANGE, { field: field });
}
}
}
return isSetPrevented;
},
parent: noop,
wrap: function(object, field, parent) {
var that = this;
var get;
var change;
var type = toString.call(object);
if (object != null && (type === "[object Object]" || type === "[object Array]")) {
var isObservableArray = object instanceof ObservableArray;
var isDataSource = object instanceof DataSource;
if (type === "[object Object]" && !isDataSource && !isObservableArray) {
if (!(object instanceof ObservableObject)) {
object = new ObservableObject(object);
}
get = eventHandler(that, GET, field, true);
object.bind(GET, get);
change = eventHandler(that, CHANGE, field, true);
object.bind(CHANGE, change);
that._handlers[field] = { get: get, change: change };
} else if (type === "[object Array]" || isObservableArray || isDataSource) {
if (!isObservableArray && !isDataSource) {
object = new ObservableArray(object);
}
change = eventHandler(that, CHANGE, field, false);
object.bind(CHANGE, change);
that._handlers[field] = { change: change };
}
object.parent = parent;
}
return object;
}
});
function equal(x, y) {
if (x === y) {
return true;
}
var xtype = kendo.type(x), ytype = kendo.type(y), field;
if (xtype !== ytype) {
return false;
}
if (xtype === "date") {
return x.getTime() === y.getTime();
}
if (xtype !== "object" && xtype !== "array") {
return false;
}
for (field in x) {
if (!equal(x[field], y[field])) {
return false;
}
}
return true;
}
var parsers = {
"number": function(value) {
if (typeof value === STRING && value.toLowerCase() === "null") {
return null;
}
return kendo.parseFloat(value);
},
"date": function(value) {
if (typeof value === STRING && value.toLowerCase() === "null") {
return null;
}
return kendo.parseDate(value);
},
"boolean": function(value) {
if (typeof value === STRING) {
if (value.toLowerCase() === "null") {
return null;
} else {
return value.toLowerCase() === "true";
}
}
return value != null ? !!value : value;
},
"string": function(value) {
if (typeof value === STRING && value.toLowerCase() === "null") {
return null;
}
return value != null ? (value + "") : value;
},
"default": function(value) {
return value;
}
};
var defaultValues = {
"string": "",
"number": 0,
"date": new Date(),
"boolean": false,
"default": ""
};
function getFieldByName(obj, name) {
var field,
fieldName;
for (fieldName in obj) {
field = obj[fieldName];
if (isPlainObject(field) && field.field && field.field === name) {
return field;
} else if (field === name) {
return field;
}
}
return null;
}
var Model = ObservableObject.extend({
init: function(data) {
var that = this;
if (!data || $.isEmptyObject(data)) {
data = $.extend({}, that.defaults, data);
if (that._initializers) {
for (var idx = 0; idx < that._initializers.length; idx++) {
var name = that._initializers[idx];
data[name] = that.defaults[name]();
}
}
}
ObservableObject.fn.init.call(that, data);
that.dirty = false;
that.dirtyFields = {};
if (that.idField) {
that.id = that.get(that.idField);
if (that.id === undefined$1) {
that.id = that._defaultId;
}
}
},
shouldSerialize: function(field) {
return ObservableObject.fn.shouldSerialize.call(this, field) &&
field !== "uid" && !(this.idField !== "id" && field === "id") &&
field !== "dirty" && field !== "dirtyFields" && field !== "_accessors";
},
_parse: function(field, value) {
var that = this,
fieldName = field,
fields = (that.fields || {}),
parse;
field = fields[field];
if (!field) {
field = getFieldByName(fields, fieldName);
}
if (field) {
parse = field.parse;
if (!parse && field.type) {
parse = parsers[field.type.toLowerCase()];
}
}
return parse ? parse(value) : value;
},
_notifyChange: function(e) {
var action = e.action;
if (action == "add" || action == "remove") {
this.dirty = true;
this.dirtyFields[e.field] = true;
}
},
editable: function(field) {
field = (this.fields || {})[field];
return field ? field.editable !== false : true;
},
set: function(field, value) {
var that = this;
var dirty = that.dirty;
if (that.editable(field)) {
value = that._parse(field, value);
if (!equal(value, that.get(field))) {
that.dirty = true;
that.dirtyFields[field] = true;
if (ObservableObject.fn.set.call(that, field, value) && !dirty) {
that.dirty = dirty;
if (!that.dirty) {
that.dirtyFields[field] = false;
}
}
} else {
that.trigger("equalSet", { field: field, value: value });
}
}
},
accept: function(data) {
var that = this,
parent = function() { return that; },
field;
for (field in data) {
var value = data[field];
if (field.charAt(0) != "_") {
value = that.wrap(data[field], field, parent);
}
that._set(field, value);
}
if (that.idField) {
that.id = that.get(that.idField);
}
that.dirty = false;
that.dirtyFields = {};
},
isNew: function() {
return this.id === this._defaultId;
}
});
Model.define = function(base, options) {
if (options === undefined$1) {
options = base;
base = Model;
}
var model,
proto = extend({ defaults: {} }, options),
name,
field,
type,
value,
idx,
length,
fields = {},
originalName,
id = proto.id,
functionFields = [];
if (id) {
proto.idField = id;
}
if (proto.id) {
delete proto.id;
}
if (id) {
proto.defaults[id] = proto._defaultId = "";
}
if (toString.call(proto.fields) === "[object Array]") {
for (idx = 0, length = proto.fields.length; idx < length; idx++) {
field = proto.fields[idx];
if (typeof field === STRING) {
fields[field] = {};
} else if (field.field) {
fields[field.field] = field;
}
}
proto.fields = fields;
}
for (name in proto.fields) {
field = proto.fields[name];
type = field.type || "default";
value = null;
originalName = name;
let nameToUse = typeof (field.field) === STRING ? field.field : name;
if (!field.nullable || field.defaultValue) {
value = proto.defaults[originalName !== nameToUse ? originalName : nameToUse] = field.defaultValue !== undefined$1 ? field.defaultValue : defaultValues[type.toLowerCase()];
if (typeof value === "function") {
functionFields.push(nameToUse);
}
}
if (options.id === nameToUse) {
proto._defaultId = value;
}
proto.defaults[originalName !== nameToUse ? originalName : nameToUse] = value;
if ($.isPlainObject(field)) {
field.parse = field.parse || parsers[type];
} else {
field = {
parse: parsers[type]
};
}
}
if (functionFields.length > 0) {
proto._initializers = functionFields;
}
model = base.extend(proto);
model.define = function(options) {
return Model.define(model, options);
};
if (proto.fields) {
model.fields = proto.fields;
model.idField = proto.idField;
}
return model;
};
var Comparer = {
selector: function(field) {
return isFunction(field) ? field : getter(field);
},
compare: function(field) {
var selector = this.selector(field);
return function(a, b) {
a = selector(a);
b = selector(b);
if (a == null && b == null) {
return 0;
}
if (a == null) {
return -1;
}
if (b == null) {
return 1;
}
if (a.localeCompare) {
return a.localeCompare(b);
}
return a > b ? 1 : (a < b ? -1 : 0);
};
},
create: function(sort) {
var compare = sort.compare || this.compare(sort.field);
if (sort.dir == "desc") {
return function(a, b) {
return compare(b, a, true);
};
}
return compare;
},
combine: function(comparers) {
return function(a, b) {
var result = comparers[0](a, b),
idx,
length;
for (idx = 1, length = comparers.length; idx < length; idx ++) {
result = result || comparers[idx](a, b);
}
return result;
};
}
};
var StableComparer = extend({}, Comparer, {
asc: function(field) {
var selector = this.selector(field);
return function(a, b) {
var valueA = selector(a);
var valueB = selector(b);
if (valueA && valueA.getTime && valueB && valueB.getTime) {
valueA = valueA.getTime();
valueB = valueB.getTime();
}
if (valueA === valueB) {
return a.__position - b.__position;
}
if (valueA == null) {
return -1;
}
if (valueB == null) {
return 1;
}
if (valueA.localeCompare) {
return valueA.localeCompare(valueB);
}
return valueA > valueB ? 1 : -1;
};
},
desc: function(field) {
var selector = this.selector(field);
return function(a, b) {
var valueA = selector(a);
var valueB = selector(b);
if (valueA && valueA.getTime && valueB && valueB.getTime) {
valueA = valueA.getTime();
valueB = valueB.getTime();
}
if (valueA === valueB) {
return a.__position - b.__position;
}
if (valueA == null) {
return 1;
}
if (valueB == null) {
return -1;
}
if (valueB.localeCompare) {
return valueB.localeCompare(valueA);
}
return valueA < valueB ? 1 : -1;
};
},
create: function(sort) {
return this[sort.dir](sort.field);
}
});
map = function(array, callback) {
var idx, length = array.length, result = new Array(length);
for (idx = 0; idx < length; idx++) {
result[idx] = callback(array[idx], idx, array);
}
return result;
};
var operators = (function() {
function quote(str) {
if (typeof str == "string") {
str = str.replace(/[\r\n]+/g, "");
}
return JSON.stringify(str);
}
function textOp(impl) {
return function(a, b, ignore, accentFoldingFiltering) {
b += "";
if (ignore) {
a = "(" + a + " + '').toString()" + ((accentFoldingFiltering) ? ".toLocaleLowerCase('" + accentFoldingFiltering + "')" : ".toLowerCase()");
b = ((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase());
}
return impl(a, quote(b), ignore);
};
}
function operator(op, a, b, ignore, accentFoldingFiltering) {
if (b != null) {
if (typeof b === STRING) {
var date = dateRegExp.exec(b);
if (date) {
b = new Date(+date[1]);
} else if (ignore) {
b = quote(((accentFoldingFiltering) ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase()));
a = "((" + a + " || '')+'')" + ((accentFoldingFiltering) ? ".toLocaleLowerCase('" + accentFoldingFiltering + "')" : ".toLowerCase()");
} else {
b = quote(b);
}
}
if (b.getTime) {
//b looks like a Date
a = "(" + a + "&&" + a + ".getTime?" + a + ".getTime():" + a + ")";
b = b.getTime();
}
}
return a + " " + op + " " + b;
}
function getMatchRegexp(pattern) {
// take a pattern, as supported by Excel match filter, and
// convert it to the equivalent JS regular expression.
// Excel patterns support:
//
// * - match any sequence of characters
// ? - match a single character
//
// to match a literal * or ?, they must be prefixed by a tilde (~)
for (var rx = "/^", esc = false, i = 0; i < pattern.length; ++i) {
var ch = pattern.charAt(i);
if (esc) {
rx += "\\" + ch;
} else if (ch == "~") {
esc = true;
continue;
} else if (ch == "*") {
rx += ".*";
} else if (ch == "?") {
rx += ".";
} else if (".+^$()[]{}|\\/\n\r\u2028\u2029\xA0".indexOf(ch) >= 0) {
rx += "\\" + ch;
} else {
rx += ch;
}
esc = false;
}
return rx + "$/";
}
return {
quote: function(value) {
if (value && value.getTime) {
return "new Date(" + value.getTime() + ")";
}
return quote(value);
},
eq: function(a, b, ignore, accentFoldingFiltering) {
return operator("==", a, b, ignore, accentFoldingFiltering);
},
neq: function(a, b, ignore, accentFoldingFiltering) {
return operator("!=", a, b, ignore, accentFoldingFiltering);
},
gt: function(a, b, ignore) {
return operator(">", a, b, ignore);
},
gte: function(a, b, ignore) {
return operator(">=", a, b, ignore);
},
lt: function(a, b, ignore) {
return operator("<", a, b, ignore);
},
lte: function(a, b, ignore) {
return operator("<=", a, b, ignore);
},
startswith: textOp(function(a, b) {
return a + ".lastIndexOf(" + b + ", 0) == 0";
}),
doesnotstartwith: textOp(function(a, b) {
return a + ".lastIndexOf(" + b + ", 0) == -1";
}),
endswith: textOp(function(a, b) {
var n = b ? b.length - 2 : 0;
return a + ".indexOf(" + b + ", " + a + ".length - " + n + ") >= 0";
}),
doesnotendwith: textOp(function(a, b) {
var n = b ? b.length - 2 : 0;
return a + ".indexOf(" + b + ", " + a + ".length - " + n + ") < 0";
}),
contains: textOp(function(a, b) {
return a + ".indexOf(" + b + ") >= 0";
}),
doesnotcontain: textOp(function(a, b) {
return a + ".indexOf(" + b + ") == -1";
}),
matches: textOp(function(a, b) {
b = b.substring(1, b.length - 1);
return getMatchRegexp(b) + ".test(" + a + ")";
}),
doesnotmatch: textOp(function(a, b) {
b = b.substring(1, b.length - 1);
return "!" + getMatchRegexp(b) + ".test(" + a + ")";
}),
isempty: function(a) {
return a + " === ''";
},
isnotempty: function(a) {
return a + " !== ''";
},
isnull: function(a) {
return "(" + a + " == null)";
},
isnotnull: function(a) {
return "(" + a + " != null)";
},
isnullorempty: function(a) {
return "(" + a + " === null) || (" + a + " === '')";
},
isnotnullorempty: function(a) {
return "(" + a + " !== null) && (" + a + " !== '')";
}
};
})();
function Query(data) {
this.data = data || [];
}
// Continue to support legacy unsafe-eval for the spreadsheet
Query.filterExpr = function(expression, options = { noEval: false }) {
if (options.noEval) {
// using no-eval for most cases
return filterExprNoEval(expression);
}
var expressions = [],
logic = { and: " && ", or: " || " },
idx,
length,
filter,
expr,
fieldFunctions = [],
operatorFunctions = [],
field,
operator,
filters = expression.filters;
for (idx = 0, length = filters.length; idx < length; idx++) {
filter = filters[idx];
field = filter.field;
operator = filter.operator;
if (filter.filters) {
expr = Query.filterExpr(filter);
//Nested function fields or operators - update their index e.g. __o[0] -> __o[1]
filter = expr.expression
.replace(/__o\[(\d+)\]/g, function(match, index) {
index = +index;
return "__o[" + (operatorFunctions.length + index) + "]";
})
.replace(/__f\[(\d+)\]/g, function(match, index) {
index = +index;
return "__f[" + (fieldFunctions.length + index) + "]";
});
operatorFunctions.push.apply(operatorFunctions, expr.operators);
fieldFunctions.push.apply(fieldFunctions, expr.fields);
} else {
if (typeof field === FUNCTION) {
expr = "__f[" + fieldFunctions.length + "](d)";
fieldFunctions.push(field);
} else {
expr = kendo.expr(field);
}
if (typeof operator === FUNCTION) {
filter = "__o[" + operatorFunctions.length + "](" + expr + ", " + operators.quote(filter.value) + ")";
operatorFunctions.push(operator);
} else {
filter = operators[(operator || "eq").toLowerCase()](expr, filter.value, filter.ignoreCase !== undefined$1 ? filter.ignoreCase : true, expression.accentFoldingFiltering);
}
}
expressions.push(filter);
}
return { expression: "(" + expressions.join(logic[expression.logic]) + ")", fields: fieldFunctions, operators: operatorFunctions };
};
function normalizeSort(field, dir) {
if (field) {
var descriptor = typeof field === STRING ? { field: field, dir: dir } : field,
descriptors = isArray(descriptor) ? descriptor : (descriptor !== undefined$1 ? [descriptor] : []);
return grep(descriptors, function(d) { return !!d.dir; });
}
}
function sortFields(sorts, dir) {
var sortObject = {};
if (sorts) {
var descriptor = typeof sorts === STRING ? { field: sorts, dir: dir } : sorts,
descriptors = isArray(descriptor) ? descriptor : (descriptor !== undefined$1 ? [descriptor] : []);
for (var i = 0; i < descriptors.length; i++) {
sortObject[descriptors[i].field] = { dir: descriptors[i].dir, index: i + 1 };
}
}
return sortObject;
}
var operatorMap = {
"==": "eq",
equals: "eq",
isequalto: "eq",
equalto: "eq",
equal: "eq",
"!=": "neq",
ne: "neq",
notequals: "neq",
isnotequalto: "neq",
notequalto: "neq",
notequal: "neq",
"<": "lt",
islessthan: "lt",
lessthan: "lt",
less: "lt",
"<=": "lte",
le: "lte",
islessthanorequalto: "lte",
lessthanequal: "lte",
">": "gt",
isgreaterthan: "gt",
greaterthan: "gt",
greater: "gt",
">=": "gte",
isgreaterthanorequalto: "gte",
greaterthanequal: "gte",
ge: "gte",
notsubstringof: "doesnotcontain",
isnull: "isnull",
isempty: "isempty",
isnotempty: "isnotempty"
};
function normalizeOperator(expression) {
var idx,
length,
filter,
operator,
filters = expression.filters;
if (filters) {
for (idx = 0, length = filters.length; idx < length; idx++) {
filter = filters[idx];
operator = filter.operator;
if (operator && typeof operator === STRING) {
filter.operator = operatorMap[operator.toLowerCase()] || operator;
}
normalizeOperator(filter);
}
}
}
function normalizeFilter(expression) {
if (expression && !isEmptyObject(expression)) {
if (isArray(expression) || !expression.filters) {
expression = {
logic: "and",
filters: isArray(expression) ? expression : [expression]
};
}
normalizeOperator(expression);
return expression;
}
}
Query.normalizeFilter = normalizeFilter;
function compareDescriptor(f1, f2) {
if (f1.logic || f2.logic) {
return false;
}
return f1.field === f2.field && f1.value === f2.value && f1.operator === f2.operator;
}
function normalizeDescriptor(filter) {
filter = filter || {};
if (isEmptyObject(filter)) {
return { logic: "and", filters: [] };
}
return normalizeFilter(filter);
}
function fieldComparer(a, b) {
if (b.logic || (a.field > b.field)) {
return 1;
} else if (a.field < b.field) {
return -1;
} else {
return 0;
}
}
function hasNotFetchedItems(items, start, end) {
for (let idx = start; idx < end; idx++) {
if (items[idx].notFetched) {
return true;
}
}
return false;
}
function compareFilters(expr1, expr2) {
expr1 = normalizeDescriptor(expr1);
expr2 = normalizeDescriptor(expr2);
if (expr1.logic !== expr2.logic) {
return false;
}
var f1, f2;
var filters1 = (expr1.filters || []).slice();
var filters2 = (expr2.filters || []).slice();
if (filters1.length !== filters2.length) {
return false;
}
filters1 = filters1.sort(fieldComparer);
filters2 = filters2.sort(fieldComparer);
for (var idx = 0; idx < filters1.length; idx++) {
f1 = filters1[idx];
f2 = filters2[idx];
if (f1.logic && f2.logic) {
if (!compareFilters(f1, f2)) {
return false;
}
} else if (!compareDescriptor(f1, f2)) {
return false;
}
}
return true;
}
Query.compareFilters = compareFilters;
function normalizeAggregate(expressions) {
return isArray(expressions) ? expressions : [expressions];
}
function normalizeGroup(field, dir, compare, skipItemSorting) {
var descriptor = typeof field === STRING ? { field: field, dir: dir, compare: compare, skipItemSorting: skipItemSorting } : field,
descriptors = isArray(descriptor) ? descriptor : (descriptor !== undefined$1 ? [descriptor] : []);
return map(descriptors, function(d) {
return {
field: d.field,
dir: d.dir || "asc",
aggregates: d.aggregates,
compare: d.compare,
skipItemSorting: d.skipItemSorting
};
});
}
function normalizeGroupWithoutCompare(field, dir, compare) {
var descriptors = normalizeGroup(field, dir, compare);
for (var i = 0; i < descriptors.length; i++) {
delete descriptors[i].compare;
}
return descriptors;
}
function anyGroupDescriptorHasCompare(groupDescriptors) {
var descriptors = isArray(groupDescriptors) ? groupDescriptors : [groupDescriptors];
for (var i = 0; i < descriptors.length; i++) {
if (descriptors[i] && isFunction(descriptors[i].compare)) {
return true;
}
}
return false;
}
Query.prototype = {
toArray: function() {
return this.data;
},
range: function(index, count) {
return new Query(this.data.slice(index, index + count));
},
skip: function(count) {
return new Query(this.data.slice(count));
},
take: function(count) {
return new Query(this.data.slice(0, count));
},
select: function(selector) {
return new Query(map(this.data, selector));
},
order: function(selector, dir, inPlace) {
var sort = { dir: dir };
if (selector) {
if (selector.compare) {
sort.compare = selector.compare;
} else {
sort.field = selector;
}
}
if (inPlace) {
return new Query(this.data.sort(Comparer.create(sort)));
}
return new Query(this.data.slice(0).sort(Comparer.create(sort)));
},
orderBy: function(selector, inPlace) {
return this.order(selector, "asc", inPlace);
},
orderByDescending: function(selector, inPlace) {
return this.order(selector, "desc", inPlace);
},
sort: function(field, dir, comparer, inPlace) {
var idx,
length,
descriptors = normalizeSort(field, dir),
comparers = [];
comparer = comparer || Comparer;
if (descriptors.length) {
for (idx = 0, length = descriptors.length; idx < length; idx++) {
comparers.push(comparer.create(descriptors[idx]));
}
return this.orderBy({ compare: comparer.combine(comparers) }, inPlace);
}
return this;
},
filter: function(expressions) {
var compiled,
data = this.data,
result = [];
expressions = normalizeFilter(expressions);
if (!expressions || expressions.filters.length === 0) {
return this;
}
compiled = Query.filterExpr(expressions, { noEval: true });
result = data.filter(compiled);
return new Query(result);
},
group: function(descriptors, allData, options) {
descriptors = normalizeGroup(descriptors || []);
allData = allData || this.data;
var that = this,
result = new Query(that.data),
descriptor;
var getFilteredData = (g, data) => {
data = data || new Query(allData).filter([{
field: g.field,
operator: "eq",
value: g.value,
ignoreCase: false
}]);
return data;
};
if (descriptors.length > 0) {
descriptor = descriptors[0];
if (options && options.groupPaging) {
result = new Query(allData).groupAllData(descriptor, allData).select(function(group) {
var cachedFilteredData;
var items = descriptors.length > 1 ? new Query(group.items).group(descriptors.slice(1), getFilteredData(group, cachedFilteredData).toArray(), options).toArray() : group.items;
return {
field: group.field,
value: group.value,
hasSubgroups: descriptors.length > 1,
items: items,
aggregates: descriptor.aggregates && descriptor.aggregates.length ? getFilteredData(group, cachedFilteredData).aggregate(descriptor.aggregates) : {},
uid: kendo.guid(),
itemCount: items.length,
subgroupCount: items.length
};
});
} else {
result = result.groupBy(descriptor).select(function(group) {
var cachedFilteredData;
return {
field: group.field,
value: group.value,
items: descriptors.length > 1 ? new Query(group.items).group(descriptors.slice(1), getFilteredData(group, cachedFilteredData).toArray()).toArray() : group.items,
hasSubgroups: descriptors.length > 1,
aggregates: descriptor.aggregates && descriptor.aggregates.length ? getFilteredData(group, cachedFilteredData).aggregate(descriptor.aggregates) : {},
};
});
}
}
return result;
},
groupBy: function(descriptor) {
var that = this;
if (isEmptyObject(descriptor) || !this.data.length) {
return new Query([]);
}
var field = descriptor.field,
sorted = descriptor.skipItemSorting ? this.data : this._sortForGrouping(field, descriptor.dir || "asc"),
accessor = kendo.accessor(field),
item,
groupValue = accessor.get(sorted[0], field),
group = {
field: field,
value: groupValue,
items: []
},
currentValue,
idx,
len,
result = [group];
for (idx = 0, len = sorted.length; idx < len; idx++) {
item = sorted[idx];
currentValue = accessor.get(item, field);
if (!groupValueComparer(groupValue, currentValue)) {
groupValue = currentValue;
group = {
field: field,
value: groupValue,
items: []
};
result.push(group);
}
group.items.push(item);
}
result = that._sortGroups(result, descriptor);
return new Query(result);
},
groupAllData: function(descriptor, allData) {
if (isEmptyObject(descriptor) || this.data && !this.data.length) {
return new Query([]);
}
var field = descriptor.field,
sorted = descriptor.skipItemSorting ? allData : new Query(allData).sort(field, descriptor.dir || "asc", StableComparer).toArray(),
accessor = kendo.accessor(field),
item,
groupValue = accessor.get(sorted[0], field),
group = {
field: field,
value: groupValue,
items: []
},
currentValue,
idx,
len,
result = [group];
for (idx = 0, len = sorted.length; idx < len; idx++) {
item = sorted[idx];
currentValue = accessor.get(item, field);
if (!groupValueComparer(groupValue, currentValue)) {
groupValue = currentValue;
group = {
field: field,
value: groupValue,
items: []
};
result.push(group);
}
group.items.push(item);
}
result = this._sortGroups(result, descriptor);
return new Query(result);
},
_sortForGrouping: function(field, dir) {
var idx, length,
data = this.data;
if (!stableSort) {
for (idx = 0, length = data.length; idx < length; idx++) {
data[idx].__position = idx;
}
data = new Query(data).sort(field, dir, StableComparer).toArray();
for (idx = 0, length = data.length; idx < length; idx++) {
delete data[idx].__position;
}
return data;
}
return this.sort(field, dir).toArray();
},
_sortGroups: function(groups, descriptor) {
var result = groups;
if (descriptor && isFunction(descriptor.compare)) {
result = new Query(result).order({ compare: descriptor.compare }, descriptor.dir || ASCENDING).toArray();
}
return result;
},
aggregate: function(aggregates) {
var idx,
len,
result = {},
state = {};
if (aggregates && aggregates.length) {
for (idx = 0, len = this.data.length; idx < len; idx++) {
calculateAggregate(result, aggregates, this.data[idx], idx, len, state);
}
}
return result;
}
};
function groupValueComparer(a, b) {
if (a && a.getTime && b && b.getTime) {
return a.getTime() === b.getTime();
}
return a === b;
}
function calculateAggregate(accumulator, aggregates, item, index, length, state) {
aggregates = aggregates || [];
var idx,
aggr,
functionName,
len = aggregates.length;
for (idx = 0; idx < len; idx++) {
aggr = aggregates[idx];
functionName = aggr.aggregate;
var field = aggr.field;
accumulator[field] = accumulator[field] || {};
state[field] = state[field] || {};
state[field][functionName] = state[field][functionName] || {};
accumulator[field][functionName] = functions[functionName.toLowerCase()](accumulator[field][functionName], item, kendo.accessor(field), index, length, state[field][functionName]);
}
}
var functions = {
sum: function(accumulator, item, accessor) {
var value = accessor.get(item);
if (!isNumber(accumulator)) {
accumulator = value;
} else if (isNumber(value)) {
accumulator += value;
}
return accumulator;
},
count: function(accumulator) {
return (accumulator || 0) + 1;
},
average: function(accumulator, item, accessor, index, length, state) {
var value = accessor.get(item);
if (state.count === undefined$1) {
state.count = 0;
}
if (!isNumber(accumulator)) {
accumulator = value;
} else if (isNumber(value)) {
accumulator += value;
}
if (isNumber(value)) {
state.count++;
}
if (index == length - 1 && isNumber(accumulator)) {
accumulator = accumulator / state.count;
}
return accumulator;
},
max: function(accumulator, item, accessor) {
var value = accessor.get(item);
if (!isNumber(accumulator) && !isDate(accumulator)) {
accumulator = value;
}
if (accumulator < value && (isNumber(value) || isDate(value))) {
accumulator = value;
}
return accumulator;
},
min: function(accumulator, item, accessor) {
var value = accessor.get(item);
if (!isNumber(accumulator) && !isDate(accumulator)) {
accumulator = value;
}
if (accumulator > value && (isNumber(value) || isDate(value))) {
accumulator = value;
}
return accumulator;
}
};
function isNumber(val) {
return typeof val === "number" && !isNaN(val);
}
function isDate(val) {
return val && val.getTime;
}
function toJSON(array) {
var idx, length = array.length, result = new Array(length);
for (idx = 0; idx < length; idx++) {
result[idx] = array[idx].toJSON();
}
return result;
}
Query.normalizeGroup = normalizeGroup;
Query.normalizeSort = normalizeSort;
Query.process = function(data, options, inPlace) {
options = options || {};
var group = options.group;
var customGroupSort = anyGroupDescriptorHasCompare(normalizeGroup(group || []));
var query = new Query(data),
groupDescriptorsWithoutCompare = normalizeGroupWithoutCompare(group || []),
normalizedSort = normalizeSort(options.sort || []),
sort = customGroupSort ? normalizedSort : groupDescriptorsWithoutCompare.concat(normalizedSort),
groupDescriptorsWithoutSort,
total,
filterCallback = options.filterCallback,
filter = options.filter,
skip = options.skip,
take = options.take;
if (sort && inPlace) {
query = query.sort(sort, undefined$1, undefined$1, inPlace);
}
if (filter) {
query = query.filter(filter);
if (filterCallback) {
query = filterCallback(query);
}
total = query.toArray().length;
}
if (sort) {
if (!inPlace) {
query = query.sort(sort);
}
if (group) {
data = query.toArray();
}
}
if (customGroupSort) {
query = query.group(group, data, options);
if (skip !== undefined$1 && take !== undefined$1 && !options.groupPaging) {
query = new Query(flatGroups(query.toArray())).range(skip, take);
groupDescriptorsWithoutSort = map(groupDescriptorsWithoutCompare, function(groupDescriptor) {
return extend({}, groupDescriptor, {
skipItemSorting: true
});
});
query = query.group(groupDescriptorsWithoutSort, data, options);
}
} else {
if (skip !== undefined$1 && take !== undefined$1) {
total = query.data.length;
if (skip + take > total && options.virtual) {
skip -= skip + take - total;
skip = skip < 0 ? 0 : skip;
}
query = query.range(skip, take);
}
if (group && (!isEmptyObject(group) || group.length !== 0)) {
query = query.group(group, data, options);
}
}
return {
total: total,
data: query.toArray()
};
};
var LocalTransport = Class.extend({
init: function(options) {
this.data = options.data;
},
read: function(options) {
options.success(this.data);
},
update: function(options) {
options.success(options.data);
},
create: function(options) {
options.success(options.data);
},
destroy: function(options) {
options.success(options.data);
}
});
var RemoteTransport = Class.extend( {
init: function(options) {
var that = this, parameterMap;
options = that.options = extend({}, that.options, options);
each(crud, function(index, type) {
if (typeof options[type] === STRING) {
options[type] = {
url: options[type]
};
}
});
that.cache = options.cache ? Cache.create(options.cache) : {
find: noop,
add: noop
};
parameterMap = options.parameterMap;
if (options.submit) {
that.submit = options.submit;
}
if (isFunction(options.push)) {
that.push = options.push;
}
if (!that.push) {
that.push = identity;
}
that.parameterMap = isFunction(parameterMap) ? parameterMap : function(options) {
var result = {};
each(options, function(option, value) {
if (option in parameterMap) {
option = parameterMap[option];
if (isPlainObject(option)) {
value = option.value(value);
option = option.key;
}
}
result[option] = value;
});
return result;
};
},
options: {
parameterMap: identity
},
create: function(options) {
return ajax(this.setup(options, CREATE));
},
read: function(options) {
var that = this,
success,
result,
cache = that.cache;
options = that.setup(options, READ);
success = options.success || noop;
options.error || noop;
result = cache.find(options.data);
if (result !== undefined$1) {
success(result);
} else {
options.success = function(result) {
cache.add(options.data, result);
success(result);
};
$.ajax(options);
}
},
update: function(options) {
return ajax(this.setup(options, UPDATE));
},
destroy: function(options) {
return ajax(this.setup(options, DESTROY));
},
setup: function(options, type) {
options = options || {};
var that = this,
parameters,
operation = that.options[type],
data = isFunction(operation.data) ? operation.data(options.data) : operation.data;
options = extend(true, {}, operation, options);
parameters = extend(true, {}, data, options.data);
options.data = that.parameterMap(parameters, type);
if (isFunction(options.url)) {
options.url = options.url(parameters);
}
return options;
}
});
var AiTransport = Class.extend( {
init: function(options) {
const that = this;
options = that.options = extend({}, that.options, options);
that.messageTypes = {
"ai": "assistant",
"system": "system",
"user": "user",
"tool": "tool"
};
},
read: function(options) {
const that = this;
options = that.setup(options);
if (that.options.requestStart) {
that.options.requestStart(options);
}
$.ajax(options);
},
success: function(response, options) {
const that = this;
const service = that.options.service;
const outputGetter = service?.outputGetter || that._getResponseData;
const isRetry = options.isRetry;
const prompt = options.prompt;
const output = {
id: kendo.guid(),
output: outputGetter(response),
prompt: prompt,
isRetry: isRetry
};
if (that.options.success) {
that.options.success(output);
}
},
error: function(response) {
const that = this;
if (that.options.error) {
that.options.error(response);
}
},
setup: function(options = {}) {
const that = this;
const service = that.options.service;
const data = that.getData(options);
const url = typeof service === "string" ? service : service.url;
const requestOptions = {
url: url,
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
success: function(response) {
that.success.call(that, response, options);
},
error: that.error
};
if (service?.headers) {
requestOptions.headers = service.headers;
}
return requestOptions;
},
getData: function(options) {
const that = this;
const service = options.service;
const isRetry = options.isRetry;
const history = options.history;
const prompt = options.prompt;
let defaultData = [
{
role: {
value: that.messageTypes.user
},
text: prompt
}
];
if (history?.length) {
defaultData = history.concat(defaultData);
}
if (service?.data && isFunction(service?.data)) {
return service.data(prompt, isRetry, history);
}
if (service?.data && Object.keys(service.data).length) {
return $.extend({}, service.data, { messages: defaultData });
}
return defaultData;
},
_getResponseData: function(response) {
return response?.Message?.Text || "An error occurred while processing the request.";
},
});
var Cache = Class.extend({
init: function() {
this._store = {};
},
add: function(key, data) {
if (key !== undefined$1) {
this._store[stringify(key)] = data;
}
},
find: function(key) {
return this._store[stringify(key)];
},
clear: function() {
this._store = {};
},
remove: function(key) {
delete this._store[stringify(key)];
}
});
Cache.create = function(options) {
var store = {
"inmemory": function() { return new Cache(); }
};
if (isPlainObject(options) && isFunction(options.find)) {
return options;
}
if (options === true) {
return new Cache();
}
return store[options]();
};
function serializeRecords(data, getters, modelInstance, originalFieldNames, fieldNames) {
var record,
getter,
originalName,
idx,
setters = {},
length;
for (idx = 0, length = data.length; idx < length; idx++) {
record = data[idx];
for (getter in getters) {
originalName = fieldNames[getter];
if (originalName && originalName !== getter) {
if (!setters[originalName]) {
setters[originalName] = kendo.setter(originalName);
}
setters[originalName](record, getters[getter](record));
delete record[getter];
}
}
}
}
function convertRecords(data, getters, modelInstance, originalFieldNames, fieldNames) {
var record,
getter,
originalName,
idx,
length;
for (idx = 0, length = data.length; idx < length; idx++) {
record = data[idx];
for (getter in getters) {
record[getter] = modelInstance._parse(getter, getters[getter](record));
originalName = fieldNames[getter];
if (originalName && originalName !== getter) {
delete record[originalName];
}
}
}
}
function convertGroup(data, getters, modelInstance, originalFieldNames, fieldNames) {
var record,
idx,
fieldName,
length;
for (idx = 0, length = data.length; idx < length; idx++) {
record = data[idx];
fieldName = originalFieldNames[record.field];
if (fieldName && fieldName != record.field) {
record.field = fieldName;
}
record.value = modelInstance._parse(record.field, record.value);
if (record.items) {
if (record.hasSubgroups) {
convertGroup(record.items, getters, modelInstance, originalFieldNames, fieldNames);
} else {
convertRecords(record.items, getters, modelInstance, originalFieldNames, fieldNames);
}
}
}
}
function wrapDataAccess(originalFunction, model, converter, getters, originalFieldNames, fieldNames) {
return function(data) {
data = originalFunction(data);
return wrapDataAccessBase(model, converter, getters, originalFieldNames, fieldNames)(data);
};
}
function wrapDataAccessBase(model, converter, getters, originalFieldNames, fieldNames) {
return function(data) {
if (data && !isEmptyObject(getters)) {
if (toString.call(data) !== "[object Array]" && !(data instanceof ObservableArray)) {
data = [data];
}
converter(data, getters, new model(), originalFieldNames, fieldNames);
}
return data || [];
};
}
var DataReader = Class.extend({
init: function(schema) {
var that = this, member, get, model, base;
schema = schema || {};
for (member in schema) {
get = schema[member];
that[member] = typeof get === STRING ? getter(get) : get;
}
base = schema.modelBase || Model;
if (isPlainObject(that.model)) {
that.model = model = base.define(that.model);
}
var dataFunction = that.data.bind(that);
that._dataAccessFunction = dataFunction;
if (that.model) {
var groupsFunction = that.groups.bind(that),
serializeFunction = that.serialize.bind(that),
originalFieldNames = {},
getters = {},
serializeGetters = {},
fieldNames = {},
shouldSerialize = false,
fieldName,
name;
model = that.model;
if (model.fields) {
each(model.fields, function(field, value) {
var fromName;
fieldName = field;
if (isPlainObject(value) && value.field) {
fieldName = value.field;
} else if (typeof value === STRING) {
fieldName = value;
}
if (isPlainObject(value) && value.from) {
fromName = value.from;
}
shouldSerialize = shouldSerialize || (fromName && fromName !== field) || fieldName !== field;
name = fromName || fieldName;
getters[field] = name.indexOf(".") !== -1 ? getter(name, true) : getter(name);
serializeGetters[field] = getter(field);
originalFieldNames[fromName || fieldName] = field;
fieldNames[field] = fromName || fieldName;
});
if (!schema.serialize && shouldSerialize) {
that.serialize = wrapDataAccess(serializeFunction, model, serializeRecords, serializeGetters, originalFieldNames, fieldNames);
}
}
that._dataAccessFunction = dataFunction;
that._wrapDataAccessBase = wrapDataAccessBase(model, convertRecords, getters, originalFieldNames, fieldNames);
that.data = wrapDataAccess(dataFunction, model, convertRecords, getters, originalFieldNames, fieldNames);
that.groups = wrapDataAccess(groupsFunction, model, convertGroup, getters, originalFieldNames, fieldNames);
}
},
errors: function(data) {
return data ? data.errors : null;
},
parse: identity,
data: identity,
total: function(data) {
return data.length;
},
groups: identity,
aggregates: function() {
return {};
},
serialize: function(data) {
return data;
}
});
function fillLastGroup(originalGroup, newGroup) {
var currOriginal;
var currentNew;
if (newGroup.items && newGroup.items.length) {
for (var i = 0; i < newGroup.items.length; i++) {
currOriginal = originalGroup.items[originalGroup.items.length - 1];
currentNew = newGroup.items[i];
if (currOriginal && currentNew) {
if (currOriginal.hasSubgroups && currOriginal.value == currentNew.value) {
fillLastGroup(currOriginal, currentNew);
} else if (currOriginal.field && currOriginal.value == currentNew.value) {
currOriginal.items.omitChangeEvent = true;
currOriginal.items.push.apply(currOriginal.items, currentNew.items);
currOriginal.items.omitChangeEvent = false;
} else {
originalGroup.items.omitChangeEvent = true;
originalGroup.items.push.apply(originalGroup.items, [currentNew]);
originalGroup.items.omitChangeEvent = false;
}
} else if (currentNew) {
originalGroup.items.omitChangeEvent = true;
originalGroup.items.push.apply(originalGroup.items, [currentNew]);
originalGroup.items.omitChangeEvent = false;
}
}
}
}
function mergeGroups(target, dest, skip, take) {
var group,
idx = 0,
items;
while (dest.length && take) {
group = dest[idx];
items = group.items;
var length = items.length;
if (target && target.field === group.field && target.value === group.value) {
if (target.hasSubgroups && target.items.length) {
mergeGroups(target.items[target.items.length - 1], group.items, skip, take);
} else {
items = items.slice(skip, skip + take);
target.items = target.items.concat(items);
}
dest.splice(idx--, 1);
} else if (group.hasSubgroups && items.length) {
mergeGroups(group, items, skip, take);
if (!group.items.length) {
dest.splice(idx--, 1);
}
} else {
items = items.slice(skip, skip + take);
group.items = items;
if (!group.items.length) {
dest.splice(idx--, 1);
}
}
if (items.length === 0) {
skip -= length;
} else {
skip = 0;
take -= items.length;
}
if (++idx >= dest.length) {
break;
}
}
if (idx < dest.length) {
dest.splice(idx, dest.length - idx);
}
}
function flatGroups(groups, indexFunction) {
var result = [];
var groupsLength = (groups || []).length;
var group;
var items;
var indexFn = isFunction(indexFunction) ? indexFunction : function(array, index) {
return array[index];
};
for (var groupIndex = 0; groupIndex < groupsLength; groupIndex++) {
group = indexFn(groups, groupIndex);
if (group.hasSubgroups) {
result = result.concat(flatGroups(group.items));
} else {
items = group.items;
for (var itemIndex = 0; itemIndex < items.length; itemIndex++) {
result.push(indexFn(items, itemIndex));
}
}
}
return result;
}
function flattenGroups(data) {
var idx,
result = [],
length,
items,
itemIndex;
for (idx = 0, length = data.length; idx < length; idx++) {
var group = data.at(idx);
if (group.items) {
if (group.hasSubgroups) {
result = result.concat(flattenGroups(group.items));
} else {
items = group.items;
for (itemIndex = 0; itemIndex < items.length; itemIndex++) {
result.push(items.at(itemIndex));
}
}
}
}
return result;
}
function wrapGroupItems(data, model) {
var idx, length, group;
if (model) {
for (idx = 0, length = data.length; idx < length; idx++) {
group = data.at(idx);
if (group.items) {
if (group.hasSubgroups) {
wrapGroupItems(group.items, model);
} else {
group.items = new LazyObservableArray(group.items, model, group.items._events);
}
}
}
}
}
function eachGroupItems(data, func) {
for (var idx = 0; idx < data.length; idx++) {
if (data[idx].hasSubgroups) {
if (eachGroupItems(data[idx].items, func)) {
return true;
}
} else if (func(data[idx].items, data[idx])) {
return true;
}
}
}
function replaceInRanges(ranges, data, item, observable) {
for (var idx = 0; idx < ranges.length; idx++) {
if (ranges[idx].data === data) {
break;
}
if (replaceInRange(ranges[idx].data, item, observable)) {
break;
}
}
}
function replaceInRange(items, item, observable) {
for (var idx = 0, length = items.length; idx < length; idx++) {
if (items[idx] && items[idx].hasSubgroups) {
return replaceInRange(items[idx].items, item, observable);
} else if (items[idx] === item || items[idx] === observable) {
items[idx] = observable;
return true;
}
}
}
function replaceWithObservable(view, data, ranges, type, serverGrouping) {
for (var viewIndex = 0, length = view.length; viewIndex < length; viewIndex++) {
var item = view[viewIndex];
if (!item || item instanceof type) {
continue;
}
if (item.hasSubgroups !== undefined$1 && !serverGrouping) {
replaceWithObservable(item.items, data, ranges, type, serverGrouping);
} else {
for (var idx = 0; idx < data.length; idx++) {
if (data[idx] === item) {
view[viewIndex] = data.at(idx);
replaceInRanges(ranges, data, item, view[viewIndex]);
break;
}
}
}
}
}
function removeModel(data, model) {
if (!data) {
return;
}
var length = data.length;
var dataItem;
var idx;
for (idx = 0; idx < length; idx++) {
dataItem = data[idx];
if (dataItem.uid && dataItem.uid == model.uid) {
data.splice(idx, 1);
return dataItem;
}
}
}
function indexOfPristineModel(data, model) {
if (model) {
return indexOf(data, function(item) {
return (item.uid && item.uid == model.uid) || (item[model.idField] === model.id && model.id !== model._defaultId);
});
}
return -1;
}
function indexOfModel(data, model) {
if (model) {
return indexOf(data, function(item) {
return item.uid == model.uid;
});
}
return -1;
}
function indexOf(data, comparer) {
var idx, length;
if (!data) {
return;
}
for (idx = 0, length = data.length; idx < length; idx++) {
if (comparer(data[idx])) {
return idx;
}
}
return -1;
}
function fieldNameFromModel(fields, name) {
if (fields && !isEmptyObject(fields)) {
var descriptor = fields[name];
var fieldName;
if (isPlainObject(descriptor)) {
fieldName = descriptor.from || descriptor.field || name;
} else {
fieldName = fields[name] || name;
}
if (isFunction(fieldName)) {
return name;
}
return fieldName;
}
return name;
}
function convertFilterDescriptorsField(descriptor, model) {
var idx,
length,
target = {};
for (var field in descriptor) {
if (field !== "filters") {
target[field] = descriptor[field];
}
}
if (descriptor.filters) {
target.filters = [];
for (idx = 0, length = descriptor.filters.length; idx < length; idx++) {
target.filters[idx] = convertFilterDescriptorsField(descriptor.filters[idx], model);
}
} else {
target.field = fieldNameFromModel(model.fields, target.field);
}
return target;
}
function convertDescriptorsField(descriptors, model) {
var idx,
length,
result = [],
target,
descriptor;
for (idx = 0, length = descriptors.length; idx < length; idx ++) {
target = {};
descriptor = descriptors[idx];
for (var field in descriptor) {
target[field] = descriptor[field];
}
target.field = fieldNameFromModel(model.fields, target.field);
if (target.aggregates && isArray(target.aggregates)) {
target.aggregates = convertDescriptorsField(target.aggregates, model);
}
result.push(target);
}
return result;
}
var DataSource = Observable.extend({
init: function(options) {
var that = this, data;
if (options) {
data = options.data;
}
options = that.options = extend({}, that.options, options);
that._map = {};
that._prefetch = {};
that._data = [];
that._pristineData = [];
that._ranges = [];
that._view = [];
that._pristineTotal = 0;
that._destroyed = [];
that._pageSize = options.pageSize;
that._page = options.page || (options.pageSize ? 1 : undefined$1);
that._sort = normalizeSort(options.sort);
that._sortFields = sortFields(options.sort);
that._filter = normalizeFilter(options.filter);
that._group = normalizeGroup(options.group);
that._aggregate = options.aggregate;
that._total = options.total;
that._groupPaging = options.groupPaging;
if (that._groupPaging) {
that._groupsState = {};
}
that._shouldDetachObservableParents = true;
Observable.fn.init.call(that);
that.transport = Transport.create(options, data, that);
if (isFunction(that.transport.push)) {
that.transport.push({
pushCreate: that._pushCreate.bind(that),
pushUpdate: that._pushUpdate.bind(that),
pushDestroy: that._pushDestroy.bind(that)
});
}
if (options.offlineStorage != null) {
if (typeof options.offlineStorage == "string") {
var key = options.offlineStorage;
that._storage = {
getItem: function() {
return JSON.parse(localStorage.getItem(key));
},
setItem: function(item) {
localStorage.setItem(key, stringify(that.reader.serialize(item)));
}
};
} else {
that._storage = options.offlineStorage;
}
}
that.reader = new kendo.data.readers[options.schema.type || "json" ](options.schema);
that.reader.model || {};
that._detachObservableParents();
that._data = that._observe(that._data);
that._online = true;
that.bind(["push", ERROR, CHANGE, REQUESTSTART, SYNC, REQUESTEND, PROGRESS], options);
},
options: {
data: null,
schema: {
modelBase: Model
},
offlineStorage: null,
serverSorting: false,
serverPaging: false,
serverFiltering: false,
serverGrouping: false,
serverAggregates: false,
batch: false,
inPlaceSort: false
},
clone: function() {
return this;
},
online: function(value) {
if (value !== undefined$1) {
if (this._online != value) {
this._online = value;
if (value) {
return this.sync();
}
}
return $.Deferred().resolve().promise();
} else {
return this._online;
}
},
offlineData: function(state) {
if (this.options.offlineStorage == null) {
return null;
}
if (state !== undefined$1) {
return this._storage.setItem(state);
}
return this._storage.getItem() || [];
},
_isGrouped: function() {
var group = this.group() || [];
return group.length;
},
_isServerGrouped: function() {
var group = this.group() || [];
return this.options.serverGrouping && group.length;
},
_isServerGroupPaged: function() {
return this._isServerGrouped() && this._groupPaging;
},
_isGroupPaged: function() {
var group = this._group || [];
return this._groupPaging && group.length;
},
_pushCreate: function(result) {
this._push(result, "pushCreate");
},
_pushUpdate: function(result) {
this._push(result, "pushUpdate");
},
_pushDestroy: function(result) {
this._push(result, "pushDestroy");
},
_push: function(result, operation) {
var data = this._readData(result);
if (!data) {
data = result;
}
this[operation](data);
},
_flatData: function(data, skip) {
if (data) {
if (this._isServerGrouped()) {
return flattenGroups(data);
}
if (!skip) {
for (var idx = 0; idx < data.length; idx++) {
data.at(idx);
}
}
}
return data;
},
parent: noop,
get: function(id) {
var idx, length, data = this._flatData(this._data, this.options.useRanges);
for (idx = 0, length = data.length; idx < length; idx++) {
if (data[idx].id == id) {
return data[idx];
}
}
},
getByUid: function(id) {
return this._getByUid(id, this._data);
},
_getByUid: function(id, dataItems) {
var idx, length, data = this._flatData(dataItems, this.options.useRanges);
if (!data) {
return;
}
for (idx = 0, length = data.length; idx < length; idx++) {
if (data[idx].uid == id) {
return data[idx];
}
}
},
indexOf: function(model) {
return indexOfModel(this._data, model);
},
at: function(index) {
return this._data.at(index);
},
data: function(value) {
var that = this;
if (value !== undefined$1) {
that._detachObservableParents();
that._data = this._observe(value);
that._pristineData = value.slice(0);
that._storeData();
that._ranges = [];
that.trigger("reset");
that._addRange(that._data);
that._total = that._data.length;
that._pristineTotal = that._total;
that._process(that._data);
} else {
if (that._data) {
for (var idx = 0; idx < that._data.length; idx++) {
that._data.at(idx);
}
}
return that._data;
}
},
view: function(value) {
if (value === undefined$1) {
return this._view;
} else {
this._view = this._observeView(value);
}
},
_observeView: function(data) {
var that = this;
replaceWithObservable(data, that._data, that._ranges, that.reader.model || ObservableObject, that._isServerGrouped());
var view = new LazyObservableArray(data, that.reader.model);
view.parent = function() { return that.parent(); };
return view;
},
flatView: function() {
var groups = this.group() || [];
if (groups.length) {
return flattenGroups(this._view);
} else {
return this._view;
}
},
add: function(model) {
return this.insert(this._data.length, model);
},
_createNewModel: function(model) {
if (this.reader.model) {
return new this.reader.model(model);
}
if (model instanceof ObservableObject) {
return model;
}
return new ObservableObject(model);
},
insert: function(index, model) {
if (!model) {
model = index;
index = 0;
}
if (!(model instanceof Model)) {
model = this._createNewModel(model);
}
if (this._isServerGrouped()) {
this._data.splice(index, 0, this._wrapInEmptyGroup(model));
} else {
this._data.splice(index, 0, model);
}
this._insertModelInRange(index, model);
return model;
},
pushInsert: function(index, items) {
var that = this;
var rangeSpan = that._getCurrentRangeSpan();
if (!items) {
items = index;
index = 0;
}
if (!isArray(items)) {
items = [items];
}
var pushed = [];
var autoSync = this.options.autoSync;
this.options.autoSync = false;
try {
for (var idx = 0; idx < items.length; idx ++) {
var item = items[idx];
var result = this.insert(index, item);
pushed.push(result);
var pristine = result.toJSON();
if (this._isServerGrouped()) {
pristine = this._wrapInEmptyGroup(pristine);
}
this._pristineData.push(pristine);
if (rangeSpan && rangeSpan.length) {
$(rangeSpan).last()[0].pristineData.push(pristine);
}
index++;
}
} finally {
this.options.autoSync = autoSync;
}
if (pushed.length) {
this.trigger("push", {
type: "create",
items: pushed
});
}
},
pushCreate: function(items) {
this.pushInsert(this._data.length, items);
},
pushUpdate: function(items) {
if (!isArray(items)) {
items = [items];
}
var pushed = [];
for (var idx = 0; idx < items.length; idx ++) {
var item = items[idx];
var model = this._createNewModel(item);
var target = this.get(model.id);
if (target) {
pushed.push(target);
target.accept(item);
target.trigger(CHANGE);
this._updatePristineForModel(target, item);
} else {
this.pushCreate(item);
}
}
if (pushed.length) {
this.trigger("push", {
type: "update",
items: pushed
});
}
},
pushDestroy: function(items) {
var pushed = this._removeItems(items);
if (pushed.length) {
this.trigger("push", {
type: "destroy",
items: pushed
});
}
},
_removeItems: function(itemsToRemove, removePristine) {
if (!isArray(itemsToRemove)) {
itemsToRemove = [itemsToRemove];
}
var shouldRemovePristine = typeof removePristine !== "undefined" ? removePristine : true;
var destroyed = [];
var autoSync = this.options.autoSync;
this.options.autoSync = false;
try {
for (var idx = 0; idx < itemsToRemove.length; idx ++) {
var item = itemsToRemove[idx];
var model = this._createNewModel(item);
var found = false;
var index = idx;
this._eachItem(this._data, function(items) {
// Ensure all children of a parent are removed before the change event is triggered.
if (index !== itemsToRemove.length - 1) {
items.omitChangeEvent = true;
items.omitCache = items.omitCache || [];
} else {
items.omitChangeEvent = false;
}
for (var idx = 0; idx < items.length; idx++) {
var item = items.at(idx);
if (item.id === model.id) {
/* When the change event is omitted, certain calculations such as 'total' are broken because only the last item reaches the change handler.
Keep track of all child items that had their change event omitted and when the change is finally triggered, concat them to the result.*/
if (items.omitChangeEvent) {
items.omitCache.push(item);
}
destroyed.push(item);
items.splice(idx, 1);
found = true;
break;
}
}
});
if (found && shouldRemovePristine) {
this._removePristineForModel(model);
this._destroyed.pop();
}
}
} finally {
this.options.autoSync = autoSync;
}
return destroyed;
},
pushMove: function(index, items) {
var pushed = this._moveItems(index, items);
if (pushed.length) {
this.trigger("push", {
type: "update",
items: pushed
});
}
},
_moveItems: function(index, items) {
if (!isArray(items)) {
items = [items];
}
var moved = [];
var autoSync = this.options.autoSync;
this.options.autoSync = false;
try {
for (var i = 0; i < items.length; i ++) {
var item = items[i];
this._eachItem(this._data, function(dataItems) {
for (var idx = 0; idx < dataItems.length; idx++) {
var dataItem = dataItems.at(idx);
if (dataItem.uid === item.uid) {
moved.push(dataItem);
dataItems.splice(index >= idx ? --index : index, 0, dataItems.splice(idx, 1)[0]);
index++;
break;
}
}
});
}
} finally {
this.options.autoSync = autoSync;
}
return moved;
},
remove: function(model) {
var result,
that = this,
hasGroups = that._isServerGrouped();
if (hasGroups && model.uid && (!model.isNew || !model.isNew())) {
that._pushInDestroyed(model);
}
this._eachItem(that._data, function(items) {
result = removeModel(items, model);
if (result && hasGroups) {
return true;
}
});
this._removeModelFromRanges(model);
return model;
},
destroyed: function() {
return this._destroyed;
},
created: function() {
var idx,
length,
result = [],
data = this._flatData(this._data, this.options.useRanges);
for (idx = 0, length = data.length; idx < length; idx++) {
if (data[idx].isNew && data[idx].isNew() && !data[idx].notFetched) {
result.push(data[idx]);
}
}
return result;
},
updated: function() {
var idx,
length,
result = [],
data = this._flatData(this._data, this.options.useRanges);
for (idx = 0, length = data.length; idx < length; idx++) {
if ((data[idx].isNew && !data[idx].isNew()) && data[idx].dirty) {
result.push(data[idx]);
}
}
return result;
},
sync: function() {
var that = this,
created = [],
updated = [],
destroyed;
that._destroyed = that._destroyed
.filter(item => !item.hasOwnProperty("_isMoved"));
destroyed = that._destroyed;
var promise = $.Deferred().resolve().promise();
if (that.online()) {
if (!that.reader.model) {
return promise;
}
created = that.created();
updated = that.updated();
var promises = [];
if (that.options.batch && that.transport.submit) {
promises = that._sendSubmit(created, updated, destroyed);
} else {
promises.push.apply(promises, that._send("create", created));
promises.push.apply(promises, that._send("update", updated));
promises.push.apply(promises, that._send("destroy", destroyed));
}
promise = $.when
.apply(null, promises)
.then(function() {
var idx, length, changedItems = [];
for (idx = 0, length = arguments.length; idx < length; idx++) {
if (arguments[idx]) {
that._accept(arguments[idx]);
changedItems.push(...arguments[idx].models);
}
}
that._storeData(true);
that._syncEnd();
that._change({ action: "sync", changedItems: changedItems });
that.trigger(SYNC);
if (that._isServerGroupPaged()) {
that.read();
}
that.data().map(function(item) {
if (item.hasOwnProperty("_isMoved")) {
delete item._isMoved;
}
return item;
});
});
} else {
that._storeData(true);
that._syncEnd();
that._change({ action: "sync" });
}
return promise;
},
_syncEnd: noop,
cancelChanges: function(model) {
var that = this;
if (model instanceof kendo.data.Model) {
that._cancelModel(model);
} else {
that._destroyed = [];
that._detachObservableParents();
that._data = that._observe(that._pristineData);
if (that.options.serverPaging) {
that._total = that._pristineTotal;
}
that._ranges = [];
that._addRange(that._data, 0);
that._changesCanceled();
that._change();
that._markOfflineUpdatesAsDirty();
if (that._isServerGrouped()) {
that.read();
}
}
},
_changesCanceled: noop,
_markOfflineUpdatesAsDirty: function() {
var that = this;
if (that.options.offlineStorage != null) {
that._eachItem(that._data, function(items) {
for (var idx = 0; idx < items.length; idx++) {
var item = items.at(idx);
if (item.__state__ == "update" || item.__state__ == "create") {
item.dirty = true;
}
}
});
}
},
hasChanges: function() {
var idx,
length,
data = this._flatData(this._data, this.options.useRanges);
if (this._destroyed.length) {
return true;
}
for (idx = 0, length = data.length; idx < length; idx++) {
if ((data[idx].isNew && data[idx].isNew()) || data[idx].dirty) {
return true;
}
}
return false;
},
_accept: function(result) {
var that = this,
models = result.models,
response = result.response,
idx = 0,
serverGroup = that._isServerGrouped(),
pristine = that._pristineData,
type = result.type,
length;
that.trigger(REQUESTEND, { response: response, type: type });
if (response && !isEmptyObject(response)) {
response = that.reader.parse(response);
if (that._handleCustomErrors(response)) {
return;
}
response = that.reader.data(response);
if (!isArray(response)) {
response = [response];
}
} else {
response = $.map(models, function(model) { return model.toJSON(); } );
}
if (type === "destroy") {
that._destroyed = [];
}
for (idx = 0, length = models.length; idx < length; idx++) {
if (type !== "destroy") {
models[idx].accept(response[idx]);
if (type === "create") {
pristine.push(serverGroup ? that._wrapInEmptyGroup(models[idx].toJSON()) : response[idx]);
} else if (type === "update") {
that._updatePristineForModel(models[idx], response[idx]);
}
} else {
that._removePristineForModel(models[idx]);
}
}
},
_updatePristineForModel: function(model, values) {
this._executeOnPristineForModel(model, function(index, items) {
kendo.deepExtend(items[index], values);
});
},
_executeOnPristineForModel: function(model, callback) {
this._eachPristineItem(
function(items) {
var index = indexOfPristineModel(items, model);
if (index > -1) {
callback(index, items);
return true;
}
});
},
_removePristineForModel: function(model) {
this._executeOnPristineForModel(model, function(index, items) {
items.splice(index, 1);
});
},
_readData: function(data) {
var read = !this._isServerGrouped() ? this.reader.data : this.reader.groups;
return read.call(this.reader, data);
},
_eachPristineItem: function(callback) {
var that = this;
var options = that.options;
var rangeSpan = that._getCurrentRangeSpan();
that._eachItem(that._pristineData, callback);
if (options.serverPaging && options.useRanges) {
each(rangeSpan, function(i, range) {
that._eachItem(range.pristineData, callback);
});
}
},
_eachItem: function(data, callback) {
if (data && data.length) {
if (this._isServerGrouped()) {
eachGroupItems(data, callback);
} else {
callback(data);
}
}
},
_pristineForModel: function(model) {
var pristine,
idx,
callback = function(items) {
idx = indexOfPristineModel(items, model);
if (idx > -1) {
pristine = items[idx];
return true;
}
};
this._eachPristineItem(callback);
return pristine;
},
_cancelModel: function(model) {
var that = this;
var pristine = this._pristineForModel(model);
this._eachItem(this._data, function(items) {
var idx = indexOfModel(items, model);
if (idx >= 0) {
if (pristine && (!model.isNew() || pristine.__state__)) {
items[idx].accept(pristine);
if (pristine.__state__ == "update") {
items[idx].dirty = true;
}
} else {
that._modelCanceled(model);
items.splice(idx, 1);
that._removeModelFromRanges(model);
}
}
});
},
_modelCanceled: noop,
_submit: function(promises, data) {
var that = this;
that.trigger(REQUESTSTART, { type: "submit" });
that.trigger(PROGRESS);
that.transport.submit(extend({
success: function(response, type) {
var promise = $.grep(promises, function(x) {
return x.type == type;
})[0];
if (promise) {
promise.resolve({
response: response,
models: promise.models,
type: type
});
}
},
error: function(response, status, error) {
for (var idx = 0; idx < promises.length; idx++) {
promises[idx].reject(response);
}
that.error(response, status, error);
}
}, data));
},
_sendSubmit: function(created, updated, destroyed) {
var that = this,
promises = [];
if (that.options.batch) {
if (created.length) {
promises.push($.Deferred(function(deferred) {
deferred.type = "create";
deferred.models = created;
}));
}
if (updated.length) {
promises.push($.Deferred(function(deferred) {
deferred.type = "update";
deferred.models = updated;
}));
}
if (destroyed.length) {
promises.push($.Deferred(function(deferred) {
deferred.type = "destroy";
deferred.models = destroyed;
}));
}
that._submit(promises, {
data: {
created: that.reader.serialize(toJSON(created)),
updated: that.reader.serialize(toJSON(updated)),
destroyed: that.reader.serialize(toJSON(destroyed))
}
});
}
return promises;
},
_promise: function(data, models, type) {
var that = this;
return $.Deferred(function(deferred) {
that.trigger(REQUESTSTART, { type: type });
that.trigger(PROGRESS);
that.transport[type].call(that.transport, extend({
success: function(response) {
deferred.resolve({
response: response,
models: models,
type: type
});
},
error: function(response, status, error) {
deferred.reject(response);
that.error(response, status, error);
}
}, data));
}).promise();
},
_send: function(method, data) {
var that = this,
idx,
length,
promises = [],
converted = that.reader.serialize(toJSON(data));
if (that.options.batch) {
if (data.length) {
promises.push(that._promise( { data: { models: converted } }, data , method));
}
} else {
for (idx = 0, length = data.length; idx < length; idx++) {
promises.push(that._promise( { data: converted[idx] }, [ data[idx] ], method));
}
}
return promises;
},
read: function(data) {
var that = this, params = that._params(data);
var deferred = $.Deferred();
that._queueRequest(params, function() {
var isPrevented = that.trigger(REQUESTSTART, { type: "read" });
if (!isPrevented) {
that.trigger(PROGRESS);
that._ranges = [];
that.trigger("reset");
if (that.online()) {
that.transport.read({
data: params,
success: function(data) {
that._ranges = [];
that.success(data, params);
deferred.resolve();
},
error: function() {
var args = slice.call(arguments);
that.error.apply(that, args);
deferred.reject.apply(deferred, args);
}
});
} else if (that.options.offlineStorage != null) {
that.success(that.offlineData(), params);
deferred.resolve();
}
} else {
that._dequeueRequest();
deferred.resolve(isPrevented);
}
});
return deferred.promise();
},
_readAggregates: function(data) {
return this.reader.aggregates(data);
},
success: function(data) {
var that = this,
options = that.options,
items,
replaceSubset;
that.trigger(REQUESTEND, { response: data, type: "read" });
if (that.online()) {
data = that.reader.parse(data);
if (that._handleCustomErrors(data)) {
that._dequeueRequest();
return;
}
that._total = that.reader.total(data);
if (that._isServerGroupPaged()) {
that._serverGroupsTotal = that._total;
}
if (that._pageSize > that._total) {
that._pageSize = that._total;
if (that.options.pageSize && that.options.pageSize > that._pageSize) {
that._pageSize = that.options.pageSize;
}
}
if (that._aggregate && options.serverAggregates) {
that._aggregateResult = that._readAggregates(data);
}
data = that._readData(data);
that._destroyed = [];
} else {
data = that._readData(data);
items = [];
var itemIds = {};
var model = that.reader.model;
var idField = model ? model.idField : "id";
var idx;
for (idx = 0; idx < this._destroyed.length; idx++) {
var id = this._destroyed[idx][idField];
itemIds[id] = id;
}
for (idx = 0; idx < data.length; idx++) {
var item = data[idx];
var state = item.__state__;
if (state == "destroy") {
if (!itemIds[item[idField]]) {
this._pushInDestroyed(this._createNewModel(item));
}
} else {
items.push(item);
}
}
data = items;
that._total = data.length;
}
that._pristineTotal = that._total;
replaceSubset = that._skip && that._data.length && that._skip < that._data.length;
if (that.options.endless) {
if (replaceSubset) {
that._pristineData.splice(that._skip, that._pristineData.length);
}
items = data.slice(0);
for (var j = 0; j < items.length; j++) {
that._pristineData.push(items[j]);
}
} else {
that._pristineData = data.slice(0);
}
that._detachObservableParents();
if (that.options.endless) {
that._data.unbind(CHANGE, that._changeHandler);
if (that._isServerGrouped() && that._data[that._data.length - 1].value === data[0].value) {
fillLastGroup(that._data[that._data.length - 1], data[0]);
data.shift();
}
data = that._observe(data);
if (replaceSubset) {
that._data.splice(that._skip, that._data.length);
}
for (var i = 0; i < data.length; i++) {
that._data.push(data[i]);
}
that._data.bind(CHANGE, that._changeHandler);
} else {
that._data = that._observe(data);
}
that._markOfflineUpdatesAsDirty();
that._storeData();
that._addRange(that._data);
that._process(that._data);
that._dequeueRequest();
},
_detachObservableParents: function() {
if (this._data && this._shouldDetachObservableParents) {
for (var idx = 0; idx < this._data.length; idx++) {
if (this._data[idx].parent) {
this._data[idx].parent = noop;
}
}
}
},
_storeData: function(updatePristine) {
var serverGrouping = this._isServerGrouped();
var model = this.reader.model;
function items(data) {
var state = [];
for (var idx = 0; idx < data.length; idx++) {
var dataItem = data.at(idx);
var item = dataItem.toJSON();
if (serverGrouping && dataItem.items) {
item.items = items(dataItem.items);
} else {
item.uid = dataItem.uid;
if (model) {
if (dataItem.isNew()) {
item.__state__ = "create";
} else if (dataItem.dirty) {
item.__state__ = "update";
}
}
}
state.push(item);
}
return state;
}
if (this.options.offlineStorage != null) {
var state = items(this._data);
var destroyed = [];
for (var idx = 0; idx < this._destroyed.length; idx++) {
var item = this._destroyed[idx].toJSON();
item.__state__ = "destroy";
destroyed.push(item);
}
this.offlineData(state.concat(destroyed));
if (updatePristine) {
this._pristineData = this.reader.reader ? this.reader.reader._wrapDataAccessBase(state) : this.reader._wrapDataAccessBase(state);
}
}
},
_addRange: function(data, skip) {
var that = this,
start = typeof (skip) !== "undefined" ? skip : (that._skip || 0),
end,
range = {
data: data,
pristineData: data.toJSON(),
timestamp: that._timeStamp()
};
if (this._isGroupPaged()) {
end = start + data.length;
range.outerStart = start;
range.outerEnd = end;
} else {
end = start + that._flatData(data, true).length;
}
range.start = start;
range.end = end;
that._ranges.push(range);
that._sortRanges();
if (that._isGroupPaged()) {
if (!that._groupsFlat) {
that._groupsFlat = [];
}
that._appendToGroupsFlat(range.data);
that._updateOuterRangesLength();
}
},
_appendToGroupsFlat: function(data) {
var length = data.length;
for (var i = 0; i < length; i++) {
this._groupsFlat.push(data[i]);
}
},
_getGroupByUid: function(uid) {
var length = this._groupsFlat.length;
var group;
for (var i = 0; i < length; i++) {
group = this._groupsFlat[i];
if (group.uid === uid) {
return group;
}
}
},
_sortRanges: function() {
this._ranges.sort(function(x, y) {
return x.start - y.start;
});
},
error: function(xhr, status, errorThrown) {
this._dequeueRequest();
this.trigger(REQUESTEND, { });
this.trigger(ERROR, { xhr: xhr, status: status, errorThrown: errorThrown });
},
_params: function(data) {
var that = this,
options = extend({
take: that.take(),
skip: that.skip(),
page: that.page(),
pageSize: that.pageSize(),
sort: that._sort,
filter: that._filter,
group: that._group,
aggregate: that._aggregate,
groupPaging: !!that._groupPaging,
isExcelExportRequest: that.options.isExcelExportRequest
}, data);
if (!that.options.serverPaging) {
delete options.take;
delete options.skip;
delete options.page;
delete options.pageSize;
}
if (!that.options.serverGrouping) {
delete options.group;
} else if (that.reader.model && options.group) {
options.group = convertDescriptorsField(options.group, that.reader.model);
}
if (!that.options.serverFiltering) {
delete options.filter;
} else if (that.reader.model && options.filter) {
options.filter = convertFilterDescriptorsField(options.filter, that.reader.model);
}
if (!that.options.serverSorting) {
delete options.sort;
} else if (that.reader.model && options.sort) {
options.sort = convertDescriptorsField(options.sort, that.reader.model);
}
if (!that.options.serverAggregates) {
delete options.aggregate;
} else if (that.reader.model && options.aggregate) {
options.aggregate = convertDescriptorsField(options.aggregate, that.reader.model);
}
if (!that.options.groupPaging || !(that.options.serverPaging && that.options.serverGrouping)) {
delete options.groupPaging;
}
if (!that.options.isExcelExportRequest) {
delete options.isExcelExportRequest;
}
return options;
},
_queueRequest: function(options, callback) {
var that = this;
if (!that._requestInProgress) {
that._requestInProgress = true;
that._pending = undefined$1;
callback();
} else {
that._pending = { callback: callback.bind(that), options: options };
}
},
_dequeueRequest: function() {
var that = this;
that._requestInProgress = false;
if (that._pending) {
that._queueRequest(that._pending.options, that._pending.callback);
}
},
_handleCustomErrors: function(response) {
if (this.reader.errors) {
var errors = this.reader.errors(response);
if (errors) {
this.trigger(ERROR, { xhr: null, status: "customerror", errorThrown: "custom error", errors: errors });
return true;
}
}
return false;
},
_shouldWrap: function(data) {
var model = this.reader.model;
if (model && data.length) {
return !(data[0] instanceof model);
}
return false;
},
_observe: function(data) {
var that = this,
model = that.reader.model;
that._shouldDetachObservableParents = true;
if (data instanceof ObservableArray) {
that._shouldDetachObservableParents = false;
if (that._shouldWrap(data)) {
data.type = that.reader.model;
data.wrapAll(data, data);
}
} else {
var arrayType = that.pageSize() && !that.options.serverPaging ? LazyObservableArray : ObservableArray;
data = new arrayType(data, that.reader.model);
data.parent = function() { return that.parent(); };
}
if (that._isServerGrouped()) {
wrapGroupItems(data, model);
}
if (that._changeHandler && that._data && that._data instanceof ObservableArray &&
!(that.options.useRanges && that.options.serverPaging)) {
that._data.unbind(CHANGE, that._changeHandler);
} else {
that._changeHandler = that._change.bind(that);
}
return data.bind(CHANGE, that._changeHandler);
},
_updateTotalForAction: function(action, items) {
var that = this;
var total = parseInt(that._total, 10);
if (!isNumber(that._total)) {
total = parseInt(that._pristineTotal, 10);
}
if (action === "add") {
total += items.length;
} else if (action === "remove") {
total -= items.length;
} else if (action !== "itemchange" && action !== "sync" && !that.options.serverPaging) {
total = that._pristineTotal;
} else if (action === "sync") {
total = that._pristineTotal = parseInt(that._total, 10);
}
that._total = total;
},
_operationsForUpdatedFields: function() {
const that = this,
updatedFields = that._updatedFields || [],
operations = {};
let found = false,
stringified;
operations.sort = that._sort;
operations.filter = that._filter;
operations.group = that._group;
operations.aggregate = that._aggregate;
stringified = stringify(operations);
found = updatedFields.some(u => stringified.indexOf((`"field":"${u}"`)) > -1);
return !found;
},
_pushInDestroyed: function(model) {
var isPushed = this._destroyed.find(function(item) {
return item.uid === model.uid;
});
if (!isPushed) {
this._destroyed.push(model);
}
},
_change: function(e) {
let that = this, idx, items, length, action = e ? e.action : "";
if (action === "remove") {
for (idx = 0, length = e.items.length; idx < length; idx++) {
if (!e.items[idx].isNew || !e.items[idx].isNew()) {
that._pushInDestroyed(e.items[idx]);
}
}
}
if (e) {
items = e.items || [];
e.partialUpdate = that._operationsForUpdatedFields() && !that._preventPartialUpdate;
if (e.action === "itemchange" && items.some(i => i.dirtyFields)) {
let item = e.items[0],
keys = Object.keys(item.dirtyFields),
result = keys;
for (const key of keys) {
if (item[key] instanceof Object) {
let stringifiedKey = kendo.stringify(item[key]);
if (stringifiedKey) {
let cleanObject = JSON.parse(stringifiedKey),
cleanObjectKeys = Object.keys(cleanObject).map((k) => key + "." + k);
result.push(...cleanObjectKeys);
}
}
}
that._updatedFields = result;
}
}
if (that.options.autoSync && (action === "add" || action === "remove" || action === "itemchange")) {
if (action === "add") {
that._preventPartialUpdate = true;
}
var handler = function(args) {
if (args.action === "sync") {
that._preventPartialUpdate = false;
that.unbind("change", handler);
that._updateTotalForAction(action, e.items);
}
};
that.first("change", handler);
that.sync();
} else {
that._updateTotalForAction(action, e ? e.items : []);
that._process(that._data, e);
}
},
_calculateAggregates: function(data, options) {
options = options || {};
var query = new Query(data),
aggregates = options.aggregate,
filter = options.filter;
if (filter) {
query = query.filter(filter);
}
return query.aggregate(aggregates);
},
_process: function(data, e) {
var that = this,
options = {},
result;
if (that.options.serverPaging !== true) {
options.skip = that._skip;
options.take = that._take || that._pageSize;
if (options.skip === undefined$1 && that._page !== undefined$1 && that._pageSize !== undefined$1) {
options.skip = (that._page - 1) * that._pageSize;
}
if (that.options.useRanges) {
options.skip = that.currentRangeStart();
}
}
if (that.options.serverSorting !== true) {
options.sort = that._sort;
}
if (that.options.serverFiltering !== true) {
options.filter = that._filter;
}
if (that.options.serverGrouping !== true) {
options.group = that._group;
}
if (that.options.serverAggregates !== true) {
options.aggregate = that._aggregate;
}
if (that.options.serverGrouping) {
that._clearEmptyGroups(data);
}
options.groupPaging = that._groupPaging;
if (that._isGroupPaged() && e && (e.action === "page" || e.action === "expandGroup" || e.action === "collapseGroup")) {
result = that._queryProcess(data, {
aggregate: that._aggregate
});
} else {
result = that._queryProcess(data, options);
}
if (that._filter && e && e.action === "add") {
var model = e.items[0],
resultData = result.data;
if (that._isGrouped() && !this._isServerGrouped()) {
resultData = flattenGroups(resultData);
}
var modelIsInView = resultData.find(function(item) {
return item.uid === model.uid;
});
if (!modelIsInView && (model.index || model.id === null)) {
result.data.splice(model.index, 0, that._isGrouped() ? that._wrapInEmptyGroup(model) : model);
result.total++;
}
}
if (that.options.serverAggregates !== true) {
// for performance reasons, calculate aggregates for part of the data only after query process
// this is necessary in the TreeList when paging
that._aggregateResult = that._calculateAggregates(result.dataToAggregate || data, options);
}
that._setView(result, options, e);
that._setFilterTotal(result.total, false);
e = e || {};
e.items = e.items || that._view;
that.trigger(CHANGE, e);
},
_setView: function(result, options, e) {
var that = this;
if (that._isGroupPaged() && !that._isServerGrouped()) {
if (e && (e.action === "page" || e.action === "expandGroup" || e.action === "collapseGroup")) {
that.view(result.data);
that._updateOuterRangesLength();
} else {
that._ranges = [];
var query = new Query(result.data);
that._addRange(that._observe(result.data));
if (options.skip + options.take > result.data.length) {
options.skip = Math.max(0, result.data.length - options.take);
}
that.view(query.range(options.skip, options.take).toArray());
}
} else {
that.view(result.data);
}
},
_clearEmptyGroups: function(data) {
for (var idx = data.length - 1; idx >= 0; idx--) {
var group = data[idx];
if (group.hasSubgroups) {
this._clearEmptyGroups(group.items);
}
if (group.items && !group.items.length && !group.itemCount) {
splice.apply(group.parent(), [idx, 1]);
}
}
},
_queryProcess: function(data, options) {
if (this.options.inPlaceSort) {
return Query.process(data, options, this.options.inPlaceSort);
}
else {
return Query.process(data, options);
}
},
_mergeState: function(options) {
var that = this;
if (options !== undefined$1) {
that._pageSize = options.pageSize;
that._page = options.page;
that._sort = options.sort;
that._filter = options.filter;
that._group = options.group;
that._aggregate = options.aggregate;
that._skip = that._currentRangeStart = options.skip;
that._take = options.take;
if (that._skip === undefined$1) {
that._skip = that._currentRangeStart = that.skip();
options.skip = that.skip();
}
if (that._take === undefined$1 && that._pageSize !== undefined$1) {
that._take = that._pageSize;
options.take = that._take;
}
if (that.options.virtual) {
options.virtual = that.options.virtual;
}
if (options.sort) {
that._sort = options.sort = normalizeSort(options.sort);
that._sortFields = sortFields(options.sort);
}
if (options.filter) {
that._filter = options.filter = (that.options.accentFoldingFiltering && !$.isEmptyObject(options.filter)) ? $.extend({}, normalizeFilter(options.filter), { accentFoldingFiltering: that.options.accentFoldingFiltering }) : normalizeFilter(options.filter);
}
if (options.group) {
that._group = options.group = normalizeGroup(options.group);
}
if (options.aggregate) {
that._aggregate = options.aggregate = normalizeAggregate(options.aggregate);
}
}
return options;
},
query: function(options) {
var result;
var remote = this.options.serverSorting || this.options.serverPaging || this.options.serverFiltering || this.options.serverGrouping || this.options.serverAggregates;
if (remote || ((this._data === undefined$1 || this._data.length === 0) && !this._destroyed.length)) {
if (this.options.endless) {
var moreItemsCount = options.pageSize - this.pageSize();
if (moreItemsCount > 0) {
moreItemsCount = this.pageSize();
options.page = options.pageSize / moreItemsCount;
options.pageSize = moreItemsCount;
} else {
options.page = 1;
this.options.endless = false;
}
}
return this.read(this._mergeState(options));
}
var isPrevented = this.trigger(REQUESTSTART, { type: "read" });
if (!isPrevented) {
this.trigger(PROGRESS);
if (options) {
options.groupPaging = this._groupPaging;
}
result = this._queryProcess(this._data, this._mergeState(options));
this._setFilterTotal(result.total, true);
this._aggregateResult = this._calculateAggregates(result.dataToAggregate || this._data, options);
this._setView(result, options);
this.trigger(REQUESTEND, { type: "read" });
this.trigger(CHANGE, { items: result.data, action: options ? options.action : "" });
}
return $.Deferred().resolve(isPrevented).promise();
},
_hasExpandedSubGroups: function(group) {
var result = false;
var length = group.items ? group.items.length : 0;
if (!group.hasSubgroups) {
return false;
}
for (var i = 0; i < length; i++) {
if (this._groupsState[group.items[i].uid]) {
result = true;
break;
}
}
return result;
},
_findGroupedRange: function(data, result, options, parents, callback) {
var that = this;
var length = data.length;
var group;
var current;
var itemsLength;
var groupCount;
var itemsToSkip;
for (var i = 0; i < length; i++) {
group = data[i];
if (options.taken >= options.take) {
break;
}
if (!that._getGroupByUid(group.uid)) {
that._groupsFlat.push(group);
}
if (that._groupsState[group.uid]) {
if (that._isServerGroupPaged()) {
if (that._fetchGroupItems(group, options, parents, callback)) {
that._fetchingGroupItems = true;
return;
}
groupCount = (group.subgroupCount || group.itemCount) + 1;
itemsToSkip = options.skip - options.skipped;
if (!that._hasExpandedSubGroups(group) && itemsToSkip > groupCount) {
options.skipped += groupCount;
continue;
}
}
if (options.includeParents && options.skipped < options.skip) {
options.skipped++;
group.excludeHeader = true;
} else if (options.includeParents) {
options.taken++;
group.excludeHeader = false;
}
if (group.hasSubgroups && group.items && group.items.length) {
group.currentItems = [];
if (!parents) {
parents = [];
}
parents.push(group);
that._findGroupedRange(group.items, group.currentItems, options, parents, callback);
parents.pop();
if (group.currentItems.length || options.taken > 0) {
result.push(group);
} else {
group.excludeHeader = false;
}
} else {
current = [];
itemsLength = group.items.length;
for (var j = 0; j < itemsLength; j++) {
if (options.skipped < options.skip) {
options.skipped++;
continue;
}
if (options.taken >= options.take) {
break;
}
current.push(group.items[j]);
options.taken++;
}
if (current.length || options.taken > 0) {
group.currentItems = current;
result.push(group);
} else {
group.excludeHeader = false;
}
}
} else {
if (options.skipped < options.skip) {
options.skipped++;
continue;
}
result.push(group);
options.taken++;
}
}
},
_expandedSubGroupItemsCount: function(group, end, includeCurrentItems) {
var that = this;
var result = 0;
var subGroup;
var endSpecified = typeof end === "number";
var length = endSpecified ? end : group.subgroupCount;
var temp;
if (!group.hasSubgroups) {
return result;
}
for (var i = 0; i < length; i++) {
subGroup = group.items[i];
if (!subGroup) {
break;
}
if (subGroup.hasSubgroups && that._groupsState[group.uid]) {
temp = that._expandedSubGroupItemsCount(subGroup, length, true);
result += temp;
if (endSpecified) {
length -= temp;
}
} else if (!subGroup.hasSubgroups && that._groupsState[subGroup.uid]) {
temp = subGroup.items ? subGroup.items.length : 0;
result += temp;
if (endSpecified) {
length -= temp;
}
}
if (includeCurrentItems) {
result += 1;
if (endSpecified) {
length -= 1;
}
}
if (endSpecified && result > length) {
return result;
}
}
return result;
},
_fetchGroupItems: function(group, options, parents, callback) {
let that = this;
let groupItemsSkip;
let firstItem;
let lastItem;
let groupItemCount = group.hasSubgroups ? group.subgroupCount : group.itemCount;
let take = options.take;
let skipped = options.skipped;
let pageSize = that.take();
let expandedSubGroupItemsCount;
if (options.includeParents) {
if (skipped < options.skip) {
skipped += 1;
} else {
take -= 1;
}
}
if (!group.items || (group.items && !group.items.length)) {
that.getGroupItems(group, options, parents, callback, 0);
return true;
} else {
expandedSubGroupItemsCount = this._expandedSubGroupItemsCount(group, options.skip - skipped);
groupItemsSkip = Math.max(options.skip - (skipped + expandedSubGroupItemsCount), 0);
if (groupItemsSkip >= groupItemCount) {
return false;
}
let lastItemIndex = Math.min(groupItemsSkip + take, groupItemCount - 1);
firstItem = group.items[groupItemsSkip];
lastItem = group.items[lastItemIndex];
if (firstItem.notFetched) {
that.getGroupItems(group, options, parents, callback, groupItemsSkip, math.round((groupItemsSkip + pageSize) / pageSize));
return true;
}
if (lastItem.notFetched) {
that.getGroupItems(group, options, parents, callback, math.max(math.floor((groupItemsSkip + pageSize) / pageSize), 0) * pageSize, math.round((groupItemsSkip + pageSize) / pageSize));
return true;
}
if (!firstItem.notFetched && !lastItem.notFetched && hasNotFetchedItems(group.items, groupItemsSkip, lastItemIndex)) {
that.getGroupItems(group, options, parents, callback, groupItemsSkip, lastItemIndex);
return true;
}
}
},
getGroupItems: function(group, options, parents, callback, groupItemsSkip, page) {
var that = this;
var take;
var filter;
var data;
var subgroups;
if (!group.items) {
group.items = [];
}
take = that.take();
filter = this._composeItemsFilter(group, parents);
data = {
page: page || 1,
pageSize: take,
skip: groupItemsSkip,
take: take,
filter: filter,
aggregate: that._aggregate,
sort: that._sort
};
subgroups = that.findSubgroups(group);
if (subgroups && subgroups.length) {
data.group = subgroups;
}
data.groupPaging = true;
that._queueWithTimeout(data, function() {
if (!that.trigger(REQUESTSTART, {
type: "read"
})) {
that.transport.read({
data: data,
success: that._groupItemsSuccessHandler(group, options.skip, that.take(), callback, groupItemsSkip),
error: function() {
var args = slice.call(arguments);
that.error.apply(that, args);
}
});
} else {
that._dequeueRequest();
}
}, 100);
},
_queueWithTimeout: function(options, callback, delay) {
let that = this;
clearTimeout(that._timeout);
that._timeout = setTimeout(function() {
that._queueRequest(options, callback);
}, delay);
},
_groupItemsSuccessHandler: function(group, skip, take, callback, groupItemsSkip) {
var that = this;
var timestamp = that._timeStamp();
callback = isFunction(callback) ? callback : noop;
var totalField = that.options.schema && that.options.schema.total ? that.options.schema.total : "Total";
return function(data) {
var temp;
var model = Model.define(that.options.schema.model);
var totalCount;
that._dequeueRequest();
that.trigger(REQUESTEND, {
response: data,
type: "read"
});
if (isFunction(totalField)) {
totalCount = totalField(data);
} else {
totalCount = data[totalField];
}
data = that.reader.parse(data);
if (group.hasSubgroups) {
temp = that.reader.groups(data);
group.subgroupCount = totalCount;
} else {
temp = that.reader.data(data);
temp = temp.map(function(item) {
return new model(item);
});
}
group.items.omitChangeEvent = true;
for (var i = 0; i < totalCount; i++) {
if (i >= groupItemsSkip && i < (groupItemsSkip + take) ) {
group.items.splice(i, 1, temp[i - groupItemsSkip]);
} else {
if (!group.items[i]) {
group.items.splice(i, 0, { notFetched: true });
}
}
}
group.items.omitChangeEvent = false;
that._updateRangePristineData(group);
that._fetchingGroupItems = false;
if (!group.countAdded) {
that._serverGroupsTotal += totalCount;
group.countAdded = true;
}
that.range(skip, take, callback, "expandGroup");
if (timestamp >= that._currentRequestTimeStamp || !that._skipRequestsInProgress) {
that.trigger(CHANGE, {});
}
};
},
findSubgroups: function(group) {
var indexOfCurrentGroup = this._group.map(function(g) {
return g.field;
}).indexOf(group.field);
return this._group.slice(indexOfCurrentGroup + 1, this._group.length);
},
_composeItemsFilter: function(group, parents) {
var filter = {
logic: "and",
filters: []
};
if (this.filter()) {
filter.filters.push(this.filter());
}
filter = extend(true, {}, filter);
filter.filters.push({
field: group.field,
operator: "eq",
value: group.value
});
if (parents) {
for (var i = 0; i < parents.length; i++) {
filter.filters.push({
field: parents[i].field,
operator: "eq",
value: parents[i].value
});
}
}
return filter;
},
_updateRangePristineData: function(group) {
var that = this;
var ranges = that._ranges;
var rangesLength = ranges.length;
var temp;
var currentGroup;
var range;
var dataLength;
var indexes;
var currIdx;
for (var i = 0; i < rangesLength; i++) {
range = ranges[i];
dataLength = range.data.length;
indexes = [];
temp = null;
for (var j = 0; j < dataLength; j++) {
currentGroup = range.data[j];
indexes.push(j);
if ((currentGroup.uid === group.uid) || (currentGroup.hasSubgroups && currentGroup.items.length && that._containsSubGroup(currentGroup, group, indexes))) {
break;
}
indexes.pop();
}
if (indexes.length) {
temp = ranges[i].pristineData;
while (indexes.length > 1) {
currIdx = indexes.splice(0, 1)[0];
temp = temp[currIdx].items;
}
temp[indexes[0]] = that._cloneGroup(group);
break;
}
}
},
_containsSubGroup: function(group, subgroup, indexes) {
var that = this;
var length = group.items.length;
var currentSubGroup;
if (group.hasSubgroups && length) {
for (var i = 0; i < length; i++) {
currentSubGroup = group.items[i];
indexes.push(i);
if (currentSubGroup.uid === subgroup.uid ||
(currentSubGroup.hasSubgroups &&
currentSubGroup.items.length &&
that._containsSubGroup(currentSubGroup, subgroup, indexes))) {
return true;
}
indexes.pop();
}
}
},
_cloneGroup: function(group) {
var that = this;
group = typeof group.toJSON == "function" ? group.toJSON() : group;
if (group.items && group.items.length) {
group.items = group.items.map(function(item) {
return that._cloneGroup(item);
});
}
return group;
},
_setFilterTotal: function(filterTotal, setDefaultValue) {
var that = this;
if (!that.options.serverFiltering) {
if (filterTotal !== undefined$1) {
that._total = filterTotal;
} else if (setDefaultValue) {
that._total = that._data.length;
}
}
},
fetch: function(callback) {
var that = this;
var fn = function(isPrevented) {
if (isPrevented !== true && isFunction(callback)) {
callback.call(that);
}
};
return this._query().done(fn);
},
_query: function(options) {
var that = this;
return that.query(extend({}, {
page: that.page(),
pageSize: that.pageSize(),
sort: that.sort(),
filter: that.filter(),
group: that.group(),
aggregate: that.aggregate()
}, options));
},
next: function(options) {
var that = this,
page = that.page(),
total = that.total();
options = options || {};
if (!page || (total && page + 1 > that.totalPages())) {
return;
}
that._skip = that._currentRangeStart = page * that.take();
page += 1;
options.page = page;
that._query(options);
return page;
},
prev: function(options) {
var that = this,
page = that.page();
options = options || {};
if (!page || page === 1) {
return;
}
that._skip = that._currentRangeStart = that._skip - that.take();
page -= 1;
options.page = page;
that._query(options);
return page;
},
page: function(val) {
var that = this,
skip;
if (val !== undefined$1) {
val = math.max(math.min(math.max(val, 1), that.totalPages()), 1);
var take = that.take();
if (that._isGroupPaged()) {
val -= 1;
that.range(val * take, take, null, "page");
return;
}
that._query(that._pageableQueryOptions({ page: val }));
return;
}
skip = that.skip();
return skip !== undefined$1 ? math.round((skip || 0) / (that.take() || 1)) + 1 : undefined$1;
},
pageSize: function(val) {
var that = this;
if (val !== undefined$1) {
that._query(that._pageableQueryOptions({ pageSize: val, page: 1 }));
return;
}
return that.take();
},
sort: function(val) {
var that = this;
if (val !== undefined$1) {
that.trigger("sort");
that._query({ sort: val });
return;
}
return that._sort;
},
filter: function(val) {
var that = this;
if (val === undefined$1) {
return that._filter;
}
that.trigger("reset");
that._query({ filter: val, page: 1 });
},
group: function(val) {
var that = this;
var options = { group: val };
if (that._groupPaging) {
// clear ranges if ungrouping is performed
if (val !== undefined$1 && (!val || !val.length) ) {
that._ranges = [];
}
options.page = 1;
}
if (val !== undefined$1) {
that._query(options);
return;
}
return that._group;
},
getGroupsFlat: function(data) {
var idx,
result = [],
length;
for (idx = 0, length = data.length; idx < length; idx++) {
var group = data[idx];
if (group.hasSubgroups) {
result = result.concat(this.getGroupsFlat(group.items));
}
result.push(group);
}
return result;
},
total: function() {
return parseInt(this._total || 0, 10);
},
groupsTotal: function(includeExpanded) {
var that = this;
if (!that._group.length) {
return that.total();
}
if (that._isServerGrouped()) {
if (that._serverGroupsTotal) {
return that._serverGroupsTotal;
}
that._serverGroupsTotal = that.total();
return that._serverGroupsTotal;
}
return that._calculateGroupsTotal(that._ranges.length ? that._ranges[0].data : [], includeExpanded);
},
_calculateGroupsTotal: function(groups, includeExpanded, itemsField, ignoreState) {
var that = this;
itemsField = itemsField || "items";
var total;
var length;
if (that._group.length && groups) {
total = 0;
length = groups.length;
for (var i = 0; i < length; i++) {
total += that.groupCount(groups[i], includeExpanded, itemsField, ignoreState);
}
that._groupsTotal = total;
return total;
}
that._groupsTotal = that._data.length;
return that._groupsTotal;
},
groupCount: function(group, includeExpanded, itemsField, ignoreState) {
var that = this;
var total = 0;
if (group.hasSubgroups && that._groupsState[group.uid]) {
if (includeExpanded && !group.excludeHeader || ignoreState) {
total += 1;
}
group[itemsField].forEach(function(subgroup) {
total += that.groupCount(subgroup, includeExpanded, itemsField, ignoreState);
});
} else {
if (that._groupsState[group.uid]) {
if (includeExpanded && !group.excludeHeader || ignoreState) {
total++;
}
total += group[itemsField] ? group[itemsField].length : 0;
} else {
total++;
}
}
return total;
},
countGroupRange: function(range) {
var total = 0;
var length = range.length;
for (var i = 0; i < length; i++) {
total += this.groupCount(range[i], true);
}
return total;
},
aggregate: function(val) {
var that = this;
if (val !== undefined$1) {
that._query({ aggregate: val });
return;
}
return that._aggregate;
},
aggregates: function() {
var result = this._aggregateResult;
if (isEmptyObject(result)) {
result = this._emptyAggregates(this.aggregate());
}
return result;
},
_emptyAggregates: function(aggregates) {
var result = {};
if (!isEmptyObject(aggregates)) {
var aggregate = {};
if (!isArray(aggregates)) {
aggregates = [aggregates];
}
for (var idx = 0; idx < aggregates.length; idx++) {
aggregate[aggregates[idx].aggregate] = 0;
result[aggregates[idx].field] = aggregate;
}
}
return result;
},
_pageableQueryOptions: function(options) {
return options;
},
_wrapInEmptyGroup: function(model) {
var groups = this.group(),
parent,
group,
idx,
length;
for (idx = groups.length - 1, length = 0; idx >= length; idx--) {
group = groups[idx];
parent = {
value: model.get ? model.get(group.field) : model[group.field],
field: group.field,
items: parent ? [parent] : [model],
hasSubgroups: !!parent,
aggregates: this._emptyAggregates(group.aggregates)
};
}
return parent;
},
totalPages: function() {
var that = this,
pageSize = that.pageSize() || that.total(),
total = that._isGroupPaged() ? that.groupsTotal(true) : that.total();
return math.ceil((total || 0) / pageSize);
},
inRange: function(skip, take) {
var that = this,
end = math.min(skip + take, that.total());
if (!that.options.serverPaging && that._data.length > 0) {
return true;
}
return that._findRange(skip, end).length > 0;
},
lastRange: function() {
var ranges = this._ranges;
return ranges[ranges.length - 1] || { start: 0, end: 0, data: [] };
},
firstItemUid: function() {
var ranges = this._ranges;
return ranges.length && ranges[0].data.length && ranges[0].data[0].uid;
},
enableRequestsInProgress: function() {
this._skipRequestsInProgress = false;
},
_timeStamp: function() {
return new Date().getTime();
},
range: function(skip, take, callback, action) {
this._currentRequestTimeStamp = this._timeStamp();
this._skipRequestsInProgress = true;
var total = this._isGroupPaged() ? this.groupsTotal(true) : this.total();
if (action === "expandGroup" || action === "collapseGroup") {
this._updateOuterRangesLength();
}
skip = math.min(skip || 0, total);
callback = isFunction(callback) ? callback : noop;
var that = this,
pageSkip = math.max(math.floor(skip / take), 0) * take,
size = math.min(pageSkip + take, total),
data;
data = that._findRange(skip, math.min(skip + take, total), callback);
if ((data.length || total === 0) && !that._fetchingGroupItems) {
that._processRangeData(data, skip, take, that._originalPageSkip || pageSkip, that._originalSize || size, {
action: action
});
that._originalPageSkip = null;
that._originalSize = null;
callback();
return;
}
if (that._isGroupPaged()) {
that._originalPageSkip = pageSkip;
that._originalSize = size;
pageSkip = math.max(math.floor(that._adjustPageSkip(skip, take) / take), 0) * take;
size = math.min(pageSkip + take, total);
}
if (take !== undefined$1 && !that._fetchingGroupItems) {
if ((that._isGroupPaged() && !that._groupRangeExists(pageSkip, take)) || !that._rangeExists(pageSkip, size)) {
that.prefetch(pageSkip, take, function() {
if (skip > pageSkip && size < that.total() && !that._rangeExists(size, math.min(size + take, that.total()))) {
that.prefetch(size, take, function() {
that.range(skip, take, callback );
});
} else {
that.range(skip, take, callback);
}
});
} else if (pageSkip < skip) {
that.prefetch(size, take, function() {
that.range(skip, take, callback );
});
}
}
},
_findRange: function(start, end, callback) {
var that = this,
ranges = that._ranges,
range,
data = [],
skipIdx,
takeIdx,
startIndex,
endIndex,
rangeData,
rangeEnd,
processed,
options = that.options,
remote = options.serverSorting || options.serverPaging || options.serverFiltering || options.serverGrouping || options.serverAggregates,
flatData,
count,
length,
groupMapOptions = {
take: end - start,
skip: start,
skipped: 0,
taken: 0,
includeParents: true
},
prevRangeEnd,
isGroupPaged = that._isGroupPaged(),
startField = isGroupPaged ? "outerStart" : "start",
endField = isGroupPaged ? "outerEnd" : "end",
currentDataLength;
for (skipIdx = 0, length = ranges.length; skipIdx < length; skipIdx++) {
range = ranges[skipIdx];
if (isGroupPaged) {
if (range.outerStart >= end) {
return [];
}
if (start > range.outerEnd) {
groupMapOptions.skipped += range.outerEnd - (prevRangeEnd || 0);
prevRangeEnd = range.outerEnd;
continue;
}
if (typeof prevRangeEnd !== "undefined" && prevRangeEnd != range.outerStart) {
groupMapOptions.skipped += range.outerStart - prevRangeEnd;
}
if (groupMapOptions.skipped > groupMapOptions.skip) {
return [];
}
if (typeof prevRangeEnd === "undefined" && start > 0 && range.start > 0) {
groupMapOptions.skipped = range.outerStart;
}
takeIdx = skipIdx;
while (true) {
this._findGroupedRange(range.data, data, groupMapOptions, null, callback);
currentDataLength = that._calculateGroupsTotal(data, true, "currentItems");
if (currentDataLength >= groupMapOptions.take) {
return data;
}
if (that._fetchingGroupItems) {
return [];
}
takeIdx++;
if (ranges[takeIdx] && ranges[takeIdx].outerStart === range.outerEnd) {
range = ranges[takeIdx];
} else {
break;
}
}
} else if (start >= range[startField] && start <= range[endField]) {
count = 0;
for (takeIdx = skipIdx; takeIdx < length; takeIdx++) {
range = ranges[takeIdx];
flatData = that._flatData(range.data, true);
if (flatData.length && start + count >= range.start) {
rangeData = range.data;
rangeEnd = range.end;
if (!remote) {
if (options.inPlaceSort) {
processed = that._queryProcess(range.data, { filter: that.filter() });
} else {
var sort = normalizeGroupWithoutCompare(that.group() || []).concat(normalizeSort(that.sort() || []));
processed = that._queryProcess(range.data, { sort: sort, filter: that.filter() });
}
flatData = rangeData = processed.data;
if (processed.total !== undefined$1) {
rangeEnd = processed.total;
}
}
startIndex = 0;
if (start + count > range.start) {
startIndex = (start + count) - range.start;
}
endIndex = flatData.length;
if (rangeEnd > end) {
endIndex = endIndex - (rangeEnd - end);
}
count += endIndex - startIndex;
data = that._mergeGroups(data, rangeData, startIndex, endIndex);
if (end <= range.end && count == end - start) {
return data;
}
}
}
break;
}
prevRangeEnd = range.outerEnd;
}
return [];
},
_getRangesMismatch: function(pageSkip) {
var that = this;
var ranges = that._ranges;
var mismatch = 0;
var i = 0;
while (true) {
var range = ranges[i];
if (!range || range.outerStart > pageSkip) {
break;
}
if (range.outerEnd != range.end) {
mismatch = range.outerEnd - range.end;
}
i++;
}
return mismatch;
},
_mergeGroups: function(data, range, skip, take) {
if (this._isServerGrouped()) {
var temp = range.toJSON(),
prevGroup;
if (data.length) {
prevGroup = data[data.length - 1];
}
mergeGroups(prevGroup, temp, skip, take);
return data.concat(temp);
}
return data.concat(range.slice(skip, take));
},
_processRangeData: function(data, skip, take, pageSkip, size, eventData) {
var that = this;
that._pending = undefined$1;
that._skip = skip > that.skip() && !that._omitPrefetch ? math.min(size, (that.totalPages() - 1) * that.take()) : pageSkip;
that._currentRangeStart = skip;
that._take = take;
var paging = that.options.serverPaging;
var sorting = that.options.serverSorting;
var filtering = that.options.serverFiltering;
var aggregates = that.options.serverAggregates;
try {
that.options.serverPaging = true;
if (!that._isServerGrouped() && !(that.group() && that.group().length)) {
that.options.serverSorting = true;
}
that.options.serverFiltering = true;
that.options.serverPaging = true;
that.options.serverAggregates = true;
if (paging) {
that._detachObservableParents();
that._data = data = that._observe(data);
}
that._process(data, eventData);
} finally {
that.options.serverPaging = paging;
that.options.serverSorting = sorting;
that.options.serverFiltering = filtering;
that.options.serverAggregates = aggregates;
}
},
skip: function() {
var that = this;
if (that._skip === undefined$1) {
return (that._page !== undefined$1 ? (that._page - 1) * (that.take() || 1) : undefined$1);
}
return that._skip;
},
currentRangeStart: function() {
return this._currentRangeStart || 0;
},
take: function() {
return this._take || this._pageSize;
},
_prefetchSuccessHandler: function(skip, size, callback, force) {
var that = this;
var timestamp = that._timeStamp();
return function(data) {
var found = false,
range = { start: skip, end: size, data: [], timestamp: that._timeStamp() },
idx,
length,
temp;
that._dequeueRequest();
that.trigger(REQUESTEND, { response: data, type: "read" });
data = that.reader.parse(data);
temp = that._readData(data);
if (temp.length) {
for (idx = 0, length = that._ranges.length; idx < length; idx++) {
if (that._ranges[idx].start === skip) {
found = true;
range = that._ranges[idx];
if (!that._isGroupPaged()) {
range.pristineData = temp;
range.data = that._observe(temp);
range.end = range.start + that._flatData(range.data, true).length;
that._sortRanges();
}
break;
}
}
if (!found) {
that._addRange(that._observe(temp), skip);
}
}
that._total = that.reader.total(data);
if (force || (timestamp >= that._currentRequestTimeStamp || !that._skipRequestsInProgress)) {
if (callback && temp.length) {
callback();
} else {
that.trigger(CHANGE, {});
}
}
};
},
prefetch: function(skip, take, callback) {
var that = this,
size = math.min(skip + take, that.total()),
options = {
take: take,
skip: skip,
page: skip / take + 1,
pageSize: take,
sort: that._sort,
filter: that._filter,
group: that._group,
aggregate: that._aggregate
};
if ((that._isGroupPaged() && !that._isServerGrouped() && that._groupRangeExists(skip, size))) {
if (callback) {
callback();
}
return;
}
if ((that._isServerGroupPaged() && !that._groupRangeExists(skip, size)) || !that._rangeExists(skip, size)) {
that._queueWithTimeout(options, function() {
if (!that.trigger(REQUESTSTART, { type: "read" })) {
if (that._omitPrefetch) {
that.trigger(PROGRESS);
}
that.transport.read({
data: that._params(options),
success: that._prefetchSuccessHandler(skip, size, callback),
error: function() {
var args = slice.call(arguments);
that.error.apply(that, args);
}
});
} else {
that._dequeueRequest();
}
}, 100);
} else if (callback) {
callback();
}
},
_multiplePrefetch: function(skip, take, callback) {
var that = this,
size = math.min(skip + take, that.total()),
options = {
take: take,
skip: skip,
page: skip / take + 1,
pageSize: take,
sort: that._sort,
filter: that._filter,
group: that._group,
aggregate: that._aggregate
};
if (!that._rangeExists(skip, size)) {
if (!that.trigger(REQUESTSTART, { type: "read" })) {
that.transport.read({
data: that._params(options),
success: that._prefetchSuccessHandler(skip, size, callback, true)
});
}
} else if (callback) {
callback();
}
},
_adjustPageSkip: function(start, take) {
var that = this;
var prevRange = that._getPrevRange(start);
var result;
var total = that.total();
var mismatch;
if (prevRange) {
mismatch = that._getRangesMismatch(start);
if (!mismatch) {
return start;
}
start -= mismatch;
}
result = math.max(math.floor(start / take), 0) * take;
if (result > total) {
while (true) {
result -= take;
if (result < total) {
break;
}
}
}
return result;
},
_getNextRange: function(end) {
var that = this,
ranges = that._ranges,
idx,
length;
for (idx = 0, length = ranges.length; idx < length; idx++) {
if (ranges[idx].start <= end && ranges[idx].end >= end) {
return ranges[idx];
}
}
},
_getPrevRange: function(start) {
var that = this,
ranges = that._ranges,
idx,
range,
length = ranges.length;
for (idx = length - 1; idx >= 0; idx--) {
if (ranges[idx].outerStart <= start) {
range = ranges[idx];
break;
}
}
return range;
},
_rangeExists: function(start, end) {
var that = this,
ranges = that._ranges,
idx,
length;
for (idx = 0, length = ranges.length; idx < length; idx++) {
if (ranges[idx].start <= start && ranges[idx].end >= end) {
return true;
}
}
return false;
},
_groupRangeExists: function(start, end) {
var that = this,
ranges = that._ranges,
idx,
length,
availableItemsCount = 0,
total = that.groupsTotal(true);
if (end > total && !that._isServerGrouped()) {
end = total;
}
for (idx = 0, length = ranges.length; idx < length; idx++) {
var range = ranges[idx];
if (range.outerStart <= start && range.outerEnd >= start) {
availableItemsCount += range.outerEnd - start;
} else if (range.outerStart <= end && range.outerEnd >= end) {
availableItemsCount += end - range.outerStart;
}
}
return availableItemsCount >= end - start;
},
_getCurrentRangeSpan: function() {
var that = this;
var ranges = that._ranges;
var start = that.currentRangeStart();
var end = start + (that.take() || 0);
var rangeSpan = [];
var range;
var idx;
var length = ranges.length;
for (idx = 0; idx < length; idx++) {
range = ranges[idx];
if ((range.start <= start && range.end >= start) || (range.start >= start && range.start <= end)) {
rangeSpan.push(range);
}
}
return rangeSpan;
},
_removeModelFromRanges: function(model) {
var that = this;
var range;
for (var idx = 0, length = this._ranges.length; idx < length; idx++) {
range = this._ranges[idx];
that._removeModelFromRange(range, model);
}
that._updateRangesLength();
},
_removeModelFromRange: function(range, model) {
this._eachItem(range.data, function(data) {
if (!data) {
return;
}
for (var idx = 0; idx < data.length; idx++) {
var dataItem = data[idx];
if (dataItem.uid && dataItem.uid == model.uid) {
[].splice.call(data, idx, 1);
break;
}
}
});
},
_insertModelInRange: function(index, model) {
var that = this;
var ranges = that._ranges || [];
var rangesLength = ranges.length;
var range;
var i;
for (i = 0; i < rangesLength; i++) {
range = ranges[i];
if (range.start <= index && range.end >= index) {
if (!that._getByUid(model.uid, range.data)) {
if (that._isServerGrouped()) {
range.data.splice(index, 0, that._wrapInEmptyGroup(model));
} else {
range.data.splice(index, 0, model);
}
}
break;
}
}
that._updateRangesLength();
},
_updateRangesLength: function() {
var that = this;
var ranges = that._ranges || [];
var rangesLength = ranges.length;
var mismatchFound = false;
var mismatchLength = 0;
var lengthDifference = 0;
var rangeLength;
var range;
var i;
for (i = 0; i < rangesLength; i++) {
range = ranges[i];
rangeLength = that._isGroupPaged() ? range.data.length : that._flatData(range.data, true).length;
lengthDifference = rangeLength - math.abs(range.end - range.start);
if (!mismatchFound && lengthDifference !== 0) {
mismatchFound = true;
mismatchLength = lengthDifference;
range.end += mismatchLength;
continue;
}
if (mismatchFound) {
range.start += mismatchLength;
range.end += mismatchLength;
}
}
},
_updateOuterRangesLength: function() {
var that = this;
var ranges = that._ranges || [];
var rangesLength = ranges.length;
var mismatchLength = 0;
var range;
var i;
var prevRange;
var rangeLength;
for (i = 0; i < rangesLength; i++) {
range = ranges[i];
rangeLength = that._isGroupPaged() ? that._calculateGroupsTotal(range.data, true, "items", true) : that._flatData(range.data, true).length;
if (prevRange) {
if (prevRange.end != range.start) {
mismatchLength = range.start - prevRange.end;
}
range.outerStart = prevRange.outerEnd + mismatchLength;
mismatchLength = 0;
} else {
range.outerStart = range.start;
}
range.outerEnd = range.outerStart + rangeLength;
prevRange = range;
}
},
isLocalTransport: function() {
return this.transport instanceof LocalTransport;
},
isRemoteTransport: function() {
return this.transport instanceof RemoteTransport;
}
});
var Transport = {};
Transport.create = function(options, data, dataSource) {
var transport,
transportOptions = options.transport ? $.extend({}, options.transport) : null;
if (transportOptions) {
transportOptions.read = typeof transportOptions.read === STRING ? { url: transportOptions.read } : transportOptions.read;
if (options.type === "jsdo") {
transportOptions.dataSource = dataSource;
}
if (options.type) {
kendo.data.transports = kendo.data.transports || {};
kendo.data.schemas = kendo.data.schemas || {};
if (!kendo.data.transports[options.type]) {
kendo.logToConsole("Unknown DataSource transport type '" + options.type + "'.\nVerify that registration scripts for this type are included after Kendo UI on the page.", "warn");
} else if (!isPlainObject(kendo.data.transports[options.type])) {
transport = new kendo.data.transports[options.type](extend(transportOptions, { data: data }));
} else {
transportOptions = extend(true, {}, kendo.data.transports[options.type], transportOptions);
}
options.schema = extend(true, {}, kendo.data.schemas[options.type], options.schema);
}
if (!transport) {
transport = isFunction(transportOptions.read) ? transportOptions : new RemoteTransport(transportOptions);
}
} else {
transport = new LocalTransport({ data: options.data || [] });
}
return transport;
};
DataSource.create = function(options) {
if (isArray(options) || options instanceof ObservableArray) {
options = { data: options };
}
var dataSource = options || {},
data = dataSource.data,
fields = dataSource.fields,
table = dataSource.table,
select = dataSource.select,
idx,
length,
model = {},
field;
if (!data && fields && !dataSource.transport) {
if (table) {
data = inferTable(table, fields);
} else if (select) {
data = inferSelect(select, fields);
if (dataSource.group === undefined$1 && data[0] && data[0].optgroup !== undefined$1) {
dataSource.group = "optgroup";
}
}
}
if (kendo.data.Model && fields && (!dataSource.schema || !dataSource.schema.model)) {
for (idx = 0, length = fields.length; idx < length; idx++) {
field = fields[idx];
if (field.type) {
model[field.field] = field;
}
}
if (!isEmptyObject(model)) {
dataSource.schema = extend(true, dataSource.schema, { model: { fields: model } });
}
}
dataSource.data = data;
select = null;
dataSource.select = null;
table = null;
dataSource.table = null;
return dataSource instanceof DataSource ? dataSource : new DataSource(dataSource);
};
function inferSelect(select, fields) {
select = $(select)[0];
var options = select.options;
var firstField = fields[0];
var secondField = fields[1];
var data = [];
var idx, length;
var optgroup;
var option;
var record;
var value;
for (idx = 0, length = options.length; idx < length; idx++) {
record = {};
option = options[idx];
optgroup = option.parentNode;
if (optgroup === select) {
optgroup = null;
}
if (option.disabled || (optgroup && optgroup.disabled)) {
continue;
}
if (optgroup) {
record.optgroup = optgroup.label;
}
record[firstField.field] = option.text;
value = option.attributes.value;
if (value && value.specified) {
value = option.value;
} else {
value = option.text;
}
record[secondField.field] = value;
data.push(record);
}
return data;
}
function inferTable(table, fields) {
var tbody = $(table)[0].tBodies[0],
rows = tbody ? tbody.rows : [],
idx,
length,
fieldIndex,
fieldCount = fields.length,
data = [],
cells,
record,
cell,
empty;
for (idx = 0, length = rows.length; idx < length; idx++) {
record = {};
empty = true;
cells = rows[idx].cells;
for (fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
cell = cells[fieldIndex];
if (cell.nodeName.toLowerCase() !== "th") {
empty = false;
record[fields[fieldIndex].field] = cell.innerHTML;
}
}
if (!empty) {
data.push(record);
}
}
return data;
}
var Node = Model.define({
idField: "id",
init: function(value) {
var that = this,
hasChildren = that.hasChildren || value && value.hasChildren,
childrenField = "items",
childrenOptions = {};
kendo.data.Model.fn.init.call(that, value);
if (typeof that.children === STRING) {
childrenField = that.children;
}
childrenOptions = {
schema: {
data: childrenField,
model: {
hasChildren: hasChildren,
id: that.idField,
fields: that.fields
}
}
};
if (typeof that.children !== STRING) {
extend(childrenOptions, that.children);
}
childrenOptions.data = value;
if (!hasChildren) {
hasChildren = childrenOptions.schema.data;
}
if (typeof hasChildren === STRING) {
hasChildren = kendo.getter(hasChildren);
}
if (isFunction(hasChildren)) {
var hasChildrenObject = hasChildren.call(that, that);
if (hasChildrenObject && hasChildrenObject.length === 0) {
that.hasChildren = false;
} else {
that.hasChildren = !!hasChildrenObject;
}
}
that._childrenOptions = childrenOptions;
if (that.hasChildren) {
that._initChildren();
}
that._loaded = !!(value && value._loaded);
},
_initChildren: function() {
var that = this;
var children, transport, parameterMap;
if (!(that.children instanceof HierarchicalDataSource)) {
children = that.children = new HierarchicalDataSource(that._childrenOptions);
transport = children.transport;
parameterMap = transport.parameterMap;
transport.parameterMap = function(data, type) {
data[that.idField || "id"] = that.id;
if (parameterMap) {
data = parameterMap.call(that, data, type);
}
return data;
};
children.parent = function() {
return that;
};
children.bind(CHANGE, function(e) {
e.node = e.node || that;
that.trigger(CHANGE, e);
});
children.bind(ERROR, function(e) {
var collection = that.parent();
if (collection) {
e.node = e.node || that;
collection.trigger(ERROR, e);
}
});
children.bind(ITEMSLOADED, function(e) {
var collection = that.parent();
if (collection) {
collection.trigger(ITEMSLOADED, e);
}
});
that._updateChildrenField();
}
},
append: function(model) {
this._initChildren();
this.loaded(true);
this.children.add(model);
},
hasChildren: false,
level: function() {
var parentNode = this.parentNode(),
level = 0;
while (parentNode && parentNode.parentNode) {
level++;
parentNode = parentNode.parentNode ? parentNode.parentNode() : null;
}
return level;
},
_updateChildrenField: function() {
var fieldName = this._childrenOptions.schema.data;
this[fieldName || "items"] = this.children.data();
},
_childrenLoaded: function() {
this._loaded = true;
this._updateChildrenField();
},
load: function() {
var options = {};
var method = "_query";
var children, promise;
if (this.hasChildren) {
this._initChildren();
children = this.children;
options[this.idField || "id"] = this.id;
if (!this._loaded) {
children._data = undefined$1;
method = "read";
}
children.one(CHANGE, this._childrenLoaded.bind(this));
if (this._matchFilter) {
options.filter = { field: '_matchFilter', operator: 'eq', value: true };
}
promise = children[method](options);
if (!this._loaded) {
this.trigger(ITEMLOAD, { promise: promise, node: this });
}
} else {
this.loaded(true);
}
return promise || $.Deferred().resolve().promise();
},
parentNode: function() {
var array = this.parent();
return array.parent();
},
loaded: function(value) {
if (value !== undefined$1) {
this._loaded = value;
} else {
return this._loaded;
}
},
shouldSerialize: function(field) {
return Model.fn.shouldSerialize.call(this, field) &&
field !== "children" &&
field !== "_loaded" &&
field !== "hasChildren" &&
field !== "_childrenOptions";
}
});
function dataMethod(name) {
return function() {
var data = this._data,
result = DataSource.fn[name].apply(this, slice.call(arguments));
if (this._data != data) {
this._attachBubbleHandlers();
}
return result;
};
}
var HierarchicalDataSource = DataSource.extend({
init: function(options) {
var node = Node.define({
children: options
});
if (options.filter && !options.serverFiltering) {
this._hierarchicalFilter = options.filter;
options.filter = null;
}
DataSource.fn.init.call(this, extend(true, {}, { schema: { modelBase: node, model: node } }, options));
this._attachBubbleHandlers();
},
_attachBubbleHandlers: function() {
var that = this;
that._data.bind(ERROR, function(e) {
that.trigger(ERROR, e);
});
that._data.bind(ITEMSLOADED, function(e) {
that.trigger(ITEMSLOADED, e);
});
},
loading: function() {
if (this._data) {
return this._data.loading() || this._childrenLoading();
}
return false;
},
_childrenLoading: function() {
var isLoading = false;
this._data.forEach(function(node) {
if (node.hasChildren && node.children.loading()) {
isLoading = true;
}
});
return isLoading;
},
read: function(data) {
var result = DataSource.fn.read.call(this, data);
if (this._hierarchicalFilter) {
if (this._data && this._data.length > 0) {
this.filter(this._hierarchicalFilter);
} else {
this.options.filter = this._hierarchicalFilter;
this._filter = normalizeFilter(this.options.filter);
this._hierarchicalFilter = null;
}
}
return result;
},
remove: function(node) {
var parentNode = node.parentNode(),
dataSource = this,
result;
if (parentNode && parentNode._initChildren) {
dataSource = parentNode.children;
}
result = DataSource.fn.remove.call(dataSource, node);
if (parentNode && !dataSource.data().length) {
parentNode.hasChildren = false;
}
return result;
},
success: dataMethod("success"),
data: dataMethod("data"),
insert: function(index, model) {
var parentNode = this.parent();
if (parentNode && parentNode._initChildren) {
parentNode.hasChildren = true;
parentNode._initChildren();
}
return DataSource.fn.insert.call(this, index, model);
},
filter: function(val) {
if (val === undefined$1) {
return this._filter;
}
if (!this.options.serverFiltering && this._markHierarchicalQuery(val)) {
val = { logic: "or", filters: [val, { field: '_matchFilter', operator: 'equals', value: true }] };
}
this.trigger("reset");
this._query({ filter: val, page: 1 });
},
_markHierarchicalQuery: function(expressions) {
var compiled;
var accentFoldingFiltering = this.options.accentFoldingFiltering;
expressions = accentFoldingFiltering ? $.extend({}, normalizeFilter(expressions), { accentFoldingFiltering: accentFoldingFiltering }) : normalizeFilter(expressions);
if (!expressions || expressions.filters.length === 0) {
this._updateHierarchicalFilter(function() {return true;});
return false;
}
compiled = Query.filterExpr(expressions, { noEval: true });
this._updateHierarchicalFilter(compiled);
return true;
},
_updateHierarchicalFilter: function(filter) {
var current;
var data = this._data;
var result = false;
for (var idx = 0; idx < data.length; idx++) {
current = data[idx];
if (current.hasChildren) {
current._matchFilter = current.children._updateHierarchicalFilter(filter);
if (!current._matchFilter) {
current._matchFilter = filter(current);
}
} else {
current._matchFilter = filter(current);
}
if (current._matchFilter) {
result = true;
}
}
return result;
},
_find: function(method, value) {
var idx, length, node, children;
var data = this._data;
if (!data) {
return;
}
node = DataSource.fn[method].call(this, value);
if (node) {
return node;
}
data = this._flatData(this._data);
for (idx = 0, length = data.length; idx < length; idx++) {
children = data[idx].children;
if (!(children instanceof HierarchicalDataSource)) {
continue;
}
node = children[method](value);
if (node) {
return node;
}
}
},
get: function(id) {
return this._find("get", id);
},
getByUid: function(uid) {
return this._find("getByUid", uid);
}
});
function inferList(list, fields) {
var items = $(list).children(),
idx,
length,
data = [],
record,
textField = fields[0].field,
urlField = fields[1] && fields[1].field,
spriteCssClassField = fields[2] && fields[2].field,
imageUrlField = fields[3] && fields[3].field,
item,
id,
textChild,
className,
children;
function elements(collection, tagName) {
return collection.filter(tagName).add(collection.find(tagName));
}
for (idx = 0, length = items.length; idx < length; idx++) {
record = { _loaded: true };
item = items.eq(idx);
textChild = item[0].firstChild;
children = item.children();
list = children.filter("ul");
children = children.filter(":not(ul)");
id = item.attr("data-id");
if (id) {
record.id = id;
}
if (textChild) {
record[textField] = textChild.nodeType == 3 ? textChild.nodeValue : children.text();
}
if (urlField) {
record[urlField] = elements(children, "a").attr("href");
}
if (imageUrlField) {
record[imageUrlField] = elements(children, "img").attr("src");
}
if (spriteCssClassField) {
className = elements(children, ".k-sprite").prop("className");
record[spriteCssClassField] = className && kendo.trim(className.replace("k-sprite", ""));
}
if (list.length) {
record.items = inferList(list.eq(0), fields);
}
if (item.attr("data-hasChildren") == "true") {
record.hasChildren = true;
}
data.push(record);
}
return data;
}
HierarchicalDataSource.create = function(options) {
options = options && options.push ? { data: options } : options;
var dataSource = options || {},
data = dataSource.data,
fields = dataSource.fields,
list = dataSource.list;
if (data && data._dataSource) {
return data._dataSource;
}
if (!data && fields && !dataSource.transport) {
if (list) {
data = inferList(list, fields);
}
}
dataSource.data = data;
return dataSource instanceof HierarchicalDataSource ? dataSource : new HierarchicalDataSource(dataSource);
};
var Buffer = kendo.Observable.extend({
init: function(dataSource, viewSize, disablePrefetch) {
kendo.Observable.fn.init.call(this);
this._prefetching = false;
this.dataSource = dataSource;
this.prefetch = !disablePrefetch;
var buffer = this;
dataSource.bind("change", function() {
buffer._change();
});
dataSource.bind("reset", function() {
buffer._reset();
});
this._syncWithDataSource();
this.setViewSize(viewSize);
},
setViewSize: function(viewSize) {
this.viewSize = viewSize;
this._recalculate();
},
at: function(index) {
var pageSize = this.pageSize,
itemPresent = true;
if (index >= this.total()) {
this.trigger("endreached", { index: index });
return null;
}
if (!this.useRanges) {
return this.dataSource.view()[index];
}
if (this.useRanges) {
// out of range request
if (index < this.dataOffset || index >= this.skip + pageSize) {
itemPresent = this.range(Math.floor(index / pageSize) * pageSize);
}
// prefetch
if (index === this.prefetchThreshold) {
this._prefetch();
}
// mid-range jump - prefetchThreshold and nextPageThreshold may be equal, do not change to else if
if (index === this.midPageThreshold) {
this.range(this.nextMidRange, true);
}
// next range jump
else if (index === this.nextPageThreshold) {
this.range(this.nextFullRange);
}
// pull-back
else if (index === this.pullBackThreshold) {
if (this.offset === this.skip) { // from full range to mid range
this.range(this.previousMidRange);
} else { // from mid range to full range
this.range(this.previousFullRange);
}
}
if (itemPresent) {
return this.dataSource.at(index - this.dataOffset);
} else {
this.trigger("endreached", { index: index });
return null;
}
}
},
indexOf: function(item) {
return this.dataSource.data().indexOf(item) + this.dataOffset;
},
total: function() {
return parseInt(this.dataSource.total(), 10);
},
next: function() {
var buffer = this,
pageSize = buffer.pageSize,
offset = buffer.skip - buffer.viewSize + pageSize,
pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize;
this.offset = offset;
this.dataSource.prefetch(pageSkip, pageSize, function() {
buffer._goToRange(offset, true);
});
},
range: function(offset, nextRange) {
if (this.offset === offset) {
return true;
}
var buffer = this,
pageSize = this.pageSize,
pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize,
dataSource = this.dataSource;
if (nextRange) {
pageSkip += pageSize;
}
if (dataSource.inRange(offset, pageSize)) {
this.offset = offset;
this._recalculate();
this._goToRange(offset);
return true;
} else if (this.prefetch) {
dataSource.prefetch(pageSkip, pageSize, function() {
buffer.offset = offset;
buffer._recalculate();
buffer._goToRange(offset, true);
});
return false;
}
return true;
},
syncDataSource: function() {
var offset = this.offset;
this.offset = null;
this.range(offset);
},
destroy: function() {
this.unbind();
},
_prefetch: function() {
var buffer = this,
pageSize = this.pageSize,
prefetchOffset = this.skip + pageSize,
dataSource = this.dataSource;
if (!dataSource.inRange(prefetchOffset, pageSize) && !this._prefetching && this.prefetch) {
this._prefetching = true;
this.trigger("prefetching", { skip: prefetchOffset, take: pageSize });
dataSource.prefetch(prefetchOffset, pageSize, function() {
buffer._prefetching = false;
buffer.trigger("prefetched", { skip: prefetchOffset, take: pageSize });
});
}
},
_goToRange: function(offset, expanding) {
if (this.offset !== offset) {
return;
}
this.dataOffset = offset;
this._expanding = expanding;
this.dataSource.range(offset, this.pageSize);
this.dataSource.enableRequestsInProgress();
},
_reset: function() {
this._syncPending = true;
},
_change: function() {
var dataSource = this.dataSource;
this.length = this.useRanges ? dataSource.lastRange().end : dataSource.view().length;
if (this._syncPending) {
this._syncWithDataSource();
this._recalculate();
this._syncPending = false;
this.trigger("reset", { offset: this.offset });
}
this.trigger("resize");
if (this._expanding) {
this.trigger("expand");
}
delete this._expanding;
},
_syncWithDataSource: function() {
var dataSource = this.dataSource;
this._firstItemUid = dataSource.firstItemUid();
this.dataOffset = this.offset = dataSource.skip() || 0;
this.pageSize = dataSource.pageSize();
this.useRanges = dataSource.options.serverPaging;
},
_recalculate: function() {
var pageSize = this.pageSize,
offset = this.offset,
viewSize = this.viewSize,
skip = Math.ceil(offset / pageSize) * pageSize;
this.skip = skip;
this.midPageThreshold = skip + pageSize - 1;
this.nextPageThreshold = skip + viewSize - 1;
this.prefetchThreshold = skip + Math.floor(pageSize / 3 * 2);
this.pullBackThreshold = this.offset - 1;
this.nextMidRange = skip + pageSize - viewSize;
this.nextFullRange = skip;
this.previousMidRange = offset - viewSize;
this.previousFullRange = skip - pageSize;
}
});
var BatchBuffer = kendo.Observable.extend({
init: function(dataSource, batchSize) {
var batchBuffer = this;
kendo.Observable.fn.init.call(batchBuffer);
this.dataSource = dataSource;
this.batchSize = batchSize;
this._total = 0;
this.buffer = new Buffer(dataSource, batchSize * 3);
this.buffer.bind({
"endreached": function(e) {
batchBuffer.trigger("endreached", { index: e.index });
},
"prefetching": function(e) {
batchBuffer.trigger("prefetching", { skip: e.skip, take: e.take });
},
"prefetched": function(e) {
batchBuffer.trigger("prefetched", { skip: e.skip, take: e.take });
},
"reset": function() {
batchBuffer._total = 0;
batchBuffer.trigger("reset");
},
"resize": function() {
batchBuffer._total = Math.ceil(this.length / batchBuffer.batchSize);
batchBuffer.trigger("resize", { total: batchBuffer.total(), offset: this.offset });
}
});
},
syncDataSource: function() {
this.buffer.syncDataSource();
},
at: function(index) {
var buffer = this.buffer,
skip = index * this.batchSize,
take = this.batchSize,
view = [],
item;
if (buffer.offset > skip) {
buffer.at(buffer.offset - 1);
}
for (var i = 0; i < take; i++) {
item = buffer.at(skip + i);
if (item === null) {
break;
}
view.push(item);
}
return view;
},
total: function() {
return this._total;
},
destroy: function() {
this.buffer.destroy();
this.unbind();
}
});
extend(true, kendo.data, {
readers: {
json: DataReader
},
Query: Query,
DataSource: DataSource,
HierarchicalDataSource: HierarchicalDataSource,
Node: Node,
Comparer: Comparer,
ObservableObject: ObservableObject,
ObservableArray: ObservableArray,
LazyObservableArray: LazyObservableArray,
LocalTransport: LocalTransport,
RemoteTransport: RemoteTransport,
AiTransport: AiTransport,
Cache: Cache,
DataReader: DataReader,
Model: Model,
Buffer: Buffer,
BatchBuffer: BatchBuffer
});
})(window.kendo.jQuery);
var kendo$1 = kendo;
exports.__meta__ = __meta__;
exports.default = kendo$1;