{"version":3,"sources":["kendo.data.js"],"names":["f","define","$","undefined","eventHandler","context","type","field","prefix","e","key","event","CHANGE","_notifyChange","trigger","equal","x","y","xtype","ytype","getTime","getFieldByName","obj","name","fieldName","isPlainObject","Query","data","this","normalizeSort","dir","descriptor","STRING","descriptors","isArray","grep","d","normalizeOperator","expression","idx","length","filter","operator","filters","operatorMap","toLowerCase","normalizeFilter","isEmptyObject","logic","compareDescriptor","f1","f2","value","normalizeDescriptor","fieldComparer","a","b","compareFilters","expr1","expr2","filters1","filters2","slice","sort","normalizeAggregate","expressions","normalizeGroup","compare","skipItemSorting","map","aggregates","normalizeGroupWithoutCompare","i","anyGroupDescriptorHasCompare","groupDescriptors","isFunction","groupValueComparer","calculateAggregate","accumulator","item","index","state","aggr","functionName","len","aggregate","functions","kendo","accessor","isNumber","val","isNaN","isDate","toJSON","array","result","Array","serializeRecords","getters","modelInstance","originalFieldNames","fieldNames","record","getter","originalName","setters","setter","convertRecords","_parse","convertGroup","hasSubgroups","items","wrapDataAccess","originalFunction","model","converter","wrapDataAccessBase","toString","call","ObservableArray","fillLastGroup","originalGroup","newGroup","currOriginal","currentNew","push","apply","mergeGroups","target","dest","skip","take","group","concat","splice","flatGroups","groups","indexFunction","groupIndex","itemIndex","groupsLength","indexFn","flattenGroups","at","wrapGroupItems","LazyObservableArray","_events","eachGroupItems","func","replaceInRanges","ranges","observable","replaceInRange","replaceWithObservable","view","serverGrouping","viewIndex","removeModel","dataItem","uid","indexOfPristineModel","indexOf","idField","id","_defaultId","indexOfModel","comparer","fieldNameFromModel","fields","from","convertFilterDescriptorsField","convertDescriptorsField","inferSelect","select","options","firstField","secondField","optgroup","option","parentNode","disabled","label","text","attributes","specified","inferTable","table","fieldIndex","cells","cell","empty","tbody","tBodies","rows","fieldCount","nodeName","innerHTML","dataMethod","_data","DataSource","fn","arguments","_attachBubbleHandlers","inferList","list","elements","collection","tagName","add","find","textChild","className","children","textField","urlField","spriteCssClassField","imageUrlField","_loaded","eq","firstChild","attr","nodeType","nodeValue","prop","trim","replace","hasChildren","ObservableObject","parsers","defaultValues","Model","Comparer","StableComparer","operators","LocalTransport","RemoteTransport","Cache","DataReader","Transport","Node","HierarchicalDataSource","Buffer","BatchBuffer","extend","proxy","ajax","each","noop","window","Observable","Class","FUNCTION","ASCENDING","CREATE","READ","UPDATE","DESTROY","SYNC","GET","ERROR","REQUESTSTART","PROGRESS","REQUESTEND","crud","identity","o","stringify","math","Math","join","pop","shift","unshift","stableSort","support","dateRegExp","init","that","wrapAll","json","parent","source","wrap","object","bind","node","action","howMany","unbind","forEach","callback","thisArg","reduce","reduceRight","every","some","remove","Symbol","iterator","prototype","events","_parent","member","_handlers","charAt","guid","shouldSerialize","hasOwnProperty","get","_set","paths","path","composite","split","set","isSetPrevented","current","change","isObservableArray","isDataSource","number","parseFloat","date","parseDate","boolean","string","default","Date","defaults","_initializers","dirty","dirtyFields","parse","editable","initiator","accept","isNew","base","proto","functionFields","nullable","defaultValue","selector","localeCompare","create","combine","comparers","asc","valueA","valueB","__position","desc","quote","str","JSON","textOp","impl","ignore","accentFoldingFiltering","toLocaleLowerCase","op","exec","getMatchRegexp","pattern","rx","esc","ch","neq","gt","gte","lt","lte","startswith","doesnotstartwith","endswith","n","doesnotendwith","contains","doesnotcontain","matches","substring","doesnotmatch","isempty","isnotempty","isnull","isnotnull","isnullorempty","isnotnullorempty","filterExpr","expr","and","or","fieldFunctions","operatorFunctions","match","ignoreCase","==","equals","isequalto","equalto","!=","ne","notequals","isnotequalto","notequalto","notequal","<","islessthan","lessthan","less","<=","le","islessthanorequalto","lessthanequal",">","isgreaterthan","greaterthan","greater",">=","isgreaterthanorequalto","greaterthanequal","ge","notsubstringof","toArray","range","count","order","inPlace","orderBy","orderByDescending","compiled","predicate","Function","allData","groupBy","sorted","groupValue","currentValue","_sortForGrouping","_sortGroups","sum","average","max","min","process","customGroupSort","query","groupDescriptorsWithoutCompare","normalizedSort","groupDescriptorsWithoutSort","total","filterCallback","groupDescriptor","read","success","update","destroy","parameterMap","url","cache","submit","setup","error","parameters","operation","_store","clear","store","inmemory","schema","dataFunction","groupsFunction","serializeFunction","serializeGetters","modelBase","_dataAccessFunction","serialize","fromName","_wrapDataAccessBase","errors","_map","_prefetch","_pristineData","_ranges","_view","_pristineTotal","_destroyed","_pageSize","pageSize","_page","page","_sort","_filter","_group","_aggregate","_total","_shouldDetachObservableParents","transport","pushCreate","_pushCreate","pushUpdate","_pushUpdate","pushDestroy","_pushDestroy","offlineStorage","_storage","getItem","localStorage","setItem","reader","readers","_detachObservableParents","_observe","_online","serverSorting","serverPaging","serverFiltering","serverAggregates","batch","inPlaceSort","clone","online","sync","Deferred","resolve","promise","offlineData","_isServerGrouped","_push","_readData","_flatData","useRanges","getByUid","_getByUid","dataItems","_storeData","_addRange","_process","_observeView","flatView","insert","_createNewModel","_wrapInEmptyGroup","_insertModelInRange","pushInsert","pushed","autoSync","pristine","rangeSpan","_getCurrentRangeSpan","last","pristineData","_updatePristineForModel","_removeItems","removePristine","shouldRemovePristine","destroyed","found","_eachItem","_removePristineForModel","hasGroups","_removeModelFromRanges","created","updated","promises","_sendSubmit","_send","when","then","_accept","_syncEnd","_change","cancelChanges","_cancelModel","_changesCanceled","_markOfflineUpdatesAsDirty","__state__","hasChanges","models","response","serverGroup","_handleCustomErrors","values","_executeOnPristineForModel","deepExtend","_eachPristineItem","_pristineForModel","_modelCanceled","_submit","status","reject","deferred","_promise","method","converted","params","_params","_queueRequest","isPrevented","_dequeueRequest","args","_readAggregates","replaceSubset","itemIds","j","_aggregateResult","_skip","endless","_changeHandler","updatePristine","start","end","timestamp","_timeStamp","_sortRanges","xhr","errorThrown","_requestInProgress","_pending","_shouldWrap","arrayType","_updateTotalForAction","parseInt","handler","first","_calculateAggregates","_take","currentRangeStart","_clearEmptyGroups","_queryProcess","dataToAggregate","_setFilterTotal","_mergeState","_currentRangeStart","moreItemsCount","remote","filterTotal","setDefaultValue","fetch","_query","done","next","totalPages","prev","_pageableQueryOptions","round","_emptyAggregates","ceil","inRange","_findRange","lastRange","firstItemUid","enableRequestsInProgress","_skipRequestsInProgress","_currentRequestTimeStamp","pageSkip","floor","size","_processRangeData","_rangeExists","prefetch","skipIdx","takeIdx","startIndex","endIndex","rangeData","rangeEnd","processed","flatData","_mergeGroups","prevGroup","temp","paging","sorting","filtering","_prefetchSuccessHandler","force","clearTimeout","_timeout","setTimeout","_multiplePrefetch","_removeModelFromRange","_updateRangesLength","rangesLength","mismatchFound","mismatchLength","lengthDifference","abs","dataSource","transportOptions","transports","schemas","logToConsole","hasChildrenObject","childrenField","childrenOptions","_childrenOptions","_initChildren","_updateChildrenField","append","loaded","level","_childrenLoaded","load","one","_matchFilter","_hierarchicalFilter","_markHierarchicalQuery","_updateHierarchicalFilter","_find","_dataSource","viewSize","disablePrefetch","_prefetching","buffer","_reset","_syncWithDataSource","setViewSize","_recalculate","itemPresent","dataOffset","prefetchThreshold","midPageThreshold","nextMidRange","nextPageThreshold","nextFullRange","pullBackThreshold","offset","previousMidRange","previousFullRange","_goToRange","nextRange","syncDataSource","prefetchOffset","expanding","_expanding","_syncPending","_firstItemUid","batchSize","batchBuffer","endreached","prefetching","prefetched","reset","resize","jQuery","amd","a1","a2","a3"],"mappings":"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","file":"kendo.data.min.js","sourcesContent":["/*!\n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n                                                                                                                                                                                                       \n\n*/\n(function (f, define) {\n    define('kendo.data', [\n        'kendo.core',\n        'kendo.data.odata',\n        'kendo.data.xml'\n    ], f);\n}(function () {\n    var __meta__ = {\n        id: 'data',\n        name: 'Data source',\n        category: 'framework',\n        description: 'Powerful component for using local and remote data.Fully supports CRUD, Sorting, Paging, Filtering, Grouping, and Aggregates.',\n        depends: ['core'],\n        features: [\n            {\n                id: 'data-odata',\n                name: 'OData',\n                description: 'Support for accessing Open Data Protocol (OData) services.',\n                depends: ['data.odata']\n            },\n            {\n                id: 'data-signalr',\n                name: 'SignalR',\n                description: 'Support for binding to SignalR hubs.',\n                depends: ['data.signalr']\n            },\n            {\n                id: 'data-XML',\n                name: 'XML',\n                description: 'Support for binding to XML.',\n                depends: ['data.xml']\n            }\n        ]\n    };\n    (function ($, undefined) {\n        var extend = $.extend, proxy = $.proxy, isPlainObject = $.isPlainObject, isEmptyObject = $.isEmptyObject, isArray = $.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', crud = [\n                CREATE,\n                READ,\n                UPDATE,\n                DESTROY\n            ], identity = function (o) {\n                return o;\n            }, 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\\((.*?)\\)\\/$/;\n        var ObservableArray = Observable.extend({\n            init: function (array, type) {\n                var that = this;\n                that.type = type || ObservableObject;\n                Observable.fn.init.call(that);\n                that.length = array.length;\n                that.wrapAll(array, that);\n            },\n            at: function (index) {\n                return this[index];\n            },\n            toJSON: function () {\n                var idx, length = this.length, value, json = new Array(length);\n                for (idx = 0; idx < length; idx++) {\n                    value = this[idx];\n                    if (value instanceof ObservableObject) {\n                        value = value.toJSON();\n                    }\n                    json[idx] = value;\n                }\n                return json;\n            },\n            parent: noop,\n            wrapAll: function (source, target) {\n                var that = this, idx, length, parent = function () {\n                        return that;\n                    };\n                target = target || [];\n                for (idx = 0, length = source.length; idx < length; idx++) {\n                    target[idx] = that.wrap(source[idx], parent);\n                }\n                return target;\n            },\n            wrap: function (object, parent) {\n                var that = this, observable;\n                if (object !== null && toString.call(object) === '[object Object]') {\n                    observable = object instanceof that.type || object instanceof Model;\n                    if (!observable) {\n                        object = object instanceof ObservableObject ? object.toJSON() : object;\n                        object = new that.type(object);\n                    }\n                    object.parent = parent;\n                    object.bind(CHANGE, function (e) {\n                        that.trigger(CHANGE, {\n                            field: e.field,\n                            node: e.node,\n                            index: e.index,\n                            items: e.items || [this],\n                            action: e.node ? e.action || 'itemloaded' : 'itemchange'\n                        });\n                    });\n                }\n                return object;\n            },\n            push: function () {\n                var index = this.length, items = this.wrapAll(arguments), result;\n                result = push.apply(this, items);\n                this.trigger(CHANGE, {\n                    action: 'add',\n                    index: index,\n                    items: items\n                });\n                return result;\n            },\n            slice: slice,\n            sort: [].sort,\n            join: join,\n            pop: function () {\n                var length = this.length, result = pop.apply(this);\n                if (length) {\n                    this.trigger(CHANGE, {\n                        action: 'remove',\n                        index: length - 1,\n                        items: [result]\n                    });\n                }\n                return result;\n            },\n            splice: function (index, howMany, item) {\n                var items = this.wrapAll(slice.call(arguments, 2)), result, i, len;\n                result = splice.apply(this, [\n                    index,\n                    howMany\n                ].concat(items));\n                if (result.length) {\n                    this.trigger(CHANGE, {\n                        action: 'remove',\n                        index: index,\n                        items: result\n                    });\n                    for (i = 0, len = result.length; i < len; i++) {\n                        if (result[i] && result[i].children) {\n                            result[i].unbind(CHANGE);\n                        }\n                    }\n                }\n                if (item) {\n                    this.trigger(CHANGE, {\n                        action: 'add',\n                        index: index,\n                        items: items\n                    });\n                }\n                return result;\n            },\n            shift: function () {\n                var length = this.length, result = shift.apply(this);\n                if (length) {\n                    this.trigger(CHANGE, {\n                        action: 'remove',\n                        index: 0,\n                        items: [result]\n                    });\n                }\n                return result;\n            },\n            unshift: function () {\n                var items = this.wrapAll(arguments), result;\n                result = unshift.apply(this, items);\n                this.trigger(CHANGE, {\n                    action: 'add',\n                    index: 0,\n                    items: items\n                });\n                return result;\n            },\n            indexOf: function (item) {\n                var that = this, idx, length;\n                for (idx = 0, length = that.length; idx < length; idx++) {\n                    if (that[idx] === item) {\n                        return idx;\n                    }\n                }\n                return -1;\n            },\n            forEach: function (callback, thisArg) {\n                var idx = 0;\n                var length = this.length;\n                var context = thisArg || window;\n                for (; idx < length; idx++) {\n                    callback.call(context, this[idx], idx, this);\n                }\n            },\n            map: function (callback, thisArg) {\n                var idx = 0;\n                var result = [];\n                var length = this.length;\n                var context = thisArg || window;\n                for (; idx < length; idx++) {\n                    result[idx] = callback.call(context, this[idx], idx, this);\n                }\n                return result;\n            },\n            reduce: function (callback) {\n                var idx = 0, result, length = this.length;\n                if (arguments.length == 2) {\n                    result = arguments[1];\n                } else if (idx < length) {\n                    result = this[idx++];\n                }\n                for (; idx < length; idx++) {\n                    result = callback(result, this[idx], idx, this);\n                }\n                return result;\n            },\n            reduceRight: function (callback) {\n                var idx = this.length - 1, result;\n                if (arguments.length == 2) {\n                    result = arguments[1];\n                } else if (idx > 0) {\n                    result = this[idx--];\n                }\n                for (; idx >= 0; idx--) {\n                    result = callback(result, this[idx], idx, this);\n                }\n                return result;\n            },\n            filter: function (callback, thisArg) {\n                var idx = 0;\n                var result = [];\n                var item;\n                var length = this.length;\n                var context = thisArg || window;\n                for (; idx < length; idx++) {\n                    item = this[idx];\n                    if (callback.call(context, item, idx, this)) {\n                        result[result.length] = item;\n                    }\n                }\n                return result;\n            },\n            find: function (callback, thisArg) {\n                var idx = 0;\n                var item;\n                var length = this.length;\n                var context = thisArg || window;\n                for (; idx < length; idx++) {\n                    item = this[idx];\n                    if (callback.call(context, item, idx, this)) {\n                        return item;\n                    }\n                }\n            },\n            every: function (callback, thisArg) {\n                var idx = 0;\n                var item;\n                var length = this.length;\n                var context = thisArg || window;\n                for (; idx < length; idx++) {\n                    item = this[idx];\n                    if (!callback.call(context, item, idx, this)) {\n                        return false;\n                    }\n                }\n                return true;\n            },\n            some: function (callback, thisArg) {\n                var idx = 0;\n                var item;\n                var length = this.length;\n                var context = thisArg || window;\n                for (; idx < length; idx++) {\n                    item = this[idx];\n                    if (callback.call(context, item, idx, this)) {\n                        return true;\n                    }\n                }\n                return false;\n            },\n            remove: function (item) {\n                var idx = this.indexOf(item);\n                if (idx !== -1) {\n                    this.splice(idx, 1);\n                }\n            },\n            empty: function () {\n                this.splice(0, this.length);\n            }\n        });\n        if (typeof Symbol !== 'undefined' && Symbol.iterator && !ObservableArray.prototype[Symbol.iterator]) {\n            ObservableArray.prototype[Symbol.iterator] = [][Symbol.iterator];\n        }\n        var LazyObservableArray = ObservableArray.extend({\n            init: function (data, type, events) {\n                Observable.fn.init.call(this);\n                this.type = type || ObservableObject;\n                if (events) {\n                    this._events = events;\n                }\n                for (var idx = 0; idx < data.length; idx++) {\n                    this[idx] = data[idx];\n                }\n                this.length = idx;\n                this._parent = proxy(function () {\n                    return this;\n                }, this);\n            },\n            at: function (index) {\n                var item = this[index];\n                if (!(item instanceof this.type)) {\n                    item = this[index] = this.wrap(item, this._parent);\n                } else {\n                    item.parent = this._parent;\n                }\n                return item;\n            }\n        });\n        function eventHandler(context, type, field, prefix) {\n            return function (e) {\n                var event = {}, key;\n                for (key in e) {\n                    event[key] = e[key];\n                }\n                if (prefix) {\n                    event.field = field + '.' + e.field;\n                } else {\n                    event.field = field;\n                }\n                if (type == CHANGE && context._notifyChange) {\n                    context._notifyChange(event);\n                }\n                context.trigger(type, event);\n            };\n        }\n        var ObservableObject = Observable.extend({\n            init: function (value) {\n                var that = this, member, field, parent = function () {\n                        return that;\n                    };\n                Observable.fn.init.call(this);\n                this._handlers = {};\n                for (field in value) {\n                    member = value[field];\n                    if (typeof member === 'object' && member && !member.getTime && field.charAt(0) != '_') {\n                        member = that.wrap(member, field, parent);\n                    }\n                    that[field] = member;\n                }\n                that.uid = kendo.guid();\n            },\n            shouldSerialize: function (field) {\n                return this.hasOwnProperty(field) && field !== '_handlers' && field !== '_events' && typeof this[field] !== FUNCTION && field !== 'uid';\n            },\n            forEach: function (f) {\n                for (var i in this) {\n                    if (this.shouldSerialize(i)) {\n                        f(this[i], i);\n                    }\n                }\n            },\n            toJSON: function () {\n                var result = {}, value, field;\n                for (field in this) {\n                    if (this.shouldSerialize(field)) {\n                        value = this[field];\n                        if (value instanceof ObservableObject || value instanceof ObservableArray) {\n                            value = value.toJSON();\n                        }\n                        result[field] = value;\n                    }\n                }\n                return result;\n            },\n            get: function (field) {\n                var that = this, result;\n                that.trigger(GET, { field: field });\n                if (field === 'this') {\n                    result = that;\n                } else {\n                    result = kendo.getter(field, true)(that);\n                }\n                return result;\n            },\n            _set: function (field, value) {\n                var that = this;\n                var composite = field.indexOf('.') >= 0;\n                if (composite) {\n                    var paths = field.split('.'), path = '';\n                    while (paths.length > 1) {\n                        path += paths.shift();\n                        var obj = kendo.getter(path, true)(that);\n                        if (obj instanceof ObservableObject) {\n                            obj.set(paths.join('.'), value);\n                            return composite;\n                        }\n                        path += '.';\n                    }\n                }\n                kendo.setter(field)(that, value);\n                return composite;\n            },\n            set: function (field, value) {\n                var that = this, isSetPrevented = false, composite = field.indexOf('.') >= 0, current = kendo.getter(field, true)(that);\n                if (current !== value) {\n                    if (current instanceof Observable && this._handlers[field]) {\n                        if (this._handlers[field].get) {\n                            current.unbind(GET, this._handlers[field].get);\n                        }\n                        current.unbind(CHANGE, this._handlers[field].change);\n                    }\n                    isSetPrevented = that.trigger('set', {\n                        field: field,\n                        value: value\n                    });\n                    if (!isSetPrevented) {\n                        if (!composite) {\n                            value = that.wrap(value, field, function () {\n                                return that;\n                            });\n                        }\n                        if (!that._set(field, value) || field.indexOf('(') >= 0 || field.indexOf('[') >= 0) {\n                            that.trigger(CHANGE, { field: field });\n                        }\n                    }\n                }\n                return isSetPrevented;\n            },\n            parent: noop,\n            wrap: function (object, field, parent) {\n                var that = this;\n                var get;\n                var change;\n                var type = toString.call(object);\n                if (object != null && (type === '[object Object]' || type === '[object Array]')) {\n                    var isObservableArray = object instanceof ObservableArray;\n                    var isDataSource = object instanceof DataSource;\n                    if (type === '[object Object]' && !isDataSource && !isObservableArray) {\n                        if (!(object instanceof ObservableObject)) {\n                            object = new ObservableObject(object);\n                        }\n                        get = eventHandler(that, GET, field, true);\n                        object.bind(GET, get);\n                        change = eventHandler(that, CHANGE, field, true);\n                        object.bind(CHANGE, change);\n                        that._handlers[field] = {\n                            get: get,\n                            change: change\n                        };\n                    } else if (type === '[object Array]' || isObservableArray || isDataSource) {\n                        if (!isObservableArray && !isDataSource) {\n                            object = new ObservableArray(object);\n                        }\n                        change = eventHandler(that, CHANGE, field, false);\n                        object.bind(CHANGE, change);\n                        that._handlers[field] = { change: change };\n                    }\n                    object.parent = parent;\n                }\n                return object;\n            }\n        });\n        function equal(x, y) {\n            if (x === y) {\n                return true;\n            }\n            var xtype = $.type(x), ytype = $.type(y), field;\n            if (xtype !== ytype) {\n                return false;\n            }\n            if (xtype === 'date') {\n                return x.getTime() === y.getTime();\n            }\n            if (xtype !== 'object' && xtype !== 'array') {\n                return false;\n            }\n            for (field in x) {\n                if (!equal(x[field], y[field])) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        var parsers = {\n            'number': function (value) {\n                if (typeof value === STRING && value.toLowerCase() === 'null') {\n                    return null;\n                }\n                return kendo.parseFloat(value);\n            },\n            'date': function (value) {\n                if (typeof value === STRING && value.toLowerCase() === 'null') {\n                    return null;\n                }\n                return kendo.parseDate(value);\n            },\n            'boolean': function (value) {\n                if (typeof value === STRING) {\n                    if (value.toLowerCase() === 'null') {\n                        return null;\n                    } else {\n                        return value.toLowerCase() === 'true';\n                    }\n                }\n                return value != null ? !!value : value;\n            },\n            'string': function (value) {\n                if (typeof value === STRING && value.toLowerCase() === 'null') {\n                    return null;\n                }\n                return value != null ? value + '' : value;\n            },\n            'default': function (value) {\n                return value;\n            }\n        };\n        var defaultValues = {\n            'string': '',\n            'number': 0,\n            'date': new Date(),\n            'boolean': false,\n            'default': ''\n        };\n        function getFieldByName(obj, name) {\n            var field, fieldName;\n            for (fieldName in obj) {\n                field = obj[fieldName];\n                if (isPlainObject(field) && field.field && field.field === name) {\n                    return field;\n                } else if (field === name) {\n                    return field;\n                }\n            }\n            return null;\n        }\n        var Model = ObservableObject.extend({\n            init: function (data) {\n                var that = this;\n                if (!data || $.isEmptyObject(data)) {\n                    data = $.extend({}, that.defaults, data);\n                    if (that._initializers) {\n                        for (var idx = 0; idx < that._initializers.length; idx++) {\n                            var name = that._initializers[idx];\n                            data[name] = that.defaults[name]();\n                        }\n                    }\n                }\n                ObservableObject.fn.init.call(that, data);\n                that.dirty = false;\n                that.dirtyFields = {};\n                if (that.idField) {\n                    that.id = that.get(that.idField);\n                    if (that.id === undefined) {\n                        that.id = that._defaultId;\n                    }\n                }\n            },\n            shouldSerialize: function (field) {\n                return ObservableObject.fn.shouldSerialize.call(this, field) && field !== 'uid' && !(this.idField !== 'id' && field === 'id') && field !== 'dirty' && field !== 'dirtyFields' && field !== '_accessors';\n            },\n            _parse: function (field, value) {\n                var that = this, fieldName = field, fields = that.fields || {}, parse;\n                field = fields[field];\n                if (!field) {\n                    field = getFieldByName(fields, fieldName);\n                }\n                if (field) {\n                    parse = field.parse;\n                    if (!parse && field.type) {\n                        parse = parsers[field.type.toLowerCase()];\n                    }\n                }\n                return parse ? parse(value) : value;\n            },\n            _notifyChange: function (e) {\n                var action = e.action;\n                if (action == 'add' || action == 'remove') {\n                    this.dirty = true;\n                    this.dirtyFields[e.field] = true;\n                }\n            },\n            editable: function (field) {\n                field = (this.fields || {})[field];\n                return field ? field.editable !== false : true;\n            },\n            set: function (field, value, initiator) {\n                var that = this;\n                var dirty = that.dirty;\n                if (that.editable(field)) {\n                    value = that._parse(field, value);\n                    if (!equal(value, that.get(field))) {\n                        that.dirty = true;\n                        that.dirtyFields[field] = true;\n                        if (ObservableObject.fn.set.call(that, field, value, initiator) && !dirty) {\n                            that.dirty = dirty;\n                            if (!that.dirty) {\n                                that.dirtyFields[field] = false;\n                            }\n                        }\n                    } else {\n                        that.trigger('equalSet', {\n                            field: field,\n                            value: value\n                        });\n                    }\n                }\n            },\n            accept: function (data) {\n                var that = this, parent = function () {\n                        return that;\n                    }, field;\n                for (field in data) {\n                    var value = data[field];\n                    if (field.charAt(0) != '_') {\n                        value = that.wrap(data[field], field, parent);\n                    }\n                    that._set(field, value);\n                }\n                if (that.idField) {\n                    that.id = that.get(that.idField);\n                }\n                that.dirty = false;\n                that.dirtyFields = {};\n            },\n            isNew: function () {\n                return this.id === this._defaultId;\n            }\n        });\n        Model.define = function (base, options) {\n            if (options === undefined) {\n                options = base;\n                base = Model;\n            }\n            var model, proto = extend({ defaults: {} }, options), name, field, type, value, idx, length, fields = {}, originalName, id = proto.id, functionFields = [];\n            if (id) {\n                proto.idField = id;\n            }\n            if (proto.id) {\n                delete proto.id;\n            }\n            if (id) {\n                proto.defaults[id] = proto._defaultId = '';\n            }\n            if (toString.call(proto.fields) === '[object Array]') {\n                for (idx = 0, length = proto.fields.length; idx < length; idx++) {\n                    field = proto.fields[idx];\n                    if (typeof field === STRING) {\n                        fields[field] = {};\n                    } else if (field.field) {\n                        fields[field.field] = field;\n                    }\n                }\n                proto.fields = fields;\n            }\n            for (name in proto.fields) {\n                field = proto.fields[name];\n                type = field.type || 'default';\n                value = null;\n                originalName = name;\n                name = typeof field.field === STRING ? field.field : name;\n                if (!field.nullable) {\n                    value = proto.defaults[originalName !== name ? originalName : name] = field.defaultValue !== undefined ? field.defaultValue : defaultValues[type.toLowerCase()];\n                    if (typeof value === 'function') {\n                        functionFields.push(name);\n                    }\n                }\n                if (options.id === name) {\n                    proto._defaultId = value;\n                }\n                proto.defaults[originalName !== name ? originalName : name] = value;\n                field.parse = field.parse || parsers[type];\n            }\n            if (functionFields.length > 0) {\n                proto._initializers = functionFields;\n            }\n            model = base.extend(proto);\n            model.define = function (options) {\n                return Model.define(model, options);\n            };\n            if (proto.fields) {\n                model.fields = proto.fields;\n                model.idField = proto.idField;\n            }\n            return model;\n        };\n        var Comparer = {\n            selector: function (field) {\n                return isFunction(field) ? field : getter(field);\n            },\n            compare: function (field) {\n                var selector = this.selector(field);\n                return function (a, b) {\n                    a = selector(a);\n                    b = selector(b);\n                    if (a == null && b == null) {\n                        return 0;\n                    }\n                    if (a == null) {\n                        return -1;\n                    }\n                    if (b == null) {\n                        return 1;\n                    }\n                    if (a.localeCompare) {\n                        return a.localeCompare(b);\n                    }\n                    return a > b ? 1 : a < b ? -1 : 0;\n                };\n            },\n            create: function (sort) {\n                var compare = sort.compare || this.compare(sort.field);\n                if (sort.dir == 'desc') {\n                    return function (a, b) {\n                        return compare(b, a, true);\n                    };\n                }\n                return compare;\n            },\n            combine: function (comparers) {\n                return function (a, b) {\n                    var result = comparers[0](a, b), idx, length;\n                    for (idx = 1, length = comparers.length; idx < length; idx++) {\n                        result = result || comparers[idx](a, b);\n                    }\n                    return result;\n                };\n            }\n        };\n        var StableComparer = extend({}, Comparer, {\n            asc: function (field) {\n                var selector = this.selector(field);\n                return function (a, b) {\n                    var valueA = selector(a);\n                    var valueB = selector(b);\n                    if (valueA && valueA.getTime && valueB && valueB.getTime) {\n                        valueA = valueA.getTime();\n                        valueB = valueB.getTime();\n                    }\n                    if (valueA === valueB) {\n                        return a.__position - b.__position;\n                    }\n                    if (valueA == null) {\n                        return -1;\n                    }\n                    if (valueB == null) {\n                        return 1;\n                    }\n                    if (valueA.localeCompare) {\n                        return valueA.localeCompare(valueB);\n                    }\n                    return valueA > valueB ? 1 : -1;\n                };\n            },\n            desc: function (field) {\n                var selector = this.selector(field);\n                return function (a, b) {\n                    var valueA = selector(a);\n                    var valueB = selector(b);\n                    if (valueA && valueA.getTime && valueB && valueB.getTime) {\n                        valueA = valueA.getTime();\n                        valueB = valueB.getTime();\n                    }\n                    if (valueA === valueB) {\n                        return a.__position - b.__position;\n                    }\n                    if (valueA == null) {\n                        return 1;\n                    }\n                    if (valueB == null) {\n                        return -1;\n                    }\n                    if (valueB.localeCompare) {\n                        return valueB.localeCompare(valueA);\n                    }\n                    return valueA < valueB ? 1 : -1;\n                };\n            },\n            create: function (sort) {\n                return this[sort.dir](sort.field);\n            }\n        });\n        map = function (array, callback) {\n            var idx, length = array.length, result = new Array(length);\n            for (idx = 0; idx < length; idx++) {\n                result[idx] = callback(array[idx], idx, array);\n            }\n            return result;\n        };\n        var operators = function () {\n            function quote(str) {\n                if (typeof str == 'string') {\n                    str = str.replace(/[\\r\\n]+/g, '');\n                }\n                return JSON.stringify(str);\n            }\n            function textOp(impl) {\n                return function (a, b, ignore, accentFoldingFiltering) {\n                    b += '';\n                    if (ignore) {\n                        a = '(' + a + ' || \\'\\').toString()' + (accentFoldingFiltering ? '.toLocaleLowerCase(\\'' + accentFoldingFiltering + '\\')' : '.toLowerCase()');\n                        b = accentFoldingFiltering ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase();\n                    }\n                    return impl(a, quote(b), ignore);\n                };\n            }\n            function operator(op, a, b, ignore, accentFoldingFiltering) {\n                if (b != null) {\n                    if (typeof b === STRING) {\n                        var date = dateRegExp.exec(b);\n                        if (date) {\n                            b = new Date(+date[1]);\n                        } else if (ignore) {\n                            b = quote(accentFoldingFiltering ? b.toLocaleLowerCase(accentFoldingFiltering) : b.toLowerCase());\n                            a = '((' + a + ' || \\'\\')+\\'\\')' + (accentFoldingFiltering ? '.toLocaleLowerCase(\\'' + accentFoldingFiltering + '\\')' : '.toLowerCase()');\n                        } else {\n                            b = quote(b);\n                        }\n                    }\n                    if (b.getTime) {\n                        a = '(' + a + '&&' + a + '.getTime?' + a + '.getTime():' + a + ')';\n                        b = b.getTime();\n                    }\n                }\n                return a + ' ' + op + ' ' + b;\n            }\n            function getMatchRegexp(pattern) {\n                for (var rx = '/^', esc = false, i = 0; i < pattern.length; ++i) {\n                    var ch = pattern.charAt(i);\n                    if (esc) {\n                        rx += '\\\\' + ch;\n                    } else if (ch == '~') {\n                        esc = true;\n                        continue;\n                    } else if (ch == '*') {\n                        rx += '.*';\n                    } else if (ch == '?') {\n                        rx += '.';\n                    } else if ('.+^$()[]{}|\\\\/\\n\\r\\u2028\\u2029\\xA0'.indexOf(ch) >= 0) {\n                        rx += '\\\\' + ch;\n                    } else {\n                        rx += ch;\n                    }\n                    esc = false;\n                }\n                return rx + '$/';\n            }\n            return {\n                quote: function (value) {\n                    if (value && value.getTime) {\n                        return 'new Date(' + value.getTime() + ')';\n                    }\n                    return quote(value);\n                },\n                eq: function (a, b, ignore, accentFoldingFiltering) {\n                    return operator('==', a, b, ignore, accentFoldingFiltering);\n                },\n                neq: function (a, b, ignore, accentFoldingFiltering) {\n                    return operator('!=', a, b, ignore, accentFoldingFiltering);\n                },\n                gt: function (a, b, ignore) {\n                    return operator('>', a, b, ignore);\n                },\n                gte: function (a, b, ignore) {\n                    return operator('>=', a, b, ignore);\n                },\n                lt: function (a, b, ignore) {\n                    return operator('<', a, b, ignore);\n                },\n                lte: function (a, b, ignore) {\n                    return operator('<=', a, b, ignore);\n                },\n                startswith: textOp(function (a, b) {\n                    return a + '.lastIndexOf(' + b + ', 0) == 0';\n                }),\n                doesnotstartwith: textOp(function (a, b) {\n                    return a + '.lastIndexOf(' + b + ', 0) == -1';\n                }),\n                endswith: textOp(function (a, b) {\n                    var n = b ? b.length - 2 : 0;\n                    return a + '.indexOf(' + b + ', ' + a + '.length - ' + n + ') >= 0';\n                }),\n                doesnotendwith: textOp(function (a, b) {\n                    var n = b ? b.length - 2 : 0;\n                    return a + '.indexOf(' + b + ', ' + a + '.length - ' + n + ') < 0';\n                }),\n                contains: textOp(function (a, b) {\n                    return a + '.indexOf(' + b + ') >= 0';\n                }),\n                doesnotcontain: textOp(function (a, b) {\n                    return a + '.indexOf(' + b + ') == -1';\n                }),\n                matches: textOp(function (a, b) {\n                    b = b.substring(1, b.length - 1);\n                    return getMatchRegexp(b) + '.test(' + a + ')';\n                }),\n                doesnotmatch: textOp(function (a, b) {\n                    b = b.substring(1, b.length - 1);\n                    return '!' + getMatchRegexp(b) + '.test(' + a + ')';\n                }),\n                isempty: function (a) {\n                    return a + ' === \\'\\'';\n                },\n                isnotempty: function (a) {\n                    return a + ' !== \\'\\'';\n                },\n                isnull: function (a) {\n                    return '(' + a + ' == null)';\n                },\n                isnotnull: function (a) {\n                    return '(' + a + ' != null)';\n                },\n                isnullorempty: function (a) {\n                    return '(' + a + ' === null) || (' + a + ' === \\'\\')';\n                },\n                isnotnullorempty: function (a) {\n                    return '(' + a + ' !== null) && (' + a + ' !== \\'\\')';\n                }\n            };\n        }();\n        function Query(data) {\n            this.data = data || [];\n        }\n        Query.filterExpr = function (expression) {\n            var expressions = [], logic = {\n                    and: ' && ',\n                    or: ' || '\n                }, idx, length, filter, expr, fieldFunctions = [], operatorFunctions = [], field, operator, filters = expression.filters;\n            for (idx = 0, length = filters.length; idx < length; idx++) {\n                filter = filters[idx];\n                field = filter.field;\n                operator = filter.operator;\n                if (filter.filters) {\n                    expr = Query.filterExpr(filter);\n                    filter = expr.expression.replace(/__o\\[(\\d+)\\]/g, function (match, index) {\n                        index = +index;\n                        return '__o[' + (operatorFunctions.length + index) + ']';\n                    }).replace(/__f\\[(\\d+)\\]/g, function (match, index) {\n                        index = +index;\n                        return '__f[' + (fieldFunctions.length + index) + ']';\n                    });\n                    operatorFunctions.push.apply(operatorFunctions, expr.operators);\n                    fieldFunctions.push.apply(fieldFunctions, expr.fields);\n                } else {\n                    if (typeof field === FUNCTION) {\n                        expr = '__f[' + fieldFunctions.length + '](d)';\n                        fieldFunctions.push(field);\n                    } else {\n                        expr = kendo.expr(field);\n                    }\n                    if (typeof operator === FUNCTION) {\n                        filter = '__o[' + operatorFunctions.length + '](' + expr + ', ' + operators.quote(filter.value) + ')';\n                        operatorFunctions.push(operator);\n                    } else {\n                        filter = operators[(operator || 'eq').toLowerCase()](expr, filter.value, filter.ignoreCase !== undefined ? filter.ignoreCase : true, expression.accentFoldingFiltering);\n                    }\n                }\n                expressions.push(filter);\n            }\n            return {\n                expression: '(' + expressions.join(logic[expression.logic]) + ')',\n                fields: fieldFunctions,\n                operators: operatorFunctions\n            };\n        };\n        function normalizeSort(field, dir) {\n            if (field) {\n                var descriptor = typeof field === STRING ? {\n                        field: field,\n                        dir: dir\n                    } : field, descriptors = isArray(descriptor) ? descriptor : descriptor !== undefined ? [descriptor] : [];\n                return grep(descriptors, function (d) {\n                    return !!d.dir;\n                });\n            }\n        }\n        var operatorMap = {\n            '==': 'eq',\n            equals: 'eq',\n            isequalto: 'eq',\n            equalto: 'eq',\n            equal: 'eq',\n            '!=': 'neq',\n            ne: 'neq',\n            notequals: 'neq',\n            isnotequalto: 'neq',\n            notequalto: 'neq',\n            notequal: 'neq',\n            '<': 'lt',\n            islessthan: 'lt',\n            lessthan: 'lt',\n            less: 'lt',\n            '<=': 'lte',\n            le: 'lte',\n            islessthanorequalto: 'lte',\n            lessthanequal: 'lte',\n            '>': 'gt',\n            isgreaterthan: 'gt',\n            greaterthan: 'gt',\n            greater: 'gt',\n            '>=': 'gte',\n            isgreaterthanorequalto: 'gte',\n            greaterthanequal: 'gte',\n            ge: 'gte',\n            notsubstringof: 'doesnotcontain',\n            isnull: 'isnull',\n            isempty: 'isempty',\n            isnotempty: 'isnotempty'\n        };\n        function normalizeOperator(expression) {\n            var idx, length, filter, operator, filters = expression.filters;\n            if (filters) {\n                for (idx = 0, length = filters.length; idx < length; idx++) {\n                    filter = filters[idx];\n                    operator = filter.operator;\n                    if (operator && typeof operator === STRING) {\n                        filter.operator = operatorMap[operator.toLowerCase()] || operator;\n                    }\n                    normalizeOperator(filter);\n                }\n            }\n        }\n        function normalizeFilter(expression) {\n            if (expression && !isEmptyObject(expression)) {\n                if (isArray(expression) || !expression.filters) {\n                    expression = {\n                        logic: 'and',\n                        filters: isArray(expression) ? expression : [expression]\n                    };\n                }\n                normalizeOperator(expression);\n                return expression;\n            }\n        }\n        Query.normalizeFilter = normalizeFilter;\n        function compareDescriptor(f1, f2) {\n            if (f1.logic || f2.logic) {\n                return false;\n            }\n            return f1.field === f2.field && f1.value === f2.value && f1.operator === f2.operator;\n        }\n        function normalizeDescriptor(filter) {\n            filter = filter || {};\n            if (isEmptyObject(filter)) {\n                return {\n                    logic: 'and',\n                    filters: []\n                };\n            }\n            return normalizeFilter(filter);\n        }\n        function fieldComparer(a, b) {\n            if (b.logic || a.field > b.field) {\n                return 1;\n            } else if (a.field < b.field) {\n                return -1;\n            } else {\n                return 0;\n            }\n        }\n        function compareFilters(expr1, expr2) {\n            expr1 = normalizeDescriptor(expr1);\n            expr2 = normalizeDescriptor(expr2);\n            if (expr1.logic !== expr2.logic) {\n                return false;\n            }\n            var f1, f2;\n            var filters1 = (expr1.filters || []).slice();\n            var filters2 = (expr2.filters || []).slice();\n            if (filters1.length !== filters2.length) {\n                return false;\n            }\n            filters1 = filters1.sort(fieldComparer);\n            filters2 = filters2.sort(fieldComparer);\n            for (var idx = 0; idx < filters1.length; idx++) {\n                f1 = filters1[idx];\n                f2 = filters2[idx];\n                if (f1.logic && f2.logic) {\n                    if (!compareFilters(f1, f2)) {\n                        return false;\n                    }\n                } else if (!compareDescriptor(f1, f2)) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        Query.compareFilters = compareFilters;\n        function normalizeAggregate(expressions) {\n            return isArray(expressions) ? expressions : [expressions];\n        }\n        function normalizeGroup(field, dir, compare, skipItemSorting) {\n            var descriptor = typeof field === STRING ? {\n                    field: field,\n                    dir: dir,\n                    compare: compare,\n                    skipItemSorting: skipItemSorting\n                } : field, descriptors = isArray(descriptor) ? descriptor : descriptor !== undefined ? [descriptor] : [];\n            return map(descriptors, function (d) {\n                return {\n                    field: d.field,\n                    dir: d.dir || 'asc',\n                    aggregates: d.aggregates,\n                    compare: d.compare,\n                    skipItemSorting: d.skipItemSorting\n                };\n            });\n        }\n        function normalizeGroupWithoutCompare(field, dir, compare) {\n            var descriptors = normalizeGroup(field, dir, compare);\n            for (var i = 0; i < descriptors.length; i++) {\n                delete descriptors[i].compare;\n            }\n            return descriptors;\n        }\n        function anyGroupDescriptorHasCompare(groupDescriptors) {\n            var descriptors = isArray(groupDescriptors) ? groupDescriptors : [groupDescriptors];\n            for (var i = 0; i < descriptors.length; i++) {\n                if (descriptors[i] && isFunction(descriptors[i].compare)) {\n                    return true;\n                }\n            }\n            return false;\n        }\n        Query.prototype = {\n            toArray: function () {\n                return this.data;\n            },\n            range: function (index, count) {\n                return new Query(this.data.slice(index, index + count));\n            },\n            skip: function (count) {\n                return new Query(this.data.slice(count));\n            },\n            take: function (count) {\n                return new Query(this.data.slice(0, count));\n            },\n            select: function (selector) {\n                return new Query(map(this.data, selector));\n            },\n            order: function (selector, dir, inPlace) {\n                var sort = { dir: dir };\n                if (selector) {\n                    if (selector.compare) {\n                        sort.compare = selector.compare;\n                    } else {\n                        sort.field = selector;\n                    }\n                }\n                if (inPlace) {\n                    return new Query(this.data.sort(Comparer.create(sort)));\n                }\n                return new Query(this.data.slice(0).sort(Comparer.create(sort)));\n            },\n            orderBy: function (selector, inPlace) {\n                return this.order(selector, 'asc', inPlace);\n            },\n            orderByDescending: function (selector, inPlace) {\n                return this.order(selector, 'desc', inPlace);\n            },\n            sort: function (field, dir, comparer, inPlace) {\n                var idx, length, descriptors = normalizeSort(field, dir), comparers = [];\n                comparer = comparer || Comparer;\n                if (descriptors.length) {\n                    for (idx = 0, length = descriptors.length; idx < length; idx++) {\n                        comparers.push(comparer.create(descriptors[idx]));\n                    }\n                    return this.orderBy({ compare: comparer.combine(comparers) }, inPlace);\n                }\n                return this;\n            },\n            filter: function (expressions) {\n                var idx, current, length, compiled, predicate, data = this.data, fields, operators, result = [], filter;\n                expressions = normalizeFilter(expressions);\n                if (!expressions || expressions.filters.length === 0) {\n                    return this;\n                }\n                compiled = Query.filterExpr(expressions);\n                fields = compiled.fields;\n                operators = compiled.operators;\n                predicate = filter = new Function('d, __f, __o', 'return ' + compiled.expression);\n                if (fields.length || operators.length) {\n                    filter = function (d) {\n                        return predicate(d, fields, operators);\n                    };\n                }\n                for (idx = 0, length = data.length; idx < length; idx++) {\n                    current = data[idx];\n                    if (filter(current)) {\n                        result.push(current);\n                    }\n                }\n                return new Query(result);\n            },\n            group: function (descriptors, allData) {\n                descriptors = normalizeGroup(descriptors || []);\n                allData = allData || this.data;\n                var that = this, result = new Query(that.data), descriptor;\n                if (descriptors.length > 0) {\n                    descriptor = descriptors[0];\n                    result = result.groupBy(descriptor).select(function (group) {\n                        var data = new Query(allData).filter([{\n                                field: group.field,\n                                operator: 'eq',\n                                value: group.value,\n                                ignoreCase: false\n                            }]);\n                        return {\n                            field: group.field,\n                            value: group.value,\n                            items: descriptors.length > 1 ? new Query(group.items).group(descriptors.slice(1), data.toArray()).toArray() : group.items,\n                            hasSubgroups: descriptors.length > 1,\n                            aggregates: data.aggregate(descriptor.aggregates)\n                        };\n                    });\n                }\n                return result;\n            },\n            groupBy: function (descriptor) {\n                var that = this;\n                if (isEmptyObject(descriptor) || !this.data.length) {\n                    return new Query([]);\n                }\n                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 = {\n                        field: field,\n                        value: groupValue,\n                        items: []\n                    }, currentValue, idx, len, result = [group];\n                for (idx = 0, len = sorted.length; idx < len; idx++) {\n                    item = sorted[idx];\n                    currentValue = accessor.get(item, field);\n                    if (!groupValueComparer(groupValue, currentValue)) {\n                        groupValue = currentValue;\n                        group = {\n                            field: field,\n                            value: groupValue,\n                            items: []\n                        };\n                        result.push(group);\n                    }\n                    group.items.push(item);\n                }\n                result = that._sortGroups(result, descriptor);\n                return new Query(result);\n            },\n            _sortForGrouping: function (field, dir) {\n                var idx, length, data = this.data;\n                if (!stableSort) {\n                    for (idx = 0, length = data.length; idx < length; idx++) {\n                        data[idx].__position = idx;\n                    }\n                    data = new Query(data).sort(field, dir, StableComparer).toArray();\n                    for (idx = 0, length = data.length; idx < length; idx++) {\n                        delete data[idx].__position;\n                    }\n                    return data;\n                }\n                return this.sort(field, dir).toArray();\n            },\n            _sortGroups: function (groups, descriptor) {\n                var result = groups;\n                if (descriptor && isFunction(descriptor.compare)) {\n                    result = new Query(result).order({ compare: descriptor.compare }, descriptor.dir || ASCENDING).toArray();\n                }\n                return result;\n            },\n            aggregate: function (aggregates) {\n                var idx, len, result = {}, state = {};\n                if (aggregates && aggregates.length) {\n                    for (idx = 0, len = this.data.length; idx < len; idx++) {\n                        calculateAggregate(result, aggregates, this.data[idx], idx, len, state);\n                    }\n                }\n                return result;\n            }\n        };\n        function groupValueComparer(a, b) {\n            if (a && a.getTime && b && b.getTime) {\n                return a.getTime() === b.getTime();\n            }\n            return a === b;\n        }\n        function calculateAggregate(accumulator, aggregates, item, index, length, state) {\n            aggregates = aggregates || [];\n            var idx, aggr, functionName, len = aggregates.length;\n            for (idx = 0; idx < len; idx++) {\n                aggr = aggregates[idx];\n                functionName = aggr.aggregate;\n                var field = aggr.field;\n                accumulator[field] = accumulator[field] || {};\n                state[field] = state[field] || {};\n                state[field][functionName] = state[field][functionName] || {};\n                accumulator[field][functionName] = functions[functionName.toLowerCase()](accumulator[field][functionName], item, kendo.accessor(field), index, length, state[field][functionName]);\n            }\n        }\n        var functions = {\n            sum: function (accumulator, item, accessor) {\n                var value = accessor.get(item);\n                if (!isNumber(accumulator)) {\n                    accumulator = value;\n                } else if (isNumber(value)) {\n                    accumulator += value;\n                }\n                return accumulator;\n            },\n            count: function (accumulator) {\n                return (accumulator || 0) + 1;\n            },\n            average: function (accumulator, item, accessor, index, length, state) {\n                var value = accessor.get(item);\n                if (state.count === undefined) {\n                    state.count = 0;\n                }\n                if (!isNumber(accumulator)) {\n                    accumulator = value;\n                } else if (isNumber(value)) {\n                    accumulator += value;\n                }\n                if (isNumber(value)) {\n                    state.count++;\n                }\n                if (index == length - 1 && isNumber(accumulator)) {\n                    accumulator = accumulator / state.count;\n                }\n                return accumulator;\n            },\n            max: function (accumulator, item, accessor) {\n                var value = accessor.get(item);\n                if (!isNumber(accumulator) && !isDate(accumulator)) {\n                    accumulator = value;\n                }\n                if (accumulator < value && (isNumber(value) || isDate(value))) {\n                    accumulator = value;\n                }\n                return accumulator;\n            },\n            min: function (accumulator, item, accessor) {\n                var value = accessor.get(item);\n                if (!isNumber(accumulator) && !isDate(accumulator)) {\n                    accumulator = value;\n                }\n                if (accumulator > value && (isNumber(value) || isDate(value))) {\n                    accumulator = value;\n                }\n                return accumulator;\n            }\n        };\n        function isNumber(val) {\n            return typeof val === 'number' && !isNaN(val);\n        }\n        function isDate(val) {\n            return val && val.getTime;\n        }\n        function toJSON(array) {\n            var idx, length = array.length, result = new Array(length);\n            for (idx = 0; idx < length; idx++) {\n                result[idx] = array[idx].toJSON();\n            }\n            return result;\n        }\n        Query.normalizeGroup = normalizeGroup;\n        Query.normalizeSort = normalizeSort;\n        Query.process = function (data, options, inPlace) {\n            options = options || {};\n            var group = options.group;\n            var customGroupSort = anyGroupDescriptorHasCompare(normalizeGroup(group || []));\n            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;\n            if (sort && inPlace) {\n                query = query.sort(sort, undefined, undefined, inPlace);\n            }\n            if (filter) {\n                query = query.filter(filter);\n                if (filterCallback) {\n                    query = filterCallback(query);\n                }\n                total = query.toArray().length;\n            }\n            if (sort && !inPlace) {\n                query = query.sort(sort);\n                if (group) {\n                    data = query.toArray();\n                }\n            }\n            if (customGroupSort) {\n                query = query.group(group, data);\n                if (skip !== undefined && take !== undefined) {\n                    query = new Query(flatGroups(query.toArray())).range(skip, take);\n                    groupDescriptorsWithoutSort = map(groupDescriptorsWithoutCompare, function (groupDescriptor) {\n                        return extend({}, groupDescriptor, { skipItemSorting: true });\n                    });\n                    query = query.group(groupDescriptorsWithoutSort, data);\n                }\n            } else {\n                if (skip !== undefined && take !== undefined) {\n                    query = query.range(skip, take);\n                }\n                if (group) {\n                    query = query.group(group, data);\n                }\n            }\n            return {\n                total: total,\n                data: query.toArray()\n            };\n        };\n        var LocalTransport = Class.extend({\n            init: function (options) {\n                this.data = options.data;\n            },\n            read: function (options) {\n                options.success(this.data);\n            },\n            update: function (options) {\n                options.success(options.data);\n            },\n            create: function (options) {\n                options.success(options.data);\n            },\n            destroy: function (options) {\n                options.success(options.data);\n            }\n        });\n        var RemoteTransport = Class.extend({\n            init: function (options) {\n                var that = this, parameterMap;\n                options = that.options = extend({}, that.options, options);\n                each(crud, function (index, type) {\n                    if (typeof options[type] === STRING) {\n                        options[type] = { url: options[type] };\n                    }\n                });\n                that.cache = options.cache ? Cache.create(options.cache) : {\n                    find: noop,\n                    add: noop\n                };\n                parameterMap = options.parameterMap;\n                if (options.submit) {\n                    that.submit = options.submit;\n                }\n                if (isFunction(options.push)) {\n                    that.push = options.push;\n                }\n                if (!that.push) {\n                    that.push = identity;\n                }\n                that.parameterMap = isFunction(parameterMap) ? parameterMap : function (options) {\n                    var result = {};\n                    each(options, function (option, value) {\n                        if (option in parameterMap) {\n                            option = parameterMap[option];\n                            if (isPlainObject(option)) {\n                                value = option.value(value);\n                                option = option.key;\n                            }\n                        }\n                        result[option] = value;\n                    });\n                    return result;\n                };\n            },\n            options: { parameterMap: identity },\n            create: function (options) {\n                return ajax(this.setup(options, CREATE));\n            },\n            read: function (options) {\n                var that = this, success, error, result, cache = that.cache;\n                options = that.setup(options, READ);\n                success = options.success || noop;\n                error = options.error || noop;\n                result = cache.find(options.data);\n                if (result !== undefined) {\n                    success(result);\n                } else {\n                    options.success = function (result) {\n                        cache.add(options.data, result);\n                        success(result);\n                    };\n                    $.ajax(options);\n                }\n            },\n            update: function (options) {\n                return ajax(this.setup(options, UPDATE));\n            },\n            destroy: function (options) {\n                return ajax(this.setup(options, DESTROY));\n            },\n            setup: function (options, type) {\n                options = options || {};\n                var that = this, parameters, operation = that.options[type], data = isFunction(operation.data) ? operation.data(options.data) : operation.data;\n                options = extend(true, {}, operation, options);\n                parameters = extend(true, {}, data, options.data);\n                options.data = that.parameterMap(parameters, type);\n                if (isFunction(options.url)) {\n                    options.url = options.url(parameters);\n                }\n                return options;\n            }\n        });\n        var Cache = Class.extend({\n            init: function () {\n                this._store = {};\n            },\n            add: function (key, data) {\n                if (key !== undefined) {\n                    this._store[stringify(key)] = data;\n                }\n            },\n            find: function (key) {\n                return this._store[stringify(key)];\n            },\n            clear: function () {\n                this._store = {};\n            },\n            remove: function (key) {\n                delete this._store[stringify(key)];\n            }\n        });\n        Cache.create = function (options) {\n            var store = {\n                'inmemory': function () {\n                    return new Cache();\n                }\n            };\n            if (isPlainObject(options) && isFunction(options.find)) {\n                return options;\n            }\n            if (options === true) {\n                return new Cache();\n            }\n            return store[options]();\n        };\n        function serializeRecords(data, getters, modelInstance, originalFieldNames, fieldNames) {\n            var record, getter, originalName, idx, setters = {}, length;\n            for (idx = 0, length = data.length; idx < length; idx++) {\n                record = data[idx];\n                for (getter in getters) {\n                    originalName = fieldNames[getter];\n                    if (originalName && originalName !== getter) {\n                        if (!setters[originalName]) {\n                            setters[originalName] = kendo.setter(originalName);\n                        }\n                        setters[originalName](record, getters[getter](record));\n                        delete record[getter];\n                    }\n                }\n            }\n        }\n        function convertRecords(data, getters, modelInstance, originalFieldNames, fieldNames) {\n            var record, getter, originalName, idx, length;\n            for (idx = 0, length = data.length; idx < length; idx++) {\n                record = data[idx];\n                for (getter in getters) {\n                    record[getter] = modelInstance._parse(getter, getters[getter](record));\n                    originalName = fieldNames[getter];\n                    if (originalName && originalName !== getter) {\n                        delete record[originalName];\n                    }\n                }\n            }\n        }\n        function convertGroup(data, getters, modelInstance, originalFieldNames, fieldNames) {\n            var record, idx, fieldName, length;\n            for (idx = 0, length = data.length; idx < length; idx++) {\n                record = data[idx];\n                fieldName = originalFieldNames[record.field];\n                if (fieldName && fieldName != record.field) {\n                    record.field = fieldName;\n                }\n                record.value = modelInstance._parse(record.field, record.value);\n                if (record.hasSubgroups) {\n                    convertGroup(record.items, getters, modelInstance, originalFieldNames, fieldNames);\n                } else {\n                    convertRecords(record.items, getters, modelInstance, originalFieldNames, fieldNames);\n                }\n            }\n        }\n        function wrapDataAccess(originalFunction, model, converter, getters, originalFieldNames, fieldNames) {\n            return function (data) {\n                data = originalFunction(data);\n                return wrapDataAccessBase(model, converter, getters, originalFieldNames, fieldNames)(data);\n            };\n        }\n        function wrapDataAccessBase(model, converter, getters, originalFieldNames, fieldNames) {\n            return function (data) {\n                if (data && !isEmptyObject(getters)) {\n                    if (toString.call(data) !== '[object Array]' && !(data instanceof ObservableArray)) {\n                        data = [data];\n                    }\n                    converter(data, getters, new model(), originalFieldNames, fieldNames);\n                }\n                return data || [];\n            };\n        }\n        var DataReader = Class.extend({\n            init: function (schema) {\n                var that = this, member, get, model, base;\n                schema = schema || {};\n                for (member in schema) {\n                    get = schema[member];\n                    that[member] = typeof get === STRING ? getter(get) : get;\n                }\n                base = schema.modelBase || Model;\n                if (isPlainObject(that.model)) {\n                    that.model = model = base.define(that.model);\n                }\n                var dataFunction = proxy(that.data, that);\n                that._dataAccessFunction = dataFunction;\n                if (that.model) {\n                    var groupsFunction = proxy(that.groups, that), serializeFunction = proxy(that.serialize, that), originalFieldNames = {}, getters = {}, serializeGetters = {}, fieldNames = {}, shouldSerialize = false, fieldName, name;\n                    model = that.model;\n                    if (model.fields) {\n                        each(model.fields, function (field, value) {\n                            var fromName;\n                            fieldName = field;\n                            if (isPlainObject(value) && value.field) {\n                                fieldName = value.field;\n                            } else if (typeof value === STRING) {\n                                fieldName = value;\n                            }\n                            if (isPlainObject(value) && value.from) {\n                                fromName = value.from;\n                            }\n                            shouldSerialize = shouldSerialize || fromName && fromName !== field || fieldName !== field;\n                            name = fromName || fieldName;\n                            getters[field] = name.indexOf('.') !== -1 ? getter(name, true) : getter(name);\n                            serializeGetters[field] = getter(field);\n                            originalFieldNames[fromName || fieldName] = field;\n                            fieldNames[field] = fromName || fieldName;\n                        });\n                        if (!schema.serialize && shouldSerialize) {\n                            that.serialize = wrapDataAccess(serializeFunction, model, serializeRecords, serializeGetters, originalFieldNames, fieldNames);\n                        }\n                    }\n                    that._dataAccessFunction = dataFunction;\n                    that._wrapDataAccessBase = wrapDataAccessBase(model, convertRecords, getters, originalFieldNames, fieldNames);\n                    that.data = wrapDataAccess(dataFunction, model, convertRecords, getters, originalFieldNames, fieldNames);\n                    that.groups = wrapDataAccess(groupsFunction, model, convertGroup, getters, originalFieldNames, fieldNames);\n                }\n            },\n            errors: function (data) {\n                return data ? data.errors : null;\n            },\n            parse: identity,\n            data: identity,\n            total: function (data) {\n                return data.length;\n            },\n            groups: identity,\n            aggregates: function () {\n                return {};\n            },\n            serialize: function (data) {\n                return data;\n            }\n        });\n        function fillLastGroup(originalGroup, newGroup) {\n            var currOriginal;\n            var currentNew;\n            if (newGroup.items && newGroup.items.length) {\n                for (var i = 0; i < newGroup.items.length; i++) {\n                    currOriginal = originalGroup.items[i];\n                    currentNew = newGroup.items[i];\n                    if (currOriginal && currentNew) {\n                        if (currOriginal.hasSubgroups) {\n                            fillLastGroup(currOriginal, currentNew);\n                        } else if (currOriginal.field && currOriginal.value == currentNew.value) {\n                            currOriginal.items.push.apply(currOriginal.items, currentNew.items);\n                        } else {\n                            originalGroup.items.push.apply(originalGroup.items, [currentNew]);\n                        }\n                    } else if (currentNew) {\n                        originalGroup.items.push.apply(originalGroup.items, [currentNew]);\n                    }\n                }\n            }\n        }\n        function mergeGroups(target, dest, skip, take) {\n            var group, idx = 0, items;\n            while (dest.length && take) {\n                group = dest[idx];\n                items = group.items;\n                var length = items.length;\n                if (target && target.field === group.field && target.value === group.value) {\n                    if (target.hasSubgroups && target.items.length) {\n                        mergeGroups(target.items[target.items.length - 1], group.items, skip, take);\n                    } else {\n                        items = items.slice(skip, skip + take);\n                        target.items = target.items.concat(items);\n                    }\n                    dest.splice(idx--, 1);\n                } else if (group.hasSubgroups && items.length) {\n                    mergeGroups(group, items, skip, take);\n                    if (!group.items.length) {\n                        dest.splice(idx--, 1);\n                    }\n                } else {\n                    items = items.slice(skip, skip + take);\n                    group.items = items;\n                    if (!group.items.length) {\n                        dest.splice(idx--, 1);\n                    }\n                }\n                if (items.length === 0) {\n                    skip -= length;\n                } else {\n                    skip = 0;\n                    take -= items.length;\n                }\n                if (++idx >= dest.length) {\n                    break;\n                }\n            }\n            if (idx < dest.length) {\n                dest.splice(idx, dest.length - idx);\n            }\n        }\n        function flatGroups(groups, indexFunction) {\n            var result = [];\n            var groupsLength = (groups || []).length;\n            var group;\n            var items;\n            var indexFn = isFunction(indexFunction) ? indexFunction : function (array, index) {\n                return array[index];\n            };\n            for (var groupIndex = 0; groupIndex < groupsLength; groupIndex++) {\n                group = indexFn(groups, groupIndex);\n                if (group.hasSubgroups) {\n                    result = result.concat(flatGroups(group.items));\n                } else {\n                    items = group.items;\n                    for (var itemIndex = 0; itemIndex < items.length; itemIndex++) {\n                        result.push(indexFn(items, itemIndex));\n                    }\n                }\n            }\n            return result;\n        }\n        function flattenGroups(data) {\n            var idx, result = [], length, items, itemIndex;\n            for (idx = 0, length = data.length; idx < length; idx++) {\n                var group = data.at(idx);\n                if (group.hasSubgroups) {\n                    result = result.concat(flattenGroups(group.items));\n                } else {\n                    items = group.items;\n                    for (itemIndex = 0; itemIndex < items.length; itemIndex++) {\n                        result.push(items.at(itemIndex));\n                    }\n                }\n            }\n            return result;\n        }\n        function wrapGroupItems(data, model) {\n            var idx, length, group;\n            if (model) {\n                for (idx = 0, length = data.length; idx < length; idx++) {\n                    group = data.at(idx);\n                    if (group.hasSubgroups) {\n                        wrapGroupItems(group.items, model);\n                    } else {\n                        group.items = new LazyObservableArray(group.items, model, group.items._events);\n                    }\n                }\n            }\n        }\n        function eachGroupItems(data, func) {\n            for (var idx = 0; idx < data.length; idx++) {\n                if (data[idx].hasSubgroups) {\n                    if (eachGroupItems(data[idx].items, func)) {\n                        return true;\n                    }\n                } else if (func(data[idx].items, data[idx])) {\n                    return true;\n                }\n            }\n        }\n        function replaceInRanges(ranges, data, item, observable) {\n            for (var idx = 0; idx < ranges.length; idx++) {\n                if (ranges[idx].data === data) {\n                    break;\n                }\n                if (replaceInRange(ranges[idx].data, item, observable)) {\n                    break;\n                }\n            }\n        }\n        function replaceInRange(items, item, observable) {\n            for (var idx = 0, length = items.length; idx < length; idx++) {\n                if (items[idx] && items[idx].hasSubgroups) {\n                    return replaceInRange(items[idx].items, item, observable);\n                } else if (items[idx] === item || items[idx] === observable) {\n                    items[idx] = observable;\n                    return true;\n                }\n            }\n        }\n        function replaceWithObservable(view, data, ranges, type, serverGrouping) {\n            for (var viewIndex = 0, length = view.length; viewIndex < length; viewIndex++) {\n                var item = view[viewIndex];\n                if (!item || item instanceof type) {\n                    continue;\n                }\n                if (item.hasSubgroups !== undefined && !serverGrouping) {\n                    replaceWithObservable(item.items, data, ranges, type, serverGrouping);\n                } else {\n                    for (var idx = 0; idx < data.length; idx++) {\n                        if (data[idx] === item) {\n                            view[viewIndex] = data.at(idx);\n                            replaceInRanges(ranges, data, item, view[viewIndex]);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        function removeModel(data, model) {\n            var length = data.length;\n            var dataItem;\n            var idx;\n            for (idx = 0; idx < length; idx++) {\n                dataItem = data[idx];\n                if (dataItem.uid && dataItem.uid == model.uid) {\n                    data.splice(idx, 1);\n                    return dataItem;\n                }\n            }\n        }\n        function indexOfPristineModel(data, model) {\n            if (model) {\n                return indexOf(data, function (item) {\n                    return item.uid && item.uid == model.uid || item[model.idField] === model.id && model.id !== model._defaultId;\n                });\n            }\n            return -1;\n        }\n        function indexOfModel(data, model) {\n            if (model) {\n                return indexOf(data, function (item) {\n                    return item.uid == model.uid;\n                });\n            }\n            return -1;\n        }\n        function indexOf(data, comparer) {\n            var idx, length;\n            for (idx = 0, length = data.length; idx < length; idx++) {\n                if (comparer(data[idx])) {\n                    return idx;\n                }\n            }\n            return -1;\n        }\n        function fieldNameFromModel(fields, name) {\n            if (fields && !isEmptyObject(fields)) {\n                var descriptor = fields[name];\n                var fieldName;\n                if (isPlainObject(descriptor)) {\n                    fieldName = descriptor.from || descriptor.field || name;\n                } else {\n                    fieldName = fields[name] || name;\n                }\n                if (isFunction(fieldName)) {\n                    return name;\n                }\n                return fieldName;\n            }\n            return name;\n        }\n        function convertFilterDescriptorsField(descriptor, model) {\n            var idx, length, target = {};\n            for (var field in descriptor) {\n                if (field !== 'filters') {\n                    target[field] = descriptor[field];\n                }\n            }\n            if (descriptor.filters) {\n                target.filters = [];\n                for (idx = 0, length = descriptor.filters.length; idx < length; idx++) {\n                    target.filters[idx] = convertFilterDescriptorsField(descriptor.filters[idx], model);\n                }\n            } else {\n                target.field = fieldNameFromModel(model.fields, target.field);\n            }\n            return target;\n        }\n        function convertDescriptorsField(descriptors, model) {\n            var idx, length, result = [], target, descriptor;\n            for (idx = 0, length = descriptors.length; idx < length; idx++) {\n                target = {};\n                descriptor = descriptors[idx];\n                for (var field in descriptor) {\n                    target[field] = descriptor[field];\n                }\n                target.field = fieldNameFromModel(model.fields, target.field);\n                if (target.aggregates && isArray(target.aggregates)) {\n                    target.aggregates = convertDescriptorsField(target.aggregates, model);\n                }\n                result.push(target);\n            }\n            return result;\n        }\n        var DataSource = Observable.extend({\n            init: function (options) {\n                var that = this, model, data;\n                if (options) {\n                    data = options.data;\n                }\n                options = that.options = extend({}, that.options, options);\n                that._map = {};\n                that._prefetch = {};\n                that._data = [];\n                that._pristineData = [];\n                that._ranges = [];\n                that._view = [];\n                that._pristineTotal = 0;\n                that._destroyed = [];\n                that._pageSize = options.pageSize;\n                that._page = options.page || (options.pageSize ? 1 : undefined);\n                that._sort = normalizeSort(options.sort);\n                that._filter = normalizeFilter(options.filter);\n                that._group = normalizeGroup(options.group);\n                that._aggregate = options.aggregate;\n                that._total = options.total;\n                that._shouldDetachObservableParents = true;\n                Observable.fn.init.call(that);\n                that.transport = Transport.create(options, data, that);\n                if (isFunction(that.transport.push)) {\n                    that.transport.push({\n                        pushCreate: proxy(that._pushCreate, that),\n                        pushUpdate: proxy(that._pushUpdate, that),\n                        pushDestroy: proxy(that._pushDestroy, that)\n                    });\n                }\n                if (options.offlineStorage != null) {\n                    if (typeof options.offlineStorage == 'string') {\n                        var key = options.offlineStorage;\n                        that._storage = {\n                            getItem: function () {\n                                return JSON.parse(localStorage.getItem(key));\n                            },\n                            setItem: function (item) {\n                                localStorage.setItem(key, stringify(that.reader.serialize(item)));\n                            }\n                        };\n                    } else {\n                        that._storage = options.offlineStorage;\n                    }\n                }\n                that.reader = new kendo.data.readers[options.schema.type || 'json'](options.schema);\n                model = that.reader.model || {};\n                that._detachObservableParents();\n                that._data = that._observe(that._data);\n                that._online = true;\n                that.bind([\n                    'push',\n                    ERROR,\n                    CHANGE,\n                    REQUESTSTART,\n                    SYNC,\n                    REQUESTEND,\n                    PROGRESS\n                ], options);\n            },\n            options: {\n                data: null,\n                schema: { modelBase: Model },\n                offlineStorage: null,\n                serverSorting: false,\n                serverPaging: false,\n                serverFiltering: false,\n                serverGrouping: false,\n                serverAggregates: false,\n                batch: false,\n                inPlaceSort: false\n            },\n            clone: function () {\n                return this;\n            },\n            online: function (value) {\n                if (value !== undefined) {\n                    if (this._online != value) {\n                        this._online = value;\n                        if (value) {\n                            return this.sync();\n                        }\n                    }\n                    return $.Deferred().resolve().promise();\n                } else {\n                    return this._online;\n                }\n            },\n            offlineData: function (state) {\n                if (this.options.offlineStorage == null) {\n                    return null;\n                }\n                if (state !== undefined) {\n                    return this._storage.setItem(state);\n                }\n                return this._storage.getItem() || [];\n            },\n            _isServerGrouped: function () {\n                var group = this.group() || [];\n                return this.options.serverGrouping && group.length;\n            },\n            _pushCreate: function (result) {\n                this._push(result, 'pushCreate');\n            },\n            _pushUpdate: function (result) {\n                this._push(result, 'pushUpdate');\n            },\n            _pushDestroy: function (result) {\n                this._push(result, 'pushDestroy');\n            },\n            _push: function (result, operation) {\n                var data = this._readData(result);\n                if (!data) {\n                    data = result;\n                }\n                this[operation](data);\n            },\n            _flatData: function (data, skip) {\n                if (data) {\n                    if (this._isServerGrouped()) {\n                        return flattenGroups(data);\n                    }\n                    if (!skip) {\n                        for (var idx = 0; idx < data.length; idx++) {\n                            data.at(idx);\n                        }\n                    }\n                }\n                return data;\n            },\n            parent: noop,\n            get: function (id) {\n                var idx, length, data = this._flatData(this._data, this.options.useRanges);\n                for (idx = 0, length = data.length; idx < length; idx++) {\n                    if (data[idx].id == id) {\n                        return data[idx];\n                    }\n                }\n            },\n            getByUid: function (id) {\n                return this._getByUid(id, this._data);\n            },\n            _getByUid: function (id, dataItems) {\n                var idx, length, data = this._flatData(dataItems, this.options.useRanges);\n                if (!data) {\n                    return;\n                }\n                for (idx = 0, length = data.length; idx < length; idx++) {\n                    if (data[idx].uid == id) {\n                        return data[idx];\n                    }\n                }\n            },\n            indexOf: function (model) {\n                return indexOfModel(this._data, model);\n            },\n            at: function (index) {\n                return this._data.at(index);\n            },\n            data: function (value) {\n                var that = this;\n                if (value !== undefined) {\n                    that._detachObservableParents();\n                    that._data = this._observe(value);\n                    that._pristineData = value.slice(0);\n                    that._storeData();\n                    that._ranges = [];\n                    that.trigger('reset');\n                    that._addRange(that._data);\n                    that._total = that._data.length;\n                    that._pristineTotal = that._total;\n                    that._process(that._data);\n                } else {\n                    if (that._data) {\n                        for (var idx = 0; idx < that._data.length; idx++) {\n                            that._data.at(idx);\n                        }\n                    }\n                    return that._data;\n                }\n            },\n            view: function (value) {\n                if (value === undefined) {\n                    return this._view;\n                } else {\n                    this._view = this._observeView(value);\n                }\n            },\n            _observeView: function (data) {\n                var that = this;\n                replaceWithObservable(data, that._data, that._ranges, that.reader.model || ObservableObject, that._isServerGrouped());\n                var view = new LazyObservableArray(data, that.reader.model);\n                view.parent = function () {\n                    return that.parent();\n                };\n                return view;\n            },\n            flatView: function () {\n                var groups = this.group() || [];\n                if (groups.length) {\n                    return flattenGroups(this._view);\n                } else {\n                    return this._view;\n                }\n            },\n            add: function (model) {\n                return this.insert(this._data.length, model);\n            },\n            _createNewModel: function (model) {\n                if (this.reader.model) {\n                    return new this.reader.model(model);\n                }\n                if (model instanceof ObservableObject) {\n                    return model;\n                }\n                return new ObservableObject(model);\n            },\n            insert: function (index, model) {\n                if (!model) {\n                    model = index;\n                    index = 0;\n                }\n                if (!(model instanceof Model)) {\n                    model = this._createNewModel(model);\n                }\n                if (this._isServerGrouped()) {\n                    this._data.splice(index, 0, this._wrapInEmptyGroup(model));\n                } else {\n                    this._data.splice(index, 0, model);\n                }\n                this._insertModelInRange(index, model);\n                return model;\n            },\n            pushInsert: function (index, items) {\n                var that = this;\n                var rangeSpan = that._getCurrentRangeSpan();\n                if (!items) {\n                    items = index;\n                    index = 0;\n                }\n                if (!isArray(items)) {\n                    items = [items];\n                }\n                var pushed = [];\n                var autoSync = this.options.autoSync;\n                this.options.autoSync = false;\n                try {\n                    for (var idx = 0; idx < items.length; idx++) {\n                        var item = items[idx];\n                        var result = this.insert(index, item);\n                        pushed.push(result);\n                        var pristine = result.toJSON();\n                        if (this._isServerGrouped()) {\n                            pristine = this._wrapInEmptyGroup(pristine);\n                        }\n                        this._pristineData.push(pristine);\n                        if (rangeSpan && rangeSpan.length) {\n                            $(rangeSpan).last()[0].pristineData.push(pristine);\n                        }\n                        index++;\n                    }\n                } finally {\n                    this.options.autoSync = autoSync;\n                }\n                if (pushed.length) {\n                    this.trigger('push', {\n                        type: 'create',\n                        items: pushed\n                    });\n                }\n            },\n            pushCreate: function (items) {\n                this.pushInsert(this._data.length, items);\n            },\n            pushUpdate: function (items) {\n                if (!isArray(items)) {\n                    items = [items];\n                }\n                var pushed = [];\n                for (var idx = 0; idx < items.length; idx++) {\n                    var item = items[idx];\n                    var model = this._createNewModel(item);\n                    var target = this.get(model.id);\n                    if (target) {\n                        pushed.push(target);\n                        target.accept(item);\n                        target.trigger(CHANGE);\n                        this._updatePristineForModel(target, item);\n                    } else {\n                        this.pushCreate(item);\n                    }\n                }\n                if (pushed.length) {\n                    this.trigger('push', {\n                        type: 'update',\n                        items: pushed\n                    });\n                }\n            },\n            pushDestroy: function (items) {\n                var pushed = this._removeItems(items);\n                if (pushed.length) {\n                    this.trigger('push', {\n                        type: 'destroy',\n                        items: pushed\n                    });\n                }\n            },\n            _removeItems: function (items, removePristine) {\n                if (!isArray(items)) {\n                    items = [items];\n                }\n                var shouldRemovePristine = typeof removePristine !== 'undefined' ? removePristine : true;\n                var destroyed = [];\n                var autoSync = this.options.autoSync;\n                this.options.autoSync = false;\n                try {\n                    for (var idx = 0; idx < items.length; idx++) {\n                        var item = items[idx];\n                        var model = this._createNewModel(item);\n                        var found = false;\n                        this._eachItem(this._data, function (items) {\n                            for (var idx = 0; idx < items.length; idx++) {\n                                var item = items.at(idx);\n                                if (item.id === model.id) {\n                                    destroyed.push(item);\n                                    items.splice(idx, 1);\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        });\n                        if (found && shouldRemovePristine) {\n                            this._removePristineForModel(model);\n                            this._destroyed.pop();\n                        }\n                    }\n                } finally {\n                    this.options.autoSync = autoSync;\n                }\n                return destroyed;\n            },\n            remove: function (model) {\n                var result, that = this, hasGroups = that._isServerGrouped();\n                this._eachItem(that._data, function (items) {\n                    result = removeModel(items, model);\n                    if (result && hasGroups) {\n                        if (!result.isNew || !result.isNew()) {\n                            that._destroyed.push(result);\n                        }\n                        return true;\n                    }\n                });\n                this._removeModelFromRanges(model);\n                return model;\n            },\n            destroyed: function () {\n                return this._destroyed;\n            },\n            created: function () {\n                var idx, length, result = [], data = this._flatData(this._data, this.options.useRanges);\n                for (idx = 0, length = data.length; idx < length; idx++) {\n                    if (data[idx].isNew && data[idx].isNew()) {\n                        result.push(data[idx]);\n                    }\n                }\n                return result;\n            },\n            updated: function () {\n                var idx, length, result = [], data = this._flatData(this._data, this.options.useRanges);\n                for (idx = 0, length = data.length; idx < length; idx++) {\n                    if (data[idx].isNew && !data[idx].isNew() && data[idx].dirty) {\n                        result.push(data[idx]);\n                    }\n                }\n                return result;\n            },\n            sync: function () {\n                var that = this, created = [], updated = [], destroyed = that._destroyed;\n                var promise = $.Deferred().resolve().promise();\n                if (that.online()) {\n                    if (!that.reader.model) {\n                        return promise;\n                    }\n                    created = that.created();\n                    updated = that.updated();\n                    var promises = [];\n                    if (that.options.batch && that.transport.submit) {\n                        promises = that._sendSubmit(created, updated, destroyed);\n                    } else {\n                        promises.push.apply(promises, that._send('create', created));\n                        promises.push.apply(promises, that._send('update', updated));\n                        promises.push.apply(promises, that._send('destroy', destroyed));\n                    }\n                    promise = $.when.apply(null, promises).then(function () {\n                        var idx, length;\n                        for (idx = 0, length = arguments.length; idx < length; idx++) {\n                            if (arguments[idx]) {\n                                that._accept(arguments[idx]);\n                            }\n                        }\n                        that._storeData(true);\n                        that._syncEnd();\n                        that._change({ action: 'sync' });\n                        that.trigger(SYNC);\n                    });\n                } else {\n                    that._storeData(true);\n                    that._syncEnd();\n                    that._change({ action: 'sync' });\n                }\n                return promise;\n            },\n            _syncEnd: noop,\n            cancelChanges: function (model) {\n                var that = this;\n                if (model instanceof kendo.data.Model) {\n                    that._cancelModel(model);\n                } else {\n                    that._destroyed = [];\n                    that._detachObservableParents();\n                    that._data = that._observe(that._pristineData);\n                    if (that.options.serverPaging) {\n                        that._total = that._pristineTotal;\n                    }\n                    that._ranges = [];\n                    that._addRange(that._data, 0);\n                    that._changesCanceled();\n                    that._change();\n                    that._markOfflineUpdatesAsDirty();\n                }\n            },\n            _changesCanceled: noop,\n            _markOfflineUpdatesAsDirty: function () {\n                var that = this;\n                if (that.options.offlineStorage != null) {\n                    that._eachItem(that._data, function (items) {\n                        for (var idx = 0; idx < items.length; idx++) {\n                            var item = items.at(idx);\n                            if (item.__state__ == 'update' || item.__state__ == 'create') {\n                                item.dirty = true;\n                            }\n                        }\n                    });\n                }\n            },\n            hasChanges: function () {\n                var idx, length, data = this._flatData(this._data, this.options.useRanges);\n                if (this._destroyed.length) {\n                    return true;\n                }\n                for (idx = 0, length = data.length; idx < length; idx++) {\n                    if (data[idx].isNew && data[idx].isNew() || data[idx].dirty) {\n                        return true;\n                    }\n                }\n                return false;\n            },\n            _accept: function (result) {\n                var that = this, models = result.models, response = result.response, idx = 0, serverGroup = that._isServerGrouped(), pristine = that._pristineData, type = result.type, length;\n                that.trigger(REQUESTEND, {\n                    response: response,\n                    type: type\n                });\n                if (response && !isEmptyObject(response)) {\n                    response = that.reader.parse(response);\n                    if (that._handleCustomErrors(response)) {\n                        return;\n                    }\n                    response = that.reader.data(response);\n                    if (!isArray(response)) {\n                        response = [response];\n                    }\n                } else {\n                    response = $.map(models, function (model) {\n                        return model.toJSON();\n                    });\n                }\n                if (type === 'destroy') {\n                    that._destroyed = [];\n                }\n                for (idx = 0, length = models.length; idx < length; idx++) {\n                    if (type !== 'destroy') {\n                        models[idx].accept(response[idx]);\n                        if (type === 'create') {\n                            pristine.push(serverGroup ? that._wrapInEmptyGroup(models[idx].toJSON()) : response[idx]);\n                        } else if (type === 'update') {\n                            that._updatePristineForModel(models[idx], response[idx]);\n                        }\n                    } else {\n                        that._removePristineForModel(models[idx]);\n                    }\n                }\n            },\n            _updatePristineForModel: function (model, values) {\n                this._executeOnPristineForModel(model, function (index, items) {\n                    kendo.deepExtend(items[index], values);\n                });\n            },\n            _executeOnPristineForModel: function (model, callback) {\n                this._eachPristineItem(function (items) {\n                    var index = indexOfPristineModel(items, model);\n                    if (index > -1) {\n                        callback(index, items);\n                        return true;\n                    }\n                });\n            },\n            _removePristineForModel: function (model) {\n                this._executeOnPristineForModel(model, function (index, items) {\n                    items.splice(index, 1);\n                });\n            },\n            _readData: function (data) {\n                var read = !this._isServerGrouped() ? this.reader.data : this.reader.groups;\n                return read.call(this.reader, data);\n            },\n            _eachPristineItem: function (callback) {\n                var that = this;\n                var options = that.options;\n                var rangeSpan = that._getCurrentRangeSpan();\n                that._eachItem(that._pristineData, callback);\n                if (options.serverPaging && options.useRanges) {\n                    each(rangeSpan, function (i, range) {\n                        that._eachItem(range.pristineData, callback);\n                    });\n                }\n            },\n            _eachItem: function (data, callback) {\n                if (data && data.length) {\n                    if (this._isServerGrouped()) {\n                        eachGroupItems(data, callback);\n                    } else {\n                        callback(data);\n                    }\n                }\n            },\n            _pristineForModel: function (model) {\n                var pristine, idx, callback = function (items) {\n                        idx = indexOfPristineModel(items, model);\n                        if (idx > -1) {\n                            pristine = items[idx];\n                            return true;\n                        }\n                    };\n                this._eachPristineItem(callback);\n                return pristine;\n            },\n            _cancelModel: function (model) {\n                var that = this;\n                var pristine = this._pristineForModel(model);\n                this._eachItem(this._data, function (items) {\n                    var idx = indexOfModel(items, model);\n                    if (idx >= 0) {\n                        if (pristine && (!model.isNew() || pristine.__state__)) {\n                            items[idx].accept(pristine);\n                            if (pristine.__state__ == 'update') {\n                                items[idx].dirty = true;\n                            }\n                        } else {\n                            that._modelCanceled(model);\n                            items.splice(idx, 1);\n                            that._removeModelFromRanges(model);\n                        }\n                    }\n                });\n            },\n            _modelCanceled: noop,\n            _submit: function (promises, data) {\n                var that = this;\n                that.trigger(REQUESTSTART, { type: 'submit' });\n                that.trigger(PROGRESS);\n                that.transport.submit(extend({\n                    success: function (response, type) {\n                        var promise = $.grep(promises, function (x) {\n                            return x.type == type;\n                        })[0];\n                        if (promise) {\n                            promise.resolve({\n                                response: response,\n                                models: promise.models,\n                                type: type\n                            });\n                        }\n                    },\n                    error: function (response, status, error) {\n                        for (var idx = 0; idx < promises.length; idx++) {\n                            promises[idx].reject(response);\n                        }\n                        that.error(response, status, error);\n                    }\n                }, data));\n            },\n            _sendSubmit: function (created, updated, destroyed) {\n                var that = this, promises = [];\n                if (that.options.batch) {\n                    if (created.length) {\n                        promises.push($.Deferred(function (deferred) {\n                            deferred.type = 'create';\n                            deferred.models = created;\n                        }));\n                    }\n                    if (updated.length) {\n                        promises.push($.Deferred(function (deferred) {\n                            deferred.type = 'update';\n                            deferred.models = updated;\n                        }));\n                    }\n                    if (destroyed.length) {\n                        promises.push($.Deferred(function (deferred) {\n                            deferred.type = 'destroy';\n                            deferred.models = destroyed;\n                        }));\n                    }\n                    that._submit(promises, {\n                        data: {\n                            created: that.reader.serialize(toJSON(created)),\n                            updated: that.reader.serialize(toJSON(updated)),\n                            destroyed: that.reader.serialize(toJSON(destroyed))\n                        }\n                    });\n                }\n                return promises;\n            },\n            _promise: function (data, models, type) {\n                var that = this;\n                return $.Deferred(function (deferred) {\n                    that.trigger(REQUESTSTART, { type: type });\n                    that.trigger(PROGRESS);\n                    that.transport[type].call(that.transport, extend({\n                        success: function (response) {\n                            deferred.resolve({\n                                response: response,\n                                models: models,\n                                type: type\n                            });\n                        },\n                        error: function (response, status, error) {\n                            deferred.reject(response);\n                            that.error(response, status, error);\n                        }\n                    }, data));\n                }).promise();\n            },\n            _send: function (method, data) {\n                var that = this, idx, length, promises = [], converted = that.reader.serialize(toJSON(data));\n                if (that.options.batch) {\n                    if (data.length) {\n                        promises.push(that._promise({ data: { models: converted } }, data, method));\n                    }\n                } else {\n                    for (idx = 0, length = data.length; idx < length; idx++) {\n                        promises.push(that._promise({ data: converted[idx] }, [data[idx]], method));\n                    }\n                }\n                return promises;\n            },\n            read: function (data) {\n                var that = this, params = that._params(data);\n                var deferred = $.Deferred();\n                that._queueRequest(params, function () {\n                    var isPrevented = that.trigger(REQUESTSTART, { type: 'read' });\n                    if (!isPrevented) {\n                        that.trigger(PROGRESS);\n                        that._ranges = [];\n                        that.trigger('reset');\n                        if (that.online()) {\n                            that.transport.read({\n                                data: params,\n                                success: function (data) {\n                                    that._ranges = [];\n                                    that.success(data, params);\n                                    deferred.resolve();\n                                },\n                                error: function () {\n                                    var args = slice.call(arguments);\n                                    that.error.apply(that, args);\n                                    deferred.reject.apply(deferred, args);\n                                }\n                            });\n                        } else if (that.options.offlineStorage != null) {\n                            that.success(that.offlineData(), params);\n                            deferred.resolve();\n                        }\n                    } else {\n                        that._dequeueRequest();\n                        deferred.resolve(isPrevented);\n                    }\n                });\n                return deferred.promise();\n            },\n            _readAggregates: function (data) {\n                return this.reader.aggregates(data);\n            },\n            success: function (data) {\n                var that = this, options = that.options, items, replaceSubset;\n                that.trigger(REQUESTEND, {\n                    response: data,\n                    type: 'read'\n                });\n                if (that.online()) {\n                    data = that.reader.parse(data);\n                    if (that._handleCustomErrors(data)) {\n                        that._dequeueRequest();\n                        return;\n                    }\n                    that._total = that.reader.total(data);\n                    if (that._pageSize > that._total) {\n                        that._pageSize = that._total;\n                        if (that.options.pageSize && that.options.pageSize > that._pageSize) {\n                            that._pageSize = that.options.pageSize;\n                        }\n                    }\n                    if (that._aggregate && options.serverAggregates) {\n                        that._aggregateResult = that._readAggregates(data);\n                    }\n                    data = that._readData(data);\n                    that._destroyed = [];\n                } else {\n                    data = that._readData(data);\n                    items = [];\n                    var itemIds = {};\n                    var model = that.reader.model;\n                    var idField = model ? model.idField : 'id';\n                    var idx;\n                    for (idx = 0; idx < this._destroyed.length; idx++) {\n                        var id = this._destroyed[idx][idField];\n                        itemIds[id] = id;\n                    }\n                    for (idx = 0; idx < data.length; idx++) {\n                        var item = data[idx];\n                        var state = item.__state__;\n                        if (state == 'destroy') {\n                            if (!itemIds[item[idField]]) {\n                                this._destroyed.push(this._createNewModel(item));\n                            }\n                        } else {\n                            items.push(item);\n                        }\n                    }\n                    data = items;\n                    that._total = data.length;\n                }\n                that._pristineTotal = that._total;\n                replaceSubset = that._skip && that._data.length && that._skip < that._data.length;\n                if (that.options.endless) {\n                    if (replaceSubset) {\n                        that._pristineData.splice(that._skip, that._pristineData.length);\n                    }\n                    items = data.slice(0);\n                    for (var j = 0; j < items.length; j++) {\n                        that._pristineData.push(items[j]);\n                    }\n                } else {\n                    that._pristineData = data.slice(0);\n                }\n                that._detachObservableParents();\n                if (that.options.endless) {\n                    that._data.unbind(CHANGE, that._changeHandler);\n                    if (that._isServerGrouped() && that._data[that._data.length - 1].value === data[0].value) {\n                        fillLastGroup(that._data[that._data.length - 1], data[0]);\n                        data.shift();\n                    }\n                    data = that._observe(data);\n                    if (replaceSubset) {\n                        that._data.splice(that._skip, that._data.length);\n                    }\n                    for (var i = 0; i < data.length; i++) {\n                        that._data.push(data[i]);\n                    }\n                    that._data.bind(CHANGE, that._changeHandler);\n                } else {\n                    that._data = that._observe(data);\n                }\n                that._markOfflineUpdatesAsDirty();\n                that._storeData();\n                that._addRange(that._data);\n                that._process(that._data);\n                that._dequeueRequest();\n            },\n            _detachObservableParents: function () {\n                if (this._data && this._shouldDetachObservableParents) {\n                    for (var idx = 0; idx < this._data.length; idx++) {\n                        if (this._data[idx].parent) {\n                            this._data[idx].parent = noop;\n                        }\n                    }\n                }\n            },\n            _storeData: function (updatePristine) {\n                var serverGrouping = this._isServerGrouped();\n                var model = this.reader.model;\n                function items(data) {\n                    var state = [];\n                    for (var idx = 0; idx < data.length; idx++) {\n                        var dataItem = data.at(idx);\n                        var item = dataItem.toJSON();\n                        if (serverGrouping && dataItem.items) {\n                            item.items = items(dataItem.items);\n                        } else {\n                            item.uid = dataItem.uid;\n                            if (model) {\n                                if (dataItem.isNew()) {\n                                    item.__state__ = 'create';\n                                } else if (dataItem.dirty) {\n                                    item.__state__ = 'update';\n                                }\n                            }\n                        }\n                        state.push(item);\n                    }\n                    return state;\n                }\n                if (this.options.offlineStorage != null) {\n                    var state = items(this._data);\n                    var destroyed = [];\n                    for (var idx = 0; idx < this._destroyed.length; idx++) {\n                        var item = this._destroyed[idx].toJSON();\n                        item.__state__ = 'destroy';\n                        destroyed.push(item);\n                    }\n                    this.offlineData(state.concat(destroyed));\n                    if (updatePristine) {\n                        this._pristineData = this.reader.reader ? this.reader.reader._wrapDataAccessBase(state) : this.reader._wrapDataAccessBase(state);\n                    }\n                }\n            },\n            _addRange: function (data, skip) {\n                var that = this, start = typeof skip !== 'undefined' ? skip : that._skip || 0, end = start + that._flatData(data, true).length;\n                that._ranges.push({\n                    start: start,\n                    end: end,\n                    data: data,\n                    pristineData: data.toJSON(),\n                    timestamp: that._timeStamp()\n                });\n                that._sortRanges();\n            },\n            _sortRanges: function () {\n                this._ranges.sort(function (x, y) {\n                    return x.start - y.start;\n                });\n            },\n            error: function (xhr, status, errorThrown) {\n                this._dequeueRequest();\n                this.trigger(REQUESTEND, {});\n                this.trigger(ERROR, {\n                    xhr: xhr,\n                    status: status,\n                    errorThrown: errorThrown\n                });\n            },\n            _params: function (data) {\n                var that = this, options = extend({\n                        take: that.take(),\n                        skip: that.skip(),\n                        page: that.page(),\n                        pageSize: that.pageSize(),\n                        sort: that._sort,\n                        filter: that._filter,\n                        group: that._group,\n                        aggregate: that._aggregate\n                    }, data);\n                if (!that.options.serverPaging) {\n                    delete options.take;\n                    delete options.skip;\n                    delete options.page;\n                    delete options.pageSize;\n                }\n                if (!that.options.serverGrouping) {\n                    delete options.group;\n                } else if (that.reader.model && options.group) {\n                    options.group = convertDescriptorsField(options.group, that.reader.model);\n                }\n                if (!that.options.serverFiltering) {\n                    delete options.filter;\n                } else if (that.reader.model && options.filter) {\n                    options.filter = convertFilterDescriptorsField(options.filter, that.reader.model);\n                }\n                if (!that.options.serverSorting) {\n                    delete options.sort;\n                } else if (that.reader.model && options.sort) {\n                    options.sort = convertDescriptorsField(options.sort, that.reader.model);\n                }\n                if (!that.options.serverAggregates) {\n                    delete options.aggregate;\n                } else if (that.reader.model && options.aggregate) {\n                    options.aggregate = convertDescriptorsField(options.aggregate, that.reader.model);\n                }\n                return options;\n            },\n            _queueRequest: function (options, callback) {\n                var that = this;\n                if (!that._requestInProgress) {\n                    that._requestInProgress = true;\n                    that._pending = undefined;\n                    callback();\n                } else {\n                    that._pending = {\n                        callback: proxy(callback, that),\n                        options: options\n                    };\n                }\n            },\n            _dequeueRequest: function () {\n                var that = this;\n                that._requestInProgress = false;\n                if (that._pending) {\n                    that._queueRequest(that._pending.options, that._pending.callback);\n                }\n            },\n            _handleCustomErrors: function (response) {\n                if (this.reader.errors) {\n                    var errors = this.reader.errors(response);\n                    if (errors) {\n                        this.trigger(ERROR, {\n                            xhr: null,\n                            status: 'customerror',\n                            errorThrown: 'custom error',\n                            errors: errors\n                        });\n                        return true;\n                    }\n                }\n                return false;\n            },\n            _shouldWrap: function (data) {\n                var model = this.reader.model;\n                if (model && data.length) {\n                    return !(data[0] instanceof model);\n                }\n                return false;\n            },\n            _observe: function (data) {\n                var that = this, model = that.reader.model;\n                that._shouldDetachObservableParents = true;\n                if (data instanceof ObservableArray) {\n                    that._shouldDetachObservableParents = false;\n                    if (that._shouldWrap(data)) {\n                        data.type = that.reader.model;\n                        data.wrapAll(data, data);\n                    }\n                } else {\n                    var arrayType = that.pageSize() && !that.options.serverPaging ? LazyObservableArray : ObservableArray;\n                    data = new arrayType(data, that.reader.model);\n                    data.parent = function () {\n                        return that.parent();\n                    };\n                }\n                if (that._isServerGrouped()) {\n                    wrapGroupItems(data, model);\n                }\n                if (that._changeHandler && that._data && that._data instanceof ObservableArray && !(that.options.useRanges && that.options.serverPaging)) {\n                    that._data.unbind(CHANGE, that._changeHandler);\n                } else {\n                    that._changeHandler = proxy(that._change, that);\n                }\n                return data.bind(CHANGE, that._changeHandler);\n            },\n            _updateTotalForAction: function (action, items) {\n                var that = this;\n                var total = parseInt(that._total, 10);\n                if (!isNumber(that._total)) {\n                    total = parseInt(that._pristineTotal, 10);\n                }\n                if (action === 'add') {\n                    total += items.length;\n                } else if (action === 'remove') {\n                    total -= items.length;\n                } else if (action !== 'itemchange' && action !== 'sync' && !that.options.serverPaging) {\n                    total = that._pristineTotal;\n                } else if (action === 'sync') {\n                    total = that._pristineTotal = parseInt(that._total, 10);\n                }\n                that._total = total;\n            },\n            _change: function (e) {\n                var that = this, idx, length, action = e ? e.action : '';\n                if (action === 'remove') {\n                    for (idx = 0, length = e.items.length; idx < length; idx++) {\n                        if (!e.items[idx].isNew || !e.items[idx].isNew()) {\n                            that._destroyed.push(e.items[idx]);\n                        }\n                    }\n                }\n                if (that.options.autoSync && (action === 'add' || action === 'remove' || action === 'itemchange')) {\n                    var handler = function (args) {\n                        if (args.action === 'sync') {\n                            that.unbind('change', handler);\n                            that._updateTotalForAction(action, e.items);\n                        }\n                    };\n                    that.first('change', handler);\n                    that.sync();\n                } else {\n                    that._updateTotalForAction(action, e ? e.items : []);\n                    that._process(that._data, e);\n                }\n            },\n            _calculateAggregates: function (data, options) {\n                options = options || {};\n                var query = new Query(data), aggregates = options.aggregate, filter = options.filter;\n                if (filter) {\n                    query = query.filter(filter);\n                }\n                return query.aggregate(aggregates);\n            },\n            _process: function (data, e) {\n                var that = this, options = {}, result;\n                if (that.options.serverPaging !== true) {\n                    options.skip = that._skip;\n                    options.take = that._take || that._pageSize;\n                    if (options.skip === undefined && that._page !== undefined && that._pageSize !== undefined) {\n                        options.skip = (that._page - 1) * that._pageSize;\n                    }\n                    if (that.options.useRanges) {\n                        options.skip = that.currentRangeStart();\n                    }\n                }\n                if (that.options.serverSorting !== true) {\n                    options.sort = that._sort;\n                }\n                if (that.options.serverFiltering !== true) {\n                    options.filter = that._filter;\n                }\n                if (that.options.serverGrouping !== true) {\n                    options.group = that._group;\n                }\n                if (that.options.serverAggregates !== true) {\n                    options.aggregate = that._aggregate;\n                }\n                if (that.options.serverGrouping) {\n                    that._clearEmptyGroups(data);\n                }\n                result = that._queryProcess(data, options);\n                if (that.options.serverAggregates !== true) {\n                    that._aggregateResult = that._calculateAggregates(result.dataToAggregate || data, options);\n                }\n                that.view(result.data);\n                that._setFilterTotal(result.total, false);\n                e = e || {};\n                e.items = e.items || that._view;\n                that.trigger(CHANGE, e);\n            },\n            _clearEmptyGroups: function (data) {\n                for (var idx = data.length - 1; idx >= 0; idx--) {\n                    var group = data[idx];\n                    if (group.hasSubgroups) {\n                        this._clearEmptyGroups(group.items);\n                    } else {\n                        if (group.items && !group.items.length) {\n                            splice.apply(group.parent(), [\n                                idx,\n                                1\n                            ]);\n                        }\n                    }\n                }\n            },\n            _queryProcess: function (data, options) {\n                if (this.options.inPlaceSort) {\n                    return Query.process(data, options, this.options.inPlaceSort);\n                } else {\n                    return Query.process(data, options);\n                }\n            },\n            _mergeState: function (options) {\n                var that = this;\n                if (options !== undefined) {\n                    that._pageSize = options.pageSize;\n                    that._page = options.page;\n                    that._sort = options.sort;\n                    that._filter = options.filter;\n                    that._group = options.group;\n                    that._aggregate = options.aggregate;\n                    that._skip = that._currentRangeStart = options.skip;\n                    that._take = options.take;\n                    if (that._skip === undefined) {\n                        that._skip = that._currentRangeStart = that.skip();\n                        options.skip = that.skip();\n                    }\n                    if (that._take === undefined && that._pageSize !== undefined) {\n                        that._take = that._pageSize;\n                        options.take = that._take;\n                    }\n                    if (options.sort) {\n                        that._sort = options.sort = normalizeSort(options.sort);\n                    }\n                    if (options.filter) {\n                        that._filter = options.filter = that.options.accentFoldingFiltering && !$.isEmptyObject(options.filter) ? $.extend({}, normalizeFilter(options.filter), { accentFoldingFiltering: that.options.accentFoldingFiltering }) : normalizeFilter(options.filter);\n                    }\n                    if (options.group) {\n                        that._group = options.group = normalizeGroup(options.group);\n                    }\n                    if (options.aggregate) {\n                        that._aggregate = options.aggregate = normalizeAggregate(options.aggregate);\n                    }\n                }\n                return options;\n            },\n            query: function (options) {\n                var result;\n                var remote = this.options.serverSorting || this.options.serverPaging || this.options.serverFiltering || this.options.serverGrouping || this.options.serverAggregates;\n                if (remote || (this._data === undefined || this._data.length === 0) && !this._destroyed.length) {\n                    if (this.options.endless) {\n                        var moreItemsCount = options.pageSize - this.pageSize();\n                        if (moreItemsCount > 0) {\n                            moreItemsCount = this.pageSize();\n                            options.page = options.pageSize / moreItemsCount;\n                            options.pageSize = moreItemsCount;\n                        } else {\n                            options.page = 1;\n                            this.options.endless = false;\n                        }\n                    }\n                    return this.read(this._mergeState(options));\n                }\n                var isPrevented = this.trigger(REQUESTSTART, { type: 'read' });\n                if (!isPrevented) {\n                    this.trigger(PROGRESS);\n                    result = this._queryProcess(this._data, this._mergeState(options));\n                    this._setFilterTotal(result.total, true);\n                    this._aggregateResult = this._calculateAggregates(result.dataToAggregate || this._data, options);\n                    this.view(result.data);\n                    this.trigger(REQUESTEND, { type: 'read' });\n                    this.trigger(CHANGE, { items: result.data });\n                }\n                return $.Deferred().resolve(isPrevented).promise();\n            },\n            _setFilterTotal: function (filterTotal, setDefaultValue) {\n                var that = this;\n                if (!that.options.serverFiltering) {\n                    if (filterTotal !== undefined) {\n                        that._total = filterTotal;\n                    } else if (setDefaultValue) {\n                        that._total = that._data.length;\n                    }\n                }\n            },\n            fetch: function (callback) {\n                var that = this;\n                var fn = function (isPrevented) {\n                    if (isPrevented !== true && isFunction(callback)) {\n                        callback.call(that);\n                    }\n                };\n                return this._query().done(fn);\n            },\n            _query: function (options) {\n                var that = this;\n                return that.query(extend({}, {\n                    page: that.page(),\n                    pageSize: that.pageSize(),\n                    sort: that.sort(),\n                    filter: that.filter(),\n                    group: that.group(),\n                    aggregate: that.aggregate()\n                }, options));\n            },\n            next: function (options) {\n                var that = this, page = that.page(), total = that.total();\n                options = options || {};\n                if (!page || total && page + 1 > that.totalPages()) {\n                    return;\n                }\n                that._skip = that._currentRangeStart = page * that.take();\n                page += 1;\n                options.page = page;\n                that._query(options);\n                return page;\n            },\n            prev: function (options) {\n                var that = this, page = that.page();\n                options = options || {};\n                if (!page || page === 1) {\n                    return;\n                }\n                that._skip = that._currentRangeStart = that._skip - that.take();\n                page -= 1;\n                options.page = page;\n                that._query(options);\n                return page;\n            },\n            page: function (val) {\n                var that = this, skip;\n                if (val !== undefined) {\n                    val = math.max(math.min(math.max(val, 1), that.totalPages()), 1);\n                    that._query(that._pageableQueryOptions({ page: val }));\n                    return;\n                }\n                skip = that.skip();\n                return skip !== undefined ? math.round((skip || 0) / (that.take() || 1)) + 1 : undefined;\n            },\n            pageSize: function (val) {\n                var that = this;\n                if (val !== undefined) {\n                    that._query(that._pageableQueryOptions({\n                        pageSize: val,\n                        page: 1\n                    }));\n                    return;\n                }\n                return that.take();\n            },\n            sort: function (val) {\n                var that = this;\n                if (val !== undefined) {\n                    that._query({ sort: val });\n                    return;\n                }\n                return that._sort;\n            },\n            filter: function (val) {\n                var that = this;\n                if (val === undefined) {\n                    return that._filter;\n                }\n                that.trigger('reset');\n                that._query({\n                    filter: val,\n                    page: 1\n                });\n            },\n            group: function (val) {\n                var that = this;\n                if (val !== undefined) {\n                    that._query({ group: val });\n                    return;\n                }\n                return that._group;\n            },\n            total: function () {\n                return parseInt(this._total || 0, 10);\n            },\n            aggregate: function (val) {\n                var that = this;\n                if (val !== undefined) {\n                    that._query({ aggregate: val });\n                    return;\n                }\n                return that._aggregate;\n            },\n            aggregates: function () {\n                var result = this._aggregateResult;\n                if (isEmptyObject(result)) {\n                    result = this._emptyAggregates(this.aggregate());\n                }\n                return result;\n            },\n            _emptyAggregates: function (aggregates) {\n                var result = {};\n                if (!isEmptyObject(aggregates)) {\n                    var aggregate = {};\n                    if (!isArray(aggregates)) {\n                        aggregates = [aggregates];\n                    }\n                    for (var idx = 0; idx < aggregates.length; idx++) {\n                        aggregate[aggregates[idx].aggregate] = 0;\n                        result[aggregates[idx].field] = aggregate;\n                    }\n                }\n                return result;\n            },\n            _pageableQueryOptions: function (options) {\n                return options;\n            },\n            _wrapInEmptyGroup: function (model) {\n                var groups = this.group(), parent, group, idx, length;\n                for (idx = groups.length - 1, length = 0; idx >= length; idx--) {\n                    group = groups[idx];\n                    parent = {\n                        value: model.get ? model.get(group.field) : model[group.field],\n                        field: group.field,\n                        items: parent ? [parent] : [model],\n                        hasSubgroups: !!parent,\n                        aggregates: this._emptyAggregates(group.aggregates)\n                    };\n                }\n                return parent;\n            },\n            totalPages: function () {\n                var that = this, pageSize = that.pageSize() || that.total();\n                return math.ceil((that.total() || 0) / pageSize);\n            },\n            inRange: function (skip, take) {\n                var that = this, end = math.min(skip + take, that.total());\n                if (!that.options.serverPaging && that._data.length > 0) {\n                    return true;\n                }\n                return that._findRange(skip, end).length > 0;\n            },\n            lastRange: function () {\n                var ranges = this._ranges;\n                return ranges[ranges.length - 1] || {\n                    start: 0,\n                    end: 0,\n                    data: []\n                };\n            },\n            firstItemUid: function () {\n                var ranges = this._ranges;\n                return ranges.length && ranges[0].data.length && ranges[0].data[0].uid;\n            },\n            enableRequestsInProgress: function () {\n                this._skipRequestsInProgress = false;\n            },\n            _timeStamp: function () {\n                return new Date().getTime();\n            },\n            range: function (skip, take, callback) {\n                this._currentRequestTimeStamp = this._timeStamp();\n                this._skipRequestsInProgress = true;\n                skip = math.min(skip || 0, this.total());\n                callback = isFunction(callback) ? callback : noop;\n                var that = this, pageSkip = math.max(math.floor(skip / take), 0) * take, size = math.min(pageSkip + take, that.total()), data;\n                data = that._findRange(skip, math.min(skip + take, that.total()));\n                if (data.length || that.total() === 0) {\n                    that._processRangeData(data, skip, take, pageSkip, size);\n                    callback();\n                    return;\n                }\n                if (take !== undefined) {\n                    if (!that._rangeExists(pageSkip, size)) {\n                        that.prefetch(pageSkip, take, function () {\n                            if (skip > pageSkip && size < that.total() && !that._rangeExists(size, math.min(size + take, that.total()))) {\n                                that.prefetch(size, take, function () {\n                                    that.range(skip, take, callback);\n                                });\n                            } else {\n                                that.range(skip, take, callback);\n                            }\n                        });\n                    } else if (pageSkip < skip) {\n                        that.prefetch(size, take, function () {\n                            that.range(skip, take, callback);\n                        });\n                    }\n                }\n            },\n            _findRange: function (start, end) {\n                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;\n                for (skipIdx = 0, length = ranges.length; skipIdx < length; skipIdx++) {\n                    range = ranges[skipIdx];\n                    if (start >= range.start && start <= range.end) {\n                        count = 0;\n                        for (takeIdx = skipIdx; takeIdx < length; takeIdx++) {\n                            range = ranges[takeIdx];\n                            flatData = that._flatData(range.data, true);\n                            if (flatData.length && start + count >= range.start) {\n                                rangeData = range.data;\n                                rangeEnd = range.end;\n                                if (!remote) {\n                                    if (options.inPlaceSort) {\n                                        processed = that._queryProcess(range.data, { filter: that.filter() });\n                                    } else {\n                                        var sort = normalizeGroupWithoutCompare(that.group() || []).concat(normalizeSort(that.sort() || []));\n                                        processed = that._queryProcess(range.data, {\n                                            sort: sort,\n                                            filter: that.filter()\n                                        });\n                                    }\n                                    flatData = rangeData = processed.data;\n                                    if (processed.total !== undefined) {\n                                        rangeEnd = processed.total;\n                                    }\n                                }\n                                startIndex = 0;\n                                if (start + count > range.start) {\n                                    startIndex = start + count - range.start;\n                                }\n                                endIndex = flatData.length;\n                                if (rangeEnd > end) {\n                                    endIndex = endIndex - (rangeEnd - end);\n                                }\n                                count += endIndex - startIndex;\n                                data = that._mergeGroups(data, rangeData, startIndex, endIndex);\n                                if (end <= range.end && count == end - start) {\n                                    return data;\n                                }\n                            }\n                        }\n                        break;\n                    }\n                }\n                return [];\n            },\n            _mergeGroups: function (data, range, skip, take) {\n                if (this._isServerGrouped()) {\n                    var temp = range.toJSON(), prevGroup;\n                    if (data.length) {\n                        prevGroup = data[data.length - 1];\n                    }\n                    mergeGroups(prevGroup, temp, skip, take);\n                    return data.concat(temp);\n                }\n                return data.concat(range.slice(skip, take));\n            },\n            _processRangeData: function (data, skip, take, pageSkip, size) {\n                var that = this;\n                that._pending = undefined;\n                that._skip = skip > that.skip() ? math.min(size, (that.totalPages() - 1) * that.take()) : pageSkip;\n                that._currentRangeStart = skip;\n                that._take = take;\n                var paging = that.options.serverPaging;\n                var sorting = that.options.serverSorting;\n                var filtering = that.options.serverFiltering;\n                var aggregates = that.options.serverAggregates;\n                try {\n                    that.options.serverPaging = true;\n                    if (!that._isServerGrouped() && !(that.group() && that.group().length)) {\n                        that.options.serverSorting = true;\n                    }\n                    that.options.serverFiltering = true;\n                    that.options.serverPaging = true;\n                    that.options.serverAggregates = true;\n                    if (paging) {\n                        that._detachObservableParents();\n                        that._data = data = that._observe(data);\n                    }\n                    that._process(data);\n                } finally {\n                    that.options.serverPaging = paging;\n                    that.options.serverSorting = sorting;\n                    that.options.serverFiltering = filtering;\n                    that.options.serverAggregates = aggregates;\n                }\n            },\n            skip: function () {\n                var that = this;\n                if (that._skip === undefined) {\n                    return that._page !== undefined ? (that._page - 1) * (that.take() || 1) : undefined;\n                }\n                return that._skip;\n            },\n            currentRangeStart: function () {\n                return this._currentRangeStart || 0;\n            },\n            take: function () {\n                return this._take || this._pageSize;\n            },\n            _prefetchSuccessHandler: function (skip, size, callback, force) {\n                var that = this;\n                var timestamp = that._timeStamp();\n                return function (data) {\n                    var found = false, range = {\n                            start: skip,\n                            end: size,\n                            data: [],\n                            timestamp: that._timeStamp()\n                        }, idx, length, temp;\n                    that._dequeueRequest();\n                    that.trigger(REQUESTEND, {\n                        response: data,\n                        type: 'read'\n                    });\n                    data = that.reader.parse(data);\n                    temp = that._readData(data);\n                    if (temp.length) {\n                        for (idx = 0, length = that._ranges.length; idx < length; idx++) {\n                            if (that._ranges[idx].start === skip) {\n                                found = true;\n                                range = that._ranges[idx];\n                                range.pristineData = temp;\n                                range.data = that._observe(temp);\n                                range.end = range.start + that._flatData(range.data, true).length;\n                                that._sortRanges();\n                                break;\n                            }\n                        }\n                        if (!found) {\n                            that._addRange(that._observe(temp), skip);\n                        }\n                    }\n                    that._total = that.reader.total(data);\n                    if (force || (timestamp >= that._currentRequestTimeStamp || !that._skipRequestsInProgress)) {\n                        if (callback && temp.length) {\n                            callback();\n                        } else {\n                            that.trigger(CHANGE, {});\n                        }\n                    }\n                };\n            },\n            prefetch: function (skip, take, callback) {\n                var that = this, size = math.min(skip + take, that.total()), options = {\n                        take: take,\n                        skip: skip,\n                        page: skip / take + 1,\n                        pageSize: take,\n                        sort: that._sort,\n                        filter: that._filter,\n                        group: that._group,\n                        aggregate: that._aggregate\n                    };\n                if (!that._rangeExists(skip, size)) {\n                    clearTimeout(that._timeout);\n                    that._timeout = setTimeout(function () {\n                        that._queueRequest(options, function () {\n                            if (!that.trigger(REQUESTSTART, { type: 'read' })) {\n                                that.transport.read({\n                                    data: that._params(options),\n                                    success: that._prefetchSuccessHandler(skip, size, callback),\n                                    error: function () {\n                                        var args = slice.call(arguments);\n                                        that.error.apply(that, args);\n                                    }\n                                });\n                            } else {\n                                that._dequeueRequest();\n                            }\n                        });\n                    }, 100);\n                } else if (callback) {\n                    callback();\n                }\n            },\n            _multiplePrefetch: function (skip, take, callback) {\n                var that = this, size = math.min(skip + take, that.total()), options = {\n                        take: take,\n                        skip: skip,\n                        page: skip / take + 1,\n                        pageSize: take,\n                        sort: that._sort,\n                        filter: that._filter,\n                        group: that._group,\n                        aggregate: that._aggregate\n                    };\n                if (!that._rangeExists(skip, size)) {\n                    if (!that.trigger(REQUESTSTART, { type: 'read' })) {\n                        that.transport.read({\n                            data: that._params(options),\n                            success: that._prefetchSuccessHandler(skip, size, callback, true)\n                        });\n                    }\n                } else if (callback) {\n                    callback();\n                }\n            },\n            _rangeExists: function (start, end) {\n                var that = this, ranges = that._ranges, idx, length;\n                for (idx = 0, length = ranges.length; idx < length; idx++) {\n                    if (ranges[idx].start <= start && ranges[idx].end >= end) {\n                        return true;\n                    }\n                }\n                return false;\n            },\n            _getCurrentRangeSpan: function () {\n                var that = this;\n                var ranges = that._ranges;\n                var start = that.currentRangeStart();\n                var end = start + (that.take() || 0);\n                var rangeSpan = [];\n                var range;\n                var idx;\n                var length = ranges.length;\n                for (idx = 0; idx < length; idx++) {\n                    range = ranges[idx];\n                    if (range.start <= start && range.end >= start || range.start >= start && range.start <= end) {\n                        rangeSpan.push(range);\n                    }\n                }\n                return rangeSpan;\n            },\n            _removeModelFromRanges: function (model) {\n                var that = this;\n                var range;\n                for (var idx = 0, length = this._ranges.length; idx < length; idx++) {\n                    range = this._ranges[idx];\n                    that._removeModelFromRange(range, model);\n                }\n                that._updateRangesLength();\n            },\n            _removeModelFromRange: function (range, model) {\n                this._eachItem(range.data, function (data) {\n                    for (var idx = 0; idx < data.length; idx++) {\n                        var dataItem = data[idx];\n                        if (dataItem.uid && dataItem.uid == model.uid) {\n                            [].splice.call(data, idx, 1);\n                            break;\n                        }\n                    }\n                });\n            },\n            _insertModelInRange: function (index, model) {\n                var that = this;\n                var ranges = that._ranges || [];\n                var rangesLength = ranges.length;\n                var range;\n                var i;\n                for (i = 0; i < rangesLength; i++) {\n                    range = ranges[i];\n                    if (range.start <= index && range.end >= index) {\n                        if (!that._getByUid(model.uid, range.data)) {\n                            if (that._isServerGrouped()) {\n                                range.data.splice(index, 0, that._wrapInEmptyGroup(model));\n                            } else {\n                                range.data.splice(index, 0, model);\n                            }\n                        }\n                        break;\n                    }\n                }\n                that._updateRangesLength();\n            },\n            _updateRangesLength: function () {\n                var that = this;\n                var ranges = that._ranges || [];\n                var rangesLength = ranges.length;\n                var mismatchFound = false;\n                var mismatchLength = 0;\n                var lengthDifference = 0;\n                var range;\n                var i;\n                for (i = 0; i < rangesLength; i++) {\n                    range = ranges[i];\n                    lengthDifference = that._flatData(range.data, true).length - math.abs(range.end - range.start);\n                    if (!mismatchFound && lengthDifference !== 0) {\n                        mismatchFound = true;\n                        mismatchLength = lengthDifference;\n                        range.end += mismatchLength;\n                        continue;\n                    }\n                    if (mismatchFound) {\n                        range.start += mismatchLength;\n                        range.end += mismatchLength;\n                    }\n                }\n            }\n        });\n        var Transport = {};\n        Transport.create = function (options, data, dataSource) {\n            var transport, transportOptions = options.transport ? $.extend({}, options.transport) : null;\n            if (transportOptions) {\n                transportOptions.read = typeof transportOptions.read === STRING ? { url: transportOptions.read } : transportOptions.read;\n                if (options.type === 'jsdo') {\n                    transportOptions.dataSource = dataSource;\n                }\n                if (options.type) {\n                    kendo.data.transports = kendo.data.transports || {};\n                    kendo.data.schemas = kendo.data.schemas || {};\n                    if (!kendo.data.transports[options.type]) {\n                        kendo.logToConsole('Unknown DataSource transport type \\'' + options.type + '\\'.\\nVerify that registration scripts for this type are included after Kendo UI on the page.', 'warn');\n                    } else if (!isPlainObject(kendo.data.transports[options.type])) {\n                        transport = new kendo.data.transports[options.type](extend(transportOptions, { data: data }));\n                    } else {\n                        transportOptions = extend(true, {}, kendo.data.transports[options.type], transportOptions);\n                    }\n                    options.schema = extend(true, {}, kendo.data.schemas[options.type], options.schema);\n                }\n                if (!transport) {\n                    transport = isFunction(transportOptions.read) ? transportOptions : new RemoteTransport(transportOptions);\n                }\n            } else {\n                transport = new LocalTransport({ data: options.data || [] });\n            }\n            return transport;\n        };\n        DataSource.create = function (options) {\n            if (isArray(options) || options instanceof ObservableArray) {\n                options = { data: options };\n            }\n            var dataSource = options || {}, data = dataSource.data, fields = dataSource.fields, table = dataSource.table, select = dataSource.select, idx, length, model = {}, field;\n            if (!data && fields && !dataSource.transport) {\n                if (table) {\n                    data = inferTable(table, fields);\n                } else if (select) {\n                    data = inferSelect(select, fields);\n                    if (dataSource.group === undefined && data[0] && data[0].optgroup !== undefined) {\n                        dataSource.group = 'optgroup';\n                    }\n                }\n            }\n            if (kendo.data.Model && fields && (!dataSource.schema || !dataSource.schema.model)) {\n                for (idx = 0, length = fields.length; idx < length; idx++) {\n                    field = fields[idx];\n                    if (field.type) {\n                        model[field.field] = field;\n                    }\n                }\n                if (!isEmptyObject(model)) {\n                    dataSource.schema = extend(true, dataSource.schema, { model: { fields: model } });\n                }\n            }\n            dataSource.data = data;\n            select = null;\n            dataSource.select = null;\n            table = null;\n            dataSource.table = null;\n            return dataSource instanceof DataSource ? dataSource : new DataSource(dataSource);\n        };\n        function inferSelect(select, fields) {\n            select = $(select)[0];\n            var options = select.options;\n            var firstField = fields[0];\n            var secondField = fields[1];\n            var data = [];\n            var idx, length;\n            var optgroup;\n            var option;\n            var record;\n            var value;\n            for (idx = 0, length = options.length; idx < length; idx++) {\n                record = {};\n                option = options[idx];\n                optgroup = option.parentNode;\n                if (optgroup === select) {\n                    optgroup = null;\n                }\n                if (option.disabled || optgroup && optgroup.disabled) {\n                    continue;\n                }\n                if (optgroup) {\n                    record.optgroup = optgroup.label;\n                }\n                record[firstField.field] = option.text;\n                value = option.attributes.value;\n                if (value && value.specified) {\n                    value = option.value;\n                } else {\n                    value = option.text;\n                }\n                record[secondField.field] = value;\n                data.push(record);\n            }\n            return data;\n        }\n        function inferTable(table, fields) {\n            var tbody = $(table)[0].tBodies[0], rows = tbody ? tbody.rows : [], idx, length, fieldIndex, fieldCount = fields.length, data = [], cells, record, cell, empty;\n            for (idx = 0, length = rows.length; idx < length; idx++) {\n                record = {};\n                empty = true;\n                cells = rows[idx].cells;\n                for (fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {\n                    cell = cells[fieldIndex];\n                    if (cell.nodeName.toLowerCase() !== 'th') {\n                        empty = false;\n                        record[fields[fieldIndex].field] = cell.innerHTML;\n                    }\n                }\n                if (!empty) {\n                    data.push(record);\n                }\n            }\n            return data;\n        }\n        var Node = Model.define({\n            idField: 'id',\n            init: function (value) {\n                var that = this, hasChildren = that.hasChildren || value && value.hasChildren, childrenField = 'items', childrenOptions = {};\n                kendo.data.Model.fn.init.call(that, value);\n                if (typeof that.children === STRING) {\n                    childrenField = that.children;\n                }\n                childrenOptions = {\n                    schema: {\n                        data: childrenField,\n                        model: {\n                            hasChildren: hasChildren,\n                            id: that.idField,\n                            fields: that.fields\n                        }\n                    }\n                };\n                if (typeof that.children !== STRING) {\n                    extend(childrenOptions, that.children);\n                }\n                childrenOptions.data = value;\n                if (!hasChildren) {\n                    hasChildren = childrenOptions.schema.data;\n                }\n                if (typeof hasChildren === STRING) {\n                    hasChildren = kendo.getter(hasChildren);\n                }\n                if (isFunction(hasChildren)) {\n                    var hasChildrenObject = hasChildren.call(that, that);\n                    if (hasChildrenObject && hasChildrenObject.length === 0) {\n                        that.hasChildren = false;\n                    } else {\n                        that.hasChildren = !!hasChildrenObject;\n                    }\n                }\n                that._childrenOptions = childrenOptions;\n                if (that.hasChildren) {\n                    that._initChildren();\n                }\n                that._loaded = !!(value && value._loaded);\n            },\n            _initChildren: function () {\n                var that = this;\n                var children, transport, parameterMap;\n                if (!(that.children instanceof HierarchicalDataSource)) {\n                    children = that.children = new HierarchicalDataSource(that._childrenOptions);\n                    transport = children.transport;\n                    parameterMap = transport.parameterMap;\n                    transport.parameterMap = function (data, type) {\n                        data[that.idField || 'id'] = that.id;\n                        if (parameterMap) {\n                            data = parameterMap(data, type);\n                        }\n                        return data;\n                    };\n                    children.parent = function () {\n                        return that;\n                    };\n                    children.bind(CHANGE, function (e) {\n                        e.node = e.node || that;\n                        that.trigger(CHANGE, e);\n                    });\n                    children.bind(ERROR, function (e) {\n                        var collection = that.parent();\n                        if (collection) {\n                            e.node = e.node || that;\n                            collection.trigger(ERROR, e);\n                        }\n                    });\n                    that._updateChildrenField();\n                }\n            },\n            append: function (model) {\n                this._initChildren();\n                this.loaded(true);\n                this.children.add(model);\n            },\n            hasChildren: false,\n            level: function () {\n                var parentNode = this.parentNode(), level = 0;\n                while (parentNode && parentNode.parentNode) {\n                    level++;\n                    parentNode = parentNode.parentNode ? parentNode.parentNode() : null;\n                }\n                return level;\n            },\n            _updateChildrenField: function () {\n                var fieldName = this._childrenOptions.schema.data;\n                this[fieldName || 'items'] = this.children.data();\n            },\n            _childrenLoaded: function () {\n                this._loaded = true;\n                this._updateChildrenField();\n            },\n            load: function () {\n                var options = {};\n                var method = '_query';\n                var children, promise;\n                if (this.hasChildren) {\n                    this._initChildren();\n                    children = this.children;\n                    options[this.idField || 'id'] = this.id;\n                    if (!this._loaded) {\n                        children._data = undefined;\n                        method = 'read';\n                    }\n                    children.one(CHANGE, proxy(this._childrenLoaded, this));\n                    if (this._matchFilter) {\n                        options.filter = {\n                            field: '_matchFilter',\n                            operator: 'eq',\n                            value: true\n                        };\n                    }\n                    promise = children[method](options);\n                } else {\n                    this.loaded(true);\n                }\n                return promise || $.Deferred().resolve().promise();\n            },\n            parentNode: function () {\n                var array = this.parent();\n                return array.parent();\n            },\n            loaded: function (value) {\n                if (value !== undefined) {\n                    this._loaded = value;\n                } else {\n                    return this._loaded;\n                }\n            },\n            shouldSerialize: function (field) {\n                return Model.fn.shouldSerialize.call(this, field) && field !== 'children' && field !== '_loaded' && field !== 'hasChildren' && field !== '_childrenOptions';\n            }\n        });\n        function dataMethod(name) {\n            return function () {\n                var data = this._data, result = DataSource.fn[name].apply(this, slice.call(arguments));\n                if (this._data != data) {\n                    this._attachBubbleHandlers();\n                }\n                return result;\n            };\n        }\n        var HierarchicalDataSource = DataSource.extend({\n            init: function (options) {\n                var node = Node.define({ children: options });\n                if (options.filter && !options.serverFiltering) {\n                    this._hierarchicalFilter = options.filter;\n                    options.filter = null;\n                }\n                DataSource.fn.init.call(this, extend(true, {}, {\n                    schema: {\n                        modelBase: node,\n                        model: node\n                    }\n                }, options));\n                this._attachBubbleHandlers();\n            },\n            _attachBubbleHandlers: function () {\n                var that = this;\n                that._data.bind(ERROR, function (e) {\n                    that.trigger(ERROR, e);\n                });\n            },\n            read: function (data) {\n                var result = DataSource.fn.read.call(this, data);\n                if (this._hierarchicalFilter) {\n                    if (this._data && this._data.length > 0) {\n                        this.filter(this._hierarchicalFilter);\n                    } else {\n                        this.options.filter = this._hierarchicalFilter;\n                        this._filter = normalizeFilter(this.options.filter);\n                        this._hierarchicalFilter = null;\n                    }\n                }\n                return result;\n            },\n            remove: function (node) {\n                var parentNode = node.parentNode(), dataSource = this, result;\n                if (parentNode && parentNode._initChildren) {\n                    dataSource = parentNode.children;\n                }\n                result = DataSource.fn.remove.call(dataSource, node);\n                if (parentNode && !dataSource.data().length) {\n                    parentNode.hasChildren = false;\n                }\n                return result;\n            },\n            success: dataMethod('success'),\n            data: dataMethod('data'),\n            insert: function (index, model) {\n                var parentNode = this.parent();\n                if (parentNode && parentNode._initChildren) {\n                    parentNode.hasChildren = true;\n                    parentNode._initChildren();\n                }\n                return DataSource.fn.insert.call(this, index, model);\n            },\n            filter: function (val) {\n                if (val === undefined) {\n                    return this._filter;\n                }\n                if (!this.options.serverFiltering && this._markHierarchicalQuery(val)) {\n                    val = {\n                        logic: 'or',\n                        filters: [\n                            val,\n                            {\n                                field: '_matchFilter',\n                                operator: 'equals',\n                                value: true\n                            }\n                        ]\n                    };\n                }\n                this.trigger('reset');\n                this._query({\n                    filter: val,\n                    page: 1\n                });\n            },\n            _markHierarchicalQuery: function (expressions) {\n                var compiled;\n                var predicate;\n                var fields;\n                var operators;\n                var filter;\n                var accentFoldingFiltering = this.options.accentFoldingFiltering;\n                expressions = accentFoldingFiltering ? $.extend({}, normalizeFilter(expressions), { accentFoldingFiltering: accentFoldingFiltering }) : normalizeFilter(expressions);\n                if (!expressions || expressions.filters.length === 0) {\n                    this._updateHierarchicalFilter(function () {\n                        return true;\n                    });\n                    return false;\n                }\n                compiled = Query.filterExpr(expressions);\n                fields = compiled.fields;\n                operators = compiled.operators;\n                predicate = filter = new Function('d, __f, __o', 'return ' + compiled.expression);\n                if (fields.length || operators.length) {\n                    filter = function (d) {\n                        return predicate(d, fields, operators);\n                    };\n                }\n                this._updateHierarchicalFilter(filter);\n                return true;\n            },\n            _updateHierarchicalFilter: function (filter) {\n                var current;\n                var data = this._data;\n                var result = false;\n                for (var idx = 0; idx < data.length; idx++) {\n                    current = data[idx];\n                    if (current.hasChildren) {\n                        current._matchFilter = current.children._updateHierarchicalFilter(filter);\n                        if (!current._matchFilter) {\n                            current._matchFilter = filter(current);\n                        }\n                    } else {\n                        current._matchFilter = filter(current);\n                    }\n                    if (current._matchFilter) {\n                        result = true;\n                    }\n                }\n                return result;\n            },\n            _find: function (method, value) {\n                var idx, length, node, children;\n                var data = this._data;\n                if (!data) {\n                    return;\n                }\n                node = DataSource.fn[method].call(this, value);\n                if (node) {\n                    return node;\n                }\n                data = this._flatData(this._data);\n                for (idx = 0, length = data.length; idx < length; idx++) {\n                    children = data[idx].children;\n                    if (!(children instanceof HierarchicalDataSource)) {\n                        continue;\n                    }\n                    node = children[method](value);\n                    if (node) {\n                        return node;\n                    }\n                }\n            },\n            get: function (id) {\n                return this._find('get', id);\n            },\n            getByUid: function (uid) {\n                return this._find('getByUid', uid);\n            }\n        });\n        function inferList(list, fields) {\n            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;\n            function elements(collection, tagName) {\n                return collection.filter(tagName).add(collection.find(tagName));\n            }\n            for (idx = 0, length = items.length; idx < length; idx++) {\n                record = { _loaded: true };\n                item = items.eq(idx);\n                textChild = item[0].firstChild;\n                children = item.children();\n                list = children.filter('ul');\n                children = children.filter(':not(ul)');\n                id = item.attr('data-id');\n                if (id) {\n                    record.id = id;\n                }\n                if (textChild) {\n                    record[textField] = textChild.nodeType == 3 ? textChild.nodeValue : children.text();\n                }\n                if (urlField) {\n                    record[urlField] = elements(children, 'a').attr('href');\n                }\n                if (imageUrlField) {\n                    record[imageUrlField] = elements(children, 'img').attr('src');\n                }\n                if (spriteCssClassField) {\n                    className = elements(children, '.k-sprite').prop('className');\n                    record[spriteCssClassField] = className && $.trim(className.replace('k-sprite', ''));\n                }\n                if (list.length) {\n                    record.items = inferList(list.eq(0), fields);\n                }\n                if (item.attr('data-hasChildren') == 'true') {\n                    record.hasChildren = true;\n                }\n                data.push(record);\n            }\n            return data;\n        }\n        HierarchicalDataSource.create = function (options) {\n            options = options && options.push ? { data: options } : options;\n            var dataSource = options || {}, data = dataSource.data, fields = dataSource.fields, list = dataSource.list;\n            if (data && data._dataSource) {\n                return data._dataSource;\n            }\n            if (!data && fields && !dataSource.transport) {\n                if (list) {\n                    data = inferList(list, fields);\n                }\n            }\n            dataSource.data = data;\n            return dataSource instanceof HierarchicalDataSource ? dataSource : new HierarchicalDataSource(dataSource);\n        };\n        var Buffer = kendo.Observable.extend({\n            init: function (dataSource, viewSize, disablePrefetch) {\n                kendo.Observable.fn.init.call(this);\n                this._prefetching = false;\n                this.dataSource = dataSource;\n                this.prefetch = !disablePrefetch;\n                var buffer = this;\n                dataSource.bind('change', function () {\n                    buffer._change();\n                });\n                dataSource.bind('reset', function () {\n                    buffer._reset();\n                });\n                this._syncWithDataSource();\n                this.setViewSize(viewSize);\n            },\n            setViewSize: function (viewSize) {\n                this.viewSize = viewSize;\n                this._recalculate();\n            },\n            at: function (index) {\n                var pageSize = this.pageSize, itemPresent = true;\n                if (index >= this.total()) {\n                    this.trigger('endreached', { index: index });\n                    return null;\n                }\n                if (!this.useRanges) {\n                    return this.dataSource.view()[index];\n                }\n                if (this.useRanges) {\n                    if (index < this.dataOffset || index >= this.skip + pageSize) {\n                        itemPresent = this.range(Math.floor(index / pageSize) * pageSize);\n                    }\n                    if (index === this.prefetchThreshold) {\n                        this._prefetch();\n                    }\n                    if (index === this.midPageThreshold) {\n                        this.range(this.nextMidRange, true);\n                    } else if (index === this.nextPageThreshold) {\n                        this.range(this.nextFullRange);\n                    } else if (index === this.pullBackThreshold) {\n                        if (this.offset === this.skip) {\n                            this.range(this.previousMidRange);\n                        } else {\n                            this.range(this.previousFullRange);\n                        }\n                    }\n                    if (itemPresent) {\n                        return this.dataSource.at(index - this.dataOffset);\n                    } else {\n                        this.trigger('endreached', { index: index });\n                        return null;\n                    }\n                }\n            },\n            indexOf: function (item) {\n                return this.dataSource.data().indexOf(item) + this.dataOffset;\n            },\n            total: function () {\n                return parseInt(this.dataSource.total(), 10);\n            },\n            next: function () {\n                var buffer = this, pageSize = buffer.pageSize, offset = buffer.skip - buffer.viewSize + pageSize, pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize;\n                this.offset = offset;\n                this.dataSource.prefetch(pageSkip, pageSize, function () {\n                    buffer._goToRange(offset, true);\n                });\n            },\n            range: function (offset, nextRange) {\n                if (this.offset === offset) {\n                    return true;\n                }\n                var buffer = this, pageSize = this.pageSize, pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize, dataSource = this.dataSource;\n                if (nextRange) {\n                    pageSkip += pageSize;\n                }\n                if (dataSource.inRange(offset, pageSize)) {\n                    this.offset = offset;\n                    this._recalculate();\n                    this._goToRange(offset);\n                    return true;\n                } else if (this.prefetch) {\n                    dataSource.prefetch(pageSkip, pageSize, function () {\n                        buffer.offset = offset;\n                        buffer._recalculate();\n                        buffer._goToRange(offset, true);\n                    });\n                    return false;\n                }\n                return true;\n            },\n            syncDataSource: function () {\n                var offset = this.offset;\n                this.offset = null;\n                this.range(offset);\n            },\n            destroy: function () {\n                this.unbind();\n            },\n            _prefetch: function () {\n                var buffer = this, pageSize = this.pageSize, prefetchOffset = this.skip + pageSize, dataSource = this.dataSource;\n                if (!dataSource.inRange(prefetchOffset, pageSize) && !this._prefetching && this.prefetch) {\n                    this._prefetching = true;\n                    this.trigger('prefetching', {\n                        skip: prefetchOffset,\n                        take: pageSize\n                    });\n                    dataSource.prefetch(prefetchOffset, pageSize, function () {\n                        buffer._prefetching = false;\n                        buffer.trigger('prefetched', {\n                            skip: prefetchOffset,\n                            take: pageSize\n                        });\n                    });\n                }\n            },\n            _goToRange: function (offset, expanding) {\n                if (this.offset !== offset) {\n                    return;\n                }\n                this.dataOffset = offset;\n                this._expanding = expanding;\n                this.dataSource.range(offset, this.pageSize);\n                this.dataSource.enableRequestsInProgress();\n            },\n            _reset: function () {\n                this._syncPending = true;\n            },\n            _change: function () {\n                var dataSource = this.dataSource;\n                this.length = this.useRanges ? dataSource.lastRange().end : dataSource.view().length;\n                if (this._syncPending) {\n                    this._syncWithDataSource();\n                    this._recalculate();\n                    this._syncPending = false;\n                    this.trigger('reset', { offset: this.offset });\n                }\n                this.trigger('resize');\n                if (this._expanding) {\n                    this.trigger('expand');\n                }\n                delete this._expanding;\n            },\n            _syncWithDataSource: function () {\n                var dataSource = this.dataSource;\n                this._firstItemUid = dataSource.firstItemUid();\n                this.dataOffset = this.offset = dataSource.skip() || 0;\n                this.pageSize = dataSource.pageSize();\n                this.useRanges = dataSource.options.serverPaging;\n            },\n            _recalculate: function () {\n                var pageSize = this.pageSize, offset = this.offset, viewSize = this.viewSize, skip = Math.ceil(offset / pageSize) * pageSize;\n                this.skip = skip;\n                this.midPageThreshold = skip + pageSize - 1;\n                this.nextPageThreshold = skip + viewSize - 1;\n                this.prefetchThreshold = skip + Math.floor(pageSize / 3 * 2);\n                this.pullBackThreshold = this.offset - 1;\n                this.nextMidRange = skip + pageSize - viewSize;\n                this.nextFullRange = skip;\n                this.previousMidRange = offset - viewSize;\n                this.previousFullRange = skip - pageSize;\n            }\n        });\n        var BatchBuffer = kendo.Observable.extend({\n            init: function (dataSource, batchSize) {\n                var batchBuffer = this;\n                kendo.Observable.fn.init.call(batchBuffer);\n                this.dataSource = dataSource;\n                this.batchSize = batchSize;\n                this._total = 0;\n                this.buffer = new Buffer(dataSource, batchSize * 3);\n                this.buffer.bind({\n                    'endreached': function (e) {\n                        batchBuffer.trigger('endreached', { index: e.index });\n                    },\n                    'prefetching': function (e) {\n                        batchBuffer.trigger('prefetching', {\n                            skip: e.skip,\n                            take: e.take\n                        });\n                    },\n                    'prefetched': function (e) {\n                        batchBuffer.trigger('prefetched', {\n                            skip: e.skip,\n                            take: e.take\n                        });\n                    },\n                    'reset': function () {\n                        batchBuffer._total = 0;\n                        batchBuffer.trigger('reset');\n                    },\n                    'resize': function () {\n                        batchBuffer._total = Math.ceil(this.length / batchBuffer.batchSize);\n                        batchBuffer.trigger('resize', {\n                            total: batchBuffer.total(),\n                            offset: this.offset\n                        });\n                    }\n                });\n            },\n            syncDataSource: function () {\n                this.buffer.syncDataSource();\n            },\n            at: function (index) {\n                var buffer = this.buffer, skip = index * this.batchSize, take = this.batchSize, view = [], item;\n                if (buffer.offset > skip) {\n                    buffer.at(buffer.offset - 1);\n                }\n                for (var i = 0; i < take; i++) {\n                    item = buffer.at(skip + i);\n                    if (item === null) {\n                        break;\n                    }\n                    view.push(item);\n                }\n                return view;\n            },\n            total: function () {\n                return this._total;\n            },\n            destroy: function () {\n                this.buffer.destroy();\n                this.unbind();\n            }\n        });\n        extend(true, kendo.data, {\n            readers: { json: DataReader },\n            Query: Query,\n            DataSource: DataSource,\n            HierarchicalDataSource: HierarchicalDataSource,\n            Node: Node,\n            ObservableObject: ObservableObject,\n            ObservableArray: ObservableArray,\n            LazyObservableArray: LazyObservableArray,\n            LocalTransport: LocalTransport,\n            RemoteTransport: RemoteTransport,\n            Cache: Cache,\n            DataReader: DataReader,\n            Model: Model,\n            Buffer: Buffer,\n            BatchBuffer: BatchBuffer\n        });\n    }(window.kendo.jQuery));\n    return window.kendo;\n}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {\n    (a3 || a2)();\n}));"]}