plotly.js 2.6.2 → 2.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +3 -3
- package/dist/README.md +19 -19
- package/dist/plotly-basic.js +85 -78
- package/dist/plotly-basic.min.js +2 -2
- package/dist/plotly-cartesian.js +85 -78
- package/dist/plotly-cartesian.min.js +2 -2
- package/dist/plotly-finance.js +85 -78
- package/dist/plotly-finance.min.js +2 -2
- package/dist/plotly-geo-assets.js +2 -2
- package/dist/plotly-geo.js +85 -78
- package/dist/plotly-geo.min.js +4 -4
- package/dist/plotly-gl2d.js +85 -78
- package/dist/plotly-gl2d.min.js +2 -2
- package/dist/plotly-gl3d.js +85 -78
- package/dist/plotly-gl3d.min.js +8 -8
- package/dist/plotly-mapbox.js +85 -78
- package/dist/plotly-mapbox.min.js +2 -2
- package/dist/plotly-strict.js +85 -78
- package/dist/plotly-strict.min.js +2 -2
- package/dist/plotly-with-meta.js +85 -78
- package/dist/plotly.js +85 -78
- package/dist/plotly.min.js +2 -2
- package/package.json +1 -1
- package/src/components/colorbar/draw.js +72 -61
- package/src/components/fx/hover.js +11 -15
- package/src/version.js +1 -1
package/dist/plotly-finance.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* plotly.js (finance) v2.6.
|
|
2
|
+
* plotly.js (finance) v2.6.3
|
|
3
3
|
* Copyright 2012-2021, Plotly, Inc.
|
|
4
4
|
* All rights reserved.
|
|
5
5
|
* Licensed under the MIT license
|
|
@@ -23183,6 +23183,19 @@ function makeColorBarData(gd) {
|
|
|
23183
23183
|
}
|
|
23184
23184
|
|
|
23185
23185
|
function drawColorBar(g, opts, gd) {
|
|
23186
|
+
var len = opts.len;
|
|
23187
|
+
var lenmode = opts.lenmode;
|
|
23188
|
+
var thickness = opts.thickness;
|
|
23189
|
+
var thicknessmode = opts.thicknessmode;
|
|
23190
|
+
var outlinewidth = opts.outlinewidth;
|
|
23191
|
+
var borderwidth = opts.borderwidth;
|
|
23192
|
+
var xanchor = opts.xanchor;
|
|
23193
|
+
var yanchor = opts.yanchor;
|
|
23194
|
+
var xpad = opts.xpad;
|
|
23195
|
+
var ypad = opts.ypad;
|
|
23196
|
+
var optsX = opts.x;
|
|
23197
|
+
var optsY = opts.y;
|
|
23198
|
+
|
|
23186
23199
|
var fullLayout = gd._fullLayout;
|
|
23187
23200
|
var gs = fullLayout._size;
|
|
23188
23201
|
|
|
@@ -23212,42 +23225,41 @@ function drawColorBar(g, opts, gd) {
|
|
|
23212
23225
|
// when the colorbar itself is pushing the margins.
|
|
23213
23226
|
// but then the fractional size is calculated based on the
|
|
23214
23227
|
// actual graph size, so that the axes will size correctly.
|
|
23215
|
-
var thickPx = Math.round(
|
|
23228
|
+
var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
|
|
23216
23229
|
var thickFrac = thickPx / gs.w;
|
|
23217
|
-
var lenPx = Math.round(
|
|
23230
|
+
var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
|
|
23218
23231
|
var lenFrac = lenPx / gs.h;
|
|
23219
|
-
var xpadFrac =
|
|
23220
|
-
var yExtraPx = (
|
|
23221
|
-
var ypadFrac =
|
|
23232
|
+
var xpadFrac = xpad / gs.w;
|
|
23233
|
+
var yExtraPx = (borderwidth + outlinewidth) / 2;
|
|
23234
|
+
var ypadFrac = ypad / gs.h;
|
|
23222
23235
|
|
|
23223
23236
|
// x positioning: do it initially just for left anchor,
|
|
23224
23237
|
// then fix at the end (since we don't know the width yet)
|
|
23225
|
-
var
|
|
23238
|
+
var uPx = Math.round(optsX * gs.w + xpad);
|
|
23226
23239
|
// for dragging... this is getting a little muddled...
|
|
23227
|
-
var
|
|
23240
|
+
var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
|
|
23228
23241
|
|
|
23229
23242
|
// y positioning we can do correctly from the start
|
|
23230
|
-
var
|
|
23231
|
-
var
|
|
23232
|
-
var yTopPx = yBottomPx - lenPx;
|
|
23243
|
+
var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
|
|
23244
|
+
var vPx = Math.round(gs.h * (1 - vFrac));
|
|
23233
23245
|
|
|
23234
23246
|
// stash a few things for makeEditable
|
|
23235
23247
|
opts._lenFrac = lenFrac;
|
|
23236
23248
|
opts._thickFrac = thickFrac;
|
|
23237
|
-
opts.
|
|
23238
|
-
opts.
|
|
23249
|
+
opts._uFrac = uFrac;
|
|
23250
|
+
opts._vFrac = vFrac;
|
|
23239
23251
|
|
|
23240
23252
|
// stash mocked axis for contour label formatting
|
|
23241
23253
|
var ax = opts._axis = mockColorBarAxis(gd, opts, zrange);
|
|
23242
23254
|
|
|
23243
23255
|
// position can't go in through supplyDefaults
|
|
23244
23256
|
// because that restricts it to [0,1]
|
|
23245
|
-
ax.position =
|
|
23257
|
+
ax.position = optsX + xpadFrac + thickFrac;
|
|
23246
23258
|
|
|
23247
23259
|
if(['top', 'bottom'].indexOf(titleSide) !== -1) {
|
|
23248
23260
|
ax.title.side = titleSide;
|
|
23249
|
-
ax.titlex =
|
|
23250
|
-
ax.titley =
|
|
23261
|
+
ax.titlex = optsX + xpadFrac;
|
|
23262
|
+
ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
|
|
23251
23263
|
}
|
|
23252
23264
|
|
|
23253
23265
|
if(line.color && opts.tickmode === 'auto') {
|
|
@@ -23255,7 +23267,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
23255
23267
|
ax.tick0 = levelsIn.start;
|
|
23256
23268
|
var dtick = levelsIn.size;
|
|
23257
23269
|
// expand if too many contours, so we don't get too many ticks
|
|
23258
|
-
var autoNtick = Lib.constrain(
|
|
23270
|
+
var autoNtick = Lib.constrain(lenPx / 50, 4, 15) + 1;
|
|
23259
23271
|
var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
|
|
23260
23272
|
if(dtFactor > 1) {
|
|
23261
23273
|
var dtexp = Math.pow(10, Math.floor(Math.log(dtFactor) / Math.LN10));
|
|
@@ -23273,8 +23285,8 @@ function drawColorBar(g, opts, gd) {
|
|
|
23273
23285
|
// set domain after init, because we may want to
|
|
23274
23286
|
// allow it outside [0,1]
|
|
23275
23287
|
ax.domain = [
|
|
23276
|
-
|
|
23277
|
-
|
|
23288
|
+
vFrac + ypadFrac,
|
|
23289
|
+
vFrac + lenFrac - ypadFrac
|
|
23278
23290
|
];
|
|
23279
23291
|
|
|
23280
23292
|
ax.setScale();
|
|
@@ -23315,15 +23327,15 @@ function drawColorBar(g, opts, gd) {
|
|
|
23315
23327
|
// draw the title so we know how much room it needs
|
|
23316
23328
|
// when we squish the axis. This one only applies to
|
|
23317
23329
|
// top or bottom titles, not right side.
|
|
23318
|
-
var x = gs.l + (
|
|
23330
|
+
var x = gs.l + (optsX + xpadFrac) * gs.w;
|
|
23319
23331
|
var fontSize = ax.title.font.size;
|
|
23320
23332
|
var y;
|
|
23321
23333
|
|
|
23322
23334
|
if(titleSide === 'top') {
|
|
23323
|
-
y = (1 - (
|
|
23335
|
+
y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
|
|
23324
23336
|
gs.t + 3 + fontSize * 0.75;
|
|
23325
23337
|
} else {
|
|
23326
|
-
y = (1 - (
|
|
23338
|
+
y = (1 - (vFrac + ypadFrac)) * gs.h +
|
|
23327
23339
|
gs.t - 3 - fontSize * 0.25;
|
|
23328
23340
|
}
|
|
23329
23341
|
drawTitle(ax._id + 'title', {
|
|
@@ -23362,7 +23374,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
23362
23374
|
// squish the axis top to make room for the title
|
|
23363
23375
|
var titleGroup = g.select('.' + cn.cbtitle);
|
|
23364
23376
|
var titleText = titleGroup.select('text');
|
|
23365
|
-
var titleTrans = [-
|
|
23377
|
+
var titleTrans = [-outlinewidth / 2, outlinewidth / 2];
|
|
23366
23378
|
var mathJaxNode = titleGroup
|
|
23367
23379
|
.select('.h' + ax._id + 'title-math-group')
|
|
23368
23380
|
.node();
|
|
@@ -23434,7 +23446,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
23434
23446
|
// Colorbar cannot currently support opacities so we
|
|
23435
23447
|
// use an opaque fill even when alpha channels present
|
|
23436
23448
|
var fillEl = d3.select(this).attr({
|
|
23437
|
-
x:
|
|
23449
|
+
x: uPx,
|
|
23438
23450
|
width: Math.max(thickPx, 2),
|
|
23439
23451
|
y: d3.min(z),
|
|
23440
23452
|
height: Math.max(d3.max(z) - d3.min(z), 2),
|
|
@@ -23458,7 +23470,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
23458
23470
|
lines.exit().remove();
|
|
23459
23471
|
lines.each(function(d) {
|
|
23460
23472
|
d3.select(this)
|
|
23461
|
-
.attr('d', 'M' +
|
|
23473
|
+
.attr('d', 'M' + uPx + ',' +
|
|
23462
23474
|
(Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
|
|
23463
23475
|
.call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
|
|
23464
23476
|
});
|
|
@@ -23466,8 +23478,8 @@ function drawColorBar(g, opts, gd) {
|
|
|
23466
23478
|
// force full redraw of labels and ticks
|
|
23467
23479
|
axLayer.selectAll('g.' + ax._id + 'tick,path').remove();
|
|
23468
23480
|
|
|
23469
|
-
var shift =
|
|
23470
|
-
(
|
|
23481
|
+
var shift = uPx + thickPx +
|
|
23482
|
+
(outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
|
|
23471
23483
|
|
|
23472
23484
|
var vals = Axes.calcTicks(ax);
|
|
23473
23485
|
var tickSign = Axes.getTickSigns(ax)[2];
|
|
@@ -23492,9 +23504,9 @@ function drawColorBar(g, opts, gd) {
|
|
|
23492
23504
|
// TODO: why are we redrawing multiple times now with this?
|
|
23493
23505
|
// I guess autoMargin doesn't like being post-promise?
|
|
23494
23506
|
function positionCB() {
|
|
23495
|
-
var
|
|
23507
|
+
var innerThickness = thickPx + outlinewidth / 2;
|
|
23496
23508
|
if(ax.ticklabelposition.indexOf('inside') === -1) {
|
|
23497
|
-
|
|
23509
|
+
innerThickness += Drawing.bBox(axLayer.node()).width;
|
|
23498
23510
|
}
|
|
23499
23511
|
|
|
23500
23512
|
titleEl = titleCont.select('text');
|
|
@@ -23509,66 +23521,65 @@ function drawColorBar(g, opts, gd) {
|
|
|
23509
23521
|
// (except for top/bottom mathjax, above)
|
|
23510
23522
|
// but the weird gs.l is because the titleunshift
|
|
23511
23523
|
// transform gets removed by Drawing.bBox
|
|
23512
|
-
titleWidth = Drawing.bBox(titleCont.node()).right -
|
|
23524
|
+
titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
|
|
23513
23525
|
}
|
|
23514
|
-
|
|
23526
|
+
innerThickness = Math.max(innerThickness, titleWidth);
|
|
23515
23527
|
}
|
|
23516
23528
|
|
|
23517
|
-
var
|
|
23518
|
-
var outerheight = yBottomPx - yTopPx;
|
|
23529
|
+
var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
|
|
23519
23530
|
|
|
23520
23531
|
g.select('.' + cn.cbbg).attr({
|
|
23521
|
-
x:
|
|
23522
|
-
y:
|
|
23523
|
-
width: Math.max(
|
|
23524
|
-
height: Math.max(
|
|
23532
|
+
x: uPx - xpad - (borderwidth + outlinewidth) / 2,
|
|
23533
|
+
y: vPx - lenPx - yExtraPx,
|
|
23534
|
+
width: Math.max(outerThickness, 2),
|
|
23535
|
+
height: Math.max(lenPx + 2 * yExtraPx, 2)
|
|
23525
23536
|
})
|
|
23526
23537
|
.call(Color.fill, opts.bgcolor)
|
|
23527
23538
|
.call(Color.stroke, opts.bordercolor)
|
|
23528
|
-
.style('stroke-width',
|
|
23539
|
+
.style('stroke-width', borderwidth);
|
|
23529
23540
|
|
|
23530
23541
|
g.selectAll('.' + cn.cboutline).attr({
|
|
23531
|
-
x:
|
|
23532
|
-
y:
|
|
23542
|
+
x: uPx,
|
|
23543
|
+
y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
|
|
23533
23544
|
width: Math.max(thickPx, 2),
|
|
23534
|
-
height: Math.max(
|
|
23545
|
+
height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
|
|
23535
23546
|
})
|
|
23536
23547
|
.call(Color.stroke, opts.outlinecolor)
|
|
23537
23548
|
.style({
|
|
23538
23549
|
fill: 'none',
|
|
23539
|
-
'stroke-width':
|
|
23550
|
+
'stroke-width': outlinewidth
|
|
23540
23551
|
});
|
|
23541
23552
|
|
|
23542
23553
|
// fix positioning for xanchor!='left'
|
|
23543
|
-
var xoffset = ({center: 0.5, right: 1}[
|
|
23554
|
+
var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
|
|
23544
23555
|
g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
|
|
23545
23556
|
|
|
23546
23557
|
// auto margin adjustment
|
|
23547
23558
|
var marginOpts = {};
|
|
23548
|
-
var tFrac = FROM_TL[
|
|
23549
|
-
var bFrac = FROM_BR[
|
|
23550
|
-
if(
|
|
23551
|
-
marginOpts.y =
|
|
23552
|
-
marginOpts.t =
|
|
23553
|
-
marginOpts.b =
|
|
23559
|
+
var tFrac = FROM_TL[yanchor];
|
|
23560
|
+
var bFrac = FROM_BR[yanchor];
|
|
23561
|
+
if(lenmode === 'pixels') {
|
|
23562
|
+
marginOpts.y = optsY;
|
|
23563
|
+
marginOpts.t = lenPx * tFrac;
|
|
23564
|
+
marginOpts.b = lenPx * bFrac;
|
|
23554
23565
|
} else {
|
|
23555
23566
|
marginOpts.t = marginOpts.b = 0;
|
|
23556
|
-
marginOpts.yt =
|
|
23557
|
-
marginOpts.yb =
|
|
23567
|
+
marginOpts.yt = optsY + len * tFrac;
|
|
23568
|
+
marginOpts.yb = optsY - len * bFrac;
|
|
23558
23569
|
}
|
|
23559
23570
|
|
|
23560
|
-
var lFrac = FROM_TL[
|
|
23561
|
-
var rFrac = FROM_BR[
|
|
23562
|
-
if(
|
|
23563
|
-
marginOpts.x =
|
|
23564
|
-
marginOpts.l =
|
|
23565
|
-
marginOpts.r =
|
|
23571
|
+
var lFrac = FROM_TL[xanchor];
|
|
23572
|
+
var rFrac = FROM_BR[xanchor];
|
|
23573
|
+
if(thicknessmode === 'pixels') {
|
|
23574
|
+
marginOpts.x = optsX;
|
|
23575
|
+
marginOpts.l = outerThickness * lFrac;
|
|
23576
|
+
marginOpts.r = outerThickness * rFrac;
|
|
23566
23577
|
} else {
|
|
23567
|
-
var extraThickness =
|
|
23578
|
+
var extraThickness = outerThickness - thickPx;
|
|
23568
23579
|
marginOpts.l = extraThickness * lFrac;
|
|
23569
23580
|
marginOpts.r = extraThickness * rFrac;
|
|
23570
|
-
marginOpts.xl =
|
|
23571
|
-
marginOpts.xr =
|
|
23581
|
+
marginOpts.xl = optsX - thickness * lFrac;
|
|
23582
|
+
marginOpts.xr = optsX + thickness * rFrac;
|
|
23572
23583
|
}
|
|
23573
23584
|
|
|
23574
23585
|
Plots.autoMargin(gd, opts._id, marginOpts);
|
|
@@ -23599,9 +23610,9 @@ function makeEditable(g, opts, gd) {
|
|
|
23599
23610
|
moveFn: function(dx, dy) {
|
|
23600
23611
|
g.attr('transform', t0 + strTranslate(dx, dy));
|
|
23601
23612
|
|
|
23602
|
-
xf = dragElement.align(opts.
|
|
23613
|
+
xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
|
|
23603
23614
|
0, 1, opts.xanchor);
|
|
23604
|
-
yf = dragElement.align(opts.
|
|
23615
|
+
yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
|
|
23605
23616
|
0, 1, opts.yanchor);
|
|
23606
23617
|
|
|
23607
23618
|
var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
|
|
@@ -28303,11 +28314,13 @@ var cartesianScatterPoints = {
|
|
|
28303
28314
|
// The actual rendering is done by private function _hover.
|
|
28304
28315
|
exports.hover = function hover(gd, evt, subplot, noHoverEvent) {
|
|
28305
28316
|
gd = Lib.getGraphDiv(gd);
|
|
28306
|
-
|
|
28317
|
+
// The 'target' property changes when bubbling out of Shadow DOM.
|
|
28318
|
+
// Throttling can delay reading the target, so we save the current value.
|
|
28319
|
+
var eventTarget = evt.target;
|
|
28307
28320
|
Lib.throttle(
|
|
28308
28321
|
gd._fullLayout._uid + constants.HOVERID,
|
|
28309
28322
|
constants.HOVERMINTIME,
|
|
28310
|
-
function() { _hover(gd, evt, subplot, noHoverEvent); }
|
|
28323
|
+
function() { _hover(gd, evt, subplot, noHoverEvent, eventTarget); }
|
|
28311
28324
|
);
|
|
28312
28325
|
};
|
|
28313
28326
|
|
|
@@ -28472,7 +28485,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
|
|
|
28472
28485
|
};
|
|
28473
28486
|
|
|
28474
28487
|
// The actual implementation is here:
|
|
28475
|
-
function _hover(gd, evt, subplot, noHoverEvent) {
|
|
28488
|
+
function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
|
|
28476
28489
|
if(!subplot) subplot = 'xy';
|
|
28477
28490
|
|
|
28478
28491
|
// if the user passed in an array of subplots,
|
|
@@ -28591,7 +28604,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
28591
28604
|
// [x|y]px: the pixels (from top left) of the mouse location
|
|
28592
28605
|
// on the currently selected plot area
|
|
28593
28606
|
// add pointerX|Y property for drawing the spikes in spikesnap 'cursor' situation
|
|
28594
|
-
var hasUserCalledHover = !
|
|
28607
|
+
var hasUserCalledHover = !eventTarget;
|
|
28595
28608
|
var xpx, ypx;
|
|
28596
28609
|
|
|
28597
28610
|
if(hasUserCalledHover) {
|
|
@@ -28608,13 +28621,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
28608
28621
|
return;
|
|
28609
28622
|
}
|
|
28610
28623
|
|
|
28611
|
-
|
|
28612
|
-
var target = evt.composedPath && evt.composedPath()[0];
|
|
28613
|
-
if(!target) {
|
|
28614
|
-
// Fallback for browsers not supporting composedPath
|
|
28615
|
-
target = evt.target;
|
|
28616
|
-
}
|
|
28617
|
-
var dbb = target.getBoundingClientRect();
|
|
28624
|
+
var dbb = eventTarget.getBoundingClientRect();
|
|
28618
28625
|
|
|
28619
28626
|
xpx = evt.clientX - dbb.left;
|
|
28620
28627
|
ypx = evt.clientY - dbb.top;
|
|
@@ -29062,15 +29069,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
29062
29069
|
if(!helpers.isUnifiedHover(hovermode)) {
|
|
29063
29070
|
hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
|
|
29064
29071
|
alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
|
|
29065
|
-
} // TODO: tagName hack is needed to appease geo.js's hack of using
|
|
29072
|
+
} // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget=true
|
|
29066
29073
|
// we should improve the "fx" API so other plots can use it without these hack.
|
|
29067
|
-
if(
|
|
29074
|
+
if(eventTarget && eventTarget.tagName) {
|
|
29068
29075
|
var hasClickToShow = Registry.getComponentMethod('annotations', 'hasClickToShow')(gd, newhoverdata);
|
|
29069
|
-
overrideCursor(d3.select(
|
|
29076
|
+
overrideCursor(d3.select(eventTarget), hasClickToShow ? 'pointer' : '');
|
|
29070
29077
|
}
|
|
29071
29078
|
|
|
29072
29079
|
// don't emit events if called manually
|
|
29073
|
-
if(!
|
|
29080
|
+
if(!eventTarget || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
|
|
29074
29081
|
|
|
29075
29082
|
if(oldhoverdata) {
|
|
29076
29083
|
gd.emit('plotly_unhover', {
|
|
@@ -90219,7 +90226,7 @@ function getSortFunc(opts, d2c) {
|
|
|
90219
90226
|
'use strict';
|
|
90220
90227
|
|
|
90221
90228
|
// package version injected by `npm run preprocess`
|
|
90222
|
-
exports.version = '2.6.
|
|
90229
|
+
exports.version = '2.6.3';
|
|
90223
90230
|
|
|
90224
90231
|
},{}]},{},[12])(12)
|
|
90225
90232
|
});
|