EnVisageOnline/Main/Source/EnVisage/Scripts/Kendo/kendo.drawing.js

8216 lines
328 KiB
JavaScript

/**
* Kendo UI v2016.1.226 (http://www.telerik.com/kendo-ui)
* Copyright 2016 Telerik AD. All rights reserved.
*
* Kendo UI commercial licenses may be obtained at
* http://www.telerik.com/purchase/license-agreement/kendo-ui-complete
* If you do not own a commercial license, this file shall be governed by the trial license terms.
*/
(function (f, define) {
define('util/main', ['kendo.core'], f);
}(function () {
(function () {
var math = Math, kendo = window.kendo, deepExtend = kendo.deepExtend;
var DEG_TO_RAD = math.PI / 180, MAX_NUM = Number.MAX_VALUE, MIN_NUM = -Number.MAX_VALUE, UNDEFINED = 'undefined';
function defined(value) {
return typeof value !== UNDEFINED;
}
function round(value, precision) {
var power = pow(precision);
return math.round(value * power) / power;
}
function pow(p) {
if (p) {
return math.pow(10, p);
} else {
return 1;
}
}
function limitValue(value, min, max) {
return math.max(math.min(value, max), min);
}
function rad(degrees) {
return degrees * DEG_TO_RAD;
}
function deg(radians) {
return radians / DEG_TO_RAD;
}
function isNumber(val) {
return typeof val === 'number' && !isNaN(val);
}
function valueOrDefault(value, defaultValue) {
return defined(value) ? value : defaultValue;
}
function sqr(value) {
return value * value;
}
function objectKey(object) {
var parts = [];
for (var key in object) {
parts.push(key + object[key]);
}
return parts.sort().join('');
}
function hashKey(str) {
var hash = 2166136261;
for (var i = 0; i < str.length; ++i) {
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
hash ^= str.charCodeAt(i);
}
return hash >>> 0;
}
function hashObject(object) {
return hashKey(objectKey(object));
}
var now = Date.now;
if (!now) {
now = function () {
return new Date().getTime();
};
}
function arrayLimits(arr) {
var length = arr.length, i, min = MAX_NUM, max = MIN_NUM;
for (i = 0; i < length; i++) {
max = math.max(max, arr[i]);
min = math.min(min, arr[i]);
}
return {
min: min,
max: max
};
}
function arrayMin(arr) {
return arrayLimits(arr).min;
}
function arrayMax(arr) {
return arrayLimits(arr).max;
}
function sparseArrayMin(arr) {
return sparseArrayLimits(arr).min;
}
function sparseArrayMax(arr) {
return sparseArrayLimits(arr).max;
}
function sparseArrayLimits(arr) {
var min = MAX_NUM, max = MIN_NUM;
for (var i = 0, length = arr.length; i < length; i++) {
var n = arr[i];
if (n !== null && isFinite(n)) {
min = math.min(min, n);
max = math.max(max, n);
}
}
return {
min: min === MAX_NUM ? undefined : min,
max: max === MIN_NUM ? undefined : max
};
}
function last(array) {
if (array) {
return array[array.length - 1];
}
}
function append(first, second) {
first.push.apply(first, second);
return first;
}
function renderTemplate(text) {
return kendo.template(text, {
useWithBlock: false,
paramName: 'd'
});
}
function renderAttr(name, value) {
return defined(value) && value !== null ? ' ' + name + '=\'' + value + '\' ' : '';
}
function renderAllAttr(attrs) {
var output = '';
for (var i = 0; i < attrs.length; i++) {
output += renderAttr(attrs[i][0], attrs[i][1]);
}
return output;
}
function renderStyle(attrs) {
var output = '';
for (var i = 0; i < attrs.length; i++) {
var value = attrs[i][1];
if (defined(value)) {
output += attrs[i][0] + ':' + value + ';';
}
}
if (output !== '') {
return output;
}
}
function renderSize(size) {
if (typeof size !== 'string') {
size += 'px';
}
return size;
}
function renderPos(pos) {
var result = [];
if (pos) {
var parts = kendo.toHyphens(pos).split('-');
for (var i = 0; i < parts.length; i++) {
result.push('k-pos-' + parts[i]);
}
}
return result.join(' ');
}
function isTransparent(color) {
return color === '' || color === null || color === 'none' || color === 'transparent' || !defined(color);
}
function arabicToRoman(n) {
var literals = {
1: 'i',
10: 'x',
100: 'c',
2: 'ii',
20: 'xx',
200: 'cc',
3: 'iii',
30: 'xxx',
300: 'ccc',
4: 'iv',
40: 'xl',
400: 'cd',
5: 'v',
50: 'l',
500: 'd',
6: 'vi',
60: 'lx',
600: 'dc',
7: 'vii',
70: 'lxx',
700: 'dcc',
8: 'viii',
80: 'lxxx',
800: 'dccc',
9: 'ix',
90: 'xc',
900: 'cm',
1000: 'm'
};
var values = [
1000,
900,
800,
700,
600,
500,
400,
300,
200,
100,
90,
80,
70,
60,
50,
40,
30,
20,
10,
9,
8,
7,
6,
5,
4,
3,
2,
1
];
var roman = '';
while (n > 0) {
if (n < values[0]) {
values.shift();
} else {
roman += literals[values[0]];
n -= values[0];
}
}
return roman;
}
function romanToArabic(r) {
r = r.toLowerCase();
var digits = {
i: 1,
v: 5,
x: 10,
l: 50,
c: 100,
d: 500,
m: 1000
};
var value = 0, prev = 0;
for (var i = 0; i < r.length; ++i) {
var v = digits[r.charAt(i)];
if (!v) {
return null;
}
value += v;
if (v > prev) {
value -= 2 * prev;
}
prev = v;
}
return value;
}
function memoize(f) {
var cache = Object.create(null);
return function () {
var id = '';
for (var i = arguments.length; --i >= 0;) {
id += ':' + arguments[i];
}
if (id in cache) {
return cache[id];
}
return f.apply(this, arguments);
};
}
function ucs2decode(string) {
var output = [], counter = 0, length = string.length, value, extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if (value >= 55296 && value <= 56319 && counter < length) {
extra = string.charCodeAt(counter++);
if ((extra & 64512) == 56320) {
output.push(((value & 1023) << 10) + (extra & 1023) + 65536);
} else {
output.push(value);
counter--;
}
} else {
output.push(value);
}
}
return output;
}
function ucs2encode(array) {
return array.map(function (value) {
var output = '';
if (value > 65535) {
value -= 65536;
output += String.fromCharCode(value >>> 10 & 1023 | 55296);
value = 56320 | value & 1023;
}
output += String.fromCharCode(value);
return output;
}).join('');
}
deepExtend(kendo, {
util: {
MAX_NUM: MAX_NUM,
MIN_NUM: MIN_NUM,
append: append,
arrayLimits: arrayLimits,
arrayMin: arrayMin,
arrayMax: arrayMax,
defined: defined,
deg: deg,
hashKey: hashKey,
hashObject: hashObject,
isNumber: isNumber,
isTransparent: isTransparent,
last: last,
limitValue: limitValue,
now: now,
objectKey: objectKey,
round: round,
rad: rad,
renderAttr: renderAttr,
renderAllAttr: renderAllAttr,
renderPos: renderPos,
renderSize: renderSize,
renderStyle: renderStyle,
renderTemplate: renderTemplate,
sparseArrayLimits: sparseArrayLimits,
sparseArrayMin: sparseArrayMin,
sparseArrayMax: sparseArrayMax,
sqr: sqr,
valueOrDefault: valueOrDefault,
romanToArabic: romanToArabic,
arabicToRoman: arabicToRoman,
memoize: memoize,
ucs2encode: ucs2encode,
ucs2decode: ucs2decode
}
});
kendo.drawing.util = kendo.util;
kendo.dataviz.util = kendo.util;
}());
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('util/text-metrics', [
'kendo.core',
'util/main'
], f);
}(function () {
(function ($) {
var doc = document, kendo = window.kendo, Class = kendo.Class, util = kendo.util, defined = util.defined;
var LRUCache = Class.extend({
init: function (size) {
this._size = size;
this._length = 0;
this._map = {};
},
put: function (key, value) {
var lru = this, map = lru._map, entry = {
key: key,
value: value
};
map[key] = entry;
if (!lru._head) {
lru._head = lru._tail = entry;
} else {
lru._tail.newer = entry;
entry.older = lru._tail;
lru._tail = entry;
}
if (lru._length >= lru._size) {
map[lru._head.key] = null;
lru._head = lru._head.newer;
lru._head.older = null;
} else {
lru._length++;
}
},
get: function (key) {
var lru = this, entry = lru._map[key];
if (entry) {
if (entry === lru._head && entry !== lru._tail) {
lru._head = entry.newer;
lru._head.older = null;
}
if (entry !== lru._tail) {
if (entry.older) {
entry.older.newer = entry.newer;
entry.newer.older = entry.older;
}
entry.older = lru._tail;
entry.newer = null;
lru._tail.newer = entry;
lru._tail = entry;
}
return entry.value;
}
}
});
var defaultMeasureBox = $('<div style=\'position: absolute !important; top: -4000px !important; width: auto !important; height: auto !important;' + 'padding: 0 !important; margin: 0 !important; border: 0 !important;' + 'line-height: normal !important; visibility: hidden !important; white-space: nowrap!important;\' />')[0];
function zeroSize() {
return {
width: 0,
height: 0,
baseline: 0
};
}
var TextMetrics = Class.extend({
init: function (options) {
this._cache = new LRUCache(1000);
this._initOptions(options);
},
options: { baselineMarkerSize: 1 },
measure: function (text, style, box) {
if (!text) {
return zeroSize();
}
var styleKey = util.objectKey(style), cacheKey = util.hashKey(text + styleKey), cachedResult = this._cache.get(cacheKey);
if (cachedResult) {
return cachedResult;
}
var size = zeroSize();
var measureBox = box ? box : defaultMeasureBox;
var baselineMarker = this._baselineMarker().cloneNode(false);
for (var key in style) {
var value = style[key];
if (defined(value)) {
measureBox.style[key] = value;
}
}
$(measureBox).text(text);
measureBox.appendChild(baselineMarker);
doc.body.appendChild(measureBox);
if ((text + '').length) {
size.width = measureBox.offsetWidth - this.options.baselineMarkerSize;
size.height = measureBox.offsetHeight;
size.baseline = baselineMarker.offsetTop + this.options.baselineMarkerSize;
}
if (size.width > 0 && size.height > 0) {
this._cache.put(cacheKey, size);
}
measureBox.parentNode.removeChild(measureBox);
return size;
},
_baselineMarker: function () {
return $('<div class=\'k-baseline-marker\' ' + 'style=\'display: inline-block; vertical-align: baseline;' + 'width: ' + this.options.baselineMarkerSize + 'px; height: ' + this.options.baselineMarkerSize + 'px;' + 'overflow: hidden;\' />')[0];
}
});
TextMetrics.current = new TextMetrics();
function measureText(text, style, measureBox) {
return TextMetrics.current.measure(text, style, measureBox);
}
function loadFonts(fonts, callback) {
var promises = [];
if (fonts.length > 0 && document.fonts) {
try {
promises = fonts.map(function (font) {
return document.fonts.load(font);
});
} catch (e) {
kendo.logToConsole(e);
}
Promise.all(promises).then(callback, callback);
} else {
callback();
}
}
kendo.util.TextMetrics = TextMetrics;
kendo.util.LRUCache = LRUCache;
kendo.util.loadFonts = loadFonts;
kendo.util.measureText = measureText;
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('util/base64', ['util/main'], f);
}(function () {
(function () {
var kendo = window.kendo, deepExtend = kendo.deepExtend, fromCharCode = String.fromCharCode;
var KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function encodeBase64(input) {
var output = '';
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = encodeUTF8(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = (chr1 & 3) << 4 | chr2 >> 4;
enc3 = (chr2 & 15) << 2 | chr3 >> 6;
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + KEY_STR.charAt(enc1) + KEY_STR.charAt(enc2) + KEY_STR.charAt(enc3) + KEY_STR.charAt(enc4);
}
return output;
}
function encodeUTF8(input) {
var output = '';
for (var i = 0; i < input.length; i++) {
var c = input.charCodeAt(i);
if (c < 128) {
output += fromCharCode(c);
} else if (c < 2048) {
output += fromCharCode(192 | c >>> 6);
output += fromCharCode(128 | c & 63);
} else if (c < 65536) {
output += fromCharCode(224 | c >>> 12);
output += fromCharCode(128 | c >>> 6 & 63);
output += fromCharCode(128 | c & 63);
}
}
return output;
}
deepExtend(kendo.util, {
encodeBase64: encodeBase64,
encodeUTF8: encodeUTF8
});
}());
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('mixins/observers', ['kendo.core'], f);
}(function () {
(function ($) {
var math = Math, kendo = window.kendo, deepExtend = kendo.deepExtend, inArray = $.inArray;
var ObserversMixin = {
observers: function () {
this._observers = this._observers || [];
return this._observers;
},
addObserver: function (element) {
if (!this._observers) {
this._observers = [element];
} else {
this._observers.push(element);
}
return this;
},
removeObserver: function (element) {
var observers = this.observers();
var index = inArray(element, observers);
if (index != -1) {
observers.splice(index, 1);
}
return this;
},
trigger: function (methodName, event) {
var observers = this._observers;
var observer;
var idx;
if (observers && !this._suspended) {
for (idx = 0; idx < observers.length; idx++) {
observer = observers[idx];
if (observer[methodName]) {
observer[methodName](event);
}
}
}
return this;
},
optionsChange: function (e) {
this.trigger('optionsChange', e);
},
geometryChange: function (e) {
this.trigger('geometryChange', e);
},
suspend: function () {
this._suspended = (this._suspended || 0) + 1;
return this;
},
resume: function () {
this._suspended = math.max((this._suspended || 0) - 1, 0);
return this;
},
_observerField: function (field, value) {
if (this[field]) {
this[field].removeObserver(this);
}
this[field] = value;
value.addObserver(this);
}
};
deepExtend(kendo, { mixins: { ObserversMixin: ObserversMixin } });
}(window.kendo.jQuery));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/geometry', [
'util/main',
'mixins/observers'
], f);
}(function () {
(function () {
var math = Math, pow = math.pow, kendo = window.kendo, Class = kendo.Class, deepExtend = kendo.deepExtend, ObserversMixin = kendo.mixins.ObserversMixin, util = kendo.util, defined = util.defined, rad = util.rad, deg = util.deg, round = util.round;
var PI_DIV_2 = math.PI / 2, MIN_NUM = util.MIN_NUM, MAX_NUM = util.MAX_NUM;
var Point = Class.extend({
init: function (x, y) {
this.x = x || 0;
this.y = y || 0;
},
equals: function (other) {
return other && other.x === this.x && other.y === this.y;
},
clone: function () {
return new Point(this.x, this.y);
},
rotate: function (angle, origin) {
return this.transform(transform().rotate(angle, origin));
},
translate: function (x, y) {
this.x += x;
this.y += y;
this.geometryChange();
return this;
},
translateWith: function (point) {
return this.translate(point.x, point.y);
},
move: function (x, y) {
this.x = this.y = 0;
return this.translate(x, y);
},
scale: function (scaleX, scaleY) {
if (!defined(scaleY)) {
scaleY = scaleX;
}
this.x *= scaleX;
this.y *= scaleY;
this.geometryChange();
return this;
},
scaleCopy: function (scaleX, scaleY) {
return this.clone().scale(scaleX, scaleY);
},
transform: function (transformation) {
var mx = toMatrix(transformation), x = this.x, y = this.y;
this.x = mx.a * x + mx.c * y + mx.e;
this.y = mx.b * x + mx.d * y + mx.f;
this.geometryChange();
return this;
},
transformCopy: function (transformation) {
var point = this.clone();
if (transformation) {
point.transform(transformation);
}
return point;
},
distanceTo: function (point) {
var dx = this.x - point.x;
var dy = this.y - point.y;
return math.sqrt(dx * dx + dy * dy);
},
round: function (digits) {
this.x = round(this.x, digits);
this.y = round(this.y, digits);
this.geometryChange();
return this;
},
toArray: function (digits) {
var doRound = defined(digits);
var x = doRound ? round(this.x, digits) : this.x;
var y = doRound ? round(this.y, digits) : this.y;
return [
x,
y
];
}
});
defineAccessors(Point.fn, [
'x',
'y'
]);
deepExtend(Point.fn, ObserversMixin);
Point.fn.toString = function (digits, separator) {
var x = this.x, y = this.y;
if (defined(digits)) {
x = round(x, digits);
y = round(y, digits);
}
separator = separator || ' ';
return x + separator + y;
};
Point.create = function (arg0, arg1) {
if (defined(arg0)) {
if (arg0 instanceof Point) {
return arg0;
} else if (arguments.length === 1 && arg0.length === 2) {
return new Point(arg0[0], arg0[1]);
} else {
return new Point(arg0, arg1);
}
}
};
Point.min = function () {
var minX = util.MAX_NUM;
var minY = util.MAX_NUM;
for (var i = 0; i < arguments.length; i++) {
var pt = arguments[i];
minX = math.min(pt.x, minX);
minY = math.min(pt.y, minY);
}
return new Point(minX, minY);
};
Point.max = function () {
var maxX = util.MIN_NUM;
var maxY = util.MIN_NUM;
for (var i = 0; i < arguments.length; i++) {
var pt = arguments[i];
maxX = math.max(pt.x, maxX);
maxY = math.max(pt.y, maxY);
}
return new Point(maxX, maxY);
};
Point.minPoint = function () {
return new Point(MIN_NUM, MIN_NUM);
};
Point.maxPoint = function () {
return new Point(MAX_NUM, MAX_NUM);
};
Point.ZERO = new Point(0, 0);
var Size = Class.extend({
init: function (width, height) {
this.width = width || 0;
this.height = height || 0;
},
equals: function (other) {
return other && other.width === this.width && other.height === this.height;
},
clone: function () {
return new Size(this.width, this.height);
},
toArray: function (digits) {
var doRound = defined(digits);
var width = doRound ? round(this.width, digits) : this.width;
var height = doRound ? round(this.height, digits) : this.height;
return [
width,
height
];
}
});
defineAccessors(Size.fn, [
'width',
'height'
]);
deepExtend(Size.fn, ObserversMixin);
Size.create = function (arg0, arg1) {
if (defined(arg0)) {
if (arg0 instanceof Size) {
return arg0;
} else if (arguments.length === 1 && arg0.length === 2) {
return new Size(arg0[0], arg0[1]);
} else {
return new Size(arg0, arg1);
}
}
};
Size.ZERO = new Size(0, 0);
var Rect = Class.extend({
init: function (origin, size) {
this.setOrigin(origin || new Point());
this.setSize(size || new Size());
},
clone: function () {
return new Rect(this.origin.clone(), this.size.clone());
},
equals: function (other) {
return other && other.origin.equals(this.origin) && other.size.equals(this.size);
},
setOrigin: function (value) {
this._observerField('origin', Point.create(value));
this.geometryChange();
return this;
},
getOrigin: function () {
return this.origin;
},
setSize: function (value) {
this._observerField('size', Size.create(value));
this.geometryChange();
return this;
},
getSize: function () {
return this.size;
},
width: function () {
return this.size.width;
},
height: function () {
return this.size.height;
},
topLeft: function () {
return this.origin.clone();
},
bottomRight: function () {
return this.origin.clone().translate(this.width(), this.height());
},
topRight: function () {
return this.origin.clone().translate(this.width(), 0);
},
bottomLeft: function () {
return this.origin.clone().translate(0, this.height());
},
center: function () {
return this.origin.clone().translate(this.width() / 2, this.height() / 2);
},
bbox: function (matrix) {
var tl = this.topLeft().transformCopy(matrix);
var tr = this.topRight().transformCopy(matrix);
var br = this.bottomRight().transformCopy(matrix);
var bl = this.bottomLeft().transformCopy(matrix);
return Rect.fromPoints(tl, tr, br, bl);
},
transformCopy: function (m) {
return Rect.fromPoints(this.topLeft().transform(m), this.bottomRight().transform(m));
}
});
deepExtend(Rect.fn, ObserversMixin);
Rect.fromPoints = function () {
var topLeft = Point.min.apply(this, arguments);
var bottomRight = Point.max.apply(this, arguments);
var size = new Size(bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
return new Rect(topLeft, size);
};
Rect.union = function (a, b) {
return Rect.fromPoints(Point.min(a.topLeft(), b.topLeft()), Point.max(a.bottomRight(), b.bottomRight()));
};
Rect.intersect = function (a, b) {
a = {
left: a.topLeft().x,
top: a.topLeft().y,
right: a.bottomRight().x,
bottom: a.bottomRight().y
};
b = {
left: b.topLeft().x,
top: b.topLeft().y,
right: b.bottomRight().x,
bottom: b.bottomRight().y
};
if (a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom) {
return Rect.fromPoints(new Point(math.max(a.left, b.left), math.max(a.top, b.top)), new Point(math.min(a.right, b.right), math.min(a.bottom, b.bottom)));
}
};
var Circle = Class.extend({
init: function (center, radius) {
this.setCenter(center || new Point());
this.setRadius(radius || 0);
},
setCenter: function (value) {
this._observerField('center', Point.create(value));
this.geometryChange();
return this;
},
getCenter: function () {
return this.center;
},
equals: function (other) {
return other && other.center.equals(this.center) && other.radius === this.radius;
},
clone: function () {
return new Circle(this.center.clone(), this.radius);
},
pointAt: function (angle) {
return this._pointAt(rad(angle));
},
bbox: function (matrix) {
var minPoint = Point.maxPoint();
var maxPoint = Point.minPoint();
var extremeAngles = ellipseExtremeAngles(this.center, this.radius, this.radius, matrix);
for (var i = 0; i < 4; i++) {
var currentPointX = this._pointAt(extremeAngles.x + i * PI_DIV_2).transformCopy(matrix);
var currentPointY = this._pointAt(extremeAngles.y + i * PI_DIV_2).transformCopy(matrix);
var currentPoint = new Point(currentPointX.x, currentPointY.y);
minPoint = Point.min(minPoint, currentPoint);
maxPoint = Point.max(maxPoint, currentPoint);
}
return Rect.fromPoints(minPoint, maxPoint);
},
_pointAt: function (angle) {
var c = this.center;
var r = this.radius;
return new Point(c.x - r * math.cos(angle), c.y - r * math.sin(angle));
}
});
defineAccessors(Circle.fn, ['radius']);
deepExtend(Circle.fn, ObserversMixin);
var Arc = Class.extend({
init: function (center, options) {
this.setCenter(center || new Point());
options = options || {};
this.radiusX = options.radiusX;
this.radiusY = options.radiusY || options.radiusX;
this.startAngle = options.startAngle;
this.endAngle = options.endAngle;
this.anticlockwise = options.anticlockwise || false;
},
clone: function () {
return new Arc(this.center, {
radiusX: this.radiusX,
radiusY: this.radiusY,
startAngle: this.startAngle,
endAngle: this.endAngle,
anticlockwise: this.anticlockwise
});
},
setCenter: function (value) {
this._observerField('center', Point.create(value));
this.geometryChange();
return this;
},
getCenter: function () {
return this.center;
},
MAX_INTERVAL: 45,
pointAt: function (angle) {
var center = this.center;
var radian = rad(angle);
return new Point(center.x + this.radiusX * math.cos(radian), center.y + this.radiusY * math.sin(radian));
},
curvePoints: function () {
var startAngle = this.startAngle;
var dir = this.anticlockwise ? -1 : 1;
var curvePoints = [this.pointAt(startAngle)];
var currentAngle = startAngle;
var interval = this._arcInterval();
var intervalAngle = interval.endAngle - interval.startAngle;
var subIntervalsCount = math.ceil(intervalAngle / this.MAX_INTERVAL);
var subIntervalAngle = intervalAngle / subIntervalsCount;
for (var i = 1; i <= subIntervalsCount; i++) {
var nextAngle = currentAngle + dir * subIntervalAngle;
var points = this._intervalCurvePoints(currentAngle, nextAngle);
curvePoints.push(points.cp1, points.cp2, points.p2);
currentAngle = nextAngle;
}
return curvePoints;
},
bbox: function (matrix) {
var arc = this;
var interval = arc._arcInterval();
var startAngle = interval.startAngle;
var endAngle = interval.endAngle;
var extremeAngles = ellipseExtremeAngles(this.center, this.radiusX, this.radiusY, matrix);
var extremeX = deg(extremeAngles.x);
var extremeY = deg(extremeAngles.y);
var currentPoint = arc.pointAt(startAngle).transformCopy(matrix);
var endPoint = arc.pointAt(endAngle).transformCopy(matrix);
var minPoint = Point.min(currentPoint, endPoint);
var maxPoint = Point.max(currentPoint, endPoint);
var currentAngleX = bboxStartAngle(extremeX, startAngle);
var currentAngleY = bboxStartAngle(extremeY, startAngle);
while (currentAngleX < endAngle || currentAngleY < endAngle) {
var currentPointX;
if (currentAngleX < endAngle) {
currentPointX = arc.pointAt(currentAngleX).transformCopy(matrix);
currentAngleX += 90;
}
var currentPointY;
if (currentAngleY < endAngle) {
currentPointY = arc.pointAt(currentAngleY).transformCopy(matrix);
currentAngleY += 90;
}
currentPoint = new Point(currentPointX.x, currentPointY.y);
minPoint = Point.min(minPoint, currentPoint);
maxPoint = Point.max(maxPoint, currentPoint);
}
return Rect.fromPoints(minPoint, maxPoint);
},
_arcInterval: function () {
var startAngle = this.startAngle;
var endAngle = this.endAngle;
var anticlockwise = this.anticlockwise;
if (anticlockwise) {
var oldStart = startAngle;
startAngle = endAngle;
endAngle = oldStart;
}
if (startAngle > endAngle || anticlockwise && startAngle === endAngle) {
endAngle += 360;
}
return {
startAngle: startAngle,
endAngle: endAngle
};
},
_intervalCurvePoints: function (startAngle, endAngle) {
var arc = this;
var p1 = arc.pointAt(startAngle);
var p2 = arc.pointAt(endAngle);
var p1Derivative = arc._derivativeAt(startAngle);
var p2Derivative = arc._derivativeAt(endAngle);
var t = (rad(endAngle) - rad(startAngle)) / 3;
var cp1 = new Point(p1.x + t * p1Derivative.x, p1.y + t * p1Derivative.y);
var cp2 = new Point(p2.x - t * p2Derivative.x, p2.y - t * p2Derivative.y);
return {
p1: p1,
cp1: cp1,
cp2: cp2,
p2: p2
};
},
_derivativeAt: function (angle) {
var arc = this;
var radian = rad(angle);
return new Point(-arc.radiusX * math.sin(radian), arc.radiusY * math.cos(radian));
}
});
defineAccessors(Arc.fn, [
'radiusX',
'radiusY',
'startAngle',
'endAngle',
'anticlockwise'
]);
deepExtend(Arc.fn, ObserversMixin);
Arc.fromPoints = function (start, end, rx, ry, largeArc, swipe) {
var arcParameters = normalizeArcParameters(start.x, start.y, end.x, end.y, rx, ry, largeArc, swipe);
return new Arc(arcParameters.center, {
startAngle: arcParameters.startAngle,
endAngle: arcParameters.endAngle,
radiusX: rx,
radiusY: ry,
anticlockwise: swipe === 0
});
};
var Matrix = Class.extend({
init: function (a, b, c, d, e, f) {
this.a = a || 0;
this.b = b || 0;
this.c = c || 0;
this.d = d || 0;
this.e = e || 0;
this.f = f || 0;
},
multiplyCopy: function (m) {
return new Matrix(this.a * m.a + this.c * m.b, this.b * m.a + this.d * m.b, this.a * m.c + this.c * m.d, this.b * m.c + this.d * m.d, this.a * m.e + this.c * m.f + this.e, this.b * m.e + this.d * m.f + this.f);
},
invert: function () {
var a = this.a, b = this.b;
var d = this.c, e = this.d;
var g = this.e, h = this.f;
var det = a * e - b * d;
if (det === 0) {
return null;
}
return new Matrix(e / det, -b / det, -d / det, a / det, (d * h - e * g) / det, (b * g - a * h) / det);
},
clone: function () {
return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
},
equals: function (other) {
if (!other) {
return false;
}
return this.a === other.a && this.b === other.b && this.c === other.c && this.d === other.d && this.e === other.e && this.f === other.f;
},
round: function (precision) {
this.a = round(this.a, precision);
this.b = round(this.b, precision);
this.c = round(this.c, precision);
this.d = round(this.d, precision);
this.e = round(this.e, precision);
this.f = round(this.f, precision);
return this;
},
toArray: function (precision) {
var arr = [
this.a,
this.b,
this.c,
this.d,
this.e,
this.f
];
if (defined(precision)) {
for (var i = 0; i < arr.length; i++) {
arr[i] = round(arr[i], precision);
}
}
return arr;
}
});
Matrix.fn.toString = function (precision, separator) {
return this.toArray(precision).join(separator || ',');
};
Matrix.translate = function (x, y) {
return new Matrix(1, 0, 0, 1, x, y);
};
Matrix.unit = function () {
return new Matrix(1, 0, 0, 1, 0, 0);
};
Matrix.rotate = function (angle, x, y) {
var m = new Matrix();
m.a = math.cos(rad(angle));
m.b = math.sin(rad(angle));
m.c = -m.b;
m.d = m.a;
m.e = x - x * m.a + y * m.b || 0;
m.f = y - y * m.a - x * m.b || 0;
return m;
};
Matrix.scale = function (scaleX, scaleY) {
return new Matrix(scaleX, 0, 0, scaleY, 0, 0);
};
Matrix.IDENTITY = Matrix.unit();
var Transformation = Class.extend({
init: function (matrix) {
this._matrix = matrix || Matrix.unit();
},
clone: function () {
return new Transformation(this._matrix.clone());
},
equals: function (other) {
return other && other._matrix.equals(this._matrix);
},
_optionsChange: function () {
this.optionsChange({
field: 'transform',
value: this
});
},
translate: function (x, y) {
this._matrix = this._matrix.multiplyCopy(Matrix.translate(x, y));
this._optionsChange();
return this;
},
scale: function (scaleX, scaleY, origin) {
if (!defined(scaleY)) {
scaleY = scaleX;
}
if (origin) {
origin = Point.create(origin);
this._matrix = this._matrix.multiplyCopy(Matrix.translate(origin.x, origin.y));
}
this._matrix = this._matrix.multiplyCopy(Matrix.scale(scaleX, scaleY));
if (origin) {
this._matrix = this._matrix.multiplyCopy(Matrix.translate(-origin.x, -origin.y));
}
this._optionsChange();
return this;
},
rotate: function (angle, origin) {
origin = Point.create(origin) || Point.ZERO;
this._matrix = this._matrix.multiplyCopy(Matrix.rotate(angle, origin.x, origin.y));
this._optionsChange();
return this;
},
multiply: function (transformation) {
var matrix = toMatrix(transformation);
this._matrix = this._matrix.multiplyCopy(matrix);
this._optionsChange();
return this;
},
matrix: function (matrix) {
if (matrix) {
this._matrix = matrix;
this._optionsChange();
return this;
} else {
return this._matrix;
}
}
});
deepExtend(Transformation.fn, ObserversMixin);
function transform(matrix) {
if (matrix === null) {
return null;
}
if (matrix instanceof Transformation) {
return matrix;
}
return new Transformation(matrix);
}
function toMatrix(value) {
if (value && kendo.isFunction(value.matrix)) {
return value.matrix();
}
return value;
}
function ellipseExtremeAngles(center, rx, ry, matrix) {
var extremeX = 0, extremeY = 0;
if (matrix) {
extremeX = math.atan2(matrix.c * ry, matrix.a * rx);
if (matrix.b !== 0) {
extremeY = math.atan2(matrix.d * ry, matrix.b * rx);
}
}
return {
x: extremeX,
y: extremeY
};
}
function bboxStartAngle(angle, start) {
while (angle < start) {
angle += 90;
}
return angle;
}
function defineAccessors(fn, fields) {
for (var i = 0; i < fields.length; i++) {
var name = fields[i];
var capitalized = name.charAt(0).toUpperCase() + name.substring(1, name.length);
fn['set' + capitalized] = setAccessor(name);
fn['get' + capitalized] = getAccessor(name);
}
}
function setAccessor(field) {
return function (value) {
if (this[field] !== value) {
this[field] = value;
this.geometryChange();
}
return this;
};
}
function getAccessor(field) {
return function () {
return this[field];
};
}
function elipseAngle(start, end, swipe) {
if (start > end) {
end += 360;
}
var alpha = math.abs(end - start);
if (!swipe) {
alpha = 360 - alpha;
}
return alpha;
}
function calculateAngle(cx, cy, rx, ry, x, y) {
var cos = round((x - cx) / rx, 3);
var sin = round((y - cy) / ry, 3);
return round(deg(math.atan2(sin, cos)));
}
function normalizeArcParameters(x1, y1, x2, y2, rx, ry, largeArc, swipe) {
var cx, cy;
var cx1, cy1;
var a, b, c, sqrt;
if (y1 !== y2) {
var x21 = x2 - x1;
var y21 = y2 - y1;
var rx2 = pow(rx, 2), ry2 = pow(ry, 2);
var k = (ry2 * x21 * (x1 + x2) + rx2 * y21 * (y1 + y2)) / (2 * rx2 * y21);
var yk2 = k - y2;
var l = -(x21 * ry2) / (rx2 * y21);
a = 1 / rx2 + pow(l, 2) / ry2;
b = 2 * (l * yk2 / ry2 - x2 / rx2);
c = pow(x2, 2) / rx2 + pow(yk2, 2) / ry2 - 1;
sqrt = math.sqrt(pow(b, 2) - 4 * a * c);
cx = (-b - sqrt) / (2 * a);
cy = k + l * cx;
cx1 = (-b + sqrt) / (2 * a);
cy1 = k + l * cx1;
} else if (x1 !== x2) {
b = -2 * y2;
c = pow((x2 - x1) * ry / (2 * rx), 2) + pow(y2, 2) - pow(ry, 2);
sqrt = math.sqrt(pow(b, 2) - 4 * c);
cx = cx1 = (x1 + x2) / 2;
cy = (-b - sqrt) / 2;
cy1 = (-b + sqrt) / 2;
} else {
return false;
}
var start = calculateAngle(cx, cy, rx, ry, x1, y1);
var end = calculateAngle(cx, cy, rx, ry, x2, y2);
var alpha = elipseAngle(start, end, swipe);
if (largeArc && alpha <= 180 || !largeArc && alpha > 180) {
cx = cx1;
cy = cy1;
start = calculateAngle(cx, cy, rx, ry, x1, y1);
end = calculateAngle(cx, cy, rx, ry, x2, y2);
}
return {
center: new Point(cx, cy),
startAngle: start,
endAngle: end
};
}
deepExtend(kendo, {
geometry: {
Arc: Arc,
Circle: Circle,
Matrix: Matrix,
Point: Point,
Rect: Rect,
Size: Size,
Transformation: Transformation,
transform: transform,
toMatrix: toMatrix
}
});
kendo.dataviz.geometry = kendo.geometry;
}());
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/core', ['drawing/geometry'], f);
}(function () {
(function ($) {
var noop = $.noop, toString = Object.prototype.toString, kendo = window.kendo, Class = kendo.Class, Widget = kendo.ui.Widget, deepExtend = kendo.deepExtend, util = kendo.util, defined = util.defined;
var Surface = Widget.extend({
init: function (element, options) {
this.options = deepExtend({}, this.options, options);
Widget.fn.init.call(this, element, this.options);
this._click = this._handler('click');
this._mouseenter = this._handler('mouseenter');
this._mouseleave = this._handler('mouseleave');
this._visual = new kendo.drawing.Group();
if (this.options.width) {
this.element.css('width', this.options.width);
}
if (this.options.height) {
this.element.css('height', this.options.height);
}
},
options: { name: 'Surface' },
events: [
'click',
'mouseenter',
'mouseleave',
'resize'
],
draw: function (element) {
this._visual.children.push(element);
},
clear: function () {
this._visual.children = [];
},
destroy: function () {
this._visual = null;
Widget.fn.destroy.call(this);
},
exportVisual: function () {
return this._visual;
},
getSize: function () {
return {
width: this.element.width(),
height: this.element.height()
};
},
setSize: function (size) {
this.element.css({
width: size.width,
height: size.height
});
this._size = size;
this._resize();
},
eventTarget: function (e) {
var domNode = $(e.touch ? e.touch.initialTouch : e.target);
var node;
while (!node && domNode.length > 0) {
node = domNode[0]._kendoNode;
if (domNode.is(this.element) || domNode.length === 0) {
break;
}
domNode = domNode.parent();
}
if (node) {
return node.srcElement;
}
},
_resize: noop,
_handler: function (event) {
var surface = this;
return function (e) {
var node = surface.eventTarget(e);
if (node) {
surface.trigger(event, {
element: node,
originalEvent: e
});
}
};
}
});
kendo.ui.plugin(Surface);
Surface.create = function (element, options) {
return SurfaceFactory.current.create(element, options);
};
var BaseNode = Class.extend({
init: function (srcElement) {
this.childNodes = [];
this.parent = null;
if (srcElement) {
this.srcElement = srcElement;
this.observe();
}
},
destroy: function () {
if (this.srcElement) {
this.srcElement.removeObserver(this);
}
var children = this.childNodes;
for (var i = 0; i < children.length; i++) {
this.childNodes[i].destroy();
}
this.parent = null;
},
load: noop,
observe: function () {
if (this.srcElement) {
this.srcElement.addObserver(this);
}
},
append: function (node) {
this.childNodes.push(node);
node.parent = this;
},
insertAt: function (node, pos) {
this.childNodes.splice(pos, 0, node);
node.parent = this;
},
remove: function (index, count) {
var end = index + count;
for (var i = index; i < end; i++) {
this.childNodes[i].removeSelf();
}
this.childNodes.splice(index, count);
},
removeSelf: function () {
this.clear();
this.destroy();
},
clear: function () {
this.remove(0, this.childNodes.length);
},
invalidate: function () {
if (this.parent) {
this.parent.invalidate();
}
},
geometryChange: function () {
this.invalidate();
},
optionsChange: function () {
this.invalidate();
},
childrenChange: function (e) {
if (e.action === 'add') {
this.load(e.items, e.index);
} else if (e.action === 'remove') {
this.remove(e.index, e.items.length);
}
this.invalidate();
}
});
var OptionsStore = Class.extend({
init: function (options, prefix) {
var field, member;
this.prefix = prefix || '';
for (field in options) {
member = options[field];
member = this._wrap(member, field);
this[field] = member;
}
},
get: function (field) {
return kendo.getter(field, true)(this);
},
set: function (field, value) {
var current = kendo.getter(field, true)(this);
if (current !== value) {
var composite = this._set(field, this._wrap(value, field));
if (!composite) {
this.optionsChange({
field: this.prefix + field,
value: value
});
}
}
},
_set: function (field, value) {
var composite = field.indexOf('.') >= 0;
if (composite) {
var parts = field.split('.'), path = '', obj;
while (parts.length > 1) {
path += parts.shift();
obj = kendo.getter(path, true)(this);
if (!obj) {
obj = new OptionsStore({}, path + '.');
obj.addObserver(this);
this[path] = obj;
}
if (obj instanceof OptionsStore) {
obj.set(parts.join('.'), value);
return composite;
}
path += '.';
}
}
this._clear(field);
kendo.setter(field)(this, value);
return composite;
},
_clear: function (field) {
var current = kendo.getter(field, true)(this);
if (current && current.removeObserver) {
current.removeObserver(this);
}
},
_wrap: function (object, field) {
var type = toString.call(object);
if (object !== null && defined(object) && type === '[object Object]') {
if (!(object instanceof OptionsStore) && !(object instanceof Class)) {
object = new OptionsStore(object, this.prefix + field + '.');
}
object.addObserver(this);
}
return object;
}
});
deepExtend(OptionsStore.fn, kendo.mixins.ObserversMixin);
var SurfaceFactory = function () {
this._items = [];
};
SurfaceFactory.prototype = {
register: function (name, type, order) {
var items = this._items, first = items[0], entry = {
name: name,
type: type,
order: order
};
if (!first || order < first.order) {
items.unshift(entry);
} else {
items.push(entry);
}
},
create: function (element, options) {
var items = this._items, match = items[0];
if (options && options.type) {
var preferred = options.type.toLowerCase();
for (var i = 0; i < items.length; i++) {
if (items[i].name === preferred) {
match = items[i];
break;
}
}
}
if (match) {
return new match.type(element, options);
}
kendo.logToConsole('Warning: Unable to create Kendo UI Drawing Surface. Possible causes:\n' + '- The browser does not support SVG, VML and Canvas. User agent: ' + navigator.userAgent + '\n' + '- The Kendo UI scripts are not fully loaded');
}
};
SurfaceFactory.current = new SurfaceFactory();
deepExtend(kendo, {
drawing: {
DASH_ARRAYS: {
dot: [
1.5,
3.5
],
dash: [
4,
3.5
],
longdash: [
8,
3.5
],
dashdot: [
3.5,
3.5,
1.5,
3.5
],
longdashdot: [
8,
3.5,
1.5,
3.5
],
longdashdotdot: [
8,
3.5,
1.5,
3.5,
1.5,
3.5
]
},
Color: kendo.Color,
BaseNode: BaseNode,
OptionsStore: OptionsStore,
Surface: Surface,
SurfaceFactory: SurfaceFactory
}
});
kendo.dataviz.drawing = kendo.drawing;
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/mixins', ['drawing/core'], f);
}(function () {
(function () {
var kendo = window.kendo, deepExtend = kendo.deepExtend, defined = kendo.util.defined;
var GRADIENT = 'gradient';
var Paintable = {
extend: function (proto) {
proto.fill = this.fill;
proto.stroke = this.stroke;
},
fill: function (color, opacity) {
var options = this.options;
if (defined(color)) {
if (color && color.nodeType != GRADIENT) {
var newFill = { color: color };
if (defined(opacity)) {
newFill.opacity = opacity;
}
options.set('fill', newFill);
} else {
options.set('fill', color);
}
return this;
} else {
return options.get('fill');
}
},
stroke: function (color, width, opacity) {
if (defined(color)) {
this.options.set('stroke.color', color);
if (defined(width)) {
this.options.set('stroke.width', width);
}
if (defined(opacity)) {
this.options.set('stroke.opacity', opacity);
}
return this;
} else {
return this.options.get('stroke');
}
}
};
var Traversable = {
extend: function (proto, childrenField) {
proto.traverse = function (callback) {
var children = this[childrenField];
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.traverse) {
child.traverse(callback);
} else {
callback(child);
}
}
return this;
};
}
};
deepExtend(kendo.drawing, {
mixins: {
Paintable: Paintable,
Traversable: Traversable
}
});
}());
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/shapes', [
'drawing/core',
'drawing/mixins',
'util/text-metrics',
'mixins/observers'
], f);
}(function () {
(function ($) {
var kendo = window.kendo, Class = kendo.Class, deepExtend = kendo.deepExtend, g = kendo.geometry, Point = g.Point, Size = g.Size, Matrix = g.Matrix, toMatrix = g.toMatrix, drawing = kendo.drawing, OptionsStore = drawing.OptionsStore, math = Math, pow = math.pow, util = kendo.util, append = util.append, arrayLimits = util.arrayLimits, defined = util.defined, last = util.last, valueOrDefault = util.valueOrDefault, ObserversMixin = kendo.mixins.ObserversMixin, inArray = $.inArray, push = [].push, pop = [].pop, splice = [].splice, shift = [].shift, slice = [].slice, unshift = [].unshift, defId = 1, START = 'start', END = 'end', HORIZONTAL = 'horizontal';
var Element = Class.extend({
nodeType: 'Element',
init: function (options) {
this._initOptions(options);
},
_initOptions: function (options) {
options = options || {};
var transform = options.transform;
var clip = options.clip;
if (transform) {
options.transform = g.transform(transform);
}
if (clip && !clip.id) {
clip.id = generateDefinitionId();
}
this.options = new OptionsStore(options);
this.options.addObserver(this);
},
transform: function (transform) {
if (defined(transform)) {
this.options.set('transform', g.transform(transform));
} else {
return this.options.get('transform');
}
},
parentTransform: function () {
var element = this, transformation, parentMatrix;
while (element.parent) {
element = element.parent;
transformation = element.transform();
if (transformation) {
parentMatrix = transformation.matrix().multiplyCopy(parentMatrix || Matrix.unit());
}
}
if (parentMatrix) {
return g.transform(parentMatrix);
}
},
currentTransform: function (parentTransform) {
var elementTransform = this.transform(), elementMatrix = toMatrix(elementTransform), parentMatrix, combinedMatrix;
if (!defined(parentTransform)) {
parentTransform = this.parentTransform();
}
parentMatrix = toMatrix(parentTransform);
if (elementMatrix && parentMatrix) {
combinedMatrix = parentMatrix.multiplyCopy(elementMatrix);
} else {
combinedMatrix = elementMatrix || parentMatrix;
}
if (combinedMatrix) {
return g.transform(combinedMatrix);
}
},
visible: function (visible) {
if (defined(visible)) {
this.options.set('visible', visible);
return this;
} else {
return this.options.get('visible') !== false;
}
},
clip: function (clip) {
var options = this.options;
if (defined(clip)) {
if (clip && !clip.id) {
clip.id = generateDefinitionId();
}
options.set('clip', clip);
return this;
} else {
return options.get('clip');
}
},
opacity: function (value) {
if (defined(value)) {
this.options.set('opacity', value);
return this;
} else {
return valueOrDefault(this.options.get('opacity'), 1);
}
},
clippedBBox: function (transformation) {
var box = this._clippedBBox(transformation);
if (box) {
var clip = this.clip();
return clip ? g.Rect.intersect(box, clip.bbox(transformation)) : box;
}
},
_clippedBBox: function (transformation) {
return this.bbox(transformation);
}
});
deepExtend(Element.fn, ObserversMixin);
var ElementsArray = Class.extend({
init: function (array) {
array = array || [];
this.length = 0;
this._splice(0, array.length, array);
},
elements: function (elements) {
if (elements) {
this._splice(0, this.length, elements);
this._change();
return this;
} else {
return this.slice(0);
}
},
push: function () {
var elements = arguments;
var result = push.apply(this, elements);
this._add(elements);
return result;
},
slice: slice,
pop: function () {
var length = this.length;
var result = pop.apply(this);
if (length) {
this._remove([result]);
}
return result;
},
splice: function (index, howMany) {
var elements = slice.call(arguments, 2);
var result = this._splice(index, howMany, elements);
this._change();
return result;
},
shift: function () {
var length = this.length;
var result = shift.apply(this);
if (length) {
this._remove([result]);
}
return result;
},
unshift: function () {
var elements = arguments;
var result = unshift.apply(this, elements);
this._add(elements);
return result;
},
indexOf: function (element) {
var that = this;
var idx;
var length;
for (idx = 0, length = that.length; idx < length; idx++) {
if (that[idx] === element) {
return idx;
}
}
return -1;
},
_splice: function (index, howMany, elements) {
var result = splice.apply(this, [
index,
howMany
].concat(elements));
this._clearObserver(result);
this._setObserver(elements);
return result;
},
_add: function (elements) {
this._setObserver(elements);
this._change();
},
_remove: function (elements) {
this._clearObserver(elements);
this._change();
},
_setObserver: function (elements) {
for (var idx = 0; idx < elements.length; idx++) {
elements[idx].addObserver(this);
}
},
_clearObserver: function (elements) {
for (var idx = 0; idx < elements.length; idx++) {
elements[idx].removeObserver(this);
}
},
_change: function () {
}
});
deepExtend(ElementsArray.fn, ObserversMixin);
var Group = Element.extend({
nodeType: 'Group',
init: function (options) {
Element.fn.init.call(this, options);
this.children = [];
},
childrenChange: function (action, items, index) {
this.trigger('childrenChange', {
action: action,
items: items,
index: index
});
},
append: function () {
append(this.children, arguments);
this._reparent(arguments, this);
this.childrenChange('add', arguments);
return this;
},
insert: function (index, element) {
this.children.splice(index, 0, element);
element.parent = this;
this.childrenChange('add', [element], index);
return this;
},
insertAt: function (element, index) {
return this.insert(index, element);
},
remove: function (element) {
var index = inArray(element, this.children);
if (index >= 0) {
this.children.splice(index, 1);
element.parent = null;
this.childrenChange('remove', [element], index);
}
return this;
},
removeAt: function (index) {
if (0 <= index && index < this.children.length) {
var element = this.children[index];
this.children.splice(index, 1);
element.parent = null;
this.childrenChange('remove', [element], index);
}
return this;
},
clear: function () {
var items = this.children;
this.children = [];
this._reparent(items, null);
this.childrenChange('remove', items, 0);
return this;
},
bbox: function (transformation) {
return elementsBoundingBox(this.children, true, this.currentTransform(transformation));
},
rawBBox: function () {
return elementsBoundingBox(this.children, false);
},
_clippedBBox: function (transformation) {
return elementsClippedBoundingBox(this.children, this.currentTransform(transformation));
},
currentTransform: function (transformation) {
return Element.fn.currentTransform.call(this, transformation) || null;
},
_reparent: function (elements, newParent) {
for (var i = 0; i < elements.length; i++) {
var child = elements[i];
var parent = child.parent;
if (parent && parent != this && parent.remove) {
parent.remove(child);
}
child.parent = newParent;
}
}
});
drawing.mixins.Traversable.extend(Group.fn, 'children');
var Text = Element.extend({
nodeType: 'Text',
init: function (content, position, options) {
Element.fn.init.call(this, options);
this.content(content);
this.position(position || new g.Point());
if (!this.options.font) {
this.options.font = '12px sans-serif';
}
if (!defined(this.options.fill)) {
this.fill('#000');
}
},
content: function (value) {
if (defined(value)) {
this.options.set('content', value);
return this;
} else {
return this.options.get('content');
}
},
measure: function () {
var metrics = util.measureText(this.content(), { font: this.options.get('font') });
return metrics;
},
rect: function () {
var size = this.measure();
var pos = this.position().clone();
return new g.Rect(pos, [
size.width,
size.height
]);
},
bbox: function (transformation) {
var combinedMatrix = toMatrix(this.currentTransform(transformation));
return this.rect().bbox(combinedMatrix);
},
rawBBox: function () {
return this.rect().bbox();
}
});
drawing.mixins.Paintable.extend(Text.fn);
definePointAccessors(Text.fn, ['position']);
var Circle = Element.extend({
nodeType: 'Circle',
init: function (geometry, options) {
Element.fn.init.call(this, options);
this.geometry(geometry || new g.Circle());
if (!defined(this.options.stroke)) {
this.stroke('#000');
}
},
bbox: function (transformation) {
var combinedMatrix = toMatrix(this.currentTransform(transformation));
var rect = this._geometry.bbox(combinedMatrix);
var strokeWidth = this.options.get('stroke.width');
if (strokeWidth) {
expandRect(rect, strokeWidth / 2);
}
return rect;
},
rawBBox: function () {
return this._geometry.bbox();
}
});
drawing.mixins.Paintable.extend(Circle.fn);
defineGeometryAccessors(Circle.fn, ['geometry']);
var Arc = Element.extend({
nodeType: 'Arc',
init: function (geometry, options) {
Element.fn.init.call(this, options);
this.geometry(geometry || new g.Arc());
if (!defined(this.options.stroke)) {
this.stroke('#000');
}
},
bbox: function (transformation) {
var combinedMatrix = toMatrix(this.currentTransform(transformation));
var rect = this.geometry().bbox(combinedMatrix);
var strokeWidth = this.options.get('stroke.width');
if (strokeWidth) {
expandRect(rect, strokeWidth / 2);
}
return rect;
},
rawBBox: function () {
return this.geometry().bbox();
},
toPath: function () {
var path = new Path();
var curvePoints = this.geometry().curvePoints();
if (curvePoints.length > 0) {
path.moveTo(curvePoints[0].x, curvePoints[0].y);
for (var i = 1; i < curvePoints.length; i += 3) {
path.curveTo(curvePoints[i], curvePoints[i + 1], curvePoints[i + 2]);
}
}
return path;
}
});
drawing.mixins.Paintable.extend(Arc.fn);
defineGeometryAccessors(Arc.fn, ['geometry']);
var GeometryElementsArray = ElementsArray.extend({
_change: function () {
this.geometryChange();
}
});
var Segment = Class.extend({
init: function (anchor, controlIn, controlOut) {
this.anchor(anchor || new Point());
this.controlIn(controlIn);
this.controlOut(controlOut);
},
bboxTo: function (toSegment, matrix) {
var rect;
var segmentAnchor = this.anchor().transformCopy(matrix);
var toSegmentAnchor = toSegment.anchor().transformCopy(matrix);
if (this.controlOut() && toSegment.controlIn()) {
rect = this._curveBoundingBox(segmentAnchor, this.controlOut().transformCopy(matrix), toSegment.controlIn().transformCopy(matrix), toSegmentAnchor);
} else {
rect = this._lineBoundingBox(segmentAnchor, toSegmentAnchor);
}
return rect;
},
_lineBoundingBox: function (p1, p2) {
return g.Rect.fromPoints(p1, p2);
},
_curveBoundingBox: function (p1, cp1, cp2, p2) {
var points = [
p1,
cp1,
cp2,
p2
], extremesX = this._curveExtremesFor(points, 'x'), extremesY = this._curveExtremesFor(points, 'y'), xLimits = arrayLimits([
extremesX.min,
extremesX.max,
p1.x,
p2.x
]), yLimits = arrayLimits([
extremesY.min,
extremesY.max,
p1.y,
p2.y
]);
return g.Rect.fromPoints(new Point(xLimits.min, yLimits.min), new Point(xLimits.max, yLimits.max));
},
_curveExtremesFor: function (points, field) {
var extremes = this._curveExtremes(points[0][field], points[1][field], points[2][field], points[3][field]);
return {
min: this._calculateCurveAt(extremes.min, field, points),
max: this._calculateCurveAt(extremes.max, field, points)
};
},
_calculateCurveAt: function (t, field, points) {
var t1 = 1 - t;
return pow(t1, 3) * points[0][field] + 3 * pow(t1, 2) * t * points[1][field] + 3 * pow(t, 2) * t1 * points[2][field] + pow(t, 3) * points[3][field];
},
_curveExtremes: function (x1, x2, x3, x4) {
var a = x1 - 3 * x2 + 3 * x3 - x4;
var b = -2 * (x1 - 2 * x2 + x3);
var c = x1 - x2;
var sqrt = math.sqrt(b * b - 4 * a * c);
var t1 = 0;
var t2 = 1;
if (a === 0) {
if (b !== 0) {
t1 = t2 = -c / b;
}
} else if (!isNaN(sqrt)) {
t1 = (-b + sqrt) / (2 * a);
t2 = (-b - sqrt) / (2 * a);
}
var min = math.max(math.min(t1, t2), 0);
if (min < 0 || min > 1) {
min = 0;
}
var max = math.min(math.max(t1, t2), 1);
if (max > 1 || max < 0) {
max = 1;
}
return {
min: min,
max: max
};
}
});
definePointAccessors(Segment.fn, [
'anchor',
'controlIn',
'controlOut'
]);
deepExtend(Segment.fn, ObserversMixin);
var Path = Element.extend({
nodeType: 'Path',
init: function (options) {
Element.fn.init.call(this, options);
this.segments = new GeometryElementsArray();
this.segments.addObserver(this);
if (!defined(this.options.stroke)) {
this.stroke('#000');
if (!defined(this.options.stroke.lineJoin)) {
this.options.set('stroke.lineJoin', 'miter');
}
}
},
moveTo: function (x, y) {
this.suspend();
this.segments.elements([]);
this.resume();
this.lineTo(x, y);
return this;
},
lineTo: function (x, y) {
var point = defined(y) ? new Point(x, y) : x, segment = new Segment(point);
this.segments.push(segment);
return this;
},
curveTo: function (controlOut, controlIn, point) {
if (this.segments.length > 0) {
var lastSegment = last(this.segments);
var segment = new Segment(point, controlIn);
this.suspend();
lastSegment.controlOut(controlOut);
this.resume();
this.segments.push(segment);
}
return this;
},
arc: function (startAngle, endAngle, radiusX, radiusY, anticlockwise) {
if (this.segments.length > 0) {
var lastSegment = last(this.segments);
var anchor = lastSegment.anchor();
var start = util.rad(startAngle);
var center = new Point(anchor.x - radiusX * math.cos(start), anchor.y - radiusY * math.sin(start));
var arc = new g.Arc(center, {
startAngle: startAngle,
endAngle: endAngle,
radiusX: radiusX,
radiusY: radiusY,
anticlockwise: anticlockwise
});
this._addArcSegments(arc);
}
return this;
},
arcTo: function (end, rx, ry, largeArc, swipe) {
if (this.segments.length > 0) {
var lastSegment = last(this.segments);
var anchor = lastSegment.anchor();
var arc = g.Arc.fromPoints(anchor, end, rx, ry, largeArc, swipe);
this._addArcSegments(arc);
}
return this;
},
_addArcSegments: function (arc) {
this.suspend();
var curvePoints = arc.curvePoints();
for (var i = 1; i < curvePoints.length; i += 3) {
this.curveTo(curvePoints[i], curvePoints[i + 1], curvePoints[i + 2]);
}
this.resume();
this.geometryChange();
},
close: function () {
this.options.closed = true;
this.geometryChange();
return this;
},
bbox: function (transformation) {
var combinedMatrix = toMatrix(this.currentTransform(transformation));
var boundingBox = this._bbox(combinedMatrix);
var strokeWidth = this.options.get('stroke.width');
if (strokeWidth) {
expandRect(boundingBox, strokeWidth / 2);
}
return boundingBox;
},
rawBBox: function () {
return this._bbox();
},
_bbox: function (matrix) {
var segments = this.segments;
var length = segments.length;
var boundingBox;
if (length === 1) {
var anchor = segments[0].anchor().transformCopy(matrix);
boundingBox = new g.Rect(anchor, Size.ZERO);
} else if (length > 0) {
for (var i = 1; i < length; i++) {
var segmentBox = segments[i - 1].bboxTo(segments[i], matrix);
if (boundingBox) {
boundingBox = g.Rect.union(boundingBox, segmentBox);
} else {
boundingBox = segmentBox;
}
}
}
return boundingBox;
}
});
drawing.mixins.Paintable.extend(Path.fn);
Path.fromRect = function (rect, options) {
return new Path(options).moveTo(rect.topLeft()).lineTo(rect.topRight()).lineTo(rect.bottomRight()).lineTo(rect.bottomLeft()).close();
};
Path.fromPoints = function (points, options) {
if (points) {
var path = new Path(options);
for (var i = 0; i < points.length; i++) {
var pt = Point.create(points[i]);
if (pt) {
if (i === 0) {
path.moveTo(pt);
} else {
path.lineTo(pt);
}
}
}
return path;
}
};
Path.fromArc = function (arc, options) {
var path = new Path(options);
var startAngle = arc.startAngle;
var start = arc.pointAt(startAngle);
path.moveTo(start.x, start.y);
path.arc(startAngle, arc.endAngle, arc.radiusX, arc.radiusY, arc.anticlockwise);
return path;
};
var MultiPath = Element.extend({
nodeType: 'MultiPath',
init: function (options) {
Element.fn.init.call(this, options);
this.paths = new GeometryElementsArray();
this.paths.addObserver(this);
if (!defined(this.options.stroke)) {
this.stroke('#000');
}
},
moveTo: function (x, y) {
var path = new Path();
path.moveTo(x, y);
this.paths.push(path);
return this;
},
lineTo: function (x, y) {
if (this.paths.length > 0) {
last(this.paths).lineTo(x, y);
}
return this;
},
curveTo: function (controlOut, controlIn, point) {
if (this.paths.length > 0) {
last(this.paths).curveTo(controlOut, controlIn, point);
}
return this;
},
arc: function (startAngle, endAngle, radiusX, radiusY, anticlockwise) {
if (this.paths.length > 0) {
last(this.paths).arc(startAngle, endAngle, radiusX, radiusY, anticlockwise);
}
return this;
},
arcTo: function (end, rx, ry, largeArc, swipe) {
if (this.paths.length > 0) {
last(this.paths).arcTo(end, rx, ry, largeArc, swipe);
}
return this;
},
close: function () {
if (this.paths.length > 0) {
last(this.paths).close();
}
return this;
},
bbox: function (transformation) {
return elementsBoundingBox(this.paths, true, this.currentTransform(transformation));
},
rawBBox: function () {
return elementsBoundingBox(this.paths, false);
},
_clippedBBox: function (transformation) {
return elementsClippedBoundingBox(this.paths, this.currentTransform(transformation));
}
});
drawing.mixins.Paintable.extend(MultiPath.fn);
var Image = Element.extend({
nodeType: 'Image',
init: function (src, rect, options) {
Element.fn.init.call(this, options);
this.src(src);
this.rect(rect || new g.Rect());
},
src: function (value) {
if (defined(value)) {
this.options.set('src', value);
return this;
} else {
return this.options.get('src');
}
},
bbox: function (transformation) {
var combinedMatrix = toMatrix(this.currentTransform(transformation));
return this._rect.bbox(combinedMatrix);
},
rawBBox: function () {
return this._rect.bbox();
}
});
defineGeometryAccessors(Image.fn, ['rect']);
var GradientStop = Class.extend({
init: function (offset, color, opacity) {
this.options = new OptionsStore({
offset: offset,
color: color,
opacity: defined(opacity) ? opacity : 1
});
this.options.addObserver(this);
}
});
defineOptionsAccessors(GradientStop.fn, [
'offset',
'color',
'opacity'
]);
deepExtend(GradientStop.fn, ObserversMixin);
GradientStop.create = function (arg) {
if (defined(arg)) {
var stop;
if (arg instanceof GradientStop) {
stop = arg;
} else if (arg.length > 1) {
stop = new GradientStop(arg[0], arg[1], arg[2]);
} else {
stop = new GradientStop(arg.offset, arg.color, arg.opacity);
}
return stop;
}
};
var StopsArray = ElementsArray.extend({
_change: function () {
this.optionsChange({ field: 'stops' });
}
});
var Gradient = Class.extend({
nodeType: 'gradient',
init: function (options) {
this.stops = new StopsArray(this._createStops(options.stops));
this.stops.addObserver(this);
this._userSpace = options.userSpace;
this.id = generateDefinitionId();
},
userSpace: function (value) {
if (defined(value)) {
this._userSpace = value;
this.optionsChange();
return this;
} else {
return this._userSpace;
}
},
_createStops: function (stops) {
var result = [];
var idx;
stops = stops || [];
for (idx = 0; idx < stops.length; idx++) {
result.push(GradientStop.create(stops[idx]));
}
return result;
},
addStop: function (offset, color, opacity) {
this.stops.push(new GradientStop(offset, color, opacity));
},
removeStop: function (stop) {
var index = this.stops.indexOf(stop);
if (index >= 0) {
this.stops.splice(index, 1);
}
}
});
deepExtend(Gradient.fn, ObserversMixin, {
optionsChange: function (e) {
this.trigger('optionsChange', {
field: 'gradient' + (e ? '.' + e.field : ''),
value: this
});
},
geometryChange: function () {
this.optionsChange();
}
});
var LinearGradient = Gradient.extend({
init: function (options) {
options = options || {};
Gradient.fn.init.call(this, options);
this.start(options.start || new Point());
this.end(options.end || new Point(1, 0));
}
});
definePointAccessors(LinearGradient.fn, [
'start',
'end'
]);
var RadialGradient = Gradient.extend({
init: function (options) {
options = options || {};
Gradient.fn.init.call(this, options);
this.center(options.center || new Point());
this._radius = defined(options.radius) ? options.radius : 1;
this._fallbackFill = options.fallbackFill;
},
radius: function (value) {
if (defined(value)) {
this._radius = value;
this.geometryChange();
return this;
} else {
return this._radius;
}
},
fallbackFill: function (value) {
if (defined(value)) {
this._fallbackFill = value;
this.optionsChange();
return this;
} else {
return this._fallbackFill;
}
}
});
definePointAccessors(RadialGradient.fn, ['center']);
var Rect = Element.extend({
nodeType: 'Rect',
init: function (geometry, options) {
Element.fn.init.call(this, options);
this.geometry(geometry || new g.Rect());
if (!defined(this.options.stroke)) {
this.stroke('#000');
}
},
bbox: function (transformation) {
var combinedMatrix = toMatrix(this.currentTransform(transformation));
var rect = this._geometry.bbox(combinedMatrix);
var strokeWidth = this.options.get('stroke.width');
if (strokeWidth) {
expandRect(rect, strokeWidth / 2);
}
return rect;
},
rawBBox: function () {
return this._geometry.bbox();
}
});
drawing.mixins.Paintable.extend(Rect.fn);
defineGeometryAccessors(Rect.fn, ['geometry']);
var Layout = Group.extend({
init: function (rect, options) {
Group.fn.init.call(this, kendo.deepExtend({}, this._defaults, options));
this._rect = rect;
this._fieldMap = {};
},
_defaults: {
alignContent: START,
justifyContent: START,
alignItems: START,
spacing: 0,
orientation: HORIZONTAL,
lineSpacing: 0,
wrap: true
},
rect: function (value) {
if (value) {
this._rect = value;
return this;
} else {
return this._rect;
}
},
_initMap: function () {
var options = this.options;
var fieldMap = this._fieldMap;
if (options.orientation == HORIZONTAL) {
fieldMap.sizeField = 'width';
fieldMap.groupsSizeField = 'height';
fieldMap.groupAxis = 'x';
fieldMap.groupsAxis = 'y';
} else {
fieldMap.sizeField = 'height';
fieldMap.groupsSizeField = 'width';
fieldMap.groupAxis = 'y';
fieldMap.groupsAxis = 'x';
}
},
reflow: function () {
if (!this._rect || this.children.length === 0) {
return;
}
this._initMap();
if (this.options.transform) {
this.transform(null);
}
var options = this.options;
var fieldMap = this._fieldMap;
var rect = this._rect;
var groupOptions = this._initGroups();
var groups = groupOptions.groups;
var groupsSize = groupOptions.groupsSize;
var sizeField = fieldMap.sizeField;
var groupsSizeField = fieldMap.groupsSizeField;
var groupAxis = fieldMap.groupAxis;
var groupsAxis = fieldMap.groupsAxis;
var groupStart = alignStart(groupsSize, rect, options.alignContent, groupsAxis, groupsSizeField);
var groupOrigin = new Point();
var elementOrigin = new Point();
var size = new g.Size();
var elementStart, bbox, element, group, groupBox;
for (var groupIdx = 0; groupIdx < groups.length; groupIdx++) {
group = groups[groupIdx];
groupOrigin[groupAxis] = elementStart = alignStart(group.size, rect, options.justifyContent, groupAxis, sizeField);
groupOrigin[groupsAxis] = groupStart;
size[sizeField] = group.size;
size[groupsSizeField] = group.lineSize;
groupBox = new g.Rect(groupOrigin, size);
for (var idx = 0; idx < group.bboxes.length; idx++) {
element = group.elements[idx];
bbox = group.bboxes[idx];
elementOrigin[groupAxis] = elementStart;
elementOrigin[groupsAxis] = alignStart(bbox.size[groupsSizeField], groupBox, options.alignItems, groupsAxis, groupsSizeField);
translateToPoint(elementOrigin, bbox, element);
elementStart += bbox.size[sizeField] + options.spacing;
}
groupStart += group.lineSize + options.lineSpacing;
}
if (!options.wrap && group.size > rect.size[sizeField]) {
var scale = rect.size[sizeField] / groupBox.size[sizeField];
var scaledStart = groupBox.topLeft().scale(scale, scale);
var scaledSize = groupBox.size[groupsSizeField] * scale;
var newStart = alignStart(scaledSize, rect, options.alignContent, groupsAxis, groupsSizeField);
var transform = g.transform();
if (groupAxis === 'x') {
transform.translate(rect.origin.x - scaledStart.x, newStart - scaledStart.y);
} else {
transform.translate(newStart - scaledStart.x, rect.origin.y - scaledStart.y);
}
transform.scale(scale, scale);
this.transform(transform);
}
},
_initGroups: function () {
var options = this.options;
var children = this.children;
var lineSpacing = options.lineSpacing;
var sizeField = this._fieldMap.sizeField;
var groupsSize = -lineSpacing;
var groups = [];
var group = this._newGroup();
var addGroup = function () {
groups.push(group);
groupsSize += group.lineSize + lineSpacing;
};
var bbox, element;
for (var idx = 0; idx < children.length; idx++) {
element = children[idx];
bbox = children[idx].clippedBBox();
if (element.visible() && bbox) {
if (options.wrap && group.size + bbox.size[sizeField] + options.spacing > this._rect.size[sizeField]) {
if (group.bboxes.length === 0) {
this._addToGroup(group, bbox, element);
addGroup();
group = this._newGroup();
} else {
addGroup();
group = this._newGroup();
this._addToGroup(group, bbox, element);
}
} else {
this._addToGroup(group, bbox, element);
}
}
}
if (group.bboxes.length) {
addGroup();
}
return {
groups: groups,
groupsSize: groupsSize
};
},
_addToGroup: function (group, bbox, element) {
group.size += bbox.size[this._fieldMap.sizeField] + this.options.spacing;
group.lineSize = Math.max(bbox.size[this._fieldMap.groupsSizeField], group.lineSize);
group.bboxes.push(bbox);
group.elements.push(element);
},
_newGroup: function () {
return {
lineSize: 0,
size: -this.options.spacing,
bboxes: [],
elements: []
};
}
});
function elementsBoundingBox(elements, applyTransform, transformation) {
var boundingBox;
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.visible()) {
var elementBoundingBox = applyTransform ? element.bbox(transformation) : element.rawBBox();
if (elementBoundingBox) {
if (boundingBox) {
boundingBox = g.Rect.union(boundingBox, elementBoundingBox);
} else {
boundingBox = elementBoundingBox;
}
}
}
}
return boundingBox;
}
function elementsClippedBoundingBox(elements, transformation) {
var boundingBox;
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.visible()) {
var elementBoundingBox = element.clippedBBox(transformation);
if (elementBoundingBox) {
if (boundingBox) {
boundingBox = g.Rect.union(boundingBox, elementBoundingBox);
} else {
boundingBox = elementBoundingBox;
}
}
}
}
return boundingBox;
}
function expandRect(rect, value) {
rect.origin.x -= value;
rect.origin.y -= value;
rect.size.width += value * 2;
rect.size.height += value * 2;
}
function defineGeometryAccessors(fn, names) {
for (var i = 0; i < names.length; i++) {
fn[names[i]] = geometryAccessor(names[i]);
}
}
function geometryAccessor(name) {
var fieldName = '_' + name;
return function (value) {
if (defined(value)) {
this._observerField(fieldName, value);
this.geometryChange();
return this;
} else {
return this[fieldName];
}
};
}
function definePointAccessors(fn, names) {
for (var i = 0; i < names.length; i++) {
fn[names[i]] = pointAccessor(names[i]);
}
}
function pointAccessor(name) {
var fieldName = '_' + name;
return function (value) {
if (defined(value)) {
this._observerField(fieldName, Point.create(value));
this.geometryChange();
return this;
} else {
return this[fieldName];
}
};
}
function defineOptionsAccessors(fn, names) {
for (var i = 0; i < names.length; i++) {
fn[names[i]] = optionsAccessor(names[i]);
}
}
function optionsAccessor(name) {
return function (value) {
if (defined(value)) {
this.options.set(name, value);
return this;
} else {
return this.options.get(name);
}
};
}
function generateDefinitionId() {
return 'kdef' + defId++;
}
function align(elements, rect, alignment) {
alignElements(elements, rect, alignment, 'x', 'width');
}
function vAlign(elements, rect, alignment) {
alignElements(elements, rect, alignment, 'y', 'height');
}
function stack(elements) {
stackElements(getStackElements(elements), 'x', 'y', 'width');
}
function vStack(elements) {
stackElements(getStackElements(elements), 'y', 'x', 'height');
}
function wrap(elements, rect) {
return wrapElements(elements, rect, 'x', 'y', 'width');
}
function vWrap(elements, rect) {
return wrapElements(elements, rect, 'y', 'x', 'height');
}
function wrapElements(elements, rect, axis, otherAxis, sizeField) {
var result = [];
var stacks = getStacks(elements, rect, sizeField);
var origin = rect.origin.clone();
var startElement;
var elementIdx;
var stack;
var idx;
for (idx = 0; idx < stacks.length; idx++) {
stack = stacks[idx];
startElement = stack[0];
origin[otherAxis] = startElement.bbox.origin[otherAxis];
translateToPoint(origin, startElement.bbox, startElement.element);
startElement.bbox.origin[axis] = origin[axis];
stackElements(stack, axis, otherAxis, sizeField);
result.push([]);
for (elementIdx = 0; elementIdx < stack.length; elementIdx++) {
result[idx].push(stack[elementIdx].element);
}
}
return result;
}
function fit(element, rect) {
var bbox = element.clippedBBox();
var elementSize = bbox.size;
var rectSize = rect.size;
if (rectSize.width < elementSize.width || rectSize.height < elementSize.height) {
var scale = math.min(rectSize.width / elementSize.width, rectSize.height / elementSize.height);
var transform = element.transform() || g.transform();
transform.scale(scale, scale);
element.transform(transform);
}
}
function getStacks(elements, rect, sizeField) {
var maxSize = rect.size[sizeField];
var stackSize = 0;
var stacks = [];
var stack = [];
var element;
var size;
var bbox;
var addElementToStack = function () {
stack.push({
element: element,
bbox: bbox
});
};
for (var idx = 0; idx < elements.length; idx++) {
element = elements[idx];
bbox = element.clippedBBox();
if (bbox) {
size = bbox.size[sizeField];
if (stackSize + size > maxSize) {
if (stack.length) {
stacks.push(stack);
stack = [];
addElementToStack();
stackSize = size;
} else {
addElementToStack();
stacks.push(stack);
stack = [];
stackSize = 0;
}
} else {
addElementToStack();
stackSize += size;
}
}
}
if (stack.length) {
stacks.push(stack);
}
return stacks;
}
function getStackElements(elements) {
var stackElements = [];
var element;
var bbox;
for (var idx = 0; idx < elements.length; idx++) {
element = elements[idx];
bbox = element.clippedBBox();
if (bbox) {
stackElements.push({
element: element,
bbox: bbox
});
}
}
return stackElements;
}
function stackElements(elements, stackAxis, otherAxis, sizeField) {
if (elements.length > 1) {
var previousBBox = elements[0].bbox;
var origin = new Point();
var element;
var bbox;
for (var idx = 1; idx < elements.length; idx++) {
element = elements[idx].element;
bbox = elements[idx].bbox;
origin[stackAxis] = previousBBox.origin[stackAxis] + previousBBox.size[sizeField];
origin[otherAxis] = bbox.origin[otherAxis];
translateToPoint(origin, bbox, element);
bbox.origin[stackAxis] = origin[stackAxis];
previousBBox = bbox;
}
}
}
function alignElements(elements, rect, alignment, axis, sizeField) {
var bbox, point;
alignment = alignment || 'start';
for (var idx = 0; idx < elements.length; idx++) {
bbox = elements[idx].clippedBBox();
if (bbox) {
point = bbox.origin.clone();
point[axis] = alignStart(bbox.size[sizeField], rect, alignment, axis, sizeField);
translateToPoint(point, bbox, elements[idx]);
}
}
}
function alignStart(size, rect, align, axis, sizeField) {
var start;
if (align == START) {
start = rect.origin[axis];
} else if (align == END) {
start = rect.origin[axis] + rect.size[sizeField] - size;
} else {
start = rect.origin[axis] + (rect.size[sizeField] - size) / 2;
}
return start;
}
function translate(x, y, element) {
var transofrm = element.transform() || g.transform();
var matrix = transofrm.matrix();
matrix.e += x;
matrix.f += y;
transofrm.matrix(matrix);
element.transform(transofrm);
}
function translateToPoint(point, bbox, element) {
translate(point.x - bbox.origin.x, point.y - bbox.origin.y, element);
}
deepExtend(drawing, {
align: align,
Arc: Arc,
Circle: Circle,
Element: Element,
ElementsArray: ElementsArray,
fit: fit,
Gradient: Gradient,
GradientStop: GradientStop,
Group: Group,
Image: Image,
Layout: Layout,
LinearGradient: LinearGradient,
MultiPath: MultiPath,
Path: Path,
RadialGradient: RadialGradient,
Rect: Rect,
Segment: Segment,
stack: stack,
Text: Text,
vAlign: vAlign,
vStack: vStack,
vWrap: vWrap,
wrap: wrap
});
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/parser', ['drawing/shapes'], f);
}(function () {
(function ($) {
var kendo = window.kendo, drawing = kendo.drawing, geometry = kendo.geometry, Class = kendo.Class, Point = geometry.Point, deepExtend = kendo.deepExtend, trim = $.trim, util = kendo.util, last = util.last;
var SEGMENT_REGEX = /([a-df-z]{1})([^a-df-z]*)(z)?/gi, SPLIT_REGEX = /[,\s]?([+\-]?(?:\d*\.\d+|\d+)(?:[eE][+\-]?\d+)?)/g, MOVE = 'm', CLOSE = 'z';
var PathParser = Class.extend({
parse: function (str, options) {
var multiPath = new drawing.MultiPath(options);
var position = new Point();
var previousCommand;
str.replace(SEGMENT_REGEX, function (match, element, params, closePath) {
var command = element.toLowerCase();
var isRelative = command === element;
var parameters = parseParameters(trim(params));
if (command === MOVE) {
if (isRelative) {
position.x += parameters[0];
position.y += parameters[1];
} else {
position.x = parameters[0];
position.y = parameters[1];
}
multiPath.moveTo(position.x, position.y);
if (parameters.length > 2) {
command = 'l';
parameters.splice(0, 2);
}
}
if (ShapeMap[command]) {
ShapeMap[command](multiPath, {
parameters: parameters,
position: position,
isRelative: isRelative,
previousCommand: previousCommand
});
if (closePath && closePath.toLowerCase() === CLOSE) {
multiPath.close();
}
} else if (command !== MOVE) {
throw new Error('Error while parsing SVG path. Unsupported command: ' + command);
}
previousCommand = command;
});
return multiPath;
}
});
var ShapeMap = {
l: function (path, options) {
var parameters = options.parameters;
var position = options.position;
for (var i = 0; i < parameters.length; i += 2) {
var point = new Point(parameters[i], parameters[i + 1]);
if (options.isRelative) {
point.translateWith(position);
}
path.lineTo(point.x, point.y);
position.x = point.x;
position.y = point.y;
}
},
c: function (path, options) {
var parameters = options.parameters;
var position = options.position;
var controlOut, controlIn, point;
for (var i = 0; i < parameters.length; i += 6) {
controlOut = new Point(parameters[i], parameters[i + 1]);
controlIn = new Point(parameters[i + 2], parameters[i + 3]);
point = new Point(parameters[i + 4], parameters[i + 5]);
if (options.isRelative) {
controlIn.translateWith(position);
controlOut.translateWith(position);
point.translateWith(position);
}
path.curveTo(controlOut, controlIn, point);
position.x = point.x;
position.y = point.y;
}
},
v: function (path, options) {
var value = options.isRelative ? 0 : options.position.x;
toLineParamaters(options.parameters, true, value);
this.l(path, options);
},
h: function (path, options) {
var value = options.isRelative ? 0 : options.position.y;
toLineParamaters(options.parameters, false, value);
this.l(path, options);
},
a: function (path, options) {
var parameters = options.parameters;
var position = options.position;
for (var i = 0; i < parameters.length; i += 7) {
var radiusX = parameters[i];
var radiusY = parameters[i + 1];
var largeArc = parameters[i + 3];
var swipe = parameters[i + 4];
var endPoint = new Point(parameters[i + 5], parameters[i + 6]);
if (options.isRelative) {
endPoint.translateWith(position);
}
path.arcTo(endPoint, radiusX, radiusY, largeArc, swipe);
position.x = endPoint.x;
position.y = endPoint.y;
}
},
s: function (path, options) {
var parameters = options.parameters;
var position = options.position;
var previousCommand = options.previousCommand;
var controlOut, endPoint, controlIn, lastControlIn;
if (previousCommand == 's' || previousCommand == 'c') {
lastControlIn = last(last(path.paths).segments).controlIn();
}
for (var i = 0; i < parameters.length; i += 4) {
controlIn = new Point(parameters[i], parameters[i + 1]);
endPoint = new Point(parameters[i + 2], parameters[i + 3]);
if (options.isRelative) {
controlIn.translateWith(position);
endPoint.translateWith(position);
}
if (lastControlIn) {
controlOut = reflectionPoint(lastControlIn, position);
} else {
controlOut = position.clone();
}
lastControlIn = controlIn;
path.curveTo(controlOut, controlIn, endPoint);
position.x = endPoint.x;
position.y = endPoint.y;
}
},
q: function (path, options) {
var parameters = options.parameters;
var position = options.position;
var cubicControlPoints, endPoint, controlPoint;
for (var i = 0; i < parameters.length; i += 4) {
controlPoint = new Point(parameters[i], parameters[i + 1]);
endPoint = new Point(parameters[i + 2], parameters[i + 3]);
if (options.isRelative) {
controlPoint.translateWith(position);
endPoint.translateWith(position);
}
cubicControlPoints = quadraticToCubicControlPoints(position, controlPoint, endPoint);
path.curveTo(cubicControlPoints.controlOut, cubicControlPoints.controlIn, endPoint);
position.x = endPoint.x;
position.y = endPoint.y;
}
},
t: function (path, options) {
var parameters = options.parameters;
var position = options.position;
var previousCommand = options.previousCommand;
var cubicControlPoints, controlPoint, endPoint;
if (previousCommand == 'q' || previousCommand == 't') {
var lastSegment = last(last(path.paths).segments);
controlPoint = lastSegment.controlIn().clone().translateWith(position.scaleCopy(-1 / 3)).scale(3 / 2);
}
for (var i = 0; i < parameters.length; i += 2) {
endPoint = new Point(parameters[i], parameters[i + 1]);
if (options.isRelative) {
endPoint.translateWith(position);
}
if (controlPoint) {
controlPoint = reflectionPoint(controlPoint, position);
} else {
controlPoint = position.clone();
}
cubicControlPoints = quadraticToCubicControlPoints(position, controlPoint, endPoint);
path.curveTo(cubicControlPoints.controlOut, cubicControlPoints.controlIn, endPoint);
position.x = endPoint.x;
position.y = endPoint.y;
}
}
};
function parseParameters(str) {
var parameters = [];
str.replace(SPLIT_REGEX, function (match, number) {
parameters.push(parseFloat(number));
});
return parameters;
}
function toLineParamaters(parameters, isVertical, value) {
var insertPosition = isVertical ? 0 : 1;
for (var i = 0; i < parameters.length; i += 2) {
parameters.splice(i + insertPosition, 0, value);
}
}
function reflectionPoint(point, center) {
if (point && center) {
return center.scaleCopy(2).translate(-point.x, -point.y);
}
}
function quadraticToCubicControlPoints(position, controlPoint, endPoint) {
var third = 1 / 3;
controlPoint = controlPoint.clone().scale(2 / 3);
return {
controlOut: controlPoint.clone().translateWith(position.scaleCopy(third)),
controlIn: controlPoint.translateWith(endPoint.scaleCopy(third))
};
}
PathParser.current = new PathParser();
drawing.Path.parse = function (str, options) {
return PathParser.current.parse(str, options);
};
deepExtend(drawing, { PathParser: PathParser });
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/svg', [
'drawing/shapes',
'util/main'
], f);
}(function () {
(function ($) {
var doc = document, kendo = window.kendo, deepExtend = kendo.deepExtend, g = kendo.geometry, d = kendo.drawing, BaseNode = d.BaseNode, util = kendo.util, defined = util.defined, isTransparent = util.isTransparent, renderAttr = util.renderAttr, renderAllAttr = util.renderAllAttr, renderTemplate = util.renderTemplate, inArray = $.inArray;
var BUTT = 'butt', DASH_ARRAYS = d.DASH_ARRAYS, GRADIENT = 'gradient', NONE = 'none', NS = '.kendo', SOLID = 'solid', SPACE = ' ', SVG_NS = 'http://www.w3.org/2000/svg', TRANSFORM = 'transform', UNDEFINED = 'undefined';
var Surface = d.Surface.extend({
init: function (element, options) {
d.Surface.fn.init.call(this, element, options);
this._root = new RootNode(this.options);
renderSVG(this.element[0], this._template(this));
this._rootElement = this.element[0].firstElementChild;
alignToScreen(this._rootElement);
this._root.attachTo(this._rootElement);
this.element.on('click' + NS, this._click);
this.element.on('mouseover' + NS, this._mouseenter);
this.element.on('mouseout' + NS, this._mouseleave);
this.resize();
},
type: 'svg',
destroy: function () {
if (this._root) {
this._root.destroy();
this._root = null;
this._rootElement = null;
this.element.off(NS);
}
d.Surface.fn.destroy.call(this);
},
translate: function (offset) {
var viewBox = kendo.format('{0} {1} {2} {3}', Math.round(offset.x), Math.round(offset.y), this._size.width, this._size.height);
this._offset = offset;
this._rootElement.setAttribute('viewBox', viewBox);
},
draw: function (element) {
d.Surface.fn.draw.call(this, element);
this._root.load([element]);
},
clear: function () {
d.Surface.fn.clear.call(this);
this._root.clear();
},
svg: function () {
return '<?xml version=\'1.0\' ?>' + this._template(this);
},
exportVisual: function () {
var visual = this._visual;
var offset = this._offset;
if (offset) {
var wrap = new d.Group();
wrap.children.push(visual);
wrap.transform(g.transform().translate(-offset.x, -offset.y));
visual = wrap;
}
return visual;
},
_resize: function () {
if (this._offset) {
this.translate(this._offset);
}
},
_template: renderTemplate('<svg style=\'width: 100%; height: 100%; overflow: hidden;\' ' + 'xmlns=\'' + SVG_NS + '\' ' + 'xmlns:xlink=\'http://www.w3.org/1999/xlink\' ' + 'version=\'1.1\'>#= d._root.render() #</svg>')
});
var Node = BaseNode.extend({
init: function (srcElement) {
BaseNode.fn.init.call(this, srcElement);
this.definitions = {};
},
destroy: function () {
if (this.element) {
this.element._kendoNode = null;
this.element = null;
}
this.clearDefinitions();
BaseNode.fn.destroy.call(this);
},
load: function (elements, pos) {
var node = this, element = node.element, childNode, srcElement, children, i;
for (i = 0; i < elements.length; i++) {
srcElement = elements[i];
children = srcElement.children;
childNode = new nodeMap[srcElement.nodeType](srcElement);
if (defined(pos)) {
node.insertAt(childNode, pos);
} else {
node.append(childNode);
}
childNode.createDefinitions();
if (children && children.length > 0) {
childNode.load(children);
}
if (element) {
childNode.attachTo(element, pos);
}
}
},
root: function () {
var root = this;
while (root.parent) {
root = root.parent;
}
return root;
},
attachTo: function (domElement, pos) {
var container = doc.createElement('div');
renderSVG(container, '<svg xmlns=\'' + SVG_NS + '\' version=\'1.1\'>' + this.render() + '</svg>');
var element = container.firstChild.firstChild;
if (element) {
if (defined(pos)) {
domElement.insertBefore(element, domElement.childNodes[pos] || null);
} else {
domElement.appendChild(element);
}
this.setElement(element);
}
},
setElement: function (element) {
var nodes = this.childNodes, childElement, i;
if (this.element) {
this.element._kendoNode = null;
}
this.element = element;
this.element._kendoNode = this;
for (i = 0; i < nodes.length; i++) {
childElement = element.childNodes[i];
nodes[i].setElement(childElement);
}
},
clear: function () {
this.clearDefinitions();
if (this.element) {
this.element.innerHTML = '';
}
var children = this.childNodes;
for (var i = 0; i < children.length; i++) {
children[i].destroy();
}
this.childNodes = [];
},
removeSelf: function () {
if (this.element) {
var parentNode = this.element.parentNode;
if (parentNode) {
parentNode.removeChild(this.element);
}
this.element = null;
}
BaseNode.fn.removeSelf.call(this);
},
template: renderTemplate('#= d.renderChildren() #'),
render: function () {
return this.template(this);
},
renderChildren: function () {
var nodes = this.childNodes, output = '', i;
for (i = 0; i < nodes.length; i++) {
output += nodes[i].render();
}
return output;
},
optionsChange: function (e) {
var field = e.field;
var value = e.value;
if (field === 'visible') {
this.css('display', value ? '' : NONE);
} else if (DefinitionMap[field] && isDefinition(field, value)) {
this.updateDefinition(field, value);
} else if (field === 'opacity') {
this.attr('opacity', value);
}
BaseNode.fn.optionsChange.call(this, e);
},
attr: function (name, value) {
if (this.element) {
this.element.setAttribute(name, value);
}
},
allAttr: function (attrs) {
for (var i = 0; i < attrs.length; i++) {
this.attr(attrs[i][0], attrs[i][1]);
}
},
css: function (name, value) {
if (this.element) {
this.element.style[name] = value;
}
},
allCss: function (styles) {
for (var i = 0; i < styles.length; i++) {
this.css(styles[i][0], styles[i][1]);
}
},
removeAttr: function (name) {
if (this.element) {
this.element.removeAttribute(name);
}
},
mapTransform: function (transform) {
var attrs = [];
if (transform) {
attrs.push([
TRANSFORM,
'matrix(' + transform.matrix().toString(6) + ')'
]);
}
return attrs;
},
renderTransform: function () {
return renderAllAttr(this.mapTransform(this.srcElement.transform()));
},
transformChange: function (value) {
if (value) {
this.allAttr(this.mapTransform(value));
} else {
this.removeAttr(TRANSFORM);
}
},
mapStyle: function () {
var options = this.srcElement.options;
var style = [[
'cursor',
options.cursor
]];
if (options.visible === false) {
style.push([
'display',
NONE
]);
}
return style;
},
renderStyle: function () {
return renderAttr('style', util.renderStyle(this.mapStyle(true)));
},
renderOpacity: function () {
return renderAttr('opacity', this.srcElement.options.opacity);
},
createDefinitions: function () {
var srcElement = this.srcElement;
var definitions = this.definitions;
var definition, field, options, hasDefinitions;
if (srcElement) {
options = srcElement.options;
for (field in DefinitionMap) {
definition = options.get(field);
if (definition && isDefinition(field, definition)) {
definitions[field] = definition;
hasDefinitions = true;
}
}
if (hasDefinitions) {
this.definitionChange({
action: 'add',
definitions: definitions
});
}
}
},
definitionChange: function (e) {
if (this.parent) {
this.parent.definitionChange(e);
}
},
updateDefinition: function (type, value) {
var definitions = this.definitions;
var current = definitions[type];
var attr = DefinitionMap[type];
var definition = {};
if (current) {
definition[type] = current;
this.definitionChange({
action: 'remove',
definitions: definition
});
delete definitions[type];
}
if (!value) {
if (current) {
this.removeAttr(attr);
}
} else {
definition[type] = value;
this.definitionChange({
action: 'add',
definitions: definition
});
definitions[type] = value;
this.attr(attr, refUrl(value.id));
}
},
clearDefinitions: function () {
var definitions = this.definitions;
var field;
for (field in definitions) {
this.definitionChange({
action: 'remove',
definitions: definitions
});
this.definitions = {};
break;
}
},
renderDefinitions: function () {
return renderAllAttr(this.mapDefinitions());
},
mapDefinitions: function () {
var definitions = this.definitions;
var attrs = [];
var field;
for (field in definitions) {
attrs.push([
DefinitionMap[field],
refUrl(definitions[field].id)
]);
}
return attrs;
}
});
var RootNode = Node.extend({
init: function (options) {
Node.fn.init.call(this);
this.options = options;
this.defs = new DefinitionNode();
},
attachTo: function (domElement) {
this.element = domElement;
this.defs.attachTo(domElement.firstElementChild);
},
clear: function () {
BaseNode.fn.clear.call(this);
},
template: renderTemplate('#=d.defs.render()##= d.renderChildren() #'),
definitionChange: function (e) {
this.defs.definitionChange(e);
}
});
var DefinitionNode = Node.extend({
init: function () {
Node.fn.init.call(this);
this.definitionMap = {};
},
attachTo: function (domElement) {
this.element = domElement;
},
template: renderTemplate('<defs>#= d.renderChildren()#</defs>'),
definitionChange: function (e) {
var definitions = e.definitions;
var action = e.action;
if (action == 'add') {
this.addDefinitions(definitions);
} else if (action == 'remove') {
this.removeDefinitions(definitions);
}
},
createDefinition: function (type, item) {
var nodeType;
if (type == 'clip') {
nodeType = ClipNode;
} else if (type == 'fill') {
if (item instanceof d.LinearGradient) {
nodeType = LinearGradientNode;
} else if (item instanceof d.RadialGradient) {
nodeType = RadialGradientNode;
}
}
return new nodeType(item);
},
addDefinitions: function (definitions) {
for (var field in definitions) {
this.addDefinition(field, definitions[field]);
}
},
addDefinition: function (type, srcElement) {
var definitionMap = this.definitionMap;
var id = srcElement.id;
var element = this.element;
var node, mapItem;
mapItem = definitionMap[id];
if (!mapItem) {
node = this.createDefinition(type, srcElement);
definitionMap[id] = {
element: node,
count: 1
};
this.append(node);
if (element) {
node.attachTo(this.element);
}
} else {
mapItem.count++;
}
},
removeDefinitions: function (definitions) {
for (var field in definitions) {
this.removeDefinition(definitions[field]);
}
},
removeDefinition: function (srcElement) {
var definitionMap = this.definitionMap;
var id = srcElement.id;
var mapItem;
mapItem = definitionMap[id];
if (mapItem) {
mapItem.count--;
if (mapItem.count === 0) {
this.remove(inArray(mapItem.element, this.childNodes), 1);
delete definitionMap[id];
}
}
}
});
var ClipNode = Node.extend({
init: function (srcElement) {
Node.fn.init.call(this);
this.srcElement = srcElement;
this.id = srcElement.id;
this.load([srcElement]);
},
template: renderTemplate('<clipPath id=\'#=d.id#\'>#= d.renderChildren()#</clipPath>')
});
var GroupNode = Node.extend({
template: renderTemplate('<g#= d.renderTransform() + d.renderStyle() + d.renderOpacity() + d.renderDefinitions()#>#= d.renderChildren() #</g>'),
optionsChange: function (e) {
if (e.field == TRANSFORM) {
this.transformChange(e.value);
}
Node.fn.optionsChange.call(this, e);
}
});
var PathNode = Node.extend({
geometryChange: function () {
this.attr('d', this.renderData());
this.invalidate();
},
optionsChange: function (e) {
switch (e.field) {
case 'fill':
if (e.value) {
this.allAttr(this.mapFill(e.value));
} else {
this.removeAttr('fill');
}
break;
case 'fill.color':
this.allAttr(this.mapFill({ color: e.value }));
break;
case 'stroke':
if (e.value) {
this.allAttr(this.mapStroke(e.value));
} else {
this.removeAttr('stroke');
}
break;
case TRANSFORM:
this.transformChange(e.value);
break;
default:
var name = this.attributeMap[e.field];
if (name) {
this.attr(name, e.value);
}
break;
}
Node.fn.optionsChange.call(this, e);
},
attributeMap: {
'fill.opacity': 'fill-opacity',
'stroke.color': 'stroke',
'stroke.width': 'stroke-width',
'stroke.opacity': 'stroke-opacity'
},
content: function () {
if (this.element) {
this.element.textContent = this.srcElement.content();
}
},
renderData: function () {
return this.printPath(this.srcElement);
},
printPath: function (path) {
var segments = path.segments, length = segments.length;
if (length > 0) {
var parts = [], output, segmentType, currentType, i;
for (i = 1; i < length; i++) {
segmentType = this.segmentType(segments[i - 1], segments[i]);
if (segmentType !== currentType) {
currentType = segmentType;
parts.push(segmentType);
}
if (segmentType === 'L') {
parts.push(this.printPoints(segments[i].anchor()));
} else {
parts.push(this.printPoints(segments[i - 1].controlOut(), segments[i].controlIn(), segments[i].anchor()));
}
}
output = 'M' + this.printPoints(segments[0].anchor()) + SPACE + parts.join(SPACE);
if (path.options.closed) {
output += 'Z';
}
return output;
}
},
printPoints: function () {
var points = arguments, length = points.length, i, result = [];
for (i = 0; i < length; i++) {
result.push(points[i].toString(3));
}
return result.join(SPACE);
},
segmentType: function (segmentStart, segmentEnd) {
return segmentStart.controlOut() && segmentEnd.controlIn() ? 'C' : 'L';
},
mapStroke: function (stroke) {
var attrs = [];
if (stroke && !isTransparent(stroke.color)) {
attrs.push([
'stroke',
stroke.color
]);
attrs.push([
'stroke-width',
stroke.width
]);
attrs.push([
'stroke-linecap',
this.renderLinecap(stroke)
]);
attrs.push([
'stroke-linejoin',
stroke.lineJoin
]);
if (defined(stroke.opacity)) {
attrs.push([
'stroke-opacity',
stroke.opacity
]);
}
if (defined(stroke.dashType)) {
attrs.push([
'stroke-dasharray',
this.renderDashType(stroke)
]);
}
} else {
attrs.push([
'stroke',
NONE
]);
}
return attrs;
},
renderStroke: function () {
return renderAllAttr(this.mapStroke(this.srcElement.options.stroke));
},
renderDashType: function (stroke) {
var width = stroke.width || 1, dashType = stroke.dashType;
if (dashType && dashType != SOLID) {
var dashArray = DASH_ARRAYS[dashType.toLowerCase()], result = [], i;
for (i = 0; i < dashArray.length; i++) {
result.push(dashArray[i] * width);
}
return result.join(' ');
}
},
renderLinecap: function (stroke) {
var dashType = stroke.dashType, lineCap = stroke.lineCap;
return dashType && dashType != SOLID ? BUTT : lineCap;
},
mapFill: function (fill) {
var attrs = [];
if (!(fill && fill.nodeType == GRADIENT)) {
if (fill && !isTransparent(fill.color)) {
attrs.push([
'fill',
fill.color
]);
if (defined(fill.opacity)) {
attrs.push([
'fill-opacity',
fill.opacity
]);
}
} else {
attrs.push([
'fill',
NONE
]);
}
}
return attrs;
},
renderFill: function () {
return renderAllAttr(this.mapFill(this.srcElement.options.fill));
},
template: renderTemplate('<path #= d.renderStyle() # #= d.renderOpacity() # ' + '#= kendo.util.renderAttr(\'d\', d.renderData()) # ' + '#= d.renderStroke() # ' + '#= d.renderFill() # ' + '#= d.renderDefinitions() # ' + '#= d.renderTransform() #></path>')
});
var ArcNode = PathNode.extend({
renderData: function () {
return this.printPath(this.srcElement.toPath());
}
});
var MultiPathNode = PathNode.extend({
renderData: function () {
var paths = this.srcElement.paths;
if (paths.length > 0) {
var result = [], i;
for (i = 0; i < paths.length; i++) {
result.push(this.printPath(paths[i]));
}
return result.join(' ');
}
}
});
var CircleNode = PathNode.extend({
geometryChange: function () {
var center = this.center();
this.attr('cx', center.x);
this.attr('cy', center.y);
this.attr('r', this.radius());
this.invalidate();
},
center: function () {
return this.srcElement.geometry().center;
},
radius: function () {
return this.srcElement.geometry().radius;
},
template: renderTemplate('<circle #= d.renderStyle() # #= d.renderOpacity() # ' + 'cx=\'#= d.center().x #\' cy=\'#= d.center().y #\' ' + 'r=\'#= d.radius() #\' ' + '#= d.renderStroke() # ' + '#= d.renderFill() # ' + '#= d.renderDefinitions() # ' + '#= d.renderTransform() # ></circle>')
});
var TextNode = PathNode.extend({
geometryChange: function () {
var pos = this.pos();
this.attr('x', pos.x);
this.attr('y', pos.y);
this.invalidate();
},
optionsChange: function (e) {
if (e.field === 'font') {
this.attr('style', util.renderStyle(this.mapStyle()));
this.geometryChange();
} else if (e.field === 'content') {
PathNode.fn.content.call(this, this.srcElement.content());
}
PathNode.fn.optionsChange.call(this, e);
},
mapStyle: function (encode) {
var style = PathNode.fn.mapStyle.call(this, encode);
var font = this.srcElement.options.font;
if (encode) {
font = kendo.htmlEncode(font);
}
style.push([
'font',
font
]);
return style;
},
pos: function () {
var pos = this.srcElement.position();
var size = this.srcElement.measure();
return pos.clone().setY(pos.y + size.baseline);
},
renderContent: function () {
var content = this.srcElement.content();
content = decodeEntities(content);
content = kendo.htmlEncode(content);
return content;
},
template: renderTemplate('<text #= d.renderStyle() # #= d.renderOpacity() # ' + 'x=\'#= this.pos().x #\' y=\'#= this.pos().y #\' ' + '#= d.renderStroke() # ' + '#= d.renderTransform() # ' + '#= d.renderDefinitions() # ' + '#= d.renderFill() #>#= d.renderContent() #</text>')
});
var ImageNode = PathNode.extend({
geometryChange: function () {
this.allAttr(this.mapPosition());
this.invalidate();
},
optionsChange: function (e) {
if (e.field === 'src') {
this.allAttr(this.mapSource());
}
PathNode.fn.optionsChange.call(this, e);
},
mapPosition: function () {
var rect = this.srcElement.rect();
var tl = rect.topLeft();
return [
[
'x',
tl.x
],
[
'y',
tl.y
],
[
'width',
rect.width() + 'px'
],
[
'height',
rect.height() + 'px'
]
];
},
renderPosition: function () {
return renderAllAttr(this.mapPosition());
},
mapSource: function (encode) {
var src = this.srcElement.src();
if (encode) {
src = kendo.htmlEncode(src);
}
return [[
'xlink:href',
src
]];
},
renderSource: function () {
return renderAllAttr(this.mapSource(true));
},
template: renderTemplate('<image preserveAspectRatio=\'none\' #= d.renderStyle() # #= d.renderTransform()# #= d.renderOpacity() # ' + '#= d.renderPosition() # #= d.renderSource() # #= d.renderDefinitions()#>' + '</image>')
});
var GradientStopNode = Node.extend({
template: renderTemplate('<stop #=d.renderOffset()# #=d.renderStyle()# />'),
renderOffset: function () {
return renderAttr('offset', this.srcElement.offset());
},
mapStyle: function () {
var srcElement = this.srcElement;
return [
[
'stop-color',
srcElement.color()
],
[
'stop-opacity',
srcElement.opacity()
]
];
},
optionsChange: function (e) {
if (e.field == 'offset') {
this.attr(e.field, e.value);
} else if (e.field == 'color' || e.field == 'opacity') {
this.css('stop-' + e.field, e.value);
}
}
});
var GradientNode = Node.extend({
init: function (srcElement) {
Node.fn.init.call(this, srcElement);
this.id = srcElement.id;
this.loadStops();
},
loadStops: function () {
var srcElement = this.srcElement;
var stops = srcElement.stops;
var element = this.element;
var stopNode;
var idx;
for (idx = 0; idx < stops.length; idx++) {
stopNode = new GradientStopNode(stops[idx]);
this.append(stopNode);
if (element) {
stopNode.attachTo(element);
}
}
},
optionsChange: function (e) {
if (e.field == 'gradient.stops') {
BaseNode.fn.clear.call(this);
this.loadStops();
} else if (e.field == GRADIENT) {
this.allAttr(this.mapCoordinates());
}
},
renderCoordinates: function () {
return renderAllAttr(this.mapCoordinates());
},
mapSpace: function () {
return [
'gradientUnits',
this.srcElement.userSpace() ? 'userSpaceOnUse' : 'objectBoundingBox'
];
}
});
var LinearGradientNode = GradientNode.extend({
template: renderTemplate('<linearGradient id=\'#=d.id#\' #=d.renderCoordinates()#>' + '#= d.renderChildren()#' + '</linearGradient>'),
mapCoordinates: function () {
var srcElement = this.srcElement;
var start = srcElement.start();
var end = srcElement.end();
var attrs = [
[
'x1',
start.x
],
[
'y1',
start.y
],
[
'x2',
end.x
],
[
'y2',
end.y
],
this.mapSpace()
];
return attrs;
}
});
var RadialGradientNode = GradientNode.extend({
template: renderTemplate('<radialGradient id=\'#=d.id#\' #=d.renderCoordinates()#>' + '#= d.renderChildren()#' + '</radialGradient>'),
mapCoordinates: function () {
var srcElement = this.srcElement;
var center = srcElement.center();
var radius = srcElement.radius();
var attrs = [
[
'cx',
center.x
],
[
'cy',
center.y
],
[
'r',
radius
],
this.mapSpace()
];
return attrs;
}
});
var RectNode = PathNode.extend({
geometryChange: function () {
var geometry = this.srcElement.geometry();
this.attr('x', geometry.origin.x);
this.attr('y', geometry.origin.y);
this.attr('width', geometry.size.width);
this.attr('height', geometry.size.height);
this.invalidate();
},
size: function () {
return this.srcElement.geometry().size;
},
origin: function () {
return this.srcElement.geometry().origin;
},
template: renderTemplate('<rect #= d.renderStyle() # #= d.renderOpacity() # ' + 'x=\'#= d.origin().x #\' y=\'#= d.origin().y #\' ' + 'width=\'#= d.size().width #\' height=\'#= d.size().height #\'' + '#= d.renderStroke() # ' + '#= d.renderFill() # ' + '#= d.renderDefinitions() # ' + '#= d.renderTransform() # />')
});
var nodeMap = {
Group: GroupNode,
Text: TextNode,
Path: PathNode,
MultiPath: MultiPathNode,
Circle: CircleNode,
Arc: ArcNode,
Image: ImageNode,
Rect: RectNode
};
var renderSVG = function (container, svg) {
container.innerHTML = svg;
};
(function () {
var testFragment = '<svg xmlns=\'' + SVG_NS + '\'></svg>', testContainer = doc.createElement('div'), hasParser = typeof DOMParser != UNDEFINED;
testContainer.innerHTML = testFragment;
if (hasParser && testContainer.firstChild.namespaceURI != SVG_NS) {
renderSVG = function (container, svg) {
var parser = new DOMParser(), chartDoc = parser.parseFromString(svg, 'text/xml'), importedDoc = doc.adoptNode(chartDoc.documentElement);
container.innerHTML = '';
container.appendChild(importedDoc);
};
}
}());
function alignToScreen(element) {
var ctm;
try {
ctm = element.getScreenCTM ? element.getScreenCTM() : null;
} catch (e) {
}
if (ctm) {
var left = -ctm.e % 1, top = -ctm.f % 1, style = element.style;
if (left !== 0 || top !== 0) {
style.left = left + 'px';
style.top = top + 'px';
}
}
}
function baseUrl() {
var base = document.getElementsByTagName('base')[0], url = '', href = document.location.href, hashIndex = href.indexOf('#');
if (base && !kendo.support.browser.msie) {
if (hashIndex !== -1) {
href = href.substring(0, hashIndex);
}
url = href;
}
return url;
}
function refUrl(id) {
return 'url(' + baseUrl() + '#' + id + ')';
}
function exportGroup(group) {
var root = new RootNode();
var bbox = group.clippedBBox();
if (bbox) {
var origin = bbox.getOrigin();
var exportRoot = new d.Group();
exportRoot.transform(g.transform().translate(-origin.x, -origin.y));
exportRoot.children.push(group);
group = exportRoot;
}
root.load([group]);
var svg = '<?xml version=\'1.0\' ?>' + '<svg xmlns=\'' + SVG_NS + '\' ' + 'xmlns:xlink=\'http://www.w3.org/1999/xlink\' ' + 'version=\'1.1\'>' + root.render() + '</svg>';
root.destroy();
return svg;
}
function exportSVG(group, options) {
var svg = exportGroup(group);
if (!options || !options.raw) {
svg = 'data:image/svg+xml;base64,' + util.encodeBase64(svg);
}
return $.Deferred().resolve(svg).promise();
}
function isDefinition(type, value) {
return type == 'clip' || type == 'fill' && (!value || value.nodeType == GRADIENT);
}
function decodeEntities(text) {
if (!text || !text.indexOf || text.indexOf('&') < 0) {
return text;
} else {
var element = decodeEntities._element;
element.innerHTML = text;
return element.textContent || element.innerText;
}
}
decodeEntities._element = document.createElement('span');
var DefinitionMap = {
clip: 'clip-path',
fill: 'fill'
};
kendo.support.svg = function () {
return doc.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1');
}();
if (kendo.support.svg) {
d.SurfaceFactory.current.register('svg', Surface, 10);
}
deepExtend(d, {
exportSVG: exportSVG,
svg: {
ArcNode: ArcNode,
CircleNode: CircleNode,
ClipNode: ClipNode,
DefinitionNode: DefinitionNode,
GradientStopNode: GradientStopNode,
GroupNode: GroupNode,
ImageNode: ImageNode,
LinearGradientNode: LinearGradientNode,
MultiPathNode: MultiPathNode,
Node: Node,
PathNode: PathNode,
RadialGradientNode: RadialGradientNode,
RectNode: RectNode,
RootNode: RootNode,
Surface: Surface,
TextNode: TextNode,
_exportGroup: exportGroup
}
});
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/canvas', [
'drawing/shapes',
'kendo.color'
], f);
}(function () {
(function ($) {
var doc = document, kendo = window.kendo, deepExtend = kendo.deepExtend, util = kendo.util, defined = util.defined, isTransparent = util.isTransparent, renderTemplate = util.renderTemplate, valueOrDefault = util.valueOrDefault, g = kendo.geometry, d = kendo.drawing, BaseNode = d.BaseNode;
var BUTT = 'butt', DASH_ARRAYS = d.DASH_ARRAYS, FRAME_DELAY = 1000 / 60, SOLID = 'solid';
var Surface = d.Surface.extend({
init: function (element, options) {
d.Surface.fn.init.call(this, element, options);
this.element[0].innerHTML = this._template(this);
var canvas = this.element[0].firstElementChild;
canvas.width = $(element).width();
canvas.height = $(element).height();
this._rootElement = canvas;
this._root = new RootNode(canvas);
},
destroy: function () {
d.Surface.fn.destroy.call(this);
if (this._root) {
this._root.destroy();
this._root = null;
}
},
type: 'canvas',
draw: function (element) {
d.Surface.fn.draw.call(this, element);
this._root.load([element], undefined, this.options.cors);
},
clear: function () {
d.Surface.fn.clear.call(this);
this._root.clear();
},
image: function () {
var root = this._root;
var rootElement = this._rootElement;
var loadingStates = [];
root.traverse(function (childNode) {
if (childNode.loading) {
loadingStates.push(childNode.loading);
}
});
var defer = $.Deferred();
$.when.apply($, loadingStates).done(function () {
root._invalidate();
try {
var data = rootElement.toDataURL();
defer.resolve(data);
} catch (e) {
defer.reject(e);
}
}).fail(function (e) {
defer.reject(e);
});
return defer.promise();
},
_resize: function () {
this._rootElement.width = this._size.width;
this._rootElement.height = this._size.height;
this._root.invalidate();
},
_template: renderTemplate('<canvas style=\'width: 100%; height: 100%;\'></canvas>')
});
var Node = BaseNode.extend({
init: function (srcElement) {
BaseNode.fn.init.call(this, srcElement);
if (srcElement) {
this.initClip();
}
},
initClip: function () {
var clip = this.srcElement.clip();
if (clip) {
this.clip = clip;
clip.addObserver(this);
}
},
clear: function () {
if (this.srcElement) {
this.srcElement.removeObserver(this);
}
this.clearClip();
BaseNode.fn.clear.call(this);
},
clearClip: function () {
if (this.clip) {
this.clip.removeObserver(this);
delete this.clip;
}
},
setClip: function (ctx) {
if (this.clip) {
ctx.beginPath();
PathNode.fn.renderPoints(ctx, this.clip);
ctx.clip();
}
},
optionsChange: function (e) {
if (e.field == 'clip') {
this.clearClip();
this.initClip();
}
BaseNode.fn.optionsChange.call(this, e);
},
setTransform: function (ctx) {
if (this.srcElement) {
var transform = this.srcElement.transform();
if (transform) {
ctx.transform.apply(ctx, transform.matrix().toArray(6));
}
}
},
loadElements: function (elements, pos, cors) {
var node = this, childNode, srcElement, children, i;
for (i = 0; i < elements.length; i++) {
srcElement = elements[i];
children = srcElement.children;
childNode = new nodeMap[srcElement.nodeType](srcElement, cors);
if (children && children.length > 0) {
childNode.load(children, pos, cors);
}
if (defined(pos)) {
node.insertAt(childNode, pos);
} else {
node.append(childNode);
}
}
},
load: function (elements, pos, cors) {
this.loadElements(elements, pos, cors);
this.invalidate();
},
setOpacity: function (ctx) {
if (this.srcElement) {
var opacity = this.srcElement.opacity();
if (defined(opacity)) {
this.globalAlpha(ctx, opacity);
}
}
},
globalAlpha: function (ctx, value) {
if (value && ctx.globalAlpha) {
value *= ctx.globalAlpha;
}
ctx.globalAlpha = value;
},
visible: function () {
var src = this.srcElement;
return !src || src && src.options.visible !== false;
}
});
var GroupNode = Node.extend({
renderTo: function (ctx) {
if (!this.visible()) {
return;
}
ctx.save();
this.setTransform(ctx);
this.setClip(ctx);
this.setOpacity(ctx);
var childNodes = this.childNodes;
for (var i = 0; i < childNodes.length; i++) {
var child = childNodes[i];
if (child.visible()) {
child.renderTo(ctx);
}
}
ctx.restore();
}
});
d.mixins.Traversable.extend(GroupNode.fn, 'childNodes');
var RootNode = GroupNode.extend({
init: function (canvas) {
GroupNode.fn.init.call(this);
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
var invalidateHandler = $.proxy(this._invalidate, this);
this.invalidate = kendo.throttle(function () {
kendo.animationFrame(invalidateHandler);
}, FRAME_DELAY);
},
destroy: function () {
GroupNode.fn.destroy.call(this);
this.canvas = null;
this.ctx = null;
},
load: function (elements, pos, cors) {
this.loadElements(elements, pos, cors);
this._invalidate();
},
_invalidate: function () {
if (!this.ctx) {
return;
}
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.renderTo(this.ctx);
}
});
d.mixins.Traversable.extend(RootNode.fn, 'childNodes');
var PathNode = Node.extend({
renderTo: function (ctx) {
ctx.save();
this.setTransform(ctx);
this.setClip(ctx);
this.setOpacity(ctx);
ctx.beginPath();
this.renderPoints(ctx, this.srcElement);
this.setLineDash(ctx);
this.setLineCap(ctx);
this.setLineJoin(ctx);
this.setFill(ctx);
this.setStroke(ctx);
ctx.restore();
},
setFill: function (ctx) {
var fill = this.srcElement.options.fill;
var hasFill = false;
if (fill) {
if (fill.nodeType == 'gradient') {
this.setGradientFill(ctx, fill);
hasFill = true;
} else if (!isTransparent(fill.color)) {
ctx.fillStyle = fill.color;
ctx.save();
this.globalAlpha(ctx, fill.opacity);
ctx.fill();
ctx.restore();
hasFill = true;
}
}
return hasFill;
},
setGradientFill: function (ctx, fill) {
var bbox = this.srcElement.rawBBox();
var gradient;
if (fill instanceof d.LinearGradient) {
var start = fill.start();
var end = fill.end();
gradient = ctx.createLinearGradient(start.x, start.y, end.x, end.y);
} else if (fill instanceof d.RadialGradient) {
var center = fill.center();
gradient = ctx.createRadialGradient(center.x, center.y, 0, center.x, center.y, fill.radius());
}
addGradientStops(gradient, fill.stops);
ctx.save();
if (!fill.userSpace()) {
ctx.transform(bbox.width(), 0, 0, bbox.height(), bbox.origin.x, bbox.origin.y);
}
ctx.fillStyle = gradient;
ctx.fill();
ctx.restore();
},
setStroke: function (ctx) {
var stroke = this.srcElement.options.stroke;
if (stroke && !isTransparent(stroke.color) && stroke.width > 0) {
ctx.strokeStyle = stroke.color;
ctx.lineWidth = valueOrDefault(stroke.width, 1);
ctx.save();
this.globalAlpha(ctx, stroke.opacity);
ctx.stroke();
ctx.restore();
return true;
}
},
dashType: function () {
var stroke = this.srcElement.options.stroke;
if (stroke && stroke.dashType) {
return stroke.dashType.toLowerCase();
}
},
setLineDash: function (ctx) {
var dashType = this.dashType();
if (dashType && dashType != SOLID) {
var dashArray = DASH_ARRAYS[dashType];
if (ctx.setLineDash) {
ctx.setLineDash(dashArray);
} else {
ctx.mozDash = dashArray;
ctx.webkitLineDash = dashArray;
}
}
},
setLineCap: function (ctx) {
var dashType = this.dashType();
var stroke = this.srcElement.options.stroke;
if (dashType && dashType !== SOLID) {
ctx.lineCap = BUTT;
} else if (stroke && stroke.lineCap) {
ctx.lineCap = stroke.lineCap;
}
},
setLineJoin: function (ctx) {
var stroke = this.srcElement.options.stroke;
if (stroke && stroke.lineJoin) {
ctx.lineJoin = stroke.lineJoin;
}
},
renderPoints: function (ctx, path) {
var segments = path.segments;
if (segments.length === 0) {
return;
}
var seg = segments[0];
var anchor = seg.anchor();
ctx.moveTo(anchor.x, anchor.y);
for (var i = 1; i < segments.length; i++) {
seg = segments[i];
anchor = seg.anchor();
var prevSeg = segments[i - 1];
var prevOut = prevSeg.controlOut();
var controlIn = seg.controlIn();
if (prevOut && controlIn) {
ctx.bezierCurveTo(prevOut.x, prevOut.y, controlIn.x, controlIn.y, anchor.x, anchor.y);
} else {
ctx.lineTo(anchor.x, anchor.y);
}
}
if (path.options.closed) {
ctx.closePath();
}
}
});
var MultiPathNode = PathNode.extend({
renderPoints: function (ctx) {
var paths = this.srcElement.paths;
for (var i = 0; i < paths.length; i++) {
PathNode.fn.renderPoints(ctx, paths[i]);
}
}
});
var CircleNode = PathNode.extend({
renderPoints: function (ctx) {
var geometry = this.srcElement.geometry();
var c = geometry.center;
var r = geometry.radius;
ctx.arc(c.x, c.y, r, 0, Math.PI * 2);
}
});
var ArcNode = PathNode.extend({
renderPoints: function (ctx) {
var path = this.srcElement.toPath();
PathNode.fn.renderPoints.call(this, ctx, path);
}
});
var TextNode = PathNode.extend({
renderTo: function (ctx) {
var text = this.srcElement;
var pos = text.position();
var size = text.measure();
ctx.save();
this.setTransform(ctx);
this.setClip(ctx);
this.setOpacity(ctx);
ctx.beginPath();
ctx.font = text.options.font;
if (this.setFill(ctx)) {
ctx.fillText(text.content(), pos.x, pos.y + size.baseline);
}
if (this.setStroke(ctx)) {
this.setLineDash(ctx);
ctx.strokeText(text.content(), pos.x, pos.y + size.baseline);
}
ctx.restore();
}
});
var ImageNode = PathNode.extend({
init: function (srcElement, cors) {
PathNode.fn.init.call(this, srcElement);
this.onLoad = $.proxy(this.onLoad, this);
this.onError = $.proxy(this.onError, this);
this.loading = $.Deferred();
var img = this.img = new Image();
if (cors && !/^data:/i.test(srcElement.src())) {
img.crossOrigin = cors;
}
img.src = srcElement.src();
if (img.complete) {
this.onLoad();
} else {
img.onload = this.onLoad;
img.onerror = this.onError;
}
},
renderTo: function (ctx) {
if (this.loading.state() === 'resolved') {
ctx.save();
this.setTransform(ctx);
this.setClip(ctx);
this.drawImage(ctx);
ctx.restore();
}
},
optionsChange: function (e) {
if (e.field === 'src') {
this.loading = $.Deferred();
this.img.src = this.srcElement.src();
} else {
PathNode.fn.optionsChange.call(this, e);
}
},
onLoad: function () {
this.loading.resolve();
this.invalidate();
},
onError: function () {
this.loading.reject(new Error('Unable to load image \'' + this.img.src + '\'. Check for connectivity and verify CORS headers.'));
},
drawImage: function (ctx) {
var rect = this.srcElement.rect();
var tl = rect.topLeft();
ctx.drawImage(this.img, tl.x, tl.y, rect.width(), rect.height());
}
});
var RectNode = PathNode.extend({
renderPoints: function (ctx) {
var geometry = this.srcElement.geometry();
var origin = geometry.origin;
var size = geometry.size;
ctx.rect(origin.x, origin.y, size.width, size.height);
}
});
function exportImage(group, options) {
var defaults = {
width: '800px',
height: '600px',
cors: 'Anonymous'
};
var bbox = group.clippedBBox();
if (bbox) {
var origin = bbox.getOrigin();
var exportRoot = new d.Group();
exportRoot.transform(g.transform().translate(-origin.x, -origin.y));
exportRoot.children.push(group);
group = exportRoot;
var size = bbox.getSize();
defaults.width = size.width + 'px';
defaults.height = size.height + 'px';
}
options = deepExtend(defaults, options);
var container = $('<div />').css({
display: 'none',
width: options.width,
height: options.height
}).appendTo(document.body);
var surface = new Surface(container, options);
surface.draw(group);
var promise = surface.image();
promise.always(function () {
surface.destroy();
container.remove();
});
return promise;
}
var nodeMap = {
Group: GroupNode,
Text: TextNode,
Path: PathNode,
MultiPath: MultiPathNode,
Circle: CircleNode,
Arc: ArcNode,
Image: ImageNode,
Rect: RectNode
};
function addGradientStops(gradient, stops) {
var color, stop, idx;
for (idx = 0; idx < stops.length; idx++) {
stop = stops[idx];
color = kendo.parseColor(stop.color());
color.a *= stop.opacity();
gradient.addColorStop(stop.offset(), color.toCssRgba());
}
}
kendo.support.canvas = function () {
return !!doc.createElement('canvas').getContext;
}();
if (kendo.support.canvas) {
d.SurfaceFactory.current.register('canvas', Surface, 20);
}
deepExtend(kendo.drawing, {
exportImage: exportImage,
canvas: {
ArcNode: ArcNode,
CircleNode: CircleNode,
GroupNode: GroupNode,
ImageNode: ImageNode,
MultiPathNode: MultiPathNode,
Node: Node,
PathNode: PathNode,
RectNode: RectNode,
RootNode: RootNode,
Surface: Surface,
TextNode: TextNode
}
});
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/vml', [
'drawing/shapes',
'kendo.color'
], f);
}(function () {
(function ($) {
var doc = document, math = Math, atan2 = math.atan2, ceil = math.ceil, sqrt = math.sqrt, kendo = window.kendo, deepExtend = kendo.deepExtend, noop = $.noop, d = kendo.drawing, BaseNode = d.BaseNode, g = kendo.geometry, toMatrix = g.toMatrix, Color = kendo.Color, util = kendo.util, isTransparent = util.isTransparent, defined = util.defined, deg = util.deg, round = util.round, valueOrDefault = util.valueOrDefault;
var NONE = 'none', NS = '.kendo', COORDINATE_MULTIPLE = 100, COORDINATE_SIZE = COORDINATE_MULTIPLE * COORDINATE_MULTIPLE, GRADIENT = 'gradient', TRANSFORM_PRECISION = 4;
var Surface = d.Surface.extend({
init: function (element, options) {
d.Surface.fn.init.call(this, element, options);
enableVML();
this.element.empty();
this._root = new RootNode();
this._root.attachTo(this.element[0]);
this.element.on('click' + NS, this._click);
this.element.on('mouseover' + NS, this._mouseenter);
this.element.on('mouseout' + NS, this._mouseleave);
},
type: 'vml',
destroy: function () {
if (this._root) {
this._root.destroy();
this._root = null;
this.element.off(NS);
}
d.Surface.fn.destroy.call(this);
},
draw: function (element) {
d.Surface.fn.draw.call(this, element);
this._root.load([element], undefined, null);
},
clear: function () {
d.Surface.fn.clear.call(this);
this._root.clear();
}
});
var Node = BaseNode.extend({
init: function (srcElement) {
BaseNode.fn.init.call(this, srcElement);
this.createElement();
this.attachReference();
},
observe: noop,
destroy: function () {
if (this.element) {
this.element._kendoNode = null;
this.element = null;
}
BaseNode.fn.destroy.call(this);
},
clear: function () {
if (this.element) {
this.element.innerHTML = '';
}
var children = this.childNodes;
for (var i = 0; i < children.length; i++) {
children[i].destroy();
}
this.childNodes = [];
},
removeSelf: function () {
if (this.element) {
this.element.parentNode.removeChild(this.element);
this.element = null;
}
BaseNode.fn.removeSelf.call(this);
},
createElement: function () {
this.element = doc.createElement('div');
},
attachReference: function () {
this.element._kendoNode = this;
},
load: function (elements, pos, transform, opacity) {
opacity = valueOrDefault(opacity, 1);
if (this.srcElement) {
opacity *= valueOrDefault(this.srcElement.options.opacity, 1);
}
for (var i = 0; i < elements.length; i++) {
var srcElement = elements[i];
var children = srcElement.children;
var combinedTransform = srcElement.currentTransform(transform);
var currentOpacity = opacity * valueOrDefault(srcElement.options.opacity, 1);
var childNode = new nodeMap[srcElement.nodeType](srcElement, combinedTransform, currentOpacity);
if (children && children.length > 0) {
childNode.load(children, pos, combinedTransform, opacity);
}
if (defined(pos)) {
this.insertAt(childNode, pos);
} else {
this.append(childNode);
}
childNode.attachTo(this.element, pos);
}
},
attachTo: function (domElement, pos) {
if (defined(pos)) {
domElement.insertBefore(this.element, domElement.children[pos] || null);
} else {
domElement.appendChild(this.element);
}
},
optionsChange: function (e) {
if (e.field == 'visible') {
this.css('display', e.value !== false ? '' : NONE);
}
},
setStyle: function () {
this.allCss(this.mapStyle());
},
mapStyle: function () {
var style = [];
if (this.srcElement && this.srcElement.options.visible === false) {
style.push([
'display',
NONE
]);
}
return style;
},
mapOpacityTo: function (attrs, multiplier) {
var opacity = valueOrDefault(this.opacity, 1);
opacity *= valueOrDefault(multiplier, 1);
attrs.push([
'opacity',
opacity
]);
},
attr: function (name, value) {
if (this.element) {
this.element[name] = value;
}
},
allAttr: function (attrs) {
for (var i = 0; i < attrs.length; i++) {
this.attr(attrs[i][0], attrs[i][1]);
}
},
css: function (name, value) {
if (this.element) {
this.element.style[name] = value;
}
},
allCss: function (styles) {
for (var i = 0; i < styles.length; i++) {
this.css(styles[i][0], styles[i][1]);
}
}
});
var RootNode = Node.extend({
createElement: function () {
Node.fn.createElement.call(this);
this.allCss([
[
'width',
'100%'
],
[
'height',
'100%'
],
[
'position',
'relative'
],
[
'visibility',
'visible'
]
]);
},
attachReference: noop
});
var ClipObserver = kendo.Class.extend({
init: function (srcElement, observer) {
this.srcElement = srcElement;
this.observer = observer;
srcElement.addObserver(this);
},
geometryChange: function () {
this.observer.optionsChange({
field: 'clip',
value: this.srcElement
});
},
clear: function () {
this.srcElement.removeObserver(this);
}
});
var ObserverNode = Node.extend({
init: function (srcElement) {
Node.fn.init.call(this, srcElement);
if (srcElement) {
this.initClip();
}
},
observe: function () {
BaseNode.fn.observe.call(this);
},
mapStyle: function () {
var style = Node.fn.mapStyle.call(this);
if (this.srcElement && this.srcElement.clip()) {
style.push([
'clip',
this.clipRect()
]);
}
return style;
},
optionsChange: function (e) {
if (e.field == 'clip') {
this.clearClip();
this.initClip();
this.setClip();
}
Node.fn.optionsChange.call(this, e);
},
clear: function () {
this.clearClip();
Node.fn.clear.call(this);
},
initClip: function () {
if (this.srcElement.clip()) {
this.clip = new ClipObserver(this.srcElement.clip(), this);
this.clip.observer = this;
}
},
clearClip: function () {
if (this.clip) {
this.clip.clear();
this.clip = null;
this.css('clip', this.clipRect());
}
},
setClip: function () {
if (this.clip) {
this.css('clip', this.clipRect());
}
},
clipRect: function () {
var clipRect = EMPTY_CLIP;
var clip = this.srcElement.clip();
if (clip) {
var bbox = this.clipBBox(clip);
var topLeft = bbox.topLeft();
var bottomRight = bbox.bottomRight();
clipRect = kendo.format('rect({0}px {1}px {2}px {3}px)', topLeft.y, bottomRight.x, bottomRight.y, topLeft.x);
}
return clipRect;
},
clipBBox: function (clip) {
var topLeft = this.srcElement.rawBBox().topLeft();
var clipBBox = clip.rawBBox();
clipBBox.origin.translate(-topLeft.x, -topLeft.y);
return clipBBox;
}
});
var GroupNode = ObserverNode.extend({
createElement: function () {
Node.fn.createElement.call(this);
this.setStyle();
},
attachTo: function (domElement, pos) {
this.css('display', NONE);
Node.fn.attachTo.call(this, domElement, pos);
if (this.srcElement.options.visible !== false) {
this.css('display', '');
}
},
_attachTo: function (domElement) {
var frag = document.createDocumentFragment();
frag.appendChild(this.element);
domElement.appendChild(frag);
},
mapStyle: function () {
var style = ObserverNode.fn.mapStyle.call(this);
style.push([
'position',
'absolute'
]);
style.push([
'white-space',
'nowrap'
]);
return style;
},
optionsChange: function (e) {
if (e.field === 'transform') {
this.refreshTransform();
}
if (e.field === 'opacity') {
this.refreshOpacity();
}
ObserverNode.fn.optionsChange.call(this, e);
},
refreshTransform: function (transform) {
var currentTransform = this.srcElement.currentTransform(transform), children = this.childNodes, length = children.length, i;
this.setClip();
for (i = 0; i < length; i++) {
children[i].refreshTransform(currentTransform);
}
},
currentOpacity: function () {
var opacity = valueOrDefault(this.srcElement.options.opacity, 1);
if (this.parent && this.parent.currentOpacity) {
opacity *= this.parent.currentOpacity();
}
return opacity;
},
refreshOpacity: function () {
var children = this.childNodes, length = children.length, i;
var opacity = this.currentOpacity();
for (i = 0; i < length; i++) {
children[i].refreshOpacity(opacity);
}
},
initClip: function () {
ObserverNode.fn.initClip.call(this);
if (this.clip) {
var bbox = this.clip.srcElement.bbox(this.srcElement.currentTransform());
if (bbox) {
this.css('width', bbox.width() + bbox.origin.x);
this.css('height', bbox.height() + bbox.origin.y);
}
}
},
clipBBox: function (clip) {
return clip.bbox(this.srcElement.currentTransform());
},
clearClip: function () {
ObserverNode.fn.clearClip.call(this);
}
});
var StrokeNode = Node.extend({
init: function (srcElement, opacity) {
this.opacity = opacity;
Node.fn.init.call(this, srcElement);
},
createElement: function () {
this.element = createElementVML('stroke');
this.setOpacity();
},
optionsChange: function (e) {
if (e.field.indexOf('stroke') === 0) {
this.setStroke();
}
},
refreshOpacity: function (opacity) {
this.opacity = opacity;
this.setStroke();
},
setStroke: function () {
this.allAttr(this.mapStroke());
},
setOpacity: function () {
this.setStroke();
},
mapStroke: function () {
var stroke = this.srcElement.options.stroke;
var attrs = [];
if (stroke && !isTransparent(stroke.color) && stroke.width !== 0) {
attrs.push([
'on',
'true'
]);
attrs.push([
'color',
stroke.color
]);
attrs.push([
'weight',
(stroke.width || 1) + 'px'
]);
this.mapOpacityTo(attrs, stroke.opacity);
if (defined(stroke.dashType)) {
attrs.push([
'dashstyle',
stroke.dashType
]);
}
if (defined(stroke.lineJoin)) {
attrs.push([
'joinstyle',
stroke.lineJoin
]);
}
if (defined(stroke.lineCap)) {
var lineCap = stroke.lineCap.toLowerCase();
if (lineCap === 'butt') {
lineCap = lineCap === 'butt' ? 'flat' : lineCap;
}
attrs.push([
'endcap',
lineCap
]);
}
} else {
attrs.push([
'on',
'false'
]);
}
return attrs;
}
});
var FillNode = Node.extend({
init: function (srcElement, transform, opacity) {
this.opacity = opacity;
Node.fn.init.call(this, srcElement);
},
createElement: function () {
this.element = createElementVML('fill');
this.setFill();
},
optionsChange: function (e) {
if (fillField(e.field)) {
this.setFill();
}
},
refreshOpacity: function (opacity) {
this.opacity = opacity;
this.setOpacity();
},
setFill: function () {
this.allAttr(this.mapFill());
},
setOpacity: function () {
this.setFill();
},
attr: function (name, value) {
var element = this.element;
if (element) {
var fields = name.split('.');
while (fields.length > 1) {
element = element[fields.shift()];
}
element[fields[0]] = value;
}
},
mapFill: function () {
var fill = this.srcElement.fill();
var attrs = [[
'on',
'false'
]];
if (fill) {
if (fill.nodeType == GRADIENT) {
attrs = this.mapGradient(fill);
} else if (!isTransparent(fill.color)) {
attrs = this.mapFillColor(fill);
}
}
return attrs;
},
mapFillColor: function (fill) {
var attrs = [
[
'on',
'true'
],
[
'color',
fill.color
]
];
this.mapOpacityTo(attrs, fill.opacity);
return attrs;
},
mapGradient: function (fill) {
var options = this.srcElement.options;
var fallbackFill = options.fallbackFill || fill.fallbackFill && fill.fallbackFill();
var attrs;
if (fill instanceof d.LinearGradient) {
attrs = this.mapLinearGradient(fill);
} else if (fill instanceof d.RadialGradient && fill.supportVML) {
attrs = this.mapRadialGradient(fill);
} else if (fallbackFill) {
attrs = this.mapFillColor(fallbackFill);
} else {
attrs = [[
'on',
'false'
]];
}
return attrs;
},
mapLinearGradient: function (fill) {
var start = fill.start();
var end = fill.end();
var angle = util.deg(atan2(end.y - start.y, end.x - start.x));
var attrs = [
[
'on',
'true'
],
[
'type',
GRADIENT
],
[
'focus',
0
],
[
'method',
'none'
],
[
'angle',
270 - angle
]
];
this.addColors(attrs);
return attrs;
},
mapRadialGradient: function (fill) {
var bbox = this.srcElement.rawBBox();
var center = fill.center();
var focusx = (center.x - bbox.origin.x) / bbox.width();
var focusy = (center.y - bbox.origin.y) / bbox.height();
var attrs = [
[
'on',
'true'
],
[
'type',
'gradienttitle'
],
[
'focus',
'100%'
],
[
'focusposition',
focusx + ' ' + focusy
],
[
'method',
'none'
]
];
this.addColors(attrs);
return attrs;
},
addColors: function (attrs) {
var options = this.srcElement.options;
var opacity = valueOrDefault(this.opacity, 1);
var stopColors = [];
var stops = options.fill.stops;
var baseColor = options.baseColor;
var colorsField = this.element.colors ? 'colors.value' : 'colors';
var color = stopColor(baseColor, stops[0], opacity);
var color2 = stopColor(baseColor, stops[stops.length - 1], opacity);
var stop;
for (var idx = 0; idx < stops.length; idx++) {
stop = stops[idx];
stopColors.push(math.round(stop.offset() * 100) + '% ' + stopColor(baseColor, stop, opacity));
}
attrs.push([
colorsField,
stopColors.join(',')
], [
'color',
color
], [
'color2',
color2
]);
}
});
var TransformNode = Node.extend({
init: function (srcElement, transform) {
this.transform = transform;
Node.fn.init.call(this, srcElement);
},
createElement: function () {
this.element = createElementVML('skew');
this.setTransform();
},
optionsChange: function (e) {
if (e.field === 'transform') {
this.refresh(this.srcElement.currentTransform());
}
},
refresh: function (transform) {
this.transform = transform;
this.setTransform();
},
transformOrigin: function () {
return '-0.5,-0.5';
},
setTransform: function () {
this.allAttr(this.mapTransform());
},
mapTransform: function () {
var transform = this.transform;
var attrs = [], matrix = toMatrix(transform);
if (matrix) {
matrix.round(TRANSFORM_PRECISION);
attrs.push([
'on',
'true'
], [
'matrix',
[
matrix.a,
matrix.c,
matrix.b,
matrix.d,
0,
0
].join(',')
], [
'offset',
matrix.e + 'px,' + matrix.f + 'px'
], [
'origin',
this.transformOrigin()
]);
} else {
attrs.push([
'on',
'false'
]);
}
return attrs;
}
});
var ShapeNode = ObserverNode.extend({
init: function (srcElement, transform, opacity) {
this.fill = this.createFillNode(srcElement, transform, opacity);
this.stroke = new StrokeNode(srcElement, opacity);
this.transform = this.createTransformNode(srcElement, transform);
ObserverNode.fn.init.call(this, srcElement);
},
attachTo: function (domElement, pos) {
this.fill.attachTo(this.element);
this.stroke.attachTo(this.element);
this.transform.attachTo(this.element);
Node.fn.attachTo.call(this, domElement, pos);
},
createFillNode: function (srcElement, transform, opacity) {
return new FillNode(srcElement, transform, opacity);
},
createTransformNode: function (srcElement, transform) {
return new TransformNode(srcElement, transform);
},
createElement: function () {
this.element = createElementVML('shape');
this.setCoordsize();
this.setStyle();
},
optionsChange: function (e) {
if (fillField(e.field)) {
this.fill.optionsChange(e);
} else if (e.field.indexOf('stroke') === 0) {
this.stroke.optionsChange(e);
} else if (e.field === 'transform') {
this.transform.optionsChange(e);
} else if (e.field === 'opacity') {
this.fill.setOpacity();
this.stroke.setOpacity();
}
ObserverNode.fn.optionsChange.call(this, e);
},
refreshTransform: function (transform) {
this.transform.refresh(this.srcElement.currentTransform(transform));
},
refreshOpacity: function (opacity) {
opacity *= valueOrDefault(this.srcElement.options.opacity, 1);
this.fill.refreshOpacity(opacity);
this.stroke.refreshOpacity(opacity);
},
mapStyle: function (width, height) {
var styles = ObserverNode.fn.mapStyle.call(this);
if (!width || !height) {
width = height = COORDINATE_MULTIPLE;
}
styles.push([
'position',
'absolute'
], [
'width',
width + 'px'
], [
'height',
height + 'px'
]);
var cursor = this.srcElement.options.cursor;
if (cursor) {
styles.push([
'cursor',
cursor
]);
}
return styles;
},
setCoordsize: function () {
this.allAttr([
[
'coordorigin',
'0 0'
],
[
'coordsize',
COORDINATE_SIZE + ' ' + COORDINATE_SIZE
]
]);
}
});
var PathDataNode = Node.extend({
createElement: function () {
this.element = createElementVML('path');
this.setPathData();
},
geometryChange: function () {
this.setPathData();
},
setPathData: function () {
this.attr('v', this.renderData());
},
renderData: function () {
return printPath(this.srcElement);
}
});
var PathNode = ShapeNode.extend({
init: function (srcElement, transform, opacity) {
this.pathData = this.createDataNode(srcElement);
ShapeNode.fn.init.call(this, srcElement, transform, opacity);
},
attachTo: function (domElement, pos) {
this.pathData.attachTo(this.element);
ShapeNode.fn.attachTo.call(this, domElement, pos);
},
createDataNode: function (srcElement) {
return new PathDataNode(srcElement);
},
geometryChange: function () {
this.pathData.geometryChange();
ShapeNode.fn.geometryChange.call(this);
}
});
var MultiPathDataNode = PathDataNode.extend({
renderData: function () {
var paths = this.srcElement.paths;
if (paths.length > 0) {
var result = [], i, open;
for (i = 0; i < paths.length; i++) {
open = i < paths.length - 1;
result.push(printPath(paths[i], open));
}
return result.join(' ');
}
}
});
var MultiPathNode = PathNode.extend({
createDataNode: function (srcElement) {
return new MultiPathDataNode(srcElement);
}
});
var CircleTransformNode = TransformNode.extend({
transformOrigin: function () {
var boundingBox = this.srcElement.geometry().bbox(), center = boundingBox.center(), originX = -ceil(center.x) / ceil(boundingBox.width()), originY = -ceil(center.y) / ceil(boundingBox.height());
return originX + ',' + originY;
}
});
var CircleNode = ShapeNode.extend({
createElement: function () {
this.element = createElementVML('oval');
this.setStyle();
},
createTransformNode: function (srcElement, transform) {
return new CircleTransformNode(srcElement, transform);
},
geometryChange: function () {
ShapeNode.fn.geometryChange.call(this);
this.setStyle();
this.refreshTransform();
},
mapStyle: function () {
var geometry = this.srcElement.geometry();
var radius = geometry.radius;
var center = geometry.center;
var diameter = ceil(radius * 2);
var styles = ShapeNode.fn.mapStyle.call(this, diameter, diameter);
styles.push([
'left',
ceil(center.x - radius) + 'px'
], [
'top',
ceil(center.y - radius) + 'px'
]);
return styles;
}
});
var ArcDataNode = PathDataNode.extend({
renderData: function () {
return printPath(this.srcElement.toPath());
}
});
var ArcNode = PathNode.extend({
createDataNode: function (srcElement) {
return new ArcDataNode(srcElement);
}
});
var TextPathDataNode = PathDataNode.extend({
createElement: function () {
PathDataNode.fn.createElement.call(this);
this.attr('textpathok', true);
},
renderData: function () {
var rect = this.srcElement.rect();
var center = rect.center();
return 'm ' + printPoints([new g.Point(rect.topLeft().x, center.y)]) + ' l ' + printPoints([new g.Point(rect.bottomRight().x, center.y)]);
}
});
var TextPathNode = Node.extend({
createElement: function () {
this.element = createElementVML('textpath');
this.attr('on', true);
this.attr('fitpath', false);
this.setStyle();
this.setString();
},
optionsChange: function (e) {
if (e.field === 'content') {
this.setString();
} else {
this.setStyle();
}
Node.fn.optionsChange.call(this, e);
},
mapStyle: function () {
return [[
'font',
this.srcElement.options.font
]];
},
setString: function () {
this.attr('string', this.srcElement.content());
}
});
var TextNode = PathNode.extend({
init: function (srcElement, transform, opacity) {
this.path = new TextPathNode(srcElement);
PathNode.fn.init.call(this, srcElement, transform, opacity);
},
createDataNode: function (srcElement) {
return new TextPathDataNode(srcElement);
},
attachTo: function (domElement, pos) {
this.path.attachTo(this.element);
PathNode.fn.attachTo.call(this, domElement, pos);
},
optionsChange: function (e) {
if (e.field === 'font' || e.field === 'content') {
this.path.optionsChange(e);
this.pathData.geometryChange(e);
}
PathNode.fn.optionsChange.call(this, e);
}
});
var ImagePathDataNode = PathDataNode.extend({
renderData: function () {
var rect = this.srcElement.rect();
var path = new d.Path().moveTo(rect.topLeft()).lineTo(rect.topRight()).lineTo(rect.bottomRight()).lineTo(rect.bottomLeft()).close();
return printPath(path);
}
});
var ImageFillNode = TransformNode.extend({
init: function (srcElement, transform, opacity) {
this.opacity = opacity;
TransformNode.fn.init.call(this, srcElement, transform);
},
createElement: function () {
this.element = createElementVML('fill');
this.attr('type', 'frame');
this.attr('rotate', true);
this.setOpacity();
this.setSrc();
this.setTransform();
},
optionsChange: function (e) {
if (e.field === 'src') {
this.setSrc();
}
TransformNode.fn.optionsChange.call(this, e);
},
geometryChange: function () {
this.refresh();
},
refreshOpacity: function (opacity) {
this.opacity = opacity;
this.setOpacity();
},
setOpacity: function () {
var attrs = [];
this.mapOpacityTo(attrs, this.srcElement.options.opacity);
this.allAttr(attrs);
},
setSrc: function () {
this.attr('src', this.srcElement.src());
},
mapTransform: function () {
var img = this.srcElement;
var rawbbox = img.rawBBox();
var rawcenter = rawbbox.center();
var fillOrigin = COORDINATE_MULTIPLE / 2;
var fillSize = COORDINATE_MULTIPLE;
var x;
var y;
var width = rawbbox.width() / fillSize;
var height = rawbbox.height() / fillSize;
var angle = 0;
var transform = this.transform;
if (transform) {
var matrix = toMatrix(transform);
var sx = sqrt(matrix.a * matrix.a + matrix.b * matrix.b);
var sy = sqrt(matrix.c * matrix.c + matrix.d * matrix.d);
width *= sx;
height *= sy;
var ax = deg(atan2(matrix.b, matrix.d));
var ay = deg(atan2(-matrix.c, matrix.a));
angle = (ax + ay) / 2;
if (angle !== 0) {
var center = img.bbox().center();
x = (center.x - fillOrigin) / fillSize;
y = (center.y - fillOrigin) / fillSize;
} else {
x = (rawcenter.x * sx + matrix.e - fillOrigin) / fillSize;
y = (rawcenter.y * sy + matrix.f - fillOrigin) / fillSize;
}
} else {
x = (rawcenter.x - fillOrigin) / fillSize;
y = (rawcenter.y - fillOrigin) / fillSize;
}
width = round(width, TRANSFORM_PRECISION);
height = round(height, TRANSFORM_PRECISION);
x = round(x, TRANSFORM_PRECISION);
y = round(y, TRANSFORM_PRECISION);
angle = round(angle, TRANSFORM_PRECISION);
return [
[
'size',
width + ',' + height
],
[
'position',
x + ',' + y
],
[
'angle',
angle
]
];
}
});
var ImageNode = PathNode.extend({
createFillNode: function (srcElement, transform, opacity) {
return new ImageFillNode(srcElement, transform, opacity);
},
createDataNode: function (srcElement) {
return new ImagePathDataNode(srcElement);
},
optionsChange: function (e) {
if (e.field === 'src' || e.field === 'transform') {
this.fill.optionsChange(e);
}
PathNode.fn.optionsChange.call(this, e);
},
geometryChange: function () {
this.fill.geometryChange();
PathNode.fn.geometryChange.call(this);
},
refreshTransform: function (transform) {
PathNode.fn.refreshTransform.call(this, transform);
this.fill.refresh(this.srcElement.currentTransform(transform));
}
});
var RectDataNode = PathDataNode.extend({
renderData: function () {
var rect = this.srcElement.geometry();
var parts = [
'm',
printPoints([rect.topLeft()]),
'l',
printPoints([
rect.topRight(),
rect.bottomRight(),
rect.bottomLeft()
]),
'x e'
];
return parts.join(' ');
}
});
var RectNode = PathNode.extend({
createDataNode: function (srcElement) {
return new RectDataNode(srcElement);
}
});
var nodeMap = {
Group: GroupNode,
Text: TextNode,
Path: PathNode,
MultiPath: MultiPathNode,
Circle: CircleNode,
Arc: ArcNode,
Image: ImageNode,
Rect: RectNode
};
function enableVML() {
if (doc.namespaces && !doc.namespaces.kvml) {
doc.namespaces.add('kvml', 'urn:schemas-microsoft-com:vml');
var stylesheet = doc.styleSheets.length > 30 ? doc.styleSheets[0] : doc.createStyleSheet();
stylesheet.addRule('.kvml', 'behavior:url(#default#VML)');
}
}
function createElementVML(type) {
var element = doc.createElement('kvml:' + type);
element.className = 'kvml';
return element;
}
function printPoints(points) {
var length = points.length;
var result = [];
for (var i = 0; i < length; i++) {
result.push(points[i].scaleCopy(COORDINATE_MULTIPLE).toString(0, ','));
}
return result.join(' ');
}
function printPath(path, open) {
var segments = path.segments, length = segments.length;
if (length > 0) {
var parts = [], output, type, currentType, i;
for (i = 1; i < length; i++) {
type = segmentType(segments[i - 1], segments[i]);
if (type !== currentType) {
currentType = type;
parts.push(type);
}
if (type === 'l') {
parts.push(printPoints([segments[i].anchor()]));
} else {
parts.push(printPoints([
segments[i - 1].controlOut(),
segments[i].controlIn(),
segments[i].anchor()
]));
}
}
output = 'm ' + printPoints([segments[0].anchor()]) + ' ' + parts.join(' ');
if (path.options.closed) {
output += ' x';
}
if (open !== true) {
output += ' e';
}
return output;
}
}
function segmentType(segmentStart, segmentEnd) {
return segmentStart.controlOut() && segmentEnd.controlIn() ? 'c' : 'l';
}
function fillField(field) {
return field.indexOf('fill') === 0 || field.indexOf(GRADIENT) === 0;
}
function stopColor(baseColor, stop, baseOpacity) {
var opacity = baseOpacity * valueOrDefault(stop.opacity(), 1);
var color;
if (baseColor) {
color = blendColors(baseColor, stop.color(), opacity);
} else {
color = blendColors(stop.color(), '#fff', 1 - opacity);
}
return color;
}
function blendColors(base, overlay, alpha) {
var baseColor = new Color(base), overlayColor = new Color(overlay), r = blendChannel(baseColor.r, overlayColor.r, alpha), g = blendChannel(baseColor.g, overlayColor.g, alpha), b = blendChannel(baseColor.b, overlayColor.b, alpha);
return new Color(r, g, b).toHex();
}
function blendChannel(a, b, alpha) {
return math.round(alpha * b + (1 - alpha) * a);
}
kendo.support.vml = function () {
var browser = kendo.support.browser;
return browser.msie && browser.version < 9;
}();
var EMPTY_CLIP = 'inherit';
if (kendo.support.browser.msie && kendo.support.browser.version < 8) {
EMPTY_CLIP = 'rect(auto auto auto auto)';
}
if (kendo.support.vml) {
d.SurfaceFactory.current.register('vml', Surface, 30);
}
deepExtend(d, {
vml: {
ArcDataNode: ArcDataNode,
ArcNode: ArcNode,
CircleTransformNode: CircleTransformNode,
CircleNode: CircleNode,
FillNode: FillNode,
GroupNode: GroupNode,
ImageNode: ImageNode,
ImageFillNode: ImageFillNode,
ImagePathDataNode: ImagePathDataNode,
MultiPathDataNode: MultiPathDataNode,
MultiPathNode: MultiPathNode,
Node: Node,
PathDataNode: PathDataNode,
PathNode: PathNode,
RectDataNode: RectDataNode,
RectNode: RectNode,
RootNode: RootNode,
StrokeNode: StrokeNode,
Surface: Surface,
TextNode: TextNode,
TextPathNode: TextPathNode,
TextPathDataNode: TextPathDataNode,
TransformNode: TransformNode
}
});
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/html', [
'kendo.color',
'drawing/shapes',
'util/main',
'util/text-metrics'
], f);
}(function () {
(function ($, parseFloat, Math) {
'use strict';
var drawing = kendo.drawing;
var geo = kendo.geometry;
var slice = Array.prototype.slice;
var browser = kendo.support.browser;
var romanNumeral = kendo.util.arabicToRoman;
var KENDO_PSEUDO_ELEMENT = 'KENDO-PSEUDO-ELEMENT';
var IMAGE_CACHE = {};
var nodeInfo = {};
nodeInfo._root = nodeInfo;
var TextRect = drawing.Text.extend({
nodeType: 'Text',
init: function (str, rect, options) {
drawing.Text.fn.init.call(this, str, rect.getOrigin(), options);
this._pdfRect = rect;
},
rect: function () {
return this._pdfRect;
},
rawBBox: function () {
return this._pdfRect;
}
});
function drawDOM(element, options) {
if (!options) {
options = {};
}
var defer = $.Deferred();
element = $(element)[0];
if (!element) {
return defer.reject('No element to export');
}
if (typeof window.getComputedStyle != 'function') {
throw new Error('window.getComputedStyle is missing. You are using an unsupported browser, or running in IE8 compatibility mode. Drawing HTML is supported in Chrome, Firefox, Safari and IE9+.');
}
if (kendo.pdf) {
kendo.pdf.defineFont(getFontFaces(element.ownerDocument));
}
function doOne(element) {
var group = new drawing.Group();
var pos = element.getBoundingClientRect();
setTransform(group, [
1,
0,
0,
1,
-pos.left,
-pos.top
]);
nodeInfo._clipbox = false;
nodeInfo._matrix = geo.Matrix.unit();
nodeInfo._stackingContext = {
element: element,
group: group
};
if (options.avoidLinks === true) {
nodeInfo._avoidLinks = 'a';
} else {
nodeInfo._avoidLinks = options.avoidLinks;
}
$(element).addClass('k-pdf-export');
renderElement(element, group);
$(element).removeClass('k-pdf-export');
return group;
}
cacheImages(element, function () {
var forceBreak = options && options.forcePageBreak;
var hasPaperSize = options && options.paperSize && options.paperSize != 'auto';
var paperOptions = hasPaperSize && kendo.pdf.getPaperOptions(function (key, def) {
return key in options ? options[key] : def;
});
var pageWidth = hasPaperSize && paperOptions.paperSize[0];
var pageHeight = hasPaperSize && paperOptions.paperSize[1];
var margin = options.margin && paperOptions.margin;
if (forceBreak || pageHeight) {
if (!margin) {
margin = {
left: 0,
top: 0,
right: 0,
bottom: 0
};
}
var group = new drawing.Group({
pdf: {
multiPage: true,
paperSize: hasPaperSize ? paperOptions.paperSize : 'auto'
}
});
handlePageBreaks(function (x) {
if (options.progress) {
var canceled = false, pageNum = 0;
(function next() {
if (pageNum < x.pages.length) {
group.append(doOne(x.pages[pageNum]));
options.progress({
pageNum: ++pageNum,
totalPages: x.pages.length,
cancel: function () {
canceled = true;
}
});
if (!canceled) {
setTimeout(next);
} else {
x.container.parentNode.removeChild(x.container);
}
} else {
x.container.parentNode.removeChild(x.container);
defer.resolve(group);
}
}());
} else {
x.pages.forEach(function (page) {
group.append(doOne(page));
});
x.container.parentNode.removeChild(x.container);
defer.resolve(group);
}
}, element, forceBreak, pageWidth ? pageWidth - margin.left - margin.right : null, pageHeight ? pageHeight - margin.top - margin.bottom : null, margin, options);
} else {
defer.resolve(doOne(element));
}
});
function makeTemplate(template) {
if (template != null) {
if (typeof template == 'string') {
template = kendo.template(template.replace(/^\s+|\s+$/g, ''));
}
if (typeof template == 'function') {
return function (data) {
var el = template(data);
if (el) {
if (typeof el == 'string') {
el = el.replace(/^\s+|\s+$/g, '');
}
return $(el)[0];
}
};
}
return function () {
return $(template).clone()[0];
};
}
}
function cloneNodes(el) {
var clone = el.cloneNode(false);
if (el.nodeType == 1) {
var $el = $(el), $clone = $(clone), i;
var data = $el.data();
for (i in data) {
$clone.data(i, data[i]);
}
if (/^canvas$/i.test(el.tagName)) {
clone.getContext('2d').drawImage(el, 0, 0);
} else if (/^input$/i.test(el.tagName)) {
el.removeAttribute('name');
} else {
for (i = el.firstChild; i; i = i.nextSibling) {
clone.appendChild(cloneNodes(i));
}
}
}
return clone;
}
function handlePageBreaks(callback, element, forceBreak, pageWidth, pageHeight, margin, options) {
var template = makeTemplate(options.template);
var doc = element.ownerDocument;
var pages = [];
var copy = cloneNodes(element);
var container = doc.createElement('KENDO-PDF-DOCUMENT');
var adjust = 0;
$(copy).find('tfoot').each(function () {
this.parentNode.appendChild(this);
});
$(copy).find('ol').each(function () {
$(this).children().each(function (index) {
this.setAttribute('kendo-split-index', index);
});
});
$(container).css({
display: 'block',
position: 'absolute',
boxSizing: 'content-box',
left: '-10000px',
top: '-10000px'
});
if (pageWidth) {
$(container).css({
width: pageWidth,
paddingLeft: margin.left,
paddingRight: margin.right
});
$(copy).css({ overflow: 'hidden' });
}
container.appendChild(copy);
element.parentNode.insertBefore(container, element);
if (options.beforePageBreak) {
setTimeout(function () {
options.beforePageBreak(container, doPageBreak);
}, 15);
} else {
setTimeout(doPageBreak, 15);
}
function doPageBreak() {
if (forceBreak != '-' || pageHeight) {
splitElement(copy);
}
var page = makePage();
copy.parentNode.insertBefore(page, copy);
page.appendChild(copy);
if (template) {
var count = pages.length;
pages.forEach(function (page, i) {
var el = template({
element: page,
pageNum: i + 1,
totalPages: pages.length
});
if (el) {
page.appendChild(el);
cacheImages(el, function () {
if (--count === 0) {
next();
}
});
}
});
} else {
next();
}
function next() {
whenImagesAreActuallyLoaded(pages, function () {
callback({
pages: pages,
container: container
});
});
}
}
function splitElement(element) {
var style = getComputedStyle(element);
var bottomPadding = parseFloat(getPropertyValue(style, 'padding-bottom'));
var bottomBorder = parseFloat(getPropertyValue(style, 'border-bottom-width'));
var saveAdjust = adjust;
adjust += bottomPadding + bottomBorder;
var isFirst = true;
for (var el = element.firstChild; el; el = el.nextSibling) {
if (el.nodeType == 1) {
isFirst = false;
var jqel = $(el);
if (jqel.is(forceBreak)) {
breakAtElement(el);
continue;
}
if (!pageHeight) {
splitElement(el);
continue;
}
if (!/^(?:static|relative)$/.test(getPropertyValue(getComputedStyle(el), 'position'))) {
continue;
}
var fall = fallsOnMargin(el);
if (fall == 1) {
breakAtElement(el);
} else if (fall) {
if (jqel.data('kendoChart') || /^(?:img|tr|iframe|svg|object|canvas|input|textarea|select|video|h[1-6])/i.test(el.tagName)) {
breakAtElement(el);
} else {
splitElement(el);
}
} else {
splitElement(el);
}
} else if (el.nodeType == 3 && pageHeight) {
splitText(el, isFirst);
isFirst = false;
}
}
adjust = saveAdjust;
}
function firstInParent(el) {
var p = el.parentNode, first = p.firstChild;
if (el === first) {
return true;
}
if (el === p.children[0]) {
if (first.nodeType == 7 || first.nodeType == 8) {
return true;
}
if (first.nodeType == 3) {
return !/\S/.test(first.data);
}
}
return false;
}
function breakAtElement(el) {
if (el.nodeType == 1 && el !== copy && firstInParent(el)) {
return breakAtElement(el.parentNode);
}
var colgroup = $(el).closest('table').find('colgroup');
var page = makePage();
var range = doc.createRange();
range.setStartBefore(copy);
range.setEndBefore(el);
page.appendChild(range.extractContents());
copy.parentNode.insertBefore(page, copy);
if (colgroup[0]) {
colgroup.clone().prependTo($(el).closest('table'));
}
}
function makePage() {
var page = doc.createElement('KENDO-PDF-PAGE');
$(page).css({
display: 'block',
boxSizing: 'content-box',
width: pageWidth || 'auto',
padding: margin.top + 'px ' + margin.right + 'px ' + margin.bottom + 'px ' + margin.left + 'px',
position: 'relative',
height: pageHeight || 'auto',
overflow: pageHeight || pageWidth ? 'hidden' : 'visible',
clear: 'both'
});
if (options && options.pageClassName) {
page.className = options.pageClassName;
}
pages.push(page);
return page;
}
function fallsOnMargin(thing) {
var box = thing.getBoundingClientRect();
if (box.width === 0 || box.height === 0) {
return 0;
}
var top = copy.getBoundingClientRect().top;
var available = pageHeight - adjust;
return box.height > available ? 3 : box.top - top > available ? 1 : box.bottom - top > available ? 2 : 0;
}
function splitText(node, isFirst) {
if (!/\S/.test(node.data)) {
return;
}
var len = node.data.length;
var range = doc.createRange();
range.selectNodeContents(node);
var fall = fallsOnMargin(range);
if (!fall) {
return;
}
var nextnode = node;
if (fall == 1) {
if (isFirst) {
breakAtElement(node.parentNode);
} else {
breakAtElement(node);
}
} else {
(function findEOP(min, pos, max) {
range.setEnd(node, pos);
if (min == pos || pos == max) {
return pos;
}
if (fallsOnMargin(range)) {
return findEOP(min, min + pos >> 1, pos);
} else {
return findEOP(pos, pos + max >> 1, max);
}
}(0, len >> 1, len));
if (!/\S/.test(range.toString()) && isFirst) {
breakAtElement(node.parentNode);
} else {
nextnode = node.splitText(range.endOffset);
var page = makePage();
range.setStartBefore(copy);
page.appendChild(range.extractContents());
copy.parentNode.insertBefore(page, copy);
}
}
splitText(nextnode);
}
}
return defer.promise();
}
drawing.drawDOM = drawDOM;
drawDOM.getFontFaces = getFontFaces;
var parseBackgroundImage = function () {
var tok_linear_gradient = /^((-webkit-|-moz-|-o-|-ms-)?linear-gradient\s*)\(/;
var tok_percent = /^([-0-9.]+%)/;
var tok_length = /^([-0-9.]+px)/;
var tok_keyword = /^(left|right|top|bottom|to|center)\W/;
var tok_angle = /^([-0-9.]+(deg|grad|rad|turn))/;
var tok_whitespace = /^(\s+)/;
var tok_popen = /^(\()/;
var tok_pclose = /^(\))/;
var tok_comma = /^(,)/;
var tok_url = /^(url)\(/;
var tok_content = /^(.*?)\)/;
var cache1 = {}, cache2 = {};
function parse(input) {
var orig = input;
if (hasOwnProperty(cache1, orig)) {
return cache1[orig];
}
function skip_ws() {
var m = tok_whitespace.exec(input);
if (m) {
input = input.substr(m[1].length);
}
}
function read(token) {
skip_ws();
var m = token.exec(input);
if (m) {
input = input.substr(m[1].length);
return m[1];
}
}
function read_stop() {
var color = kendo.parseColor(input, true);
var length, percent;
if (color) {
input = input.substr(color.match[0].length);
color = color.toRGB();
if (!(length = read(tok_length))) {
percent = read(tok_percent);
}
return {
color: color,
length: length,
percent: percent
};
}
}
function read_linear_gradient(propName) {
var angle;
var to1, to2;
var stops = [];
var reverse = false;
if (read(tok_popen)) {
angle = read(tok_angle);
if (angle) {
angle = parseAngle(angle);
read(tok_comma);
} else {
to1 = read(tok_keyword);
if (to1 == 'to') {
to1 = read(tok_keyword);
} else if (to1 && /^-/.test(propName)) {
reverse = true;
}
to2 = read(tok_keyword);
read(tok_comma);
}
if (/-moz-/.test(propName) && angle == null && to1 == null) {
var x = read(tok_percent), y = read(tok_percent);
reverse = true;
if (x == '0%') {
to1 = 'left';
} else if (x == '100%') {
to1 = 'right';
}
if (y == '0%') {
to2 = 'top';
} else if (y == '100%') {
to2 = 'bottom';
}
read(tok_comma);
}
while (input && !read(tok_pclose)) {
var stop = read_stop();
if (!stop) {
break;
}
stops.push(stop);
read(tok_comma);
}
return {
type: 'linear',
angle: angle,
to: to1 && to2 ? to1 + ' ' + to2 : to1 ? to1 : to2 ? to2 : null,
stops: stops,
reverse: reverse
};
}
}
function read_url() {
if (read(tok_popen)) {
var url = read(tok_content);
url = url.replace(/^['"]+|["']+$/g, '');
read(tok_pclose);
return {
type: 'url',
url: url
};
}
}
var tok;
if (tok = read(tok_linear_gradient)) {
tok = read_linear_gradient(tok);
} else if (tok = read(tok_url)) {
tok = read_url();
}
return cache1[orig] = tok || { type: 'none' };
}
return function (input) {
if (hasOwnProperty(cache2, input)) {
return cache2[input];
}
return cache2[input] = splitProperty(input).map(parse);
};
}();
var splitProperty = function () {
var cache = {};
return function (input, separator) {
if (!separator) {
separator = /^\s*,\s*/;
}
var cacheKey = input + separator;
if (hasOwnProperty(cache, cacheKey)) {
return cache[cacheKey];
}
var ret = [];
var last = 0, pos = 0;
var in_paren = 0;
var in_string = false;
var m;
function looking_at(rx) {
return m = rx.exec(input.substr(pos));
}
function trim(str) {
return str.replace(/^\s+|\s+$/g, '');
}
while (pos < input.length) {
if (!in_string && looking_at(/^[\(\[\{]/)) {
in_paren++;
pos++;
} else if (!in_string && looking_at(/^[\)\]\}]/)) {
in_paren--;
pos++;
} else if (!in_string && looking_at(/^[\"\']/)) {
in_string = m[0];
pos++;
} else if (in_string == '\'' && looking_at(/^\\\'/)) {
pos += 2;
} else if (in_string == '"' && looking_at(/^\\\"/)) {
pos += 2;
} else if (in_string == '\'' && looking_at(/^\'/)) {
in_string = false;
pos++;
} else if (in_string == '"' && looking_at(/^\"/)) {
in_string = false;
pos++;
} else if (looking_at(separator)) {
if (!in_string && !in_paren && pos > last) {
ret.push(trim(input.substring(last, pos)));
last = pos + m[0].length;
}
pos += m[0].length;
} else {
pos++;
}
}
if (last < pos) {
ret.push(trim(input.substring(last, pos)));
}
return cache[cacheKey] = ret;
};
}();
var getFontURL = function () {
var cache = {};
return function (el) {
var url = cache[el];
if (!url) {
var m;
if (m = /url\((['"]?)([^'")]*?)\1\)\s+format\((['"]?)truetype\3\)/.exec(el)) {
url = cache[el] = m[2];
} else if (m = /url\((['"]?)([^'")]*?\.ttf)\1\)/.exec(el)) {
url = cache[el] = m[2];
}
}
return url;
};
}();
function getFontFaces(doc) {
if (doc == null) {
doc = document;
}
var result = {};
for (var i = 0; i < doc.styleSheets.length; ++i) {
doStylesheet(doc.styleSheets[i]);
}
return result;
function doStylesheet(ss) {
if (ss) {
var rules = null;
try {
rules = ss.cssRules;
} catch (ex) {
}
if (rules) {
addRules(ss, rules);
}
}
}
function findFonts(rule) {
var src = getPropertyValue(rule.style, 'src');
if (src) {
return splitProperty(src).reduce(function (a, el) {
var font = getFontURL(el);
if (font) {
a.push(font);
}
return a;
}, []);
} else {
var font = getFontURL(rule.cssText);
return font ? [font] : [];
}
}
function addRules(styleSheet, rules) {
for (var i = 0; i < rules.length; ++i) {
var r = rules[i];
switch (r.type) {
case 3:
doStylesheet(r.styleSheet);
break;
case 5:
var style = r.style;
var family = splitProperty(getPropertyValue(style, 'font-family'));
var bold = /^([56789]00|bold)$/i.test(getPropertyValue(style, 'font-weight'));
var italic = 'italic' == getPropertyValue(style, 'font-style');
var src = findFonts(r);
if (src.length > 0) {
addRule(styleSheet, family, bold, italic, src[0]);
}
}
}
}
function addRule(styleSheet, names, bold, italic, url) {
if (!/^data:/i.test(url)) {
if (!(/^[^\/:]+:\/\//.test(url) || /^\//.test(url))) {
url = String(styleSheet.href).replace(/[^\/]*$/, '') + url;
}
}
names.forEach(function (name) {
name = name.replace(/^(['"]?)(.*?)\1$/, '$2');
if (bold) {
name += '|bold';
}
if (italic) {
name += '|italic';
}
result[name] = url;
});
}
}
function hasOwnProperty(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
function getCounter(name) {
name = '_counter_' + name;
return nodeInfo[name];
}
function getAllCounters(name) {
var values = [], p = nodeInfo;
name = '_counter_' + name;
while (p) {
if (hasOwnProperty(p, name)) {
values.push(p[name]);
}
p = Object.getPrototypeOf(p);
}
return values.reverse();
}
function incCounter(name, inc) {
var p = nodeInfo;
name = '_counter_' + name;
while (p && !hasOwnProperty(p, name)) {
p = Object.getPrototypeOf(p);
}
if (!p) {
p = nodeInfo._root;
}
p[name] = (p[name] || 0) + (inc == null ? 1 : inc);
}
function resetCounter(name, val) {
name = '_counter_' + name;
nodeInfo[name] = val == null ? 0 : val;
}
function doCounters(a, f, def) {
for (var i = 0; i < a.length;) {
var name = a[i++];
var val = parseFloat(a[i]);
if (isNaN(val)) {
f(name, def);
} else {
f(name, val);
++i;
}
}
}
function parseColor(str, css) {
var color = kendo.parseColor(str);
if (color) {
color = color.toRGB();
if (css) {
color = color.toCssRgba();
} else if (color.a === 0) {
color = null;
}
}
return color;
}
function whenImagesAreActuallyLoaded(elements, callback) {
var pending = 0;
elements.forEach(function (el) {
var images = el.querySelectorAll('img');
for (var i = 0; i < images.length; ++i) {
var img = images[i];
if (!img.complete) {
pending++;
img.onload = img.onerror = next;
}
}
});
if (!pending) {
next();
}
function next() {
if (--pending <= 0) {
callback();
}
}
}
function cacheImages(element, callback) {
var urls = [];
function add(url) {
if (!IMAGE_CACHE[url]) {
IMAGE_CACHE[url] = true;
urls.push(url);
}
}
(function dive(element) {
if (/^img$/i.test(element.tagName)) {
add(element.src);
}
parseBackgroundImage(getPropertyValue(getComputedStyle(element), 'background-image')).forEach(function (bg) {
if (bg.type == 'url') {
add(bg.url);
}
});
if (element.children) {
slice.call(element.children).forEach(dive);
}
}(element));
var count = urls.length;
function next() {
if (--count <= 0) {
callback();
}
}
if (count === 0) {
next();
}
urls.forEach(function (url) {
var img = IMAGE_CACHE[url] = new Image();
if (!/^data:/i.test(url)) {
img.crossOrigin = 'Anonymous';
}
img.src = url;
if (img.complete) {
next();
} else {
img.onload = next;
img.onerror = function () {
IMAGE_CACHE[url] = null;
next();
};
}
});
}
function alphaNumeral(n) {
var result = '';
do {
var r = n % 26;
result = String.fromCharCode(97 + r) + result;
n = Math.floor(n / 26);
} while (n > 0);
return result;
}
function pushNodeInfo(element, style, group) {
nodeInfo = Object.create(nodeInfo);
nodeInfo[element.tagName.toLowerCase()] = {
element: element,
style: style
};
var decoration = getPropertyValue(style, 'text-decoration');
if (decoration && decoration != 'none') {
var color = getPropertyValue(style, 'color');
decoration.split(/\s+/g).forEach(function (name) {
if (!nodeInfo[name]) {
nodeInfo[name] = color;
}
});
}
if (createsStackingContext(style)) {
nodeInfo._stackingContext = {
element: element,
group: group
};
}
}
function popNodeInfo() {
nodeInfo = Object.getPrototypeOf(nodeInfo);
}
function updateClipbox(path) {
if (nodeInfo._clipbox != null) {
var box = path.bbox(nodeInfo._matrix);
if (nodeInfo._clipbox) {
nodeInfo._clipbox = geo.Rect.intersect(nodeInfo._clipbox, box);
} else {
nodeInfo._clipbox = box;
}
}
}
function emptyClipbox() {
var cb = nodeInfo._clipbox;
if (cb == null) {
return true;
}
if (cb) {
return cb.width() === 0 || cb.height() === 0;
}
}
function createsStackingContext(style) {
function prop(name) {
return getPropertyValue(style, name);
}
if (prop('transform') != 'none' || prop('position') != 'static' && prop('z-index') != 'auto' || prop('opacity') < 1) {
return true;
}
}
function getComputedStyle(element, pseudoElt) {
return window.getComputedStyle(element, pseudoElt || null);
}
function getPropertyValue(style, prop) {
return style.getPropertyValue(prop) || browser.webkit && style.getPropertyValue('-webkit-' + prop) || browser.mozilla && style.getPropertyValue('-moz-' + prop) || browser.opera && style.getPropertyValue('-o-' + prop) || browser.msie && style.getPropertyValue('-ms-' + prop);
}
function pleaseSetPropertyValue(style, prop, value, important) {
style.setProperty(prop, value, important);
if (browser.webkit) {
style.setProperty('-webkit-' + prop, value, important);
} else if (browser.mozilla) {
style.setProperty('-moz-' + prop, value, important);
} else if (browser.opera) {
style.setProperty('-o-' + prop, value, important);
} else if (browser.msie) {
style.setProperty('-ms-' + prop, value, important);
prop = 'ms' + prop.replace(/(^|-)([a-z])/g, function (s, p1, p2) {
return p1 + p2.toUpperCase();
});
style[prop] = value;
}
}
function actuallyGetRangeBoundingRect(range) {
if (browser.msie || browser.chrome) {
var a = range.getClientRects(), box, count = 0;
if (a.length <= 3) {
for (var i = 0; i < a.length; ++i) {
if (a[i].width <= 1) {
count++;
} else {
box = a[i];
}
}
if (count == a.length - 1) {
return box;
}
}
}
return range.getBoundingClientRect();
}
function getBorder(style, side) {
side = 'border-' + side;
return {
width: parseFloat(getPropertyValue(style, side + '-width')),
style: getPropertyValue(style, side + '-style'),
color: parseColor(getPropertyValue(style, side + '-color'), true)
};
}
function saveStyle(element, func) {
var prev = element.style.cssText;
var result = func();
element.style.cssText = prev;
return result;
}
function getBorderRadius(style, side) {
var r = getPropertyValue(style, 'border-' + side + '-radius').split(/\s+/g).map(parseFloat);
if (r.length == 1) {
r.push(r[0]);
}
return sanitizeRadius({
x: r[0],
y: r[1]
});
}
function getContentBox(element) {
var box = element.getBoundingClientRect();
box = innerBox(box, 'border-*-width', element);
box = innerBox(box, 'padding-*', element);
return box;
}
function innerBox(box, prop, element) {
var style, wt, wr, wb, wl;
if (typeof prop == 'string') {
style = getComputedStyle(element);
wt = parseFloat(getPropertyValue(style, prop.replace('*', 'top')));
wr = parseFloat(getPropertyValue(style, prop.replace('*', 'right')));
wb = parseFloat(getPropertyValue(style, prop.replace('*', 'bottom')));
wl = parseFloat(getPropertyValue(style, prop.replace('*', 'left')));
} else if (typeof prop == 'number') {
wt = wr = wb = wl = prop;
}
return {
top: box.top + wt,
right: box.right - wr,
bottom: box.bottom - wb,
left: box.left + wl,
width: box.right - box.left - wr - wl,
height: box.bottom - box.top - wb - wt
};
}
function getTransform(style) {
var transform = getPropertyValue(style, 'transform');
if (transform == 'none') {
return null;
}
var matrix = /^\s*matrix\(\s*(.*?)\s*\)\s*$/.exec(transform);
if (matrix) {
var origin = getPropertyValue(style, 'transform-origin');
matrix = matrix[1].split(/\s*,\s*/g).map(parseFloat);
origin = origin.split(/\s+/g).map(parseFloat);
return {
matrix: matrix,
origin: origin
};
}
}
function radiansToDegrees(radians) {
return 180 * radians / Math.PI % 360;
}
function parseAngle(angle) {
var num = parseFloat(angle);
if (/grad$/.test(angle)) {
return Math.PI * num / 200;
} else if (/rad$/.test(angle)) {
return num;
} else if (/turn$/.test(angle)) {
return Math.PI * num * 2;
} else if (/deg$/.test(angle)) {
return Math.PI * num / 180;
}
}
function setTransform(shape, m) {
m = new geo.Matrix(m[0], m[1], m[2], m[3], m[4], m[5]);
shape.transform(m);
return m;
}
function setClipping(shape, clipPath) {
shape.clip(clipPath);
}
function addArcToPath(path, x, y, options) {
var points = new geo.Arc([
x,
y
], options).curvePoints(), i = 1;
while (i < points.length) {
path.curveTo(points[i++], points[i++], points[i++]);
}
}
function sanitizeRadius(r) {
if (r.x <= 0 || r.y <= 0) {
r.x = r.y = 0;
}
return r;
}
function adjustBorderRadiusForBox(box, rTL, rTR, rBR, rBL) {
var tl_x = Math.max(0, rTL.x), tl_y = Math.max(0, rTL.y);
var tr_x = Math.max(0, rTR.x), tr_y = Math.max(0, rTR.y);
var br_x = Math.max(0, rBR.x), br_y = Math.max(0, rBR.y);
var bl_x = Math.max(0, rBL.x), bl_y = Math.max(0, rBL.y);
var f = Math.min(box.width / (tl_x + tr_x), box.height / (tr_y + br_y), box.width / (br_x + bl_x), box.height / (bl_y + tl_y));
if (f < 1) {
tl_x *= f;
tl_y *= f;
tr_x *= f;
tr_y *= f;
br_x *= f;
br_y *= f;
bl_x *= f;
bl_y *= f;
}
return {
tl: {
x: tl_x,
y: tl_y
},
tr: {
x: tr_x,
y: tr_y
},
br: {
x: br_x,
y: br_y
},
bl: {
x: bl_x,
y: bl_y
}
};
}
function elementRoundBox(element, box, type) {
var style = getComputedStyle(element);
var rTL = getBorderRadius(style, 'top-left');
var rTR = getBorderRadius(style, 'top-right');
var rBL = getBorderRadius(style, 'bottom-left');
var rBR = getBorderRadius(style, 'bottom-right');
if (type == 'padding' || type == 'content') {
var bt = getBorder(style, 'top');
var br = getBorder(style, 'right');
var bb = getBorder(style, 'bottom');
var bl = getBorder(style, 'left');
rTL.x -= bl.width;
rTL.y -= bt.width;
rTR.x -= br.width;
rTR.y -= bt.width;
rBR.x -= br.width;
rBR.y -= bb.width;
rBL.x -= bl.width;
rBL.y -= bb.width;
if (type == 'content') {
var pt = parseFloat(getPropertyValue(style, 'padding-top'));
var pr = parseFloat(getPropertyValue(style, 'padding-right'));
var pb = parseFloat(getPropertyValue(style, 'padding-bottom'));
var pl = parseFloat(getPropertyValue(style, 'padding-left'));
rTL.x -= pl;
rTL.y -= pt;
rTR.x -= pr;
rTR.y -= pt;
rBR.x -= pr;
rBR.y -= pb;
rBL.x -= pl;
rBL.y -= pb;
}
}
if (typeof type == 'number') {
rTL.x -= type;
rTL.y -= type;
rTR.x -= type;
rTR.y -= type;
rBR.x -= type;
rBR.y -= type;
rBL.x -= type;
rBL.y -= type;
}
return roundBox(box, rTL, rTR, rBR, rBL);
}
function roundBox(box, rTL0, rTR0, rBR0, rBL0) {
var tmp = adjustBorderRadiusForBox(box, rTL0, rTR0, rBR0, rBL0);
var rTL = tmp.tl;
var rTR = tmp.tr;
var rBR = tmp.br;
var rBL = tmp.bl;
var path = new drawing.Path({
fill: null,
stroke: null
});
path.moveTo(box.left, box.top + rTL.y);
if (rTL.x) {
addArcToPath(path, box.left + rTL.x, box.top + rTL.y, {
startAngle: -180,
endAngle: -90,
radiusX: rTL.x,
radiusY: rTL.y
});
}
path.lineTo(box.right - rTR.x, box.top);
if (rTR.x) {
addArcToPath(path, box.right - rTR.x, box.top + rTR.y, {
startAngle: -90,
endAngle: 0,
radiusX: rTR.x,
radiusY: rTR.y
});
}
path.lineTo(box.right, box.bottom - rBR.y);
if (rBR.x) {
addArcToPath(path, box.right - rBR.x, box.bottom - rBR.y, {
startAngle: 0,
endAngle: 90,
radiusX: rBR.x,
radiusY: rBR.y
});
}
path.lineTo(box.left + rBL.x, box.bottom);
if (rBL.x) {
addArcToPath(path, box.left + rBL.x, box.bottom - rBL.y, {
startAngle: 90,
endAngle: 180,
radiusX: rBL.x,
radiusY: rBL.y
});
}
return path.close();
}
function formatCounter(val, style) {
var str = parseFloat(val) + '';
switch (style) {
case 'decimal-leading-zero':
if (str.length < 2) {
str = '0' + str;
}
return str;
case 'lower-roman':
return romanNumeral(val).toLowerCase();
case 'upper-roman':
return romanNumeral(val).toUpperCase();
case 'lower-latin':
case 'lower-alpha':
return alphaNumeral(val - 1);
case 'upper-latin':
case 'upper-alpha':
return alphaNumeral(val - 1).toUpperCase();
default:
return str;
}
}
function evalPseudoElementContent(element, content) {
function displayCounter(name, style, separator) {
if (!separator) {
return formatCounter(getCounter(name) || 0, style);
}
separator = separator.replace(/^\s*(["'])(.*)\1\s*$/, '$2');
return getAllCounters(name).map(function (val) {
return formatCounter(val, style);
}).join(separator);
}
var a = splitProperty(content, /^\s+/);
var result = [], m;
a.forEach(function (el) {
var tmp;
if (m = /^\s*(["'])(.*)\1\s*$/.exec(el)) {
result.push(m[2].replace(/\\([0-9a-f]{4})/gi, function (s, p) {
return String.fromCharCode(parseInt(p, 16));
}));
} else if (m = /^\s*counter\((.*?)\)\s*$/.exec(el)) {
tmp = splitProperty(m[1]);
result.push(displayCounter(tmp[0], tmp[1]));
} else if (m = /^\s*counters\((.*?)\)\s*$/.exec(el)) {
tmp = splitProperty(m[1]);
result.push(displayCounter(tmp[0], tmp[2], tmp[1]));
} else if (m = /^\s*attr\((.*?)\)\s*$/.exec(el)) {
result.push(element.getAttribute(m[1]) || '');
} else {
result.push(el);
}
});
return result.join('');
}
function getCssText(style) {
if (style.cssText) {
return style.cssText;
}
var result = [];
for (var i = 0; i < style.length; ++i) {
result.push(style[i] + ': ' + getPropertyValue(style, style[i]));
}
return result.join(';\n');
}
function _renderWithPseudoElements(element, group) {
if (element.tagName == KENDO_PSEUDO_ELEMENT) {
_renderElement(element, group);
return;
}
var fake = [];
function pseudo(kind, place) {
var style = getComputedStyle(element, kind);
if (style.content && style.content != 'normal' && style.content != 'none' && style.width != '0px') {
var psel = element.ownerDocument.createElement(KENDO_PSEUDO_ELEMENT);
psel.style.cssText = getCssText(style);
psel.textContent = evalPseudoElementContent(element, style.content);
element.insertBefore(psel, place);
fake.push(psel);
}
}
pseudo(':before', element.firstChild);
pseudo(':after', null);
var saveClass = element.className;
element.className += ' kendo-pdf-hide-pseudo-elements';
_renderElement(element, group);
element.className = saveClass;
fake.forEach(function (el) {
element.removeChild(el);
});
}
function _renderElement(element, group) {
var style = getComputedStyle(element);
var top = getBorder(style, 'top');
var right = getBorder(style, 'right');
var bottom = getBorder(style, 'bottom');
var left = getBorder(style, 'left');
var rTL0 = getBorderRadius(style, 'top-left');
var rTR0 = getBorderRadius(style, 'top-right');
var rBL0 = getBorderRadius(style, 'bottom-left');
var rBR0 = getBorderRadius(style, 'bottom-right');
var dir = getPropertyValue(style, 'direction');
var backgroundColor = getPropertyValue(style, 'background-color');
backgroundColor = parseColor(backgroundColor);
var backgroundImage = parseBackgroundImage(getPropertyValue(style, 'background-image'));
var backgroundRepeat = splitProperty(getPropertyValue(style, 'background-repeat'));
var backgroundPosition = splitProperty(getPropertyValue(style, 'background-position'));
var backgroundOrigin = splitProperty(getPropertyValue(style, 'background-origin'));
var backgroundSize = splitProperty(getPropertyValue(style, 'background-size'));
if (browser.msie && browser.version < 10) {
backgroundPosition = splitProperty(element.currentStyle.backgroundPosition);
}
var innerbox = innerBox(element.getBoundingClientRect(), 'border-*-width', element);
(function () {
var clip = getPropertyValue(style, 'clip');
var m = /^\s*rect\((.*)\)\s*$/.exec(clip);
if (m) {
var a = m[1].split(/[ ,]+/g);
var top = a[0] == 'auto' ? innerbox.top : parseFloat(a[0]) + innerbox.top;
var right = a[1] == 'auto' ? innerbox.right : parseFloat(a[1]) + innerbox.left;
var bottom = a[2] == 'auto' ? innerbox.bottom : parseFloat(a[2]) + innerbox.top;
var left = a[3] == 'auto' ? innerbox.left : parseFloat(a[3]) + innerbox.left;
var tmp = new drawing.Group();
var clipPath = new drawing.Path().moveTo(left, top).lineTo(right, top).lineTo(right, bottom).lineTo(left, bottom).close();
setClipping(tmp, clipPath);
group.append(tmp);
group = tmp;
updateClipbox(clipPath);
}
}());
var boxes, i, cells;
var display = getPropertyValue(style, 'display');
if (display == 'table-row') {
boxes = [];
for (i = 0, cells = element.children; i < cells.length; ++i) {
boxes.push(cells[i].getBoundingClientRect());
}
} else {
boxes = element.getClientRects();
if (boxes.length == 1) {
boxes = [element.getBoundingClientRect()];
}
}
boxes = adjustBoxes(boxes);
for (i = 0; i < boxes.length; ++i) {
drawOneBox(boxes[i], i === 0, i == boxes.length - 1);
}
if (boxes.length > 0 && display == 'list-item') {
drawBullet(boxes[0]);
}
(function () {
function clipit() {
var clipPath = elementRoundBox(element, innerbox, 'padding');
var tmp = new drawing.Group();
setClipping(tmp, clipPath);
group.append(tmp);
group = tmp;
updateClipbox(clipPath);
}
if (isFormField(element)) {
clipit();
} else if (/^(hidden|auto|scroll)/.test(getPropertyValue(style, 'overflow'))) {
clipit();
} else if (/^(hidden|auto|scroll)/.test(getPropertyValue(style, 'overflow-x'))) {
clipit();
} else if (/^(hidden|auto|scroll)/.test(getPropertyValue(style, 'overflow-y'))) {
clipit();
}
}());
if (!maybeRenderWidget(element, group)) {
renderContents(element, group);
}
return group;
function adjustBoxes(boxes) {
if (/^td$/i.test(element.tagName)) {
var table = nodeInfo.table;
if (table && getPropertyValue(table.style, 'border-collapse') == 'collapse') {
var tableBorderLeft = getBorder(table.style, 'left').width;
var tableBorderTop = getBorder(table.style, 'top').width;
if (tableBorderLeft === 0 && tableBorderTop === 0) {
return boxes;
}
var tableBox = table.element.getBoundingClientRect();
var firstCell = table.element.rows[0].cells[0];
var firstCellBox = firstCell.getBoundingClientRect();
if (firstCellBox.top == tableBox.top || firstCellBox.left == tableBox.left) {
return slice.call(boxes).map(function (box) {
return {
left: box.left + tableBorderLeft,
top: box.top + tableBorderTop,
right: box.right + tableBorderLeft,
bottom: box.bottom + tableBorderTop,
height: box.height,
width: box.width
};
});
}
}
}
return boxes;
}
function drawEdge(color, len, Wtop, Wleft, Wright, rl, rr, transform) {
if (Wtop <= 0) {
return;
}
var path, edge = new drawing.Group();
setTransform(edge, transform);
group.append(edge);
sanitizeRadius(rl);
sanitizeRadius(rr);
path = new drawing.Path({
fill: { color: color },
stroke: null
});
edge.append(path);
path.moveTo(rl.x ? Math.max(rl.x, Wleft) : 0, 0).lineTo(len - (rr.x ? Math.max(rr.x, Wright) : 0), 0).lineTo(len - Math.max(rr.x, Wright), Wtop).lineTo(Math.max(rl.x, Wleft), Wtop).close();
if (rl.x) {
drawRoundCorner(Wleft, rl, [
-1,
0,
0,
1,
rl.x,
0
]);
}
if (rr.x) {
drawRoundCorner(Wright, rr, [
1,
0,
0,
1,
len - rr.x,
0
]);
}
function drawRoundCorner(Wright, r, transform) {
var angle = Math.PI / 2 * Wright / (Wright + Wtop);
var ri = {
x: r.x - Wright,
y: r.y - Wtop
};
var path = new drawing.Path({
fill: { color: color },
stroke: null
}).moveTo(0, 0);
setTransform(path, transform);
addArcToPath(path, 0, r.y, {
startAngle: -90,
endAngle: -radiansToDegrees(angle),
radiusX: r.x,
radiusY: r.y
});
if (ri.x > 0 && ri.y > 0) {
path.lineTo(ri.x * Math.cos(angle), r.y - ri.y * Math.sin(angle));
addArcToPath(path, 0, r.y, {
startAngle: -radiansToDegrees(angle),
endAngle: -90,
radiusX: ri.x,
radiusY: ri.y,
anticlockwise: true
});
} else if (ri.x > 0) {
path.lineTo(ri.x, Wtop).lineTo(0, Wtop);
} else {
path.lineTo(ri.x, Wtop).lineTo(ri.x, 0);
}
edge.append(path.close());
}
}
function drawBackground(box) {
var background = new drawing.Group();
setClipping(background, roundBox(box, rTL0, rTR0, rBR0, rBL0));
group.append(background);
if (element.tagName == 'A' && element.href && !/^#?$/.test($(element).attr('href'))) {
if (!nodeInfo._avoidLinks || !$(element).is(nodeInfo._avoidLinks)) {
background._pdfLink = {
url: element.href,
top: box.top,
right: box.right,
bottom: box.bottom,
left: box.left
};
}
}
if (backgroundColor) {
var path = new drawing.Path({
fill: { color: backgroundColor.toCssRgba() },
stroke: null
});
path.moveTo(box.left, box.top).lineTo(box.right, box.top).lineTo(box.right, box.bottom).lineTo(box.left, box.bottom).close();
background.append(path);
}
for (var i = backgroundImage.length; --i >= 0;) {
drawOneBackground(background, box, backgroundImage[i], backgroundRepeat[i % backgroundRepeat.length], backgroundPosition[i % backgroundPosition.length], backgroundOrigin[i % backgroundOrigin.length], backgroundSize[i % backgroundSize.length]);
}
}
function drawOneBackground(group, box, background, backgroundRepeat, backgroundPosition, backgroundOrigin, backgroundSize) {
if (!background || background == 'none') {
return;
}
if (background.type == 'url') {
if (/^url\(\"data:image\/svg/i.test(background.url)) {
return;
}
var img = IMAGE_CACHE[background.url];
if (img && img.width > 0 && img.height > 0) {
drawBackgroundImage(group, box, img.width, img.height, function (group, rect) {
group.append(new drawing.Image(background.url, rect));
});
}
} else if (background.type == 'linear') {
drawBackgroundImage(group, box, box.width, box.height, gradientRenderer(background));
} else {
return;
}
function drawBackgroundImage(group, box, img_width, img_height, renderBG) {
var aspect_ratio = img_width / img_height;
var orgBox = box;
if (backgroundOrigin == 'content-box') {
orgBox = innerBox(orgBox, 'border-*-width', element);
orgBox = innerBox(orgBox, 'padding-*', element);
} else if (backgroundOrigin == 'padding-box') {
orgBox = innerBox(orgBox, 'border-*-width', element);
}
if (!/^\s*auto(\s+auto)?\s*$/.test(backgroundSize)) {
var size = backgroundSize.split(/\s+/g);
if (/%$/.test(size[0])) {
img_width = orgBox.width * parseFloat(size[0]) / 100;
} else {
img_width = parseFloat(size[0]);
}
if (size.length == 1 || size[1] == 'auto') {
img_height = img_width / aspect_ratio;
} else if (/%$/.test(size[1])) {
img_height = orgBox.height * parseFloat(size[1]) / 100;
} else {
img_height = parseFloat(size[1]);
}
}
var pos = (backgroundPosition + '').split(/\s+/);
if (pos.length == 1) {
pos[1] = '50%';
}
if (/%$/.test(pos[0])) {
pos[0] = parseFloat(pos[0]) / 100 * (orgBox.width - img_width);
} else {
pos[0] = parseFloat(pos[0]);
}
if (/%$/.test(pos[1])) {
pos[1] = parseFloat(pos[1]) / 100 * (orgBox.height - img_height);
} else {
pos[1] = parseFloat(pos[1]);
}
var rect = new geo.Rect([
orgBox.left + pos[0],
orgBox.top + pos[1]
], [
img_width,
img_height
]);
function rewX() {
while (rect.origin.x > box.left) {
rect.origin.x -= img_width;
}
}
function rewY() {
while (rect.origin.y > box.top) {
rect.origin.y -= img_height;
}
}
function repeatX() {
while (rect.origin.x < box.right) {
renderBG(group, rect.clone());
rect.origin.x += img_width;
}
}
if (backgroundRepeat == 'no-repeat') {
renderBG(group, rect);
} else if (backgroundRepeat == 'repeat-x') {
rewX();
repeatX();
} else if (backgroundRepeat == 'repeat-y') {
rewY();
while (rect.origin.y < box.bottom) {
renderBG(group, rect.clone());
rect.origin.y += img_height;
}
} else if (backgroundRepeat == 'repeat') {
rewX();
rewY();
var origin = rect.origin.clone();
while (rect.origin.y < box.bottom) {
rect.origin.x = origin.x;
repeatX();
rect.origin.y += img_height;
}
}
}
}
function drawBullet() {
var listStyleType = getPropertyValue(style, 'list-style-type');
if (listStyleType == 'none') {
return;
}
var listStylePosition = getPropertyValue(style, 'list-style-position');
function _drawBullet(f) {
saveStyle(element, function () {
element.style.position = 'relative';
var bullet = element.ownerDocument.createElement(KENDO_PSEUDO_ELEMENT);
bullet.style.position = 'absolute';
bullet.style.boxSizing = 'border-box';
if (listStylePosition == 'outside') {
bullet.style.width = '6em';
bullet.style.left = '-6.8em';
bullet.style.textAlign = 'right';
} else {
bullet.style.left = '0px';
}
f(bullet);
element.insertBefore(bullet, element.firstChild);
renderElement(bullet, group);
element.removeChild(bullet);
});
}
function elementIndex(f) {
var a = element.parentNode.children;
var k = element.getAttribute('kendo-split-index');
if (k != null) {
return f(k | 0, a.length);
}
for (var i = 0; i < a.length; ++i) {
if (a[i] === element) {
return f(i, a.length);
}
}
}
switch (listStyleType) {
case 'circle':
case 'disc':
case 'square':
_drawBullet(function (bullet) {
bullet.style.fontSize = '60%';
bullet.style.lineHeight = '200%';
bullet.style.paddingRight = '0.5em';
bullet.style.fontFamily = 'DejaVu Serif';
bullet.innerHTML = {
'disc': '\u25CF',
'circle': '\u25EF',
'square': '\u25A0'
}[listStyleType];
});
break;
case 'decimal':
case 'decimal-leading-zero':
_drawBullet(function (bullet) {
elementIndex(function (idx) {
++idx;
if (listStyleType == 'decimal-leading-zero' && (idx + '').length < 2) {
idx = '0' + idx;
}
bullet.innerHTML = idx + '.';
});
});
break;
case 'lower-roman':
case 'upper-roman':
_drawBullet(function (bullet) {
elementIndex(function (idx) {
idx = romanNumeral(idx + 1);
if (listStyleType == 'upper-roman') {
idx = idx.toUpperCase();
}
bullet.innerHTML = idx + '.';
});
});
break;
case 'lower-latin':
case 'lower-alpha':
case 'upper-latin':
case 'upper-alpha':
_drawBullet(function (bullet) {
elementIndex(function (idx) {
idx = alphaNumeral(idx);
if (/^upper/i.test(listStyleType)) {
idx = idx.toUpperCase();
}
bullet.innerHTML = idx + '.';
});
});
break;
}
}
function drawOneBox(box, isFirst, isLast) {
if (box.width === 0 || box.height === 0) {
return;
}
drawBackground(box);
var shouldDrawLeft = left.width > 0 && (isFirst && dir == 'ltr' || isLast && dir == 'rtl');
var shouldDrawRight = right.width > 0 && (isLast && dir == 'ltr' || isFirst && dir == 'rtl');
if (top.width === 0 && left.width === 0 && right.width === 0 && bottom.width === 0) {
return;
}
if (true) {
if (top.color == right.color && top.color == bottom.color && top.color == left.color) {
if (top.width == right.width && top.width == bottom.width && top.width == left.width) {
if (shouldDrawLeft && shouldDrawRight) {
box = innerBox(box, top.width / 2);
var path = elementRoundBox(element, box, top.width / 2);
path.options.stroke = {
color: top.color,
width: top.width
};
group.append(path);
return;
}
}
}
if (rTL0.x === 0 && rTR0.x === 0 && rBR0.x === 0 && rBL0.x === 0) {
if (top.width < 2 && left.width < 2 && right.width < 2 && bottom.width < 2) {
if (top.width > 0) {
group.append(new drawing.Path({
stroke: {
width: top.width,
color: top.color
}
}).moveTo(box.left, box.top + top.width / 2).lineTo(box.right, box.top + top.width / 2));
}
if (bottom.width > 0) {
group.append(new drawing.Path({
stroke: {
width: bottom.width,
color: bottom.color
}
}).moveTo(box.left, box.bottom - bottom.width / 2).lineTo(box.right, box.bottom - bottom.width / 2));
}
if (shouldDrawLeft) {
group.append(new drawing.Path({
stroke: {
width: left.width,
color: left.color
}
}).moveTo(box.left + left.width / 2, box.top).lineTo(box.left + left.width / 2, box.bottom));
}
if (shouldDrawRight) {
group.append(new drawing.Path({
stroke: {
width: right.width,
color: right.color
}
}).moveTo(box.right - right.width / 2, box.top).lineTo(box.right - right.width / 2, box.bottom));
}
return;
}
}
}
var tmp = adjustBorderRadiusForBox(box, rTL0, rTR0, rBR0, rBL0);
var rTL = tmp.tl;
var rTR = tmp.tr;
var rBR = tmp.br;
var rBL = tmp.bl;
drawEdge(top.color, box.width, top.width, left.width, right.width, rTL, rTR, [
1,
0,
0,
1,
box.left,
box.top
]);
drawEdge(bottom.color, box.width, bottom.width, right.width, left.width, rBR, rBL, [
-1,
0,
0,
-1,
box.right,
box.bottom
]);
function inv(p) {
return {
x: p.y,
y: p.x
};
}
drawEdge(left.color, box.height, left.width, bottom.width, top.width, inv(rBL), inv(rTL), [
0,
-1,
1,
0,
box.left,
box.bottom
]);
drawEdge(right.color, box.height, right.width, top.width, bottom.width, inv(rTR), inv(rBR), [
0,
1,
-1,
0,
box.right,
box.top
]);
}
}
function gradientRenderer(gradient) {
return function (group, rect) {
var width = rect.width(), height = rect.height();
switch (gradient.type) {
case 'linear':
var angle = gradient.angle != null ? gradient.angle : Math.PI;
switch (gradient.to) {
case 'top':
angle = 0;
break;
case 'left':
angle = -Math.PI / 2;
break;
case 'bottom':
angle = Math.PI;
break;
case 'right':
angle = Math.PI / 2;
break;
case 'top left':
case 'left top':
angle = -Math.atan2(height, width);
break;
case 'top right':
case 'right top':
angle = Math.atan2(height, width);
break;
case 'bottom left':
case 'left bottom':
angle = Math.PI + Math.atan2(height, width);
break;
case 'bottom right':
case 'right bottom':
angle = Math.PI - Math.atan2(height, width);
break;
}
if (gradient.reverse) {
angle -= Math.PI;
}
angle %= 2 * Math.PI;
if (angle < 0) {
angle += 2 * Math.PI;
}
var pxlen = Math.abs(width * Math.sin(angle)) + Math.abs(height * Math.cos(angle));
var scaledAngle = Math.atan(width * Math.tan(angle) / height);
var sin = Math.sin(scaledAngle), cos = Math.cos(scaledAngle);
var len = Math.abs(sin) + Math.abs(cos);
var x = len / 2 * sin;
var y = len / 2 * cos;
if (angle > Math.PI / 2 && angle <= 3 * Math.PI / 2) {
x = -x;
y = -y;
}
var implicit = [], right = 0;
var stops = gradient.stops.map(function (s, i) {
var offset = s.percent;
if (offset) {
offset = parseFloat(offset) / 100;
} else if (s.length) {
offset = parseFloat(s.length) / pxlen;
} else if (i === 0) {
offset = 0;
} else if (i == gradient.stops.length - 1) {
offset = 1;
}
var stop = {
color: s.color.toCssRgba(),
offset: offset
};
if (offset != null) {
right = offset;
implicit.forEach(function (s, i) {
var stop = s.stop;
stop.offset = s.left + (right - s.left) * (i + 1) / (implicit.length + 1);
});
implicit = [];
} else {
implicit.push({
left: right,
stop: stop
});
}
return stop;
});
var start = [
0.5 - x,
0.5 + y
];
var end = [
0.5 + x,
0.5 - y
];
group.append(drawing.Path.fromRect(rect).stroke(null).fill(new drawing.LinearGradient({
start: start,
end: end,
stops: stops,
userSpace: false
})));
break;
case 'radial':
if (window.console && window.console.log) {
window.console.log('Radial gradients are not yet supported in HTML renderer');
}
break;
}
};
}
function maybeRenderWidget(element, group) {
if (element.getAttribute(kendo.attr('role'))) {
var widget = kendo.widgetInstance($(element));
if (widget && (widget.exportDOMVisual || widget.exportVisual)) {
var visual;
if (widget.exportDOMVisual) {
visual = widget.exportDOMVisual();
} else {
visual = widget.exportVisual();
}
if (!visual) {
return false;
}
var wrap = new drawing.Group();
wrap.children.push(visual);
var bbox = element.getBoundingClientRect();
wrap.transform(geo.transform().translate(bbox.left, bbox.top));
group.append(wrap);
return true;
}
}
}
function renderImage(element, url, group) {
var box = getContentBox(element);
var rect = new geo.Rect([
box.left,
box.top
], [
box.width,
box.height
]);
var image = new drawing.Image(url, rect);
setClipping(image, elementRoundBox(element, box, 'content'));
group.append(image);
}
function zIndexSort(a, b) {
var sa = getComputedStyle(a);
var sb = getComputedStyle(b);
var za = parseFloat(getPropertyValue(sa, 'z-index'));
var zb = parseFloat(getPropertyValue(sb, 'z-index'));
var pa = getPropertyValue(sa, 'position');
var pb = getPropertyValue(sb, 'position');
if (isNaN(za) && isNaN(zb)) {
if (/static|absolute/.test(pa) && /static|absolute/.test(pb)) {
return 0;
}
if (pa == 'static') {
return -1;
}
if (pb == 'static') {
return 1;
}
return 0;
}
if (isNaN(za)) {
return zb === 0 ? 0 : zb > 0 ? -1 : 1;
}
if (isNaN(zb)) {
return za === 0 ? 0 : za > 0 ? 1 : -1;
}
return parseFloat(za) - parseFloat(zb);
}
function isFormField(element) {
return /^(?:textarea|select|input)$/i.test(element.tagName);
}
function getSelectedOption(element) {
if (element.selectedOptions && element.selectedOptions.length > 0) {
return element.selectedOptions[0];
}
return element.options[element.selectedIndex];
}
function renderCheckbox(element, group) {
var style = getComputedStyle(element);
var color = getPropertyValue(style, 'color');
var box = element.getBoundingClientRect();
if (element.type == 'checkbox') {
group.append(drawing.Path.fromRect(new geo.Rect([
box.left + 1,
box.top + 1
], [
box.width - 2,
box.height - 2
])).stroke(color, 1));
if (element.checked) {
group.append(new drawing.Path().stroke(color, 1.2).moveTo(box.left + 0.22 * box.width, box.top + 0.55 * box.height).lineTo(box.left + 0.45 * box.width, box.top + 0.75 * box.height).lineTo(box.left + 0.78 * box.width, box.top + 0.22 * box.width));
}
} else {
group.append(new drawing.Circle(new geo.Circle([
(box.left + box.right) / 2,
(box.top + box.bottom) / 2
], Math.min(box.width - 2, box.height - 2) / 2)).stroke(color, 1));
if (element.checked) {
group.append(new drawing.Circle(new geo.Circle([
(box.left + box.right) / 2,
(box.top + box.bottom) / 2
], Math.min(box.width - 8, box.height - 8) / 2)).fill(color).stroke(null));
}
}
}
function renderFormField(element, group) {
var tag = element.tagName.toLowerCase();
if (tag == 'input' && (element.type == 'checkbox' || element.type == 'radio')) {
return renderCheckbox(element, group);
}
var p = element.parentNode;
var doc = element.ownerDocument;
var el = doc.createElement(KENDO_PSEUDO_ELEMENT);
var option;
el.style.cssText = getCssText(getComputedStyle(element));
if (tag == 'input') {
el.style.whiteSpace = 'pre';
}
if (tag == 'select' || tag == 'textarea') {
el.style.overflow = 'auto';
}
if (tag == 'select') {
if (element.multiple) {
for (var i = 0; i < element.options.length; ++i) {
option = doc.createElement(KENDO_PSEUDO_ELEMENT);
option.style.cssText = getCssText(getComputedStyle(element.options[i]));
option.style.display = 'block';
option.textContent = element.options[i].textContent;
el.appendChild(option);
}
} else {
option = getSelectedOption(element);
if (option) {
el.textContent = option.textContent;
}
}
} else {
el.textContent = element.value;
}
p.insertBefore(el, element);
el.scrollLeft = element.scrollLeft;
el.scrollTop = element.scrollTop;
renderContents(el, group);
p.removeChild(el);
}
function renderContents(element, group) {
if (nodeInfo._stackingContext.element === element) {
nodeInfo._stackingContext.group = group;
}
switch (element.tagName.toLowerCase()) {
case 'img':
renderImage(element, element.src, group);
break;
case 'canvas':
try {
renderImage(element, element.toDataURL('image/png'), group);
} catch (ex) {
}
break;
case 'textarea':
case 'input':
case 'select':
renderFormField(element, group);
break;
default:
var blocks = [], floats = [], inline = [], positioned = [];
for (var i = element.firstChild; i; i = i.nextSibling) {
switch (i.nodeType) {
case 3:
if (/\S/.test(i.data)) {
renderText(element, i, group);
}
break;
case 1:
var style = getComputedStyle(i);
var display = getPropertyValue(style, 'display');
var floating = getPropertyValue(style, 'float');
var position = getPropertyValue(style, 'position');
if (position != 'static') {
positioned.push(i);
} else if (display != 'inline') {
if (floating != 'none') {
floats.push(i);
} else {
blocks.push(i);
}
} else {
inline.push(i);
}
break;
}
}
blocks.sort(zIndexSort).forEach(function (el) {
renderElement(el, group);
});
floats.sort(zIndexSort).forEach(function (el) {
renderElement(el, group);
});
inline.sort(zIndexSort).forEach(function (el) {
renderElement(el, group);
});
positioned.sort(zIndexSort).forEach(function (el) {
renderElement(el, group);
});
}
}
function renderText(element, node, group) {
if (emptyClipbox()) {
return;
}
var style = getComputedStyle(element);
if (parseFloat(getPropertyValue(style, 'text-indent')) < -500) {
return;
}
var text = node.data;
var start = 0;
var end = text.search(/\S\s*$/) + 1;
if (!end) {
return;
}
var fontSize = getPropertyValue(style, 'font-size');
var lineHeight = getPropertyValue(style, 'line-height');
var font = [
getPropertyValue(style, 'font-style'),
getPropertyValue(style, 'font-variant'),
getPropertyValue(style, 'font-weight'),
fontSize,
getPropertyValue(style, 'font-family')
].join(' ');
fontSize = parseFloat(fontSize);
lineHeight = parseFloat(lineHeight);
if (fontSize === 0) {
return;
}
var color = getPropertyValue(style, 'color');
var range = element.ownerDocument.createRange();
var align = getPropertyValue(style, 'text-align');
var isJustified = align == 'justify';
var whiteSpace = getPropertyValue(style, 'white-space');
var textOverflow, saveTextOverflow;
if (browser.msie) {
textOverflow = style.textOverflow;
if (textOverflow == 'ellipsis') {
saveTextOverflow = element.style.textOverflow;
element.style.textOverflow = 'clip';
}
}
var estimateLineLength = element.getBoundingClientRect().width / fontSize * 5;
if (estimateLineLength === 0) {
estimateLineLength = 500;
}
while (!doChunk()) {
}
if (browser.msie && textOverflow == 'ellipsis') {
element.style.textOverflow = saveTextOverflow;
}
return;
function doChunk() {
var origStart = start;
var box, pos = text.substr(start).search(/\S/);
start += pos;
if (pos < 0 || start >= end) {
return true;
}
range.setStart(node, start);
range.setEnd(node, start + 1);
box = actuallyGetRangeBoundingRect(range);
var found = false;
if (isJustified) {
pos = text.substr(start).search(/\s/);
if (pos >= 0) {
range.setEnd(node, start + pos);
var r = range.getBoundingClientRect();
if (r.bottom == box.bottom) {
box = r;
found = true;
start += pos;
}
}
}
if (!found) {
pos = function findEOL(min, eol, max) {
range.setEnd(node, eol);
var r = actuallyGetRangeBoundingRect(range);
if (r.bottom != box.bottom && min < eol) {
return findEOL(min, min + eol >> 1, eol);
} else if (r.right != box.right) {
box = r;
if (eol < max) {
return findEOL(eol, eol + max >> 1, max);
} else {
return eol;
}
} else {
return eol;
}
}(start, Math.min(end, start + estimateLineLength), end);
if (pos == start) {
return true;
}
start = pos;
pos = range.toString().search(/\s+$/);
if (pos === 0) {
return;
}
if (pos > 0) {
range.setEnd(node, range.startOffset + pos);
box = range.getBoundingClientRect();
}
}
if (browser.msie) {
box = range.getClientRects()[0];
}
var str = range.toString();
if (!/^(?:pre|pre-wrap)$/i.test(whiteSpace)) {
str = str.replace(/\s+/g, ' ');
} else if (/\t/.test(str)) {
var cc = 0;
for (pos = origStart; pos < range.startOffset; ++pos) {
var code = text.charCodeAt(pos);
if (code == 9) {
cc += 8 - cc % 8;
} else if (code == 10 || code == 13) {
cc = 0;
} else {
cc++;
}
}
while ((pos = str.search('\t')) >= 0) {
var indent = ' '.substr(0, 8 - (cc + pos) % 8);
str = str.substr(0, pos) + indent + str.substr(pos + 1);
}
}
drawText(str, box);
}
function drawText(str, box) {
if (browser.msie && !isNaN(lineHeight)) {
var size = kendo.util.measureText(str, { font: font });
var top = (box.top + box.bottom - size.height) / 2;
box = {
top: top,
right: box.right,
bottom: top + size.height,
left: box.left,
height: size.height,
width: box.right - box.left
};
}
var text = new TextRect(str, new geo.Rect([
box.left,
box.top
], [
box.width,
box.height
]), {
font: font,
fill: { color: color }
});
group.append(text);
decorate(box);
}
function decorate(box) {
line(nodeInfo['underline'], box.bottom);
line(nodeInfo['line-through'], box.bottom - box.height / 2.7);
line(nodeInfo['overline'], box.top);
function line(color, ypos) {
if (color) {
var width = fontSize / 12;
var path = new drawing.Path({
stroke: {
width: width,
color: color
}
});
ypos -= width;
path.moveTo(box.left, ypos).lineTo(box.right, ypos);
group.append(path);
}
}
}
}
function groupInStackingContext(element, group, zIndex) {
var main;
if (zIndex != 'auto') {
main = nodeInfo._stackingContext.group;
zIndex = parseFloat(zIndex);
} else {
main = group;
zIndex = 0;
}
var a = main.children;
for (var i = 0; i < a.length; ++i) {
if (a[i]._dom_zIndex != null && a[i]._dom_zIndex > zIndex) {
break;
}
}
var tmp = new drawing.Group();
main.insertAt(tmp, i);
tmp._dom_zIndex = zIndex;
if (main !== group) {
if (nodeInfo._clipbox) {
var m = nodeInfo._matrix.invert();
var r = nodeInfo._clipbox.transformCopy(m);
setClipping(tmp, drawing.Path.fromRect(r));
}
}
return tmp;
}
function renderElement(element, container) {
var style = getComputedStyle(element);
var counterReset = getPropertyValue(style, 'counter-reset');
if (counterReset) {
doCounters(splitProperty(counterReset, /^\s+/), resetCounter, 0);
}
var counterIncrement = getPropertyValue(style, 'counter-increment');
if (counterIncrement) {
doCounters(splitProperty(counterIncrement, /^\s+/), incCounter, 1);
}
if (/^(style|script|link|meta|iframe|svg|col|colgroup)$/i.test(element.tagName)) {
return;
}
if (nodeInfo._clipbox == null) {
return;
}
var opacity = parseFloat(getPropertyValue(style, 'opacity'));
var visibility = getPropertyValue(style, 'visibility');
var display = getPropertyValue(style, 'display');
if (opacity === 0 || visibility == 'hidden' || display == 'none') {
return;
}
var tr = getTransform(style);
var group;
var zIndex = getPropertyValue(style, 'z-index');
if ((tr || opacity < 1) && zIndex == 'auto') {
zIndex = 0;
}
group = groupInStackingContext(element, container, zIndex);
if (opacity < 1) {
group.opacity(opacity * group.opacity());
}
pushNodeInfo(element, style, group);
if (!tr) {
_renderWithPseudoElements(element, group);
} else {
saveStyle(element, function () {
pleaseSetPropertyValue(element.style, 'transform', 'none', 'important');
pleaseSetPropertyValue(element.style, 'transition', 'none', 'important');
if (getPropertyValue(style, 'position') == 'static') {
pleaseSetPropertyValue(element.style, 'position', 'relative', 'important');
}
var bbox = element.getBoundingClientRect();
var x = bbox.left + tr.origin[0];
var y = bbox.top + tr.origin[1];
var m = [
1,
0,
0,
1,
-x,
-y
];
m = mmul(m, tr.matrix);
m = mmul(m, [
1,
0,
0,
1,
x,
y
]);
m = setTransform(group, m);
nodeInfo._matrix = nodeInfo._matrix.multiplyCopy(m);
_renderWithPseudoElements(element, group);
});
}
popNodeInfo();
}
function mmul(a, b) {
var a1 = a[0], b1 = a[1], c1 = a[2], d1 = a[3], e1 = a[4], f1 = a[5];
var a2 = b[0], b2 = b[1], c2 = b[2], d2 = b[3], e2 = b[4], f2 = b[5];
return [
a1 * a2 + b1 * c2,
a1 * b2 + b1 * d2,
c1 * a2 + d1 * c2,
c1 * b2 + d1 * d2,
e1 * a2 + f1 * c2 + e2,
e1 * b2 + f1 * d2 + f2
];
}
}(window.kendo.jQuery, parseFloat, Math));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('drawing/animation', [
'drawing/geometry',
'drawing/core'
], f);
}(function () {
(function ($) {
var noop = $.noop, kendo = window.kendo, Class = kendo.Class, util = kendo.util, animationFrame = kendo.animationFrame, deepExtend = kendo.deepExtend;
var Animation = Class.extend({
init: function (element, options) {
var anim = this;
anim.options = deepExtend({}, anim.options, options);
anim.element = element;
},
options: {
duration: 500,
easing: 'swing'
},
setup: noop,
step: noop,
play: function () {
var anim = this, options = anim.options, easing = $.easing[options.easing], duration = options.duration, delay = options.delay || 0, start = util.now() + delay, finish = start + duration;
if (duration === 0) {
anim.step(1);
anim.abort();
} else {
setTimeout(function () {
var loop = function () {
if (anim._stopped) {
return;
}
var wallTime = util.now();
var time = util.limitValue(wallTime - start, 0, duration);
var pos = time / duration;
var easingPos = easing(pos, time, 0, 1, duration);
anim.step(easingPos);
if (wallTime < finish) {
animationFrame(loop);
} else {
anim.abort();
}
};
loop();
}, delay);
}
},
abort: function () {
this._stopped = true;
},
destroy: function () {
this.abort();
}
});
var AnimationFactory = function () {
this._items = [];
};
AnimationFactory.prototype = {
register: function (name, type) {
this._items.push({
name: name,
type: type
});
},
create: function (element, options) {
var items = this._items;
var match;
if (options && options.type) {
var type = options.type.toLowerCase();
for (var i = 0; i < items.length; i++) {
if (items[i].name.toLowerCase() === type) {
match = items[i];
break;
}
}
}
if (match) {
return new match.type(element, options);
}
}
};
AnimationFactory.current = new AnimationFactory();
Animation.create = function (type, element, options) {
return AnimationFactory.current.create(type, element, options);
};
deepExtend(kendo.drawing, {
Animation: Animation,
AnimationFactory: AnimationFactory
});
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.drawing', [
'kendo.color',
'util/main',
'util/text-metrics',
'util/base64',
'mixins/observers',
'drawing/geometry',
'drawing/core',
'drawing/mixins',
'drawing/shapes',
'drawing/parser',
'drawing/svg',
'drawing/canvas',
'drawing/vml',
'drawing/html',
'drawing/animation'
], f);
}(function () {
var __meta__ = {
id: 'drawing',
name: 'Drawing API',
category: 'framework',
description: 'The Kendo UI low-level drawing API',
depends: [
'core',
'color'
]
};
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));