/*! * DevExtreme * Version: 14.1.9-pre * Build date: Nov 7, 2014 * * Copyright (c) 2012 - 2014 Developer Express Inc. ALL RIGHTS RESERVED * EULA: https://www.devexpress.com/Support/EULAs/DevExtreme.xml */ "use strict"; if (!window.DevExpress) { /*! Module core, file devexpress.js */ (function($, global, undefined) { (function checkjQueryVersion(version) { version = version.split("."); if (version[0] < 1 || version[0] == 1 && version[1] < 10) throw Error("Your version of jQuery is too old. Please upgrade jQuery to 1.10.0 or later."); })($.fn.jquery); var Class = function() { var wrapOverridden = function(baseProto, methodName, method) { return function() { var prevCallBase = this.callBase; this.callBase = baseProto[methodName]; try { return method.apply(this, arguments) } finally { this.callBase = prevCallBase } } }; var clonePrototype = function(obj) { var func = function(){}; func.prototype = obj.prototype; return new func }; var classImpl = function(){}; var redefine = function(members) { var that = this; if (!members) return that; var memberNames = $.map(members, function(_, k) { return k }); $.each(["toString", "toLocaleString", "valueOf"], function() { if (members[this]) memberNames.push(this) }); $.each(memberNames, function() { var overridden = $.isFunction(that.prototype[this]) && $.isFunction(members[this]); that.prototype[this] = overridden ? wrapOverridden(that.parent.prototype, this, members[this]) : members[this] }); return that }; var include = function() { var classObj = this; $.each(arguments, function() { if (this.ctor) classObj._includedCtors.push(this.ctor); for (var name in this) { if (name === "ctor") continue; if (name in classObj.prototype) throw Error("Member name collision: " + name); classObj.prototype[name] = this[name] } }); return classObj }; var subclassOf = function(parentClass) { if (this.parent === parentClass) return true; if (!this.parent || !this.parent.subclassOf) return false; return this.parent.subclassOf(parentClass) }; classImpl.inherit = function(members) { var inheritor = function() { if (!this || this === global || typeof this.constructor !== "function") throw Error("A class must be instantiated using the 'new' keyword"); var instance = this, ctor = instance.ctor; if (ctor) ctor.apply(instance, arguments); $.each(instance.constructor._includedCtors, function() { this.call(instance) }) }; inheritor.prototype = clonePrototype(this); inheritor.inherit = this.inherit; inheritor.redefine = redefine; inheritor.include = include; inheritor.subclassOf = subclassOf; inheritor.parent = this; inheritor._includedCtors = this._includedCtors ? this._includedCtors.slice(0) : []; inheritor.prototype.constructor = inheritor; inheritor.redefine(members); return inheritor }; return classImpl }(); function createQueue(discardPendingTasks) { var _tasks = [], _busy = false; function exec() { while (_tasks.length) { _busy = true; var task = _tasks.shift(), result = task(); if (result === undefined) continue; if (result.then) { $.when(result).always(exec); return } throw Error("Queued task returned unexpected result"); } _busy = false } function add(task, removeTaskCallback) { if (!discardPendingTasks) _tasks.push(task); else { if (_tasks[0] && removeTaskCallback) removeTaskCallback(_tasks[0]); _tasks = [task] } if (!_busy) exec() } function busy() { return _busy } return { add: add, busy: busy } } var parseUrl = function() { var a = document.createElement("a"), props = ["protocol", "hostname", "port", "pathname", "search", "hash"]; var normalizePath = function(value) { if (value.charAt(0) !== "/") value = "/" + value; return value }; return function(url) { a.href = url; var result = {}; $.each(props, function() { result[this] = a[this] }); result.pathname = normalizePath(result.pathname); return result } }(); global.DevExpress = global.DevExpress || {}; var enqueueAsync = function(task) { var deferred = $.Deferred(); setTimeout(function() { deferred.resolve(task()) }, 60); return deferred }; var hideTopOverlayCallback = function() { var callbacks = []; return { add: function(callback) { var indexOfCallback = $.inArray(callback, callbacks); if (indexOfCallback === -1) callbacks.push(callback) }, remove: function(callback) { var indexOfCallback = $.inArray(callback, callbacks); if (indexOfCallback !== -1) callbacks.splice(indexOfCallback, 1) }, fire: function() { var callback = callbacks.pop(), result = !!callback; if (result) callback(); return result }, hasCallback: function() { return callbacks.length > 0 }, reset: function() { callbacks = [] } } }(); var overlayTargetContainer = function() { var defaultTargetContainer = "body"; return function(targetContainer) { if (arguments.length) defaultTargetContainer = targetContainer; return defaultTargetContainer } }(); $.extend(global.DevExpress, { VERSION: "14.1.8", abstract: function() { throw Error("Not implemented"); }, Class: Class, createQueue: createQueue, enqueue: createQueue().add, enqueueAsync: enqueueAsync, parseUrl: parseUrl, hideTopOverlayCallback: hideTopOverlayCallback, hardwareBackButton: $.Callbacks(), overlayTargetContainer: overlayTargetContainer, rtlEnabled: false }) })(jQuery, this); /*! Module core, file inflector.js */ (function($, DX, undefined) { var _normalize = function(text) { if (text === undefined || text === null) return ""; return String(text) }; var _ucfirst = function(text) { return _normalize(text).charAt(0).toUpperCase() + text.substr(1) }; var _chop = function(text) { return _normalize(text).replace(/([a-z\d])([A-Z])/g, "$1 $2").split(/[\s_-]+/) }; var dasherize = function(text) { return $.map(_chop(text), function(p) { return p.toLowerCase() }).join("-") }; var underscore = function(text) { return dasherize(text).replace(/-/g, "_") }; var camelize = function(text, upperFirst) { return $.map(_chop(text), function(p, i) { p = p.toLowerCase(); if (upperFirst || i > 0) p = _ucfirst(p); return p }).join("") }; var humanize = function(text) { return _ucfirst(dasherize(text).replace(/-/g, " ")) }; var titleize = function(text) { return $.map(_chop(text), function(p) { return _ucfirst(p.toLowerCase()) }).join(" ") }; DX.inflector = { dasherize: dasherize, camelize: camelize, humanize: humanize, titleize: titleize, underscore: underscore } })(jQuery, DevExpress); /*! Module core, file utils.common.js */ (function($, DX, undefined) { var isDefined = function(object) { return object !== null && object !== undefined }; var isString = function(object) { return $.type(object) === 'string' }; var isNumber = function(object) { return typeof object === "number" && isFinite(object) || $.isNumeric(object) }; var isObject = function(object) { return $.type(object) === 'object' }; var isArray = function(object) { return $.type(object) === 'array' }; var isDate = function(object) { return $.type(object) === 'date' }; var isFunction = function(object) { return $.type(object) === 'function' }; var isExponential = function(value) { return isNumber(value) && value.toString().indexOf('e') !== -1 }; var extendFromObject = function(target, source, overrideExistingValues) { target = target || {}; for (var prop in source) if (source.hasOwnProperty(prop)) { var value = source[prop]; if (!(prop in target) || overrideExistingValues) target[prop] = value } return target }; var clone = function() { function Clone(){} return function(obj) { Clone.prototype = obj; return new Clone } }(); var executeAsync = function(action, context) { var deferred = $.Deferred(), normalizedContext = context || this; setTimeout(function() { var result = action.call(normalizedContext); if (result && result.done && $.isFunction(result.done)) result.done(function() { deferred.resolveWith(normalizedContext) }); else deferred.resolveWith(normalizedContext) }, 0); return deferred.promise() }; var stringFormat = function() { var s = arguments[0]; for (var i = 0; i < arguments.length - 1; i++) { var reg = new RegExp("\\{" + i + "\\}", "gm"); s = s.replace(reg, arguments[i + 1]) } return s }; var findBestMatches = function(targetFilter, items, mapFn) { var bestMatches = [], maxMatchCount = 0; $.each(items, function(index, itemSrc) { var matchCount = 0, item = mapFn ? mapFn(itemSrc) : itemSrc; $.each(targetFilter, function(paramName) { var value = item[paramName]; if (value === undefined) return; if (value === targetFilter[paramName]) { matchCount++; return } matchCount = -1; return false }); if (matchCount < maxMatchCount) return; if (matchCount > maxMatchCount) { bestMatches.length = 0; maxMatchCount = matchCount } bestMatches.push(itemSrc) }); return bestMatches }; var preg_quote = function(str) { return (str + "").replace(/([\+\*\?\\\.\[\^\]\$\(\)\{\}\>\<\|\=\!\:])/g, "\\$1") }; var replaceAll = function(text, searchToken, replacementToken) { return text.replace(new RegExp("(" + preg_quote(searchToken) + ")", "gi"), replacementToken) }; var splitPair = function(raw) { switch (typeof raw) { case"string": return raw.split(/\s+/, 2); case"object": return [raw.x || raw.h, raw.y || raw.v]; case"number": return [raw]; default: return raw } }; var stringPairToObject = function(raw) { var pair = splitPair(raw), x = parseInt(pair && pair[0], 10), y = parseInt(pair && pair[1], 10); if (!isFinite(x)) x = 0; if (!isFinite(y)) y = x; return { x: x, y: y } }; function icontains(elem, text) { var result = false; $.each($(elem).contents(), function(index, content) { if (content.nodeType === 3 && (content.textContent || content.nodeValue || "").toLowerCase().indexOf((text || "").toLowerCase()) > -1) { result = true; return false } }); return result } $.expr[":"].dxicontains = $.expr.createPseudo(function(text) { return function(elem) { return icontains(elem, text) } }); function deepExtendArraySafe(target, changes) { var prevValue, newValue; for (var name in changes) { prevValue = target[name]; newValue = changes[name]; if (target === newValue) continue; if ($.isPlainObject(newValue) && !(newValue instanceof $.Event)) target[name] = deepExtendArraySafe($.isPlainObject(prevValue) ? prevValue : {}, newValue); else if (newValue !== undefined) target[name] = newValue } return target } function unwrapObservable(value) { if (DX.support.hasKo) return ko.utils.unwrapObservable(value); return value } DX.utils = { isDefined: isDefined, isString: isString, isNumber: isNumber, isObject: isObject, isArray: isArray, isDate: isDate, isFunction: isFunction, isExponential: isExponential, extendFromObject: extendFromObject, clone: clone, executeAsync: executeAsync, stringFormat: stringFormat, findBestMatches: findBestMatches, replaceAll: replaceAll, deepExtendArraySafe: deepExtendArraySafe, splitPair: splitPair, stringPairToObject: stringPairToObject, unwrapObservable: unwrapObservable } })(jQuery, DevExpress); /*! Module core, file utils.console.js */ (function($, DX, undefined) { var logger = function() { var console = window.console; function info(text) { if (!console || !$.isFunction(console.info)) return; console.info(text) } function warn(text) { if (!console || !$.isFunction(console.warn)) return; console.warn(text) } function error(text) { if (!console || !$.isFunction(console.error)) return; console.error(text) } return { info: info, warn: warn, error: error } }(); var debug = function() { function assert(condition, message) { if (!condition) throw new Error(message); } function assertParam(parameter, message) { assert(parameter !== null && parameter !== undefined, message) } return { assert: assert, assertParam: assertParam } }(); $.extend(DX.utils, { logger: logger, debug: debug }) })(jQuery, DevExpress); /*! Module core, file utils.math.js */ (function($, DX, undefined) { var PI = Math.PI, LN10 = Math.LN10; var cos = Math.cos, sin = Math.sin, abs = Math.abs, log = Math.log, floor = Math.floor, ceil = Math.ceil, max = Math.max, min = Math.min, isNaN = window.isNaN, Number = window.Number, NaN = window.NaN; var isNumber = DX.utils.isNumber, isExponential = DX.utils.isExponential; var getPrecision = function(value) { var stringFraction, stringValue = value.toString(), pointIndex = stringValue.indexOf('.'), startIndex, precision; if (isExponential(value)) { precision = getDecimalOrder(value); if (precision < 0) return Math.abs(precision); else return 0 } if (pointIndex !== -1) { startIndex = pointIndex + 1; stringFraction = stringValue.substring(startIndex, startIndex + 20); return stringFraction.length } return 0 }; var getLog = function(value, base) { if (!value) return 0; return Math.log(value) / Math.log(base) }; var raiseTo = function(power, base) { return Math.pow(base, power) }; var sign = function(value) { if (value === 0) return 0; return value / abs(value) }; var normalizeAngle = function(angle) { return (angle % 360 + 360) % 360 }; var convertAngleToRendererSpace = function(angle) { return 90 - angle }; var degreesToRadians = function(value) { return PI * value / 180 }; var getCosAndSin = function(angle) { var angleInRadians = degreesToRadians(angle); return { cos: cos(angleInRadians), sin: sin(angleInRadians) } }; var DECIMAL_ORDER_THRESHOLD = 1E-14; var getDecimalOrder = function(number) { var n = abs(number), cn; if (!isNaN(n)) { if (n > 0) { n = log(n) / LN10; cn = ceil(n); return cn - n < DECIMAL_ORDER_THRESHOLD ? cn : floor(n) } return 0 } return NaN }; var getAppropriateFormat = function(start, end, count) { var order = max(getDecimalOrder(start), getDecimalOrder(end)), precision = -getDecimalOrder(abs(end - start) / count), format; if (!isNaN(order) && !isNaN(precision)) { if (abs(order) <= 4) { format = 'fixedPoint'; precision < 0 && (precision = 0); precision > 4 && (precision = 4) } else { format = 'exponential'; precision += order - 1; precision > 3 && (precision = 3) } return { format: format, precision: precision } } return null }; var getFraction = function(value) { var valueString, dotIndex; if (isNumber(value)) { valueString = value.toString(); dotIndex = valueString.indexOf('.'); if (dotIndex >= 0) if (isExponential(value)) return valueString.substr(dotIndex + 1, valueString.indexOf('e') - dotIndex - 1); else { valueString = value.toFixed(20); return valueString.substr(dotIndex + 1, valueString.length - dotIndex + 1) } } return '' }; var getSignificantDigitPosition = function(value) { var fraction = getFraction(value), i; if (fraction) for (i = 0; i < fraction.length; i++) if (fraction.charAt(i) !== '0') return i + 1; return 0 }; var adjustValue = function(value) { var fraction = getFraction(value), nextValue, i; if (fraction) for (i = 1; i <= fraction.length; i++) { nextValue = roundValue(value, i); if (nextValue !== 0 && fraction[i - 2] && fraction[i - 1] && fraction[i - 2] === fraction[i - 1]) return nextValue } return value }; var roundValue = function(value, precision) { if (precision > 20) precision = 20; if (isNumber(value)) if (isExponential(value)) return Number(value.toExponential(precision)); else return Number(value.toFixed(precision)) }; var applyPrecisionByMinDelta = function(min, delta, value) { var minPrecision = getPrecision(min), deltaPrecision = getPrecision(delta); return roundValue(value, minPrecision < deltaPrecision ? deltaPrecision : minPrecision) }; $.extend(DX.utils, { getLog: getLog, raiseTo: raiseTo, sign: sign, normalizeAngle: normalizeAngle, convertAngleToRendererSpace: convertAngleToRendererSpace, degreesToRadians: degreesToRadians, getCosAndSin: getCosAndSin, getDecimalOrder: getDecimalOrder, getAppropriateFormat: getAppropriateFormat, getFraction: getFraction, adjustValue: adjustValue, roundValue: roundValue, applyPrecisionByMinDelta: applyPrecisionByMinDelta, getSignificantDigitPosition: getSignificantDigitPosition }); DX.utils.getPrecision = getPrecision })(jQuery, DevExpress); /*! Module core, file utils.date.js */ (function($, DX, undefined) { var isObject = DX.utils.isObject, isString = DX.utils.isString, isDate = DX.utils.isDate, isDefined = DX.utils.isDefined; var dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year']; var addSubValues = function(value1, value2, isSub) { return value1 + (isSub ? -1 : 1) * value2 }; var toMilliseconds = function(value) { switch (value) { case'millisecond': return 1; case'second': return toMilliseconds('millisecond') * 1000; case'minute': return toMilliseconds('second') * 60; case'hour': return toMilliseconds('minute') * 60; case'day': return toMilliseconds('hour') * 24; case'week': return toMilliseconds('day') * 7; case'month': return toMilliseconds('day') * 30; case'quarter': return toMilliseconds('month') * 3; case'year': return toMilliseconds('day') * 365; default: return 0 } }; function parseISO8601(isoString) { var result = new Date(0); var chunks = isoString.replace("Z", "").split("T"), date = String(chunks[0]).split("-"), time = String(chunks[1]).split(":"); var year, month, day, hours, minutes, seconds, milliseconds; year = Number(date[0]); month = Number(date[1]) - 1; day = Number(date[2]); result.setDate(day); result.setMonth(month); result.setFullYear(year); if (time.length) { hours = Number(time[0]); minutes = Number(time[1]); seconds = Number(String(time[2]).split(".")[0]); milliseconds = Number(String(time[2]).split(".")[1]) || 0; result.setHours(hours); result.setMinutes(minutes); result.setSeconds(seconds); result.setMilliseconds(milliseconds) } return result } function formatISO8601(date) { function pad(n) { if (n < 10) return "0".concat(n); return String(n) } return [date.getFullYear(), "-", pad(date.getMonth() + 1), "-", pad(date.getDate()), "T", pad(date.getHours()), ":", pad(date.getMinutes()), ":", pad(date.getSeconds()), "Z"].join("") } var convertMillisecondsToDateUnits = function(value) { var i, dateUnitCount, dateUnitInterval, dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'month', 'year'], result = {}; for (i = dateUnitIntervals.length - 1; i >= 0; i--) { dateUnitInterval = dateUnitIntervals[i]; dateUnitCount = Math.floor(value / toMilliseconds(dateUnitInterval)); if (dateUnitCount > 0) { result[dateUnitInterval + 's'] = dateUnitCount; value -= convertDateUnitToMilliseconds(dateUnitInterval, dateUnitCount) } } return result }; var convertDateTickIntervalToMilliseconds = function(tickInterval) { var milliseconds = 0; if (isObject(tickInterval)) $.each(tickInterval, function(key, value) { milliseconds += convertDateUnitToMilliseconds(key.substr(0, key.length - 1), value) }); if (isString(tickInterval)) milliseconds = convertDateUnitToMilliseconds(tickInterval, 1); return milliseconds }; var convertDateUnitToMilliseconds = function(dateUnit, count) { return toMilliseconds(dateUnit) * count }; var getDateUnitInterval = function(tickInterval) { var maxInterval = -1, i; if (isString(tickInterval)) return tickInterval; if (isObject(tickInterval)) { $.each(tickInterval, function(key, value) { for (i = 0; i < dateUnitIntervals.length; i++) if (value && (key === dateUnitIntervals[i] + 's' || key === dateUnitIntervals[i]) && maxInterval < i) maxInterval = i }); return dateUnitIntervals[maxInterval] } return '' }; var correctDateWithUnitBeginning = function(date, dateInterval) { var dayMonth, firstQuarterMonth, dateUnitInterval = getDateUnitInterval(dateInterval); switch (dateUnitInterval) { case'second': date.setMilliseconds(0); break; case'minute': date.setSeconds(0, 0); break; case'hour': date.setMinutes(0, 0, 0); break; case'year': date.setMonth(0); case'month': date.setDate(1); case'day': date.setHours(0, 0, 0, 0); break; case'week': dayMonth = date.getDate(); if (date.getDay() !== 0) dayMonth += 7 - date.getDay(); date.setDate(dayMonth); date.setHours(0, 0, 0, 0); break; case'quarter': firstQuarterMonth = DX.formatHelper.getFirstQuarterMonth(date.getMonth()); if (date.getMonth() !== firstQuarterMonth) date.setMonth(firstQuarterMonth); date.setDate(1); date.setHours(0, 0, 0, 0); break } }; var getDatesDifferences = function(date1, date2) { var differences, counter = 0; differences = { year: date1.getFullYear() !== date2.getFullYear(), month: date1.getMonth() !== date2.getMonth(), day: date1.getDate() !== date2.getDate(), hour: date1.getHours() !== date2.getHours(), minute: date1.getMinutes() !== date2.getMinutes(), second: date1.getSeconds() !== date2.getSeconds() }; $.each(differences, function(key, value) { if (value) counter++ }); differences.count = counter; return differences }; var addInterval = function(value, interval, isNegative) { var result = null, intervalObject; if (isDate(value)) { intervalObject = isString(interval) ? getDateIntervalByString(interval.toLowerCase()) : interval; result = new Date(value.getTime()); if (intervalObject.years) result.setFullYear(addSubValues(result.getFullYear(), intervalObject.years, isNegative)); if (intervalObject.quarters) result.setMonth(addSubValues(result.getMonth(), 3 * intervalObject.quarters, isNegative)); if (intervalObject.months) result.setMonth(addSubValues(result.getMonth(), intervalObject.months, isNegative)); if (intervalObject.weeks) result.setDate(addSubValues(result.getDate(), 7 * intervalObject.weeks, isNegative)); if (intervalObject.days) result.setDate(addSubValues(result.getDate(), intervalObject.days, isNegative)); if (intervalObject.hours) result.setHours(addSubValues(result.getHours(), intervalObject.hours, isNegative)); if (intervalObject.minutes) result.setMinutes(addSubValues(result.getMinutes(), intervalObject.minutes, isNegative)); if (intervalObject.seconds) result.setSeconds(addSubValues(result.getSeconds(), intervalObject.seconds, isNegative)); if (intervalObject.milliseconds) result.setMilliseconds(addSubValues(value.getMilliseconds(), intervalObject.milliseconds, isNegative)) } else result = addSubValues(value, interval, isNegative); return result }; var getDateIntervalByString = function(intervalString) { var result = {}; switch (intervalString) { case'year': result.years = 1; break; case'month': result.months = 1; break; case'quarter': result.months = 3; break; case'week': result.days = 7; break; case'day': result.days = 1; break; case'hour': result.hours = 1; break; case'minute': result.minutes = 1; break; case'second': result.seconds = 1; break; case'millisecond': result.milliseconds = 1; break } return result }; var sameMonthAndYear = function(date1, date2) { return date1 && date2 && date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() }; var getFirstMonthDate = function(date) { return new Date(date.getFullYear(), date.getMonth(), 1) }; var dateInRange = function(date, min, max) { return normalizeDate(date, min, max) === date }; var normalizeDate = function(date, min, max) { var normalizedDate = date; if (isDefined(min) && date < min) normalizedDate = min; if (isDefined(max) && date > max) normalizedDate = max; return normalizedDate }; var getPower = function(value) { return value.toExponential().split("e")[1] }; $.extend(DX.utils, { dateUnitIntervals: dateUnitIntervals, parseIso8601Date: parseISO8601, formatIso8601Date: formatISO8601, convertMillisecondsToDateUnits: convertMillisecondsToDateUnits, convertDateTickIntervalToMilliseconds: convertDateTickIntervalToMilliseconds, convertDateUnitToMilliseconds: convertDateUnitToMilliseconds, getDateUnitInterval: getDateUnitInterval, getDatesDifferences: getDatesDifferences, correctDateWithUnitBeginning: correctDateWithUnitBeginning, addInterval: addInterval, getDateIntervalByString: getDateIntervalByString, sameMonthAndYear: sameMonthAndYear, getFirstMonthDate: getFirstMonthDate, dateInRange: dateInRange, normalizeDate: normalizeDate, getPower: getPower }) })(jQuery, DevExpress); /*! Module core, file utils.dom.js */ (function($, DX, undefined) { var IOS_APP_BAR_HEIGHT = "20px"; var timeRedrawOnResize = 100; var createResizeHandler = function(callback) { var $window = $(window), timeout; var debug_callback = arguments[1]; var handler = function() { var width = $window.width(), height = $window.height(); clearTimeout(timeout); timeout = setTimeout(function() { $window.width() === width && $window.height() === height && callback(); debug_callback && debug_callback() }, timeRedrawOnResize) }; handler.stop = function() { clearTimeout(timeout); return this }; return handler }; var windowResizeCallbacks = function() { var prevSize, callbacks = $.Callbacks(), jqWindow = $(window), resizeEventHandlerAttached = false, originalCallbacksAdd = callbacks.add, originalCallbacksRemove = callbacks.remove; var formatSize = function() { return [jqWindow.width(), jqWindow.height()].join() }; var handleResize = function() { var now = formatSize(); if (now === prevSize) return; prevSize = now; setTimeout(callbacks.fire) }; prevSize = formatSize(); callbacks.add = function() { var result = originalCallbacksAdd.apply(callbacks, arguments); if (!resizeEventHandlerAttached && callbacks.has()) { jqWindow.on("resize", handleResize); resizeEventHandlerAttached = true } return result }; callbacks.remove = function() { var result = originalCallbacksRemove.apply(callbacks, arguments); if (!callbacks.has() && resizeEventHandlerAttached) { jqWindow.off("resize", handleResize); resizeEventHandlerAttached = false } return result }; return callbacks }(); var resetActiveElement = function() { var activeElement = document.activeElement; if (activeElement && activeElement !== document.body && activeElement.blur) activeElement.blur() }; var createMarkupFromString = function(str) { var tempElement = $("
"); if (window.WinJS) WinJS.Utilities.setInnerHTMLUnsafe(tempElement.get(0), str); else tempElement.append(str); return tempElement.contents() }; var initMobileViewport = function(options) { options = $.extend({}, options); var device = DX.devices.current(); var realDevice = DX.devices.real(); var allowZoom = options.allowZoom, allowPan = options.allowPan, allowSelection = "allowSelection" in options ? options.allowSelection : device.platform == "desktop"; DX.overlayTargetContainer(".dx-viewport"); var metaSelector = "meta[name=viewport]"; if (!$(metaSelector).length) $("").attr("name", "viewport").appendTo("head"); var metaVerbs = ["width=device-width"], msTouchVerbs = []; if (allowZoom) msTouchVerbs.push("pinch-zoom"); else metaVerbs.push("initial-scale=1.0", "maximum-scale=1.0, user-scalable=no"); if (allowPan) msTouchVerbs.push("pan-x", "pan-y"); if (!allowPan && !allowZoom) $("html, body").css({ "-ms-content-zooming": "none", "-ms-user-select": "none", overflow: "hidden" }); else $("html").css("-ms-overflow-style", "-ms-autohiding-scrollbar"); if (!allowSelection) { if (realDevice.ios) $(document).on("selectstart", function() { return false }); $(".dx-viewport").css("user-select", "none") } $(metaSelector).attr("content", metaVerbs.join()); $("html").css("-ms-touch-action", msTouchVerbs.join(" ") || "none"); if (DX.support.touch) $(document).off(".dxInitMobileViewport").on("touchmove.dxInitMobileViewport", function(e) { var count = e.originalEvent.touches.length, zoomDisabled = !allowZoom && count > 1, panDisabled = !allowPan && count === 1 && !e.isScrollingEvent; if (zoomDisabled || panDisabled) e.preventDefault() }); realDevice = DX.devices.real(); if (realDevice.ios) { var isPhoneGap = document.location.protocol === "file:"; if (!isPhoneGap) windowResizeCallbacks.add(function() { var windowWidth = $(window).width(); $("body").width(windowWidth) }); else if (realDevice.version[0] > 6) { $(".dx-viewport").css("position", "relative"); $("body").css({"box-sizing": "border-box"}); $("body").css("padding-top", IOS_APP_BAR_HEIGHT); if (realDevice.version[0] === 7 && realDevice.version[1] < 1) { var setDeviceHeight = function() { var deviceHeight = "height=device-" + (Math.abs(window.orientation) === 90 ? "width" : "height"); $(metaSelector).attr("content", metaVerbs.join() + "," + deviceHeight) }; $(window).on("orientationchange", setDeviceHeight); setDeviceHeight() } } } }; var triggerVisibilityChangeEvent = function(event) { return function(element) { $(element || "body").find(".dx-visibility-change-handler").each(function() { $(this).triggerHandler(event) }) } }; $.extend(DX.utils, { createResizeHandler: createResizeHandler, windowResizeCallbacks: windowResizeCallbacks, resetActiveElement: resetActiveElement, createMarkupFromString: createMarkupFromString, triggerShownEvent: triggerVisibilityChangeEvent("dxshown"), triggerHidingEvent: triggerVisibilityChangeEvent("dxhiding"), initMobileViewport: initMobileViewport }); DX.utils.__timeRedrawOnResize = timeRedrawOnResize })(jQuery, DevExpress); /*! Module core, file utils.graphics.js */ (function($, DX, undefined) { var isFunction = DX.utils.isFunction, iDevice = /iphone|ipad/.test(navigator.userAgent.toLowerCase()); var processSeriesTemplate = function(seriesTemplate, items) { var customizeSeries = isFunction(seriesTemplate.customizeSeries) ? seriesTemplate.customizeSeries : $.noop, nameField = seriesTemplate.nameField || 'series', generatedSeries = {}, seriesOrder = [], series; for (var i = 0, length = items.length; i < length; i++) { var data = items[i]; if (nameField in data) { series = generatedSeries[data[nameField]]; if (!series) { series = generatedSeries[data[nameField]] = { name: data[nameField], data: [] }; seriesOrder.push(series.name) } series.data.push(data) } } return $.map(seriesOrder, function(orderedName) { var group = generatedSeries[orderedName], seriesOptions = customizeSeries.call(null, group.name); return $.extend(group, seriesOptions) }) }; var getNextDefsSvgId = function() { var numDefsSvgElements = 1; return function() { return 'DevExpress_' + numDefsSvgElements++ } }(); var getRootOffset = function(renderer) { var node, result = { left: 0, top: 0 }, pointTransform, root = renderer.getRoot(); if (root) { node = root.element; if (node.getScreenCTM && !iDevice) { var ctm = node.getScreenCTM(); if (ctm) { pointTransform = node.createSVGPoint().matrixTransform(ctm); result.left = pointTransform.x + (document.body.scrollLeft || document.documentElement.scrollLeft); result.top = pointTransform.y + (document.body.scrollTop || document.documentElement.scrollTop) } else { result.left = document.body.scrollLeft || document.documentElement.scrollLeft; result.top = document.body.scrollTop || document.documentElement.scrollTop } } else result = $(node).offset() } return result }; $.extend(DX.utils, { processSeriesTemplate: processSeriesTemplate, getNextDefsSvgId: getNextDefsSvgId, getRootOffset: getRootOffset }) })(jQuery, DevExpress); /*! Module core, file utils.arrays.js */ (function($, DX, undefined) { var wrapToArray = function(entity) { return $.isArray(entity) ? entity : [entity] }; var removeDublicates = function(from, what) { if (!$.isArray(from) || from.length === 0) return []; if (!$.isArray(what) || what.length === 0) return from.slice(); var result = []; $.each(from, function(_, value) { var bIndex = $.inArray(value, what); if (bIndex === -1) result.push(value) }); return result }; $.extend(DX.utils, { wrapToArray: wrapToArray, removeDublicates: removeDublicates }) })(jQuery, DevExpress); /*! Module core, file devices.js */ (function($, DX, undefined) { var KNOWN_UA_TABLE = { iPhone: "iPhone", iPhone5: "iPhone 5", iPad: "iPad", iPadMini: "iPad Mini", androidPhone: "Android Mobile", androidTablet: "Android", win8: "MSAppHost", win8Phone: "Windows Phone 8", msSurface: "MSIE ARM Tablet PC", desktop: "desktop", tizen: "Tizen Mobile" }; var DEFAULT_DEVICE = { deviceType: "", platform: "", version: [], phone: false, tablet: false, android: false, ios: false, win8: false, tizen: false, generic: false }; var GENERIC_DEVICE = $.extend(DEFAULT_DEVICE, { platform: "generic", deviceType: "desktop", generic: true }); var uaParsers = { win8: function(userAgent) { var isPhone = /windows phone/i.test(userAgent), isTablet = !isPhone && /arm(.*)trident/i.test(userAgent), isDesktop = !isPhone && !isTablet && /msapphost/i.test(userAgent); if (!(isPhone || isTablet || isDesktop)) return; var matches = userAgent.match(/windows phone (\d+).(\d+)/i) || userAgent.match(/windows nt (\d+).(\d+)/i), version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10)] : []; return { deviceType: isPhone ? "phone" : isTablet ? "tablet" : "desktop", platform: "win8", version: version } }, ios: function(userAgent) { if (!/ip(hone|od|ad)/i.test(userAgent)) return; var isPhone = /ip(hone|od)/i.test(userAgent); var matches = userAgent.match(/os (\d+)_(\d+)_?(\d+)?/i); var version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : []; return { deviceType: isPhone ? "phone" : "tablet", platform: "ios", version: version } }, android: function(userAgent) { if (!/android|htc_|silk/i.test(userAgent)) return; var isPhone = /mobile/i.test(userAgent); var matches = userAgent.match(/android (\d+)\.(\d+)\.?(\d+)?/i); var version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : []; return { deviceType: isPhone ? "phone" : "tablet", platform: "android", version: version } }, tizen: function(userAgent) { if (!/tizen/i.test(userAgent)) return; var isPhone = /mobile/i.test(userAgent); var matches = userAgent.match(/tizen (\d+)\.(\d+)/i); var version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10)] : []; return { deviceType: isPhone ? "phone" : "tablet", platform: "tizen", version: version } } }; DX.Devices = DX.Class.inherit({ ctor: function(options) { this._window = options && options.window || window; this._realDevice = this._getDevice(); this._currentDevice = undefined; this._currentOrientation = undefined; this.orientationChanged = $.Callbacks(); this._recalculateOrientation(); DX.utils.windowResizeCallbacks.add($.proxy(this._recalculateOrientation, this)) }, current: function(deviceOrName) { if (deviceOrName) { this._currentDevice = this._getDevice(deviceOrName); DX.ui.themes.init({_autoInit: true}) } else { if (!this._currentDevice) { deviceOrName = undefined; try { deviceOrName = this._getDeviceOrNameFromWindowScope() } catch(e) { deviceOrName = this._getDeviceNameFromSessionStorage() } finally { if (!deviceOrName) deviceOrName = this._getDeviceNameFromSessionStorage() } this._currentDevice = this._getDevice(deviceOrName) } return this._currentDevice } }, real: function() { var forceDevice = arguments[0]; if ($.isPlainObject(forceDevice)) { $.extend(this._realDevice, forceDevice); return } return $.extend({}, this._realDevice) }, orientation: function() { return this._currentOrientation }, isRippleEmulator: function() { return !!this._window.tinyHippos }, attachCssClasses: function(element, device) { var realDevice = this._realDevice, $element = $(element); device = device || this.current(); if (device.deviceType) $element.addClass("dx-device-" + device.deviceType); $element.addClass("dx-device-" + realDevice.platform); if (realDevice.version && realDevice.version.length) $element.addClass("dx-device-" + realDevice.platform + "-" + realDevice.version[0]); if (DX.devices.isSimulator()) $element.addClass("dx-simulator"); if (DX.rtlEnabled) $element.addClass("dx-rtl") }, isSimulator: function() { try { return this._isSimulator || this._window.top !== this._window.self && this._window.top["dx-force-device"] || this.isRippleEmulator() } catch(e) { return false } }, forceSimulator: function() { this._isSimulator = true }, _getDevice: function(deviceName) { if (deviceName === "genericPhone") deviceName = { deviceType: "phone", platform: "generic", generic: true }; if ($.isPlainObject(deviceName)) return this._fromConfig(deviceName); else { var ua; if (deviceName) { ua = KNOWN_UA_TABLE[deviceName]; if (!ua) throw Error("Unknown device"); } else ua = navigator.userAgent; return this._fromUA(ua) } }, _getDeviceOrNameFromWindowScope: function() { var result; if (this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"]) result = this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"]; return result }, _getDeviceNameFromSessionStorage: function() { return this._window.sessionStorage && (sessionStorage.getItem("dx-force-device") || sessionStorage.getItem("dx-simulator-device")) }, _fromConfig: function(config) { var shortcuts = { phone: config.deviceType === "phone", tablet: config.deviceType === "tablet", android: config.platform === "android", ios: config.platform === "ios", win8: config.platform === "win8", tizen: config.platform === "tizen", generic: config.platform === "generic" }; return $.extend({}, DEFAULT_DEVICE, this._currentDevice, shortcuts, config) }, _fromUA: function(ua) { var config; $.each(uaParsers, function(platform, parser) { config = parser(ua); return !config }); if (config) return this._fromConfig(config); return GENERIC_DEVICE }, _changeOrientation: function() { var $window = $(this._window), orientation = $window.height() > $window.width() ? "portrait" : "landscape"; if (this._currentOrientation === orientation) return; this._currentOrientation = orientation; this.orientationChanged.fire({orientation: orientation}) }, _recalculateOrientation: function() { var windowWidth = $(this._window).width(); if (this._currentWidth === windowWidth) return; this._currentWidth = windowWidth; this._changeOrientation() } }); DX.devices = new DX.Devices })(jQuery, DevExpress); /*! Module core, file browser.js */ (function($, DX, global, undefined) { var webkitRegExp = /(webkit)[ \/]([\w.]+)/, operaRegExp = /(opera)(?:.*version)?[ \/]([\w.]+)/, ieRegExp = /(msie) (\d{1,2}\.\d)/, ie11RegExp = /(trident).*rv:(\d{1,2}\.\d)/, mozillaRegExp = /(mozilla)(?:.*? rv:([\w.]+))?/; var ua = navigator.userAgent.toLowerCase(); var browser = function() { var result = {}, matches = webkitRegExp.exec(ua) || operaRegExp.exec(ua) || ieRegExp.exec(ua) || ie11RegExp.exec(ua) || ua.indexOf("compatible") < 0 && mozillaRegExp.exec(ua) || [], browserName = matches[1], browserVersion = matches[2]; if (browserName === "trident") browserName = "msie"; if (browserName) { result[browserName] = true; result.version = browserVersion } return result }(); DX.browser = browser })(jQuery, DevExpress, this); /*! Module core, file support.js */ (function($, DX, window) { var cssPrefixes = ["", "Webkit", "Moz", "O", "ms"], styles = document.createElement("dx").style; var transitionEndEventNames = { WebkitTransition: 'webkitTransitionEnd', MozTransition: 'transitionend', OTransition: 'oTransitionEnd', msTransition: 'MsTransitionEnd', transition: 'transitionend' }; var styleProp = function(prop) { prop = DX.inflector.camelize(prop, true); for (var i = 0, cssPrefixesCount = cssPrefixes.length; i < cssPrefixesCount; i++) { var specific = cssPrefixes[i] + prop; if (specific in styles) return specific } }; var supportProp = function(prop) { return !!styleProp(prop) }; var isNativeScrollingSupported = function(device) { var realDevice = DX.devices.real(), realPlatform = realDevice.platform, realVersion = realDevice.version, isObsoleteAndroid = realVersion && realVersion[0] < 4 && realPlatform === "android", isNativeScrollDevice = !isObsoleteAndroid && $.inArray(realPlatform, ["ios", "android", "win8"]) > -1; return isNativeScrollDevice }; DX.support = { touch: "ontouchstart" in window || !!window.navigator.msMaxTouchPoints, pointer: window.navigator.pointerEnabled || window.navigator.msPointerEnabled, transform3d: supportProp("transform"), transition: supportProp("transition"), transitionEndEventName: transitionEndEventNames[styleProp("transition")], animation: supportProp("animation"), nativeScrolling: isNativeScrollingSupported(), winJS: "WinJS" in window, styleProp: styleProp, supportProp: supportProp, hasKo: !!window.ko, hasNg: !window.ko && !!window.angular, inputType: function(type) { if (type === "text") return true; var input = document.createElement("input"); try { input.setAttribute("type", type); input.value = "wrongValue"; return !input.value } catch(e) { return false } } } })(jQuery, DevExpress, this); /*! Module core, file position.js */ (function($, DX, undefined) { var horzRe = /left|right/, vertRe = /top|bottom/, collisionRe = /fit|flip|none/; var normalizeAlign = function(raw) { var result = { h: "center", v: "center" }; var pair = DX.utils.splitPair(raw); if (pair) $.each(pair, function() { var w = String(this).toLowerCase(); if (horzRe.test(w)) result.h = w; else if (vertRe.test(w)) result.v = w }); return result }; var normalizeOffset = function(raw) { var values = DX.utils.stringPairToObject(raw); return { h: values.x, v: values.y } }; var normalizeCollision = function(raw) { var pair = DX.utils.splitPair(raw), h = String(pair && pair[0]).toLowerCase(), v = String(pair && pair[1]).toLowerCase(); if (!collisionRe.test(h)) h = "none"; if (!collisionRe.test(v)) v = h; return { h: h, v: v } }; var getAlignFactor = function(align) { switch (align) { case"center": return 0.5; case"right": case"bottom": return 1; default: return 0 } }; var inverseAlign = function(align) { switch (align) { case"left": return "right"; case"right": return "left"; case"top": return "bottom"; case"bottom": return "top"; default: return align } }; var calculateOversize = function(data, bounds) { var oversize = 0; if (data.myLocation < bounds.min) oversize += bounds.min - data.myLocation; if (data.myLocation > bounds.max) oversize += data.myLocation - bounds.max; return oversize }; var initMyLocation = function(data) { data.myLocation = data.atLocation + getAlignFactor(data.atAlign) * data.atSize - getAlignFactor(data.myAlign) * data.mySize + data.offset }; var decolliders = { fit: function(data, bounds) { var result = false; if (data.myLocation > bounds.max) { data.myLocation = bounds.max; result = true } if (data.myLocation < bounds.min) { data.myLocation = bounds.min; result = true } return result }, flip: function(data, bounds) { if (data.myAlign === "center" && data.atAlign === "center") return false; if (data.myLocation < bounds.min || data.myLocation > bounds.max) { var inverseData = $.extend({}, data, { myAlign: inverseAlign(data.myAlign), atAlign: inverseAlign(data.atAlign), offset: -data.offset }); initMyLocation(inverseData); inverseData.oversize = calculateOversize(inverseData, bounds); if (inverseData.myLocation >= bounds.min && inverseData.myLocation <= bounds.max || inverseData.myLocation > data.myLocation || inverseData.oversize < data.oversize) { data.myLocation = inverseData.myLocation; data.oversize = inverseData.oversize; return true } } return false } }; var scrollbarWidth; var defaultPositionResult = { h: { location: 0, flip: false, fit: false, oversize: 0 }, v: { location: 0, flip: false, fit: false, oversize: 0 } }; var calculatePosition = function(what, options) { var $what = $(what), currentOffset = $what.offset(), result = $.extend(true, {}, defaultPositionResult, { h: {location: currentOffset.left}, v: {location: currentOffset.top} }); if (!options) return result; var my = normalizeAlign(options.my), at = normalizeAlign(options.at), of = options.of || window, offset = normalizeOffset(options.offset), collision = normalizeCollision(options.collision), boundaryOffset = normalizeOffset(options.boundaryOffset); var h = { mySize: $what.outerWidth(), myAlign: my.h, atAlign: at.h, offset: offset.h, collision: collision.h, boundaryOffset: boundaryOffset.h }; var v = { mySize: $what.outerHeight(), myAlign: my.v, atAlign: at.v, offset: offset.v, collision: collision.v, boundaryOffset: boundaryOffset.v }; if (of.preventDefault) { h.atLocation = of.pageX; v.atLocation = of.pageY; h.atSize = 0; v.atSize = 0 } else { of = $(of); if ($.isWindow(of[0])) { h.atLocation = of.scrollLeft(); v.atLocation = of.scrollTop(); h.atSize = of.width(); v.atSize = of.height() } else if (of[0].nodeType === 9) { h.atLocation = 0; v.atLocation = 0; h.atSize = of.width(); v.atSize = of.height() } else { var o = of.offset(); h.atLocation = o.left; v.atLocation = o.top; h.atSize = of.outerWidth(); v.atSize = of.outerHeight() } } initMyLocation(h); initMyLocation(v); var bounds = function() { var win = $(window), windowWidth = win.width(), windowHeight = win.height(), left = win.scrollLeft(), top = win.scrollTop(), hScrollbar = document.width > document.documentElement.clientWidth, vScrollbar = document.height > document.documentElement.clientHeight, hZoomLevel = DX.support.touch ? document.documentElement.clientWidth / (vScrollbar ? windowWidth - scrollbarWidth : windowWidth) : 1, vZoomLevel = DX.support.touch ? document.documentElement.clientHeight / (hScrollbar ? windowHeight - scrollbarWidth : windowHeight) : 1; if (scrollbarWidth === undefined) scrollbarWidth = calculateScrollbarWidth(); return { h: { min: left + h.boundaryOffset, max: left + windowWidth / hZoomLevel - h.mySize - h.boundaryOffset }, v: { min: top + v.boundaryOffset, max: top + windowHeight / vZoomLevel - v.mySize - v.boundaryOffset } } }(); h.oversize = calculateOversize(h, bounds.h); v.oversize = calculateOversize(v, bounds.v); if (decolliders[h.collision]) result.h[h.collision] = decolliders[h.collision](h, bounds.h); if (decolliders[v.collision]) result.v[v.collision] = decolliders[v.collision](v, bounds.v); $.extend(true, result, { h: { location: Math.round(h.myLocation), oversize: Math.round(h.oversize) }, v: { location: Math.round(v.myLocation), oversize: Math.round(v.oversize) } }); return result }; var position = function(what, options) { var $what = $(what); if (!options) return $what.offset(); DX.translator.resetPosition($what); var offset = $what.offset(), targetPosition = options.h && options.v ? options : calculatePosition($what, options); DX.translator.move($what, { left: Math.round(targetPosition.h.location - offset.left), top: Math.round(targetPosition.v.location - offset.top) }); return targetPosition }; $.extend(DX, { calculatePosition: calculatePosition, position: position, inverseAlign: inverseAlign }); var calculateScrollbarWidth = function() { var $scrollDiv = $("
").css({ width: 100, height: 100, overflow: "scroll", position: "absolute", top: -9999 }).appendTo($("body")), result = $scrollDiv.get(0).offsetWidth - $scrollDiv.get(0).clientWidth; $scrollDiv.remove(); return result } })(jQuery, DevExpress); /*! Module core, file action.js */ (function($, DX, undefined) { var actionExecutors = {}; var registerExecutor = function(name, executor) { if ($.isPlainObject(name)) { $.each(name, registerExecutor); return } actionExecutors[name] = executor }; var unregisterExecutor = function(name) { var args = $.makeArray(arguments); $.each(args, function() { delete actionExecutors[this] }) }; registerExecutor({ func: {execute: function(e) { if ($.isFunction(e.action)) { e.result = e.action.apply(e.context, e.args); e.handled = true } }}, url: {execute: function(e) { if (typeof e.action === "string" && e.action.charAt(0) !== "#") document.location = e.action }}, hash: {execute: function(e) { if (typeof e.action === "string" && e.action.charAt(0) === "#") document.location.hash = e.action }} }); var Action = DX.Class.inherit({ ctor: function(action, config) { config = config || {}; this._action = action || $.noop; this._context = config.context || window; this._beforeExecute = config.beforeExecute || $.noop; this._afterExecute = config.afterExecute || $.noop; this._component = config.component; this._excludeValidators = config.excludeValidators; this._validatingTargetName = config.validatingTargetName }, execute: function() { var e = { action: this._action, args: Array.prototype.slice.call(arguments), context: this._context, component: this._component, validatingTargetName: this._validatingTargetName, cancel: false, handled: false }; if (!this._validateAction(e)) return; this._beforeExecute.call(this._context, e); if (e.cancel) return; var result = this._executeAction(e); this._afterExecute.call(this._context, e); return result }, _validateAction: function(e) { var excludeValidators = this._excludeValidators; $.each(actionExecutors, function(name, executor) { if (excludeValidators && $.inArray(name, excludeValidators) > -1) return; if (executor.validate) executor.validate(e); if (e.cancel) return false }); return !e.cancel }, _executeAction: function(e) { var result; $.each(actionExecutors, function(index, executor) { if (executor.execute) executor.execute(e); if (e.handled) { result = e.result; return false } }); return result } }); $.extend(DX, { registerActionExecutor: registerExecutor, unregisterActionExecutor: unregisterExecutor, Action: Action }); DX.__internals = {actionExecutors: actionExecutors} })(jQuery, DevExpress); /*! Module core, file translator.js */ (function($, DX, undefined) { var support = DX.support, TRANSLATOR_DATA_KEY = "dxTranslator", TRANSFORM_MATRIX_REGEX = /matrix(3d)?\((.+?)\)/, TRANSLATE_REGEX = /translate(?:3d)?\((.+?)\)/; var locate = function($element) { var result, position, finalPosition; if (support.transform3d) { var translate = getTranslate($element); result = { left: translate.x, top: translate.y } } else { var originalTop = $element.css("top"), originalLeft = $element.css("left"); position = $element.position(); $element.css({ transform: "none", top: 0, left: 0 }); clearCache($element); finalPosition = $element.position(); result = { left: position.left - finalPosition.left || parseInt(originalLeft) || 0, top: position.top - finalPosition.top || parseInt(originalTop) || 0 }; $element.css({ top: originalTop, left: originalLeft }) } return result }; var move = function($element, position) { if (!support.transform3d) { $element.css(position); return } var translate = getTranslate($element), left = position.left, top = position.top; if (left !== undefined) translate.x = left || 0; if (top !== undefined) translate.y = top || 0; $element.css({transform: getTranslateCss(translate)}); if (isPersentValue(left) || isPersentValue(top)) clearCache($element) }; var isPersentValue = function(value) { return $.type(value) === "string" && value[value.length - 1] === "%" }; var getTranslate = function($element) { var result = $element.data(TRANSLATOR_DATA_KEY); if (!result) { var transformValue = $element.css("transform") || getTranslateCss({ x: 0, y: 0 }), matrix = transformValue.match(TRANSFORM_MATRIX_REGEX), is3D = matrix && matrix[1]; if (matrix) { matrix = matrix[2].split(","); if (is3D === "3d") matrix = matrix.slice(12, 15); else { matrix.push(0); matrix = matrix.slice(4, 7) } } else matrix = [0, 0, 0]; result = { x: parseFloat(matrix[0]), y: parseFloat(matrix[1]), z: parseFloat(matrix[2]) }; cacheTranslate($element, result) } return result }; var cacheTranslate = function($element, translate) { $element.data(TRANSLATOR_DATA_KEY, translate) }; var clearCache = function($element) { $element.removeData(TRANSLATOR_DATA_KEY) }; var resetPosition = function($element) { $element.css({ left: 0, top: 0, transform: "none" }); clearCache($element) }; var parseTranslate = function(translateString) { var result = translateString.match(TRANSLATE_REGEX); if (!result || !result[1]) return; result = result[1].split(","); result = { x: parseFloat(result[0]), y: parseFloat(result[1]), z: parseFloat(result[2]) }; return result }; var getTranslateCss = function(translate) { translate.x = translate.x || 0; translate.y = translate.y || 0; var xValueString = isPersentValue(translate.x) ? translate.x : translate.x + "px"; var yValueString = isPersentValue(translate.y) ? translate.y : translate.y + "px"; return "translate(" + xValueString + ", " + yValueString + ")" }; DX.translator = { move: move, locate: locate, clearCache: clearCache, parseTranslate: parseTranslate, getTranslate: getTranslate, getTranslateCss: getTranslateCss, resetPosition: resetPosition } })(jQuery, DevExpress); /*! Module core, file animationFrame.js */ (function($, DX, undefined) { var FRAME_ANIMATION_STEP_TIME = 1000 / 60, requestAnimationFrame = function(callback, element) { return this.setTimeout(callback, FRAME_ANIMATION_STEP_TIME) }, cancelAnimationFrame = function(requestID) { return this.clearTimeout(requestID) }, nativeRequestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame, nativeCancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame; if (nativeRequestAnimationFrame && nativeCancelAnimationFrame) { requestAnimationFrame = nativeRequestAnimationFrame; cancelAnimationFrame = nativeCancelAnimationFrame } if (nativeRequestAnimationFrame && !nativeCancelAnimationFrame) { var cancelledRequests = {}; requestAnimationFrame = function(callback) { var requestId = nativeRequestAnimationFrame.call(window, function() { try { if (requestId in cancelledRequests) return; callback.apply(this, arguments) } finally { delete cancelledRequests[requestId] } }); return requestId }; cancelAnimationFrame = function(requestId) { cancelledRequests[requestId] = true } } requestAnimationFrame = $.proxy(requestAnimationFrame, window); cancelAnimationFrame = $.proxy(cancelAnimationFrame, window); $.extend(DX, { requestAnimationFrame: requestAnimationFrame, cancelAnimationFrame: cancelAnimationFrame }) })(jQuery, DevExpress); /*! Module core, file animator.js */ (function($, DX, undefined) { DX.Animator = DX.Class.inherit({ ctor: function() { this._finished = true; this._stopped = false }, start: function() { this._stopped = false; this._finished = false; this._stepCore() }, stop: function() { this._stopped = true }, _stepCore: function() { if (this._isStopped()) { this._stop(); return } if (this._isFinished()) { this._finished = true; this._complete(); return } this._step(); DX.requestAnimationFrame.call(window, $.proxy(this._stepCore, this)) }, _step: DX.abstract, _isFinished: $.noop, _stop: $.noop, _complete: $.noop, _isStopped: function() { return this._stopped }, inProgress: function() { return !(this._stopped || this._finished) } }) })(jQuery, DevExpress); /*! Module core, file fx.js */ (function($, DX, undefined) { var translator = DX.translator, support = DX.support, transitionEndEventName = support.transitionEndEventName + ".dxFX"; var CSS_TRANSITION_EASING_REGEX = /cubic-bezier\((\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\)/, RELATIVE_VALUE_REGEX = /^([+-])=(.*)/i, ANIM_DATA_KEY = "dxAnimData", ANIM_QUEUE_KEY = "dxAnimQueue", TRANSFORM_PROP = "transform"; var TransitionAnimationStrategy = { animate: function($element, config) { var that = this, deferred = $.Deferred(); config.transitionAnimation = {finish: function() { that._cleanup($element, config); deferred.resolveWith($element, [config, $element]) }}; this._startAnimation($element, config); this._completeAnimationCallback($element, config).done(function() { config.transitionAnimation.finish() }); if (!config.duration) config.transitionAnimation.finish(); return deferred.promise() }, _completeAnimationCallback: function($element, config) { var startTime = $.now() + config.delay, deferred = $.Deferred(), transitionEndFired = $.Deferred(), simulatedTransitionEndFired = $.Deferred(); $element.one(transitionEndEventName, function(e) { if ($.now() - startTime >= config.duration) transitionEndFired.reject() }); config.transitionAnimation.simulatedEndEventTimer = setTimeout(function() { simulatedTransitionEndFired.reject() }, config.duration + config.delay); $.when(transitionEndFired, simulatedTransitionEndFired).fail($.proxy(function() { deferred.resolve() }, this)); return deferred.promise() }, _startAnimation: function($element, config) { $element.css("transform"); $element.css({ transitionProperty: "all", transitionDelay: config.delay + "ms", transitionDuration: config.duration + "ms", transitionTimingFunction: config.easing }); setProps($element, config.to) }, _cleanup: function($element, config) { $element.css("transition", "none").off(transitionEndEventName); clearTimeout(config.transitionAnimation.simulatedEndEventTimer) }, stop: function($element, config, jumpToEnd) { if (!config) return; if (jumpToEnd) config.transitionAnimation.finish(); else { $.each(config.to, function(key) { $element.css(key, $element.css(key)) }); this._cleanup($element, config) } } }; var FrameAnimationStrategy = { animate: function($element, config) { var deferred = $.Deferred(), that = this; if (!config) return deferred.reject().promise(); $.each(config.to, function(prop) { if (config.from[prop] === undefined) config.from[prop] = that._normalizeValue($element.css(prop)) }); if (config.to[TRANSFORM_PROP]) { config.from[TRANSFORM_PROP] = that._parseTransform(config.from[TRANSFORM_PROP]); config.to[TRANSFORM_PROP] = that._parseTransform(config.to[TRANSFORM_PROP]) } config.frameAnimation = { to: config.to, from: config.from, currentValue: config.from, easing: convertTransitionTimingFuncToJQueryEasing(config.easing), duration: config.duration, startTime: (new Date).valueOf(), finish: function() { this.currentValue = this.to; this.draw(); deferred.resolve() }, draw: function() { var currentValue = $.extend({}, this.currentValue); if (currentValue[TRANSFORM_PROP]) currentValue[TRANSFORM_PROP] = $.map(currentValue[TRANSFORM_PROP], function(value, prop) { if (prop === "translate") return translator.getTranslateCss(value); else if (prop === "scale") return "scale(" + value + ")"; else if (prop.substr(0, prop.length - 1) === "rotate") return prop + "(" + value + "deg)" }).join(" "); $element.css(currentValue) } }; if (config.delay) { config.frameAnimation.startTime += config.delay; config.frameAnimation.delayTimeout = setTimeout(function() { that._animationStep($element, config) }, config.delay) } else that._animationStep($element, config); return deferred.promise() }, _parseTransform: function(transformString) { var result = {}; $.each(transformString.match(/(\w|\d)+\([^\)]*\)\s*/g), function(i, part) { var translateData = translator.parseTranslate(part), scaleData = part.match(/scale\((.+?)\)/), rotateData = part.match(/(rotate.)\((.+)deg\)/); if (translateData) result.translate = translateData; if (scaleData && scaleData[1]) result.scale = parseFloat(scaleData[1]); if (rotateData && rotateData[1]) result[rotateData[1]] = parseFloat(rotateData[2]) }); return result }, stop: function($element, config, jumpToEnd) { var frameAnimation = config && config.frameAnimation; if (!frameAnimation) return; clearTimeout(frameAnimation.delayTimeout); if (jumpToEnd) frameAnimation.finish(); delete config.frameAnimation }, _animationStep: function($element, config) { var frameAnimation = config && config.frameAnimation; if (!frameAnimation) return; var now = (new Date).valueOf(); if (now >= frameAnimation.startTime + frameAnimation.duration) { frameAnimation.finish(); return } frameAnimation.currentValue = this._calcStepValue(frameAnimation, now - frameAnimation.startTime); frameAnimation.draw(); DX.requestAnimationFrame($.proxy(function() { this._animationStep($element, config) }, this)) }, _calcStepValue: function(frameAnimation, currentDuration) { var calcValueRecursively = function(from, to) { var result = $.isArray(to) ? [] : {}; var calcEasedValue = function(propName) { var x = currentDuration / frameAnimation.duration, t = currentDuration, b = 1 * from[propName], c = to[propName] - from[propName], d = frameAnimation.duration; return $.easing[frameAnimation.easing](x, t, b, c, d) }; $.each(to, function(propName, endPropValue) { if (typeof endPropValue === "string" && parseFloat(endPropValue, 10) === false) return true; result[propName] = typeof endPropValue === "object" ? calcValueRecursively(from[propName], endPropValue) : calcEasedValue(propName) }); return result }; return calcValueRecursively(frameAnimation.from, frameAnimation.to) }, _normalizeValue: function(value) { var numericValue = parseFloat(value, 10); if (numericValue === false) return value; return numericValue } }; var animationStrategies = { transition: support.transition ? TransitionAnimationStrategy : FrameAnimationStrategy, frame: FrameAnimationStrategy }; var getAnimationStrategy = function(config) { return animationStrategies[config && config.strategy || "transition"] }; var TransitionTimingFuncMap = { linear: "cubic-bezier(0, 0, 1, 1)", ease: "cubic-bezier(0.25, 0.1, 0.25, 1)", "ease-in": "cubic-bezier(0.42, 0, 1, 1)", "ease-out": "cubic-bezier(0, 0, 0.58, 1)", "ease-in-out": "cubic-bezier(0.42, 0, 0.58, 1)" }; var convertTransitionTimingFuncToJQueryEasing = function(cssTransitionEasing) { cssTransitionEasing = TransitionTimingFuncMap[cssTransitionEasing] || cssTransitionEasing; var bezCoeffs = cssTransitionEasing.match(CSS_TRANSITION_EASING_REGEX); if (!bezCoeffs) return "linear"; bezCoeffs = bezCoeffs.slice(1, 5); $.each(bezCoeffs, function(index, value) { bezCoeffs[index] = parseFloat(value) }); var easingName = "cubicbezier_" + bezCoeffs.join("_").replace(/\./g, "p"); if (!$.isFunction($.easing[easingName])) { var polynomBezier = function(x1, y1, x2, y2) { var Cx = 3 * x1, Bx = 3 * (x2 - x1) - Cx, Ax = 1 - Cx - Bx, Cy = 3 * y1, By = 3 * (y2 - y1) - Cy, Ay = 1 - Cy - By; var bezierX = function(t) { return t * (Cx + t * (Bx + t * Ax)) }; var bezierY = function(t) { return t * (Cy + t * (By + t * Ay)) }; var findXfor = function(t) { var x = t, i = 0, z; while (i < 14) { z = bezierX(x) - t; if (Math.abs(z) < 1e-3) break; x = x - z / derivativeX(x); i++ } return x }; var derivativeX = function(t) { return Cx + t * (2 * Bx + t * 3 * Ax) }; return function(t) { return bezierY(findXfor(t)) } }; $.easing[easingName] = function(x, t, b, c, d) { return c * polynomBezier(bezCoeffs[0], bezCoeffs[1], bezCoeffs[2], bezCoeffs[3])(t / d) + b } } return easingName }; var baseConfigValidator = function(config, animationType) { $.each(["from", "to"], function() { if (!$.isPlainObject(config[this])) throw Error("Animation with the '" + animationType + "' type requires '" + this + "' configuration as an plain object."); }) }; var CustomAnimationConfigurator = {setup: function($element, config){}}; var SlideAnimationConfigurator = { validateConfig: function(config) { baseConfigValidator(config, "slide") }, setup: function($element, config) { var location = translator.locate($element); this._setUpConfig(location, config.from); this._setUpConfig(location, config.to); translator.clearCache($element); if (!support.transform3d && $element.css("position") === "static") $element.css("position", "relative") }, _setUpConfig: function(location, config) { config.left = "left" in config ? config.left : "+=0"; config.top = "top" in config ? config.top : "+=0"; this._initNewPosition(location, config) }, _initNewPosition: function(location, config) { var position = { left: config.left, top: config.top }; delete config.left; delete config.top; var relativeValue = this._getRelativeValue(position.left); if (relativeValue !== undefined) position.left = relativeValue + location.left; else config.left = 0; relativeValue = this._getRelativeValue(position.top); if (relativeValue !== undefined) position.top = relativeValue + location.top; else config.top = 0; var translate = { x: 0, y: 0 }; if (support.transform3d) translate = { x: position.left, y: position.top }; else { config.left = position.left; config.top = position.top } config[TRANSFORM_PROP] = translator.getTranslateCss(translate) }, _getRelativeValue: function(value) { var relativeValue; if (typeof value === "string" && (relativeValue = RELATIVE_VALUE_REGEX.exec(value))) return parseInt(relativeValue[1] + "1") * relativeValue[2] } }; var FadeAnimationConfigurator = {setup: function($element, config) { var from = config.from, fromOpacity = $.isPlainObject(from) ? $element.css("opacity") : String(from), toOpacity = String(config.to); config.from = {opacity: fromOpacity}; config.to = {opacity: toOpacity} }}; var PopAnimationConfigurator = { validateConfig: function(config) { baseConfigValidator(config, "pop") }, setup: function($element, config) { var from = config.from, to = config.to, fromOpacity = "opacity" in from ? from.opacity : $element.css("opacity"), toOpacity = "opacity" in to ? to.opacity : 1, fromScale = "scale" in from ? from.scale : 0, toScale = "scale" in to ? to.scale : 1; config.from = {opacity: fromOpacity}; var translate = translator.getTranslate($element); config.from[TRANSFORM_PROP] = this._getCssTransform(translate, fromScale); config.to = {opacity: toOpacity}; config.to[TRANSFORM_PROP] = this._getCssTransform(translate, toScale) }, _getCssTransform: function(translate, scale) { return translator.getTranslateCss(translate) + "scale(" + scale + ")" } }; var animationConfigurators = { custom: CustomAnimationConfigurator, slide: SlideAnimationConfigurator, fade: FadeAnimationConfigurator, pop: PopAnimationConfigurator }; var getAnimationConfigurator = function(type) { var result = animationConfigurators[type]; if (!result) throw Error("Unknown animation type \"" + type + "\""); return result }; var defaultConfig = { type: "custom", from: {}, to: {}, duration: 400, start: $.noop, complete: $.noop, easing: "ease", delay: 0 }; var animate = function(element, config) { var $element = $(element); config = $.extend(true, {}, defaultConfig, config); if (!$element.length) return $.Deferred().resolve().promise(); var configurator = getAnimationConfigurator(config.type); if ($.isFunction(configurator.validateConfig)) configurator.validateConfig(config); return pushInAnimationQueue($element, config) }; var pushInAnimationQueue = function($element, config) { config.deferred = config.deferred || $.Deferred(); var queueData = getAnimQueueData($element); writeAnimQueueData($element, queueData); queueData.push(config); if (!isAnimating($element)) shiftFromAnimationQueue($element, queueData); return config.deferred.promise() }; var getAnimQueueData = function($element) { return $element.data(ANIM_QUEUE_KEY) || [] }; var writeAnimQueueData = function($element, queueData) { $element.data(ANIM_QUEUE_KEY, queueData) }; var destroyAnimQueueData = function($element) { $element.removeData(ANIM_QUEUE_KEY) }; var isAnimating = function($element) { return !!$element.data(ANIM_DATA_KEY) }; var shiftFromAnimationQueue = function($element, queueData) { var queueData = getAnimQueueData($element); if (!queueData.length) return; var config = queueData.shift(); if (queueData.length === 0) destroyAnimQueueData($element); executeAnimation($element, config).done(function() { shiftFromAnimationQueue($element) }) }; var executeAnimation = function($element, config) { setupPosition($element, config.from); setupPosition($element, config.to); var configurator = getAnimationConfigurator(config.type); configurator.setup($element, config); $element.data(ANIM_DATA_KEY, config); if (DX.fx.off) config.duration = 0; setProps($element, config.from); config.start.apply(this, [$element, config]); return getAnimationStrategy(config).animate($element, config).done(function() { $element.removeData(ANIM_DATA_KEY); config.complete.apply(this, [$element, config]); config.deferred.resolveWith(this, [$element, config]) }) }; var setupPosition = function($element, config) { if (!config.position) return; var position = DX.calculatePosition($element, config.position), offset = $element.offset(), currentPosition = $element.position(); $.extend(config, { left: position.h.location - offset.left + currentPosition.left, top: position.v.location - offset.top + currentPosition.top }); delete config.position }; var setProps = function($element, props) { $.each(props, function(key, value) { $element.css(key, value) }) }; var stop = function(element, jumpToEnd) { var $element = $(element), queueData = getAnimQueueData($element); $.each(queueData, function(_, config) { config.duration = 0 }); var config = $element.data(ANIM_DATA_KEY); getAnimationStrategy(config).stop($element, config, jumpToEnd); $element.removeData(ANIM_DATA_KEY); destroyAnimQueueData($element) }; DX.fx = { off: false, animationTypes: animationConfigurators, animate: animate, isAnimating: isAnimating, stop: stop }; DX.fx.__internals = {convertTransitionTimingFuncToJQueryEasing: convertTransitionTimingFuncToJQueryEasing} })(jQuery, DevExpress); /*! Module core, file endpointSelector.js */ (function($, DX, undefined) { var location = window.location, DXPROXY_HOST = "dxproxy.devexpress.com:8000", WIN_JS = location.protocol === "ms-appx:", IS_DXPROXY = location.host === DXPROXY_HOST, IS_LOCAL = isLocalHostName(location.hostname); function isLocalHostName(url) { return /^(localhost$|127\.)/i.test(url) } var extractProxyAppId = function() { return location.pathname.split("/")[1] }; var formatProxyUrl = function(localUrl) { var urlData = DX.parseUrl(localUrl); if (!isLocalHostName(urlData.hostname)) return localUrl; return "http://" + DXPROXY_HOST + "/" + extractProxyAppId() + "_" + urlData.port + urlData.pathname + urlData.search }; var EndpointSelector = DX.EndpointSelector = function(config) { this.config = config }; EndpointSelector.prototype = {urlFor: function(key) { var bag = this.config[key]; if (!bag) throw Error("Unknown endpoint key"); if (IS_DXPROXY) return formatProxyUrl(bag.local); if (bag.production) if (WIN_JS && !Debug.debuggerEnabled || !WIN_JS && !IS_LOCAL) return bag.production; return bag.local }} })(jQuery, DevExpress); /*! Module core, file formatHelper.js */ (function($, DX, undefined) { var utils = DX.utils; DX.NumericFormat = { currency: 'C', fixedpoint: 'N', exponential: '', percent: 'P', decimal: 'D' }; DX.LargeNumberFormatPostfixes = { 1: 'K', 2: 'M', 3: 'B', 4: 'T' }; var MAX_LARGE_NUMBER_POWER = 4, DECIMAL_BASE = 10; DX.LargeNumberFormatPowers = { largenumber: 'auto', thousands: 1, millions: 2, billions: 3, trillions: 4 }; DX.DateTimeFormat = { longdate: 'D', longtime: 'T', monthandday: 'M', monthandyear: 'Y', quarterandyear: 'qq', shortdate: 'd', shorttime: 't', millisecond: 'fff', second: 'T', minute: 't', hour: 't', day: 'dd', week: 'dd', month: 'MMMM', quarter: 'qq', year: 'yyyy', longdatelongtime: 'D', shortdateshorttime: 'd' }; DX.formatHelper = { defaultQuarterFormat: 'Q{0}', romanDigits: ['I', 'II', 'III', 'IV'], _addFormatSeparator: function(format1, format2) { var separator = ' '; if (format2) return format1 + separator + format2; return format1 }, _getDateTimeFormatPattern: function(dateTimeFormat) { return Globalize.findClosestCulture().calendar.patterns[DX.DateTimeFormat[dateTimeFormat.toLowerCase()]] }, _isDateFormatContains: function(format) { var result = false; $.each(DX.DateTimeFormat, function(key, value) { result = key === format.toLowerCase(); return !result }); return result }, getQuarter: function(month) { return Math.floor(month / 3) }, getFirstQuarterMonth: function(month) { return this.getQuarter(month) * 3 }, _getQuarterString: function(date, format) { var quarter = this.getQuarter(date.getMonth()); switch (format) { case'q': return this.romanDigits[quarter]; case'qq': return utils.stringFormat(this.defaultQuarterFormat, this.romanDigits[quarter]); case'Q': return (quarter + 1).toString(); case'QQ': return utils.stringFormat(this.defaultQuarterFormat, (quarter + 1).toString()) } return '' }, _formatCustomString: function(value, format) { var regExp = /qq|q|QQ|Q/g, quarterFormat, result = '', index = 0; regExp.lastIndex = 0; while (index < format.length) { quarterFormat = regExp.exec(format); if (!quarterFormat || quarterFormat.index > index) result += Globalize.format(value, format.substring(index, quarterFormat ? quarterFormat.index : format.length)); if (quarterFormat) { result += this._getQuarterString(value, quarterFormat[0]); index = quarterFormat.index + quarterFormat[0].length } else index = format.length } return result }, _parseNumberFormatString: function(format) { var formatList, formatObject = {}; if (!format || typeof format !== 'string') return; formatList = format.toLowerCase().split(' '); $.each(formatList, function(index, value) { if (value in DX.NumericFormat) formatObject.formatType = value; else if (value in DX.LargeNumberFormatPowers) formatObject.power = DX.LargeNumberFormatPowers[value] }); if (formatObject.power && !formatObject.formatType) formatObject.formatType = 'fixedpoint'; if (formatObject.formatType) return formatObject }, _calculateNumberPower: function(value, base, minPower, maxPower) { var number = Math.abs(value); var power = 0; if (number > 1) while (number && number >= base && (maxPower === undefined || power < maxPower)) { power++; number = number / base } else if (number > 0 && number < 1) while (number < 1 && (minPower === undefined || power > minPower)) { power--; number = number * base } return power }, _getNumberByPower: function(number, power, base) { var result = number; while (power > 0) { result = result / base; power-- } while (power < 0) { result = result * base; power++ } return result }, _formatNumber: function(value, formatObject, precision) { var powerPostfix; if (formatObject.power === 'auto') formatObject.power = this._calculateNumberPower(value, 1000, 0, MAX_LARGE_NUMBER_POWER); if (formatObject.power) value = this._getNumberByPower(value, formatObject.power, 1000); powerPostfix = DX.LargeNumberFormatPostfixes[formatObject.power] || ''; return this._formatNumberCore(value, formatObject.formatType, precision) + powerPostfix }, _formatNumberExponential: function(value, precision) { var power = this._calculateNumberPower(value, DECIMAL_BASE), number = this._getNumberByPower(value, power, DECIMAL_BASE), powString; precision = precision === undefined ? 1 : precision; if (number.toFixed(precision || 0) >= DECIMAL_BASE) { power++; number = number / DECIMAL_BASE } powString = (power >= 0 ? '+' : '') + power.toString(); return this._formatNumberCore(number, 'fixedpoint', precision) + 'E' + powString }, _formatNumberCore: function(value, format, precision) { if (format === 'exponential') return this._formatNumberExponential(value, precision); else return Globalize.format(value, DX.NumericFormat[format] + (utils.isNumber(precision) ? precision : 0)) }, _formatDate: function(date, format, formatString) { var resultFormat = DX.DateTimeFormat[format.toLowerCase()]; format = format.toLowerCase(); if (format === 'quarterandyear') resultFormat = this._getQuarterString(date, resultFormat) + ' yyyy'; if (format === 'quarter') return this._getQuarterString(date, resultFormat); if (format === 'longdatelongtime') return this._formatDate(date, 'longdate') + ' ' + this._formatDate(date, 'longtime'); if (format === 'shortdateshorttime') return this._formatDate(date, 'shortDate') + ' ' + this._formatDate(date, 'shortTime'); return Globalize.format(date, resultFormat) }, format: function(value, format, precision) { if (format && format.format) if (format.dateType) return this._formatDateEx(value, format); else if (utils.isNumber(value) && isFinite(value)) return this._formatNumberEx(value, format); return this._format(value, format, precision) }, _format: function(value, format, precision) { var numberFormatObject; if (!utils.isString(format) || format === '' || !utils.isNumber(value) && !utils.isDate(value)) return utils.isDefined(value) ? value.toString() : ''; numberFormatObject = this._parseNumberFormatString(format); if (utils.isNumber(value) && numberFormatObject) return this._formatNumber(value, numberFormatObject, precision); if (utils.isDate(value) && this._isDateFormatContains(format)) return this._formatDate(value, format); if (!numberFormatObject && !this._isDateFormatContains(format)) return this._formatCustomString(value, format) }, _formatNumberEx: function(value, formatInfo) { var that = this, numericFormatType = DX.NumericFormat[formatInfo.format.toLowerCase()], numberFormat = Globalize.culture().numberFormat, currencyFormat = formatInfo.currencyCulture && Globalize.cultures[formatInfo.currencyCulture] ? Globalize.cultures[formatInfo.currencyCulture].numberFormat.currency : numberFormat.currency, percentFormat = numberFormat.percent, formatSettings = that._getUnitFormatSettings(value, formatInfo), unit = formatSettings.unit, precision = formatSettings.precision, showTrailingZeros = formatSettings.showTrailingZeros, includeGroupSeparator = formatSettings.includeGroupSeparator, groupSymbol = numberFormat[","], floatingSymbol = numberFormat["."], number, isNegative, pattern, currentFormat, regexParts = /n|\$|-|%/g, result = ""; if (!utils.isDefined(value)) return ''; value = that._applyUnitToValue(value, unit); number = Math.abs(value); isNegative = value < 0; switch (numericFormatType) { case DX.NumericFormat.decimal: pattern = "n"; number = Math[isNegative ? "ceil" : "floor"](number); if (precision > 0) { var str = "" + number; for (var i = str.length; i < precision; i += 1) str = "0" + str; number = str } if (isNegative) number = "-" + number; break; case DX.NumericFormat.fixedpoint: currentFormat = numberFormat; case DX.NumericFormat.currency: currentFormat = currentFormat || currencyFormat; case DX.NumericFormat.percent: currentFormat = currentFormat || percentFormat; pattern = isNegative ? currentFormat.pattern[0] : currentFormat.pattern[1] || "n"; number = Globalize.format(number * (numericFormatType === DX.NumericFormat.percent ? 100 : 1), "N" + precision); if (!showTrailingZeros) number = that._excludeTrailingZeros(number, floatingSymbol); if (!includeGroupSeparator) number = number.replace(new RegExp('\\' + groupSymbol, 'g'), ''); break; case DX.NumericFormat.exponential: return that._formatNumberExponential(value, precision); default: throw"Illegal numeric format: '" + numericFormatType + "'"; } for (; ; ) { var lastIndex = regexParts.lastIndex, matches = regexParts.exec(pattern); result += pattern.slice(lastIndex, matches ? matches.index : pattern.length); if (matches) switch (matches[0]) { case"-": if (/[1-9]/.test(number)) result += numberFormat["-"]; break; case"$": result += currencyFormat.symbol; break; case"%": result += percentFormat.symbol; break; case"n": result += number + unit; break } else break } return (formatInfo.plus && value > 0 ? "+" : '') + result }, _excludeTrailingZeros: function(strValue, floatingSymbol) { var floatingIndex = strValue.indexOf(floatingSymbol), stopIndex, i; if (floatingIndex < 0) return strValue; stopIndex = strValue.length; for (i = stopIndex - 1; i >= floatingIndex && (strValue[i] === '0' || i === floatingIndex); i--) stopIndex--; return strValue.substring(0, stopIndex) }, _getUnitFormatSettings: function(value, formatInfo) { var unit = formatInfo.unit || '', precision = formatInfo.precision || 0, includeGroupSeparator = formatInfo.includeGroupSeparator || false, showTrailingZeros = formatInfo.showTrailingZeros === undefined ? true : formatInfo.showTrailingZeros, significantDigits = formatInfo.significantDigits || 1, absValue; if (unit.toLowerCase() === 'auto') { showTrailingZeros = false; absValue = Math.abs(value); if (significantDigits < 1) significantDigits = 1; if (absValue >= 1000000000) { unit = 'B'; absValue /= 1000000000 } else if (absValue >= 1000000) { unit = 'M'; absValue /= 1000000 } else if (absValue >= 1000) { unit = 'K'; absValue /= 1000 } else unit = ''; if (absValue == 0) precision = 0; else if (absValue < 1) { precision = significantDigits; var smallValue = Math.pow(10, -significantDigits); while (absValue < smallValue) { smallValue /= 10; precision++ } } else if (absValue >= 100) precision = significantDigits - 3; else if (absValue >= 10) precision = significantDigits - 2; else precision = significantDigits - 1 } if (precision < 0) precision = 0; return { unit: unit, precision: precision, showTrailingZeros: showTrailingZeros, includeGroupSeparator: includeGroupSeparator } }, _applyUnitToValue: function(value, unit) { if (unit == 'B') return value.toFixed(1) / 1000000000; if (unit == 'M') return value / 1000000; if (unit == 'K') return value / 1000; return value }, _formatDateEx: function(value, formatInfo) { var that = this, format = formatInfo.format, dateType = formatInfo.dateType, calendar = Globalize.culture().calendars.standard, time = undefined, index, dateStr; format = format.toLowerCase(); if (!utils.isDefined(value)) return ''; if (dateType !== 'num' || format === 'dayofweek') switch (format) { case'monthyear': return that._formatDate(value, 'monthandyear'); case'quarteryear': return that._getQuarterString(value, 'QQ') + ' ' + value.getFullYear(); case'daymonthyear': return that._formatDate(value, dateType + 'Date'); case'datehour': time = new Date(value.getTime()); time.setMinutes(0); dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date'); return dateType === 'timeOnly' ? that._formatDate(time, 'shorttime') : dateStr + ' ' + that._formatDate(time, 'shorttime'); case'datehourminute': dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date'); return dateType === 'timeOnly' ? that._formatDate(value, 'shorttime') : dateStr + ' ' + that._formatDate(value, 'shorttime'); case'datehourminutesecond': dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date'); return dateType === 'timeOnly' ? that._formatDate(value, 'longtime') : dateStr + ' ' + that._formatDate(value, 'longtime'); case'year': dateStr = value.toString(); return dateType === 'abbr' ? dateStr.slice(2, 4) : dateStr; case'quarter': return utils.stringFormat(that.defaultQuarterFormat, value.toString()); case'month': index = value - 1; return dateType === 'abbr' ? calendar.months.namesAbbr[index] : calendar.months.names[index]; case'hour': if (dateType === 'long') { time = new Date; time.setHours(value); time.setMinutes(0); return that._formatDate(time, 'shorttime') } else return value.toString(); case'dayofweek': index = utils.isString(value) ? $.inArray(value, ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']) : value; if (dateType !== 'num') return dateType === 'abbr' ? calendar.days.namesAbbr[index] : calendar.days.names[index]; else return ((index - calendar.firstDay + 1 + 7) % 8).toString(); default: return value.toString() } else return value.toString() }, getTimeFormat: function(showSecond) { if (showSecond) return this._getDateTimeFormatPattern('longtime'); return this._getDateTimeFormatPattern('shorttime') }, getDateFormatByDifferences: function(dateDifferences) { var resultFormat = ''; if (dateDifferences.millisecond) resultFormat = DX.DateTimeFormat.millisecond; if (dateDifferences.hour || dateDifferences.minute || dateDifferences.second) resultFormat = this._addFormatSeparator(this.getTimeFormat(dateDifferences.second), resultFormat); if (dateDifferences.year && dateDifferences.month && dateDifferences.day) return this._addFormatSeparator(this._getDateTimeFormatPattern('shortdate'), resultFormat); if (dateDifferences.year && dateDifferences.month) return DX.DateTimeFormat['monthandyear']; if (dateDifferences.year) return DX.DateTimeFormat['year']; if (dateDifferences.month && dateDifferences.day) return this._addFormatSeparator(this._getDateTimeFormatPattern('monthandday'), resultFormat); if (dateDifferences.month) return DX.DateTimeFormat['month']; if (dateDifferences.day) return this._addFormatSeparator('dddd, dd', resultFormat); return resultFormat }, getDateFormatByTicks: function(ticks) { var resultFormat, maxDif, currentDif, i, dateUnitInterval; if (ticks.length > 1) { maxDif = utils.getDatesDifferences(ticks[0], ticks[1]); for (i = 1; i < ticks.length - 1; i++) { currentDif = utils.getDatesDifferences(ticks[i], ticks[i + 1]); if (maxDif.count < currentDif.count) maxDif = currentDif } } else maxDif = { year: true, month: true, day: true, hour: ticks[0].getHours() > 0, minute: ticks[0].getMinutes() > 0, second: ticks[0].getSeconds() > 0 }; resultFormat = this.getDateFormatByDifferences(maxDif); return resultFormat }, getDateFormatByTickInterval: function(startValue, endValue, tickInterval) { var resultFormat, dateDifferences, dateUnitInterval, dateDifferencesConverter = { quarter: 'month', week: 'day' }, correctDateDifferences = function(dateDifferences, tickInterval, value) { switch (tickInterval) { case'year': dateDifferences.month = value; case'quarter': case'month': dateDifferences.day = value; case'week': case'day': dateDifferences.hour = value; case'hour': dateDifferences.minute = value; case'minute': dateDifferences.second = value; case'second': dateDifferences.millisecond = value } }, correctDifferencesByMaxDate = function(differences, minDate, maxDate) { if (!maxDate.getMilliseconds() && maxDate.getSeconds()) { if (maxDate.getSeconds() - minDate.getSeconds() === 1) { differences.millisecond = true; differences.second = false } } else if (!maxDate.getSeconds() && maxDate.getMinutes()) { if (maxDate.getMinutes() - minDate.getMinutes() === 1) { differences.second = true; differences.minute = false } } else if (!maxDate.getMinutes() && maxDate.getHours()) { if (maxDate.getHours() - minDate.getHours() === 1) { differences.minute = true; differences.hour = false } } else if (!maxDate.getHours() && maxDate.getDate() > 1) { if (maxDate.getDate() - minDate.getDate() === 1) { differences.hour = true; differences.day = false } } else if (maxDate.getDate() === 1 && maxDate.getMonth()) { if (maxDate.getMonth() - minDate.getMonth() === 1) { differences.day = true; differences.month = false } } else if (!maxDate.getMonth() && maxDate.getFullYear()) if (maxDate.getFullYear() - minDate.getFullYear() === 1) { differences.month = true; differences.year = false } }; tickInterval = utils.isString(tickInterval) ? tickInterval.toLowerCase() : tickInterval; dateDifferences = utils.getDatesDifferences(startValue, endValue); if (startValue !== endValue) correctDifferencesByMaxDate(dateDifferences, startValue > endValue ? endValue : startValue, startValue > endValue ? startValue : endValue); dateUnitInterval = utils.getDateUnitInterval(dateDifferences); correctDateDifferences(dateDifferences, dateUnitInterval, true); dateUnitInterval = utils.getDateUnitInterval(tickInterval || 'second'); correctDateDifferences(dateDifferences, dateUnitInterval, false); dateDifferences[dateDifferencesConverter[dateUnitInterval] || dateUnitInterval] = true; resultFormat = this.getDateFormatByDifferences(dateDifferences); return resultFormat } } })(jQuery, DevExpress); /*! Module core, file color.js */ (function(DX, undefined) { var standardColorNames = { 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', darkgreen: '006400', darkkhaki: 'bdb76b', darkmagenta: '8b008b', darkolivegreen: '556b2f', darkorange: 'ff8c00', darkorchid: '9932cc', darkred: '8b0000', darksalmon: 'e9967a', darkseagreen: '8fbc8f', darkslateblue: '483d8b', darkslategray: '2f4f4f', darkturquoise: '00ced1', darkviolet: '9400d3', deeppink: 'ff1493', deepskyblue: '00bfff', dimgray: '696969', dodgerblue: '1e90ff', feldspar: 'd19275', firebrick: 'b22222', floralwhite: 'fffaf0', forestgreen: '228b22', fuchsia: 'ff00ff', gainsboro: 'dcdcdc', ghostwhite: 'f8f8ff', gold: 'ffd700', goldenrod: 'daa520', gray: '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', lightgrey: 'd3d3d3', lightgreen: '90ee90', lightpink: 'ffb6c1', lightsalmon: 'ffa07a', lightseagreen: '20b2aa', lightskyblue: '87cefa', lightslateblue: '8470ff', lightslategray: '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', snow: 'fffafa', springgreen: '00ff7f', steelblue: '4682b4', tan: 'd2b48c', teal: '008080', thistle: 'd8bfd8', tomato: 'ff6347', turquoise: '40e0d0', violet: 'ee82ee', violetred: 'd02090', wheat: 'f5deb3', white: 'ffffff', whitesmoke: 'f5f5f5', yellow: 'ffff00', yellowgreen: '9acd32' }; var standardColorTypes = [{ re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, process: function(colorString) { return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10)] } }, { re: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*\.*\d+)\)$/, process: function(colorString) { return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10), parseFloat(colorString[4])] } }, { re: /^#(\w{2})(\w{2})(\w{2})$/, process: function(colorString) { return [parseInt(colorString[1], 16), parseInt(colorString[2], 16), parseInt(colorString[3], 16)] } }, { re: /^#(\w{1})(\w{1})(\w{1})$/, process: function(colorString) { return [parseInt(colorString[1] + colorString[1], 16), parseInt(colorString[2] + colorString[2], 16), parseInt(colorString[3] + colorString[3], 16)] } }, { re: /^hsv\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, process: function(colorString) { var h = parseInt(colorString[1], 10), s = parseInt(colorString[2], 10), v = parseInt(colorString[3], 10), rgb = hsvToRgb(h, s, v); return [rgb[0], rgb[1], rgb[2], 1, [h, s, v]] } }, { re: /^hsl\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, process: function(colorString) { var h = parseInt(colorString[1], 10), s = parseInt(colorString[2], 10), l = parseInt(colorString[3], 10), rgb = hslToRgb(h, s, l); return [rgb[0], rgb[1], rgb[2], 1, null, [h, s, l]] } }]; function Color(value) { this.baseColor = value; var color; if (value) { color = String(value).toLowerCase().replace(/ /g, ''); color = standardColorNames[color] ? '#' + standardColorNames[color] : color; color = parseColor(color) } if (!color) this.colorIsInvalid = true; color = color || {}; this.r = normalize(color[0]); this.g = normalize(color[1]); this.b = normalize(color[2]); this.a = normalize(color[3], 1, 1); if (color[4]) this.hsv = { h: color[4][0], s: color[4][1], v: color[4][2] }; else this.hsv = toHsvFromRgb(this.r, this.g, this.b); if (color[5]) this.hsl = { h: color[5][0], s: color[5][1], l: color[5][2] }; else this.hsl = toHslFromRgb(this.r, this.g, this.b) } function parseColor(color) { if (color === "transparent") return [0, 0, 0, 0]; var result, i = 0, ii = standardColorTypes.length, str; for (; i < ii; ++i) { str = standardColorTypes[i].re.exec(color); if (str) return standardColorTypes[i].process(str) } return null } function normalize(colorComponent, def, max) { def = def || 0; max = max || 255; return colorComponent < 0 || isNaN(colorComponent) ? def : colorComponent > max ? max : colorComponent } function toHexFromRgb(r, g, b) { return '#' + (0X01000000 | r << 16 | g << 8 | b).toString(16).slice(1) } function toHsvFromRgb(r, g, b) { var max = Math.max(r, g, b), min = Math.min(r, g, b), delta = max - min, H, S, V; V = max; S = max === 0 ? 0 : 1 - min / max; if (max === min) H = 0; else switch (max) { case r: H = 60 * ((g - b) / delta); if (g < b) H = H + 360; break; case g: H = 60 * ((b - r) / delta) + 120; break; case b: H = 60 * ((r - g) / delta) + 240; break } S *= 100; V *= 100 / 255; return { h: Math.round(H), s: Math.round(S), v: Math.round(V) } } function hsvToRgb(h, s, v) { var Vdec, Vinc, Vmin, Hi, a, r, g, b; Hi = Math.floor(h / 60); Vmin = (100 - s) * v / 100; a = (v - Vmin) * (h % 60 / 60); Vinc = Vmin + a; Vdec = v - a; switch (Hi) { case 0: r = v; g = Vinc; b = Vmin; break; case 1: r = Vdec; g = v; b = Vmin; break; case 2: r = Vmin; g = v; b = Vinc; break; case 3: r = Vmin; g = Vdec; b = v; break; case 4: r = Vinc; g = Vmin; b = v; break; case 5: r = v; g = Vmin; b = Vdec; break } return [Math.round(r * 2.55), Math.round(g * 2.55), Math.round(b * 2.55)] } function calculateHue(r, g, b, delta) { var max = Math.max(r, g, b); switch (max) { case r: return (g - b) / delta + (g < b ? 6 : 0); case g: return (b - r) / delta + 2; case b: return (r - g) / delta + 4 } } function toHslFromRgb(r, g, b) { r = convertTo01Bounds(r, 255); g = convertTo01Bounds(g, 255); b = convertTo01Bounds(b, 255); var max = Math.max(r, g, b), min = Math.min(r, g, b), maxMinSumm = max + min, h, s, l = maxMinSumm / 2; if (max === min) h = s = 0; else { var delta = max - min; if (l > 0.5) s = delta / (2 - maxMinSumm); else s = delta / maxMinSumm; h = calculateHue(r, g, b, delta); h /= 6 } return { h: _round(h * 360), s: _round(s * 100), l: _round(l * 100) } } function makeTc(colorPart, h) { var Tc = h; if (colorPart === "r") Tc = h + 1 / 3; if (colorPart === "b") Tc = h - 1 / 3; return Tc } function modifyTc(Tc) { if (Tc < 0) Tc += 1; if (Tc > 1) Tc -= 1; return Tc } function hueToRgb(p, q, Tc) { Tc = modifyTc(Tc); if (Tc < 1 / 6) return p + (q - p) * 6 * Tc; if (Tc < 1 / 2) return q; if (Tc < 2 / 3) return p + (q - p) * (2 / 3 - Tc) * 6; return p } function hslToRgb(h, s, l) { var r, g, b, h = convertTo01Bounds(h, 360), s = convertTo01Bounds(s, 100), l = convertTo01Bounds(l, 100); if (s === 0) r = g = b = l; else { var q = l < 0.5 ? l * (1 + s) : l + s - l * s, p = 2 * l - q; r = hueToRgb(p, q, makeTc("r", h)); g = hueToRgb(p, q, makeTc("g", h)); b = hueToRgb(p, q, makeTc("b", h)) } return [_round(r * 255), _round(g * 255), _round(b * 255)] } function convertTo01Bounds(n, max) { n = Math.min(max, Math.max(0, parseFloat(n))); if (Math.abs(n - max) < 0.000001) return 1; return n % max / parseFloat(max) } function isIntegerBtwMinAndMax(number, min, max) { min = min || 0; max = max || 255; if (number % 1 !== 0 || number < min || number > max || typeof number !== 'number' || isNaN(number)) return false; return true } var _round = Math.round; Color.prototype = { constructor: Color, highlight: function(step) { step = step || 10; return this.alter(step).toHex() }, darken: function(step) { step = step || 10; return this.alter(-step).toHex() }, alter: function(step) { var result = new Color; result.r = normalize(this.r + step); result.g = normalize(this.g + step); result.b = normalize(this.b + step); return result }, blend: function(blendColor, opacity) { var other = blendColor instanceof Color ? blendColor : new Color(blendColor), result = new Color; result.r = normalize(_round(this.r * (1 - opacity) + other.r * opacity)); result.g = normalize(_round(this.g * (1 - opacity) + other.g * opacity)); result.b = normalize(_round(this.b * (1 - opacity) + other.b * opacity)); return result }, toHex: function() { return toHexFromRgb(this.r, this.g, this.b) }, getPureColor: function() { var rgb = hsvToRgb(this.hsv.h, 100, 100); return new Color("rgb(" + rgb.join(",") + ")") }, isValidHex: function(hex) { return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex) }, isValidRGB: function(r, g, b) { if (!isIntegerBtwMinAndMax(r) || !isIntegerBtwMinAndMax(g) || !isIntegerBtwMinAndMax(b)) return false; return true }, isValidAlpha: function(a) { if (isNaN(a) || a < 0 || a > 1 || typeof a !== 'number') return false; return true }, colorIsInvalid: false }; DX.Color = Color })(DevExpress); /*! Module core, file localization.js */ (function($, DX, undefined) { Globalize.localize = function(key, cultureSelector) { var neutral = (cultureSelector || this.cultureSelector || "").substring(0, 2); return this.findClosestCulture(cultureSelector).messages[key] || this.findClosestCulture(neutral).messages[key] || this.cultures["default"].messages[key] }; var localization = function() { var newMessages = {}; return { setup: function(localizablePrefix) { this.localizeString = function(text) { var regex = new RegExp("(^|[^a-zA-Z_0-9" + localizablePrefix + "-]+)(" + localizablePrefix + "{1,2})([a-zA-Z_0-9-]+)", "g"), escapeString = localizablePrefix + localizablePrefix; return text.replace(regex, function(str, prefix, escape, localizationKey) { var result = prefix + localizablePrefix + localizationKey; if (escape !== escapeString) if (Globalize.cultures["default"].messages[localizationKey]) result = prefix + Globalize.localize(localizationKey); else newMessages[localizationKey] = DX.inflector.humanize(localizationKey); return result }) } }, localizeNode: function(node) { var that = this; $(node).each(function(index, nodeItem) { if (!nodeItem.nodeType) return; if (nodeItem.nodeType === 3) nodeItem.nodeValue = that.localizeString(nodeItem.nodeValue); else { $.each(nodeItem.attributes || [], function(index, attr) { if (typeof attr.value === "string") { var localizedValue = that.localizeString(attr.value); if (attr.value !== localizedValue) attr.value = localizedValue } }); $(nodeItem).contents().each(function(index, node) { that.localizeNode(node) }) } }) }, getDictionary: function(onlyNew) { if (onlyNew) return newMessages; return $.extend({}, newMessages, Globalize.cultures["default"].messages) } } }(); localization.setup("@"); DX.localization = localization })(jQuery, DevExpress); /*! Module core, file localization.en.js */ Globalize.addCultureInfo("default", {messages: { Yes: "Yes", No: "No", Cancel: "Cancel", Clear: "Clear", Done: "Done", Loading: "Loading...", Select: "Select...", Search: "Search", Back: "Back", OK: "OK", "dxLookup-searchPlaceholder": "Minimum character number: {0}", "dxCollectionContainerWidget-noDataText": "No data to display", "dxList-pullingDownText": "Pull down to refresh...", "dxList-pulledDownText": "Release to refresh...", "dxList-refreshingText": "Refreshing...", "dxList-pageLoadingText": "Loading...", "dxList-nextButtonText": "More", "dxListEditDecorator-delete": "Delete", "dxListEditDecorator-more": "More", "dxScrollView-pullingDownText": "Pull down to refresh...", "dxScrollView-pulledDownText": "Release to refresh...", "dxScrollView-refreshingText": "Refreshing...", "dxScrollView-reachBottomText": "Loading...", "dxSwitch-onText": "ON", "dxSwitch-offText": "OFF", "dxDateBox-simulatedDataPickerTitleTime": "Select time", "dxDateBox-simulatedDataPickerTitleDate": "Select date", "dxDateBox-simulatedDataPickerTitleDateTime": "Select date and time", "dxDataGrid-columnChooserTitle": "Column Chooser", "dxDataGrid-columnChooserEmptyText": "Drag a column here to hide it", "dxDataGrid-groupContinuesMessage": "Continues on the next page", "dxDataGrid-groupContinuedMessage": "Continued from the previous page", "dxDataGrid-editingEditRow": "Edit", "dxDataGrid-editingSaveRowChanges": "Save", "dxDataGrid-editingCancelRowChanges": "Cancel", "dxDataGrid-editingDeleteRow": "Delete", "dxDataGrid-editingUndeleteRow": "Undelete", "dxDataGrid-editingConfirmDeleteMessage": "Are you sure you want to delete this record?", "dxDataGrid-editingConfirmDeleteTitle": "", "dxDataGrid-groupPanelEmptyText": "Drag a column header here to group by that column", "dxDataGrid-noDataText": "No data", "dxDataGrid-searchPanelPlaceholder": "Search...", "dxDataGrid-filterRowShowAllText": "(All)", "dxDataGrid-filterRowResetOperationText": "Reset", "dxDataGrid-filterRowOperationEquals": "Equals", "dxDataGrid-filterRowOperationNotEquals": "Does not equal", "dxDataGrid-filterRowOperationLess": "Less than", "dxDataGrid-filterRowOperationLessOrEquals": "Less than or equal to", "dxDataGrid-filterRowOperationGreater": "Greater than", "dxDataGrid-filterRowOperationGreaterOrEquals": "Greater than or equal to", "dxDataGrid-filterRowOperationStartsWith": "Starts with", "dxDataGrid-filterRowOperationContains": "Contains", "dxDataGrid-filterRowOperationNotContains": "Does not contain", "dxDataGrid-filterRowOperationEndsWith": "Ends with", "dxDataGrid-trueText": "true", "dxDataGrid-falseText": "false", "dxDataGrid-sortingAscendingText": "Sort Ascending", "dxDataGrid-sortingDescendingText": "Sort Descending", "dxDataGrid-sortingClearText": "Clear Sorting" }}); /*! Module core, file data.js */ (function($, DX, undefined) { var bracketsToDots = function(expr) { return expr.replace(/\[/g, ".").replace(/\]/g, "") }; var unwrapObservable = DX.utils.unwrapObservable; var isObservable = function(value) { return DX.support.hasKo && ko.isObservable(value) }; var readPropValue = function(obj, propName) { if (propName === "this") return obj; return obj[propName] }; var assignPropValue = function(obj, propName, value) { if (propName === "this") throw Error("Cannot assign to self"); var propValue = obj[propName]; if (isObservable(propValue)) propValue(value); else obj[propName] = value }; var compileGetter = function(expr) { if (arguments.length > 1) expr = $.makeArray(arguments); if (!expr || expr === "this") return function(obj) { return obj }; if ($.isFunction(expr)) return expr; if ($.isArray(expr)) return combineGetters(expr); expr = bracketsToDots(expr); var path = expr.split("."); return function(obj, options) { options = options || {}; var current = unwrapObservable(obj); $.each(path, function() { if (!current) return false; var next = unwrapObservable(current[this]); if ($.isFunction(next) && !options.functionsAsIs) next = next.call(current); current = next }); return current } }; var combineGetters = function(getters) { var compiledGetters = {}; $.each(getters, function() { compiledGetters[this] = compileGetter(this) }); return function(obj, options) { var result = {}; $.each(compiledGetters, function(name) { var value = this(obj, options), current, path, last, i; if (value === undefined) return; current = result; path = name.split("."); last = path.length - 1; for (i = 0; i < last; i++) current = current[path[i]] = {}; current[path[i]] = value }); return result } }; var compileSetter = function(expr) { expr = expr || "this"; expr = bracketsToDots(expr); var pos = expr.lastIndexOf("."), targetGetter = compileGetter(expr.substr(0, pos)), targetPropName = expr.substr(1 + pos); return function(obj, value, options) { options = options || {}; var target = targetGetter(obj, {functionsAsIs: options.functionsAsIs}), prevTargetValue = readPropValue(target, targetPropName); if (!options.functionsAsIs && $.isFunction(prevTargetValue) && !isObservable(prevTargetValue)) target[targetPropName](value); else { prevTargetValue = unwrapObservable(prevTargetValue); if (options.merge && $.isPlainObject(value) && (prevTargetValue === undefined || $.isPlainObject(prevTargetValue)) && !(value instanceof $.Event)) { if (!prevTargetValue) assignPropValue(target, targetPropName, {}); DX.utils.deepExtendArraySafe(unwrapObservable(readPropValue(target, targetPropName)), value) } else assignPropValue(target, targetPropName, value) } } }; var normalizeBinaryCriterion = function(crit) { return [crit[0], crit.length < 3 ? "=" : String(crit[1]).toLowerCase(), crit.length < 2 ? true : crit[crit.length - 1]] }; var normalizeSortingInfo = function(info) { if (!$.isArray(info)) info = [info]; return $.map(info, function(i) { return { selector: $.isFunction(i) || typeof i === "string" ? i : i.getter || i.field || i.selector, desc: !!(i.desc || String(i.dir).charAt(0).toLowerCase() === "d") } }) }; var Guid = DX.Class.inherit({ ctor: function(value) { if (value) value = String(value); this._value = this._normalize(value || this._generate()) }, _normalize: function(value) { value = value.replace(/[^a-f0-9]/ig, "").toLowerCase(); while (value.length < 32) value += "0"; return [value.substr(0, 8), value.substr(8, 4), value.substr(12, 4), value.substr(16, 4), value.substr(20, 12)].join("-") }, _generate: function() { var value = ""; for (var i = 0; i < 32; i++) value += Math.round(Math.random() * 15).toString(16); return value }, toString: function() { return this._value }, valueOf: function() { return this._value }, toJSON: function() { return this._value } }); var toComparable = function(value, caseSensitive) { if (value instanceof Date) return value.getTime(); if (value instanceof Guid) return value.valueOf(); if (!caseSensitive && typeof value === "string") return value.toLowerCase(); return value }; var keysEqual = function(keyExpr, key1, key2) { if ($.isArray(keyExpr)) { var names = $.map(key1, function(v, k) { return k }), name; for (var i = 0; i < names.length; i++) { name = names[i]; if (toComparable(key1[name], true) != toComparable(key2[name], true)) return false } return true } return toComparable(key1, true) == toComparable(key2, true) }; var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var base64_encode = function(input) { if (!$.isArray(input)) input = stringToByteArray(String(input)); var result = ""; for (var i = 0; i < input.length; i += 3) { var octet1 = input[i], octet2 = input[i + 1], octet3 = input[i + 2]; result += $.map([octet1 >> 2, (octet1 & 3) << 4 | octet2 >> 4, isNaN(octet2) ? 64 : (octet2 & 15) << 2 | octet3 >> 6, isNaN(octet3) ? 64 : octet3 & 63], function(item) { return BASE64_CHARS.charAt(item) }).join("") } return result }; var stringToByteArray = function(str) { var bytes = [], code, i; for (i = 0; i < str.length; i++) { code = str.charCodeAt(i); if (code < 128) bytes.push(code); else if (code < 2048) bytes.push(192 + (code >> 6), 128 + (code & 63)); else if (code < 65536) bytes.push(224 + (code >> 12), 128 + (code >> 6 & 63), 128 + (code & 63)); else if (code < 2097152) bytes.push(240 + (code >> 18), 128 + (code >> 12 & 63), 128 + (code >> 6 & 63), 128 + (code & 63)) } return bytes }; var errorMessageFromXhr = function() { var textStatusMessages = { timeout: "Network connection timeout", error: "Unspecified network error", parsererror: "Unexpected server response" }; var textStatusDetails = { timeout: "possible causes: the remote host is not accessible, overloaded or is not included into the domain white-list when being run in the native container", error: "if the remote host is located on another domain, make sure it properly supports cross-origin resource sharing (CORS), or use the JSONP approach instead", parsererror: "the remote host did not respond with valid JSON data" }; var explainTextStatus = function(textStatus) { var result = textStatusMessages[textStatus]; if (!result) return textStatus; result += " (" + textStatusDetails[textStatus] + ")"; return result }; return function(xhr, textStatus) { if (xhr.status < 400) return explainTextStatus(textStatus); return xhr.statusText } }(); var data = DX.data = { utils: { compileGetter: compileGetter, compileSetter: compileSetter, normalizeBinaryCriterion: normalizeBinaryCriterion, normalizeSortingInfo: normalizeSortingInfo, toComparable: toComparable, keysEqual: keysEqual, errorMessageFromXhr: errorMessageFromXhr }, Guid: Guid, base64_encode: base64_encode, queryImpl: {}, queryAdapters: {}, query: function() { var impl = $.isArray(arguments[0]) ? "array" : "remote"; return data.queryImpl[impl].apply(this, arguments) }, errorHandler: null, _handleError: function(error) { if (window.console) console.warn("[DevExpress.data]: " + error); if (data.errorHandler) data.errorHandler(error) } } })(jQuery, DevExpress); /*! Module core, file data.query.array.js */ (function($, DX, undefined) { var Class = DX.Class, data = DX.data, queryImpl = data.queryImpl, compileGetter = data.utils.compileGetter, toComparable = data.utils.toComparable; var Iterator = Class.inherit({ toArray: function() { var result = []; this.reset(); while (this.next()) result.push(this.current()); return result }, countable: function() { return false } }); var ArrayIterator = Iterator.inherit({ ctor: function(array) { this.array = array; this.index = -1 }, next: function() { if (this.index + 1 < this.array.length) { this.index++; return true } return false }, current: function() { return this.array[this.index] }, reset: function() { this.index = -1 }, toArray: function() { return this.array.slice(0) }, countable: function() { return true }, count: function() { return this.array.length } }); var WrappedIterator = Iterator.inherit({ ctor: function(iter) { this.iter = iter }, next: function() { return this.iter.next() }, current: function() { return this.iter.current() }, reset: function() { return this.iter.reset() } }); var MapIterator = WrappedIterator.inherit({ ctor: function(iter, mapper) { this.callBase(iter); this.index = -1; this.mapper = mapper }, current: function() { return this.mapper(this.callBase(), this.index) }, next: function() { var hasNext = this.callBase(); if (hasNext) this.index++; return hasNext } }); var SortIterator = Iterator.inherit({ ctor: function(iter, getter, desc) { if (!(iter instanceof MapIterator)) iter = new MapIterator(iter, this._wrap); this.iter = iter; this.rules = [{ getter: getter, desc: desc }] }, thenBy: function(getter, desc) { var result = new SortIterator(this.sortedIter || this.iter, getter, desc); if (!this.sortedIter) result.rules = this.rules.concat(result.rules); return result }, next: function() { this._ensureSorted(); return this.sortedIter.next() }, current: function() { this._ensureSorted(); return this.sortedIter.current() }, reset: function() { delete this.sortedIter }, countable: function() { return this.sortedIter || this.iter.countable() }, count: function() { if (this.sortedIter) return this.sortedIter.count(); return this.iter.count() }, _ensureSorted: function() { if (this.sortedIter) return; $.each(this.rules, function() { this.getter = compileGetter(this.getter) }); this.sortedIter = new MapIterator(new ArrayIterator(this.iter.toArray().sort($.proxy(this._compare, this))), this._unwrap) }, _wrap: function(record, index) { return { index: index, value: record } }, _unwrap: function(wrappedItem) { return wrappedItem.value }, _compare: function(x, y) { var xIndex = x.index, yIndex = y.index; x = x.value; y = y.value; if (x === y) return xIndex - yIndex; for (var i = 0, rulesCount = this.rules.length; i < rulesCount; i++) { var rule = this.rules[i], xValue = toComparable(rule.getter(x)), yValue = toComparable(rule.getter(y)), factor = rule.desc ? -1 : 1; if (xValue < yValue) return -factor; if (xValue > yValue) return factor; if (xValue !== yValue) return !xValue ? -factor : factor } return xIndex - yIndex } }); var compileCriteria = function() { var compileGroup = function(crit) { var operands = [], bag = ["return function(d) { return "], index = 0, pushAnd = false; $.each(crit, function() { if ($.isArray(this) || $.isFunction(this)) { if (pushAnd) bag.push(" && "); operands.push(compileCriteria(this)); bag.push("op[", index, "](d)"); index++; pushAnd = true } else { bag.push(/and|&/i.test(this) ? " && " : " || "); pushAnd = false } }); bag.push(" }"); return new Function("op", bag.join(""))(operands) }; var toString = function(value) { return DX.utils.isDefined(value) ? value.toString() : '' }; var compileBinary = function(crit) { crit = data.utils.normalizeBinaryCriterion(crit); var getter = compileGetter(crit[0]), op = crit[1], value = crit[2]; value = toComparable(value); switch (op.toLowerCase()) { case"=": return compileEquals(getter, value); case"<>": return compileEquals(getter, value, true); case">": return function(obj) { return toComparable(getter(obj)) > value }; case"<": return function(obj) { return toComparable(getter(obj)) < value }; case">=": return function(obj) { return toComparable(getter(obj)) >= value }; case"<=": return function(obj) { return toComparable(getter(obj)) <= value }; case"startswith": return function(obj) { return toComparable(toString(getter(obj))).indexOf(value) === 0 }; case"endswith": return function(obj) { var getterValue = toComparable(toString(getter(obj))); return getterValue.lastIndexOf(value) === getterValue.length - toString(value).length }; case"contains": return function(obj) { return toComparable(toString(getter(obj))).indexOf(value) > -1 }; case"notcontains": return function(obj) { return toComparable(toString(getter(obj))).indexOf(value) === -1 } } throw Error("Unknown filter operation: " + op); }; function compileEquals(getter, value, negate) { return function(obj) { obj = toComparable(getter(obj)); var result = useStrictComparison(value) ? obj === value : obj == value; if (negate) result = !result; return result } } function useStrictComparison(value) { return value === "" || value === 0 || value === null || value === false || value === undefined } return function(crit) { if ($.isFunction(crit)) return crit; if ($.isArray(crit[0])) return compileGroup(crit); return compileBinary(crit) } }(); var FilterIterator = WrappedIterator.inherit({ ctor: function(iter, criteria) { this.callBase(iter); this.criteria = compileCriteria(criteria) }, next: function() { while (this.iter.next()) if (this.criteria(this.current())) return true; return false } }); var GroupIterator = Iterator.inherit({ ctor: function(iter, getter) { this.iter = iter; this.getter = getter }, next: function() { this._ensureGrouped(); return this.groupedIter.next() }, current: function() { this._ensureGrouped(); return this.groupedIter.current() }, reset: function() { delete this.groupedIter }, countable: function() { return !!this.groupedIter }, count: function() { return this.groupedIter.count() }, _ensureGrouped: function() { if (this.groupedIter) return; var hash = {}, keys = [], iter = this.iter, getter = compileGetter(this.getter); iter.reset(); while (iter.next()) { var current = iter.current(), key = getter(current); if (key in hash) hash[key].push(current); else { hash[key] = [current]; keys.push(key) } } this.groupedIter = new ArrayIterator($.map(keys, function(key) { return { key: key, items: hash[key] } })) } }); var SelectIterator = WrappedIterator.inherit({ ctor: function(iter, getter) { this.callBase(iter); this.getter = compileGetter(getter) }, current: function() { return this.getter(this.callBase()) }, countable: function() { return this.iter.countable() }, count: function() { return this.iter.count() } }); var SliceIterator = WrappedIterator.inherit({ ctor: function(iter, skip, take) { this.callBase(iter); this.skip = Math.max(0, skip); this.take = Math.max(0, take); this.pos = 0 }, next: function() { if (this.pos >= this.skip + this.take) return false; while (this.pos < this.skip && this.iter.next()) this.pos++; this.pos++; return this.iter.next() }, reset: function() { this.callBase(); this.pos = 0 }, countable: function() { return this.iter.countable() }, count: function() { return Math.min(this.iter.count() - this.skip, this.take) } }); queryImpl.array = function(iter, queryOptions) { queryOptions = queryOptions || {}; if (!(iter instanceof Iterator)) iter = new ArrayIterator(iter); var handleError = function(error) { var handler = queryOptions.errorHandler; if (handler) handler(error); data._handleError(error) }; var aggregate = function(seed, step, finalize) { var d = $.Deferred().fail(handleError); try { iter.reset(); if (arguments.length < 2) { step = arguments[0]; seed = iter.next() ? iter.current() : undefined } var accumulator = seed; while (iter.next()) accumulator = step(accumulator, iter.current()); d.resolve(finalize ? finalize(accumulator) : accumulator) } catch(x) { d.reject(x) } return d.promise() }; var select = function(getter) { if (!$.isFunction(getter) && !$.isArray(getter)) getter = $.makeArray(arguments); return chainQuery(new SelectIterator(iter, getter)) }; var selectProp = function(name) { return select(compileGetter(name)) }; var chainQuery = function(iter) { return queryImpl.array(iter, queryOptions) }; return { toArray: function() { return iter.toArray() }, enumerate: function() { var d = $.Deferred().fail(handleError); try { d.resolve(iter.toArray()) } catch(x) { d.reject(x) } return d.promise() }, sortBy: function(getter, desc) { return chainQuery(new SortIterator(iter, getter, desc)) }, thenBy: function(getter, desc) { if (iter instanceof SortIterator) return chainQuery(iter.thenBy(getter, desc)); throw Error(); }, filter: function(criteria) { if (!$.isArray(criteria)) criteria = $.makeArray(arguments); return chainQuery(new FilterIterator(iter, criteria)) }, slice: function(skip, take) { if (take === undefined) take = Number.MAX_VALUE; return chainQuery(new SliceIterator(iter, skip, take)) }, select: select, groupBy: function(getter) { return chainQuery(new GroupIterator(iter, getter)) }, aggregate: aggregate, count: function() { if (iter.countable()) { var d = $.Deferred().fail(handleError); try { d.resolve(iter.count()) } catch(x) { d.reject(x) } return d.promise() } return aggregate(0, function(count) { return 1 + count }) }, sum: function(getter) { if (getter) return selectProp(getter).sum(); return aggregate(0, function(sum, item) { return sum + item }) }, min: function(getter) { if (getter) return selectProp(getter).min(); return aggregate(function(min, item) { return item < min ? item : min }) }, max: function(getter) { if (getter) return selectProp(getter).max(); return aggregate(function(max, item) { return item > max ? item : max }) }, avg: function(getter) { if (getter) return selectProp(getter).avg(); var count = 0; return aggregate(0, function(sum, item) { count++; return sum + item }, function(sum) { return count ? sum / count : undefined }) } } } })(jQuery, DevExpress); /*! Module core, file data.query.remote.js */ (function($, DX, undefined) { var data = DX.data, queryImpl = data.queryImpl; queryImpl.remote = function(url, queryOptions, tasks) { tasks = tasks || []; queryOptions = queryOptions || {}; var createTask = function(name, args) { return { name: name, args: args } }; var exec = function(executorTask) { var d = $.Deferred(), adapterFactory, adapter, taskQueue, currentTask; var rejectWithNotify = function(error) { var handler = queryOptions.errorHandler; if (handler) handler(error); data._handleError(error); d.reject(error) }; try { adapterFactory = queryOptions.adapter || "odata"; if (!$.isFunction(adapterFactory)) adapterFactory = data.queryAdapters[adapterFactory]; adapter = adapterFactory(queryOptions); taskQueue = [].concat(tasks).concat(executorTask); while (taskQueue.length) { currentTask = taskQueue[0]; if (String(currentTask.name) !== "enumerate") if (!adapter[currentTask.name] || adapter[currentTask.name].apply(adapter, currentTask.args) === false) break; taskQueue.shift() } adapter.exec(url).done(function(result, extra) { if (!taskQueue.length) d.resolve(result, extra); else { var clientChain = queryImpl.array(result, {errorHandler: queryOptions.errorHandler}); $.each(taskQueue, function() { clientChain = clientChain[this.name].apply(clientChain, this.args) }); clientChain.done($.proxy(d.resolve, d)).fail($.proxy(d.reject, d)) } }).fail(rejectWithNotify) } catch(x) { rejectWithNotify(x) } return d.promise() }; var query = {}; $.each(["sortBy", "thenBy", "filter", "slice", "select", "groupBy"], function() { var name = this; query[name] = function() { return queryImpl.remote(url, queryOptions, tasks.concat(createTask(name, arguments))) } }); $.each(["count", "min", "max", "sum", "avg", "aggregate", "enumerate"], function() { var name = this; query[name] = function() { return exec.call(this, createTask(name, arguments)) } }); return query } })(jQuery, DevExpress); /*! Module core, file data.odata.js */ (function($, DX, undefined) { var data = DX.data, utils = DX.utils, Guid = data.Guid; var GUID_REGEX = /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/; var VERBOSE_DATE_REGEX = /^\/Date\((-?\d+)((\+|-)?(\d+)?)\)\/$/; var ISO8601_DATE_REGEX = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/; var TIMEZONE_OFFSET = (new Date).getTimezoneOffset() * 60 * 1000; var JSON_VERBOSE_MIME_TYPE = "application/json;odata=verbose"; function stringify(object) { return JSON.stringify(object, replacer); function replacer(key, value) { if (this[key] instanceof Date) return utils.formatIso8601Date(this[key]); return value } } var ajaxOptionsForRequest = function(request, requestOptions) { request = $.extend({ method: "get", url: "", params: {}, payload: null, headers: {} }, request); requestOptions = requestOptions || {}; var beforeSend = requestOptions.beforeSend; if (beforeSend) beforeSend(request); var method = (request.method || "get").toLowerCase(), isGet = method === "get", useJsonp = isGet && requestOptions.jsonp, params = $.extend({}, request.params), ajaxData = isGet ? params : stringify(request.payload), qs = !isGet && $.param(params), url = request.url, contentType = !isGet && JSON_VERBOSE_MIME_TYPE; if (qs) url += (url.indexOf("?") > -1 ? "&" : "?") + qs; if (useJsonp) ajaxData["$format"] = "json"; return { url: url, data: ajaxData, dataType: useJsonp ? "jsonp" : "json", jsonp: useJsonp && "$callback", type: method, timeout: 30000, headers: request.headers, contentType: contentType, accepts: {json: [JSON_VERBOSE_MIME_TYPE, "text/plain"].join()}, xhrFields: {withCredentials: requestOptions.withCredentials} } }; var sendRequest = function(request, requestOptions) { var d = $.Deferred(); $.ajax(ajaxOptionsForRequest(request, requestOptions)).always(function(obj, textStatus) { var tuplet = interpretJsonFormat(obj, textStatus), error = tuplet.error, data = tuplet.data, nextUrl = tuplet.nextUrl, extra; if (error) d.reject(error); else if (requestOptions.countOnly) d.resolve(tuplet.count); else if (nextUrl) sendRequest({url: nextUrl}, requestOptions).fail($.proxy(d.reject, d)).done(function(nextData) { d.resolve(data.concat(nextData)) }); else { if (isFinite(tuplet.count)) extra = {totalCount: tuplet.count}; d.resolve(data, extra) } }); return d.promise() }; var formatDotNetError = function(errorObj) { var message, currentError = errorObj; if ("message" in errorObj) if (errorObj.message.value) message = errorObj.message.value; else message = errorObj.message; while (currentError = currentError.innererror || currentError.internalexception) { message = currentError.message; if (currentError.internalexception && message.indexOf("inner exception") === -1) break } return message }; var errorFromResponse = function(obj, textStatus) { if (textStatus === "nocontent") return null; var httpStatus = 200, message = "Unknown error", response = obj; if (textStatus !== "success") { httpStatus = obj.status; message = data.utils.errorMessageFromXhr(obj, textStatus); try { response = $.parseJSON(obj.responseText) } catch(x) {} } var errorObj = response && (response.error || response["@odata.error"]); if (errorObj) { message = formatDotNetError(errorObj) || message; if (httpStatus === 200) httpStatus = 500; if (errorObj.code) httpStatus = Number(errorObj.code); return $.extend(Error(message), { httpStatus: httpStatus, errorDetails: errorObj }) } else if (httpStatus !== 200) return $.extend(Error(message), {httpStatus: httpStatus}) }; var interpretJsonFormat = function(obj, textStatus) { var error = errorFromResponse(obj, textStatus), value; if (error) return {error: error}; if (!$.isPlainObject(obj)) return {data: obj}; if ("d" in obj && (utils.isArray(obj.d) || utils.isObject(obj.d))) value = interpretVerboseJsonFormat(obj, textStatus); else value = interpretLightJsonFormat(obj, textStatus); transformTypes(value); return value }; var interpretVerboseJsonFormat = function(obj, textStatus) { var data = obj.d; if (!data) return {error: Error("Malformed or unsupported JSON response received")}; data = data.results || data; return { data: data, nextUrl: obj.d.__next, count: parseInt(obj.d.__count, 10) } }; var interpretLightJsonFormat = function(obj, textStatus) { var data = obj.value || obj; if (!data) return {error: Error("Malformed or unsupported JSON response received")}; return { data: data, nextUrl: obj["@odata.nextLink"], count: parseInt(obj["@odata.count"], 10) } }; var EdmLiteral = DX.Class.inherit({ ctor: function(value) { this._value = value }, valueOf: function() { return this._value } }); var transformTypes = function(obj) { $.each(obj, function(key, value) { if (value !== null && typeof value === "object") transformTypes(value); else if (typeof value === "string") if (GUID_REGEX.test(value)) obj[key] = new Guid(value); else if (value.match(VERBOSE_DATE_REGEX)) obj[key] = new Date(TIMEZONE_OFFSET + Number(RegExp.$1) + RegExp.$2 * 60000); else if (ISO8601_DATE_REGEX.test(value)) obj[key] = new Date(utils.parseIso8601Date(obj[key]).valueOf()) }) }; var serializeDate = function() { var pad = function(part) { part = String(part); if (part.length < 2) part = "0" + part; return part }; return function(date) { var result = ["datetime'", date.getFullYear(), "-", pad(date.getMonth() + 1), "-", pad(date.getDate())]; if (date.getHours() || date.getMinutes() || date.getSeconds() || date.getMilliseconds()) { result.push("T", pad(date.getHours()), ":", pad(date.getMinutes()), ":", pad(date.getSeconds())); if (date.getMilliseconds()) result.push(".", date.getMilliseconds()) } result.push("'"); return result.join("") } }(); var serializeString = function(value) { return "'" + value.replace(/": createBinaryOperationFormatter("ne"), ">": createBinaryOperationFormatter("gt"), ">=": createBinaryOperationFormatter("ge"), "<": createBinaryOperationFormatter("lt"), "<=": createBinaryOperationFormatter("le"), startswith: createStringFuncFormatter("startswith"), endswith: createStringFuncFormatter("endswith"), // yo2dh : 2015-02-11 여기서 변환하지 않고 ODATA URI를 직접 입력 passby: function(prop, val, bag) { bag.push(prop); } }; var formattersV2 = $.extend({}, formatters, { contains: createStringFuncFormatter("substringof", true), notcontains: createStringFuncFormatter("not substringof", true) }); var formattersV4 = $.extend({}, formatters, { contains: createStringFuncFormatter("contains"), notcontains: createStringFuncFormatter("not contains") }); var compileBinary = function(criteria, bag, protocolVersion) { criteria = data.utils.normalizeBinaryCriterion(criteria); var op = criteria[1], formatters = protocolVersion === 4 ? formattersV4 : formattersV2, formatter = formatters[op.toLowerCase()]; if (!formatter) throw Error("Unknown filter operation: " + op); formatter(serializePropName(criteria[0]), serializeValue(criteria[2], protocolVersion), bag) }; var compileGroup = function(criteria, bag, protocolVersion) { var pushAnd = false; $.each(criteria, function() { if ($.isArray(this)) { if (pushAnd) bag.push(" and "); bag.push("("); compileCore(this, bag, protocolVersion); bag.push(")"); pushAnd = true } else { bag.push(/and|&/i.test(this) ? " and " : " or "); pushAnd = false } }) }; var compileCore = function(criteria, bag, protocolVersion) { if ($.isArray(criteria[0])) compileGroup(criteria, bag, protocolVersion); else compileBinary(criteria, bag, protocolVersion) }; return function(criteria, protocolVersion) { var bag = []; compileCore(criteria, bag, protocolVersion); return bag.join("") } }(); var createODataQueryAdapter = function(queryOptions) { var sorting = [], criteria = [], select, skip, take, countQuery; var hasSlice = function() { return skip || take !== undefined }; var sortCore = function(getter, desc, reset) { if (hasSlice() || typeof getter !== "string") return false; if (reset) sorting = []; var rule = serializePropName(getter); if (desc) rule += " desc"; sorting.push(rule) }; var generateExpand = function() { var hash = {}; if (queryOptions.expand) $.each($.makeArray(queryOptions.expand), function() { hash[serializePropName(this)] = 1 }); if (select) $.each(select, function() { var path = this.split("."); if (path.length < 2) return; path.pop(); hash[serializePropName(path.join("."))] = 1 }); return $.map(hash, function(k, v) { return v }).join() || undefined }; var requestData = function() { var result = {}; if (!countQuery) { if (sorting.length) result["$orderby"] = sorting.join(","); if (skip) result["$skip"] = skip; if (take !== undefined) result["$top"] = take; if (select) result["$select"] = serializePropName(select.join()); result["$expand"] = generateExpand() } if (criteria.length) result["$filter"] = compileCriteria(criteria.length < 2 ? criteria[0] : criteria, queryOptions.version); if (countQuery) result["$top"] = 0; if (queryOptions.requireTotalCount || countQuery) if (queryOptions.version !== 4) result["$inlinecount"] = "allpages"; else result["$count"] = "true"; return result }; return { exec: function(url) { return sendRequest({ url: url, params: $.extend(requestData(), queryOptions && queryOptions.params) }, { beforeSend: queryOptions.beforeSend, jsonp: queryOptions.jsonp, withCredentials: queryOptions.withCredentials, countOnly: countQuery }) }, sortBy: function(getter, desc) { return sortCore(getter, desc, true) }, thenBy: function(getter, desc) { return sortCore(getter, desc, false) }, slice: function(skipCount, takeCount) { if (hasSlice()) return false; skip = skipCount; take = takeCount }, filter: function(criterion) { if (hasSlice() || $.isFunction(criterion)) return false; if (!$.isArray(criterion)) criterion = $.makeArray(arguments); if (criteria.length) criteria.push("and"); criteria.push(criterion) }, select: function(expr) { if (select || $.isFunction(expr)) return false; if (!$.isArray(expr)) expr = $.makeArray(arguments); select = expr }, count: function() { countQuery = true } } }; $.extend(true, data, { EdmLiteral: EdmLiteral, utils: {odata: { sendRequest: sendRequest, serializePropName: serializePropName, serializeValue: serializeValue, serializeKey: serializeKey, keyConverters: keyConverters }}, queryAdapters: {odata: createODataQueryAdapter} }); data.OData__internals = {interpretJsonFormat: interpretJsonFormat} })(jQuery, DevExpress); /*! Module core, file data.store.abstract.js */ (function($, DX, undefined) { var Class = DX.Class, abstract = DX.abstract, data = DX.data, normalizeSortingInfo = data.utils.normalizeSortingInfo; var STORE_CALLBACK_NAMES = ["loading", "loaded", "modifying", "modified", "inserting", "inserted", "updating", "updated", "removing", "removed"]; function multiLevelGroup(query, groupInfo) { query = query.groupBy(groupInfo[0].selector); if (groupInfo.length > 1) query = query.select(function(g) { return $.extend({}, g, {items: multiLevelGroup(data.query(g.items), groupInfo.slice(1)).toArray()}) }); return query } data.utils.multiLevelGroup = multiLevelGroup; function arrangeSortingInfo(groupInfo, sortInfo) { var filteredGroup = []; $.each(groupInfo, function(_, group) { var collision = $.grep(sortInfo, function(sort) { return group.selector == sort.selector }); if (collision.length < 1) filteredGroup.push(group) }); return filteredGroup.concat(sortInfo) } data.Store = Class.inherit({ ctor: function(options) { var that = this; options = options || {}; $.each(STORE_CALLBACK_NAMES, function() { var callbacks = that[this] = $.Callbacks(); if (this in options) callbacks.add(options[this]) }); this._key = options.key; this._errorHandler = options.errorHandler; this._useDefaultSearch = true }, _customLoadOptions: function() { return null }, key: function() { return this._key }, keyOf: function(obj) { if (!this._keyGetter) this._keyGetter = data.utils.compileGetter(this.key()); return this._keyGetter(obj) }, _requireKey: function() { if (!this.key()) throw Error("Key expression is required for this operation"); }, load: function(options) { var that = this; options = options || {}; this.loading.fire(options); return this._loadImpl(options).done(function(result, extra) { that.loaded.fire(result, extra) }) }, _loadImpl: function(options) { var filter = options.filter, sort = options.sort, select = options.select, group = options.group, skip = options.skip, take = options.take, q = this.createQuery(options); if (filter) q = q.filter(filter); if (group) group = normalizeSortingInfo(group); if (sort || group) { sort = normalizeSortingInfo(sort || []); if (group) sort = arrangeSortingInfo(group, sort); $.each(sort, function(index) { q = q[index ? "thenBy" : "sortBy"](this.selector, this.desc) }) } if (select) q = q.select(select); if (group) q = multiLevelGroup(q, group); if (take || skip) q = q.slice(skip || 0, take); return q.enumerate() }, createQuery: abstract, totalCount: function(options) { return this._addFailHandlers(this._totalCountImpl(options)) }, _totalCountImpl: function(options) { options = options || {}; var q = this.createQuery(), group = options.group, filter = options.filter; if (filter) q = q.filter(filter); if (group) { group = normalizeSortingInfo(group); q = multiLevelGroup(q, group) } return q.count() }, byKey: function(key, extraOptions) { return this._addFailHandlers(this._byKeyImpl(key, extraOptions)) }, _byKeyImpl: abstract, insert: function(values) { var that = this; that.modifying.fire(); that.inserting.fire(values); return that._addFailHandlers(that._insertImpl(values).done(function(callbackValues, callbackKey) { that.inserted.fire(callbackValues, callbackKey); that.modified.fire() })) }, _insertImpl: abstract, update: function(key, values) { var that = this; that.modifying.fire(); that.updating.fire(key, values); return that._addFailHandlers(that._updateImpl(key, values).done(function(callbackKey, callbackValues) { that.updated.fire(callbackKey, callbackValues); that.modified.fire() })) }, _updateImpl: abstract, remove: function(key) { var that = this; that.modifying.fire(); that.removing.fire(key); return that._addFailHandlers(that._removeImpl(key).done(function(callbackKey) { that.removed.fire(callbackKey); that.modified.fire() })) }, _removeImpl: abstract, _addFailHandlers: function(deferred) { return deferred.fail(this._errorHandler, data._handleError) } }) })(jQuery, DevExpress); /*! Module core, file data.store.array.js */ (function($, DX, undefined) { var data = DX.data, Guid = data.Guid; var trivialPromise = function(_) { var d = $.Deferred(); return d.resolve.apply(d, arguments).promise() }; var rejectedPromise = function(_) { var d = $.Deferred(); return d.reject.apply(d, arguments).promise() }; data.ArrayStore = data.Store.inherit({ ctor: function(options) { if ($.isArray(options)) options = {data: options}; else options = options || {}; this.callBase(options); var initialArray = options.data; if (initialArray && !$.isArray(initialArray)) throw Error("Invalid 'data' option value"); this._array = initialArray || [] }, createQuery: function() { return data.query(this._array, {errorHandler: this._errorHandler}) }, _byKeyImpl: function(key) { return trivialPromise(this._array[this._indexByKey(key)]) }, _insertImpl: function(values) { var keyExpr = this.key(), keyValue, obj = {}; $.extend(obj, values); if (keyExpr) { keyValue = this.keyOf(obj); if (keyValue === undefined || typeof keyValue === "object" && $.isEmptyObject(keyValue)) { if ($.isArray(keyExpr)) throw Error("Compound keys cannot be auto-generated"); keyValue = obj[keyExpr] = String(new Guid) } else if (this._array[this._indexByKey(keyValue)] !== undefined) return rejectedPromise(Error("Attempt to insert an item with the duplicate key")) } else keyValue = obj; this._array.push(obj); return trivialPromise(values, keyValue) }, _updateImpl: function(key, values) { var target; if (this.key()) { var index = this._indexByKey(key); if (index < 0) return rejectedPromise(Error("Data item not found")); target = this._array[index] } else target = key; DX.utils.deepExtendArraySafe(target, values); return trivialPromise(key, values) }, _removeImpl: function(key) { var index = this._indexByKey(key); if (index > -1) this._array.splice(index, 1); return trivialPromise(key) }, _indexByKey: function(key) { for (var i = 0, arrayLength = this._array.length; i < arrayLength; i++) if (data.utils.keysEqual(this.key(), this.keyOf(this._array[i]), key)) return i; return -1 }, clear: function() { this._array = [] } }) })(jQuery, DevExpress); /*! Module core, file data.store.local.js */ (function($, DX, undefined) { var Class = DX.Class, abstract = DX.abstract, data = DX.data; var LocalStoreBackend = Class.inherit({ ctor: function(store, storeOptions) { this._store = store; this._dirty = false; var immediate = this._immediate = storeOptions.immediate; var flushInterval = Math.max(100, storeOptions.flushInterval || 10 * 1000); if (!immediate) { var saveProxy = $.proxy(this.save, this); setInterval(saveProxy, flushInterval); $(window).on("beforeunload", saveProxy); if (window.cordova) document.addEventListener("pause", saveProxy, false) } }, notifyChanged: function() { this._dirty = true; if (this._immediate) this.save() }, load: function() { this._store._array = this._loadImpl(); this._dirty = false }, save: function() { if (!this._dirty) return; this._saveImpl(this._store._array); this._dirty = false }, _loadImpl: abstract, _saveImpl: abstract }); var DomLocalStoreBackend = LocalStoreBackend.inherit({ ctor: function(store, storeOptions) { this.callBase(store, storeOptions); var name = storeOptions.name; if (!name) throw Error("Name is required"); this._key = "dx-data-localStore-" + name }, _loadImpl: function() { var raw = localStorage.getItem(this._key); if (raw) return JSON.parse(raw); return [] }, _saveImpl: function(array) { if (!array.length) localStorage.removeItem(this._key); else localStorage.setItem(this._key, JSON.stringify(array)) } }); var localStoreBackends = {dom: DomLocalStoreBackend}; data.LocalStore = data.ArrayStore.inherit({ ctor: function(options) { if (typeof options === "string") options = {name: options}; else options = options || {}; this.callBase(options); this._backend = new localStoreBackends[options.backend || "dom"](this, options); this._backend.load() }, clear: function() { this.callBase(); this._backend.notifyChanged() }, _insertImpl: function(values) { var b = this._backend; return this.callBase(values).done($.proxy(b.notifyChanged, b)) }, _updateImpl: function(key, values) { var b = this._backend; return this.callBase(key, values).done($.proxy(b.notifyChanged, b)) }, _removeImpl: function(key) { var b = this._backend; return this.callBase(key).done($.proxy(b.notifyChanged, b)) } }) })(jQuery, DevExpress); /*! Module core, file data.store.odata.js */ (function($, DX, undefined) { var Class = DX.Class, data = DX.data, utils = DX.utils, odataUtils = data.utils.odata; var escapeServiceOperationParams = function(params, version) { if (!params) return params; var result = {}; $.each(params, function(k, v) { result[k] = odataUtils.serializeValue(v, version) }); return result }; var convertSimpleKey = function(keyType, keyValue) { var converter = odataUtils.keyConverters[keyType]; if (!converter) throw Error("Unknown key type: " + keyType); return converter(keyValue) }; var SharedMethods = { _extractServiceOptions: function(options) { options = options || {}; this._url = String(options.url).replace(/\/+$/, ""); this._beforeSend = options.beforeSend; this._jsonp = options.jsonp; this._version = options.version; this._withCredentials = options.withCredentials }, _sendRequest: function(url, method, params, payload) { return odataUtils.sendRequest({ url: url, method: method, params: params || {}, payload: payload }, { beforeSend: this._beforeSend, jsonp: this._jsonp, withCredentials: this._withCredentials }) }, version: function() { return this._version } }; var ODataStore = data.Store.inherit({ ctor: function(options) { this.callBase(options); this._extractServiceOptions(options); this._keyType = options.keyType }, _customLoadOptions: function() { return ["expand", "customQueryParams"] }, _byKeyImpl: function(key, extraOptions) { var params = {}; if (extraOptions) if (extraOptions.expand) params["$expand"] = $.map($.makeArray(extraOptions.expand), odataUtils.serializePropName).join(); return this._sendRequest(this._byKeyUrl(key), "GET", params) }, createQuery: function(loadOptions) { loadOptions = loadOptions || {}; return data.query(this._url, { beforeSend: this._beforeSend, errorHandler: this._errorHandler, jsonp: this._jsonp, version: this._version, withCredentials: this._withCredentials, params: escapeServiceOperationParams(loadOptions.customQueryParams, this._version), expand: loadOptions.expand, requireTotalCount: loadOptions.requireTotalCount }) }, _insertImpl: function(values) { this._requireKey(); var that = this, d = $.Deferred(); $.when(this._sendRequest(this._url, "POST", null, values)).done(function(serverResponse) { d.resolve(values, that.keyOf(serverResponse)) }).fail($.proxy(d.reject, d)); return d.promise() }, _updateImpl: function(key, values) { var d = $.Deferred(); $.when(this._sendRequest(this._byKeyUrl(key), "MERGE", null, values)).done(function() { d.resolve(key, values) }).fail($.proxy(d.reject, d)); return d.promise() }, _removeImpl: function(key) { var d = $.Deferred(); $.when(this._sendRequest(this._byKeyUrl(key), "DELETE")).done(function() { d.resolve(key) }).fail($.proxy(d.reject, d)); return d.promise() }, _byKeyUrl: function(key) { var keyType = this._keyType; if ($.isPlainObject(keyType)) $.each(keyType, function(subKeyName, subKeyType) { key[subKeyName] = convertSimpleKey(subKeyType, key[subKeyName]) }); else if (keyType) key = convertSimpleKey(keyType, key); return this._url + "(" + encodeURIComponent(odataUtils.serializeKey(key, this._version)) + ")" } }).include(SharedMethods); var ODataContext = Class.inherit({ ctor: function(options) { var that = this; that._extractServiceOptions(options); that._errorHandler = options.errorHandler; $.each(options.entities || [], function(entityAlias, entityOptions) { that[entityAlias] = new ODataStore($.extend({}, options, {url: that._url + "/" + encodeURIComponent(entityOptions.name || entityAlias)}, entityOptions)) }) }, get: function(operationName, params) { return this.invoke(operationName, params, "GET") }, invoke: function(operationName, params, httpMethod) { httpMethod = httpMethod || "POST"; var d = $.Deferred(); $.when(this._sendRequest(this._url + "/" + encodeURIComponent(operationName), httpMethod, escapeServiceOperationParams(params, this._version))).done(function(r) { if (r && operationName in r) r = r[operationName]; d.resolve(r) }).fail([this._errorHandler, data._handleError, $.proxy(d.reject, d)]); return d.promise() }, objectLink: function(entityAlias, key) { var store = this[entityAlias]; if (!store) throw Error("Unknown entity name or alias: " + entityAlias); if (!utils.isDefined(key)) return null; return {__metadata: {uri: store._byKeyUrl(key)}} } }).include(SharedMethods); $.extend(data, { ODataStore: ODataStore, ODataContext: ODataContext }) })(jQuery, DevExpress); /*! Module core, file data.store.rest.js */ (function($, DX, undefined) { var data = DX.data; function createAjaxFailureHandler(deferred) { return function(xhr, textStatus) { if (!xhr || !xhr.getResponseHeader) deferred.reject.apply(deferred, arguments); else deferred.reject(Error(data.utils.errorMessageFromXhr(xhr, textStatus))) } } function operationCustomizerPropName(operationName) { return "_customize" + DX.inflector.camelize(operationName, true) } function pathPropName(operationName) { return "_" + operationName + "Path" } data.RestStore = data.Store.inherit({ ctor: function(options) { DX.utils.logger.warn("RestStore is deprecated, use CustomStore instead"); var that = this; that.callBase(options); options = options || {}; that._url = String(options.url).replace(/\/+$/, ""); that._jsonp = options.jsonp; that._withCredentials = options.withCredentials; $.each(["Load", "Insert", "Update", "Remove", "ByKey", "Operation"], function() { var value = options["customize" + this]; if (value) that[operationCustomizerPropName(this)] = value }); $.each(["load", "insert", "update", "remove", "byKey"], function() { var value = options[this + "Path"]; if (value) that[pathPropName(this)] = value }) }, _loadImpl: function(options) { var d = $.Deferred(), ajaxOptions = { url: this._formatUrlNoKey("load"), type: "GET" }; $.when(this._createAjax(ajaxOptions, "load", options)).done($.proxy(d.resolve, d)).fail(createAjaxFailureHandler(d)); return this._addFailHandlers(d.promise()) }, createQuery: function() { throw Error("Not supported"); }, _insertImpl: function(values) { var d = $.Deferred(), that = this, ajaxOptions = { url: this._formatUrlNoKey("insert"), type: "POST", contentType: "application/json", data: JSON.stringify(values) }; $.when(this._createAjax(ajaxOptions, "insert")).done(function(serverResponse) { d.resolve(values, that.key() && that.keyOf(serverResponse)) }).fail(createAjaxFailureHandler(d)); return d.promise() }, _updateImpl: function(key, values) { var d = $.Deferred(), ajaxOptions = { url: this._formatUrlWithKey("update", key), type: "PUT", contentType: "application/json", data: JSON.stringify(values) }; $.when(this._createAjax(ajaxOptions, "update")).done(function() { d.resolve(key, values) }).fail(createAjaxFailureHandler(d)); return d.promise() }, _removeImpl: function(key) { var d = $.Deferred(), ajaxOptions = { url: this._formatUrlWithKey("remove", key), type: "DELETE" }; $.when(this._createAjax(ajaxOptions, "remove")).done(function() { d.resolve(key) }).fail(createAjaxFailureHandler(d)); return d.promise() }, _byKeyImpl: function(key) { var d = $.Deferred(), ajaxOptions = { url: this._formatUrlWithKey("byKey", key), type: "GET" }; $.when(this._createAjax(ajaxOptions, "byKey")).done(function(data) { d.resolve(data) }).fail(createAjaxFailureHandler(d)); return d.promise() }, _createAjax: function(ajaxOptions, operationName, extra) { var customizationFunc, customizationResult; function isDeferred(obj) { return "done" in obj && "fail" in obj } if (this._jsonp && ajaxOptions.type === "GET") ajaxOptions.dataType = "jsonp"; else $.extend(true, ajaxOptions, {xhrFields: {withCredentials: this._withCredentials}}); customizationFunc = this[operationCustomizerPropName("operation")]; if (customizationFunc) { customizationResult = customizationFunc(ajaxOptions, operationName, extra); if (customizationResult) { if (isDeferred(customizationResult)) return customizationResult; ajaxOptions = customizationResult } } customizationFunc = this[operationCustomizerPropName(operationName)]; if (customizationFunc) { customizationResult = customizationFunc(ajaxOptions, extra); if (customizationResult) { if (isDeferred(customizationResult)) return customizationResult; ajaxOptions = customizationResult } } return $.ajax(ajaxOptions) }, _formatUrlNoKey: function(operationName) { var url = this._url, path = this[pathPropName(operationName)]; if (!path) return url; if ($.isFunction(path)) return path(url); return url + "/" + path }, _formatUrlWithKey: function(operationName, key) { var url = this._url, path = this[pathPropName(operationName)]; if (!path) return url + "/" + encodeURIComponent(key); if ($.isFunction(path)) return path(url, key); return url + "/" + path + "/" + encodeURIComponent(key) } }) })(jQuery, DevExpress); /*! Module core, file data.store.custom.js */ (function($, DX, undefined) { var data = DX.data; var ERROR_QUERY_NOT_SUPPORTED = "CustomStore does not support creating queries", ERROR_MISSING_USER_FUNC = "Required option is not specified or is not a function: ", ERROR_INVALID_RETURN = "Invalid return value: "; var TOTAL_COUNT = "totalCount", LOAD = "load", BY_KEY = "byKey", INSERT = "insert", UPDATE = "update", REMOVE = "remove"; function isPromise(obj) { return obj && $.isFunction(obj.done) && $.isFunction(obj.fail) && $.isFunction(obj.promise) } function trivialPromise(value) { return $.Deferred().resolve(value).promise() } function ensureRequiredFuncOption(name, obj) { if (!$.isFunction(obj)) throw Error(ERROR_MISSING_USER_FUNC + name); } function throwInvalidUserFuncResult(name) { throw Error(ERROR_INVALID_RETURN + name); } function createUserFuncFailureHandler(pendingDeferred) { function errorMessageFromXhr(promiseArguments) { var xhr = promiseArguments[0], textStatus = promiseArguments[1]; if (!xhr || !xhr.getResponseHeader) return null; return data.utils.errorMessageFromXhr(xhr, textStatus) } return function(arg) { var error; if (arg instanceof Error) error = arg; else error = Error(errorMessageFromXhr(arguments) || arg && String(arg) || "Unknown error"); pendingDeferred.reject(error) } } data.CustomStore = data.Store.inherit({ ctor: function(options) { options = options || {}; this.callBase(options); this._useDefaultSearch = false; this._loadFunc = options[LOAD]; this._totalCountFunc = options[TOTAL_COUNT]; this._byKeyFunc = options[BY_KEY] || options.lookup; this._insertFunc = options[INSERT]; this._updateFunc = options[UPDATE]; this._removeFunc = options[REMOVE] }, createQuery: function() { throw Error(ERROR_QUERY_NOT_SUPPORTED); }, _totalCountImpl: function(options) { var userFunc = this._totalCountFunc, userResult, d = $.Deferred(); ensureRequiredFuncOption(TOTAL_COUNT, userFunc); userResult = userFunc(options); if (!isPromise(userResult)) { userResult = Number(userResult); if (!isFinite(userResult)) throwInvalidUserFuncResult(TOTAL_COUNT); userResult = trivialPromise(userResult) } userResult.done(function(count) { d.resolve(Number(count)) }).fail(createUserFuncFailureHandler(d)); return d.promise() }, _loadImpl: function(options) { var userFunc = this._loadFunc, userResult, d = $.Deferred(); ensureRequiredFuncOption(LOAD, userFunc); userResult = userFunc(options); if ($.isArray(userResult)) userResult = trivialPromise(userResult); else if (userResult === null || userResult === undefined) userResult = trivialPromise([]); else if (!isPromise(userResult)) throwInvalidUserFuncResult(LOAD); userResult.done(function(data, extra) { d.resolve(data, extra) }).fail(createUserFuncFailureHandler(d)); return this._addFailHandlers(d.promise()) }, _byKeyImpl: function(key) { var userFunc = this._byKeyFunc, userResult, d = $.Deferred(); ensureRequiredFuncOption(BY_KEY, userFunc); userResult = userFunc(key); if (!isPromise(userResult)) userResult = trivialPromise(userResult); userResult.done(function(obj) { d.resolve(obj) }).fail(createUserFuncFailureHandler(d)); return d.promise() }, _insertImpl: function(values) { var userFunc = this._insertFunc, userResult, d = $.Deferred(); ensureRequiredFuncOption(INSERT, userFunc); userResult = userFunc(values); if (!isPromise(userResult)) userResult = trivialPromise(userResult); userResult.done(function(newKey) { d.resolve(values, newKey) }).fail(createUserFuncFailureHandler(d)); return d.promise() }, _updateImpl: function(key, values) { var userFunc = this._updateFunc, userResult, d = $.Deferred(); ensureRequiredFuncOption(UPDATE, userFunc); userResult = userFunc(key, values); if (!isPromise(userResult)) userResult = trivialPromise(); userResult.done(function() { d.resolve(key, values) }).fail(createUserFuncFailureHandler(d)); return d.promise() }, _removeImpl: function(key) { var userFunc = this._removeFunc, userResult, d = $.Deferred(); ensureRequiredFuncOption(REMOVE, userFunc); userResult = userFunc(key); if (!isPromise(userResult)) userResult = trivialPromise(); userResult.done(function() { d.resolve(key) }).fail(createUserFuncFailureHandler(d)); return d.promise() } }); data.CustomStore_internals = {ERRORS: { QUERY_NOT_SUPPORTED: ERROR_QUERY_NOT_SUPPORTED, MISSING_USER_FUNC: ERROR_MISSING_USER_FUNC, INVALID_RETURN: ERROR_INVALID_RETURN }} })(jQuery, DevExpress); /*! Module core, file data.dataSource.js */ (function($, DX, undefined) { var data = DX.data, CustomStore = data.CustomStore, Class = DX.Class; var storeTypeRegistry = { jaydata: "JayDataStore", breeze: "BreezeStore", odata: "ODataStore", local: "LocalStore", array: "ArrayStore" }; function normalizeDataSourceOptions(options) { var store; function createCustomStoreFromLoadFunc() { var storeConfig = {}; $.each(["key", "load", "byKey", "lookup", "totalCount", "insert", "update", "remove"], function() { storeConfig[this] = options[this]; delete options[this] }); return new CustomStore(storeConfig) } function createStoreFromConfig(storeConfig) { var storeCtor = data[storeTypeRegistry[storeConfig.type]]; delete storeConfig.type; return new storeCtor(storeConfig) } function createCustomStoreFromUrl(url) { return new CustomStore({load: function() { return $.getJSON(url) }}) } if (typeof options === "string") options = createCustomStoreFromUrl(options); if (options === undefined) options = []; if ($.isArray(options) || options instanceof data.Store) options = {store: options}; else options = $.extend({}, options); if (options.store === undefined) options.store = []; store = options.store; if ("load" in options) store = createCustomStoreFromLoadFunc(); else if ($.isArray(store)) store = new data.ArrayStore(store); else if ($.isPlainObject(store)) store = createStoreFromConfig($.extend({}, store)); options.store = store; return options } function normalizeStoreLoadOptionAccessorArguments(originalArguments) { switch (originalArguments.length) { case 0: return undefined; case 1: return originalArguments[0] } return $.makeArray(originalArguments) } function generateStoreLoadOptionAccessor(optionName) { return function() { var args = normalizeStoreLoadOptionAccessorArguments(arguments); if (args !== undefined) this._storeLoadOptions[optionName] = args; return this._storeLoadOptions[optionName] } } function addOldUserDataSourceBackwardCompatibilityOptions(dataSource, storeLoadOptions) { storeLoadOptions.refresh = !dataSource._paginate || dataSource._pageIndex === 0; if (storeLoadOptions.searchValue !== null) storeLoadOptions.searchString = storeLoadOptions.searchValue } var DataSource = Class.inherit({ ctor: function(options) { options = normalizeDataSourceOptions(options); this._store = options.store; this._storeLoadOptions = this._extractLoadOptions(options); this._mapFunc = options.map; this._postProcessFunc = options.postProcess; this._pageIndex = 0; this._pageSize = options.pageSize !== undefined ? options.pageSize : 20; this._items = []; this._totalCount = -1; this._isLoaded = false; this._loadingCount = 0; this._preferSync = options._preferSync; this._loadQueue = this._createLoadQueue(); this._searchValue = "searchValue" in options ? options.searchValue : null; this._searchOperation = options.searchOperation || "contains"; this._searchExpr = options.searchExpr; this._paginate = options.paginate; if (this._paginate === undefined) this._paginate = !this.group(); this._isLastPage = !this._paginate; this._userData = {}; this.changed = $.Callbacks(); this.loadError = $.Callbacks(); this.loadingChanged = $.Callbacks() }, dispose: function() { this.changed.empty(); this.loadError.empty(); this.loadingChanged.empty(); delete this._store; this._disposed = true }, _extractLoadOptions: function(options) { var result = {}, names = ["sort", "filter", "select", "group", "requireTotalCount"], customNames = this._store._customLoadOptions(); if (customNames) names = names.concat(customNames); $.each(names, function() { result[this] = options[this] }); return result }, loadOptions: function() { return this._storeLoadOptions }, items: function() { return this._items }, pageIndex: function(newIndex) { if (newIndex !== undefined) { this._pageIndex = newIndex; this._isLastPage = !this._paginate } return this._pageIndex }, paginate: function(value) { if (arguments.length < 1) return this._paginate; value = !!value; if (this._paginate !== value) { this._paginate = value; this.pageIndex(0) } }, isLastPage: function() { return this._isLastPage }, sort: generateStoreLoadOptionAccessor("sort"), filter: function() { var newFilter = normalizeStoreLoadOptionAccessorArguments(arguments); if (newFilter !== undefined) { this._storeLoadOptions.filter = newFilter; this.pageIndex(0) } return this._storeLoadOptions.filter }, group: generateStoreLoadOptionAccessor("group"), select: generateStoreLoadOptionAccessor("select"), searchValue: function(value) { if (value !== undefined) { this.pageIndex(0); this._searchValue = value } return this._searchValue }, searchOperation: function(op) { if (op !== undefined) { this.pageIndex(0); this._searchOperation = op } return this._searchOperation }, searchExpr: function(expr) { var argc = arguments.length; if (argc) { if (argc > 1) expr = $.makeArray(arguments); this.pageIndex(0); this._searchExpr = expr } return this._searchExpr }, store: function() { return this._store }, key: function() { return this._store && this._store.key() }, totalCount: function() { return this._totalCount }, isLoaded: function() { return this._isLoaded }, isLoading: function() { return this._loadingCount > 0 }, _createLoadQueue: function() { return DX.createQueue() }, _changeLoadingCount: function(increment) { var oldLoading = this.isLoading(), newLoading; this._loadingCount += increment; newLoading = this.isLoading(); if (oldLoading ^ newLoading) this.loadingChanged.fire(newLoading) }, _scheduleLoadCallbacks: function(deferred) { var thisSource = this; thisSource._changeLoadingCount(1); deferred.always(function() { thisSource._changeLoadingCount(-1) }) }, _scheduleChangedCallbacks: function(deferred) { var that = this; deferred.done(function() { that.changed.fire() }) }, loadSingle: function(propName, propValue) { var that = this; var d = $.Deferred().fail(this.loadError.fire), key = this.key(), store = this._store, loadOptions = this._createStoreLoadOptions(); function handleSuccess(data) { d.resolve(that._transformLoadedData(data)[0]) } if (arguments.length < 2) { propValue = propName; propName = key } delete loadOptions.skip; delete loadOptions.group; delete loadOptions.refresh; delete loadOptions.pageIndex; delete loadOptions.searchString; if (propName === key || store instanceof data.CustomStore) store.byKey(propValue, loadOptions).done(handleSuccess).fail(d.reject); else { loadOptions.take = 1; loadOptions._preferSync = true; loadOptions.filter = loadOptions.filter ? [loadOptions.filter, [propName, propValue]] : [propName, propValue]; store.load(loadOptions).done(handleSuccess).fail(d.reject) } return d.promise() }, load: function() { var thisSource = this, d = $.Deferred(), errorCallback = this.loadError, storeLoadOptions; this._scheduleLoadCallbacks(d); this._scheduleChangedCallbacks(d); storeLoadOptions = this._createStoreLoadOptions(); function loadTask() { if (thisSource._disposed) return undefined; return thisSource._loadFromStore(storeLoadOptions, d) } this._loadQueue.add(function() { loadTask(); return d.promise() }, function() { thisSource._changeLoadingCount(-1) }); return d.promise().fail($.proxy(errorCallback.fire, errorCallback)) }, _addSearchOptions: function(storeLoadOptions) { if (this._disposed) return; if (this.store()._useDefaultSearch) this._addSearchFilter(storeLoadOptions); else { storeLoadOptions.searchValue = this._searchValue; storeLoadOptions.searchExpr = this._searchExpr } }, _createStoreLoadOptions: function() { var result = $.extend({}, this._storeLoadOptions); this._addSearchOptions(result); if (this._paginate) { result.pageIndex = this._pageIndex; if (this._pageSize) { result.skip = this._pageIndex * this._pageSize; result.take = this._pageSize } } result.userData = this._userData; addOldUserDataSourceBackwardCompatibilityOptions(this, result); return result }, _addSearchFilter: function(storeLoadOptions) { var value = this._searchValue, op = this._searchOperation, selector = this._searchExpr, searchFilter = []; if (!value) return; if (!selector) selector = "this"; if (!$.isArray(selector)) selector = [selector]; $.each(selector, function(i, item) { if (searchFilter.length) searchFilter.push("or"); searchFilter.push([item, op, value]) }); if (storeLoadOptions.filter) storeLoadOptions.filter = [searchFilter, storeLoadOptions.filter]; else storeLoadOptions.filter = searchFilter }, _loadFromStore: function(storeLoadOptions, pendingDeferred) { var thisSource = this; function handleSuccess(data, extra) { function processResult() { thisSource._processStoreLoadResult(data, extra, storeLoadOptions, pendingDeferred) } if (thisSource._preferSync) processResult(); else DX.utils.executeAsync(processResult) } return this.store().load(storeLoadOptions).done(handleSuccess).fail($.proxy(pendingDeferred.reject, pendingDeferred)) }, _processStoreLoadResult: function(data, extra, storeLoadOptions, pendingDeferred) { var thisSource = this; function resolvePendingDeferred() { thisSource._isLoaded = true; thisSource._totalCount = isFinite(extra.totalCount) ? extra.totalCount : -1; return pendingDeferred.resolve(data, extra) } function proceedLoadingTotalCount() { thisSource.store().totalCount(storeLoadOptions).done(function(count) { extra.totalCount = count; resolvePendingDeferred() }).fail(function(){}) } if (thisSource._disposed) return; data = thisSource._transformLoadedData(data); if (!$.isPlainObject(extra)) extra = {}; thisSource._items = data; if (!data.length || !thisSource._paginate || thisSource._pageSize && data.length < thisSource._pageSize) thisSource._isLastPage = true; if (storeLoadOptions.requireTotalCount && !isFinite(extra.totalCount)) proceedLoadingTotalCount(); else resolvePendingDeferred() }, _transformLoadedData: function(data) { var result = $.makeArray(data); if (this._mapFunc) result = $.map(result, this._mapFunc); if (this._postProcessFunc) result = this._postProcessFunc(result); return result } }); data.Store.redefine({toDataSource: function(options) { DX.utils.logger.warn("toDataSource() method is deprecated, use 'new DevExpress.data.DataSource(...)' instead"); return new DataSource($.extend({store: this}, options)) }}); $.extend(true, data, { DataSource: DataSource, createDataSource: function(options) { DX.utils.logger.warn("createDataSource() method is deprecated, use 'new DevExpress.data.DataSource(...)' instead"); return new DataSource(options) }, utils: { storeTypeRegistry: storeTypeRegistry, normalizeDataSourceOptions: normalizeDataSourceOptions } }) })(jQuery, DevExpress); /*! Module core, file ko.js */ (function($, DX, undefined) { if (!DX.support.hasKo) return; var ko = window.ko; (function checkKnockoutVersion(version) { version = version.split("."); if (version[0] < 2 || version[0] == 2 && version[1] < 3) throw Error("Your version of KnockoutJS is too old. Please upgrade KnockoutJS to 2.3.0 or later."); })(ko.version) })(jQuery, DevExpress); /*! Module core, file ng.js */ (function($, DX, undefined) { if (!DX.support.hasNg) return; DX.ng = {module: window.angular.module("dx", ["ngSanitize"])} })(jQuery, DevExpress); /*! Module core, file component.js */ (function($, DX, undefined) { var ui = DX.ui, utils = DX.utils, dataUtils = DX.data.utils; var Component = DX.Class.inherit({ NAME: "Component", _deprecatedOptions: {}, _optionAliases: {}, _setDefaultOptions: function(){}, _defaultOptionsRules: function() { return [] }, _setOptionsByDevice: function() { var rules = this._defaultOptionsRules(), currentDevice = DX.devices.current(), result = {}; if (this._customRules) rules = rules.concat(this._customRules); var deviceMatch = function(device, filter) { filter = $.makeArray(filter); return filter.length === 1 && $.isEmptyObject(filter[0]) || utils.findBestMatches(device, filter).length > 0 }; $.each(rules, function(index, rule) { var deviceFilter = rule.device || {}, match; if ($.isFunction(deviceFilter)) match = deviceFilter(currentDevice); else match = deviceMatch(currentDevice, deviceFilter); if (match) $.extend(result, rule.options) }); this.option(result) }, _optionsByReference: function() { return {} }, ctor: function(options) { if (!this.NAME) throw Error("NAME is not specified"); this._options = {}; this._updateLockCount = 0; this.optionChanged = $.Callbacks(); this.beginUpdate(); try { this._suppressDeprecatedWarnings(); this._setDefaultOptions(); this._setOptionsByDevice(); this._resumeDeprecatedWarnings(); this._initialOptions = $.extend({}, this.option()); this._initOptions(options || {}) } finally { this.endUpdate() } }, _initOptions: function(options) { this.option(options) }, _optionValuesEqual: function(name, oldValue, newValue) { oldValue = dataUtils.toComparable(oldValue, true); newValue = dataUtils.toComparable(newValue, true); if (oldValue && newValue && oldValue.jquery && newValue.jquery) return newValue.is(oldValue); if (oldValue === null || typeof oldValue !== "object") return oldValue === newValue; return false }, _init: $.noop, _optionChanged: $.noop, instance: function() { return this }, beginUpdate: function() { this._updateLockCount++ }, endUpdate: function() { this._updateLockCount--; if (!this._updateLockCount) if (!this._initializing && !this._initialized) { this._initializing = true; try { this._init() } finally { this._initializing = false; this._initialized = true } } }, _logWarningIfDeprecated: function(option) { var info = this._deprecatedOptions[option]; if (info && !this._deprecatedOptionsSuppressed) this._logDeprecatedWarning(option, info) }, _logDeprecatedWarningCount: 0, _logDeprecatedWarning: function(option, info) { utils.logger.warn("'" + option + "' option is deprecated since " + info.since + ". " + info.message); ++this._logDeprecatedWarningCount }, _suppressDeprecatedWarnings: function() { this._deprecatedOptionsSuppressed = true }, _resumeDeprecatedWarnings: function() { this._deprecatedOptionsSuppressed = false }, _getOptionAliases: function(option) { return $.map(this._optionAliases, function(aliasedOption, alias) { return option === aliasedOption ? alias : undefined }) }, _notifyOptionChanged: function(option, value, previousValue) { var that = this, optionWithAliases; if (this._initialized) { optionWithAliases = this._getOptionAliases(option); optionWithAliases.push(option); $.each(optionWithAliases, function(index, name) { var topLevelName = name.split(/[.\[]/)[0]; that.optionChanged.fireWith(that, [topLevelName, value, previousValue]); that._optionChanged(topLevelName, value, previousValue) }) } }, initialOption: function(optionName) { var options = this._initialOptions; return options[optionName] }, option: function(options) { var that = this, name = options, value = arguments[1]; if (arguments.length < 2 && $.type(name) !== "object") { if (name) { this._logWarningIfDeprecated(name); if (this._optionAliases[name]) name = this._optionAliases[name] } $.each(this._optionAliases, function(alias, option) { that._options[alias] = dataUtils.compileGetter(option)(that._options, {functionsAsIs: true}) }); return dataUtils.compileGetter(name)(that._options, {functionsAsIs: true}) } if (typeof name === "string") { options = {}; options[name] = value } that.beginUpdate(); try { $.each(options, function(name, value) { that._logWarningIfDeprecated(name); if (that._optionAliases[name]) name = that._optionAliases[name]; var prevValue = dataUtils.compileGetter(name)(that._options, {functionsAsIs: true}); if (that._optionValuesEqual(name, prevValue, value)) return; dataUtils.compileSetter(name)(that._options, value, { functionsAsIs: true, merge: !that._optionsByReference()[name] }); that._notifyOptionChanged(name, value, prevValue) }) } finally { that.endUpdate() } } }); $.extend(DX, {Component: Component}) })(jQuery, DevExpress); /*! Module core, file DOMComponent.js */ (function($, DX, undefined) { var windowResizeCallbacks = DX.utils.windowResizeCallbacks; var RTL_DIRECTION_CLASS = "dx-rtl", COMPONENT_NAMES_DATA_KEY = "dxComponents", VISIBILITY_CHANGE_CLASS = "dx-visibility-change-handler", VISIBILITY_CHANGE_EVENTNAMESPACE = "dxVisibilityChange"; var DOMComponent = DX.Component.inherit({ NAME: "DOMComponent", NAMESPACE: DX, _setDefaultOptions: function() { this.callBase(); this.option({rtlEnabled: DX.rtlEnabled}) }, ctor: function(element, options) { this._$element = $(element); this._element().data(this.NAME, this); this._attachInstanceToElement(this._$element); this.disposing = $.Callbacks(); this.callBase(options) }, _attachInstanceToElement: $.noop, _visibilityChanged: DX.abstract, _dimensionChanged: DX.abstract, _init: function() { this.callBase(); this._attachWindowResizeCallback() }, _attachWindowResizeCallback: function() { if (this._isDimensionChangeSupported()) { var windowResizeCallBack = this._windowResizeCallBack = $.proxy(this._dimensionChanged, this); windowResizeCallbacks.add(windowResizeCallBack) } }, _isDimensionChangeSupported: function() { return this._dimensionChanged !== DX.abstract }, _render: function() { this._toggleRTLDirection(this.option("rtlEnabled")); this._renderVisiblityChange() }, _renderVisiblityChange: function() { if (!this._isVisibilityChangeSupported()) return; this._element().addClass(VISIBILITY_CHANGE_CLASS); this._attachVisiblityChangeHandlers() }, _attachVisiblityChangeHandlers: function() { var that = this; that._element().off("." + VISIBILITY_CHANGE_EVENTNAMESPACE).on("dxhiding." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() { that._visibilityChanged(false) }).on("dxshown." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() { that._visibilityChanged(true) }) }, _isVisibilityChangeSupported: function() { return this._visibilityChanged !== DX.abstract }, _clean: $.noop, _modelByElement: $.noop, _invalidate: function() { if (!this._updateLockCount) throw Error("Invalidate called outside update transaction"); this._requireRefresh = true }, _refresh: function() { this._clean(); this._render() }, _dispose: function() { this._clean(); this._detachWindowResizeCallback(); this.optionChanged.empty(); this.disposing.fireWith(this).empty() }, _detachWindowResizeCallback: function() { if (this._isDimensionChangeSupported()) windowResizeCallbacks.remove(this._windowResizeCallBack) }, _toggleRTLDirection: function(rtl) { this._element().toggleClass(RTL_DIRECTION_CLASS, rtl) }, _createAction: function(actionSource, config) { var that = this; config = $.extend({}, config); var element = config.element || that._element(), model = that._modelByElement(element); config.context = model || that; config.component = that; var action = new DX.Action(actionSource, config); return function(e) { if (!arguments.length) e = {}; if (e instanceof $.Event) throw Error("Action must be executed with jQuery.Event like action({ jQueryEvent: event })"); if (!$.isPlainObject(e)) e = {actionValue: e}; return action.execute.call(action, $.extend(e, { component: that, element: element, model: model })) } }, _createActionByOption: function(optionName, config) { if (typeof optionName !== "string") throw Error("Option name type is unexpected"); this._suppressDeprecatedWarnings(); var action = this._createAction(this.option(optionName), config); this._resumeDeprecatedWarnings(); return action }, _optionChanged: function(name, value, prevValue) { if (name === "rtlEnabled") this._invalidate() }, _element: function() { return this._$element }, endUpdate: function() { var requireRender = !this._initializing && !this._initialized; this.callBase.apply(this, arguments); if (!this._updateLockCount) if (requireRender) this._render(); else if (this._requireRefresh) { this._requireRefresh = false; this._refresh() } } }); var registerComponent = function(name, componentClass) { componentClass.redefine({_attachInstanceToElement: function($element) { $element.data(name, this); if (!$element.data(COMPONENT_NAMES_DATA_KEY)) $element.data(COMPONENT_NAMES_DATA_KEY, []); $element.data(COMPONENT_NAMES_DATA_KEY).push(name) }}); componentClass.prototype.NAMESPACE[name] = componentClass; componentClass.prototype.NAME = name; componentClass.defaultOptions = function(rule) { componentClass.prototype._customRules = componentClass.prototype._customRules || []; componentClass.prototype._customRules.push(rule) }; $.fn[name] = function(options) { var isMemberInvoke = typeof options === "string", result; if (isMemberInvoke) { var memberName = options, memberArgs = $.makeArray(arguments).slice(1); this.each(function() { var instance = $(this).data(name); if (!instance) throw Error(DX.utils.stringFormat("Component {0} has not been initialized on this element", name)); var member = instance[memberName], memberValue = member.apply(instance, memberArgs); if (result === undefined) result = memberValue }) } else { this.each(function() { var instance = $(this).data(name); if (instance) instance.option(options); else new componentClass(this, options) }); result = this } return result } }; var getComponents = function(element) { element = $(element); var names = element.data(COMPONENT_NAMES_DATA_KEY); if (!names) return []; return $.map(names, function(name) { return element.data(name) }) }; var disposeComponents = function() { $.each(getComponents(this), function() { this._dispose() }) }; var originalCleanData = $.cleanData; $.cleanData = function(element) { $.each(element, disposeComponents); return originalCleanData.apply(this, arguments) }; registerComponent("DOMComponent", DOMComponent); DX.registerComponent = registerComponent })(jQuery, DevExpress); /*! Module core, file social.js */ DevExpress.social = {}; /*! Module core, file facebook.js */ (function($, DX, undefined) { function notifyDeprecated() { DX.utils.logger.warn("DevExpress.social API is deprecated. Use official Facebook library instead") } var social = DX.social; var location = window.location, navigator = window.navigator, encodeURIComponent = window.encodeURIComponent, decodeURIComponent = window.decodeURIComponent, iosStandaloneMode = navigator.standalone, cordovaMode = false; if (window.cordova) $(document).on("deviceready", function() { cordovaMode = true }); var ACCESS_TOKEN_KEY = "dx-facebook-access-token", IOS_STANDALONE_STEP1_KEY = "dx-facebook-step1", IOS_STANDALONE_STEP2_KEY = "dx-facebook-step2"; var accessToken = null, expires = null, connectionChanged = $.Callbacks(); var pendingLoginRedirectUrl; var isConnected = function() { return !!accessToken }; var getAccessTokenObject = function() { return { accessToken: accessToken, expiresIn: accessToken ? expires : 0 } }; var FB = social.Facebook = { loginRedirectUrl: "FacebookLoginCallback.html", connectionChanged: connectionChanged, isConnected: isConnected, getAccessTokenObject: getAccessTokenObject, jsonp: false }; var login = function(appId, options) { notifyDeprecated(); options = options || {}; if (cordovaMode) pendingLoginRedirectUrl = "https://www.facebook.com/connect/login_success.html"; else pendingLoginRedirectUrl = formatLoginRedirectUrl(); var scope = (options.permissions || []).join(), url = "https://www.facebook.com/dialog/oauth?display=popup&client_id=" + appId + "&redirect_uri=" + encodeURIComponent(pendingLoginRedirectUrl) + "&scope=" + encodeURIComponent(scope) + "&response_type=token"; if (iosStandaloneMode) putData(IOS_STANDALONE_STEP1_KEY, location.href); if (cordovaMode) startLogin_cordova(url); else startLogin_browser(url) }; var formatLoginRedirectUrl = function() { var pathSegments = location.pathname.split(/\//g); pathSegments.pop(); pathSegments.push(FB.loginRedirectUrl); return location.protocol + "//" + location.host + pathSegments.join("/") }; var startLogin_browser = function(loginUrl) { var width = 512, height = 320, left = (screen.width - width) / 2, top = (screen.height - height) / 2; window.open(loginUrl, null, "width=" + width + ",height=" + height + ",toolbar=0,scrollbars=0,status=0,resizable=0,menuBar=0,left=" + left + ",top=" + top) }; var startLogin_cordova = function(loginUrl) { var ref = window.open(loginUrl, "_blank"); ref.addEventListener('exit', function(event) { pendingLoginRedirectUrl = null }); ref.addEventListener('loadstop', function(event) { var url = unescape(event.url); if (url.indexOf(pendingLoginRedirectUrl) === 0) { ref.close(); _processLoginRedirectUrl(url) } }) }; var handleLoginRedirect = function() { var opener = window.opener; if (iosStandaloneMode) { putData(IOS_STANDALONE_STEP2_KEY, location.href); location.href = getData(IOS_STANDALONE_STEP1_KEY) } else if (opener && opener.DevExpress) { opener.DevExpress.social.Facebook._processLoginRedirectUrl(location.href); window.close() } }; var _processLoginRedirectUrl = function(url) { var params = parseUrlFragment(url); expires = params.expires_in; changeToken(params.access_token); pendingLoginRedirectUrl = null }; var parseUrlFragment = function(url) { var hash = url.split("#")[1]; if (!hash) return {}; var pairs = hash.split(/&/g), result = {}; $.each(pairs, function(i) { var splitPair = this.split("="); result[splitPair[0]] = decodeURIComponent(splitPair[1]) }); return result }; var logout = function() { notifyDeprecated(); changeToken(null) }; var changeToken = function(value) { if (value === accessToken) return; accessToken = value; putData(ACCESS_TOKEN_KEY, value); connectionChanged.fire(!!value) }; var api = function(resource, method, params) { notifyDeprecated(); if (!isConnected()) throw Error("Not connected"); if (typeof method !== "string") { params = method; method = undefined } method = (method || "get").toLowerCase(); var d = $.Deferred(); var args = arguments; $.ajax({ url: "https://graph.facebook.com/" + resource, type: method, data: $.extend({access_token: accessToken}, params), dataType: FB.jsonp && method === "get" ? "jsonp" : "json" }).done(function(response) { response = response || simulateErrorResponse(); if (response.error) d.reject(response.error); else d.resolve(response) }).fail(function(xhr) { var response; try { response = $.parseJSON(xhr.responseText); var tries = args[3] || 0; if (tries++ < 3 && response.error.code == 190 && response.error.error_subcode == 466) { setTimeout(function() { api(resource, method, params, tries).done(function(result) { d.resolve(result) }).fail(function(error) { d.reject(error) }) }, 500); return } } catch(x) { response = simulateErrorResponse() } d.reject(response.error) }); return d.promise() }; var simulateErrorResponse = function() { return {error: {message: "Unknown error"}} }; var ensureStorageBackend = function() { if (!hasStorageBackend()) throw Error("HTML5 sessionStorage or jQuery.cookie plugin is required"); }; var hasStorageBackend = function() { return !!($.cookie || window.sessionStorage) }; var putData = function(key, data) { ensureStorageBackend(); data = JSON.stringify(data); if (window.sessionStorage) if (data === null) sess.removeItem(key); else sessionStorage.setItem(key, data); else $.cookie(key, data) }; var getData = function(key) { ensureStorageBackend(); try { return JSON.parse(window.sessionStorage ? sessionStorage.getItem(key) : $.cookie(key)) } catch(x) { return null } }; if (hasStorageBackend()) accessToken = getData(ACCESS_TOKEN_KEY); if (iosStandaloneMode) { var url = getData(IOS_STANDALONE_STEP2_KEY); if (url) { _processLoginRedirectUrl(url); putData(IOS_STANDALONE_STEP1_KEY, null); putData(IOS_STANDALONE_STEP2_KEY, null) } } $.extend(FB, { login: login, logout: logout, handleLoginRedirect: handleLoginRedirect, _processLoginRedirectUrl: _processLoginRedirectUrl, api: api }) })(jQuery, DevExpress); /*! Module core, file ui.js */ (function($, DX, undefined) { var ui = DX.ui = {}; var TemplateProvider = DX.Class.inherit({ getTemplateClass: function() { return Template }, supportDefaultTemplate: function() { return false }, getDefaultTemplate: function() { return null } }); var Template = DX.Class.inherit({ ctor: function(element, owner) { this._template = this._element = $(element).detach(); this._owner = owner }, render: function(container) { var renderedTemplate = this._template.clone(); container.append(renderedTemplate); return renderedTemplate }, dispose: function() { this._owner = null }, owner: function() { return this._owner } }); var GESTURE_LOCK_KEY = "dxGestureLock"; DX.registerActionExecutor({ designMode: {validate: function(e) { if (DX.designMode) e.cancel = true }}, gesture: {validate: function(e) { if (!e.args.length) return; var args = e.args[0], element = args[e.validatingTargetName] || args.element; while (element && element.length) { if (element.data(GESTURE_LOCK_KEY)) { e.cancel = true; break } element = element.parent() } }}, disabled: {validate: function(e) { if (!e.args.length) return; var args = e.args[0], element = args[e.validatingTargetName] || args.element; if (element && element.is(".dx-state-disabled, .dx-state-disabled *")) e.cancel = true }} }); $.extend(ui, { TemplateProvider: TemplateProvider, Template: Template, initViewport: function() { DX.utils.logger.warn("DevExpress.ui.initViewport is deprecated. Use DX.utils.initMobileViewport instead"); DX.utils.initMobileViewport() } }); ui.__internals = ui.__internals || {}; $.extend(ui.__internals, {Template: Template}) })(jQuery, DevExpress); /*! Module core, file ko.components.js */ (function($, DX, undefined) { if (!DX.support.hasKo) return; var ko = window.ko, ui = DX.ui, LOCKS_DATA_KEY = "dxKoLocks", CREATED_WITH_KO_DATA_KEY = "dxKoCreation"; var Locks = function() { var info = {}; var currentCount = function(lockName) { return info[lockName] || 0 }; return { obtain: function(lockName) { info[lockName] = currentCount(lockName) + 1 }, release: function(lockName) { var count = currentCount(lockName); if (count < 1) throw Error("Not locked"); if (count === 1) delete info[lockName]; else info[lockName] = count - 1 }, locked: function(lockName) { return currentCount(lockName) > 0 } } }; var registerComponentKoBinding = function(componentName) { ko.bindingHandlers[componentName] = {init: function(domNode, valueAccessor) { var element = $(domNode), ctorOptions = {}, optionNameToModelMap = {}; var applyModelValueToOption = function(optionName, modelValue) { var component = element.data(componentName), locks = element.data(LOCKS_DATA_KEY), optionValue = ko.utils.unwrapObservable(modelValue); if (ko.isWriteableObservable(modelValue)) optionNameToModelMap[optionName] = modelValue; if (component) { if (locks.locked(optionName)) return; locks.obtain(optionName); try { component.option(optionName, optionValue) } finally { locks.release(optionName) } } else ctorOptions[optionName] = optionValue }; var handleOptionChanged = function(optionName, optionValue) { if (!(optionName in optionNameToModelMap)) return; var element = this._$element, locks = element.data(LOCKS_DATA_KEY); if (locks.locked(optionName)) return; locks.obtain(optionName); try { optionNameToModelMap[optionName](optionValue) } finally { locks.release(optionName) } }; var createComponent = function() { element.data(CREATED_WITH_KO_DATA_KEY, true); element[componentName](ctorOptions); ctorOptions = null; element.data(LOCKS_DATA_KEY, new Locks); element.data(componentName).optionChanged.add(handleOptionChanged) }; ko.computed(function() { var component = element.data(componentName); if (component) component.beginUpdate(); $.each(ko.unwrap(valueAccessor()), function(modelName, modelValueExpr) { ko.computed(function() { applyModelValueToOption(modelName, modelValueExpr) }, null, {disposeWhenNodeIsRemoved: domNode}) }); if (component) component.endUpdate(); else createComponent() }, null, {disposeWhenNodeIsRemoved: domNode}); return {controlsDescendantBindings: ui[componentName] && ui[componentName].subclassOf(ui.Widget)} }} }; var KoComponent = DX.DOMComponent.inherit({_modelByElement: function(element) { if (element.length) return ko.dataFor(element.get(0)) }}); var originalRegisterComponent = DX.registerComponent; var registerKoComponent = function(name, componentClass) { originalRegisterComponent(name, componentClass); registerComponentKoBinding(name) }; ko.bindingHandlers.dxAction = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) { var $element = $(element); var unwrappedValue = ko.utils.unwrapObservable(valueAccessor()), actionSource = unwrappedValue, actionOptions = {context: element}; if (unwrappedValue.execute) { actionSource = unwrappedValue.execute; $.extend(actionOptions, unwrappedValue) } var action = new DX.Action(actionSource, actionOptions); $element.off(".dxActionBinding").on("dxclick.dxActionBinding", function(e) { action.execute({ element: $element, model: viewModel, evaluate: function(expression) { var context = viewModel; if (expression.length > 0 && expression[0] === "$") context = ko.contextFor(element); var getter = DX.data.utils.compileGetter(expression); return getter(context) }, jQueryEvent: e }); if (!actionOptions.bubbling) e.stopPropagation() }) }}; var cleanKoData = function(element, andSelf) { var cleanNode = function() { ko.cleanNode(this) }; if (andSelf) element.each(cleanNode); else element.find("*").each(cleanNode) }; var originalEmpty = $.fn.empty; $.fn.empty = function() { cleanKoData(this, false); return originalEmpty.apply(this, arguments) }; var originalRemove = $.fn.remove; $.fn.remove = function(selector, keepData) { if (!keepData) { var subject = this; if (selector) subject = subject.filter(selector); cleanKoData(subject, true) } return originalRemove.call(this, selector, keepData) }; var originalHtml = $.fn.html; $.fn.html = function(value) { if (typeof value === "string") cleanKoData(this, false); return originalHtml.apply(this, arguments) }; DX.registerComponent = registerKoComponent; registerKoComponent("DOMComponent", KoComponent) })(jQuery, DevExpress); /*! Module core, file ng.components.js */ (function($, DX, undefined) { if (!DX.support.hasNg) return; var ui = DX.ui, compileSetter = DX.data.utils.compileSetter, compileGetter = DX.data.utils.compileGetter; var CREATED_WITH_NG_DATA_KEY = "dxNgCreation", TEMPLATES_DATA_KEY = "dxTemplates", COMPILER_DATA_KEY = "dxNgCompiler", DEFAULT_COMPILER_DATA_KEY = "dxDefaultCompilerGetter", ANONYMOUS_TEMPLATE_NAME = "template"; var phoneJsModule = DX.ng.module; var ComponentBuilder = DX.Class.inherit({ ctor: function(options) { this._componentName = options.componentName; this._$element = options.$element; this._$templates = options.$templates; this._scope = options.scope; this._compile = options.compile; this._ngOptions = options.ngOptions; this._componentDisposing = $.Callbacks(); this._$element.data(CREATED_WITH_NG_DATA_KEY, true); if (options.ngOptions.data) this._initDataScope(options.ngOptions.data) }, initDefaultCompilerGetter: function() { var that = this; that._$element.data(DEFAULT_COMPILER_DATA_KEY, function($template) { return that._compilerByTemplate($template) }) }, initTemplateCompilers: function() { var that = this; if (this._$templates) this._$templates.each(function(i, template) { $(template).data(COMPILER_DATA_KEY, that._compilerByTemplate(template)) }) }, initComponentWithBindings: function() { this._initComponent(this._scope); this._initComponentBindings() }, _initDataScope: function(data) { if (typeof data === "string") { var dataStr = data, rootScope = this._scope; data = rootScope.$eval(data); this._scope = rootScope.$new(); this._synchronizeDataScopes(rootScope, this._scope, data, dataStr) } $.extend(this._scope, data) }, _synchronizeDataScopes: function(parentScope, childScope, data, parentPrefix) { var that = this; $.each(data, function(fieldPath) { that._synchronizeScopeField({ parentScope: parentScope, childScope: childScope, fieldPath: fieldPath, parentPrefix: parentPrefix }) }) }, _initComponent: function(scope) { this._component = this._$element[this._componentName](this._evalOptions(scope)).data(this._componentName) }, _initComponentBindings: function() { var that = this, optionDependencies = {}; if (that._ngOptions.bindingOptions) $.each(that._ngOptions.bindingOptions, function(optionPath, valuePath) { var separatorIndex = optionPath.search(/\[|\./), optionForSubscribe = separatorIndex > -1 ? optionPath.substring(0, separatorIndex) : optionPath, prevWatchMethod, clearWatcher; if (!optionDependencies[optionForSubscribe]) optionDependencies[optionForSubscribe] = {}; optionDependencies[optionForSubscribe][optionPath] = valuePath; var watchCallback = function(newValue, oldValue) { if (newValue !== oldValue) { that._component.option(optionPath, newValue); updateWatcher() } }; var updateWatcher = function() { var watchMethod = $.isArray(that._scope.$eval(valuePath)) ? "$watchCollection" : "$watch"; if (prevWatchMethod !== watchMethod) { if (clearWatcher) clearWatcher(); clearWatcher = that._scope[watchMethod](valuePath, watchCallback, true); prevWatchMethod = watchMethod } }; updateWatcher(); that._component.disposing.add(function() { clearWatcher(); that._componentDisposing.fire() }) }); that._component.optionChanged.add(function(optionName, optionValue) { if (that._scope.$root.$$phase === "$digest" || !optionDependencies || !optionDependencies[optionName]) return; safeApply(function(scope) { $.each(optionDependencies[optionName], function(optionPath, valuePath) { var setter = compileSetter(valuePath), getter = compileGetter(optionPath); var tmpData = {}; tmpData[optionName] = optionValue; setter(scope, getter(tmpData)) }) }, that._scope) }) }, _compilerByTemplate: function(template) { var that = this, scopeItemsPath = this._getScopeItemsPath(); return function(data, index) { var $resultMarkup = $(template).clone(), templateScope; if (data !== undefined) { var dataIsScope = data.$id, templateScope = dataIsScope ? data : that._createScopeWithData(data); $resultMarkup.on("$destroy", function() { var destroyAlreadyCalled = !templateScope.$parent; if (destroyAlreadyCalled) return; templateScope.$destroy() }) } else templateScope = that._scope; if (scopeItemsPath) that._synchronizeScopes(templateScope, scopeItemsPath, index); safeApply(that._compile($resultMarkup), templateScope); return $resultMarkup } }, _getScopeItemsPath: function() { if (ui[this._componentName].subclassOf(ui.CollectionContainerWidget) && this._ngOptions.bindingOptions) return this._ngOptions.bindingOptions.items }, _createScopeWithData: function(data) { var newScope = this._scope.$new(true); if (typeof data === "object") $.extend(newScope, data); else newScope.scopeValue = data; return newScope }, _synchronizeScopes: function(itemScope, parentPrefix, itemIndex) { var that = this, item = compileGetter(parentPrefix + "[" + itemIndex + "]")(this._scope); if (!$.isPlainObject(item)) item = {scopeValue: item}; $.each(item, function(itemPath) { that._synchronizeScopeField({ parentScope: that._scope, childScope: itemScope, fieldPath: itemPath, parentPrefix: parentPrefix, itemIndex: itemIndex }) }) }, _synchronizeScopeField: function(args) { var parentScope = args.parentScope, childScope = args.childScope, fieldPath = args.fieldPath, parentPrefix = args.parentPrefix, itemIndex = args.itemIndex; var innerPathSuffix = fieldPath === "scopeValue" ? "" : "." + fieldPath, collectionField = itemIndex !== undefined, optionOuterBag = [parentPrefix], optionOuterPath; if (collectionField) optionOuterBag.push("[", itemIndex, "]"); optionOuterBag.push(innerPathSuffix); optionOuterPath = optionOuterBag.join(""); var clearParentWatcher = parentScope.$watch(optionOuterPath, function(newValue, oldValue) { if (newValue !== oldValue) compileSetter(fieldPath)(childScope, newValue) }); var clearItemWatcher = childScope.$watch(fieldPath, function(newValue, oldValue) { if (newValue !== oldValue) { if (collectionField && !compileGetter(parentPrefix)(parentScope)[itemIndex]) { clearItemWatcher(); return } compileSetter(optionOuterPath)(parentScope, newValue) } }); this._componentDisposing.add([clearParentWatcher, clearItemWatcher]) }, _evalOptions: function(scope) { var result = $.extend({}, this._ngOptions); delete result.data; delete result.bindingOptions; if (this._ngOptions.bindingOptions) $.each(this._ngOptions.bindingOptions, function(key, value) { result[key] = scope.$eval(value) }); return result } }); var safeApply = function(func, scope) { if (scope.$root.$$phase) func(scope); else scope.$apply(function() { func(scope) }) }; var extractTemplates = function($element, componentName) { if ($element.data(TEMPLATES_DATA_KEY)) return $element.data(TEMPLATES_DATA_KEY); var $templates; if (ui[componentName] && ui[componentName].subclassOf(ui.Widget) && $.trim($element.html())) { var isAnonymousTemplate = !$element.children().first().attr("data-options"); if (isAnonymousTemplate) $templates = $("
").attr("data-options", "dxTemplate: { name: '" + ANONYMOUS_TEMPLATE_NAME + "' }").append($element.contents()); else $templates = $element.children().detach(); $element.data(TEMPLATES_DATA_KEY, $templates) } return $templates }; var NgComponent = DX.DOMComponent.inherit({ _modelByElement: function(element) { if (element.length) return element.scope() }, _createAction: function() { var action = this.callBase.apply(this, arguments); var component = this, wrappedAction = function() { var that = this, scope = component._modelByElement(component._element()), args = arguments; if (!scope || scope.$root.$$phase) return action.apply(that, args); return scope.$apply(function() { return action.apply(that, args) }) }; return wrappedAction } }); var originalRegisterComponent = DX.registerComponent; var registerNgComponent = function(componentName, componentClass) { originalRegisterComponent(componentName, componentClass); phoneJsModule.directive(componentName, ["$compile", function(compile) { return { restrict: "A", compile: function($element) { var $templates = extractTemplates($element, componentName); return function(scope, $element, attrs) { var componentBuilder = new ComponentBuilder({ componentName: componentName, compile: compile, $element: $element, scope: scope, ngOptions: attrs[componentName] ? scope.$eval(attrs[componentName]) : {}, $templates: $templates }); componentBuilder.initTemplateCompilers(); componentBuilder.initDefaultCompilerGetter(); componentBuilder.initComponentWithBindings() } } } }]) }; DX.registerComponent = registerNgComponent; registerNgComponent("DOMComponent", NgComponent) })(jQuery, DevExpress); /*! Module core, file ko.templates.js */ (function($, DX, undefined) { if (!DX.support.hasKo) return; var ko = window.ko, ui = DX.ui, CREATED_WITH_KO_DATA_KEY = "dxKoCreation"; var KoTemplate = ui.Template.inherit({ ctor: function(element) { this.callBase.apply(this, arguments); this._template = $("
").append(element); this._registerKoTemplate() }, _cleanTemplateElement: function() { this._element.each(function() { ko.cleanNode(this) }) }, _registerKoTemplate: function() { var template = this._template.get(0); new ko.templateSources.anonymousTemplate(template)['nodes'](template) }, render: function(container, data) { data = data !== undefined ? data : ko.dataFor(container.get(0)) || {}; var containerBindingContext = ko.contextFor(container[0]); var bindingContext = containerBindingContext ? containerBindingContext.createChildContext(data) : data; var renderBag = $("
").appendTo(container); ko.renderTemplate(this._template.get(0), bindingContext, null, renderBag.get(0)); var result = renderBag.contents(); container.append(result); renderBag.remove(); return result }, dispose: function() { this.callBase(); this._template.remove() } }); var KoTemplateProvider = ui.TemplateProvider.inherit({ getTemplateClass: function(widget) { return this._createdWithKo(widget) ? KoTemplate : this.callBase(widget) }, supportDefaultTemplate: function(widget) { return this._createdWithKo(widget) ? true : this.callBase(widget) }, getDefaultTemplate: function(widget) { if (this._createdWithKo(widget)) return defaultKoTemplate(widget.NAME) }, _createdWithKo: function(widget) { return !!widget._element().data(CREATED_WITH_KO_DATA_KEY) } }); var defaultKoTemplate = function() { var cache = {}; return function(widgetName) { if (!DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName]) widgetName = "base"; if (!cache[widgetName]) { var html = DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName](), markup = DX.utils.createMarkupFromString(html); cache[widgetName] = new KoTemplate(markup) } return cache[widgetName] } }(); var createElementWithBindAttr = function(tagName, bindings, closeTag, additionalProperties) { closeTag = closeTag === undefined ? true : closeTag; var bindAttr = $.map(bindings, function(value, key) { return key + ":" + value }).join(","); additionalProperties = additionalProperties || ""; return "<" + tagName + " data-bind=\"" + bindAttr + "\" " + additionalProperties + ">" + (closeTag ? "" : "") }; var defaultKoTemplateBasicBindings = {css: "{ 'dx-state-disabled': $data.disabled, 'dx-state-invisible': !($data.visible === undefined || ko.unwrap($data.visible)) }"}; var DEFAULT_ITEM_TEMPLATE_GENERATORS = {base: function() { var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)], htmlBinding = createElementWithBindAttr("div", {html: "html"}), textBinding = createElementWithBindAttr("div", {text: "text"}), primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}); template.push("", htmlBinding, "", "", textBinding, "", "", primitiveBinding, "", "
"); return template.join("") }}; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxPivotTabs = function() { var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(), titleBinding = createElementWithBindAttr("span", {text: "title"}); var divInnerStart = template.indexOf(">") + 1, divInnerFinish = template.length - 6; template = [template.substring(0, divInnerStart), titleBinding, template.substring(divInnerFinish, template.length)]; return template.join("") }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxPanorama = function() { var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(), headerBinding = createElementWithBindAttr("div", {text: "header"}, true, 'class="dx-panorama-item-header"'); var divInnerStart = template.indexOf(">") + 1; template = [template.substring(0, divInnerStart), "", headerBinding, "", template.substring(divInnerStart, template.length)]; return template.join("") }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxList = function() { var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(), keyBinding = createElementWithBindAttr("div", {text: "key"}); template = [template.substring(0, template.length - 6), "" + keyBinding + "", "
"]; return template.join("") }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxToolbar = function() { var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(); template = [template.substring(0, template.length - 6), ""]; $.each(["button", "tabs", "dropDownMenu"], function() { var bindingName = DX.inflector.camelize(["dx", "-", this].join("")), bindingObj = {}; bindingObj[bindingName] = "$data.options"; template.push("", createElementWithBindAttr("div", bindingObj), "") }); template.push(""); return template.join("") }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxGallery = function() { var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(), primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}), imgBinding = createElementWithBindAttr("img", {attr: "{ src: String($data) }"}, false); template = template.replace(primitiveBinding, imgBinding); return template }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs = function() { var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(), baseTextBinding = createElementWithBindAttr("div", {text: "text"}), iconBinding = createElementWithBindAttr("span", { attr: "{ 'class': 'dx-icon-' + $data.icon }", css: "{ 'dx-icon': true }" }), iconSrcBinding = createElementWithBindAttr("img", { attr: "{ src: $data.iconSrc }", css: "{ 'dx-icon': true }" }, false), textBinding = "" + iconBinding + "" + "" + iconSrcBinding + "" + ""; template = template.replace("", "").replace(baseTextBinding, textBinding); return template }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxActionSheet = function() { return createElementWithBindAttr("div", {dxButton: "{ text: $data.text, clickAction: $data.clickAction, type: $data.type, disabled: !!ko.unwrap($data.disabled) }"}) }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxNavBar = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu = function() { var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)], iconBinding = createElementWithBindAttr("span", { attr: "{ 'class': 'dx-icon-' + $data.icon }", css: "{ 'dx-icon': true }" }), iconSrcBinding = createElementWithBindAttr("img", { attr: "{ src: $data.iconSrc }", css: "{ 'dx-icon': true }" }), textBinding = createElementWithBindAttr("span", { text: "text", css: "{ 'dx-menu-item-text': true }" }), primitiveBinding = createElementWithBindAttr("span", { text: "String($data)", css: "{ 'dx-menu-item-text': true }" }), popout = '
'; template.push('
', '', iconBinding, '', '', iconSrcBinding, '', '', textBinding, '', '', primitiveBinding, '', '', popout, '', '
', '
'); return template.join("") }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxContextMenu = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu; $.extend(ui, { TemplateProvider: KoTemplateProvider, Template: KoTemplate, defaultTemplate: defaultKoTemplate }); ui.__internals = ui.__internals || {}; $.extend(ui.__internals, {KoTemplate: KoTemplate}) })(jQuery, DevExpress); /*! Module core, file ng.templates.js */ (function($, DX, undefined) { if (!DX.support.hasNg) return; var ui = DX.ui; var CREATED_WITH_NG_DATA_KEY = "dxNgCreation", COMPILER_DATA_KEY = "dxNgCompiler", DEFAULT_COMPILER_DATA_KEY = "dxDefaultCompilerGetter"; var NgTemplate = ui.Template.inherit({ ctor: function() { this.callBase.apply(this, arguments); this._compiler = this._template.data(COMPILER_DATA_KEY) }, render: function(container, data, index) { var compiler = this._compiler, result = $.isFunction(compiler) ? compiler(data, index) : compiler; container.append(result); return result }, setCompiler: function(compilerGetter) { this._compiler = compilerGetter(this._element) } }); var NgTemplateProvider = ui.TemplateProvider.inherit({ getTemplateClass: function(widget) { if (this._createdWithNg(widget)) return NgTemplate; return this.callBase(widget) }, supportDefaultTemplate: function(widget) { return this._createdWithNg(widget) ? true : this.callBase(widget) }, getDefaultTemplate: function(widget) { if (this._createdWithNg(widget)) { var compilerGetter = widget._element().data(DEFAULT_COMPILER_DATA_KEY), template = defaultNgTemplate(widget.NAME); template.setCompiler(compilerGetter); return template } }, _createdWithNg: function(widget) { return !!widget._element().data(CREATED_WITH_NG_DATA_KEY) } }); var defaultNgTemplate = function() { var cache = {}; return function(widgetName) { if (!DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName]) widgetName = "base"; if (!cache[widgetName]) cache[widgetName] = DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName](); return new NgTemplate(cache[widgetName]) } }(); var baseElements = { container: function() { return $("
").attr("ng-class", "{ 'dx-state-invisible': !visible && visible != undefined, 'dx-state-disabled': !!disabled }") }, html: function() { return $("
").attr("ng-if", "html").attr("ng-bind-html", "html") }, text: function() { return $("
").attr("ng-if", "text").attr("ng-bind", "text") }, primitive: function() { return $("
").attr("ng-if", "scopeValue").attr("ng-bind-html", "'' + scopeValue") } }; var DEFAULT_ITEM_TEMPLATE_GENERATORS = {base: function() { return baseElements.container().append(baseElements.html()).append(baseElements.text()).append(baseElements.primitive()) }}; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxList = function() { return DEFAULT_ITEM_TEMPLATE_GENERATORS.base().append($("
").attr("ng-if", "key").attr("ng-bind", "key")) }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxToolbar = function() { var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(); $.each(["button", "tabs", "dropDownMenu"], function(i, widgetName) { var bindingName = "dx-" + DX.inflector.dasherize(this); $("
").attr("ng-if", "widget === '" + widgetName + "'").attr(bindingName, "options").appendTo(template) }); return template }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxGallery = function() { return baseElements.container().append(baseElements.html()).append(baseElements.text()).append($("").attr("ng-if", "scopeValue").attr("ng-src", "{{'' + scopeValue}}")) }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs = function() { var container = baseElements.container(); var text = $("").addClass("dx-tab-text").attr("ng-bind", "text").attr("ng-if", "text"), icon = $("").attr("ng-if", "icon").addClass("dx-icon").attr("ng-class", "'dx-icon-' + icon"), iconSrc = $("").attr("ng-if", "iconSrc").addClass("dx-icon").attr("ng-src", "{{iconSrc}}"); return container.append(baseElements.html()).append(icon).append(iconSrc).append(text).append(baseElements.primitive()) }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu = function() { var container = baseElements.container(); var content = $("
").addClass("dx-menu-item-content"), text = $("").attr("ng-if", "text").addClass("dx-menu-item-text").attr("ng-bind", "text"), icon = $("").attr("ng-if", "icon").addClass("dx-icon").attr("ng-class", "'dx-icon-' + icon"), iconSrc = $("").attr("ng-if", "iconSrc").addClass("dx-icon").attr("ng-src", "{{iconSrc}}"), popout = $("").addClass("dx-menu-item-popout-container").attr("ng-if", "items").append($("
").addClass("dx-menu-item-popout")); content.append(baseElements.html()).append(icon).append(iconSrc).append(text).append(popout).append(baseElements.primitive()).appendTo(container); return container }, DEFAULT_ITEM_TEMPLATE_GENERATORS.dxActionSheet = function() { return $("
").attr("dx-button", "{ bindingOptions: { text: 'text', clickAction: 'clickAction', type: 'type', disabled: 'disabled' } }") }; DEFAULT_ITEM_TEMPLATE_GENERATORS.dxNavBar = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs; $.extend(ui, { Template: NgTemplate, TemplateProvider: NgTemplateProvider }) })(jQuery, DevExpress); /*! Module core, file ui.themes.js */ (function($, DX, undefined) { var DX_LINK_SELECTOR = "link[rel=dx-theme]", THEME_ATTR = "data-theme", ACTIVE_ATTR = "data-active"; var context, $activeThemeLink, knownThemes, currentThemeName, pendingThemeName; var THEME_MARKER_PREFIX = "dx."; function readThemeMarker() { var element = $("
", context).addClass("dx-theme-marker").appendTo(context.documentElement), result; try { result = element.css("font-family"); if (!result) return null; result = result.replace(/["']/g, ""); if (result.substr(0, THEME_MARKER_PREFIX.length) !== THEME_MARKER_PREFIX) return null; return result.substr(THEME_MARKER_PREFIX.length) } finally { element.remove() } } function waitForThemeLoad(themeName, callback) { var timerId, waitStartTime; pendingThemeName = themeName; function handleLoaded() { pendingThemeName = null; callback() } if (isPendingThemeLoaded()) handleLoaded(); else { waitStartTime = $.now(); timerId = setInterval(function() { var isLoaded = isPendingThemeLoaded(), isTimeout = !isLoaded && $.now() - waitStartTime > 15 * 1000; if (isTimeout) DX.utils.logger.warn("Theme loading timed out: " + pendingThemeName); if (isLoaded || isTimeout) { clearInterval(timerId); handleLoaded() } }, 10) } } function isPendingThemeLoaded() { return !pendingThemeName || readThemeMarker() === pendingThemeName } function processMarkup() { var $allThemeLinks = $(DX_LINK_SELECTOR, context); if (!$allThemeLinks.length) return; knownThemes = {}; $activeThemeLink = $(DX.utils.createMarkupFromString(""), context); $allThemeLinks.each(function() { var link = $(this, context), fullThemeName = link.attr(THEME_ATTR), url = link.attr("href"), isActive = link.attr(ACTIVE_ATTR) === "true"; knownThemes[fullThemeName] = { url: url, isActive: isActive } }); $allThemeLinks.last().after($activeThemeLink); $allThemeLinks.remove() } function resolveFullThemeName(desiredThemeName) { var desiredThemeParts = desiredThemeName.split("."), result = null; if (knownThemes) $.each(knownThemes, function(knownThemeName, themeData) { var knownThemeParts = knownThemeName.split("."); if (knownThemeParts[0] !== desiredThemeParts[0]) return; if (desiredThemeParts[1] && desiredThemeParts[1] !== knownThemeParts[1]) return; if (!result || themeData.isActive) result = knownThemeName; if (themeData.isActive) return false }); return result } function initContext(newContext) { try { if (newContext !== context) knownThemes = null } catch(x) { knownThemes = null } context = newContext } function init(options) { options = options || {}; initContext(options.context || document); processMarkup(); currentThemeName = undefined; current(options) } function current(options) { if (!arguments.length) return currentThemeName || readThemeMarker(); options = options || {}; if (typeof options === "string") options = {theme: options}; var isAutoInit = options._autoInit, loadCallback = options.loadCallback, currentThemeData; currentThemeName = options.theme || currentThemeName; if (isAutoInit && !currentThemeName) currentThemeName = themeNameFromDevice(DX.devices.current()); currentThemeName = resolveFullThemeName(currentThemeName); if (currentThemeName) currentThemeData = knownThemes[currentThemeName]; if (currentThemeData) { $activeThemeLink.removeAttr("href"); $activeThemeLink.attr("href", knownThemes[currentThemeName].url); if (loadCallback) waitForThemeLoad(currentThemeName, loadCallback); else if (pendingThemeName) pendingThemeName = currentThemeName } else if (isAutoInit) { if (loadCallback) loadCallback() } else throw Error("Unknown theme: " + currentThemeName); } function themeNameFromDevice(device) { var themeName = device.platform, majorVersion = device.version && device.version[0]; if (themeName === "ios" && (!majorVersion || majorVersion > 6)) themeName += "7"; return themeName } function getCssClasses(themeName) { themeName = themeName || current(); var result = [], themeNameParts = themeName && themeName.split("."); if (themeNameParts) { result.push("dx-theme-" + themeNameParts[0], "dx-theme-" + themeNameParts[0] + "-typography"); if (themeNameParts.length > 1) result.push("dx-color-scheme-" + themeNameParts[1]) } return result } function attachCssClasses(element, themeName) { $(element).addClass(getCssClasses(themeName).join(" ")) } function detachCssClasses(element, themeName) { $(element).removeClass(getCssClasses(themeName).join(" ")) } $.holdReady(true); init({ _autoInit: true, loadCallback: function() { $.holdReady(false) } }); $(function() { if ($(DX_LINK_SELECTOR, context).length) throw Error("LINK[rel=dx-theme] tags must go before DevExpress included scripts"); }); DX.ui.themes = { init: init, current: current, attachCssClasses: attachCssClasses, detachCssClasses: detachCssClasses }; DX.ui.themes.__internals = { themeNameFromDevice: themeNameFromDevice, waitForThemeLoad: waitForThemeLoad, resetTheme: function() { $activeThemeLink.attr("href", "about:blank"); currentThemeName = null; pendingThemeName = null } } })(jQuery, DevExpress); /*! Module core, file ui.events.js */ (function($, DX, undefined) { var ui = DX.ui, eventNS = $.event, specialNS = eventNS.special, EVENT_SOURCES_REGEX = { mouse: /(mouse|wheel|click)/i, wheel: /wheel/i, touch: /^touch/i, keyboard: /^key/i, pointer: /pointer/i }; var eventSource = function(e) { var result = "other"; $.each(EVENT_SOURCES_REGEX, function(key) { if (this.test(e.type)) { result = key; return false } }); return result }; var isPointerEvent = function(e) { return eventSource(e) === "pointer" }; var isMouseEvent = function(e) { return eventSource(e) === "mouse" || isPointerEvent(e) && e.pointerType === "mouse" }; var isTouchEvent = function(e) { return eventSource(e) === "touch" || isPointerEvent(e) && e.pointerType === "touch" }; var isKeyboardEvent = function(e) { return eventSource(e) === "keyboard" }; var isMouseWheelEvent = function(e) { return EVENT_SOURCES_REGEX["wheel"].test(e.type) }; var addNamespace = function(eventNames, namespace) { if (!namespace) throw Error("Namespace is not defined"); if (typeof eventNames === "string") return addNamespace(eventNames.split(/\s+/g), namespace); $.each(eventNames, function(index, eventName) { eventNames[index] = eventName + "." + namespace }); return eventNames.join(" ") }; var eventData = function(e) { if (isPointerEvent(e) && isTouchEvent(e)) { var touch = (e.originalEvent.originalEvent || e.originalEvent).changedTouches[0]; return { x: touch.pageX, y: touch.pageY, time: e.timeStamp } } if (isMouseEvent(e)) return { x: e.pageX, y: e.pageY, time: e.timeStamp }; if (isTouchEvent(e)) { var touch = (e.changedTouches || e.originalEvent.changedTouches)[0]; return { x: touch.pageX, y: touch.pageY, time: e.timeStamp } } }; var eventDelta = function(from, to) { return { x: to.x - from.x, y: to.y - from.y, time: to.time - from.time || 1 } }; var hasTouches = function(e) { if (isTouchEvent(e)) return (e.originalEvent.touches || []).length; return 0 }; var needSkipEvent = function(e) { var $target = $(e.target), touchInInput = $target.is("input, textarea, select"); if (isMouseWheelEvent(e) && touchInInput) return false; if (isMouseEvent(e)) return touchInInput || e.which > 1; if (isTouchEvent(e)) return touchInInput && $target.is(":focus") || (e.originalEvent.changedTouches || e.originalEvent.originalEvent.changedTouches).length !== 1 }; var createEvent = function(sourceEvent, props) { var event = $.Event(sourceEvent), originalEvent = event.originalEvent, propNames = $.event.props.slice(); if (isMouseEvent(sourceEvent) || isTouchEvent(sourceEvent)) $.merge(propNames, $.event.mouseHooks.props); if (isKeyboardEvent(sourceEvent)) $.merge(propNames, $.event.keyHooks.props); if (originalEvent) $.each(propNames, function() { event[this] = originalEvent[this] }); if (props) $.extend(event, props); return event }; var fireEvent = function(props) { var event = createEvent(props.originalEvent, props); $.event.trigger(event, null, props.target || event.target); return event }; var handleGestureEvent = function(e, type) { var gestureEvent = $(e.target).data("dxGestureEvent"); if (!gestureEvent || gestureEvent === type) { $(e.target).data("dxGestureEvent", type); return true } return false }; var registerEvent = function(eventName, eventObject) { var strategy = {}; if ("noBubble" in eventObject) strategy.noBubble = eventObject.noBubble; if ("bindType" in eventObject) strategy.bindType = eventObject.bindType; if ("delegateType" in eventObject) strategy.delegateType = eventObject.delegateType; $.each(["setup", "teardown", "add", "remove", "trigger", "handle", "_default", "dispose"], function(_, methodName) { if (!eventObject[methodName]) return; strategy[methodName] = function() { var args = $.makeArray(arguments); args.unshift(this); return eventObject[methodName].apply(eventObject, args) } }); specialNS[eventName] = strategy }; ui.events = { eventSource: eventSource, isPointerEvent: isPointerEvent, isMouseEvent: isMouseEvent, isTouchEvent: isTouchEvent, isKeyboardEvent: isKeyboardEvent, addNamespace: addNamespace, hasTouches: hasTouches, eventData: eventData, eventDelta: eventDelta, needSkipEvent: needSkipEvent, createEvent: createEvent, fireEvent: fireEvent, handleGestureEvent: handleGestureEvent, registerEvent: registerEvent } })(jQuery, DevExpress); /*! Module core, file ko.events.js */ (function($, DX, undefined) { if (!DX.support.hasKo) return; var ko = window.ko, events = DX.ui.events; var originalRegisterEvent = events.registerEvent; var registerKoEvent = function(eventName, eventObject) { originalRegisterEvent(eventName, eventObject); var koBindingEventName = events.addNamespace(eventName, eventName + "Binding"); ko.bindingHandlers[eventName] = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) { var $element = $(element), unwrappedValue = ko.utils.unwrapObservable(valueAccessor()), eventSource = unwrappedValue.execute ? unwrappedValue.execute : unwrappedValue; $element.off(koBindingEventName).on(koBindingEventName, $.isPlainObject(unwrappedValue) ? unwrappedValue : {}, function(e) { eventSource(viewModel, e) }) }} }; $.extend(events, {registerEvent: registerKoEvent}) })(jQuery, DevExpress); /*! Module core, file ng.events.js */ (function($, DX, undefined) { if (!DX.support.hasNg) return; var events = DX.ui.events; var originalRegisterEvent = events.registerEvent; var registerNgEvent = function(eventName, eventObject) { originalRegisterEvent(eventName, eventObject); var ngEventName = eventName.slice(0, 2) + eventName.charAt(2).toUpperCase() + eventName.slice(3); DX.ng.module.directive(ngEventName, ['$parse', function($parse) { return function(scope, element, attr) { var attrValue = $.trim(attr[ngEventName]), handler, eventOptions = {}; if (attrValue.charAt(0) === "{") { eventOptions = scope.$eval(attrValue); handler = $parse(eventOptions.execute) } else handler = $parse(attr[ngEventName]); element.on(eventName, eventOptions, function(e) { scope.$apply(function() { handler(scope, {$event: e}) }) }) } }]) }; $.extend(events, {registerEvent: registerNgEvent}) })(jQuery, DevExpress); /*! Module core, file ui.hierarchicalKeyDownProcessor.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; ui.HierarchicalKeyDownProcessor = DX.Class.inherit({ _keydown: events.addNamespace("keydown", "HierarchicalKeyDownProcessor"), codes: { "9": "tab", "13": "enter", "27": "escape", "33": "pageUp", "34": "pageDown", "37": "leftArrow", "38": "upArrow", "39": "rightArrow", "40": "downArrow", "32": "space", "70": "F", "65": "A" }, ctor: function(options) { var _this = this; options = options || {}; if (options.element) this._element = $(options.element); this._handler = options.handler; this._context = options.context; this._childProcessors = []; if (this._element) this._element.on(this._keydown, function(e) { _this.process(e) }) }, dispose: function() { if (this._element) this._element.off(this._keydown); this._element = undefined; this._handler = undefined; this._context = undefined; this._childProcessors = undefined }, attachChildProcessor: function() { var childProcessor = new ui.HierarchicalKeyDownProcessor; this._childProcessors.push(childProcessor); return childProcessor }, reinitialize: function(childHandler, childContext) { this._context = childContext; this._handler = childHandler; return this }, process: function(e) { var args = { key: this.codes[e.which], ctrl: e.ctrlKey, shift: e.shiftKey, originalEvent: e }; if (this.codes[e.which] && this._handler && this._handler.call(this._context, args)) $.each(this._childProcessors, function(index, childProcessor) { childProcessor.process(e) }) } }) })(jQuery, DevExpress); /*! Module core, file ui.dialog.js */ (function($, DX, undefined) { var ui = DX.ui, utils = DX.utils; var DEFAULT_BUTTON = { text: "OK", clickAction: function() { return true } }; var DX_DIALOG_CLASSNAME = "dx-dialog", DX_DIALOG_WRAPPER_CLASSNAME = DX_DIALOG_CLASSNAME + "-wrapper", DX_DIALOG_ROOT_CLASSNAME = DX_DIALOG_CLASSNAME + "-root", DX_DIALOG_CONTENT_CLASSNAME = DX_DIALOG_CLASSNAME + "-content", DX_DIALOG_MESSAGE_CLASSNAME = DX_DIALOG_CLASSNAME + "-message", DX_DIALOG_BUTTONS_CLASSNAME = DX_DIALOG_CLASSNAME + "-buttons", DX_DIALOG_BUTTON_CLASSNAME = DX_DIALOG_CLASSNAME + "-button"; var FakeDialogComponent = DX.Component.inherit({ NAME: "dxDialog", ctor: function(element, options) { this.callBase(options) }, _defaultOptionsRules: function() { return this.callBase().slice(0).concat([{ device: [{platform: "ios"}, {platform: "ios7"}], options: {width: 276} }, { device: {platform: "android"}, options: { lWidth: "60%", pWidth: "80%" } }, { device: { platform: "win8", phone: false }, options: {width: function() { return $(window).width() }} }, { device: { platform: "win8", phone: true }, options: {position: { my: "top center", at: "top center", of: window, offset: "0 0" }} }]) } }); var dialog = function(options) { var that = this, result; if (!ui.dxPopup) throw new Error("DevExpress.ui.dxPopup required"); var deferred = $.Deferred(); var defaultOptions = (new FakeDialogComponent).option(); options = $.extend(defaultOptions, options); var $holder = $(DX.overlayTargetContainer()); var $element = $("
").addClass(DX_DIALOG_CLASSNAME).appendTo($holder); var $message = $("
").addClass(DX_DIALOG_MESSAGE_CLASSNAME).html(String(options.message)); var $buttons = $("
").addClass(DX_DIALOG_BUTTONS_CLASSNAME); var popupInstance = $element.dxPopup({ title: options.title || that.title, height: "auto", width: function() { var isPortrait = $(window).height() > $(window).width(), key = (isPortrait ? "p" : "l") + "Width", widthOption = options.hasOwnProperty(key) ? options[key] : options["width"]; return $.isFunction(widthOption) ? widthOption() : widthOption }, contentReadyAction: function() { popupInstance.content().addClass(DX_DIALOG_CONTENT_CLASSNAME).append($message).append($buttons) }, animation: { show: { type: "pop", duration: 400 }, hide: { type: "pop", duration: 400, to: { opacity: 0, scale: 0 }, from: { opacity: 1, scale: 1 } } }, rtlEnabled: DX.rtlEnabled }).data("dxPopup"); popupInstance._wrapper().addClass(DX_DIALOG_WRAPPER_CLASSNAME); if (options.position) popupInstance.option("position", options.position); $.each(options.buttons || [DEFAULT_BUTTON], function() { var button = $("
").addClass(DX_DIALOG_BUTTON_CLASSNAME).appendTo($buttons); var action = new DX.Action(this.clickAction, {context: popupInstance}); button.dxButton($.extend(this, {clickAction: function() { result = action.execute(arguments); hide() }})) }); popupInstance._wrapper().addClass(DX_DIALOG_ROOT_CLASSNAME); function show() { popupInstance.show(); utils.resetActiveElement(); return deferred.promise() } function hide(value) { popupInstance.hide().done(function() { popupInstance._element().remove() }); deferred.resolve(result || value) } return { show: show, hide: hide } }; var alert = function(message, title) { var dialogInstance, options = $.isPlainObject(message) ? message : { title: title, message: message }; dialogInstance = ui.dialog.custom(options); return dialogInstance.show() }; var confirm = function(message, title) { var dialogInstance, options = $.isPlainObject(message) ? message : { title: title, message: message, buttons: [{ text: Globalize.localize("Yes"), clickAction: function() { return true } }, { text: Globalize.localize("No"), clickAction: function() { return false } }] }; dialogInstance = ui.dialog.custom(options); return dialogInstance.show() }; var notify = function(message, type, displayTime) { var options = $.isPlainObject(message) ? message : {message: message}; if (!ui.dxToast) { alert(options.message); return } var userHiddenAction = options.hiddenAction; $.extend(options, { type: type, displayTime: displayTime, hiddenAction: function(args) { args.element.remove(); new DX.Action(userHiddenAction, {context: args.model}).execute(arguments) } }); $("
").appendTo(DX.overlayTargetContainer()).dxToast(options).dxToast("instance").show() }; $.extend(ui, { notify: notify, dialog: { custom: dialog, alert: alert, confirm: confirm, FakeDialogComponent: FakeDialogComponent } }) })(jQuery, DevExpress); /*! Module core, file ui.dataHelper.js */ (function($, DX, undefined) { var data = DX.data; var DATA_SOURCE_OPTIONS_METHOD = "_dataSourceOptions", DATA_SOURCE_CHANGED_METHOD = "_handleDataSourceChanged", DATA_SOURCE_LOAD_ERROR_METHOD = "_handleDataSourceLoadError", DATA_SOURCE_LOADING_CHANGED_METHOD = "_handleDataSourceLoadingChanged"; DX.ui.DataHelperMixin = { ctor: function() { this.disposing.add(function() { this._disposeDataSource() }) }, _refreshDataSource: function() { this._initDataSource(); this._loadDataSource() }, _initDataSource: function() { var dataSourceOptions = this.option("dataSource"), widgetDataSourceOptions, dataSourceType; this._disposeDataSource(); if (dataSourceOptions) { if (dataSourceOptions instanceof data.DataSource) { this._isSharedDataSource = true; this._dataSource = dataSourceOptions } else { widgetDataSourceOptions = DATA_SOURCE_OPTIONS_METHOD in this ? this[DATA_SOURCE_OPTIONS_METHOD]() : {}; dataSourceType = this._dataSourceType ? this._dataSourceType() : data.DataSource; this._dataSource = new dataSourceType($.extend(true, {}, widgetDataSourceOptions, data.utils.normalizeDataSourceOptions(dataSourceOptions))) } this._addDataSourceHandlers() } }, _addDataSourceHandlers: function() { if (DATA_SOURCE_CHANGED_METHOD in this) this._addDataSourceChangeHandler(); if (DATA_SOURCE_LOAD_ERROR_METHOD in this) this._addDataSourceLoadErrorHandler(); if (DATA_SOURCE_LOADING_CHANGED_METHOD in this) this._addDataSourceLoadingChangedHandler() }, _addDataSourceChangeHandler: function() { var that = this, dataSource = this._dataSource; this._dataSourceChangedHandler = function() { that[DATA_SOURCE_CHANGED_METHOD](dataSource.items()) }; dataSource.changed.add(this._dataSourceChangedHandler) }, _addDataSourceLoadErrorHandler: function() { this._dataSourceLoadErrorHandler = $.proxy(this[DATA_SOURCE_LOAD_ERROR_METHOD], this); this._dataSource.loadError.add(this._dataSourceLoadErrorHandler) }, _addDataSourceLoadingChangedHandler: function() { this._dataSourceLoadingChangedHandler = $.proxy(this[DATA_SOURCE_LOADING_CHANGED_METHOD], this); this._dataSource.loadingChanged.add(this._dataSourceLoadingChangedHandler) }, _loadDataSource: function() { if (this._dataSource) { var dataSource = this._dataSource; if (dataSource.isLoaded()) this._dataSourceChangedHandler(); else dataSource.load() } }, _loadSingle: function(key, value) { key = key === "this" ? this._dataSource.key() || "this" : key; return this._dataSource.loadSingle(key, value) }, _disposeDataSource: function() { if (this._dataSource) { if (this._isSharedDataSource) { delete this._isSharedDataSource; this._dataSource.changed.remove(this._dataSourceChangedHandler); this._dataSource.loadError.remove(this._dataSourceLoadErrorHandler); this._dataSource.loadingChanged.remove(this._dataSourceLoadingChangedHandler) } else this._dataSource.dispose(); delete this._dataSource; delete this._dataSourceChangedHandler; delete this._dataSourceLoadErrorHandler; delete this._dataSourceLoadingChangedHandler } } } })(jQuery, DevExpress); /*! Module core, file ui.events.mspointer.js */ (function($, DX, undefined) { var POINTER_TYPE_MAP = { 2: "touch", 3: "pen", 4: "mouse" }; var pointerEventHook = { filter: function(event, originalEvent) { var pointerType = originalEvent.pointerType; if ($.isNumeric(pointerType)) event.pointerType = POINTER_TYPE_MAP[pointerType]; return event }, props: $.event.mouseHooks.props.concat(["pointerId", "originalTarget", "namespace", "width", "height", "pressure", "result", "tiltX", "charCode", "tiltY", "detail", "isPrimary", "prevValue"]) }; $.each(["MSPointerDown", "MSPointerMove", "MSPointerUp", "MSPointerCancel", "MSPointerOver", "MSPointerOut", "MSPointerEnter", "MSPointerLeave", "pointerdown", "pointermove", "pointerup", "pointercancel", "pointerover", "pointerout", "pointerenter", "pointerleave"], function() { $.event.fixHooks[this] = pointerEventHook }) })(jQuery, DevExpress); /*! Module core, file ui.events.touch.js */ (function($, DX, undefined) { var touchEventHook = { filter: function(event, originalEvent) { if (originalEvent.changedTouches.length) $.each(["pageX", "pageY", "screenX", "screenY", "clientX", "clientY"], function() { event[this] = originalEvent.changedTouches[0][this] }); return event }, props: $.event.mouseHooks.props.concat(["touches", "changedTouches", "targetTouches", "detail", "result", "namespace", "originalTarget", "charCode", "prevValue"]) }; $.each(["touchstart", "touchmove", "touchend", "touchcancel"], function() { $.event.fixHooks[this] = touchEventHook }) })(jQuery, DevExpress); /*! Module core, file ui.events.pointer.js */ (function($, DX, undefined) { var ui = DX.ui, support = DX.support, device = $.proxy(DX.devices.real, DX.devices), events = ui.events; var POINTER_EVENTS_NAMESPACE = "dxPointerEvents", MouseStrategyEventMap = { dxpointerdown: "mousedown", dxpointermove: "mousemove", dxpointerup: "mouseup", dxpointercancel: "" }, TouchStrategyEventMap = { dxpointerdown: "touchstart", dxpointermove: "touchmove", dxpointerup: "touchend", dxpointercancel: "touchcancel" }, PointerStrategyEventMap = { dxpointerdown: "pointerdown", dxpointermove: "pointermove", dxpointerup: "pointerup", dxpointercancel: "pointercancel" }, MouseAndTouchStrategyEventMap = { dxpointerdown: "touchstart mousedown", dxpointermove: "touchmove mousemove", dxpointerup: "touchend mouseup", dxpointercancel: "touchcancel" }; var eventMap = function() { if (support.touch && !(device().tablet || device().phone)) return MouseAndTouchStrategyEventMap; if (support.pointer) return MouseStrategyEventMap; if (support.touch) return TouchStrategyEventMap; return MouseStrategyEventMap }(); var skipTouchWithSameIdentifier = function(pointerEvent) { return device().platform === "ios" && (pointerEvent === "dxpointerdown" || pointerEvent === "dxpointerup") }; var SingleEventStrategy = DX.Class.inherit({ ctor: function(eventName, originalEvents) { this._eventName = eventName; this._eventNamespace = [POINTER_EVENTS_NAMESPACE, ".", this._eventName].join(""); this._originalEvents = originalEvents; this._pointerId = 0; this._handlerCount = 0 }, _handler: function(e) { if (this._eventName === "dxpointerdown") $(e.target).data("dxGestureEvent", null); if (events.isTouchEvent(e) && skipTouchWithSameIdentifier(this._eventName)) { var touch = e.changedTouches[0]; if (this._pointerId === touch.identifier && this._pointerId !== 0) return; this._pointerId = touch.identifier } return events.fireEvent({ type: this._eventName, pointerType: events.eventSource(e), originalEvent: e }) }, setup: function() { if (this._handlerCount > 0) return; $(document).on(events.addNamespace(this._originalEvents, this._eventNamespace), $.proxy(this._handler, this)) }, add: function() { this._handlerCount++ }, remove: function() { this._handlerCount-- }, teardown: function() { if (this._handlerCount) return; $(document).off("." + this._eventNamespace) }, dispose: function() { $(document).off("." + this._eventNamespace) } }); var MultiEventStrategy = SingleEventStrategy.inherit({ EVENT_LOCK_TIMEOUT: 100, _handler: function(e) { if (events.isTouchEvent(e)) this._skipNextEvents = true; if (events.isMouseEvent(e) && this._mouseLocked) return; if (events.isMouseEvent(e) && this._skipNextEvents) { this._skipNextEvents = false; this._mouseLocked = true; clearTimeout(this._unlockMouseTimer); this._unlockMouseTimer = setTimeout($.proxy(function() { this._mouseLocked = false }, this), this.EVENT_LOCK_TIMEOUT); return } return this.callBase(e) }, dispose: function() { this.callBase(); this._skipNextEvents = false; this._mouseLocked = false; clearTimeout(this._unlockMouseTimer) } }); var getStrategy = function() { return eventMap === MouseAndTouchStrategyEventMap ? MultiEventStrategy : SingleEventStrategy }; $.each(eventMap, function(pointerEvent, originalEvents) { var Strategy = getStrategy(); events.registerEvent(pointerEvent, new Strategy(pointerEvent, originalEvents)) }); DX.ui.events.__internals = DX.ui.events.__internals || {}; $.extend(DX.ui.events.__internals, { SingleEventStrategy: SingleEventStrategy, MultiEventStrategy: MultiEventStrategy, MouseStrategyEventMap: MouseStrategyEventMap, TouchStrategyEventMap: TouchStrategyEventMap, PointerStrategyEventMap: PointerStrategyEventMap, MouseAndTouchStrategyEventMap: MouseAndTouchStrategyEventMap, eventMap: eventMap }) })(jQuery, DevExpress); /*! Module core, file ui.events.click.js */ (function($, DX, wnd, undefined) { var ua = navigator.userAgent, screen = wnd.screen, ui = DX.ui, utils = DX.utils, events = ui.events, support = DX.support, device = $.proxy(DX.devices.real, DX.devices), EVENTS_NAME_SPACE = "dxSpecialEvents", CLICK_NAME_SPACE = "dxClick" + EVENTS_NAME_SPACE, CLICK_EVENT_NAME = "dxclick", SCROLLABLE_PARENT_DATA_KEY = "dxClickScrollableParent", SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY = "dxClickScrollableParentOffset", preferNativeClick = function() { var iPhone4SAndElder = device().deviceType === "phone" && screen.height <= 480, iPad2AndElder = device().deviceType === "tablet" && wnd.devicePixelRatio < 2, IOS7AndNewer = device().platform === "ios" && device().version[0] > 6; return IOS7AndNewer && (iPhone4SAndElder || iPad2AndElder) }(), useNativeClick = function() { if (!support.touch) return true; var chromeInfo = ua.match(/Chrome\/([0-9]+)/) || [], chrome = !!chromeInfo[0], chromeVersion = ~~chromeInfo[1], android = device().platform === "android"; if (chrome) if (android) { if ($("meta[name=viewport][content*='width=device-width']").length) return false; if (chromeVersion > 31 && wnd.innerWidth <= screen.width) return true; if ($("meta[name=viewport][content*='user-scalable=no']").length) return true } else return true; return false }(); var SimulatedStrategy = DX.Class.inherit({ TOUCH_BOUNDARY: 10, ctor: function() { this._startX = 0; this._startY = 0; this._handlerCount = 0; this._target = null }, _touchWasMoved: function(e) { var boundary = this.TOUCH_BOUNDARY; return Math.abs(e.pageX - this._startX) > boundary || Math.abs(e.pageY - this._startY) > boundary }, _getClosestScrollable: function($element) { var $scrollParent = $(); if ($element.data(SCROLLABLE_PARENT_DATA_KEY)) $scrollParent = $element.data(SCROLLABLE_PARENT_DATA_KEY); else { var $current = $element; while ($current.length) { if ($current[0].scrollHeight - $current[0].offsetHeight > 1) { $scrollParent = $current; $element.data(SCROLLABLE_PARENT_DATA_KEY, $scrollParent); break } $current = $current.parent() } } return $scrollParent }, _saveClosestScrollableOffset: function($element) { var $scrollable = this._getClosestScrollable($element); if ($scrollable.length) $element.data(SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY, $scrollable.scrollTop()) }, _closestScrollableWasMoved: function($element) { var $scrollable = $element.data(SCROLLABLE_PARENT_DATA_KEY); return $scrollable && $scrollable.scrollTop() !== $element.data(SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY) }, _hasClosestScrollable: function($element) { var $scrollable = this._getClosestScrollable($element); if (!$scrollable.length) return false; if ($scrollable.is("body")) return false; if ($scrollable === window) return false; if ($scrollable.css("overflow") === "hidden") return false; return true }, _handleStart: function(e) { this._reset(); if (events.isMouseEvent(e) && e.which !== 1) return; this._saveClosestScrollableOffset($(e.target)); this._target = e.target; this._startX = e.pageX; this._startY = e.pageY }, _handleEnd: function(e) { var $target = $(e.target); if (!$target.is(this._target) || this._touchWasMoved(e)) return; if (this._nativeClickShouldBeUsed($target) || this._closestScrollableWasMoved($target)) return; var targetIsInput = $target.is("input, textarea"); if (!targetIsInput && !e.dxPreventBlur) utils.resetActiveElement(); this._fireClickEvent(e) }, _handleCancel: function(e) { this._reset() }, _reset: function() { this._target = null }, _handleClick: function(e) { var $target = $(e.target); if ($target.is(this._target)) { if (this._nativeClickShouldBeUsed($target)) this._fireClickEvent(e) } else if ($target.is("input, textarea")) utils.resetActiveElement() }, _nativeClickShouldBeUsed: function($target) { return preferNativeClick && this._hasClosestScrollable($target) }, _fireClickEvent: function(e) { if (events.handleGestureEvent(e, CLICK_EVENT_NAME)) events.fireEvent({ type: CLICK_EVENT_NAME, originalEvent: e }) }, _makeElementClickable: function($element) { if (!$element.attr("onclick")) $element.attr("onclick", "void(0)") }, setup: function(element) { var $element = $(element); this._makeElementClickable($element); if (this._handlerCount > 0) return; var $doc = $(document).on(events.addNamespace("dxpointerdown", CLICK_NAME_SPACE), $.proxy(this._handleStart, this)).on(events.addNamespace("dxpointerup", CLICK_NAME_SPACE), $.proxy(this._handleEnd, this)).on(events.addNamespace("dxpointercancel", CLICK_NAME_SPACE), $.proxy(this._handleCancel, this)).on(events.addNamespace("click", CLICK_NAME_SPACE), $.proxy(this._handleClick, this)) }, add: function() { this._handlerCount++ }, remove: function() { this._handlerCount-- }, teardown: function(element) { if (this._handlerCount) return; $(element).off("." + CLICK_NAME_SPACE); this.dispose() }, dispose: function() { $(document).off("." + CLICK_NAME_SPACE) } }); var NativeStrategy = DX.Class.inherit({ bindType: "click", delegateType: "click", handle: function(element, event) { event.type = "dxclick"; if (events.handleGestureEvent(event, CLICK_EVENT_NAME)) return event.handleObj.handler.call(element, event) } }); events.registerEvent(CLICK_EVENT_NAME, new(useNativeClick ? NativeStrategy : SimulatedStrategy)); DX.ui.events.__internals = DX.ui.events.__internals || {}; $.extend(DX.ui.events.__internals, { NativeClickStrategy: NativeStrategy, SimulatedClickStrategy: SimulatedStrategy, preferNativeClickAccessor: function(value) { if (!arguments.length) return preferNativeClick; preferNativeClick = value } }) })(jQuery, DevExpress, window); /*! Module core, file ui.events.hold.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, jqSpecialEvent = $.event.special, EVENTS_NAME_SPACE = "dxSpecialEvents", HOLD_NAME_SPACE = "dxHold", HOLD_EVENT_NAME = "dxhold", HOLD_TIMER_DATA_KEY = EVENTS_NAME_SPACE + "HoldTimer"; var Hold = DX.Class.inherit({ HOLD_TIMEOUT: 750, TOUCH_BOUNDARY: 5, _startX: 0, _startY: 0, _touchWasMoved: function(e) { var boundary = this.TOUCH_BOUNDARY; return Math.abs(e.pageX - this._startX) > boundary || Math.abs(e.pageY - this._startY) > boundary }, setup: function(element, data) { var $target, holdInited = false; var handleStart = function(e) { if (holdInited) return; $target = $(e.target); holdInited = true; if ($target.data(HOLD_TIMER_DATA_KEY)) return; this._startX = e.pageX; this._startY = e.pageY; var holdTimeout = data && "timeout" in data ? data.timeout : this.HOLD_TIMEOUT; var holdTimer = setTimeout(function() { $target.removeData(HOLD_TIMER_DATA_KEY); if (events.handleGestureEvent(e, HOLD_EVENT_NAME)) events.fireEvent({ type: HOLD_EVENT_NAME, originalEvent: e }) }, holdTimeout); $target.data(HOLD_TIMER_DATA_KEY, holdTimer) }; var handleMove = function(e) { if (!this._touchWasMoved(e)) return; handleEnd() }; var handleEnd = function() { if ($target) { clearTimeout($target.data(HOLD_TIMER_DATA_KEY)); $target.removeData(HOLD_TIMER_DATA_KEY); $target = null; holdInited = false } }; $(element).on(events.addNamespace("dxpointerdown", HOLD_NAME_SPACE), $.proxy(handleStart, this)).on(events.addNamespace("dxpointermove", HOLD_NAME_SPACE), $.proxy(handleMove, this)).on(events.addNamespace("dxpointerup", HOLD_NAME_SPACE), $.proxy(handleEnd, this)) }, teardown: function(element) { element = $(element); clearTimeout(element.data(HOLD_TIMER_DATA_KEY)); element.removeData(HOLD_TIMER_DATA_KEY).off("." + HOLD_NAME_SPACE) } }); events.registerEvent(HOLD_EVENT_NAME, new Hold) })(jQuery, DevExpress); /*! Module core, file ui.events.hover.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var HOVER_EVENTS_NAMESPACE = "dxSpecialEvents", HOVER_START = "dxhoverstart", HOVER_END = "dxhoverend", MOUSE_ENTER = "mouseenter", MOUSE_LEAVE = "mouseleave", TOUCH_START = "dxpointerdown"; var HoverStart = DX.Class.inherit({ ctor: function() { this._wasTouch = false; this._selector = undefined }, setup: function(element, data) { var $element = $(element); this._selector = data ? data.selector : undefined; if (!!$element.data("dxHoverStart")) return; $element.data("dxHoverStart", true).on(events.addNamespace(MOUSE_ENTER, HOVER_EVENTS_NAMESPACE), this._selector, $.proxy(this._handleEnter, this)).on(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE), $.proxy(this._handleTouchStart, this)) }, _handleEnter: function(e) { if (!this._wasTouch) events.fireEvent({ type: HOVER_START, originalEvent: e }) }, _handleTouchStart: function(e) { this._wasTouch = events.isTouchEvent(e) }, teardown: function(element) { $(element).data("dxHoverStart", false).off(events.addNamespace(MOUSE_ENTER, HOVER_EVENTS_NAMESPACE), this._selector).off(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE)) } }); var HoverEnd = DX.Class.inherit({ ctor: function() { this._wasTouch = false; this._selector = undefined }, setup: function(element, data) { var $element = $(element); this._selector = data ? data.selector : undefined; if (!!$element.data("dxHoverEnd")) return; $element.data("dxHoverEnd", true).on(events.addNamespace(MOUSE_LEAVE, HOVER_EVENTS_NAMESPACE), this._selector, $.proxy(this._handleLeave, this)).on(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE), $.proxy(this._handleTouchStart, this)) }, _handleLeave: function(e) { if (!this._wasTouch) events.fireEvent({ type: HOVER_END, originalEvent: e }) }, _handleTouchStart: function(e) { this._wasTouch = events.isTouchEvent(e) }, teardown: function(element) { $(element).data("dxHoverEnd", false).off(events.addNamespace(MOUSE_LEAVE, HOVER_EVENTS_NAMESPACE), this._selector).off(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE)) } }); events.registerEvent(HOVER_START, new HoverStart); events.registerEvent(HOVER_END, new HoverEnd) })(jQuery, DevExpress); /*! Module core, file ui.events.wheel.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var EVENT_NAME = "dxmousewheel", EVENT_NAMESPACE = "dxWheel"; var WHEEL_DISTANCE = 10; $.event.fixHooks["wheel"] = $.event.mouseHooks; var wheelEvent = document.onmousewheel !== undefined ? "mousewheel" : "wheel"; var wheel = { setup: function(element, data) { var $element = $(element); $element.on(events.addNamespace(wheelEvent, EVENT_NAMESPACE), $.proxy(wheel._handleWheel, wheel)) }, teardown: function(element) { var $element = $(element); $element.off("." + EVENT_NAMESPACE) }, _handleWheel: function(e) { $(e.target).data("dxGestureEvent", null); var delta = this._getWheelDelta(e.originalEvent); events.fireEvent({ type: EVENT_NAME, originalEvent: e, delta: delta }); e.stopPropagation() }, _getWheelDelta: function(event) { return event.wheelDelta / 60 || -event.deltaY } }; events.registerEvent(EVENT_NAME, wheel) })(jQuery, DevExpress); /*! Module core, file ui.gestureEmitter.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var GestureEmitter = DX.Class.inherit({ ctor: function(element) { this._$element = $(element); this._cancelCallback = $.Callbacks() }, getElement: function() { return this._$element }, getDirection: function() { return this.direction }, validate: function(e) { return e.type !== "dxmousewheel" }, configurate: function(data) { $.extend(this, data) }, addCancelCallback: function(callback) { this._cancelCallback.add(callback) }, removeCancelCallback: function() { this._cancelCallback.empty() }, init: $.noop, start: $.noop, move: $.noop, end: $.noop, cancel: $.noop, wheel: $.noop, _fireEvent: function(eventName, event, params) { var eventData = { type: eventName, originalEvent: event, target: this.getElement().get(0) }; event = events.fireEvent($.extend(eventData, params)); if (event.cancel) this._cancel(event); return event }, _cancel: function(e) { this._cancelCallback.fire() } }); var gestureEmitters = []; $.extend(ui, { GestureEmitter: GestureEmitter, gestureEmitters: gestureEmitters }) })(jQuery, DevExpress); /*! Module core, file ui.scrollEmitter.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var SCROLL_INIT_EVENT = "dxscrollinit", SCROLL_START_EVENT = "dxscrollstart", SCROLL_MOVE_EVENT = "dxscroll", SCROLL_END_EVENT = "dxscrollend", SCROLL_STOP_EVENT = "dxscrollstop", SCROLL_CANCEL_EVENT = "dxscrollcancel", SCROLL_WHEEL_EVENT = "dxscrollwheel", INERTIA_TIMEOUT = 100, VELOCITY_CALC_TIMEOUT = 200, FRAME_DURATION = Math.round(1000 / 60); var ScrollEmitter = ui.GestureEmitter.inherit({ ctor: function(element) { this.callBase(element); this.direction = "vertical" }, init: function(e) { this._savedEventData = this._prevEventData = events.eventData(e); this._fireEvent(SCROLL_INIT_EVENT, e) }, start: function(e) { this._fireEvent(SCROLL_START_EVENT, e, {delta: events.eventDelta(this._prevEventData, events.eventData(e))}) }, move: function(e) { var currentEventData = events.eventData(e); this._fireEvent(SCROLL_MOVE_EVENT, e, {delta: events.eventDelta(this._prevEventData, currentEventData)}); var eventDelta = events.eventDelta(this._savedEventData, currentEventData); if (eventDelta.time > VELOCITY_CALC_TIMEOUT) this._savedEventData = this._prevEventData; this._prevEventData = currentEventData }, end: function(e) { var endEventDelta = events.eventDelta(this._prevEventData, events.eventData(e)); var velocity = { x: 0, y: 0 }; if (endEventDelta.time < INERTIA_TIMEOUT) { var deltaEventData = events.eventDelta(this._savedEventData, this._prevEventData); velocity = { x: deltaEventData.x * FRAME_DURATION / deltaEventData.time, y: deltaEventData.y * FRAME_DURATION / deltaEventData.time } } this._fireEvent(SCROLL_END_EVENT, e, {velocity: velocity}) }, stop: function(e) { this._fireEvent(SCROLL_STOP_EVENT, e) }, cancel: function(e) { this._fireEvent(SCROLL_CANCEL_EVENT, e) }, wheel: function(e) { this._fireEvent(SCROLL_WHEEL_EVENT, e, {delta: e.delta}) } }); ui.gestureEmitters.push({ emitter: ScrollEmitter, events: [SCROLL_INIT_EVENT, SCROLL_START_EVENT, SCROLL_MOVE_EVENT, SCROLL_END_EVENT, SCROLL_STOP_EVENT, SCROLL_CANCEL_EVENT, SCROLL_WHEEL_EVENT] }) })(jQuery, DevExpress); /*! Module core, file ui.swipeEmitter.js */ (function($, DX, undefined) { var ui = DX.ui, utils = DX.utils, events = ui.events, SWIPE_START_EVENT = "dxswipestart", SWIPE_EVENT = "dxswipe", SWIPE_END_EVENT = "dxswipeend"; var HorizontalStrategy = { defaultItemSizeFunc: function() { return this.getElement().width() }, getBounds: function() { return [this._maxLeftOffset, this._maxRightOffset] }, calcOffsetRatio: function(e) { var endEventData = events.eventData(e); return (endEventData.x - (this._startEventData && this._startEventData.x || 0)) / this._itemSizeFunc().call(this, e) }, isFastSwipe: function(e) { var endEventData = events.eventData(e); return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.x - this._tickData.x) >= endEventData.time - this._tickData.time } }; var VerticalStrategy = { defaultItemSizeFunc: function() { return this.getElement().height() }, getBounds: function() { return [this._maxTopOffset, this._maxBottomOffset] }, calcOffsetRatio: function(e) { var endEventData = events.eventData(e); return (endEventData.y - (this._startEventData && this._startEventData.y || 0)) / this._itemSizeFunc().call(this, e) }, isFastSwipe: function(e) { var endEventData = events.eventData(e); return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.y - this._tickData.y) >= endEventData.time - this._tickData.time } }; var STRATEGIES = { horizontal: HorizontalStrategy, vertical: VerticalStrategy }; var SwipeEmitter = ui.GestureEmitter.inherit({ TICK_INTERVAL: 300, FAST_SWIPE_SPEED_LIMIT: 5, ctor: function(element) { this.callBase(element); this.direction = "horizontal"; this.elastic = true }, _getStrategy: function() { return STRATEGIES[this.direction] }, _defaultItemSizeFunc: function() { return this._getStrategy().defaultItemSizeFunc.call(this) }, _itemSizeFunc: function() { return this.itemSizeFunc || this._defaultItemSizeFunc }, init: function(e) { this._startEventData = events.eventData(e); this._tickData = {time: 0} }, start: function(e) { e = this._fireEvent(SWIPE_START_EVENT, e); if (!e.cancel) { this._maxLeftOffset = e.maxLeftOffset; this._maxRightOffset = e.maxRightOffset; this._maxTopOffset = e.maxTopOffset; this._maxBottomOffset = e.maxBottomOffset } }, move: function(e) { var strategy = this._getStrategy(), moveEventData = events.eventData(e), offset = strategy.calcOffsetRatio.call(this, e); offset = this._fitOffset(offset, this.elastic); if (moveEventData.time - this._tickData.time > this.TICK_INTERVAL) this._tickData = moveEventData; this._fireEvent(SWIPE_EVENT, e, {offset: offset}); e.preventDefault() }, end: function(e) { var strategy = this._getStrategy(), offsetRatio = strategy.calcOffsetRatio.call(this, e), isFast = strategy.isFastSwipe.call(this, e), startOffset = offsetRatio, targetOffset = this._calcTargetOffset(offsetRatio, isFast); startOffset = this._fitOffset(startOffset, this.elastic); targetOffset = this._fitOffset(targetOffset, false); this._fireEvent(SWIPE_END_EVENT, e, { offset: startOffset, targetOffset: targetOffset }) }, _fitOffset: function(offset, elastic) { var strategy = this._getStrategy(), bounds = strategy.getBounds.call(this); if (offset < -bounds[0]) return elastic ? (-2 * bounds[0] + offset) / 3 : -bounds[0]; if (offset > bounds[1]) return elastic ? (2 * bounds[1] + offset) / 3 : bounds[1]; return offset }, _calcTargetOffset: function(offsetRatio, isFast) { var result; if (isFast) { result = Math.ceil(Math.abs(offsetRatio)); if (offsetRatio < 0) result = -result } else result = Math.round(offsetRatio); return result } }); ui.gestureEmitters.push({ emitter: SwipeEmitter, events: [SWIPE_START_EVENT, SWIPE_EVENT, SWIPE_END_EVENT] }) })(jQuery, DevExpress); /*! Module core, file ui.dragEmitter.js */ (function($, DX, undefined) { var ui = DX.ui, utils = DX.utils, events = ui.events, wrapToArray = utils.wrapToArray; var DRAG_START_EVENT = "dxdragstart", DRAG_EVENT = "dxdrag", DRAG_END_EVENT = "dxdragend", DRAG_ENTER_EVENT = "dxdragenter", DRAG_LEAVE_EVENT = "dxdragleave", DROP_EVENT = "dxdrop"; var knownDropTargets = [], knownDropTargetConfigs = []; var dropTargetRegistration = { setup: function(element, data) { var knownDropTarget = $.inArray(element, knownDropTargets) !== -1; if (!knownDropTarget) { knownDropTargets.push(element); knownDropTargetConfigs.push(data || {}) } }, teardown: function(element, data) { var elementEvents = $._data(element, "events"), handlersCount = 0; $.each([DRAG_ENTER_EVENT, DRAG_LEAVE_EVENT, DROP_EVENT], function(_, eventName) { var eventHandlers = elementEvents[eventName]; if (eventHandlers) handlersCount += eventHandlers.length }); if (!handlersCount) { var index = $.inArray(element, knownDropTargets); knownDropTargets.splice(index, 1); knownDropTargetConfigs.splice(index, 1) } } }; events.registerEvent(DRAG_ENTER_EVENT, dropTargetRegistration); events.registerEvent(DRAG_LEAVE_EVENT, dropTargetRegistration); events.registerEvent(DROP_EVENT, dropTargetRegistration); var getItemConfig = function($element) { var dropTargetIndex = $.inArray($element.get(0), knownDropTargets); return knownDropTargetConfigs[dropTargetIndex] }; var getItemPosition = function($element) { var dropTargetConfig = getItemConfig($element); if (dropTargetConfig.itemPositionFunc) return dropTargetConfig.itemPositionFunc(); else return $element.offset() }; var getItemSize = function($element) { var dropTargetConfig = getItemConfig($element); if (dropTargetConfig.itemSizeFunc) return dropTargetConfig.itemSizeFunc(); else return { width: $element.width(), height: $element.height() } }; var DragEmitter = ui.GestureEmitter.inherit({ ctor: function(element) { this.callBase(element); this.direction = "both" }, init: function(e) { var eventData = events.eventData(e); this._startEventData = eventData }, start: function(e) { e = this._fireEvent(DRAG_START_EVENT, e); this._maxLeftOffset = e.maxLeftOffset; this._maxRightOffset = e.maxRightOffset; this._maxTopOffset = e.maxTopOffset; this._maxBottomOffset = e.maxBottomOffset; var dropTargets = wrapToArray(e.targetElements || knownDropTargets); this._$dropTargetElements = $.map(dropTargets, function(element) { return $(element) }) }, move: function(e) { var eventData = events.eventData(e), dragOffset = this._calculateOffset(eventData); this._fireEvent(DRAG_EVENT, e, {offset: dragOffset}); this._processDropTargets(e, dragOffset); e.preventDefault() }, _calculateOffset: function(eventData) { return { x: this._calculateXOffset(eventData), y: this._calculateYOffset(eventData) } }, _calculateXOffset: function(eventData) { if (this.direction !== "vertical") { var offset = eventData.x - this._startEventData.x; return this._fitOffset(offset, this._maxLeftOffset, this._maxRightOffset) } return 0 }, _calculateYOffset: function(eventData) { if (this.direction !== "horizontal") { var offset = eventData.y - this._startEventData.y; return this._fitOffset(offset, this._maxTopOffset, this._maxBottomOffset) } return 0 }, _fitOffset: function(offset, minOffset, maxOffset) { if (minOffset != null) offset = Math.max(offset, -minOffset); if (maxOffset != null) offset = Math.min(offset, maxOffset); return offset }, _processDropTargets: function(e, dragOffset) { var target = this._findDropTarget(e), sameTarget = target === this._$currentDropTarget; if (!sameTarget) { this._fireDropTargetEvent(e, DRAG_LEAVE_EVENT); this._$currentDropTarget = target; this._fireDropTargetEvent(e, DRAG_ENTER_EVENT) } }, _fireDropTargetEvent: function(event, eventName) { if (!this._$currentDropTarget) return; var eventData = { type: eventName, originalEvent: event, draggingElement: this._$element.get(0), target: this._$currentDropTarget.get(0) }; events.fireEvent(eventData) }, _findDropTarget: function(e) { var that = this, $result; $.each(this._$dropTargetElements, function(_, $target) { if (that._checkDropTarget($target, e)) { $result = $target; return false } }); return $result }, _checkDropTarget: function($target, e) { var isDraggingElement = $target.get(0) === this._$element.get(0); if (isDraggingElement) return false; var targetPosition = getItemPosition($target); if (e.pageX < targetPosition.left) return false; if (e.pageY < targetPosition.top) return false; var targetSize = getItemSize($target); if (e.pageX > targetPosition.left + targetSize.width) return false; if (e.pageY > targetPosition.top + targetSize.height) return false; return $target }, end: function(e) { var eventData = events.eventData(e); this._fireEvent(DRAG_END_EVENT, e, {offset: this._calculateOffset(eventData)}); this._fireDropTargetEvent(e, DROP_EVENT); delete this._$currentDropTarget } }); ui.gestureEmitters.push({ emitter: DragEmitter, events: [DRAG_START_EVENT, DRAG_EVENT, DRAG_END_EVENT] }); DX.ui.events.__internals = DX.ui.events.__internals || {}; $.extend(DX.ui.events.__internals, {dropTargets: knownDropTargets}) })(jQuery, DevExpress); /*! Module core, file ui.events.gesture.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, utils = DX.utils; var abs = Math.abs; var GESTURE_EVENT = "dxGesture", GESTURE_EVENT_DATA = "dxGestureEmitter", GESTURE_LOCK_KEY = "dxGestureLock", GESTURE_UNLOCK_TIMEOUT = 400, TOUCH_BOUNDARY = 10, HORIZONTAL = "horizontal", VERTICAL = "vertical", BOTH = "both"; var GestureEventManager = DX.Class.inherit({ SLEEP: 0, INITED: 1, STARTED: 2, ctor: function() { this._attachHandlers(); this.reset() }, _attachHandlers: function() { $(document).on(events.addNamespace("dxpointerdown", GESTURE_EVENT), $.proxy(this._handlePointerDown, this)).on(events.addNamespace("dxpointermove", GESTURE_EVENT), $.proxy(this._handlePointerMove, this)).on(events.addNamespace("dxpointerup dxpointercancel", GESTURE_EVENT), $.proxy(this._handlePointerUp, this)).on(events.addNamespace("dxmousewheel", GESTURE_EVENT), $.proxy(this._handleMouseWheel, this)) }, _eachEmitter: function(callback) { $.each(this._activeEmitters || {}, function(direction, emitter) { return callback(emitter, direction) }) }, _noEmitters: function() { return $.isEmptyObject(this._activeEmitters) }, reset: function() { this._eachEmitter(function(emitter) { emitter.removeCancelCallback() }); this._forgetGesture(); this._stage = this.SLEEP; this._activeEmitters = {} }, _handlePointerDown: function(e) { if (events.needSkipEvent(e) || events.hasTouches(e) > 1) return; this.reset(); this._activeEmitters = this._closestEmitter(e); if (this._noEmitters()) return; this._startEvent = e; this._startEventData = events.eventData(e); this._stage = this.INITED; this._applyToActive("init", e) }, _applyToActive: function(method) { var args = $.makeArray(arguments).slice(1); this._eachEmitter(function(emitter) { if (method in emitter) emitter[method].apply(emitter, args) }) }, _closestEmitter: function(e) { var result = {}, foundForAllDirections = false, $element = $(e.target); while ($element.length && !foundForAllDirections) { var emitter = $element.data(GESTURE_EVENT_DATA); if (emitter && emitter.validate(e)) { var direction = emitter.getDirection(e); if (direction) { emitter.addCancelCallback($.proxy(this._handleCancel, this, emitter, e)); result[direction] = result[direction] || emitter } } foundForAllDirections = result[HORIZONTAL] && result[VERTICAL] || result[BOTH]; $element = $element.parent() } return result }, _handleCancel: function(canceledEmitter, e) { var canceledDirection; this._eachEmitter(function(emitter, direction) { if (emitter === canceledEmitter) { canceledDirection = direction; emitter.removeCancelCallback() } }); this._forgetGesture([canceledEmitter]); this._cancelEmitter(canceledEmitter, e); if (this._noEmitters()) this.reset() }, _handlePointerMove: function(e) { if (this._stage === this.INITED && this._directionDetected(e)) this._handleStart(e); if (this._stage === this.STARTED) this._handleMove(e) }, _directionDetected: function(e) { var delta = events.eventDelta(this._startEventData, events.eventData(e)); return delta.x || delta.y }, _handleStart: function(e) { this._filterEmitters(e); if (this._noEmitters()) return; this._resetActiveElement(); this._applyToActive("start", this._startEvent); this._stage = this.STARTED }, _resetActiveElement: function() { if (DX.devices.real().platform !== "ios") return; this._eachEmitter(function(emitter) { if ($(":focus", emitter.getElement()).length) utils.resetActiveElement() }) }, _filterEmitters: function(e) { this._filterByDirection(e); if (this._emitersAmount() > 1) this._takeFirstEmitter() }, _emitersAmount: function() { var result = 0; this._eachEmitter(function() { result++ }); return result }, _filterByDirection: function(e) { var delta = events.eventDelta(this._startEventData, events.eventData(e)), horizontalMove = abs(delta.y) < abs(delta.x), verticalMove = abs(delta.y) > abs(delta.x), horizontalEmmiter = this._activeEmitters[HORIZONTAL], verticalEmmiter = this._activeEmitters[VERTICAL], bothEmitter = this._activeEmitters[BOTH], existsHorizontalEmitter = horizontalEmmiter || bothEmitter, existsVerticalEmitter = verticalEmmiter || bothEmitter; if (horizontalMove && existsHorizontalEmitter) this._cancelEmitter(verticalEmmiter, e); else if (verticalMove && existsVerticalEmitter) this._cancelEmitter(horizontalEmmiter, e) }, _cancelEmitter: function(canceledEmmiter, e) { if (!canceledEmmiter) return; canceledEmmiter.cancel(e); delete this._activeEmitters[canceledEmmiter.getDirection(e)] }, _takeFirstEmitter: function() { var activeEmitters = {}; this._eachEmitter(function(emitter, direction) { activeEmitters[direction] = emitter; return false }); this._activeEmitters = activeEmitters }, _prepareGesture: function() { this._gestureLocked = true; clearTimeout(this._gestureEndTimer); this._eachEmitter(function(emitter) { emitter.getElement().data(GESTURE_LOCK_KEY, true) }); ui.feedback.reset() }, _handleMove: function(e) { if (!this._gestureLocked) { var delta = events.eventDelta(this._startEventData, events.eventData(e)); if (abs(delta.x) > TOUCH_BOUNDARY || abs(delta.y) > TOUCH_BOUNDARY) { events.handleGestureEvent(e, GESTURE_EVENT); this._prepareGesture() } } this._applyToActive("move", e) }, _forgetGesture: function(activeEmitters) { activeEmitters = activeEmitters || this._activeEmitters; if (this._noEmitters()) return; this._gestureLocked = false; this._gestureEndTimer = setTimeout(function() { $.each(activeEmitters, function(_, emitter) { emitter.getElement().data(GESTURE_LOCK_KEY, false) }) }, GESTURE_UNLOCK_TIMEOUT) }, _handlePointerUp: function(e) { if (!DX.devices.isRippleEmulator() && events.hasTouches(e)) return; if (this._stage === this.STARTED) this._applyToActive("end", e); else if (this._stage === this.INITED) this._applyToActive("stop", e); this.reset() }, _handleMouseWheel: function(e) { this._handlePointerDown(e); if (this._stage !== this.INITED) return; this._takeFirstEmitter(); this._eachEmitter(function(emitter, direction) { var prop = direction !== "horizontal" ? "pageY" : "pageX"; e[prop] += e.delta }); this._handlePointerMove(e); this._handlePointerUp(e) }, isActive: function(element) { var result = false; this._eachEmitter(function(emitter) { result = result || emitter.getElement().is(element) }); return result } }); var gestureEventManager = new GestureEventManager; var registerEmitter = function(emitterConfig) { var emitterClass = emitterConfig.emitter; $.each(emitterConfig.events, function(_, eventName) { events.registerEvent(eventName, { noBubble: true, setup: function(element, data) { var emitter = $(element).data(GESTURE_EVENT_DATA) || new emitterClass(element); emitter.configurate(data); $(element).data(GESTURE_EVENT_DATA, emitter) }, teardown: function(element) { if (gestureEventManager.isActive(element)) gestureEventManager.reset(); $(element).removeData(GESTURE_EVENT_DATA) } }) }) }; $.each(ui.gestureEmitters, function(_, emitterConfig) { registerEmitter(emitterConfig) }); events.__internals = events.__internals || {}; $.extend(events.__internals, {registerEmitter: registerEmitter}) })(jQuery, DevExpress); /*! Module core, file ui.widget.js */ (function($, DX, undefined) { var ui = DX.ui, UI_FEEDBACK = "UIFeedback", UI_FEEDBACK_CLASS = "dx-feedback", ACTIVE_STATE_CLASS = "dx-state-active", DISABLED_STATE_CLASS = "dx-state-disabled", INVISIBLE_STATE_CLASS = "dx-state-invisible", HOVER_STATE_CLASS = "dx-state-hover", FEEDBACK_SHOW_TIMEOUT = 30, FEEDBACK_HIDE_TIMEOUT = 400, HOVER_START = "dxhoverstart", HOVER_END = "dxhoverend", ANONYMOUS_TEMPLATE_NAME = "template", TEMPLATE_SELECTOR = "[data-options*='dxTemplate']", TEMPLATES_DATA_KEY = "dxTemplates"; var getTemplateOptions = function(element) { var options = $(element).data("options"); if ($.trim(options).charAt(0) !== "{") options = "{" + options + "}"; return new Function("return " + options)().dxTemplate }; var activeElement, events = ui.events; ui.feedback = {reset: function() { handleEnd(true) }}; ui.Widget = DX.DOMComponent.inherit({ NAME: "Widget", NAMESPACE: ui, _setDefaultOptions: function() { this.callBase(); this.option({ disabled: false, visible: true, activeStateEnabled: true, width: undefined, height: undefined, contentReadyAction: null, hoverStateEnabled: false }) }, _init: function() { this.callBase(); this._feedbackShowTimeout = FEEDBACK_SHOW_TIMEOUT; this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT; if (this._templatesSupported()) { this._initTemplates(); this._initContentReadyAction() } }, _templatesSupported: function() { return this._renderContentImpl !== DX.abstract }, _initTemplates: function() { var that = this, templates = {}, dataTemplateElements = this._element().data(TEMPLATES_DATA_KEY), templateElements = dataTemplateElements ? dataTemplateElements : this._element().contents().filter(TEMPLATE_SELECTOR); this._templateProvider = new ui.TemplateProvider; this._templateClass = this._templateProvider.getTemplateClass(this); if (templateElements.length) { var templatesMap = {}; templateElements.each(function() { var templateOptions = getTemplateOptions(this); if (!templateOptions) return; if (!templateOptions.name) throw Error("Template name was not specified"); templatesMap[templateOptions.name] = templatesMap[templateOptions.name] || []; templatesMap[templateOptions.name].push(this) }); $.each(templatesMap, function(templateName, value) { var deviceTemplate = that._findTemplateByDevice(value); if (deviceTemplate) templates[templateName] = that._createTemplate(deviceTemplate) }) } else templates[ANONYMOUS_TEMPLATE_NAME] = that._createTemplate(that._element().contents()); this.option("_templates", templates) }, _getTemplateByOption: function(optionName) { return this._getTemplate(this.option(optionName)) }, _getTemplate: function(templateName) { var result = this._acquireTemplate.apply(this, arguments); if (!result && this._templateProvider.supportDefaultTemplate(this)) { result = this._templateProvider.getDefaultTemplate(this); if (!result) throw Error(DX.utils.stringFormat("Template \"{0}\" was not found and no default template specified!", templateName)); } return result }, _acquireTemplate: function(templateSource) { if (templateSource == null) return templateSource; if (templateSource instanceof this._templateClass) return templateSource; if (templateSource.nodeType || templateSource.jquery) { templateSource = $(templateSource); if (templateSource.is("script")) templateSource = templateSource.html(); return this._createTemplate(templateSource) } if (typeof templateSource === "string") return this.option("_templates")[templateSource]; if ($.isFunction(templateSource)) { var args = $.makeArray(arguments).slice(1); return this._acquireTemplate(templateSource.apply(this, args)) } return this._acquireTemplate(templateSource.toString()) }, _createTemplate: function(element) { return new this._templateClass(element, this) }, _findTemplateByDevice: function(templates) { var suitableTemplate = DX.utils.findBestMatches(DX.devices.current(), templates, function(template) { return getTemplateOptions(template) })[0]; $.each(templates, function(index, template) { if (template !== suitableTemplate) $(template).remove() }); return suitableTemplate }, _cleanTemplates: function() { var that = this; $.each(this.option("_templates"), function(templateName, template) { if (that === template.owner()) template.dispose() }) }, _initContentReadyAction: function() { this._contentReadyAction = this._createActionByOption("contentReadyAction", {excludeValidators: ["gesture", "designMode", "disabled"]}) }, _render: function() { this.callBase(); this._element().addClass("dx-widget"); this._toggleDisabledState(this.option("disabled")); this._toggleVisibility(this.option("visible")); this._refreshFeedback(); this._renderDimensions(); if (this._templatesSupported()) this._renderContent(); this._attachHoverEvents() }, _renderContent: function() { this._renderContentImpl(); this._fireContentReadyAction() }, _renderContentImpl: DX.abstract, _fireContentReadyAction: function() { this._contentReadyAction({excludeValidators: ["disabled", "gesture"]}) }, _dispose: function() { if (this._templatesSupported()) this._cleanTemplates(); this._contentReadyAction = null; this._clearTimers(); if (activeElement && activeElement.closest(this._element()).length) activeElement = null; this.callBase() }, _clean: function() { this.callBase(); this._element().empty() }, _clearTimers: function() { clearTimeout(this._feedbackHideTimer); clearTimeout(this._feedbackShowTimer) }, _toggleVisibility: function(visible) { this._element().toggleClass(INVISIBLE_STATE_CLASS, !visible) }, _attachHoverEvents: function() { var that = this, hoverableSelector = that._activeStateUnit, nameStart = events.addNamespace(HOVER_START, UI_FEEDBACK), nameEnd = events.addNamespace(HOVER_END, UI_FEEDBACK); that._element().off(nameStart, hoverableSelector).off(nameEnd, hoverableSelector); if (this.option("hoverStateEnabled")) { var startAction = new DX.Action(function(args) { var $target = args.element; that._refreshHoveredElement($target) }); that._element().on(nameStart, hoverableSelector, {selector: hoverableSelector}, function(e) { startAction.execute({element: $(e.target)}) }).on(nameEnd, hoverableSelector, {selector: hoverableSelector}, function(e) { e.stopImmediatePropagation(); that._forgetHoveredElement() }) } else this._toggleHoverClass(false) }, _refreshHoveredElement: function(hoveredElement) { var selector = this._activeStateUnit || this._element(); this._forgetHoveredElement(); this._hoveredElement = hoveredElement.closest(selector); this._toggleHoverClass(true) }, _forgetHoveredElement: function() { this._toggleHoverClass(false); delete this._hoveredElement }, _toggleHoverClass: function(value) { if (this._hoveredElement) this._hoveredElement.toggleClass(HOVER_STATE_CLASS, value && this.option("hoverStateEnabled")) }, _renderDimensions: function() { var width = this.option("width"), height = this.option("height"); this._setDimension(width, "width"); this._setDimension(height, "height") }, _setDimension: function(dimensionSize, dimension) { var $element = this._element(); dimensionSize = $.isFunction(dimensionSize) ? dimensionSize() : dimensionSize; if ($.isNumeric(dimensionSize)) dimensionSize = dimensionSize + "px"; if (!dimensionSize && dimension === "width") dimensionSize = this._calculateWidth(); $element.css(dimension, dimensionSize) }, _calculateWidth: function() { var $element = this._element(), explicitWidth = $element[0].style.width, calculatedWidth; if (explicitWidth[explicitWidth.length - 1] === "%" && !this.option("width")) return explicitWidth; else calculatedWidth = explicitWidth && explicitWidth !== "auto" && explicitWidth !== "inherit" ? $element.outerWidth() : this.option("width"); return calculatedWidth }, _refreshFeedback: function() { if (this._feedbackDisabled()) { this._feedbackOff(true); this._element().removeClass(UI_FEEDBACK_CLASS) } else this._element().addClass(UI_FEEDBACK_CLASS) }, _feedbackDisabled: function() { return !this.option("activeStateEnabled") || this.option("disabled") }, _feedbackOn: function(element, immediate) { if (this._feedbackDisabled()) return; this._clearTimers(); if (immediate) this._feedbackShow(element); else this._feedbackShowTimer = window.setTimeout($.proxy(this._feedbackShow, this, element), this._feedbackShowTimeout); this._saveActiveElement() }, _feedbackShow: function(element) { var activeStateElement = this._element(); if (this._activeStateUnit) activeStateElement = $(element).closest(this._activeStateUnit); if (!activeStateElement.hasClass(DISABLED_STATE_CLASS)) { activeStateElement.addClass(ACTIVE_STATE_CLASS); this._toggleHoverClass(false) } }, _saveActiveElement: function() { activeElement = this._element() }, _feedbackOff: function(immediate) { this._clearTimers(); if (immediate) this._feedbackHide(); else this._feedbackHideTimer = window.setTimeout($.proxy(this._feedbackHide, this), this._feedbackHideTimeout) }, _feedbackHide: function() { var activeStateElement = this._element(); if (this._activeStateUnit) activeStateElement = activeStateElement.find(this._activeStateUnit); activeStateElement.removeClass(ACTIVE_STATE_CLASS); this._toggleHoverClass(!this.option("disabled")); this._clearActiveElement() }, _clearActiveElement: function() { var rootDomElement = this._element().get(0), activeDomElement = activeElement && activeElement.get(0); if (activeDomElement && (activeDomElement === rootDomElement || $.contains(rootDomElement, activeDomElement))) activeElement = null }, _toggleDisabledState: function(value) { this._element().toggleClass(DISABLED_STATE_CLASS, Boolean(value)); this._toggleHoverClass(!value) }, _optionChanged: function(name, value) { switch (name) { case"disabled": this._toggleDisabledState(value); this._refreshFeedback(); break; case"activeStateEnabled": this._refreshFeedback(); break; case"hoverStateEnabled": this._attachHoverEvents(); break; case"visible": this._toggleVisibility(value); break; case"width": case"height": this._renderDimensions(); break; case"contentReadyAction": this._initContentReadyAction(); break; case"_templates": this._refresh(); break; default: this.callBase.apply(this, arguments) } }, repaint: function() { this._refresh() } }); var handleStart = function(args, immediate) { var e = args.jQueryEvent, $target = args.element, widget; if (events.needSkipEvent(e)) return; if (activeElement) { widget = getWidget(activeElement); if (widget) widget._feedbackOff(true) } var closestFeedbackElement = $target.closest("." + UI_FEEDBACK_CLASS); if (closestFeedbackElement.length) { widget = getWidget(closestFeedbackElement); if (!widget) return; widget._feedbackOn($target, immediate); if (immediate) widget._feedbackOff() } }; var handleEnd = function(immediate) { if (!activeElement) return; var widget = getWidget(activeElement); if (widget) widget._feedbackOff(immediate) }; var getWidget = function(widgetElement) { var result; $.each(widgetElement.data("dxComponents") || [], function(index, componentName) { if (ui[componentName] && ui[componentName].subclassOf(ui.Widget)) { result = widgetElement.data(componentName); return false } }); return result }; $(function() { var startAction = new DX.Action(handleStart); $(document).on(events.addNamespace("dxpointerdown", UI_FEEDBACK), function(e) { startAction.execute({ jQueryEvent: e, element: $(e.target) }) }).on(events.addNamespace("dxpointerup dxpointercancel", UI_FEEDBACK), function(e) { var activeElementClicked = activeElement && $(e.target).closest("." + UI_FEEDBACK_CLASS).get(0) === activeElement.get(0); if (activeElementClicked) startAction.execute({ jQueryEvent: e, element: $(e.target) }, true); handleEnd() }) }) })(jQuery, DevExpress); /*! Module core, file ui.editor.js */ (function($, DX, undefined) { var ui = DX.ui; DX.registerComponent("dxEditor", ui.Widget.inherit({ _setDefaultOptions: function() { this.callBase(); this.option({ value: undefined, valueChangeAction: undefined }) }, _recreateValueChangeAction: function() { this._valueChangeAction = this._createActionByOption("valueChangeAction") }, _suppressValueChangeAction: function() { this._valueChangeActionSuppressed = true }, _resumeValueChangeAction: function() { this._valueChangeActionSuppressed = false }, _render: function() { this._recreateValueChangeAction(); this.callBase() }, _raiseValueChangeAction: function(value, previousValue, extraArguments) { var args = { value: value, previousValue: previousValue, jQueryEvent: this._valueChangeEventInstance }; if (extraArguments) args = $.extend(args, extraArguments); this._valueChangeAction(args) }, _optionChanged: function(name, value, previousValue) { switch (name) { case"valueChangeAction": this._recreateValueChangeAction(); break; case"value": if (!this._valueChangeActionSuppressed) this._raiseValueChangeAction(value, previousValue); this._valueChangeEventInstance = undefined; break; default: this.callBase.apply(this, arguments) } } })) })(jQuery, DevExpress); /*! Module core, file ui.template.js */ (function($, DX, undefined) { var isString = DX.utils.isString; var currentTemplateEngine; var templateEngines = []; var BaseTemplate = DevExpress.Class.inherit({ _compile: function(html, element) { return element }, _render: function(template, data) { return template }, ctor: function(element) { this._element = $(element); if (this._element.length === 1) { if (this._element[0].nodeName.toLowerCase() !== "script") this._element = $("
").append(this._element); this._template = this._compile(this._element.html() || "", this._element) } }, render: function(container, data) { var result; if (this._template) { result = this._render(this._template, data); if (isString(result)) result = $.parseHTML(result); result = $(result); if (container) container.append(result); return result } }, owner: $.noop, dispose: $.noop }); var createTemplateEngine = function(options) { if (options && options.compile && options.render) return BaseTemplate.inherit({ allowRenderToDetachedContainer: options.allowRenderToDetachedContainer !== false, _compile: options.compile, _render: options.render }); else throw Error("Template Engine must contains compile and render methods"); }; if (window.ko) { var koCustomTemplateEngine = function(){}; koCustomTemplateEngine.prototype = ko.utils.extend(new ko.templateEngine, { renderTemplateSource: function(templateSource, bindingContext, options) { var precompiledTemplate = templateSource["data"]("precompiledTemplate"); if (!precompiledTemplate) { precompiledTemplate = new currentTemplateEngine(templateSource.domElement); templateSource["data"]("precompiledTemplate", precompiledTemplate) } return precompiledTemplate.render(null, bindingContext.$data) }, allowTemplateRewriting: false }) } DevExpress.ui.setTemplateEngine = function(templateEngine) { if (isString(templateEngine)) { currentTemplateEngine = templateEngines && templateEngines[templateEngine]; if (!currentTemplateEngine && templateEngine !== "default") throw Error(DX.utils.stringFormat("Template Engine \"{0}\" is not supported", templateEngine)); } else currentTemplateEngine = createTemplateEngine(templateEngine) || currentTemplateEngine; if (window.ko) ko.setTemplateEngine(currentTemplateEngine ? new koCustomTemplateEngine : new ko.nativeTemplateEngine) }; DevExpress.ui.TemplateProvider = DevExpress.ui.TemplateProvider.inherit({getTemplateClass: function() { if (currentTemplateEngine) return currentTemplateEngine; return this.callBase.apply(this, arguments) }}); var registerTemplateEngine = function(name, templateOptions) { templateEngines[name] = createTemplateEngine(templateOptions) }; registerTemplateEngine("jquery-tmpl", { compile: function(html, element) { return element }, render: function(template, data) { return template.tmpl(data) } }); registerTemplateEngine("jsrender", { compile: function(html) { return $.templates(html) }, render: function(template, data) { return template.render(data) } }); registerTemplateEngine("mustache", { compile: function(html) { return Mustache.compile(html) }, render: function(template, data) { return template(data) } }); registerTemplateEngine("hogan", { compile: function(html) { return Hogan.compile(html) }, render: function(template, data) { return template.render(data) } }); registerTemplateEngine("underscore", { compile: function(html) { return _.template(html) }, render: function(template, data) { return template(data) } }); registerTemplateEngine("handlebars", { compile: function(html) { return Handlebars.compile(html) }, render: function(template, data) { return template(data) } }); registerTemplateEngine("doT", { compile: function(html) { return doT.template(html) }, render: function(template, data) { return template(data) } }) })(jQuery, DevExpress); /*! Module core, file ui.collectionContainerWidget.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var CollectionContainerWidget = ui.Widget.inherit({ _setDefaultOptions: function() { this.callBase(); this.option({ items: [], itemTemplate: "item", itemRender: null, itemRenderedAction: null, itemClickAction: null, itemHoldAction: null, itemHoldTimeout: 750, noDataText: Globalize.localize("dxCollectionContainerWidget-noDataText"), dataSource: null, selectedIndex: -1, itemSelectAction: null, itemTemplateProperty: "template" }) }, _init: function() { this.callBase(); this._cleanRenderedItems(); this._refreshDataSource() }, _dataSourceOptions: function() { var options = { paginate: false, _preferSync: false }; if ($.isArray(this.option("dataSource"))) options._preferSync = true; return options }, _cleanRenderedItems: function() { this._renderedItemsCount = 0 }, _fireSelectItemEvent: function(index, prevIndex) { if (this._selectionEnabled()) { this._updateSelectedIndex(index, prevIndex); this._handleItemEvent(this._selectedItemElement(index), "itemSelectAction", { selectedIndex: index, previousIndex: prevIndex }, {excludeValidators: ["gesture", "disabled"]}) } }, _optionChanged: function(name, value, prevValue) { switch (name) { case"items": case"itemTemplateProperty": if (this._selectionEnabled()) { var itemsCount = value && value.length || 0, maxIndex = Math.max(itemsCount - 1, 0); if (maxIndex < this.option("selectedIndex")) this.option("selectedIndex", 0) } this._cleanRenderedItems(); this._invalidate(); break; case"dataSource": this._refreshDataSource(); if (!this._dataSource) this.option("items", []); this._renderEmptyMessage(); break; case"noDataText": this._renderEmptyMessage(); break; case"itemTemplate": this._invalidate(); break; case"itemRender": this._itemRender = null; this._invalidate(); break; case"itemRenderedAction": this._createItemRenderAction(); break; case"itemClickAction": break; case"itemHoldAction": case"itemHoldTimeout": this._attachHoldEvent(); break; case"selectedIndex": this._fireSelectItemEvent(value, prevValue); break; case"itemSelectAction": break; default: this.callBase(name, value, prevValue) } }, _expectNextPageLoading: function() { this._startIndexForAppendedItems = 0 }, _expectLastItemLoading: function() { this._startIndexForAppendedItems = -1 }, _forgetNextPageLoading: function() { this._startIndexForAppendedItems = null }, _handleDataSourceChanged: function(newItems) { var items = this.option("items"); if (this._initialized && items && this._shouldAppendItems()) { this._renderedItemsCount = items.length; if (!this._dataSource.isLastPage() || this._startIndexForAppendedItems !== -1) this.option().items = items.concat(newItems.slice(this._startIndexForAppendedItems)); this._renderContent(); this._forgetNextPageLoading() } else this.option("items", newItems) }, _handleDataSourceLoadError: function() { this._forgetNextPageLoading() }, _shouldAppendItems: function() { return this._startIndexForAppendedItems != null && this._allowDinamicItemsAppend() }, _allowDinamicItemsAppend: function() { return false }, _clean: function() { this._itemContainer().empty() }, _refresh: function() { this._cleanRenderedItems(); this.callBase.apply(this, arguments) }, _itemContainer: function() { return this._element() }, _itemClass: DX.abstract, _itemSelector: function() { return "." + this._itemClass() }, _itemDataKey: DX.abstract, _itemElements: function() { return this._itemContainer().find(this._itemSelector()) }, _render: function() { this.callBase(); this._attachClickEvent(); this._attachHoldEvent(); if (this._selectionEnabled()) { this._renderSelectedIndex(this.option("selectedIndex")); this._attachSelectedEvent() } }, _selectionEnabled: function() { return this._renderSelectedIndex !== DX.abstract }, _selectionByClickEnabled: function() { return true }, _renderSelectedIndex: DX.abstract, _attachSelectedEvent: function() { if (!this._selectionByClickEnabled()) return; var itemSelector = this._itemSelector(), itemSelectHandler = this._createAction($.proxy(function(e) { this._handleItemSelect(e.jQueryEvent) }, this), {validatingTargetName: "itemElement"}), eventName = events.addNamespace("dxclick", this.NAME); this._element().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(function(e) { var $itemElement = $(e.target).closest(itemSelector); itemSelectHandler({ itemElement: $itemElement, jQueryEvent: e }); this._handleItemClick(e) }, this)) }, _handleItemSelect: function(e) { if (events.needSkipEvent(e)) return; var items = this.option("items"), selectedItem = $(e.currentTarget).data(this._itemDataKey()), selectedItemIndex = $.inArray(selectedItem, items); this.option("selectedIndex", selectedItemIndex) }, _updateSelectedIndex: function() { this._renderSelectedIndex.apply(this, arguments) }, _selectedItemElement: function(index) { return this._itemElements().eq(index) }, _attachClickEvent: function() { if (this._selectionEnabled() && this._selectionByClickEnabled()) return; var itemSelector = this._itemSelector(), eventName = events.addNamespace("dxclick", this.NAME); this._itemContainer().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(this._handleItemClick, this)) }, _handleItemClick: function(e) { this._handleItemJQueryEvent(e, "itemClickAction") }, _attachHoldEvent: function() { var $itemContainer = this._itemContainer(), itemSelector = this._itemSelector(), eventName = events.addNamespace("dxhold", this.NAME); $itemContainer.off(eventName, itemSelector); if (this._shouldAttachHoldEvent()) $itemContainer.on(eventName, itemSelector, {timeout: this.option("itemHoldTimeout")}, $.proxy(this._handleItemHold, this)) }, _shouldAttachHoldEvent: function() { return this.option("itemHoldAction") }, _handleItemHold: function(e) { this._handleItemJQueryEvent(e, "itemHoldAction") }, _renderContentImpl: function() { var items = this.option("items") || []; if (this._renderedItemsCount) this._renderItems(items.slice(this._renderedItemsCount)); else this._renderItems(items) }, _renderItems: function(items) { if (items.length) $.each(items, $.proxy(this._renderItem, this)); this._renderEmptyMessage() }, _renderItem: function(index, itemData, container) { container = container || this._itemContainer(); var itemRenderer = this._getItemRenderer(), itemTemplateName = this._getItemTemplateName(itemData), itemTemplate = this._getTemplate(itemTemplateName, index, itemData), itemElement, renderArgs = { index: index, item: itemData, container: container }; if (itemRenderer) itemElement = this._createItemByRenderer(itemRenderer, renderArgs); else if (itemTemplate) itemElement = this._createItemByTemplate(itemTemplate, renderArgs); else itemElement = this._createItemByRenderer(this._itemRenderDefault, renderArgs); itemElement.addClass(this._itemClass()).data(this._itemDataKey(), itemData); var postprocessRenderArgs = { itemElement: itemElement, itemData: itemData, itemIndex: index }; this._postprocessRenderItem(postprocessRenderArgs); this._getItemRenderAction()({ itemElement: itemElement, itemData: itemData }); return itemElement }, _createItemRenderAction: function() { return this._itemRenderAction = this._createActionByOption("itemRenderedAction", { element: this._element(), excludeValidators: ["gesture", "designMode", "disabled"] }) }, _getItemRenderAction: function() { return this._itemRenderAction || this._createItemRenderAction() }, _getItemRenderer: function() { this._itemRender = this._itemRender || this.option("itemRender"); return this._itemRender }, _createItemByRenderer: function(itemRenderer, renderArgs) { var itemElement = $("
").appendTo(renderArgs.container); var rendererResult = itemRenderer.call(this, renderArgs.item, renderArgs.index, itemElement); if (rendererResult != null && itemElement[0] !== rendererResult[0]) itemElement.append(rendererResult); return itemElement }, _getItemTemplateName: function(itemData) { var templateProperty = this.option("itemTemplateProperty"); return itemData && itemData[templateProperty] || this.option("itemTemplate") }, _createItemByTemplate: function(itemTemplate, renderArgs) { return itemTemplate.render(renderArgs.container, renderArgs.item, renderArgs.index, "ignoreTarget") }, _itemRenderDefault: function(item, index, itemElement) { if ($.isPlainObject(item)) { if (item.visible !== undefined && !item.visible) itemElement.hide(); if (item.disabled) itemElement.addClass("dx-state-disabled"); if (item.text) itemElement.text(item.text); if (item.html) itemElement.html(item.html) } else itemElement.html(String(item)) }, _postprocessRenderItem: $.noop, _renderEmptyMessage: function() { if (!this._selectionEnabled()) { var noDataText = this.option("noDataText"), items = this.option("items"), dataSourceLoading = this._dataSource && this._dataSource.isLoading(), hideNoData = !noDataText || items && items.length || dataSourceLoading; if (hideNoData && this._$nodata) { this._$nodata.remove(); this._$nodata = null } if (!hideNoData) { this._$nodata = this._$nodata || $("
").addClass("dx-empty-message"); this._$nodata.appendTo(this._itemContainer()).text(noDataText) } } }, _handleItemJQueryEvent: function(jQueryEvent, handlerOptionName, actionArgs, actionConfig) { this._handleItemEvent(jQueryEvent.target, handlerOptionName, $.extend(actionArgs, {jQueryEvent: jQueryEvent}), actionConfig) }, _handleItemEvent: function(initiator, handlerOptionName, actionArgs, actionConfig) { var action = this._createActionByOption(handlerOptionName, $.extend({validatingTargetName: "itemElement"}, actionConfig)); return this._handleItemEventImpl(initiator, action, actionArgs) }, _handleItemEventByHandler: function(initiator, handler, actionArgs, actionConfig) { var action = this._createAction(handler, $.extend({validatingTargetName: "itemElement"}, actionConfig)); return this._handleItemEventImpl(initiator, action, actionArgs) }, _handleItemEventImpl: function(initiator, action, actionArgs) { var $itemElement = this._closestItemElement($(initiator)); actionArgs = $.extend({ itemElement: $itemElement, itemData: this._getItemData($itemElement) }, actionArgs); return action(actionArgs) }, _closestItemElement: function($element) { return $($element).closest(this._itemSelector()) }, _getItemData: function($itemElement) { return $itemElement.data(this._itemDataKey()) }, itemElements: function() { return this._itemElements() }, itemsContainer: function() { return this._itemContainer() } }).include(ui.DataHelperMixin); ui.CollectionContainerWidget = CollectionContainerWidget })(jQuery, DevExpress); /*! Module core, file ui.tooltip.js */ (function($, DX, undefined) { var $tooltip = null; var createTooltip = function(options) { options = $.extend({position: "top"}, options); var content = options.content; delete options.content; return $("
").html(content).appendTo(DX.overlayTargetContainer()).dxTooltip(options) }; var removeTooltip = function() { if (!$tooltip) return; $tooltip.remove(); $tooltip = null }; var tooltip = { show: function(options) { removeTooltip(); $tooltip = createTooltip(options); return $tooltip.dxTooltip("show") }, hide: function() { if (!$tooltip) return $.when(); return $tooltip.dxTooltip("hide").done(removeTooltip).promise() } }; DX.ui.tooltip = tooltip })(jQuery, DevExpress) } if (!DevExpress.MOD_WIDGETS_BASE) { if (!window.DevExpress) throw Error('Required module is not referenced: core'); /*! Module widgets-base, file ui.scrollable.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var SCROLLABLE = "dxScrollable", SCROLLABLE_STRATEGY = "dxScrollableStrategy", SCROLLABLE_CLASS = "dx-scrollable", SCROLLABLE_DISABLED_CLASS = "dx-scrollable-disabled", SCROLLABLE_CONTAINER_CLASS = "dx-scrollable-container", SCROLLABLE_CONTENT_CLASS = "dx-scrollable-content", VERTICAL = "vertical", HORIZONTAL = "horizontal", BOTH = "both"; DX.registerComponent(SCROLLABLE, DX.DOMComponent.inherit({ NAMESPACE: ui, _setDefaultOptions: function() { this.callBase(); this.option({ disabled: false, scrollAction: null, direction: VERTICAL, showScrollbar: true, useNative: true, updateAction: null, useSimulatedScrollbar: false, useKeyboard: true, inertiaEnabled: true, bounceEnabled: true, scrollByContent: true, scrollByThumb: false, startAction: null, endAction: null, bounceAction: null, stopAction: null }) }, _defaultOptionsRules: function() { return this.callBase().slice(0).concat([{ device: function(device) { return !DX.support.nativeScrolling }, options: { useNative: false, useSimulatedScrollbar: true } }, { device: function(device) { return !DX.support.nativeScrolling && !DX.devices.isSimulator() && DX.devices.real().platform === "generic" && device.platform === "generic" }, options: { scrollByThumb: true, scrollByContent: DX.support.touch, showScrollbar: "onHover", bounceEnabled: false } }, { device: function(device) { return DX.support.nativeScrolling && DX.devices.real().platform === "android" }, options: {useSimulatedScrollbar: true} }]) }, _init: function() { this.callBase(); this._initMarkup(); this._attachNativeScrollbarsCustomizationCss(); this._locked = false }, _visibilityChanged: function(visible) { if (visible) { this.update(); this._savedScrollOffset && this.scrollTo(this._savedScrollOffset) } else this._savedScrollOffset = this.scrollOffset() }, _initMarkup: function() { var $element = this._element().addClass(SCROLLABLE_CLASS), $container = this._$container = $("
").addClass(SCROLLABLE_CONTAINER_CLASS), $content = this._$content = $("
").addClass(SCROLLABLE_CONTENT_CLASS); $content.append($element.contents()).appendTo($container); $container.appendTo($element) }, _dimensionChanged: function() { this.update() }, _attachNativeScrollbarsCustomizationCss: function() { if (!(navigator.platform.indexOf('Mac') > -1 && DevExpress.browser['webkit'])) this._element().addClass("dx-scrollable-customizable-scrollbars") }, _render: function() { this._renderDirection(); this._renderStrategy(); this._attachEventHandlers(); this._renderDisabledState(); this._createActions(); this.update(); this.callBase() }, _toggleRTLDirection: function(rtl) { this.callBase(rtl); if (rtl) this.scrollTo({left: this.scrollWidth() - this.clientWidth()}) }, _attachEventHandlers: function() { var strategy = this._strategy; var initEventData = { getDirection: $.proxy(strategy.getDirection, strategy), validate: $.proxy(this._validate, this) }; this._$container.off("." + SCROLLABLE).on(events.addNamespace("scroll", SCROLLABLE), $.proxy(strategy.handleScroll, strategy)).on(events.addNamespace("dxscrollinit", SCROLLABLE), initEventData, $.proxy(strategy.handleInit, strategy)).on(events.addNamespace("dxscrollstart", SCROLLABLE), $.proxy(strategy.handleStart, strategy)).on(events.addNamespace("dxscroll", SCROLLABLE), $.proxy(strategy.handleMove, strategy)).on(events.addNamespace("dxscrollend", SCROLLABLE), $.proxy(strategy.handleEnd, strategy)).on(events.addNamespace("dxscrollcancel", SCROLLABLE), $.proxy(strategy.handleCancel, strategy)).on(events.addNamespace("dxscrollstop", SCROLLABLE), $.proxy(strategy.handleStop, strategy)) }, _validate: function(e) { this.update(); return this._strategy.validate(e) }, _renderDisabledState: function() { this._element().toggleClass(SCROLLABLE_DISABLED_CLASS, this.option("disabled")); if (this.option("disabled")) this._lock(); else this._unlock() }, _renderDirection: function() { this._element().removeClass("dx-scrollable-" + HORIZONTAL).removeClass("dx-scrollable-" + VERTICAL).removeClass("dx-scrollable-" + BOTH).addClass("dx-scrollable-" + this.option("direction")) }, _renderStrategy: function() { this._createStrategy(); this._strategy.render(); this._element().data(SCROLLABLE_STRATEGY, this._strategy) }, _createStrategy: function() { this._strategy = this.option("useNative") ? new ui.NativeScrollableStrategy(this) : new ui.SimulatedScrollableStrategy(this) }, _createActions: function() { this._strategy.createActions() }, _clean: function() { this._strategy.dispose() }, _optionChanged: function(optionName, optionValue) { switch (optionName) { case"startAction": case"endAction": case"stopAction": case"updateAction": case"scrollAction": case"bounceAction": this._createActions(); break; case"direction": this._resetInactiveDirection(); this._invalidate(); break; case"inertiaEnabled": case"bounceEnabled": case"scrollByContent": case"scrollByThumb": case"bounceEnabled": case"useNative": case"useKeyboard": case"showScrollbar": case"useSimulatedScrollbar": this._invalidate(); break; case"disabled": this._renderDisabledState(); break; default: this.callBase.apply(this, arguments) } }, _resetInactiveDirection: function() { var inactiveProp = this._getInactiveProp(); if (!inactiveProp) return; var scrollOffset = this.scrollOffset(); scrollOffset[inactiveProp] = 0; this.scrollTo(scrollOffset) }, _getInactiveProp: function() { var direction = this.option("direction"); if (direction === VERTICAL) return "left"; if (direction === HORIZONTAL) return "top" }, _location: function() { return this._strategy.location() }, _normalizeLocation: function(location) { var direction = this.option("direction"); return { left: $.isPlainObject(location) ? -(location.left || location.x || 0) : direction !== VERTICAL ? -location : 0, top: $.isPlainObject(location) ? -(location.top || location.y || 0) : direction !== HORIZONTAL ? -location : 0 } }, _isLocked: function() { return this._locked }, _lock: function() { this._locked = true }, _unlock: function() { this._locked = false }, _isDirection: function(direction) { var current = this.option("direction"); if (direction === VERTICAL) return current !== HORIZONTAL; if (direction === HORIZONTAL) return current !== VERTICAL; return current === direction }, _updateAllowedDirection: function() { var allowedDirections = this._strategy._allowedDirections(); if (this._isDirection(BOTH) && allowedDirections.vertical && allowedDirections.horizontal) this._allowedDirectionValue = BOTH; else if (this._isDirection(HORIZONTAL) && allowedDirections.horizontal) this._allowedDirectionValue = HORIZONTAL; else if (this._isDirection(VERTICAL) && allowedDirections.vertical) this._allowedDirectionValue = VERTICAL; else this._allowedDirectionValue = null }, _allowedDirection: function() { return this._allowedDirectionValue }, content: function() { return this._$content }, scrollOffset: function() { var location = this._location(); return { top: -location.top, left: -location.left } }, scrollTop: function() { return this.scrollOffset().top }, scrollLeft: function() { return this.scrollOffset().left }, clientHeight: function() { return this._$container.height() }, scrollHeight: function() { return this.content().height() }, clientWidth: function() { return this._$container.width() }, scrollWidth: function() { return this.content().width() }, update: function() { this._strategy.update(); this._updateAllowedDirection(); return $.Deferred().resolve().promise() }, scrollBy: function(distance) { distance = this._normalizeLocation(distance); if (!distance.top && !distance.left) return; this._strategy.scrollBy(distance) }, scrollTo: function(targetLocation) { targetLocation = this._normalizeLocation(targetLocation); var location = this._location(); this.scrollBy({ left: location.left - targetLocation.left, top: location.top - targetLocation.top }) }, scrollToElement: function(element) { var $element = $(element); if (!$element.length || !this._element().find($element).length) return; var position = { top: 0, left: 0 }; var direction = this.option("direction"); if (direction !== VERTICAL) position.left = this._elementPosition($element, HORIZONTAL); if (direction !== HORIZONTAL) position.top = this._elementPosition($element, VERTICAL); this.scrollTo(position) }, _elementPosition: function($element, direction) { var elementPosition = $element.position()[direction === VERTICAL ? 'top' : 'left']; var elementSize = $element[direction === VERTICAL ? 'outerHeight' : 'outerWidth'](); var elementBottom = elementPosition + elementSize; var scrollLocation = direction === VERTICAL ? this.scrollTop() : this.scrollLeft(); var clientSize = direction === VERTICAL ? this.clientHeight() : this.clientWidth(); var isAlreadyVisible = scrollLocation <= elementPosition && elementBottom <= scrollLocation + clientSize; var isElementBelowScrollLocation = scrollLocation > elementPosition; return isAlreadyVisible ? scrollLocation : elementPosition + (isElementBelowScrollLocation ? 0 : elementSize - clientSize) } })) })(jQuery, DevExpress); /*! Module widgets-base, file ui.scrollbar.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var SCROLLBAR = "dxScrollbar", SCROLLABLE_SCROLLBAR_CLASS = "dx-scrollable-scrollbar", SCROLLABLE_SCROLLBAR_ACTIVE_CLASS = SCROLLABLE_SCROLLBAR_CLASS + "-active", SCROLLABLE_SCROLL_CLASS = "dx-scrollable-scroll", SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden", HOVER_ENABLED_STATE = "dx-scrollbar-hoverable", VERTICAL = "vertical", HORIZONTAL = "horizontal", THUMB_MIN_SIZE = 15; var SCROLLBAR_VISIBLE = { onScroll: "onScroll", onHover: "onHover", always: "always", never: "never" }; DX.registerComponent(SCROLLBAR, ui.Widget.inherit({ _setDefaultOptions: function() { this.callBase(); this.option({ direction: null, visible: false, activeStateEnabled: false, visibilityMode: SCROLLBAR_VISIBLE.onScroll, containerSize: 0, contentSize: 0 }) }, _init: function() { this.callBase(); this._isHovered = false }, _render: function() { this._renderThumb(); this.callBase(); this._renderDirection(); this._update(); this._attachPointerDownHandler(); this.option("hoverStateEnabled", this._isHoverMode()); this._element().toggleClass(HOVER_ENABLED_STATE, this.option("hoverStateEnabled")) }, _renderThumb: function() { this._$thumb = $("
").addClass(SCROLLABLE_SCROLL_CLASS); this._element().addClass(SCROLLABLE_SCROLLBAR_CLASS).append(this._$thumb) }, isThumb: function($element) { return !!this._element().find($element).length }, _isHoverMode: function() { return this.option("visibilityMode") === SCROLLBAR_VISIBLE.onHover }, _renderDirection: function() { var direction = this.option("direction"); this._element().addClass("dx-scrollbar-" + direction); this._dimension = direction === HORIZONTAL ? "width" : "height"; this._prop = direction === HORIZONTAL ? "left" : "top" }, _attachPointerDownHandler: function() { this._$thumb.on(events.addNamespace("dxpointerdown", SCROLLBAR), $.proxy(this.feedbackOn, this)) }, feedbackOn: function() { this._element().addClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS); activeScrollbar = this }, feedbackOff: function() { this._element().removeClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS); activeScrollbar = null }, cursorEnter: function() { this._isHovered = true; this.option("visible", true) }, cursorLeave: function() { this._isHovered = false; this.option("visible", false) }, _renderDimensions: function() { this._$thumb.height(this.option("height")); this._$thumb.width(this.option("width")) }, _toggleVisibility: function(visible) { visible = this._adjustVisibility(visible); this.option().visible = visible; this._$thumb.toggleClass("dx-state-invisible", !visible) }, _adjustVisibility: function(visible) { if (this.containerToContentRatio() && !this._needScrollbar()) return false; switch (this.option("visibilityMode")) { case SCROLLBAR_VISIBLE.onScroll: break; case SCROLLBAR_VISIBLE.onHover: visible = visible || !!this._isHovered; break; case SCROLLBAR_VISIBLE.never: visible = false; break; case SCROLLBAR_VISIBLE.always: visible = true; break } return visible }, moveTo: function(location) { if (this._isHidden()) return; if ($.isPlainObject(location)) location = location[this._prop] || 0; var scrollBarLocation = {}; scrollBarLocation[this._prop] = this._calculateScrollBarPosition(location); DX.translator.move(this._$thumb, scrollBarLocation) }, _calculateScrollBarPosition: function(location) { return -location * this._thumbRatio }, _update: function() { var containerSize = this.option("containerSize"), contentSize = this.option("contentSize"); this._containerToContentRatio = containerSize / contentSize; var thumbSize = Math.round(Math.max(Math.round(containerSize * this._containerToContentRatio), THUMB_MIN_SIZE)); this._thumbRatio = (containerSize - thumbSize) / (contentSize - containerSize); this.option(this._dimension, thumbSize); this._element().toggle(this._needScrollbar()) }, _isHidden: function() { return this.option("visibilityMode") === SCROLLBAR_VISIBLE.never }, _needScrollbar: function() { return !this._isHidden() && this._containerToContentRatio < 1 }, containerToContentRatio: function() { return this._containerToContentRatio }, _normalizeSize: function(size) { return $.isPlainObject(size) ? size[this._dimension] || 0 : size }, _clean: function() { this.callBase(); if (this === activeScrollbar) activeScrollbar = null; this._$thumb.off("." + SCROLLBAR) }, _optionChanged: function(name, value) { if (this._isHidden()) return; switch (name) { case"containerSize": case"contentSize": this.option()[name] = this._normalizeSize(value); this._update(); break; case"visibilityMode": case"direction": this._invalidate(); break; default: this.callBase.apply(this, arguments) } } })); var activeScrollbar = null; $(document).on(events.addNamespace("dxpointerup", SCROLLBAR), function() { if (activeScrollbar) activeScrollbar.feedbackOff() }) })(jQuery, DevExpress); /*! Module widgets-base, file ui.scrollable.native.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, utils = DX.utils, devices = DX.devices, abs = Math.abs; var SCROLLABLE_NATIVE = "dxNativeScrollable", SCROLLABLE_NATIVE_CLASS = "dx-scrollable-native", SCROLLABLE_SCROLLBAR_SIMULATED = "dx-scrollable-scrollbar-simulated", SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden", VERTICAL = "vertical", HORIZONTAL = "horizontal", GESTURE_LOCK_KEY = "dxGestureLock", GESTURE_LOCK_TIMEOUT = 400, HIDE_SCROLLBAR_TIMOUT = 500; ui.NativeScrollableStrategy = DX.Class.inherit({ ctor: function(scrollable) { this._init(scrollable) }, _init: function(scrollable) { this._component = scrollable; this._$element = scrollable._element(); this._$container = scrollable._$container; this._$content = scrollable._$content; this._direction = scrollable.option("direction"); this._useSimulatedScrollbar = scrollable.option("useSimulatedScrollbar"); this._showScrollbar = scrollable.option("showScrollbar"); this.option = $.proxy(scrollable.option, scrollable); this._createActionByOption = $.proxy(scrollable._createActionByOption, scrollable); this._isLocked = $.proxy(scrollable._isLocked, scrollable); this._isDirection = $.proxy(scrollable._isDirection, scrollable); this._allowedDirection = $.proxy(scrollable._allowedDirection, scrollable) }, render: function() { this._$element.addClass(SCROLLABLE_NATIVE_CLASS).addClass(SCROLLABLE_NATIVE_CLASS + "-" + devices.real().platform).toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this._showScrollbar); if (this._showScrollbar && this._useSimulatedScrollbar) this._renderScrollbars() }, _renderScrollbars: function() { this._scrollbars = {}; this._hideScrollbarTimeout = 0; this._$element.addClass(SCROLLABLE_SCROLLBAR_SIMULATED); this._renderScrollbar(VERTICAL); this._renderScrollbar(HORIZONTAL) }, _renderScrollbar: function(direction) { if (!this._isDirection(direction)) return; var $scrollbar = $("
").dxScrollbar({direction: direction}).appendTo(this._$element); this._scrollbars[direction] = $scrollbar.dxScrollbar("instance") }, handleInit: $.noop, handleStart: $.noop, handleMove: function(e) { if (this._isLocked()) { e.cancel = true; return } if (this._allowedDirection()) e.originalEvent.originalEvent.isScrollingEvent = true }, handleEnd: $.noop, handleStop: $.noop, _eachScrollbar: function(callback) { callback = $.proxy(callback, this); $.each(this._scrollbars || {}, function(direction, scrollbar) { callback(scrollbar, direction) }) }, createActions: function() { var actionConfig = {excludeValidators: ["gesture"]}; this._scrollAction = this._createActionByOption("scrollAction", actionConfig); this._updateAction = this._createActionByOption("updateAction", actionConfig) }, _createActionArgs: function() { var location = this.location(); return { jQueryEvent: this._eventForUserAction, scrollOffset: { top: -location.top, left: -location.left }, reachedLeft: this._isDirection(HORIZONTAL) ? location.left >= 0 : undefined, reachedRight: this._isDirection(HORIZONTAL) ? location.left <= this._containerSize.width - this._componentContentSize.width : undefined, reachedTop: this._isDirection(VERTICAL) ? location.top >= 0 : undefined, reachedBottom: this._isDirection(VERTICAL) ? location.top <= this._containerSize.height - this._componentContentSize.height : undefined } }, handleScroll: function(e) { if (!this._isScrollLocationChanged()) { e.stopImmediatePropagation(); return } this._eventForUserAction = e; this._moveScrollbars(); this._scrollAction(this._createActionArgs()); this._treatNativeGesture(); this._lastLocation = this.location() }, _isScrollLocationChanged: function() { var currentLocation = this.location(), lastLocation = this._lastLocation || {}, isTopChanged = lastLocation.top !== currentLocation.top, isLeftChanged = lastLocation.left !== currentLocation.left; return isTopChanged || isLeftChanged }, _moveScrollbars: function() { this._eachScrollbar(function(scrollbar) { scrollbar.moveTo(this.location()); scrollbar.option("visible", true) }); this._hideScrollbars() }, _hideScrollbars: function() { clearTimeout(this._hideScrollbarTimeout); this._hideScrollbarTimeout = setTimeout($.proxy(function() { this._eachScrollbar(function(scrollbar) { scrollbar.option("visible", false) }) }, this), HIDE_SCROLLBAR_TIMOUT) }, _treatNativeGesture: function() { this._prepareGesture(); this._forgetGesture() }, _prepareGesture: function() { if (this._gestureEndTimer) { clearTimeout(this._gestureEndTimer); this._gestureEndTimer = null } else this._$element.data(GESTURE_LOCK_KEY, true) }, _forgetGesture: function() { this._gestureEndTimer = setTimeout($.proxy(function() { this._$element.data(GESTURE_LOCK_KEY, false); this._gestureEndTimer = null }, this), GESTURE_LOCK_TIMEOUT) }, location: function() { return { left: -this._$container.scrollLeft(), top: -this._$container.scrollTop() } }, disabledChanged: $.noop, update: function() { this._update(); this._updateAction(this._createActionArgs()) }, _update: function() { this._updateDimensions(); this._updateScrollbars() }, _updateDimensions: function() { this._containerSize = { height: this._$container.height(), width: this._$container.width() }; this._componentContentSize = { height: this._component.content().height(), width: this._component.content().width() }; this._contentSize = { height: this._$content.height(), width: this._$content.width() } }, _updateScrollbars: function() { this._eachScrollbar(function(scrollbar, direction) { var dimension = direction === VERTICAL ? "height" : "width"; scrollbar.option({ containerSize: this._containerSize[dimension], contentSize: this._componentContentSize[dimension] }) }) }, _allowedDirections: function() { return { vertical: this._isDirection(VERTICAL) && this._contentSize.height > this._containerSize.height, horizontal: this._isDirection(HORIZONTAL) && this._contentSize.width > this._containerSize.width } }, dispose: function() { this._$element.removeClass(function(index, className) { var scrollableNativeRegexp = new RegExp(SCROLLABLE_NATIVE_CLASS + "\\S*", "g"); if (scrollableNativeRegexp.test(className)) return className.match(scrollableNativeRegexp).join(" ") }); this._$element.off("." + SCROLLABLE_NATIVE); this._$container.off("." + SCROLLABLE_NATIVE); this._removeScrollbars(); clearTimeout(this._gestureEndTimer) }, _removeScrollbars: function() { this._eachScrollbar(function(scrollbar) { scrollbar._element().remove() }) }, scrollBy: function(distance) { var location = this.location(); this._$container.scrollTop(-location.top - distance.top); this._$container.scrollLeft(-location.left - distance.left) }, validate: function() { return !this.option("disabled") && this._allowedDirection() }, getDirection: function() { return this._allowedDirection() } }) })(jQuery, DevExpress); /*! Module widgets-base, file ui.scrollable.simulated.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, math = Math; var realDevice = DX.devices.real; var isSluggishPlatform = realDevice.platform === "win8" || realDevice.platform === "android"; var SCROLLABLE_SIMULATED = "dxSimulatedScrollable", SCROLLABLE_STRATEGY = "dxScrollableStrategy", SCROLLABLE_SIMULATED_CURSOR = SCROLLABLE_SIMULATED + "Cursor", SCROLLABLE_SIMULATED_KEYBOARD = SCROLLABLE_SIMULATED + "Keyboard", SCROLLABLE_SIMULATED_CLASS = "dx-scrollable-simulated", SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden", VERTICAL = "vertical", HORIZONTAL = "horizontal", ACCELERATION = isSluggishPlatform ? 0.95 : 0.92, OUT_BOUNDS_ACCELERATION = 0.5, MIN_VELOCITY_LIMIT = 1, FRAME_DURATION = math.round(1000 / 60), SCROLL_LINE_HEIGHT = 20, BOUNCE_MIN_VELOCITY_LIMIT = MIN_VELOCITY_LIMIT / 5, BOUNCE_DURATION = isSluggishPlatform ? 300 : 400, BOUNCE_FRAMES = BOUNCE_DURATION / FRAME_DURATION, BOUNCE_ACCELERATION_SUM = (1 - math.pow(ACCELERATION, BOUNCE_FRAMES)) / (1 - ACCELERATION); var KEY_CODES = { PAGE_UP: 33, PAGE_DOWN: 34, END: 35, HOME: 36, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40 }; var InertiaAnimator = DX.Animator.inherit({ ctor: function(scroller) { this.callBase(); this.scroller = scroller }, VELOCITY_LIMIT: MIN_VELOCITY_LIMIT, _isFinished: function() { return math.abs(this.scroller._velocity) <= this.VELOCITY_LIMIT }, _step: function() { this.scroller._scrollStep(this.scroller._velocity); this.scroller._velocity *= this._acceleration() }, _acceleration: function() { return this.scroller._inBounds() ? ACCELERATION : OUT_BOUNDS_ACCELERATION }, _complete: function() { this.scroller._scrollComplete() }, _stop: function() { this.scroller._stopComplete() } }); var BounceAnimator = InertiaAnimator.inherit({ VELOCITY_LIMIT: BOUNCE_MIN_VELOCITY_LIMIT, _isFinished: function() { return this.scroller._crossBoundOnNextStep() || this.callBase() }, _acceleration: function() { return ACCELERATION }, _complete: function() { this.scroller._move(this.scroller._bounceLocation); this.callBase() } }); var isWheelEvent = function(e) { return e.type === "dxmousewheel" }; var Scroller = ui.Scroller = DX.Class.inherit({ ctor: function(options) { this._initOptions(options); this._initAnimators(); this._initScrollbar() }, _initOptions: function(options) { this._location = 0; this._topReached = false; this._bottomReached = false; this._axis = options.direction === HORIZONTAL ? "x" : "y"; this._prop = options.direction === HORIZONTAL ? "left" : "top"; this._dimension = options.direction === HORIZONTAL ? "width" : "height"; this._scrollProp = options.direction === HORIZONTAL ? "scrollLeft" : "scrollTop"; $.each(options, $.proxy(function(optionName, optionValue) { this["_" + optionName] = optionValue }, this)) }, _initAnimators: function() { this._inertiaAnimator = new InertiaAnimator(this); this._bounceAnimator = new BounceAnimator(this) }, _initScrollbar: function() { this._$scrollbar = $("
").dxScrollbar({ direction: this._direction, visible: this._scrollByThumb, visibilityMode: this._visibilityModeNormalize(this._scrollbarVisible), containerSize: this._containerSize(), contentSize: this._contentSize() }).appendTo(this._$container); this._scrollbar = this._$scrollbar.dxScrollbar("instance") }, _visibilityModeNormalize: function(mode) { return mode === true ? "onScroll" : mode === false ? "never" : mode }, _scrollStep: function(delta) { var prevLocation = this._location; this._location += delta; this._suppressBounce(); this._move(); if (prevLocation !== this._location) { this._scrollAction(); this._$element.triggerHandler("scroll") } }, _suppressBounce: function() { if (this._bounceEnabled || this._inBounds(this._location)) return; this._velocity = 0; this._location = this._boundLocation() }, _boundLocation: function() { var location = math.min(this._location, this._maxOffset); return math.max(location, this._minOffset) }, _move: function(location) { this._location = location !== undefined ? location : this._location; this._moveContent(); this._moveScrollbar() }, _moveContent: function() { var targetLocation = {}; targetLocation[this._prop] = this._location; DX.translator.move(this._$content, targetLocation) }, _moveScrollbar: function() { this._scrollbar.moveTo(this._location) }, _scrollComplete: function() { if (this._inBounds()) { this._hideScrollbar(); this._correctLocation(); if (this._completeDeferred) this._completeDeferred.resolve() } this._scrollToBounds() }, _correctLocation: function() { this._location = math.round(this._location); this._move() }, _scrollToBounds: function() { if (this._inBounds()) return; this._bounceAction(); this._setupBounce(); this._bounceAnimator.start() }, _setupBounce: function() { var boundLocation = this._bounceLocation = this._boundLocation(), bounceDistance = boundLocation - this._location; this._velocity = bounceDistance / BOUNCE_ACCELERATION_SUM }, _inBounds: function(location) { location = location !== undefined ? location : this._location; return location >= this._minOffset && location <= this._maxOffset }, _crossBoundOnNextStep: function() { var location = this._location, nextLocation = location + this._velocity; return location < this._minOffset && nextLocation >= this._minOffset || location > this._maxOffset && nextLocation <= this._maxOffset }, _handleInit: function(e) { this._stopDeferred = $.Deferred(); this._stopScrolling(); this._prepareThumbScrolling(e); return this._stopDeferred.promise() }, _stopScrolling: function() { this._hideScrollbar(); this._inertiaAnimator.stop(); this._bounceAnimator.stop() }, _prepareThumbScrolling: function(e) { if (isWheelEvent(e.originalEvent)) return; var $target = $(e.originalEvent.target); var scrollbarClicked = this._isScrollbar($target); if (scrollbarClicked) this._moveToMouseLocation(e); this._thumbScrolling = scrollbarClicked || this._isThumb($target); if (this._thumbScrolling) this._scrollbar.feedbackOn() }, _moveToMouseLocation: function(e) { var mouseLocation = e["page" + this._axis.toUpperCase()] - this._$element.offset()[this._prop]; var location = this._location + mouseLocation / this._containerToContentRatio() - this._$container.height() / 2; this._scrollStep(-location) }, _stopComplete: function() { if (this._stopDeferred) this._stopDeferred.resolve() }, _handleStart: function() { this._showScrollbar() }, _handleMove: function(delta) { delta = delta[this._axis]; if (this._thumbScrolling) delta = -delta / this._containerToContentRatio(); if (!this._inBounds()) delta *= OUT_BOUNDS_ACCELERATION; this._scrollStep(delta) }, _containerToContentRatio: function() { return this._scrollbar.containerToContentRatio() }, _handleEnd: function(velocity) { this._completeDeferred = $.Deferred(); this._velocity = velocity[this._axis]; this._handleInertia(); this._resetThumbScrolling(); return this._completeDeferred.promise() }, _handleInertia: function() { this._suppressIntertia(); this._inertiaAnimator.start() }, _suppressIntertia: function() { if (!this._inertiaEnabled || this._thumbScrolling) this._velocity = 0 }, _resetThumbScrolling: function() { this._thumbScrolling = false }, _handleStop: function() { this._resetThumbScrolling(); this._scrollToBounds() }, _handleDispose: function() { this._stopScrolling(); this._$scrollbar.remove() }, _handleUpdate: function() { this._update(); this._moveToBounds() }, _update: function() { this._stopScrolling(); this._updateLocation(); this._updateBounds(); this._updateScrollbar(); this._moveScrollbar(); this._updateScrollbarVisibility() }, _updateLocation: function() { this._location = DX.translator.locate(this._$content)[this._prop] }, _updateBounds: function() { this._maxOffset = 0; this._minOffset = math.min(this._containerSize() - this._contentSize(), 0) }, _updateScrollbar: function() { this._scrollbar.option({ containerSize: this._containerSize(), contentSize: this._contentSize() }) }, _updateScrollbarVisibility: function() { this._showScrollbar(); this._hideScrollbar() }, _moveToBounds: function() { this._location = this._boundLocation(); this._move() }, _handleCreateActions: function(actions) { this._scrollAction = actions.scrollAction; this._bounceAction = actions.bounceAction }, _showScrollbar: function() { this._scrollbar.option("visible", true) }, _hideScrollbar: function() { this._scrollbar.option("visible", false) }, _containerSize: function() { return this._$container[this._dimension]() }, _contentSize: function() { return this._$content[this._dimension]() }, _validateEvent: function(e) { var $target = $(e.originalEvent.target); if (this._isThumb($target) || this._isScrollbar($target)) { e.preventDefault(); return true } return this._isContent($target) }, _isThumb: function($element) { return this._scrollByThumb && this._scrollbar.isThumb($element) }, _isScrollbar: function($element) { return this._scrollByThumb && $element && $element.is(this._$scrollbar) }, _isContent: function($element) { return this._scrollByContent && !!$element.closest(this._$element).length }, _reachedMin: function() { return this._location <= this._minOffset }, _reachedMax: function() { return this._location >= this._maxOffset }, _handleCursorEnter: function() { this._scrollbar.cursorEnter() }, _handleCursorLeave: function() { this._scrollbar.cursorLeave() } }); var hoveredScrollable, activeScrollable; ui.SimulatedScrollableStrategy = DX.Class.inherit({ ctor: function(scrollable) { this._init(scrollable) }, _init: function(scrollable) { this._component = scrollable; this._$element = scrollable._element(); this._$container = scrollable._$container.prop("tabindex", 0); this._$content = scrollable._$content; this.option = $.proxy(scrollable.option, scrollable); this._createActionByOption = $.proxy(scrollable._createActionByOption, scrollable); this._isLocked = $.proxy(scrollable._isLocked, scrollable); this._isDirection = $.proxy(scrollable._isDirection, scrollable); this._allowedDirection = $.proxy(scrollable._allowedDirection, scrollable) }, render: function() { this._$element.addClass(SCROLLABLE_SIMULATED_CLASS); this._createScrollers(); this._attachKeyboardHandler(); this._attachCursorHandlers() }, _createScrollers: function() { this._scrollers = {}; if (this._isDirection(HORIZONTAL)) this._createScroller(HORIZONTAL); if (this._isDirection(VERTICAL)) this._createScroller(VERTICAL); this._$element.toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this.option("showScrollbar")) }, _createScroller: function(direction) { this._scrollers[direction] = new Scroller(this._scrollerOptions(direction)) }, _scrollerOptions: function(direction) { return { direction: direction, $content: this._$content, $container: this._$container, $element: this._$element, scrollByContent: this.option("scrollByContent"), scrollByThumb: this.option("scrollByThumb"), scrollbarVisible: this.option("showScrollbar"), bounceEnabled: this.option("bounceEnabled"), inertiaEnabled: this.option("inertiaEnabled") } }, handleInit: function(e) { this._supressDirections(e); this._eventForUserAction = e; this._handleEvent("Init", e).done(this._stopAction) }, _supressDirections: function(e) { if (isWheelEvent(e.originalEvent)) { this._prepareDirections(true); return } this._prepareDirections(); this._eachScroller(function(scroller, direction) { var isValid = scroller._validateEvent(e); this._validDirections[direction] = isValid }) }, _prepareDirections: function(value) { value = value || false; this._validDirections = {}; this._validDirections[HORIZONTAL] = value; this._validDirections[VERTICAL] = value }, _eachScroller: function(callback) { callback = $.proxy(callback, this); $.each(this._scrollers, function(direction, scroller) { callback(scroller, direction) }) }, handleStart: function(e) { this._saveActive(); this._handleEvent("Start").done(this._startAction) }, _saveActive: function() { activeScrollable = this }, _resetActive: function() { activeScrollable = null }, _validateDirection: function(delta) { var result = false; this._eachScroller(function(scroller) { result = result || scroller._validateDirection(delta) }); return result }, handleMove: function(e) { if (this._isLocked()) { e.cancel = true; this._resetActive(); return } e.preventDefault && e.preventDefault(); this._adjustDistance(e.delta); this._eventForUserAction = e; this._handleEvent("Move", e.delta) }, _adjustDistance: function(distance) { distance.x *= this._validDirections[HORIZONTAL]; distance.y *= this._validDirections[VERTICAL] }, handleEnd: function(e) { this._resetActive(); this._refreshCursorState(e.originalEvent && e.originalEvent.target); this._adjustDistance(e.velocity); this._eventForUserAction = e; return this._handleEvent("End", e.velocity).done(this._endAction) }, handleCancel: function(e) { this._resetActive(); this._eventForUserAction = e; return this._handleEvent("End", { x: 0, y: 0 }) }, handleStop: function() { this._resetActive(); this._handleEvent("Stop") }, handleScroll: function() { var distance = { left: this._$container.scrollLeft(), top: this._$container.scrollTop() }; this._$container.scrollLeft(-distance.left); this._$container.scrollTop(-distance.top); this.scrollBy(distance) }, _attachKeyboardHandler: function() { this._$element.off("." + SCROLLABLE_SIMULATED_KEYBOARD); if (!this.option("disabled") && this.option("useKeyboard")) this._$element.on(events.addNamespace("keydown", SCROLLABLE_SIMULATED_KEYBOARD), $.proxy(this._handleKeyDown, this)) }, _handleKeyDown: function(e) { if (!this._$container.is(document.activeElement)) return; var handled = true; switch (e.keyCode) { case KEY_CODES.DOWN: this._scrollByLine({y: 1}); break; case KEY_CODES.UP: this._scrollByLine({y: -1}); break; case KEY_CODES.RIGHT: this._scrollByLine({x: 1}); break; case KEY_CODES.LEFT: this._scrollByLine({x: -1}); break; case KEY_CODES.PAGE_DOWN: this._scrollByPage(1); break; case KEY_CODES.PAGE_UP: this._scrollByPage(-1); break; case KEY_CODES.HOME: this._scrollToHome(); break; case KEY_CODES.END: this._scrollToEnd(); break; default: handled = false; break } if (handled) { e.stopPropagation(); e.preventDefault() } }, _scrollByLine: function(lines) { this.scrollBy({ top: (lines.y || 0) * -SCROLL_LINE_HEIGHT, left: (lines.x || 0) * -SCROLL_LINE_HEIGHT }) }, _scrollByPage: function(page) { var prop = this._wheelProp(), dimension = this._dimensionByProp(prop); var distance = {}; distance[prop] = page * -this._$container[dimension](); this.scrollBy(distance) }, _dimensionByProp: function(prop) { return prop === "left" ? "width" : "height" }, _scrollToHome: function() { var prop = this._wheelProp(); var distance = {}; distance[prop] = 0; this._component.scrollTo(distance) }, _scrollToEnd: function() { var prop = this._wheelProp(), dimension = this._dimensionByProp(prop); var distance = {}; distance[prop] = this._$content[dimension]() - this._$container[dimension](); this._component.scrollTo(distance) }, createActions: function() { this._startAction = this._createActionHandler("startAction"); this._stopAction = this._createActionHandler("stopAction"); this._endAction = this._createActionHandler("endAction"); this._updateAction = this._createActionHandler("updateAction"); this._createScrollerActions() }, _createScrollerActions: function() { this._handleEvent("CreateActions", { scrollAction: this._createActionHandler("scrollAction"), bounceAction: this._createActionHandler("bounceAction") }) }, _createActionHandler: function(optionName) { var that = this, actionHandler = that._createActionByOption(optionName, {excludeValidators: ["gesture"]}); return function() { actionHandler($.extend(that._createActionArgs(), arguments)) } }, _createActionArgs: function() { var scrollerX = this._scrollers[HORIZONTAL], scrollerY = this._scrollers[VERTICAL]; return { jQueryEvent: this._eventForUserAction, scrollOffset: { top: scrollerY && -scrollerY._location, left: scrollerX && -scrollerX._location }, reachedLeft: scrollerX && scrollerX._reachedMax(), reachedRight: scrollerX && scrollerX._reachedMin(), reachedTop: scrollerY && scrollerY._reachedMax(), reachedBottom: scrollerY && scrollerY._reachedMin() } }, _handleEvent: function(eventName) { var args = $.makeArray(arguments).slice(1), deferreds = $.map(this._scrollers, function(scroller) { return scroller["_handle" + eventName].apply(scroller, args) }); return $.when.apply($, deferreds).promise() }, location: function() { return DX.translator.locate(this._$content) }, disabledChanged: function() { this._attachCursorHandlers() }, _attachCursorHandlers: function() { this._$element.off("." + SCROLLABLE_SIMULATED_CURSOR); if (!this.option("disabled") && this._isHoverMode()) this._$element.on(events.addNamespace("mouseenter", SCROLLABLE_SIMULATED_CURSOR), $.proxy(this._handleCursorEnter, this)).on(events.addNamespace("mouseleave", SCROLLABLE_SIMULATED_CURSOR), $.proxy(this._handleCursorLeave, this)) }, _isHoverMode: function() { return this.option("showScrollbar") === "onHover" }, _handleCursorEnter: function(e) { e = e || {}; e.originalEvent = e.originalEvent || {}; if (activeScrollable || e.originalEvent._hoverHandled) return; if (hoveredScrollable) hoveredScrollable._handleCursorLeave(); hoveredScrollable = this; this._handleEvent("CursorEnter"); e.originalEvent._hoverHandled = true }, _handleCursorLeave: function(e) { if (hoveredScrollable !== this || activeScrollable === hoveredScrollable) return; this._handleEvent("CursorLeave"); hoveredScrollable = null; this._refreshCursorState(e && e.relatedTarget) }, _refreshCursorState: function(target) { if (!this._isHoverMode() && (!target || activeScrollable)) return; var $target = $(target); var $scrollable = $target.closest("." + SCROLLABLE_SIMULATED_CLASS + ":not(.dx-state-disabled)"); var targetScrollable = $scrollable.length && $scrollable.data(SCROLLABLE_STRATEGY); if (hoveredScrollable && hoveredScrollable !== targetScrollable) hoveredScrollable._handleCursorLeave(); if (targetScrollable) targetScrollable._handleCursorEnter() }, update: function() { return this._handleEvent("Update").done(this._updateAction) }, _allowedDirections: function() { var bounceEnabled = this.option("bounceEnabled"); return { vertical: this._isDirection(VERTICAL) && (this._scrollers[VERTICAL]._minOffset < 0 || bounceEnabled), horizontal: this._isDirection(HORIZONTAL) && (this._scrollers[HORIZONTAL]._minOffset < 0 || bounceEnabled) } }, scrollBy: function(distance) { this._prepareDirections(true); this._handleEvent("Start").done(this._startAction); this._handleEvent("Move", { x: distance.left, y: distance.top }); this._handleEvent("End", { x: 0, y: 0 }).done(this._endAction) }, validate: function(e) { if (this.option("disabled")) return false; if (this.option("bounceEnabled")) return true; return isWheelEvent(e) ? this._validateWheel(e) : this._validateMove() }, _validateWheel: function(e) { var scroller = this._scrollers[this._wheelDirection()]; var reachedMin = scroller._reachedMin(); var reachedMax = scroller._reachedMax(); var contentGreaterThanContainer = !reachedMin || !reachedMax; var locatedNotAtBound = !reachedMin && !reachedMax; var scrollFromMin = reachedMin && e.delta > 0; var scrollFromMax = reachedMax && e.delta < 0; return contentGreaterThanContainer && (locatedNotAtBound || scrollFromMin || scrollFromMax) }, _validateMove: function() { return this._allowedDirection() }, getDirection: function(e) { return isWheelEvent(e) ? this._wheelDirection() : this._allowedDirection() }, _wheelProp: function() { return this._wheelDirection() === HORIZONTAL ? "left" : "top" }, _wheelDirection: function() { switch (this.option("direction")) { case HORIZONTAL: return HORIZONTAL; case VERTICAL: return VERTICAL; default: return this._scrollers[VERTICAL]._containerToContentRatio() >= 1 ? HORIZONTAL : VERTICAL } }, dispose: function() { if (activeScrollable === this) activeScrollable = null; if (hoveredScrollable === this) hoveredScrollable = null; this._handleEvent("Dispose"); this._detachEventHandlers(); this._$element.removeClass(SCROLLABLE_SIMULATED_CLASS); this._eventForUserAction = null; clearTimeout(this._gestureEndTimer) }, _detachEventHandlers: function() { this._$element.off("." + SCROLLABLE_SIMULATED_CURSOR); this._$container.off("." + SCROLLABLE_SIMULATED_KEYBOARD) } }); ui.dxScrollable.__internals = $.extend(ui.dxScrollable.__internals || {}, { ACCELERATION: ACCELERATION, MIN_VELOCITY_LIMIT: MIN_VELOCITY_LIMIT, FRAME_DURATION: FRAME_DURATION, SCROLL_LINE_HEIGHT: SCROLL_LINE_HEIGHT }) })(jQuery, DevExpress); /*! Module widgets-base, file ui.scrollView.js */ (function($, DX, undefined) { var ui = DX.ui; var SCROLLVIEW_CLASS = "dx-scrollview", SCROLLVIEW_CONTENT_CLASS = SCROLLVIEW_CLASS + "-content", SCROLLVIEW_TOP_POCKET_CLASS = SCROLLVIEW_CLASS + "-top-pocket", SCROLLVIEW_BOTTOM_POCKET_CLASS = SCROLLVIEW_CLASS + "-bottom-pocket", SCROLLVIEW_PULLDOWN_CLASS = SCROLLVIEW_CLASS + "-pull-down", SCROLLVIEW_PULLDOWN_IMAGE_CLASS = SCROLLVIEW_PULLDOWN_CLASS + "-image", SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = SCROLLVIEW_PULLDOWN_CLASS + "-indicator", SCROLLVIEW_PULLDOWN_TEXT_CLASS = SCROLLVIEW_PULLDOWN_CLASS + "-text", SCROLLVIEW_REACHBOTTOM_CLASS = SCROLLVIEW_CLASS + "-scrollbottom", SCROLLVIEW_REACHBOTTOM_INDICATOR_CLASS = SCROLLVIEW_REACHBOTTOM_CLASS + "-indicator", SCROLLVIEW_REACHBOTTOM_TEXT_CLASS = SCROLLVIEW_REACHBOTTOM_CLASS + "-text", SCROLLVIEW_LOADPANEL = SCROLLVIEW_CLASS + "-loadpanel"; DX.registerComponent("dxScrollView", ui.dxScrollable.inherit({ _setDefaultOptions: function() { this.callBase(); this.option({ pullingDownText: Globalize.localize("dxScrollView-pullingDownText"), pulledDownText: Globalize.localize("dxScrollView-pulledDownText"), refreshingText: Globalize.localize("dxScrollView-refreshingText"), reachBottomText: Globalize.localize("dxScrollView-reachBottomText"), pullDownAction: null, reachBottomAction: null, refreshStrategy: "pullDown" }) }, _defaultOptionsRules: function() { return this.callBase().slice(0).concat([{ device: function(device) { return DevExpress.devices.real().platform === "android" }, options: {refreshStrategy: "swipeDown"} }, { device: function(device) { return DevExpress.devices.real().platform === "win8" }, options: {refreshStrategy: "slideDown"} }]) }, _init: function() { this.callBase(); this._loadingIndicatorEnabled = true }, _initMarkup: function() { this.callBase(); this._element().addClass(SCROLLVIEW_CLASS); this._initContent(); this._initTopPocket(); this._initBottomPocket(); this._initLoadPanel() }, _initContent: function() { var $content = $("
").addClass(SCROLLVIEW_CONTENT_CLASS); this._$content.wrapInner($content) }, _initTopPocket: function() { var $topPocket = this._$topPocket = $("
").addClass(SCROLLVIEW_TOP_POCKET_CLASS), $pullDown = this._$pullDown = $("
").addClass(SCROLLVIEW_PULLDOWN_CLASS); $topPocket.append($pullDown); this._$content.prepend($topPocket) }, _initBottomPocket: function() { var $bottomPocket = this._$bottomPocket = $("
").addClass(SCROLLVIEW_BOTTOM_POCKET_CLASS), $reachBottom = this._$reachBottom = $("
").addClass(SCROLLVIEW_REACHBOTTOM_CLASS), $loadContainer = $("
").addClass(SCROLLVIEW_REACHBOTTOM_INDICATOR_CLASS), $loadIndicator = $("
").dxLoadIndicator(), $text = this._$reachBottomText = $("
").addClass(SCROLLVIEW_REACHBOTTOM_TEXT_CLASS); this._updateReachBottomText(); $reachBottom.append($loadContainer.append($loadIndicator)).append($text); $bottomPocket.append($reachBottom); this._$content.append($bottomPocket) }, _initLoadPanel: function() { this._loadPanel = $("
").addClass(SCROLLVIEW_LOADPANEL).appendTo(this._element()).dxLoadPanel({ shading: false, delay: 400, position: {of: this._element()} }).dxLoadPanel("instance") }, _updateReachBottomText: function() { this._$reachBottomText.text(this.option("reachBottomText")) }, _createStrategy: function() { var strategyName = this.option("useNative") ? this.option("refreshStrategy") : "simulated"; var strategyClass = ui.scrollViewRefreshStrategies[strategyName]; if (!strategyClass) throw Error("Unknown dxScrollView refresh strategy " + this.option("refreshStrategy")); this._strategy = new strategyClass(this); this._strategy.pullDownCallbacks.add($.proxy(this._handlePullDown, this)); this._strategy.releaseCallbacks.add($.proxy(this._handleRelease, this)); this._strategy.reachBottomCallbacks.add($.proxy(this._handleReachBottom, this)) }, _createActions: function() { this.callBase(); this._pullDownAction = this._createActionByOption("pullDownAction", {excludeValidators: ["gesture"]}); this._reachBottomAction = this._createActionByOption("reachBottomAction", {excludeValidators: ["gesture"]}); this._pullDownEnable(!!this.option("pullDownAction") && !DX.designMode); this._reachBottomEnable(!!this.option("reachBottomAction") && !DX.designMode) }, _pullDownEnable: function(enabled) { this._$pullDown.toggle(enabled); this._strategy.pullDownEnable(enabled) }, _reachBottomEnable: function(enabled) { this._$reachBottom.toggle(enabled); this._strategy.reachBottomEnable(enabled) }, _handlePullDown: function() { this._loadingIndicator(false); this._pullDownLoading() }, _loadingIndicator: function(value) { if (arguments.length < 1) return this._loadingIndicatorEnabled; this._loadingIndicatorEnabled = value }, _pullDownLoading: function() { this.startLoading(); this._pullDownAction() }, _handleReachBottom: function() { this._loadingIndicator(false); this._reachBottomLoading() }, _reachBottomLoading: function() { this.startLoading(); this._reachBottomAction() }, _handleRelease: function() { this.finishLoading(); this._loadingIndicator(true) }, _optionChanged: function(optionName, optionValue) { switch (optionName) { case"pullDownAction": case"reachBottomAction": this._createActions(); break; case"pullingDownText": case"pulledDownText": case"refreshingText": case"refreshStrategy": this._invalidate(); break; case"reachBottomText": this._updateReachBottomText(); break; default: this.callBase.apply(this, arguments) } }, content: function() { return this._$content.children().eq(1) }, release: function(preventReachBottom) { if (preventReachBottom !== undefined) this.toggleLoading(!preventReachBottom); return this._strategy.release() }, toggleLoading: function(showOrHide) { this._reachBottomEnable(showOrHide) }, isFull: function() { return this.content().height() >= this._$container.height() }, refresh: function() { if (!this.option("pullDownAction")) return; this._strategy.pendingRelease(); this._pullDownLoading() }, startLoading: function() { if (this._loadingIndicator() && this._element().is(":visible")) this._loadPanel.show(); this._lock() }, finishLoading: function() { if (this._loadingIndicator()) this._loadPanel.hide(); this._unlock() }, _dispose: function() { this.callBase(); if (this._loadPanel) this._loadPanel._element().remove() } })); ui.scrollViewRefreshStrategies = {} })(jQuery, DevExpress); /*! Module widgets-base, file ui.scrollView.native.pullDown.js */ (function($, DX, undefined) { var ui = DX.ui, math = Math; var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading", SCROLLVIEW_PULLDOWN_READY_CLASS = "dx-scrollview-pull-down-ready", SCROLLVIEW_PULLDOWN_IMAGE_CLASS = "dx-scrollview-pull-down-image", SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator", SCROLLVIEW_PULLDOWN_TEXT_CLASS = "dx-scrollview-pull-down-text", STATE_RELEASED = 0, STATE_READY = 1, STATE_REFRESHING = 2, STATE_LOADING = 3; var SCROLLVIEW_CONTENT_PADDING = 2; var PullDownNativeScrollViewStrategy = ui.NativeScrollableStrategy.inherit({ _init: function(scrollView) { this.callBase(scrollView); this._$topPocket = scrollView._$topPocket; this._$pullDown = scrollView._$pullDown; this._$bottomPocket = scrollView._$bottomPocket; this._$refreshingText = scrollView._$refreshingText; this._$scrollViewContent = scrollView.content(); this._initCallbacks() }, _initCallbacks: function() { this.pullDownCallbacks = $.Callbacks(); this.releaseCallbacks = $.Callbacks(); this.reachBottomCallbacks = $.Callbacks() }, render: function() { this.callBase(); this._renderPullDown(); this._releaseState() }, _renderPullDown: function() { var $image = $("
").addClass(SCROLLVIEW_PULLDOWN_IMAGE_CLASS), $loadContainer = $("
").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS), $loadIndicator = $("
").dxLoadIndicator(), $text = this._$pullDownText = $("
").addClass(SCROLLVIEW_PULLDOWN_TEXT_CLASS); this._$pullingDownText = $("
").text(this.option("pullingDownText")).appendTo($text); this._$pulledDownText = $("
").text(this.option("pulledDownText")).appendTo($text); this._$refreshingText = $("
").text(this.option("refreshingText")).appendTo($text); this._$pullDown.empty().append($image).append($loadContainer.append($loadIndicator)).append($text) }, _releaseState: function() { this._state = STATE_RELEASED; this._refreshPullDownText() }, _refreshPullDownText: function() { this._$pullingDownText.css("opacity", this._state === STATE_RELEASED ? 1 : 0); this._$pulledDownText.css("opacity", this._state === STATE_READY ? 1 : 0); this._$refreshingText.css("opacity", this._state === STATE_REFRESHING ? 1 : 0) }, update: function() { this.callBase(); this._setTopPocketOffset() }, _updateDimensions: function() { this.callBase(); this._topPocketSize = this._$topPocket.height(); this._bottomPocketSize = this._$bottomPocket.height(); this._scrollOffset = this._$container.height() - this._$content.height(); this._pushBackFromBoundary() }, _allowedDirections: function() { var allowedDirections = this.callBase(); allowedDirections.vertical = allowedDirections.vertical || this._pullDownEnabled; return allowedDirections }, _setTopPocketOffset: function() { this._$topPocket.css({top: -this._topPocketSize}) }, handleEnd: function() { this._complete() }, handleStop: function() { this._complete() }, _complete: function() { if (this._state === STATE_READY) { this._setPullDownOffset(this._topPocketSize); clearTimeout(this._pullDownRefreshTimeout); this._pullDownRefreshTimeout = setTimeout($.proxy(function() { this._pullDownRefreshing() }, this), 400) } }, _setPullDownOffset: function(offset) { DX.translator.move(this._$topPocket, {top: offset}); DX.translator.move(this._$scrollViewContent, {top: offset}) }, handleScroll: function(e) { this.callBase(e); this._pushBackFromBoundary(); if (this._state === STATE_REFRESHING) return; this._location = this.location().top; if (this._isPullDown()) this._pullDownReady(); else if (this._isReachBottom()) this._reachBottom(); else this._stateReleased() }, _pushBackFromBoundary: function() { var scrollTopPos = this._$container.scrollTop(), scrollBottomPos = this._scrollOffset + scrollTopPos - SCROLLVIEW_CONTENT_PADDING; if (!scrollTopPos) this._$container.scrollTop(1); else if (!scrollBottomPos) this._$container.scrollTop(1 - this._scrollOffset) }, _isPullDown: function() { return this._pullDownEnabled && this._location >= this._topPocketSize }, _isReachBottom: function() { return this._reachBottomEnabled && this._location <= this._scrollOffset + this._bottomPocketSize }, _reachBottom: function() { if (this._state === STATE_LOADING) return; this._state = STATE_LOADING; this.reachBottomCallbacks.fire() }, _pullDownReady: function() { if (this._state === STATE_READY) return; this._state = STATE_READY; this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_READY_CLASS); this._refreshPullDownText() }, _stateReleased: function() { if (this._state === STATE_RELEASED) return; this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS); this._releaseState() }, _pullDownRefreshing: function() { if (this._state === STATE_REFRESHING) return; this._state = STATE_REFRESHING; this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS); this._refreshPullDownText(); this.pullDownCallbacks.fire() }, pullDownEnable: function(enabled) { this._pullDownEnabled = enabled }, reachBottomEnable: function(enabled) { this._reachBottomEnabled = enabled }, pendingRelease: function() { this._state = STATE_READY }, release: function() { var deferred = $.Deferred(); this._updateDimensions(); clearTimeout(this._releaseTimeout); this._releaseTimeout = setTimeout($.proxy(function() { this._setPullDownOffset(0); this._stateReleased(); this.releaseCallbacks.fire(); this._updateAction(); deferred.resolve() }, this), 400); return deferred.promise() }, location: function() { return { left: -this._$container.scrollLeft(), top: 1 - this._$container.scrollTop() } }, scrollBy: function(distance) { var location = this.location(); this._$container.scrollTop(-location.top - distance.top + 1); this._$container.scrollLeft(-location.left - distance.left) }, dispose: function() { clearTimeout(this._pullDownRefreshTimeout); clearTimeout(this._releaseTimeout); this.callBase() } }); ui.scrollViewRefreshStrategies.pullDown = PullDownNativeScrollViewStrategy })(jQuery, DevExpress); /*! Module widgets-base, file ui.scrollView.native.swipeDown.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, math = Math; var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading", SCROLLVIEW_OBSOLETE_ANDROID_CLASS = "dx-scrollview-obsolete-android-browser", PULLDOWN_HEIGHT = 160, STATE_RELEASED = 0, STATE_READY = 1, STATE_REFRESHING = 2, STATE_LOADING = 3, STATE_TOUCHED = 4, STATE_PULLED = 5; var SwipeDownNativeScrollViewStrategy = ui.NativeScrollableStrategy.inherit({ _init: function(scrollView) { this.callBase(scrollView); this._$topPocket = scrollView._$topPocket; this._$bottomPocket = scrollView._$bottomPocket; this._$pullDown = scrollView._$pullDown; this._$scrollViewContent = scrollView.content(); this._initCallbacks(); this._releaseState(); this._location = 0 }, _initCallbacks: function() { this.pullDownCallbacks = $.Callbacks(); this.releaseCallbacks = $.Callbacks(); this.reachBottomCallbacks = $.Callbacks() }, render: function() { this.callBase(); this._renderPullDown() }, _renderPullDown: function() { this._$pullDown.empty().append($("
")).append($("
")).append($("
")).append($("
")) }, _releaseState: function() { this._state = STATE_RELEASED; this._$pullDown.css({ width: "0%", opacity: 0 }); this._updateDimensions() }, _updateDimensions: function() { this.callBase(); this._topPocketSize = this._$topPocket.height(); this._bottomPocketSize = this._$bottomPocket.height(); this._scrollOffset = this._$container.height() - this._$content.height() }, _allowedDirections: function() { var allowedDirections = this.callBase(); allowedDirections.vertical = allowedDirections.vertical || this._pullDownEnabled; return allowedDirections }, handleInit: function(e) { this.callBase(e); if (this._state === STATE_RELEASED && this._location === 0) { this._startClientY = events.eventData(e.originalEvent).y; this._state = STATE_TOUCHED } }, handleMove: function(e) { this.callBase(e); this._deltaY = events.eventData(e.originalEvent).y - this._startClientY; if (this._state === STATE_TOUCHED) if (this._pullDownEnabled && this._deltaY > 0) { e.preventDefault(); this._state = STATE_PULLED } else this._complete(); if (this._state === STATE_PULLED) { if (this._deltaY < 0) { this._complete(); return } this._$pullDown.css({ opacity: 1, width: math.min(math.abs(this._deltaY * 100 / PULLDOWN_HEIGHT), 100) + "%" }); if (this._isPullDown()) this._pullDownRefreshing() } }, _isPullDown: function() { return this._pullDownEnabled && this._deltaY >= PULLDOWN_HEIGHT }, handleEnd: function() { this._complete() }, handleStop: function() { this._complete() }, _complete: function() { if (this._state === STATE_TOUCHED || this._state === STATE_PULLED) this._releaseState() }, handleScroll: function(e) { this.callBase(e); if (this._state === STATE_REFRESHING) return; var currentLocation = this.location().top, scrollDelta = this._location - currentLocation; this._location = currentLocation; if (scrollDelta > 0 && this._isReachBottom()) this._reachBottom(); else this._stateReleased() }, _isReachBottom: function() { return this._reachBottomEnabled && this._location <= this._scrollOffset + this._bottomPocketSize }, _reachBottom: function() { this.reachBottomCallbacks.fire() }, _stateReleased: function() { if (this._state === STATE_RELEASED) return; this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS); this._releaseState() }, _pullDownRefreshing: function() { if (this._state === STATE_REFRESHING) return; this._state = STATE_REFRESHING; clearTimeout(this._pullDownRefreshTimeout); this._pullDownRefreshTimeout = setTimeout($.proxy(function() { this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS); this.pullDownCallbacks.fire() }, this), 400) }, pullDownEnable: function(enabled) { this._$topPocket.toggle(enabled); this._pullDownEnabled = enabled }, reachBottomEnable: function(enabled) { this._reachBottomEnabled = enabled }, pendingRelease: function() { this._state = STATE_READY }, release: function() { var deferred = $.Deferred(); this._updateDimensions(); clearTimeout(this._releaseTimeout); this._releaseTimeout = setTimeout($.proxy(function() { this._stateReleased(); this.releaseCallbacks.fire(); this._updateAction(); deferred.resolve() }, this), 800); return deferred.promise() }, dispose: function() { clearTimeout(this._pullDownRefreshTimeout); clearTimeout(this._releaseTimeout); this.callBase() } }); ui.scrollViewRefreshStrategies.swipeDown = SwipeDownNativeScrollViewStrategy })(jQuery, DevExpress); /*! Module widgets-base, file ui.scrollView.native.slideDown.js */ (function($, DX, undefined) { var ui = DX.ui; var DX_SLIDE_DOWN_NATIVE_SCROLLVIEW_STRATEGY = "dxSlideDownNativeScrollViewStrategy", STATE_RELEASED = 0, STATE_READY = 1, STATE_LOADING = 2, LOADING_HEIGHT = 80; var SlideDownNativeScrollViewStrategy = ui.NativeScrollableStrategy.inherit({ _init: function(scrollView) { this.callBase(scrollView); this._$topPocket = scrollView._$topPocket; this._$bottomPocket = scrollView._$bottomPocket; this._initCallbacks() }, _initCallbacks: function() { this.pullDownCallbacks = $.Callbacks(); this.releaseCallbacks = $.Callbacks(); this.reachBottomCallbacks = $.Callbacks() }, render: function() { this.callBase(); this._renderPullDown(); this._renderBottom(); this._releaseState(); this._updateDimensions() }, _renderPullDown: function() { this._$topPocket.empty() }, _renderBottom: function() { this._$bottomPocket.empty().append("") }, _releaseState: function() { if (this._state === STATE_RELEASED) return; this._state = STATE_RELEASED }, _updateDimensions: function() { this._scrollOffset = this._$container.prop("scrollHeight") - this._$container.prop("clientHeight"); this._containerSize = { height: this._$container.prop("clientHeight"), width: this._$container.prop("clientWidth") }; this._contentSize = this._componentContentSize = { height: this._$container.prop("scrollHeight"), width: this._$container.prop("scrollWidth") } }, handleScroll: function(e) { this.callBase(e); if (this._isReachBottom(this._lastLocation.top)) this._reachBottom() }, _isReachBottom: function(location) { this._scrollContent = this._$container.prop("scrollHeight") - this._$container.prop("clientHeight"); return this._reachBottomEnabled && location < -this._scrollContent + LOADING_HEIGHT }, _reachBottom: function() { if (this._state === STATE_LOADING) return; this._state = STATE_LOADING; this.reachBottomCallbacks.fire() }, pullDownEnable: function(enabled) { this._pullDownEnabled = enabled }, reachBottomEnable: function(enabled) { this._reachBottomEnabled = enabled; this._$bottomPocket.toggle(enabled) }, pendingRelease: function() { this._state = STATE_READY }, release: function() { var deferred = $.Deferred(); this._state = STATE_RELEASED; this.releaseCallbacks.fire(); this.update(); return deferred.resolve().promise() } }); ui.scrollViewRefreshStrategies.slideDown = SlideDownNativeScrollViewStrategy })(jQuery, DevExpress); /*! Module widgets-base, file ui.scrollView.simulated.js */ (function($, DX, undefined) { var ui = DX.ui, math = Math; var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading", SCROLLVIEW_PULLDOWN_READY_CLASS = "dx-scrollview-pull-down-ready", SCROLLVIEW_PULLDOWN_IMAGE_CLASS = "dx-scrollview-pull-down-image", SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator", SCROLLVIEW_PULLDOWN_TEXT_CLASS = "dx-scrollview-pull-down-text", STATE_RELEASED = 0, STATE_READY = 1, STATE_REFRESHING = 2, STATE_LOADING = 3; var ScrollViewScroller = ui.ScrollViewScroller = ui.Scroller.inherit({ ctor: function() { this.callBase.apply(this, arguments); this._initCallbacks(); this._releaseState() }, _releaseState: function() { this._state = STATE_RELEASED; this._refreshPullDownText() }, _refreshPullDownText: function() { this._$pullingDownText.css("opacity", this._state === STATE_RELEASED ? 1 : 0); this._$pulledDownText.css("opacity", this._state === STATE_READY ? 1 : 0); this._$refreshingText.css("opacity", this._state === STATE_REFRESHING ? 1 : 0) }, _initCallbacks: function() { this.pullDownCallbacks = $.Callbacks(); this.releaseCallbacks = $.Callbacks(); this.reachBottomCallbacks = $.Callbacks() }, _updateBounds: function() { var considerPockets = this._direction !== "horizontal"; this._topPocketSize = considerPockets ? this._$topPocket[this._dimension]() : 0; this._bottomPocketSize = considerPockets ? this._$bottomPocket[this._dimension]() : 0; this._updateOffsets() }, _updateOffsets: function() { this._minOffset = math.min(this._containerSize() - this._contentSize() + this._bottomPocketSize, -this._topPocketSize); this._maxOffset = -this._topPocketSize; this._bottomBound = this._minOffset - this._bottomPocketSize }, _updateScrollbar: function() { this._scrollbar.option({ containerSize: this._containerSize(), contentSize: this._contentSize() - this._topPocketSize - this._bottomPocketSize }) }, _moveContent: function() { this.callBase(); if (this._isPullDown()) this._pullDownReady(); else if (this._isReachBottom()) this._reachBottomReady(); else if (this._state !== STATE_RELEASED) this._stateReleased() }, _moveScrollbar: function() { this._scrollbar.moveTo(this._topPocketSize + this._location) }, _isPullDown: function() { return this._pullDownEnabled && this._location >= 0 }, _isReachBottom: function() { return this._reachBottomEnabled && this._location <= this._bottomBound }, _scrollComplete: function() { if (this._inBounds() && this._state === STATE_READY) this._pullDownRefreshing(); else if (this._inBounds() && this._state === STATE_LOADING) this._reachBottomLoading(); else this.callBase() }, _reachBottomReady: function() { if (this._state === STATE_LOADING) return; this._state = STATE_LOADING; this._minOffset = math.min(this._containerSize() - this._contentSize(), 0) }, _reachBottomLoading: function() { this.reachBottomCallbacks.fire() }, _pullDownReady: function() { if (this._state === STATE_READY) return; this._state = STATE_READY; this._maxOffset = 0; this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_READY_CLASS); this._refreshPullDownText() }, _stateReleased: function() { if (this._state === STATE_RELEASED) return; this._releaseState(); this._updateOffsets(); this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS); this.releaseCallbacks.fire() }, _pullDownRefreshing: function() { if (this._state === STATE_REFRESHING) return; this._state = STATE_REFRESHING; this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS); this._refreshPullDownText(); this.pullDownCallbacks.fire() }, _handleRelease: function() { if (this._state === STATE_RELEASED) this._moveToBounds(); this._update(); return DX.utils.executeAsync($.proxy(this._release, this)) }, _release: function() { this._stateReleased(); this._scrollComplete() }, _handleReachBottomEnabling: function(enabled) { if (this._reachBottomEnabled === enabled) return; this._reachBottomEnabled = enabled; this._updateBounds() }, _handlePullDownEnabling: function(enabled) { if (this._pullDownEnabled === enabled) return; this._pullDownEnabled = enabled; this._considerTopPocketChange(); this._handleUpdate() }, _considerTopPocketChange: function() { this._location -= this._$topPocket.height() || -this._topPocketSize; this._move() }, _handlePendingRelease: function() { this._state = STATE_READY } }); var SimulatedScrollViewStrategy = ui.SimulatedScrollableStrategy.inherit({ _init: function(scrollView) { this.callBase(scrollView); this._$pullDown = scrollView._$pullDown; this._$topPocket = scrollView._$topPocket; this._$bottomPocket = scrollView._$bottomPocket; this._initCallbacks() }, _initCallbacks: function() { this.pullDownCallbacks = $.Callbacks(); this.releaseCallbacks = $.Callbacks(); this.reachBottomCallbacks = $.Callbacks() }, render: function() { this._renderPullDown(); this.callBase() }, _renderPullDown: function() { var $image = $("
").addClass(SCROLLVIEW_PULLDOWN_IMAGE_CLASS), $loadContainer = $("
").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS), $loadIndicator = $("
").dxLoadIndicator(), $text = this._$pullDownText = $("
").addClass(SCROLLVIEW_PULLDOWN_TEXT_CLASS); this._$pullingDownText = $("
").text(this.option("pullingDownText")).appendTo($text); this._$pulledDownText = $("
").text(this.option("pulledDownText")).appendTo($text); this._$refreshingText = $("
").text(this.option("refreshingText")).appendTo($text); this._$pullDown.empty().append($image).append($loadContainer.append($loadIndicator)).append($text) }, pullDownEnable: function(enabled) { this._handleEvent("PullDownEnabling", enabled) }, reachBottomEnable: function(enabled) { this._handleEvent("ReachBottomEnabling", enabled) }, _createScroller: function(direction) { var that = this; var scroller = that._scrollers[direction] = new ScrollViewScroller(that._scrollerOptions(direction)); scroller.pullDownCallbacks.add(function() { that.pullDownCallbacks.fire() }); scroller.releaseCallbacks.add(function() { that.releaseCallbacks.fire() }); scroller.reachBottomCallbacks.add(function() { that.reachBottomCallbacks.fire() }) }, _scrollerOptions: function(direction) { return $.extend(this.callBase(direction), { $topPocket: this._$topPocket, $bottomPocket: this._$bottomPocket, $pullDown: this._$pullDown, $pullDownText: this._$pullDownText, $pullingDownText: this._$pullingDownText, $pulledDownText: this._$pulledDownText, $refreshingText: this._$refreshingText }) }, pendingRelease: function() { this._handleEvent("PendingRelease") }, release: function() { return this._handleEvent("Release").done(this._updateAction) } }); ui.scrollViewRefreshStrategies.simulated = SimulatedScrollViewStrategy })(jQuery, DevExpress); /*! Module widgets-base, file ui.map.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, utils = DX.utils, winJS = DX.support.winJS, wrapToArray = utils.wrapToArray, removeDublicates = utils.removeDublicates, titleize = DX.inflector.titleize; ui.MapProvider = DX.Class.inherit({ _defaultRouteWeight: function() { return 5 }, _defaultRouteOpacity: function() { return .5 }, _defaultRouteColor: function() { return "#0000FF" }, ctor: function(map, $container) { this._mapWidget = map; this._$container = $container }, load: $.noop, render: function() { var deferred = $.Deferred(), that = this; this._renderImpl().done(function() { var markersPromise = that.addMarkers(that._option("markers")); var routesPromise = that.addRoutes(that._option("routes")); $.when(markersPromise, routesPromise).done(function() { deferred.resolve(true) }) }); return deferred.promise() }, _renderImpl: DX.abstract, updateDimensions: DX.abstract, updateMapType: DX.abstract, updateCenter: DX.abstract, updateZoom: DX.abstract, updateControls: DX.abstract, updateMarkers: function(markerOptionsToRemove, markerOptionsToAdd) { var deferred = $.Deferred(), that = this; this.removeMarkers(markerOptionsToRemove).done(function() { that.addMarkers(markerOptionsToAdd).done(function() { deferred.resolve.apply(deferred, arguments) }) }); return deferred.promise() }, addMarkers: DX.abstract, removeMarkers: DX.abstract, adjustViewport: DX.abstract, updateRoutes: function(routeOptionsToRemove, routeOptionsToAdd) { var deferred = $.Deferred(), that = this; this.removeRoutes(routeOptionsToRemove).done(function() { that.addRoutes(routeOptionsToAdd).done(function() { deferred.resolve.apply(deferred, arguments) }) }); return deferred.promise() }, addRoutes: DX.abstract, removeRoutes: DX.abstract, clean: DX.abstract, cancelEvents: false, map: function() { return this._map }, mapRendered: function() { return !!this._map }, _option: function(name, value) { if (value === undefined) return this._mapWidget.option(name); this._mapWidget.setOptionSilent(name, value) }, _keyOption: function(providerName) { var key = this._option("key"); return key[providerName] === undefined ? key : key[providerName] }, _parseTooltipOptions: function(option) { return { text: option.text || option, visible: option.isShown || false } }, _addEventNamespace: function(name) { return events.addNamespace(name, this._mapWidget.NAME) }, _createAction: function() { var mapWidget = this._mapWidget; return mapWidget._createAction.apply(mapWidget, arguments) }, _fireAction: function(name, actionArguments) { var option = this._option(name); if (option) this._createAction(option)(actionArguments) }, _fireClickAction: function(actionArguments) { this._fireAction("clickAction", actionArguments) }, _fireMarkerAddedAction: function(actionArguments) { this._fireAction("markerAddedAction", actionArguments) }, _fireMarkerRemovedAction: function(actionArguments) { this._fireAction("markerRemovedAction", actionArguments) }, _fireRouteAddedAction: function(actionArguments) { this._fireAction("routeAddedAction", actionArguments) }, _fireRouteRemovedAction: function(actionArguments) { this._fireAction("routeRemovedAction", actionArguments) } }); var providers = {}; ui.registerMapProvider = function(name, provider) { providers[name] = provider }; var MAP_CLASS = "dx-map", MAP_CONTAINER_CLASS = "dx-map-container", MAP_SHIELD_CLASS = "dx-map-shield"; DX.registerComponent("dxMap", ui.Widget.inherit({ ctor: function() { this.callBase.apply(this, arguments); this.addMarker = $.proxy(this._addFunction, this, "markers"); this.removeMarker = $.proxy(this._removeFunction, this, "markers"); this.addRoute = $.proxy(this._addFunction, this, "routes"); this.removeRoute = $.proxy(this._removeFunction, this, "routes") }, _addFunction: function(optionName, addingValue) { var deferred = $.Deferred(), that = this, providerDeffered = $.Deferred(), optionValue = this.option(optionName), addingValues = wrapToArray(addingValue); optionValue.push.apply(optionValue, addingValues); this._notificationDeffered = providerDeffered; this.option(optionName, optionValue); providerDeffered.done(function(instance) { deferred.resolveWith(that, instance && instance.length > 1 ? [instance] : instance) }); return deferred.promise() }, _removeFunction: function(optionName, removingValue) { var deferred = $.Deferred(), that = this, providerDeffered = $.Deferred(), optionValue = this.option(optionName), removingValues = wrapToArray(removingValue); $.each(removingValues, function(_, removingValue) { var index = $.isNumeric(removingValue) ? removingValue : $.inArray(removingValue, optionValue); if (index !== -1) optionValue.splice(index, 1); else throw new Error(titleize(optionName.substring(0, optionName.length - 1)) + " '" + removingValue + "' you are trying to remove does not exist"); }); this._notificationDeffered = providerDeffered; this.option(optionName, optionValue); providerDeffered.done(function() { deferred.resolveWith(that) }); return deferred.promise() }, _deprecatedOptions: {location: { since: "14.1", message: "Use the 'center' option instead." }}, _optionAliases: {center: "location"}, _setDefaultOptions: function() { this.callBase(); this.option({ center: { lat: 0, lng: 0 }, location: { lat: 0, lng: 0 }, width: 300, height: 300, zoom: 1, type: "roadmap", provider: "google", autoAdjust: true, markers: [], markerIconSrc: null, markerAddedAction: null, markerRemovedAction: null, routes: [], routeAddedAction: null, routeRemovedAction: null, key: { bing: "", google: "", googleStatic: "" }, controls: false, readyAction: null, updateAction: null, clickAction: null }) }, _init: function() { this._checkMarkersOption(this.option("markers")); this._checkRoutesOption(this.option("routes")); this.callBase(); this._initContainer(); this._grabEvents(); this._initProvider(); this._cleanRenderedMarkers(); this._cleanRenderedRoutes() }, _cleanRenderedMarkers: function() { this._renderedMarkers = [] }, _cleanRenderedRoutes: function(routes) { this._renderedRoutes = [] }, _checkMarkersOption: function(markers) { if (!$.isArray(markers)) throw new Error("Markers option should be an array"); }, _checkRoutesOption: function(routes) { if (!$.isArray(routes)) throw new Error("Routes option should be an array"); }, _visibilityChanged: function(visible) { if (visible) this._dimensionChanged() }, _dimensionChanged: function() { this._execAsyncProviderAction("updateDimensions") }, _initContainer: function() { this._$container = $("
").addClass(MAP_CONTAINER_CLASS); this._element().append(this._$container) }, _grabEvents: function() { var eventName = events.addNamespace("dxpointerdown", this.NAME); this._element().on(eventName, $.proxy(this._cancelEvent, this)) }, _cancelEvent: function(e) { var cancelByProvider = this._provider.cancelEvents && !this.option("disabled"); if (!DX.designMode && cancelByProvider) e.stopPropagation() }, _initProvider: function() { var provider = this.option("provider"); if (winJS && this.option("provider") === "google") throw new Error("Google provider cannot be used in winJS application"); this._cleanProvider(); this._provider = new providers[provider](this, this._$container); this._mapLoader = this._provider.load() }, _render: function() { this.callBase(); this._element().addClass(MAP_CLASS); this._renderShield(); this._execAsyncProviderAction("render").done($.proxy(function() { this._saveRenderedMarkers(); this._saveRenderedRoutes() }, this)) }, _saveRenderedMarkers: function(markers) { markers = markers || this.option("markers"); this._renderedMarkers = markers.slice() }, _saveRenderedRoutes: function(routes) { routes = routes || this.option("routes"); this._renderedRoutes = routes.slice() }, _renderShield: function() { if (DX.designMode || this.option("disabled")) { var $shield = $("
").addClass(MAP_SHIELD_CLASS); this._element().append($shield) } else { var $shield = this._element().find("." + MAP_SHIELD_CLASS); $shield.remove() } }, _clean: function() { this._cleanProvider(); this._cleanRenderedMarkers(); this._cleanRenderedRoutes() }, _cleanProvider: function() { if (this._provider) this._provider.clean() }, _optionChanged: function(name, value, prevValue) { if (this._cancelOptionChange) return; var notificationDeffered = this._notificationDeffered; delete this._notificationDeffered; switch (name) { case"disabled": this._renderShield(); this.callBase.apply(this, arguments); break; case"width": case"height": this.callBase.apply(this, arguments); this._dimensionChanged(); break; case"type": this._execAsyncProviderAction("updateMapType"); break; case"center": this._execAsyncProviderAction("updateCenter"); break; case"zoom": this._execAsyncProviderAction("updateZoom"); break; case"controls": this._execAsyncProviderAction("updateControls"); break; case"markers": this._checkMarkersOption(value); this._execAsyncProviderAction("updateMarkers", $.proxy(function() { return notificationDeffered ? removeDublicates(this._renderedMarkers, value) : this._renderedMarkers }, this), $.proxy(function() { return notificationDeffered ? removeDublicates(value, this._renderedMarkers) : value }, this)).done($.proxy(function() { this._saveRenderedMarkers(value); if (notificationDeffered) notificationDeffered.resolve.apply(notificationDeffered, arguments) }, this)); break; case"markerIconSrc": this._execAsyncProviderAction("updateMarkers", prevValue, value); break; case"autoAdjust": this._execAsyncProviderAction("adjustViewport"); break; case"routes": this._checkRoutesOption(value); this._execAsyncProviderAction("updateRoutes", $.proxy(function() { return notificationDeffered ? removeDublicates(this._renderedRoutes, value) : this._renderedRoutes }, this), $.proxy(function() { return notificationDeffered ? removeDublicates(value, this._renderedRoutes) : value }, this)).done($.proxy(function() { this._saveRenderedRoutes(value); if (notificationDeffered) notificationDeffered.resolve.apply(notificationDeffered, arguments) }, this)); break; case"key": utils.logger.warn("Key option can not be modified after initialization"); case"provider": this._initProvider(); this._invalidate(); break; case"readyAction": case"updateAction": case"markerAddedAction": case"markerRemovedAction": case"routeAddedAction": case"routeRemovedAction": case"clickAction": break; default: this.callBase.apply(this, arguments) } }, _execAsyncProviderAction: function(name) { if (!this._provider.mapRendered() && !(name === "render")) return $.when(undefined).promise(); var deferred = $.Deferred(), that = this, options = $.makeArray(arguments).slice(1); $.when(this._mapLoader).done(function() { var provider = that._provider; $.each(options, function(index, option) { if ($.isFunction(option)) options[index] = option() }); provider[name].apply(provider, options).done(function(mapRefreshed) { deferred.resolve.apply(deferred, $.makeArray(arguments).slice(1)); if (mapRefreshed) that._triggerReadyAction(); else that._triggerUpdateAction() }) }); return deferred.promise() }, _triggerReadyAction: function() { this._createActionByOption("readyAction")({originalMap: this._provider.map()}) }, _triggerUpdateAction: function() { this._createActionByOption("updateAction")() }, setOptionSilent: function(name, value) { this._cancelOptionChange = true; this.option(name, value); this._cancelOptionChange = false } })) })(jQuery, DevExpress); /*! Module widgets-base, file ui.map.bing.js */ (function($, DX, undefined) { var ui = DX.ui, winJS = DX.support.winJS; var BING_MAP_READY = "_bingScriptReady", BING_URL = "https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&s=1&onScriptLoad=" + BING_MAP_READY, BING_LOCAL_FILES1 = "ms-appx:///Bing.Maps.JavaScript/js/veapicore.js", BING_LOCAL_FILES2 = "ms-appx:///Bing.Maps.JavaScript/js/veapiModules.js", BING_CREDENTIALS = "AhuxC0dQ1DBTNo8L-H9ToVMQStmizZzBJdraTSgCzDSWPsA1Qd8uIvFSflzxdaLH", MIN_LOCATION_RECT_LENGTH = 0.0000000000000001; var msMapsLoader; ui.registerMapProvider("bing", ui.MapProvider.inherit({ _mapType: function(type) { var mapTypes = { roadmap: Microsoft.Maps.MapTypeId.road, hybrid: Microsoft.Maps.MapTypeId.aerial }; return mapTypes[type] || mapTypes.roadmap }, _movementMode: function(type) { var movementTypes = { driving: Microsoft.Maps.Directions.RouteMode.driving, walking: Microsoft.Maps.Directions.RouteMode.walking }; return movementTypes[type] || movementTypes.driving }, _resolveLocation: function(location) { var d = $.Deferred(); if (typeof location === "string") { var searchManager = new Microsoft.Maps.Search.SearchManager(this._map); var searchRequest = { where: location, count: 1, callback: function(searchResponse) { var boundsBox = searchResponse.results[0].location; d.resolve(new Microsoft.Maps.Location(boundsBox.latitude, boundsBox.longitude)) } }; searchManager.geocode(searchRequest) } else if ($.isPlainObject(location) && $.isNumeric(location.lat) && $.isNumeric(location.lng)) d.resolve(new Microsoft.Maps.Location(location.lat, location.lng)); else if ($.isArray(location)) d.resolve(new Microsoft.Maps.Location(location[0], location[1])); return d.promise() }, _normalizeLocation: function(location) { return { lat: location.latitude, lng: location.longitude } }, load: function() { if (!msMapsLoader) { msMapsLoader = $.Deferred(); window[BING_MAP_READY] = $.proxy(this._mapReady, this); if (winJS) $.when($.getScript(BING_LOCAL_FILES1), $.getScript(BING_LOCAL_FILES2)).done(function() { Microsoft.Maps.loadModule("Microsoft.Maps.Map", {callback: window[BING_MAP_READY]}) }); else $.getScript(BING_URL) } this._markers = []; this._routes = []; return msMapsLoader }, _mapReady: function() { try { delete window[BING_MAP_READY] } catch(e) { window[BING_MAP_READY] = undefined } var searchModulePromise = $.Deferred(); var directionsModulePromise = $.Deferred(); Microsoft.Maps.loadModule('Microsoft.Maps.Search', {callback: $.proxy(searchModulePromise.resolve, searchModulePromise)}); Microsoft.Maps.loadModule('Microsoft.Maps.Directions', {callback: $.proxy(directionsModulePromise.resolve, directionsModulePromise)}); $.when(searchModulePromise, directionsModulePromise).done(function() { msMapsLoader.resolve() }) }, _renderImpl: function() { var deferred = $.Deferred(), initPromise = $.Deferred(), controls = this._option("controls"); var options = { credentials: this._keyOption("bing") || BING_CREDENTIALS, mapTypeId: this._mapType(this._option("type")), zoom: this._option("zoom"), showDashboard: controls, showMapTypeSelector: controls, showScalebar: controls }; this._map = new Microsoft.Maps.Map(this._$container[0], options); var handler = Microsoft.Maps.Events.addHandler(this._map, 'tiledownloadcomplete', $.proxy(initPromise.resolve, initPromise)); this._viewChangeHandler = Microsoft.Maps.Events.addHandler(this._map, 'viewchange', $.proxy(this._handleViewChange, this)); this._clickHandler = Microsoft.Maps.Events.addHandler(this._map, 'click', $.proxy(this._handleClickAction, this)); var locationPromise = this._renderCenter(); $.when(initPromise, locationPromise).done(function() { Microsoft.Maps.Events.removeHandler(handler); deferred.resolve() }); return deferred.promise() }, _handleViewChange: function() { var center = this._map.getCenter(); this._option("center", this._normalizeLocation(center)); if (!this._preventZoomChangeEvent) this._option("zoom", this._map.getZoom()) }, updateDimensions: function() { this._map.setOptions({ width: this._$container.width(), height: this._$container.height() }); return $.Deferred().resolve().promise() }, updateMapType: function() { this._map.setView({mapTypeId: this._mapType(this._option("type"))}); return $.Deferred().resolve().promise() }, updateCenter: function() { return this._renderCenter() }, _renderCenter: function() { var deferred = $.Deferred(), that = this; this._resolveLocation(this._option("center")).done(function(location) { that._map.setView({ animate: false, center: location }); deferred.resolve() }); return deferred.promise() }, updateZoom: function() { this._map.setView({ animate: false, zoom: this._option("zoom") }); return $.Deferred().resolve().promise() }, updateControls: function() { this.clean(); return this.render() }, addMarkers: function(options) { var deferred = $.Deferred(), that = this; var markerPromises = $.map(options, function(options) { return that._addMarker(options) }); $.when.apply($, markerPromises).done(function() { var instances = $.map($.makeArray(arguments), function(markerObject) { return markerObject.pushpin }); deferred.resolve(false, instances) }); return deferred.promise() }, _addMarker: function(options) { var that = this; return this._renderMarker(options).done(function(markerObject) { that._markers.push($.extend({options: options}, markerObject)); that._updateMarkersBounds(); that._fitBounds(); that._fireMarkerAddedAction({ options: options, originalMarker: markerObject.pushpin }) }) }, _renderMarker: function(options) { var d = $.Deferred(), that = this; this._resolveLocation(options.location).done(function(location) { var pushpin = new Microsoft.Maps.Pushpin(location, {icon: options.iconSrc || that._option("markerIconSrc")}); that._map.entities.push(pushpin); var infobox = that._renderTooltip(location, options.tooltip); var handler; if (options.clickAction || options.tooltip) { var markerClickAction = that._createAction(options.clickAction || $.noop), markerNormalizedLocation = that._normalizeLocation(location); handler = Microsoft.Maps.Events.addHandler(pushpin, "click", function() { markerClickAction({location: markerNormalizedLocation}); if (infobox) infobox.setOptions({visible: true}) }) } d.resolve({ location: location, pushpin: pushpin, infobox: infobox, handler: handler }) }); return d.promise() }, _renderTooltip: function(location, options) { if (!options) return; options = this._parseTooltipOptions(options); var infobox = new Microsoft.Maps.Infobox(location, { description: options.text, offset: new Microsoft.Maps.Point(0, 33), visible: options.visible }); this._map.entities.push(infobox, null); return infobox }, removeMarkers: function(options) { var that = this; $.each(options, function(_, options) { that._removeMarker(options) }); return $.Deferred().resolve().promise() }, _removeMarker: function(options) { var that = this; $.each(this._markers, function(markerIndex, markerObject) { if (markerObject.options !== options) return true; var marker = that._markers[markerIndex]; that._map.entities.remove(marker.pushpin); if (marker.infobox) that._map.entities.remove(marker.infobox); if (marker.handler) Microsoft.Maps.Events.removeHandler(marker.handler); that._markers.splice(markerIndex, 1); that._updateMarkersBounds(); that._fitBounds(); that._fireMarkerRemovedAction({options: options}); return false }) }, _updateMarkersBounds: function() { var that = this; this._clearBounds(); $.each(this._markers, function(_, markerObject) { that._extendBounds(markerObject.location) }) }, _clearMarkers: function() { for (var i = 0; this._markers.length > 0; ) this._removeMarker(this._markers[0].options) }, adjustViewport: function() { return this._fitBounds() }, _clearBounds: function() { this._bounds = null }, _extendBounds: function(location) { if (this._bounds) this._bounds = new Microsoft.Maps.LocationRect.fromLocations(this._bounds.getNorthwest(), this._bounds.getSoutheast(), location); else this._bounds = new Microsoft.Maps.LocationRect(location, MIN_LOCATION_RECT_LENGTH, MIN_LOCATION_RECT_LENGTH) }, _fitBounds: function() { var autoAdjust = this._option("autoAdjust"); if (this._bounds && autoAdjust) { var zoomBeforeFitting = this._map.getZoom(); this._preventZoomChangeEvent = true; var bounds = this._bounds.clone(); bounds.height = bounds.height * 1.1; bounds.width = bounds.width * 1.1; this._map.setView({ animate: false, bounds: bounds }); var zoomAfterFitting = this._map.getZoom(); if (zoomBeforeFitting < zoomAfterFitting) this._map.setView({ animate: false, zoom: zoomBeforeFitting }); else this._option("zoom", zoomAfterFitting); delete this._preventZoomChangeEvent } return $.Deferred().resolve().promise() }, addRoutes: function(options) { var deferred = $.Deferred(), that = this; var routePromises = $.map(options, function(options) { return that._addRoute(options) }); $.when.apply($, routePromises).done(function() { deferred.resolve(false, $.makeArray(arguments)) }); return deferred.promise() }, _addRoute: function(options) { var that = this; return this._renderRoute(options).done(function(instance) { that._routes.push({ options: options, instance: instance }); that._fireRouteAddedAction({ options: options, originalRoute: instance }) }) }, _renderRoute: function(options) { var d = $.Deferred(), that = this; var points = $.map(options.locations, function(point) { return that._resolveLocation(point) }); $.when.apply($, points).done(function() { var locations = $.makeArray(arguments), direction = new Microsoft.Maps.Directions.DirectionsManager(that._map), color = new DX.Color(options.color || that._defaultRouteColor()).toHex(), routeColor = new Microsoft.Maps.Color.fromHex(color); routeColor.a = (options.opacity || that._defaultRouteOpacity()) * 255; direction.setRenderOptions({ autoUpdateMapView: false, displayRouteSelector: false, waypointPushpinOptions: {visible: false}, drivingPolylineOptions: { strokeColor: routeColor, strokeThickness: options.weight || that._defaultRouteWeight() }, walkingPolylineOptions: { strokeColor: routeColor, strokeThickness: options.weight || that._defaultRouteWeight() } }); direction.setRequestOptions({ routeMode: that._movementMode(options.mode), routeDraggable: false }); $.each(locations, function(_, location) { var waypoint = new Microsoft.Maps.Directions.Waypoint({location: location}); direction.addWaypoint(waypoint) }); var handler = Microsoft.Maps.Events.addHandler(direction, 'directionsUpdated', function() { Microsoft.Maps.Events.removeHandler(handler); d.resolve(direction) }); direction.calculateDirections() }); return d.promise() }, removeRoutes: function(options) { var that = this; $.each(options, function(routeIndex, options) { that._removeRoute(options) }); return $.Deferred().resolve().promise() }, _removeRoute: function(options) { var that = this; $.each(this._routes, function(routeIndex, routeObject) { if (routeObject.options !== options) return true; that._routes[routeIndex].instance.dispose(); that._routes.splice(routeIndex, 1); that._fireRouteRemovedAction({options: options}); return false }) }, _clearRoutes: function() { for (var i = 0; this._routes.length > 0; ) this._removeRoute(this._routes[0].options) }, _handleClickAction: function(e) { if (e.targetType == "map") { var point = new Microsoft.Maps.Point(e.getX(), e.getY()), location = e.target.tryPixelToLocation(point); this._fireClickAction({location: this._normalizeLocation(location)}) } }, clean: function() { if (this._map) { Microsoft.Maps.Events.removeHandler(this._viewChangeHandler); Microsoft.Maps.Events.removeHandler(this._clickHandler); this._clearMarkers(); this._clearRoutes(); this._map.dispose() } }, cancelEvents: true })); if (!ui.dxMap.__internals) ui.dxMap.__internals = {}; $.extend(ui.dxMap.__internals, {remapBingConstant: function(newValue) { BING_URL = newValue }}) })(jQuery, DevExpress); /*! Module widgets-base, file ui.map.google.js */ (function($, DX, undefined) { var ui = DX.ui; var GOOGLE_MAP_READY = "_googleScriptReady", GOOGLE_URL = "https://maps.google.com/maps/api/js?v=3.9&sensor=false&callback=" + GOOGLE_MAP_READY; var googleMapsLoader; ui.registerMapProvider("google", ui.MapProvider.inherit({ _mapType: function(type) { var mapTypes = { hybrid: google.maps.MapTypeId.HYBRID, roadmap: google.maps.MapTypeId.ROADMAP }; return mapTypes[type] || mapTypes.hybrid }, _movementMode: function(type) { var movementTypes = { driving: google.maps.TravelMode.DRIVING, walking: google.maps.TravelMode.WALKING }; return movementTypes[type] || movementTypes.driving }, _resolveLocation: function(location) { var d = $.Deferred(); if (typeof location === "string") { var geocoder = new google.maps.Geocoder; geocoder.geocode({address: location}, function(results, status) { if (status === google.maps.GeocoderStatus.OK) d.resolve(results[0].geometry.location) }) } else if ($.isArray(location)) d.resolve(new google.maps.LatLng(location[0], location[1])); else if ($.isPlainObject(location) && $.isNumeric(location.lat) && $.isNumeric(location.lng)) d.resolve(new google.maps.LatLng(location.lat, location.lng)); return d.promise() }, _normalizeLocation: function(location) { return { lat: location.lat(), lng: location.lng() } }, load: function() { if (!googleMapsLoader) { googleMapsLoader = $.Deferred(); var key = this._keyOption("google"); window[GOOGLE_MAP_READY] = $.proxy(this._mapReady, this); $.getScript(GOOGLE_URL + (key ? "&key=" + key : "")) } this._markers = []; this._routes = []; return googleMapsLoader.promise() }, _mapReady: function() { try { delete window[GOOGLE_MAP_READY] } catch(e) { window[GOOGLE_MAP_READY] = undefined } googleMapsLoader.resolve() }, _renderImpl: function() { var deferred = $.Deferred(), initPromise = $.Deferred(), controls = this._option("controls"); var options = { zoom: this._option("zoom"), center: new google.maps.LatLng(0, 0), mapTypeId: this._mapType(this._option("type")), panControl: controls, zoomControl: controls, mapTypeControl: controls, streetViewControl: controls }; this._map = new google.maps.Map(this._$container[0], options); var listner = google.maps.event.addListener(this._map, 'idle', $.proxy(initPromise.resolve, initPromise)); this._zoomChangeListener = google.maps.event.addListener(this._map, 'zoom_changed', $.proxy(this._handleZoomChange, this)); this._centerChangeListener = google.maps.event.addListener(this._map, 'center_changed', $.proxy(this._handleCenterChange, this)); this._clickListener = google.maps.event.addListener(this._map, 'click', $.proxy(this._handleClickAction, this)); var locationPromise = this._renderCenter(); $.when(initPromise, locationPromise).done(function() { google.maps.event.removeListener(listner); deferred.resolve() }); return deferred.promise() }, updateDimensions: function() { google.maps.event.trigger(this._map, 'resize'); return $.Deferred().resolve().promise() }, updateMapType: function() { this._map.setMapTypeId(this._mapType(this._option("type"))); return $.Deferred().resolve().promise() }, updateCenter: function() { return this._renderCenter() }, _handleCenterChange: function() { var center = this._map.getCenter(); this._option("center", this._normalizeLocation(center)) }, _renderCenter: function() { var deferred = $.Deferred(), that = this; this._resolveLocation(this._option("center")).done(function(location) { that._map.setCenter(location); deferred.resolve() }); return deferred.promise() }, _handleZoomChange: function() { if (!this._preventZoomChangeEvent) this._option("zoom", this._map.getZoom()) }, updateZoom: function() { this._map.setZoom(this._option("zoom")); return $.Deferred().resolve().promise() }, updateControls: function() { var controls = this._option("controls"); this._map.setOptions({ panControl: controls, zoomControl: controls, mapTypeControl: controls, streetViewControl: controls }); return $.Deferred().resolve().promise() }, addMarkers: function(options) { var deferred = $.Deferred(), that = this; var markerPromises = $.map(options, function(options) { return that._addMarker(options) }); $.when.apply($, markerPromises).done(function() { var instances = $.map($.makeArray(arguments), function(markerObject) { return markerObject.marker }); deferred.resolve(false, instances) }); return deferred.promise() }, _addMarker: function(options) { var that = this; return this._renderMarker(options).done(function(markerObject) { that._markers.push($.extend({options: options}, markerObject)); that._updateMarkersBounds(); that._fitBounds(); that._fireMarkerAddedAction({ options: options, originalMarker: markerObject.marker }) }) }, _renderMarker: function(options) { var d = $.Deferred(), that = this; this._resolveLocation(options.location).done(function(location) { var marker = new google.maps.Marker({ position: location, map: that._map, icon: options.iconSrc || that._option("markerIconSrc") }), listner; var infoWindow = that._renderTooltip(marker, options.tooltip); if (options.clickAction || options.tooltip) { var markerClickAction = that._createAction(options.clickAction || $.noop), markerNormalizedLocation = that._normalizeLocation(location); listner = google.maps.event.addListener(marker, "click", function() { markerClickAction({location: markerNormalizedLocation}); if (infoWindow) infoWindow.open(that._map, marker) }) } d.resolve({ location: location, marker: marker, listner: listner }) }); return d.promise() }, _renderTooltip: function(marker, options) { if (!options) return; options = this._parseTooltipOptions(options); var infoWindow = new google.maps.InfoWindow({content: options.text}); if (options.visible) infoWindow.open(this._map, marker); return infoWindow }, removeMarkers: function(markersOptionsToRemove) { var that = this; $.each(markersOptionsToRemove, function(_, markerOptionToRemove) { that._removeMarker(markerOptionToRemove) }); return $.Deferred().resolve().promise() }, _removeMarker: function(markersOptionToRemove) { var that = this; $.each(this._markers, function(markerIndex, markerObject) { if (markerObject.options !== markersOptionToRemove) return true; var marker = that._markers[markerIndex]; marker.marker.setMap(null); if (marker.listner) google.maps.event.removeListener(marker.listner); that._markers.splice(markerIndex, 1); that._updateMarkersBounds(); that._fitBounds(); that._fireMarkerRemovedAction({options: markerObject.options}); return false }) }, _updateMarkersBounds: function() { var that = this; this._clearBounds(); $.each(this._markers, function(_, markerObject) { that._extendBounds(markerObject.location) }) }, _clearMarkers: function() { for (var i = 0; this._markers.length > 0; ) this._removeMarker(this._markers[0].options) }, adjustViewport: function() { return this._fitBounds() }, _extendBounds: function(location) { if (this._bounds) this._bounds.extend(location); else { this._bounds = new google.maps.LatLngBounds; this._bounds.extend(location) } }, _fitBounds: function() { var autoAdjust = this._option("autoAdjust"); if (this._bounds && autoAdjust) { var zoomBeforeFitting = this._map.getZoom(); this._preventZoomChangeEvent = true; this._map.fitBounds(this._bounds); var zoomAfterFitting = this._map.getZoom(); if (zoomBeforeFitting < zoomAfterFitting) this._map.setZoom(zoomBeforeFitting); else this._option("zoom", zoomAfterFitting); delete this._preventZoomChangeEvent } return $.Deferred().resolve().promise() }, _clearBounds: function() { this._bounds = null }, addRoutes: function(options) { var deferred = $.Deferred(), that = this; var routePromises = $.map(options, function(options) { return that._addRoute(options) }); $.when.apply($, routePromises).done(function() { deferred.resolve(false, $.makeArray(arguments)) }); return deferred.promise() }, _addRoute: function(options) { var that = this; return this._renderRoute(options).done(function(instance) { that._routes.push({ options: options, instance: instance }); that._fireRouteAddedAction({ options: options, originalRoute: instance }) }) }, _renderRoute: function(options) { var d = $.Deferred(), that = this, directionsService = new google.maps.DirectionsService; var points = $.map(options.locations, function(point) { return that._resolveLocation(point) }); $.when.apply($, points).done(function() { var locations = $.makeArray(arguments), origin = locations.shift(), destination = locations.pop(), waypoints = $.map(locations, function(location) { return { location: location, stopover: true } }); var request = { origin: origin, destination: destination, waypoints: waypoints, optimizeWaypoints: true, travelMode: that._movementMode(options.mode) }; directionsService.route(request, function(response, status) { if (status === google.maps.DirectionsStatus.OK) { var color = new DX.Color(options.color || that._defaultRouteColor()).toHex(), directionOptions = { directions: response, map: that._map, suppressMarkers: true, preserveViewport: true, polylineOptions: { strokeWeight: options.weight || that._defaultRouteWeight(), strokeOpacity: options.opacity || that._defaultRouteOpacity(), strokeColor: color } }; var route = new google.maps.DirectionsRenderer(directionOptions); d.resolve(route) } }) }); return d.promise() }, removeRoutes: function(options) { var that = this; $.each(options, function(routeIndex, options) { that._removeRoute(options) }); return $.Deferred().resolve().promise() }, _removeRoute: function(options) { var that = this; $.each(this._routes, function(routeIndex, routeObject) { if (routeObject.options !== options) return true; that._routes[routeIndex].instance.setMap(null); that._routes.splice(routeIndex, 1); that._fireRouteRemovedAction({options: options}); return false }) }, _clearRoutes: function() { for (var i = 0; this._routes.length > 0; ) this._removeRoute(this._routes[0].options) }, _handleClickAction: function(e) { this._fireClickAction({location: this._normalizeLocation(e.latLng)}) }, clean: function() { if (this._map) { google.maps.event.removeListener(this._zoomChangeListener); google.maps.event.removeListener(this._centerChangeListener); google.maps.event.removeListener(this._clickListener); this._clearMarkers(); this._clearRoutes(); delete this._map; this._$container.empty() } }, cancelEvents: true })); if (!ui.dxMap.__internals) ui.dxMap.__internals = {}; $.extend(ui.dxMap.__internals, {remapGoogleConstant: function(newValue) { GOOGLE_URL = newValue }}) })(jQuery, DevExpress); /*! Module widgets-base, file ui.map.googleStatic.js */ (function($, DX, undefined) { var ui = DX.ui; var GOOGLE_STATIC_URL = "https://maps.google.com/maps/api/staticmap?"; ui.registerMapProvider("googleStatic", ui.MapProvider.inherit({ _locationToString: function(location) { return !$.isPlainObject(location) ? location.toString().replace(/ /g, "+") : location.lat + "," + location.lng }, _renderImpl: function() { return this._updateMap() }, updateDimensions: function() { return this._updateMap() }, updateMapType: function() { return this._updateMap() }, updateCenter: function() { return this._updateMap() }, updateZoom: function() { return this._updateMap() }, updateControls: function() { return $.Deferred().resolve().promise() }, addMarkers: function(options) { var that = this; return this._updateMap().done(function() { $.each(options, function(_, options) { that._fireMarkerAddedAction({options: options}) }) }) }, removeMarkers: function(options) { var that = this; return this._updateMap().done(function() { $.each(options, function(_, options) { that._fireMarkerRemovedAction({options: options}) }) }) }, adjustViewport: function() { return $.Deferred().resolve().promise() }, addRoutes: function(options) { var that = this; return this._updateMap().done(function() { $.each(options, function(_, options) { that._fireRouteAddedAction({options: options}) }) }) }, removeRoutes: function(options) { var that = this; return this._updateMap().done(function() { $.each(options, function(_, options) { that._fireRouteRemovedAction({options: options}) }) }) }, clean: function() { this._$container.css("background-image", "none"); this._$container.off(this._addEventNamespace("dxclick")) }, mapRendered: function() { return true }, _updateMap: function() { var key = this._keyOption("googleStatic"); var requestOptions = ["sensor=false", "size=" + this._option("width") + "x" + this._option("height"), "maptype=" + this._option("type"), "center=" + this._locationToString(this._option("center")), "zoom=" + this._option("zoom"), this._markersSubstring()]; requestOptions.push.apply(requestOptions, this._routeSubstrings()); if (key) requestOptions.push("key=" + key); var request = GOOGLE_STATIC_URL + requestOptions.join("&"); this._$container.css("background", "url(\"" + request + "\") no-repeat 0 0"); this._attachClickEvent(); return $.Deferred().resolve(true).promise() }, _markersSubstring: function() { var that = this, markers = [], markerIcon = this._option("markerIconSrc"); if (markerIcon) markers.push("icon:" + markerIcon); $.each(this._option("markers"), function(_, marker) { markers.push(that._locationToString(marker.location)) }); return "markers=" + markers.join("|") }, _routeSubstrings: function() { var that = this, routes = []; $.each(this._option("routes"), function(_, route) { var color = new DX.Color(route.color || that._defaultRouteColor()).toHex().replace('#', '0x'), opacity = Math.round((route.opacity || that._defaultRouteOpacity()) * 255).toString(16), width = route.weight || that._defaultRouteWeight(), locations = []; $.each(route.locations, function(_, routePoint) { locations.push(that._locationToString(routePoint)) }); routes.push("path=color:" + color + opacity + "|weight:" + width + "|" + locations.join("|")) }); return routes }, _attachClickEvent: function() { var that = this, eventName = this._addEventNamespace("dxclick"); this._$container.off(eventName).on(eventName, function(e) { that._fireClickAction({jQueryEvent: e}) }) } })); if (!ui.dxMap.__internals) ui.dxMap.__internals = {}; $.extend(ui.dxMap.__internals, {remapGoogleStaticConstant: function(newValue) { GOOGLE_STATIC_URL = newValue }}) })(jQuery, DevExpress); /*! Module widgets-base, file ui.swipeable.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, DX_SWIPEABLE = "dxSwipeable", SWIPEABLE_CLASS = "dx-swipeable", ACTION_TO_EVENT_MAP = { startAction: "dxswipestart", updateAction: "dxswipe", endAction: "dxswipeend", cancelAction: "dxswipecancel" }; DX.registerComponent(DX_SWIPEABLE, DX.DOMComponent.inherit({ NAMESPACE: ui, _setDefaultOptions: function() { this.callBase(); this.option({ elastic: true, direction: "horizontal", itemSizeFunc: null, startAction: null, updateAction: null, endAction: null, cancelAction: null }) }, _render: function() { this.callBase(); this._element().addClass(SWIPEABLE_CLASS); this._attachEventHandlers() }, _attachEventHandlers: function() { this._detachEventHanlers(); if (this.option("disabled")) return; var NAME = this.NAME; this._createEventData(); $.each(ACTION_TO_EVENT_MAP, $.proxy(function(actionName, eventName) { var action = this._createActionByOption(actionName, { context: this, excludeValidators: ["gesture"] }); eventName = events.addNamespace(eventName, NAME); this._element().on(eventName, this._eventData, function(e) { return action({jQueryEvent: e}) }) }, this)) }, _createEventData: function() { this._eventData = { elastic: this.option("elastic"), itemSizeFunc: this.option("itemSizeFunc"), direction: this.option("direction") } }, _detachEventHanlers: function() { this._element().off("." + DX_SWIPEABLE) }, _optionChanged: function(name) { switch (name) { case"disabled": case"startAction": case"updateAction": case"endAction": case"cancelAction": case"elastic": case"itemSizeFunc": case"direction": this._detachEventHanlers(); this._attachEventHandlers(); break; case"rtlEnabled": break; default: this.callBase.apply(this, arguments) } } })) })(jQuery, DevExpress); /*! Module widgets-base, file ui.button.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var BUTTON_CLASS = "dx-button", BUTTON_CONTENT_CLASS = "dx-button-content", BUTTON_CONTENT_SELECTOR = ".dx-button-content", BUTTON_TEXT_CLASS = "dx-button-text", BUTTON_HAS_TEXT_CLASS = "dx-button-has-text", BUTTON_HAS_ICON_CLASS = "dx-button-has-icon", BUTTON_TEXT_SELECTOR = ".dx-button-text", BUTTON_BACK_ARROW_CLASS = "dx-button-back-arrow", ICON_CLASS = "dx-icon", ICON_SELECTOR = ".dx-icon", BUTTON_FEEDBACK_HIDE_TIMEOUT = 100; DX.registerComponent("dxButton", ui.Widget.inherit({ _setDefaultOptions: function() { this.callBase(); this.option({ clickAction: null, type: "normal", text: "", icon: "", iconSrc: "", hoverStateEnabled: true }) }, _init: function() { this.callBase(); this._feedbackHideTimeout = BUTTON_FEEDBACK_HIDE_TIMEOUT }, _render: function() { this.callBase(); this._element().addClass(BUTTON_CLASS).append($("
").addClass(BUTTON_CONTENT_CLASS)); this._renderClick(); this._renderIcon(); this._renderType(); this._renderText() }, _renderClick: function() { var that = this, eventName = events.addNamespace("dxclick", this.NAME); this._clickAction = this._createActionByOption("clickAction"); this._element().off(eventName).on(eventName, function(e) { that._clickAction({jQueryEvent: e}) }) }, _removeTypesCss: function() { var css = this._element().attr("class"); css = css.replace(/\bdx-button-[-a-z0-9]+\b/gi, ""); this._element().attr("class", css) }, _renderIcon: function() { var contentElement = this._element().find(BUTTON_CONTENT_SELECTOR), iconElement = contentElement.find(ICON_SELECTOR), icon = this.option("icon"), iconSrc = this.option("iconSrc"); iconElement.remove(); if (this.option("type") === "back" && !icon) icon = "back"; if (!icon && !iconSrc) return; if (icon) iconElement = $("").addClass("dx-icon-" + icon); else if (iconSrc) iconElement = $("").attr("src", iconSrc); contentElement.prepend(iconElement.addClass(ICON_CLASS)); this._element().addClass(BUTTON_HAS_ICON_CLASS) }, _renderType: function() { var type = this.option("type"); if (type) this._element().addClass("dx-button-" + type); if (type === "back") this._element().prepend($("").addClass(BUTTON_BACK_ARROW_CLASS)) }, _renderText: function() { var text = this.option("text"), contentElement = this._element().find(BUTTON_CONTENT_SELECTOR), back = this.option("type") === "back"; var textElement = contentElement.find(BUTTON_TEXT_SELECTOR); if (!text && !back) { textElement.remove(); return } if (!textElement.length) textElement = $('').addClass(BUTTON_TEXT_CLASS).appendTo(contentElement); textElement.text(text || DX.localization.localizeString("@Back")); this._element().addClass(BUTTON_HAS_TEXT_CLASS) }, _clean: function() { this.callBase(); this._removeTypesCss() }, _optionChanged: function(name) { switch (name) { case"clickAction": this._renderClick(); break; case"icon": case"iconSrc": this._renderIcon(); break; case"text": this._renderText(); break; case"type": this._invalidate(); break; default: this.callBase.apply(this, arguments) } } })) })(jQuery, DevExpress); /*! Module widgets-base, file ui.checkBox.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var CHECKBOX_CLASS = "dx-checkbox", CHECKBOX_ICON_CLASS = "dx-checkbox-icon", CHECKBOX_CHECKED_CLASS = "dx-checkbox-checked", CHECKBOX_INDETERMINATE_CLASS = "dx-checkbox-indeterminate", CHECKBOX_FEEDBACK_HIDE_TIMEOUT = 100, CHECKBOX_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxCheckBox"); DX.registerComponent("dxCheckBox", ui.dxEditor.inherit({ _deprecatedOptions: {checked: { since: "14.1", message: "Use the 'value' option instead." }}, _optionAliases: {checked: "value"}, _setDefaultOptions: function() { this.callBase(); this.option({ value: undefined, valueChangeAction: null, hoverStateEnabled: true }) }, _init: function() { this.callBase(); this._feedbackHideTimeout = CHECKBOX_FEEDBACK_HIDE_TIMEOUT }, _render: function() { this.callBase(); this._element().addClass(CHECKBOX_CLASS); this._$iconContainer = $(""); this._$iconContainer.addClass(CHECKBOX_ICON_CLASS).appendTo(this._element()); this._renderValue(); this._renderClick(); this._updateContentSize() }, _renderDimensions: function() { this.callBase(); this._updateContentSize() }, _updateContentSize: function() { var $element = this._element(), width = this.option("width"), height = this.option("height"); if (this._$iconContainer && (width || height)) { width = this._element().width(); height = this._element().height(); var minDimention = Math.min(height, width); this._$iconContainer.css({ height: minDimention, width: minDimention, "margin-top": (height - minDimention) / 2, "margin-left": (width - minDimention) / 2 }) } }, _renderClick: function() { var clickAction = this._createAction(this._handleClick); this._element().off(CHECKBOX_DXCLICK_EVENT_NAME).on(CHECKBOX_DXCLICK_EVENT_NAME, function(e) { clickAction({jQueryEvent: e}) }) }, _handleClick: function(args) { var that = args.component; that._valueChangeEventInstance = args.jQueryEvent; that.option("value", !that.option("value")) }, _renderValue: function() { var $element = this._element(), checked = this.option("value"), indeterminate = checked === undefined; $element.toggleClass(CHECKBOX_CHECKED_CLASS, Boolean(checked)); $element.toggleClass(CHECKBOX_INDETERMINATE_CLASS, indeterminate) }, _optionChanged: function(name) { switch (name) { case"value": this._renderValue(); default: this.callBase.apply(this, arguments) } } })) })(jQuery, DevExpress); /*! Module widgets-base, file ui.textEditor.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var TEXTEDITOR_CLASS = "dx-texteditor", TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input", TEXTEDITOR_INPUT_SELECTOR = "." + TEXTEDITOR_INPUT_CLASS, TEXTEDITOR_BORDER_CLASS = "dx-texteditor-border", TEXTEDITOR_PLACEHOLDER_CLASS = "dx-placeholder", TEXTEDITOR_SHOW_CLEAR_BUTTON_CLASS = "dx-show-clear-button", TEXTEDITOR_CLEAR_ICON_CLASS = "dx-icon-clear", TEXTEDITOR_CLEAR_BUTTON_CLASS = "dx-clear-button-area", TEXTEDITOR_EMPTY_INPUT_CLASS = "dx-texteditor-empty", TEXTEDITOR_STATE_FOCUSED_CLASS = "dx-state-focused", EVENTS_LIST = ["focusIn", "focusOut", "keyDown", "keyPress", "keyUp", "change", "cut", "copy", "paste", "input"]; var nativeClearButtonCancelSupport = function() { return DX.browser["msie"] && DX.browser.version > 9 || !DX.browser["msie"] }(); DX.registerComponent("dxTextEditor", ui.dxEditor.inherit({ _deprecatedOptions: { valueUpdateEvent: { since: "14.1", message: "Use the 'valueChangeEvent' option instead." }, valueUpdateAction: { since: "14.1", message: "Use the 'valueChangeAction' option instead." } }, _optionAliases: {valueUpdateEvent: "valueChangeEvent"}, _setDefaultOptions: function() { this.callBase(); this.option({ value: "", showClearButton: false, valueChangeEvent: "change", valueUpdateAction: null, placeholder: "", readOnly: false, focusInAction: null, focusOutAction: null, keyDownAction: null, keyPressAction: null, keyUpAction: null, changeAction: null, inputAction: null, cutAction: null, copyAction: null, pasteAction: null, enterKeyAction: null, mode: "text", activeStateEnabled: false, hoverStateEnabled: true }) }, _input: function() { return this._element().find(TEXTEDITOR_INPUT_SELECTOR) }, _render: function() { this._element().addClass(TEXTEDITOR_CLASS); this._renderInput(); this._renderInputType(); this._renderValue(); this._renderProps(); this._renderPlaceholder(); this._renderEvents(); this._toggleClearButton(); this._renderEnterKeyAction(); this._renderEmptinessEvent(); this._renderFocusEvent(); this.callBase() }, _renderInput: function(inputContainer) { (inputContainer || this._element()).append($("
").addClass(TEXTEDITOR_BORDER_CLASS).append($("").addClass(TEXTEDITOR_INPUT_CLASS))) }, _renderValue: function(formattedValue) { var text = formattedValue || this.option("value"); if (this._input().val() !== text) { this._input().val(text); this._toggleEmptinessEventHandler() } }, _isValueValid: function() { var validity = this._input().get(0).validity; if (validity) return validity.valid; return true }, _toggleEmptiness: function(visibility) { this._element().toggleClass(TEXTEDITOR_EMPTY_INPUT_CLASS, visibility) }, _togglePlaceholderVisibility: function(visibility) { if (!this._$placeholder) return; if (DX.browser["msie"]) this._$placeholder.toggle(!this._input().is(":focus") && visibility); else this._$placeholder.toggle(visibility) }, _renderProps: function() { this._input().prop({ readOnly: this._readOnlyPropValue(), disabled: this.option("disabled") }) }, _readOnlyPropValue: function() { return this.option("readOnly") }, _renderPlaceholder: function() { var that = this, $input = that._input(), placeholderText = that.option("placeholder"), $placeholder = this._$placeholder = $('
').attr("data-dx_placeholder", placeholderText), startEvent = events.addNamespace("dxclick", this.NAME); $placeholder.on(startEvent, function() { $input.focus() }); $placeholder.appendTo($input.parent()); $placeholder.addClass(TEXTEDITOR_PLACEHOLDER_CLASS) }, _toggleClearButton: function() { if (!nativeClearButtonCancelSupport) return; var $element = this._element(), showing = this.option("showClearButton") && !this.option("readOnly"); $element.toggleClass(TEXTEDITOR_SHOW_CLEAR_BUTTON_CLASS, showing); if (showing) this._renderClearButton(); else this._$clearButton && this._$clearButton.remove() }, _renderClearButton: function() { var $clearButton = $("").addClass(TEXTEDITOR_CLEAR_BUTTON_CLASS).append($("").addClass(TEXTEDITOR_CLEAR_ICON_CLASS)).on(events.addNamespace("dxpointerdown", this.NAME), function() { return false }).on(events.addNamespace("dxpointerup", this.NAME), $.proxy(this._handleClearValue, this)); this._element().append($clearButton); this._$clearButton = $clearButton }, _handleClearValue: function() { var $input = this._input(); this.option("value", ""); if ($input.is(":focus")) { $input.val(""); this._toggleEmptinessEventHandler() } else $input.trigger("focus") }, _renderEvents: function() { var that = this, $input = that._input(); that._renderValueUpdateEvent(); $.each(EVENTS_LIST, function(_, event) { var eventName = events.addNamespace(event.toLowerCase(), that.NAME), action = that._createActionByOption(event + "Action"); $input.off(eventName).on(eventName, function(e) { action({jQueryEvent: e}) }) }) }, _renderValueUpdateEvent: function() { var eventNamespace = this.NAME + "ValueUpdate"; var valueChangeEvent = events.addNamespace(this.option("valueChangeEvent"), eventNamespace); this._input().off("." + eventNamespace).on(valueChangeEvent, $.proxy(this._handleValueChangeEvent, this)); this._valueUpdateAction = this._createActionByOption("valueUpdateAction") }, _renderFocusEvent: function() { var $element = this._element(); $element.find("." + TEXTEDITOR_INPUT_CLASS).focusin(function() { $element.addClass(TEXTEDITOR_STATE_FOCUSED_CLASS) }).focusout(function() { $element.removeClass(TEXTEDITOR_STATE_FOCUSED_CLASS) }).filter(":focus").addClass(TEXTEDITOR_STATE_FOCUSED_CLASS); if (DX.browser["msie"]) this._input().on('focus', $.proxy(function() { this._togglePlaceholderVisibility(false) }, this)) }, _renderEmptinessEvent: function() { var $input = this._input(); $input.on("input blur", $.proxy(this._toggleEmptinessEventHandler, this)); this._toggleEmptinessEventHandler() }, _toggleEmptinessEventHandler: function(value) { var value = this._input().val(), visibility = (value === "" || value === null) && this._isValueValid(); this._toggleEmptiness(visibility); this._togglePlaceholderVisibility(visibility) }, _handleValueChangeEvent: function(e, formattedValue) { this._valueChangeEventInstance = e; this._suppressValueUpdateAction = true; this.option("value", arguments.length > 1 ? formattedValue : this._input().val()); this._suppressValueUpdateAction = false; this._valueUpdateAction({ value: this.option("value"), jQueryEvent: e }) }, _renderEnterKeyAction: function() { if (this.option("enterKeyAction")) { this._enterKeyAction = this._createActionByOption("enterKeyAction"); this._input().on("keyup.enterKey.dxTextEditor", $.proxy(this._handleEnterKeyUp, this)) } else { this._input().off("keyup.enterKey.dxTextEditor"); this._enterKeyAction = undefined } }, _handleEnterKeyUp: function(e) { if (e.which === 13) this._enterKeyAction({jQueryEvent: e}) }, _toggleDisabledState: function() { this.callBase.apply(this, arguments); this._renderProps() }, _updateValue: function() { this._renderValue(); if (!this._suppressValueUpdateAction) this._valueUpdateAction({value: this.option("value")}) }, _suppressUpdateValue: function() { this._valueUpdateSuppressed = true }, _resumeUpdateValue: function() { this._valueUpdateSuppressed = false }, _optionChanged: function(optionName) { if ($.inArray(optionName.replace("Action", ""), EVENTS_LIST) > -1) { this._renderEvents(); return } switch (optionName) { case"valueChangeEvent": case"valueUpdateAction": this._renderValueUpdateEvent(); break; case"readOnly": this._renderProps(); this._toggleClearButton(); break; case"mode": this._renderInputType(); break; case"enterKeyAction": this._renderEnterKeyAction(); break; case"placeholder": this._invalidate(); break; case"showClearButton": this._toggleClearButton(); break; case"value": if (!this._valueUpdateSuppressed) this._updateValue(); default: this.callBase.apply(this, arguments) } }, _renderInputType: function() { this._setInputType(this.option("mode")) }, _setInputType: function(type) { var input = this._input(); if (type === "search") type = "text"; try { input.prop("type", type) } catch(e) { input.prop("type", "text") } }, focus: function() { this._input().focus() }, blur: function() { if (this._input().is(document.activeElement)) DX.utils.resetActiveElement() } })) })(jQuery, DevExpress); /*! Module widgets-base, file ui.textBox.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, devices = DX.devices, ua = window.navigator.userAgent, ignoreCode = [8, 9, 13, 33, 34, 35, 36, 37, 38, 39, 40, 46], TEXTBOX_CLASS = "dx-textbox", SEARCHBOX_CLASS = "dx-searchbox", SEARCH_ICON_CLASS = "dx-icon-search"; DX.registerComponent("dxTextBox", ui.dxTextEditor.inherit({ _setDefaultOptions: function() { this.callBase(); this.option({ mode: "text", maxLength: null }) }, _render: function() { this.callBase(); this._element().addClass(TEXTBOX_CLASS); this._renderMaxLengthHandlers(); this._renderSearchMode() }, _renderMaxLengthHandlers: function() { if (this._isAndroid()) this._input().on(events.addNamespace("keydown", this.NAME), $.proxy(this._onKeyDownAndroidHandler, this)).on(events.addNamespace("change", this.NAME), $.proxy(this._onChangeAndroidHandler, this)) }, _renderProps: function() { this.callBase(); if (this._isAndroid()) return; var maxLength = this.option("maxLength"); if (maxLength > 0) this._input().prop("maxLength", maxLength) }, _renderSearchMode: function() { var $element = this._$element; if (this.option("mode") === "search") { this._renderSearchIcon(); $element.addClass(SEARCHBOX_CLASS); this._showClearButton = this.option("showClearButton"); this.option("showClearButton", true) } if (this.option("mode") !== "search") { $element.removeClass(SEARCHBOX_CLASS); this._$searchIcon && this._$searchIcon.remove(); this.option("showClearButton", this._showClearButton === undefined ? this.option("showClearButton") : this._showClearButton) } }, _renderSearchIcon: function() { var $searchIcon = $("
").addClass(SEARCH_ICON_CLASS); $searchIcon.prependTo(this._input().parent()); this._$searchIcon = $searchIcon }, _optionChanged: function(name) { switch (name) { case"maxLength": this._renderProps(); this._renderMaxLengthHandlers(); break; case"mode": this._renderSearchMode(); default: this.callBase.apply(this, arguments) } }, _onKeyDownAndroidHandler: function(e) { var maxLength = this.option("maxLength"); if (maxLength) { var $input = $(e.target), code = e.keyCode; this._cutOffExtraChar($input); return $input.val().length < maxLength || $.inArray(code, ignoreCode) !== -1 || window.getSelection().toString() !== "" } else return true }, _onChangeAndroidHandler: function(e) { var $input = $(e.target); if (this.option("maxLength")) this._cutOffExtraChar($input) }, _cutOffExtraChar: function($input) { var maxLength = this.option("maxLength"), textInput = $input.val(); if (textInput.length > maxLength) $input.val(textInput.substr(0, maxLength)) }, _isAndroid: function() { var realDevice = devices.real(); var version = realDevice.version.join("."); return realDevice.platform === "android" && version && /^(2\.|4\.1)/.test(version) && !/chrome/i.test(ua) } })); ui.dxTextBox.__internals = { uaAccessor: function(value) { if (!arguments.length) return ui; ua = value }, SEARCHBOX_CLASS: SEARCHBOX_CLASS, SEARCH_ICON_CLASS: SEARCH_ICON_CLASS } })(jQuery, DevExpress); /*! Module widgets-base, file ui.dropDownEditor.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events, DROP_DOWN_EDITOR_CLASS = "dx-dropdowneditor", DROP_DOWN_EDITOR_READONLY_CLASS = "dx-dropdowneditor-readonly", DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS = "dx-dropdowneditor-input-wrapper", DROP_DOWN_EDITOR_BUTTON_CLASS = "dx-dropdowneditor-button", DROP_DOWN_EDITOR_BUTTON_ICON = "dx-dropdowneditor-icon", DROP_DOWN_EDITOR_OVERLAY = "dx-dropdowneditor-overlay", DROP_DOWN_EDITOR_ACTIVE = "dx-dropdowneditor-active", DROP_DOWN_EDITOR_BUTTON_VISIBLE = "dx-dropdowneditor-button-visible", DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxDropDownEditor"), DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME = events.addNamespace("mousedown", "dxDropDownEditor"), keyboardKeys = { upArrow: 38, downArrow: 40 }; DX.registerComponent("dxDropDownEditor", ui.dxTextBox.inherit({ _setDefaultOptions: function() { this.callBase(); this.option({ openAction: null, closeAction: null }) }, open: function() { this._showDropDown() }, close: function() { this._hideDropDown() }, _clean: function() { this.callBase(); if (this._dropDownContainer) { this._dropDownContainer.remove(); this._dropDown = undefined } }, _render: function() { this._dropDownContainerRendered = false; this._element().addClass(DROP_DOWN_EDITOR_CLASS); this._renderButton(); this.callBase(); this._renderKeyboardEvents(); var that = this; this._input().on("blur", function(e) { if (that._hideOnBlur() && !that._needToPreventBlur) that._hideDropDown(); that._needToPreventBlur = false }) }, _renderInput: function(inputContainer) { this._inputWrapper = inputContainer || $("
"); this._inputWrapper.addClass(DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS); this._element().prepend(this._inputWrapper); this.callBase(this._inputWrapper) }, _renderButton: function(hideButton) { this._button = $("
").addClass(DROP_DOWN_EDITOR_BUTTON_CLASS); this._attachButtonEvents(); this._updateButtonReadonlyState(); this._buttonIcon = $("
").addClass(DROP_DOWN_EDITOR_BUTTON_ICON).appendTo(this._button); this._button.appendTo(this._element()); if (hideButton) { this._element().removeClass(DROP_DOWN_EDITOR_BUTTON_VISIBLE); this._button.hide() } else this._element().addClass(DROP_DOWN_EDITOR_BUTTON_VISIBLE) }, _attachButtonEvents: function() { var that = this, dxClickAction, mouseDownAction; this._button.off(DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME).off(DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME); if (!this.option("readOnly")) { dxClickAction = this._createAction(function() { that._toggleDropDown(); that._dropDownClickHandler() }); mouseDownAction = this._createAction(function(args) { that._mouseDownFocusKeeper(args.jQueryEvent) }); this._button.on(DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME, function(e) { dxClickAction({jQueryEvent: e}) }).on(DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME, function(e) { mouseDownAction({jQueryEvent: e}) }) } }, _updateButtonReadonlyState: function() { this._button.removeClass(DROP_DOWN_EDITOR_READONLY_CLASS); if (this.option("readOnly")) this._button.addClass(DROP_DOWN_EDITOR_READONLY_CLASS) }, _renderKeyboardEvents: function() { this._input().off(events.addNamespace("keydown", "dxDropDownEditor")).on(events.addNamespace("keydown", "dxDropDownEditor"), $.proxy(this._onKeyDownHandler, this)) }, _dropDownClickHandler: function() { if (!this._deviceHasTouchScreen() && !this._input().is(":focus")) this.focus(); this._needToPreventBlur = false }, _mouseDownFocusKeeper: function(e) { this._needToPreventBlur = true; if (e && e.preventDefault) e.preventDefault() }, _deviceHasTouchScreen: function() { var device = DevExpress.devices.real(); return device.phone || device.tablet }, _hideOnBlur: function() { return true }, _renderDropDownContent: function() { return [] }, _dropDownVisible: function() { return this._dropDown && this._dropDown.option("visible") }, _toggleDropDown: function() { this._dropDownVisible() ? this._hideDropDown() : this._showDropDown() }, _showDropDown: function() { if (!this._dropDownVisible()) { this._renderDropDownContainer(); this._dropDown.show(); this._element().addClass(DROP_DOWN_EDITOR_ACTIVE) } }, _hideDropDown: function() { if (this._dropDownVisible()) { this._element().removeClass(DROP_DOWN_EDITOR_ACTIVE); this._dropDown.hide() } }, _renderDropDownContainer: function() { var that = this, dropDownContent; if (!this._dropDownContainerRendered) { this._dropDownContainer = $("
").addClass(DROP_DOWN_EDITOR_OVERLAY).addClass(that.option("customOverlayCssClass")); this._element().append(this._dropDownContainer); this._createDropDown(); dropDownContent = this._renderDropDownContent(); if (!$.isArray(dropDownContent)) dropDownContent = [dropDownContent]; $.each(dropDownContent, function(index, contentElement) { contentElement.off(DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME).on(DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME, function(e) { that._mouseDownFocusKeeper(e) }).off(DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME).on(DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME, function() { that._dropDownClickHandler() }); that._dropDownContainer.append(contentElement) }); this._dropDownContainerRendered = true } }, _createDropDown: function(options) { this._dropDown = this._dropDownContainer.dxOverlay($.extend(true, { position: { offset: "0 -1", my: "left top", at: "left bottom", of: this._element(), collision: "flip flip" }, showTitle: false, width: "auto", height: "auto", shading: false, rtlEnabled: this.option("rtlEnabled"), closeOnTargetScroll: $.proxy(this._closeOnScrollHandler, this), closeOnOutsideClick: $.proxy(this._closeOutsideDropDownHandler, this), animation: { show: false, hide: false }, shownAction: this.option("openAction"), hiddenAction: this.option("closeAction") }, options)).dxOverlay("instance") }, _closeOnScrollHandler: function(e) { this._hideDropDown(); return true }, _closeOutsideDropDownHandler: function(e, ignoreContainerClicks) { if (e.target !== this._input()[0] && e.target !== this._button[0] && !this._button.find($(e.target)).length && (!ignoreContainerClicks || !this._dropDown._container().find($(e.target)).length)) this._hideDropDown(); return false }, _onKeyDownHandler: function(e) { if (e.altKey) { if (e.which === keyboardKeys.downArrow) this._showDropDown(); if (e.which === keyboardKeys.upArrow) this._hideDropDown() } }, _optionChanged: function(name, value) { switch (name) { case"rtlEnabled": this.callBase.apply(this, arguments); if (this._dropDownContainerRendered) this._dropDown.option(name, value); break; case"openAction": if (this._dropDownContainerRendered) this._dropDown.option("shownAction", value); break; case"closeAction": if (this._dropDownContainerRendered) this._dropDown.option("hiddenAction", value); break; case"readOnly": this._attachButtonEvents(); this._updateButtonReadonlyState(); default: this.callBase.apply(this, arguments) } } })); ui.dxDropDownEditor.__internals = { DROP_DOWN_EDITOR_CLASS: DROP_DOWN_EDITOR_CLASS, DROP_DOWN_EDITOR_READONLY_CLASS: DROP_DOWN_EDITOR_READONLY_CLASS, DROP_DOWN_EDITOR_BUTTON_ICON: DROP_DOWN_EDITOR_BUTTON_ICON, DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS: DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS, DROP_DOWN_EDITOR_BUTTON_CLASS: DROP_DOWN_EDITOR_BUTTON_CLASS, DROP_DOWN_EDITOR_OVERLAY: DROP_DOWN_EDITOR_OVERLAY, DROP_DOWN_EDITOR_ACTIVE: DROP_DOWN_EDITOR_ACTIVE, DROP_DOWN_EDITOR_BUTTON_VISIBLE: DROP_DOWN_EDITOR_BUTTON_VISIBLE } })(jQuery, DevExpress); /*! Module widgets-base, file ui.textArea.js */ (function($, DX, undefined) { var ui = DX.ui, events = ui.events; var TEXTAREA_CLASS = "dx-textarea", TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input", TEXTEDITOR_BORDER_CLASS = "dx-texteditor-border"; DX.registerComponent("dxTextArea", ui.dxTextBox.inherit({ _setDefaultOptions: function() { this.callBase(); this.option({}) }, _render: function() { this.callBase(); this._element().addClass(TEXTAREA_CLASS) }, _renderInput: function() { this._element().append($("
").addClass(TEXTEDITOR_BORDER_CLASS).append($("