提交 02c9b5f6 编写于 作者: L lang

Fix, Fix, Fix

上级 3ee2de73
...@@ -5,7 +5,7 @@ define(function(require) { ...@@ -5,7 +5,7 @@ define(function(require) {
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var echartsAPIList = [ var echartsAPIList = [
'getZr', 'getCoordinateSystem', 'getWidth', 'getHeight', 'dispatch' 'getDom', 'getZr', 'getCoordinateSystem', 'getWidth', 'getHeight', 'dispatch'
]; ];
function ExtensionAPI(echarts) { function ExtensionAPI(echarts) {
......
...@@ -47,6 +47,9 @@ define(function (require) { ...@@ -47,6 +47,9 @@ define(function (require) {
dataItem.__el = rect; dataItem.__el = rect;
rect.__data = dataItem; rect.__data = dataItem;
// Attach data on the el
rect.data = dataItem;
group.add(rect); group.add(rect);
// Animation // Animation
...@@ -55,20 +58,20 @@ define(function (require) { ...@@ -55,20 +58,20 @@ define(function (require) {
}, 1000, 300 * dataIndex / data.count(), 'cubicOut'); }, 1000, 300 * dataIndex / data.count(), 'cubicOut');
}) })
.update(function (newData, oldData) { .update(function (newData, oldData) {
var el = oldData.__el; var rect = oldData.__el;
// 空数据 // 空数据
if (newData.getValue() == null) { if (newData.getValue() == null) {
group.remove(el); group.remove(rect);
return; return;
} }
el.animateTo({ rect.animateTo({
shape: newData.layout shape: newData.layout
}, 500, 'cubicOut'); }, 500, 'cubicOut');
newData.__el = el; newData.__el = rect;
// Add back // Add back
group.add(el); group.add(rect);
}) })
.remove(function (dataItem, idx) { .remove(function (dataItem, idx) {
var el = dataItem.__el; var el = dataItem.__el;
......
...@@ -4,6 +4,47 @@ define(function (require) { ...@@ -4,6 +4,47 @@ define(function (require) {
var Group = require('zrender/container/Group'); var Group = require('zrender/container/Group');
var symbolCreators = require('../../util/symbol'); var symbolCreators = require('../../util/symbol');
function getSymbolElement(dataItem) {
return dataItem.__symbolEl;
}
function createSymbol(dataItem, enableAnimation) {
var layout = dataItem.layout;
var color = dataItem.getVisual('color');
var symbolSize = dataItem.getVisual('symbolSize');
var symbolType = dataItem.getVisual('symbol') || 'circle';
var symbolEl = symbolCreators.createSymbol(symbolType, -0.5, -0.5, 1, 1, color);
symbolEl.position = [layout.x, layout.y];
if (enableAnimation) {
symbolEl.scale = [0.1, 0.1];
symbolEl.animateTo({
scale: [symbolSize, symbolSize]
}, 500);
// symbolEl
// .on('mouseover', function () {
// this.animateTo({
// scale: [symbolSize * 1.4, symbolSize * 1.4]
// }, 400, 'elasticOut');
// })
// .on('mouseout', function () {
// this.animateTo({
// scale: [symbolSize, symbolSize]
// }, 400, 'elasticOut');
// });
}
else {
symbolEl.scale = [symbolSize, symbolSize];
}
return symbolEl;
}
function DataSymbol() { function DataSymbol() {
this.group = new Group(); this.group = new Group();
...@@ -11,11 +52,6 @@ define(function (require) { ...@@ -11,11 +52,6 @@ define(function (require) {
this.z = 0; this.z = 0;
this.zlevel = 0; this.zlevel = 0;
this.animation = {
easing: 'cubicOut',
duration: 300
}
} }
DataSymbol.prototype = { DataSymbol.prototype = {
...@@ -24,10 +60,13 @@ define(function (require) { ...@@ -24,10 +60,13 @@ define(function (require) {
return this._data; return this._data;
}, },
updateData: function (data) { getSymbolElements: function () {
return this._data.map(getSymbolElement);
},
updateData: function (data, enableAnimation) {
var group = this.group; var group = this.group;
var animationConfig = this.animation;
data.diff(this._data) data.diff(this._data)
.add(function (dataItem) { .add(function (dataItem) {
...@@ -37,28 +76,19 @@ define(function (require) { ...@@ -37,28 +76,19 @@ define(function (require) {
return; return;
} }
var layout = dataItem.layout; var symbolShape = createSymbol(dataItem, enableAnimation);
var color = dataItem.getVisual('color');
var symbolSize = dataItem.getVisual('symbolSize');
var symbolType = dataItem.getVisual('symbol') || 'circle';
var symbolShape = symbolCreators.createSymbol(symbolType, -0.5, -0.5, 1, 1, color);
symbolShape.scale = [0.1, 0.1]; dataItem.__symbolEl = symbolShape;
symbolShape.position = [layout.x, layout.y];
symbolShape.animateTo({ // Attach data on the el
scale: [symbolSize, symbolSize] symbolShape.data = dataItem;
}, 500);
dataItem.__el = symbolShape;
group.add(symbolShape); group.add(symbolShape);
}) })
.update(function (newData, oldData) { .update(function (newData, oldData) {
var symbolSize = newData.getVisual('symbolSize'); var symbolSize = newData.getVisual('symbolSize');
var layout = newData.layout; var layout = newData.layout;
var el = oldData.__el; var el = oldData.__symbolEl;
// 空数据 // 空数据
// TODO // TODO
...@@ -66,52 +96,67 @@ define(function (require) { ...@@ -66,52 +96,67 @@ define(function (require) {
group.remove(el); group.remove(el);
return; return;
} }
el.animateTo({
scale: [symbolSize, symbolSize],
position: [layout.x, layout.y]
}, animationConfig.duration, animationConfig.easing);
newData.__el = el; // TODO Merge animateTo and attr methods into one
if (enableAnimation) {
el.animateTo({
scale: [symbolSize, symbolSize],
position: [layout.x, layout.y]
}, 300, 'cubicOut');
}
else {
el.attr({
scale: [symbolSize, symbolSize],
position: [layout.x, layout.y]
});
}
newData.__symbolEl = el;
// Add back // Add back
group.add(el); group.add(el);
}) })
.remove(function (dataItem) { .remove(function (dataItem) {
var el = dataItem.__el; var el = dataItem.__symbolEl;
if (el) { if (el) {
el.animateTo({ if (enableAnimation) {
scale: [0, 0] el.animateTo({
}, 200, 'cubicOut', function () { scale: [0, 0]
}, 200, 'cubicOut', function () {
group.remove(el);
});
}
else {
group.remove(el); group.remove(el);
}); }
} }
}) })
.execute(); .execute();
// Update common properties // Update common properties
data.each(function (dataItem) { data.each(function (dataItem) {
var el = dataItem.__el; var el = dataItem.__symbolEl;
el.z = this.z; el.z = this.z;
zrUtil.extend( zrUtil.extend(
el.style, el.style,
dataItem.getModel('itemStyle.normal').getItemStyle(['fill', 'stroke']) dataItem.getModel('itemStyle.normal').getItemStyle()
); );
var symbolSize = dataItem.getVisual('symbolSize'); var symbolSize = dataItem.getVisual('symbolSize');
// Adjust the line width // Adjust the line width
el.__lineWidth = el.__lineWidth || el.style.lineWidth; el.__lineWidth = el.__lineWidth || el.style.lineWidth;
el.style.lineWidth = el.__lineWidth / symbolSize; el.style.lineWidth = el.__lineWidth / symbolSize;
}, this) }, this);
this._data = data; this._data = data;
}, },
remove: function () { remove: function (enableAnimation) {
if (this._data) { if (this._data) {
var group = this.group; var group = this.group;
this._data.each(function (dataItem) { this._data.each(function (dataItem) {
var el = dataItem.__el; var el = dataItem.__symbolEl;
el.animateTo({ el.animateTo({
scale: [0, 0] scale: [0, 0]
}, 200, 'cubicOut', function () { }, 200, 'cubicOut', function () {
......
...@@ -53,6 +53,7 @@ define(function(require) { ...@@ -53,6 +53,7 @@ define(function(require) {
var coordinateSystem = seriesModel.coordinateSystem; var coordinateSystem = seriesModel.coordinateSystem;
var isCoordinateSystemPolar = coordinateSystem.type === 'polar'; var isCoordinateSystemPolar = coordinateSystem.type === 'polar';
// TODO Update after animation
if ( if (
isCoordinateSystemPolar isCoordinateSystemPolar
&& points.length > 2 && points.length > 2
...@@ -100,9 +101,9 @@ define(function(require) { ...@@ -100,9 +101,9 @@ define(function(require) {
if (! isPointsSame(this._pointsWithName, pointsWithName)) { if (! isPointsSame(this._pointsWithName, pointsWithName)) {
this._updateAnimation(data, pointsWithName); this._updateAnimation(data, pointsWithName);
// Add back
this.group.add(this._polyline);
} }
// Add back
group.add(this._polyline);
} }
this._data = data; this._data = data;
......
...@@ -2,7 +2,6 @@ define(function(require) { ...@@ -2,7 +2,6 @@ define(function(require) {
'use strict'; 'use strict';
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var vector = require('zrender/core/vector');
var elementList = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea']; var elementList = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea'];
......
...@@ -13,7 +13,7 @@ define(function (require) { ...@@ -13,7 +13,7 @@ define(function (require) {
type: 'dataZoom', type: 'dataZoom',
init: function (echarts) { init: function () {
/** /**
* @private * @private
* @type {Object} * @type {Object}
......
...@@ -9,27 +9,5 @@ define(function (require) { ...@@ -9,27 +9,5 @@ define(function (require) {
var echarts = require('../echarts'); var echarts = require('../echarts');
// Series Filter // Series Filter
echarts.registerProcessor(function (ecModel) { echarts.registerProcessor(require('./legend/legendFilter'));
var legendModel = ecModel.getComponent('legend');
if (legendModel) {
ecModel.filterSeries(function (series) {
return legendModel.isSelected(series.name);
});
}
});
// Series color
echarts.registerVisualCoding(function (ecModel) {
var legendModel = ecModel.getComponent('legend');
if (legendModel) {
var legendData = legendModel.getData();
ecModel.eachSeries(function (series) {
var data = legendData.getByName(series.name);
var color = data && data.get('itemStyle.normal.color');
if (color) {
series.setVisual('color', color);
}
});
}
});
}); });
\ No newline at end of file
...@@ -2,6 +2,7 @@ define(function (require) { ...@@ -2,6 +2,7 @@ define(function (require) {
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var numberUtil = require('../../util/number'); var numberUtil = require('../../util/number');
var formatUtil = require('../../util/format');
var symbolCreator = require('../../util/symbol'); var symbolCreator = require('../../util/symbol');
function createSelectActionDispatcher(uid, seriesName, api) { function createSelectActionDispatcher(uid, seriesName, api) {
...@@ -18,7 +19,7 @@ define(function (require) { ...@@ -18,7 +19,7 @@ define(function (require) {
render: function (legendModel, ecModel, api) { render: function (legendModel, ecModel, api) {
var itemGap = legendModel.get('itemGap'); var itemGap = legendModel.get('itemGap');
var padding = numberUtil.normalizeCssArray( var padding = formatUtil.normalizeCssArray(
legendModel.get('padding') legendModel.get('padding')
); );
var orient = legendModel.get('orient'); var orient = legendModel.get('orient');
......
define(function () {
return function (ecModel) {
var legendModel = ecModel.getComponent('legend');
if (legendModel) {
ecModel.filterSeries(function (series) {
return legendModel.isSelected(series.name);
});
}
}
});
\ No newline at end of file
define(function (require) { define(function (require) {
var numberUtil = require('../util/number'); var numberUtil = require('../util/number');
var formatUtil = require('../util/format');
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
function categoryDefaultFormatter(val) { function categoryDefaultFormatter(val) {
...@@ -27,7 +28,7 @@ define(function (require) { ...@@ -27,7 +28,7 @@ define(function (require) {
break; break;
default: default:
labelFormatter = function (val) { labelFormatter = function (val) {
return numberUtil.addCommas(numberUtil.round(val)); return formatUtil.addCommas(numberUtil.round(val));
}; };
} }
} }
......
...@@ -82,6 +82,19 @@ define(function(require) { ...@@ -82,6 +82,19 @@ define(function(require) {
init: function (option, parentModel, rawDataIndex, independentVar, dependentVar) { init: function (option, parentModel, rawDataIndex, independentVar, dependentVar) {
// Normalize option to { value: [] }
var value = option.value;
// Pending
if (value == null
&& (zrUtil.isArray(option)
|| typeof (option) === 'number')
) {
value = option;
option = {
value: option
}
}
/** /**
* @type {string} * @type {string}
* @memeberOf module:echarts/data/List~Entry * @memeberOf module:echarts/data/List~Entry
...@@ -98,8 +111,6 @@ define(function(require) { ...@@ -98,8 +111,6 @@ define(function(require) {
*/ */
this.option = option; this.option = option;
var value = option.value == null ? option : option.value;
if (value === '-' || value == null) { if (value === '-' || value == null) {
value = [rawDataIndex, null]; value = [rawDataIndex, null];
} }
...@@ -143,6 +154,13 @@ define(function(require) { ...@@ -143,6 +154,13 @@ define(function(require) {
this.rawDataIndex = rawDataIndex; this.rawDataIndex = rawDataIndex;
}, },
/**
* Get raw value which is given by option
*/
getRawValue: function () {
return this.get('value') || this.get();
},
setDataIndex: function (index) { setDataIndex: function (index) {
if (this.dataIndexIndex != null) { if (this.dataIndexIndex != null) {
this._value[this.dataIndexIndex] = index; this._value[this.dataIndexIndex] = index;
...@@ -162,6 +180,7 @@ define(function(require) { ...@@ -162,6 +180,7 @@ define(function(require) {
var capitalized = dim[0].toUpperCase() + dim.substr(1); var capitalized = dim[0].toUpperCase() + dim.substr(1);
var indexKey = dim + 'Index'; var indexKey = dim + 'Index';
var getterName = 'get' + capitalized; var getterName = 'get' + capitalized;
Entry.prototype[getterName] = function (stack) { Entry.prototype[getterName] = function (stack) {
var index = this[indexKey]; var index = this[indexKey];
if (index >= 0) { if (index >= 0) {
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
* setTheme * setTheme
* axis position 统一处理 * axis position 统一处理
* 规范 Symbol 配置和绘制, customPath * 规范 Symbol 配置和绘制, customPath
*
* 每次 update 只刷新 model 变化的那些 component(需要做依赖收集)
*/ */
define(function (require) { define(function (require) {
...@@ -31,6 +33,11 @@ define(function (require) { ...@@ -31,6 +33,11 @@ define(function (require) {
var ECharts = function (dom, theme, opts) { var ECharts = function (dom, theme, opts) {
opts = opts || {}; opts = opts || {};
/**
* @type {HTMLDomElement}
* @private
*/
this._dom = dom;
/** /**
* @type {module:zrender/ZRender} * @type {module:zrender/ZRender}
* @private * @private
...@@ -105,6 +112,10 @@ define(function (require) { ...@@ -105,6 +112,10 @@ define(function (require) {
ECharts.prototype = { ECharts.prototype = {
getDom: function () {
return this._dom;
},
getZr: function () { getZr: function () {
return this._zr; return this._zr;
}, },
...@@ -155,7 +166,7 @@ define(function (require) { ...@@ -155,7 +166,7 @@ define(function (require) {
}, },
updateImmediately: function (event) { updateImmediately: function (event) {
// console.time('update'); console.time('update');
var ecModel = this._model; var ecModel = this._model;
...@@ -179,7 +190,7 @@ define(function (require) { ...@@ -179,7 +190,7 @@ define(function (require) {
this._needsUpdate = false; this._needsUpdate = false;
// console.timeEnd('update'); console.timeEnd('update');
}, },
resize: function () { resize: function () {
...@@ -229,7 +240,7 @@ define(function (require) { ...@@ -229,7 +240,7 @@ define(function (require) {
ComponentModel.parseComponentType(seriesModel.type).sub ComponentModel.parseComponentType(seriesModel.type).sub
); );
if (chart) { if (chart) {
chart.init(this._extensionAPI); chart.init(ecModel, this._extensionAPI);
chartsMap[id] = chart; chartsMap[id] = chart;
chartsList.push(chart); chartsList.push(chart);
zr.add(chart.group); zr.add(chart.group);
...@@ -247,7 +258,7 @@ define(function (require) { ...@@ -247,7 +258,7 @@ define(function (require) {
var chart = chartsList[i]; var chart = chartsList[i];
if (! chart.__keepAlive) { if (! chart.__keepAlive) {
zr.remove(chart.group); zr.remove(chart.group);
chart.dispose(); chart.dispose(this._extensionAPI);
chartsList.splice(i, 1); chartsList.splice(i, 1);
delete chartsMap[chart.__id]; delete chartsMap[chart.__id];
} }
...@@ -274,7 +285,7 @@ define(function (require) { ...@@ -274,7 +285,7 @@ define(function (require) {
if (! component) { if (! component) {
// Create and add component // Create and add component
component = ComponentView.create(componentType, componentModel); component = ComponentView.create(componentType, componentModel);
component.init(this._extensionAPI); component.init(ecModel, this._extensionAPI);
componentsMap[id] = component; componentsMap[id] = component;
componentsList.push(component); componentsList.push(component);
...@@ -291,7 +302,7 @@ define(function (require) { ...@@ -291,7 +302,7 @@ define(function (require) {
var component = componentsList[i]; var component = componentsList[i];
if (! component.__keepAlive) { if (! component.__keepAlive) {
this._zr.remove(component.group); this._zr.remove(component.group);
component.dispose(); component.dispose(this._extensionAPI);
componentsList.splice(i, 1); componentsList.splice(i, 1);
delete componentsMap[component.__id]; delete componentsMap[component.__id];
} }
......
...@@ -116,6 +116,11 @@ define(function(require) { ...@@ -116,6 +116,11 @@ define(function(require) {
return result; return result;
} }
/**
* @param {string} seriesType
* @param {module:echarts/model/Global} ecModel
* @param {module:echarts/ExtensionAPI} api
*/
function barLayoutGrid(seriesType, ecModel, api) { function barLayoutGrid(seriesType, ecModel, api) {
var barWidthAndOffset = calBarWidthAndOffset( var barWidthAndOffset = calBarWidthAndOffset(
......
...@@ -3,8 +3,12 @@ define(function(require) { ...@@ -3,8 +3,12 @@ define(function(require) {
'use strict'; 'use strict';
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
var formatUtil = require('../util/format');
var ComponentModel = require('./Component'); var ComponentModel = require('./Component');
var encodeHTML = formatUtil.encodeHTML;
var addCommas = formatUtil.addCommas;
var SeriesModel = ComponentModel.extend({ var SeriesModel = ComponentModel.extend({
type: '', type: '',
...@@ -77,8 +81,22 @@ define(function(require) { ...@@ -77,8 +81,22 @@ define(function(require) {
return this._data; return this._data;
}, },
restoreData: function () { /**
* Default tooltip formatter
*
* @param {module:echarts/model/Model} dataItem
*/
formatTooltipHTML: function (dataItem) {
var value = dataItem.get('value');
var formattedValue = zrUtil.isArray(value)
? zrUtil.map(value, addCommas) : addCommas(value);
return encodeHTML(this.name) + '<br />'
+ encodeHTML(dataItem.name) + ' : '
+ formattedValue;
},
restoreData: function () {
// PENDING // PENDING
// Legend may have wrong symbol if visual is cleared // Legend may have wrong symbol if visual is cleared
// this.clearVisual(); // this.clearVisual();
......
// TODO Parse shadow style
define(function (require) { define(function (require) {
var zrUtil = require('zrender/core/util'); var zrUtil = require('zrender/core/util');
......
define(function (require) {
/**
* 每三位默认加,格式化
* @type {string|number} x
*/
function addCommas(x) {
if (isNaN(x)) {
return '-';
}
x = (x + '').split('.');
return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,'$1,')
+ (x.length > 1 ? ('.' + x[1]) : '');
}
/**
* @param {string} str
* @return {string} str
*/
function toCamelCase(str) {
return str.toLowerCase().replace(/-(.)/g, function(match, group1) {
return group1.toUpperCase();
});
}
/**
* Normalize css liked array configuration
* e.g.
* 3 => [3, 3, 3, 3]
* [4, 2] => [4, 2, 4, 2]
* [4, 3, 2] => [4, 3, 2, 3]
* @param {number|Array.<number>} val
*/
function normalizeCssArray(val) {
var len = val.length;
if (typeof (val) === 'number') {
return [val, val, val, val];
}
else if (len === 2) {
// vertical | horizontal
return [val[0], val[1], val[0], val[1]];
}
else if (len === 3) {
// top | horizontal | bottom
return [val[0], val[1], val[2], val[1]];
}
return val;
}
function encodeHTML(source) {
return String(source)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
return {
normalizeCssArray: normalizeCssArray,
addCommas: addCommas,
toCamelCase: toCamelCase,
encodeHTML: encodeHTML
};
});
\ No newline at end of file
...@@ -64,43 +64,6 @@ define(function (require) { ...@@ -64,43 +64,6 @@ define(function (require) {
return +percent; return +percent;
} }
/**
* Normalize css liked array configuration
* e.g.
* 3 => [3, 3, 3, 3]
* [4, 2] => [4, 2, 4, 2]
* [4, 3, 2] => [4, 3, 2, 3]
* @param {number|Array.<number>} val
*/
function normalizeCssArray(val) {
var len = val.length;
if (typeof (val) === 'number') {
return [val, val, val, val];
}
else if (len === 2) {
// vertical | horizontal
return [val[0], val[1], val[0], val[1]];
}
else if (len === 3) {
// top | horizontal | bottom
return [val[0], val[1], val[2], val[1]];
}
return val;
}
/**
* 每三位默认加,格式化
* @type {string|number} x
*/
function addCommas(x) {
if (isNaN(x)) {
return '-';
}
x = (x + '').split('.');
return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,'$1,')
+ (x.length > 1 ? ('.' + x[1]) : '');
}
/** /**
* Fix rounding error of float numbers * Fix rounding error of float numbers
*/ */
...@@ -115,10 +78,6 @@ define(function (require) { ...@@ -115,10 +78,6 @@ define(function (require) {
parsePercent: parsePercent, parsePercent: parsePercent,
normalizeCssArray: normalizeCssArray,
addCommas: addCommas,
round: round round: round
}; };
}); });
\ No newline at end of file
...@@ -23,9 +23,9 @@ define(function (require) { ...@@ -23,9 +23,9 @@ define(function (require) {
type: '', type: '',
init: function () {}, init: function (ecModel, api) {},
render: function () {}, render: function (seriesModel, ecModel, api) {},
remove: function () { remove: function () {
this.group.clear(); this.group.clear();
......
...@@ -22,7 +22,7 @@ define(function (require) { ...@@ -22,7 +22,7 @@ define(function (require) {
constructor: Component, constructor: Component,
init: function () {}, init: function (ecModel, api) {},
render: function (componentModel, ecModel, api) {}, render: function (componentModel, ecModel, api) {},
......
...@@ -15,7 +15,7 @@ define(function (require) { ...@@ -15,7 +15,7 @@ define(function (require) {
var symbolType = dataItem.get('symbol'); var symbolType = dataItem.get('symbol');
var symbolSize = dataItem.get('symbolSize'); var symbolSize = dataItem.get('symbolSize');
if (typeof symbolSize === 'function') { if (typeof symbolSize === 'function') {
var rawValue = dataItem.get('value') || dataItem.get(); var rawValue = dataItem.get('value');
dataItem.setVisual({ dataItem.setVisual({
symbol: symbolType, symbol: symbolType,
symbolSize: symbolSize(rawValue) symbolSize: symbolSize(rawValue)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册