/** * Kendo UI v2016.1.420 (http://www.telerik.com/kendo-ui) * Copyright 2016 Telerik AD. All rights reserved. * * Kendo UI commercial licenses may be obtained at * http://www.telerik.com/purchase/license-agreement/kendo-ui-complete * If you do not own a commercial license, this file shall be governed by the trial license terms. */ (function (f, define) { define('kendo.core', ['jquery'], f); }(function () { var __meta__ = { id: 'core', name: 'Core', category: 'framework', description: 'The core of the Kendo framework.' }; (function ($, window, undefined) { var kendo = window.kendo = window.kendo || { cultures: {} }, extend = $.extend, each = $.each, isArray = $.isArray, proxy = $.proxy, noop = $.noop, math = Math, Template, JSON = window.JSON || {}, support = {}, percentRegExp = /%/, formatRegExp = /\{(\d+)(:[^\}]+)?\}/g, boxShadowRegExp = /(\d+(?:\.?)\d*)px\s*(\d+(?:\.?)\d*)px\s*(\d+(?:\.?)\d*)px\s*(\d+)?/i, numberRegExp = /^(\+|-?)\d+(\.?)\d*$/, FUNCTION = 'function', STRING = 'string', NUMBER = 'number', OBJECT = 'object', NULL = 'null', BOOLEAN = 'boolean', UNDEFINED = 'undefined', getterCache = {}, setterCache = {}, slice = [].slice; kendo.version = '2016.1.420'.replace(/^\s+|\s+$/g, ''); function Class() { } Class.extend = function (proto) { var base = function () { }, member, that = this, subclass = proto && proto.init ? proto.init : function () { that.apply(this, arguments); }, fn; base.prototype = that.prototype; fn = subclass.fn = subclass.prototype = new base(); for (member in proto) { if (proto[member] != null && proto[member].constructor === Object) { fn[member] = extend(true, {}, base.prototype[member], proto[member]); } else { fn[member] = proto[member]; } } fn.constructor = subclass; subclass.extend = that.extend; return subclass; }; Class.prototype._initOptions = function (options) { this.options = deepExtend({}, this.options, options); }; var isFunction = kendo.isFunction = function (fn) { return typeof fn === 'function'; }; var preventDefault = function () { this._defaultPrevented = true; }; var isDefaultPrevented = function () { return this._defaultPrevented === true; }; var Observable = Class.extend({ init: function () { this._events = {}; }, bind: function (eventName, handlers, one) { var that = this, idx, eventNames = typeof eventName === STRING ? [eventName] : eventName, length, original, handler, handlersIsFunction = typeof handlers === FUNCTION, events; if (handlers === undefined) { for (idx in eventName) { that.bind(idx, eventName[idx]); } return that; } for (idx = 0, length = eventNames.length; idx < length; idx++) { eventName = eventNames[idx]; handler = handlersIsFunction ? handlers : handlers[eventName]; if (handler) { if (one) { original = handler; handler = function () { that.unbind(eventName, handler); original.apply(that, arguments); }; handler.original = original; } events = that._events[eventName] = that._events[eventName] || []; events.push(handler); } } return that; }, one: function (eventNames, handlers) { return this.bind(eventNames, handlers, true); }, first: function (eventName, handlers) { var that = this, idx, eventNames = typeof eventName === STRING ? [eventName] : eventName, length, handler, handlersIsFunction = typeof handlers === FUNCTION, events; for (idx = 0, length = eventNames.length; idx < length; idx++) { eventName = eventNames[idx]; handler = handlersIsFunction ? handlers : handlers[eventName]; if (handler) { events = that._events[eventName] = that._events[eventName] || []; events.unshift(handler); } } return that; }, trigger: function (eventName, e) { var that = this, events = that._events[eventName], idx, length; if (events) { e = e || {}; e.sender = that; e._defaultPrevented = false; e.preventDefault = preventDefault; e.isDefaultPrevented = isDefaultPrevented; events = events.slice(); for (idx = 0, length = events.length; idx < length; idx++) { events[idx].call(that, e); } return e._defaultPrevented === true; } return false; }, unbind: function (eventName, handler) { var that = this, events = that._events[eventName], idx; if (eventName === undefined) { that._events = {}; } else if (events) { if (handler) { for (idx = events.length - 1; idx >= 0; idx--) { if (events[idx] === handler || events[idx].original === handler) { events.splice(idx, 1); } } } else { that._events[eventName] = []; } } return that; } }); function compilePart(part, stringPart) { if (stringPart) { return '\'' + part.split('\'').join('\\\'').split('\\"').join('\\\\\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t') + '\''; } else { var first = part.charAt(0), rest = part.substring(1); if (first === '=') { return '+(' + rest + ')+'; } else if (first === ':') { return '+$kendoHtmlEncode(' + rest + ')+'; } else { return ';' + part + ';$kendoOutput+='; } } } var argumentNameRegExp = /^\w+/, encodeRegExp = /\$\{([^}]*)\}/g, escapedCurlyRegExp = /\\\}/g, curlyRegExp = /__CURLY__/g, escapedSharpRegExp = /\\#/g, sharpRegExp = /__SHARP__/g, zeros = [ '', '0', '00', '000', '0000' ]; Template = { paramName: 'data', useWithBlock: true, render: function (template, data) { var idx, length, html = ''; for (idx = 0, length = data.length; idx < length; idx++) { html += template(data[idx]); } return html; }, compile: function (template, options) { var settings = extend({}, this, options), paramName = settings.paramName, argumentName = paramName.match(argumentNameRegExp)[0], useWithBlock = settings.useWithBlock, functionBody = 'var $kendoOutput, $kendoHtmlEncode = kendo.htmlEncode;', fn, parts, idx; if (isFunction(template)) { return template; } functionBody += useWithBlock ? 'with(' + paramName + '){' : ''; functionBody += '$kendoOutput='; parts = template.replace(escapedCurlyRegExp, '__CURLY__').replace(encodeRegExp, '#=$kendoHtmlEncode($1)#').replace(curlyRegExp, '}').replace(escapedSharpRegExp, '__SHARP__').split('#'); for (idx = 0; idx < parts.length; idx++) { functionBody += compilePart(parts[idx], idx % 2 === 0); } functionBody += useWithBlock ? ';}' : ';'; functionBody += 'return $kendoOutput;'; functionBody = functionBody.replace(sharpRegExp, '#'); try { fn = new Function(argumentName, functionBody); fn._slotCount = Math.floor(parts.length / 2); return fn; } catch (e) { throw new Error(kendo.format('Invalid template:\'{0}\' Generated code:\'{1}\'', template, functionBody)); } } }; function pad(number, digits, end) { number = number + ''; digits = digits || 2; end = digits - number.length; if (end) { return zeros[digits].substring(0, end) + number; } return number; } (function () { var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\' }, rep, toString = {}.toString; if (typeof Date.prototype.toJSON !== FUNCTION) { Date.prototype.toJSON = function () { var that = this; return isFinite(that.valueOf()) ? pad(that.getUTCFullYear(), 4) + '-' + pad(that.getUTCMonth() + 1) + '-' + pad(that.getUTCDate()) + 'T' + pad(that.getUTCHours()) + ':' + pad(that.getUTCMinutes()) + ':' + pad(that.getUTCSeconds()) + 'Z' : null; }; String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function () { return this.valueOf(); }; } function quote(string) { escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === STRING ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }) + '"' : '"' + string + '"'; } function str(key, holder) { var i, k, v, length, mind = gap, partial, value = holder[key], type; if (value && typeof value === OBJECT && typeof value.toJSON === FUNCTION) { value = value.toJSON(key); } if (typeof rep === FUNCTION) { value = rep.call(holder, key, value); } type = typeof value; if (type === STRING) { return quote(value); } else if (type === NUMBER) { return isFinite(value) ? String(value) : NULL; } else if (type === BOOLEAN || type === NULL) { return String(value); } else if (type === OBJECT) { if (!value) { return NULL; } gap += indent; partial = []; if (toString.apply(value) === '[object Array]') { length = value.length; for (i = 0; i < length; i++) { partial[i] = str(i, value) || NULL; } v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']'; gap = mind; return v; } if (rep && typeof rep === OBJECT) { length = rep.length; for (i = 0; i < length; i++) { if (typeof rep[i] === STRING) { k = rep[i]; v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } else { for (k in value) { if (Object.hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}'; gap = mind; return v; } } if (typeof JSON.stringify !== FUNCTION) { JSON.stringify = function (value, replacer, space) { var i; gap = ''; indent = ''; if (typeof space === NUMBER) { for (i = 0; i < space; i += 1) { indent += ' '; } } else if (typeof space === STRING) { indent = space; } rep = replacer; if (replacer && typeof replacer !== FUNCTION && (typeof replacer !== OBJECT || typeof replacer.length !== NUMBER)) { throw new Error('JSON.stringify'); } return str('', { '': value }); }; } }()); (function () { var dateFormatRegExp = /dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|HH|H|hh|h|mm|m|fff|ff|f|tt|ss|s|zzz|zz|z|"[^"]*"|'[^']*'/g, standardFormatRegExp = /^(n|c|p|e)(\d*)$/i, literalRegExp = /(\\.)|(['][^']*[']?)|(["][^"]*["]?)/g, commaRegExp = /\,/g, EMPTY = '', POINT = '.', COMMA = ',', SHARP = '#', ZERO = '0', PLACEHOLDER = '??', EN = 'en-US', objectToString = {}.toString; kendo.cultures['en-US'] = { name: EN, numberFormat: { pattern: ['-n'], decimals: 2, ',': ',', '.': '.', groupSize: [3], percent: { pattern: [ '-n %', 'n %' ], decimals: 2, ',': ',', '.': '.', groupSize: [3], symbol: '%' }, currency: { name: 'US Dollar', abbr: 'USD', pattern: [ '($n)', '$n' ], decimals: 2, ',': ',', '.': '.', groupSize: [3], symbol: '$' } }, calendars: { standard: { days: { names: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], namesAbbr: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ], namesShort: [ 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' ] }, months: { names: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], namesAbbr: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] }, AM: [ 'AM', 'am', 'AM' ], PM: [ 'PM', 'pm', 'PM' ], patterns: { d: 'M/d/yyyy', D: 'dddd, MMMM dd, yyyy', F: 'dddd, MMMM dd, yyyy h:mm:ss tt', g: 'M/d/yyyy h:mm tt', G: 'M/d/yyyy h:mm:ss tt', m: 'MMMM dd', M: 'MMMM dd', s: 'yyyy\'-\'MM\'-\'ddTHH\':\'mm\':\'ss', t: 'h:mm tt', T: 'h:mm:ss tt', u: 'yyyy\'-\'MM\'-\'dd HH\':\'mm\':\'ss\'Z\'', y: 'MMMM, yyyy', Y: 'MMMM, yyyy' }, '/': '/', ':': ':', firstDay: 0, twoDigitYearMax: 2029 } } }; function findCulture(culture) { if (culture) { if (culture.numberFormat) { return culture; } if (typeof culture === STRING) { var cultures = kendo.cultures; return cultures[culture] || cultures[culture.split('-')[0]] || null; } return null; } return null; } function getCulture(culture) { if (culture) { culture = findCulture(culture); } return culture || kendo.cultures.current; } kendo.culture = function (cultureName) { var cultures = kendo.cultures, culture; if (cultureName !== undefined) { culture = findCulture(cultureName) || cultures[EN]; culture.calendar = culture.calendars.standard; cultures.current = culture; } else { return cultures.current; } }; kendo.findCulture = findCulture; kendo.getCulture = getCulture; kendo.culture(EN); function formatDate(date, format, culture) { culture = getCulture(culture); var calendar = culture.calendars.standard, days = calendar.days, months = calendar.months; format = calendar.patterns[format] || format; return format.replace(dateFormatRegExp, function (match) { var minutes; var result; var sign; if (match === 'd') { result = date.getDate(); } else if (match === 'dd') { result = pad(date.getDate()); } else if (match === 'ddd') { result = days.namesAbbr[date.getDay()]; } else if (match === 'dddd') { result = days.names[date.getDay()]; } else if (match === 'M') { result = date.getMonth() + 1; } else if (match === 'MM') { result = pad(date.getMonth() + 1); } else if (match === 'MMM') { result = months.namesAbbr[date.getMonth()]; } else if (match === 'MMMM') { result = months.names[date.getMonth()]; } else if (match === 'yy') { result = pad(date.getFullYear() % 100); } else if (match === 'yyyy') { result = pad(date.getFullYear(), 4); } else if (match === 'h') { result = date.getHours() % 12 || 12; } else if (match === 'hh') { result = pad(date.getHours() % 12 || 12); } else if (match === 'H') { result = date.getHours(); } else if (match === 'HH') { result = pad(date.getHours()); } else if (match === 'm') { result = date.getMinutes(); } else if (match === 'mm') { result = pad(date.getMinutes()); } else if (match === 's') { result = date.getSeconds(); } else if (match === 'ss') { result = pad(date.getSeconds()); } else if (match === 'f') { result = math.floor(date.getMilliseconds() / 100); } else if (match === 'ff') { result = date.getMilliseconds(); if (result > 99) { result = math.floor(result / 10); } result = pad(result); } else if (match === 'fff') { result = pad(date.getMilliseconds(), 3); } else if (match === 'tt') { result = date.getHours() < 12 ? calendar.AM[0] : calendar.PM[0]; } else if (match === 'zzz') { minutes = date.getTimezoneOffset(); sign = minutes < 0; result = math.abs(minutes / 60).toString().split('.')[0]; minutes = math.abs(minutes) - result * 60; result = (sign ? '+' : '-') + pad(result); result += ':' + pad(minutes); } else if (match === 'zz' || match === 'z') { result = date.getTimezoneOffset() / 60; sign = result < 0; result = math.abs(result).toString().split('.')[0]; result = (sign ? '+' : '-') + (match === 'zz' ? pad(result) : result); } return result !== undefined ? result : match.slice(1, match.length - 1); }); } function formatNumber(number, format, culture) { culture = getCulture(culture); var numberFormat = culture.numberFormat, decimal = numberFormat[POINT], precision = numberFormat.decimals, pattern = numberFormat.pattern[0], literals = [], symbol, isCurrency, isPercent, customPrecision, formatAndPrecision, negative = number < 0, integer, fraction, integerLength, fractionLength, replacement = EMPTY, value = EMPTY, idx, length, ch, hasGroup, hasNegativeFormat, decimalIndex, sharpIndex, zeroIndex, hasZero, hasSharp, percentIndex, currencyIndex, startZeroIndex, start = -1, end; if (number === undefined) { return EMPTY; } if (!isFinite(number)) { return number; } if (!format) { return culture.name.length ? number.toLocaleString() : number.toString(); } formatAndPrecision = standardFormatRegExp.exec(format); if (formatAndPrecision) { format = formatAndPrecision[1].toLowerCase(); isCurrency = format === 'c'; isPercent = format === 'p'; if (isCurrency || isPercent) { numberFormat = isCurrency ? numberFormat.currency : numberFormat.percent; decimal = numberFormat[POINT]; precision = numberFormat.decimals; symbol = numberFormat.symbol; pattern = numberFormat.pattern[negative ? 0 : 1]; } customPrecision = formatAndPrecision[2]; if (customPrecision) { precision = +customPrecision; } if (format === 'e') { return customPrecision ? number.toExponential(precision) : number.toExponential(); } if (isPercent) { number *= 100; } number = round(number, precision); negative = number < 0; number = number.split(POINT); integer = number[0]; fraction = number[1]; if (negative) { integer = integer.substring(1); } value = groupInteger(integer, 0, integer.length, numberFormat); if (fraction) { value += decimal + fraction; } if (format === 'n' && !negative) { return value; } number = EMPTY; for (idx = 0, length = pattern.length; idx < length; idx++) { ch = pattern.charAt(idx); if (ch === 'n') { number += value; } else if (ch === '$' || ch === '%') { number += symbol; } else { number += ch; } } return number; } if (negative) { number = -number; } if (format.indexOf('\'') > -1 || format.indexOf('"') > -1 || format.indexOf('\\') > -1) { format = format.replace(literalRegExp, function (match) { var quoteChar = match.charAt(0).replace('\\', ''), literal = match.slice(1).replace(quoteChar, ''); literals.push(literal); return PLACEHOLDER; }); } format = format.split(';'); if (negative && format[1]) { format = format[1]; hasNegativeFormat = true; } else if (number === 0) { format = format[2] || format[0]; if (format.indexOf(SHARP) == -1 && format.indexOf(ZERO) == -1) { return format; } } else { format = format[0]; } percentIndex = format.indexOf('%'); currencyIndex = format.indexOf('$'); isPercent = percentIndex != -1; isCurrency = currencyIndex != -1; if (isPercent) { number *= 100; } if (isCurrency && format[currencyIndex - 1] === '\\') { format = format.split('\\').join(''); isCurrency = false; } if (isCurrency || isPercent) { numberFormat = isCurrency ? numberFormat.currency : numberFormat.percent; decimal = numberFormat[POINT]; precision = numberFormat.decimals; symbol = numberFormat.symbol; } hasGroup = format.indexOf(COMMA) > -1; if (hasGroup) { format = format.replace(commaRegExp, EMPTY); } decimalIndex = format.indexOf(POINT); length = format.length; if (decimalIndex != -1) { fraction = number.toString().split('e'); if (fraction[1]) { fraction = round(number, Math.abs(fraction[1])); } else { fraction = fraction[0]; } fraction = fraction.split(POINT)[1] || EMPTY; zeroIndex = format.lastIndexOf(ZERO) - decimalIndex; sharpIndex = format.lastIndexOf(SHARP) - decimalIndex; hasZero = zeroIndex > -1; hasSharp = sharpIndex > -1; idx = fraction.length; if (!hasZero && !hasSharp) { format = format.substring(0, decimalIndex) + format.substring(decimalIndex + 1); length = format.length; decimalIndex = -1; idx = 0; } if (hasZero && zeroIndex > sharpIndex) { idx = zeroIndex; } else if (sharpIndex > zeroIndex) { if (hasSharp && idx > sharpIndex) { idx = sharpIndex; } else if (hasZero && idx < zeroIndex) { idx = zeroIndex; } } if (idx > -1) { number = round(number, idx); } } else { number = round(number); } sharpIndex = format.indexOf(SHARP); startZeroIndex = zeroIndex = format.indexOf(ZERO); if (sharpIndex == -1 && zeroIndex != -1) { start = zeroIndex; } else if (sharpIndex != -1 && zeroIndex == -1) { start = sharpIndex; } else { start = sharpIndex > zeroIndex ? zeroIndex : sharpIndex; } sharpIndex = format.lastIndexOf(SHARP); zeroIndex = format.lastIndexOf(ZERO); if (sharpIndex == -1 && zeroIndex != -1) { end = zeroIndex; } else if (sharpIndex != -1 && zeroIndex == -1) { end = sharpIndex; } else { end = sharpIndex > zeroIndex ? sharpIndex : zeroIndex; } if (start == length) { end = start; } if (start != -1) { value = number.toString().split(POINT); integer = value[0]; fraction = value[1] || EMPTY; integerLength = integer.length; fractionLength = fraction.length; if (negative && number * -1 >= 0) { negative = false; } number = format.substring(0, start); if (negative && !hasNegativeFormat) { number += '-'; } for (idx = start; idx < length; idx++) { ch = format.charAt(idx); if (decimalIndex == -1) { if (end - idx < integerLength) { number += integer; break; } } else { if (zeroIndex != -1 && zeroIndex < idx) { replacement = EMPTY; } if (decimalIndex - idx <= integerLength && decimalIndex - idx > -1) { number += integer; idx = decimalIndex; } if (decimalIndex === idx) { number += (fraction ? decimal : EMPTY) + fraction; idx += end - decimalIndex + 1; continue; } } if (ch === ZERO) { number += ch; replacement = ch; } else if (ch === SHARP) { number += replacement; } } if (hasGroup) { number = groupInteger(number, start, end, numberFormat); } if (end >= start) { number += format.substring(end + 1); } if (isCurrency || isPercent) { value = EMPTY; for (idx = 0, length = number.length; idx < length; idx++) { ch = number.charAt(idx); value += ch === '$' || ch === '%' ? symbol : ch; } number = value; } length = literals.length; if (length) { for (idx = 0; idx < length; idx++) { number = number.replace(PLACEHOLDER, literals[idx]); } } } return number; } var groupInteger = function (number, start, end, numberFormat) { var decimalIndex = number.indexOf(numberFormat[POINT]); var groupSizes = numberFormat.groupSize.slice(); var groupSize = groupSizes.shift(); var integer, integerLength; var idx, parts, value; var newGroupSize; end = decimalIndex !== -1 ? decimalIndex : end + 1; integer = number.substring(start, end); integerLength = integer.length; if (integerLength >= groupSize) { idx = integerLength; parts = []; while (idx > -1) { value = integer.substring(idx - groupSize, idx); if (value) { parts.push(value); } idx -= groupSize; newGroupSize = groupSizes.shift(); groupSize = newGroupSize !== undefined ? newGroupSize : groupSize; if (groupSize === 0) { parts.push(integer.substring(0, idx)); break; } } integer = parts.reverse().join(numberFormat[COMMA]); number = number.substring(0, start) + integer + number.substring(end); } return number; }; var round = function (value, precision) { precision = precision || 0; value = value.toString().split('e'); value = Math.round(+(value[0] + 'e' + (value[1] ? +value[1] + precision : precision))); value = value.toString().split('e'); value = +(value[0] + 'e' + (value[1] ? +value[1] - precision : -precision)); return value.toFixed(precision); }; var toString = function (value, fmt, culture) { if (fmt) { if (objectToString.call(value) === '[object Date]') { return formatDate(value, fmt, culture); } else if (typeof value === NUMBER) { return formatNumber(value, fmt, culture); } } return value !== undefined ? value : ''; }; kendo.format = function (fmt) { var values = arguments; return fmt.replace(formatRegExp, function (match, index, placeholderFormat) { var value = values[parseInt(index, 10) + 1]; return toString(value, placeholderFormat ? placeholderFormat.substring(1) : ''); }); }; kendo._extractFormat = function (format) { if (format.slice(0, 3) === '{0:') { format = format.slice(3, format.length - 1); } return format; }; kendo._activeElement = function () { try { return document.activeElement; } catch (e) { return document.documentElement.activeElement; } }; kendo._round = round; kendo.toString = toString; }()); (function () { var nonBreakingSpaceRegExp = /\u00A0/g, exponentRegExp = /[eE][\-+]?[0-9]+/, shortTimeZoneRegExp = /[+|\-]\d{1,2}/, longTimeZoneRegExp = /[+|\-]\d{1,2}:?\d{2}/, dateRegExp = /^\/Date\((.*?)\)\/$/, offsetRegExp = /[+-]\d*/, formatsSequence = [ 'G', 'g', 'd', 'F', 'D', 'y', 'm', 'T', 't' ], numberRegExp = { 2: /^\d{1,2}/, 3: /^\d{1,3}/, 4: /^\d{4}/ }, objectToString = {}.toString; function outOfRange(value, start, end) { return !(value >= start && value <= end); } function designatorPredicate(designator) { return designator.charAt(0); } function mapDesignators(designators) { return $.map(designators, designatorPredicate); } function adjustDST(date, hours) { if (!hours && date.getHours() === 23) { date.setHours(date.getHours() + 2); } } function lowerArray(data) { var idx = 0, length = data.length, array = []; for (; idx < length; idx++) { array[idx] = (data[idx] + '').toLowerCase(); } return array; } function lowerLocalInfo(localInfo) { var newLocalInfo = {}, property; for (property in localInfo) { newLocalInfo[property] = lowerArray(localInfo[property]); } return newLocalInfo; } function parseExact(value, format, culture) { if (!value) { return null; } var lookAhead = function (match) { var i = 0; while (format[idx] === match) { i++; idx++; } if (i > 0) { idx -= 1; } return i; }, getNumber = function (size) { var rg = numberRegExp[size] || new RegExp('^\\d{1,' + size + '}'), match = value.substr(valueIdx, size).match(rg); if (match) { match = match[0]; valueIdx += match.length; return parseInt(match, 10); } return null; }, getIndexByName = function (names, lower) { var i = 0, length = names.length, name, nameLength, matchLength = 0, matchIdx = 0, subValue; for (; i < length; i++) { name = names[i]; nameLength = name.length; subValue = value.substr(valueIdx, nameLength); if (lower) { subValue = subValue.toLowerCase(); } if (subValue == name && nameLength > matchLength) { matchLength = nameLength; matchIdx = i; } } if (matchLength) { valueIdx += matchLength; return matchIdx + 1; } return null; }, checkLiteral = function () { var result = false; if (value.charAt(valueIdx) === format[idx]) { valueIdx++; result = true; } return result; }, calendar = culture.calendars.standard, year = null, month = null, day = null, hours = null, minutes = null, seconds = null, milliseconds = null, idx = 0, valueIdx = 0, literal = false, date = new Date(), twoDigitYearMax = calendar.twoDigitYearMax || 2029, defaultYear = date.getFullYear(), ch, count, length, pattern, pmHour, UTC, matches, amDesignators, pmDesignators, hoursOffset, minutesOffset, hasTime, match; if (!format) { format = 'd'; } pattern = calendar.patterns[format]; if (pattern) { format = pattern; } format = format.split(''); length = format.length; for (; idx < length; idx++) { ch = format[idx]; if (literal) { if (ch === '\'') { literal = false; } else { checkLiteral(); } } else { if (ch === 'd') { count = lookAhead('d'); if (!calendar._lowerDays) { calendar._lowerDays = lowerLocalInfo(calendar.days); } if (day !== null && count > 2) { continue; } day = count < 3 ? getNumber(2) : getIndexByName(calendar._lowerDays[count == 3 ? 'namesAbbr' : 'names'], true); if (day === null || outOfRange(day, 1, 31)) { return null; } } else if (ch === 'M') { count = lookAhead('M'); if (!calendar._lowerMonths) { calendar._lowerMonths = lowerLocalInfo(calendar.months); } month = count < 3 ? getNumber(2) : getIndexByName(calendar._lowerMonths[count == 3 ? 'namesAbbr' : 'names'], true); if (month === null || outOfRange(month, 1, 12)) { return null; } month -= 1; } else if (ch === 'y') { count = lookAhead('y'); year = getNumber(count); if (year === null) { return null; } if (count == 2) { if (typeof twoDigitYearMax === 'string') { twoDigitYearMax = defaultYear + parseInt(twoDigitYearMax, 10); } year = defaultYear - defaultYear % 100 + year; if (year > twoDigitYearMax) { year -= 100; } } } else if (ch === 'h') { lookAhead('h'); hours = getNumber(2); if (hours == 12) { hours = 0; } if (hours === null || outOfRange(hours, 0, 11)) { return null; } } else if (ch === 'H') { lookAhead('H'); hours = getNumber(2); if (hours === null || outOfRange(hours, 0, 23)) { return null; } } else if (ch === 'm') { lookAhead('m'); minutes = getNumber(2); if (minutes === null || outOfRange(minutes, 0, 59)) { return null; } } else if (ch === 's') { lookAhead('s'); seconds = getNumber(2); if (seconds === null || outOfRange(seconds, 0, 59)) { return null; } } else if (ch === 'f') { count = lookAhead('f'); match = value.substr(valueIdx, count).match(numberRegExp[3]); milliseconds = getNumber(count); if (milliseconds !== null) { milliseconds = parseFloat('0.' + match[0], 10); milliseconds = kendo._round(milliseconds, 3); milliseconds *= 1000; } if (milliseconds === null || outOfRange(milliseconds, 0, 999)) { return null; } } else if (ch === 't') { count = lookAhead('t'); amDesignators = calendar.AM; pmDesignators = calendar.PM; if (count === 1) { amDesignators = mapDesignators(amDesignators); pmDesignators = mapDesignators(pmDesignators); } pmHour = getIndexByName(pmDesignators); if (!pmHour && !getIndexByName(amDesignators)) { return null; } } else if (ch === 'z') { UTC = true; count = lookAhead('z'); if (value.substr(valueIdx, 1) === 'Z') { checkLiteral(); continue; } matches = value.substr(valueIdx, 6).match(count > 2 ? longTimeZoneRegExp : shortTimeZoneRegExp); if (!matches) { return null; } matches = matches[0].split(':'); hoursOffset = matches[0]; minutesOffset = matches[1]; if (!minutesOffset && hoursOffset.length > 3) { valueIdx = hoursOffset.length - 2; minutesOffset = hoursOffset.substring(valueIdx); hoursOffset = hoursOffset.substring(0, valueIdx); } hoursOffset = parseInt(hoursOffset, 10); if (outOfRange(hoursOffset, -12, 13)) { return null; } if (count > 2) { minutesOffset = parseInt(minutesOffset, 10); if (isNaN(minutesOffset) || outOfRange(minutesOffset, 0, 59)) { return null; } } } else if (ch === '\'') { literal = true; checkLiteral(); } else if (!checkLiteral()) { return null; } } } hasTime = hours !== null || minutes !== null || seconds || null; if (year === null && month === null && day === null && hasTime) { year = defaultYear; month = date.getMonth(); day = date.getDate(); } else { if (year === null) { year = defaultYear; } if (day === null) { day = 1; } } if (pmHour && hours < 12) { hours += 12; } if (UTC) { if (hoursOffset) { hours += -hoursOffset; } if (minutesOffset) { minutes += -minutesOffset; } value = new Date(Date.UTC(year, month, day, hours, minutes, seconds, milliseconds)); } else { value = new Date(year, month, day, hours, minutes, seconds, milliseconds); adjustDST(value, hours); } if (year < 100) { value.setFullYear(year); } if (value.getDate() !== day && UTC === undefined) { return null; } return value; } function parseMicrosoftFormatOffset(offset) { var sign = offset.substr(0, 1) === '-' ? -1 : 1; offset = offset.substring(1); offset = parseInt(offset.substr(0, 2), 10) * 60 + parseInt(offset.substring(2), 10); return sign * offset; } kendo.parseDate = function (value, formats, culture) { if (objectToString.call(value) === '[object Date]') { return value; } var idx = 0; var date = null; var length, patterns; var tzoffset; if (value && value.indexOf('/D') === 0) { date = dateRegExp.exec(value); if (date) { date = date[1]; tzoffset = offsetRegExp.exec(date.substring(1)); date = new Date(parseInt(date, 10)); if (tzoffset) { tzoffset = parseMicrosoftFormatOffset(tzoffset[0]); date = kendo.timezone.apply(date, 0); date = kendo.timezone.convert(date, 0, -1 * tzoffset); } return date; } } culture = kendo.getCulture(culture); if (!formats) { formats = []; patterns = culture.calendar.patterns; length = formatsSequence.length; for (; idx < length; idx++) { formats[idx] = patterns[formatsSequence[idx]]; } idx = 0; formats = [ 'yyyy/MM/dd HH:mm:ss', 'yyyy/MM/dd HH:mm', 'yyyy/MM/dd', 'ddd MMM dd yyyy HH:mm:ss', 'yyyy-MM-ddTHH:mm:ss.fffffffzzz', 'yyyy-MM-ddTHH:mm:ss.fffzzz', 'yyyy-MM-ddTHH:mm:sszzz', 'yyyy-MM-ddTHH:mm:ss.fffffff', 'yyyy-MM-ddTHH:mm:ss.fff', 'yyyy-MM-ddTHH:mmzzz', 'yyyy-MM-ddTHH:mmzz', 'yyyy-MM-ddTHH:mm:ss', 'yyyy-MM-ddTHH:mm', 'yyyy-MM-dd HH:mm:ss', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd', 'HH:mm:ss', 'HH:mm' ].concat(formats); } formats = isArray(formats) ? formats : [formats]; length = formats.length; for (; idx < length; idx++) { date = parseExact(value, formats[idx], culture); if (date) { return date; } } return date; }; kendo.parseInt = function (value, culture) { var result = kendo.parseFloat(value, culture); if (result) { result = result | 0; } return result; }; kendo.parseFloat = function (value, culture, format) { if (!value && value !== 0) { return null; } if (typeof value === NUMBER) { return value; } value = value.toString(); culture = kendo.getCulture(culture); var number = culture.numberFormat, percent = number.percent, currency = number.currency, symbol = currency.symbol, percentSymbol = percent.symbol, negative = value.indexOf('-'), parts, isPercent; if (exponentRegExp.test(value)) { value = parseFloat(value.replace(number['.'], '.')); if (isNaN(value)) { value = null; } return value; } if (negative > 0) { return null; } else { negative = negative > -1; } if (value.indexOf(symbol) > -1 || format && format.toLowerCase().indexOf('c') > -1) { number = currency; parts = number.pattern[0].replace('$', symbol).split('n'); if (value.indexOf(parts[0]) > -1 && value.indexOf(parts[1]) > -1) { value = value.replace(parts[0], '').replace(parts[1], ''); negative = true; } } else if (value.indexOf(percentSymbol) > -1) { isPercent = true; number = percent; symbol = percentSymbol; } value = value.replace('-', '').replace(symbol, '').replace(nonBreakingSpaceRegExp, ' ').split(number[','].replace(nonBreakingSpaceRegExp, ' ')).join('').replace(number['.'], '.'); value = parseFloat(value); if (isNaN(value)) { value = null; } else if (negative) { value *= -1; } if (value && isPercent) { value /= 100; } return value; }; }()); function getShadows(element) { var shadow = element.css(kendo.support.transitions.css + 'box-shadow') || element.css('box-shadow'), radius = shadow ? shadow.match(boxShadowRegExp) || [ 0, 0, 0, 0, 0 ] : [ 0, 0, 0, 0, 0 ], blur = math.max(+radius[3], +(radius[4] || 0)); return { left: -radius[1] + blur, right: +radius[1] + blur, bottom: +radius[2] + blur }; } function wrap(element, autosize) { var browser = support.browser, percentage, isRtl = element.css('direction') == 'rtl'; if (!element.parent().hasClass('k-animation-container')) { var shadows = getShadows(element), width = element[0].style.width, height = element[0].style.height, percentWidth = percentRegExp.test(width), percentHeight = percentRegExp.test(height); if (browser.opera) { shadows.left = shadows.right = shadows.bottom = 5; } percentage = percentWidth || percentHeight; if (!percentWidth && (!autosize || autosize && width)) { width = element.outerWidth(); } if (!percentHeight && (!autosize || autosize && height)) { height = element.outerHeight(); } element.wrap($('
').addClass('k-animation-container').css({ width: width, height: height, marginLeft: shadows.left * (isRtl ? 1 : -1), paddingLeft: shadows.left, paddingRight: shadows.right, paddingBottom: shadows.bottom })); if (percentage) { element.css({ width: '100%', height: '100%', boxSizing: 'border-box', mozBoxSizing: 'border-box', webkitBoxSizing: 'border-box' }); } } else { var wrapper = element.parent('.k-animation-container'), wrapperStyle = wrapper[0].style; if (wrapper.is(':hidden')) { wrapper.show(); } percentage = percentRegExp.test(wrapperStyle.width) || percentRegExp.test(wrapperStyle.height); if (!percentage) { wrapper.css({ width: element.outerWidth(), height: element.outerHeight(), boxSizing: 'content-box', mozBoxSizing: 'content-box', webkitBoxSizing: 'content-box' }); } } if (browser.msie && math.floor(browser.version) <= 7) { element.css({ zoom: 1 }); element.children('.k-menu').width(element.width()); } return element.parent(); } function deepExtend(destination) { var i = 1, length = arguments.length; for (i = 1; i < length; i++) { deepExtendOne(destination, arguments[i]); } return destination; } function deepExtendOne(destination, source) { var ObservableArray = kendo.data.ObservableArray, LazyObservableArray = kendo.data.LazyObservableArray, DataSource = kendo.data.DataSource, HierarchicalDataSource = kendo.data.HierarchicalDataSource, property, propValue, propType, propInit, destProp; for (property in source) { propValue = source[property]; propType = typeof propValue; if (propType === OBJECT && propValue !== null) { propInit = propValue.constructor; } else { propInit = null; } if (propInit && propInit !== Array && propInit !== ObservableArray && propInit !== LazyObservableArray && propInit !== DataSource && propInit !== HierarchicalDataSource) { if (propValue instanceof Date) { destination[property] = new Date(propValue.getTime()); } else if (isFunction(propValue.clone)) { destination[property] = propValue.clone(); } else { destProp = destination[property]; if (typeof destProp === OBJECT) { destination[property] = destProp || {}; } else { destination[property] = {}; } deepExtendOne(destination[property], propValue); } } else if (propType !== UNDEFINED) { destination[property] = propValue; } } return destination; } function testRx(agent, rxs, dflt) { for (var rx in rxs) { if (rxs.hasOwnProperty(rx) && rxs[rx].test(agent)) { return rx; } } return dflt !== undefined ? dflt : agent; } function toHyphens(str) { return str.replace(/([a-z][A-Z])/g, function (g) { return g.charAt(0) + '-' + g.charAt(1).toLowerCase(); }); } function toCamelCase(str) { return str.replace(/\-(\w)/g, function (strMatch, g1) { return g1.toUpperCase(); }); } function getComputedStyles(element, properties) { var styles = {}, computedStyle; if (document.defaultView && document.defaultView.getComputedStyle) { computedStyle = document.defaultView.getComputedStyle(element, ''); if (properties) { $.each(properties, function (idx, value) { styles[value] = computedStyle.getPropertyValue(value); }); } } else { computedStyle = element.currentStyle; if (properties) { $.each(properties, function (idx, value) { styles[value] = computedStyle[toCamelCase(value)]; }); } } if (!kendo.size(styles)) { styles = computedStyle; } return styles; } function isScrollable(element) { if (element && element.className && typeof element.className === 'string' && element.className.indexOf('k-auto-scrollable') > -1) { return true; } var overflow = getComputedStyles(element, ['overflow']).overflow; return overflow == 'auto' || overflow == 'scroll'; } function scrollLeft(element, value) { var webkit = support.browser.webkit; var mozila = support.browser.mozilla; var el = element instanceof $ ? element[0] : element; var isRtl; if (!element) { return; } isRtl = support.isRtl(element); if (value !== undefined) { if (isRtl && webkit) { el.scrollLeft = el.scrollWidth - el.clientWidth - value; } else if (isRtl && mozila) { el.scrollLeft = -value; } else { el.scrollLeft = value; } } else { if (isRtl && webkit) { return el.scrollWidth - el.clientWidth - el.scrollLeft; } else { return Math.abs(el.scrollLeft); } } } (function () { support._scrollbar = undefined; support.scrollbar = function (refresh) { if (!isNaN(support._scrollbar) && !refresh) { return support._scrollbar; } else { var div = document.createElement('div'), result; div.style.cssText = 'overflow:scroll;overflow-x:hidden;zoom:1;clear:both;display:block'; div.innerHTML = ' '; document.body.appendChild(div); support._scrollbar = result = div.offsetWidth - div.scrollWidth; document.body.removeChild(div); return result; } }; support.isRtl = function (element) { return $(element).closest('.k-rtl').length > 0; }; var table = document.createElement('table'); try { table.innerHTML = ''; support.tbodyInnerHtml = true; } catch (e) { support.tbodyInnerHtml = false; } support.touch = 'ontouchstart' in window; support.msPointers = window.MSPointerEvent; support.pointers = window.PointerEvent; var transitions = support.transitions = false, transforms = support.transforms = false, elementProto = 'HTMLElement' in window ? HTMLElement.prototype : []; support.hasHW3D = 'WebKitCSSMatrix' in window && 'm11' in new window.WebKitCSSMatrix() || 'MozPerspective' in document.documentElement.style || 'msPerspective' in document.documentElement.style; each([ 'Moz', 'webkit', 'O', 'ms' ], function () { var prefix = this.toString(), hasTransitions = typeof table.style[prefix + 'Transition'] === STRING; if (hasTransitions || typeof table.style[prefix + 'Transform'] === STRING) { var lowPrefix = prefix.toLowerCase(); transforms = { css: lowPrefix != 'ms' ? '-' + lowPrefix + '-' : '', prefix: prefix, event: lowPrefix === 'o' || lowPrefix === 'webkit' ? lowPrefix : '' }; if (hasTransitions) { transitions = transforms; transitions.event = transitions.event ? transitions.event + 'TransitionEnd' : 'transitionend'; } return false; } }); table = null; support.transforms = transforms; support.transitions = transitions; support.devicePixelRatio = window.devicePixelRatio === undefined ? 1 : window.devicePixelRatio; try { support.screenWidth = window.outerWidth || window.screen ? window.screen.availWidth : window.innerWidth; support.screenHeight = window.outerHeight || window.screen ? window.screen.availHeight : window.innerHeight; } catch (e) { support.screenWidth = window.screen.availWidth; support.screenHeight = window.screen.availHeight; } support.detectOS = function (ua) { var os = false, minorVersion, match = [], notAndroidPhone = !/mobile safari/i.test(ua), agentRxs = { wp: /(Windows Phone(?: OS)?)\s(\d+)\.(\d+(\.\d+)?)/, fire: /(Silk)\/(\d+)\.(\d+(\.\d+)?)/, android: /(Android|Android.*(?:Opera|Firefox).*?\/)\s*(\d+)\.(\d+(\.\d+)?)/, iphone: /(iPhone|iPod).*OS\s+(\d+)[\._]([\d\._]+)/, ipad: /(iPad).*OS\s+(\d+)[\._]([\d_]+)/, meego: /(MeeGo).+NokiaBrowser\/(\d+)\.([\d\._]+)/, webos: /(webOS)\/(\d+)\.(\d+(\.\d+)?)/, blackberry: /(BlackBerry|BB10).*?Version\/(\d+)\.(\d+(\.\d+)?)/, playbook: /(PlayBook).*?Tablet\s*OS\s*(\d+)\.(\d+(\.\d+)?)/, windows: /(MSIE)\s+(\d+)\.(\d+(\.\d+)?)/, tizen: /(tizen).*?Version\/(\d+)\.(\d+(\.\d+)?)/i, sailfish: /(sailfish).*rv:(\d+)\.(\d+(\.\d+)?).*firefox/i, ffos: /(Mobile).*rv:(\d+)\.(\d+(\.\d+)?).*Firefox/ }, osRxs = { ios: /^i(phone|pad|pod)$/i, android: /^android|fire$/i, blackberry: /^blackberry|playbook/i, windows: /windows/, wp: /wp/, flat: /sailfish|ffos|tizen/i, meego: /meego/ }, formFactorRxs = { tablet: /playbook|ipad|fire/i }, browserRxs = { omini: /Opera\sMini/i, omobile: /Opera\sMobi/i, firefox: /Firefox|Fennec/i, mobilesafari: /version\/.*safari/i, ie: /MSIE|Windows\sPhone/i, chrome: /chrome|crios/i, webkit: /webkit/i }; for (var agent in agentRxs) { if (agentRxs.hasOwnProperty(agent)) { match = ua.match(agentRxs[agent]); if (match) { if (agent == 'windows' && 'plugins' in navigator) { return false; } os = {}; os.device = agent; os.tablet = testRx(agent, formFactorRxs, false); os.browser = testRx(ua, browserRxs, 'default'); os.name = testRx(agent, osRxs); os[os.name] = true; os.majorVersion = match[2]; os.minorVersion = match[3].replace('_', '.'); minorVersion = os.minorVersion.replace('.', '').substr(0, 2); os.flatVersion = os.majorVersion + minorVersion + new Array(3 - (minorVersion.length < 3 ? minorVersion.length : 2)).join('0'); os.cordova = typeof window.PhoneGap !== UNDEFINED || typeof window.cordova !== UNDEFINED; os.appMode = window.navigator.standalone || /file|local|wmapp/.test(window.location.protocol) || os.cordova; if (os.android && (support.devicePixelRatio < 1.5 && os.flatVersion < 400 || notAndroidPhone) && (support.screenWidth > 800 || support.screenHeight > 800)) { os.tablet = agent; } break; } } } return os; }; var mobileOS = support.mobileOS = support.detectOS(navigator.userAgent); support.wpDevicePixelRatio = mobileOS.wp ? screen.width / 320 : 0; support.kineticScrollNeeded = mobileOS && (support.touch || support.msPointers || support.pointers); support.hasNativeScrolling = false; if (mobileOS.ios || mobileOS.android && mobileOS.majorVersion > 2 || mobileOS.wp) { support.hasNativeScrolling = mobileOS; } support.delayedClick = function () { if (support.touch) { if (mobileOS.ios) { return true; } if (mobileOS.android) { if (!support.browser.chrome) { return true; } if (support.browser.version < 32) { return false; } return !($('meta[name=viewport]').attr('content') || '').match(/user-scalable=no/i); } } return false; }; support.mouseAndTouchPresent = support.touch && !(support.mobileOS.ios || support.mobileOS.android); support.detectBrowser = function (ua) { var browser = false, match = [], browserRxs = { edge: /(edge)[ \/]([\w.]+)/i, webkit: /(chrome)[ \/]([\w.]+)/i, safari: /(webkit)[ \/]([\w.]+)/i, opera: /(opera)(?:.*version|)[ \/]([\w.]+)/i, msie: /(msie\s|trident.*? rv:)([\w.]+)/i, mozilla: /(mozilla)(?:.*? rv:([\w.]+)|)/i }; for (var agent in browserRxs) { if (browserRxs.hasOwnProperty(agent)) { match = ua.match(browserRxs[agent]); if (match) { browser = {}; browser[agent] = true; browser[match[1].toLowerCase().split(' ')[0].split('/')[0]] = true; browser.version = parseInt(document.documentMode || match[2], 10); break; } } } return browser; }; support.browser = support.detectBrowser(navigator.userAgent); support.detectClipboardAccess = function () { var commands = { copy: document.queryCommandSupported ? document.queryCommandSupported('copy') : false, cut: document.queryCommandSupported ? document.queryCommandSupported('cut') : false, paste: document.queryCommandSupported ? document.queryCommandSupported('paste') : false }; if (support.browser.chrome && support.browser.version >= 43) { commands.copy = true; commands.cut = true; } return commands; }; support.clipboard = support.detectClipboardAccess(); support.zoomLevel = function () { try { var browser = support.browser; var ie11WidthCorrection = 0; var docEl = document.documentElement; if (browser.msie && browser.version == 11 && docEl.scrollHeight > docEl.clientHeight && !support.touch) { ie11WidthCorrection = support.scrollbar(); } return support.touch ? docEl.clientWidth / window.innerWidth : browser.msie && browser.version >= 10 ? ((top || window).document.documentElement.offsetWidth + ie11WidthCorrection) / (top || window).innerWidth : 1; } catch (e) { return 1; } }; support.cssBorderSpacing = typeof document.documentElement.style.borderSpacing != 'undefined' && !(support.browser.msie && support.browser.version < 8); (function (browser) { var cssClass = '', docElement = $(document.documentElement), majorVersion = parseInt(browser.version, 10); if (browser.msie) { cssClass = 'ie'; } else if (browser.mozilla) { cssClass = 'ff'; } else if (browser.safari) { cssClass = 'safari'; } else if (browser.webkit) { cssClass = 'webkit'; } else if (browser.opera) { cssClass = 'opera'; } else if (browser.edge) { cssClass = 'edge'; } if (cssClass) { cssClass = 'k-' + cssClass + ' k-' + cssClass + majorVersion; } if (support.mobileOS) { cssClass += ' k-mobile'; } docElement.addClass(cssClass); }(support.browser)); support.eventCapture = document.documentElement.addEventListener; var input = document.createElement('input'); support.placeholder = 'placeholder' in input; support.propertyChangeEvent = 'onpropertychange' in input; support.input = function () { var types = [ 'number', 'date', 'time', 'month', 'week', 'datetime', 'datetime-local' ]; var length = types.length; var value = 'test'; var result = {}; var idx = 0; var type; for (; idx < length; idx++) { type = types[idx]; input.setAttribute('type', type); input.value = value; result[type.replace('-', '')] = input.type !== 'text' && input.value !== value; } return result; }(); input.style.cssText = 'float:left;'; support.cssFloat = !!input.style.cssFloat; input = null; support.stableSort = function () { var threshold = 513; var sorted = [{ index: 0, field: 'b' }]; for (var i = 1; i < threshold; i++) { sorted.push({ index: i, field: 'a' }); } sorted.sort(function (a, b) { return a.field > b.field ? 1 : a.field < b.field ? -1 : 0; }); return sorted[0].index === 1; }(); support.matchesSelector = elementProto.webkitMatchesSelector || elementProto.mozMatchesSelector || elementProto.msMatchesSelector || elementProto.oMatchesSelector || elementProto.matchesSelector || elementProto.matches || function (selector) { var nodeList = document.querySelectorAll ? (this.parentNode || document).querySelectorAll(selector) || [] : $(selector), i = nodeList.length; while (i--) { if (nodeList[i] == this) { return true; } } return false; }; support.pushState = window.history && window.history.pushState; var documentMode = document.documentMode; support.hashChange = 'onhashchange' in window && !(support.browser.msie && (!documentMode || documentMode <= 8)); support.customElements = 'registerElement' in window.document; }()); function size(obj) { var result = 0, key; for (key in obj) { if (obj.hasOwnProperty(key) && key != 'toJSON') { result++; } } return result; } function getOffset(element, type, positioned) { if (!type) { type = 'offset'; } var result = element[type](); if (support.browser.msie && (support.pointers || support.msPointers) && !positioned) { result.top -= window.pageYOffset - document.documentElement.scrollTop; result.left -= window.pageXOffset - document.documentElement.scrollLeft; } return result; } var directions = { left: { reverse: 'right' }, right: { reverse: 'left' }, down: { reverse: 'up' }, up: { reverse: 'down' }, top: { reverse: 'bottom' }, bottom: { reverse: 'top' }, 'in': { reverse: 'out' }, out: { reverse: 'in' } }; function parseEffects(input) { var effects = {}; each(typeof input === 'string' ? input.split(' ') : input, function (idx) { effects[idx] = this; }); return effects; } function fx(element) { return new kendo.effects.Element(element); } var effects = {}; $.extend(effects, { enabled: true, Element: function (element) { this.element = $(element); }, promise: function (element, options) { if (!element.is(':visible')) { element.css({ display: element.data('olddisplay') || 'block' }).css('display'); } if (options.hide) { element.data('olddisplay', element.css('display')).hide(); } if (options.init) { options.init(); } if (options.completeCallback) { options.completeCallback(element); } element.dequeue(); }, disable: function () { this.enabled = false; this.promise = this.promiseShim; }, enable: function () { this.enabled = true; this.promise = this.animatedPromise; } }); effects.promiseShim = effects.promise; function prepareAnimationOptions(options, duration, reverse, complete) { if (typeof options === STRING) { if (isFunction(duration)) { complete = duration; duration = 400; reverse = false; } if (isFunction(reverse)) { complete = reverse; reverse = false; } if (typeof duration === BOOLEAN) { reverse = duration; duration = 400; } options = { effects: options, duration: duration, reverse: reverse, complete: complete }; } return extend({ effects: {}, duration: 400, reverse: false, init: noop, teardown: noop, hide: false }, options, { completeCallback: options.complete, complete: noop }); } function animate(element, options, duration, reverse, complete) { var idx = 0, length = element.length, instance; for (; idx < length; idx++) { instance = $(element[idx]); instance.queue(function () { effects.promise(instance, prepareAnimationOptions(options, duration, reverse, complete)); }); } return element; } function toggleClass(element, classes, options, add) { if (classes) { classes = classes.split(' '); each(classes, function (idx, value) { element.toggleClass(value, add); }); } return element; } if (!('kendoAnimate' in $.fn)) { extend($.fn, { kendoStop: function (clearQueue, gotoEnd) { return this.stop(clearQueue, gotoEnd); }, kendoAnimate: function (options, duration, reverse, complete) { return animate(this, options, duration, reverse, complete); }, kendoAddClass: function (classes, options) { return kendo.toggleClass(this, classes, options, true); }, kendoRemoveClass: function (classes, options) { return kendo.toggleClass(this, classes, options, false); }, kendoToggleClass: function (classes, options, toggle) { return kendo.toggleClass(this, classes, options, toggle); } }); } var ampRegExp = /&/g, ltRegExp = //g; function htmlEncode(value) { return ('' + value).replace(ampRegExp, '&').replace(ltRegExp, '<').replace(gtRegExp, '>').replace(quoteRegExp, '"').replace(aposRegExp, '''); } var eventTarget = function (e) { return e.target; }; if (support.touch) { eventTarget = function (e) { var touches = 'originalEvent' in e ? e.originalEvent.changedTouches : 'changedTouches' in e ? e.changedTouches : null; return touches ? document.elementFromPoint(touches[0].clientX, touches[0].clientY) : e.target; }; each([ 'swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap' ], function (m, value) { $.fn[value] = function (callback) { return this.bind(value, callback); }; }); } if (support.touch) { if (!support.mobileOS) { support.mousedown = 'mousedown touchstart'; support.mouseup = 'mouseup touchend'; support.mousemove = 'mousemove touchmove'; support.mousecancel = 'mouseleave touchcancel'; support.click = 'click'; support.resize = 'resize'; } else { support.mousedown = 'touchstart'; support.mouseup = 'touchend'; support.mousemove = 'touchmove'; support.mousecancel = 'touchcancel'; support.click = 'touchend'; support.resize = 'orientationchange'; } } else if (support.pointers) { support.mousemove = 'pointermove'; support.mousedown = 'pointerdown'; support.mouseup = 'pointerup'; support.mousecancel = 'pointercancel'; support.click = 'pointerup'; support.resize = 'orientationchange resize'; } else if (support.msPointers) { support.mousemove = 'MSPointerMove'; support.mousedown = 'MSPointerDown'; support.mouseup = 'MSPointerUp'; support.mousecancel = 'MSPointerCancel'; support.click = 'MSPointerUp'; support.resize = 'orientationchange resize'; } else { support.mousemove = 'mousemove'; support.mousedown = 'mousedown'; support.mouseup = 'mouseup'; support.mousecancel = 'mouseleave'; support.click = 'click'; support.resize = 'resize'; } var wrapExpression = function (members, paramName) { var result = paramName || 'd', index, idx, length, member, count = 1; for (idx = 0, length = members.length; idx < length; idx++) { member = members[idx]; if (member !== '') { index = member.indexOf('['); if (index !== 0) { if (index == -1) { member = '.' + member; } else { count++; member = '.' + member.substring(0, index) + ' || {})' + member.substring(index); } } count++; result += member + (idx < length - 1 ? ' || {})' : ')'); } } return new Array(count).join('(') + result; }, localUrlRe = /^([a-z]+:)?\/\//i; extend(kendo, { widgets: [], _widgetRegisteredCallbacks: [], ui: kendo.ui || {}, fx: kendo.fx || fx, effects: kendo.effects || effects, mobile: kendo.mobile || {}, data: kendo.data || {}, dataviz: kendo.dataviz || {}, drawing: kendo.drawing || {}, spreadsheet: { messages: {} }, keys: { INSERT: 45, DELETE: 46, BACKSPACE: 8, TAB: 9, ENTER: 13, ESC: 27, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, END: 35, HOME: 36, SPACEBAR: 32, PAGEUP: 33, PAGEDOWN: 34, F2: 113, F10: 121, F12: 123, NUMPAD_PLUS: 107, NUMPAD_MINUS: 109, NUMPAD_DOT: 110 }, support: kendo.support || support, animate: kendo.animate || animate, ns: '', attr: function (value) { return 'data-' + kendo.ns + value; }, getShadows: getShadows, wrap: wrap, deepExtend: deepExtend, getComputedStyles: getComputedStyles, webComponents: kendo.webComponents || [], isScrollable: isScrollable, scrollLeft: scrollLeft, size: size, toCamelCase: toCamelCase, toHyphens: toHyphens, getOffset: kendo.getOffset || getOffset, parseEffects: kendo.parseEffects || parseEffects, toggleClass: kendo.toggleClass || toggleClass, directions: kendo.directions || directions, Observable: Observable, Class: Class, Template: Template, template: proxy(Template.compile, Template), render: proxy(Template.render, Template), stringify: proxy(JSON.stringify, JSON), eventTarget: eventTarget, htmlEncode: htmlEncode, isLocalUrl: function (url) { return url && !localUrlRe.test(url); }, expr: function (expression, safe, paramName) { expression = expression || ''; if (typeof safe == STRING) { paramName = safe; safe = false; } paramName = paramName || 'd'; if (expression && expression.charAt(0) !== '[') { expression = '.' + expression; } if (safe) { expression = expression.replace(/"([^.]*)\.([^"]*)"/g, '"$1_$DOT$_$2"'); expression = expression.replace(/'([^.]*)\.([^']*)'/g, '\'$1_$DOT$_$2\''); expression = wrapExpression(expression.split('.'), paramName); expression = expression.replace(/_\$DOT\$_/g, '.'); } else { expression = paramName + expression; } return expression; }, getter: function (expression, safe) { var key = expression + safe; return getterCache[key] = getterCache[key] || new Function('d', 'return ' + kendo.expr(expression, safe)); }, setter: function (expression) { return setterCache[expression] = setterCache[expression] || new Function('d,value', kendo.expr(expression) + '=value'); }, accessor: function (expression) { return { get: kendo.getter(expression), set: kendo.setter(expression) }; }, guid: function () { var id = '', i, random; for (i = 0; i < 32; i++) { random = math.random() * 16 | 0; if (i == 8 || i == 12 || i == 16 || i == 20) { id += '-'; } id += (i == 12 ? 4 : i == 16 ? random & 3 | 8 : random).toString(16); } return id; }, roleSelector: function (role) { return role.replace(/(\S+)/g, '[' + kendo.attr('role') + '=$1],').slice(0, -1); }, directiveSelector: function (directives) { var selectors = directives.split(' '); if (selectors) { for (var i = 0; i < selectors.length; i++) { if (selectors[i] != 'view') { selectors[i] = selectors[i].replace(/(\w*)(view|bar|strip|over)$/, '$1-$2'); } } } return selectors.join(' ').replace(/(\S+)/g, 'kendo-mobile-$1,').slice(0, -1); }, triggeredByInput: function (e) { return /^(label|input|textarea|select)$/i.test(e.target.tagName); }, onWidgetRegistered: function (callback) { for (var i = 0, len = kendo.widgets.length; i < len; i++) { callback(kendo.widgets[i]); } kendo._widgetRegisteredCallbacks.push(callback); }, logToConsole: function (message, type) { var console = window.console; if (!kendo.suppressLog && typeof console != 'undefined' && console.log) { console[type || 'log'](message); } } }); var Widget = Observable.extend({ init: function (element, options) { var that = this; that.element = kendo.jQuery(element).handler(that); that.angular('init', options); Observable.fn.init.call(that); var dataSource = options ? options.dataSource : null; if (dataSource) { options = extend({}, options, { dataSource: {} }); } options = that.options = extend(true, {}, that.options, options); if (dataSource) { options.dataSource = dataSource; } if (!that.element.attr(kendo.attr('role'))) { that.element.attr(kendo.attr('role'), (options.name || '').toLowerCase()); } that.element.data('kendo' + options.prefix + options.name, that); that.bind(that.events, options); }, events: [], options: { prefix: '' }, _hasBindingTarget: function () { return !!this.element[0].kendoBindingTarget; }, _tabindex: function (target) { target = target || this.wrapper; var element = this.element, TABINDEX = 'tabindex', tabindex = target.attr(TABINDEX) || element.attr(TABINDEX); element.removeAttr(TABINDEX); target.attr(TABINDEX, !isNaN(tabindex) ? tabindex : 0); }, setOptions: function (options) { this._setEvents(options); $.extend(this.options, options); }, _setEvents: function (options) { var that = this, idx = 0, length = that.events.length, e; for (; idx < length; idx++) { e = that.events[idx]; if (that.options[e] && options[e]) { that.unbind(e, that.options[e]); } } that.bind(that.events, options); }, resize: function (force) { var size = this.getSize(), currentSize = this._size; if (force || (size.width > 0 || size.height > 0) && (!currentSize || size.width !== currentSize.width || size.height !== currentSize.height)) { this._size = size; this._resize(size, force); this.trigger('resize', size); } }, getSize: function () { return kendo.dimensions(this.element); }, size: function (size) { if (!size) { return this.getSize(); } else { this.setSize(size); } }, setSize: $.noop, _resize: $.noop, destroy: function () { var that = this; that.element.removeData('kendo' + that.options.prefix + that.options.name); that.element.removeData('handler'); that.unbind(); }, _destroy: function () { this.destroy(); }, angular: function () { }, _muteAngularRebind: function (callback) { this._muteRebind = true; callback.call(this); this._muteRebind = false; } }); var DataBoundWidget = Widget.extend({ dataItems: function () { return this.dataSource.flatView(); }, _angularItems: function (cmd) { var that = this; that.angular(cmd, function () { return { elements: that.items(), data: $.map(that.dataItems(), function (dataItem) { return { dataItem: dataItem }; }) }; }); } }); kendo.dimensions = function (element, dimensions) { var domElement = element[0]; if (dimensions) { element.css(dimensions); } return { width: domElement.offsetWidth, height: domElement.offsetHeight }; }; kendo.notify = noop; var templateRegExp = /template$/i, jsonRegExp = /^\s*(?:\{(?:.|\r\n|\n)*\}|\[(?:.|\r\n|\n)*\])\s*$/, jsonFormatRegExp = /^\{(\d+)(:[^\}]+)?\}|^\[[A-Za-z_]*\]$/, dashRegExp = /([A-Z])/g; function parseOption(element, option) { var value; if (option.indexOf('data') === 0) { option = option.substring(4); option = option.charAt(0).toLowerCase() + option.substring(1); } option = option.replace(dashRegExp, '-$1'); value = element.getAttribute('data-' + kendo.ns + option); if (value === null) { value = undefined; } else if (value === 'null') { value = null; } else if (value === 'true') { value = true; } else if (value === 'false') { value = false; } else if (numberRegExp.test(value)) { value = parseFloat(value); } else if (jsonRegExp.test(value) && !jsonFormatRegExp.test(value)) { value = new Function('return (' + value + ')')(); } return value; } function parseOptions(element, options) { var result = {}, option, value; for (option in options) { value = parseOption(element, option); if (value !== undefined) { if (templateRegExp.test(option)) { value = kendo.template($('#' + value).html()); } result[option] = value; } } return result; } kendo.initWidget = function (element, options, roles) { var result, option, widget, idx, length, role, value, dataSource, fullPath, widgetKeyRegExp; if (!roles) { roles = kendo.ui.roles; } else if (roles.roles) { roles = roles.roles; } element = element.nodeType ? element : element[0]; role = element.getAttribute('data-' + kendo.ns + 'role'); if (!role) { return; } fullPath = role.indexOf('.') === -1; if (fullPath) { widget = roles[role]; } else { widget = kendo.getter(role)(window); } var data = $(element).data(), widgetKey = widget ? 'kendo' + widget.fn.options.prefix + widget.fn.options.name : ''; if (fullPath) { widgetKeyRegExp = new RegExp('^kendo.*' + role + '$', 'i'); } else { widgetKeyRegExp = new RegExp('^' + widgetKey + '$', 'i'); } for (var key in data) { if (key.match(widgetKeyRegExp)) { if (key === widgetKey) { result = data[key]; } else { return data[key]; } } } if (!widget) { return; } dataSource = parseOption(element, 'dataSource'); options = $.extend({}, parseOptions(element, widget.fn.options), options); if (dataSource) { if (typeof dataSource === STRING) { options.dataSource = kendo.getter(dataSource)(window); } else { options.dataSource = dataSource; } } for (idx = 0, length = widget.fn.events.length; idx < length; idx++) { option = widget.fn.events[idx]; value = parseOption(element, option); if (value !== undefined) { options[option] = kendo.getter(value)(window); } } if (!result) { result = new widget(element, options); } else if (!$.isEmptyObject(options)) { result.setOptions(options); } return result; }; kendo.rolesFromNamespaces = function (namespaces) { var roles = [], idx, length; if (!namespaces[0]) { namespaces = [ kendo.ui, kendo.dataviz.ui ]; } for (idx = 0, length = namespaces.length; idx < length; idx++) { roles[idx] = namespaces[idx].roles; } return extend.apply(null, [{}].concat(roles.reverse())); }; kendo.init = function (element) { var roles = kendo.rolesFromNamespaces(slice.call(arguments, 1)); $(element).find('[data-' + kendo.ns + 'role]').addBack().each(function () { kendo.initWidget(this, {}, roles); }); }; kendo.destroy = function (element) { $(element).find('[data-' + kendo.ns + 'role]').addBack().each(function () { var data = $(this).data(); for (var key in data) { if (key.indexOf('kendo') === 0 && typeof data[key].destroy === FUNCTION) { data[key].destroy(); } } }); }; function containmentComparer(a, b) { return $.contains(a, b) ? -1 : 1; } function resizableWidget() { var widget = $(this); return $.inArray(widget.attr('data-' + kendo.ns + 'role'), [ 'slider', 'rangeslider' ]) > -1 || widget.is(':visible'); } kendo.resize = function (element, force) { var widgets = $(element).find('[data-' + kendo.ns + 'role]').addBack().filter(resizableWidget); if (!widgets.length) { return; } var widgetsArray = $.makeArray(widgets); widgetsArray.sort(containmentComparer); $.each(widgetsArray, function () { var widget = kendo.widgetInstance($(this)); if (widget) { widget.resize(force); } }); }; kendo.parseOptions = parseOptions; extend(kendo.ui, { Widget: Widget, DataBoundWidget: DataBoundWidget, roles: {}, progress: function (container, toggle) { var mask = container.find('.k-loading-mask'), support = kendo.support, browser = support.browser, isRtl, leftRight, webkitCorrection, containerScrollLeft; if (toggle) { if (!mask.length) { isRtl = support.isRtl(container); leftRight = isRtl ? 'right' : 'left'; containerScrollLeft = container.scrollLeft(); webkitCorrection = browser.webkit ? !isRtl ? 0 : container[0].scrollWidth - container.width() - 2 * containerScrollLeft : 0; mask = $('
Loading...
').width('100%').height('100%').css('top', container.scrollTop()).css(leftRight, Math.abs(containerScrollLeft) + webkitCorrection).prependTo(container); } } else if (mask) { mask.remove(); } }, plugin: function (widget, register, prefix) { var name = widget.fn.options.name, getter; register = register || kendo.ui; prefix = prefix || ''; register[name] = widget; register.roles[name.toLowerCase()] = widget; getter = 'getKendo' + prefix + name; name = 'kendo' + prefix + name; var widgetEntry = { name: name, widget: widget, prefix: prefix || '' }; kendo.widgets.push(widgetEntry); for (var i = 0, len = kendo._widgetRegisteredCallbacks.length; i < len; i++) { kendo._widgetRegisteredCallbacks[i](widgetEntry); } $.fn[name] = function (options) { var value = this, args; if (typeof options === STRING) { args = slice.call(arguments, 1); this.each(function () { var widget = $.data(this, name), method, result; if (!widget) { throw new Error(kendo.format('Cannot call method \'{0}\' of {1} before it is initialized', options, name)); } method = widget[options]; if (typeof method !== FUNCTION) { throw new Error(kendo.format('Cannot find method \'{0}\' of {1}', options, name)); } result = method.apply(widget, args); if (result !== undefined) { value = result; return false; } }); } else { this.each(function () { return new widget(this, options); }); } return value; }; $.fn[name].widget = widget; $.fn[getter] = function () { return this.data(name); }; } }); var ContainerNullObject = { bind: function () { return this; }, nullObject: true, options: {} }; var MobileWidget = Widget.extend({ init: function (element, options) { Widget.fn.init.call(this, element, options); this.element.autoApplyNS(); this.wrapper = this.element; this.element.addClass('km-widget'); }, destroy: function () { Widget.fn.destroy.call(this); this.element.kendoDestroy(); }, options: { prefix: 'Mobile' }, events: [], view: function () { var viewElement = this.element.closest(kendo.roleSelector('view splitview modalview drawer')); return kendo.widgetInstance(viewElement, kendo.mobile.ui) || ContainerNullObject; }, viewHasNativeScrolling: function () { var view = this.view(); return view && view.options.useNativeScrolling; }, container: function () { var element = this.element.closest(kendo.roleSelector('view layout modalview drawer splitview')); return kendo.widgetInstance(element.eq(0), kendo.mobile.ui) || ContainerNullObject; } }); extend(kendo.mobile, { init: function (element) { kendo.init(element, kendo.mobile.ui, kendo.ui, kendo.dataviz.ui); }, appLevelNativeScrolling: function () { return kendo.mobile.application && kendo.mobile.application.options && kendo.mobile.application.options.useNativeScrolling; }, roles: {}, ui: { Widget: MobileWidget, DataBoundWidget: DataBoundWidget.extend(MobileWidget.prototype), roles: {}, plugin: function (widget) { kendo.ui.plugin(widget, kendo.mobile.ui, 'Mobile'); } } }); deepExtend(kendo.dataviz, { init: function (element) { kendo.init(element, kendo.dataviz.ui); }, ui: { roles: {}, themes: {}, views: [], plugin: function (widget) { kendo.ui.plugin(widget, kendo.dataviz.ui); } }, roles: {} }); kendo.touchScroller = function (elements, options) { if (!options) { options = {}; } options.useNative = true; return $(elements).map(function (idx, element) { element = $(element); if (support.kineticScrollNeeded && kendo.mobile.ui.Scroller && !element.data('kendoMobileScroller')) { element.kendoMobileScroller(options); return element.data('kendoMobileScroller'); } else { return false; } })[0]; }; kendo.preventDefault = function (e) { e.preventDefault(); }; kendo.widgetInstance = function (element, suites) { var role = element.data(kendo.ns + 'role'), widgets = [], i, length; if (role) { if (role === 'content') { role = 'scroller'; } if (suites) { if (suites[0]) { for (i = 0, length = suites.length; i < length; i++) { widgets.push(suites[i].roles[role]); } } else { widgets.push(suites.roles[role]); } } else { widgets = [ kendo.ui.roles[role], kendo.dataviz.ui.roles[role], kendo.mobile.ui.roles[role] ]; } if (role.indexOf('.') >= 0) { widgets = [kendo.getter(role)(window)]; } for (i = 0, length = widgets.length; i < length; i++) { var widget = widgets[i]; if (widget) { var instance = element.data('kendo' + widget.fn.options.prefix + widget.fn.options.name); if (instance) { return instance; } } } } }; kendo.onResize = function (callback) { var handler = callback; if (support.mobileOS.android) { handler = function () { setTimeout(callback, 600); }; } $(window).on(support.resize, handler); return handler; }; kendo.unbindResize = function (callback) { $(window).off(support.resize, callback); }; kendo.attrValue = function (element, key) { return element.data(kendo.ns + key); }; kendo.days = { Sunday: 0, Monday: 1, Tuesday: 2, Wednesday: 3, Thursday: 4, Friday: 5, Saturday: 6 }; function focusable(element, isTabIndexNotNaN) { var nodeName = element.nodeName.toLowerCase(); return (/input|select|textarea|button|object/.test(nodeName) ? !element.disabled : 'a' === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) && visible(element); } function visible(element) { return $.expr.filters.visible(element) && !$(element).parents().addBack().filter(function () { return $.css(this, 'visibility') === 'hidden'; }).length; } $.extend($.expr[':'], { kendoFocusable: function (element) { var idx = $.attr(element, 'tabindex'); return focusable(element, !isNaN(idx) && idx > -1); } }); var MOUSE_EVENTS = [ 'mousedown', 'mousemove', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'mouseup', 'click' ]; var EXCLUDE_BUST_CLICK_SELECTOR = 'label, input, [data-rel=external]'; var MouseEventNormalizer = { setupMouseMute: function () { var idx = 0, length = MOUSE_EVENTS.length, element = document.documentElement; if (MouseEventNormalizer.mouseTrap || !support.eventCapture) { return; } MouseEventNormalizer.mouseTrap = true; MouseEventNormalizer.bustClick = false; MouseEventNormalizer.captureMouse = false; var handler = function (e) { if (MouseEventNormalizer.captureMouse) { if (e.type === 'click') { if (MouseEventNormalizer.bustClick && !$(e.target).is(EXCLUDE_BUST_CLICK_SELECTOR)) { e.preventDefault(); e.stopPropagation(); } } else { e.stopPropagation(); } } }; for (; idx < length; idx++) { element.addEventListener(MOUSE_EVENTS[idx], handler, true); } }, muteMouse: function (e) { MouseEventNormalizer.captureMouse = true; if (e.data.bustClick) { MouseEventNormalizer.bustClick = true; } clearTimeout(MouseEventNormalizer.mouseTrapTimeoutID); }, unMuteMouse: function () { clearTimeout(MouseEventNormalizer.mouseTrapTimeoutID); MouseEventNormalizer.mouseTrapTimeoutID = setTimeout(function () { MouseEventNormalizer.captureMouse = false; MouseEventNormalizer.bustClick = false; }, 400); } }; var eventMap = { down: 'touchstart mousedown', move: 'mousemove touchmove', up: 'mouseup touchend touchcancel', cancel: 'mouseleave touchcancel' }; if (support.touch && (support.mobileOS.ios || support.mobileOS.android)) { eventMap = { down: 'touchstart', move: 'touchmove', up: 'touchend touchcancel', cancel: 'touchcancel' }; } else if (support.pointers) { eventMap = { down: 'pointerdown', move: 'pointermove', up: 'pointerup', cancel: 'pointercancel pointerleave' }; } else if (support.msPointers) { eventMap = { down: 'MSPointerDown', move: 'MSPointerMove', up: 'MSPointerUp', cancel: 'MSPointerCancel MSPointerLeave' }; } if (support.msPointers && !('onmspointerenter' in window)) { $.each({ MSPointerEnter: 'MSPointerOver', MSPointerLeave: 'MSPointerOut' }, function (orig, fix) { $.event.special[orig] = { delegateType: fix, bindType: fix, handle: function (event) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; if (!related || related !== target && !$.contains(target, related)) { event.type = handleObj.origType; ret = handleObj.handler.apply(this, arguments); event.type = fix; } return ret; } }; }); } var getEventMap = function (e) { return eventMap[e] || e; }, eventRegEx = /([^ ]+)/g; kendo.applyEventMap = function (events, ns) { events = events.replace(eventRegEx, getEventMap); if (ns) { events = events.replace(eventRegEx, '$1.' + ns); } return events; }; var on = $.fn.on; function kendoJQuery(selector, context) { return new kendoJQuery.fn.init(selector, context); } extend(true, kendoJQuery, $); kendoJQuery.fn = kendoJQuery.prototype = new $(); kendoJQuery.fn.constructor = kendoJQuery; kendoJQuery.fn.init = function (selector, context) { if (context && context instanceof $ && !(context instanceof kendoJQuery)) { context = kendoJQuery(context); } return $.fn.init.call(this, selector, context, rootjQuery); }; kendoJQuery.fn.init.prototype = kendoJQuery.fn; var rootjQuery = kendoJQuery(document); extend(kendoJQuery.fn, { handler: function (handler) { this.data('handler', handler); return this; }, autoApplyNS: function (ns) { this.data('kendoNS', ns || kendo.guid()); return this; }, on: function () { var that = this, ns = that.data('kendoNS'); if (arguments.length === 1) { return on.call(that, arguments[0]); } var context = that, args = slice.call(arguments); if (typeof args[args.length - 1] === UNDEFINED) { args.pop(); } var callback = args[args.length - 1], events = kendo.applyEventMap(args[0], ns); if (support.mouseAndTouchPresent && events.search(/mouse|click/) > -1 && this[0] !== document.documentElement) { MouseEventNormalizer.setupMouseMute(); var selector = args.length === 2 ? null : args[1], bustClick = events.indexOf('click') > -1 && events.indexOf('touchend') > -1; on.call(this, { touchstart: MouseEventNormalizer.muteMouse, touchend: MouseEventNormalizer.unMuteMouse }, selector, { bustClick: bustClick }); } if (typeof callback === STRING) { context = that.data('handler'); callback = context[callback]; args[args.length - 1] = function (e) { callback.call(context, e); }; } args[0] = events; on.apply(that, args); return that; }, kendoDestroy: function (ns) { ns = ns || this.data('kendoNS'); if (ns) { this.off('.' + ns); } return this; } }); kendo.jQuery = kendoJQuery; kendo.eventMap = eventMap; kendo.timezone = function () { var months = { Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5, Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11 }; var days = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 }; function ruleToDate(year, rule) { var date; var targetDay; var ourDay; var month = rule[3]; var on = rule[4]; var time = rule[5]; var cache = rule[8]; if (!cache) { rule[8] = cache = {}; } if (cache[year]) { return cache[year]; } if (!isNaN(on)) { date = new Date(Date.UTC(year, months[month], on, time[0], time[1], time[2], 0)); } else if (on.indexOf('last') === 0) { date = new Date(Date.UTC(year, months[month] + 1, 1, time[0] - 24, time[1], time[2], 0)); targetDay = days[on.substr(4, 3)]; ourDay = date.getUTCDay(); date.setUTCDate(date.getUTCDate() + targetDay - ourDay - (targetDay > ourDay ? 7 : 0)); } else if (on.indexOf('>=') >= 0) { date = new Date(Date.UTC(year, months[month], on.substr(5), time[0], time[1], time[2], 0)); targetDay = days[on.substr(0, 3)]; ourDay = date.getUTCDay(); date.setUTCDate(date.getUTCDate() + targetDay - ourDay + (targetDay < ourDay ? 7 : 0)); } return cache[year] = date; } function findRule(utcTime, rules, zone) { rules = rules[zone]; if (!rules) { var time = zone.split(':'); var offset = 0; if (time.length > 1) { offset = time[0] * 60 + Number(time[1]); } return [ -1000000, 'max', '-', 'Jan', 1, [ 0, 0, 0 ], offset, '-' ]; } var year = new Date(utcTime).getUTCFullYear(); rules = jQuery.grep(rules, function (rule) { var from = rule[0]; var to = rule[1]; return from <= year && (to >= year || from == year && to == 'only' || to == 'max'); }); rules.push(utcTime); rules.sort(function (a, b) { if (typeof a != 'number') { a = Number(ruleToDate(year, a)); } if (typeof b != 'number') { b = Number(ruleToDate(year, b)); } return a - b; }); var rule = rules[jQuery.inArray(utcTime, rules) - 1] || rules[rules.length - 1]; return isNaN(rule) ? rule : null; } function findZone(utcTime, zones, timezone) { var zoneRules = zones[timezone]; if (typeof zoneRules === 'string') { zoneRules = zones[zoneRules]; } if (!zoneRules) { throw new Error('Timezone "' + timezone + '" is either incorrect, or kendo.timezones.min.js is not included.'); } for (var idx = zoneRules.length - 1; idx >= 0; idx--) { var until = zoneRules[idx][3]; if (until && utcTime > until) { break; } } var zone = zoneRules[idx + 1]; if (!zone) { throw new Error('Timezone "' + timezone + '" not found on ' + utcTime + '.'); } return zone; } function zoneAndRule(utcTime, zones, rules, timezone) { if (typeof utcTime != NUMBER) { utcTime = Date.UTC(utcTime.getFullYear(), utcTime.getMonth(), utcTime.getDate(), utcTime.getHours(), utcTime.getMinutes(), utcTime.getSeconds(), utcTime.getMilliseconds()); } var zone = findZone(utcTime, zones, timezone); return { zone: zone, rule: findRule(utcTime, rules, zone[1]) }; } function offset(utcTime, timezone) { if (timezone == 'Etc/UTC' || timezone == 'Etc/GMT') { return 0; } var info = zoneAndRule(utcTime, this.zones, this.rules, timezone); var zone = info.zone; var rule = info.rule; return kendo.parseFloat(rule ? zone[0] - rule[6] : zone[0]); } function abbr(utcTime, timezone) { var info = zoneAndRule(utcTime, this.zones, this.rules, timezone); var zone = info.zone; var rule = info.rule; var base = zone[2]; if (base.indexOf('/') >= 0) { return base.split('/')[rule && +rule[6] ? 1 : 0]; } else if (base.indexOf('%s') >= 0) { return base.replace('%s', !rule || rule[7] == '-' ? '' : rule[7]); } return base; } function convert(date, fromOffset, toOffset) { if (typeof fromOffset == STRING) { fromOffset = this.offset(date, fromOffset); } if (typeof toOffset == STRING) { toOffset = this.offset(date, toOffset); } var fromLocalOffset = date.getTimezoneOffset(); date = new Date(date.getTime() + (fromOffset - toOffset) * 60000); var toLocalOffset = date.getTimezoneOffset(); return new Date(date.getTime() + (toLocalOffset - fromLocalOffset) * 60000); } function apply(date, timezone) { return this.convert(date, date.getTimezoneOffset(), timezone); } function remove(date, timezone) { return this.convert(date, timezone, date.getTimezoneOffset()); } function toLocalDate(time) { return this.apply(new Date(time), 'Etc/UTC'); } return { zones: {}, rules: {}, offset: offset, convert: convert, apply: apply, remove: remove, abbr: abbr, toLocalDate: toLocalDate }; }(); kendo.date = function () { var MS_PER_MINUTE = 60000, MS_PER_DAY = 86400000; function adjustDST(date, hours) { if (hours === 0 && date.getHours() === 23) { date.setHours(date.getHours() + 2); return true; } return false; } function setDayOfWeek(date, day, dir) { var hours = date.getHours(); dir = dir || 1; day = (day - date.getDay() + 7 * dir) % 7; date.setDate(date.getDate() + day); adjustDST(date, hours); } function dayOfWeek(date, day, dir) { date = new Date(date); setDayOfWeek(date, day, dir); return date; } function firstDayOfMonth(date) { return new Date(date.getFullYear(), date.getMonth(), 1); } function lastDayOfMonth(date) { var last = new Date(date.getFullYear(), date.getMonth() + 1, 0), first = firstDayOfMonth(date), timeOffset = Math.abs(last.getTimezoneOffset() - first.getTimezoneOffset()); if (timeOffset) { last.setHours(first.getHours() + timeOffset / 60); } return last; } function getDate(date) { date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); adjustDST(date, 0); return date; } function toUtcTime(date) { return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); } function getMilliseconds(date) { return date.getTime() - getDate(date); } function isInTimeRange(value, min, max) { var msMin = getMilliseconds(min), msMax = getMilliseconds(max), msValue; if (!value || msMin == msMax) { return true; } if (min >= max) { max += MS_PER_DAY; } msValue = getMilliseconds(value); if (msMin > msValue) { msValue += MS_PER_DAY; } if (msMax < msMin) { msMax += MS_PER_DAY; } return msValue >= msMin && msValue <= msMax; } function isInDateRange(value, min, max) { var msMin = min.getTime(), msMax = max.getTime(), msValue; if (msMin >= msMax) { msMax += MS_PER_DAY; } msValue = value.getTime(); return msValue >= msMin && msValue <= msMax; } function addDays(date, offset) { var hours = date.getHours(); date = new Date(date); setTime(date, offset * MS_PER_DAY); adjustDST(date, hours); return date; } function setTime(date, milliseconds, ignoreDST) { var offset = date.getTimezoneOffset(); var difference; date.setTime(date.getTime() + milliseconds); if (!ignoreDST) { difference = date.getTimezoneOffset() - offset; date.setTime(date.getTime() + difference * MS_PER_MINUTE); } } function setHours(date, time) { date = new Date(kendo.date.getDate(date).getTime() + kendo.date.getMilliseconds(time)); adjustDST(date, time.getHours()); return date; } function today() { return getDate(new Date()); } function isToday(date) { return getDate(date).getTime() == today().getTime(); } function toInvariantTime(date) { var staticDate = new Date(1980, 1, 1, 0, 0, 0); if (date) { staticDate.setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); } return staticDate; } return { adjustDST: adjustDST, dayOfWeek: dayOfWeek, setDayOfWeek: setDayOfWeek, getDate: getDate, isInDateRange: isInDateRange, isInTimeRange: isInTimeRange, isToday: isToday, nextDay: function (date) { return addDays(date, 1); }, previousDay: function (date) { return addDays(date, -1); }, toUtcTime: toUtcTime, MS_PER_DAY: MS_PER_DAY, MS_PER_HOUR: 60 * MS_PER_MINUTE, MS_PER_MINUTE: MS_PER_MINUTE, setTime: setTime, setHours: setHours, addDays: addDays, today: today, toInvariantTime: toInvariantTime, firstDayOfMonth: firstDayOfMonth, lastDayOfMonth: lastDayOfMonth, getMilliseconds: getMilliseconds }; }(); kendo.stripWhitespace = function (element) { if (document.createNodeIterator) { var iterator = document.createNodeIterator(element, NodeFilter.SHOW_TEXT, function (node) { return node.parentNode == element ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; }, false); while (iterator.nextNode()) { if (iterator.referenceNode && !iterator.referenceNode.textContent.trim()) { iterator.referenceNode.parentNode.removeChild(iterator.referenceNode); } } } else { for (var i = 0; i < element.childNodes.length; i++) { var child = element.childNodes[i]; if (child.nodeType == 3 && !/\S/.test(child.nodeValue)) { element.removeChild(child); i--; } if (child.nodeType == 1) { kendo.stripWhitespace(child); } } } }; var animationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { setTimeout(callback, 1000 / 60); }; kendo.animationFrame = function (callback) { animationFrame.call(window, callback); }; var animationQueue = []; kendo.queueAnimation = function (callback) { animationQueue[animationQueue.length] = callback; if (animationQueue.length === 1) { kendo.runNextAnimation(); } }; kendo.runNextAnimation = function () { kendo.animationFrame(function () { if (animationQueue[0]) { animationQueue.shift()(); if (animationQueue[0]) { kendo.runNextAnimation(); } } }); }; kendo.parseQueryStringParams = function (url) { var queryString = url.split('?')[1] || '', params = {}, paramParts = queryString.split(/&|=/), length = paramParts.length, idx = 0; for (; idx < length; idx += 2) { if (paramParts[idx] !== '') { params[decodeURIComponent(paramParts[idx])] = decodeURIComponent(paramParts[idx + 1]); } } return params; }; kendo.elementUnderCursor = function (e) { if (typeof e.x.client != 'undefined') { return document.elementFromPoint(e.x.client, e.y.client); } }; kendo.wheelDeltaY = function (jQueryEvent) { var e = jQueryEvent.originalEvent, deltaY = e.wheelDeltaY, delta; if (e.wheelDelta) { if (deltaY === undefined || deltaY) { delta = e.wheelDelta; } } else if (e.detail && e.axis === e.VERTICAL_AXIS) { delta = -e.detail * 10; } return delta; }; kendo.throttle = function (fn, delay) { var timeout; var lastExecTime = 0; if (!delay || delay <= 0) { return fn; } var throttled = function () { var that = this; var elapsed = +new Date() - lastExecTime; var args = arguments; function exec() { fn.apply(that, args); lastExecTime = +new Date(); } if (!lastExecTime) { return exec(); } if (timeout) { clearTimeout(timeout); } if (elapsed > delay) { exec(); } else { timeout = setTimeout(exec, delay - elapsed); } }; throttled.cancel = function () { clearTimeout(timeout); }; return throttled; }; kendo.caret = function (element, start, end) { var rangeElement; var isPosition = start !== undefined; if (end === undefined) { end = start; } if (element[0]) { element = element[0]; } if (isPosition && element.disabled) { return; } try { if (element.selectionStart !== undefined) { if (isPosition) { element.focus(); element.setSelectionRange(start, end); } else { start = [ element.selectionStart, element.selectionEnd ]; } } else if (document.selection) { if ($(element).is(':visible')) { element.focus(); } rangeElement = element.createTextRange(); if (isPosition) { rangeElement.collapse(true); rangeElement.moveStart('character', start); rangeElement.moveEnd('character', end - start); rangeElement.select(); } else { var rangeDuplicated = rangeElement.duplicate(), selectionStart, selectionEnd; rangeElement.moveToBookmark(document.selection.createRange().getBookmark()); rangeDuplicated.setEndPoint('EndToStart', rangeElement); selectionStart = rangeDuplicated.text.length; selectionEnd = selectionStart + rangeElement.text.length; start = [ selectionStart, selectionEnd ]; } } } catch (e) { start = []; } return start; }; kendo.compileMobileDirective = function (element, scope) { var angular = window.angular; element.attr('data-' + kendo.ns + 'role', element[0].tagName.toLowerCase().replace('kendo-mobile-', '').replace('-', '')); angular.element(element).injector().invoke([ '$compile', function ($compile) { $compile(element)(scope); if (!/^\$(digest|apply)$/.test(scope.$$phase)) { scope.$digest(); } } ]); return kendo.widgetInstance(element, kendo.mobile.ui); }; kendo.antiForgeryTokens = function () { var tokens = {}, csrf_token = $('meta[name=csrf-token],meta[name=_csrf]').attr('content'), csrf_param = $('meta[name=csrf-param],meta[name=_csrf_header]').attr('content'); $('input[name^=\'__RequestVerificationToken\']').each(function () { tokens[this.name] = this.value; }); if (csrf_param !== undefined && csrf_token !== undefined) { tokens[csrf_param] = csrf_token; } return tokens; }; kendo.cycleForm = function (form) { var firstElement = form.find('input, .k-widget').first(); var lastElement = form.find('button, .k-button').last(); function focus(el) { var widget = kendo.widgetInstance(el); if (widget && widget.focus) { widget.focus(); } else { el.focus(); } } lastElement.on('keydown', function (e) { if (e.keyCode == kendo.keys.TAB && !e.shiftKey) { e.preventDefault(); focus(firstElement); } }); firstElement.on('keydown', function (e) { if (e.keyCode == kendo.keys.TAB && e.shiftKey) { e.preventDefault(); focus(lastElement); } }); }; (function () { function postToProxy(dataURI, fileName, proxyURL, proxyTarget) { var form = $('
').attr({ action: proxyURL, method: 'POST', target: proxyTarget }); var data = kendo.antiForgeryTokens(); data.fileName = fileName; var parts = dataURI.split(';base64,'); data.contentType = parts[0].replace('data:', ''); data.base64 = parts[1]; for (var name in data) { if (data.hasOwnProperty(name)) { $('').attr({ value: data[name], name: name, type: 'hidden' }).appendTo(form); } } form.appendTo('body').submit().remove(); } var fileSaver = document.createElement('a'); var downloadAttribute = 'download' in fileSaver && !kendo.support.browser.edge; function saveAsBlob(dataURI, fileName) { var blob = dataURI; if (typeof dataURI == 'string') { var parts = dataURI.split(';base64,'); var contentType = parts[0]; var base64 = atob(parts[1]); var array = new Uint8Array(base64.length); for (var idx = 0; idx < base64.length; idx++) { array[idx] = base64.charCodeAt(idx); } blob = new Blob([array.buffer], { type: contentType }); } navigator.msSaveBlob(blob, fileName); } function saveAsDataURI(dataURI, fileName) { if (window.Blob && dataURI instanceof Blob) { dataURI = URL.createObjectURL(dataURI); } fileSaver.download = fileName; fileSaver.href = dataURI; var e = document.createEvent('MouseEvents'); e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); fileSaver.dispatchEvent(e); } kendo.saveAs = function (options) { var save = postToProxy; if (!options.forceProxy) { if (downloadAttribute) { save = saveAsDataURI; } else if (navigator.msSaveBlob) { save = saveAsBlob; } } save(options.dataURI, options.fileName, options.proxyURL, options.proxyTarget); }; }()); kendo.proxyModelSetters = function proxyModelSetters(data) { var observable = {}; Object.keys(data || {}).forEach(function (property) { Object.defineProperty(observable, property, { get: function () { return data[property]; }, set: function (value) { data[property] = value; data.dirty = true; } }); }); return observable; }; }(jQuery, window)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.router', ['kendo.core'], f); }(function () { var __meta__ = { id: 'router', name: 'Router', category: 'framework', description: 'The Router class is responsible for tracking the application state and navigating between the application states.', depends: ['core'], hidden: false }; (function ($, undefined) { var kendo = window.kendo, CHANGE = 'change', BACK = 'back', SAME = 'same', support = kendo.support, location = window.location, history = window.history, CHECK_URL_INTERVAL = 50, BROKEN_BACK_NAV = kendo.support.browser.msie, hashStrip = /^#*/, document = window.document; function absoluteURL(path, pathPrefix) { if (!pathPrefix) { return path; } if (path + '/' === pathPrefix) { path = pathPrefix; } var regEx = new RegExp('^' + pathPrefix, 'i'); if (!regEx.test(path)) { path = pathPrefix + '/' + path; } return location.protocol + '//' + (location.host + '/' + path).replace(/\/\/+/g, '/'); } function hashDelimiter(bang) { return bang ? '#!' : '#'; } function locationHash(hashDelimiter) { var href = location.href; if (hashDelimiter === '#!' && href.indexOf('#') > -1 && href.indexOf('#!') < 0) { return null; } return href.split(hashDelimiter)[1] || ''; } function stripRoot(root, url) { if (url.indexOf(root) === 0) { return url.substr(root.length).replace(/\/\//g, '/'); } else { return url; } } var HistoryAdapter = kendo.Class.extend({ back: function () { if (BROKEN_BACK_NAV) { setTimeout(function () { history.back(); }); } else { history.back(); } }, forward: function () { if (BROKEN_BACK_NAV) { setTimeout(function () { history.forward(); }); } else { history.forward(); } }, length: function () { return history.length; }, replaceLocation: function (url) { location.replace(url); } }); var PushStateAdapter = HistoryAdapter.extend({ init: function (root) { this.root = root; }, navigate: function (to) { history.pushState({}, document.title, absoluteURL(to, this.root)); }, replace: function (to) { history.replaceState({}, document.title, absoluteURL(to, this.root)); }, normalize: function (url) { return stripRoot(this.root, url); }, current: function () { var current = location.pathname; if (location.search) { current += location.search; } return stripRoot(this.root, current); }, change: function (callback) { $(window).bind('popstate.kendo', callback); }, stop: function () { $(window).unbind('popstate.kendo'); }, normalizeCurrent: function (options) { var fixedUrl, root = options.root, pathname = location.pathname, hash = locationHash(hashDelimiter(options.hashBang)); if (root === pathname + '/') { fixedUrl = root; } if (root === pathname && hash) { fixedUrl = absoluteURL(hash.replace(hashStrip, ''), root); } if (fixedUrl) { history.pushState({}, document.title, fixedUrl); } } }); function fixHash(url) { return url.replace(/^(#)?/, '#'); } function fixBang(url) { return url.replace(/^(#(!)?)?/, '#!'); } var HashAdapter = HistoryAdapter.extend({ init: function (bang) { this._id = kendo.guid(); this.prefix = hashDelimiter(bang); this.fix = bang ? fixBang : fixHash; }, navigate: function (to) { location.hash = this.fix(to); }, replace: function (to) { this.replaceLocation(this.fix(to)); }, normalize: function (url) { if (url.indexOf(this.prefix) < 0) { return url; } else { return url.split(this.prefix)[1]; } }, change: function (callback) { if (support.hashChange) { $(window).on('hashchange.' + this._id, callback); } else { this._interval = setInterval(callback, CHECK_URL_INTERVAL); } }, stop: function () { $(window).off('hashchange.' + this._id); clearInterval(this._interval); }, current: function () { return locationHash(this.prefix); }, normalizeCurrent: function (options) { var pathname = location.pathname, root = options.root; if (options.pushState && root !== pathname) { this.replaceLocation(root + this.prefix + stripRoot(root, pathname)); return true; } return false; } }); var History = kendo.Observable.extend({ start: function (options) { options = options || {}; this.bind([ CHANGE, BACK, SAME ], options); if (this._started) { return; } this._started = true; options.root = options.root || '/'; var adapter = this.createAdapter(options), current; if (adapter.normalizeCurrent(options)) { return; } current = adapter.current(); $.extend(this, { adapter: adapter, root: options.root, historyLength: adapter.length(), current: current, locations: [current] }); adapter.change($.proxy(this, '_checkUrl')); }, createAdapter: function (options) { return support.pushState && options.pushState ? new PushStateAdapter(options.root) : new HashAdapter(options.hashBang); }, stop: function () { if (!this._started) { return; } this.adapter.stop(); this.unbind(CHANGE); this._started = false; }, change: function (callback) { this.bind(CHANGE, callback); }, replace: function (to, silent) { this._navigate(to, silent, function (adapter) { adapter.replace(to); this.locations[this.locations.length - 1] = this.current; }); }, navigate: function (to, silent) { if (to === '#:back') { this.backCalled = true; this.adapter.back(); return; } this._navigate(to, silent, function (adapter) { adapter.navigate(to); this.locations.push(this.current); }); }, _navigate: function (to, silent, callback) { var adapter = this.adapter; to = adapter.normalize(to); if (this.current === to || this.current === decodeURIComponent(to)) { this.trigger(SAME); return; } if (!silent) { if (this.trigger(CHANGE, { url: to })) { return; } } this.current = to; callback.call(this, adapter); this.historyLength = adapter.length(); }, _checkUrl: function () { var adapter = this.adapter, current = adapter.current(), newLength = adapter.length(), navigatingInExisting = this.historyLength === newLength, back = current === this.locations[this.locations.length - 2] && navigatingInExisting, backCalled = this.backCalled, prev = this.current; if (current === null || this.current === current || this.current === decodeURIComponent(current)) { return true; } this.historyLength = newLength; this.backCalled = false; this.current = current; if (back && this.trigger('back', { url: prev, to: current })) { adapter.forward(); this.current = prev; return; } if (this.trigger(CHANGE, { url: current, backButtonPressed: !backCalled })) { if (back) { adapter.forward(); } else { adapter.back(); this.historyLength--; } this.current = prev; return; } if (back) { this.locations.pop(); } else { this.locations.push(current); } } }); kendo.History = History; kendo.History.HistoryAdapter = HistoryAdapter; kendo.History.HashAdapter = HashAdapter; kendo.History.PushStateAdapter = PushStateAdapter; kendo.absoluteURL = absoluteURL; kendo.history = new History(); }(window.kendo.jQuery)); (function () { var kendo = window.kendo, history = kendo.history, Observable = kendo.Observable, INIT = 'init', ROUTE_MISSING = 'routeMissing', CHANGE = 'change', BACK = 'back', SAME = 'same', optionalParam = /\((.*?)\)/g, namedParam = /(\(\?)?:\w+/g, splatParam = /\*\w+/g, escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; function namedParamReplace(match, optional) { return optional ? match : '([^/]+)'; } function routeToRegExp(route, ignoreCase) { return new RegExp('^' + route.replace(escapeRegExp, '\\$&').replace(optionalParam, '(?:$1)?').replace(namedParam, namedParamReplace).replace(splatParam, '(.*?)') + '$', ignoreCase ? 'i' : ''); } function stripUrl(url) { return url.replace(/(\?.*)|(#.*)/g, ''); } var Route = kendo.Class.extend({ init: function (route, callback, ignoreCase) { if (!(route instanceof RegExp)) { route = routeToRegExp(route, ignoreCase); } this.route = route; this._callback = callback; }, callback: function (url, back) { var params, idx = 0, length, queryStringParams = kendo.parseQueryStringParams(url); queryStringParams._back = back; url = stripUrl(url); params = this.route.exec(url).slice(1); length = params.length; for (; idx < length; idx++) { if (typeof params[idx] !== 'undefined') { params[idx] = decodeURIComponent(params[idx]); } } params.push(queryStringParams); this._callback.apply(null, params); }, worksWith: function (url, back) { if (this.route.test(stripUrl(url))) { this.callback(url, back); return true; } else { return false; } } }); var Router = Observable.extend({ init: function (options) { if (!options) { options = {}; } Observable.fn.init.call(this); this.routes = []; this.pushState = options.pushState; this.hashBang = options.hashBang; this.root = options.root; this.ignoreCase = options.ignoreCase !== false; this.bind([ INIT, ROUTE_MISSING, CHANGE, SAME ], options); }, destroy: function () { history.unbind(CHANGE, this._urlChangedProxy); history.unbind(SAME, this._sameProxy); history.unbind(BACK, this._backProxy); this.unbind(); }, start: function () { var that = this, sameProxy = function () { that._same(); }, backProxy = function (e) { that._back(e); }, urlChangedProxy = function (e) { that._urlChanged(e); }; history.start({ same: sameProxy, change: urlChangedProxy, back: backProxy, pushState: that.pushState, hashBang: that.hashBang, root: that.root }); var initEventObject = { url: history.current || '/', preventDefault: $.noop }; if (!that.trigger(INIT, initEventObject)) { that._urlChanged(initEventObject); } this._urlChangedProxy = urlChangedProxy; this._backProxy = backProxy; }, route: function (route, callback) { this.routes.push(new Route(route, callback, this.ignoreCase)); }, navigate: function (url, silent) { kendo.history.navigate(url, silent); }, replace: function (url, silent) { kendo.history.replace(url, silent); }, _back: function (e) { if (this.trigger(BACK, { url: e.url, to: e.to })) { e.preventDefault(); } }, _same: function () { this.trigger(SAME); }, _urlChanged: function (e) { var url = e.url; var back = e.backButtonPressed; if (!url) { url = '/'; } if (this.trigger(CHANGE, { url: e.url, params: kendo.parseQueryStringParams(e.url), backButtonPressed: back })) { e.preventDefault(); return; } var idx = 0, routes = this.routes, route, length = routes.length; for (; idx < length; idx++) { route = routes[idx]; if (route.worksWith(url, back)) { return; } } if (this.trigger(ROUTE_MISSING, { url: url, params: kendo.parseQueryStringParams(url), backButtonPressed: back })) { e.preventDefault(); } } }); kendo.Router = Router; }()); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.data.odata', ['kendo.core'], f); }(function () { var __meta__ = { id: 'data.odata', name: 'OData', category: 'framework', depends: ['core'], hidden: true }; (function ($, undefined) { var kendo = window.kendo, extend = $.extend, odataFilters = { eq: 'eq', neq: 'ne', gt: 'gt', gte: 'ge', lt: 'lt', lte: 'le', contains: 'substringof', doesnotcontain: 'substringof', endswith: 'endswith', startswith: 'startswith', isnull: 'eq', isnotnull: 'ne', isempty: 'eq', isnotempty: 'ne' }, odataFiltersVersionFour = extend({}, odataFilters, { contains: 'contains' }), mappers = { pageSize: $.noop, page: $.noop, filter: function (params, filter, useVersionFour) { if (filter) { filter = toOdataFilter(filter, useVersionFour); if (filter) { params.$filter = filter; } } }, sort: function (params, orderby) { var expr = $.map(orderby, function (value) { var order = value.field.replace(/\./g, '/'); if (value.dir === 'desc') { order += ' desc'; } return order; }).join(','); if (expr) { params.$orderby = expr; } }, skip: function (params, skip) { if (skip) { params.$skip = skip; } }, take: function (params, take) { if (take) { params.$top = take; } } }, defaultDataType = { read: { dataType: 'jsonp' } }; function toOdataFilter(filter, useOdataFour) { var result = [], logic = filter.logic || 'and', idx, length, field, type, format, operator, value, ignoreCase, filters = filter.filters; for (idx = 0, length = filters.length; idx < length; idx++) { filter = filters[idx]; field = filter.field; value = filter.value; operator = filter.operator; if (filter.filters) { filter = toOdataFilter(filter, useOdataFour); } else { ignoreCase = filter.ignoreCase; field = field.replace(/\./g, '/'); filter = odataFilters[operator]; if (useOdataFour) { filter = odataFiltersVersionFour[operator]; } if (operator === 'isnull' || operator === 'isnotnull') { filter = kendo.format('{0} {1} null', field, filter); } else if (operator === 'isempty' || operator === 'isnotempty') { filter = kendo.format('{0} {1} \'\'', field, filter); } else if (filter && value !== undefined) { type = $.type(value); if (type === 'string') { format = '\'{1}\''; value = value.replace(/'/g, '\'\''); if (ignoreCase === true) { field = 'tolower(' + field + ')'; } } else if (type === 'date') { if (useOdataFour) { format = '{1:yyyy-MM-ddTHH:mm:ss+00:00}'; } else { format = 'datetime\'{1:yyyy-MM-ddTHH:mm:ss}\''; } } else { format = '{1}'; } if (filter.length > 3) { if (filter !== 'substringof') { format = '{0}({2},' + format + ')'; } else { format = '{0}(' + format + ',{2})'; if (operator === 'doesnotcontain') { if (useOdataFour) { format = '{0}({2},\'{1}\') eq -1'; filter = 'indexof'; } else { format += ' eq false'; } } } } else { format = '{2} {0} ' + format; } filter = kendo.format(format, filter, value, field); } } result.push(filter); } filter = result.join(' ' + logic + ' '); if (result.length > 1) { filter = '(' + filter + ')'; } return filter; } function stripMetadata(obj) { for (var name in obj) { if (name.indexOf('@odata') === 0) { delete obj[name]; } } } extend(true, kendo.data, { schemas: { odata: { type: 'json', data: function (data) { return data.d.results || [data.d]; }, total: 'd.__count' } }, transports: { odata: { read: { cache: true, dataType: 'jsonp', jsonp: '$callback' }, update: { cache: true, dataType: 'json', contentType: 'application/json', type: 'PUT' }, create: { cache: true, dataType: 'json', contentType: 'application/json', type: 'POST' }, destroy: { cache: true, dataType: 'json', type: 'DELETE' }, parameterMap: function (options, type, useVersionFour) { var params, value, option, dataType; options = options || {}; type = type || 'read'; dataType = (this.options || defaultDataType)[type]; dataType = dataType ? dataType.dataType : 'json'; if (type === 'read') { params = { $inlinecount: 'allpages' }; if (dataType != 'json') { params.$format = 'json'; } for (option in options) { if (mappers[option]) { mappers[option](params, options[option], useVersionFour); } else { params[option] = options[option]; } } } else { if (dataType !== 'json') { throw new Error('Only json dataType can be used for ' + type + ' operation.'); } if (type !== 'destroy') { for (option in options) { value = options[option]; if (typeof value === 'number') { options[option] = value + ''; } } params = kendo.stringify(options); } } return params; } } } }); extend(true, kendo.data, { schemas: { 'odata-v4': { type: 'json', data: function (data) { data = $.extend({}, data); stripMetadata(data); if (data.value) { return data.value; } return [data]; }, total: function (data) { return data['@odata.count']; } } }, transports: { 'odata-v4': { read: { cache: true, dataType: 'json' }, update: { cache: true, dataType: 'json', contentType: 'application/json;IEEE754Compatible=true', type: 'PUT' }, create: { cache: true, dataType: 'json', contentType: 'application/json;IEEE754Compatible=true', type: 'POST' }, destroy: { cache: true, dataType: 'json', type: 'DELETE' }, parameterMap: function (options, type) { var result = kendo.data.transports.odata.parameterMap(options, type, true); if (type == 'read') { result.$count = true; delete result.$inlinecount; } return result; } } } }); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.data.xml', ['kendo.core'], f); }(function () { var __meta__ = { id: 'data.xml', name: 'XML', category: 'framework', depends: ['core'], hidden: true }; (function ($, undefined) { var kendo = window.kendo, isArray = $.isArray, isPlainObject = $.isPlainObject, map = $.map, each = $.each, extend = $.extend, getter = kendo.getter, Class = kendo.Class; var XmlDataReader = Class.extend({ init: function (options) { var that = this, total = options.total, model = options.model, parse = options.parse, errors = options.errors, serialize = options.serialize, data = options.data; if (model) { if (isPlainObject(model)) { var base = options.modelBase || kendo.data.Model; if (model.fields) { each(model.fields, function (field, value) { if (isPlainObject(value) && value.field) { if (!$.isFunction(value.field)) { value = extend(value, { field: that.getter(value.field) }); } } else { value = { field: that.getter(value) }; } model.fields[field] = value; }); } var id = model.id; if (id) { var idField = {}; idField[that.xpathToMember(id, true)] = { field: that.getter(id) }; model.fields = extend(idField, model.fields); model.id = that.xpathToMember(id); } model = base.define(model); } that.model = model; } if (total) { if (typeof total == 'string') { total = that.getter(total); that.total = function (data) { return parseInt(total(data), 10); }; } else if (typeof total == 'function') { that.total = total; } } if (errors) { if (typeof errors == 'string') { errors = that.getter(errors); that.errors = function (data) { return errors(data) || null; }; } else if (typeof errors == 'function') { that.errors = errors; } } if (data) { if (typeof data == 'string') { data = that.xpathToMember(data); that.data = function (value) { var result = that.evaluate(value, data), modelInstance; result = isArray(result) ? result : [result]; if (that.model && model.fields) { modelInstance = new that.model(); return map(result, function (value) { if (value) { var record = {}, field; for (field in model.fields) { record[field] = modelInstance._parse(field, model.fields[field].field(value)); } return record; } }); } return result; }; } else if (typeof data == 'function') { that.data = data; } } if (typeof parse == 'function') { var xmlParse = that.parse; that.parse = function (data) { var xml = parse.call(that, data); return xmlParse.call(that, xml); }; } if (typeof serialize == 'function') { that.serialize = serialize; } }, total: function (result) { return this.data(result).length; }, errors: function (data) { return data ? data.errors : null; }, serialize: function (data) { return data; }, parseDOM: function (element) { var result = {}, parsedNode, node, nodeType, nodeName, member, attribute, attributes = element.attributes, attributeCount = attributes.length, idx; for (idx = 0; idx < attributeCount; idx++) { attribute = attributes[idx]; result['@' + attribute.nodeName] = attribute.nodeValue; } for (node = element.firstChild; node; node = node.nextSibling) { nodeType = node.nodeType; if (nodeType === 3 || nodeType === 4) { result['#text'] = node.nodeValue; } else if (nodeType === 1) { parsedNode = this.parseDOM(node); nodeName = node.nodeName; member = result[nodeName]; if (isArray(member)) { member.push(parsedNode); } else if (member !== undefined) { member = [ member, parsedNode ]; } else { member = parsedNode; } result[nodeName] = member; } } return result; }, evaluate: function (value, expression) { var members = expression.split('.'), member, result, length, intermediateResult, idx; while (member = members.shift()) { value = value[member]; if (isArray(value)) { result = []; expression = members.join('.'); for (idx = 0, length = value.length; idx < length; idx++) { intermediateResult = this.evaluate(value[idx], expression); intermediateResult = isArray(intermediateResult) ? intermediateResult : [intermediateResult]; result.push.apply(result, intermediateResult); } return result; } } return value; }, parse: function (xml) { var documentElement, tree, result = {}; documentElement = xml.documentElement || $.parseXML(xml).documentElement; tree = this.parseDOM(documentElement); result[documentElement.nodeName] = tree; return result; }, xpathToMember: function (member, raw) { if (!member) { return ''; } member = member.replace(/^\//, '').replace(/\//g, '.'); if (member.indexOf('@') >= 0) { return member.replace(/\.?(@.*)/, raw ? '$1' : '["$1"]'); } if (member.indexOf('text()') >= 0) { return member.replace(/(\.?text\(\))/, raw ? '#text' : '["#text"]'); } return member; }, getter: function (member) { return getter(this.xpathToMember(member), true); } }); $.extend(true, kendo.data, { XmlDataReader: XmlDataReader, readers: { xml: XmlDataReader } }); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.data', [ 'kendo.core', 'kendo.data.odata', 'kendo.data.xml' ], f); }(function () { var __meta__ = { id: 'data', name: 'Data source', category: 'framework', description: 'Powerful component for using local and remote data.Fully supports CRUD, Sorting, Paging, Filtering, Grouping, and Aggregates.', depends: ['core'], features: [ { id: 'data-odata', name: 'OData', description: 'Support for accessing Open Data Protocol (OData) services.', depends: ['data.odata'] }, { id: 'data-signalr', name: 'SignalR', description: 'Support for binding to SignalR hubs.', depends: ['data.signalr'] }, { id: 'data-XML', name: 'XML', description: 'Support for binding to XML.', depends: ['data.xml'] } ] }; (function ($, undefined) { 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', CREATE = 'create', READ = 'read', UPDATE = 'update', DESTROY = 'destroy', CHANGE = 'change', SYNC = 'sync', GET = 'get', ERROR = 'error', REQUESTSTART = 'requestStart', PROGRESS = 'progress', REQUESTEND = 'requestEnd', crud = [ CREATE, READ, UPDATE, DESTROY ], identity = function (o) { return o; }, getter = kendo.getter, stringify = kendo.stringify, math = Math, push = [].push, join = [].join, pop = [].pop, splice = [].splice, shift = [].shift, slice = [].slice, unshift = [].unshift, toString = {}.toString, stableSort = kendo.support.stableSort, dateRegExp = /^\/Date\((.*?)\)\/$/, newLineRegExp = /(\r+|\n+)/g, quoteRegExp = /(?=['\\])/g; var ObservableArray = Observable.extend({ init: function (array, type) { var that = this; that.type = type || ObservableObject; Observable.fn.init.call(that); that.length = array.length; that.wrapAll(array, that); }, at: function (index) { return this[index]; }, toJSON: function () { var idx, length = this.length, value, json = new Array(length); for (idx = 0; idx < length; idx++) { value = this[idx]; if (value instanceof ObservableObject) { value = value.toJSON(); } json[idx] = value; } return json; }, parent: noop, wrapAll: function (source, target) { var that = this, idx, length, parent = function () { return that; }; target = target || []; for (idx = 0, length = source.length; idx < length; idx++) { target[idx] = that.wrap(source[idx], parent); } return target; }, wrap: function (object, parent) { var that = this, observable; if (object !== null && toString.call(object) === '[object Object]') { observable = object instanceof that.type || object instanceof Model; if (!observable) { object = object instanceof ObservableObject ? object.toJSON() : object; object = new that.type(object); } object.parent = parent; object.bind(CHANGE, function (e) { that.trigger(CHANGE, { field: e.field, node: e.node, index: e.index, items: e.items || [this], action: e.node ? e.action || 'itemloaded' : 'itemchange' }); }); } return object; }, push: function () { var index = this.length, items = this.wrapAll(arguments), result; result = push.apply(this, items); this.trigger(CHANGE, { action: 'add', index: index, items: items }); return result; }, slice: slice, sort: [].sort, join: join, pop: function () { var length = this.length, result = pop.apply(this); if (length) { this.trigger(CHANGE, { action: 'remove', index: length - 1, items: [result] }); } return result; }, splice: function (index, howMany, item) { var items = this.wrapAll(slice.call(arguments, 2)), result, i, len; result = splice.apply(this, [ index, howMany ].concat(items)); if (result.length) { this.trigger(CHANGE, { action: 'remove', index: index, items: result }); for (i = 0, len = result.length; i < len; i++) { if (result[i] && result[i].children) { result[i].unbind(CHANGE); } } } if (item) { this.trigger(CHANGE, { action: 'add', index: index, items: items }); } return result; }, shift: function () { var length = this.length, result = shift.apply(this); if (length) { this.trigger(CHANGE, { action: 'remove', index: 0, items: [result] }); } return result; }, unshift: function () { var items = this.wrapAll(arguments), result; result = unshift.apply(this, items); this.trigger(CHANGE, { action: 'add', index: 0, items: items }); return result; }, indexOf: function (item) { var that = this, idx, length; for (idx = 0, length = that.length; idx < length; idx++) { if (that[idx] === item) { return idx; } } return -1; }, forEach: function (callback) { var idx = 0, length = this.length; for (; idx < length; idx++) { callback(this[idx], idx, this); } }, map: function (callback) { var idx = 0, result = [], length = this.length; for (; idx < length; idx++) { result[idx] = callback(this[idx], idx, this); } return result; }, reduce: function (callback) { var idx = 0, result, length = this.length; if (arguments.length == 2) { result = arguments[1]; } else if (idx < length) { result = this[idx++]; } for (; idx < length; idx++) { result = callback(result, this[idx], idx, this); } return result; }, reduceRight: function (callback) { var idx = this.length - 1, result; if (arguments.length == 2) { result = arguments[1]; } else if (idx > 0) { result = this[idx--]; } for (; idx >= 0; idx--) { result = callback(result, this[idx], idx, this); } return result; }, filter: function (callback) { var idx = 0, result = [], item, length = this.length; for (; idx < length; idx++) { item = this[idx]; if (callback(item, idx, this)) { result[result.length] = item; } } return result; }, find: function (callback) { var idx = 0, item, length = this.length; for (; idx < length; idx++) { item = this[idx]; if (callback(item, idx, this)) { return item; } } }, every: function (callback) { var idx = 0, item, length = this.length; for (; idx < length; idx++) { item = this[idx]; if (!callback(item, idx, this)) { return false; } } return true; }, some: function (callback) { var idx = 0, item, length = this.length; for (; idx < length; idx++) { item = this[idx]; if (callback(item, idx, this)) { return true; } } return false; }, remove: function (item) { var idx = this.indexOf(item); if (idx !== -1) { this.splice(idx, 1); } }, empty: function () { this.splice(0, this.length); } }); var LazyObservableArray = ObservableArray.extend({ init: function (data, type) { Observable.fn.init.call(this); this.type = type || ObservableObject; for (var idx = 0; idx < data.length; idx++) { this[idx] = data[idx]; } this.length = idx; this._parent = proxy(function () { return this; }, this); }, at: function (index) { var item = this[index]; if (!(item instanceof this.type)) { item = this[index] = this.wrap(item, this._parent); } else { item.parent = this._parent; } return item; } }); function eventHandler(context, type, field, prefix) { return function (e) { var event = {}, key; for (key in e) { event[key] = e[key]; } if (prefix) { event.field = field + '.' + e.field; } else { event.field = field; } if (type == CHANGE && context._notifyChange) { context._notifyChange(event); } context.trigger(type, event); }; } var ObservableObject = Observable.extend({ init: function (value) { var that = this, member, field, parent = function () { return that; }; Observable.fn.init.call(this); this._handlers = {}; for (field in value) { member = value[field]; if (typeof member === 'object' && member && !member.getTime && field.charAt(0) != '_') { member = that.wrap(member, field, parent); } that[field] = member; } that.uid = kendo.guid(); }, shouldSerialize: function (field) { return this.hasOwnProperty(field) && field !== '_handlers' && field !== '_events' && typeof this[field] !== FUNCTION && field !== 'uid'; }, forEach: function (f) { for (var i in this) { if (this.shouldSerialize(i)) { f(this[i], i); } } }, toJSON: function () { var result = {}, value, field; for (field in this) { if (this.shouldSerialize(field)) { value = this[field]; if (value instanceof ObservableObject || value instanceof ObservableArray) { value = value.toJSON(); } result[field] = value; } } return result; }, get: function (field) { var that = this, result; that.trigger(GET, { field: field }); if (field === 'this') { result = that; } else { result = kendo.getter(field, true)(that); } return result; }, _set: function (field, value) { var that = this; var composite = field.indexOf('.') >= 0; if (composite) { var paths = field.split('.'), path = ''; while (paths.length > 1) { path += paths.shift(); var obj = kendo.getter(path, true)(that); if (obj instanceof ObservableObject) { obj.set(paths.join('.'), value); return composite; } path += '.'; } } kendo.setter(field)(that, value); return composite; }, set: function (field, value) { var that = this, isSetPrevented = false, composite = field.indexOf('.') >= 0, current = kendo.getter(field, true)(that); if (current !== value) { if (current instanceof Observable && this._handlers[field]) { if (this._handlers[field].get) { current.unbind(GET, this._handlers[field].get); } current.unbind(CHANGE, this._handlers[field].change); } isSetPrevented = that.trigger('set', { field: field, value: value }); if (!isSetPrevented) { if (!composite) { value = that.wrap(value, field, function () { return that; }); } if (!that._set(field, value) || field.indexOf('(') >= 0 || field.indexOf('[') >= 0) { that.trigger(CHANGE, { field: field }); } } } return isSetPrevented; }, parent: noop, wrap: function (object, field, parent) { var that = this; var get; var change; var type = toString.call(object); if (object != null && (type === '[object Object]' || type === '[object Array]')) { var isObservableArray = object instanceof ObservableArray; var isDataSource = object instanceof DataSource; if (type === '[object Object]' && !isDataSource && !isObservableArray) { if (!(object instanceof ObservableObject)) { object = new ObservableObject(object); } get = eventHandler(that, GET, field, true); object.bind(GET, get); change = eventHandler(that, CHANGE, field, true); object.bind(CHANGE, change); that._handlers[field] = { get: get, change: change }; } else if (type === '[object Array]' || isObservableArray || isDataSource) { if (!isObservableArray && !isDataSource) { object = new ObservableArray(object); } change = eventHandler(that, CHANGE, field, false); object.bind(CHANGE, change); that._handlers[field] = { change: change }; } object.parent = parent; } return object; } }); function equal(x, y) { if (x === y) { return true; } var xtype = $.type(x), ytype = $.type(y), field; if (xtype !== ytype) { return false; } if (xtype === 'date') { return x.getTime() === y.getTime(); } if (xtype !== 'object' && xtype !== 'array') { return false; } for (field in x) { if (!equal(x[field], y[field])) { return false; } } return true; } var parsers = { 'number': function (value) { return kendo.parseFloat(value); }, 'date': function (value) { return kendo.parseDate(value); }, 'boolean': function (value) { if (typeof value === STRING) { return value.toLowerCase() === 'true'; } return value != null ? !!value : value; }, 'string': function (value) { return value != null ? value + '' : value; }, 'default': function (value) { return value; } }; var defaultValues = { 'string': '', 'number': 0, 'date': new Date(), 'boolean': false, 'default': '' }; function getFieldByName(obj, name) { var field, fieldName; for (fieldName in obj) { field = obj[fieldName]; if (isPlainObject(field) && field.field && field.field === name) { return field; } else if (field === name) { return field; } } return null; } var Model = ObservableObject.extend({ init: function (data) { var that = this; if (!data || $.isEmptyObject(data)) { data = $.extend({}, that.defaults, data); if (that._initializers) { for (var idx = 0; idx < that._initializers.length; idx++) { var name = that._initializers[idx]; data[name] = that.defaults[name](); } } } ObservableObject.fn.init.call(that, data); that.dirty = false; if (that.idField) { that.id = that.get(that.idField); if (that.id === undefined) { that.id = that._defaultId; } } }, shouldSerialize: function (field) { return ObservableObject.fn.shouldSerialize.call(this, field) && field !== 'uid' && !(this.idField !== 'id' && field === 'id') && field !== 'dirty' && field !== '_accessors'; }, _parse: function (field, value) { var that = this, fieldName = field, fields = that.fields || {}, parse; field = fields[field]; if (!field) { field = getFieldByName(fields, fieldName); } if (field) { parse = field.parse; if (!parse && field.type) { parse = parsers[field.type.toLowerCase()]; } } return parse ? parse(value) : value; }, _notifyChange: function (e) { var action = e.action; if (action == 'add' || action == 'remove') { this.dirty = true; } }, editable: function (field) { field = (this.fields || {})[field]; return field ? field.editable !== false : true; }, set: function (field, value, initiator) { var that = this; var dirty = that.dirty; if (that.editable(field)) { value = that._parse(field, value); if (!equal(value, that.get(field))) { that.dirty = true; if (ObservableObject.fn.set.call(that, field, value, initiator) && !dirty) { that.dirty = dirty; } } } }, accept: function (data) { var that = this, parent = function () { return that; }, field; for (field in data) { var value = data[field]; if (field.charAt(0) != '_') { value = that.wrap(data[field], field, parent); } that._set(field, value); } if (that.idField) { that.id = that.get(that.idField); } that.dirty = false; }, isNew: function () { return this.id === this._defaultId; } }); Model.define = function (base, options) { if (options === undefined) { options = base; base = Model; } var model, proto = extend({ defaults: {} }, options), name, field, type, value, idx, length, fields = {}, originalName, id = proto.id, functionFields = []; if (id) { proto.idField = id; } if (proto.id) { delete proto.id; } if (id) { proto.defaults[id] = proto._defaultId = ''; } if (toString.call(proto.fields) === '[object Array]') { for (idx = 0, length = proto.fields.length; idx < length; idx++) { field = proto.fields[idx]; if (typeof field === STRING) { fields[field] = {}; } else if (field.field) { fields[field.field] = field; } } proto.fields = fields; } for (name in proto.fields) { field = proto.fields[name]; type = field.type || 'default'; value = null; originalName = name; name = typeof field.field === STRING ? field.field : name; if (!field.nullable) { value = proto.defaults[originalName !== name ? originalName : name] = field.defaultValue !== undefined ? field.defaultValue : defaultValues[type.toLowerCase()]; if (typeof value === 'function') { functionFields.push(name); } } if (options.id === name) { proto._defaultId = value; } proto.defaults[originalName !== name ? originalName : name] = value; field.parse = field.parse || parsers[type]; } if (functionFields.length > 0) { proto._initializers = functionFields; } model = base.extend(proto); model.define = function (options) { return Model.define(model, options); }; if (proto.fields) { model.fields = proto.fields; model.idField = proto.idField; } return model; }; var Comparer = { selector: function (field) { return isFunction(field) ? field : getter(field); }, compare: function (field) { var selector = this.selector(field); return function (a, b) { a = selector(a); b = selector(b); if (a == null && b == null) { return 0; } if (a == null) { return -1; } if (b == null) { return 1; } if (a.localeCompare) { return a.localeCompare(b); } return a > b ? 1 : a < b ? -1 : 0; }; }, create: function (sort) { var compare = sort.compare || this.compare(sort.field); if (sort.dir == 'desc') { return function (a, b) { return compare(b, a, true); }; } return compare; }, combine: function (comparers) { return function (a, b) { var result = comparers[0](a, b), idx, length; for (idx = 1, length = comparers.length; idx < length; idx++) { result = result || comparers[idx](a, b); } return result; }; } }; var StableComparer = extend({}, Comparer, { asc: function (field) { var selector = this.selector(field); return function (a, b) { var valueA = selector(a); var valueB = selector(b); if (valueA && valueA.getTime && valueB && valueB.getTime) { valueA = valueA.getTime(); valueB = valueB.getTime(); } if (valueA === valueB) { return a.__position - b.__position; } if (valueA == null) { return -1; } if (valueB == null) { return 1; } if (valueA.localeCompare) { return valueA.localeCompare(valueB); } return valueA > valueB ? 1 : -1; }; }, desc: function (field) { var selector = this.selector(field); return function (a, b) { var valueA = selector(a); var valueB = selector(b); if (valueA && valueA.getTime && valueB && valueB.getTime) { valueA = valueA.getTime(); valueB = valueB.getTime(); } if (valueA === valueB) { return a.__position - b.__position; } if (valueA == null) { return 1; } if (valueB == null) { return -1; } if (valueB.localeCompare) { return valueB.localeCompare(valueA); } return valueA < valueB ? 1 : -1; }; }, create: function (sort) { return this[sort.dir](sort.field); } }); map = function (array, callback) { var idx, length = array.length, result = new Array(length); for (idx = 0; idx < length; idx++) { result[idx] = callback(array[idx], idx, array); } return result; }; var operators = function () { function quote(value) { return value.replace(quoteRegExp, '\\').replace(newLineRegExp, ''); } function operator(op, a, b, ignore) { var date; if (b != null) { if (typeof b === STRING) { b = quote(b); date = dateRegExp.exec(b); if (date) { b = new Date(+date[1]); } else if (ignore) { b = '\'' + b.toLowerCase() + '\''; a = '((' + a + ' || \'\')+\'\').toLowerCase()'; } else { b = '\'' + b + '\''; } } if (b.getTime) { a = '(' + a + '&&' + a + '.getTime?' + a + '.getTime():' + a + ')'; b = b.getTime(); } } return a + ' ' + op + ' ' + b; } return { quote: function (value) { if (value && value.getTime) { return 'new Date(' + value.getTime() + ')'; } if (typeof value == 'string') { return '\'' + quote(value) + '\''; } return '' + value; }, eq: function (a, b, ignore) { return operator('==', a, b, ignore); }, neq: function (a, b, ignore) { return operator('!=', a, b, ignore); }, gt: function (a, b, ignore) { return operator('>', a, b, ignore); }, gte: function (a, b, ignore) { return operator('>=', a, b, ignore); }, lt: function (a, b, ignore) { return operator('<', a, b, ignore); }, lte: function (a, b, ignore) { return operator('<=', a, b, ignore); }, startswith: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.lastIndexOf(\'' + b + '\', 0) == 0'; }, doesnotstartwith: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.lastIndexOf(\'' + b + '\', 0) == -1'; }, endswith: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.indexOf(\'' + b + '\', ' + a + '.length - ' + (b || '').length + ') >= 0'; }, doesnotendwith: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.indexOf(\'' + b + '\', ' + a + '.length - ' + (b || '').length + ') < 0'; }, contains: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.indexOf(\'' + b + '\') >= 0'; }, doesnotcontain: function (a, b, ignore) { if (ignore) { a = '(' + a + ' || \'\').toLowerCase()'; if (b) { b = b.toLowerCase(); } } if (b) { b = quote(b); } return a + '.indexOf(\'' + b + '\') == -1'; }, isempty: function (a) { return a + ' === \'\''; }, isnotempty: function (a) { return a + ' !== \'\''; }, isnull: function (a) { return '(' + a + ' === null || ' + a + ' === undefined)'; }, isnotnull: function (a) { return '(' + a + ' !== null && ' + a + ' !== undefined)'; } }; }(); function Query(data) { this.data = data || []; } Query.filterExpr = function (expression) { var expressions = [], logic = { and: ' && ', or: ' || ' }, idx, length, filter, expr, fieldFunctions = [], operatorFunctions = [], field, operator, filters = expression.filters; for (idx = 0, length = filters.length; idx < length; idx++) { filter = filters[idx]; field = filter.field; operator = filter.operator; if (filter.filters) { expr = Query.filterExpr(filter); filter = expr.expression.replace(/__o\[(\d+)\]/g, function (match, index) { index = +index; return '__o[' + (operatorFunctions.length + index) + ']'; }).replace(/__f\[(\d+)\]/g, function (match, index) { index = +index; return '__f[' + (fieldFunctions.length + index) + ']'; }); operatorFunctions.push.apply(operatorFunctions, expr.operators); fieldFunctions.push.apply(fieldFunctions, expr.fields); } else { if (typeof field === FUNCTION) { expr = '__f[' + fieldFunctions.length + '](d)'; fieldFunctions.push(field); } else { expr = kendo.expr(field); } if (typeof operator === FUNCTION) { filter = '__o[' + operatorFunctions.length + '](' + expr + ', ' + operators.quote(filter.value) + ')'; operatorFunctions.push(operator); } else { filter = operators[(operator || 'eq').toLowerCase()](expr, filter.value, filter.ignoreCase !== undefined ? filter.ignoreCase : true); } } expressions.push(filter); } return { expression: '(' + expressions.join(logic[expression.logic]) + ')', fields: fieldFunctions, operators: operatorFunctions }; }; function normalizeSort(field, dir) { if (field) { var descriptor = typeof field === STRING ? { field: field, dir: dir } : field, descriptors = isArray(descriptor) ? descriptor : descriptor !== undefined ? [descriptor] : []; return grep(descriptors, function (d) { return !!d.dir; }); } } var operatorMap = { '==': 'eq', equals: 'eq', isequalto: 'eq', equalto: 'eq', equal: 'eq', '!=': 'neq', ne: 'neq', notequals: 'neq', isnotequalto: 'neq', notequalto: 'neq', notequal: 'neq', '<': 'lt', islessthan: 'lt', lessthan: 'lt', less: 'lt', '<=': 'lte', le: 'lte', islessthanorequalto: 'lte', lessthanequal: 'lte', '>': 'gt', isgreaterthan: 'gt', greaterthan: 'gt', greater: 'gt', '>=': 'gte', isgreaterthanorequalto: 'gte', greaterthanequal: 'gte', ge: 'gte', notsubstringof: 'doesnotcontain', isnull: 'isnull', isempty: 'isempty', isnotempty: 'isnotempty' }; function normalizeOperator(expression) { var idx, length, filter, operator, filters = expression.filters; if (filters) { for (idx = 0, length = filters.length; idx < length; idx++) { filter = filters[idx]; operator = filter.operator; if (operator && typeof operator === STRING) { filter.operator = operatorMap[operator.toLowerCase()] || operator; } normalizeOperator(filter); } } } function normalizeFilter(expression) { if (expression && !isEmptyObject(expression)) { if (isArray(expression) || !expression.filters) { expression = { logic: 'and', filters: isArray(expression) ? expression : [expression] }; } normalizeOperator(expression); return expression; } } Query.normalizeFilter = normalizeFilter; function compareDescriptor(f1, f2) { if (f1.logic || f2.logic) { return false; } return f1.field === f2.field && f1.value === f2.value && f1.operator === f2.operator; } function normalizeDescriptor(filter) { filter = filter || {}; if (isEmptyObject(filter)) { return { logic: 'and', filters: [] }; } return normalizeFilter(filter); } function fieldComparer(a, b) { if (b.logic || a.field > b.field) { return 1; } else if (a.field < b.field) { return -1; } else { return 0; } } function compareFilters(expr1, expr2) { expr1 = normalizeDescriptor(expr1); expr2 = normalizeDescriptor(expr2); if (expr1.logic !== expr2.logic) { return false; } var f1, f2; var filters1 = (expr1.filters || []).slice(); var filters2 = (expr2.filters || []).slice(); if (filters1.length !== filters2.length) { return false; } filters1 = filters1.sort(fieldComparer); filters2 = filters2.sort(fieldComparer); for (var idx = 0; idx < filters1.length; idx++) { f1 = filters1[idx]; f2 = filters2[idx]; if (f1.logic && f2.logic) { if (!compareFilters(f1, f2)) { return false; } } else if (!compareDescriptor(f1, f2)) { return false; } } return true; } Query.compareFilters = compareFilters; function normalizeAggregate(expressions) { return isArray(expressions) ? expressions : [expressions]; } function normalizeGroup(field, dir) { var descriptor = typeof field === STRING ? { field: field, dir: dir } : field, descriptors = isArray(descriptor) ? descriptor : descriptor !== undefined ? [descriptor] : []; return map(descriptors, function (d) { return { field: d.field, dir: d.dir || 'asc', aggregates: d.aggregates }; }); } Query.prototype = { toArray: function () { return this.data; }, range: function (index, count) { return new Query(this.data.slice(index, index + count)); }, skip: function (count) { return new Query(this.data.slice(count)); }, take: function (count) { return new Query(this.data.slice(0, count)); }, select: function (selector) { return new Query(map(this.data, selector)); }, order: function (selector, dir) { var sort = { dir: dir }; if (selector) { if (selector.compare) { sort.compare = selector.compare; } else { sort.field = selector; } } return new Query(this.data.slice(0).sort(Comparer.create(sort))); }, orderBy: function (selector) { return this.order(selector, 'asc'); }, orderByDescending: function (selector) { return this.order(selector, 'desc'); }, sort: function (field, dir, comparer) { var idx, length, descriptors = normalizeSort(field, dir), comparers = []; comparer = comparer || Comparer; if (descriptors.length) { for (idx = 0, length = descriptors.length; idx < length; idx++) { comparers.push(comparer.create(descriptors[idx])); } return this.orderBy({ compare: comparer.combine(comparers) }); } return this; }, filter: function (expressions) { var idx, current, length, compiled, predicate, data = this.data, fields, operators, result = [], filter; expressions = normalizeFilter(expressions); if (!expressions || expressions.filters.length === 0) { return this; } compiled = Query.filterExpr(expressions); fields = compiled.fields; operators = compiled.operators; predicate = filter = new Function('d, __f, __o', 'return ' + compiled.expression); if (fields.length || operators.length) { filter = function (d) { return predicate(d, fields, operators); }; } for (idx = 0, length = data.length; idx < length; idx++) { current = data[idx]; if (filter(current)) { result.push(current); } } return new Query(result); }, group: function (descriptors, allData) { descriptors = normalizeGroup(descriptors || []); allData = allData || this.data; var that = this, result = new Query(that.data), descriptor; if (descriptors.length > 0) { descriptor = descriptors[0]; result = result.groupBy(descriptor).select(function (group) { var data = new Query(allData).filter([{ field: group.field, operator: 'eq', value: group.value, ignoreCase: false }]); return { field: group.field, value: group.value, items: descriptors.length > 1 ? new Query(group.items).group(descriptors.slice(1), data.toArray()).toArray() : group.items, hasSubgroups: descriptors.length > 1, aggregates: data.aggregate(descriptor.aggregates) }; }); } return result; }, groupBy: function (descriptor) { if (isEmptyObject(descriptor) || !this.data.length) { return new Query([]); } var field = descriptor.field, sorted = this._sortForGrouping(field, descriptor.dir || 'asc'), accessor = kendo.accessor(field), item, groupValue = accessor.get(sorted[0], field), group = { field: field, value: groupValue, items: [] }, currentValue, idx, len, result = [group]; for (idx = 0, len = sorted.length; idx < len; idx++) { item = sorted[idx]; currentValue = accessor.get(item, field); if (!groupValueComparer(groupValue, currentValue)) { groupValue = currentValue; group = { field: field, value: groupValue, items: [] }; result.push(group); } group.items.push(item); } return new Query(result); }, _sortForGrouping: function (field, dir) { var idx, length, data = this.data; if (!stableSort) { for (idx = 0, length = data.length; idx < length; idx++) { data[idx].__position = idx; } data = new Query(data).sort(field, dir, StableComparer).toArray(); for (idx = 0, length = data.length; idx < length; idx++) { delete data[idx].__position; } return data; } return this.sort(field, dir).toArray(); }, aggregate: function (aggregates) { var idx, len, result = {}, state = {}; if (aggregates && aggregates.length) { for (idx = 0, len = this.data.length; idx < len; idx++) { calculateAggregate(result, aggregates, this.data[idx], idx, len, state); } } return result; } }; function groupValueComparer(a, b) { if (a && a.getTime && b && b.getTime) { return a.getTime() === b.getTime(); } return a === b; } function calculateAggregate(accumulator, aggregates, item, index, length, state) { aggregates = aggregates || []; var idx, aggr, functionName, len = aggregates.length; for (idx = 0; idx < len; idx++) { aggr = aggregates[idx]; functionName = aggr.aggregate; var field = aggr.field; accumulator[field] = accumulator[field] || {}; state[field] = state[field] || {}; state[field][functionName] = state[field][functionName] || {}; accumulator[field][functionName] = functions[functionName.toLowerCase()](accumulator[field][functionName], item, kendo.accessor(field), index, length, state[field][functionName]); } } var functions = { sum: function (accumulator, item, accessor) { var value = accessor.get(item); if (!isNumber(accumulator)) { accumulator = value; } else if (isNumber(value)) { accumulator += value; } return accumulator; }, count: function (accumulator) { return (accumulator || 0) + 1; }, average: function (accumulator, item, accessor, index, length, state) { var value = accessor.get(item); if (state.count === undefined) { state.count = 0; } if (!isNumber(accumulator)) { accumulator = value; } else if (isNumber(value)) { accumulator += value; } if (isNumber(value)) { state.count++; } if (index == length - 1 && isNumber(accumulator)) { accumulator = accumulator / state.count; } return accumulator; }, max: function (accumulator, item, accessor) { var value = accessor.get(item); if (!isNumber(accumulator) && !isDate(accumulator)) { accumulator = value; } if (accumulator < value && (isNumber(value) || isDate(value))) { accumulator = value; } return accumulator; }, min: function (accumulator, item, accessor) { var value = accessor.get(item); if (!isNumber(accumulator) && !isDate(accumulator)) { accumulator = value; } if (accumulator > value && (isNumber(value) || isDate(value))) { accumulator = value; } return accumulator; } }; function isNumber(val) { return typeof val === 'number' && !isNaN(val); } function isDate(val) { return val && val.getTime; } function toJSON(array) { var idx, length = array.length, result = new Array(length); for (idx = 0; idx < length; idx++) { result[idx] = array[idx].toJSON(); } return result; } Query.process = function (data, options) { options = options || {}; var query = new Query(data), group = options.group, sort = normalizeGroup(group || []).concat(normalizeSort(options.sort || [])), total, filterCallback = options.filterCallback, filter = options.filter, skip = options.skip, take = options.take; if (filter) { query = query.filter(filter); if (filterCallback) { query = filterCallback(query); } total = query.toArray().length; } if (sort) { query = query.sort(sort); if (group) { data = query.toArray(); } } if (skip !== undefined && take !== undefined) { query = query.range(skip, take); } if (group) { query = query.group(group, data); } return { total: total, data: query.toArray() }; }; var LocalTransport = Class.extend({ init: function (options) { this.data = options.data; }, read: function (options) { options.success(this.data); }, update: function (options) { options.success(options.data); }, create: function (options) { options.success(options.data); }, destroy: function (options) { options.success(options.data); } }); var RemoteTransport = Class.extend({ init: function (options) { var that = this, parameterMap; options = that.options = extend({}, that.options, options); each(crud, function (index, type) { if (typeof options[type] === STRING) { options[type] = { url: options[type] }; } }); that.cache = options.cache ? Cache.create(options.cache) : { find: noop, add: noop }; parameterMap = options.parameterMap; if (isFunction(options.push)) { that.push = options.push; } if (!that.push) { that.push = identity; } that.parameterMap = isFunction(parameterMap) ? parameterMap : function (options) { var result = {}; each(options, function (option, value) { if (option in parameterMap) { option = parameterMap[option]; if (isPlainObject(option)) { value = option.value(value); option = option.key; } } result[option] = value; }); return result; }; }, options: { parameterMap: identity }, create: function (options) { return ajax(this.setup(options, CREATE)); }, read: function (options) { var that = this, success, error, result, cache = that.cache; options = that.setup(options, READ); success = options.success || noop; error = options.error || noop; result = cache.find(options.data); if (result !== undefined) { success(result); } else { options.success = function (result) { cache.add(options.data, result); success(result); }; $.ajax(options); } }, update: function (options) { return ajax(this.setup(options, UPDATE)); }, destroy: function (options) { return ajax(this.setup(options, DESTROY)); }, setup: function (options, type) { options = options || {}; var that = this, parameters, operation = that.options[type], data = isFunction(operation.data) ? operation.data(options.data) : operation.data; options = extend(true, {}, operation, options); parameters = extend(true, {}, data, options.data); options.data = that.parameterMap(parameters, type); if (isFunction(options.url)) { options.url = options.url(parameters); } return options; } }); var Cache = Class.extend({ init: function () { this._store = {}; }, add: function (key, data) { if (key !== undefined) { this._store[stringify(key)] = data; } }, find: function (key) { return this._store[stringify(key)]; }, clear: function () { this._store = {}; }, remove: function (key) { delete this._store[stringify(key)]; } }); Cache.create = function (options) { var store = { 'inmemory': function () { return new Cache(); } }; if (isPlainObject(options) && isFunction(options.find)) { return options; } if (options === true) { return new Cache(); } return store[options](); }; function serializeRecords(data, getters, modelInstance, originalFieldNames, fieldNames) { var record, getter, originalName, idx, setters = {}, length; for (idx = 0, length = data.length; idx < length; idx++) { record = data[idx]; for (getter in getters) { originalName = fieldNames[getter]; if (originalName && originalName !== getter) { if (!setters[originalName]) { setters[originalName] = kendo.setter(originalName); } setters[originalName](record, getters[getter](record)); delete record[getter]; } } } } function convertRecords(data, getters, modelInstance, originalFieldNames, fieldNames) { var record, getter, originalName, idx, length; for (idx = 0, length = data.length; idx < length; idx++) { record = data[idx]; for (getter in getters) { record[getter] = modelInstance._parse(getter, getters[getter](record)); originalName = fieldNames[getter]; if (originalName && originalName !== getter) { delete record[originalName]; } } } } function convertGroup(data, getters, modelInstance, originalFieldNames, fieldNames) { var record, idx, fieldName, length; for (idx = 0, length = data.length; idx < length; idx++) { record = data[idx]; fieldName = originalFieldNames[record.field]; if (fieldName && fieldName != record.field) { record.field = fieldName; } record.value = modelInstance._parse(record.field, record.value); if (record.hasSubgroups) { convertGroup(record.items, getters, modelInstance, originalFieldNames, fieldNames); } else { convertRecords(record.items, getters, modelInstance, originalFieldNames, fieldNames); } } } function wrapDataAccess(originalFunction, model, converter, getters, originalFieldNames, fieldNames) { return function (data) { data = originalFunction(data); if (data && !isEmptyObject(getters)) { if (toString.call(data) !== '[object Array]' && !(data instanceof ObservableArray)) { data = [data]; } converter(data, getters, new model(), originalFieldNames, fieldNames); } return data || []; }; } var DataReader = Class.extend({ init: function (schema) { var that = this, member, get, model, base; schema = schema || {}; for (member in schema) { get = schema[member]; that[member] = typeof get === STRING ? getter(get) : get; } base = schema.modelBase || Model; if (isPlainObject(that.model)) { that.model = model = base.define(that.model); } var dataFunction = proxy(that.data, that); that._dataAccessFunction = dataFunction; if (that.model) { var groupsFunction = proxy(that.groups, that), serializeFunction = proxy(that.serialize, that), originalFieldNames = {}, getters = {}, serializeGetters = {}, fieldNames = {}, shouldSerialize = false, fieldName; model = that.model; if (model.fields) { each(model.fields, function (field, value) { var fromName; fieldName = field; if (isPlainObject(value) && value.field) { fieldName = value.field; } else if (typeof value === STRING) { fieldName = value; } if (isPlainObject(value) && value.from) { fromName = value.from; } shouldSerialize = shouldSerialize || fromName && fromName !== field || fieldName !== field; getters[field] = getter(fromName || fieldName); serializeGetters[field] = getter(field); originalFieldNames[fromName || fieldName] = field; fieldNames[field] = fromName || fieldName; }); if (!schema.serialize && shouldSerialize) { that.serialize = wrapDataAccess(serializeFunction, model, serializeRecords, serializeGetters, originalFieldNames, fieldNames); } } that._dataAccessFunction = dataFunction; that.data = wrapDataAccess(dataFunction, model, convertRecords, getters, originalFieldNames, fieldNames); that.groups = wrapDataAccess(groupsFunction, model, convertGroup, getters, originalFieldNames, fieldNames); } }, errors: function (data) { return data ? data.errors : null; }, parse: identity, data: identity, total: function (data) { return data.length; }, groups: identity, aggregates: function () { return {}; }, serialize: function (data) { return data; } }); function mergeGroups(target, dest, skip, take) { var group, idx = 0, items; while (dest.length && take) { group = dest[idx]; items = group.items; var length = items.length; if (target && target.field === group.field && target.value === group.value) { if (target.hasSubgroups && target.items.length) { mergeGroups(target.items[target.items.length - 1], group.items, skip, take); } else { items = items.slice(skip, skip + take); target.items = target.items.concat(items); } dest.splice(idx--, 1); } else if (group.hasSubgroups && items.length) { mergeGroups(group, items, skip, take); if (!group.items.length) { dest.splice(idx--, 1); } } else { items = items.slice(skip, skip + take); group.items = items; if (!group.items.length) { dest.splice(idx--, 1); } } if (items.length === 0) { skip -= length; } else { skip = 0; take -= items.length; } if (++idx >= dest.length) { break; } } if (idx < dest.length) { dest.splice(idx, dest.length - idx); } } function flattenGroups(data) { var idx, result = [], length, items, itemIndex; for (idx = 0, length = data.length; idx < length; idx++) { var group = data.at(idx); if (group.hasSubgroups) { result = result.concat(flattenGroups(group.items)); } else { items = group.items; for (itemIndex = 0; itemIndex < items.length; itemIndex++) { result.push(items.at(itemIndex)); } } } return result; } function wrapGroupItems(data, model) { var idx, length, group; if (model) { for (idx = 0, length = data.length; idx < length; idx++) { group = data.at(idx); if (group.hasSubgroups) { wrapGroupItems(group.items, model); } else { group.items = new LazyObservableArray(group.items, model); } } } } function eachGroupItems(data, func) { for (var idx = 0, length = data.length; idx < length; idx++) { if (data[idx].hasSubgroups) { if (eachGroupItems(data[idx].items, func)) { return true; } } else if (func(data[idx].items, data[idx])) { return true; } } } function replaceInRanges(ranges, data, item, observable) { for (var idx = 0; idx < ranges.length; idx++) { if (ranges[idx].data === data) { break; } if (replaceInRange(ranges[idx].data, item, observable)) { break; } } } function replaceInRange(items, item, observable) { for (var idx = 0, length = items.length; idx < length; idx++) { if (items[idx] && items[idx].hasSubgroups) { return replaceInRange(items[idx].items, item, observable); } else if (items[idx] === item || items[idx] === observable) { items[idx] = observable; return true; } } } function replaceWithObservable(view, data, ranges, type, serverGrouping) { for (var viewIndex = 0, length = view.length; viewIndex < length; viewIndex++) { var item = view[viewIndex]; if (!item || item instanceof type) { continue; } if (item.hasSubgroups !== undefined && !serverGrouping) { replaceWithObservable(item.items, data, ranges, type, serverGrouping); } else { for (var idx = 0; idx < data.length; idx++) { if (data[idx] === item) { view[viewIndex] = data.at(idx); replaceInRanges(ranges, data, item, view[viewIndex]); break; } } } } } function removeModel(data, model) { var idx, length; for (idx = 0, length = data.length; idx < length; idx++) { var dataItem = data.at(idx); if (dataItem.uid == model.uid) { data.splice(idx, 1); return dataItem; } } } function indexOfPristineModel(data, model) { if (model) { return indexOf(data, function (item) { return item.uid && item.uid == model.uid || item[model.idField] === model.id && model.id !== model._defaultId; }); } return -1; } function indexOfModel(data, model) { if (model) { return indexOf(data, function (item) { return item.uid == model.uid; }); } return -1; } function indexOf(data, comparer) { var idx, length; for (idx = 0, length = data.length; idx < length; idx++) { if (comparer(data[idx])) { return idx; } } return -1; } function fieldNameFromModel(fields, name) { if (fields && !isEmptyObject(fields)) { var descriptor = fields[name]; var fieldName; if (isPlainObject(descriptor)) { fieldName = descriptor.from || descriptor.field || name; } else { fieldName = fields[name] || name; } if (isFunction(fieldName)) { return name; } return fieldName; } return name; } function convertFilterDescriptorsField(descriptor, model) { var idx, length, target = {}; for (var field in descriptor) { if (field !== 'filters') { target[field] = descriptor[field]; } } if (descriptor.filters) { target.filters = []; for (idx = 0, length = descriptor.filters.length; idx < length; idx++) { target.filters[idx] = convertFilterDescriptorsField(descriptor.filters[idx], model); } } else { target.field = fieldNameFromModel(model.fields, target.field); } return target; } function convertDescriptorsField(descriptors, model) { var idx, length, result = [], target, descriptor; for (idx = 0, length = descriptors.length; idx < length; idx++) { target = {}; descriptor = descriptors[idx]; for (var field in descriptor) { target[field] = descriptor[field]; } target.field = fieldNameFromModel(model.fields, target.field); if (target.aggregates && isArray(target.aggregates)) { target.aggregates = convertDescriptorsField(target.aggregates, model); } result.push(target); } return result; } var DataSource = Observable.extend({ init: function (options) { var that = this, model, data; if (options) { data = options.data; } options = that.options = extend({}, that.options, options); that._map = {}; that._prefetch = {}; that._data = []; that._pristineData = []; that._ranges = []; that._view = []; that._pristineTotal = 0; that._destroyed = []; that._pageSize = options.pageSize; that._page = options.page || (options.pageSize ? 1 : undefined); that._sort = normalizeSort(options.sort); that._filter = normalizeFilter(options.filter); that._group = normalizeGroup(options.group); that._aggregate = options.aggregate; that._total = options.total; that._shouldDetachObservableParents = true; Observable.fn.init.call(that); that.transport = Transport.create(options, data, that); if (isFunction(that.transport.push)) { that.transport.push({ pushCreate: proxy(that._pushCreate, that), pushUpdate: proxy(that._pushUpdate, that), pushDestroy: proxy(that._pushDestroy, that) }); } if (options.offlineStorage != null) { if (typeof options.offlineStorage == 'string') { var key = options.offlineStorage; that._storage = { getItem: function () { return JSON.parse(localStorage.getItem(key)); }, setItem: function (item) { localStorage.setItem(key, stringify(that.reader.serialize(item))); } }; } else { that._storage = options.offlineStorage; } } that.reader = new kendo.data.readers[options.schema.type || 'json'](options.schema); model = that.reader.model || {}; that._detachObservableParents(); that._data = that._observe(that._data); that._online = true; that.bind([ 'push', ERROR, CHANGE, REQUESTSTART, SYNC, REQUESTEND, PROGRESS ], options); }, options: { data: null, schema: { modelBase: Model }, offlineStorage: null, serverSorting: false, serverPaging: false, serverFiltering: false, serverGrouping: false, serverAggregates: false, batch: false }, clone: function () { return this; }, online: function (value) { if (value !== undefined) { if (this._online != value) { this._online = value; if (value) { return this.sync(); } } return $.Deferred().resolve().promise(); } else { return this._online; } }, offlineData: function (state) { if (this.options.offlineStorage == null) { return null; } if (state !== undefined) { return this._storage.setItem(state); } return this._storage.getItem() || []; }, _isServerGrouped: function () { var group = this.group() || []; return this.options.serverGrouping && group.length; }, _pushCreate: function (result) { this._push(result, 'pushCreate'); }, _pushUpdate: function (result) { this._push(result, 'pushUpdate'); }, _pushDestroy: function (result) { this._push(result, 'pushDestroy'); }, _push: function (result, operation) { var data = this._readData(result); if (!data) { data = result; } this[operation](data); }, _flatData: function (data, skip) { if (data) { if (this._isServerGrouped()) { return flattenGroups(data); } if (!skip) { for (var idx = 0; idx < data.length; idx++) { data.at(idx); } } } return data; }, parent: noop, get: function (id) { var idx, length, data = this._flatData(this._data); for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].id == id) { return data[idx]; } } }, getByUid: function (id) { var idx, length, data = this._flatData(this._data); if (!data) { return; } for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].uid == id) { return data[idx]; } } }, indexOf: function (model) { return indexOfModel(this._data, model); }, at: function (index) { return this._data.at(index); }, data: function (value) { var that = this; if (value !== undefined) { that._detachObservableParents(); that._data = this._observe(value); that._pristineData = value.slice(0); that._storeData(); that._ranges = []; that.trigger('reset'); that._addRange(that._data); that._total = that._data.length; that._pristineTotal = that._total; that._process(that._data); } else { if (that._data) { for (var idx = 0; idx < that._data.length; idx++) { that._data.at(idx); } } return that._data; } }, view: function (value) { if (value === undefined) { return this._view; } else { this._view = this._observeView(value); } }, _observeView: function (data) { var that = this; replaceWithObservable(data, that._data, that._ranges, that.reader.model || ObservableObject, that._isServerGrouped()); var view = new LazyObservableArray(data, that.reader.model); view.parent = function () { return that.parent(); }; return view; }, flatView: function () { var groups = this.group() || []; if (groups.length) { return flattenGroups(this._view); } else { return this._view; } }, add: function (model) { return this.insert(this._data.length, model); }, _createNewModel: function (model) { if (this.reader.model) { return new this.reader.model(model); } if (model instanceof ObservableObject) { return model; } return new ObservableObject(model); }, insert: function (index, model) { if (!model) { model = index; index = 0; } if (!(model instanceof Model)) { model = this._createNewModel(model); } if (this._isServerGrouped()) { this._data.splice(index, 0, this._wrapInEmptyGroup(model)); } else { this._data.splice(index, 0, model); } return model; }, pushCreate: function (items) { if (!isArray(items)) { items = [items]; } var pushed = []; var autoSync = this.options.autoSync; this.options.autoSync = false; try { for (var idx = 0; idx < items.length; idx++) { var item = items[idx]; var result = this.add(item); pushed.push(result); var pristine = result.toJSON(); if (this._isServerGrouped()) { pristine = this._wrapInEmptyGroup(pristine); } this._pristineData.push(pristine); } } finally { this.options.autoSync = autoSync; } if (pushed.length) { this.trigger('push', { type: 'create', items: pushed }); } }, pushUpdate: function (items) { if (!isArray(items)) { items = [items]; } var pushed = []; for (var idx = 0; idx < items.length; idx++) { var item = items[idx]; var model = this._createNewModel(item); var target = this.get(model.id); if (target) { pushed.push(target); target.accept(item); target.trigger(CHANGE); this._updatePristineForModel(target, item); } else { this.pushCreate(item); } } if (pushed.length) { this.trigger('push', { type: 'update', items: pushed }); } }, pushDestroy: function (items) { var pushed = this._removeItems(items); if (pushed.length) { this.trigger('push', { type: 'destroy', items: pushed }); } }, _removeItems: function (items) { if (!isArray(items)) { items = [items]; } var destroyed = []; var autoSync = this.options.autoSync; this.options.autoSync = false; try { for (var idx = 0; idx < items.length; idx++) { var item = items[idx]; var model = this._createNewModel(item); var found = false; this._eachItem(this._data, function (items) { for (var idx = 0; idx < items.length; idx++) { var item = items.at(idx); if (item.id === model.id) { destroyed.push(item); items.splice(idx, 1); found = true; break; } } }); if (found) { this._removePristineForModel(model); this._destroyed.pop(); } } } finally { this.options.autoSync = autoSync; } return destroyed; }, remove: function (model) { var result, that = this, hasGroups = that._isServerGrouped(); this._eachItem(that._data, function (items) { result = removeModel(items, model); if (result && hasGroups) { if (!result.isNew || !result.isNew()) { that._destroyed.push(result); } return true; } }); this._removeModelFromRanges(model); this._updateRangesLength(); return model; }, destroyed: function () { return this._destroyed; }, created: function () { var idx, length, result = [], data = this._flatData(this._data); for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].isNew && data[idx].isNew()) { result.push(data[idx]); } } return result; }, updated: function () { var idx, length, result = [], data = this._flatData(this._data); for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].isNew && !data[idx].isNew() && data[idx].dirty) { result.push(data[idx]); } } return result; }, sync: function () { var that = this, created = [], updated = [], destroyed = that._destroyed; var promise = $.Deferred().resolve().promise(); if (that.online()) { if (!that.reader.model) { return promise; } created = that.created(); updated = that.updated(); var promises = []; if (that.options.batch && that.transport.submit) { promises = that._sendSubmit(created, updated, destroyed); } else { promises.push.apply(promises, that._send('create', created)); promises.push.apply(promises, that._send('update', updated)); promises.push.apply(promises, that._send('destroy', destroyed)); } promise = $.when.apply(null, promises).then(function () { var idx, length; for (idx = 0, length = arguments.length; idx < length; idx++) { that._accept(arguments[idx]); } that._storeData(true); that._change({ action: 'sync' }); that.trigger(SYNC); }); } else { that._storeData(true); that._change({ action: 'sync' }); } return promise; }, cancelChanges: function (model) { var that = this; if (model instanceof kendo.data.Model) { that._cancelModel(model); } else { that._destroyed = []; that._detachObservableParents(); that._data = that._observe(that._pristineData); if (that.options.serverPaging) { that._total = that._pristineTotal; } that._ranges = []; that._addRange(that._data); that._change(); that._markOfflineUpdatesAsDirty(); } }, _markOfflineUpdatesAsDirty: function () { var that = this; if (that.options.offlineStorage != null) { that._eachItem(that._data, function (items) { for (var idx = 0; idx < items.length; idx++) { var item = items.at(idx); if (item.__state__ == 'update') { item.dirty = true; } } }); } }, hasChanges: function () { var idx, length, data = this._flatData(this._data); if (this._destroyed.length) { return true; } for (idx = 0, length = data.length; idx < length; idx++) { if (data[idx].isNew && data[idx].isNew() || data[idx].dirty) { return true; } } return false; }, _accept: function (result) { var that = this, models = result.models, response = result.response, idx = 0, serverGroup = that._isServerGrouped(), pristine = that._pristineData, type = result.type, length; that.trigger(REQUESTEND, { response: response, type: type }); if (response && !isEmptyObject(response)) { response = that.reader.parse(response); if (that._handleCustomErrors(response)) { return; } response = that.reader.data(response); if (!isArray(response)) { response = [response]; } } else { response = $.map(models, function (model) { return model.toJSON(); }); } if (type === 'destroy') { that._destroyed = []; } for (idx = 0, length = models.length; idx < length; idx++) { if (type !== 'destroy') { models[idx].accept(response[idx]); if (type === 'create') { pristine.push(serverGroup ? that._wrapInEmptyGroup(models[idx]) : response[idx]); } else if (type === 'update') { that._updatePristineForModel(models[idx], response[idx]); } } else { that._removePristineForModel(models[idx]); } } }, _updatePristineForModel: function (model, values) { this._executeOnPristineForModel(model, function (index, items) { kendo.deepExtend(items[index], values); }); }, _executeOnPristineForModel: function (model, callback) { this._eachPristineItem(function (items) { var index = indexOfPristineModel(items, model); if (index > -1) { callback(index, items); return true; } }); }, _removePristineForModel: function (model) { this._executeOnPristineForModel(model, function (index, items) { items.splice(index, 1); }); }, _readData: function (data) { var read = !this._isServerGrouped() ? this.reader.data : this.reader.groups; return read.call(this.reader, data); }, _eachPristineItem: function (callback) { this._eachItem(this._pristineData, callback); }, _eachItem: function (data, callback) { if (data && data.length) { if (this._isServerGrouped()) { eachGroupItems(data, callback); } else { callback(data); } } }, _pristineForModel: function (model) { var pristine, idx, callback = function (items) { idx = indexOfPristineModel(items, model); if (idx > -1) { pristine = items[idx]; return true; } }; this._eachPristineItem(callback); return pristine; }, _cancelModel: function (model) { var pristine = this._pristineForModel(model); this._eachItem(this._data, function (items) { var idx = indexOfModel(items, model); if (idx >= 0) { if (pristine && (!model.isNew() || pristine.__state__)) { items[idx].accept(pristine); if (pristine.__state__ == 'update') { items[idx].dirty = true; } } else { items.splice(idx, 1); } } }); }, _submit: function (promises, data) { var that = this; that.trigger(REQUESTSTART, { type: 'submit' }); that.transport.submit(extend({ success: function (response, type) { var promise = $.grep(promises, function (x) { return x.type == type; })[0]; if (promise) { promise.resolve({ response: response, models: promise.models, type: type }); } }, error: function (response, status, error) { for (var idx = 0; idx < promises.length; idx++) { promises[idx].reject(response); } that.error(response, status, error); } }, data)); }, _sendSubmit: function (created, updated, destroyed) { var that = this, promises = []; if (that.options.batch) { if (created.length) { promises.push($.Deferred(function (deferred) { deferred.type = 'create'; deferred.models = created; })); } if (updated.length) { promises.push($.Deferred(function (deferred) { deferred.type = 'update'; deferred.models = updated; })); } if (destroyed.length) { promises.push($.Deferred(function (deferred) { deferred.type = 'destroy'; deferred.models = destroyed; })); } that._submit(promises, { data: { created: that.reader.serialize(toJSON(created)), updated: that.reader.serialize(toJSON(updated)), destroyed: that.reader.serialize(toJSON(destroyed)) } }); } return promises; }, _promise: function (data, models, type) { var that = this; return $.Deferred(function (deferred) { that.trigger(REQUESTSTART, { type: type }); that.transport[type].call(that.transport, extend({ success: function (response) { deferred.resolve({ response: response, models: models, type: type }); }, error: function (response, status, error) { deferred.reject(response); that.error(response, status, error); } }, data)); }).promise(); }, _send: function (method, data) { var that = this, idx, length, promises = [], converted = that.reader.serialize(toJSON(data)); if (that.options.batch) { if (data.length) { promises.push(that._promise({ data: { models: converted } }, data, method)); } } else { for (idx = 0, length = data.length; idx < length; idx++) { promises.push(that._promise({ data: converted[idx] }, [data[idx]], method)); } } return promises; }, read: function (data) { var that = this, params = that._params(data); var deferred = $.Deferred(); that._queueRequest(params, function () { var isPrevented = that.trigger(REQUESTSTART, { type: 'read' }); if (!isPrevented) { that.trigger(PROGRESS); that._ranges = []; that.trigger('reset'); if (that.online()) { that.transport.read({ data: params, success: function (data) { that.success(data, params); deferred.resolve(); }, error: function () { var args = slice.call(arguments); that.error.apply(that, args); deferred.reject.apply(deferred, args); } }); } else if (that.options.offlineStorage != null) { that.success(that.offlineData(), params); deferred.resolve(); } } else { that._dequeueRequest(); deferred.resolve(isPrevented); } }); return deferred.promise(); }, _readAggregates: function (data) { return this.reader.aggregates(data); }, success: function (data) { var that = this, options = that.options; that.trigger(REQUESTEND, { response: data, type: 'read' }); if (that.online()) { data = that.reader.parse(data); if (that._handleCustomErrors(data)) { that._dequeueRequest(); return; } that._total = that.reader.total(data); if (that._aggregate && options.serverAggregates) { that._aggregateResult = that._readAggregates(data); } data = that._readData(data); } else { data = that._readData(data); var items = []; var itemIds = {}; var model = that.reader.model; var idField = model ? model.idField : 'id'; var idx; for (idx = 0; idx < this._destroyed.length; idx++) { var id = this._destroyed[idx][idField]; itemIds[id] = id; } for (idx = 0; idx < data.length; idx++) { var item = data[idx]; var state = item.__state__; if (state == 'destroy') { if (!itemIds[item[idField]]) { this._destroyed.push(this._createNewModel(item)); } } else { items.push(item); } } data = items; that._total = data.length; } that._pristineTotal = that._total; that._pristineData = data.slice(0); that._detachObservableParents(); that._data = that._observe(data); that._markOfflineUpdatesAsDirty(); that._storeData(); that._addRange(that._data); that._process(that._data); that._dequeueRequest(); }, _detachObservableParents: function () { if (this._data && this._shouldDetachObservableParents) { for (var idx = 0; idx < this._data.length; idx++) { if (this._data[idx].parent) { this._data[idx].parent = noop; } } } }, _storeData: function (updatePristine) { var serverGrouping = this._isServerGrouped(); var model = this.reader.model; function items(data) { var state = []; for (var idx = 0; idx < data.length; idx++) { var dataItem = data.at(idx); var item = dataItem.toJSON(); if (serverGrouping && dataItem.items) { item.items = items(dataItem.items); } else { item.uid = dataItem.uid; if (model) { if (dataItem.isNew()) { item.__state__ = 'create'; } else if (dataItem.dirty) { item.__state__ = 'update'; } } } state.push(item); } return state; } if (this.options.offlineStorage != null) { var state = items(this._data); var destroyed = []; for (var idx = 0; idx < this._destroyed.length; idx++) { var item = this._destroyed[idx].toJSON(); item.__state__ = 'destroy'; destroyed.push(item); } this.offlineData(state.concat(destroyed)); if (updatePristine) { this._pristineData = this._readData(state); } } }, _addRange: function (data) { var that = this, start = that._skip || 0, end = start + that._flatData(data, true).length; that._ranges.push({ start: start, end: end, data: data, timestamp: new Date().getTime() }); that._ranges.sort(function (x, y) { return x.start - y.start; }); }, error: function (xhr, status, errorThrown) { this._dequeueRequest(); this.trigger(REQUESTEND, {}); this.trigger(ERROR, { xhr: xhr, status: status, errorThrown: errorThrown }); }, _params: function (data) { var that = this, options = extend({ take: that.take(), skip: that.skip(), page: that.page(), pageSize: that.pageSize(), sort: that._sort, filter: that._filter, group: that._group, aggregate: that._aggregate }, data); if (!that.options.serverPaging) { delete options.take; delete options.skip; delete options.page; delete options.pageSize; } if (!that.options.serverGrouping) { delete options.group; } else if (that.reader.model && options.group) { options.group = convertDescriptorsField(options.group, that.reader.model); } if (!that.options.serverFiltering) { delete options.filter; } else if (that.reader.model && options.filter) { options.filter = convertFilterDescriptorsField(options.filter, that.reader.model); } if (!that.options.serverSorting) { delete options.sort; } else if (that.reader.model && options.sort) { options.sort = convertDescriptorsField(options.sort, that.reader.model); } if (!that.options.serverAggregates) { delete options.aggregate; } else if (that.reader.model && options.aggregate) { options.aggregate = convertDescriptorsField(options.aggregate, that.reader.model); } return options; }, _queueRequest: function (options, callback) { var that = this; if (!that._requestInProgress) { that._requestInProgress = true; that._pending = undefined; callback(); } else { that._pending = { callback: proxy(callback, that), options: options }; } }, _dequeueRequest: function () { var that = this; that._requestInProgress = false; if (that._pending) { that._queueRequest(that._pending.options, that._pending.callback); } }, _handleCustomErrors: function (response) { if (this.reader.errors) { var errors = this.reader.errors(response); if (errors) { this.trigger(ERROR, { xhr: null, status: 'customerror', errorThrown: 'custom error', errors: errors }); return true; } } return false; }, _shouldWrap: function (data) { var model = this.reader.model; if (model && data.length) { return !(data[0] instanceof model); } return false; }, _observe: function (data) { var that = this, model = that.reader.model; that._shouldDetachObservableParents = true; if (data instanceof ObservableArray) { that._shouldDetachObservableParents = false; if (that._shouldWrap(data)) { data.type = that.reader.model; data.wrapAll(data, data); } } else { var arrayType = that.pageSize() && !that.options.serverPaging ? LazyObservableArray : ObservableArray; data = new arrayType(data, that.reader.model); data.parent = function () { return that.parent(); }; } if (that._isServerGrouped()) { wrapGroupItems(data, model); } if (that._changeHandler && that._data && that._data instanceof ObservableArray) { that._data.unbind(CHANGE, that._changeHandler); } else { that._changeHandler = proxy(that._change, that); } return data.bind(CHANGE, that._changeHandler); }, _updateTotalForAction: function (action, items) { var that = this; var total = parseInt(that._total, 10); if (!isNumber(that._total)) { total = parseInt(that._pristineTotal, 10); } if (action === 'add') { total += items.length; } else if (action === 'remove') { total -= items.length; } else if (action !== 'itemchange' && action !== 'sync' && !that.options.serverPaging) { total = that._pristineTotal; } else if (action === 'sync') { total = that._pristineTotal = parseInt(that._total, 10); } that._total = total; }, _change: function (e) { var that = this, idx, length, action = e ? e.action : ''; if (action === 'remove') { for (idx = 0, length = e.items.length; idx < length; idx++) { if (!e.items[idx].isNew || !e.items[idx].isNew()) { that._destroyed.push(e.items[idx]); } } } if (that.options.autoSync && (action === 'add' || action === 'remove' || action === 'itemchange')) { var handler = function (args) { if (args.action === 'sync') { that.unbind('change', handler); that._updateTotalForAction(action, e.items); } }; that.first('change', handler); that.sync(); } else { that._updateTotalForAction(action, e ? e.items : []); that._process(that._data, e); } }, _calculateAggregates: function (data, options) { options = options || {}; var query = new Query(data), aggregates = options.aggregate, filter = options.filter; if (filter) { query = query.filter(filter); } return query.aggregate(aggregates); }, _process: function (data, e) { var that = this, options = {}, result; if (that.options.serverPaging !== true) { options.skip = that._skip; options.take = that._take || that._pageSize; if (options.skip === undefined && that._page !== undefined && that._pageSize !== undefined) { options.skip = (that._page - 1) * that._pageSize; } } if (that.options.serverSorting !== true) { options.sort = that._sort; } if (that.options.serverFiltering !== true) { options.filter = that._filter; } if (that.options.serverGrouping !== true) { options.group = that._group; } if (that.options.serverAggregates !== true) { options.aggregate = that._aggregate; that._aggregateResult = that._calculateAggregates(data, options); } result = that._queryProcess(data, options); that.view(result.data); if (result.total !== undefined && !that.options.serverFiltering) { that._total = result.total; } e = e || {}; e.items = e.items || that._view; that.trigger(CHANGE, e); }, _queryProcess: function (data, options) { return Query.process(data, options); }, _mergeState: function (options) { var that = this; if (options !== undefined) { that._pageSize = options.pageSize; that._page = options.page; that._sort = options.sort; that._filter = options.filter; that._group = options.group; that._aggregate = options.aggregate; that._skip = that._currentRangeStart = options.skip; that._take = options.take; if (that._skip === undefined) { that._skip = that._currentRangeStart = that.skip(); options.skip = that.skip(); } if (that._take === undefined && that._pageSize !== undefined) { that._take = that._pageSize; options.take = that._take; } if (options.sort) { that._sort = options.sort = normalizeSort(options.sort); } if (options.filter) { that._filter = options.filter = normalizeFilter(options.filter); } if (options.group) { that._group = options.group = normalizeGroup(options.group); } if (options.aggregate) { that._aggregate = options.aggregate = normalizeAggregate(options.aggregate); } } return options; }, query: function (options) { var result; var remote = this.options.serverSorting || this.options.serverPaging || this.options.serverFiltering || this.options.serverGrouping || this.options.serverAggregates; if (remote || (this._data === undefined || this._data.length === 0) && !this._destroyed.length) { return this.read(this._mergeState(options)); } var isPrevented = this.trigger(REQUESTSTART, { type: 'read' }); if (!isPrevented) { this.trigger(PROGRESS); result = this._queryProcess(this._data, this._mergeState(options)); if (!this.options.serverFiltering) { if (result.total !== undefined) { this._total = result.total; } else { this._total = this._data.length; } } this._aggregateResult = this._calculateAggregates(this._data, options); this.view(result.data); this.trigger(REQUESTEND, { type: 'read' }); this.trigger(CHANGE, { items: result.data }); } return $.Deferred().resolve(isPrevented).promise(); }, fetch: function (callback) { var that = this; var fn = function (isPrevented) { if (isPrevented !== true && isFunction(callback)) { callback.call(that); } }; return this._query().then(fn); }, _query: function (options) { var that = this; return that.query(extend({}, { page: that.page(), pageSize: that.pageSize(), sort: that.sort(), filter: that.filter(), group: that.group(), aggregate: that.aggregate() }, options)); }, next: function (options) { var that = this, page = that.page(), total = that.total(); options = options || {}; if (!page || total && page + 1 > that.totalPages()) { return; } that._skip = that._currentRangeStart = page * that.take(); page += 1; options.page = page; that._query(options); return page; }, prev: function (options) { var that = this, page = that.page(); options = options || {}; if (!page || page === 1) { return; } that._skip = that._currentRangeStart = that._skip - that.take(); page -= 1; options.page = page; that._query(options); return page; }, page: function (val) { var that = this, skip; if (val !== undefined) { val = math.max(math.min(math.max(val, 1), that.totalPages()), 1); that._query({ page: val }); return; } skip = that.skip(); return skip !== undefined ? math.round((skip || 0) / (that.take() || 1)) + 1 : undefined; }, pageSize: function (val) { var that = this; if (val !== undefined) { that._query({ pageSize: val, page: 1 }); return; } return that.take(); }, sort: function (val) { var that = this; if (val !== undefined) { that._query({ sort: val }); return; } return that._sort; }, filter: function (val) { var that = this; if (val === undefined) { return that._filter; } that.trigger('reset'); that._query({ filter: val, page: 1 }); }, group: function (val) { var that = this; if (val !== undefined) { that._query({ group: val }); return; } return that._group; }, total: function () { return parseInt(this._total || 0, 10); }, aggregate: function (val) { var that = this; if (val !== undefined) { that._query({ aggregate: val }); return; } return that._aggregate; }, aggregates: function () { var result = this._aggregateResult; if (isEmptyObject(result)) { result = this._emptyAggregates(this.aggregate()); } return result; }, _emptyAggregates: function (aggregates) { var result = {}; if (!isEmptyObject(aggregates)) { var aggregate = {}; if (!isArray(aggregates)) { aggregates = [aggregates]; } for (var idx = 0; idx < aggregates.length; idx++) { aggregate[aggregates[idx].aggregate] = 0; result[aggregates[idx].field] = aggregate; } } return result; }, _wrapInEmptyGroup: function (model) { var groups = this.group(), parent, group, idx, length; for (idx = groups.length - 1, length = 0; idx >= length; idx--) { group = groups[idx]; parent = { value: model.get(group.field), field: group.field, items: parent ? [parent] : [model], hasSubgroups: !!parent, aggregates: this._emptyAggregates(group.aggregates) }; } return parent; }, totalPages: function () { var that = this, pageSize = that.pageSize() || that.total(); return math.ceil((that.total() || 0) / pageSize); }, inRange: function (skip, take) { var that = this, end = math.min(skip + take, that.total()); if (!that.options.serverPaging && that._data.length > 0) { return true; } return that._findRange(skip, end).length > 0; }, lastRange: function () { var ranges = this._ranges; return ranges[ranges.length - 1] || { start: 0, end: 0, data: [] }; }, firstItemUid: function () { var ranges = this._ranges; return ranges.length && ranges[0].data.length && ranges[0].data[0].uid; }, enableRequestsInProgress: function () { this._skipRequestsInProgress = false; }, _timeStamp: function () { return new Date().getTime(); }, range: function (skip, take) { this._currentRequestTimeStamp = this._timeStamp(); this._skipRequestsInProgress = true; skip = math.min(skip || 0, this.total()); var that = this, pageSkip = math.max(math.floor(skip / take), 0) * take, size = math.min(pageSkip + take, that.total()), data; data = that._findRange(skip, math.min(skip + take, that.total())); if (data.length) { that._pending = undefined; that._skip = skip > that.skip() ? math.min(size, (that.totalPages() - 1) * that.take()) : pageSkip; that._currentRangeStart = skip; that._take = take; var paging = that.options.serverPaging; var sorting = that.options.serverSorting; var filtering = that.options.serverFiltering; var aggregates = that.options.serverAggregates; try { that.options.serverPaging = true; if (!that._isServerGrouped() && !(that.group() && that.group().length)) { that.options.serverSorting = true; } that.options.serverFiltering = true; that.options.serverPaging = true; that.options.serverAggregates = true; if (paging) { that._detachObservableParents(); that._data = data = that._observe(data); } that._process(data); } finally { that.options.serverPaging = paging; that.options.serverSorting = sorting; that.options.serverFiltering = filtering; that.options.serverAggregates = aggregates; } return; } if (take !== undefined) { if (!that._rangeExists(pageSkip, size)) { that.prefetch(pageSkip, take, function () { if (skip > pageSkip && size < that.total() && !that._rangeExists(size, math.min(size + take, that.total()))) { that.prefetch(size, take, function () { that.range(skip, take); }); } else { that.range(skip, take); } }); } else if (pageSkip < skip) { that.prefetch(size, take, function () { that.range(skip, take); }); } } }, _findRange: function (start, end) { 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; for (skipIdx = 0, length = ranges.length; skipIdx < length; skipIdx++) { range = ranges[skipIdx]; if (start >= range.start && start <= range.end) { count = 0; for (takeIdx = skipIdx; takeIdx < length; takeIdx++) { range = ranges[takeIdx]; flatData = that._flatData(range.data, true); if (flatData.length && start + count >= range.start) { rangeData = range.data; rangeEnd = range.end; if (!remote) { var sort = normalizeGroup(that.group() || []).concat(normalizeSort(that.sort() || [])); processed = that._queryProcess(range.data, { sort: sort, filter: that.filter() }); flatData = rangeData = processed.data; if (processed.total !== undefined) { rangeEnd = processed.total; } } startIndex = 0; if (start + count > range.start) { startIndex = start + count - range.start; } endIndex = flatData.length; if (rangeEnd > end) { endIndex = endIndex - (rangeEnd - end); } count += endIndex - startIndex; data = that._mergeGroups(data, rangeData, startIndex, endIndex); if (end <= range.end && count == end - start) { return data; } } } break; } } return []; }, _mergeGroups: function (data, range, skip, take) { if (this._isServerGrouped()) { var temp = range.toJSON(), prevGroup; if (data.length) { prevGroup = data[data.length - 1]; } mergeGroups(prevGroup, temp, skip, take); return data.concat(temp); } return data.concat(range.slice(skip, take)); }, skip: function () { var that = this; if (that._skip === undefined) { return that._page !== undefined ? (that._page - 1) * (that.take() || 1) : undefined; } return that._skip; }, currentRangeStart: function () { return this._currentRangeStart || 0; }, take: function () { return this._take || this._pageSize; }, _prefetchSuccessHandler: function (skip, size, callback, force) { var that = this; var timestamp = that._timeStamp(); return function (data) { var found = false, range = { start: skip, end: size, data: [], timestamp: that._timeStamp() }, idx, length, temp; that._dequeueRequest(); that.trigger(REQUESTEND, { response: data, type: 'read' }); data = that.reader.parse(data); temp = that._readData(data); if (temp.length) { for (idx = 0, length = that._ranges.length; idx < length; idx++) { if (that._ranges[idx].start === skip) { found = true; range = that._ranges[idx]; break; } } if (!found) { that._ranges.push(range); } } range.data = that._observe(temp); range.end = range.start + that._flatData(range.data, true).length; that._ranges.sort(function (x, y) { return x.start - y.start; }); that._total = that.reader.total(data); if (force || (timestamp >= that._currentRequestTimeStamp || !that._skipRequestsInProgress)) { if (callback && temp.length) { callback(); } else { that.trigger(CHANGE, {}); } } }; }, prefetch: function (skip, take, callback) { var that = this, size = math.min(skip + take, that.total()), options = { take: take, skip: skip, page: skip / take + 1, pageSize: take, sort: that._sort, filter: that._filter, group: that._group, aggregate: that._aggregate }; if (!that._rangeExists(skip, size)) { clearTimeout(that._timeout); that._timeout = setTimeout(function () { that._queueRequest(options, function () { if (!that.trigger(REQUESTSTART, { type: 'read' })) { that.transport.read({ data: that._params(options), success: that._prefetchSuccessHandler(skip, size, callback), error: function () { var args = slice.call(arguments); that.error.apply(that, args); } }); } else { that._dequeueRequest(); } }); }, 100); } else if (callback) { callback(); } }, _multiplePrefetch: function (skip, take, callback) { var that = this, size = math.min(skip + take, that.total()), options = { take: take, skip: skip, page: skip / take + 1, pageSize: take, sort: that._sort, filter: that._filter, group: that._group, aggregate: that._aggregate }; if (!that._rangeExists(skip, size)) { if (!that.trigger(REQUESTSTART, { type: 'read' })) { that.transport.read({ data: that._params(options), success: that._prefetchSuccessHandler(skip, size, callback, true) }); } } else if (callback) { callback(); } }, _rangeExists: function (start, end) { var that = this, ranges = that._ranges, idx, length; for (idx = 0, length = ranges.length; idx < length; idx++) { if (ranges[idx].start <= start && ranges[idx].end >= end) { return true; } } return false; }, _removeModelFromRanges: function (model) { var result, found, range; for (var idx = 0, length = this._ranges.length; idx < length; idx++) { range = this._ranges[idx]; this._eachItem(range.data, function (items) { result = removeModel(items, model); if (result) { found = true; } }); if (found) { break; } } }, _updateRangesLength: function () { var startOffset = 0, range, rangeLength; for (var idx = 0, length = this._ranges.length; idx < length; idx++) { range = this._ranges[idx]; range.start = range.start - startOffset; rangeLength = this._flatData(range.data, true).length; startOffset = range.end - rangeLength; range.end = range.start + rangeLength; } } }); var Transport = {}; Transport.create = function (options, data, dataSource) { var transport, transportOptions = options.transport ? $.extend({}, options.transport) : null; if (transportOptions) { transportOptions.read = typeof transportOptions.read === STRING ? { url: transportOptions.read } : transportOptions.read; if (options.type === 'jsdo') { transportOptions.dataSource = dataSource; } if (options.type) { kendo.data.transports = kendo.data.transports || {}; kendo.data.schemas = kendo.data.schemas || {}; if (!kendo.data.transports[options.type]) { kendo.logToConsole('Unknown DataSource transport type \'' + options.type + '\'.\nVerify that registration scripts for this type are included after Kendo UI on the page.', 'warn'); } else if (!isPlainObject(kendo.data.transports[options.type])) { transport = new kendo.data.transports[options.type](extend(transportOptions, { data: data })); } else { transportOptions = extend(true, {}, kendo.data.transports[options.type], transportOptions); } options.schema = extend(true, {}, kendo.data.schemas[options.type], options.schema); } if (!transport) { transport = isFunction(transportOptions.read) ? transportOptions : new RemoteTransport(transportOptions); } } else { transport = new LocalTransport({ data: options.data || [] }); } return transport; }; DataSource.create = function (options) { if (isArray(options) || options instanceof ObservableArray) { options = { data: options }; } var dataSource = options || {}, data = dataSource.data, fields = dataSource.fields, table = dataSource.table, select = dataSource.select, idx, length, model = {}, field; if (!data && fields && !dataSource.transport) { if (table) { data = inferTable(table, fields); } else if (select) { data = inferSelect(select, fields); if (dataSource.group === undefined && data[0] && data[0].optgroup !== undefined) { dataSource.group = 'optgroup'; } } } if (kendo.data.Model && fields && (!dataSource.schema || !dataSource.schema.model)) { for (idx = 0, length = fields.length; idx < length; idx++) { field = fields[idx]; if (field.type) { model[field.field] = field; } } if (!isEmptyObject(model)) { dataSource.schema = extend(true, dataSource.schema, { model: { fields: model } }); } } dataSource.data = data; select = null; dataSource.select = null; table = null; dataSource.table = null; return dataSource instanceof DataSource ? dataSource : new DataSource(dataSource); }; function inferSelect(select, fields) { select = $(select)[0]; var options = select.options; var firstField = fields[0]; var secondField = fields[1]; var data = []; var idx, length; var optgroup; var option; var record; var value; for (idx = 0, length = options.length; idx < length; idx++) { record = {}; option = options[idx]; optgroup = option.parentNode; if (optgroup === select) { optgroup = null; } if (option.disabled || optgroup && optgroup.disabled) { continue; } if (optgroup) { record.optgroup = optgroup.label; } record[firstField.field] = option.text; value = option.attributes.value; if (value && value.specified) { value = option.value; } else { value = option.text; } record[secondField.field] = value; data.push(record); } return data; } function inferTable(table, fields) { var tbody = $(table)[0].tBodies[0], rows = tbody ? tbody.rows : [], idx, length, fieldIndex, fieldCount = fields.length, data = [], cells, record, cell, empty; for (idx = 0, length = rows.length; idx < length; idx++) { record = {}; empty = true; cells = rows[idx].cells; for (fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) { cell = cells[fieldIndex]; if (cell.nodeName.toLowerCase() !== 'th') { empty = false; record[fields[fieldIndex].field] = cell.innerHTML; } } if (!empty) { data.push(record); } } return data; } var Node = Model.define({ idField: 'id', init: function (value) { var that = this, hasChildren = that.hasChildren || value && value.hasChildren, childrenField = 'items', childrenOptions = {}; kendo.data.Model.fn.init.call(that, value); if (typeof that.children === STRING) { childrenField = that.children; } childrenOptions = { schema: { data: childrenField, model: { hasChildren: hasChildren, id: that.idField, fields: that.fields } } }; if (typeof that.children !== STRING) { extend(childrenOptions, that.children); } childrenOptions.data = value; if (!hasChildren) { hasChildren = childrenOptions.schema.data; } if (typeof hasChildren === STRING) { hasChildren = kendo.getter(hasChildren); } if (isFunction(hasChildren)) { that.hasChildren = !!hasChildren.call(that, that); } that._childrenOptions = childrenOptions; if (that.hasChildren) { that._initChildren(); } that._loaded = !!(value && value._loaded); }, _initChildren: function () { var that = this; var children, transport, parameterMap; if (!(that.children instanceof HierarchicalDataSource)) { children = that.children = new HierarchicalDataSource(that._childrenOptions); transport = children.transport; parameterMap = transport.parameterMap; transport.parameterMap = function (data, type) { data[that.idField || 'id'] = that.id; if (parameterMap) { data = parameterMap(data, type); } return data; }; children.parent = function () { return that; }; children.bind(CHANGE, function (e) { e.node = e.node || that; that.trigger(CHANGE, e); }); children.bind(ERROR, function (e) { var collection = that.parent(); if (collection) { e.node = e.node || that; collection.trigger(ERROR, e); } }); that._updateChildrenField(); } }, append: function (model) { this._initChildren(); this.loaded(true); this.children.add(model); }, hasChildren: false, level: function () { var parentNode = this.parentNode(), level = 0; while (parentNode && parentNode.parentNode) { level++; parentNode = parentNode.parentNode ? parentNode.parentNode() : null; } return level; }, _updateChildrenField: function () { var fieldName = this._childrenOptions.schema.data; this[fieldName || 'items'] = this.children.data(); }, _childrenLoaded: function () { this._loaded = true; this._updateChildrenField(); }, load: function () { var options = {}; var method = '_query'; var children, promise; if (this.hasChildren) { this._initChildren(); children = this.children; options[this.idField || 'id'] = this.id; if (!this._loaded) { children._data = undefined; method = 'read'; } children.one(CHANGE, proxy(this._childrenLoaded, this)); promise = children[method](options); } else { this.loaded(true); } return promise || $.Deferred().resolve().promise(); }, parentNode: function () { var array = this.parent(); return array.parent(); }, loaded: function (value) { if (value !== undefined) { this._loaded = value; } else { return this._loaded; } }, shouldSerialize: function (field) { return Model.fn.shouldSerialize.call(this, field) && field !== 'children' && field !== '_loaded' && field !== 'hasChildren' && field !== '_childrenOptions'; } }); function dataMethod(name) { return function () { var data = this._data, result = DataSource.fn[name].apply(this, slice.call(arguments)); if (this._data != data) { this._attachBubbleHandlers(); } return result; }; } var HierarchicalDataSource = DataSource.extend({ init: function (options) { var node = Node.define({ children: options }); DataSource.fn.init.call(this, extend(true, {}, { schema: { modelBase: node, model: node } }, options)); this._attachBubbleHandlers(); }, _attachBubbleHandlers: function () { var that = this; that._data.bind(ERROR, function (e) { that.trigger(ERROR, e); }); }, remove: function (node) { var parentNode = node.parentNode(), dataSource = this, result; if (parentNode && parentNode._initChildren) { dataSource = parentNode.children; } result = DataSource.fn.remove.call(dataSource, node); if (parentNode && !dataSource.data().length) { parentNode.hasChildren = false; } return result; }, success: dataMethod('success'), data: dataMethod('data'), insert: function (index, model) { var parentNode = this.parent(); if (parentNode && parentNode._initChildren) { parentNode.hasChildren = true; parentNode._initChildren(); } return DataSource.fn.insert.call(this, index, model); }, _find: function (method, value) { var idx, length, node, children; var data = this._data; if (!data) { return; } node = DataSource.fn[method].call(this, value); if (node) { return node; } data = this._flatData(this._data); for (idx = 0, length = data.length; idx < length; idx++) { children = data[idx].children; if (!(children instanceof HierarchicalDataSource)) { continue; } node = children[method](value); if (node) { return node; } } }, get: function (id) { return this._find('get', id); }, getByUid: function (uid) { return this._find('getByUid', uid); } }); function inferList(list, fields) { var items = $(list).children(), idx, length, data = [], record, textField = fields[0].field, urlField = fields[1] && fields[1].field, spriteCssClassField = fields[2] && fields[2].field, imageUrlField = fields[3] && fields[3].field, item, id, textChild, className, children; function elements(collection, tagName) { return collection.filter(tagName).add(collection.find(tagName)); } for (idx = 0, length = items.length; idx < length; idx++) { record = { _loaded: true }; item = items.eq(idx); textChild = item[0].firstChild; children = item.children(); list = children.filter('ul'); children = children.filter(':not(ul)'); id = item.attr('data-id'); if (id) { record.id = id; } if (textChild) { record[textField] = textChild.nodeType == 3 ? textChild.nodeValue : children.text(); } if (urlField) { record[urlField] = elements(children, 'a').attr('href'); } if (imageUrlField) { record[imageUrlField] = elements(children, 'img').attr('src'); } if (spriteCssClassField) { className = elements(children, '.k-sprite').prop('className'); record[spriteCssClassField] = className && $.trim(className.replace('k-sprite', '')); } if (list.length) { record.items = inferList(list.eq(0), fields); } if (item.attr('data-hasChildren') == 'true') { record.hasChildren = true; } data.push(record); } return data; } HierarchicalDataSource.create = function (options) { options = options && options.push ? { data: options } : options; var dataSource = options || {}, data = dataSource.data, fields = dataSource.fields, list = dataSource.list; if (data && data._dataSource) { return data._dataSource; } if (!data && fields && !dataSource.transport) { if (list) { data = inferList(list, fields); } } dataSource.data = data; return dataSource instanceof HierarchicalDataSource ? dataSource : new HierarchicalDataSource(dataSource); }; var Buffer = kendo.Observable.extend({ init: function (dataSource, viewSize, disablePrefetch) { kendo.Observable.fn.init.call(this); this._prefetching = false; this.dataSource = dataSource; this.prefetch = !disablePrefetch; var buffer = this; dataSource.bind('change', function () { buffer._change(); }); dataSource.bind('reset', function () { buffer._reset(); }); this._syncWithDataSource(); this.setViewSize(viewSize); }, setViewSize: function (viewSize) { this.viewSize = viewSize; this._recalculate(); }, at: function (index) { var pageSize = this.pageSize, itemPresent = true; if (index >= this.total()) { this.trigger('endreached', { index: index }); return null; } if (!this.useRanges) { return this.dataSource.view()[index]; } if (this.useRanges) { if (index < this.dataOffset || index >= this.skip + pageSize) { itemPresent = this.range(Math.floor(index / pageSize) * pageSize); } if (index === this.prefetchThreshold) { this._prefetch(); } if (index === this.midPageThreshold) { this.range(this.nextMidRange, true); } else if (index === this.nextPageThreshold) { this.range(this.nextFullRange); } else if (index === this.pullBackThreshold) { if (this.offset === this.skip) { this.range(this.previousMidRange); } else { this.range(this.previousFullRange); } } if (itemPresent) { return this.dataSource.at(index - this.dataOffset); } else { this.trigger('endreached', { index: index }); return null; } } }, indexOf: function (item) { return this.dataSource.data().indexOf(item) + this.dataOffset; }, total: function () { return parseInt(this.dataSource.total(), 10); }, next: function () { var buffer = this, pageSize = buffer.pageSize, offset = buffer.skip - buffer.viewSize + pageSize, pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize; this.offset = offset; this.dataSource.prefetch(pageSkip, pageSize, function () { buffer._goToRange(offset, true); }); }, range: function (offset, nextRange) { if (this.offset === offset) { return true; } var buffer = this, pageSize = this.pageSize, pageSkip = math.max(math.floor(offset / pageSize), 0) * pageSize, dataSource = this.dataSource; if (nextRange) { pageSkip += pageSize; } if (dataSource.inRange(offset, pageSize)) { this.offset = offset; this._recalculate(); this._goToRange(offset); return true; } else if (this.prefetch) { dataSource.prefetch(pageSkip, pageSize, function () { buffer.offset = offset; buffer._recalculate(); buffer._goToRange(offset, true); }); return false; } return true; }, syncDataSource: function () { var offset = this.offset; this.offset = null; this.range(offset); }, destroy: function () { this.unbind(); }, _prefetch: function () { var buffer = this, pageSize = this.pageSize, prefetchOffset = this.skip + pageSize, dataSource = this.dataSource; if (!dataSource.inRange(prefetchOffset, pageSize) && !this._prefetching && this.prefetch) { this._prefetching = true; this.trigger('prefetching', { skip: prefetchOffset, take: pageSize }); dataSource.prefetch(prefetchOffset, pageSize, function () { buffer._prefetching = false; buffer.trigger('prefetched', { skip: prefetchOffset, take: pageSize }); }); } }, _goToRange: function (offset, expanding) { if (this.offset !== offset) { return; } this.dataOffset = offset; this._expanding = expanding; this.dataSource.range(offset, this.pageSize); this.dataSource.enableRequestsInProgress(); }, _reset: function () { this._syncPending = true; }, _change: function () { var dataSource = this.dataSource; this.length = this.useRanges ? dataSource.lastRange().end : dataSource.view().length; if (this._syncPending) { this._syncWithDataSource(); this._recalculate(); this._syncPending = false; this.trigger('reset', { offset: this.offset }); } this.trigger('resize'); if (this._expanding) { this.trigger('expand'); } delete this._expanding; }, _syncWithDataSource: function () { var dataSource = this.dataSource; this._firstItemUid = dataSource.firstItemUid(); this.dataOffset = this.offset = dataSource.skip() || 0; this.pageSize = dataSource.pageSize(); this.useRanges = dataSource.options.serverPaging; }, _recalculate: function () { var pageSize = this.pageSize, offset = this.offset, viewSize = this.viewSize, skip = Math.ceil(offset / pageSize) * pageSize; this.skip = skip; this.midPageThreshold = skip + pageSize - 1; this.nextPageThreshold = skip + viewSize - 1; this.prefetchThreshold = skip + Math.floor(pageSize / 3 * 2); this.pullBackThreshold = this.offset - 1; this.nextMidRange = skip + pageSize - viewSize; this.nextFullRange = skip; this.previousMidRange = offset - viewSize; this.previousFullRange = skip - pageSize; } }); var BatchBuffer = kendo.Observable.extend({ init: function (dataSource, batchSize) { var batchBuffer = this; kendo.Observable.fn.init.call(batchBuffer); this.dataSource = dataSource; this.batchSize = batchSize; this._total = 0; this.buffer = new Buffer(dataSource, batchSize * 3); this.buffer.bind({ 'endreached': function (e) { batchBuffer.trigger('endreached', { index: e.index }); }, 'prefetching': function (e) { batchBuffer.trigger('prefetching', { skip: e.skip, take: e.take }); }, 'prefetched': function (e) { batchBuffer.trigger('prefetched', { skip: e.skip, take: e.take }); }, 'reset': function () { batchBuffer._total = 0; batchBuffer.trigger('reset'); }, 'resize': function () { batchBuffer._total = Math.ceil(this.length / batchBuffer.batchSize); batchBuffer.trigger('resize', { total: batchBuffer.total(), offset: this.offset }); } }); }, syncDataSource: function () { this.buffer.syncDataSource(); }, at: function (index) { var buffer = this.buffer, skip = index * this.batchSize, take = this.batchSize, view = [], item; if (buffer.offset > skip) { buffer.at(buffer.offset - 1); } for (var i = 0; i < take; i++) { item = buffer.at(skip + i); if (item === null) { break; } view.push(item); } return view; }, total: function () { return this._total; }, destroy: function () { this.buffer.destroy(); this.unbind(); } }); extend(true, kendo.data, { readers: { json: DataReader }, Query: Query, DataSource: DataSource, HierarchicalDataSource: HierarchicalDataSource, Node: Node, ObservableObject: ObservableObject, ObservableArray: ObservableArray, LazyObservableArray: LazyObservableArray, LocalTransport: LocalTransport, RemoteTransport: RemoteTransport, Cache: Cache, DataReader: DataReader, Model: Model, Buffer: Buffer, BatchBuffer: BatchBuffer }); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.binder', [ 'kendo.core', 'kendo.data' ], f); }(function () { var __meta__ = { id: 'binder', name: 'MVVM', category: 'framework', description: 'Model View ViewModel (MVVM) is a design pattern which helps developers separate the Model (the data) from the View (the UI).', depends: [ 'core', 'data' ] }; (function ($, undefined) { var kendo = window.kendo, Observable = kendo.Observable, ObservableObject = kendo.data.ObservableObject, ObservableArray = kendo.data.ObservableArray, toString = {}.toString, binders = {}, Class = kendo.Class, proxy = $.proxy, VALUE = 'value', SOURCE = 'source', EVENTS = 'events', CHECKED = 'checked', CSS = 'css', deleteExpando = true, FUNCTION = 'function', CHANGE = 'change'; (function () { var a = document.createElement('a'); try { delete a.test; } catch (e) { deleteExpando = false; } }()); var Binding = Observable.extend({ init: function (parents, path) { var that = this; Observable.fn.init.call(that); that.source = parents[0]; that.parents = parents; that.path = path; that.dependencies = {}; that.dependencies[path] = true; that.observable = that.source instanceof Observable; that._access = function (e) { that.dependencies[e.field] = true; }; if (that.observable) { that._change = function (e) { that.change(e); }; that.source.bind(CHANGE, that._change); } }, _parents: function () { var parents = this.parents; var value = this.get(); if (value && typeof value.parent == 'function') { var parent = value.parent(); if ($.inArray(parent, parents) < 0) { parents = [parent].concat(parents); } } return parents; }, change: function (e) { var dependency, ch, field = e.field, that = this; if (that.path === 'this') { that.trigger(CHANGE, e); } else { for (dependency in that.dependencies) { if (dependency.indexOf(field) === 0) { ch = dependency.charAt(field.length); if (!ch || ch === '.' || ch === '[') { that.trigger(CHANGE, e); break; } } } } }, start: function (source) { source.bind('get', this._access); }, stop: function (source) { source.unbind('get', this._access); }, get: function () { var that = this, source = that.source, index = 0, path = that.path, result = source; if (!that.observable) { return result; } that.start(that.source); result = source.get(path); while (result === undefined && source) { source = that.parents[++index]; if (source instanceof ObservableObject) { result = source.get(path); } } if (result === undefined) { source = that.source; while (result === undefined && source) { source = source.parent(); if (source instanceof ObservableObject) { result = source.get(path); } } } if (typeof result === 'function') { index = path.lastIndexOf('.'); if (index > 0) { source = source.get(path.substring(0, index)); } that.start(source); if (source !== that.source) { result = result.call(source, that.source); } else { result = result.call(source); } that.stop(source); } if (source && source !== that.source) { that.currentSource = source; source.unbind(CHANGE, that._change).bind(CHANGE, that._change); } that.stop(that.source); return result; }, set: function (value) { var source = this.currentSource || this.source; var field = kendo.getter(this.path)(source); if (typeof field === 'function') { if (source !== this.source) { field.call(source, this.source, value); } else { field.call(source, value); } } else { source.set(this.path, value); } }, destroy: function () { if (this.observable) { this.source.unbind(CHANGE, this._change); if (this.currentSource) { this.currentSource.unbind(CHANGE, this._change); } } this.unbind(); } }); var EventBinding = Binding.extend({ get: function () { var source = this.source, path = this.path, index = 0, handler; handler = source.get(path); while (!handler && source) { source = this.parents[++index]; if (source instanceof ObservableObject) { handler = source.get(path); } } return proxy(handler, source); } }); var TemplateBinding = Binding.extend({ init: function (source, path, template) { var that = this; Binding.fn.init.call(that, source, path); that.template = template; }, render: function (value) { var html; this.start(this.source); html = kendo.render(this.template, value); this.stop(this.source); return html; } }); var Binder = Class.extend({ init: function (element, bindings, options) { this.element = element; this.bindings = bindings; this.options = options; }, bind: function (binding, attribute) { var that = this; binding = attribute ? binding[attribute] : binding; binding.bind(CHANGE, function (e) { that.refresh(attribute || e); }); that.refresh(attribute); }, destroy: function () { } }); var TypedBinder = Binder.extend({ dataType: function () { var dataType = this.element.getAttribute('data-type') || this.element.type || 'text'; return dataType.toLowerCase(); }, parsedValue: function () { return this._parseValue(this.element.value, this.dataType()); }, _parseValue: function (value, dataType) { if (dataType == 'date') { value = kendo.parseDate(value, 'yyyy-MM-dd'); } else if (dataType == 'datetime-local') { value = kendo.parseDate(value, [ 'yyyy-MM-ddTHH:mm:ss', 'yyyy-MM-ddTHH:mm' ]); } else if (dataType == 'number') { value = kendo.parseFloat(value); } else if (dataType == 'boolean') { value = value.toLowerCase(); if (kendo.parseFloat(value) !== null) { value = Boolean(kendo.parseFloat(value)); } else { value = value.toLowerCase() === 'true'; } } return value; } }); binders.attr = Binder.extend({ refresh: function (key) { this.element.setAttribute(key, this.bindings.attr[key].get()); } }); binders.css = Binder.extend({ init: function (element, bindings, options) { Binder.fn.init.call(this, element, bindings, options); this.classes = {}; }, refresh: function (className) { var element = $(this.element), binding = this.bindings.css[className], hasClass = this.classes[className] = binding.get(); if (hasClass) { element.addClass(className); } else { element.removeClass(className); } } }); binders.style = Binder.extend({ refresh: function (key) { this.element.style[key] = this.bindings.style[key].get() || ''; } }); binders.enabled = Binder.extend({ refresh: function () { if (this.bindings.enabled.get()) { this.element.removeAttribute('disabled'); } else { this.element.setAttribute('disabled', 'disabled'); } } }); binders.readonly = Binder.extend({ refresh: function () { if (this.bindings.readonly.get()) { this.element.setAttribute('readonly', 'readonly'); } else { this.element.removeAttribute('readonly'); } } }); binders.disabled = Binder.extend({ refresh: function () { if (this.bindings.disabled.get()) { this.element.setAttribute('disabled', 'disabled'); } else { this.element.removeAttribute('disabled'); } } }); binders.events = Binder.extend({ init: function (element, bindings, options) { Binder.fn.init.call(this, element, bindings, options); this.handlers = {}; }, refresh: function (key) { var element = $(this.element), binding = this.bindings.events[key], handler = this.handlers[key]; if (handler) { element.off(key, handler); } handler = this.handlers[key] = binding.get(); element.on(key, binding.source, handler); }, destroy: function () { var element = $(this.element), handler; for (handler in this.handlers) { element.off(handler, this.handlers[handler]); } } }); binders.text = Binder.extend({ refresh: function () { var text = this.bindings.text.get(); var dataFormat = this.element.getAttribute('data-format') || ''; if (text == null) { text = ''; } $(this.element).text(kendo.toString(text, dataFormat)); } }); binders.visible = Binder.extend({ refresh: function () { if (this.bindings.visible.get()) { this.element.style.display = ''; } else { this.element.style.display = 'none'; } } }); binders.invisible = Binder.extend({ refresh: function () { if (!this.bindings.invisible.get()) { this.element.style.display = ''; } else { this.element.style.display = 'none'; } } }); binders.html = Binder.extend({ refresh: function () { this.element.innerHTML = this.bindings.html.get(); } }); binders.value = TypedBinder.extend({ init: function (element, bindings, options) { TypedBinder.fn.init.call(this, element, bindings, options); this._change = proxy(this.change, this); this.eventName = options.valueUpdate || CHANGE; $(this.element).on(this.eventName, this._change); this._initChange = false; }, change: function () { this._initChange = this.eventName != CHANGE; this.bindings[VALUE].set(this.parsedValue()); this._initChange = false; }, refresh: function () { if (!this._initChange) { var value = this.bindings[VALUE].get(); if (value == null) { value = ''; } var type = this.dataType(); if (type == 'date') { value = kendo.toString(value, 'yyyy-MM-dd'); } else if (type == 'datetime-local') { value = kendo.toString(value, 'yyyy-MM-ddTHH:mm:ss'); } this.element.value = value; } this._initChange = false; }, destroy: function () { $(this.element).off(this.eventName, this._change); } }); binders.source = Binder.extend({ init: function (element, bindings, options) { Binder.fn.init.call(this, element, bindings, options); var source = this.bindings.source.get(); if (source instanceof kendo.data.DataSource && options.autoBind !== false) { source.fetch(); } }, refresh: function (e) { var that = this, source = that.bindings.source.get(); if (source instanceof ObservableArray || source instanceof kendo.data.DataSource) { e = e || {}; if (e.action == 'add') { that.add(e.index, e.items); } else if (e.action == 'remove') { that.remove(e.index, e.items); } else if (e.action != 'itemchange') { that.render(); } } else { that.render(); } }, container: function () { var element = this.element; if (element.nodeName.toLowerCase() == 'table') { if (!element.tBodies[0]) { element.appendChild(document.createElement('tbody')); } element = element.tBodies[0]; } return element; }, template: function () { var options = this.options, template = options.template, nodeName = this.container().nodeName.toLowerCase(); if (!template) { if (nodeName == 'select') { if (options.valueField || options.textField) { template = kendo.format('', options.valueField || options.textField, options.textField || options.valueField); } else { template = ''; } } else if (nodeName == 'tbody') { template = '#:data#'; } else if (nodeName == 'ul' || nodeName == 'ol') { template = '
  • #:data#
  • '; } else { template = '#:data#'; } template = kendo.template(template); } return template; }, add: function (index, items) { var element = this.container(), parents, idx, length, child, clone = element.cloneNode(false), reference = element.children[index]; $(clone).html(kendo.render(this.template(), items)); if (clone.children.length) { parents = this.bindings.source._parents(); for (idx = 0, length = items.length; idx < length; idx++) { child = clone.children[0]; element.insertBefore(child, reference || null); bindElement(child, items[idx], this.options.roles, [items[idx]].concat(parents)); } } }, remove: function (index, items) { var idx, element = this.container(); for (idx = 0; idx < items.length; idx++) { var child = element.children[index]; unbindElementTree(child, true); element.removeChild(child); } }, render: function () { var source = this.bindings.source.get(), parents, idx, length, element = this.container(), template = this.template(); if (source == null) { return; } if (source instanceof kendo.data.DataSource) { source = source.view(); } if (!(source instanceof ObservableArray) && toString.call(source) !== '[object Array]') { source = [source]; } if (this.bindings.template) { unbindElementChildren(element, true); $(element).html(this.bindings.template.render(source)); if (element.children.length) { parents = this.bindings.source._parents(); for (idx = 0, length = source.length; idx < length; idx++) { bindElement(element.children[idx], source[idx], this.options.roles, [source[idx]].concat(parents)); } } } else { $(element).html(kendo.render(template, source)); } } }); binders.input = { checked: TypedBinder.extend({ init: function (element, bindings, options) { TypedBinder.fn.init.call(this, element, bindings, options); this._change = proxy(this.change, this); $(this.element).change(this._change); }, change: function () { var element = this.element; var value = this.value(); if (element.type == 'radio') { value = this.parsedValue(); this.bindings[CHECKED].set(value); } else if (element.type == 'checkbox') { var source = this.bindings[CHECKED].get(); var index; if (source instanceof ObservableArray) { value = this.parsedValue(); if (value instanceof Date) { for (var i = 0; i < source.length; i++) { if (source[i] instanceof Date && +source[i] === +value) { index = i; break; } } } else { index = source.indexOf(value); } if (index > -1) { source.splice(index, 1); } else { source.push(value); } } else { this.bindings[CHECKED].set(value); } } }, refresh: function () { var value = this.bindings[CHECKED].get(), source = value, type = this.dataType(), element = this.element; if (element.type == 'checkbox') { if (source instanceof ObservableArray) { var index = -1; value = this.parsedValue(); if (value instanceof Date) { for (var i = 0; i < source.length; i++) { if (source[i] instanceof Date && +source[i] === +value) { index = i; break; } } } else { index = source.indexOf(value); } element.checked = index >= 0; } else { element.checked = source; } } else if (element.type == 'radio' && value != null) { if (type == 'date') { value = kendo.toString(value, 'yyyy-MM-dd'); } else if (type == 'datetime-local') { value = kendo.toString(value, 'yyyy-MM-ddTHH:mm:ss'); } if (element.value === value.toString()) { element.checked = true; } else { element.checked = false; } } }, value: function () { var element = this.element, value = element.value; if (element.type == 'checkbox') { value = element.checked; } return value; }, destroy: function () { $(this.element).off(CHANGE, this._change); } }) }; binders.select = { source: binders.source.extend({ refresh: function (e) { var that = this, source = that.bindings.source.get(); if (source instanceof ObservableArray || source instanceof kendo.data.DataSource) { e = e || {}; if (e.action == 'add') { that.add(e.index, e.items); } else if (e.action == 'remove') { that.remove(e.index, e.items); } else if (e.action == 'itemchange' || e.action === undefined) { that.render(); if (that.bindings.value) { if (that.bindings.value) { var val = retrievePrimitiveValues(that.bindings.value.get(), $(that.element).data('valueField')); if (val === null) { that.element.selectedIndex = -1; } else { that.element.value = val; } } } } } else { that.render(); } } }), value: TypedBinder.extend({ init: function (target, bindings, options) { TypedBinder.fn.init.call(this, target, bindings, options); this._change = proxy(this.change, this); $(this.element).change(this._change); }, parsedValue: function () { var dataType = this.dataType(); var values = []; var value, option, idx, length; for (idx = 0, length = this.element.options.length; idx < length; idx++) { option = this.element.options[idx]; if (option.selected) { value = option.attributes.value; if (value && value.specified) { value = option.value; } else { value = option.text; } values.push(this._parseValue(value, dataType)); } } return values; }, change: function () { var values = [], element = this.element, source, field = this.options.valueField || this.options.textField, valuePrimitive = this.options.valuePrimitive, option, valueIndex, value, idx, length; for (idx = 0, length = element.options.length; idx < length; idx++) { option = element.options[idx]; if (option.selected) { value = option.attributes.value; if (value && value.specified) { value = option.value; } else { value = option.text; } values.push(this._parseValue(value, this.dataType())); } } if (field) { source = this.bindings.source.get(); if (source instanceof kendo.data.DataSource) { source = source.view(); } for (valueIndex = 0; valueIndex < values.length; valueIndex++) { for (idx = 0, length = source.length; idx < length; idx++) { var sourceValue = this._parseValue(source[idx].get(field), this.dataType()); var match = String(sourceValue) === values[valueIndex]; if (match) { values[valueIndex] = source[idx]; break; } } } } value = this.bindings[VALUE].get(); if (value instanceof ObservableArray) { value.splice.apply(value, [ 0, value.length ].concat(values)); } else if (!valuePrimitive && (value instanceof ObservableObject || value === null || value === undefined || !field)) { this.bindings[VALUE].set(values[0]); } else { this.bindings[VALUE].set(values[0].get(field)); } }, refresh: function () { var optionIndex, element = this.element, options = element.options, value = this.bindings[VALUE].get(), values = value, field = this.options.valueField || this.options.textField, found = false, type = this.dataType(), optionValue; if (!(values instanceof ObservableArray)) { values = new ObservableArray([value]); } element.selectedIndex = -1; for (var valueIndex = 0; valueIndex < values.length; valueIndex++) { value = values[valueIndex]; if (field && value instanceof ObservableObject) { value = value.get(field); } if (type == 'date') { value = kendo.toString(values[valueIndex], 'yyyy-MM-dd'); } else if (type == 'datetime-local') { value = kendo.toString(values[valueIndex], 'yyyy-MM-ddTHH:mm:ss'); } for (optionIndex = 0; optionIndex < options.length; optionIndex++) { optionValue = options[optionIndex].value; if (optionValue === '' && value !== '') { optionValue = options[optionIndex].text; } if (value != null && optionValue == value.toString()) { options[optionIndex].selected = true; found = true; } } } }, destroy: function () { $(this.element).off(CHANGE, this._change); } }) }; function dataSourceBinding(bindingName, fieldName, setter) { return Binder.extend({ init: function (widget, bindings, options) { var that = this; Binder.fn.init.call(that, widget.element[0], bindings, options); that.widget = widget; that._dataBinding = proxy(that.dataBinding, that); that._dataBound = proxy(that.dataBound, that); that._itemChange = proxy(that.itemChange, that); }, itemChange: function (e) { bindElement(e.item[0], e.data, this._ns(e.ns), [e.data].concat(this.bindings[bindingName]._parents())); }, dataBinding: function (e) { var idx, length, widget = this.widget, items = e.removedItems || widget.items(); for (idx = 0, length = items.length; idx < length; idx++) { unbindElementTree(items[idx], false); } }, _ns: function (ns) { ns = ns || kendo.ui; var all = [ kendo.ui, kendo.dataviz.ui, kendo.mobile.ui ]; all.splice($.inArray(ns, all), 1); all.unshift(ns); return kendo.rolesFromNamespaces(all); }, dataBound: function (e) { var idx, length, widget = this.widget, items = e.addedItems || widget.items(), dataSource = widget[fieldName], view, parents, hds = kendo.data.HierarchicalDataSource; if (hds && dataSource instanceof hds) { return; } if (items.length) { view = e.addedDataItems || dataSource.flatView(); parents = this.bindings[bindingName]._parents(); for (idx = 0, length = view.length; idx < length; idx++) { bindElement(items[idx], view[idx], this._ns(e.ns), [view[idx]].concat(parents)); } } }, refresh: function (e) { var that = this, source, widget = that.widget, select, multiselect; e = e || {}; if (!e.action) { that.destroy(); widget.bind('dataBinding', that._dataBinding); widget.bind('dataBound', that._dataBound); widget.bind('itemChange', that._itemChange); source = that.bindings[bindingName].get(); if (widget[fieldName] instanceof kendo.data.DataSource && widget[fieldName] != source) { if (source instanceof kendo.data.DataSource) { widget[setter](source); } else if (source && source._dataSource) { widget[setter](source._dataSource); } else { widget[fieldName].data(source); select = kendo.ui.Select && widget instanceof kendo.ui.Select; multiselect = kendo.ui.MultiSelect && widget instanceof kendo.ui.MultiSelect; if (that.bindings.value && (select || multiselect)) { widget.value(retrievePrimitiveValues(that.bindings.value.get(), widget.options.dataValueField)); } } } } }, destroy: function () { var widget = this.widget; widget.unbind('dataBinding', this._dataBinding); widget.unbind('dataBound', this._dataBound); widget.unbind('itemChange', this._itemChange); } }); } binders.widget = { events: Binder.extend({ init: function (widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; this.handlers = {}; }, refresh: function (key) { var binding = this.bindings.events[key], handler = this.handlers[key]; if (handler) { this.widget.unbind(key, handler); } handler = binding.get(); this.handlers[key] = function (e) { e.data = binding.source; handler(e); if (e.data === binding.source) { delete e.data; } }; this.widget.bind(key, this.handlers[key]); }, destroy: function () { var handler; for (handler in this.handlers) { this.widget.unbind(handler, this.handlers[handler]); } } }), checked: Binder.extend({ init: function (widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; this._change = proxy(this.change, this); this.widget.bind(CHANGE, this._change); }, change: function () { this.bindings[CHECKED].set(this.value()); }, refresh: function () { this.widget.check(this.bindings[CHECKED].get() === true); }, value: function () { var element = this.element, value = element.value; if (value == 'on' || value == 'off') { value = element.checked; } return value; }, destroy: function () { this.widget.unbind(CHANGE, this._change); } }), visible: Binder.extend({ init: function (widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; }, refresh: function () { var visible = this.bindings.visible.get(); this.widget.wrapper[0].style.display = visible ? '' : 'none'; } }), invisible: Binder.extend({ init: function (widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; }, refresh: function () { var invisible = this.bindings.invisible.get(); this.widget.wrapper[0].style.display = invisible ? 'none' : ''; } }), enabled: Binder.extend({ init: function (widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; }, refresh: function () { if (this.widget.enable) { this.widget.enable(this.bindings.enabled.get()); } } }), disabled: Binder.extend({ init: function (widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; }, refresh: function () { if (this.widget.enable) { this.widget.enable(!this.bindings.disabled.get()); } } }), source: dataSourceBinding('source', 'dataSource', 'setDataSource'), value: Binder.extend({ init: function (widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; this._change = $.proxy(this.change, this); this.widget.first(CHANGE, this._change); var value = this.bindings.value.get(); this._valueIsObservableObject = !options.valuePrimitive && (value == null || value instanceof ObservableObject); this._valueIsObservableArray = value instanceof ObservableArray; this._initChange = false; }, _source: function () { var source; if (this.widget.dataItem) { source = this.widget.dataItem(); if (source && source instanceof ObservableObject) { return [source]; } } if (this.bindings.source) { source = this.bindings.source.get(); } if (!source || source instanceof kendo.data.DataSource) { source = this.widget.dataSource.flatView(); } return source; }, change: function () { var value = this.widget.value(), field = this.options.dataValueField || this.options.dataTextField, isArray = toString.call(value) === '[object Array]', isObservableObject = this._valueIsObservableObject, valueIndex, valueLength, values = [], sourceItem, sourceValue, idx, length, source; this._initChange = true; if (field) { if (value === '' && (isObservableObject || this.options.valuePrimitive)) { value = null; } else { source = this._source(); if (isArray) { valueLength = value.length; values = value.slice(0); } for (idx = 0, length = source.length; idx < length; idx++) { sourceItem = source[idx]; sourceValue = sourceItem.get(field); if (isArray) { for (valueIndex = 0; valueIndex < valueLength; valueIndex++) { if (sourceValue == values[valueIndex]) { values[valueIndex] = sourceItem; break; } } } else if (sourceValue == value) { value = isObservableObject ? sourceItem : sourceValue; break; } } if (values[0]) { if (this._valueIsObservableArray) { value = values; } else if (isObservableObject || !field) { value = values[0]; } else { value = values[0].get(field); } } } } this.bindings.value.set(value); this._initChange = false; }, refresh: function () { if (!this._initChange) { var widget = this.widget; var options = widget.options; var textField = options.dataTextField; var valueField = options.dataValueField || textField; var value = this.bindings.value.get(); var text = options.text || ''; var idx = 0, length; var values = []; if (value === undefined) { value = null; } if (valueField) { if (value instanceof ObservableArray) { for (length = value.length; idx < length; idx++) { values[idx] = value[idx].get(valueField); } value = values; } else if (value instanceof ObservableObject) { text = value.get(textField); value = value.get(valueField); } } if (options.autoBind === false && !options.cascadeFrom && widget.listView && !widget.listView.bound()) { if (textField === valueField && !text) { text = value; } if (!text && (value || value === 0) && options.valuePrimitive) { widget.value(value); } else { widget._preselect(value, text); } } else { widget.value(value); } } this._initChange = false; }, destroy: function () { this.widget.unbind(CHANGE, this._change); } }), gantt: { dependencies: dataSourceBinding('dependencies', 'dependencies', 'setDependenciesDataSource') }, multiselect: { value: Binder.extend({ init: function (widget, bindings, options) { Binder.fn.init.call(this, widget.element[0], bindings, options); this.widget = widget; this._change = $.proxy(this.change, this); this.widget.first(CHANGE, this._change); this._initChange = false; }, change: function () { var that = this, oldValues = that.bindings[VALUE].get(), valuePrimitive = that.options.valuePrimitive, newValues = valuePrimitive ? that.widget.value() : that.widget.dataItems(); var field = this.options.dataValueField || this.options.dataTextField; newValues = newValues.slice(0); that._initChange = true; if (oldValues instanceof ObservableArray) { var remove = []; var newLength = newValues.length; var i = 0, j = 0; var old = oldValues[i]; var same = false; var removeIndex; var newValue; var found; while (old !== undefined) { found = false; for (j = 0; j < newLength; j++) { if (valuePrimitive) { same = newValues[j] == old; } else { newValue = newValues[j]; newValue = newValue.get ? newValue.get(field) : newValue; same = newValue == (old.get ? old.get(field) : old); } if (same) { newValues.splice(j, 1); newLength -= 1; found = true; break; } } if (!found) { remove.push(old); arraySplice(oldValues, i, 1); removeIndex = i; } else { i += 1; } old = oldValues[i]; } arraySplice(oldValues, oldValues.length, 0, newValues); if (remove.length) { oldValues.trigger('change', { action: 'remove', items: remove, index: removeIndex }); } if (newValues.length) { oldValues.trigger('change', { action: 'add', items: newValues, index: oldValues.length - 1 }); } } else { that.bindings[VALUE].set(newValues); } that._initChange = false; }, refresh: function () { if (!this._initChange) { var options = this.options, widget = this.widget, field = options.dataValueField || options.dataTextField, value = this.bindings.value.get(), data = value, idx = 0, length, values = [], selectedValue; if (value === undefined) { value = null; } if (field) { if (value instanceof ObservableArray) { for (length = value.length; idx < length; idx++) { selectedValue = value[idx]; values[idx] = selectedValue.get ? selectedValue.get(field) : selectedValue; } value = values; } else if (value instanceof ObservableObject) { value = value.get(field); } } if (options.autoBind === false && options.valuePrimitive !== true && !widget._isBound()) { widget._preselect(data, value); } else { widget.value(value); } } }, destroy: function () { this.widget.unbind(CHANGE, this._change); } }) }, scheduler: { source: dataSourceBinding('source', 'dataSource', 'setDataSource').extend({ dataBound: function (e) { var idx; var length; var widget = this.widget; var elements = e.addedItems || widget.items(); var data, parents; if (elements.length) { data = e.addedDataItems || widget.dataItems(); parents = this.bindings.source._parents(); for (idx = 0, length = data.length; idx < length; idx++) { bindElement(elements[idx], data[idx], this._ns(e.ns), [data[idx]].concat(parents)); } } } }) } }; var arraySplice = function (arr, idx, remove, add) { add = add || []; remove = remove || 0; var addLength = add.length; var oldLength = arr.length; var shifted = [].slice.call(arr, idx + remove); var shiftedLength = shifted.length; var index; if (addLength) { addLength = idx + addLength; index = 0; for (; idx < addLength; idx++) { arr[idx] = add[index]; index++; } arr.length = addLength; } else if (remove) { arr.length = idx; remove += idx; while (idx < remove) { delete arr[--remove]; } } if (shiftedLength) { shiftedLength = idx + shiftedLength; index = 0; for (; idx < shiftedLength; idx++) { arr[idx] = shifted[index]; index++; } arr.length = shiftedLength; } idx = arr.length; while (idx < oldLength) { delete arr[idx]; idx++; } }; var BindingTarget = Class.extend({ init: function (target, options) { this.target = target; this.options = options; this.toDestroy = []; }, bind: function (bindings) { var key, hasValue, hasSource, hasEvents, hasChecked, hasCss, widgetBinding = this instanceof WidgetBindingTarget, specificBinders = this.binders(); for (key in bindings) { if (key == VALUE) { hasValue = true; } else if (key == SOURCE) { hasSource = true; } else if (key == EVENTS && !widgetBinding) { hasEvents = true; } else if (key == CHECKED) { hasChecked = true; } else if (key == CSS) { hasCss = true; } else { this.applyBinding(key, bindings, specificBinders); } } if (hasSource) { this.applyBinding(SOURCE, bindings, specificBinders); } if (hasValue) { this.applyBinding(VALUE, bindings, specificBinders); } if (hasChecked) { this.applyBinding(CHECKED, bindings, specificBinders); } if (hasEvents && !widgetBinding) { this.applyBinding(EVENTS, bindings, specificBinders); } if (hasCss && !widgetBinding) { this.applyBinding(CSS, bindings, specificBinders); } }, binders: function () { return binders[this.target.nodeName.toLowerCase()] || {}; }, applyBinding: function (name, bindings, specificBinders) { var binder = specificBinders[name] || binders[name], toDestroy = this.toDestroy, attribute, binding = bindings[name]; if (binder) { binder = new binder(this.target, bindings, this.options); toDestroy.push(binder); if (binding instanceof Binding) { binder.bind(binding); toDestroy.push(binding); } else { for (attribute in binding) { binder.bind(binding, attribute); toDestroy.push(binding[attribute]); } } } else if (name !== 'template') { throw new Error('The ' + name + ' binding is not supported by the ' + this.target.nodeName.toLowerCase() + ' element'); } }, destroy: function () { var idx, length, toDestroy = this.toDestroy; for (idx = 0, length = toDestroy.length; idx < length; idx++) { toDestroy[idx].destroy(); } } }); var WidgetBindingTarget = BindingTarget.extend({ binders: function () { return binders.widget[this.target.options.name.toLowerCase()] || {}; }, applyBinding: function (name, bindings, specificBinders) { var binder = specificBinders[name] || binders.widget[name], toDestroy = this.toDestroy, attribute, binding = bindings[name]; if (binder) { binder = new binder(this.target, bindings, this.target.options); toDestroy.push(binder); if (binding instanceof Binding) { binder.bind(binding); toDestroy.push(binding); } else { for (attribute in binding) { binder.bind(binding, attribute); toDestroy.push(binding[attribute]); } } } else { throw new Error('The ' + name + ' binding is not supported by the ' + this.target.options.name + ' widget'); } } }); function bindingTargetForRole(element, roles) { var widget = kendo.initWidget(element, {}, roles); if (widget) { return new WidgetBindingTarget(widget); } } var keyValueRegExp = /[A-Za-z0-9_\-]+:(\{([^}]*)\}|[^,}]+)/g, whiteSpaceRegExp = /\s/g; function parseBindings(bind) { var result = {}, idx, length, token, colonIndex, key, value, tokens; tokens = bind.match(keyValueRegExp); for (idx = 0, length = tokens.length; idx < length; idx++) { token = tokens[idx]; colonIndex = token.indexOf(':'); key = token.substring(0, colonIndex); value = token.substring(colonIndex + 1); if (value.charAt(0) == '{') { value = parseBindings(value); } result[key] = value; } return result; } function createBindings(bindings, source, type) { var binding, result = {}; for (binding in bindings) { result[binding] = new type(source, bindings[binding]); } return result; } function bindElement(element, source, roles, parents) { var role = element.getAttribute('data-' + kendo.ns + 'role'), idx, bind = element.getAttribute('data-' + kendo.ns + 'bind'), children = element.children, childrenCopy = [], deep = true, bindings, options = {}, target; parents = parents || [source]; if (role || bind) { unbindElement(element, false); } if (role) { target = bindingTargetForRole(element, roles); } if (bind) { bind = parseBindings(bind.replace(whiteSpaceRegExp, '')); if (!target) { options = kendo.parseOptions(element, { textField: '', valueField: '', template: '', valueUpdate: CHANGE, valuePrimitive: false, autoBind: true }); options.roles = roles; target = new BindingTarget(element, options); } target.source = source; bindings = createBindings(bind, parents, Binding); if (options.template) { bindings.template = new TemplateBinding(parents, '', options.template); } if (bindings.click) { bind.events = bind.events || {}; bind.events.click = bind.click; bindings.click.destroy(); delete bindings.click; } if (bindings.source) { deep = false; } if (bind.attr) { bindings.attr = createBindings(bind.attr, parents, Binding); } if (bind.style) { bindings.style = createBindings(bind.style, parents, Binding); } if (bind.events) { bindings.events = createBindings(bind.events, parents, EventBinding); } if (bind.css) { bindings.css = createBindings(bind.css, parents, Binding); } target.bind(bindings); } if (target) { element.kendoBindingTarget = target; } if (deep && children) { for (idx = 0; idx < children.length; idx++) { childrenCopy[idx] = children[idx]; } for (idx = 0; idx < childrenCopy.length; idx++) { bindElement(childrenCopy[idx], source, roles, parents); } } } function bind(dom, object) { var idx, length, node, roles = kendo.rolesFromNamespaces([].slice.call(arguments, 2)); object = kendo.observable(object); dom = $(dom); for (idx = 0, length = dom.length; idx < length; idx++) { node = dom[idx]; if (node.nodeType === 1) { bindElement(node, object, roles); } } } function unbindElement(element, destroyWidget) { var bindingTarget = element.kendoBindingTarget; if (bindingTarget) { bindingTarget.destroy(); if (deleteExpando) { delete element.kendoBindingTarget; } else if (element.removeAttribute) { element.removeAttribute('kendoBindingTarget'); } else { element.kendoBindingTarget = null; } } if (destroyWidget) { var widget = kendo.widgetInstance($(element)); if (widget && typeof widget.destroy === FUNCTION) { widget.destroy(); } } } function unbindElementTree(element, destroyWidgets) { unbindElement(element, destroyWidgets); unbindElementChildren(element, destroyWidgets); } function unbindElementChildren(element, destroyWidgets) { var children = element.children; if (children) { for (var idx = 0, length = children.length; idx < length; idx++) { unbindElementTree(children[idx], destroyWidgets); } } } function unbind(dom) { var idx, length; dom = $(dom); for (idx = 0, length = dom.length; idx < length; idx++) { unbindElementTree(dom[idx], false); } } function notify(widget, namespace) { var element = widget.element, bindingTarget = element[0].kendoBindingTarget; if (bindingTarget) { bind(element, bindingTarget.source, namespace); } } function retrievePrimitiveValues(value, valueField) { var values = []; var idx = 0; var length; var item; if (!valueField) { return value; } if (value instanceof ObservableArray) { for (length = value.length; idx < length; idx++) { item = value[idx]; values[idx] = item.get ? item.get(valueField) : item[valueField]; } value = values; } else if (value instanceof ObservableObject) { value = value.get(valueField); } return value; } kendo.unbind = unbind; kendo.bind = bind; kendo.data.binders = binders; kendo.data.Binder = Binder; kendo.notify = notify; kendo.observable = function (object) { if (!(object instanceof ObservableObject)) { object = new ObservableObject(object); } return object; }; kendo.observableHierarchy = function (array) { var dataSource = kendo.data.HierarchicalDataSource.create(array); function recursiveRead(data) { var i, children; for (i = 0; i < data.length; i++) { data[i]._initChildren(); children = data[i].children; children.fetch(); data[i].items = children.data(); recursiveRead(data[i].items); } } dataSource.fetch(); recursiveRead(dataSource.data()); dataSource._data._dataSource = dataSource; return dataSource._data; }; }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.fx', ['kendo.core'], f); }(function () { var __meta__ = { id: 'fx', name: 'Effects', category: 'framework', description: 'Required for animation effects in all Kendo UI widgets.', depends: ['core'] }; (function ($, undefined) { var kendo = window.kendo, fx = kendo.effects, each = $.each, extend = $.extend, proxy = $.proxy, support = kendo.support, browser = support.browser, transforms = support.transforms, transitions = support.transitions, scaleProperties = { scale: 0, scalex: 0, scaley: 0, scale3d: 0 }, translateProperties = { translate: 0, translatex: 0, translatey: 0, translate3d: 0 }, hasZoom = typeof document.documentElement.style.zoom !== 'undefined' && !transforms, matrix3dRegExp = /matrix3?d?\s*\(.*,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?/i, cssParamsRegExp = /^(-?[\d\.\-]+)?[\w\s]*,?\s*(-?[\d\.\-]+)?[\w\s]*/i, translateXRegExp = /translatex?$/i, oldEffectsRegExp = /(zoom|fade|expand)(\w+)/, singleEffectRegExp = /(zoom|fade|expand)/, unitRegExp = /[xy]$/i, transformProps = [ 'perspective', 'rotate', 'rotatex', 'rotatey', 'rotatez', 'rotate3d', 'scale', 'scalex', 'scaley', 'scalez', 'scale3d', 'skew', 'skewx', 'skewy', 'translate', 'translatex', 'translatey', 'translatez', 'translate3d', 'matrix', 'matrix3d' ], transform2d = [ 'rotate', 'scale', 'scalex', 'scaley', 'skew', 'skewx', 'skewy', 'translate', 'translatex', 'translatey', 'matrix' ], transform2units = { 'rotate': 'deg', scale: '', skew: 'px', translate: 'px' }, cssPrefix = transforms.css, round = Math.round, BLANK = '', PX = 'px', NONE = 'none', AUTO = 'auto', WIDTH = 'width', HEIGHT = 'height', HIDDEN = 'hidden', ORIGIN = 'origin', ABORT_ID = 'abortId', OVERFLOW = 'overflow', TRANSLATE = 'translate', POSITION = 'position', COMPLETE_CALLBACK = 'completeCallback', TRANSITION = cssPrefix + 'transition', TRANSFORM = cssPrefix + 'transform', BACKFACE = cssPrefix + 'backface-visibility', PERSPECTIVE = cssPrefix + 'perspective', DEFAULT_PERSPECTIVE = '1500px', TRANSFORM_PERSPECTIVE = 'perspective(' + DEFAULT_PERSPECTIVE + ')', directions = { left: { reverse: 'right', property: 'left', transition: 'translatex', vertical: false, modifier: -1 }, right: { reverse: 'left', property: 'left', transition: 'translatex', vertical: false, modifier: 1 }, down: { reverse: 'up', property: 'top', transition: 'translatey', vertical: true, modifier: 1 }, up: { reverse: 'down', property: 'top', transition: 'translatey', vertical: true, modifier: -1 }, top: { reverse: 'bottom' }, bottom: { reverse: 'top' }, 'in': { reverse: 'out', modifier: -1 }, out: { reverse: 'in', modifier: 1 }, vertical: { reverse: 'vertical' }, horizontal: { reverse: 'horizontal' } }; kendo.directions = directions; extend($.fn, { kendoStop: function (clearQueue, gotoEnd) { if (transitions) { return fx.stopQueue(this, clearQueue || false, gotoEnd || false); } else { return this.stop(clearQueue, gotoEnd); } } }); if (transforms && !transitions) { each(transform2d, function (idx, value) { $.fn[value] = function (val) { if (typeof val == 'undefined') { return animationProperty(this, value); } else { var that = $(this)[0], transformValue = value + '(' + val + transform2units[value.replace(unitRegExp, '')] + ')'; if (that.style.cssText.indexOf(TRANSFORM) == -1) { $(this).css(TRANSFORM, transformValue); } else { that.style.cssText = that.style.cssText.replace(new RegExp(value + '\\(.*?\\)', 'i'), transformValue); } } return this; }; $.fx.step[value] = function (fx) { $(fx.elem)[value](fx.now); }; }); var curProxy = $.fx.prototype.cur; $.fx.prototype.cur = function () { if (transform2d.indexOf(this.prop) != -1) { return parseFloat($(this.elem)[this.prop]()); } return curProxy.apply(this, arguments); }; } kendo.toggleClass = function (element, classes, options, add) { if (classes) { classes = classes.split(' '); if (transitions) { options = extend({ exclusive: 'all', duration: 400, ease: 'ease-out' }, options); element.css(TRANSITION, options.exclusive + ' ' + options.duration + 'ms ' + options.ease); setTimeout(function () { element.css(TRANSITION, '').css(HEIGHT); }, options.duration); } each(classes, function (idx, value) { element.toggleClass(value, add); }); } return element; }; kendo.parseEffects = function (input, mirror) { var effects = {}; if (typeof input === 'string') { each(input.split(' '), function (idx, value) { var redirectedEffect = !singleEffectRegExp.test(value), resolved = value.replace(oldEffectsRegExp, function (match, $1, $2) { return $1 + ':' + $2.toLowerCase(); }), effect = resolved.split(':'), direction = effect[1], effectBody = {}; if (effect.length > 1) { effectBody.direction = mirror && redirectedEffect ? directions[direction].reverse : direction; } effects[effect[0]] = effectBody; }); } else { each(input, function (idx) { var direction = this.direction; if (direction && mirror && !singleEffectRegExp.test(idx)) { this.direction = directions[direction].reverse; } effects[idx] = this; }); } return effects; }; function parseInteger(value) { return parseInt(value, 10); } function parseCSS(element, property) { return parseInteger(element.css(property)); } function keys(obj) { var acc = []; for (var propertyName in obj) { acc.push(propertyName); } return acc; } function strip3DTransforms(properties) { for (var key in properties) { if (transformProps.indexOf(key) != -1 && transform2d.indexOf(key) == -1) { delete properties[key]; } } return properties; } function normalizeCSS(element, properties) { var transformation = [], cssValues = {}, lowerKey, key, value, isTransformed; for (key in properties) { lowerKey = key.toLowerCase(); isTransformed = transforms && transformProps.indexOf(lowerKey) != -1; if (!support.hasHW3D && isTransformed && transform2d.indexOf(lowerKey) == -1) { delete properties[key]; } else { value = properties[key]; if (isTransformed) { transformation.push(key + '(' + value + ')'); } else { cssValues[key] = value; } } } if (transformation.length) { cssValues[TRANSFORM] = transformation.join(' '); } return cssValues; } if (transitions) { extend(fx, { transition: function (element, properties, options) { var css, delay = 0, oldKeys = element.data('keys') || [], timeoutID; options = extend({ duration: 200, ease: 'ease-out', complete: null, exclusive: 'all' }, options); var stopTransitionCalled = false; var stopTransition = function () { if (!stopTransitionCalled) { stopTransitionCalled = true; if (timeoutID) { clearTimeout(timeoutID); timeoutID = null; } element.removeData(ABORT_ID).dequeue().css(TRANSITION, '').css(TRANSITION); options.complete.call(element); } }; options.duration = $.fx ? $.fx.speeds[options.duration] || options.duration : options.duration; css = normalizeCSS(element, properties); $.merge(oldKeys, keys(css)); element.data('keys', $.unique(oldKeys)).height(); element.css(TRANSITION, options.exclusive + ' ' + options.duration + 'ms ' + options.ease).css(TRANSITION); element.css(css).css(TRANSFORM); if (transitions.event) { element.one(transitions.event, stopTransition); if (options.duration !== 0) { delay = 500; } } timeoutID = setTimeout(stopTransition, options.duration + delay); element.data(ABORT_ID, timeoutID); element.data(COMPLETE_CALLBACK, stopTransition); }, stopQueue: function (element, clearQueue, gotoEnd) { var cssValues, taskKeys = element.data('keys'), retainPosition = !gotoEnd && taskKeys, completeCallback = element.data(COMPLETE_CALLBACK); if (retainPosition) { cssValues = kendo.getComputedStyles(element[0], taskKeys); } if (completeCallback) { completeCallback(); } if (retainPosition) { element.css(cssValues); } return element.removeData('keys').stop(clearQueue); } }); } function animationProperty(element, property) { if (transforms) { var transform = element.css(TRANSFORM); if (transform == NONE) { return property == 'scale' ? 1 : 0; } var match = transform.match(new RegExp(property + '\\s*\\(([\\d\\w\\.]+)')), computed = 0; if (match) { computed = parseInteger(match[1]); } else { match = transform.match(matrix3dRegExp) || [ 0, 0, 0, 0, 0 ]; property = property.toLowerCase(); if (translateXRegExp.test(property)) { computed = parseFloat(match[3] / match[2]); } else if (property == 'translatey') { computed = parseFloat(match[4] / match[2]); } else if (property == 'scale') { computed = parseFloat(match[2]); } else if (property == 'rotate') { computed = parseFloat(Math.atan2(match[2], match[1])); } } return computed; } else { return parseFloat(element.css(property)); } } var EffectSet = kendo.Class.extend({ init: function (element, options) { var that = this; that.element = element; that.effects = []; that.options = options; that.restore = []; }, run: function (effects) { var that = this, effect, idx, jdx, length = effects.length, element = that.element, options = that.options, deferred = $.Deferred(), start = {}, end = {}, target, children, childrenLength; that.effects = effects; deferred.then($.proxy(that, 'complete')); element.data('animating', true); for (idx = 0; idx < length; idx++) { effect = effects[idx]; effect.setReverse(options.reverse); effect.setOptions(options); that.addRestoreProperties(effect.restore); effect.prepare(start, end); children = effect.children(); for (jdx = 0, childrenLength = children.length; jdx < childrenLength; jdx++) { children[jdx].duration(options.duration).run(); } } for (var effectName in options.effects) { extend(end, options.effects[effectName].properties); } if (!element.is(':visible')) { extend(start, { display: element.data('olddisplay') || 'block' }); } if (transforms && !options.reset) { target = element.data('targetTransform'); if (target) { start = extend(target, start); } } start = normalizeCSS(element, start); if (transforms && !transitions) { start = strip3DTransforms(start); } element.css(start).css(TRANSFORM); for (idx = 0; idx < length; idx++) { effects[idx].setup(); } if (options.init) { options.init(); } element.data('targetTransform', end); fx.animate(element, end, extend({}, options, { complete: deferred.resolve })); return deferred.promise(); }, stop: function () { $(this.element).kendoStop(true, true); }, addRestoreProperties: function (restore) { var element = this.element, value, i = 0, length = restore.length; for (; i < length; i++) { value = restore[i]; this.restore.push(value); if (!element.data(value)) { element.data(value, element.css(value)); } } }, restoreCallback: function () { var element = this.element; for (var i = 0, length = this.restore.length; i < length; i++) { var value = this.restore[i]; element.css(value, element.data(value)); } }, complete: function () { var that = this, idx = 0, element = that.element, options = that.options, effects = that.effects, length = effects.length; element.removeData('animating').dequeue(); if (options.hide) { element.data('olddisplay', element.css('display')).hide(); } this.restoreCallback(); if (hasZoom && !transforms) { setTimeout($.proxy(this, 'restoreCallback'), 0); } for (; idx < length; idx++) { effects[idx].teardown(); } if (options.completeCallback) { options.completeCallback(element); } } }); fx.promise = function (element, options) { var effects = [], effectClass, effectSet = new EffectSet(element, options), parsedEffects = kendo.parseEffects(options.effects), effect; options.effects = parsedEffects; for (var effectName in parsedEffects) { effectClass = fx[capitalize(effectName)]; if (effectClass) { effect = new effectClass(element, parsedEffects[effectName].direction); effects.push(effect); } } if (effects[0]) { effectSet.run(effects); } else { if (!element.is(':visible')) { element.css({ display: element.data('olddisplay') || 'block' }).css('display'); } if (options.init) { options.init(); } element.dequeue(); effectSet.complete(); } }; extend(fx, { animate: function (elements, properties, options) { var useTransition = options.transition !== false; delete options.transition; if (transitions && 'transition' in fx && useTransition) { fx.transition(elements, properties, options); } else { if (transforms) { elements.animate(strip3DTransforms(properties), { queue: false, show: false, hide: false, duration: options.duration, complete: options.complete }); } else { elements.each(function () { var element = $(this), multiple = {}; each(transformProps, function (idx, value) { var params, currentValue = properties ? properties[value] + ' ' : null; if (currentValue) { var single = properties; if (value in scaleProperties && properties[value] !== undefined) { params = currentValue.match(cssParamsRegExp); if (transforms) { extend(single, { scale: +params[0] }); } } else { if (value in translateProperties && properties[value] !== undefined) { var position = element.css(POSITION), isFixed = position == 'absolute' || position == 'fixed'; if (!element.data(TRANSLATE)) { if (isFixed) { element.data(TRANSLATE, { top: parseCSS(element, 'top') || 0, left: parseCSS(element, 'left') || 0, bottom: parseCSS(element, 'bottom'), right: parseCSS(element, 'right') }); } else { element.data(TRANSLATE, { top: parseCSS(element, 'marginTop') || 0, left: parseCSS(element, 'marginLeft') || 0 }); } } var originalPosition = element.data(TRANSLATE); params = currentValue.match(cssParamsRegExp); if (params) { var dX = value == TRANSLATE + 'y' ? +null : +params[1], dY = value == TRANSLATE + 'y' ? +params[1] : +params[2]; if (isFixed) { if (!isNaN(originalPosition.right)) { if (!isNaN(dX)) { extend(single, { right: originalPosition.right - dX }); } } else { if (!isNaN(dX)) { extend(single, { left: originalPosition.left + dX }); } } if (!isNaN(originalPosition.bottom)) { if (!isNaN(dY)) { extend(single, { bottom: originalPosition.bottom - dY }); } } else { if (!isNaN(dY)) { extend(single, { top: originalPosition.top + dY }); } } } else { if (!isNaN(dX)) { extend(single, { marginLeft: originalPosition.left + dX }); } if (!isNaN(dY)) { extend(single, { marginTop: originalPosition.top + dY }); } } } } } if (!transforms && value != 'scale' && value in single) { delete single[value]; } if (single) { extend(multiple, single); } } }); if (browser.msie) { delete multiple.scale; } element.animate(multiple, { queue: false, show: false, hide: false, duration: options.duration, complete: options.complete }); }); } } } }); fx.animatedPromise = fx.promise; var Effect = kendo.Class.extend({ init: function (element, direction) { var that = this; that.element = element; that._direction = direction; that.options = {}; that._additionalEffects = []; if (!that.restore) { that.restore = []; } }, reverse: function () { this._reverse = true; return this.run(); }, play: function () { this._reverse = false; return this.run(); }, add: function (additional) { this._additionalEffects.push(additional); return this; }, direction: function (value) { this._direction = value; return this; }, duration: function (duration) { this._duration = duration; return this; }, compositeRun: function () { var that = this, effectSet = new EffectSet(that.element, { reverse: that._reverse, duration: that._duration }), effects = that._additionalEffects.concat([that]); return effectSet.run(effects); }, run: function () { if (this._additionalEffects && this._additionalEffects[0]) { return this.compositeRun(); } var that = this, element = that.element, idx = 0, restore = that.restore, length = restore.length, value, deferred = $.Deferred(), start = {}, end = {}, target, children = that.children(), childrenLength = children.length; deferred.then($.proxy(that, '_complete')); element.data('animating', true); for (idx = 0; idx < length; idx++) { value = restore[idx]; if (!element.data(value)) { element.data(value, element.css(value)); } } for (idx = 0; idx < childrenLength; idx++) { children[idx].duration(that._duration).run(); } that.prepare(start, end); if (!element.is(':visible')) { extend(start, { display: element.data('olddisplay') || 'block' }); } if (transforms) { target = element.data('targetTransform'); if (target) { start = extend(target, start); } } start = normalizeCSS(element, start); if (transforms && !transitions) { start = strip3DTransforms(start); } element.css(start).css(TRANSFORM); that.setup(); element.data('targetTransform', end); fx.animate(element, end, { duration: that._duration, complete: deferred.resolve }); return deferred.promise(); }, stop: function () { var idx = 0, children = this.children(), childrenLength = children.length; for (idx = 0; idx < childrenLength; idx++) { children[idx].stop(); } $(this.element).kendoStop(true, true); return this; }, restoreCallback: function () { var element = this.element; for (var i = 0, length = this.restore.length; i < length; i++) { var value = this.restore[i]; element.css(value, element.data(value)); } }, _complete: function () { var that = this, element = that.element; element.removeData('animating').dequeue(); that.restoreCallback(); if (that.shouldHide()) { element.data('olddisplay', element.css('display')).hide(); } if (hasZoom && !transforms) { setTimeout($.proxy(that, 'restoreCallback'), 0); } that.teardown(); }, setOptions: function (options) { extend(true, this.options, options); }, children: function () { return []; }, shouldHide: $.noop, setup: $.noop, prepare: $.noop, teardown: $.noop, directions: [], setReverse: function (reverse) { this._reverse = reverse; return this; } }); function capitalize(word) { return word.charAt(0).toUpperCase() + word.substring(1); } function createEffect(name, definition) { var effectClass = Effect.extend(definition), directions = effectClass.prototype.directions; fx[capitalize(name)] = effectClass; fx.Element.prototype[name] = function (direction, opt1, opt2, opt3) { return new effectClass(this.element, direction, opt1, opt2, opt3); }; each(directions, function (idx, theDirection) { fx.Element.prototype[name + capitalize(theDirection)] = function (opt1, opt2, opt3) { return new effectClass(this.element, theDirection, opt1, opt2, opt3); }; }); } var FOUR_DIRECTIONS = [ 'left', 'right', 'up', 'down' ], IN_OUT = [ 'in', 'out' ]; createEffect('slideIn', { directions: FOUR_DIRECTIONS, divisor: function (value) { this.options.divisor = value; return this; }, prepare: function (start, end) { var that = this, tmp, element = that.element, direction = directions[that._direction], offset = -direction.modifier * (direction.vertical ? element.outerHeight() : element.outerWidth()), startValue = offset / (that.options && that.options.divisor || 1) + PX, endValue = '0px'; if (that._reverse) { tmp = start; start = end; end = tmp; } if (transforms) { start[direction.transition] = startValue; end[direction.transition] = endValue; } else { start[direction.property] = startValue; end[direction.property] = endValue; } } }); createEffect('tile', { directions: FOUR_DIRECTIONS, init: function (element, direction, previous) { Effect.prototype.init.call(this, element, direction); this.options = { previous: previous }; }, previousDivisor: function (value) { this.options.previousDivisor = value; return this; }, children: function () { var that = this, reverse = that._reverse, previous = that.options.previous, divisor = that.options.previousDivisor || 1, dir = that._direction; var children = [kendo.fx(that.element).slideIn(dir).setReverse(reverse)]; if (previous) { children.push(kendo.fx(previous).slideIn(directions[dir].reverse).divisor(divisor).setReverse(!reverse)); } return children; } }); function createToggleEffect(name, property, defaultStart, defaultEnd) { createEffect(name, { directions: IN_OUT, startValue: function (value) { this._startValue = value; return this; }, endValue: function (value) { this._endValue = value; return this; }, shouldHide: function () { return this._shouldHide; }, prepare: function (start, end) { var that = this, startValue, endValue, out = this._direction === 'out', startDataValue = that.element.data(property), startDataValueIsSet = !(isNaN(startDataValue) || startDataValue == defaultStart); if (startDataValueIsSet) { startValue = startDataValue; } else if (typeof this._startValue !== 'undefined') { startValue = this._startValue; } else { startValue = out ? defaultStart : defaultEnd; } if (typeof this._endValue !== 'undefined') { endValue = this._endValue; } else { endValue = out ? defaultEnd : defaultStart; } if (this._reverse) { start[property] = endValue; end[property] = startValue; } else { start[property] = startValue; end[property] = endValue; } that._shouldHide = end[property] === defaultEnd; } }); } createToggleEffect('fade', 'opacity', 1, 0); createToggleEffect('zoom', 'scale', 1, 0.01); createEffect('slideMargin', { prepare: function (start, end) { var that = this, element = that.element, options = that.options, origin = element.data(ORIGIN), offset = options.offset, margin, reverse = that._reverse; if (!reverse && origin === null) { element.data(ORIGIN, parseFloat(element.css('margin-' + options.axis))); } margin = element.data(ORIGIN) || 0; end['margin-' + options.axis] = !reverse ? margin + offset : margin; } }); createEffect('slideTo', { prepare: function (start, end) { var that = this, element = that.element, options = that.options, offset = options.offset.split(','), reverse = that._reverse; if (transforms) { end.translatex = !reverse ? offset[0] : 0; end.translatey = !reverse ? offset[1] : 0; } else { end.left = !reverse ? offset[0] : 0; end.top = !reverse ? offset[1] : 0; } element.css('left'); } }); createEffect('expand', { directions: [ 'horizontal', 'vertical' ], restore: [OVERFLOW], prepare: function (start, end) { var that = this, element = that.element, options = that.options, reverse = that._reverse, property = that._direction === 'vertical' ? HEIGHT : WIDTH, setLength = element[0].style[property], oldLength = element.data(property), length = parseFloat(oldLength || setLength), realLength = round(element.css(property, AUTO)[property]()); start.overflow = HIDDEN; length = options && options.reset ? realLength || length : length || realLength; end[property] = (reverse ? 0 : length) + PX; start[property] = (reverse ? length : 0) + PX; if (oldLength === undefined) { element.data(property, setLength); } }, shouldHide: function () { return this._reverse; }, teardown: function () { var that = this, element = that.element, property = that._direction === 'vertical' ? HEIGHT : WIDTH, length = element.data(property); if (length == AUTO || length === BLANK) { setTimeout(function () { element.css(property, AUTO).css(property); }, 0); } } }); var TRANSFER_START_STATE = { position: 'absolute', marginLeft: 0, marginTop: 0, scale: 1 }; createEffect('transfer', { init: function (element, target) { this.element = element; this.options = { target: target }; this.restore = []; }, setup: function () { this.element.appendTo(document.body); }, prepare: function (start, end) { var that = this, element = that.element, outerBox = fx.box(element), innerBox = fx.box(that.options.target), currentScale = animationProperty(element, 'scale'), scale = fx.fillScale(innerBox, outerBox), transformOrigin = fx.transformOrigin(innerBox, outerBox); extend(start, TRANSFER_START_STATE); end.scale = 1; element.css(TRANSFORM, 'scale(1)').css(TRANSFORM); element.css(TRANSFORM, 'scale(' + currentScale + ')'); start.top = outerBox.top; start.left = outerBox.left; start.transformOrigin = transformOrigin.x + PX + ' ' + transformOrigin.y + PX; if (that._reverse) { start.scale = scale; } else { end.scale = scale; } } }); var CLIPS = { top: 'rect(auto auto $size auto)', bottom: 'rect($size auto auto auto)', left: 'rect(auto $size auto auto)', right: 'rect(auto auto auto $size)' }; var ROTATIONS = { top: { start: 'rotatex(0deg)', end: 'rotatex(180deg)' }, bottom: { start: 'rotatex(-180deg)', end: 'rotatex(0deg)' }, left: { start: 'rotatey(0deg)', end: 'rotatey(-180deg)' }, right: { start: 'rotatey(180deg)', end: 'rotatey(0deg)' } }; function clipInHalf(container, direction) { var vertical = kendo.directions[direction].vertical, size = container[vertical ? HEIGHT : WIDTH]() / 2 + 'px'; return CLIPS[direction].replace('$size', size); } createEffect('turningPage', { directions: FOUR_DIRECTIONS, init: function (element, direction, container) { Effect.prototype.init.call(this, element, direction); this._container = container; }, prepare: function (start, end) { var that = this, reverse = that._reverse, direction = reverse ? directions[that._direction].reverse : that._direction, rotation = ROTATIONS[direction]; start.zIndex = 1; if (that._clipInHalf) { start.clip = clipInHalf(that._container, kendo.directions[direction].reverse); } start[BACKFACE] = HIDDEN; end[TRANSFORM] = TRANSFORM_PERSPECTIVE + (reverse ? rotation.start : rotation.end); start[TRANSFORM] = TRANSFORM_PERSPECTIVE + (reverse ? rotation.end : rotation.start); }, setup: function () { this._container.append(this.element); }, face: function (value) { this._face = value; return this; }, shouldHide: function () { var that = this, reverse = that._reverse, face = that._face; return reverse && !face || !reverse && face; }, clipInHalf: function (value) { this._clipInHalf = value; return this; }, temporary: function () { this.element.addClass('temp-page'); return this; } }); createEffect('staticPage', { directions: FOUR_DIRECTIONS, init: function (element, direction, container) { Effect.prototype.init.call(this, element, direction); this._container = container; }, restore: ['clip'], prepare: function (start, end) { var that = this, direction = that._reverse ? directions[that._direction].reverse : that._direction; start.clip = clipInHalf(that._container, direction); start.opacity = 0.999; end.opacity = 1; }, shouldHide: function () { var that = this, reverse = that._reverse, face = that._face; return reverse && !face || !reverse && face; }, face: function (value) { this._face = value; return this; } }); createEffect('pageturn', { directions: [ 'horizontal', 'vertical' ], init: function (element, direction, face, back) { Effect.prototype.init.call(this, element, direction); this.options = {}; this.options.face = face; this.options.back = back; }, children: function () { var that = this, options = that.options, direction = that._direction === 'horizontal' ? 'left' : 'top', reverseDirection = kendo.directions[direction].reverse, reverse = that._reverse, temp, faceClone = options.face.clone(true).removeAttr('id'), backClone = options.back.clone(true).removeAttr('id'), element = that.element; if (reverse) { temp = direction; direction = reverseDirection; reverseDirection = temp; } return [ kendo.fx(options.face).staticPage(direction, element).face(true).setReverse(reverse), kendo.fx(options.back).staticPage(reverseDirection, element).setReverse(reverse), kendo.fx(faceClone).turningPage(direction, element).face(true).clipInHalf(true).temporary().setReverse(reverse), kendo.fx(backClone).turningPage(reverseDirection, element).clipInHalf(true).temporary().setReverse(reverse) ]; }, prepare: function (start, end) { start[PERSPECTIVE] = DEFAULT_PERSPECTIVE; start.transformStyle = 'preserve-3d'; start.opacity = 0.999; end.opacity = 1; }, teardown: function () { this.element.find('.temp-page').remove(); } }); createEffect('flip', { directions: [ 'horizontal', 'vertical' ], init: function (element, direction, face, back) { Effect.prototype.init.call(this, element, direction); this.options = {}; this.options.face = face; this.options.back = back; }, children: function () { var that = this, options = that.options, direction = that._direction === 'horizontal' ? 'left' : 'top', reverseDirection = kendo.directions[direction].reverse, reverse = that._reverse, temp, element = that.element; if (reverse) { temp = direction; direction = reverseDirection; reverseDirection = temp; } return [ kendo.fx(options.face).turningPage(direction, element).face(true).setReverse(reverse), kendo.fx(options.back).turningPage(reverseDirection, element).setReverse(reverse) ]; }, prepare: function (start) { start[PERSPECTIVE] = DEFAULT_PERSPECTIVE; start.transformStyle = 'preserve-3d'; } }); var RESTORE_OVERFLOW = !support.mobileOS.android; var IGNORE_TRANSITION_EVENT_SELECTOR = '.km-touch-scrollbar, .km-actionsheet-wrapper'; createEffect('replace', { _before: $.noop, _after: $.noop, init: function (element, previous, transitionClass) { Effect.prototype.init.call(this, element); this._previous = $(previous); this._transitionClass = transitionClass; }, duration: function () { throw new Error('The replace effect does not support duration setting; the effect duration may be customized through the transition class rule'); }, beforeTransition: function (callback) { this._before = callback; return this; }, afterTransition: function (callback) { this._after = callback; return this; }, _both: function () { return $().add(this._element).add(this._previous); }, _containerClass: function () { var direction = this._direction, containerClass = 'k-fx k-fx-start k-fx-' + this._transitionClass; if (direction) { containerClass += ' k-fx-' + direction; } if (this._reverse) { containerClass += ' k-fx-reverse'; } return containerClass; }, complete: function (e) { if (!this.deferred || e && $(e.target).is(IGNORE_TRANSITION_EVENT_SELECTOR)) { return; } var container = this.container; container.removeClass('k-fx-end').removeClass(this._containerClass()).off(transitions.event, this.completeProxy); this._previous.hide().removeClass('k-fx-current'); this.element.removeClass('k-fx-next'); if (RESTORE_OVERFLOW) { container.css(OVERFLOW, ''); } if (!this.isAbsolute) { this._both().css(POSITION, ''); } this.deferred.resolve(); delete this.deferred; }, run: function () { if (this._additionalEffects && this._additionalEffects[0]) { return this.compositeRun(); } var that = this, element = that.element, previous = that._previous, container = element.parents().filter(previous.parents()).first(), both = that._both(), deferred = $.Deferred(), originalPosition = element.css(POSITION), originalOverflow; if (!container.length) { container = element.parent(); } this.container = container; this.deferred = deferred; this.isAbsolute = originalPosition == 'absolute'; if (!this.isAbsolute) { both.css(POSITION, 'absolute'); } if (RESTORE_OVERFLOW) { originalOverflow = container.css(OVERFLOW); container.css(OVERFLOW, 'hidden'); } if (!transitions) { this.complete(); } else { element.addClass('k-fx-hidden'); container.addClass(this._containerClass()); this.completeProxy = $.proxy(this, 'complete'); container.on(transitions.event, this.completeProxy); kendo.animationFrame(function () { element.removeClass('k-fx-hidden').addClass('k-fx-next'); previous.css('display', '').addClass('k-fx-current'); that._before(previous, element); kendo.animationFrame(function () { container.removeClass('k-fx-start').addClass('k-fx-end'); that._after(previous, element); }); }); } return deferred.promise(); }, stop: function () { this.complete(); } }); var Animation = kendo.Class.extend({ init: function () { var that = this; that._tickProxy = proxy(that._tick, that); that._started = false; }, tick: $.noop, done: $.noop, onEnd: $.noop, onCancel: $.noop, start: function () { if (!this.enabled()) { return; } if (!this.done()) { this._started = true; kendo.animationFrame(this._tickProxy); } else { this.onEnd(); } }, enabled: function () { return true; }, cancel: function () { this._started = false; this.onCancel(); }, _tick: function () { var that = this; if (!that._started) { return; } that.tick(); if (!that.done()) { kendo.animationFrame(that._tickProxy); } else { that._started = false; that.onEnd(); } } }); var Transition = Animation.extend({ init: function (options) { var that = this; extend(that, options); Animation.fn.init.call(that); }, done: function () { return this.timePassed() >= this.duration; }, timePassed: function () { return Math.min(this.duration, new Date() - this.startDate); }, moveTo: function (options) { var that = this, movable = that.movable; that.initial = movable[that.axis]; that.delta = options.location - that.initial; that.duration = typeof options.duration == 'number' ? options.duration : 300; that.tick = that._easeProxy(options.ease); that.startDate = new Date(); that.start(); }, _easeProxy: function (ease) { var that = this; return function () { that.movable.moveAxis(that.axis, ease(that.timePassed(), that.initial, that.delta, that.duration)); }; } }); extend(Transition, { easeOutExpo: function (t, b, c, d) { return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; }, easeOutBack: function (t, b, c, d, s) { s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; } }); fx.Animation = Animation; fx.Transition = Transition; fx.createEffect = createEffect; fx.box = function (element) { element = $(element); var result = element.offset(); result.width = element.outerWidth(); result.height = element.outerHeight(); return result; }; fx.transformOrigin = function (inner, outer) { var x = (inner.left - outer.left) * outer.width / (outer.width - inner.width), y = (inner.top - outer.top) * outer.height / (outer.height - inner.height); return { x: isNaN(x) ? 0 : x, y: isNaN(y) ? 0 : y }; }; fx.fillScale = function (inner, outer) { return Math.min(inner.width / outer.width, inner.height / outer.height); }; fx.fitScale = function (inner, outer) { return Math.max(inner.width / outer.width, inner.height / outer.height); }; }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.view', [ 'kendo.core', 'kendo.binder', 'kendo.fx' ], f); }(function () { var __meta__ = { id: 'view', name: 'View', category: 'framework', description: 'The View class instantiates and handles the events of a certain screen from the application.', depends: [ 'core', 'binder', 'fx' ], hidden: false }; (function ($, undefined) { var kendo = window.kendo, Observable = kendo.Observable, SCRIPT = 'SCRIPT', INIT = 'init', SHOW = 'show', HIDE = 'hide', TRANSITION_START = 'transitionStart', TRANSITION_END = 'transitionEnd', ATTACH = 'attach', DETACH = 'detach', sizzleErrorRegExp = /unrecognized expression/; var View = Observable.extend({ init: function (content, options) { var that = this; options = options || {}; Observable.fn.init.call(that); that.content = content; that.id = kendo.guid(); that.tagName = options.tagName || 'div'; that.model = options.model; that._wrap = options.wrap !== false; this._evalTemplate = options.evalTemplate || false; that._fragments = {}; that.bind([ INIT, SHOW, HIDE, TRANSITION_START, TRANSITION_END ], options); }, render: function (container) { var that = this, notInitialized = !that.element; if (notInitialized) { that.element = that._createElement(); } if (container) { $(container).append(that.element); } if (notInitialized) { kendo.bind(that.element, that.model); that.trigger(INIT); } if (container) { that._eachFragment(ATTACH); that.trigger(SHOW); } return that.element; }, clone: function () { return new ViewClone(this); }, triggerBeforeShow: function () { return true; }, triggerBeforeHide: function () { return true; }, showStart: function () { this.element.css('display', ''); }, showEnd: function () { }, hideEnd: function () { this.hide(); }, beforeTransition: function (type) { this.trigger(TRANSITION_START, { type: type }); }, afterTransition: function (type) { this.trigger(TRANSITION_END, { type: type }); }, hide: function () { this._eachFragment(DETACH); this.element.detach(); this.trigger(HIDE); }, destroy: function () { var element = this.element; if (element) { kendo.unbind(element); kendo.destroy(element); element.remove(); } }, fragments: function (fragments) { $.extend(this._fragments, fragments); }, _eachFragment: function (methodName) { for (var placeholder in this._fragments) { this._fragments[placeholder][methodName](this, placeholder); } }, _createElement: function () { var that = this, wrapper = '<' + that.tagName + ' />', element, content; try { content = $(document.getElementById(that.content) || that.content); if (content[0].tagName === SCRIPT) { content = content.html(); } } catch (e) { if (sizzleErrorRegExp.test(e.message)) { content = that.content; } } if (typeof content === 'string') { content = content.replace(/^\s+|\s+$/g, ''); if (that._evalTemplate) { content = kendo.template(content)(that.model || {}); } element = $(wrapper).append(content); if (!that._wrap) { element = element.contents(); } } else { element = content; if (that._evalTemplate) { var result = $(kendo.template($('
    ').append(element.clone(true)).html())(that.model || {})); if ($.contains(document, element[0])) { element.replaceWith(result); } element = result; } if (that._wrap) { element = element.wrapAll(wrapper).parent(); } } return element; } }); var ViewClone = kendo.Class.extend({ init: function (view) { $.extend(this, { element: view.element.clone(true), transition: view.transition, id: view.id }); view.element.parent().append(this.element); }, hideEnd: function () { this.element.remove(); }, beforeTransition: $.noop, afterTransition: $.noop }); var Layout = View.extend({ init: function (content, options) { View.fn.init.call(this, content, options); this.containers = {}; }, container: function (selector) { var container = this.containers[selector]; if (!container) { container = this._createContainer(selector); this.containers[selector] = container; } return container; }, showIn: function (selector, view, transition) { this.container(selector).show(view, transition); }, _createContainer: function (selector) { var root = this.render(), element = root.find(selector), container; if (!element.length && root.is(selector)) { if (root.is(selector)) { element = root; } else { throw new Error('can\'t find a container with the specified ' + selector + ' selector'); } } container = new ViewContainer(element); container.bind('accepted', function (e) { e.view.render(element); }); return container; } }); var Fragment = View.extend({ attach: function (view, placeholder) { view.element.find(placeholder).replaceWith(this.render()); }, detach: function () { } }); var transitionRegExp = /^(\w+)(:(\w+))?( (\w+))?$/; function parseTransition(transition) { if (!transition) { return {}; } var matches = transition.match(transitionRegExp) || []; return { type: matches[1], direction: matches[3], reverse: matches[5] === 'reverse' }; } var ViewContainer = Observable.extend({ init: function (container) { Observable.fn.init.call(this); this.container = container; this.history = []; this.view = null; this.running = false; }, after: function () { this.running = false; this.trigger('complete', { view: this.view }); this.trigger('after'); }, end: function () { this.view.showEnd(); this.previous.hideEnd(); this.after(); }, show: function (view, transition, locationID) { if (!view.triggerBeforeShow() || this.view && !this.view.triggerBeforeHide()) { this.trigger('after'); return false; } locationID = locationID || view.id; var that = this, current = view === that.view ? view.clone() : that.view, history = that.history, previousEntry = history[history.length - 2] || {}, back = previousEntry.id === locationID, theTransition = transition || (back ? history[history.length - 1].transition : view.transition), transitionData = parseTransition(theTransition); if (that.running) { that.effect.stop(); } if (theTransition === 'none') { theTransition = null; } that.trigger('accepted', { view: view }); that.view = view; that.previous = current; that.running = true; if (!back) { history.push({ id: locationID, transition: theTransition }); } else { history.pop(); } if (!current) { view.showStart(); view.showEnd(); that.after(); return true; } if (!theTransition || !kendo.effects.enabled) { view.showStart(); that.end(); } else { view.element.addClass('k-fx-hidden'); view.showStart(); if (back && !transition) { transitionData.reverse = !transitionData.reverse; } that.effect = kendo.fx(view.element).replace(current.element, transitionData.type).beforeTransition(function () { view.beforeTransition('show'); current.beforeTransition('hide'); }).afterTransition(function () { view.afterTransition('show'); current.afterTransition('hide'); }).direction(transitionData.direction).setReverse(transitionData.reverse); that.effect.run().then(function () { that.end(); }); } return true; } }); kendo.ViewContainer = ViewContainer; kendo.Fragment = Fragment; kendo.Layout = Layout; kendo.View = View; kendo.ViewClone = ViewClone; }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.dom', ['kendo.core'], f); }(function () { var __meta__ = { id: 'dom', name: 'Virtual DOM', category: 'framework', depends: ['core'], advanced: true }; (function (kendo) { function Node() { this.node = null; } Node.prototype = { remove: function () { this.node.parentNode.removeChild(this.node); this.attr = {}; }, attr: {}, text: function () { return ''; } }; function NullNode() { } NullNode.prototype = { nodeName: '#null', attr: { style: {} }, children: [], remove: function () { } }; var NULL_NODE = new NullNode(); function Element(nodeName, attr, children) { this.nodeName = nodeName; this.attr = attr || {}; this.children = children || []; } Element.prototype = new Node(); Element.prototype.appendTo = function (parent) { var node = document.createElement(this.nodeName); var children = this.children; for (var index = 0; index < children.length; index++) { children[index].render(node, NULL_NODE); } parent.appendChild(node); return node; }; Element.prototype.render = function (parent, cached) { var node; if (cached.nodeName !== this.nodeName) { cached.remove(); node = this.appendTo(parent); } else { node = cached.node; var index; var children = this.children; var length = children.length; var cachedChildren = cached.children; var cachedLength = cachedChildren.length; if (Math.abs(cachedLength - length) > 2) { this.render({ appendChild: function (node) { parent.replaceChild(node, cached.node); } }, NULL_NODE); return; } for (index = 0; index < length; index++) { children[index].render(node, cachedChildren[index] || NULL_NODE); } for (index = length; index < cachedLength; index++) { cachedChildren[index].remove(); } } this.node = node; this.syncAttributes(cached.attr); this.removeAttributes(cached.attr); }; Element.prototype.syncAttributes = function (cachedAttr) { var attr = this.attr; for (var name in attr) { var value = attr[name]; var cachedValue = cachedAttr[name]; if (name === 'style') { this.setStyle(value, cachedValue); } else if (value !== cachedValue) { this.setAttribute(name, value, cachedValue); } } }; Element.prototype.setStyle = function (style, cachedValue) { var node = this.node; var key; if (cachedValue) { for (key in style) { if (style[key] !== cachedValue[key]) { node.style[key] = style[key]; } } } else { for (key in style) { node.style[key] = style[key]; } } }; Element.prototype.removeStyle = function (cachedStyle) { var style = this.attr.style || {}; var node = this.node; for (var key in cachedStyle) { if (style[key] === undefined) { node.style[key] = ''; } } }; Element.prototype.removeAttributes = function (cachedAttr) { var attr = this.attr; for (var name in cachedAttr) { if (name === 'style') { this.removeStyle(cachedAttr.style); } else if (attr[name] === undefined) { this.removeAttribute(name); } } }; Element.prototype.removeAttribute = function (name) { var node = this.node; if (name === 'style') { node.style.cssText = ''; } else if (name === 'className') { node.className = ''; } else { node.removeAttribute(name); } }; Element.prototype.setAttribute = function (name, value) { var node = this.node; if (node[name] !== undefined) { node[name] = value; } else { node.setAttribute(name, value); } }; Element.prototype.text = function () { var str = ''; for (var i = 0; i < this.children.length; ++i) { str += this.children[i].text(); } return str; }; function TextNode(nodeValue) { this.nodeValue = nodeValue; } TextNode.prototype = new Node(); TextNode.prototype.nodeName = '#text'; TextNode.prototype.render = function (parent, cached) { var node; if (cached.nodeName !== this.nodeName) { cached.remove(); node = document.createTextNode(this.nodeValue); parent.appendChild(node); } else { node = cached.node; if (this.nodeValue !== cached.nodeValue) { node.nodeValue = this.nodeValue; } } this.node = node; }; TextNode.prototype.text = function () { return this.nodeValue; }; function HtmlNode(html) { this.html = html; } HtmlNode.prototype = { nodeName: '#html', attr: {}, remove: function () { for (var index = 0; index < this.nodes.length; index++) { this.nodes[index].parentNode.removeChild(this.nodes[index]); } }, render: function (parent, cached) { if (cached.nodeName !== this.nodeName || cached.html !== this.html) { cached.remove(); var lastChild = parent.lastChild; insertHtml(parent, this.html); this.nodes = []; for (var child = lastChild ? lastChild.nextSibling : parent.firstChild; child; child = child.nextSibling) { this.nodes.push(child); } } else { this.nodes = cached.nodes.slice(0); } } }; var HTML_CONTAINER = document.createElement('div'); function insertHtml(node, html) { HTML_CONTAINER.innerHTML = html; while (HTML_CONTAINER.firstChild) { node.appendChild(HTML_CONTAINER.firstChild); } } function html(value) { return new HtmlNode(value); } function element(nodeName, attrs, children) { return new Element(nodeName, attrs, children); } function text(value) { return new TextNode(value); } function Tree(root) { this.root = root; this.children = []; } Tree.prototype = { html: html, element: element, text: text, render: function (children) { var cachedChildren = this.children; var index; var length; for (index = 0, length = children.length; index < length; index++) { children[index].render(this.root, cachedChildren[index] || NULL_NODE); } for (index = length; index < cachedChildren.length; index++) { cachedChildren[index].remove(); } this.children = children; } }; kendo.dom = { html: html, text: text, element: element, Tree: Tree, Node: Node }; }(window.kendo)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.ooxml', ['kendo.core'], f); }(function () { var __meta__ = { id: 'ooxml', name: 'XLSX generation', category: 'framework', advanced: true, depends: ['core'] }; (function ($, kendo) { var RELS = '\r\n' + '' + '' + '' + '' + ''; var CORE = kendo.template('\r\n' + '' + '${creator}' + '${lastModifiedBy}' + '${created}' + '${modified}' + ''); var APP = kendo.template('\r\n' + '' + 'Microsoft Excel' + '0' + 'false' + '' + '' + '' + 'Worksheets' + '' + '' + '${sheets.length}' + '' + '' + '' + '' + '' + '# for (var idx = 0; idx < sheets.length; idx++) { #' + '# if (sheets[idx].options.title) { #' + '${sheets[idx].options.title}' + '# } else { #' + 'Sheet${idx+1}' + '# } #' + '# } #' + '' + '' + 'false' + 'false' + 'false' + '14.0300' + ''); var CONTENT_TYPES = kendo.template('\r\n' + '' + '' + '' + '' + '' + '' + '# for (var idx = 1; idx <= count; idx++) { #' + '' + '# } #' + '' + '' + ''); var WORKBOOK = kendo.template('\r\n' + '' + '' + '' + '' + '' + '' + '' + '# for (var idx = 0; idx < sheets.length; idx++) { #' + '# var options = sheets[idx].options; #' + '# var name = options.name || options.title #' + '# if (name) { #' + '' + '# } else { #' + '' + '# } #' + '# } #' + '' + '# if (definedNames.length) { #' + '' + ' # for (var di = 0; di < definedNames.length; di++) { #' + '' + ' # } #' + '' + '# } #' + '' + ''); var WORKSHEET = kendo.template('\r\n' + '' + '' + '' + '' + '# if (frozenRows || frozenColumns) { #' + '' + '# } #' + '' + '' + '' + '# if (columns && columns.length > 0) { #' + '' + '# for (var ci = 0; ci < columns.length; ci++) { #' + '# var column = columns[ci]; #' + '# var columnIndex = typeof column.index === "number" ? column.index + 1 : (ci + 1); #' + '# if (column.width) { #' + '' + '# } #' + '# } #' + '' + '# } #' + '' + '# for (var ri = 0; ri < data.length; ri++) { #' + '# var row = data[ri]; #' + '# var rowIndex = typeof row.index === "number" ? row.index + 1 : (ri + 1); #' + '' + '# for (var ci = 0; ci < row.data.length; ci++) { #' + '# var cell = row.data[ci];#' + '' + '# if (cell.formula != null) { #' + '${cell.formula}' + '# } #' + '# if (cell.value != null) { #' + '${cell.value}' + '# } #' + '' + '# } #' + '' + '# } #' + '' + '# if (filter) { #' + '' + '# } #' + '# if (mergeCells.length) { #' + '' + '# for (var ci = 0; ci < mergeCells.length; ci++) { #' + '' + '# } #' + '' + '# } #' + '' + ''); var WORKBOOK_RELS = kendo.template('\r\n' + '' + '# for (var idx = 1; idx <= count; idx++) { #' + '' + '# } #' + '' + '' + ''); var SHARED_STRINGS = kendo.template('\r\n' + '' + '# for (var index in indexes) { #' + '${index.substring(1)}' + '# } #' + ''); var STYLES = kendo.template('' + '' + '' + '# for (var fi = 0; fi < formats.length; fi++) { #' + '# var format = formats[fi]; #' + '' + '# } #' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '# for (var fi = 0; fi < fonts.length; fi++) { #' + '# var font = fonts[fi]; #' + '' + '# if (font.fontSize) { #' + '' + '# } else { #' + '' + '# } #' + '# if (font.bold) { #' + '' + '# } #' + '# if (font.italic) { #' + '' + '# } #' + '# if (font.underline) { #' + '' + '# } #' + '# if (font.color) { #' + '' + '# } else { #' + '' + '# } #' + '# if (font.fontFamily) { #' + '' + '' + '# } else { #' + '' + '' + '' + '# } #' + '' + '# } #' + '' + '' + '' + '' + '# for (var fi = 0; fi < fills.length; fi++) { #' + '# var fill = fills[fi]; #' + '# if (fill.background) { #' + '' + '' + '' + '' + '' + '# } #' + '# } #' + '' + '' + '' + '# for (var bi = 0; bi < borders.length; bi++) { #' + '#= kendo.ooxml.borderTemplate(borders[bi]) #' + '# } #' + '' + '' + '' + '' + '' + '' + '# for (var si = 0; si < styles.length; si++) { #' + '# var style = styles[si]; #' + '' + '# if (style.textAlign || style.verticalAlign || style.wrap) { #' + '' + '# } #' + '' + '# } #' + '' + '' + '' + '' + '' + '' + ''); function numChar(colIndex) { var letter = Math.floor(colIndex / 26) - 1; return (letter >= 0 ? numChar(letter) : '') + String.fromCharCode(65 + colIndex % 26); } function ref(rowIndex, colIndex) { return numChar(colIndex) + (rowIndex + 1); } function $ref(rowIndex, colIndex) { return numChar(colIndex) + '$' + (rowIndex + 1); } function filterRowIndex(options) { var frozenRows = options.frozenRows || (options.freezePane || {}).rowSplit || 1; return frozenRows - 1; } function toWidth(px) { return (px / 7 * 100 + 0.5) / 100; } function toHeight(px) { return px * 0.75; } var DATE_EPOCH = new Date(1900, 0, 0); var Worksheet = kendo.Class.extend({ init: function (options, sharedStrings, styles, borders) { this.options = options; this._strings = sharedStrings; this._styles = styles; this._borders = borders; }, toXML: function (index) { this._mergeCells = this.options.mergedCells || []; this._rowsByIndex = []; var rows = this.options.rows || []; for (var i = 0; i < rows.length; i++) { var ri = rows[i].index; if (typeof ri !== 'number') { ri = i; } rows[i].index = ri; this._rowsByIndex[ri] = rows[i]; } var data = []; for (i = 0; i < rows.length; i++) { data.push(this._row(rows[i], i)); } data.sort(function (a, b) { return a.index - b.index; }); var filter = this.options.filter; if (filter && typeof filter.from === 'number' && typeof filter.to === 'number') { filter = { from: ref(filterRowIndex(this.options), filter.from), to: ref(filterRowIndex(this.options), filter.to) }; } var freezePane = this.options.freezePane || {}; return WORKSHEET({ frozenColumns: this.options.frozenColumns || freezePane.colSplit, frozenRows: this.options.frozenRows || freezePane.rowSplit, columns: this.options.columns, defaults: this.options.defaults || {}, data: data, index: index, mergeCells: this._mergeCells, filter: filter }); }, _row: function (row) { var data = []; var offset = 0; var sheet = this; var cellRefs = {}; $.each(row.cells, function (i, cell) { if (!cell) { return; } var cellIndex; if (typeof cell.index === 'number') { cellIndex = cell.index; offset = cellIndex - i; } else { cellIndex = i + offset; } if (cell.colSpan) { offset += cell.colSpan - 1; } var items = sheet._cell(cell, row.index, cellIndex); $.each(items, function (i, cellData) { if (cellRefs[cellData.ref]) { return; } cellRefs[cellData.ref] = true; data.push(cellData); }); }); return { data: data, height: row.height, index: row.index }; }, _lookupString: function (value) { var key = '$' + value; var index = this._strings.indexes[key]; if (index !== undefined) { value = index; } else { value = this._strings.indexes[key] = this._strings.uniqueCount; this._strings.uniqueCount++; } this._strings.count++; return value; }, _lookupStyle: function (style) { var json = kendo.stringify(style); if (json == '{}') { return 0; } var index = $.inArray(json, this._styles); if (index < 0) { index = this._styles.push(json) - 1; } return index + 1; }, _lookupBorder: function (border) { var json = kendo.stringify(border); if (json == '{}') { return; } var index = $.inArray(json, this._borders); if (index < 0) { index = this._borders.push(json) - 1; } return index + 1; }, _cell: function (data, rowIndex, cellIndex) { if (!data) { return []; } var value = data.value; var border = {}; if (data.borderLeft) { border.left = data.borderLeft; } if (data.borderRight) { border.right = data.borderRight; } if (data.borderTop) { border.top = data.borderTop; } if (data.borderBottom) { border.bottom = data.borderBottom; } border = this._lookupBorder(border); var style = { bold: data.bold, color: data.color, background: data.background, italic: data.italic, underline: data.underline, fontFamily: data.fontFamily || data.fontName, fontSize: data.fontSize, format: data.format, textAlign: data.textAlign || data.hAlign, verticalAlign: data.verticalAlign || data.vAlign, wrap: data.wrap, borderId: border }; var columns = this.options.columns || []; var column = columns[cellIndex]; var type = typeof value; if (column && column.autoWidth) { var displayValue = value; if (type === 'number') { displayValue = kendo.toString(value, data.format); } column.width = Math.max(column.width || 0, (displayValue + '').length); } if (type === 'string') { value = this._lookupString(value); type = 's'; } else if (type === 'number') { type = 'n'; } else if (type === 'boolean') { type = 'b'; value = +value; } else if (value && value.getTime) { type = null; var offset = (value.getTimezoneOffset() - DATE_EPOCH.getTimezoneOffset()) * kendo.date.MS_PER_MINUTE; value = (value - DATE_EPOCH - offset) / kendo.date.MS_PER_DAY + 1; if (!style.format) { style.format = 'mm-dd-yy'; } } else { type = null; value = null; } style = this._lookupStyle(style); var cells = []; var cellRef = ref(rowIndex, cellIndex); cells.push({ value: value, formula: data.formula, type: type, style: style, ref: cellRef }); var colSpan = data.colSpan || 1; var rowSpan = data.rowSpan || 1; var ci; if (colSpan > 1 || rowSpan > 1) { this._mergeCells.push(cellRef + ':' + ref(rowIndex + rowSpan - 1, cellIndex + colSpan - 1)); for (var ri = rowIndex + 1; ri < rowIndex + rowSpan; ri++) { if (!this._rowsByIndex[ri]) { this._rowsByIndex[ri] = { index: ri, cells: [] }; } for (ci = cellIndex; ci < cellIndex + colSpan; ci++) { this._rowsByIndex[ri].cells.splice(ci, 0, {}); } } for (ci = cellIndex + 1; ci < cellIndex + colSpan; ci++) { cells.push({ ref: ref(rowIndex, ci) }); } } return cells; } }); var defaultFormats = { 'General': 0, '0': 1, '0.00': 2, '#,##0': 3, '#,##0.00': 4, '0%': 9, '0.00%': 10, '0.00E+00': 11, '# ?/?': 12, '# ??/??': 13, 'mm-dd-yy': 14, 'd-mmm-yy': 15, 'd-mmm': 16, 'mmm-yy': 17, 'h:mm AM/PM': 18, 'h:mm:ss AM/PM': 19, 'h:mm': 20, 'h:mm:ss': 21, 'm/d/yy h:mm': 22, '#,##0 ;(#,##0)': 37, '#,##0 ;[Red](#,##0)': 38, '#,##0.00;(#,##0.00)': 39, '#,##0.00;[Red](#,##0.00)': 40, 'mm:ss': 45, '[h]:mm:ss': 46, 'mmss.0': 47, '##0.0E+0': 48, '@': 49, '[$-404]e/m/d': 27, 'm/d/yy': 30, 't0': 59, 't0.00': 60, 't#,##0': 61, 't#,##0.00': 62, 't0%': 67, 't0.00%': 68, 't# ?/?': 69, 't# ??/??': 70 }; function convertColor(color) { if (color.length < 6) { color = color.replace(/(\w)/g, function ($0, $1) { return $1 + $1; }); } color = color.substring(1).toUpperCase(); if (color.length < 8) { color = 'FF' + color; } return color; } var Workbook = kendo.Class.extend({ init: function (options) { this.options = options || {}; this._strings = { indexes: {}, count: 0, uniqueCount: 0 }; this._styles = []; this._borders = []; this._sheets = $.map(this.options.sheets || [], $.proxy(function (options) { options.defaults = this.options; return new Worksheet(options, this._strings, this._styles, this._borders); }, this)); }, toDataURL: function () { if (typeof JSZip === 'undefined') { throw new Error('JSZip not found. Check http://docs.telerik.com/kendo-ui/framework/excel/introduction#requirements for more details.'); } var zip = new JSZip(); var docProps = zip.folder('docProps'); docProps.file('core.xml', CORE({ creator: this.options.creator || 'Kendo UI', lastModifiedBy: this.options.creator || 'Kendo UI', created: this.options.date || new Date().toJSON(), modified: this.options.date || new Date().toJSON() })); var sheetCount = this._sheets.length; docProps.file('app.xml', APP({ sheets: this._sheets })); var rels = zip.folder('_rels'); rels.file('.rels', RELS); var xl = zip.folder('xl'); var xlRels = xl.folder('_rels'); xlRels.file('workbook.xml.rels', WORKBOOK_RELS({ count: sheetCount })); xl.file('workbook.xml', WORKBOOK({ sheets: this._sheets, definedNames: $.map(this._sheets, function (sheet, index) { var options = sheet.options; var filter = options.filter; if (filter && typeof filter.from !== 'undefined' && typeof filter.to !== 'undefined') { return { localSheetId: index, name: options.name || options.title || 'Sheet' + (index + 1), from: $ref(filterRowIndex(options), filter.from), to: $ref(filterRowIndex(options), filter.to) }; } }) })); var worksheets = xl.folder('worksheets'); for (var idx = 0; idx < sheetCount; idx++) { worksheets.file(kendo.format('sheet{0}.xml', idx + 1), this._sheets[idx].toXML(idx)); } var borders = $.map(this._borders, $.parseJSON); var styles = $.map(this._styles, $.parseJSON); var hasFont = function (style) { return style.underline || style.bold || style.italic || style.color || style.fontFamily || style.fontSize; }; var fonts = $.map(styles, function (style) { if (style.color) { style.color = convertColor(style.color); } if (hasFont(style)) { return style; } }); var formats = $.map(styles, function (style) { if (style.format && defaultFormats[style.format] === undefined) { return style; } }); var fills = $.map(styles, function (style) { if (style.background) { style.background = convertColor(style.background); return style; } }); xl.file('styles.xml', STYLES({ fonts: fonts, fills: fills, formats: formats, borders: borders, styles: $.map(styles, function (style) { var result = {}; if (hasFont(style)) { result.fontId = $.inArray(style, fonts) + 1; } if (style.background) { result.fillId = $.inArray(style, fills) + 2; } result.textAlign = style.textAlign; result.verticalAlign = style.verticalAlign; result.wrap = style.wrap; result.borderId = style.borderId; if (style.format) { if (defaultFormats[style.format] !== undefined) { result.numFmtId = defaultFormats[style.format]; } else { result.numFmtId = 165 + $.inArray(style, formats); } } return result; }) })); xl.file('sharedStrings.xml', SHARED_STRINGS(this._strings)); zip.file('[Content_Types].xml', CONTENT_TYPES({ count: sheetCount })); return 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + zip.generate({ compression: 'DEFLATE' }); } }); function borderStyle(width) { var alias = 'thin'; if (width === 2) { alias = 'medium'; } else if (width === 3) { alias = 'thick'; } return alias; } function borderSideTemplate(name, style) { var result = ''; if (style && style.size) { result += '<' + name + ' style="' + borderStyle(style.size) + '">'; if (style.color) { result += ''; } result += ''; } return result; } function borderTemplate(border) { return '' + borderSideTemplate('left', border.left) + borderSideTemplate('right', border.right) + borderSideTemplate('top', border.top) + borderSideTemplate('bottom', border.bottom) + ''; } kendo.ooxml = { Workbook: Workbook, Worksheet: Worksheet, toWidth: toWidth, toHeight: toHeight, borderTemplate: borderTemplate }; }(kendo.jQuery, kendo)); return kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.excel', [ 'kendo.core', 'kendo.data', 'kendo.ooxml' ], f); }(function () { var __meta__ = { id: 'excel', name: 'Excel export', category: 'framework', advanced: true, mixin: true, depends: [ 'data', 'ooxml' ] }; (function ($, kendo) { kendo.ExcelExporter = kendo.Class.extend({ init: function (options) { options.columns = this._trimColumns(options.columns || []); this.allColumns = $.map(this._leafColumns(options.columns || []), this._prepareColumn); this.columns = $.grep(this.allColumns, function (column) { return !column.hidden; }); this.options = options; var dataSource = options.dataSource; if (dataSource instanceof kendo.data.DataSource) { this.dataSource = new dataSource.constructor($.extend({}, dataSource.options, { page: options.allPages ? 0 : dataSource.page(), filter: dataSource.filter(), pageSize: options.allPages ? dataSource.total() : dataSource.pageSize(), sort: dataSource.sort(), group: dataSource.group(), aggregate: dataSource.aggregate() })); var data = dataSource.data(); if (data.length > 0) { this.dataSource._data = data; var transport = this.dataSource.transport; if (dataSource._isServerGrouped() && transport.options.data) { transport.options.data = null; } } } else { this.dataSource = kendo.data.DataSource.create(dataSource); } }, _trimColumns: function (columns) { var that = this; return $.grep(columns, function (column) { var result = !!column.field; if (!result && column.columns) { result = that._trimColumns(column.columns).length > 0; } return result; }); }, _leafColumns: function (columns) { var result = []; for (var idx = 0; idx < columns.length; idx++) { if (!columns[idx].columns) { result.push(columns[idx]); continue; } result = result.concat(this._leafColumns(columns[idx].columns)); } return result; }, workbook: function () { return $.Deferred($.proxy(function (d) { this.dataSource.fetch().then($.proxy(function () { var workbook = { sheets: [{ columns: this._columns(), rows: this._rows(), freezePane: this._freezePane(), filter: this._filter() }] }; d.resolve(workbook, this.dataSource.view()); }, this)); }, this)).promise(); }, _prepareColumn: function (column) { if (!column.field) { return; } var value = function (dataItem) { return dataItem.get(column.field); }; var values = null; if (column.values) { values = {}; $.each(column.values, function () { values[this.value] = this.text; }); value = function (dataItem) { return values[dataItem.get(column.field)]; }; } return $.extend({}, column, { value: value, values: values, groupHeaderTemplate: kendo.template(column.groupHeaderTemplate || '#= title #: #= value #'), groupFooterTemplate: column.groupFooterTemplate ? kendo.template(column.groupFooterTemplate) : null, footerTemplate: column.footerTemplate ? kendo.template(column.footerTemplate) : null }); }, _filter: function () { if (!this.options.filterable) { return null; } var depth = this._depth(); return { from: depth, to: depth + this.columns.length - 1 }; }, _dataRow: function (dataItem, level, depth) { if (this._hierarchical()) { level = this.dataSource.level(dataItem) + 1; } var cells = []; for (var li = 0; li < level; li++) { cells[li] = { background: '#dfdfdf', color: '#333' }; } if (depth && dataItem.items) { var column = $.grep(this.allColumns, function (column) { return column.field == dataItem.field; })[0]; var title = column && column.title ? column.title : dataItem.field; var template = column ? column.groupHeaderTemplate : null; var value = title + ': ' + dataItem.value; var group = $.extend({ title: title, field: dataItem.field, value: column && column.values ? column.values[dataItem.value] : dataItem.value, aggregates: dataItem.aggregates }, dataItem.aggregates[dataItem.field]); if (template) { value = template(group); } cells.push({ value: value, background: '#dfdfdf', color: '#333', colSpan: this.columns.length + depth - level }); var rows = this._dataRows(dataItem.items, level + 1); rows.unshift({ type: 'group-header', cells: cells }); return rows.concat(this._footer(dataItem)); } else { var dataCells = []; for (var ci = 0; ci < this.columns.length; ci++) { dataCells[ci] = this._cell(dataItem, this.columns[ci]); } if (this._hierarchical()) { dataCells[0].colSpan = depth - level + 1; } return [{ type: 'data', cells: cells.concat(dataCells) }]; } }, _dataRows: function (dataItems, level) { var depth = this._depth(); var rows = []; for (var i = 0; i < dataItems.length; i++) { rows.push.apply(rows, this._dataRow(dataItems[i], level, depth)); } return rows; }, _footer: function (dataItem) { var rows = []; var footer = false; var cells = $.map(this.columns, $.proxy(function (column) { if (column.groupFooterTemplate) { footer = true; return { background: '#dfdfdf', color: '#333', value: column.groupFooterTemplate($.extend({}, this.dataSource.aggregates(), dataItem.aggregates, dataItem.aggregates[column.field])) }; } else { return { background: '#dfdfdf', color: '#333' }; } }, this)); if (footer) { rows.push({ type: 'group-footer', cells: $.map(new Array(this.dataSource.group().length), function () { return { background: '#dfdfdf', color: '#333' }; }).concat(cells) }); } return rows; }, _isColumnVisible: function (column) { return this._visibleColumns([column]).length > 0 && (column.field || column.columns); }, _visibleColumns: function (columns) { var that = this; return $.grep(columns, function (column) { var result = !column.hidden; if (result && column.columns) { result = that._visibleColumns(column.columns).length > 0; } return result; }); }, _headerRow: function (row, groups) { var headers = $.map(row.cells, function (cell) { return { background: '#7a7a7a', color: '#fff', value: cell.title, colSpan: cell.colSpan > 1 ? cell.colSpan : 1, rowSpan: row.rowSpan > 1 && !cell.colSpan ? row.rowSpan : 1 }; }); if (this._hierarchical()) { headers[0].colSpan = this._depth() + 1; } return { type: 'header', cells: $.map(new Array(groups.length), function () { return { background: '#7a7a7a', color: '#fff' }; }).concat(headers) }; }, _prependHeaderRows: function (rows) { var groups = this.dataSource.group(); var headerRows = [{ rowSpan: 1, cells: [], index: 0 }]; this._prepareHeaderRows(headerRows, this.options.columns); for (var idx = headerRows.length - 1; idx >= 0; idx--) { rows.unshift(this._headerRow(headerRows[idx], groups)); } }, _prepareHeaderRows: function (rows, columns, parentCell, parentRow) { var row = parentRow || rows[rows.length - 1]; var childRow = rows[row.index + 1]; var totalColSpan = 0; var column; var cell; for (var idx = 0; idx < columns.length; idx++) { column = columns[idx]; if (this._isColumnVisible(column)) { cell = { title: column.title || column.field, colSpan: 0 }; row.cells.push(cell); if (column.columns && column.columns.length) { if (!childRow) { childRow = { rowSpan: 0, cells: [], index: rows.length }; rows.push(childRow); } cell.colSpan = this._trimColumns(this._visibleColumns(column.columns)).length; this._prepareHeaderRows(rows, column.columns, cell, childRow); totalColSpan += cell.colSpan - 1; row.rowSpan = rows.length - row.index; } } } if (parentCell) { parentCell.colSpan += totalColSpan; } }, _rows: function () { var groups = this.dataSource.group(); var rows = this._dataRows(this.dataSource.view(), 0); if (this.columns.length) { this._prependHeaderRows(rows); var footer = false; var cells = $.map(this.columns, $.proxy(function (column) { if (column.footerTemplate) { footer = true; var aggregates = this.dataSource.aggregates(); return { background: '#dfdfdf', color: '#333', value: column.footerTemplate($.extend({}, aggregates, aggregates[column.field])) }; } else { return { background: '#dfdfdf', color: '#333' }; } }, this)); if (footer) { rows.push({ type: 'footer', cells: $.map(new Array(groups.length), function () { return { background: '#dfdfdf', color: '#333' }; }).concat(cells) }); } } return rows; }, _headerDepth: function (columns) { var result = 1; var max = 0; for (var idx = 0; idx < columns.length; idx++) { if (columns[idx].columns) { var temp = this._headerDepth(columns[idx].columns); if (temp > max) { max = temp; } } } return result + max; }, _freezePane: function () { var columns = this._visibleColumns(this.options.columns || []); var colSplit = this._visibleColumns(this._trimColumns(this._leafColumns($.grep(columns, function (column) { return column.locked; })))).length; return { rowSplit: this._headerDepth(columns), colSplit: colSplit ? colSplit + this.dataSource.group().length : 0 }; }, _cell: function (dataItem, column) { return { value: column.value(dataItem) }; }, _hierarchical: function () { return this.options.hierarchy && this.dataSource.level; }, _depth: function () { var dataSource = this.dataSource; var depth = 0; var view, i, level; if (this._hierarchical()) { view = dataSource.view(); for (i = 0; i < view.length; i++) { level = dataSource.level(view[i]); if (level > depth) { depth = level; } } depth++; } else { depth = dataSource.group().length; } return depth; }, _columns: function () { var depth = this._depth(); var columns = $.map(new Array(depth), function () { return { width: 20 }; }); return columns.concat($.map(this.columns, function (column) { return { width: parseInt(column.width, 10), autoWidth: column.width ? false : true }; })); } }); kendo.ExcelMixin = { extend: function (proto) { proto.events.push('excelExport'); proto.options.excel = $.extend(proto.options.excel, this.options); proto.saveAsExcel = this.saveAsExcel; }, options: { proxyURL: '', allPages: false, filterable: false, fileName: 'Export.xlsx' }, saveAsExcel: function () { var excel = this.options.excel || {}; var exporter = new kendo.ExcelExporter({ columns: this.columns, dataSource: this.dataSource, allPages: excel.allPages, filterable: excel.filterable, hierarchy: excel.hierarchy }); exporter.workbook().then($.proxy(function (book, data) { if (!this.trigger('excelExport', { workbook: book, data: data })) { var workbook = new kendo.ooxml.Workbook(book); kendo.saveAs({ dataURI: workbook.toDataURL(), fileName: book.fileName || excel.fileName, proxyURL: excel.proxyURL, forceProxy: excel.forceProxy }); } }, this)); } }; }(kendo.jQuery, kendo)); return kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.data.signalr', ['kendo.data'], f); }(function () { var __meta__ = { id: 'data.signalr', name: 'SignalR', category: 'framework', depends: ['data'], hidden: true }; (function ($) { var transport = kendo.data.RemoteTransport.extend({ init: function (options) { var signalr = options && options.signalr ? options.signalr : {}; var promise = signalr.promise; if (!promise) { throw new Error('The "promise" option must be set.'); } if (typeof promise.done != 'function' || typeof promise.fail != 'function') { throw new Error('The "promise" option must be a Promise.'); } this.promise = promise; var hub = signalr.hub; if (!hub) { throw new Error('The "hub" option must be set.'); } if (typeof hub.on != 'function' || typeof hub.invoke != 'function') { throw new Error('The "hub" option is not a valid SignalR hub proxy.'); } this.hub = hub; kendo.data.RemoteTransport.fn.init.call(this, options); }, push: function (callbacks) { var client = this.options.signalr.client || {}; if (client.create) { this.hub.on(client.create, callbacks.pushCreate); } if (client.update) { this.hub.on(client.update, callbacks.pushUpdate); } if (client.destroy) { this.hub.on(client.destroy, callbacks.pushDestroy); } }, _crud: function (options, type) { var hub = this.hub; var server = this.options.signalr.server; if (!server || !server[type]) { throw new Error(kendo.format('The "server.{0}" option must be set.', type)); } var args = [server[type]]; var data = this.parameterMap(options.data, type); if (!$.isEmptyObject(data)) { args.push(data); } this.promise.done(function () { hub.invoke.apply(hub, args).done(options.success).fail(options.error); }); }, read: function (options) { this._crud(options, 'read'); }, create: function (options) { this._crud(options, 'create'); }, update: function (options) { this._crud(options, 'update'); }, destroy: function (options) { this._crud(options, 'destroy'); } }); $.extend(true, kendo.data, { transports: { signalr: transport } }); }(window.kendo.jQuery)); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('kendo.color', ['kendo.core'], f); }(function () { var __meta__ = { id: 'color', name: 'Color utils', category: 'framework', advanced: true, description: 'Color utilities used across components', depends: ['core'] }; (function ($, parseFloat, parseInt) { var Color = function (value) { var color = this, formats = Color.formats, re, processor, parts, i, channels; if (arguments.length === 1) { value = color.resolveColor(value); for (i = 0; i < formats.length; i++) { re = formats[i].re; processor = formats[i].process; parts = re.exec(value); if (parts) { channels = processor(parts); color.r = channels[0]; color.g = channels[1]; color.b = channels[2]; } } } else { color.r = arguments[0]; color.g = arguments[1]; color.b = arguments[2]; } color.r = color.normalizeByte(color.r); color.g = color.normalizeByte(color.g); color.b = color.normalizeByte(color.b); }; Color.prototype = { toHex: function () { var color = this, pad = color.padDigit, r = color.r.toString(16), g = color.g.toString(16), b = color.b.toString(16); return '#' + pad(r) + pad(g) + pad(b); }, resolveColor: function (value) { value = value || 'black'; if (value.charAt(0) == '#') { value = value.substr(1, 6); } value = value.replace(/ /g, ''); value = value.toLowerCase(); value = Color.namedColors[value] || value; return value; }, normalizeByte: function (value) { return value < 0 || isNaN(value) ? 0 : value > 255 ? 255 : value; }, padDigit: function (value) { return value.length === 1 ? '0' + value : value; }, brightness: function (value) { var color = this, round = Math.round; color.r = round(color.normalizeByte(color.r * value)); color.g = round(color.normalizeByte(color.g * value)); color.b = round(color.normalizeByte(color.b * value)); return color; }, percBrightness: function () { var color = this; return Math.sqrt(0.241 * color.r * color.r + 0.691 * color.g * color.g + 0.068 * color.b * color.b); } }; Color.formats = [ { re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, process: function (parts) { return [ parseInt(parts[1], 10), parseInt(parts[2], 10), parseInt(parts[3], 10) ]; } }, { re: /^(\w{2})(\w{2})(\w{2})$/, process: function (parts) { return [ parseInt(parts[1], 16), parseInt(parts[2], 16), parseInt(parts[3], 16) ]; } }, { re: /^(\w{1})(\w{1})(\w{1})$/, process: function (parts) { return [ parseInt(parts[1] + parts[1], 16), parseInt(parts[2] + parts[2], 16), parseInt(parts[3] + parts[3], 16) ]; } } ]; Color.namedColors = { aliceblue: 'f0f8ff', antiquewhite: 'faebd7', aqua: '00ffff', aquamarine: '7fffd4', azure: 'f0ffff', beige: 'f5f5dc', bisque: 'ffe4c4', black: '000000', blanchedalmond: 'ffebcd', blue: '0000ff', blueviolet: '8a2be2', brown: 'a52a2a', burlywood: 'deb887', cadetblue: '5f9ea0', chartreuse: '7fff00', chocolate: 'd2691e', coral: 'ff7f50', cornflowerblue: '6495ed', cornsilk: 'fff8dc', crimson: 'dc143c', cyan: '00ffff', darkblue: '00008b', darkcyan: '008b8b', darkgoldenrod: 'b8860b', darkgray: 'a9a9a9', darkgrey: 'a9a9a9', darkgreen: '006400', darkkhaki: 'bdb76b', darkmagenta: '8b008b', darkolivegreen: '556b2f', darkorange: 'ff8c00', darkorchid: '9932cc', darkred: '8b0000', darksalmon: 'e9967a', darkseagreen: '8fbc8f', darkslateblue: '483d8b', darkslategray: '2f4f4f', darkslategrey: '2f4f4f', darkturquoise: '00ced1', darkviolet: '9400d3', deeppink: 'ff1493', deepskyblue: '00bfff', dimgray: '696969', dimgrey: '696969', dodgerblue: '1e90ff', firebrick: 'b22222', floralwhite: 'fffaf0', forestgreen: '228b22', fuchsia: 'ff00ff', gainsboro: 'dcdcdc', ghostwhite: 'f8f8ff', gold: 'ffd700', goldenrod: 'daa520', gray: '808080', grey: '808080', green: '008000', greenyellow: 'adff2f', honeydew: 'f0fff0', hotpink: 'ff69b4', indianred: 'cd5c5c', indigo: '4b0082', ivory: 'fffff0', khaki: 'f0e68c', lavender: 'e6e6fa', lavenderblush: 'fff0f5', lawngreen: '7cfc00', lemonchiffon: 'fffacd', lightblue: 'add8e6', lightcoral: 'f08080', lightcyan: 'e0ffff', lightgoldenrodyellow: 'fafad2', lightgray: 'd3d3d3', lightgrey: 'd3d3d3', lightgreen: '90ee90', lightpink: 'ffb6c1', lightsalmon: 'ffa07a', lightseagreen: '20b2aa', lightskyblue: '87cefa', lightslategray: '778899', lightslategrey: '778899', lightsteelblue: 'b0c4de', lightyellow: 'ffffe0', lime: '00ff00', limegreen: '32cd32', linen: 'faf0e6', magenta: 'ff00ff', maroon: '800000', mediumaquamarine: '66cdaa', mediumblue: '0000cd', mediumorchid: 'ba55d3', mediumpurple: '9370d8', mediumseagreen: '3cb371', mediumslateblue: '7b68ee', mediumspringgreen: '00fa9a', mediumturquoise: '48d1cc', mediumvioletred: 'c71585', midnightblue: '191970', mintcream: 'f5fffa', mistyrose: 'ffe4e1', moccasin: 'ffe4b5', navajowhite: 'ffdead', navy: '000080', oldlace: 'fdf5e6', olive: '808000', olivedrab: '6b8e23', orange: 'ffa500', orangered: 'ff4500', orchid: 'da70d6', palegoldenrod: 'eee8aa', palegreen: '98fb98', paleturquoise: 'afeeee', palevioletred: 'd87093', papayawhip: 'ffefd5', peachpuff: 'ffdab9', peru: 'cd853f', pink: 'ffc0cb', plum: 'dda0dd', powderblue: 'b0e0e6', purple: '800080', red: 'ff0000', rosybrown: 'bc8f8f', royalblue: '4169e1', saddlebrown: '8b4513', salmon: 'fa8072', sandybrown: 'f4a460', seagreen: '2e8b57', seashell: 'fff5ee', sienna: 'a0522d', silver: 'c0c0c0', skyblue: '87ceeb', slateblue: '6a5acd', slategray: '708090', slategrey: '708090', snow: 'fffafa', springgreen: '00ff7f', steelblue: '4682b4', tan: 'd2b48c', teal: '008080', thistle: 'd8bfd8', tomato: 'ff6347', turquoise: '40e0d0', violet: 'ee82ee', wheat: 'f5deb3', white: 'ffffff', whitesmoke: 'f5f5f5', yellow: 'ffff00', yellowgreen: '9acd32' }; var namedColorRegexp = ['transparent']; for (var i in Color.namedColors) { if (Color.namedColors.hasOwnProperty(i)) { namedColorRegexp.push(i); } } namedColorRegexp = new RegExp('^(' + namedColorRegexp.join('|') + ')(\\W|$)', 'i'); function parseColor(color, nothrow) { var m, ret; if (color == null || color == 'none') { return null; } if (color instanceof _Color) { return color; } color = color.toLowerCase(); if (m = namedColorRegexp.exec(color)) { if (m[1] == 'transparent') { color = new _RGB(1, 1, 1, 0); } else { color = parseColor(Color.namedColors[m[1]], nothrow); } color.match = [m[1]]; return color; } if (m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})\b/i.exec(color)) { ret = new _Bytes(parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16), 1); } else if (m = /^#?([0-9a-f])([0-9a-f])([0-9a-f])\b/i.exec(color)) { ret = new _Bytes(parseInt(m[1] + m[1], 16), parseInt(m[2] + m[2], 16), parseInt(m[3] + m[3], 16), 1); } else if (m = /^rgb\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/.exec(color)) { ret = new _Bytes(parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10), 1); } else if (m = /^rgba\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9.]+)\s*\)/.exec(color)) { ret = new _Bytes(parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10), parseFloat(m[4])); } else if (m = /^rgb\(\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9]*\.?[0-9]+)%\s*\)/.exec(color)) { ret = new _RGB(parseFloat(m[1]) / 100, parseFloat(m[2]) / 100, parseFloat(m[3]) / 100, 1); } else if (m = /^rgba\(\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9]*\.?[0-9]+)%\s*,\s*([0-9.]+)\s*\)/.exec(color)) { ret = new _RGB(parseFloat(m[1]) / 100, parseFloat(m[2]) / 100, parseFloat(m[3]) / 100, parseFloat(m[4])); } if (ret) { ret.match = m; } else if (!nothrow) { throw new Error('Cannot parse color: ' + color); } return ret; } function hex(n, width, pad) { if (!pad) { pad = '0'; } n = n.toString(16); while (width > n.length) { n = '0' + n; } return n; } function hue2rgb(p, q, t) { if (t < 0) { t += 1; } if (t > 1) { t -= 1; } if (t < 1 / 6) { return p + (q - p) * 6 * t; } if (t < 1 / 2) { return q; } if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; } return p; } var _Color = kendo.Class.extend({ toHSV: function () { return this; }, toRGB: function () { return this; }, toHex: function () { return this.toBytes().toHex(); }, toBytes: function () { return this; }, toCss: function () { return '#' + this.toHex(); }, toCssRgba: function () { var rgb = this.toBytes(); return 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat((+this.a).toFixed(3)) + ')'; }, toDisplay: function () { if (kendo.support.browser.msie && kendo.support.browser.version < 9) { return this.toCss(); } return this.toCssRgba(); }, equals: function (c) { return c === this || c !== null && this.toCssRgba() == parseColor(c).toCssRgba(); }, diff: function (c2) { if (c2 == null) { return NaN; } var c1 = this.toBytes(); c2 = c2.toBytes(); return Math.sqrt(Math.pow((c1.r - c2.r) * 0.3, 2) + Math.pow((c1.g - c2.g) * 0.59, 2) + Math.pow((c1.b - c2.b) * 0.11, 2)); }, clone: function () { var c = this.toBytes(); if (c === this) { c = new _Bytes(c.r, c.g, c.b, c.a); } return c; } }); var _RGB = _Color.extend({ init: function (r, g, b, a) { this.r = r; this.g = g; this.b = b; this.a = a; }, toHSV: function () { var min, max, delta, h, s, v; var r = this.r, g = this.g, b = this.b; min = Math.min(r, g, b); max = Math.max(r, g, b); v = max; delta = max - min; if (delta === 0) { return new _HSV(0, 0, v, this.a); } if (max !== 0) { s = delta / max; if (r == max) { h = (g - b) / delta; } else if (g == max) { h = 2 + (b - r) / delta; } else { h = 4 + (r - g) / delta; } h *= 60; if (h < 0) { h += 360; } } else { s = 0; h = -1; } return new _HSV(h, s, v, this.a); }, toHSL: function () { var r = this.r, g = this.g, b = this.b; var max = Math.max(r, g, b), min = Math.min(r, g, b); var h, s, l = (max + min) / 2; if (max == min) { h = s = 0; } else { var d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h *= 60; s *= 100; l *= 100; } return new _HSL(h, s, l, this.a); }, toBytes: function () { return new _Bytes(this.r * 255, this.g * 255, this.b * 255, this.a); } }); var _Bytes = _RGB.extend({ init: function (r, g, b, a) { this.r = Math.round(r); this.g = Math.round(g); this.b = Math.round(b); this.a = a; }, toRGB: function () { return new _RGB(this.r / 255, this.g / 255, this.b / 255, this.a); }, toHSV: function () { return this.toRGB().toHSV(); }, toHSL: function () { return this.toRGB().toHSL(); }, toHex: function () { return hex(this.r, 2) + hex(this.g, 2) + hex(this.b, 2); }, toBytes: function () { return this; } }); var _HSV = _Color.extend({ init: function (h, s, v, a) { this.h = h; this.s = s; this.v = v; this.a = a; }, toRGB: function () { var h = this.h, s = this.s, v = this.v; var i, r, g, b, f, p, q, t; if (s === 0) { r = g = b = v; } else { h /= 60; i = Math.floor(h); f = h - i; p = v * (1 - s); q = v * (1 - s * f); t = v * (1 - s * (1 - f)); switch (i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; default: r = v; g = p; b = q; break; } } return new _RGB(r, g, b, this.a); }, toHSL: function () { return this.toRGB().toHSL(); }, toBytes: function () { return this.toRGB().toBytes(); } }); var _HSL = _Color.extend({ init: function (h, s, l, a) { this.h = h; this.s = s; this.l = l; this.a = a; }, toRGB: function () { var h = this.h, s = this.s, l = this.l; var r, g, b; if (s === 0) { r = g = b = l; } else { h /= 360; s /= 100; l /= 100; var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } return new _RGB(r, g, b, this.a); }, toHSV: function () { return this.toRGB().toHSV(); }, toBytes: function () { return this.toRGB().toBytes(); } }); Color.fromBytes = function (r, g, b, a) { return new _Bytes(r, g, b, a != null ? a : 1); }; Color.fromRGB = function (r, g, b, a) { return new _RGB(r, g, b, a != null ? a : 1); }; Color.fromHSV = function (h, s, v, a) { return new _HSV(h, s, v, a != null ? a : 1); }; Color.fromHSL = function (h, s, l, a) { return new _HSL(h, s, l, a != null ? a : 1); }; kendo.Color = Color; kendo.parseColor = parseColor; }(window.kendo.jQuery, parseFloat, parseInt)); }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('util/main', ['kendo.core'], f); }(function () { (function () { var math = Math, kendo = window.kendo, deepExtend = kendo.deepExtend; var DEG_TO_RAD = math.PI / 180, MAX_NUM = Number.MAX_VALUE, MIN_NUM = -Number.MAX_VALUE, UNDEFINED = 'undefined'; function defined(value) { return typeof value !== UNDEFINED; } function round(value, precision) { var power = pow(precision); return math.round(value * power) / power; } function pow(p) { if (p) { return math.pow(10, p); } else { return 1; } } function limitValue(value, min, max) { return math.max(math.min(value, max), min); } function rad(degrees) { return degrees * DEG_TO_RAD; } function deg(radians) { return radians / DEG_TO_RAD; } function isNumber(val) { return typeof val === 'number' && !isNaN(val); } function valueOrDefault(value, defaultValue) { return defined(value) ? value : defaultValue; } function sqr(value) { return value * value; } function objectKey(object) { var parts = []; for (var key in object) { parts.push(key + object[key]); } return parts.sort().join(''); } function hashKey(str) { var hash = 2166136261; for (var i = 0; i < str.length; ++i) { hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24); hash ^= str.charCodeAt(i); } return hash >>> 0; } function hashObject(object) { return hashKey(objectKey(object)); } var now = Date.now; if (!now) { now = function () { return new Date().getTime(); }; } function arrayLimits(arr) { var length = arr.length, i, min = MAX_NUM, max = MIN_NUM; for (i = 0; i < length; i++) { max = math.max(max, arr[i]); min = math.min(min, arr[i]); } return { min: min, max: max }; } function arrayMin(arr) { return arrayLimits(arr).min; } function arrayMax(arr) { return arrayLimits(arr).max; } function sparseArrayMin(arr) { return sparseArrayLimits(arr).min; } function sparseArrayMax(arr) { return sparseArrayLimits(arr).max; } function sparseArrayLimits(arr) { var min = MAX_NUM, max = MIN_NUM; for (var i = 0, length = arr.length; i < length; i++) { var n = arr[i]; if (n !== null && isFinite(n)) { min = math.min(min, n); max = math.max(max, n); } } return { min: min === MAX_NUM ? undefined : min, max: max === MIN_NUM ? undefined : max }; } function last(array) { if (array) { return array[array.length - 1]; } } function append(first, second) { first.push.apply(first, second); return first; } function renderTemplate(text) { return kendo.template(text, { useWithBlock: false, paramName: 'd' }); } function renderAttr(name, value) { return defined(value) && value !== null ? ' ' + name + '=\'' + value + '\' ' : ''; } function renderAllAttr(attrs) { var output = ''; for (var i = 0; i < attrs.length; i++) { output += renderAttr(attrs[i][0], attrs[i][1]); } return output; } function renderStyle(attrs) { var output = ''; for (var i = 0; i < attrs.length; i++) { var value = attrs[i][1]; if (defined(value)) { output += attrs[i][0] + ':' + value + ';'; } } if (output !== '') { return output; } } function renderSize(size) { if (typeof size !== 'string') { size += 'px'; } return size; } function renderPos(pos) { var result = []; if (pos) { var parts = kendo.toHyphens(pos).split('-'); for (var i = 0; i < parts.length; i++) { result.push('k-pos-' + parts[i]); } } return result.join(' '); } function isTransparent(color) { return color === '' || color === null || color === 'none' || color === 'transparent' || !defined(color); } function arabicToRoman(n) { var literals = { 1: 'i', 10: 'x', 100: 'c', 2: 'ii', 20: 'xx', 200: 'cc', 3: 'iii', 30: 'xxx', 300: 'ccc', 4: 'iv', 40: 'xl', 400: 'cd', 5: 'v', 50: 'l', 500: 'd', 6: 'vi', 60: 'lx', 600: 'dc', 7: 'vii', 70: 'lxx', 700: 'dcc', 8: 'viii', 80: 'lxxx', 800: 'dccc', 9: 'ix', 90: 'xc', 900: 'cm', 1000: 'm' }; var values = [ 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]; var roman = ''; while (n > 0) { if (n < values[0]) { values.shift(); } else { roman += literals[values[0]]; n -= values[0]; } } return roman; } function romanToArabic(r) { r = r.toLowerCase(); var digits = { i: 1, v: 5, x: 10, l: 50, c: 100, d: 500, m: 1000 }; var value = 0, prev = 0; for (var i = 0; i < r.length; ++i) { var v = digits[r.charAt(i)]; if (!v) { return null; } value += v; if (v > prev) { value -= 2 * prev; } prev = v; } return value; } function memoize(f) { var cache = Object.create(null); return function () { var id = ''; for (var i = arguments.length; --i >= 0;) { id += ':' + arguments[i]; } if (id in cache) { return cache[id]; } return f.apply(this, arguments); }; } function ucs2decode(string) { var output = [], counter = 0, length = string.length, value, extra; while (counter < length) { value = string.charCodeAt(counter++); if (value >= 55296 && value <= 56319 && counter < length) { extra = string.charCodeAt(counter++); if ((extra & 64512) == 56320) { output.push(((value & 1023) << 10) + (extra & 1023) + 65536); } else { output.push(value); counter--; } } else { output.push(value); } } return output; } function ucs2encode(array) { return array.map(function (value) { var output = ''; if (value > 65535) { value -= 65536; output += String.fromCharCode(value >>> 10 & 1023 | 55296); value = 56320 | value & 1023; } output += String.fromCharCode(value); return output; }).join(''); } deepExtend(kendo, { util: { MAX_NUM: MAX_NUM, MIN_NUM: MIN_NUM, append: append, arrayLimits: arrayLimits, arrayMin: arrayMin, arrayMax: arrayMax, defined: defined, deg: deg, hashKey: hashKey, hashObject: hashObject, isNumber: isNumber, isTransparent: isTransparent, last: last, limitValue: limitValue, now: now, objectKey: objectKey, round: round, rad: rad, renderAttr: renderAttr, renderAllAttr: renderAllAttr, renderPos: renderPos, renderSize: renderSize, renderStyle: renderStyle, renderTemplate: renderTemplate, sparseArrayLimits: sparseArrayLimits, sparseArrayMin: sparseArrayMin, sparseArrayMax: sparseArrayMax, sqr: sqr, valueOrDefault: valueOrDefault, romanToArabic: romanToArabic, arabicToRoman: arabicToRoman, memoize: memoize, ucs2encode: ucs2encode, ucs2decode: ucs2decode } }); kendo.drawing.util = kendo.util; kendo.dataviz.util = kendo.util; }()); return window.kendo; }, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) { (a3 || a2)(); })); (function (f, define) { define('util/text-metrics', [ 'kendo.core', 'util/main' ], f); }(function () { (function ($) { var doc = document, kendo = window.kendo, Class = kendo.Class, util = kendo.util, defined = util.defined; var LRUCache = Class.extend({ init: function (size) { this._size = size; this._length = 0; this._map = {}; }, put: function (key, value) { var lru = this, map = lru._map, entry = { key: key, value: value }; map[key] = entry; if (!lru._head) { lru._head = lru._tail = entry; } else { lru._tail.newer = entry; entry.older = lru._tail; lru._tail = entry; } if (lru._length >= lru._size) { map[lru._head.key] = null; lru._head = lru._head.newer; lru._head.older = null; } else { lru._length++; } }, get: function (key) { var lru = this, entry = lru._map[key]; if (entry) { if (entry === lru._head && entry !== lru._tail) { lru._head = entry.newer; lru._head.older = null; } if (entry !== lru._tail) { if (entry.older) { entry.older.newer = entry.newer; entry.newer.older = entry.older; } entry.older = lru._tail; entry.newer = null; lru._tail.newer = entry; lru._tail = entry; } return entry.value; } } }); var defaultMeasureBox = $('