diff --git a/draftlogs/8065_add.md b/draftlogs/8065_add.md new file mode 100644 index 00000000000..1dc05fd4ed3 --- /dev/null +++ b/draftlogs/8065_add.md @@ -0,0 +1 @@ +- Add *auto* to the `textposition` of `scatter`, `scatterpolar`, `scatterternary`, `scattercarpet` and `scattersmith` traces, to place text labels without overlaps and with leader lines for labels moved away from their points, and `textpriority` to set the order in which those labels take their positions [[#8065](https://github.com/plotly/plotly.js/pull/8065)] diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js index 3a71319c838..1bee348ca09 100644 --- a/src/components/drawing/index.js +++ b/src/components/drawing/index.js @@ -1240,32 +1240,172 @@ var TEXTOFFSETSIGN = { top: -1 }; -function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) { - var group = d3.select(s.node().parentNode); +// px between the end of a leader line and the label it points at +var LEADER_END_GAP = 2; +/** + * Compute the geometry of a text label relative to its point. + * + * @param textPosition - a `textposition` value other than *auto* + * @param fontSize - the font size in px + * @param markerRadius - the calculated marker radius in px, or 0 without markers + * @param numLines - the line count of the label + * @returns `anchor` for the `text-anchor` attribute, and `dx` and `dy` of the label group in px + */ +function textPointOffset(textPosition, fontSize, markerRadius, numLines) { var v = textPosition.indexOf('top') !== -1 ? 'top' : textPosition.indexOf('bottom') !== -1 ? 'bottom' : 'middle'; var h = textPosition.indexOf('left') !== -1 ? 'end' : textPosition.indexOf('right') !== -1 ? 'start' : 'middle'; + var sx = TEXTOFFSETSIGN[h]; + var sy = TEXTOFFSETSIGN[v]; // if markers are shown, offset a little more than // the nominal marker size // ie 2/1.6 * nominal, bcs some markers are a bit bigger var r = markerRadius ? markerRadius / 0.8 + 1 : 0; - var numLines = (svgTextUtils.lineCount(s) - 1) * LINE_SPACING + 1; - var dx = TEXTOFFSETSIGN[h] * r; - var dy = fontSize * 0.75 + TEXTOFFSETSIGN[v] * r + ((TEXTOFFSETSIGN[v] - 1) * numLines * fontSize) / 2; + var lineSpan = ((numLines || 1) - 1) * LINE_SPACING + 1; + return { + anchor: h, + dx: sx * r, + dy: fontSize * 0.75 + sy * r + ((sy - 1) * lineSpan * fontSize) / 2 + }; +} + +/** + * Compute the geometry of an *auto* text label from its measured box, so that + * every position keeps the same clearance between the marker and the text. + * + * @param textPosition - a `textposition` value other than *auto* + * @param markerRadius - the calculated marker radius in px, or 0 without markers + * @param markerSymbol - the marker symbol of the point, name or number + * @param bb - the label box from `drawing.bBox`, relative to the text anchor + * @param gap - extra px between the point and the label, set by the *auto* placement + * @returns the same shape as the fixed-position geometry: `anchor`, `dx`, `dy`, and `leader` + */ +drawing.textPointBoxOffset = function (textPosition, markerRadius, markerSymbol, bb, gap) { + var v = textPosition.indexOf('top') !== -1 ? 'top' : textPosition.indexOf('bottom') !== -1 ? 'bottom' : 'middle'; + var h = textPosition.indexOf('left') !== -1 ? 'end' : textPosition.indexOf('right') !== -1 ? 'start' : 'middle'; + var sx = TEXTOFFSETSIGN[h]; + var sy = TEXTOFFSETSIGN[v]; + var r = markerRadius || 0; + + // the clearance the side positions of the fixed-position geometry leave + var clearance = (r ? r / 4 + 1 : 0) + (gap || 0); + + // a corner label keeps the same clearance along the diagonal: from the + // edge of a circle, or from the corner of a square, which reaches the + // farthest of all symbols on the diagonal + var reach = r + clearance; + if (sx && sy) { + var isCircle = r && drawing.symbolNumber(markerSymbol) % 100 === 0; + reach = isCircle ? (r + clearance) / Math.SQRT2 : r + clearance / Math.SQRT2; + } + var ax = sx * reach; + var ay = sy * reach; + + var out = { + anchor: h, + dx: ax, + dy: sy < 0 ? ay - bb.bottom : sy > 0 ? ay - bb.top : -(bb.top + bb.bottom) / 2, + leader: null + }; + + if (gap > 0 && (sx || sy)) { + var norm = Math.sqrt(sx * sx + sy * sy); + var ux = sx / norm; + var uy = sy / norm; + out.leader = [ux * (r + 1), uy * (r + 1), ax - ux * LEADER_END_GAP, ay - uy * LEADER_END_GAP]; + } + + return out; +}; + +/** + * Resolve the `textposition` of one point. + * + * @returns the position, or null when the *auto* placement found no free spot for the label + */ +function getTextPosition(d, trace) { + var pos = d.tp || trace.textposition; + if (pos !== 'auto') return pos; + // the scatter *auto* placement sets `_tpAuto` after it draws all points of the subplot + return d._tpAuto === undefined ? 'middle center' : d._tpAuto; +} + +/** + * Measure a text label, from its `` node or from the MathJax render that replaces it. + * + * @param s - d3 selection of one `` element, inside its own `` + * @returns the label box from `drawing.bBox`, with `top` and `bottom` relative to the text anchor + */ +drawing.textPointBBox = function (s) { + var math = d3.select(s.node().parentNode).select('g.text-math-group'); + if (!math.size()) return drawing.bBox(s.node()); + + var bb = drawing.bBox(math.node()); + // the MathJax svg is placed in the frame of the `` node + bb.top = +math.select('svg').attr('y') - +s.attr('y'); + bb.bottom = bb.top + bb.height; + return bb; +}; + +/** + * Position a text label relative to its point, and join its leader line. + * + * @param s - d3 selection of one `` element, inside its own `` + * @param d - the calcdata point + * @param trace - the full trace + * @param markerRadius - the calculated marker radius in px, or undefined without markers + * @param dontTouchParent - true to leave the `transform` of the parent `` alone + */ +drawing.textPointPosition = function (s, d, trace, markerRadius, dontTouchParent) { + var group = d3.select(s.node().parentNode); + var isAuto = (d.tp || trace.textposition) === 'auto'; + var textPosition = getTextPosition(d, trace); + + var offset; + if (isAuto && textPosition) { + var symbol = d.mx || (trace.marker || {}).symbol; + var bb = drawing.textPointBBox(s); + offset = drawing.textPointBoxOffset(textPosition, markerRadius, symbol, bb, d._tpAutoGap); + + // a MathJax render is aligned to the anchor it had when it rendered + group.select('svg.text-math').attr('x', +s.attr('x') - (bb.width * (1 - TEXTOFFSETSIGN[offset.anchor])) / 2); + } else { + offset = textPointOffset( + textPosition || 'middle center', + drawing.textPointFontSize(d, trace), + markerRadius, + svgTextUtils.lineCount(s) + ); + } // fix the overall text group position - s.attr('text-anchor', h); + s.attr('text-anchor', offset.anchor); if (!dontTouchParent) { - group.attr('transform', strTranslate(dx, dy)); + // the whole group, so that a MathJax render is hidden with its source text + group.style('display', textPosition === null ? 'none' : null); + group.attr('transform', strTranslate(offset.dx, offset.dy)); } -} -function extracTextFontSize(d, trace) { + var leader = group.selectAll('path.textleader').data(d._tpAutoLeader ? [d._tpAutoLeader] : []); + leader.exit().remove(); + leader.enter().insert('path', ':first-child').classed('textleader', true).style('fill', 'none'); + leader.each(function (seg) { + // the leader is set in the plot frame, and the group is translated by (dx, dy) + var dx = offset.dx; + var dy = offset.dy; + d3.select(this) + .attr('d', 'M' + (seg[0] - dx) + ',' + (seg[1] - dy) + 'L' + (seg[2] - dx) + ',' + (seg[3] - dy)) + .style('stroke-width', 1) + .call(Color.stroke, s.node().style.fill); + }); +}; + +drawing.textPointFontSize = function (d, trace) { var fontSize = d.ts || trace.textfont.size; return isNumeric(fontSize) && fontSize > 0 ? fontSize : 0; -} +}; // draw text at points drawing.textPointStyle = function (s, trace, gd) { @@ -1306,8 +1446,7 @@ drawing.textPointStyle = function (s, trace, gd) { }); } - var pos = d.tp || trace.textposition; - var fontSize = extracTextFontSize(d, trace); + var fontSize = drawing.textPointFontSize(d, trace); var fontColor = selectedTextColorFn ? selectedTextColorFn(d) : d.tc || trace.textfont.color; p.call(drawing.font, { @@ -1322,8 +1461,10 @@ drawing.textPointStyle = function (s, trace, gd) { color: fontColor }) .text(text) - .call(svgTextUtils.convertToTspans, gd) - .call(textPointPosition, pos, fontSize, d.mrc); + .call(svgTextUtils.convertToTspans, gd, function () { + // a MathJax label is positioned once it is rendered + drawing.textPointPosition(p, d, trace, d.mrc); + }); }); }; @@ -1335,12 +1476,10 @@ drawing.selectedTextStyle = function (s, trace) { s.each(function (d) { var tx = d3.select(this); var tc = fns.selectedTextColorFn(d); - var tp = d.tp || trace.textposition; - var fontSize = extracTextFontSize(d, trace); Color.fill(tx, tc); var dontTouchParent = Registry.traceIs(trace, 'bar-like'); - textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc, dontTouchParent); + drawing.textPointPosition(tx, d, trace, d.mrc2 || d.mrc, dontTouchParent); }); }; diff --git a/src/lib/geometry2d.js b/src/lib/geometry2d.js index 199ca224eda..cc8c6b8bbe0 100644 --- a/src/lib/geometry2d.js +++ b/src/lib/geometry2d.js @@ -232,3 +232,351 @@ exports.findPointOnPath = function findPointOnPath(path, val, coord, opts) { } return pt; }; + +// candidate positions of a label, in order of preference +const POSITIONS = [ + 'top center', + 'bottom center', + 'middle right', + 'middle left', + 'top right', + 'top left', + 'bottom right', + 'bottom left' +]; + +// a label that may sit on its point tries that first +const POSITIONS_ON_POINT = ['middle center', ...POSITIONS]; + +// ring 0 touches the point, every ring after it adds LEADER_STEP +// font sizes of distance and a leader line back to the point +const LEADER_RINGS = 6; +const LEADER_STEP = 1; + +// a label without a leader line must keep CLUSTER_GAP font sizes +// from every other marker, or a reader cannot tell which point is its own +const CLUSTER_GAP = 1; + +// minimum px between a label and anything else +const PAD = 2; + +// markers within NEIGHBOR_RADIUS font sizes of a point push its label +// to the far side, so labels around a cluster point away from it +const NEIGHBOR_RADIUS = 3; + +// side of one cell of the spatial index, in px +const CELL_SIZE = 64; + +/** + * Place labels around their points, so that no label covers a marker, + * another label, or a leader line, and every label stays inside the area. + * + * Labels are placed in order of decreasing `priority`, then in the given + * order, so an earlier label wins a contested spot. Every label takes the + * first free candidate: the eight positions next to the point first, then + * the same positions farther out with a leader line back to the point. + * The positions are tried in the order that points away from the markers + * near the point, and in a fixed order when there are none. A position + * next to the point is used only when no other marker sits close to the + * label, so a leader line shows which point the label belongs to whenever + * that is in doubt. A label with no free candidate, or with its point + * outside the area, is hidden. + * + * @param opts.width - the width of the area in px + * @param opts.height - the height of the area in px + * @param opts.markers - the marker boxes, as `{x0, y0, x1, y1, owner}`; + * a label may cover the marker with its own `owner` + * @param opts.fixed - the other boxes that labels stay clear of, as `{x0, y0, x1, y1}` + * @param opts.labels - the labels to place, each with: + * `x`, `y` - the point in px; + * `owner` - the value that links the label to its marker, the label itself when absent; + * `radius` - the marker radius in px, or 0; + * `fontSize` - the font size in px, which scales the leader step and the clearance from other markers; + * `priority` - a number, higher first, 0 when absent; + * `onPoint` - true when the label may also sit on its point; + * `prefer`, `preferGap` - the position and gap the label had before: the label goes back next to + * its point at that position when it can, else it stays where it was, and only then it searches again; + * `rect(position, gap)` - the box of the label at a `textposition` value, `gap` px farther + * from the point, as `{x0, y0, x1, y1, leader}`, with `leader` as `[x0, y0, x1, y1]` + * from the marker edge to the box when `gap` is above 0, else null + * @returns one entry per label, in the given order: `{position, gap, leader}`, + * or null when the label is hidden + */ +exports.placeLabels = function placeLabels(opts) { + const index = makeIndex(opts.width, opts.height); + const markers = opts.markers || []; + const fixed = opts.fixed || []; + const labels = opts.labels; + + for (let i = 0; i < markers.length; i++) { + const m = markers[i]; + const rect = makeRect(m.x0 - PAD, m.y0 - PAD, m.x1 + PAD, m.y1 + PAD, m.owner); + rect.isMarker = true; + insert(index, rect); + } + for (let i = 0; i < fixed.length; i++) { + const f = fixed[i]; + insert(index, makeRect(f.x0, f.y0, f.x1, f.y1, f.owner)); + } + + const results = new Array(labels.length); + const order = sortLabels(labels); + for (let i = 0; i < order.length; i++) { + results[order[i]] = placeOne(index, labels[order[i]]); + } + return results; +}; + +// the order in which the labels are placed: by priority, high to low, then as given +function sortLabels(labels) { + const order = labels.map((label, i) => i); + order.sort((a, b) => (labels[b].priority || 0) - (labels[a].priority || 0) || a - b); + return order; +} + +function placeOne(index, label) { + const owner = label.owner === undefined ? label : label.owner; + const step = LEADER_STEP * label.fontSize; + const rings = step ? LEADER_RINGS : 0; + + // a point outside the area gets no label, even when a candidate box would fit inside + if (label.x < 0 || label.x > index.width || label.y < 0 || label.y > index.height) return null; + + // a label that was placed before does not step ring by ring on a redraw, so a pan does not shuffle leader lines + if (label.prefer) { + const out = + tryCandidate(index, label, owner, label.prefer, 0, rings) || + (label.preferGap && tryCandidate(index, label, owner, label.prefer, label.preferGap, rings)); + if (out) return out; + } + + const positions = orderPositions(index, label, owner); + + for (let ring = 0; ring <= rings; ring++) { + const gap = ring * step; + + for (let k = 0; k < positions.length; k++) { + const out = tryCandidate(index, label, owner, positions[k], gap, rings); + if (out) return out; + } + } + + return null; +} + +// take a candidate when its box and leader line are free, and it is not ambiguous +function tryCandidate(index, label, owner, pos, gap, rings) { + if (gap && pos === 'middle center') return null; + + const box = label.rect(pos, gap); + const rect = makeRect(box.x0, box.y0, box.x1, box.y1, owner); + if (!rectIsFree(index, rect)) return null; + if (!gap && rings && isAmbiguous(index, rect, CLUSTER_GAP * label.fontSize)) return null; + + const seg = box.leader; + const line = seg ? makeLine(seg[0], seg[1], seg[2], seg[3], owner) : null; + if (line && !lineIsFree(index, line, label.x, label.y)) return null; + + insert(index, rect); + if (line) insert(index, line); + return { position: pos, gap, leader: seg || null }; +} + +// the candidate positions of a label, sorted so that the ones that point +// away from the nearby markers come first; ties keep the default order +function orderPositions(index, label, owner) { + const positions = label.onPoint ? POSITIONS_ON_POINT : POSITIONS; + const r = ((label.radius || 0) + NEIGHBOR_RADIUS * label.fontSize) ** 2; + const b = cellBounds( + index, + label.x - Math.sqrt(r), + label.y - Math.sqrt(r), + label.x + Math.sqrt(r), + label.y + Math.sqrt(r) + ); + const cells = index.cells; + let ax = 0; + let ay = 0; + + for (let row = b[1]; row <= b[3]; row++) { + for (let col = b[0]; col <= b[2]; col++) { + const cell = cells[row * index.ncols + col]; + if (!cell) continue; + + for (let i = 0; i < cell.length; i++) { + const ob = cell[i]; + if (!ob.isMarker || ob.owner === owner) continue; + const dx = label.x - (ob.x0 + ob.x1) / 2; + const dy = label.y - (ob.y0 + ob.y1) / 2; + const d2 = dx * dx + dy * dy; + if (!d2 || d2 > r) continue; + // nearer markers push harder + ax += dx / d2; + ay += dy / d2; + } + } + } + + let out = positions; + if (ax || ay) { + const scored = positions.map((pos, k) => { + const sx = pos.indexOf('right') !== -1 ? 1 : pos.indexOf('left') !== -1 ? -1 : 0; + const sy = pos.indexOf('bottom') !== -1 ? 1 : pos.indexOf('top') !== -1 ? -1 : 0; + const norm = Math.sqrt(sx * sx + sy * sy) || 1; + return { pos, k, score: (sx * ax + sy * ay) / norm }; + }); + scored.sort((a, b) => b.score - a.score || a.k - b.k); + out = scored.map((s) => s.pos); + } + + const prefer = label.prefer; + if (prefer && out.indexOf(prefer) > 0) out = [prefer, ...out.filter((pos) => pos !== prefer)]; + return out; +} + +// true when another marker sits within `margin` px of a label box, +// measured from the nearest edge or corner of the box +function isAmbiguous(index, rect, margin) { + const b = cellBounds(index, rect.x0 - margin, rect.y0 - margin, rect.x1 + margin, rect.y1 + margin); + const cells = index.cells; + + for (let row = b[1]; row <= b[3]; row++) { + for (let col = b[0]; col <= b[2]; col++) { + const cell = cells[row * index.ncols + col]; + if (!cell) continue; + + for (let i = 0; i < cell.length; i++) { + const ob = cell[i]; + if (!ob.isMarker || ob.owner === rect.owner) continue; + const dx = Math.max(0, ob.x0 - rect.x1, rect.x0 - ob.x1); + const dy = Math.max(0, ob.y0 - rect.y1, rect.y0 - ob.y1); + if (dx * dx + dy * dy < margin * margin) return true; + } + } + } + + return false; +} + +function makeRect(x0, y0, x1, y1, owner) { + return { x0, y0, x1, y1, owner, isLine: false, isMarker: false }; +} + +function makeLine(x0, y0, x1, y1, owner) { + return { x0, y0, x1, y1, owner, isLine: true, isMarker: false }; +} + +function makeIndex(width, height) { + return { + width, + height, + ncols: Math.max(1, Math.ceil(width / CELL_SIZE)), + nrows: Math.max(1, Math.ceil(height / CELL_SIZE)), + cells: [] + }; +} + +// the cells that cover a box, clamped to the grid, as [col0, row0, col1, row1] +function cellBounds(index, x0, y0, x1, y1) { + const maxCol = index.ncols - 1; + const maxRow = index.nrows - 1; + return [ + constrain(Math.floor(Math.min(x0, x1) / CELL_SIZE), 0, maxCol), + constrain(Math.floor(Math.min(y0, y1) / CELL_SIZE), 0, maxRow), + constrain(Math.floor(Math.max(x0, x1) / CELL_SIZE), 0, maxCol), + constrain(Math.floor(Math.max(y0, y1) / CELL_SIZE), 0, maxRow) + ]; +} + +function insert(index, ob) { + const b = cellBounds(index, ob.x0, ob.y0, ob.x1, ob.y1); + const cells = index.cells; + + for (let row = b[1]; row <= b[3]; row++) { + for (let col = b[0]; col <= b[2]; col++) { + const id = row * index.ncols + col; + if (!cells[id]) cells[id] = []; + cells[id].push(ob); + } + } +} + +// a label box is free when it stays inside the area +// and hits nothing but the marker of its own point +function rectIsFree(index, rect) { + const x0 = rect.x0 - PAD; + const y0 = rect.y0 - PAD; + const x1 = rect.x1 + PAD; + const y1 = rect.y1 + PAD; + if (x0 < 0 || y0 < 0 || x1 > index.width || y1 > index.height) return false; + + const b = cellBounds(index, x0, y0, x1, y1); + const cells = index.cells; + + for (let row = b[1]; row <= b[3]; row++) { + for (let col = b[0]; col <= b[2]; col++) { + const cell = cells[row * index.ncols + col]; + if (!cell) continue; + + for (let i = 0; i < cell.length; i++) { + const ob = cell[i]; + if (ob.owner === rect.owner) continue; + const hit = ob.isLine + ? lineHitsRect(ob, x0, y0, x1, y1) + : ob.x0 < x1 && ob.x1 > x0 && ob.y0 < y1 && ob.y1 > y0; + if (hit) return false; + } + } + } + + return true; +} + +// a leader line is free when it crosses nothing but the marker of its own point +// and the obstacles that already cover the point (px, py), which no candidate can escape +function lineIsFree(index, line, px, py) { + const b = cellBounds(index, line.x0, line.y0, line.x1, line.y1); + const cells = index.cells; + + for (let row = b[1]; row <= b[3]; row++) { + for (let col = b[0]; col <= b[2]; col++) { + const cell = cells[row * index.ncols + col]; + if (!cell) continue; + + for (let i = 0; i < cell.length; i++) { + const ob = cell[i]; + if (ob.owner === line.owner) continue; + let hit; + if (ob.isLine) { + hit = segmentsIntersect(line.x0, line.y0, line.x1, line.y1, ob.x0, ob.y0, ob.x1, ob.y1); + } else if (!pointInRect(px, py, ob.x0, ob.y0, ob.x1, ob.y1)) { + hit = lineHitsRect(line, ob.x0, ob.y0, ob.x1, ob.y1); + } + if (hit) return false; + } + } + } + + return true; +} + +function lineHitsRect(line, x0, y0, x1, y1) { + if (pointInRect(line.x0, line.y0, x0, y0, x1, y1)) return true; + if (pointInRect(line.x1, line.y1, x0, y0, x1, y1)) return true; + + const { x0: ax, y0: ay, x1: bx, y1: by } = line; + return !!( + segmentsIntersect(ax, ay, bx, by, x0, y0, x1, y0) || + segmentsIntersect(ax, ay, bx, by, x1, y0, x1, y1) || + segmentsIntersect(ax, ay, bx, by, x1, y1, x0, y1) || + segmentsIntersect(ax, ay, bx, by, x0, y1, x0, y0) + ); +} + +function pointInRect(x, y, x0, y0, x1, y1) { + return x > x0 && x < x1 && y > y0 && y < y1; +} + +function constrain(v, v0, v1) { + return Math.max(v0, Math.min(v1, v)); +} diff --git a/src/lib/index.js b/src/lib/index.js index 7c0d136e026..0b6585560d2 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -164,6 +164,7 @@ lib.segmentsIntersect = geom2dModule.segmentsIntersect; lib.segmentDistance = geom2dModule.segmentDistance; lib.getTextLocation = geom2dModule.getTextLocation; lib.clearLocationCache = geom2dModule.clearLocationCache; +lib.placeLabels = geom2dModule.placeLabels; lib.getVisibleSegment = geom2dModule.getVisibleSegment; lib.findPointOnPath = geom2dModule.findPointOnPath; diff --git a/src/plot_api/helpers.js b/src/plot_api/helpers.js index 1dc17062f52..36cac61120f 100644 --- a/src/plot_api/helpers.js +++ b/src/plot_api/helpers.js @@ -324,6 +324,8 @@ function commonPrefix(name1, name2, show1, show2) { // textposition - support partial attributes (ie just 'top') // and incorrect use of middle / center etc. function cleanTextPosition(textposition) { + if (textposition === 'auto') return textposition; + var posY = 'middle'; var posX = 'center'; diff --git a/src/plots/map/layout_attributes.js b/src/plots/map/layout_attributes.js index 0c55c82f2e9..4ba96b648b2 100644 --- a/src/plots/map/layout_attributes.js +++ b/src/plots/map/layout_attributes.js @@ -319,7 +319,12 @@ var attrs = (module.exports = overrideAll( ].join(' ') }, textfont: fontAttr, - textposition: Lib.extendFlat({}, textposition, { arrayOk: false }) + textposition: Lib.extendFlat({}, textposition, { + // *auto* placement runs in the svg scatter plot code only + values: textposition.values.filter((v) => v !== 'auto'), + arrayOk: false, + description: 'Sets the positions of the `text` elements with respects to the (x,y) coordinates.' + }) } }) }, diff --git a/src/traces/quiver/attributes.js b/src/traces/quiver/attributes.js index d6fcdda809d..a618eed12d7 100644 --- a/src/traces/quiver/attributes.js +++ b/src/traces/quiver/attributes.js @@ -99,7 +99,11 @@ var attrs = { // Text and labels (shared with scatter) text: scatterAttrs.text, - textposition: scatterAttrs.textposition, + textposition: extendFlat({}, scatterAttrs.textposition, { + // *auto* placement runs in the svg scatter plot code only + values: scatterAttrs.textposition.values.filter((v) => v !== 'auto'), + description: 'Sets the positions of the `text` elements with respects to the (x,y) coordinates.' + }), textfont: scatterAttrs.textfont, // Marker: color, colorscale, arrowhead sizing, and line styling for arrows diff --git a/src/traces/scatter/arrays_to_calcdata.js b/src/traces/scatter/arrays_to_calcdata.js index 07eac057140..4be6b2152d9 100644 --- a/src/traces/scatter/arrays_to_calcdata.js +++ b/src/traces/scatter/arrays_to_calcdata.js @@ -13,6 +13,7 @@ module.exports = function arraysToCalcdata(cd, trace) { Lib.mergeArray(trace.hovertext, cd, 'htx'); Lib.mergeArray(trace.customdata, cd, 'data'); Lib.mergeArray(trace.textposition, cd, 'tp'); + Lib.mergeArray(trace.textpriority, cd, 'tP'); if(trace.textfont) { Lib.mergeArrayCastPositive(trace.textfont.size, cd, 'ts'); Lib.mergeArray(trace.textfont.color, cd, 'tc'); diff --git a/src/traces/scatter/attributes.js b/src/traces/scatter/attributes.js index 255496750a0..6a83e7368e5 100644 --- a/src/traces/scatter/attributes.js +++ b/src/traces/scatter/attributes.js @@ -663,12 +663,38 @@ module.exports = { 'middle right', 'bottom left', 'bottom center', - 'bottom right' + 'bottom right', + 'auto' ], dflt: 'middle center', arrayOk: true, editType: 'calc', - description: ['Sets the positions of the `text` elements', 'with respects to the (x,y) coordinates.'].join(' ') + description: [ + 'Sets the positions of the `text` elements', + 'with respects to the (x,y) coordinates.', + 'With *auto*, each label takes the first position around its point', + 'that overlaps no marker and no other label on the subplot.', + 'When the positions next to the point are taken, or another point', + 'sits close to the label, the label moves farther out with a leader', + 'line back to the point. A label with no free position is hidden.', + 'Labels are placed in the order of `textpriority`.', + 'Auto placement considers markers and text labels only.', + 'It does not avoid annotations, shapes, images, or the legend.' + ].join(' ') + }, + textpriority: { + valType: 'number', + dflt: 0, + arrayOk: true, + editType: 'calc', + description: [ + 'Sets the placement priority of the `text` elements', + 'with `textposition` *auto*, per point or for the whole trace.', + 'A label with a higher priority takes its position', + 'before the labels of lower priority on the subplot,', + 'so it stays next to its point and is hidden last.', + 'Labels of equal priority are placed in trace and data order.' + ].join(' ') }, textfont: fontAttrs({ editType: 'calc', diff --git a/src/traces/scatter/auto_text_position.js b/src/traces/scatter/auto_text_position.js new file mode 100644 index 00000000000..b2715a8cec4 --- /dev/null +++ b/src/traces/scatter/auto_text_position.js @@ -0,0 +1,146 @@ +'use strict'; + +const d3 = require('@plotly/d3'); +const Lib = require('../../lib'); +const Drawing = require('../../components/drawing'); +const subTypes = require('./subtypes'); + +/** + * Resolve the *auto* text positions of all scatter traces on one subplot. + * + * Every drawn marker and every label with a fixed position blocks the *auto* + * labels, which `Lib.placeLabels` then places by `textpriority`, trace order, + * and data order. + * + * Sets `_tpAuto`, `_tpAutoGap`, and `_tpAutoLeader` on every calcdata point + * with an *auto* position and repositions its `` node. Does nothing + * when no trace of the subplot uses *auto*. + * + * A label that MathJax has not rendered yet has no box, so it is skipped, + * and the whole pass runs again once every pending render is done. + * + * @param gd - the graph div + * @param plotinfo - the subplot, with `xaxis` and `yaxis` + * @param traceGroups - d3 selection of the `g.trace` groups, bound to calcdata + */ +module.exports = function autoTextPosition(gd, plotinfo, traceGroups) { + let hasAuto = false; + traceGroups.each((cd) => { + const trace = cd[0].trace; + if (trace.visible === true && hasAutoTextPosition(trace)) hasAuto = true; + }); + if (!hasAuto) return; + + const xa = plotinfo.xaxis; + const ya = plotinfo.yaxis; + const markers = []; + const fixed = []; + const labels = []; + let pending = false; + + traceGroups.each(function (cd) { + const trace = cd[0].trace; + if (trace.visible !== true) return; + + const hasMarkers = subTypes.hasMarkers(trace); + const tr = d3.select(this); + + if (hasMarkers) { + tr.selectAll('path.point').each((d) => { + const x = xa.c2p(d.x); + const y = ya.c2p(d.y); + const r = d.mrc || 0; + markers.push({ x0: x - r, y0: y - r, x1: x + r, y1: y + r, owner: d }); + }); + } + + if (!subTypes.hasText(trace)) return; + + // a label without a marker or a line can also sit on its point + const onPoint = !hasMarkers && !subTypes.hasLines(trace); + + tr.selectAll('g.textpoint').each(function (d) { + const g = d3.select(this); + const tx = g.select('text'); + if (!tx.size()) return; + + // `convertToTspans` hides the tex source until MathJax replaces it + if (tx.node().style.display === 'none' && !g.select('g.text-math-group').size()) { + pending = true; + return; + } + + const pos = d.tp || trace.textposition; + const x = xa.c2p(d.x); + const y = ya.c2p(d.y); + const label = { + tx, + trace, + x, + y, + owner: d, + radius: d.mrc || 0, + fontSize: Drawing.textPointFontSize(d, trace), + priority: Lib.extractOption(d, trace, 'tP', 'textpriority'), + onPoint, + // `_tpAuto` survives a relayout, so a pan or zoom keeps the labels in place where it can + prefer: d._tpAuto || undefined, + preferGap: d._tpAutoGap, + rect: labelRect(d, trace, x, y, Drawing.textPointBBox(tx)) + }; + + if (pos === 'auto') { + labels.push(label); + } else { + const box = label.rect(pos, 0); + box.owner = d; + fixed.push(box); + } + }); + }); + + const results = Lib.placeLabels({ width: xa._length, height: ya._length, markers, fixed, labels }); + + for (let i = 0; i < labels.length; i++) { + const label = labels[i]; + const d = label.owner; + const out = results[i]; + d._tpAuto = out ? out.position : null; + d._tpAutoGap = out ? out.gap : 0; + // in the plot frame, so the leader does not depend on the `` node in mid-transition + d._tpAutoLeader = out ? out.leader : null; + Drawing.textPointPosition(label.tx, d, label.trace, d.mrc); + } + + if (pending) { + gd._promises.push(Promise.all(gd._promises).then(() => autoTextPosition(gd, plotinfo, traceGroups))); + } +}; + +function hasAutoTextPosition(trace) { + const tp = trace.textposition; + return tp === 'auto' || (Lib.isArrayOrTypedArray(tp) && tp.indexOf('auto') !== -1); +} + +// the box of a label at a given position and gap, plus its leader line, in the plot frame +function labelRect(d, trace, x, y, bb) { + const symbol = d.mx || (trace.marker || {}).symbol; + + return (pos, gap) => { + const offset = Drawing.textPointBoxOffset(pos, d.mrc, symbol, bb, gap); + + let x0 = x + offset.dx; + if (offset.anchor === 'end') x0 -= bb.width; + else if (offset.anchor === 'middle') x0 -= bb.width / 2; + const y0 = y + offset.dy + bb.top; + + const seg = offset.leader; + return { + x0, + y0, + x1: x0 + bb.width, + y1: y0 + bb.height, + leader: seg ? [x + seg[0], y + seg[1], x + seg[2], y + seg[3]] : null + }; + }; +} diff --git a/src/traces/scatter/plot.js b/src/traces/scatter/plot.js index 3c9e19df936..bbbd42acc88 100644 --- a/src/traces/scatter/plot.js +++ b/src/traces/scatter/plot.js @@ -12,6 +12,7 @@ var subTypes = require('./subtypes'); var linePoints = require('./line_points'); var linkTraces = require('./link_traces'); var polygonTester = require('../../lib/polygon').tester; +var autoTextPosition = require('./auto_text_position'); module.exports = function plot(gd, plotinfo, cdscatter, scatterLayer, transitionOpts, makeOnCompleteCallback) { var join, onComplete; @@ -61,11 +62,13 @@ module.exports = function plot(gd, plotinfo, cdscatter, scatterLayer, transition scatterLayer.selectAll('g.trace').each(function(d, i) { plotOne(gd, i, plotinfo, d, cdscatterSorted, this, transitionOpts); }); + autoTextPosition(gd, plotinfo, scatterLayer.selectAll('g.trace')); }); } else { join.each(function(d, i) { plotOne(gd, i, plotinfo, d, cdscatterSorted, this, transitionOpts); }); + autoTextPosition(gd, plotinfo, join); } if(isFullReplot) { diff --git a/src/traces/scatter/text_defaults.js b/src/traces/scatter/text_defaults.js index 36bbb9c674a..0bce05a6526 100644 --- a/src/traces/scatter/text_defaults.js +++ b/src/traces/scatter/text_defaults.js @@ -9,7 +9,10 @@ var Lib = require('../../lib'); module.exports = function(traceIn, traceOut, layout, coerce, opts) { opts = opts || {}; - coerce('textposition'); + var textposition = coerce('textposition'); + if (textposition === 'auto' || (Lib.isArrayOrTypedArray(textposition) && textposition.indexOf('auto') !== -1)) { + coerce('textpriority'); + } Lib.coerceFont(coerce, 'textfont', opts.font || layout.font, opts); if(!opts.noSelect) { diff --git a/src/traces/scatter3d/attributes.js b/src/traces/scatter3d/attributes.js index 7191d73c1b6..a56d7c6b01a 100644 --- a/src/traces/scatter3d/attributes.js +++ b/src/traces/scatter3d/attributes.js @@ -158,7 +158,12 @@ var attrs = (module.exports = overrideAll( colorAttributes('marker') ), - textposition: extendFlat({}, scatterAttrs.textposition, { dflt: 'top center' }), + textposition: extendFlat({}, scatterAttrs.textposition, { + // *auto* placement runs in the svg scatter plot code only + values: scatterAttrs.textposition.values.filter((v) => v !== 'auto'), + dflt: 'top center', + description: 'Sets the positions of the `text` elements with respects to the (x,y) coordinates.' + }), textfont: fontAttrs({ noFontShadow: true, noFontLineposition: true, diff --git a/src/traces/scattercarpet/attributes.js b/src/traces/scattercarpet/attributes.js index e5ea51d82cd..22db4d3004d 100644 --- a/src/traces/scattercarpet/attributes.js +++ b/src/traces/scattercarpet/attributes.js @@ -110,6 +110,7 @@ module.exports = { textfont: scatterAttrs.textfont, textposition: scatterAttrs.textposition, + textpriority: scatterAttrs.textpriority, selected: scatterAttrs.selected, unselected: scatterAttrs.unselected, diff --git a/src/traces/scattergeo/attributes.js b/src/traces/scattergeo/attributes.js index 1aeddeb5474..60236b65f10 100644 --- a/src/traces/scattergeo/attributes.js +++ b/src/traces/scattergeo/attributes.js @@ -104,7 +104,11 @@ module.exports = overrideAll( }), textfont: scatterAttrs.textfont, - textposition: scatterAttrs.textposition, + textposition: extendFlat({}, scatterAttrs.textposition, { + // *auto* placement runs in the svg scatter plot code only + values: scatterAttrs.textposition.values.filter((v) => v !== 'auto'), + description: 'Sets the positions of the `text` elements with respects to the (x,y) coordinates.' + }), line: { color: scatterLineAttrs.color, diff --git a/src/traces/scattergl/attributes.js b/src/traces/scattergl/attributes.js index 59188554c52..482ffde2dce 100644 --- a/src/traces/scattergl/attributes.js +++ b/src/traces/scattergl/attributes.js @@ -37,7 +37,11 @@ var attrs = (module.exports = overrideAll( text: scatterAttrs.text, hovertext: scatterAttrs.hovertext, - textposition: scatterAttrs.textposition, + textposition: extendFlat({}, scatterAttrs.textposition, { + // *auto* placement runs in the svg scatter plot code only + values: scatterAttrs.textposition.values.filter((v) => v !== 'auto'), + description: 'Sets the positions of the `text` elements with respects to the (x,y) coordinates.' + }), textfont: fontAttrs({ noFontShadow: true, noFontLineposition: true, diff --git a/src/traces/scatterpolar/attributes.js b/src/traces/scatterpolar/attributes.js index 115cfba0377..cf066e3390e 100644 --- a/src/traces/scatterpolar/attributes.js +++ b/src/traces/scatterpolar/attributes.js @@ -94,6 +94,7 @@ module.exports = { cliponaxis: extendFlat({}, scatterAttrs.cliponaxis, { dflt: false }), textposition: scatterAttrs.textposition, + textpriority: scatterAttrs.textpriority, textfont: scatterAttrs.textfont, fill: extendFlat({}, scatterAttrs.fill, { diff --git a/src/traces/scatterpolargl/attributes.js b/src/traces/scatterpolargl/attributes.js index 80f896b4dbc..d803a06dd6b 100644 --- a/src/traces/scatterpolargl/attributes.js +++ b/src/traces/scatterpolargl/attributes.js @@ -1,7 +1,7 @@ 'use strict'; -// No cliponaxis or hoveron -const { cliponaxis, hoveron, ...scatterPolarAttrs } = require('../scatterpolar/attributes'); +// No cliponaxis or hoveron, and no textpriority without *auto* textposition +const { cliponaxis, hoveron, textpriority, ...scatterPolarAttrs } = require('../scatterpolar/attributes'); const { connectgaps, line: { color, dash, width }, diff --git a/src/traces/scattersmith/attributes.js b/src/traces/scattersmith/attributes.js index c6e8cdbfaee..9d96ad8525c 100644 --- a/src/traces/scattersmith/attributes.js +++ b/src/traces/scattersmith/attributes.js @@ -50,6 +50,7 @@ module.exports = { cliponaxis: extendFlat({}, scatterAttrs.cliponaxis, { dflt: false }), textposition: scatterAttrs.textposition, + textpriority: scatterAttrs.textpriority, textfont: scatterAttrs.textfont, fill: extendFlat({}, scatterAttrs.fill, { diff --git a/src/traces/scatterternary/attributes.js b/src/traces/scatterternary/attributes.js index 315c04c4144..0efa8c5714e 100644 --- a/src/traces/scatterternary/attributes.js +++ b/src/traces/scatterternary/attributes.js @@ -139,6 +139,7 @@ module.exports = { textfont: scatterAttrs.textfont, textposition: scatterAttrs.textposition, + textpriority: scatterAttrs.textpriority, selected: scatterAttrs.selected, unselected: scatterAttrs.unselected, diff --git a/src/types/generated/schema.d.ts b/src/types/generated/schema.d.ts index fda9a6817e9..5bd55af6a59 100644 --- a/src/types/generated/schema.d.ts +++ b/src/types/generated/schema.d.ts @@ -7337,10 +7337,15 @@ export interface ScatterData { /** Sets the text font. */ textfont?: FontArray; /** - * Sets the positions of the `text` elements with respects to the (x,y) coordinates. + * Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend. * @default 'middle center' */ - textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right')[]; + textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto')[]; + /** + * Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order. + * @default 0 + */ + textpriority?: number | number[]; /** Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example "y: %{y}". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of "data: %{x}, %{y}" will result in a value of "data: 1, %{y}" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. */ texttemplate?: string | string[]; /** @@ -8063,10 +8068,15 @@ export interface ScattercarpetData { /** Sets the text font. */ textfont?: FontArray; /** - * Sets the positions of the `text` elements with respects to the (x,y) coordinates. + * Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend. * @default 'middle center' */ - textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right')[]; + textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto')[]; + /** + * Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order. + * @default 0 + */ + textpriority?: number | number[]; /** Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example "y: %{y}". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of "data: %{x}, %{y}" will result in a value of "data: 1, %{y}" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `a`, `b` and `text`. */ texttemplate?: string | string[]; /** @@ -9098,10 +9108,15 @@ export interface ScatterpolarData { /** Sets the text font. */ textfont?: FontArray; /** - * Sets the positions of the `text` elements with respects to the (x,y) coordinates. + * Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend. * @default 'middle center' */ - textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right')[]; + textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto')[]; + /** + * Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order. + * @default 0 + */ + textpriority?: number | number[]; /** Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example "y: %{y}". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of "data: %{x}, %{y}" will result in a value of "data: 1, %{y}" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `r`, `theta` and `text`. */ texttemplate?: string | string[]; /** @@ -9491,10 +9506,15 @@ export interface ScattersmithData { /** Sets the text font. */ textfont?: FontArray; /** - * Sets the positions of the `text` elements with respects to the (x,y) coordinates. + * Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend. * @default 'middle center' */ - textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right')[]; + textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto')[]; + /** + * Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order. + * @default 0 + */ + textpriority?: number | number[]; /** Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example "y: %{y}". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of "data: %{x}, %{y}" will result in a value of "data: 1, %{y}" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `real`, `imag` and `text`. */ texttemplate?: string | string[]; /** @@ -9682,10 +9702,15 @@ export interface ScatterternaryData { /** Sets the text font. */ textfont?: FontArray; /** - * Sets the positions of the `text` elements with respects to the (x,y) coordinates. + * Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend. * @default 'middle center' */ - textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right')[]; + textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | 'auto')[]; + /** + * Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order. + * @default 0 + */ + textpriority?: number | number[]; /** Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example "y: %{y}". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of "data: %{x}, %{y}" will result in a value of "data: 1, %{y}" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `a`, `b`, `c` and `text`. */ texttemplate?: string | string[]; /** diff --git a/test/image/mocks/text_chart_autoposition.json b/test/image/mocks/text_chart_autoposition.json new file mode 100644 index 00000000000..0238e78b139 --- /dev/null +++ b/test/image/mocks/text_chart_autoposition.json @@ -0,0 +1,271 @@ +{ + "data": [ + { + "name": "symbols and font sizes", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [2, 2.15, 2.3, 2.1, 2.25, 2.4], + "y": [7, 7.1, 7.2, 6.85, 6.95, 7.05], + "text": [ + "circle", + "square", + "diamond", + "open circle", + "star", + "big text" + ], + "marker": { + "size": 12, + "symbol": [ + "circle", + "square", + "diamond", + "circle-open", + "star", + "circle" + ] + }, + "textfont": { + "size": [11, 11, 11, 11, 11, 18] + } + }, + { + "name": "multi-line", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [5, 5.2, 5.1, 5.35], + "y": [7, 7.1, 6.8, 6.9], + "text": ["Two
lines", "one line", "plain", "Three
short
lines"], + "marker": { + "size": 12, + "color": "#d62728" + } + }, + { + "name": "bubbles", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [8, 8.4, 8.2], + "y": [7, 7.1, 6.7], + "text": ["bubble 40", "bubble 18", "bubble 8"], + "marker": { + "size": [40, 18, 8], + "color": "#2ca02c", + "opacity": 0.6 + } + }, + { + "name": "clock: natural side", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [ + 10.8, 10.875, 10.9299, 10.95, 10.9299, 10.875, 10.8, 10.725, 10.6701, + 10.65, 10.6701, 10.725 + ], + "y": [ + 7.15, 7.1299, 7.075, 7.0, 6.925, 6.8701, 6.85, 6.8701, 6.925, 7.0, + 7.075, 7.1299 + ], + "text": ["12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"], + "marker": { + "size": 12, + "color": "#17becf" + } + }, + { + "name": "text only", + "type": "scatter", + "mode": "text", + "textposition": "auto", + "x": [1, 1, 1.05], + "y": [5, 5, 5], + "text": ["one", "two", "three"], + "textfont": { + "color": "#9467bd" + } + }, + { + "name": "fixed mixed with auto", + "type": "scatter", + "mode": "markers+text", + "textposition": ["top center", "auto", "auto", "bottom center"], + "x": [3.2, 3.25, 3.3, 3.35], + "y": [5, 5.05, 5.1, 5.15], + "text": ["fixed top", "auto A", "auto B", "fixed bottom"], + "marker": { + "size": 12, + "symbol": "square", + "color": "#8c564b" + } + }, + { + "name": "order trap: obstacles", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [5.7, 6.3, 6.0, 5.5, 5.8], + "y": [5, 5, 4.72, 5.28, 5.55], + "text": ["", "", "", "", ""], + "marker": { + "size": 12, + "color": "#7f7f7f" + } + }, + { + "name": "order trap", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [5.8, 6.0], + "y": [5.28, 5.0], + "text": ["A: first in data", "B: boxed in"], + "marker": { + "size": 12, + "color": "#e377c2" + } + }, + { + "name": "diagonal chain", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [9.0, 9.22, 9.44, 9.66, 9.88, 10.1, 10.32], + "y": [ + 4.4, 4.6000000000000005, 4.800000000000001, 5.0, 5.2, 5.4, + 5.6000000000000005 + ], + "text": ["d1", "d2", "d3", "d4", "d5", "d6", "d7"], + "marker": { + "size": 12, + "color": "#bcbd22" + } + }, + { + "name": "row: alternate sides", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [ + 1.0, 1.32, 1.6400000000000001, 1.96, 2.2800000000000002, 2.6, 2.92, 3.24 + ], + "y": [3, 3, 3, 3, 3, 3, 3, 3], + "text": ["r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8"], + "marker": { + "size": 12, + "color": "#1f77b4" + } + }, + { + "name": "ring: inside or outside", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [5.2, 5.5889, 5.75, 5.5889, 5.2, 4.8111, 4.65, 4.8111], + "y": [3.55, 3.3889, 3.0, 2.6111, 2.45, 2.6111, 3.0, 3.3889], + "text": ["N", "NE", "E", "SE", "S", "SW", "W", "NW"], + "marker": { + "size": 12, + "color": "#ff7f0e" + } + }, + { + "name": "two clusters: crossing leaders", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [ + 8.6, 8.7141, 8.6705, 8.5295, 8.4859, 9.5, 9.6141, 9.5705, 9.4295, 9.3859 + ], + "y": [ + 3.12, 3.0371, 2.9029, 2.9029, 3.0371, 3.12, 3.0371, 2.9029, 2.9029, + 3.0371 + ], + "text": ["L1", "L2", "L3", "L4", "L5", "R1", "R2", "R3", "R4", "R5"], + "marker": { + "size": 12, + "color": "#2ca02c" + } + }, + { + "name": "blob: how many fit", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [ + 10.841, 10.686, 11.136, 10.615, 11.032, 10.879, 10.602, 11.007, 10.584, + 10.94, 10.613, 10.632, 10.932, 11.294, 10.661 + ], + "y": [ + 2.779, 3.102, 3.358, 3.062, 2.917, 3.381, 2.637, 3.287, 2.832, 2.715, + 2.694, 2.847, 3.253, 2.745, 3.065 + ], + "text": [ + "b1", + "b2", + "b3", + "b4", + "b5", + "b6", + "b7", + "b8", + "b9", + "b10", + "b11", + "b12", + "b13", + "b14", + "b15" + ], + "marker": { + "size": 12, + "color": "#d62728" + } + }, + { + "name": "edges and corners", + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "x": [0, 12, 0, 12, 6, 6, 0, 12], + "y": [8, 8, 0, 0, 8, 0, 4.2, 4.2], + "text": [ + "top-left corner", + "top-right corner", + "bottom-left corner", + "bottom-right corner", + "top edge", + "bottom edge", + "left edge", + "right edge" + ], + "marker": { + "size": 12, + "color": "#ff7f0e" + } + } + ], + "layout": { + "title": { + "text": "textposition: auto" + }, + "width": 1200, + "height": 800, + "margin": { + "l": 50, + "r": 30, + "t": 60, + "b": 50 + }, + "showlegend": false, + "xaxis": { + "range": [0, 12] + }, + "yaxis": { + "range": [0, 8] + } + } +} diff --git a/test/image/mocks/text_chart_autoposition_real.json b/test/image/mocks/text_chart_autoposition_real.json new file mode 100644 index 00000000000..6c5dbfcebd7 --- /dev/null +++ b/test/image/mocks/text_chart_autoposition_real.json @@ -0,0 +1,176 @@ +{ + "data": [ + { + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "name": "Mostly women", + "x": [ + 0.0184, 0.06007, 0.07486, 0.08976, 0.103, 0.26177, 0.26871, 0.41749, + 0.48319, 1.02648, 1.21504, 1.24624, 1.36008, 1.5286, 1.70498, 2.11077, + 2.17576, 2.64545, 2.82591, 3.71193, 4.50175, 6.02744, 6.17446, 9.76152, + 12.51926, 14.993 + ], + "y": [ + 38, 148, 177, 135, 30, 49, 112, 66, 53, 12, 37, 757, 15, 21, 9, 6, 3620, + 98, 141, 35, 118, 17, 176, 147, 43, 253 + ], + "text": [ + "Scleroderma", + "Lupus", + "Ovarian cancer", + "Cervical cancer", + "Sjögren's", + "Uterine cancer", + "Multiple sclerosis", + "Rheumatoid arthritis", + "Eating disorders", + "ME/CFS", + "Endometriosis", + "Breast cancer", + "Fibromyalgia", + "Uterine fibroids", + "PCOS", + "Vulvodynia", + "Alzheimer's", + "Long COVID", + "PTSD", + "TMJ disorders", + "Osteoporosis", + "Gallstones", + "Major depression", + "Osteoarthritis", + "Migraine", + "Anxiety disorders" + ], + "marker": { + "size": 11, + "color": "#d6307a", + "symbol": "circle" + }, + "textfont": { + "color": "#d6307a", + "size": 12 + } + }, + { + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "name": "Both sexes", + "x": [ + 0.00999, 0.0294, 0.0335, 0.037, 0.04432, 0.05773, 0.06068, 0.1946, + 0.27344, 0.29726, 0.43472, 0.45, 0.66307, 0.99967, 1.41777, 1.81145, + 2.19793, 2.27642, 2.27919, 4.17511, 6.46848, 8.17586, 8.20703, 10.8788, + 11.79027, 15.17152, 30.55351, 37.39665 + ], + "y": [ + 86, 155, 288, 7, 56, 434, 124, 439, 255, 50, 361, 262, 12, 216, 662, 22, + 72, 422, 21, 158, 73, 242, 613, 745, 1102, 810, 1172, 377 + ], + "text": [ + "Cystic fibrosis", + "Sickle cell disease", + "Pancreatic cancer", + "Myasthenia gravis", + "Stomach cancer", + "Brain cancer", + "Down syndrome", + "Lung cancer", + "Parkinson's", + "Crohn's disease", + "Colorectal cancer", + "Schizophrenia", + "Celiac disease", + "Epilepsy", + "Opioid use disorder", + "Interstitial cystitis", + "Bipolar disorder", + "Stroke", + "Psoriasis", + "COPD", + "ADHD", + "Asthma", + "Alcohol use disorder", + "Chronic kidney disease", + "Diabetes", + "Chronic pain", + "Obesity", + "Hypertension" + ], + "marker": { + "size": 11, + "color": "#8a96ab", + "symbol": "square" + }, + "textfont": { + "color": "#8a96ab", + "size": 12 + } + }, + { + "type": "scatter", + "mode": "markers+text", + "textposition": "auto", + "name": "Mostly men", + "x": [ + 0.00178, 0.00967, 0.01147, 0.01625, 0.03426, 0.05116, 0.09161, 0.09585, + 0.364, 0.70565, 1.08791, 2.42288, 3.90382 + ], + "y": [37, 252, 40, 61, 195, 9, 82, 12, 3294, 86, 314, 339, 404], + "text": [ + "Duchenne/Becker MD", + "ALS", + "Fragile X", + "Esophageal cancer", + "Liver cancer", + "Tourette", + "Spinal cord injury", + "Testicular cancer", + "HIV", + "Hepatitis C", + "Prostate cancer", + "Autism", + "Coronary heart disease" + ], + "marker": { + "size": 11, + "color": "#2f63d1", + "symbol": "diamond" + }, + "textfont": { + "color": "#2f63d1", + "size": 12 + } + } + ], + "layout": { + "width": 1000, + "height": 640, + "margin": { + "l": 70, + "r": 40, + "t": 60, + "b": 70 + }, + "xaxis": { + "type": "log", + "title": { + "text": "Share of US population (%)" + } + }, + "yaxis": { + "type": "log", + "title": { + "text": "NIH FY2025 funding ($M)" + } + }, + "title": { + "text": "NIH funding against prevalence, textposition: auto" + }, + "legend": { + "orientation": "h", + "y": 1.06 + } + } +} diff --git a/test/image/mocks/text_chart_autoposition_timeseries.json b/test/image/mocks/text_chart_autoposition_timeseries.json new file mode 100644 index 00000000000..493526cd21d --- /dev/null +++ b/test/image/mocks/text_chart_autoposition_timeseries.json @@ -0,0 +1 @@ +{"data": [{"type": "scatter", "mode": "lines+markers+text", "textposition": "auto", "textpriority": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "texttemplate": "%{y:.1f}", "textfont": {"size": 9}, "line": {"width": 1}, "marker": {"size": 4}, "x": ["2026-03-01 00:00", "2026-03-01 00:04", "2026-03-01 00:08", "2026-03-01 00:12", "2026-03-01 00:16", "2026-03-01 00:20", "2026-03-01 00:24", "2026-03-01 00:28", "2026-03-01 00:32", "2026-03-01 00:36", "2026-03-01 00:40", "2026-03-01 00:44", "2026-03-01 00:48", "2026-03-01 00:52", "2026-03-01 00:56", "2026-03-01 01:00", "2026-03-01 01:04", "2026-03-01 01:08", "2026-03-01 01:12", "2026-03-01 01:16", "2026-03-01 01:20", "2026-03-01 01:24", "2026-03-01 01:28", "2026-03-01 01:32", "2026-03-01 01:36", "2026-03-01 01:40", "2026-03-01 01:44", "2026-03-01 01:48", "2026-03-01 01:52", "2026-03-01 01:56", "2026-03-01 02:00", "2026-03-01 02:04", "2026-03-01 02:08", "2026-03-01 02:12", "2026-03-01 02:16", "2026-03-01 02:20", "2026-03-01 02:24", "2026-03-01 02:28", "2026-03-01 02:32", "2026-03-01 02:36", "2026-03-01 02:40", "2026-03-01 02:44", "2026-03-01 02:48", "2026-03-01 02:52", "2026-03-01 02:56", "2026-03-01 03:00", "2026-03-01 03:04", "2026-03-01 03:08", "2026-03-01 03:12", "2026-03-01 03:16", "2026-03-01 03:20", "2026-03-01 03:24", "2026-03-01 03:28", "2026-03-01 03:32", "2026-03-01 03:36", "2026-03-01 03:40", "2026-03-01 03:44", "2026-03-01 03:48", "2026-03-01 03:52", "2026-03-01 03:56", "2026-03-01 04:00", "2026-03-01 04:04", "2026-03-01 04:08", "2026-03-01 04:12", "2026-03-01 04:16", "2026-03-01 04:20", "2026-03-01 04:24", "2026-03-01 04:28", "2026-03-01 04:32", "2026-03-01 04:36", "2026-03-01 04:40", "2026-03-01 04:44", "2026-03-01 04:48", "2026-03-01 04:52", "2026-03-01 04:56", "2026-03-01 05:00", "2026-03-01 05:04", "2026-03-01 05:08", "2026-03-01 05:12", "2026-03-01 05:16", "2026-03-01 05:20", "2026-03-01 05:24", "2026-03-01 05:28", "2026-03-01 05:32", "2026-03-01 05:36", "2026-03-01 05:40", "2026-03-01 05:44", "2026-03-01 05:48", "2026-03-01 05:52", "2026-03-01 05:56", "2026-03-01 06:00", "2026-03-01 06:04", "2026-03-01 06:08", "2026-03-01 06:12", "2026-03-01 06:16", "2026-03-01 06:20", "2026-03-01 06:24", "2026-03-01 06:28", "2026-03-01 06:32", "2026-03-01 06:36", "2026-03-01 06:40", "2026-03-01 06:44", "2026-03-01 06:48", "2026-03-01 06:52", "2026-03-01 06:56", "2026-03-01 07:00", "2026-03-01 07:04", "2026-03-01 07:08", "2026-03-01 07:12", "2026-03-01 07:16", "2026-03-01 07:20", "2026-03-01 07:24", "2026-03-01 07:28", "2026-03-01 07:32", "2026-03-01 07:36", "2026-03-01 07:40", "2026-03-01 07:44", "2026-03-01 07:48", "2026-03-01 07:52", "2026-03-01 07:56", "2026-03-01 08:00", "2026-03-01 08:04", "2026-03-01 08:08", "2026-03-01 08:12", "2026-03-01 08:16", "2026-03-01 08:20", "2026-03-01 08:24", "2026-03-01 08:28", "2026-03-01 08:32", "2026-03-01 08:36", "2026-03-01 08:40", "2026-03-01 08:44", "2026-03-01 08:48", "2026-03-01 08:52", "2026-03-01 08:56", "2026-03-01 09:00", "2026-03-01 09:04", "2026-03-01 09:08", "2026-03-01 09:12", "2026-03-01 09:16", "2026-03-01 09:20", "2026-03-01 09:24", "2026-03-01 09:28", "2026-03-01 09:32", "2026-03-01 09:36", "2026-03-01 09:40", "2026-03-01 09:44", "2026-03-01 09:48", "2026-03-01 09:52", "2026-03-01 09:56", "2026-03-01 10:00", "2026-03-01 10:04", "2026-03-01 10:08", "2026-03-01 10:12", "2026-03-01 10:16", "2026-03-01 10:20", "2026-03-01 10:24", "2026-03-01 10:28", "2026-03-01 10:32", "2026-03-01 10:36", "2026-03-01 10:40", "2026-03-01 10:44", "2026-03-01 10:48", "2026-03-01 10:52", "2026-03-01 10:56", "2026-03-01 11:00", "2026-03-01 11:04", "2026-03-01 11:08", "2026-03-01 11:12", "2026-03-01 11:16", "2026-03-01 11:20", "2026-03-01 11:24", "2026-03-01 11:28", "2026-03-01 11:32", "2026-03-01 11:36", "2026-03-01 11:40", "2026-03-01 11:44", "2026-03-01 11:48", "2026-03-01 11:52", "2026-03-01 11:56", "2026-03-01 12:00", "2026-03-01 12:04", "2026-03-01 12:08", "2026-03-01 12:12", "2026-03-01 12:16", "2026-03-01 12:20", "2026-03-01 12:24", "2026-03-01 12:28", "2026-03-01 12:32", "2026-03-01 12:36", "2026-03-01 12:40", "2026-03-01 12:44", "2026-03-01 12:48", "2026-03-01 12:52", "2026-03-01 12:56", "2026-03-01 13:00", "2026-03-01 13:04", "2026-03-01 13:08", "2026-03-01 13:12", "2026-03-01 13:16", "2026-03-01 13:20", "2026-03-01 13:24", "2026-03-01 13:28", "2026-03-01 13:32", "2026-03-01 13:36", "2026-03-01 13:40", "2026-03-01 13:44", "2026-03-01 13:48", "2026-03-01 13:52", "2026-03-01 13:56", "2026-03-01 14:00", "2026-03-01 14:04", "2026-03-01 14:08", "2026-03-01 14:12", "2026-03-01 14:16", "2026-03-01 14:20", "2026-03-01 14:24", "2026-03-01 14:28", "2026-03-01 14:32", "2026-03-01 14:36", "2026-03-01 14:40", "2026-03-01 14:44", "2026-03-01 14:48", "2026-03-01 14:52", "2026-03-01 14:56", "2026-03-01 15:00", "2026-03-01 15:04", "2026-03-01 15:08", "2026-03-01 15:12", "2026-03-01 15:16", "2026-03-01 15:20", "2026-03-01 15:24", "2026-03-01 15:28", "2026-03-01 15:32", "2026-03-01 15:36", "2026-03-01 15:40", "2026-03-01 15:44", "2026-03-01 15:48", "2026-03-01 15:52", "2026-03-01 15:56", "2026-03-01 16:00", "2026-03-01 16:04", "2026-03-01 16:08", "2026-03-01 16:12", "2026-03-01 16:16", "2026-03-01 16:20", "2026-03-01 16:24", "2026-03-01 16:28", "2026-03-01 16:32", "2026-03-01 16:36", "2026-03-01 16:40", "2026-03-01 16:44", "2026-03-01 16:48", "2026-03-01 16:52", "2026-03-01 16:56", "2026-03-01 17:00", "2026-03-01 17:04", "2026-03-01 17:08", "2026-03-01 17:12", "2026-03-01 17:16", "2026-03-01 17:20", "2026-03-01 17:24", "2026-03-01 17:28", "2026-03-01 17:32", "2026-03-01 17:36", "2026-03-01 17:40", "2026-03-01 17:44", "2026-03-01 17:48", "2026-03-01 17:52", "2026-03-01 17:56", "2026-03-01 18:00", "2026-03-01 18:04", "2026-03-01 18:08", "2026-03-01 18:12", "2026-03-01 18:16", "2026-03-01 18:20", "2026-03-01 18:24", "2026-03-01 18:28", "2026-03-01 18:32", "2026-03-01 18:36", "2026-03-01 18:40", "2026-03-01 18:44", "2026-03-01 18:48", "2026-03-01 18:52", "2026-03-01 18:56", "2026-03-01 19:00", "2026-03-01 19:04", "2026-03-01 19:08", "2026-03-01 19:12", "2026-03-01 19:16", "2026-03-01 19:20", "2026-03-01 19:24", "2026-03-01 19:28", "2026-03-01 19:32", "2026-03-01 19:36", "2026-03-01 19:40", "2026-03-01 19:44", "2026-03-01 19:48", "2026-03-01 19:52", "2026-03-01 19:56", "2026-03-01 20:00", "2026-03-01 20:04", "2026-03-01 20:08", "2026-03-01 20:12", "2026-03-01 20:16", "2026-03-01 20:20", "2026-03-01 20:24", "2026-03-01 20:28", "2026-03-01 20:32", "2026-03-01 20:36", "2026-03-01 20:40", "2026-03-01 20:44", "2026-03-01 20:48", "2026-03-01 20:52", "2026-03-01 20:56", "2026-03-01 21:00", "2026-03-01 21:04", "2026-03-01 21:08", "2026-03-01 21:12", "2026-03-01 21:16", "2026-03-01 21:20", "2026-03-01 21:24", "2026-03-01 21:28", "2026-03-01 21:32", "2026-03-01 21:36", "2026-03-01 21:40", "2026-03-01 21:44", "2026-03-01 21:48", "2026-03-01 21:52", "2026-03-01 21:56", "2026-03-01 22:00", "2026-03-01 22:04", "2026-03-01 22:08", "2026-03-01 22:12", "2026-03-01 22:16", "2026-03-01 22:20", "2026-03-01 22:24", "2026-03-01 22:28", "2026-03-01 22:32", "2026-03-01 22:36", "2026-03-01 22:40", "2026-03-01 22:44", "2026-03-01 22:48", "2026-03-01 22:52", "2026-03-01 22:56", "2026-03-01 23:00", "2026-03-01 23:04", "2026-03-01 23:08", "2026-03-01 23:12", "2026-03-01 23:16", "2026-03-01 23:20", "2026-03-01 23:24", "2026-03-01 23:28", "2026-03-01 23:32", "2026-03-01 23:36", "2026-03-01 23:40", "2026-03-01 23:44", "2026-03-01 23:48", "2026-03-01 23:52", "2026-03-01 23:56", "2026-03-02 00:00", "2026-03-02 00:04", "2026-03-02 00:08", "2026-03-02 00:12", "2026-03-02 00:16", "2026-03-02 00:20", "2026-03-02 00:24", "2026-03-02 00:28", "2026-03-02 00:32", "2026-03-02 00:36", "2026-03-02 00:40", "2026-03-02 00:44", "2026-03-02 00:48", "2026-03-02 00:52", "2026-03-02 00:56", "2026-03-02 01:00", "2026-03-02 01:04", "2026-03-02 01:08", "2026-03-02 01:12", "2026-03-02 01:16", "2026-03-02 01:20", "2026-03-02 01:24", "2026-03-02 01:28", "2026-03-02 01:32", "2026-03-02 01:36", "2026-03-02 01:40", "2026-03-02 01:44", "2026-03-02 01:48", "2026-03-02 01:52", "2026-03-02 01:56", "2026-03-02 02:00", "2026-03-02 02:04", "2026-03-02 02:08", "2026-03-02 02:12", "2026-03-02 02:16", "2026-03-02 02:20", "2026-03-02 02:24", "2026-03-02 02:28", "2026-03-02 02:32", "2026-03-02 02:36", "2026-03-02 02:40", "2026-03-02 02:44", "2026-03-02 02:48", "2026-03-02 02:52", "2026-03-02 02:56", "2026-03-02 03:00", "2026-03-02 03:04", "2026-03-02 03:08", "2026-03-02 03:12", "2026-03-02 03:16", "2026-03-02 03:20", "2026-03-02 03:24", "2026-03-02 03:28", "2026-03-02 03:32", "2026-03-02 03:36", "2026-03-02 03:40", "2026-03-02 03:44", "2026-03-02 03:48", "2026-03-02 03:52", "2026-03-02 03:56", "2026-03-02 04:00", "2026-03-02 04:04", "2026-03-02 04:08", "2026-03-02 04:12", "2026-03-02 04:16", "2026-03-02 04:20", "2026-03-02 04:24", "2026-03-02 04:28", "2026-03-02 04:32", "2026-03-02 04:36", "2026-03-02 04:40", "2026-03-02 04:44", "2026-03-02 04:48", "2026-03-02 04:52", "2026-03-02 04:56", "2026-03-02 05:00", "2026-03-02 05:04", "2026-03-02 05:08", "2026-03-02 05:12", "2026-03-02 05:16", "2026-03-02 05:20", "2026-03-02 05:24", "2026-03-02 05:28", "2026-03-02 05:32", "2026-03-02 05:36", "2026-03-02 05:40", "2026-03-02 05:44", "2026-03-02 05:48", "2026-03-02 05:52", "2026-03-02 05:56", "2026-03-02 06:00", "2026-03-02 06:04", "2026-03-02 06:08", "2026-03-02 06:12", "2026-03-02 06:16", "2026-03-02 06:20", "2026-03-02 06:24", "2026-03-02 06:28", "2026-03-02 06:32", "2026-03-02 06:36", "2026-03-02 06:40", "2026-03-02 06:44", "2026-03-02 06:48", "2026-03-02 06:52", "2026-03-02 06:56", "2026-03-02 07:00", "2026-03-02 07:04", "2026-03-02 07:08", "2026-03-02 07:12", "2026-03-02 07:16", "2026-03-02 07:20", "2026-03-02 07:24", "2026-03-02 07:28", "2026-03-02 07:32", "2026-03-02 07:36", "2026-03-02 07:40", "2026-03-02 07:44", "2026-03-02 07:48", "2026-03-02 07:52", "2026-03-02 07:56", "2026-03-02 08:00", "2026-03-02 08:04", "2026-03-02 08:08", "2026-03-02 08:12", "2026-03-02 08:16", "2026-03-02 08:20", "2026-03-02 08:24", "2026-03-02 08:28", "2026-03-02 08:32", "2026-03-02 08:36", "2026-03-02 08:40", "2026-03-02 08:44", "2026-03-02 08:48", "2026-03-02 08:52", "2026-03-02 08:56", "2026-03-02 09:00", "2026-03-02 09:04", "2026-03-02 09:08", "2026-03-02 09:12", "2026-03-02 09:16", "2026-03-02 09:20", "2026-03-02 09:24", "2026-03-02 09:28", "2026-03-02 09:32", "2026-03-02 09:36", "2026-03-02 09:40", "2026-03-02 09:44", "2026-03-02 09:48", "2026-03-02 09:52", "2026-03-02 09:56", "2026-03-02 10:00", "2026-03-02 10:04", "2026-03-02 10:08", "2026-03-02 10:12", "2026-03-02 10:16", "2026-03-02 10:20", "2026-03-02 10:24", "2026-03-02 10:28", "2026-03-02 10:32", "2026-03-02 10:36", "2026-03-02 10:40", "2026-03-02 10:44", "2026-03-02 10:48", "2026-03-02 10:52", "2026-03-02 10:56", "2026-03-02 11:00", "2026-03-02 11:04", "2026-03-02 11:08", "2026-03-02 11:12", "2026-03-02 11:16", "2026-03-02 11:20", "2026-03-02 11:24", "2026-03-02 11:28", "2026-03-02 11:32", "2026-03-02 11:36", "2026-03-02 11:40", "2026-03-02 11:44", "2026-03-02 11:48", "2026-03-02 11:52", "2026-03-02 11:56", "2026-03-02 12:00", "2026-03-02 12:04", "2026-03-02 12:08", "2026-03-02 12:12", "2026-03-02 12:16", "2026-03-02 12:20", "2026-03-02 12:24", "2026-03-02 12:28", "2026-03-02 12:32", "2026-03-02 12:36", "2026-03-02 12:40", "2026-03-02 12:44", "2026-03-02 12:48", "2026-03-02 12:52", "2026-03-02 12:56", "2026-03-02 13:00", "2026-03-02 13:04", "2026-03-02 13:08", "2026-03-02 13:12", "2026-03-02 13:16", "2026-03-02 13:20", "2026-03-02 13:24", "2026-03-02 13:28", "2026-03-02 13:32", "2026-03-02 13:36", "2026-03-02 13:40", "2026-03-02 13:44", "2026-03-02 13:48", "2026-03-02 13:52", "2026-03-02 13:56", "2026-03-02 14:00", "2026-03-02 14:04", "2026-03-02 14:08", "2026-03-02 14:12", "2026-03-02 14:16", "2026-03-02 14:20", "2026-03-02 14:24", "2026-03-02 14:28", "2026-03-02 14:32", "2026-03-02 14:36", "2026-03-02 14:40", "2026-03-02 14:44", "2026-03-02 14:48", "2026-03-02 14:52", "2026-03-02 14:56", "2026-03-02 15:00", "2026-03-02 15:04", "2026-03-02 15:08", "2026-03-02 15:12", "2026-03-02 15:16", "2026-03-02 15:20", "2026-03-02 15:24", "2026-03-02 15:28", "2026-03-02 15:32", "2026-03-02 15:36", "2026-03-02 15:40", "2026-03-02 15:44", "2026-03-02 15:48", "2026-03-02 15:52", "2026-03-02 15:56", "2026-03-02 16:00", "2026-03-02 16:04", "2026-03-02 16:08", "2026-03-02 16:12", "2026-03-02 16:16", "2026-03-02 16:20", "2026-03-02 16:24", "2026-03-02 16:28", "2026-03-02 16:32", "2026-03-02 16:36", "2026-03-02 16:40", "2026-03-02 16:44", "2026-03-02 16:48", "2026-03-02 16:52", "2026-03-02 16:56", "2026-03-02 17:00", "2026-03-02 17:04", "2026-03-02 17:08", "2026-03-02 17:12", "2026-03-02 17:16", "2026-03-02 17:20", "2026-03-02 17:24", "2026-03-02 17:28", "2026-03-02 17:32", "2026-03-02 17:36", "2026-03-02 17:40", "2026-03-02 17:44", "2026-03-02 17:48", "2026-03-02 17:52", "2026-03-02 17:56", "2026-03-02 18:00", "2026-03-02 18:04", "2026-03-02 18:08", "2026-03-02 18:12", "2026-03-02 18:16", "2026-03-02 18:20", "2026-03-02 18:24", "2026-03-02 18:28", "2026-03-02 18:32", "2026-03-02 18:36", "2026-03-02 18:40", "2026-03-02 18:44", "2026-03-02 18:48", "2026-03-02 18:52", "2026-03-02 18:56", "2026-03-02 19:00", "2026-03-02 19:04", "2026-03-02 19:08", "2026-03-02 19:12", "2026-03-02 19:16", "2026-03-02 19:20", "2026-03-02 19:24", "2026-03-02 19:28", "2026-03-02 19:32", "2026-03-02 19:36", "2026-03-02 19:40", "2026-03-02 19:44", "2026-03-02 19:48", "2026-03-02 19:52", "2026-03-02 19:56", "2026-03-02 20:00", "2026-03-02 20:04", "2026-03-02 20:08", "2026-03-02 20:12", "2026-03-02 20:16", "2026-03-02 20:20", "2026-03-02 20:24", "2026-03-02 20:28", "2026-03-02 20:32", "2026-03-02 20:36", "2026-03-02 20:40", "2026-03-02 20:44", "2026-03-02 20:48", "2026-03-02 20:52", "2026-03-02 20:56", "2026-03-02 21:00", "2026-03-02 21:04", "2026-03-02 21:08", "2026-03-02 21:12", "2026-03-02 21:16", "2026-03-02 21:20", "2026-03-02 21:24", "2026-03-02 21:28", "2026-03-02 21:32", "2026-03-02 21:36", "2026-03-02 21:40", "2026-03-02 21:44", "2026-03-02 21:48", "2026-03-02 21:52", "2026-03-02 21:56", "2026-03-02 22:00", "2026-03-02 22:04", "2026-03-02 22:08", "2026-03-02 22:12", "2026-03-02 22:16", "2026-03-02 22:20", "2026-03-02 22:24", "2026-03-02 22:28", "2026-03-02 22:32", "2026-03-02 22:36", "2026-03-02 22:40", "2026-03-02 22:44", "2026-03-02 22:48", "2026-03-02 22:52", "2026-03-02 22:56", "2026-03-02 23:00", "2026-03-02 23:04", "2026-03-02 23:08", "2026-03-02 23:12", "2026-03-02 23:16", "2026-03-02 23:20", "2026-03-02 23:24", "2026-03-02 23:28", "2026-03-02 23:32", "2026-03-02 23:36", "2026-03-02 23:40", "2026-03-02 23:44", "2026-03-02 23:48", "2026-03-02 23:52", "2026-03-02 23:56", "2026-03-03 00:00", "2026-03-03 00:04", "2026-03-03 00:08", "2026-03-03 00:12", "2026-03-03 00:16", "2026-03-03 00:20", "2026-03-03 00:24", "2026-03-03 00:28", "2026-03-03 00:32", "2026-03-03 00:36", "2026-03-03 00:40", "2026-03-03 00:44", "2026-03-03 00:48", "2026-03-03 00:52", "2026-03-03 00:56", "2026-03-03 01:00", "2026-03-03 01:04", "2026-03-03 01:08", "2026-03-03 01:12", "2026-03-03 01:16", "2026-03-03 01:20", "2026-03-03 01:24", "2026-03-03 01:28", "2026-03-03 01:32", "2026-03-03 01:36", "2026-03-03 01:40", "2026-03-03 01:44", "2026-03-03 01:48", "2026-03-03 01:52", "2026-03-03 01:56", "2026-03-03 02:00", "2026-03-03 02:04", "2026-03-03 02:08", "2026-03-03 02:12", "2026-03-03 02:16", "2026-03-03 02:20", "2026-03-03 02:24", "2026-03-03 02:28", "2026-03-03 02:32", "2026-03-03 02:36", "2026-03-03 02:40", "2026-03-03 02:44", "2026-03-03 02:48", "2026-03-03 02:52", "2026-03-03 02:56", "2026-03-03 03:00", "2026-03-03 03:04", "2026-03-03 03:08", "2026-03-03 03:12", "2026-03-03 03:16", "2026-03-03 03:20", "2026-03-03 03:24", "2026-03-03 03:28", "2026-03-03 03:32", "2026-03-03 03:36", "2026-03-03 03:40", "2026-03-03 03:44", "2026-03-03 03:48", "2026-03-03 03:52", "2026-03-03 03:56", "2026-03-03 04:00", "2026-03-03 04:04", "2026-03-03 04:08", "2026-03-03 04:12", "2026-03-03 04:16", "2026-03-03 04:20", "2026-03-03 04:24", "2026-03-03 04:28", "2026-03-03 04:32", "2026-03-03 04:36", "2026-03-03 04:40", "2026-03-03 04:44", "2026-03-03 04:48", "2026-03-03 04:52", "2026-03-03 04:56", "2026-03-03 05:00", "2026-03-03 05:04", "2026-03-03 05:08", "2026-03-03 05:12", "2026-03-03 05:16", "2026-03-03 05:20", "2026-03-03 05:24", "2026-03-03 05:28", "2026-03-03 05:32", "2026-03-03 05:36", "2026-03-03 05:40", "2026-03-03 05:44", "2026-03-03 05:48", "2026-03-03 05:52", "2026-03-03 05:56", "2026-03-03 06:00", "2026-03-03 06:04", "2026-03-03 06:08", "2026-03-03 06:12", "2026-03-03 06:16", "2026-03-03 06:20", "2026-03-03 06:24", "2026-03-03 06:28", "2026-03-03 06:32", "2026-03-03 06:36", "2026-03-03 06:40", "2026-03-03 06:44", "2026-03-03 06:48", "2026-03-03 06:52", "2026-03-03 06:56", "2026-03-03 07:00", "2026-03-03 07:04", "2026-03-03 07:08", "2026-03-03 07:12", "2026-03-03 07:16", "2026-03-03 07:20", "2026-03-03 07:24", "2026-03-03 07:28", "2026-03-03 07:32", "2026-03-03 07:36", "2026-03-03 07:40", "2026-03-03 07:44", "2026-03-03 07:48", "2026-03-03 07:52", "2026-03-03 07:56", "2026-03-03 08:00", "2026-03-03 08:04", "2026-03-03 08:08", "2026-03-03 08:12", "2026-03-03 08:16", "2026-03-03 08:20", "2026-03-03 08:24", "2026-03-03 08:28", "2026-03-03 08:32", "2026-03-03 08:36", "2026-03-03 08:40", "2026-03-03 08:44", "2026-03-03 08:48", "2026-03-03 08:52", "2026-03-03 08:56", "2026-03-03 09:00", "2026-03-03 09:04", "2026-03-03 09:08", "2026-03-03 09:12", "2026-03-03 09:16", "2026-03-03 09:20", "2026-03-03 09:24", "2026-03-03 09:28", "2026-03-03 09:32", "2026-03-03 09:36", "2026-03-03 09:40", "2026-03-03 09:44", "2026-03-03 09:48", "2026-03-03 09:52", "2026-03-03 09:56", "2026-03-03 10:00", "2026-03-03 10:04", "2026-03-03 10:08", "2026-03-03 10:12", "2026-03-03 10:16", "2026-03-03 10:20", "2026-03-03 10:24", "2026-03-03 10:28", "2026-03-03 10:32", "2026-03-03 10:36", "2026-03-03 10:40", "2026-03-03 10:44", "2026-03-03 10:48", "2026-03-03 10:52", "2026-03-03 10:56", "2026-03-03 11:00", "2026-03-03 11:04", "2026-03-03 11:08", "2026-03-03 11:12", "2026-03-03 11:16", "2026-03-03 11:20", "2026-03-03 11:24", "2026-03-03 11:28", "2026-03-03 11:32", "2026-03-03 11:36", "2026-03-03 11:40", "2026-03-03 11:44", "2026-03-03 11:48", "2026-03-03 11:52", "2026-03-03 11:56", "2026-03-03 12:00", "2026-03-03 12:04", "2026-03-03 12:08", "2026-03-03 12:12", "2026-03-03 12:16", "2026-03-03 12:20", "2026-03-03 12:24", "2026-03-03 12:28", "2026-03-03 12:32", "2026-03-03 12:36", "2026-03-03 12:40", "2026-03-03 12:44", "2026-03-03 12:48", "2026-03-03 12:52", "2026-03-03 12:56", "2026-03-03 13:00", "2026-03-03 13:04", "2026-03-03 13:08", "2026-03-03 13:12", "2026-03-03 13:16", "2026-03-03 13:20", "2026-03-03 13:24", "2026-03-03 13:28", "2026-03-03 13:32", "2026-03-03 13:36", "2026-03-03 13:40", "2026-03-03 13:44", "2026-03-03 13:48", "2026-03-03 13:52", "2026-03-03 13:56", "2026-03-03 14:00", "2026-03-03 14:04", "2026-03-03 14:08", "2026-03-03 14:12", "2026-03-03 14:16", "2026-03-03 14:20", "2026-03-03 14:24", "2026-03-03 14:28", "2026-03-03 14:32", "2026-03-03 14:36", "2026-03-03 14:40", "2026-03-03 14:44", "2026-03-03 14:48", "2026-03-03 14:52", "2026-03-03 14:56", "2026-03-03 15:00", "2026-03-03 15:04", "2026-03-03 15:08", "2026-03-03 15:12", "2026-03-03 15:16", "2026-03-03 15:20", "2026-03-03 15:24", "2026-03-03 15:28", "2026-03-03 15:32", "2026-03-03 15:36", "2026-03-03 15:40", "2026-03-03 15:44", "2026-03-03 15:48", "2026-03-03 15:52", "2026-03-03 15:56", "2026-03-03 16:00", "2026-03-03 16:04", "2026-03-03 16:08", "2026-03-03 16:12", "2026-03-03 16:16", "2026-03-03 16:20", "2026-03-03 16:24", "2026-03-03 16:28", "2026-03-03 16:32", "2026-03-03 16:36", "2026-03-03 16:40", "2026-03-03 16:44", "2026-03-03 16:48", "2026-03-03 16:52", "2026-03-03 16:56", "2026-03-03 17:00", "2026-03-03 17:04", "2026-03-03 17:08", "2026-03-03 17:12", "2026-03-03 17:16", "2026-03-03 17:20", "2026-03-03 17:24", "2026-03-03 17:28", "2026-03-03 17:32", "2026-03-03 17:36", "2026-03-03 17:40", "2026-03-03 17:44", "2026-03-03 17:48", "2026-03-03 17:52", "2026-03-03 17:56", "2026-03-03 18:00", "2026-03-03 18:04", "2026-03-03 18:08", "2026-03-03 18:12", "2026-03-03 18:16", "2026-03-03 18:20", "2026-03-03 18:24", "2026-03-03 18:28", "2026-03-03 18:32", "2026-03-03 18:36", "2026-03-03 18:40", "2026-03-03 18:44", "2026-03-03 18:48", "2026-03-03 18:52", "2026-03-03 18:56", "2026-03-03 19:00", "2026-03-03 19:04", "2026-03-03 19:08", "2026-03-03 19:12", "2026-03-03 19:16", "2026-03-03 19:20", "2026-03-03 19:24", "2026-03-03 19:28", "2026-03-03 19:32", "2026-03-03 19:36", "2026-03-03 19:40", "2026-03-03 19:44", "2026-03-03 19:48", "2026-03-03 19:52", "2026-03-03 19:56", "2026-03-03 20:00", "2026-03-03 20:04", "2026-03-03 20:08", "2026-03-03 20:12", "2026-03-03 20:16", "2026-03-03 20:20", "2026-03-03 20:24", "2026-03-03 20:28", "2026-03-03 20:32", "2026-03-03 20:36", "2026-03-03 20:40", "2026-03-03 20:44", "2026-03-03 20:48", "2026-03-03 20:52", "2026-03-03 20:56", "2026-03-03 21:00", "2026-03-03 21:04", "2026-03-03 21:08", "2026-03-03 21:12", "2026-03-03 21:16", "2026-03-03 21:20", "2026-03-03 21:24", "2026-03-03 21:28", "2026-03-03 21:32", "2026-03-03 21:36", "2026-03-03 21:40", "2026-03-03 21:44", "2026-03-03 21:48", "2026-03-03 21:52", "2026-03-03 21:56", "2026-03-03 22:00", "2026-03-03 22:04", "2026-03-03 22:08", "2026-03-03 22:12", "2026-03-03 22:16", "2026-03-03 22:20", "2026-03-03 22:24", "2026-03-03 22:28", "2026-03-03 22:32", "2026-03-03 22:36", "2026-03-03 22:40", "2026-03-03 22:44", "2026-03-03 22:48", "2026-03-03 22:52", "2026-03-03 22:56", "2026-03-03 23:00", "2026-03-03 23:04", "2026-03-03 23:08", "2026-03-03 23:12", "2026-03-03 23:16", "2026-03-03 23:20", "2026-03-03 23:24", "2026-03-03 23:28", "2026-03-03 23:32", "2026-03-03 23:36", "2026-03-03 23:40", "2026-03-03 23:44", "2026-03-03 23:48", "2026-03-03 23:52", "2026-03-03 23:56", "2026-03-04 00:00", "2026-03-04 00:04", "2026-03-04 00:08", "2026-03-04 00:12", "2026-03-04 00:16", "2026-03-04 00:20", "2026-03-04 00:24", "2026-03-04 00:28", "2026-03-04 00:32", "2026-03-04 00:36", "2026-03-04 00:40", "2026-03-04 00:44", "2026-03-04 00:48", "2026-03-04 00:52", "2026-03-04 00:56", "2026-03-04 01:00", "2026-03-04 01:04", "2026-03-04 01:08", "2026-03-04 01:12", "2026-03-04 01:16", "2026-03-04 01:20", "2026-03-04 01:24", "2026-03-04 01:28", "2026-03-04 01:32", "2026-03-04 01:36", "2026-03-04 01:40", "2026-03-04 01:44", "2026-03-04 01:48", "2026-03-04 01:52", "2026-03-04 01:56", "2026-03-04 02:00", "2026-03-04 02:04", "2026-03-04 02:08", "2026-03-04 02:12", "2026-03-04 02:16", "2026-03-04 02:20", "2026-03-04 02:24", "2026-03-04 02:28", "2026-03-04 02:32", "2026-03-04 02:36", "2026-03-04 02:40", "2026-03-04 02:44", "2026-03-04 02:48", "2026-03-04 02:52", "2026-03-04 02:56", "2026-03-04 03:00", "2026-03-04 03:04", "2026-03-04 03:08", "2026-03-04 03:12", "2026-03-04 03:16", "2026-03-04 03:20", "2026-03-04 03:24", "2026-03-04 03:28", "2026-03-04 03:32", "2026-03-04 03:36", "2026-03-04 03:40", "2026-03-04 03:44", "2026-03-04 03:48", "2026-03-04 03:52", "2026-03-04 03:56", "2026-03-04 04:00", "2026-03-04 04:04", "2026-03-04 04:08", "2026-03-04 04:12", "2026-03-04 04:16", "2026-03-04 04:20", "2026-03-04 04:24", "2026-03-04 04:28", "2026-03-04 04:32", "2026-03-04 04:36", "2026-03-04 04:40", "2026-03-04 04:44", "2026-03-04 04:48", "2026-03-04 04:52", "2026-03-04 04:56", "2026-03-04 05:00", "2026-03-04 05:04", "2026-03-04 05:08", "2026-03-04 05:12", "2026-03-04 05:16", "2026-03-04 05:20", "2026-03-04 05:24", "2026-03-04 05:28", "2026-03-04 05:32", "2026-03-04 05:36", "2026-03-04 05:40", "2026-03-04 05:44", "2026-03-04 05:48", "2026-03-04 05:52", "2026-03-04 05:56", "2026-03-04 06:00", "2026-03-04 06:04", "2026-03-04 06:08", "2026-03-04 06:12", "2026-03-04 06:16", "2026-03-04 06:20", "2026-03-04 06:24", "2026-03-04 06:28", "2026-03-04 06:32", "2026-03-04 06:36", "2026-03-04 06:40", "2026-03-04 06:44", "2026-03-04 06:48", "2026-03-04 06:52", "2026-03-04 06:56", "2026-03-04 07:00", "2026-03-04 07:04", "2026-03-04 07:08", "2026-03-04 07:12", "2026-03-04 07:16", "2026-03-04 07:20", "2026-03-04 07:24", "2026-03-04 07:28", "2026-03-04 07:32", "2026-03-04 07:36", "2026-03-04 07:40", "2026-03-04 07:44", "2026-03-04 07:48", "2026-03-04 07:52", "2026-03-04 07:56", "2026-03-04 08:00", "2026-03-04 08:04", "2026-03-04 08:08", "2026-03-04 08:12", "2026-03-04 08:16", "2026-03-04 08:20", "2026-03-04 08:24", "2026-03-04 08:28", "2026-03-04 08:32", "2026-03-04 08:36", "2026-03-04 08:40", "2026-03-04 08:44", "2026-03-04 08:48", "2026-03-04 08:52", "2026-03-04 08:56", "2026-03-04 09:00", "2026-03-04 09:04", "2026-03-04 09:08", "2026-03-04 09:12", "2026-03-04 09:16", "2026-03-04 09:20", "2026-03-04 09:24", "2026-03-04 09:28", "2026-03-04 09:32", "2026-03-04 09:36", "2026-03-04 09:40", "2026-03-04 09:44", "2026-03-04 09:48", "2026-03-04 09:52", "2026-03-04 09:56", "2026-03-04 10:00", "2026-03-04 10:04", "2026-03-04 10:08", "2026-03-04 10:12", "2026-03-04 10:16", "2026-03-04 10:20", "2026-03-04 10:24", "2026-03-04 10:28", "2026-03-04 10:32", "2026-03-04 10:36", "2026-03-04 10:40", "2026-03-04 10:44", "2026-03-04 10:48", "2026-03-04 10:52", "2026-03-04 10:56", "2026-03-04 11:00", "2026-03-04 11:04", "2026-03-04 11:08", "2026-03-04 11:12", "2026-03-04 11:16", "2026-03-04 11:20", "2026-03-04 11:24", "2026-03-04 11:28", "2026-03-04 11:32", "2026-03-04 11:36", "2026-03-04 11:40", "2026-03-04 11:44", "2026-03-04 11:48", "2026-03-04 11:52", "2026-03-04 11:56", "2026-03-04 12:00", "2026-03-04 12:04", "2026-03-04 12:08", "2026-03-04 12:12", "2026-03-04 12:16", "2026-03-04 12:20", "2026-03-04 12:24", "2026-03-04 12:28", "2026-03-04 12:32", "2026-03-04 12:36", "2026-03-04 12:40", "2026-03-04 12:44", "2026-03-04 12:48", "2026-03-04 12:52", "2026-03-04 12:56", "2026-03-04 13:00", "2026-03-04 13:04", "2026-03-04 13:08", "2026-03-04 13:12", "2026-03-04 13:16", "2026-03-04 13:20", "2026-03-04 13:24", "2026-03-04 13:28", "2026-03-04 13:32", "2026-03-04 13:36", "2026-03-04 13:40", "2026-03-04 13:44", "2026-03-04 13:48", "2026-03-04 13:52", "2026-03-04 13:56", "2026-03-04 14:00", "2026-03-04 14:04", "2026-03-04 14:08", "2026-03-04 14:12", "2026-03-04 14:16", "2026-03-04 14:20", "2026-03-04 14:24", "2026-03-04 14:28", "2026-03-04 14:32", "2026-03-04 14:36", "2026-03-04 14:40", "2026-03-04 14:44", "2026-03-04 14:48", "2026-03-04 14:52", "2026-03-04 14:56", "2026-03-04 15:00", "2026-03-04 15:04", "2026-03-04 15:08", "2026-03-04 15:12", "2026-03-04 15:16", "2026-03-04 15:20", "2026-03-04 15:24", "2026-03-04 15:28", "2026-03-04 15:32", "2026-03-04 15:36", "2026-03-04 15:40", "2026-03-04 15:44", "2026-03-04 15:48", "2026-03-04 15:52", "2026-03-04 15:56", "2026-03-04 16:00", "2026-03-04 16:04", "2026-03-04 16:08", "2026-03-04 16:12", "2026-03-04 16:16", "2026-03-04 16:20", "2026-03-04 16:24", "2026-03-04 16:28", "2026-03-04 16:32", "2026-03-04 16:36", "2026-03-04 16:40", "2026-03-04 16:44", "2026-03-04 16:48", "2026-03-04 16:52", "2026-03-04 16:56", "2026-03-04 17:00", "2026-03-04 17:04", "2026-03-04 17:08", "2026-03-04 17:12", "2026-03-04 17:16", "2026-03-04 17:20", "2026-03-04 17:24", "2026-03-04 17:28", "2026-03-04 17:32", "2026-03-04 17:36", "2026-03-04 17:40", "2026-03-04 17:44", "2026-03-04 17:48", "2026-03-04 17:52", "2026-03-04 17:56", "2026-03-04 18:00", "2026-03-04 18:04", "2026-03-04 18:08", "2026-03-04 18:12", "2026-03-04 18:16", "2026-03-04 18:20", "2026-03-04 18:24", "2026-03-04 18:28", "2026-03-04 18:32", "2026-03-04 18:36", "2026-03-04 18:40", "2026-03-04 18:44", "2026-03-04 18:48", "2026-03-04 18:52", "2026-03-04 18:56", "2026-03-04 19:00", "2026-03-04 19:04", "2026-03-04 19:08", "2026-03-04 19:12", "2026-03-04 19:16", "2026-03-04 19:20", "2026-03-04 19:24", "2026-03-04 19:28", "2026-03-04 19:32", "2026-03-04 19:36", "2026-03-04 19:40", "2026-03-04 19:44", "2026-03-04 19:48", "2026-03-04 19:52", "2026-03-04 19:56", "2026-03-04 20:00", "2026-03-04 20:04", "2026-03-04 20:08", "2026-03-04 20:12", "2026-03-04 20:16", "2026-03-04 20:20", "2026-03-04 20:24", "2026-03-04 20:28", "2026-03-04 20:32", "2026-03-04 20:36", "2026-03-04 20:40", "2026-03-04 20:44", "2026-03-04 20:48", "2026-03-04 20:52", "2026-03-04 20:56", "2026-03-04 21:00", "2026-03-04 21:04", "2026-03-04 21:08", "2026-03-04 21:12", "2026-03-04 21:16", "2026-03-04 21:20", "2026-03-04 21:24", "2026-03-04 21:28", "2026-03-04 21:32", "2026-03-04 21:36", "2026-03-04 21:40", "2026-03-04 21:44", "2026-03-04 21:48", "2026-03-04 21:52", "2026-03-04 21:56", "2026-03-04 22:00", "2026-03-04 22:04", "2026-03-04 22:08", "2026-03-04 22:12", "2026-03-04 22:16", "2026-03-04 22:20", "2026-03-04 22:24", "2026-03-04 22:28", "2026-03-04 22:32", "2026-03-04 22:36", "2026-03-04 22:40", "2026-03-04 22:44", "2026-03-04 22:48", "2026-03-04 22:52", "2026-03-04 22:56", "2026-03-04 23:00", "2026-03-04 23:04", "2026-03-04 23:08", "2026-03-04 23:12", "2026-03-04 23:16", "2026-03-04 23:20", "2026-03-04 23:24", "2026-03-04 23:28", "2026-03-04 23:32", "2026-03-04 23:36", "2026-03-04 23:40", "2026-03-04 23:44", "2026-03-04 23:48", "2026-03-04 23:52", "2026-03-04 23:56", "2026-03-05 00:00", "2026-03-05 00:04", "2026-03-05 00:08", "2026-03-05 00:12", "2026-03-05 00:16", "2026-03-05 00:20", "2026-03-05 00:24", "2026-03-05 00:28", "2026-03-05 00:32", "2026-03-05 00:36", "2026-03-05 00:40", "2026-03-05 00:44", "2026-03-05 00:48", "2026-03-05 00:52", "2026-03-05 00:56", "2026-03-05 01:00", "2026-03-05 01:04", "2026-03-05 01:08", "2026-03-05 01:12", "2026-03-05 01:16", "2026-03-05 01:20", "2026-03-05 01:24", "2026-03-05 01:28", "2026-03-05 01:32", "2026-03-05 01:36", "2026-03-05 01:40", "2026-03-05 01:44", "2026-03-05 01:48", "2026-03-05 01:52", "2026-03-05 01:56", "2026-03-05 02:00", "2026-03-05 02:04", "2026-03-05 02:08", "2026-03-05 02:12", "2026-03-05 02:16", "2026-03-05 02:20", "2026-03-05 02:24", "2026-03-05 02:28", "2026-03-05 02:32", "2026-03-05 02:36", "2026-03-05 02:40", "2026-03-05 02:44", "2026-03-05 02:48", "2026-03-05 02:52", "2026-03-05 02:56", "2026-03-05 03:00", "2026-03-05 03:04", "2026-03-05 03:08", "2026-03-05 03:12", "2026-03-05 03:16", "2026-03-05 03:20", "2026-03-05 03:24", "2026-03-05 03:28", "2026-03-05 03:32", "2026-03-05 03:36", "2026-03-05 03:40", "2026-03-05 03:44", "2026-03-05 03:48", "2026-03-05 03:52", "2026-03-05 03:56", "2026-03-05 04:00", "2026-03-05 04:04", "2026-03-05 04:08", "2026-03-05 04:12", "2026-03-05 04:16", "2026-03-05 04:20", "2026-03-05 04:24", "2026-03-05 04:28", "2026-03-05 04:32", "2026-03-05 04:36", "2026-03-05 04:40", "2026-03-05 04:44", "2026-03-05 04:48", "2026-03-05 04:52", "2026-03-05 04:56", "2026-03-05 05:00", "2026-03-05 05:04", "2026-03-05 05:08", "2026-03-05 05:12", "2026-03-05 05:16", "2026-03-05 05:20", "2026-03-05 05:24", "2026-03-05 05:28", "2026-03-05 05:32", "2026-03-05 05:36", "2026-03-05 05:40", "2026-03-05 05:44", "2026-03-05 05:48", "2026-03-05 05:52", "2026-03-05 05:56", "2026-03-05 06:00", "2026-03-05 06:04", "2026-03-05 06:08", "2026-03-05 06:12", "2026-03-05 06:16", "2026-03-05 06:20", "2026-03-05 06:24", "2026-03-05 06:28", "2026-03-05 06:32", "2026-03-05 06:36", "2026-03-05 06:40", "2026-03-05 06:44", "2026-03-05 06:48", "2026-03-05 06:52", "2026-03-05 06:56", "2026-03-05 07:00", "2026-03-05 07:04", "2026-03-05 07:08", "2026-03-05 07:12", "2026-03-05 07:16", "2026-03-05 07:20", "2026-03-05 07:24", "2026-03-05 07:28", "2026-03-05 07:32", "2026-03-05 07:36", "2026-03-05 07:40", "2026-03-05 07:44", "2026-03-05 07:48", "2026-03-05 07:52", "2026-03-05 07:56", "2026-03-05 08:00", "2026-03-05 08:04", "2026-03-05 08:08", "2026-03-05 08:12", "2026-03-05 08:16", "2026-03-05 08:20", "2026-03-05 08:24", "2026-03-05 08:28", "2026-03-05 08:32", "2026-03-05 08:36", "2026-03-05 08:40", "2026-03-05 08:44", "2026-03-05 08:48", "2026-03-05 08:52", "2026-03-05 08:56", "2026-03-05 09:00", "2026-03-05 09:04", "2026-03-05 09:08", "2026-03-05 09:12", "2026-03-05 09:16", "2026-03-05 09:20", "2026-03-05 09:24", "2026-03-05 09:28", "2026-03-05 09:32", "2026-03-05 09:36", "2026-03-05 09:40", "2026-03-05 09:44", "2026-03-05 09:48", "2026-03-05 09:52", "2026-03-05 09:56", "2026-03-05 10:00", "2026-03-05 10:04", "2026-03-05 10:08", "2026-03-05 10:12", "2026-03-05 10:16", "2026-03-05 10:20", "2026-03-05 10:24", "2026-03-05 10:28", "2026-03-05 10:32", "2026-03-05 10:36", "2026-03-05 10:40", "2026-03-05 10:44", "2026-03-05 10:48", "2026-03-05 10:52", "2026-03-05 10:56", "2026-03-05 11:00", "2026-03-05 11:04", "2026-03-05 11:08", "2026-03-05 11:12", "2026-03-05 11:16", "2026-03-05 11:20", "2026-03-05 11:24", "2026-03-05 11:28", "2026-03-05 11:32", "2026-03-05 11:36", "2026-03-05 11:40", "2026-03-05 11:44", "2026-03-05 11:48", "2026-03-05 11:52", "2026-03-05 11:56", "2026-03-05 12:00", "2026-03-05 12:04", "2026-03-05 12:08", "2026-03-05 12:12", "2026-03-05 12:16", "2026-03-05 12:20", "2026-03-05 12:24", "2026-03-05 12:28", "2026-03-05 12:32", "2026-03-05 12:36", "2026-03-05 12:40", "2026-03-05 12:44", "2026-03-05 12:48", "2026-03-05 12:52", "2026-03-05 12:56", "2026-03-05 13:00", "2026-03-05 13:04", "2026-03-05 13:08", "2026-03-05 13:12", "2026-03-05 13:16", "2026-03-05 13:20", "2026-03-05 13:24", "2026-03-05 13:28", "2026-03-05 13:32", "2026-03-05 13:36", "2026-03-05 13:40", "2026-03-05 13:44", "2026-03-05 13:48", "2026-03-05 13:52", "2026-03-05 13:56", "2026-03-05 14:00", "2026-03-05 14:04", "2026-03-05 14:08", "2026-03-05 14:12", "2026-03-05 14:16", "2026-03-05 14:20", "2026-03-05 14:24", "2026-03-05 14:28", "2026-03-05 14:32", "2026-03-05 14:36", "2026-03-05 14:40", "2026-03-05 14:44", "2026-03-05 14:48", "2026-03-05 14:52", "2026-03-05 14:56", "2026-03-05 15:00", "2026-03-05 15:04", "2026-03-05 15:08", "2026-03-05 15:12", "2026-03-05 15:16", "2026-03-05 15:20", "2026-03-05 15:24", "2026-03-05 15:28", "2026-03-05 15:32", "2026-03-05 15:36", "2026-03-05 15:40", "2026-03-05 15:44", "2026-03-05 15:48", "2026-03-05 15:52", "2026-03-05 15:56", "2026-03-05 16:00", "2026-03-05 16:04", "2026-03-05 16:08", "2026-03-05 16:12", "2026-03-05 16:16", "2026-03-05 16:20", "2026-03-05 16:24", "2026-03-05 16:28", "2026-03-05 16:32", "2026-03-05 16:36", "2026-03-05 16:40", "2026-03-05 16:44", "2026-03-05 16:48", "2026-03-05 16:52", "2026-03-05 16:56", "2026-03-05 17:00", "2026-03-05 17:04", "2026-03-05 17:08", "2026-03-05 17:12", "2026-03-05 17:16", "2026-03-05 17:20", "2026-03-05 17:24", "2026-03-05 17:28", "2026-03-05 17:32", "2026-03-05 17:36", "2026-03-05 17:40", "2026-03-05 17:44", "2026-03-05 17:48", "2026-03-05 17:52", "2026-03-05 17:56", "2026-03-05 18:00", "2026-03-05 18:04", "2026-03-05 18:08", "2026-03-05 18:12", "2026-03-05 18:16", "2026-03-05 18:20", "2026-03-05 18:24", "2026-03-05 18:28", "2026-03-05 18:32", "2026-03-05 18:36", "2026-03-05 18:40", "2026-03-05 18:44", "2026-03-05 18:48", "2026-03-05 18:52", "2026-03-05 18:56", "2026-03-05 19:00", "2026-03-05 19:04", "2026-03-05 19:08", "2026-03-05 19:12", "2026-03-05 19:16", "2026-03-05 19:20", "2026-03-05 19:24", "2026-03-05 19:28", "2026-03-05 19:32", "2026-03-05 19:36", "2026-03-05 19:40", "2026-03-05 19:44", "2026-03-05 19:48", "2026-03-05 19:52", "2026-03-05 19:56", "2026-03-05 20:00", "2026-03-05 20:04", "2026-03-05 20:08", "2026-03-05 20:12", "2026-03-05 20:16", "2026-03-05 20:20", "2026-03-05 20:24", "2026-03-05 20:28", "2026-03-05 20:32", "2026-03-05 20:36", "2026-03-05 20:40", "2026-03-05 20:44", "2026-03-05 20:48", "2026-03-05 20:52", "2026-03-05 20:56", "2026-03-05 21:00", "2026-03-05 21:04", "2026-03-05 21:08", "2026-03-05 21:12", "2026-03-05 21:16", "2026-03-05 21:20", "2026-03-05 21:24", "2026-03-05 21:28", "2026-03-05 21:32", "2026-03-05 21:36", "2026-03-05 21:40", "2026-03-05 21:44", "2026-03-05 21:48", "2026-03-05 21:52", "2026-03-05 21:56", "2026-03-05 22:00", "2026-03-05 22:04", "2026-03-05 22:08", "2026-03-05 22:12", "2026-03-05 22:16", "2026-03-05 22:20", "2026-03-05 22:24", "2026-03-05 22:28", "2026-03-05 22:32", "2026-03-05 22:36", "2026-03-05 22:40", "2026-03-05 22:44", "2026-03-05 22:48", "2026-03-05 22:52", "2026-03-05 22:56", "2026-03-05 23:00", "2026-03-05 23:04", "2026-03-05 23:08", "2026-03-05 23:12", "2026-03-05 23:16", "2026-03-05 23:20", "2026-03-05 23:24", "2026-03-05 23:28", "2026-03-05 23:32", "2026-03-05 23:36", "2026-03-05 23:40", "2026-03-05 23:44", "2026-03-05 23:48", "2026-03-05 23:52", "2026-03-05 23:56", "2026-03-06 00:00", "2026-03-06 00:04", "2026-03-06 00:08", "2026-03-06 00:12", "2026-03-06 00:16", "2026-03-06 00:20", "2026-03-06 00:24", "2026-03-06 00:28", "2026-03-06 00:32", "2026-03-06 00:36", "2026-03-06 00:40", "2026-03-06 00:44", "2026-03-06 00:48", "2026-03-06 00:52", "2026-03-06 00:56", "2026-03-06 01:00", "2026-03-06 01:04", "2026-03-06 01:08", "2026-03-06 01:12", "2026-03-06 01:16", "2026-03-06 01:20", "2026-03-06 01:24", "2026-03-06 01:28", "2026-03-06 01:32", "2026-03-06 01:36", "2026-03-06 01:40", "2026-03-06 01:44", "2026-03-06 01:48", "2026-03-06 01:52", "2026-03-06 01:56", "2026-03-06 02:00", "2026-03-06 02:04", "2026-03-06 02:08", "2026-03-06 02:12", "2026-03-06 02:16", "2026-03-06 02:20", "2026-03-06 02:24", "2026-03-06 02:28", "2026-03-06 02:32", "2026-03-06 02:36", "2026-03-06 02:40", "2026-03-06 02:44", "2026-03-06 02:48", "2026-03-06 02:52", "2026-03-06 02:56", "2026-03-06 03:00", "2026-03-06 03:04", "2026-03-06 03:08", "2026-03-06 03:12", "2026-03-06 03:16", "2026-03-06 03:20", "2026-03-06 03:24", "2026-03-06 03:28", "2026-03-06 03:32", "2026-03-06 03:36", "2026-03-06 03:40", "2026-03-06 03:44", "2026-03-06 03:48", "2026-03-06 03:52", "2026-03-06 03:56", "2026-03-06 04:00", "2026-03-06 04:04", "2026-03-06 04:08", "2026-03-06 04:12", "2026-03-06 04:16", "2026-03-06 04:20", "2026-03-06 04:24", "2026-03-06 04:28", "2026-03-06 04:32", "2026-03-06 04:36", "2026-03-06 04:40", "2026-03-06 04:44", "2026-03-06 04:48", "2026-03-06 04:52", "2026-03-06 04:56", "2026-03-06 05:00", "2026-03-06 05:04", "2026-03-06 05:08", "2026-03-06 05:12", "2026-03-06 05:16", "2026-03-06 05:20", "2026-03-06 05:24", "2026-03-06 05:28", "2026-03-06 05:32", "2026-03-06 05:36", "2026-03-06 05:40", "2026-03-06 05:44", "2026-03-06 05:48", "2026-03-06 05:52", "2026-03-06 05:56", "2026-03-06 06:00", "2026-03-06 06:04", "2026-03-06 06:08", "2026-03-06 06:12", "2026-03-06 06:16", "2026-03-06 06:20", "2026-03-06 06:24", "2026-03-06 06:28", "2026-03-06 06:32", "2026-03-06 06:36", "2026-03-06 06:40", "2026-03-06 06:44", "2026-03-06 06:48", "2026-03-06 06:52", "2026-03-06 06:56", "2026-03-06 07:00", "2026-03-06 07:04", "2026-03-06 07:08", "2026-03-06 07:12", "2026-03-06 07:16", "2026-03-06 07:20", "2026-03-06 07:24", "2026-03-06 07:28", "2026-03-06 07:32", "2026-03-06 07:36", "2026-03-06 07:40", "2026-03-06 07:44", "2026-03-06 07:48", "2026-03-06 07:52", "2026-03-06 07:56", "2026-03-06 08:00", "2026-03-06 08:04", "2026-03-06 08:08", "2026-03-06 08:12", "2026-03-06 08:16", "2026-03-06 08:20", "2026-03-06 08:24", "2026-03-06 08:28", "2026-03-06 08:32", "2026-03-06 08:36", "2026-03-06 08:40", "2026-03-06 08:44", "2026-03-06 08:48", "2026-03-06 08:52", "2026-03-06 08:56", "2026-03-06 09:00", "2026-03-06 09:04", "2026-03-06 09:08", "2026-03-06 09:12", "2026-03-06 09:16", "2026-03-06 09:20", "2026-03-06 09:24", "2026-03-06 09:28", "2026-03-06 09:32", "2026-03-06 09:36", "2026-03-06 09:40", "2026-03-06 09:44", "2026-03-06 09:48", "2026-03-06 09:52", "2026-03-06 09:56", "2026-03-06 10:00", "2026-03-06 10:04", "2026-03-06 10:08", "2026-03-06 10:12", "2026-03-06 10:16", "2026-03-06 10:20", "2026-03-06 10:24", "2026-03-06 10:28", "2026-03-06 10:32", "2026-03-06 10:36", "2026-03-06 10:40", "2026-03-06 10:44", "2026-03-06 10:48", "2026-03-06 10:52", "2026-03-06 10:56", "2026-03-06 11:00", "2026-03-06 11:04", "2026-03-06 11:08", "2026-03-06 11:12", "2026-03-06 11:16", "2026-03-06 11:20", "2026-03-06 11:24", "2026-03-06 11:28", "2026-03-06 11:32", "2026-03-06 11:36", "2026-03-06 11:40", "2026-03-06 11:44", "2026-03-06 11:48", "2026-03-06 11:52", "2026-03-06 11:56", "2026-03-06 12:00", "2026-03-06 12:04", "2026-03-06 12:08", "2026-03-06 12:12", "2026-03-06 12:16", "2026-03-06 12:20", "2026-03-06 12:24", "2026-03-06 12:28", "2026-03-06 12:32", "2026-03-06 12:36", "2026-03-06 12:40", "2026-03-06 12:44", "2026-03-06 12:48", "2026-03-06 12:52", "2026-03-06 12:56", "2026-03-06 13:00", "2026-03-06 13:04", "2026-03-06 13:08", "2026-03-06 13:12", "2026-03-06 13:16", "2026-03-06 13:20", "2026-03-06 13:24", "2026-03-06 13:28", "2026-03-06 13:32", "2026-03-06 13:36", "2026-03-06 13:40", "2026-03-06 13:44", "2026-03-06 13:48", "2026-03-06 13:52", "2026-03-06 13:56", "2026-03-06 14:00", "2026-03-06 14:04", "2026-03-06 14:08", "2026-03-06 14:12", "2026-03-06 14:16", "2026-03-06 14:20", "2026-03-06 14:24", "2026-03-06 14:28", "2026-03-06 14:32", "2026-03-06 14:36", "2026-03-06 14:40", "2026-03-06 14:44", "2026-03-06 14:48", "2026-03-06 14:52", "2026-03-06 14:56", "2026-03-06 15:00", "2026-03-06 15:04", "2026-03-06 15:08", "2026-03-06 15:12", "2026-03-06 15:16", "2026-03-06 15:20", "2026-03-06 15:24", "2026-03-06 15:28", "2026-03-06 15:32", "2026-03-06 15:36", "2026-03-06 15:40", "2026-03-06 15:44", "2026-03-06 15:48", "2026-03-06 15:52", "2026-03-06 15:56", "2026-03-06 16:00", "2026-03-06 16:04", "2026-03-06 16:08", "2026-03-06 16:12", "2026-03-06 16:16", "2026-03-06 16:20", "2026-03-06 16:24", "2026-03-06 16:28", "2026-03-06 16:32", "2026-03-06 16:36", "2026-03-06 16:40", "2026-03-06 16:44", "2026-03-06 16:48", "2026-03-06 16:52", "2026-03-06 16:56", "2026-03-06 17:00", "2026-03-06 17:04", "2026-03-06 17:08", "2026-03-06 17:12", "2026-03-06 17:16", "2026-03-06 17:20", "2026-03-06 17:24", "2026-03-06 17:28", "2026-03-06 17:32", "2026-03-06 17:36", "2026-03-06 17:40", "2026-03-06 17:44", "2026-03-06 17:48", "2026-03-06 17:52", "2026-03-06 17:56", "2026-03-06 18:00", "2026-03-06 18:04", "2026-03-06 18:08", "2026-03-06 18:12", "2026-03-06 18:16", "2026-03-06 18:20", "2026-03-06 18:24", "2026-03-06 18:28", "2026-03-06 18:32", "2026-03-06 18:36", "2026-03-06 18:40", "2026-03-06 18:44", "2026-03-06 18:48", "2026-03-06 18:52", "2026-03-06 18:56", "2026-03-06 19:00", "2026-03-06 19:04", "2026-03-06 19:08", "2026-03-06 19:12", "2026-03-06 19:16", "2026-03-06 19:20", "2026-03-06 19:24", "2026-03-06 19:28", "2026-03-06 19:32", "2026-03-06 19:36", "2026-03-06 19:40", "2026-03-06 19:44", "2026-03-06 19:48", "2026-03-06 19:52", "2026-03-06 19:56", "2026-03-06 20:00", "2026-03-06 20:04", "2026-03-06 20:08", "2026-03-06 20:12", "2026-03-06 20:16", "2026-03-06 20:20", "2026-03-06 20:24", "2026-03-06 20:28", "2026-03-06 20:32", "2026-03-06 20:36", "2026-03-06 20:40", "2026-03-06 20:44", "2026-03-06 20:48", "2026-03-06 20:52", "2026-03-06 20:56", "2026-03-06 21:00", "2026-03-06 21:04", "2026-03-06 21:08", "2026-03-06 21:12", "2026-03-06 21:16", "2026-03-06 21:20", "2026-03-06 21:24", "2026-03-06 21:28", "2026-03-06 21:32", "2026-03-06 21:36", "2026-03-06 21:40", "2026-03-06 21:44", "2026-03-06 21:48", "2026-03-06 21:52", "2026-03-06 21:56", "2026-03-06 22:00", "2026-03-06 22:04", "2026-03-06 22:08", "2026-03-06 22:12", "2026-03-06 22:16", "2026-03-06 22:20", "2026-03-06 22:24", "2026-03-06 22:28", "2026-03-06 22:32", "2026-03-06 22:36", "2026-03-06 22:40", "2026-03-06 22:44", "2026-03-06 22:48", "2026-03-06 22:52", "2026-03-06 22:56", "2026-03-06 23:00", "2026-03-06 23:04", "2026-03-06 23:08", "2026-03-06 23:12", "2026-03-06 23:16", "2026-03-06 23:20", "2026-03-06 23:24", "2026-03-06 23:28", "2026-03-06 23:32", "2026-03-06 23:36", "2026-03-06 23:40", "2026-03-06 23:44", "2026-03-06 23:48", "2026-03-06 23:52", "2026-03-06 23:56", "2026-03-07 00:00", "2026-03-07 00:04", "2026-03-07 00:08", "2026-03-07 00:12", "2026-03-07 00:16", "2026-03-07 00:20", "2026-03-07 00:24", "2026-03-07 00:28", "2026-03-07 00:32", "2026-03-07 00:36", "2026-03-07 00:40", "2026-03-07 00:44", "2026-03-07 00:48", "2026-03-07 00:52", "2026-03-07 00:56", "2026-03-07 01:00", "2026-03-07 01:04", "2026-03-07 01:08", "2026-03-07 01:12", "2026-03-07 01:16", "2026-03-07 01:20", "2026-03-07 01:24", "2026-03-07 01:28", "2026-03-07 01:32", "2026-03-07 01:36", "2026-03-07 01:40", "2026-03-07 01:44", "2026-03-07 01:48", "2026-03-07 01:52", "2026-03-07 01:56", "2026-03-07 02:00", "2026-03-07 02:04", "2026-03-07 02:08", "2026-03-07 02:12", "2026-03-07 02:16", "2026-03-07 02:20", "2026-03-07 02:24", "2026-03-07 02:28", "2026-03-07 02:32", "2026-03-07 02:36", "2026-03-07 02:40", "2026-03-07 02:44", "2026-03-07 02:48", "2026-03-07 02:52", "2026-03-07 02:56", "2026-03-07 03:00", "2026-03-07 03:04", "2026-03-07 03:08", "2026-03-07 03:12", "2026-03-07 03:16", "2026-03-07 03:20", "2026-03-07 03:24", "2026-03-07 03:28", "2026-03-07 03:32", "2026-03-07 03:36", "2026-03-07 03:40", "2026-03-07 03:44", "2026-03-07 03:48", "2026-03-07 03:52", "2026-03-07 03:56", "2026-03-07 04:00", "2026-03-07 04:04", "2026-03-07 04:08", "2026-03-07 04:12", "2026-03-07 04:16", "2026-03-07 04:20", "2026-03-07 04:24", "2026-03-07 04:28", "2026-03-07 04:32", "2026-03-07 04:36", "2026-03-07 04:40", "2026-03-07 04:44", "2026-03-07 04:48", "2026-03-07 04:52", "2026-03-07 04:56", "2026-03-07 05:00", "2026-03-07 05:04", "2026-03-07 05:08", "2026-03-07 05:12", "2026-03-07 05:16", "2026-03-07 05:20", "2026-03-07 05:24", "2026-03-07 05:28", "2026-03-07 05:32", "2026-03-07 05:36", "2026-03-07 05:40", "2026-03-07 05:44", "2026-03-07 05:48", "2026-03-07 05:52", "2026-03-07 05:56", "2026-03-07 06:00", "2026-03-07 06:04", "2026-03-07 06:08", "2026-03-07 06:12", "2026-03-07 06:16", "2026-03-07 06:20", "2026-03-07 06:24", "2026-03-07 06:28", "2026-03-07 06:32", "2026-03-07 06:36", "2026-03-07 06:40", "2026-03-07 06:44", "2026-03-07 06:48", "2026-03-07 06:52", "2026-03-07 06:56", "2026-03-07 07:00", "2026-03-07 07:04", "2026-03-07 07:08", "2026-03-07 07:12", "2026-03-07 07:16", "2026-03-07 07:20", "2026-03-07 07:24", "2026-03-07 07:28", "2026-03-07 07:32", "2026-03-07 07:36", "2026-03-07 07:40", "2026-03-07 07:44", "2026-03-07 07:48", "2026-03-07 07:52", "2026-03-07 07:56", "2026-03-07 08:00", "2026-03-07 08:04", "2026-03-07 08:08", "2026-03-07 08:12", "2026-03-07 08:16", "2026-03-07 08:20", "2026-03-07 08:24", "2026-03-07 08:28", "2026-03-07 08:32", "2026-03-07 08:36", "2026-03-07 08:40", "2026-03-07 08:44", "2026-03-07 08:48", "2026-03-07 08:52", "2026-03-07 08:56", "2026-03-07 09:00", "2026-03-07 09:04", "2026-03-07 09:08", "2026-03-07 09:12", "2026-03-07 09:16", "2026-03-07 09:20", "2026-03-07 09:24", "2026-03-07 09:28", "2026-03-07 09:32", "2026-03-07 09:36", "2026-03-07 09:40", "2026-03-07 09:44", "2026-03-07 09:48", "2026-03-07 09:52", "2026-03-07 09:56", "2026-03-07 10:00", "2026-03-07 10:04", "2026-03-07 10:08", "2026-03-07 10:12", "2026-03-07 10:16", "2026-03-07 10:20", "2026-03-07 10:24", "2026-03-07 10:28", "2026-03-07 10:32", "2026-03-07 10:36", "2026-03-07 10:40", "2026-03-07 10:44", "2026-03-07 10:48", "2026-03-07 10:52", "2026-03-07 10:56", "2026-03-07 11:00", "2026-03-07 11:04", "2026-03-07 11:08", "2026-03-07 11:12", "2026-03-07 11:16", "2026-03-07 11:20", "2026-03-07 11:24", "2026-03-07 11:28", "2026-03-07 11:32", "2026-03-07 11:36", "2026-03-07 11:40", "2026-03-07 11:44", "2026-03-07 11:48", "2026-03-07 11:52", "2026-03-07 11:56", "2026-03-07 12:00", "2026-03-07 12:04", "2026-03-07 12:08", "2026-03-07 12:12", "2026-03-07 12:16", "2026-03-07 12:20", "2026-03-07 12:24", "2026-03-07 12:28", "2026-03-07 12:32", "2026-03-07 12:36", "2026-03-07 12:40", "2026-03-07 12:44", "2026-03-07 12:48", "2026-03-07 12:52", "2026-03-07 12:56", "2026-03-07 13:00", "2026-03-07 13:04", "2026-03-07 13:08", "2026-03-07 13:12", "2026-03-07 13:16", "2026-03-07 13:20", "2026-03-07 13:24", "2026-03-07 13:28", "2026-03-07 13:32", "2026-03-07 13:36", "2026-03-07 13:40", "2026-03-07 13:44", "2026-03-07 13:48", "2026-03-07 13:52", "2026-03-07 13:56", "2026-03-07 14:00", "2026-03-07 14:04", "2026-03-07 14:08", "2026-03-07 14:12", "2026-03-07 14:16", "2026-03-07 14:20", "2026-03-07 14:24", "2026-03-07 14:28", "2026-03-07 14:32", "2026-03-07 14:36", "2026-03-07 14:40", "2026-03-07 14:44", "2026-03-07 14:48", "2026-03-07 14:52", "2026-03-07 14:56", "2026-03-07 15:00", "2026-03-07 15:04", "2026-03-07 15:08", "2026-03-07 15:12", "2026-03-07 15:16", "2026-03-07 15:20", "2026-03-07 15:24", "2026-03-07 15:28", "2026-03-07 15:32", "2026-03-07 15:36", "2026-03-07 15:40", "2026-03-07 15:44", "2026-03-07 15:48", "2026-03-07 15:52", "2026-03-07 15:56", "2026-03-07 16:00", "2026-03-07 16:04", "2026-03-07 16:08", "2026-03-07 16:12", "2026-03-07 16:16", "2026-03-07 16:20", "2026-03-07 16:24", "2026-03-07 16:28", "2026-03-07 16:32", "2026-03-07 16:36", "2026-03-07 16:40", "2026-03-07 16:44", "2026-03-07 16:48", "2026-03-07 16:52", "2026-03-07 16:56", "2026-03-07 17:00", "2026-03-07 17:04", "2026-03-07 17:08", "2026-03-07 17:12", "2026-03-07 17:16", "2026-03-07 17:20", "2026-03-07 17:24", "2026-03-07 17:28", "2026-03-07 17:32", "2026-03-07 17:36", "2026-03-07 17:40", "2026-03-07 17:44", "2026-03-07 17:48", "2026-03-07 17:52", "2026-03-07 17:56", "2026-03-07 18:00", "2026-03-07 18:04", "2026-03-07 18:08", "2026-03-07 18:12", "2026-03-07 18:16", "2026-03-07 18:20", "2026-03-07 18:24", "2026-03-07 18:28", "2026-03-07 18:32", "2026-03-07 18:36", "2026-03-07 18:40", "2026-03-07 18:44", "2026-03-07 18:48", "2026-03-07 18:52", "2026-03-07 18:56", "2026-03-07 19:00", "2026-03-07 19:04", "2026-03-07 19:08", "2026-03-07 19:12", "2026-03-07 19:16", "2026-03-07 19:20", "2026-03-07 19:24", "2026-03-07 19:28", "2026-03-07 19:32", "2026-03-07 19:36", "2026-03-07 19:40", "2026-03-07 19:44", "2026-03-07 19:48", "2026-03-07 19:52", "2026-03-07 19:56", "2026-03-07 20:00", "2026-03-07 20:04", "2026-03-07 20:08", "2026-03-07 20:12", "2026-03-07 20:16", "2026-03-07 20:20", "2026-03-07 20:24", "2026-03-07 20:28", "2026-03-07 20:32", "2026-03-07 20:36", "2026-03-07 20:40", "2026-03-07 20:44", "2026-03-07 20:48", "2026-03-07 20:52", "2026-03-07 20:56", "2026-03-07 21:00", "2026-03-07 21:04", "2026-03-07 21:08", "2026-03-07 21:12", "2026-03-07 21:16", "2026-03-07 21:20", "2026-03-07 21:24", "2026-03-07 21:28", "2026-03-07 21:32", "2026-03-07 21:36", "2026-03-07 21:40", "2026-03-07 21:44", "2026-03-07 21:48", "2026-03-07 21:52", "2026-03-07 21:56", "2026-03-07 22:00", "2026-03-07 22:04", "2026-03-07 22:08", "2026-03-07 22:12", "2026-03-07 22:16", "2026-03-07 22:20", "2026-03-07 22:24", "2026-03-07 22:28", "2026-03-07 22:32", "2026-03-07 22:36", "2026-03-07 22:40", "2026-03-07 22:44", "2026-03-07 22:48", "2026-03-07 22:52", "2026-03-07 22:56", "2026-03-07 23:00", "2026-03-07 23:04", "2026-03-07 23:08", "2026-03-07 23:12", "2026-03-07 23:16", "2026-03-07 23:20", "2026-03-07 23:24", "2026-03-07 23:28", "2026-03-07 23:32", "2026-03-07 23:36", "2026-03-07 23:40", "2026-03-07 23:44", "2026-03-07 23:48", "2026-03-07 23:52", "2026-03-07 23:56", "2026-03-08 00:00", "2026-03-08 00:04", "2026-03-08 00:08", "2026-03-08 00:12", "2026-03-08 00:16", "2026-03-08 00:20", "2026-03-08 00:24", "2026-03-08 00:28", "2026-03-08 00:32", "2026-03-08 00:36", "2026-03-08 00:40", "2026-03-08 00:44", "2026-03-08 00:48", "2026-03-08 00:52", "2026-03-08 00:56", "2026-03-08 01:00", "2026-03-08 01:04", "2026-03-08 01:08", "2026-03-08 01:12", "2026-03-08 01:16", "2026-03-08 01:20", "2026-03-08 01:24", "2026-03-08 01:28", "2026-03-08 01:32", "2026-03-08 01:36", "2026-03-08 01:40", "2026-03-08 01:44", "2026-03-08 01:48", "2026-03-08 01:52", "2026-03-08 01:56", "2026-03-08 02:00", "2026-03-08 02:04", "2026-03-08 02:08", "2026-03-08 02:12", "2026-03-08 02:16", "2026-03-08 02:20", "2026-03-08 02:24", "2026-03-08 02:28", "2026-03-08 02:32", "2026-03-08 02:36", "2026-03-08 02:40", "2026-03-08 02:44", "2026-03-08 02:48", "2026-03-08 02:52", "2026-03-08 02:56", "2026-03-08 03:00", "2026-03-08 03:04", "2026-03-08 03:08", "2026-03-08 03:12", "2026-03-08 03:16", "2026-03-08 03:20", "2026-03-08 03:24", "2026-03-08 03:28", "2026-03-08 03:32", "2026-03-08 03:36", "2026-03-08 03:40", "2026-03-08 03:44", "2026-03-08 03:48", "2026-03-08 03:52", "2026-03-08 03:56", "2026-03-08 04:00", "2026-03-08 04:04", "2026-03-08 04:08", "2026-03-08 04:12", "2026-03-08 04:16", "2026-03-08 04:20", "2026-03-08 04:24", "2026-03-08 04:28", "2026-03-08 04:32", "2026-03-08 04:36", "2026-03-08 04:40", "2026-03-08 04:44", "2026-03-08 04:48", "2026-03-08 04:52", "2026-03-08 04:56", "2026-03-08 05:00", "2026-03-08 05:04", "2026-03-08 05:08", "2026-03-08 05:12", "2026-03-08 05:16", "2026-03-08 05:20", "2026-03-08 05:24", "2026-03-08 05:28", "2026-03-08 05:32", "2026-03-08 05:36", "2026-03-08 05:40", "2026-03-08 05:44", "2026-03-08 05:48", "2026-03-08 05:52", "2026-03-08 05:56", "2026-03-08 06:00", "2026-03-08 06:04", "2026-03-08 06:08", "2026-03-08 06:12", "2026-03-08 06:16", "2026-03-08 06:20", "2026-03-08 06:24", "2026-03-08 06:28", "2026-03-08 06:32", "2026-03-08 06:36", "2026-03-08 06:40", "2026-03-08 06:44", "2026-03-08 06:48", "2026-03-08 06:52", "2026-03-08 06:56", "2026-03-08 07:00", "2026-03-08 07:04", "2026-03-08 07:08", "2026-03-08 07:12", "2026-03-08 07:16", "2026-03-08 07:20", "2026-03-08 07:24", "2026-03-08 07:28", "2026-03-08 07:32", "2026-03-08 07:36", "2026-03-08 07:40", "2026-03-08 07:44", "2026-03-08 07:48", "2026-03-08 07:52", "2026-03-08 07:56", "2026-03-08 08:00", "2026-03-08 08:04", "2026-03-08 08:08", "2026-03-08 08:12", "2026-03-08 08:16", "2026-03-08 08:20", "2026-03-08 08:24", "2026-03-08 08:28", "2026-03-08 08:32", "2026-03-08 08:36", "2026-03-08 08:40", "2026-03-08 08:44", "2026-03-08 08:48", "2026-03-08 08:52", "2026-03-08 08:56", "2026-03-08 09:00", "2026-03-08 09:04", "2026-03-08 09:08", "2026-03-08 09:12", "2026-03-08 09:16", "2026-03-08 09:20", "2026-03-08 09:24", "2026-03-08 09:28", "2026-03-08 09:32", "2026-03-08 09:36", "2026-03-08 09:40", "2026-03-08 09:44", "2026-03-08 09:48", "2026-03-08 09:52", "2026-03-08 09:56", "2026-03-08 10:00", "2026-03-08 10:04", "2026-03-08 10:08", "2026-03-08 10:12", "2026-03-08 10:16", "2026-03-08 10:20", "2026-03-08 10:24", "2026-03-08 10:28", "2026-03-08 10:32", "2026-03-08 10:36", "2026-03-08 10:40", "2026-03-08 10:44", "2026-03-08 10:48", "2026-03-08 10:52", "2026-03-08 10:56", "2026-03-08 11:00", "2026-03-08 11:04", "2026-03-08 11:08", "2026-03-08 11:12", "2026-03-08 11:16", "2026-03-08 11:20", "2026-03-08 11:24", "2026-03-08 11:28", "2026-03-08 11:32", "2026-03-08 11:36", "2026-03-08 11:40", "2026-03-08 11:44", "2026-03-08 11:48", "2026-03-08 11:52", "2026-03-08 11:56", "2026-03-08 12:00", "2026-03-08 12:04", "2026-03-08 12:08", "2026-03-08 12:12", "2026-03-08 12:16", "2026-03-08 12:20", "2026-03-08 12:24", "2026-03-08 12:28", "2026-03-08 12:32", "2026-03-08 12:36", "2026-03-08 12:40", "2026-03-08 12:44", "2026-03-08 12:48", "2026-03-08 12:52", "2026-03-08 12:56", "2026-03-08 13:00", "2026-03-08 13:04", "2026-03-08 13:08", "2026-03-08 13:12", "2026-03-08 13:16", "2026-03-08 13:20", "2026-03-08 13:24", "2026-03-08 13:28", "2026-03-08 13:32", "2026-03-08 13:36", "2026-03-08 13:40", "2026-03-08 13:44", "2026-03-08 13:48", "2026-03-08 13:52", "2026-03-08 13:56", "2026-03-08 14:00", "2026-03-08 14:04", "2026-03-08 14:08", "2026-03-08 14:12", "2026-03-08 14:16", "2026-03-08 14:20", "2026-03-08 14:24", "2026-03-08 14:28", "2026-03-08 14:32", "2026-03-08 14:36", "2026-03-08 14:40", "2026-03-08 14:44", "2026-03-08 14:48", "2026-03-08 14:52", "2026-03-08 14:56", "2026-03-08 15:00", "2026-03-08 15:04", "2026-03-08 15:08", "2026-03-08 15:12", "2026-03-08 15:16", "2026-03-08 15:20", "2026-03-08 15:24", "2026-03-08 15:28", "2026-03-08 15:32", "2026-03-08 15:36", "2026-03-08 15:40", "2026-03-08 15:44", "2026-03-08 15:48", "2026-03-08 15:52", "2026-03-08 15:56", "2026-03-08 16:00", "2026-03-08 16:04", "2026-03-08 16:08", "2026-03-08 16:12", "2026-03-08 16:16", "2026-03-08 16:20", "2026-03-08 16:24", "2026-03-08 16:28", "2026-03-08 16:32", "2026-03-08 16:36", "2026-03-08 16:40", "2026-03-08 16:44", "2026-03-08 16:48", "2026-03-08 16:52", "2026-03-08 16:56", "2026-03-08 17:00", "2026-03-08 17:04", "2026-03-08 17:08", "2026-03-08 17:12", "2026-03-08 17:16", "2026-03-08 17:20", "2026-03-08 17:24", "2026-03-08 17:28", "2026-03-08 17:32", "2026-03-08 17:36", "2026-03-08 17:40", "2026-03-08 17:44", "2026-03-08 17:48", "2026-03-08 17:52", "2026-03-08 17:56", "2026-03-08 18:00", "2026-03-08 18:04", "2026-03-08 18:08", "2026-03-08 18:12", "2026-03-08 18:16", "2026-03-08 18:20", "2026-03-08 18:24", "2026-03-08 18:28", "2026-03-08 18:32", "2026-03-08 18:36", "2026-03-08 18:40", "2026-03-08 18:44", "2026-03-08 18:48", "2026-03-08 18:52", "2026-03-08 18:56", "2026-03-08 19:00", "2026-03-08 19:04", "2026-03-08 19:08", "2026-03-08 19:12", "2026-03-08 19:16", "2026-03-08 19:20", "2026-03-08 19:24", "2026-03-08 19:28", "2026-03-08 19:32", "2026-03-08 19:36", "2026-03-08 19:40", "2026-03-08 19:44", "2026-03-08 19:48", "2026-03-08 19:52", "2026-03-08 19:56", "2026-03-08 20:00", "2026-03-08 20:04", "2026-03-08 20:08", "2026-03-08 20:12", "2026-03-08 20:16", "2026-03-08 20:20", "2026-03-08 20:24", "2026-03-08 20:28", "2026-03-08 20:32", "2026-03-08 20:36", "2026-03-08 20:40", "2026-03-08 20:44", "2026-03-08 20:48", "2026-03-08 20:52", "2026-03-08 20:56", "2026-03-08 21:00", "2026-03-08 21:04", "2026-03-08 21:08", "2026-03-08 21:12", "2026-03-08 21:16", "2026-03-08 21:20", "2026-03-08 21:24", "2026-03-08 21:28", "2026-03-08 21:32", "2026-03-08 21:36", "2026-03-08 21:40", "2026-03-08 21:44", "2026-03-08 21:48", "2026-03-08 21:52", "2026-03-08 21:56", "2026-03-08 22:00", "2026-03-08 22:04", "2026-03-08 22:08", "2026-03-08 22:12", "2026-03-08 22:16", "2026-03-08 22:20", "2026-03-08 22:24", "2026-03-08 22:28", "2026-03-08 22:32", "2026-03-08 22:36", "2026-03-08 22:40", "2026-03-08 22:44", "2026-03-08 22:48", "2026-03-08 22:52", "2026-03-08 22:56", "2026-03-08 23:00", "2026-03-08 23:04", "2026-03-08 23:08", "2026-03-08 23:12", "2026-03-08 23:16", "2026-03-08 23:20", "2026-03-08 23:24", "2026-03-08 23:28", "2026-03-08 23:32", "2026-03-08 23:36", "2026-03-08 23:40", "2026-03-08 23:44", "2026-03-08 23:48", "2026-03-08 23:52", "2026-03-08 23:56", "2026-03-09 00:00", "2026-03-09 00:04", "2026-03-09 00:08", "2026-03-09 00:12", "2026-03-09 00:16", "2026-03-09 00:20", "2026-03-09 00:24", "2026-03-09 00:28", "2026-03-09 00:32", "2026-03-09 00:36", "2026-03-09 00:40", "2026-03-09 00:44", "2026-03-09 00:48", "2026-03-09 00:52", "2026-03-09 00:56", "2026-03-09 01:00", "2026-03-09 01:04", "2026-03-09 01:08", "2026-03-09 01:12", "2026-03-09 01:16", "2026-03-09 01:20", "2026-03-09 01:24", "2026-03-09 01:28", "2026-03-09 01:32", "2026-03-09 01:36", "2026-03-09 01:40", "2026-03-09 01:44", "2026-03-09 01:48", "2026-03-09 01:52", "2026-03-09 01:56", "2026-03-09 02:00", "2026-03-09 02:04", "2026-03-09 02:08", "2026-03-09 02:12", "2026-03-09 02:16", "2026-03-09 02:20", "2026-03-09 02:24", "2026-03-09 02:28", "2026-03-09 02:32", "2026-03-09 02:36", "2026-03-09 02:40", "2026-03-09 02:44", "2026-03-09 02:48", "2026-03-09 02:52", "2026-03-09 02:56", "2026-03-09 03:00", "2026-03-09 03:04", "2026-03-09 03:08", "2026-03-09 03:12", "2026-03-09 03:16", "2026-03-09 03:20", "2026-03-09 03:24", "2026-03-09 03:28", "2026-03-09 03:32", "2026-03-09 03:36", "2026-03-09 03:40", "2026-03-09 03:44", "2026-03-09 03:48", "2026-03-09 03:52", "2026-03-09 03:56", "2026-03-09 04:00", "2026-03-09 04:04", "2026-03-09 04:08", "2026-03-09 04:12", "2026-03-09 04:16", "2026-03-09 04:20", "2026-03-09 04:24", "2026-03-09 04:28", "2026-03-09 04:32", "2026-03-09 04:36", "2026-03-09 04:40", "2026-03-09 04:44", "2026-03-09 04:48", "2026-03-09 04:52", "2026-03-09 04:56", "2026-03-09 05:00", "2026-03-09 05:04", "2026-03-09 05:08", "2026-03-09 05:12", "2026-03-09 05:16", "2026-03-09 05:20", "2026-03-09 05:24", "2026-03-09 05:28", "2026-03-09 05:32", "2026-03-09 05:36", "2026-03-09 05:40", "2026-03-09 05:44", "2026-03-09 05:48", "2026-03-09 05:52", "2026-03-09 05:56", "2026-03-09 06:00", "2026-03-09 06:04", "2026-03-09 06:08", "2026-03-09 06:12", "2026-03-09 06:16", "2026-03-09 06:20", "2026-03-09 06:24", "2026-03-09 06:28", "2026-03-09 06:32", "2026-03-09 06:36", "2026-03-09 06:40", "2026-03-09 06:44", "2026-03-09 06:48", "2026-03-09 06:52", "2026-03-09 06:56", "2026-03-09 07:00", "2026-03-09 07:04", "2026-03-09 07:08", "2026-03-09 07:12", "2026-03-09 07:16", "2026-03-09 07:20", "2026-03-09 07:24", "2026-03-09 07:28", "2026-03-09 07:32", "2026-03-09 07:36", "2026-03-09 07:40", "2026-03-09 07:44", "2026-03-09 07:48", "2026-03-09 07:52", "2026-03-09 07:56", "2026-03-09 08:00", "2026-03-09 08:04", "2026-03-09 08:08", "2026-03-09 08:12", "2026-03-09 08:16", "2026-03-09 08:20", "2026-03-09 08:24", "2026-03-09 08:28", "2026-03-09 08:32", "2026-03-09 08:36", "2026-03-09 08:40", "2026-03-09 08:44", "2026-03-09 08:48", "2026-03-09 08:52", "2026-03-09 08:56", "2026-03-09 09:00", "2026-03-09 09:04", "2026-03-09 09:08", "2026-03-09 09:12", "2026-03-09 09:16", "2026-03-09 09:20", "2026-03-09 09:24", "2026-03-09 09:28", "2026-03-09 09:32", "2026-03-09 09:36", "2026-03-09 09:40", "2026-03-09 09:44", "2026-03-09 09:48", "2026-03-09 09:52", "2026-03-09 09:56", "2026-03-09 10:00", "2026-03-09 10:04", "2026-03-09 10:08", "2026-03-09 10:12", "2026-03-09 10:16", "2026-03-09 10:20", "2026-03-09 10:24", "2026-03-09 10:28", "2026-03-09 10:32", "2026-03-09 10:36", "2026-03-09 10:40", "2026-03-09 10:44", "2026-03-09 10:48", "2026-03-09 10:52", "2026-03-09 10:56", "2026-03-09 11:00", "2026-03-09 11:04", "2026-03-09 11:08", "2026-03-09 11:12", "2026-03-09 11:16", "2026-03-09 11:20", "2026-03-09 11:24", "2026-03-09 11:28", "2026-03-09 11:32", "2026-03-09 11:36", "2026-03-09 11:40", "2026-03-09 11:44", "2026-03-09 11:48", "2026-03-09 11:52", "2026-03-09 11:56", "2026-03-09 12:00", "2026-03-09 12:04", "2026-03-09 12:08", "2026-03-09 12:12", "2026-03-09 12:16", "2026-03-09 12:20", "2026-03-09 12:24", "2026-03-09 12:28", "2026-03-09 12:32", "2026-03-09 12:36", "2026-03-09 12:40", "2026-03-09 12:44", "2026-03-09 12:48", "2026-03-09 12:52", "2026-03-09 12:56", "2026-03-09 13:00", "2026-03-09 13:04", "2026-03-09 13:08", "2026-03-09 13:12", "2026-03-09 13:16", "2026-03-09 13:20", "2026-03-09 13:24", "2026-03-09 13:28", "2026-03-09 13:32", "2026-03-09 13:36", "2026-03-09 13:40", "2026-03-09 13:44", "2026-03-09 13:48", "2026-03-09 13:52", "2026-03-09 13:56", "2026-03-09 14:00", "2026-03-09 14:04", "2026-03-09 14:08", "2026-03-09 14:12", "2026-03-09 14:16", "2026-03-09 14:20", "2026-03-09 14:24", "2026-03-09 14:28", "2026-03-09 14:32", "2026-03-09 14:36", "2026-03-09 14:40", "2026-03-09 14:44", "2026-03-09 14:48", "2026-03-09 14:52", "2026-03-09 14:56", "2026-03-09 15:00", "2026-03-09 15:04", "2026-03-09 15:08", "2026-03-09 15:12", "2026-03-09 15:16", "2026-03-09 15:20", "2026-03-09 15:24", "2026-03-09 15:28", "2026-03-09 15:32", "2026-03-09 15:36", "2026-03-09 15:40", "2026-03-09 15:44", "2026-03-09 15:48", "2026-03-09 15:52", "2026-03-09 15:56", "2026-03-09 16:00", "2026-03-09 16:04", "2026-03-09 16:08", "2026-03-09 16:12", "2026-03-09 16:16", "2026-03-09 16:20", "2026-03-09 16:24", "2026-03-09 16:28", "2026-03-09 16:32", "2026-03-09 16:36", "2026-03-09 16:40", "2026-03-09 16:44", "2026-03-09 16:48", "2026-03-09 16:52", "2026-03-09 16:56", "2026-03-09 17:00", "2026-03-09 17:04", "2026-03-09 17:08", "2026-03-09 17:12", "2026-03-09 17:16", "2026-03-09 17:20", "2026-03-09 17:24", "2026-03-09 17:28", "2026-03-09 17:32", "2026-03-09 17:36", "2026-03-09 17:40", "2026-03-09 17:44", "2026-03-09 17:48", "2026-03-09 17:52", "2026-03-09 17:56", "2026-03-09 18:00", "2026-03-09 18:04", "2026-03-09 18:08", "2026-03-09 18:12", "2026-03-09 18:16", "2026-03-09 18:20", "2026-03-09 18:24", "2026-03-09 18:28", "2026-03-09 18:32", "2026-03-09 18:36", "2026-03-09 18:40", "2026-03-09 18:44", "2026-03-09 18:48", "2026-03-09 18:52", "2026-03-09 18:56", "2026-03-09 19:00", "2026-03-09 19:04", "2026-03-09 19:08", "2026-03-09 19:12", "2026-03-09 19:16", "2026-03-09 19:20", "2026-03-09 19:24", "2026-03-09 19:28", "2026-03-09 19:32", "2026-03-09 19:36", "2026-03-09 19:40", "2026-03-09 19:44", "2026-03-09 19:48", "2026-03-09 19:52", "2026-03-09 19:56", "2026-03-09 20:00", "2026-03-09 20:04", "2026-03-09 20:08", "2026-03-09 20:12", "2026-03-09 20:16", "2026-03-09 20:20", "2026-03-09 20:24", "2026-03-09 20:28", "2026-03-09 20:32", "2026-03-09 20:36", "2026-03-09 20:40", "2026-03-09 20:44", "2026-03-09 20:48", "2026-03-09 20:52", "2026-03-09 20:56", "2026-03-09 21:00", "2026-03-09 21:04", "2026-03-09 21:08", "2026-03-09 21:12", "2026-03-09 21:16", "2026-03-09 21:20", "2026-03-09 21:24", "2026-03-09 21:28", "2026-03-09 21:32", "2026-03-09 21:36", "2026-03-09 21:40", "2026-03-09 21:44", "2026-03-09 21:48", "2026-03-09 21:52", "2026-03-09 21:56", "2026-03-09 22:00", "2026-03-09 22:04", "2026-03-09 22:08", "2026-03-09 22:12", "2026-03-09 22:16", "2026-03-09 22:20", "2026-03-09 22:24", "2026-03-09 22:28", "2026-03-09 22:32", "2026-03-09 22:36", "2026-03-09 22:40", "2026-03-09 22:44", "2026-03-09 22:48", "2026-03-09 22:52", "2026-03-09 22:56", "2026-03-09 23:00", "2026-03-09 23:04", "2026-03-09 23:08", "2026-03-09 23:12", "2026-03-09 23:16", "2026-03-09 23:20", "2026-03-09 23:24", "2026-03-09 23:28", "2026-03-09 23:32", "2026-03-09 23:36", "2026-03-09 23:40", "2026-03-09 23:44", "2026-03-09 23:48", "2026-03-09 23:52", "2026-03-09 23:56", "2026-03-10 00:00", "2026-03-10 00:04", "2026-03-10 00:08", "2026-03-10 00:12", "2026-03-10 00:16", "2026-03-10 00:20", "2026-03-10 00:24", "2026-03-10 00:28", "2026-03-10 00:32", "2026-03-10 00:36", "2026-03-10 00:40", "2026-03-10 00:44", "2026-03-10 00:48", "2026-03-10 00:52", "2026-03-10 00:56", "2026-03-10 01:00", "2026-03-10 01:04", "2026-03-10 01:08", "2026-03-10 01:12", "2026-03-10 01:16", "2026-03-10 01:20", "2026-03-10 01:24", "2026-03-10 01:28", "2026-03-10 01:32", "2026-03-10 01:36", "2026-03-10 01:40", "2026-03-10 01:44", "2026-03-10 01:48", "2026-03-10 01:52", "2026-03-10 01:56", "2026-03-10 02:00", "2026-03-10 02:04", "2026-03-10 02:08", "2026-03-10 02:12", "2026-03-10 02:16", "2026-03-10 02:20", "2026-03-10 02:24", "2026-03-10 02:28", "2026-03-10 02:32", "2026-03-10 02:36", "2026-03-10 02:40", "2026-03-10 02:44", "2026-03-10 02:48", "2026-03-10 02:52", "2026-03-10 02:56", "2026-03-10 03:00", "2026-03-10 03:04", "2026-03-10 03:08", "2026-03-10 03:12", "2026-03-10 03:16", "2026-03-10 03:20", "2026-03-10 03:24", "2026-03-10 03:28", "2026-03-10 03:32", "2026-03-10 03:36", "2026-03-10 03:40", "2026-03-10 03:44", "2026-03-10 03:48", "2026-03-10 03:52", "2026-03-10 03:56", "2026-03-10 04:00", "2026-03-10 04:04", "2026-03-10 04:08", "2026-03-10 04:12", "2026-03-10 04:16", "2026-03-10 04:20", "2026-03-10 04:24", "2026-03-10 04:28", "2026-03-10 04:32", "2026-03-10 04:36", "2026-03-10 04:40", "2026-03-10 04:44", "2026-03-10 04:48", "2026-03-10 04:52", "2026-03-10 04:56", "2026-03-10 05:00", "2026-03-10 05:04", "2026-03-10 05:08", "2026-03-10 05:12", "2026-03-10 05:16", "2026-03-10 05:20", "2026-03-10 05:24", "2026-03-10 05:28", "2026-03-10 05:32", "2026-03-10 05:36", "2026-03-10 05:40", "2026-03-10 05:44", "2026-03-10 05:48", "2026-03-10 05:52", "2026-03-10 05:56", "2026-03-10 06:00", "2026-03-10 06:04", "2026-03-10 06:08", "2026-03-10 06:12", "2026-03-10 06:16", "2026-03-10 06:20", "2026-03-10 06:24", "2026-03-10 06:28", "2026-03-10 06:32", "2026-03-10 06:36", "2026-03-10 06:40", "2026-03-10 06:44", "2026-03-10 06:48", "2026-03-10 06:52", "2026-03-10 06:56", "2026-03-10 07:00", "2026-03-10 07:04", "2026-03-10 07:08", "2026-03-10 07:12", "2026-03-10 07:16", "2026-03-10 07:20", "2026-03-10 07:24", "2026-03-10 07:28", "2026-03-10 07:32", "2026-03-10 07:36", "2026-03-10 07:40", "2026-03-10 07:44", "2026-03-10 07:48", "2026-03-10 07:52", "2026-03-10 07:56", "2026-03-10 08:00", "2026-03-10 08:04", "2026-03-10 08:08", "2026-03-10 08:12", "2026-03-10 08:16", "2026-03-10 08:20", "2026-03-10 08:24", "2026-03-10 08:28", "2026-03-10 08:32", "2026-03-10 08:36", "2026-03-10 08:40", "2026-03-10 08:44", "2026-03-10 08:48", "2026-03-10 08:52", "2026-03-10 08:56", "2026-03-10 09:00", "2026-03-10 09:04", "2026-03-10 09:08", "2026-03-10 09:12", "2026-03-10 09:16", "2026-03-10 09:20", "2026-03-10 09:24", "2026-03-10 09:28", "2026-03-10 09:32", "2026-03-10 09:36", "2026-03-10 09:40", "2026-03-10 09:44", "2026-03-10 09:48", "2026-03-10 09:52", "2026-03-10 09:56", "2026-03-10 10:00", "2026-03-10 10:04", "2026-03-10 10:08", "2026-03-10 10:12", "2026-03-10 10:16", "2026-03-10 10:20", "2026-03-10 10:24", "2026-03-10 10:28", "2026-03-10 10:32", "2026-03-10 10:36", "2026-03-10 10:40", "2026-03-10 10:44", "2026-03-10 10:48", "2026-03-10 10:52", "2026-03-10 10:56", "2026-03-10 11:00", "2026-03-10 11:04", "2026-03-10 11:08", "2026-03-10 11:12", "2026-03-10 11:16", "2026-03-10 11:20", "2026-03-10 11:24", "2026-03-10 11:28", "2026-03-10 11:32", "2026-03-10 11:36", "2026-03-10 11:40", "2026-03-10 11:44", "2026-03-10 11:48", "2026-03-10 11:52", "2026-03-10 11:56", "2026-03-10 12:00", "2026-03-10 12:04", "2026-03-10 12:08", "2026-03-10 12:12", "2026-03-10 12:16", "2026-03-10 12:20", "2026-03-10 12:24", "2026-03-10 12:28", "2026-03-10 12:32", "2026-03-10 12:36", "2026-03-10 12:40", "2026-03-10 12:44", "2026-03-10 12:48", "2026-03-10 12:52", "2026-03-10 12:56", "2026-03-10 13:00", "2026-03-10 13:04", "2026-03-10 13:08", "2026-03-10 13:12", "2026-03-10 13:16", "2026-03-10 13:20", "2026-03-10 13:24", "2026-03-10 13:28", "2026-03-10 13:32", "2026-03-10 13:36", "2026-03-10 13:40", "2026-03-10 13:44", "2026-03-10 13:48", "2026-03-10 13:52", "2026-03-10 13:56", "2026-03-10 14:00", "2026-03-10 14:04", "2026-03-10 14:08", "2026-03-10 14:12", "2026-03-10 14:16", "2026-03-10 14:20", "2026-03-10 14:24", "2026-03-10 14:28", "2026-03-10 14:32", "2026-03-10 14:36", "2026-03-10 14:40", "2026-03-10 14:44", "2026-03-10 14:48", "2026-03-10 14:52", "2026-03-10 14:56", "2026-03-10 15:00", "2026-03-10 15:04", "2026-03-10 15:08", "2026-03-10 15:12", "2026-03-10 15:16", "2026-03-10 15:20", "2026-03-10 15:24", "2026-03-10 15:28", "2026-03-10 15:32", "2026-03-10 15:36", "2026-03-10 15:40", "2026-03-10 15:44", "2026-03-10 15:48", "2026-03-10 15:52", "2026-03-10 15:56", "2026-03-10 16:00", "2026-03-10 16:04", "2026-03-10 16:08", "2026-03-10 16:12", "2026-03-10 16:16", "2026-03-10 16:20", "2026-03-10 16:24", "2026-03-10 16:28", "2026-03-10 16:32", "2026-03-10 16:36", "2026-03-10 16:40", "2026-03-10 16:44", "2026-03-10 16:48", "2026-03-10 16:52", "2026-03-10 16:56", "2026-03-10 17:00", "2026-03-10 17:04", "2026-03-10 17:08", "2026-03-10 17:12", "2026-03-10 17:16", "2026-03-10 17:20", "2026-03-10 17:24", "2026-03-10 17:28", "2026-03-10 17:32", "2026-03-10 17:36", "2026-03-10 17:40", "2026-03-10 17:44", "2026-03-10 17:48", "2026-03-10 17:52", "2026-03-10 17:56", "2026-03-10 18:00", "2026-03-10 18:04", "2026-03-10 18:08", "2026-03-10 18:12", "2026-03-10 18:16", "2026-03-10 18:20", "2026-03-10 18:24", "2026-03-10 18:28", "2026-03-10 18:32", "2026-03-10 18:36", "2026-03-10 18:40", "2026-03-10 18:44", "2026-03-10 18:48", "2026-03-10 18:52", "2026-03-10 18:56", "2026-03-10 19:00", "2026-03-10 19:04", "2026-03-10 19:08", "2026-03-10 19:12", "2026-03-10 19:16", "2026-03-10 19:20", "2026-03-10 19:24", "2026-03-10 19:28", "2026-03-10 19:32", "2026-03-10 19:36", "2026-03-10 19:40", "2026-03-10 19:44", "2026-03-10 19:48", "2026-03-10 19:52", "2026-03-10 19:56", "2026-03-10 20:00", "2026-03-10 20:04", "2026-03-10 20:08", "2026-03-10 20:12", "2026-03-10 20:16", "2026-03-10 20:20", "2026-03-10 20:24", "2026-03-10 20:28", "2026-03-10 20:32", "2026-03-10 20:36", "2026-03-10 20:40", "2026-03-10 20:44", "2026-03-10 20:48", "2026-03-10 20:52", "2026-03-10 20:56", "2026-03-10 21:00", "2026-03-10 21:04", "2026-03-10 21:08", "2026-03-10 21:12", "2026-03-10 21:16", "2026-03-10 21:20", "2026-03-10 21:24", "2026-03-10 21:28", "2026-03-10 21:32", "2026-03-10 21:36", "2026-03-10 21:40", "2026-03-10 21:44", "2026-03-10 21:48", "2026-03-10 21:52", "2026-03-10 21:56", "2026-03-10 22:00", "2026-03-10 22:04", "2026-03-10 22:08", "2026-03-10 22:12", "2026-03-10 22:16", "2026-03-10 22:20", "2026-03-10 22:24", "2026-03-10 22:28", "2026-03-10 22:32", "2026-03-10 22:36", "2026-03-10 22:40", "2026-03-10 22:44", "2026-03-10 22:48", "2026-03-10 22:52", "2026-03-10 22:56", "2026-03-10 23:00", "2026-03-10 23:04", "2026-03-10 23:08", "2026-03-10 23:12", "2026-03-10 23:16", "2026-03-10 23:20", "2026-03-10 23:24", "2026-03-10 23:28", "2026-03-10 23:32", "2026-03-10 23:36", "2026-03-10 23:40", "2026-03-10 23:44", "2026-03-10 23:48", "2026-03-10 23:52", "2026-03-10 23:56", "2026-03-11 00:00", "2026-03-11 00:04", "2026-03-11 00:08", "2026-03-11 00:12", "2026-03-11 00:16", "2026-03-11 00:20", "2026-03-11 00:24", "2026-03-11 00:28", "2026-03-11 00:32", "2026-03-11 00:36", "2026-03-11 00:40", "2026-03-11 00:44", "2026-03-11 00:48", "2026-03-11 00:52", "2026-03-11 00:56", "2026-03-11 01:00", "2026-03-11 01:04", "2026-03-11 01:08", "2026-03-11 01:12", "2026-03-11 01:16", "2026-03-11 01:20", "2026-03-11 01:24", "2026-03-11 01:28", "2026-03-11 01:32", "2026-03-11 01:36", "2026-03-11 01:40", "2026-03-11 01:44", "2026-03-11 01:48", "2026-03-11 01:52", "2026-03-11 01:56", "2026-03-11 02:00", "2026-03-11 02:04", "2026-03-11 02:08", "2026-03-11 02:12", "2026-03-11 02:16", "2026-03-11 02:20", "2026-03-11 02:24", "2026-03-11 02:28", "2026-03-11 02:32", "2026-03-11 02:36", "2026-03-11 02:40", "2026-03-11 02:44", "2026-03-11 02:48", "2026-03-11 02:52", "2026-03-11 02:56", "2026-03-11 03:00", "2026-03-11 03:04", "2026-03-11 03:08", "2026-03-11 03:12", "2026-03-11 03:16", "2026-03-11 03:20", "2026-03-11 03:24", "2026-03-11 03:28", "2026-03-11 03:32", "2026-03-11 03:36", "2026-03-11 03:40", "2026-03-11 03:44", "2026-03-11 03:48", "2026-03-11 03:52", "2026-03-11 03:56", "2026-03-11 04:00", "2026-03-11 04:04", "2026-03-11 04:08", "2026-03-11 04:12", "2026-03-11 04:16", "2026-03-11 04:20", "2026-03-11 04:24", "2026-03-11 04:28", "2026-03-11 04:32", "2026-03-11 04:36", "2026-03-11 04:40", "2026-03-11 04:44", "2026-03-11 04:48", "2026-03-11 04:52", "2026-03-11 04:56", "2026-03-11 05:00", "2026-03-11 05:04", "2026-03-11 05:08", "2026-03-11 05:12", "2026-03-11 05:16", "2026-03-11 05:20", "2026-03-11 05:24", "2026-03-11 05:28", "2026-03-11 05:32", "2026-03-11 05:36", "2026-03-11 05:40", "2026-03-11 05:44", "2026-03-11 05:48", "2026-03-11 05:52", "2026-03-11 05:56", "2026-03-11 06:00", "2026-03-11 06:04", "2026-03-11 06:08", "2026-03-11 06:12", "2026-03-11 06:16", "2026-03-11 06:20", "2026-03-11 06:24", "2026-03-11 06:28", "2026-03-11 06:32", "2026-03-11 06:36", "2026-03-11 06:40", "2026-03-11 06:44", "2026-03-11 06:48", "2026-03-11 06:52", "2026-03-11 06:56", "2026-03-11 07:00", "2026-03-11 07:04", "2026-03-11 07:08", "2026-03-11 07:12", "2026-03-11 07:16", "2026-03-11 07:20", "2026-03-11 07:24", "2026-03-11 07:28", "2026-03-11 07:32", "2026-03-11 07:36", "2026-03-11 07:40", "2026-03-11 07:44", "2026-03-11 07:48", "2026-03-11 07:52", "2026-03-11 07:56", "2026-03-11 08:00", "2026-03-11 08:04", "2026-03-11 08:08", "2026-03-11 08:12", "2026-03-11 08:16", "2026-03-11 08:20", "2026-03-11 08:24", "2026-03-11 08:28", "2026-03-11 08:32", "2026-03-11 08:36", "2026-03-11 08:40", "2026-03-11 08:44", "2026-03-11 08:48", "2026-03-11 08:52", "2026-03-11 08:56", "2026-03-11 09:00", "2026-03-11 09:04", "2026-03-11 09:08", "2026-03-11 09:12", "2026-03-11 09:16", "2026-03-11 09:20", "2026-03-11 09:24", "2026-03-11 09:28", "2026-03-11 09:32", "2026-03-11 09:36", "2026-03-11 09:40", "2026-03-11 09:44", "2026-03-11 09:48", "2026-03-11 09:52", "2026-03-11 09:56", "2026-03-11 10:00", "2026-03-11 10:04", "2026-03-11 10:08", "2026-03-11 10:12", "2026-03-11 10:16", "2026-03-11 10:20", "2026-03-11 10:24", "2026-03-11 10:28", "2026-03-11 10:32", "2026-03-11 10:36", "2026-03-11 10:40", "2026-03-11 10:44", "2026-03-11 10:48", "2026-03-11 10:52", "2026-03-11 10:56", "2026-03-11 11:00", "2026-03-11 11:04", "2026-03-11 11:08", "2026-03-11 11:12", "2026-03-11 11:16", "2026-03-11 11:20", "2026-03-11 11:24", "2026-03-11 11:28", "2026-03-11 11:32", "2026-03-11 11:36", "2026-03-11 11:40", "2026-03-11 11:44", "2026-03-11 11:48", "2026-03-11 11:52", "2026-03-11 11:56", "2026-03-11 12:00", "2026-03-11 12:04", "2026-03-11 12:08", "2026-03-11 12:12", "2026-03-11 12:16", "2026-03-11 12:20", "2026-03-11 12:24", "2026-03-11 12:28", "2026-03-11 12:32", "2026-03-11 12:36", "2026-03-11 12:40", "2026-03-11 12:44", "2026-03-11 12:48", "2026-03-11 12:52", "2026-03-11 12:56", "2026-03-11 13:00", "2026-03-11 13:04", "2026-03-11 13:08", "2026-03-11 13:12", "2026-03-11 13:16", "2026-03-11 13:20", "2026-03-11 13:24", "2026-03-11 13:28", "2026-03-11 13:32", "2026-03-11 13:36", "2026-03-11 13:40", "2026-03-11 13:44", "2026-03-11 13:48", "2026-03-11 13:52", "2026-03-11 13:56", "2026-03-11 14:00", "2026-03-11 14:04", "2026-03-11 14:08", "2026-03-11 14:12", "2026-03-11 14:16", "2026-03-11 14:20", "2026-03-11 14:24", "2026-03-11 14:28", "2026-03-11 14:32", "2026-03-11 14:36", "2026-03-11 14:40", "2026-03-11 14:44", "2026-03-11 14:48", "2026-03-11 14:52", "2026-03-11 14:56", "2026-03-11 15:00", "2026-03-11 15:04", "2026-03-11 15:08", "2026-03-11 15:12", "2026-03-11 15:16", "2026-03-11 15:20", "2026-03-11 15:24", "2026-03-11 15:28", "2026-03-11 15:32", "2026-03-11 15:36", "2026-03-11 15:40", "2026-03-11 15:44", "2026-03-11 15:48", "2026-03-11 15:52", "2026-03-11 15:56", "2026-03-11 16:00", "2026-03-11 16:04", "2026-03-11 16:08", "2026-03-11 16:12", "2026-03-11 16:16", "2026-03-11 16:20", "2026-03-11 16:24", "2026-03-11 16:28", "2026-03-11 16:32", "2026-03-11 16:36", "2026-03-11 16:40", "2026-03-11 16:44", "2026-03-11 16:48", "2026-03-11 16:52", "2026-03-11 16:56", "2026-03-11 17:00", "2026-03-11 17:04", "2026-03-11 17:08", "2026-03-11 17:12", "2026-03-11 17:16", "2026-03-11 17:20", "2026-03-11 17:24", "2026-03-11 17:28", "2026-03-11 17:32", "2026-03-11 17:36", "2026-03-11 17:40", "2026-03-11 17:44", "2026-03-11 17:48", "2026-03-11 17:52", "2026-03-11 17:56", "2026-03-11 18:00", "2026-03-11 18:04", "2026-03-11 18:08", "2026-03-11 18:12", "2026-03-11 18:16", "2026-03-11 18:20", "2026-03-11 18:24", "2026-03-11 18:28", "2026-03-11 18:32", "2026-03-11 18:36", "2026-03-11 18:40", "2026-03-11 18:44", "2026-03-11 18:48", "2026-03-11 18:52", "2026-03-11 18:56", "2026-03-11 19:00", "2026-03-11 19:04", "2026-03-11 19:08", "2026-03-11 19:12", "2026-03-11 19:16", "2026-03-11 19:20", "2026-03-11 19:24", "2026-03-11 19:28", "2026-03-11 19:32", "2026-03-11 19:36", "2026-03-11 19:40", "2026-03-11 19:44", "2026-03-11 19:48", "2026-03-11 19:52", "2026-03-11 19:56", "2026-03-11 20:00", "2026-03-11 20:04", "2026-03-11 20:08", "2026-03-11 20:12", "2026-03-11 20:16", "2026-03-11 20:20", "2026-03-11 20:24", "2026-03-11 20:28", "2026-03-11 20:32", "2026-03-11 20:36", "2026-03-11 20:40", "2026-03-11 20:44", "2026-03-11 20:48", "2026-03-11 20:52", "2026-03-11 20:56", "2026-03-11 21:00", "2026-03-11 21:04", "2026-03-11 21:08", "2026-03-11 21:12", "2026-03-11 21:16", "2026-03-11 21:20", "2026-03-11 21:24", "2026-03-11 21:28", "2026-03-11 21:32", "2026-03-11 21:36", "2026-03-11 21:40", "2026-03-11 21:44", "2026-03-11 21:48", "2026-03-11 21:52", "2026-03-11 21:56", "2026-03-11 22:00", "2026-03-11 22:04", "2026-03-11 22:08", "2026-03-11 22:12", "2026-03-11 22:16", "2026-03-11 22:20", "2026-03-11 22:24", "2026-03-11 22:28", "2026-03-11 22:32", "2026-03-11 22:36", "2026-03-11 22:40", "2026-03-11 22:44", "2026-03-11 22:48", "2026-03-11 22:52", "2026-03-11 22:56", "2026-03-11 23:00", "2026-03-11 23:04", "2026-03-11 23:08", "2026-03-11 23:12", "2026-03-11 23:16", "2026-03-11 23:20", "2026-03-11 23:24", "2026-03-11 23:28", "2026-03-11 23:32", "2026-03-11 23:36", "2026-03-11 23:40", "2026-03-11 23:44", "2026-03-11 23:48", "2026-03-11 23:52", "2026-03-11 23:56", "2026-03-12 00:00", "2026-03-12 00:04", "2026-03-12 00:08", "2026-03-12 00:12", "2026-03-12 00:16", "2026-03-12 00:20", "2026-03-12 00:24", "2026-03-12 00:28", "2026-03-12 00:32", "2026-03-12 00:36", "2026-03-12 00:40", "2026-03-12 00:44", "2026-03-12 00:48", "2026-03-12 00:52", "2026-03-12 00:56", "2026-03-12 01:00", "2026-03-12 01:04", "2026-03-12 01:08", "2026-03-12 01:12", "2026-03-12 01:16", "2026-03-12 01:20", "2026-03-12 01:24", "2026-03-12 01:28", "2026-03-12 01:32", "2026-03-12 01:36", "2026-03-12 01:40", "2026-03-12 01:44", "2026-03-12 01:48", "2026-03-12 01:52", "2026-03-12 01:56", "2026-03-12 02:00", "2026-03-12 02:04", "2026-03-12 02:08", "2026-03-12 02:12", "2026-03-12 02:16", "2026-03-12 02:20", "2026-03-12 02:24", "2026-03-12 02:28", "2026-03-12 02:32", "2026-03-12 02:36", "2026-03-12 02:40", "2026-03-12 02:44", "2026-03-12 02:48", "2026-03-12 02:52", "2026-03-12 02:56", "2026-03-12 03:00", "2026-03-12 03:04", "2026-03-12 03:08", "2026-03-12 03:12", "2026-03-12 03:16", "2026-03-12 03:20", "2026-03-12 03:24", "2026-03-12 03:28", "2026-03-12 03:32", "2026-03-12 03:36", "2026-03-12 03:40", "2026-03-12 03:44", "2026-03-12 03:48", "2026-03-12 03:52", "2026-03-12 03:56", "2026-03-12 04:00", "2026-03-12 04:04", "2026-03-12 04:08", "2026-03-12 04:12", "2026-03-12 04:16", "2026-03-12 04:20", "2026-03-12 04:24", "2026-03-12 04:28", "2026-03-12 04:32", "2026-03-12 04:36", "2026-03-12 04:40", "2026-03-12 04:44", "2026-03-12 04:48", "2026-03-12 04:52", "2026-03-12 04:56", "2026-03-12 05:00", "2026-03-12 05:04", "2026-03-12 05:08", "2026-03-12 05:12", "2026-03-12 05:16", "2026-03-12 05:20", "2026-03-12 05:24", "2026-03-12 05:28", "2026-03-12 05:32", "2026-03-12 05:36", "2026-03-12 05:40", "2026-03-12 05:44", "2026-03-12 05:48", "2026-03-12 05:52", "2026-03-12 05:56", "2026-03-12 06:00", "2026-03-12 06:04", "2026-03-12 06:08", "2026-03-12 06:12", "2026-03-12 06:16", "2026-03-12 06:20", "2026-03-12 06:24", "2026-03-12 06:28", "2026-03-12 06:32", "2026-03-12 06:36", "2026-03-12 06:40", "2026-03-12 06:44", "2026-03-12 06:48", "2026-03-12 06:52", "2026-03-12 06:56", "2026-03-12 07:00", "2026-03-12 07:04", "2026-03-12 07:08", "2026-03-12 07:12", "2026-03-12 07:16", "2026-03-12 07:20", "2026-03-12 07:24", "2026-03-12 07:28", "2026-03-12 07:32", "2026-03-12 07:36", "2026-03-12 07:40", "2026-03-12 07:44", "2026-03-12 07:48", "2026-03-12 07:52", "2026-03-12 07:56", "2026-03-12 08:00", "2026-03-12 08:04", "2026-03-12 08:08", "2026-03-12 08:12", "2026-03-12 08:16", "2026-03-12 08:20", "2026-03-12 08:24", "2026-03-12 08:28", "2026-03-12 08:32", "2026-03-12 08:36", "2026-03-12 08:40", "2026-03-12 08:44", "2026-03-12 08:48", "2026-03-12 08:52", "2026-03-12 08:56", "2026-03-12 09:00", "2026-03-12 09:04", "2026-03-12 09:08", "2026-03-12 09:12", "2026-03-12 09:16", "2026-03-12 09:20", "2026-03-12 09:24", "2026-03-12 09:28", "2026-03-12 09:32", "2026-03-12 09:36", "2026-03-12 09:40", "2026-03-12 09:44", "2026-03-12 09:48", "2026-03-12 09:52", "2026-03-12 09:56", "2026-03-12 10:00", "2026-03-12 10:04", "2026-03-12 10:08", "2026-03-12 10:12", "2026-03-12 10:16", "2026-03-12 10:20", "2026-03-12 10:24", "2026-03-12 10:28", "2026-03-12 10:32", "2026-03-12 10:36", "2026-03-12 10:40", "2026-03-12 10:44", "2026-03-12 10:48", "2026-03-12 10:52", "2026-03-12 10:56", "2026-03-12 11:00", "2026-03-12 11:04", "2026-03-12 11:08", "2026-03-12 11:12", "2026-03-12 11:16", "2026-03-12 11:20", "2026-03-12 11:24", "2026-03-12 11:28", "2026-03-12 11:32", "2026-03-12 11:36", "2026-03-12 11:40", "2026-03-12 11:44", "2026-03-12 11:48", "2026-03-12 11:52", "2026-03-12 11:56", "2026-03-12 12:00", "2026-03-12 12:04", "2026-03-12 12:08", "2026-03-12 12:12", "2026-03-12 12:16", "2026-03-12 12:20", "2026-03-12 12:24", "2026-03-12 12:28", "2026-03-12 12:32", "2026-03-12 12:36", "2026-03-12 12:40", "2026-03-12 12:44", "2026-03-12 12:48", "2026-03-12 12:52", "2026-03-12 12:56", "2026-03-12 13:00", "2026-03-12 13:04", "2026-03-12 13:08", "2026-03-12 13:12", "2026-03-12 13:16", "2026-03-12 13:20", "2026-03-12 13:24", "2026-03-12 13:28", "2026-03-12 13:32", "2026-03-12 13:36", "2026-03-12 13:40", "2026-03-12 13:44", "2026-03-12 13:48", "2026-03-12 13:52", "2026-03-12 13:56", "2026-03-12 14:00", "2026-03-12 14:04", "2026-03-12 14:08", "2026-03-12 14:12", "2026-03-12 14:16", "2026-03-12 14:20", "2026-03-12 14:24", "2026-03-12 14:28", "2026-03-12 14:32", "2026-03-12 14:36", "2026-03-12 14:40", "2026-03-12 14:44", "2026-03-12 14:48", "2026-03-12 14:52", "2026-03-12 14:56", "2026-03-12 15:00", "2026-03-12 15:04", "2026-03-12 15:08", "2026-03-12 15:12", "2026-03-12 15:16", "2026-03-12 15:20", "2026-03-12 15:24", "2026-03-12 15:28", "2026-03-12 15:32", "2026-03-12 15:36", "2026-03-12 15:40", "2026-03-12 15:44", "2026-03-12 15:48", "2026-03-12 15:52", "2026-03-12 15:56", "2026-03-12 16:00", "2026-03-12 16:04", "2026-03-12 16:08", "2026-03-12 16:12", "2026-03-12 16:16", "2026-03-12 16:20", "2026-03-12 16:24", "2026-03-12 16:28", "2026-03-12 16:32", "2026-03-12 16:36", "2026-03-12 16:40", "2026-03-12 16:44", "2026-03-12 16:48", "2026-03-12 16:52", "2026-03-12 16:56", "2026-03-12 17:00", "2026-03-12 17:04", "2026-03-12 17:08", "2026-03-12 17:12", "2026-03-12 17:16", "2026-03-12 17:20", "2026-03-12 17:24", "2026-03-12 17:28", "2026-03-12 17:32", "2026-03-12 17:36", "2026-03-12 17:40", "2026-03-12 17:44", "2026-03-12 17:48", "2026-03-12 17:52", "2026-03-12 17:56", "2026-03-12 18:00", "2026-03-12 18:04", "2026-03-12 18:08", "2026-03-12 18:12", "2026-03-12 18:16", "2026-03-12 18:20", "2026-03-12 18:24", "2026-03-12 18:28", "2026-03-12 18:32", "2026-03-12 18:36", "2026-03-12 18:40", "2026-03-12 18:44", "2026-03-12 18:48", "2026-03-12 18:52", "2026-03-12 18:56", "2026-03-12 19:00", "2026-03-12 19:04", "2026-03-12 19:08", "2026-03-12 19:12", "2026-03-12 19:16", "2026-03-12 19:20", "2026-03-12 19:24", "2026-03-12 19:28", "2026-03-12 19:32", "2026-03-12 19:36", "2026-03-12 19:40", "2026-03-12 19:44", "2026-03-12 19:48", "2026-03-12 19:52", "2026-03-12 19:56", "2026-03-12 20:00", "2026-03-12 20:04", "2026-03-12 20:08", "2026-03-12 20:12", "2026-03-12 20:16", "2026-03-12 20:20", "2026-03-12 20:24", "2026-03-12 20:28", "2026-03-12 20:32", "2026-03-12 20:36", "2026-03-12 20:40", "2026-03-12 20:44", "2026-03-12 20:48", "2026-03-12 20:52", "2026-03-12 20:56", "2026-03-12 21:00", "2026-03-12 21:04", "2026-03-12 21:08", "2026-03-12 21:12", "2026-03-12 21:16", "2026-03-12 21:20", "2026-03-12 21:24", "2026-03-12 21:28", "2026-03-12 21:32", "2026-03-12 21:36", "2026-03-12 21:40", "2026-03-12 21:44", "2026-03-12 21:48", "2026-03-12 21:52", "2026-03-12 21:56", "2026-03-12 22:00", "2026-03-12 22:04", "2026-03-12 22:08", "2026-03-12 22:12", "2026-03-12 22:16", "2026-03-12 22:20", "2026-03-12 22:24", "2026-03-12 22:28", "2026-03-12 22:32", "2026-03-12 22:36", "2026-03-12 22:40", "2026-03-12 22:44", "2026-03-12 22:48", "2026-03-12 22:52", "2026-03-12 22:56", "2026-03-12 23:00", "2026-03-12 23:04", "2026-03-12 23:08", "2026-03-12 23:12", "2026-03-12 23:16", "2026-03-12 23:20", "2026-03-12 23:24", "2026-03-12 23:28", "2026-03-12 23:32", "2026-03-12 23:36", "2026-03-12 23:40", "2026-03-12 23:44", "2026-03-12 23:48", "2026-03-12 23:52", "2026-03-12 23:56", "2026-03-13 00:00", "2026-03-13 00:04", "2026-03-13 00:08", "2026-03-13 00:12", "2026-03-13 00:16", "2026-03-13 00:20", "2026-03-13 00:24", "2026-03-13 00:28", "2026-03-13 00:32", "2026-03-13 00:36", "2026-03-13 00:40", "2026-03-13 00:44", "2026-03-13 00:48", "2026-03-13 00:52", "2026-03-13 00:56", "2026-03-13 01:00", "2026-03-13 01:04", "2026-03-13 01:08", "2026-03-13 01:12", "2026-03-13 01:16", "2026-03-13 01:20", "2026-03-13 01:24", "2026-03-13 01:28", "2026-03-13 01:32", "2026-03-13 01:36", "2026-03-13 01:40", "2026-03-13 01:44", "2026-03-13 01:48", "2026-03-13 01:52", "2026-03-13 01:56", "2026-03-13 02:00", "2026-03-13 02:04", "2026-03-13 02:08", "2026-03-13 02:12", "2026-03-13 02:16", "2026-03-13 02:20", "2026-03-13 02:24", "2026-03-13 02:28", "2026-03-13 02:32", "2026-03-13 02:36", "2026-03-13 02:40", "2026-03-13 02:44", "2026-03-13 02:48", "2026-03-13 02:52", "2026-03-13 02:56", "2026-03-13 03:00", "2026-03-13 03:04", "2026-03-13 03:08", "2026-03-13 03:12", "2026-03-13 03:16", "2026-03-13 03:20", "2026-03-13 03:24", "2026-03-13 03:28", "2026-03-13 03:32", "2026-03-13 03:36", "2026-03-13 03:40", "2026-03-13 03:44", "2026-03-13 03:48", "2026-03-13 03:52", "2026-03-13 03:56", "2026-03-13 04:00", "2026-03-13 04:04", "2026-03-13 04:08", "2026-03-13 04:12", "2026-03-13 04:16", "2026-03-13 04:20", "2026-03-13 04:24", "2026-03-13 04:28", "2026-03-13 04:32", "2026-03-13 04:36", "2026-03-13 04:40", "2026-03-13 04:44", "2026-03-13 04:48", "2026-03-13 04:52", "2026-03-13 04:56", "2026-03-13 05:00", "2026-03-13 05:04", "2026-03-13 05:08", "2026-03-13 05:12", "2026-03-13 05:16", "2026-03-13 05:20", "2026-03-13 05:24", "2026-03-13 05:28", "2026-03-13 05:32", "2026-03-13 05:36", "2026-03-13 05:40", "2026-03-13 05:44", "2026-03-13 05:48", "2026-03-13 05:52", "2026-03-13 05:56", "2026-03-13 06:00", "2026-03-13 06:04", "2026-03-13 06:08", "2026-03-13 06:12", "2026-03-13 06:16", "2026-03-13 06:20", "2026-03-13 06:24", "2026-03-13 06:28", "2026-03-13 06:32", "2026-03-13 06:36", "2026-03-13 06:40", "2026-03-13 06:44", "2026-03-13 06:48", "2026-03-13 06:52", "2026-03-13 06:56", "2026-03-13 07:00", "2026-03-13 07:04", "2026-03-13 07:08", "2026-03-13 07:12", "2026-03-13 07:16", "2026-03-13 07:20", "2026-03-13 07:24", "2026-03-13 07:28", "2026-03-13 07:32", "2026-03-13 07:36", "2026-03-13 07:40", "2026-03-13 07:44", "2026-03-13 07:48", "2026-03-13 07:52", "2026-03-13 07:56", "2026-03-13 08:00", "2026-03-13 08:04", "2026-03-13 08:08", "2026-03-13 08:12", "2026-03-13 08:16", "2026-03-13 08:20", "2026-03-13 08:24", "2026-03-13 08:28", "2026-03-13 08:32", "2026-03-13 08:36", "2026-03-13 08:40", "2026-03-13 08:44", "2026-03-13 08:48", "2026-03-13 08:52", "2026-03-13 08:56", "2026-03-13 09:00", "2026-03-13 09:04", "2026-03-13 09:08", "2026-03-13 09:12", "2026-03-13 09:16", "2026-03-13 09:20", "2026-03-13 09:24", "2026-03-13 09:28", "2026-03-13 09:32", "2026-03-13 09:36", "2026-03-13 09:40", "2026-03-13 09:44", "2026-03-13 09:48", "2026-03-13 09:52", "2026-03-13 09:56", "2026-03-13 10:00", "2026-03-13 10:04", "2026-03-13 10:08", "2026-03-13 10:12", "2026-03-13 10:16", "2026-03-13 10:20", "2026-03-13 10:24", "2026-03-13 10:28", "2026-03-13 10:32", "2026-03-13 10:36", "2026-03-13 10:40", "2026-03-13 10:44", "2026-03-13 10:48", "2026-03-13 10:52", "2026-03-13 10:56", "2026-03-13 11:00", "2026-03-13 11:04", "2026-03-13 11:08", "2026-03-13 11:12", "2026-03-13 11:16", "2026-03-13 11:20", "2026-03-13 11:24", "2026-03-13 11:28", "2026-03-13 11:32", "2026-03-13 11:36", "2026-03-13 11:40", "2026-03-13 11:44", "2026-03-13 11:48", "2026-03-13 11:52", "2026-03-13 11:56", "2026-03-13 12:00", "2026-03-13 12:04", "2026-03-13 12:08", "2026-03-13 12:12", "2026-03-13 12:16", "2026-03-13 12:20", "2026-03-13 12:24", "2026-03-13 12:28", "2026-03-13 12:32", "2026-03-13 12:36", "2026-03-13 12:40", "2026-03-13 12:44", "2026-03-13 12:48", "2026-03-13 12:52", "2026-03-13 12:56", "2026-03-13 13:00", "2026-03-13 13:04", "2026-03-13 13:08", "2026-03-13 13:12", "2026-03-13 13:16", "2026-03-13 13:20", "2026-03-13 13:24", "2026-03-13 13:28", "2026-03-13 13:32", "2026-03-13 13:36", "2026-03-13 13:40", "2026-03-13 13:44", "2026-03-13 13:48", "2026-03-13 13:52", "2026-03-13 13:56", "2026-03-13 14:00", "2026-03-13 14:04", "2026-03-13 14:08", "2026-03-13 14:12", "2026-03-13 14:16", "2026-03-13 14:20", "2026-03-13 14:24", "2026-03-13 14:28", "2026-03-13 14:32", "2026-03-13 14:36", "2026-03-13 14:40", "2026-03-13 14:44", "2026-03-13 14:48", "2026-03-13 14:52", "2026-03-13 14:56", "2026-03-13 15:00", "2026-03-13 15:04", "2026-03-13 15:08", "2026-03-13 15:12", "2026-03-13 15:16", "2026-03-13 15:20", "2026-03-13 15:24", "2026-03-13 15:28", "2026-03-13 15:32", "2026-03-13 15:36", "2026-03-13 15:40", "2026-03-13 15:44", "2026-03-13 15:48", "2026-03-13 15:52", "2026-03-13 15:56", "2026-03-13 16:00", "2026-03-13 16:04", "2026-03-13 16:08", "2026-03-13 16:12", "2026-03-13 16:16", "2026-03-13 16:20", "2026-03-13 16:24", "2026-03-13 16:28", "2026-03-13 16:32", "2026-03-13 16:36", "2026-03-13 16:40", "2026-03-13 16:44", "2026-03-13 16:48", "2026-03-13 16:52", "2026-03-13 16:56", "2026-03-13 17:00", "2026-03-13 17:04", "2026-03-13 17:08", "2026-03-13 17:12", "2026-03-13 17:16", "2026-03-13 17:20", "2026-03-13 17:24", "2026-03-13 17:28", "2026-03-13 17:32", "2026-03-13 17:36", "2026-03-13 17:40", "2026-03-13 17:44", "2026-03-13 17:48", "2026-03-13 17:52", "2026-03-13 17:56", "2026-03-13 18:00", "2026-03-13 18:04", "2026-03-13 18:08", "2026-03-13 18:12", "2026-03-13 18:16", "2026-03-13 18:20", "2026-03-13 18:24", "2026-03-13 18:28", "2026-03-13 18:32", "2026-03-13 18:36", "2026-03-13 18:40", "2026-03-13 18:44", "2026-03-13 18:48", "2026-03-13 18:52", "2026-03-13 18:56", "2026-03-13 19:00", "2026-03-13 19:04", "2026-03-13 19:08", "2026-03-13 19:12", "2026-03-13 19:16", "2026-03-13 19:20", "2026-03-13 19:24", "2026-03-13 19:28", "2026-03-13 19:32", "2026-03-13 19:36", "2026-03-13 19:40", "2026-03-13 19:44", "2026-03-13 19:48", "2026-03-13 19:52", "2026-03-13 19:56", "2026-03-13 20:00", "2026-03-13 20:04", "2026-03-13 20:08", "2026-03-13 20:12", "2026-03-13 20:16", "2026-03-13 20:20", "2026-03-13 20:24", "2026-03-13 20:28", "2026-03-13 20:32", "2026-03-13 20:36", "2026-03-13 20:40", "2026-03-13 20:44", "2026-03-13 20:48", "2026-03-13 20:52", "2026-03-13 20:56", "2026-03-13 21:00", "2026-03-13 21:04", "2026-03-13 21:08", "2026-03-13 21:12", "2026-03-13 21:16", "2026-03-13 21:20", "2026-03-13 21:24", "2026-03-13 21:28", "2026-03-13 21:32", "2026-03-13 21:36", "2026-03-13 21:40", "2026-03-13 21:44", "2026-03-13 21:48", "2026-03-13 21:52", "2026-03-13 21:56", "2026-03-13 22:00", "2026-03-13 22:04", "2026-03-13 22:08", "2026-03-13 22:12", "2026-03-13 22:16", "2026-03-13 22:20", "2026-03-13 22:24", "2026-03-13 22:28", "2026-03-13 22:32", "2026-03-13 22:36", "2026-03-13 22:40", "2026-03-13 22:44", "2026-03-13 22:48", "2026-03-13 22:52", "2026-03-13 22:56", "2026-03-13 23:00", "2026-03-13 23:04", "2026-03-13 23:08", "2026-03-13 23:12", "2026-03-13 23:16", "2026-03-13 23:20", "2026-03-13 23:24", "2026-03-13 23:28", "2026-03-13 23:32", "2026-03-13 23:36", "2026-03-13 23:40", "2026-03-13 23:44", "2026-03-13 23:48", "2026-03-13 23:52", "2026-03-13 23:56", "2026-03-14 00:00", "2026-03-14 00:04", "2026-03-14 00:08", "2026-03-14 00:12", "2026-03-14 00:16", "2026-03-14 00:20", "2026-03-14 00:24", "2026-03-14 00:28", "2026-03-14 00:32", "2026-03-14 00:36", "2026-03-14 00:40", "2026-03-14 00:44", "2026-03-14 00:48", "2026-03-14 00:52", "2026-03-14 00:56", "2026-03-14 01:00", "2026-03-14 01:04", "2026-03-14 01:08", "2026-03-14 01:12", "2026-03-14 01:16", "2026-03-14 01:20", "2026-03-14 01:24", "2026-03-14 01:28", "2026-03-14 01:32", "2026-03-14 01:36", "2026-03-14 01:40", "2026-03-14 01:44", "2026-03-14 01:48", "2026-03-14 01:52", "2026-03-14 01:56", "2026-03-14 02:00", "2026-03-14 02:04", "2026-03-14 02:08", "2026-03-14 02:12", "2026-03-14 02:16", "2026-03-14 02:20", "2026-03-14 02:24", "2026-03-14 02:28", "2026-03-14 02:32", "2026-03-14 02:36", "2026-03-14 02:40", "2026-03-14 02:44", "2026-03-14 02:48", "2026-03-14 02:52", "2026-03-14 02:56", "2026-03-14 03:00", "2026-03-14 03:04", "2026-03-14 03:08", "2026-03-14 03:12", "2026-03-14 03:16", "2026-03-14 03:20", "2026-03-14 03:24", "2026-03-14 03:28", "2026-03-14 03:32", "2026-03-14 03:36", "2026-03-14 03:40", "2026-03-14 03:44", "2026-03-14 03:48", "2026-03-14 03:52", "2026-03-14 03:56", "2026-03-14 04:00", "2026-03-14 04:04", "2026-03-14 04:08", "2026-03-14 04:12", "2026-03-14 04:16", "2026-03-14 04:20", "2026-03-14 04:24", "2026-03-14 04:28", "2026-03-14 04:32", "2026-03-14 04:36", "2026-03-14 04:40", "2026-03-14 04:44", "2026-03-14 04:48", "2026-03-14 04:52", "2026-03-14 04:56", "2026-03-14 05:00", "2026-03-14 05:04", "2026-03-14 05:08", "2026-03-14 05:12", "2026-03-14 05:16", "2026-03-14 05:20", "2026-03-14 05:24", "2026-03-14 05:28", "2026-03-14 05:32", "2026-03-14 05:36", "2026-03-14 05:40", "2026-03-14 05:44", "2026-03-14 05:48", "2026-03-14 05:52", "2026-03-14 05:56", "2026-03-14 06:00", "2026-03-14 06:04", "2026-03-14 06:08", "2026-03-14 06:12", "2026-03-14 06:16", "2026-03-14 06:20", "2026-03-14 06:24", "2026-03-14 06:28", "2026-03-14 06:32", "2026-03-14 06:36", "2026-03-14 06:40", "2026-03-14 06:44", "2026-03-14 06:48", "2026-03-14 06:52", "2026-03-14 06:56", "2026-03-14 07:00", "2026-03-14 07:04", "2026-03-14 07:08", "2026-03-14 07:12", "2026-03-14 07:16", "2026-03-14 07:20", "2026-03-14 07:24", "2026-03-14 07:28", "2026-03-14 07:32", "2026-03-14 07:36", "2026-03-14 07:40", "2026-03-14 07:44", "2026-03-14 07:48", "2026-03-14 07:52", "2026-03-14 07:56", "2026-03-14 08:00", "2026-03-14 08:04", "2026-03-14 08:08", "2026-03-14 08:12", "2026-03-14 08:16", "2026-03-14 08:20", "2026-03-14 08:24", "2026-03-14 08:28", "2026-03-14 08:32", "2026-03-14 08:36", "2026-03-14 08:40", "2026-03-14 08:44", "2026-03-14 08:48", "2026-03-14 08:52", "2026-03-14 08:56", "2026-03-14 09:00", "2026-03-14 09:04", "2026-03-14 09:08", "2026-03-14 09:12", "2026-03-14 09:16", "2026-03-14 09:20", "2026-03-14 09:24", "2026-03-14 09:28", "2026-03-14 09:32", "2026-03-14 09:36", "2026-03-14 09:40", "2026-03-14 09:44", "2026-03-14 09:48", "2026-03-14 09:52", "2026-03-14 09:56", "2026-03-14 10:00", "2026-03-14 10:04", "2026-03-14 10:08", "2026-03-14 10:12", "2026-03-14 10:16", "2026-03-14 10:20", "2026-03-14 10:24", "2026-03-14 10:28", "2026-03-14 10:32", "2026-03-14 10:36", "2026-03-14 10:40", "2026-03-14 10:44", "2026-03-14 10:48", "2026-03-14 10:52", "2026-03-14 10:56", "2026-03-14 11:00", "2026-03-14 11:04", "2026-03-14 11:08", "2026-03-14 11:12", "2026-03-14 11:16", "2026-03-14 11:20", "2026-03-14 11:24", "2026-03-14 11:28", "2026-03-14 11:32", "2026-03-14 11:36", "2026-03-14 11:40", "2026-03-14 11:44", "2026-03-14 11:48", "2026-03-14 11:52", "2026-03-14 11:56", "2026-03-14 12:00", "2026-03-14 12:04", "2026-03-14 12:08", "2026-03-14 12:12", "2026-03-14 12:16", "2026-03-14 12:20", "2026-03-14 12:24", "2026-03-14 12:28", "2026-03-14 12:32", "2026-03-14 12:36", "2026-03-14 12:40", "2026-03-14 12:44", "2026-03-14 12:48", "2026-03-14 12:52", "2026-03-14 12:56", "2026-03-14 13:00", "2026-03-14 13:04", "2026-03-14 13:08", "2026-03-14 13:12", "2026-03-14 13:16", "2026-03-14 13:20", "2026-03-14 13:24", "2026-03-14 13:28", "2026-03-14 13:32", "2026-03-14 13:36", "2026-03-14 13:40", "2026-03-14 13:44", "2026-03-14 13:48", "2026-03-14 13:52", "2026-03-14 13:56", "2026-03-14 14:00", "2026-03-14 14:04", "2026-03-14 14:08", "2026-03-14 14:12", "2026-03-14 14:16", "2026-03-14 14:20", "2026-03-14 14:24", "2026-03-14 14:28", "2026-03-14 14:32", "2026-03-14 14:36", "2026-03-14 14:40", "2026-03-14 14:44", "2026-03-14 14:48", "2026-03-14 14:52", "2026-03-14 14:56", "2026-03-14 15:00", "2026-03-14 15:04", "2026-03-14 15:08", "2026-03-14 15:12", "2026-03-14 15:16", "2026-03-14 15:20", "2026-03-14 15:24", "2026-03-14 15:28", "2026-03-14 15:32", "2026-03-14 15:36", "2026-03-14 15:40", "2026-03-14 15:44", "2026-03-14 15:48", "2026-03-14 15:52", "2026-03-14 15:56", "2026-03-14 16:00", "2026-03-14 16:04", "2026-03-14 16:08", "2026-03-14 16:12", "2026-03-14 16:16", "2026-03-14 16:20", "2026-03-14 16:24", "2026-03-14 16:28", "2026-03-14 16:32", "2026-03-14 16:36", "2026-03-14 16:40", "2026-03-14 16:44", "2026-03-14 16:48", "2026-03-14 16:52", "2026-03-14 16:56", "2026-03-14 17:00", "2026-03-14 17:04", "2026-03-14 17:08", "2026-03-14 17:12", "2026-03-14 17:16", "2026-03-14 17:20", "2026-03-14 17:24", "2026-03-14 17:28", "2026-03-14 17:32", "2026-03-14 17:36", "2026-03-14 17:40", "2026-03-14 17:44", "2026-03-14 17:48", "2026-03-14 17:52", "2026-03-14 17:56", "2026-03-14 18:00", "2026-03-14 18:04", "2026-03-14 18:08", "2026-03-14 18:12", "2026-03-14 18:16", "2026-03-14 18:20", "2026-03-14 18:24", "2026-03-14 18:28", "2026-03-14 18:32", "2026-03-14 18:36", "2026-03-14 18:40", "2026-03-14 18:44", "2026-03-14 18:48", "2026-03-14 18:52", "2026-03-14 18:56", "2026-03-14 19:00", "2026-03-14 19:04", "2026-03-14 19:08", "2026-03-14 19:12", "2026-03-14 19:16", "2026-03-14 19:20", "2026-03-14 19:24", "2026-03-14 19:28", "2026-03-14 19:32", "2026-03-14 19:36", "2026-03-14 19:40", "2026-03-14 19:44", "2026-03-14 19:48", "2026-03-14 19:52", "2026-03-14 19:56", "2026-03-14 20:00", "2026-03-14 20:04", "2026-03-14 20:08", "2026-03-14 20:12", "2026-03-14 20:16", "2026-03-14 20:20", "2026-03-14 20:24", "2026-03-14 20:28", "2026-03-14 20:32", "2026-03-14 20:36", "2026-03-14 20:40", "2026-03-14 20:44", "2026-03-14 20:48", "2026-03-14 20:52", "2026-03-14 20:56", "2026-03-14 21:00", "2026-03-14 21:04", "2026-03-14 21:08", "2026-03-14 21:12", "2026-03-14 21:16", "2026-03-14 21:20", "2026-03-14 21:24", "2026-03-14 21:28", "2026-03-14 21:32", "2026-03-14 21:36", "2026-03-14 21:40", "2026-03-14 21:44", "2026-03-14 21:48", "2026-03-14 21:52", "2026-03-14 21:56", "2026-03-14 22:00", "2026-03-14 22:04", "2026-03-14 22:08", "2026-03-14 22:12", "2026-03-14 22:16", "2026-03-14 22:20", "2026-03-14 22:24", "2026-03-14 22:28", "2026-03-14 22:32", "2026-03-14 22:36", "2026-03-14 22:40", "2026-03-14 22:44", "2026-03-14 22:48", "2026-03-14 22:52", "2026-03-14 22:56", "2026-03-14 23:00", "2026-03-14 23:04", "2026-03-14 23:08", "2026-03-14 23:12", "2026-03-14 23:16", "2026-03-14 23:20", "2026-03-14 23:24", "2026-03-14 23:28", "2026-03-14 23:32", "2026-03-14 23:36", "2026-03-14 23:40", "2026-03-14 23:44", "2026-03-14 23:48", "2026-03-14 23:52", "2026-03-14 23:56"], "y": [49.91, 49.81, 49.75, 50.17, 50.09, 49.19, 49.41, 49.26, 49.15, 49.23, 49.39, 50.1, 50.49, 50.55, 50.09, 49.48, 49.64, 50.43, 50.45, 50.38, 50.69, 49.8, 49.62, 49.92, 50.45, 50.29, 50.51, 50.65, 51.11, 50.42, 50.75, 49.83, 48.26, 47.93, 47.42, 48.0, 48.44, 47.74, 48.29, 47.72, 47.72, 47.59, 47.7, 48.24, 48.66, 48.9, 49.31, 49.61, 49.24, 48.83, 48.57, 48.89, 48.77, 50.19, 49.7, 49.04, 49.52, 50.39, 50.68, 51.17, 52.0, 51.91, 51.01, 50.68, 51.23, 50.34, 50.36, 50.5, 50.3, 50.73, 51.06, 52.43, 52.76, 52.34, 51.95, 51.42, 51.96, 51.58, 51.51, 51.92, 51.45, 51.25, 50.12, 49.47, 49.14, 49.4, 50.13, 50.12, 50.27, 50.37, 51.01, 51.53, 51.66, 51.02, 51.54, 51.74, 52.44, 52.37, 53.5, 53.21, 54.1, 54.09, 53.7, 52.95, 52.8, 53.6, 54.02, 54.35, 52.84, 53.21, 53.47, 53.08, 52.64, 52.58, 53.57, 52.86, 52.55, 53.31, 52.98, 52.7, 52.71, 51.91, 52.0, 51.24, 51.74, 51.71, 53.05, 53.15, 53.91, 53.05, 52.91, 53.05, 54.04, 52.95, 53.48, 53.77, 54.61, 54.95, 54.88, 54.47, 53.63, 53.68, 53.49, 54.63, 54.17, 54.28, 53.25, 52.95, 53.05, 53.48, 54.28, 54.17, 53.41, 53.62, 53.86, 54.08, 53.58, 54.18, 54.15, 54.49, 55.16, 55.43, 55.49, 56.67, 56.68, 56.37, 56.31, 57.08, 57.01, 57.18, 57.75, 57.29, 56.11, 56.16, 56.18, 55.69, 56.1, 56.34, 55.62, 55.82, 55.58, 54.58, 54.76, 54.64, 54.1, 54.33, 54.54, 54.1, 54.26, 54.78, 54.26, 54.4, 54.32, 55.59, 54.36, 54.69, 54.41, 54.26, 55.32, 55.21, 56.45, 56.05, 56.14, 55.73, 55.2, 55.13, 54.86, 54.88, 53.52, 54.65, 54.46, 55.42, 54.7, 54.79, 56.59, 55.93, 54.92, 54.49, 54.69, 55.01, 55.68, 55.41, 54.35, 54.0, 54.66, 54.85, 53.58, 53.48, 54.25, 55.44, 55.67, 55.74, 54.89, 54.28, 54.22, 54.44, 54.7, 54.32, 53.54, 53.0, 52.25, 52.59, 51.15, 50.93, 51.18, 52.07, 52.07, 52.63, 52.34, 51.85, 51.4, 52.29, 52.84, 53.08, 55.02, 54.9, 55.17, 55.25, 55.01, 56.3, 57.08, 56.1, 55.74, 55.88, 56.23, 55.3, 53.84, 52.62, 52.52, 52.41, 52.57, 52.06, 51.28, 50.04, 50.24, 50.46, 51.04, 51.5, 51.35, 52.13, 52.01, 51.57, 51.23, 50.85, 49.54, 49.64, 49.8, 49.58, 49.16, 49.4, 50.45, 50.46, 50.15, 49.79, 49.75, 49.0, 48.94, 49.0, 50.13, 50.69, 51.3, 50.84, 51.23, 50.52, 50.7, 50.93, 50.46, 51.65, 51.95, 50.77, 51.09, 50.82, 50.81, 51.07, 51.28, 50.03, 49.34, 49.82, 50.6, 51.73, 52.78, 51.49, 51.92, 50.73, 51.69, 51.8, 51.08, 52.27, 52.61, 51.42, 51.57, 51.1, 51.14, 50.84, 51.65, 50.76, 50.94, 52.01, 51.47, 51.57, 51.66, 51.21, 51.57, 51.6, 51.0, 52.04, 52.47, 52.32, 51.9, 51.39, 52.1, 51.97, 52.21, 52.05, 52.38, 52.26, 52.68, 52.51, 52.96, 53.3, 53.17, 52.59, 51.97, 51.49, 50.87, 51.37, 51.31, 52.23, 53.55, 53.5, 52.5, 52.22, 52.13, 51.19, 51.02, 51.17, 50.87, 50.39, 49.93, 51.0, 50.89, 50.37, 50.14, 50.71, 50.29, 50.57, 51.0, 51.42, 52.24, 51.86, 52.5, 51.98, 51.7, 52.38, 52.83, 52.77, 52.0, 52.3, 51.88, 51.28, 50.87, 51.0, 49.71, 49.93, 50.04, 49.68, 50.31, 50.67, 50.3, 49.89, 50.31, 49.39, 49.2, 48.84, 48.91, 49.06, 49.1, 49.8, 49.94, 49.75, 49.03, 49.48, 49.81, 50.68, 50.22, 50.23, 50.19, 50.13, 50.14, 49.11, 49.62, 50.02, 50.7, 52.03, 51.8, 51.74, 51.71, 52.84, 51.75, 52.01, 51.08, 49.51, 48.31, 47.51, 48.21, 47.72, 47.63, 46.98, 47.41, 46.8, 47.65, 47.1, 46.7, 46.84, 46.92, 47.84, 47.95, 47.27, 46.99, 46.7, 47.2, 47.49, 47.47, 48.04, 47.76, 47.73, 47.88, 48.84, 48.8, 48.62, 48.02, 48.47, 48.15, 48.39, 47.28, 47.96, 47.2, 46.79, 47.49, 46.74, 46.76, 46.87, 46.33, 47.21, 48.17, 47.02, 46.21, 46.77, 46.05, 45.9, 46.06, 46.55, 46.49, 46.61, 46.22, 47.07, 46.83, 47.1, 46.85, 46.97, 46.93, 46.9, 46.35, 46.9, 47.81, 48.0, 48.48, 49.01, 49.59, 49.78, 49.91, 50.43, 50.47, 49.87, 49.89, 48.76, 48.78, 49.05, 49.81, 49.91, 50.47, 50.46, 49.83, 48.99, 48.43, 47.64, 48.07, 47.98, 48.36, 48.44, 49.1, 49.75, 49.37, 49.22, 48.91, 47.96, 48.41, 49.15, 49.17, 48.89, 49.56, 48.17, 48.31, 48.43, 48.12, 48.99, 49.59, 49.44, 49.4, 49.18, 48.89, 48.13, 48.99, 49.63, 50.12, 49.46, 50.72, 51.89, 51.97, 51.39, 50.84, 51.07, 50.5, 50.47, 51.12, 50.19, 51.39, 52.3, 51.51, 50.63, 50.45, 49.82, 49.67, 48.13, 48.03, 49.15, 48.5, 48.36, 47.5, 47.93, 47.84, 49.05, 49.19, 48.98, 49.33, 49.04, 48.26, 48.48, 48.4, 48.53, 48.79, 48.51, 48.79, 49.86, 49.19, 50.25, 50.1, 49.64, 51.1, 51.17, 51.97, 52.42, 51.37, 51.41, 51.07, 50.24, 49.17, 49.25, 49.62, 49.86, 49.68, 49.21, 48.63, 48.33, 47.74, 47.66, 47.7, 47.21, 47.12, 46.72, 46.79, 47.16, 47.32, 47.66, 46.71, 46.55, 46.79, 47.23, 46.33, 46.5, 47.29, 47.24, 47.24, 47.56, 47.76, 48.21, 48.29, 48.42, 47.98, 47.92, 48.71, 48.61, 48.54, 48.27, 48.78, 48.29, 48.87, 48.33, 47.73, 47.9, 48.02, 48.24, 48.91, 48.69, 48.98, 48.45, 49.24, 49.63, 49.96, 50.08, 49.6, 49.41, 49.73, 49.72, 49.8, 48.99, 49.12, 48.72, 48.1, 48.04, 46.97, 47.45, 48.01, 48.02, 47.46, 46.94, 46.91, 45.52, 45.72, 46.2, 46.09, 45.87, 46.07, 46.35, 47.08, 47.15, 46.8, 46.58, 46.76, 47.76, 47.61, 47.03, 46.57, 45.38, 45.67, 44.94, 44.3, 43.23, 42.69, 43.18, 42.53, 41.63, 41.9, 41.86, 42.28, 42.88, 43.02, 42.38, 42.46, 42.91, 42.7, 41.98, 42.81, 42.7, 42.6, 42.76, 43.52, 43.81, 43.73, 44.27, 45.67, 46.59, 47.06, 46.45, 48.77, 48.07, 47.89, 47.51, 48.54, 48.82, 47.99, 48.19, 48.55, 48.39, 47.69, 47.3, 47.09, 47.16, 46.91, 47.41, 46.89, 45.92, 45.56, 46.45, 46.18, 47.66, 48.0, 47.34, 46.9, 47.11, 46.46, 47.95, 47.4, 47.86, 48.78, 48.74, 48.16, 48.04, 48.29, 48.85, 48.91, 48.09, 48.16, 47.79, 46.52, 46.17, 45.39, 45.84, 47.09, 48.26, 47.95, 47.71, 48.17, 48.84, 48.61, 48.56, 49.91, 49.85, 49.56, 49.64, 49.99, 49.38, 49.25, 48.56, 48.42, 49.58, 50.03, 49.98, 49.42, 49.24, 49.89, 49.55, 50.43, 49.6, 49.43, 50.49, 49.28, 50.0, 48.89, 48.86, 48.78, 49.3, 47.42, 46.32, 46.06, 46.16, 45.7, 45.65, 45.03, 44.88, 44.48, 44.74, 45.19, 46.15, 45.83, 45.72, 45.84, 45.74, 45.8, 44.94, 45.27, 44.81, 44.34, 43.5, 44.33, 44.36, 45.16, 45.42, 44.49, 43.95, 44.53, 44.18, 43.64, 43.66, 43.68, 43.2, 43.14, 42.99, 41.57, 42.04, 41.72, 42.67, 42.12, 41.33, 42.22, 41.42, 41.21, 41.75, 41.71, 40.89, 41.18, 41.24, 42.19, 42.7, 44.66, 43.78, 43.89, 43.38, 44.2, 44.81, 45.37, 44.99, 44.65, 43.54, 44.69, 45.1, 45.04, 45.7, 46.24, 46.9, 45.99, 45.64, 45.84, 46.14, 46.79, 46.25, 46.4, 47.8, 48.26, 48.81, 48.83, 49.31, 50.41, 50.46, 51.19, 50.64, 50.98, 51.5, 51.02, 51.66, 51.22, 50.71, 50.7, 51.84, 51.99, 52.51, 52.02, 52.03, 51.28, 50.92, 51.4, 51.35, 52.19, 52.03, 51.87, 52.6, 52.15, 51.2, 51.96, 52.17, 50.82, 50.83, 50.57, 51.61, 51.14, 50.77, 50.21, 49.57, 49.16, 48.31, 47.73, 46.81, 45.98, 45.12, 44.91, 44.6, 43.97, 44.38, 44.46, 44.31, 44.15, 45.22, 45.46, 45.84, 44.37, 44.09, 42.9, 42.79, 43.16, 42.89, 43.34, 42.86, 43.35, 42.55, 42.54, 42.95, 43.41, 43.46, 44.76, 44.61, 44.45, 42.91, 44.11, 44.01, 43.42, 44.34, 45.2, 45.36, 44.59, 44.95, 44.68, 44.08, 44.83, 43.65, 44.12, 44.51, 45.85, 46.13, 44.97, 44.57, 44.72, 45.04, 45.73, 44.64, 44.54, 45.24, 46.26, 47.45, 47.27, 47.98, 49.05, 49.78, 50.22, 50.72, 50.23, 49.35, 49.96, 49.75, 49.74, 49.4, 49.17, 49.33, 48.73, 48.79, 48.97, 48.94, 48.52, 49.02, 50.16, 49.8, 50.54, 51.06, 49.45, 49.01, 48.64, 49.14, 49.27, 49.57, 49.96, 49.42, 48.98, 48.27, 48.2, 48.17, 48.31, 47.91, 48.49, 49.07, 50.02, 50.44, 50.55, 50.94, 51.29, 50.87, 51.63, 52.62, 53.76, 53.7, 53.82, 54.0, 53.92, 54.21, 54.05, 53.86, 54.83, 54.84, 54.78, 55.21, 55.2, 55.27, 55.13, 54.29, 54.19, 53.42, 53.48, 52.7, 53.2, 53.58, 53.68, 53.55, 53.72, 52.47, 51.76, 51.64, 51.81, 51.73, 51.09, 51.15, 50.85, 50.2, 50.39, 50.26, 50.97, 51.35, 51.76, 51.92, 51.38, 50.79, 49.89, 51.62, 50.94, 50.79, 50.56, 50.38, 50.02, 48.9, 48.32, 47.52, 47.5, 47.14, 46.78, 46.98, 46.69, 47.31, 47.13, 47.33, 46.58, 47.05, 46.86, 47.17, 47.43, 47.37, 47.56, 47.37, 48.23, 48.83, 49.14, 48.45, 47.82, 47.47, 47.37, 47.69, 47.2, 47.96, 48.01, 46.84, 46.62, 45.13, 44.78, 44.55, 44.3, 44.22, 44.1, 43.86, 44.88, 45.71, 45.11, 45.96, 45.07, 44.68, 45.7, 44.45, 44.9, 44.25, 44.28, 44.29, 45.42, 45.02, 45.08, 45.56, 45.49, 45.09, 45.15, 45.31, 45.93, 45.45, 45.27, 45.56, 45.55, 45.52, 45.6, 45.27, 44.89, 45.25, 44.69, 45.5, 45.72, 45.04, 45.31, 45.5, 46.05, 46.82, 46.67, 46.31, 46.02, 45.51, 45.15, 45.42, 45.52, 45.31, 44.97, 45.27, 45.07, 44.54, 44.56, 44.51, 43.98, 44.6, 45.21, 45.33, 45.5, 45.91, 45.97, 46.59, 47.65, 47.75, 48.05, 48.62, 48.44, 47.8, 48.38, 47.48, 48.6, 49.15, 49.28, 49.32, 50.39, 49.81, 49.12, 48.78, 48.65, 48.07, 48.2, 48.32, 47.86, 48.87, 48.06, 47.33, 47.61, 47.53, 47.83, 47.5, 46.93, 46.61, 46.26, 46.65, 46.43, 46.96, 47.38, 48.05, 48.63, 49.13, 49.61, 49.31, 49.16, 48.08, 48.3, 47.93, 48.21, 48.56, 47.78, 47.21, 47.06, 46.81, 46.97, 46.34, 46.44, 45.5, 44.3, 44.84, 44.16, 43.94, 43.21, 42.5, 42.41, 42.32, 43.06, 43.47, 43.44, 44.03, 44.82, 45.17, 45.02, 45.73, 46.88, 47.34, 48.45, 49.04, 49.57, 48.92, 48.28, 48.28, 47.31, 47.01, 47.59, 47.24, 47.62, 46.85, 46.62, 47.3, 47.48, 47.71, 48.77, 49.58, 49.06, 49.87, 49.5, 49.5, 49.52, 50.17, 49.49, 49.77, 50.09, 50.58, 50.44, 51.03, 50.59, 51.26, 51.45, 50.58, 50.81, 50.9, 50.67, 50.22, 50.07, 49.2, 50.23, 49.55, 49.16, 49.87, 50.22, 50.65, 51.55, 51.33, 50.67, 51.17, 51.62, 51.39, 50.6, 51.34, 51.65, 50.8, 51.25, 50.36, 50.06, 49.39, 49.02, 48.54, 48.2, 48.67, 48.87, 49.27, 49.94, 49.72, 49.77, 50.1, 51.12, 51.64, 52.44, 53.0, 53.57, 52.43, 52.91, 52.98, 52.95, 52.58, 52.27, 52.48, 52.93, 51.97, 52.06, 51.69, 51.08, 51.3, 51.07, 50.66, 50.18, 50.35, 50.33, 49.67, 49.17, 49.08, 49.34, 48.73, 49.04, 48.57, 50.23, 49.66, 49.2, 49.33, 48.8, 49.32, 50.42, 50.18, 50.28, 49.96, 49.96, 50.82, 51.34, 50.77, 51.68, 52.35, 52.59, 52.14, 52.14, 51.62, 51.87, 51.64, 50.27, 50.82, 50.92, 51.55, 51.43, 51.52, 52.16, 52.35, 52.47, 54.35, 54.16, 54.18, 55.14, 54.55, 53.84, 52.9, 53.16, 53.47, 53.85, 52.96, 53.51, 54.15, 54.01, 53.95, 54.28, 54.41, 54.71, 53.96, 53.78, 52.98, 53.3, 53.55, 53.42, 53.53, 52.52, 52.99, 52.65, 52.67, 53.29, 52.77, 53.43, 53.44, 53.38, 53.65, 52.83, 53.13, 53.1, 53.66, 53.46, 53.17, 53.33, 53.23, 52.46, 52.29, 53.01, 52.89, 52.31, 52.7, 51.53, 50.23, 50.22, 50.32, 50.45, 49.91, 49.82, 48.98, 49.13, 48.18, 48.13, 48.32, 47.3, 47.04, 47.57, 48.55, 47.68, 47.93, 47.23, 46.48, 47.51, 47.96, 47.52, 47.7, 48.13, 48.27, 49.66, 50.03, 48.23, 48.09, 47.69, 47.61, 47.67, 47.32, 46.73, 47.61, 48.02, 47.65, 48.11, 48.55, 49.34, 48.72, 49.21, 48.86, 49.58, 49.47, 48.12, 48.18, 47.15, 47.07, 47.1, 46.91, 46.08, 45.49, 45.08, 45.02, 45.9, 46.4, 46.19, 47.03, 46.27, 46.76, 46.72, 46.93, 47.37, 47.01, 47.56, 47.6, 49.09, 48.93, 49.71, 50.11, 49.4, 50.23, 49.59, 48.26, 48.8, 49.47, 49.51, 49.36, 50.33, 50.75, 50.34, 50.77, 50.01, 49.67, 49.05, 47.75, 47.09, 47.88, 47.26, 46.99, 46.35, 46.94, 47.01, 47.36, 47.35, 46.7, 46.18, 46.76, 46.79, 47.32, 45.47, 46.23, 46.01, 47.39, 47.14, 47.21, 47.67, 47.19, 47.77, 47.42, 48.25, 48.76, 49.08, 48.67, 48.57, 48.78, 47.58, 47.3, 47.91, 47.19, 48.02, 47.68, 47.92, 47.27, 47.62, 47.94, 48.67, 49.51, 50.27, 50.39, 49.65, 50.45, 49.66, 49.4, 49.85, 50.12, 51.08, 51.05, 50.02, 49.85, 49.96, 49.75, 50.6, 50.44, 49.57, 49.86, 49.17, 50.21, 50.37, 49.52, 50.18, 51.59, 50.36, 50.89, 51.17, 51.25, 51.43, 51.7, 51.25, 52.07, 51.22, 52.37, 53.24, 52.46, 52.41, 53.21, 52.85, 52.7, 52.4, 53.06, 52.63, 52.57, 52.84, 52.66, 52.09, 51.24, 50.31, 49.59, 48.57, 48.16, 48.38, 48.44, 47.98, 47.41, 46.86, 46.09, 45.43, 45.95, 45.19, 45.3, 45.02, 46.57, 45.57, 45.77, 45.65, 45.28, 45.56, 45.74, 45.19, 45.54, 45.86, 46.73, 46.43, 47.38, 47.32, 46.19, 46.58, 46.6, 46.13, 46.77, 46.55, 47.23, 47.24, 47.74, 48.2, 48.52, 47.93, 48.52, 48.56, 49.79, 50.08, 50.53, 50.06, 49.82, 49.88, 49.18, 48.49, 48.46, 48.44, 48.6, 49.29, 49.07, 49.5, 49.42, 49.31, 49.48, 48.25, 48.33, 47.98, 47.46, 46.38, 46.18, 45.13, 45.75, 45.7, 44.77, 44.47, 45.04, 44.78, 44.71, 44.6, 44.63, 43.72, 43.82, 43.6, 45.5, 45.47, 45.28, 45.97, 45.96, 46.19, 45.74, 46.76, 46.45, 46.75, 47.49, 47.36, 47.41, 47.81, 48.27, 47.65, 47.8, 47.28, 46.89, 46.56, 47.36, 48.37, 49.97, 49.93, 49.43, 48.86, 49.85, 48.93, 48.76, 48.44, 49.52, 48.93, 49.61, 50.4, 50.3, 50.57, 49.63, 49.59, 49.47, 47.93, 48.22, 48.47, 47.48, 46.69, 46.3, 46.06, 45.96, 45.46, 44.95, 45.23, 45.04, 45.08, 45.04, 45.41, 45.41, 46.02, 46.16, 46.77, 47.58, 46.76, 47.37, 48.5, 47.94, 47.97, 47.79, 48.1, 48.45, 48.08, 48.91, 48.41, 48.36, 49.01, 50.2, 49.89, 50.36, 50.49, 49.53, 48.96, 48.26, 47.99, 47.78, 47.84, 48.65, 48.93, 50.55, 50.39, 50.86, 51.09, 51.97, 51.7, 52.18, 53.11, 52.62, 52.52, 52.77, 52.45, 51.88, 52.94, 52.75, 53.73, 53.35, 53.16, 53.58, 53.38, 52.77, 52.29, 52.4, 51.96, 51.97, 50.58, 50.23, 50.12, 49.81, 49.21, 48.7, 48.77, 49.69, 48.85, 48.71, 49.32, 49.54, 49.49, 49.23, 49.25, 49.21, 47.91, 47.52, 46.4, 47.25, 47.8, 47.37, 47.9, 49.42, 49.05, 49.85, 50.07, 49.93, 49.27, 48.95, 48.73, 47.37, 47.74, 47.59, 47.91, 47.71, 49.55, 48.56, 48.03, 48.5, 49.94, 49.35, 50.46, 49.9, 50.68, 50.71, 52.03, 53.06, 52.61, 54.32, 53.56, 53.3, 54.32, 53.79, 53.33, 53.34, 53.55, 53.71, 53.19, 53.24, 53.56, 54.39, 54.5, 53.66, 53.6, 53.16, 53.88, 52.8, 53.08, 52.38, 53.1, 53.5, 53.56, 53.79, 53.51, 53.85, 53.74, 54.11, 54.06, 52.49, 52.13, 53.0, 53.81, 53.8, 53.64, 53.37, 53.68, 53.96, 53.29, 53.62, 54.29, 53.63, 53.44, 53.65, 54.01, 53.68, 53.29, 52.95, 53.12, 53.31, 53.24, 52.35, 51.65, 52.0, 51.23, 51.34, 51.1, 50.71, 50.71, 51.71, 51.85, 51.63, 50.71, 51.01, 51.67, 52.0, 52.66, 52.89, 52.05, 51.98, 52.26, 52.65, 52.3, 52.21, 52.39, 53.1, 53.65, 53.96, 54.12, 53.42, 52.69, 52.58, 53.16, 53.33, 53.6, 52.63, 51.7, 52.34, 52.27, 51.44, 51.94, 52.05, 53.78, 54.46, 54.58, 54.39, 54.44, 54.29, 53.34, 53.83, 53.92, 52.19, 51.77, 51.23, 51.8, 51.74, 52.59, 51.59, 50.91, 51.53, 51.11, 50.45, 50.12, 49.67, 50.0, 50.67, 49.7, 49.53, 49.55, 49.61, 50.12, 50.19, 49.84, 49.17, 48.09, 47.91, 47.96, 48.55, 48.36, 49.78, 49.74, 49.46, 49.7, 49.12, 49.26, 48.04, 48.48, 48.55, 48.71, 48.83, 48.09, 47.59, 48.57, 48.9, 48.56, 48.84, 49.11, 50.3, 50.96, 51.19, 50.9, 51.95, 51.85, 51.29, 50.53, 50.0, 49.79, 50.25, 50.79, 51.47, 51.53, 52.0, 53.31, 53.79, 54.68, 53.68, 53.16, 52.65, 50.99, 51.01, 51.83, 51.47, 51.56, 51.01, 50.7, 50.86, 50.12, 50.82, 49.66, 49.86, 49.56, 50.47, 50.91, 49.64, 48.2, 47.63, 47.38, 47.32, 47.39, 47.85, 47.07, 46.05, 46.28, 46.14, 46.15, 45.84, 45.82, 46.8, 45.89, 45.24, 45.72, 46.74, 46.68, 45.99, 44.87, 45.13, 44.48, 45.89, 47.38, 47.57, 47.91, 47.88, 48.61, 48.63, 48.7, 49.54, 49.93, 51.21, 50.2, 49.86, 49.32, 49.84, 49.55, 49.92, 49.22, 49.18, 50.57, 51.54, 50.39, 50.6, 51.08, 50.76, 50.09, 50.48, 50.53, 50.85, 50.74, 52.13, 51.54, 51.21, 51.49, 51.9, 51.04, 51.79, 50.88, 50.87, 50.67, 50.23, 50.9, 49.48, 49.05, 48.53, 49.08, 50.03, 50.5, 51.32, 49.96, 50.06, 49.23, 49.02, 49.19, 49.26, 50.1, 48.91, 48.43, 47.57, 46.64, 47.31, 47.47, 48.46, 49.2, 49.26, 48.69, 49.31, 48.91, 48.21, 47.56, 47.68, 48.48, 48.55, 49.31, 49.38, 49.14, 50.79, 51.86, 51.94, 51.41, 50.41, 50.64, 50.48, 50.75, 50.93, 51.17, 51.83, 51.98, 51.51, 51.02, 51.35, 50.68, 51.1, 51.5, 51.45, 50.95, 49.86, 49.19, 48.23, 48.28, 48.05, 47.54, 48.11, 48.23, 48.29, 48.66, 49.31, 48.36, 48.82, 47.76, 47.32, 47.98, 48.44, 48.87, 49.0, 49.87, 48.95, 48.79, 48.84, 50.08, 50.7, 51.31, 50.82, 52.16, 52.4, 51.75, 53.12, 52.2, 51.63, 51.46, 50.84, 51.14, 51.29, 51.33, 52.44, 51.41, 52.2, 51.66, 52.51, 53.6, 54.91, 54.7, 53.9, 54.02, 53.91, 52.77, 53.16, 52.54, 53.36, 53.87, 53.62, 53.57, 53.36, 53.01, 54.81, 54.15, 54.1, 54.62, 54.29, 53.83, 52.96, 53.61, 53.97, 54.17, 53.18, 53.42, 53.52, 53.25, 52.36, 52.28, 51.71, 51.72, 51.73, 51.49, 51.99, 51.91, 52.19, 52.4, 52.95, 52.32, 52.06, 52.57, 52.61, 53.24, 53.62, 53.28, 53.74, 53.51, 54.02, 55.05, 55.6, 56.87, 55.8, 55.35, 55.09, 54.74, 54.87, 54.55, 55.13, 55.61, 55.75, 55.03, 55.26, 55.56, 55.66, 55.56, 56.29, 55.84, 55.5, 55.79, 55.99, 56.38, 56.09, 55.18, 54.33, 53.98, 54.38, 54.77, 53.58, 53.83, 53.7, 53.0, 54.26, 54.33, 54.74, 56.19, 55.71, 55.36, 56.15, 55.24, 55.18, 55.1, 55.58, 55.71, 55.05, 55.53, 55.93, 55.18, 54.67, 54.26, 53.48, 54.05, 53.78, 53.53, 52.84, 52.55, 53.39, 53.77, 52.72, 52.07, 52.41, 52.07, 51.69, 51.14, 50.32, 50.37, 50.14, 50.82, 50.76, 50.17, 50.58, 51.38, 50.91, 49.87, 49.58, 48.78, 49.79, 48.96, 48.79, 49.7, 50.22, 49.91, 49.44, 49.35, 49.21, 50.13, 50.03, 49.22, 49.83, 50.45, 50.31, 50.77, 50.78, 50.04, 49.99, 49.31, 48.94, 48.4, 48.63, 48.77, 48.0, 47.49, 47.54, 47.87, 47.95, 46.67, 47.51, 48.62, 49.6, 49.93, 50.34, 49.94, 50.05, 49.37, 49.46, 48.61, 48.99, 48.8, 49.28, 49.41, 49.14, 49.67, 48.97, 48.83, 48.53, 49.01, 48.98, 49.16, 49.5, 48.1, 47.58, 47.7, 48.35, 48.73, 49.54, 49.42, 49.49, 49.2, 48.95, 48.48, 48.18, 48.1, 47.75, 47.81, 46.76, 47.08, 47.25, 47.57, 47.34, 47.09, 47.74, 47.69, 48.93, 48.11, 48.0, 47.36, 46.94, 46.53, 46.31, 46.85, 46.23, 46.67, 45.87, 45.71, 46.59, 46.93, 47.16, 47.59, 47.99, 48.41, 49.28, 48.67, 48.65, 49.06, 49.53, 49.88, 50.66, 50.35, 49.53, 50.31, 50.3, 49.96, 49.99, 49.73, 50.34, 50.86, 51.03, 51.34, 51.33, 51.92, 50.46, 49.75, 49.73, 49.49, 48.93, 49.32, 48.75, 48.91, 49.0, 49.06, 48.58, 48.49, 49.26, 49.6, 50.18, 50.13, 49.11, 48.85, 48.78, 49.58, 50.27, 50.52, 50.0, 50.08, 49.92, 49.77, 49.04, 49.34, 49.33, 49.83, 48.95, 48.3, 50.52, 49.98, 50.15, 50.41, 49.82, 50.86, 50.8, 50.87, 51.95, 51.43, 51.11, 50.88, 50.04, 50.21, 50.49, 50.59, 50.97, 51.47, 51.64, 51.46, 52.17, 51.71, 52.51, 52.34, 52.76, 53.8, 52.36, 52.2, 51.91, 52.9, 52.6, 54.18, 53.18, 53.33, 53.03, 53.27, 52.87, 52.54, 51.39, 51.43, 50.5, 49.71, 49.77, 49.7, 50.32, 49.5, 49.77, 49.96, 49.78, 49.3, 49.27, 49.82, 49.6, 50.11, 49.95, 50.98, 50.98, 50.85, 49.87, 49.02, 49.26, 49.14, 49.33, 48.93, 48.86, 48.51, 48.72, 48.61, 49.76, 49.35, 50.04, 49.4, 49.13, 48.65, 49.43, 49.7, 49.79, 49.94, 49.29, 50.14, 50.97, 50.93, 50.92, 51.29, 51.16, 51.02, 50.7, 50.48, 50.19, 50.62, 50.41, 50.15, 49.77, 48.87, 49.83, 50.14, 50.66, 50.33, 51.19, 51.26, 52.1, 52.05, 51.99, 51.63, 51.64, 51.74, 52.61, 53.48, 53.46, 54.12, 52.41, 52.08, 52.19, 52.68, 52.88, 52.79, 52.45, 51.92, 53.03, 53.64, 54.35, 54.27, 53.87, 54.12, 54.02, 53.87, 53.77, 53.32, 52.73, 52.53, 51.65, 51.97, 52.44, 51.93, 50.79, 51.01, 51.13, 51.12, 50.3, 49.14, 50.19, 50.06, 50.36, 50.31, 50.55, 49.77, 49.51, 48.7, 48.08, 47.69, 46.65, 46.44, 46.09, 45.46, 45.47, 45.55, 45.14, 46.44, 46.94, 47.68, 47.53, 48.11, 48.61, 48.03, 47.66, 49.45, 49.22, 49.52, 49.41, 49.92, 49.32, 48.73, 49.44, 49.57, 48.09, 48.14, 48.07, 48.54, 48.76, 48.99, 49.06, 49.25, 48.58, 48.12, 47.64, 46.88, 47.42, 48.12, 48.52, 48.19, 47.91, 47.68, 48.4, 48.75, 49.82, 49.24, 49.12, 48.38, 47.56, 47.52, 47.36, 47.11, 46.25, 46.44, 46.34, 46.96, 47.35, 46.62, 46.92, 46.63, 47.61, 47.64, 47.39, 47.2, 46.35, 47.19, 48.52, 47.51, 47.41, 47.39, 47.09, 47.88, 48.67, 48.55, 49.82, 49.84, 49.7, 49.88, 49.43, 50.31, 50.68, 50.45, 50.33, 49.78, 49.94, 49.17, 49.18, 48.89, 49.25, 49.89, 50.37, 50.29, 49.86, 49.68, 49.67, 49.97, 49.63, 49.06, 49.18, 50.02, 51.14, 51.59, 50.97, 51.79, 51.25, 50.76, 51.0, 50.15, 50.63, 50.59, 50.81, 50.3, 50.81, 51.1, 50.86, 51.41, 49.78, 50.01, 49.94, 49.46, 49.58, 49.89, 49.45, 49.39, 49.38, 49.63, 50.37, 50.08, 50.87, 50.07, 50.25, 49.21, 49.27, 49.72, 50.94, 50.95, 50.48, 51.09, 51.09, 51.13, 51.66, 52.28, 51.19, 51.2, 51.17, 50.5, 49.52, 49.49, 49.22, 48.8, 48.74, 48.56, 48.6, 49.57, 49.56, 50.7, 51.43, 51.98, 51.51, 51.3, 50.72, 50.96, 50.9, 51.14, 51.3, 51.38, 51.14, 50.53, 50.25, 50.68, 50.57, 50.52, 51.03, 51.3, 50.39, 50.33, 49.8, 49.78, 50.02, 50.32, 51.31, 50.99, 50.79, 51.12, 51.67, 51.02, 51.41, 51.78, 51.66, 51.46, 51.87, 52.08, 52.28, 51.8, 50.73, 50.66, 50.48, 50.75, 50.27, 50.65, 50.88, 50.42, 50.98, 50.75, 50.32, 50.46, 50.45, 49.89, 50.27, 50.26, 49.8, 48.75, 49.03, 49.11, 49.2, 50.04, 48.55, 49.34, 50.17, 49.58, 50.19, 49.7, 49.08, 49.04, 50.16, 50.37, 50.39, 50.92, 50.52, 51.41, 52.33, 52.54, 52.01, 52.62, 52.74, 53.07, 53.69, 53.88, 53.26, 54.09, 54.18, 54.29, 54.57, 54.67, 55.02, 55.04, 54.83, 54.41, 54.01, 53.76, 54.28, 53.99, 53.84, 53.7, 53.95, 54.26, 55.36, 54.42, 54.19, 54.45, 53.35, 54.33, 54.17, 53.61, 54.12, 52.72, 52.8, 52.15, 52.09, 52.28, 52.71, 52.9, 54.09, 54.05, 53.76, 54.42, 54.29, 54.46, 52.01, 52.24, 52.15, 51.85, 51.42, 51.93, 50.67, 52.54, 53.18, 53.34, 54.41, 54.49, 53.86, 54.4, 53.33, 53.63, 54.27, 54.51, 53.55, 53.6, 53.45, 52.94, 51.49, 50.75, 50.44, 51.1, 52.73, 53.19, 52.66, 52.35, 52.95, 53.26, 53.43, 53.51, 54.15, 55.41, 55.31, 55.3, 55.5, 55.11, 53.69, 53.91, 53.4, 54.12, 54.14, 54.96, 54.35, 54.94, 53.86, 54.35, 54.12, 54.6, 54.29, 54.61, 54.82, 54.96, 55.12, 56.03, 55.57, 56.3, 55.96, 56.57, 57.84, 57.21, 55.77, 55.75, 55.22, 54.8, 54.51, 54.1, 54.87, 55.45, 56.04, 57.3, 56.69, 55.06, 56.18, 56.2, 56.05, 54.84, 53.93, 54.27, 54.1, 52.73, 52.11, 52.69, 53.41, 53.47, 55.1, 55.61, 56.59, 57.26, 57.61, 56.65, 55.56, 55.0, 55.06, 54.96, 55.08, 54.97, 55.16, 55.65, 55.54, 55.26, 53.58, 54.03, 53.48, 52.87, 53.33, 53.82, 54.15, 54.64, 53.89, 53.67, 53.27, 54.24, 54.68, 54.44, 54.85, 54.98, 54.81, 54.99, 55.4, 55.21, 54.36, 54.48, 54.23, 53.46, 52.93, 52.72, 52.69, 52.97, 52.78, 53.0, 52.71, 52.99, 53.17, 53.45, 54.24, 53.98, 52.95, 52.84, 53.27, 53.22, 53.35, 52.25, 51.7, 51.99, 52.42, 51.92, 52.1, 51.63, 50.91, 50.93, 51.04, 51.26, 51.67, 52.65, 53.16, 52.88, 53.39, 52.44, 52.45, 53.04, 53.38, 53.81, 54.88, 54.34, 54.73, 54.58, 55.16, 55.12, 55.49, 56.31, 56.56, 56.3, 55.96, 55.42, 55.94, 56.6, 56.33, 55.11, 54.63, 54.8, 54.14, 52.88, 52.55, 51.28, 51.45, 51.18, 51.19, 51.95, 51.36, 50.05, 50.03, 50.31, 49.44, 49.23, 49.04, 49.08, 48.73, 50.35, 50.19, 50.29, 50.0, 48.41, 49.27, 47.39, 48.26, 47.5, 46.73, 46.73, 48.12, 48.35, 48.27, 47.84, 48.27, 48.09, 48.55, 47.4, 47.77, 48.01, 47.23, 46.67, 46.65, 46.42, 46.67, 45.87, 45.42, 46.78, 46.34, 46.16, 46.13, 46.04, 46.84, 46.56, 47.15, 46.69, 47.22, 47.15, 47.1, 47.1, 47.49, 46.83, 46.31, 47.6, 47.96, 47.78, 48.21, 48.21, 46.89, 47.05, 47.04, 47.31, 46.9, 46.83, 47.57, 47.53, 47.32, 47.6, 47.41, 48.1, 48.03, 48.29, 47.9, 47.2, 47.68, 47.89, 48.31, 48.79, 47.93, 48.04, 46.88, 47.25, 46.66, 47.0, 47.5, 47.23, 47.27, 48.06, 47.1, 47.55, 47.67, 48.28, 47.33, 47.38, 48.1, 48.95, 48.51, 48.37, 49.51, 48.67, 48.67, 48.8, 48.93, 48.39, 49.0, 49.55, 50.65, 50.16, 49.87, 50.53, 51.61, 51.57, 50.62, 50.48, 51.05, 51.44, 52.08, 53.19, 52.87, 52.27, 51.5, 51.4, 51.98, 52.98, 53.05, 53.0, 52.86, 53.53, 53.01, 52.88, 52.78, 52.71, 53.74, 53.13, 54.54, 54.06, 53.48, 53.02, 53.34, 53.27, 53.88, 53.3, 52.23, 51.97, 52.1, 51.17, 51.08, 51.38, 50.87, 50.36, 49.7, 49.62, 49.9, 51.55, 52.22, 51.42, 50.47, 50.39, 51.32, 51.69, 51.34, 51.92, 52.7, 53.53, 52.82, 53.02, 52.19, 51.67, 50.87, 50.69, 49.82, 50.29, 50.27, 49.75, 50.04, 50.96, 51.15, 50.78, 50.59, 50.52, 50.09, 49.06, 48.85, 49.62, 49.13, 47.99, 47.97, 48.68, 47.67, 47.83, 48.12, 48.48, 48.84, 49.23, 48.3, 48.7, 49.55, 49.43, 49.66, 49.06, 49.86, 49.49, 50.49, 50.26, 50.66, 50.32, 51.44, 50.23, 50.45, 49.19, 48.49, 49.65, 50.2, 48.99, 49.01, 48.66, 49.03, 50.16, 50.55, 50.8, 51.08, 50.41, 50.82, 51.36, 50.96, 50.56, 51.42, 51.51, 50.8, 50.53, 50.24, 50.2, 50.15, 50.0, 51.0, 51.48, 52.34, 51.28, 51.32, 52.0, 52.4, 51.94, 51.45, 51.99, 51.83, 52.18, 52.23, 52.11, 52.14, 51.6, 52.59, 52.87, 53.65, 53.26, 52.87, 52.62, 52.05, 52.42, 52.8, 52.43, 52.19, 52.38, 51.88, 51.59, 52.5, 52.0, 51.65, 53.12, 51.78, 51.04, 52.09, 51.81, 52.07, 53.3, 52.8, 52.39, 52.59, 52.49, 52.13, 52.01, 51.17, 51.43, 51.9, 51.76, 51.59, 51.89, 51.53, 51.31, 51.25, 52.11, 52.03, 51.93, 51.79, 51.52, 50.91, 50.34, 50.85, 50.49, 50.54, 50.24, 49.44, 49.17, 50.03, 49.78, 49.38, 49.13, 48.95, 49.11, 48.88, 48.84, 48.57, 48.81, 49.02, 49.17, 49.57, 49.52, 50.25, 50.53, 51.41, 51.33, 51.47, 51.03, 51.02, 51.49, 51.24, 52.11, 52.09, 52.99, 52.31, 52.09, 51.75, 52.32, 52.66, 52.56, 52.24, 52.18, 52.57, 53.02, 52.92, 52.6, 52.61, 52.63, 52.73, 52.4, 53.4, 52.95, 53.8, 54.56, 55.04, 56.06, 56.28, 55.96, 55.53, 55.01, 55.42, 54.42, 53.48, 54.33, 54.85, 55.0, 55.45, 55.81, 55.58, 54.59, 55.27, 55.43, 54.5, 54.49, 54.12, 53.97, 53.69, 53.95, 53.74, 52.98, 53.32, 53.55, 52.62, 52.81, 53.29, 53.13, 53.18, 52.66, 51.56, 51.84, 51.75, 51.97, 51.79, 51.6, 51.66, 51.59, 52.08, 51.79, 50.88, 50.95, 50.15, 48.63, 48.0, 47.77, 47.34, 46.47, 46.41, 47.21, 47.76, 47.81, 48.41, 48.18, 47.68, 48.14, 47.52, 47.77, 47.8, 47.63, 47.4, 48.14, 47.22, 47.44, 47.32, 46.92, 47.01, 47.26, 47.28, 47.48, 48.38, 48.05, 48.34, 47.33, 47.66, 46.58, 47.03, 46.81, 46.97, 46.16, 46.25, 46.82, 47.25, 47.3, 47.35, 48.09, 48.57, 48.22, 47.91, 47.54, 47.57, 46.92, 45.69, 45.64, 45.88, 46.08, 46.81, 46.09, 45.86, 45.08, 45.33, 45.36, 45.16, 45.28, 44.95, 44.44, 45.5, 46.08, 46.05, 45.2, 45.17, 45.61, 45.8, 46.49, 47.29, 47.3, 47.07, 46.83, 46.65, 47.26, 47.06, 46.11, 46.47, 46.48, 46.27, 45.16, 45.96, 46.46, 45.85, 46.02, 45.45, 44.73, 43.57, 44.17, 44.81, 44.73, 44.8, 45.96, 45.59, 44.96, 45.14, 45.57, 45.48, 44.71, 44.36, 44.88, 45.41, 44.5, 43.88, 43.41, 43.53, 44.98, 44.91, 45.05, 44.67, 46.33, 46.04, 45.81, 45.99, 45.27, 45.85, 45.93, 45.51, 45.24, 44.2, 43.98, 42.74, 42.61, 42.46, 42.26, 42.07, 41.72, 42.62, 43.64, 43.66, 44.47, 44.4, 44.33, 43.95, 44.49, 44.97, 44.29, 44.5, 44.3, 43.88, 43.98, 42.95, 42.83, 44.11, 44.49, 43.92, 44.37, 44.54, 44.45, 44.21, 44.33, 44.09, 44.1, 44.66, 45.26, 44.58, 44.4, 45.48, 46.65, 46.94, 47.97, 48.73, 48.68, 47.51, 47.52, 46.8, 46.94, 48.05, 48.24, 47.81, 47.15, 46.03, 44.96, 46.04, 46.63, 46.62, 46.6, 46.63, 46.69, 47.6, 47.88, 46.73, 47.43, 46.33, 46.16, 45.4, 45.52, 44.85, 44.13, 43.62, 44.23, 44.24, 44.75, 45.68, 45.9, 46.33, 45.82, 45.85, 45.25, 45.67, 46.3, 46.96, 47.0, 47.6, 47.56, 47.27, 47.63, 48.11, 49.47, 49.92, 49.26, 48.69, 47.93, 48.02, 47.4, 48.27, 48.13, 48.55, 48.67, 48.9, 48.3, 48.32, 48.1, 48.07, 48.19, 48.63, 48.38, 48.91, 49.13, 50.13, 48.14, 47.79, 48.59, 47.1, 48.05, 48.14, 46.95, 47.45, 46.87, 46.38, 47.33, 47.15, 46.64, 47.91, 48.51, 48.34, 47.9, 47.82, 48.81, 48.24, 47.51, 48.33, 48.19, 48.29, 48.64, 48.43, 47.01, 46.94, 47.74, 49.09, 49.04, 49.04, 49.88, 50.24, 50.41, 49.22, 48.98, 49.13, 48.24, 48.06, 49.12, 48.98, 48.14, 47.05, 47.1, 46.81, 46.35, 46.56, 46.8, 46.97, 47.24, 46.56, 46.25, 46.12, 46.17, 46.84, 46.47, 46.07, 47.04, 47.2, 46.41, 46.3, 45.63, 45.04, 44.33, 43.97, 45.33, 46.03, 46.94, 47.65, 47.62, 47.9, 48.01, 47.41, 46.76, 47.37, 46.69, 46.88, 47.33, 47.83, 48.1, 47.42, 47.79, 47.75, 47.21, 46.07, 46.42, 45.56, 44.63, 45.78, 45.15, 44.99, 45.14, 45.28, 44.76, 44.44, 45.03, 44.96, 45.05, 43.85, 43.63, 44.27, 43.95, 43.5, 43.86, 44.34, 44.65, 44.42, 44.98, 46.06, 46.84, 45.96, 47.8, 47.05, 46.37, 46.63, 46.64, 46.92, 47.77, 48.38, 47.87, 47.96, 48.61, 49.26, 49.95, 50.45, 50.86, 50.54, 49.73, 49.99, 49.72, 50.47, 49.94, 49.71, 49.46, 50.05, 50.5, 50.51, 50.67, 51.63, 50.54, 50.97, 51.6, 52.3, 52.74, 52.22, 51.85, 52.21, 51.81, 51.66, 50.72, 49.99, 50.2, 49.94, 49.48, 49.38, 49.57, 49.43, 49.54, 49.6, 49.46, 49.46, 48.94, 48.66, 47.59, 46.94, 46.29, 46.12, 46.88, 46.93, 47.08, 46.58, 46.82, 47.9, 47.89, 47.44, 46.79, 47.01, 46.51, 47.0, 46.46, 45.53, 45.91, 45.22, 45.68, 46.38, 46.1, 46.3, 47.21, 46.99, 48.01, 47.85, 47.33, 47.44, 47.63, 48.36, 48.92, 49.17, 49.58, 49.69, 50.17, 49.86, 49.21, 49.36, 50.98, 51.45, 51.0, 51.81, 50.66, 50.49, 50.72, 50.3, 49.94, 49.84, 49.52, 49.06, 48.43, 47.52, 46.99, 46.99, 47.65, 47.3, 46.63, 47.66, 47.02, 47.14, 46.63, 46.27, 46.58, 46.92, 47.75, 48.19, 48.32, 48.73, 48.14, 48.9, 49.24, 49.55, 49.92, 49.03, 48.37, 48.48, 48.6, 48.97, 49.06, 48.97, 49.74, 49.96, 50.41, 51.11, 51.85, 52.0, 52.4, 52.51, 53.1, 54.41, 53.7, 53.17, 54.06, 54.09, 53.75, 53.26, 53.75, 54.01, 55.14, 54.98, 55.42, 56.31, 55.32, 54.58, 54.65, 54.22, 53.88, 53.41, 53.25, 52.64, 51.82, 52.01, 52.05, 52.6, 52.86, 53.05, 53.44, 52.83, 52.47, 52.59, 53.1, 53.42, 53.23, 53.05, 53.14, 52.38, 52.84, 53.25, 53.74, 54.26, 54.78, 53.55, 53.62, 52.69, 52.06, 51.94, 52.61, 52.76, 52.84, 53.86, 53.92, 53.27, 52.37, 51.8, 51.83, 50.87, 51.12, 51.28, 50.82, 50.87, 51.16, 50.76, 51.18, 50.73, 51.07, 51.92, 52.08, 51.27, 51.3, 51.32, 50.78, 50.01, 49.78, 50.3, 50.79, 51.49, 51.43, 52.58, 52.03, 52.25, 52.06, 52.91, 52.87, 52.2, 52.3, 51.58, 51.02, 51.56, 51.52, 52.0, 51.44, 52.18, 52.04, 50.82, 50.27, 49.42, 48.56, 48.89, 49.13, 49.5, 49.07, 49.41, 48.54, 48.28, 48.22, 47.91, 48.01, 48.04, 48.36, 48.58, 49.18, 48.91, 49.32, 49.5, 49.66, 49.74, 48.45, 49.64, 49.09, 48.63, 48.47, 47.71, 48.81, 48.46, 48.08, 47.62, 47.93, 48.81, 49.0, 48.55, 49.37, 49.56, 49.13, 49.11, 49.2, 49.36, 49.37, 49.4, 50.53, 52.22, 52.28, 51.68, 51.02, 51.49, 50.48, 50.36, 50.59, 50.69, 50.44, 51.53, 51.98, 51.65, 52.09, 51.94, 51.59, 51.31, 52.0, 51.62, 51.55, 52.13, 52.27, 52.37, 51.92, 53.28, 53.71, 52.21, 52.95, 52.12, 51.25, 50.81, 51.55, 51.35, 51.45, 50.42, 51.06, 50.88, 50.09, 50.28, 50.57, 50.61, 51.37, 51.69, 52.56, 52.48, 52.49, 52.96, 53.6, 53.32, 54.39, 54.37, 54.29, 54.47, 53.86, 52.8, 53.98, 54.53, 53.89, 53.89, 54.19, 53.81, 54.6, 54.21, 54.72, 54.25, 54.47, 55.31, 55.49, 55.08, 55.11, 55.45, 55.08, 54.74, 55.71, 56.43, 55.9, 54.99, 54.12, 53.37, 53.13, 53.03, 52.14, 52.19, 50.4, 50.48, 51.43, 50.67, 48.93, 49.05, 49.49, 49.26, 49.41, 50.2, 51.21, 51.54, 50.77, 50.85, 50.24, 50.22, 50.07, 49.73, 50.65, 50.5, 49.61, 49.84, 50.26, 50.28, 49.81, 49.56, 49.21, 48.92, 48.52, 48.42, 47.64, 47.83, 47.41, 47.99, 48.26, 49.19, 48.39, 49.27, 49.22, 49.6, 50.14, 50.72, 50.74, 51.0, 50.92, 51.34, 50.78, 51.01, 51.91, 53.08, 53.66, 54.46, 54.68, 55.22, 56.29, 56.13, 55.05, 54.85, 54.86, 54.27, 53.47, 53.1, 52.3, 52.8, 53.77, 54.1, 53.18, 53.24, 52.66, 52.78, 52.23, 52.77, 53.14, 52.88, 53.13, 53.1, 54.08, 52.86, 53.05, 53.73, 53.44, 53.07, 53.11, 52.5, 52.13, 51.47, 51.33, 50.05, 49.69, 50.03, 49.8, 49.56, 50.11, 51.05, 50.59, 51.3, 50.22, 49.71, 50.04, 50.19, 50.26, 50.77, 50.64, 51.08, 50.77, 50.38, 49.24, 49.66, 49.15, 49.77, 50.38, 50.24, 50.29, 50.4, 50.27, 49.39, 50.27, 49.92, 50.24, 50.41, 50.58, 50.7, 51.23, 50.68, 51.27, 51.34, 51.34, 51.06, 51.01, 51.34, 50.61, 49.57, 49.41, 49.84, 49.67, 50.5, 51.26, 52.08, 52.91, 53.01, 53.29, 52.81, 51.15, 51.37, 50.88, 50.74, 49.23, 49.79, 49.67, 49.32, 48.64, 48.18, 47.71, 47.17, 46.38, 46.33, 46.2, 46.79, 45.8, 45.62, 45.17, 45.47, 45.53, 46.13, 47.31, 47.37, 47.74, 47.33, 47.31, 47.38, 48.71, 48.06, 48.01, 48.07, 47.65, 47.91, 47.96, 48.07, 47.68, 48.17, 47.64, 47.47, 48.03, 48.91, 48.48, 48.88, 48.85, 49.5, 49.58, 50.61, 51.51, 50.9, 50.68, 50.22, 50.17, 49.07, 48.09, 48.74, 48.97, 49.44, 48.91, 48.3, 48.22, 49.08, 49.15, 49.27, 50.0, 50.22, 50.33, 50.58, 50.45, 51.39, 51.3, 50.84, 51.23, 51.77, 51.46, 51.86, 52.47, 50.41, 49.37, 49.62, 49.07, 50.1, 50.29, 50.22, 50.26, 50.02, 49.64, 49.72, 50.33, 49.39, 49.55, 49.29, 49.35, 48.91, 49.02, 48.4, 48.42, 48.29, 47.33, 47.63, 45.99, 45.85, 45.04, 45.29, 45.18, 45.77, 45.73, 45.69, 46.45, 46.24, 46.3, 47.23, 47.68, 48.92, 49.21, 48.91, 49.58, 50.14, 49.97, 50.3, 50.24, 50.54, 50.55, 50.46, 51.46, 51.71, 50.87, 50.98, 50.78, 50.95, 51.08, 51.28, 50.23, 49.29, 50.14, 50.12, 50.92, 51.22, 50.88, 49.85, 50.16, 50.46, 51.5, 51.35, 51.37, 50.26, 49.89, 50.04, 49.83, 49.31, 50.17, 51.13, 50.47, 50.52, 50.25, 51.14, 51.26, 51.59, 51.0, 51.77, 51.56, 52.64, 53.25, 52.79, 53.05, 53.14, 52.94, 53.33, 53.25, 53.2, 52.76, 52.26, 52.26, 52.32, 52.92, 52.05, 52.07, 52.99, 52.52, 51.85, 51.25, 51.7, 50.91, 50.9, 50.48, 50.13, 49.94, 49.72, 49.5, 49.48, 49.65, 49.39, 49.68, 49.4, 49.14, 49.18, 48.17, 47.71, 47.36, 46.8, 46.72, 46.35, 45.87, 46.57, 47.88, 48.52, 48.73, 49.43, 49.63, 49.48, 49.56, 49.37, 48.06, 47.59, 47.14, 47.49, 47.25, 46.23, 46.28, 46.53, 47.06, 47.34, 48.83, 48.33, 49.15, 49.72, 49.35, 49.28, 48.85, 48.8, 48.56, 48.32, 48.35, 47.76, 48.48, 49.04, 48.64, 49.18, 48.57, 47.53, 47.77, 48.14, 47.73, 48.09, 49.31, 51.13, 50.58, 50.77, 50.01, 51.71, 51.42, 51.91, 51.92, 51.25, 51.1, 50.27, 49.88, 49.72, 49.86, 48.5, 48.49, 50.05, 49.48, 49.69, 49.44, 47.76, 47.2, 46.85, 47.42, 47.45, 47.37, 47.83, 47.95, 47.89, 48.33, 47.54, 47.47, 48.27, 47.02, 46.6, 46.77, 46.97, 46.83, 47.15, 46.67, 47.33, 47.5, 48.64, 49.17, 49.52, 50.38, 49.89, 49.72, 48.67, 49.22, 50.23, 49.93, 49.2, 49.89, 49.45, 49.16, 50.1, 49.89, 49.78, 50.75, 51.09, 50.43, 51.32, 50.25, 50.85, 51.13, 50.79, 50.31, 49.63, 50.68, 50.74, 50.35, 50.68, 51.39, 51.56, 51.94, 52.48, 52.46, 52.6, 52.48, 51.84, 51.04, 51.29, 50.84, 50.81, 50.64, 51.21, 51.36, 51.51, 51.31, 51.2, 50.98, 51.11, 50.05, 50.04, 50.26, 50.49, 49.83, 49.58, 49.36, 49.05, 48.34, 47.72, 47.77, 48.05, 48.17, 47.69, 47.97, 47.89, 47.63, 47.12, 46.88, 47.37, 47.31, 47.29, 46.74, 48.48, 47.16, 46.0, 45.76, 45.97, 47.11, 47.48, 47.71, 48.3, 48.4, 47.25, 47.46, 47.64, 48.99, 48.58, 49.36, 48.56, 49.51, 49.6, 50.11, 50.53, 50.92, 50.96, 50.55, 50.44, 49.98, 49.91, 48.95, 49.07, 49.67, 50.4, 51.18, 51.25, 51.13, 50.96, 51.17, 51.58, 51.75, 50.91, 51.72, 51.97, 52.53, 52.51, 52.3, 53.42, 52.71, 51.64, 52.8, 52.89, 52.58, 52.17, 50.93, 52.03, 52.41, 52.67, 53.11, 52.5, 52.72, 53.32, 51.93, 52.25, 52.65, 52.66, 52.08, 51.94, 51.62, 51.81, 51.45, 51.88, 51.53, 51.19, 51.87, 51.73, 52.02, 51.2, 52.09, 51.18, 51.21, 51.05, 50.57, 50.4, 51.13, 52.15, 51.97, 51.71, 50.55, 51.57, 50.9, 50.33, 50.39, 50.82, 51.72, 52.99, 53.38, 53.03, 52.57, 52.41, 52.85, 53.36, 53.67, 52.46, 52.07, 52.9, 52.52, 52.42, 54.01, 53.89, 54.66, 55.67, 56.02, 55.63, 54.15, 53.55, 53.87, 54.15, 54.77, 54.01, 54.05, 52.74, 52.15, 52.43, 51.07, 51.54, 52.61, 51.69, 51.5, 52.5, 52.75, 52.94, 52.94, 52.06, 51.94, 52.67, 52.67, 53.05, 52.77, 52.19, 51.89, 51.22, 50.38, 50.36, 50.22, 49.65, 50.07, 49.51, 49.78, 50.08, 51.08, 51.26, 51.71, 51.72, 50.84, 51.34, 52.32, 52.2, 53.41, 53.9, 55.02, 54.81, 54.18, 54.13, 53.61, 53.66, 53.44, 53.47, 53.35, 52.7, 52.33, 53.04, 52.94, 52.08, 50.83, 50.62, 50.77, 50.05, 48.98, 49.33, 51.26, 51.76, 51.13, 51.03, 50.94, 50.16, 49.31, 49.24, 49.73, 49.89, 49.48, 49.8, 50.11, 49.52, 48.8, 49.21, 49.91, 50.15, 50.86, 51.72, 50.77, 51.04, 51.81, 52.45, 53.26, 52.84, 53.2, 53.6, 53.17, 53.22, 52.36, 51.8, 51.96, 52.55, 52.5, 53.37, 54.2, 53.52, 53.39, 53.02, 53.45, 53.82, 53.26, 53.75, 52.89, 53.53, 52.0, 51.85, 51.39, 51.77, 51.89, 50.53, 49.71, 49.37, 50.09, 51.07, 51.46, 52.28, 51.78, 52.0, 52.03, 51.34, 51.11, 50.87, 51.13, 51.4, 51.05, 50.71, 49.55, 49.86, 49.8, 49.79, 50.12, 49.82, 49.25, 48.9, 48.72, 48.87, 48.53, 48.3, 47.53, 47.34, 46.34, 46.02, 46.42, 46.6, 46.57, 46.51, 47.12, 46.47, 46.8, 46.44, 46.68, 46.65, 46.39, 46.65, 46.33, 45.68, 45.47, 44.81, 45.0, 44.74, 44.08, 44.42, 44.77, 44.77, 44.7, 45.35, 45.28, 45.53, 44.94, 45.37, 45.38, 45.78, 45.7, 45.34, 44.71, 44.69, 44.52, 43.85, 44.73, 45.45, 44.32, 43.15, 42.37, 42.62, 44.38, 43.78, 43.71, 44.64, 44.45, 45.23, 45.89, 45.95, 46.56, 47.19, 46.41, 46.37, 46.07, 46.16, 45.51, 45.0, 45.14, 45.23, 46.16, 46.36, 47.29, 48.13, 48.85, 46.76, 46.36, 46.71, 45.98, 45.74, 46.23, 46.33, 46.2, 47.31, 47.11, 47.84, 47.85, 47.95, 47.78, 47.32, 47.24, 46.48, 46.91, 47.04, 46.84, 47.38, 46.8, 45.69, 46.03, 45.28]}], "layout": {"title": {"text": "5,040 readings at four-minute steps, textposition: auto, textpriority 1 on the extrema of each four-hour window"}, "width": 1200, "height": 500, "margin": {"l": 50, "r": 20, "t": 60, "b": 50}, "xaxis": {"title": {"text": "time"}}, "yaxis": {"title": {"text": "reading"}}}} diff --git a/test/jasmine/bundle_tests/mathjax_test.js b/test/jasmine/bundle_tests/mathjax_test.js index 21704fa8130..14998c13173 100644 --- a/test/jasmine/bundle_tests/mathjax_test.js +++ b/test/jasmine/bundle_tests/mathjax_test.js @@ -1,9 +1,11 @@ var Plotly = require('../../../lib/index'); +var Lib = require('../../../src/lib'); var d3Select = require('../../strict-d3').select; var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); var loadScript = require('../assets/load_script'); +var click = require('../assets/click'); // eslint-disable-next-line no-undef var mathjaxVersion = __karma__.config.mathjaxVersion; @@ -203,4 +205,104 @@ describe('Test MathJax v' + mathjaxVersion + ':', function() { .then(done, done.fail); }); }); + + describe('Test scatter text labels:', function() { + var gd; + + var layout = { + width: 500, + height: 500, + margin: {l: 50, r: 50, t: 50, b: 50}, + xaxis: {range: [0, 4]}, + yaxis: {range: [0, 4]} + }; + + beforeEach(function() { + gd = createGraphDiv(); + }); + + afterEach(destroyGraphDiv); + + function hiddenSourceCount() { + return d3Select(gd).selectAll('.textpoint text').filter(function() { + return this.style.display === 'none'; + }).size(); + } + + it('should keep the tex source hidden when a point is selected', function(done) { + Plotly.newPlot(gd, [{ + mode: 'markers+text', + x: [1, 2], + y: [1, 2], + text: ['$\\alpha$', '$\\beta$'], + textposition: 'top center' + }], Lib.extendFlat({clickmode: 'event+select'}, layout)) + .then(function() { + expect(d3Select(gd).selectAll('.textpoint .text-math-group').size()).toBe(2, 'math groups'); + expect(hiddenSourceCount()).toBe(2, 'before selection'); + return new Promise(function(resolve) { + gd.once('plotly_selected', resolve); + click(150, 350); + }); + }) + .then(function() { + expect(gd._fullData[0].selectedpoints).toEqual([0]); + expect(hiddenSourceCount()).toBe(2, 'after selection'); + }) + .then(done, done.fail); + }); + + it('should place *auto* labels by their rendered box and hide the whole label', function(done) { + var n = 12; + var x = []; + var y = []; + var text = []; + var textposition = []; + for(var i = 0; i < n; i++) { + x.push(2); + y.push(2); + text.push(i ? '$\\alpha_{' + i + '}$' : '$\\alpha + \\beta + \\gamma + \\delta$'); + textposition.push(i ? 'auto' : 'top center'); + } + // a point outside the plot area gets no label + x.push(5); + y.push(2); + text.push('$\\omega$'); + textposition.push('auto'); + + Plotly.newPlot(gd, [{ + mode: 'markers+text', + x: x, + y: y, + text: text, + textposition: textposition, + marker: {size: 10} + }], layout) + .then(function() { + var gd3 = d3Select(gd); + var cd = gd.calcdata[0]; + var boxes = [gd3.select('.point').node().getBoundingClientRect()]; + + expect(gd3.selectAll('.textpoint .text-math-group').size()).toBe(n + 1, 'math groups'); + expect(cd[n]._tpAuto).toBe(null, 'label outside the plot area'); + + gd3.selectAll('.textpoint').each(function(d) { + var rect = d3Select(this).select('.text-math-group svg').node().getBoundingClientRect(); + if(d._tpAuto === null) expect(rect.width).toBe(0, 'hidden label ' + d.i); + else boxes.push(rect); + }); + + var overlaps = 0; + for(var i = 0; i < boxes.length; i++) { + for(var j = i + 1; j < boxes.length; j++) { + var a = boxes[i]; + var b = boxes[j]; + if(a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top) overlaps++; + } + } + expect(overlaps).toBe(0, 'overlaps among the marker and the visible labels'); + }) + .then(done, done.fail); + }); + }); }); diff --git a/test/jasmine/tests/lib_geometry2d_test.js b/test/jasmine/tests/lib_geometry2d_test.js index 6879426a9a4..bb6048a217c 100644 --- a/test/jasmine/tests/lib_geometry2d_test.js +++ b/test/jasmine/tests/lib_geometry2d_test.js @@ -51,6 +51,99 @@ describe('segmentsIntersect', function() { }); }); +describe('placeLabels', function() { + var W = 20; + var H = 10; + + // a W x H box next to its point, like a text label with a 5px marker + function rect(x, y) { + return function(pos, gap) { + var sx = pos.indexOf('right') !== -1 ? 1 : pos.indexOf('left') !== -1 ? -1 : 0; + var sy = pos.indexOf('bottom') !== -1 ? 1 : pos.indexOf('top') !== -1 ? -1 : 0; + var r = 6 + gap; + var x0 = x + sx * r - (sx > 0 ? 0 : sx < 0 ? W : W / 2); + var y0 = y + sy * r - (sy > 0 ? 0 : sy < 0 ? H : H / 2); + return { + x0: x0, + y0: y0, + x1: x0 + W, + y1: y0 + H, + leader: gap ? [x + sx * 5, y + sy * 5, x + sx * r, y + sy * r] : null + }; + }; + } + + function label(x, y, opts) { + return Object.assign({x: x, y: y, owner: {}, radius: 5, fontSize: 10, rect: rect(x, y)}, opts); + } + + function marker(lab) { + return {x0: lab.x - 5, y0: lab.y - 5, x1: lab.x + 5, y1: lab.y + 5, owner: lab.owner}; + } + + function place(labels, opts) { + return geom2d.placeLabels(Object.assign({width: 200, height: 200, labels: labels}, opts)); + } + + it('places an isolated label at the first position', function() { + var out = place([label(100, 100)]); + expect(out[0].position).toBe('top center'); + expect(out[0].gap).toBe(0); + expect(out[0].leader).toBe(null); + }); + + it('places labels in order of priority, then in the given order', function() { + var a = label(100, 100, {onPoint: true}); + var b = label(100, 100, {onPoint: true, priority: 1}); + var out = place([a, b]); + expect(out[1].position).toBe('middle center'); + expect(out[0].position).toBe('top center'); + }); + + it('avoids fixed boxes and the markers of other points', function() { + var a = label(100, 100); + var fixed = {x0: 80, y0: 70, x1: 120, y1: 92, owner: {}}; + var out = place([a], {fixed: [fixed], markers: [marker(a)]}); + expect(out[0].position).toBe('bottom center'); + expect(out[0].gap).toBe(0); + }); + + it('moves a label out with a leader line when another marker is close', function() { + var a = label(100, 100); + var b = label(102, 102); + var out = place([a, b], {markers: [marker(a), marker(b)]}); + expect(out[0].gap).toBeGreaterThan(0); + expect(out[1].gap).toBeGreaterThan(0); + expect(out[0].leader.length).toBe(4); + expect(out[0].position).not.toBe(out[1].position); + }); + + it('keeps the preferred position of a label while it is free', function() { + var out = place([label(100, 100, {prefer: 'bottom center'})]); + expect(out[0].position).toBe('bottom center'); + + var fixed = {x0: 80, y0: 108, x1: 120, y1: 130}; + out = place([label(100, 100, {prefer: 'bottom center'})], {fixed: [fixed]}); + expect(out[0].position).toBe('top center'); + }); + + it('keeps the preferred gap of a label unless it can go next to its point', function() { + var a = label(100, 100, {prefer: 'bottom center', preferGap: 25}); + var b = label(102, 102); + var out = place([a, b], {markers: [marker(a), marker(b)]}); + expect(out[0].position).toBe('bottom center'); + expect(out[0].gap).toBe(25); + + out = place([label(100, 100, {prefer: 'bottom center', preferGap: 25})]); + expect(out[0].gap).toBe(0); + }); + + it('hides a label outside the area', function() { + var out = place([label(300, 100)]); + expect(out[0]).toBe(null); + }); +}); + describe('segmentDistance', function() { function check(x1, y1, x2, y2, x3, y3, x4, y4, expected) { var result1 = geom2d.segmentDistance(x1, y1, x2, y2, x3, y3, x4, y4); diff --git a/test/jasmine/tests/plot_api_test.js b/test/jasmine/tests/plot_api_test.js index d71ea4a1e77..8f3c7e42942 100644 --- a/test/jasmine/tests/plot_api_test.js +++ b/test/jasmine/tests/plot_api_test.js @@ -2569,6 +2569,22 @@ describe('Test plot api', function () { expect(gd.data[0].scl).toBe(undefined); }); + it('should keep *auto* textposition on scatter traces', function () { + var data = [ + { + type: 'scatter', + mode: 'text', + x: [1], + y: [1], + text: ['a'], + textposition: 'auto' + } + ]; + + Plotly.newPlot(gd, data); + expect(gd.data[0].textposition).toBe('auto'); + }); + it("should not delete rename 'scl' to 'colorscale' when colorscale is defined ", function () { var data = [ { diff --git a/test/jasmine/tests/scatter_test.js b/test/jasmine/tests/scatter_test.js index 4c27d0a9bb8..df134c0d955 100644 --- a/test/jasmine/tests/scatter_test.js +++ b/test/jasmine/tests/scatter_test.js @@ -48,6 +48,45 @@ describe('Test scatter', function() { traceOut = {}; }); + it('should accept *auto* textposition', function() { + traceIn = { + x: [1, 2], + y: [1, 2], + mode: 'markers+text', + text: ['a', 'b'], + textposition: 'auto' + }; + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.textposition).toBe('auto'); + }); + + it('should coerce textpriority with *auto* textposition only', function() { + traceIn = { + x: [1, 2], + y: [1, 2], + mode: 'markers+text', + text: ['a', 'b'], + textposition: 'auto', + textpriority: [2, 1] + }; + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.textpriority).toEqual([2, 1]); + + traceIn.textposition = ['top center', 'auto']; + delete traceIn.textpriority; + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.textpriority).toBe(0); + + traceIn.textposition = 'top center'; + traceIn.textpriority = [2, 1]; + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.textpriority).toBeUndefined(); + }); + it('should set visible to false when x and y are empty', function() { traceIn = {}; supplyDefaults(traceIn, traceOut, defaultColor, layout); @@ -698,6 +737,341 @@ describe('end-to-end scatter tests', function() { }).then(done, done.fail); }); + describe('with textposition *auto*', function() { + var layout = { + width: 500, + height: 500, + margin: {l: 50, r: 50, t: 50, b: 50}, + xaxis: {range: [0, 4]}, + yaxis: {range: [0, 4]} + }; + + function visibleLabelBoxes() { + var boxes = []; + d3SelectAll('.textpoint').each(function() { + if(this.style.display !== 'none') boxes.push(this.querySelector('text').getBoundingClientRect()); + }); + return boxes; + } + + function hiddenLabelCount() { + return d3SelectAll('.textpoint').filter(function() { + return this.style.display === 'none'; + }).size(); + } + + function countOverlaps(boxes) { + var n = 0; + for(var i = 0; i < boxes.length; i++) { + for(var j = i + 1; j < boxes.length; j++) { + var a = boxes[i]; + var b = boxes[j]; + if(a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top) n++; + } + } + return n; + } + + function textPointTransforms() { + var out = []; + d3SelectAll('.textpoint').each(function() { + out.push(d3Select(this).attr('transform')); + }); + return out; + } + + function makeStack(n) { + var x = []; + var y = []; + var text = []; + for(var i = 0; i < n; i++) { + x.push(2); + y.push(2); + text.push('label ' + i); + } + return {mode: 'markers+text', textposition: 'auto', x: x, y: y, text: text, marker: {size: 10}}; + } + + it('should place labels without overlaps, add leader lines and hide the rest', function(done) { + Plotly.newPlot(gd, [makeStack(40)], layout) + .then(function() { + var cd = gd.calcdata[0]; + var hidden = 0; + var leaders = 0; + for(var i = 0; i < cd.length; i++) { + if(cd[i]._tpAuto === null) hidden++; + else if(cd[i]._tpAutoGap > 0) leaders++; + } + + // the stacked markers block every position next to the point, + // so even the first label moves out with a leader line + expect(cd[0]._tpAuto).toBe('top center'); + expect(cd[0]._tpAutoGap).toBeGreaterThan(0); + expect(hidden).toBeGreaterThan(0); + expect(leaders).toBeGreaterThan(0); + + var boxes = visibleLabelBoxes(); + expect(boxes.length).toBe(40 - hidden); + expect(countOverlaps(boxes)).toBe(0); + expect(d3SelectAll('.textpoint path.textleader').size()).toBe(leaders); + }) + .then(done, done.fail); + }); + + it('should place the labels with the highest textpriority first', function(done) { + var stack = makeStack(3); + stack.textpriority = [0, 0, 1]; + + Plotly.newPlot(gd, [stack], layout) + .then(function() { + var cd = gd.calcdata[0]; + expect(cd[2]._tpAuto).toBe('top center'); + expect(cd[0]._tpAuto).not.toBe('top center'); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + + // a trace-wide priority puts a whole trace ahead of the others + return Plotly.newPlot(gd, [makeStack(1), Lib.extendFlat(makeStack(1), {textpriority: 1})], layout); + }) + .then(function() { + expect(gd.calcdata[1][0]._tpAuto).toBe('top center'); + expect(gd.calcdata[0][0]._tpAuto).not.toBe('top center'); + }) + .then(done, done.fail); + }); + + it('should keep the position of a label across a zoom while it is free', function(done) { + Plotly.newPlot(gd, [{ + mode: 'markers+text', + textposition: 'auto', + x: [2], + y: [2], + text: ['auto'] + }, { + mode: 'markers+text', + textposition: 'bottom center', + x: [2], + y: [2.25], + text: ['fixed'] + }], layout) + .then(function() { + // the fixed label hangs over the point, so the *auto* label goes below it + expect(gd.calcdata[0][0]._tpAuto).toBe('bottom center'); + return Plotly.relayout(gd, {'xaxis.range': [1.5, 2.5], 'yaxis.range': [1.5, 2.5]}); + }) + .then(function() { + // the zoom frees the top, but the label stays where it was + expect(gd.calcdata[0][0]._tpAuto).toBe('bottom center'); + return Plotly.relayout(gd, {'xaxis.range': [0, 4], 'yaxis.range': [0, 4]}); + }) + .then(function() { + expect(gd.calcdata[0][0]._tpAuto).toBe('bottom center'); + }) + .then(done, done.fail); + }); + + it('should let an isolated label take the first candidate', function(done) { + Plotly.newPlot(gd, [{ + mode: 'markers+text', + textposition: 'auto', + x: [1, 3], + y: [1, 3], + text: ['a', 'b'] + }], layout) + .then(function() { + expect(gd.calcdata[0][0]._tpAuto).toBe('top center'); + expect(gd.calcdata[0][1]._tpAuto).toBe('top center'); + expect(d3SelectAll('.textpoint path.textleader').size()).toBe(0); + expect(hiddenLabelCount()).toBe(0); + }) + .then(done, done.fail); + }); + + it('should add a leader line to every label in a cluster', function(done) { + Plotly.newPlot(gd, [{ + mode: 'markers+text', + textposition: 'auto', + x: [1, 1.05, 3], + y: [1, 1.05, 3], + text: ['a', 'b', 'c'] + }], layout) + .then(function() { + var cd = gd.calcdata[0]; + expect(cd[0]._tpAutoGap).toBeGreaterThan(0); + expect(cd[1]._tpAutoGap).toBeGreaterThan(0); + expect(cd[2]._tpAutoGap).toBe(0); + expect(d3SelectAll('.textpoint path.textleader').size()).toBe(2); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + }) + .then(done, done.fail); + }); + + it('should place text-only labels on their point first', function(done) { + Plotly.newPlot(gd, [{ + mode: 'text', + textposition: 'auto', + x: [1, 1, 1], + y: [1, 1, 1], + text: ['a', 'b', 'c'] + }], layout) + .then(function() { + var cd = gd.calcdata[0]; + expect(cd[0]._tpAuto).toBe('middle center'); + expect(cd[1]._tpAutoGap).toBeGreaterThan(0); + expect(cd[2]._tpAutoGap).toBeGreaterThan(0); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + expect(d3SelectAll('.textpoint path.textleader').size()).toBe(2); + }) + .then(done, done.fail); + }); + + it('should respect fixed labels and per-point *auto* values', function(done) { + Plotly.newPlot(gd, [{ + mode: 'markers+text', + textposition: ['top center', 'auto'], + x: [2, 2], + y: [2, 2], + text: ['fixed', 'auto'] + }], layout) + .then(function() { + var cd = gd.calcdata[0]; + expect(cd[0]._tpAuto).toBeUndefined(); + expect(cd[1]._tpAuto).toBe('bottom center'); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + }) + .then(done, done.fail); + }); + + it('should place labels again after a zoom', function(done) { + var x = []; + var y = []; + var text = []; + for(var i = 0; i < 8; i++) { + x.push(2 + 0.02 * i); + y.push(2 + 0.02 * (i % 3)); + text.push('point ' + i); + } + + function countHidden() { + var n = 0; + gd.calcdata[0].forEach(function(d) { + if(d._tpAuto === null) n++; + }); + return n; + } + + function countArrows() { + var n = 0; + gd.calcdata[0].forEach(function(d) { + if(d._tpAutoGap > 0) n++; + }); + return n; + } + + var hiddenAtStart; + var arrowsAtStart; + + Plotly.newPlot(gd, [{ + mode: 'markers+text', + textposition: 'auto', + x: x, + y: y, + text: text + }], layout) + .then(function() { + hiddenAtStart = countHidden(); + arrowsAtStart = countArrows(); + expect(arrowsAtStart).toBeGreaterThan(0); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + return Plotly.relayout(gd, {'xaxis.range': [1.8, 2.4], 'yaxis.range': [1.8, 2.4]}); + }) + .then(function() { + expect(countHidden()).toBe(0); + expect(countArrows()).toBeLessThan(arrowsAtStart); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + // the last three points fall outside this range + return Plotly.relayout(gd, {'xaxis.range': [1.8, 2.09], 'yaxis.range': [1.8, 2.4]}); + }) + .then(function() { + var cd = gd.calcdata[0]; + expect(cd[5]._tpAuto).toBe(null); + expect(cd[6]._tpAuto).toBe(null); + expect(cd[7]._tpAuto).toBe(null); + expect(cd[0]._tpAuto).not.toBe(null); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + return Plotly.relayout(gd, {'xaxis.range': [0, 4], 'yaxis.range': [0, 4]}); + }) + .then(function() { + expect(countHidden()).toBe(hiddenAtStart); + expect(countArrows()).toBe(arrowsAtStart); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + }) + .then(done, done.fail); + }); + + it('should keep the placement across style edits and selection', function(done) { + var transforms; + + Plotly.newPlot(gd, [makeStack(12)], layout) + .then(function() { + transforms = textPointTransforms(); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + return Plotly.restyle(gd, 'textfont.color', 'red'); + }) + .then(function() { + expect(textPointTransforms()).toEqual(transforms); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + return Plotly.restyle(gd, 'selectedpoints', [[0, 1]]); + }) + .then(function() { + expect(textPointTransforms()).toEqual(transforms); + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + return Plotly.relayout(gd, 'xaxis.range', [1, 3]); + }) + .then(function() { + expect(countOverlaps(visibleLabelBoxes())).toBe(0); + return Plotly.restyle(gd, 'textposition', 'top center'); + }) + .then(function() { + var cd = gd.calcdata[0]; + expect(cd[0]._tpAuto).toBeUndefined(); + expect(d3SelectAll('.textpoint path.textleader').size()).toBe(0); + expect(hiddenLabelCount()).toBe(0); + }) + .then(done, done.fail); + }); + + it('should draw the leader lines at the new point positions after an animation', function(done) { + function leaderPaths() { + var out = []; + d3SelectAll('.textpoint path.textleader').each(function() { + out.push(d3Select(this).attr('d')); + }); + return out; + } + + var animated; + + Plotly.newPlot(gd, [makeStack(3)], layout) + .then(function() { + expect(leaderPaths().length).toBe(3); + return Plotly.animate(gd, [{data: [{x: [1, 1, 1], y: [3, 3, 3]}]}], { + frame: {redraw: false, duration: 100}, + transition: {duration: 100} + }); + }) + .then(function() { + animated = leaderPaths(); + expect(animated.length).toBe(3); + return Plotly.redraw(gd); + }) + .then(function() { + // a full redraw draws the leader lines where the animation should have left them + expect(leaderPaths()).toEqual(animated); + }) + .then(done, done.fail); + }); + }); + it('should remove all point and text nodes on blank data', function(done) { function assertNodeCnt(ptCnt, txCnt) { expect(d3SelectAll('.point').size()).toEqual(ptCnt); diff --git a/test/jasmine/tests/scattermap_test.js b/test/jasmine/tests/scattermap_test.js index 9d49db1951d..0bd94dc777e 100644 --- a/test/jasmine/tests/scattermap_test.js +++ b/test/jasmine/tests/scattermap_test.js @@ -33,7 +33,7 @@ describe('scattermap defaults', function() { function _supply(traceIn) { var traceOut = { visible: true }; var defaultColor = '#444'; - var layout = { _dataLength: 1 }; + var layout = { _dataLength: 1, font: { family: 'Arial', size: 12, color: '#444' } }; ScatterMap.supplyDefaults(traceIn, traceOut, defaultColor, layout); @@ -123,6 +123,18 @@ describe('scattermap defaults', function() { expect(fullTrace.marker).toBeDefined(); expect(fullTrace.marker.line).toBeUndefined(); }); + + it('should not accept *auto* textposition', function() { + var fullTrace = _supply({ + mode: 'markers+text', + lon: [10, 20], + lat: [10, 20], + text: ['a', 'b'], + textposition: 'auto' + }); + + expect(fullTrace.textposition).toBe('middle center'); + }); }); describe('scattermap convert', function() { diff --git a/test/plot-schema.json b/test/plot-schema.json index cebf8f090da..9376185e72c 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -54656,7 +54656,7 @@ }, "textposition": { "arrayOk": true, - "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates.", + "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend.", "dflt": "middle center", "editType": "calc", "valType": "enumerated", @@ -54669,9 +54669,17 @@ "middle right", "bottom left", "bottom center", - "bottom right" + "bottom right", + "auto" ] }, + "textpriority": { + "arrayOk": true, + "description": "Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order.", + "dflt": 0, + "editType": "calc", + "valType": "number" + }, "texttemplate": { "arrayOk": true, "description": "Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of \"data: %{x}, %{y}\" will result in a value of \"data: 1, %{y}\" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. ", @@ -59333,7 +59341,7 @@ }, "textposition": { "arrayOk": true, - "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates.", + "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend.", "dflt": "middle center", "editType": "calc", "valType": "enumerated", @@ -59346,9 +59354,17 @@ "middle right", "bottom left", "bottom center", - "bottom right" + "bottom right", + "auto" ] }, + "textpriority": { + "arrayOk": true, + "description": "Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order.", + "dflt": 0, + "editType": "calc", + "valType": "number" + }, "texttemplate": { "arrayOk": true, "description": "Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of \"data: %{x}, %{y}\" will result in a value of \"data: 1, %{y}\" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `a`, `b` and `text`.", @@ -67075,7 +67091,7 @@ }, "textposition": { "arrayOk": true, - "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates.", + "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend.", "dflt": "middle center", "editType": "calc", "valType": "enumerated", @@ -67088,9 +67104,17 @@ "middle right", "bottom left", "bottom center", - "bottom right" + "bottom right", + "auto" ] }, + "textpriority": { + "arrayOk": true, + "description": "Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order.", + "dflt": 0, + "editType": "calc", + "valType": "number" + }, "texttemplate": { "arrayOk": true, "description": "Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of \"data: %{x}, %{y}\" will result in a value of \"data: 1, %{y}\" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `r`, `theta` and `text`.", @@ -71118,7 +71142,7 @@ }, "textposition": { "arrayOk": true, - "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates.", + "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend.", "dflt": "middle center", "editType": "calc", "valType": "enumerated", @@ -71131,9 +71155,17 @@ "middle right", "bottom left", "bottom center", - "bottom right" + "bottom right", + "auto" ] }, + "textpriority": { + "arrayOk": true, + "description": "Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order.", + "dflt": 0, + "editType": "calc", + "valType": "number" + }, "texttemplate": { "arrayOk": true, "description": "Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of \"data: %{x}, %{y}\" will result in a value of \"data: 1, %{y}\" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `real`, `imag` and `text`.", @@ -73195,7 +73227,7 @@ }, "textposition": { "arrayOk": true, - "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates.", + "description": "Sets the positions of the `text` elements with respects to the (x,y) coordinates. With *auto*, each label takes the first position around its point that overlaps no marker and no other label on the subplot. When the positions next to the point are taken, or another point sits close to the label, the label moves farther out with a leader line back to the point. A label with no free position is hidden. Labels are placed in the order of `textpriority`. Auto placement considers markers and text labels only. It does not avoid annotations, shapes, images, or the legend.", "dflt": "middle center", "editType": "calc", "valType": "enumerated", @@ -73208,9 +73240,17 @@ "middle right", "bottom left", "bottom center", - "bottom right" + "bottom right", + "auto" ] }, + "textpriority": { + "arrayOk": true, + "description": "Sets the placement priority of the `text` elements with `textposition` *auto*, per point or for the whole trace. A label with a higher priority takes its position before the labels of lower priority on the subplot, so it stays next to its point and is hidden last. Labels of equal priority are placed in trace and data order.", + "dflt": 0, + "editType": "calc", + "valType": "number" + }, "texttemplate": { "arrayOk": true, "description": "Template string used for rendering the information text that appears on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Variables that can't be found will be replaced with the specifier. For example, a template of \"data: %{x}, %{y}\" will result in a value of \"data: 1, %{y}\" if x is 1 and y is missing. Variables with an undefined value will be replaced with the fallback value. All attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. Finally, the template string has access to variables `a`, `b`, `c` and `text`.",