{"version":3,"file":"app-05951105.js","sources":["../../node_modules/d3-time/src/interval.js","../../node_modules/d3-time/src/millisecond.js","../../node_modules/d3-time/src/duration.js","../../node_modules/d3-time/src/second.js","../../node_modules/d3-time/src/minute.js","../../node_modules/d3-time/src/hour.js","../../node_modules/d3-time/src/day.js","../../node_modules/d3-time/src/week.js","../../node_modules/d3-time/src/month.js","../../node_modules/d3-time/src/year.js","../../node_modules/d3-array/src/ascending.js","../../node_modules/d3-array/src/descending.js","../../node_modules/d3-array/src/bisector.js","../../node_modules/d3-array/src/number.js","../../node_modules/d3-array/src/bisect.js","../../node_modules/internmap/src/index.js","../../node_modules/d3-array/src/ticks.js","../../node_modules/d3-time/src/ticks.js","../../node_modules/d3-time-format/src/locale.js","../../node_modules/d3-time-format/src/defaultLocale.js","../../node_modules/d3-selection/src/namespaces.js","../../node_modules/d3-selection/src/namespace.js","../../node_modules/d3-selection/src/creator.js","../../node_modules/d3-selection/src/selector.js","../../node_modules/d3-selection/src/selection/select.js","../../node_modules/d3-selection/src/array.js","../../node_modules/d3-selection/src/selectorAll.js","../../node_modules/d3-selection/src/selection/selectAll.js","../../node_modules/d3-selection/src/matcher.js","../../node_modules/d3-selection/src/selection/selectChild.js","../../node_modules/d3-selection/src/selection/selectChildren.js","../../node_modules/d3-selection/src/selection/filter.js","../../node_modules/d3-selection/src/selection/sparse.js","../../node_modules/d3-selection/src/selection/enter.js","../../node_modules/d3-selection/src/constant.js","../../node_modules/d3-selection/src/selection/data.js","../../node_modules/d3-selection/src/selection/exit.js","../../node_modules/d3-selection/src/selection/join.js","../../node_modules/d3-selection/src/selection/merge.js","../../node_modules/d3-selection/src/selection/order.js","../../node_modules/d3-selection/src/selection/sort.js","../../node_modules/d3-selection/src/selection/call.js","../../node_modules/d3-selection/src/selection/nodes.js","../../node_modules/d3-selection/src/selection/node.js","../../node_modules/d3-selection/src/selection/size.js","../../node_modules/d3-selection/src/selection/empty.js","../../node_modules/d3-selection/src/selection/each.js","../../node_modules/d3-selection/src/selection/attr.js","../../node_modules/d3-selection/src/window.js","../../node_modules/d3-selection/src/selection/style.js","../../node_modules/d3-selection/src/selection/property.js","../../node_modules/d3-selection/src/selection/classed.js","../../node_modules/d3-selection/src/selection/text.js","../../node_modules/d3-selection/src/selection/html.js","../../node_modules/d3-selection/src/selection/raise.js","../../node_modules/d3-selection/src/selection/lower.js","../../node_modules/d3-selection/src/selection/append.js","../../node_modules/d3-selection/src/selection/insert.js","../../node_modules/d3-selection/src/selection/remove.js","../../node_modules/d3-selection/src/selection/clone.js","../../node_modules/d3-selection/src/selection/datum.js","../../node_modules/d3-selection/src/selection/on.js","../../node_modules/d3-selection/src/selection/dispatch.js","../../node_modules/d3-selection/src/selection/iterator.js","../../node_modules/d3-selection/src/selection/index.js","../../node_modules/d3-selection/src/select.js","../../node_modules/d3-selection/src/sourceEvent.js","../../node_modules/d3-selection/src/pointer.js","../../node_modules/d3-selection/src/selectAll.js","../../node_modules/d3-dispatch/src/dispatch.js","../../node_modules/d3-drag/src/noevent.js","../../node_modules/d3-drag/src/nodrag.js","../../node_modules/d3-drag/src/constant.js","../../node_modules/d3-drag/src/event.js","../../node_modules/d3-drag/src/drag.js","../../node_modules/d3-color/src/define.js","../../node_modules/d3-color/src/color.js","../../node_modules/d3-interpolate/src/constant.js","../../node_modules/d3-interpolate/src/color.js","../../node_modules/d3-interpolate/src/rgb.js","../../node_modules/d3-interpolate/src/numberArray.js","../../node_modules/d3-interpolate/src/array.js","../../node_modules/d3-interpolate/src/date.js","../../node_modules/d3-interpolate/src/number.js","../../node_modules/d3-interpolate/src/object.js","../../node_modules/d3-interpolate/src/string.js","../../node_modules/d3-interpolate/src/value.js","../../node_modules/d3-interpolate/src/round.js","../../node_modules/d3-interpolate/src/transform/decompose.js","../../node_modules/d3-interpolate/src/transform/parse.js","../../node_modules/d3-interpolate/src/transform/index.js","../../node_modules/d3-timer/src/timer.js","../../node_modules/d3-timer/src/timeout.js","../../node_modules/d3-transition/src/transition/schedule.js","../../node_modules/d3-transition/src/interrupt.js","../../node_modules/d3-transition/src/selection/interrupt.js","../../node_modules/d3-transition/src/transition/tween.js","../../node_modules/d3-transition/src/transition/interpolate.js","../../node_modules/d3-transition/src/transition/attr.js","../../node_modules/d3-transition/src/transition/attrTween.js","../../node_modules/d3-transition/src/transition/delay.js","../../node_modules/d3-transition/src/transition/duration.js","../../node_modules/d3-transition/src/transition/ease.js","../../node_modules/d3-transition/src/transition/easeVarying.js","../../node_modules/d3-transition/src/transition/filter.js","../../node_modules/d3-transition/src/transition/merge.js","../../node_modules/d3-transition/src/transition/on.js","../../node_modules/d3-transition/src/transition/remove.js","../../node_modules/d3-transition/src/transition/select.js","../../node_modules/d3-transition/src/transition/selectAll.js","../../node_modules/d3-transition/src/transition/selection.js","../../node_modules/d3-transition/src/transition/style.js","../../node_modules/d3-transition/src/transition/styleTween.js","../../node_modules/d3-transition/src/transition/text.js","../../node_modules/d3-transition/src/transition/textTween.js","../../node_modules/d3-transition/src/transition/transition.js","../../node_modules/d3-transition/src/transition/end.js","../../node_modules/d3-transition/src/transition/index.js","../../node_modules/d3-ease/src/linear.js","../../node_modules/d3-ease/src/cubic.js","../../node_modules/d3-transition/src/selection/transition.js","../../node_modules/d3-transition/src/selection/index.js","../../node_modules/d3-brush/src/brush.js","../../node_modules/d3-dsv/src/dsv.js","../../node_modules/d3-dsv/src/csv.js","../../node_modules/d3-dsv/src/tsv.js","../../node_modules/d3-scale/src/init.js","../../node_modules/d3-scale/src/ordinal.js","../../node_modules/d3-scale/src/constant.js","../../node_modules/d3-scale/src/number.js","../../node_modules/d3-scale/src/continuous.js","../../node_modules/d3-format/src/formatDecimal.js","../../node_modules/d3-format/src/exponent.js","../../node_modules/d3-format/src/formatGroup.js","../../node_modules/d3-format/src/formatNumerals.js","../../node_modules/d3-format/src/formatSpecifier.js","../../node_modules/d3-format/src/formatTrim.js","../../node_modules/d3-format/src/formatPrefixAuto.js","../../node_modules/d3-format/src/formatRounded.js","../../node_modules/d3-format/src/formatTypes.js","../../node_modules/d3-format/src/identity.js","../../node_modules/d3-format/src/locale.js","../../node_modules/d3-format/src/defaultLocale.js","../../node_modules/d3-format/src/precisionFixed.js","../../node_modules/d3-format/src/precisionPrefix.js","../../node_modules/d3-format/src/precisionRound.js","../../node_modules/d3-scale/src/tickFormat.js","../../node_modules/d3-scale/src/linear.js","../../node_modules/d3-scale/src/nice.js","../../node_modules/d3-scale/src/log.js","../../node_modules/d3-scale/src/symlog.js","../../node_modules/d3-scale/src/time.js","../../node_modules/d3-scale/src/utcTime.js","../../node_modules/d3-shape/src/constant.js","../../node_modules/d3-shape/src/math.js","../../node_modules/d3-path/src/path.js","../../node_modules/d3-shape/src/path.js","../../node_modules/d3-shape/src/array.js","../../node_modules/d3-shape/src/curve/linear.js","../../node_modules/d3-shape/src/point.js","../../node_modules/d3-shape/src/line.js","../../node_modules/d3-shape/src/noop.js","../../node_modules/d3-shape/src/curve/basis.js","../../node_modules/d3-shape/src/curve/basisClosed.js","../../node_modules/d3-shape/src/curve/basisOpen.js","../../node_modules/d3-shape/src/curve/bundle.js","../../node_modules/d3-shape/src/curve/cardinal.js","../../node_modules/d3-shape/src/curve/cardinalClosed.js","../../node_modules/d3-shape/src/curve/cardinalOpen.js","../../node_modules/d3-shape/src/curve/catmullRom.js","../../node_modules/d3-shape/src/curve/catmullRomClosed.js","../../node_modules/d3-shape/src/curve/catmullRomOpen.js","../../node_modules/d3-shape/src/curve/linearClosed.js","../../node_modules/d3-shape/src/curve/monotone.js","../../node_modules/d3-shape/src/curve/natural.js","../../node_modules/d3-shape/src/curve/step.js","../../node_modules/d3-axis/src/identity.js","../../node_modules/d3-axis/src/axis.js","../../node_modules/d3-zoom/src/transform.js","../../node_modules/billboard.js/dist-esm/billboard.js","../../public/js/app.ts"],"sourcesContent":["const t0 = new Date, t1 = new Date;\n\nexport function timeInterval(floori, offseti, count, field) {\n\n function interval(date) {\n return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date;\n }\n\n interval.floor = (date) => {\n return floori(date = new Date(+date)), date;\n };\n\n interval.ceil = (date) => {\n return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;\n };\n\n interval.round = (date) => {\n const d0 = interval(date), d1 = interval.ceil(date);\n return date - d0 < d1 - date ? d0 : d1;\n };\n\n interval.offset = (date, step) => {\n return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;\n };\n\n interval.range = (start, stop, step) => {\n const range = [];\n start = interval.ceil(start);\n step = step == null ? 1 : Math.floor(step);\n if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date\n let previous;\n do range.push(previous = new Date(+start)), offseti(start, step), floori(start);\n while (previous < start && start < stop);\n return range;\n };\n\n interval.filter = (test) => {\n return timeInterval((date) => {\n if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);\n }, (date, step) => {\n if (date >= date) {\n if (step < 0) while (++step <= 0) {\n while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty\n } else while (--step >= 0) {\n while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty\n }\n }\n });\n };\n\n if (count) {\n interval.count = (start, end) => {\n t0.setTime(+start), t1.setTime(+end);\n floori(t0), floori(t1);\n return Math.floor(count(t0, t1));\n };\n\n interval.every = (step) => {\n step = Math.floor(step);\n return !isFinite(step) || !(step > 0) ? null\n : !(step > 1) ? interval\n : interval.filter(field\n ? (d) => field(d) % step === 0\n : (d) => interval.count(0, d) % step === 0);\n };\n }\n\n return interval;\n}\n","import {timeInterval} from \"./interval.js\";\n\nexport const millisecond = timeInterval(() => {\n // noop\n}, (date, step) => {\n date.setTime(+date + step);\n}, (start, end) => {\n return end - start;\n});\n\n// An optimized implementation for this simple case.\nmillisecond.every = (k) => {\n k = Math.floor(k);\n if (!isFinite(k) || !(k > 0)) return null;\n if (!(k > 1)) return millisecond;\n return timeInterval((date) => {\n date.setTime(Math.floor(date / k) * k);\n }, (date, step) => {\n date.setTime(+date + step * k);\n }, (start, end) => {\n return (end - start) / k;\n });\n};\n\nexport const milliseconds = millisecond.range;\n","export const durationSecond = 1000;\nexport const durationMinute = durationSecond * 60;\nexport const durationHour = durationMinute * 60;\nexport const durationDay = durationHour * 24;\nexport const durationWeek = durationDay * 7;\nexport const durationMonth = durationDay * 30;\nexport const durationYear = durationDay * 365;\n","import {timeInterval} from \"./interval.js\";\nimport {durationSecond} from \"./duration.js\";\n\nexport const second = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds());\n}, (date, step) => {\n date.setTime(+date + step * durationSecond);\n}, (start, end) => {\n return (end - start) / durationSecond;\n}, (date) => {\n return date.getUTCSeconds();\n});\n\nexport const seconds = second.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationMinute, durationSecond} from \"./duration.js\";\n\nexport const timeMinute = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);\n}, (date, step) => {\n date.setTime(+date + step * durationMinute);\n}, (start, end) => {\n return (end - start) / durationMinute;\n}, (date) => {\n return date.getMinutes();\n});\n\nexport const timeMinutes = timeMinute.range;\n\nexport const utcMinute = timeInterval((date) => {\n date.setUTCSeconds(0, 0);\n}, (date, step) => {\n date.setTime(+date + step * durationMinute);\n}, (start, end) => {\n return (end - start) / durationMinute;\n}, (date) => {\n return date.getUTCMinutes();\n});\n\nexport const utcMinutes = utcMinute.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationHour, durationMinute, durationSecond} from \"./duration.js\";\n\nexport const timeHour = timeInterval((date) => {\n date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);\n}, (date, step) => {\n date.setTime(+date + step * durationHour);\n}, (start, end) => {\n return (end - start) / durationHour;\n}, (date) => {\n return date.getHours();\n});\n\nexport const timeHours = timeHour.range;\n\nexport const utcHour = timeInterval((date) => {\n date.setUTCMinutes(0, 0, 0);\n}, (date, step) => {\n date.setTime(+date + step * durationHour);\n}, (start, end) => {\n return (end - start) / durationHour;\n}, (date) => {\n return date.getUTCHours();\n});\n\nexport const utcHours = utcHour.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationDay, durationMinute} from \"./duration.js\";\n\nexport const timeDay = timeInterval(\n date => date.setHours(0, 0, 0, 0),\n (date, step) => date.setDate(date.getDate() + step),\n (start, end) => (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay,\n date => date.getDate() - 1\n);\n\nexport const timeDays = timeDay.range;\n\nexport const utcDay = timeInterval((date) => {\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step);\n}, (start, end) => {\n return (end - start) / durationDay;\n}, (date) => {\n return date.getUTCDate() - 1;\n});\n\nexport const utcDays = utcDay.range;\n\nexport const unixDay = timeInterval((date) => {\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step);\n}, (start, end) => {\n return (end - start) / durationDay;\n}, (date) => {\n return Math.floor(date / durationDay);\n});\n\nexport const unixDays = unixDay.range;\n","import {timeInterval} from \"./interval.js\";\nimport {durationMinute, durationWeek} from \"./duration.js\";\n\nfunction timeWeekday(i) {\n return timeInterval((date) => {\n date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);\n date.setHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setDate(date.getDate() + step * 7);\n }, (start, end) => {\n return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;\n });\n}\n\nexport const timeSunday = timeWeekday(0);\nexport const timeMonday = timeWeekday(1);\nexport const timeTuesday = timeWeekday(2);\nexport const timeWednesday = timeWeekday(3);\nexport const timeThursday = timeWeekday(4);\nexport const timeFriday = timeWeekday(5);\nexport const timeSaturday = timeWeekday(6);\n\nexport const timeSundays = timeSunday.range;\nexport const timeMondays = timeMonday.range;\nexport const timeTuesdays = timeTuesday.range;\nexport const timeWednesdays = timeWednesday.range;\nexport const timeThursdays = timeThursday.range;\nexport const timeFridays = timeFriday.range;\nexport const timeSaturdays = timeSaturday.range;\n\nfunction utcWeekday(i) {\n return timeInterval((date) => {\n date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);\n date.setUTCHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setUTCDate(date.getUTCDate() + step * 7);\n }, (start, end) => {\n return (end - start) / durationWeek;\n });\n}\n\nexport const utcSunday = utcWeekday(0);\nexport const utcMonday = utcWeekday(1);\nexport const utcTuesday = utcWeekday(2);\nexport const utcWednesday = utcWeekday(3);\nexport const utcThursday = utcWeekday(4);\nexport const utcFriday = utcWeekday(5);\nexport const utcSaturday = utcWeekday(6);\n\nexport const utcSundays = utcSunday.range;\nexport const utcMondays = utcMonday.range;\nexport const utcTuesdays = utcTuesday.range;\nexport const utcWednesdays = utcWednesday.range;\nexport const utcThursdays = utcThursday.range;\nexport const utcFridays = utcFriday.range;\nexport const utcSaturdays = utcSaturday.range;\n","import {timeInterval} from \"./interval.js\";\n\nexport const timeMonth = timeInterval((date) => {\n date.setDate(1);\n date.setHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setMonth(date.getMonth() + step);\n}, (start, end) => {\n return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;\n}, (date) => {\n return date.getMonth();\n});\n\nexport const timeMonths = timeMonth.range;\n\nexport const utcMonth = timeInterval((date) => {\n date.setUTCDate(1);\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCMonth(date.getUTCMonth() + step);\n}, (start, end) => {\n return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;\n}, (date) => {\n return date.getUTCMonth();\n});\n\nexport const utcMonths = utcMonth.range;\n","import {timeInterval} from \"./interval.js\";\n\nexport const timeYear = timeInterval((date) => {\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setFullYear(date.getFullYear() + step);\n}, (start, end) => {\n return end.getFullYear() - start.getFullYear();\n}, (date) => {\n return date.getFullYear();\n});\n\n// An optimized implementation for this simple case.\ntimeYear.every = (k) => {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {\n date.setFullYear(Math.floor(date.getFullYear() / k) * k);\n date.setMonth(0, 1);\n date.setHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setFullYear(date.getFullYear() + step * k);\n });\n};\n\nexport const timeYears = timeYear.range;\n\nexport const utcYear = timeInterval((date) => {\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n}, (date, step) => {\n date.setUTCFullYear(date.getUTCFullYear() + step);\n}, (start, end) => {\n return end.getUTCFullYear() - start.getUTCFullYear();\n}, (date) => {\n return date.getUTCFullYear();\n});\n\n// An optimized implementation for this simple case.\nutcYear.every = (k) => {\n return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {\n date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);\n date.setUTCMonth(0, 1);\n date.setUTCHours(0, 0, 0, 0);\n }, (date, step) => {\n date.setUTCFullYear(date.getUTCFullYear() + step * k);\n });\n};\n\nexport const utcYears = utcYear.range;\n","export default function ascending(a, b) {\n return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n","export default function descending(a, b) {\n return a == null || b == null ? NaN\n : b < a ? -1\n : b > a ? 1\n : b >= a ? 0\n : NaN;\n}\n","import ascending from \"./ascending.js\";\nimport descending from \"./descending.js\";\n\nexport default function bisector(f) {\n let compare1, compare2, delta;\n\n // If an accessor is specified, promote it to a comparator. In this case we\n // can test whether the search value is (self-) comparable. We can’t do this\n // for a comparator (except for specific, known comparators) because we can’t\n // tell if the comparator is symmetric, and an asymmetric comparator can’t be\n // used to test whether a single value is comparable.\n if (f.length !== 2) {\n compare1 = ascending;\n compare2 = (d, x) => ascending(f(d), x);\n delta = (d, x) => f(d) - x;\n } else {\n compare1 = f === ascending || f === descending ? f : zero;\n compare2 = f;\n delta = f;\n }\n\n function left(a, x, lo = 0, hi = a.length) {\n if (lo < hi) {\n if (compare1(x, x) !== 0) return hi;\n do {\n const mid = (lo + hi) >>> 1;\n if (compare2(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n } while (lo < hi);\n }\n return lo;\n }\n\n function right(a, x, lo = 0, hi = a.length) {\n if (lo < hi) {\n if (compare1(x, x) !== 0) return hi;\n do {\n const mid = (lo + hi) >>> 1;\n if (compare2(a[mid], x) <= 0) lo = mid + 1;\n else hi = mid;\n } while (lo < hi);\n }\n return lo;\n }\n\n function center(a, x, lo = 0, hi = a.length) {\n const i = left(a, x, lo, hi - 1);\n return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i;\n }\n\n return {left, center, right};\n}\n\nfunction zero() {\n return 0;\n}\n","export default function number(x) {\n return x === null ? NaN : +x;\n}\n\nexport function* numbers(values, valueof) {\n if (valueof === undefined) {\n for (let value of values) {\n if (value != null && (value = +value) >= value) {\n yield value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) {\n yield value;\n }\n }\n }\n}\n","import ascending from \"./ascending.js\";\nimport bisector from \"./bisector.js\";\nimport number from \"./number.js\";\n\nconst ascendingBisect = bisector(ascending);\nexport const bisectRight = ascendingBisect.right;\nexport const bisectLeft = ascendingBisect.left;\nexport const bisectCenter = bisector(number).center;\nexport default bisectRight;\n","export class InternMap extends Map {\n constructor(entries, key = keyof) {\n super();\n Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}});\n if (entries != null) for (const [key, value] of entries) this.set(key, value);\n }\n get(key) {\n return super.get(intern_get(this, key));\n }\n has(key) {\n return super.has(intern_get(this, key));\n }\n set(key, value) {\n return super.set(intern_set(this, key), value);\n }\n delete(key) {\n return super.delete(intern_delete(this, key));\n }\n}\n\nexport class InternSet extends Set {\n constructor(values, key = keyof) {\n super();\n Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}});\n if (values != null) for (const value of values) this.add(value);\n }\n has(value) {\n return super.has(intern_get(this, value));\n }\n add(value) {\n return super.add(intern_set(this, value));\n }\n delete(value) {\n return super.delete(intern_delete(this, value));\n }\n}\n\nfunction intern_get({_intern, _key}, value) {\n const key = _key(value);\n return _intern.has(key) ? _intern.get(key) : value;\n}\n\nfunction intern_set({_intern, _key}, value) {\n const key = _key(value);\n if (_intern.has(key)) return _intern.get(key);\n _intern.set(key, value);\n return value;\n}\n\nfunction intern_delete({_intern, _key}, value) {\n const key = _key(value);\n if (_intern.has(key)) {\n value = _intern.get(key);\n _intern.delete(key);\n }\n return value;\n}\n\nfunction keyof(value) {\n return value !== null && typeof value === \"object\" ? value.valueOf() : value;\n}\n","const e10 = Math.sqrt(50),\n e5 = Math.sqrt(10),\n e2 = Math.sqrt(2);\n\nfunction tickSpec(start, stop, count) {\n const step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log10(step)),\n error = step / Math.pow(10, power),\n factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1;\n let i1, i2, inc;\n if (power < 0) {\n inc = Math.pow(10, -power) / factor;\n i1 = Math.round(start * inc);\n i2 = Math.round(stop * inc);\n if (i1 / inc < start) ++i1;\n if (i2 / inc > stop) --i2;\n inc = -inc;\n } else {\n inc = Math.pow(10, power) * factor;\n i1 = Math.round(start / inc);\n i2 = Math.round(stop / inc);\n if (i1 * inc < start) ++i1;\n if (i2 * inc > stop) --i2;\n }\n if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2);\n return [i1, i2, inc];\n}\n\nexport default function ticks(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n if (!(count > 0)) return [];\n if (start === stop) return [start];\n const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count) : tickSpec(start, stop, count);\n if (!(i2 >= i1)) return [];\n const n = i2 - i1 + 1, ticks = new Array(n);\n if (reverse) {\n if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) / -inc;\n else for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) * inc;\n } else {\n if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) / -inc;\n else for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) * inc;\n }\n return ticks;\n}\n\nexport function tickIncrement(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n return tickSpec(start, stop, count)[2];\n}\n\nexport function tickStep(start, stop, count) {\n stop = +stop, start = +start, count = +count;\n const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count);\n return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc);\n}\n","import {bisector, tickStep} from \"d3-array\";\nimport {durationDay, durationHour, durationMinute, durationMonth, durationSecond, durationWeek, durationYear} from \"./duration.js\";\nimport {millisecond} from \"./millisecond.js\";\nimport {second} from \"./second.js\";\nimport {timeMinute, utcMinute} from \"./minute.js\";\nimport {timeHour, utcHour} from \"./hour.js\";\nimport {timeDay, unixDay} from \"./day.js\";\nimport {timeSunday, utcSunday} from \"./week.js\";\nimport {timeMonth, utcMonth} from \"./month.js\";\nimport {timeYear, utcYear} from \"./year.js\";\n\nfunction ticker(year, month, week, day, hour, minute) {\n\n const tickIntervals = [\n [second, 1, durationSecond],\n [second, 5, 5 * durationSecond],\n [second, 15, 15 * durationSecond],\n [second, 30, 30 * durationSecond],\n [minute, 1, durationMinute],\n [minute, 5, 5 * durationMinute],\n [minute, 15, 15 * durationMinute],\n [minute, 30, 30 * durationMinute],\n [ hour, 1, durationHour ],\n [ hour, 3, 3 * durationHour ],\n [ hour, 6, 6 * durationHour ],\n [ hour, 12, 12 * durationHour ],\n [ day, 1, durationDay ],\n [ day, 2, 2 * durationDay ],\n [ week, 1, durationWeek ],\n [ month, 1, durationMonth ],\n [ month, 3, 3 * durationMonth ],\n [ year, 1, durationYear ]\n ];\n\n function ticks(start, stop, count) {\n const reverse = stop < start;\n if (reverse) [start, stop] = [stop, start];\n const interval = count && typeof count.range === \"function\" ? count : tickInterval(start, stop, count);\n const ticks = interval ? interval.range(start, +stop + 1) : []; // inclusive stop\n return reverse ? ticks.reverse() : ticks;\n }\n\n function tickInterval(start, stop, count) {\n const target = Math.abs(stop - start) / count;\n const i = bisector(([,, step]) => step).right(tickIntervals, target);\n if (i === tickIntervals.length) return year.every(tickStep(start / durationYear, stop / durationYear, count));\n if (i === 0) return millisecond.every(Math.max(tickStep(start, stop, count), 1));\n const [t, step] = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];\n return t.every(step);\n }\n\n return [ticks, tickInterval];\n}\n\nconst [utcTicks, utcTickInterval] = ticker(utcYear, utcMonth, utcSunday, unixDay, utcHour, utcMinute);\nconst [timeTicks, timeTickInterval] = ticker(timeYear, timeMonth, timeSunday, timeDay, timeHour, timeMinute);\n\nexport {utcTicks, utcTickInterval, timeTicks, timeTickInterval};\n","import {\n timeDay,\n timeSunday,\n timeMonday,\n timeThursday,\n timeYear,\n utcDay,\n utcSunday,\n utcMonday,\n utcThursday,\n utcYear\n} from \"d3-time\";\n\nfunction localDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);\n date.setFullYear(d.y);\n return date;\n }\n return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);\n}\n\nfunction utcDate(d) {\n if (0 <= d.y && d.y < 100) {\n var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));\n date.setUTCFullYear(d.y);\n return date;\n }\n return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));\n}\n\nfunction newDate(y, m, d) {\n return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0};\n}\n\nexport default function formatLocale(locale) {\n var locale_dateTime = locale.dateTime,\n locale_date = locale.date,\n locale_time = locale.time,\n locale_periods = locale.periods,\n locale_weekdays = locale.days,\n locale_shortWeekdays = locale.shortDays,\n locale_months = locale.months,\n locale_shortMonths = locale.shortMonths;\n\n var periodRe = formatRe(locale_periods),\n periodLookup = formatLookup(locale_periods),\n weekdayRe = formatRe(locale_weekdays),\n weekdayLookup = formatLookup(locale_weekdays),\n shortWeekdayRe = formatRe(locale_shortWeekdays),\n shortWeekdayLookup = formatLookup(locale_shortWeekdays),\n monthRe = formatRe(locale_months),\n monthLookup = formatLookup(locale_months),\n shortMonthRe = formatRe(locale_shortMonths),\n shortMonthLookup = formatLookup(locale_shortMonths);\n\n var formats = {\n \"a\": formatShortWeekday,\n \"A\": formatWeekday,\n \"b\": formatShortMonth,\n \"B\": formatMonth,\n \"c\": null,\n \"d\": formatDayOfMonth,\n \"e\": formatDayOfMonth,\n \"f\": formatMicroseconds,\n \"g\": formatYearISO,\n \"G\": formatFullYearISO,\n \"H\": formatHour24,\n \"I\": formatHour12,\n \"j\": formatDayOfYear,\n \"L\": formatMilliseconds,\n \"m\": formatMonthNumber,\n \"M\": formatMinutes,\n \"p\": formatPeriod,\n \"q\": formatQuarter,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatSeconds,\n \"u\": formatWeekdayNumberMonday,\n \"U\": formatWeekNumberSunday,\n \"V\": formatWeekNumberISO,\n \"w\": formatWeekdayNumberSunday,\n \"W\": formatWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatYear,\n \"Y\": formatFullYear,\n \"Z\": formatZone,\n \"%\": formatLiteralPercent\n };\n\n var utcFormats = {\n \"a\": formatUTCShortWeekday,\n \"A\": formatUTCWeekday,\n \"b\": formatUTCShortMonth,\n \"B\": formatUTCMonth,\n \"c\": null,\n \"d\": formatUTCDayOfMonth,\n \"e\": formatUTCDayOfMonth,\n \"f\": formatUTCMicroseconds,\n \"g\": formatUTCYearISO,\n \"G\": formatUTCFullYearISO,\n \"H\": formatUTCHour24,\n \"I\": formatUTCHour12,\n \"j\": formatUTCDayOfYear,\n \"L\": formatUTCMilliseconds,\n \"m\": formatUTCMonthNumber,\n \"M\": formatUTCMinutes,\n \"p\": formatUTCPeriod,\n \"q\": formatUTCQuarter,\n \"Q\": formatUnixTimestamp,\n \"s\": formatUnixTimestampSeconds,\n \"S\": formatUTCSeconds,\n \"u\": formatUTCWeekdayNumberMonday,\n \"U\": formatUTCWeekNumberSunday,\n \"V\": formatUTCWeekNumberISO,\n \"w\": formatUTCWeekdayNumberSunday,\n \"W\": formatUTCWeekNumberMonday,\n \"x\": null,\n \"X\": null,\n \"y\": formatUTCYear,\n \"Y\": formatUTCFullYear,\n \"Z\": formatUTCZone,\n \"%\": formatLiteralPercent\n };\n\n var parses = {\n \"a\": parseShortWeekday,\n \"A\": parseWeekday,\n \"b\": parseShortMonth,\n \"B\": parseMonth,\n \"c\": parseLocaleDateTime,\n \"d\": parseDayOfMonth,\n \"e\": parseDayOfMonth,\n \"f\": parseMicroseconds,\n \"g\": parseYear,\n \"G\": parseFullYear,\n \"H\": parseHour24,\n \"I\": parseHour24,\n \"j\": parseDayOfYear,\n \"L\": parseMilliseconds,\n \"m\": parseMonthNumber,\n \"M\": parseMinutes,\n \"p\": parsePeriod,\n \"q\": parseQuarter,\n \"Q\": parseUnixTimestamp,\n \"s\": parseUnixTimestampSeconds,\n \"S\": parseSeconds,\n \"u\": parseWeekdayNumberMonday,\n \"U\": parseWeekNumberSunday,\n \"V\": parseWeekNumberISO,\n \"w\": parseWeekdayNumberSunday,\n \"W\": parseWeekNumberMonday,\n \"x\": parseLocaleDate,\n \"X\": parseLocaleTime,\n \"y\": parseYear,\n \"Y\": parseFullYear,\n \"Z\": parseZone,\n \"%\": parseLiteralPercent\n };\n\n // These recursive directive definitions must be deferred.\n formats.x = newFormat(locale_date, formats);\n formats.X = newFormat(locale_time, formats);\n formats.c = newFormat(locale_dateTime, formats);\n utcFormats.x = newFormat(locale_date, utcFormats);\n utcFormats.X = newFormat(locale_time, utcFormats);\n utcFormats.c = newFormat(locale_dateTime, utcFormats);\n\n function newFormat(specifier, formats) {\n return function(date) {\n var string = [],\n i = -1,\n j = 0,\n n = specifier.length,\n c,\n pad,\n format;\n\n if (!(date instanceof Date)) date = new Date(+date);\n\n while (++i < n) {\n if (specifier.charCodeAt(i) === 37) {\n string.push(specifier.slice(j, i));\n if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);\n else pad = c === \"e\" ? \" \" : \"0\";\n if (format = formats[c]) c = format(date, pad);\n string.push(c);\n j = i + 1;\n }\n }\n\n string.push(specifier.slice(j, i));\n return string.join(\"\");\n };\n }\n\n function newParse(specifier, Z) {\n return function(string) {\n var d = newDate(1900, undefined, 1),\n i = parseSpecifier(d, specifier, string += \"\", 0),\n week, day;\n if (i != string.length) return null;\n\n // If a UNIX timestamp is specified, return it.\n if (\"Q\" in d) return new Date(d.Q);\n if (\"s\" in d) return new Date(d.s * 1000 + (\"L\" in d ? d.L : 0));\n\n // If this is utcParse, never use the local timezone.\n if (Z && !(\"Z\" in d)) d.Z = 0;\n\n // The am-pm flag is 0 for AM, and 1 for PM.\n if (\"p\" in d) d.H = d.H % 12 + d.p * 12;\n\n // If the month was not specified, inherit from the quarter.\n if (d.m === undefined) d.m = \"q\" in d ? d.q : 0;\n\n // Convert day-of-week and week-of-year to day-of-year.\n if (\"V\" in d) {\n if (d.V < 1 || d.V > 53) return null;\n if (!(\"w\" in d)) d.w = 1;\n if (\"Z\" in d) {\n week = utcDate(newDate(d.y, 0, 1)), day = week.getUTCDay();\n week = day > 4 || day === 0 ? utcMonday.ceil(week) : utcMonday(week);\n week = utcDay.offset(week, (d.V - 1) * 7);\n d.y = week.getUTCFullYear();\n d.m = week.getUTCMonth();\n d.d = week.getUTCDate() + (d.w + 6) % 7;\n } else {\n week = localDate(newDate(d.y, 0, 1)), day = week.getDay();\n week = day > 4 || day === 0 ? timeMonday.ceil(week) : timeMonday(week);\n week = timeDay.offset(week, (d.V - 1) * 7);\n d.y = week.getFullYear();\n d.m = week.getMonth();\n d.d = week.getDate() + (d.w + 6) % 7;\n }\n } else if (\"W\" in d || \"U\" in d) {\n if (!(\"w\" in d)) d.w = \"u\" in d ? d.u % 7 : \"W\" in d ? 1 : 0;\n day = \"Z\" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();\n d.m = 0;\n d.d = \"W\" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;\n }\n\n // If a time zone is specified, all fields are interpreted as UTC and then\n // offset according to the specified time zone.\n if (\"Z\" in d) {\n d.H += d.Z / 100 | 0;\n d.M += d.Z % 100;\n return utcDate(d);\n }\n\n // Otherwise, all fields are in local time.\n return localDate(d);\n };\n }\n\n function parseSpecifier(d, specifier, string, j) {\n var i = 0,\n n = specifier.length,\n m = string.length,\n c,\n parse;\n\n while (i < n) {\n if (j >= m) return -1;\n c = specifier.charCodeAt(i++);\n if (c === 37) {\n c = specifier.charAt(i++);\n parse = parses[c in pads ? specifier.charAt(i++) : c];\n if (!parse || ((j = parse(d, string, j)) < 0)) return -1;\n } else if (c != string.charCodeAt(j++)) {\n return -1;\n }\n }\n\n return j;\n }\n\n function parsePeriod(d, string, i) {\n var n = periodRe.exec(string.slice(i));\n return n ? (d.p = periodLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseShortWeekday(d, string, i) {\n var n = shortWeekdayRe.exec(string.slice(i));\n return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseWeekday(d, string, i) {\n var n = weekdayRe.exec(string.slice(i));\n return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseShortMonth(d, string, i) {\n var n = shortMonthRe.exec(string.slice(i));\n return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseMonth(d, string, i) {\n var n = monthRe.exec(string.slice(i));\n return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;\n }\n\n function parseLocaleDateTime(d, string, i) {\n return parseSpecifier(d, locale_dateTime, string, i);\n }\n\n function parseLocaleDate(d, string, i) {\n return parseSpecifier(d, locale_date, string, i);\n }\n\n function parseLocaleTime(d, string, i) {\n return parseSpecifier(d, locale_time, string, i);\n }\n\n function formatShortWeekday(d) {\n return locale_shortWeekdays[d.getDay()];\n }\n\n function formatWeekday(d) {\n return locale_weekdays[d.getDay()];\n }\n\n function formatShortMonth(d) {\n return locale_shortMonths[d.getMonth()];\n }\n\n function formatMonth(d) {\n return locale_months[d.getMonth()];\n }\n\n function formatPeriod(d) {\n return locale_periods[+(d.getHours() >= 12)];\n }\n\n function formatQuarter(d) {\n return 1 + ~~(d.getMonth() / 3);\n }\n\n function formatUTCShortWeekday(d) {\n return locale_shortWeekdays[d.getUTCDay()];\n }\n\n function formatUTCWeekday(d) {\n return locale_weekdays[d.getUTCDay()];\n }\n\n function formatUTCShortMonth(d) {\n return locale_shortMonths[d.getUTCMonth()];\n }\n\n function formatUTCMonth(d) {\n return locale_months[d.getUTCMonth()];\n }\n\n function formatUTCPeriod(d) {\n return locale_periods[+(d.getUTCHours() >= 12)];\n }\n\n function formatUTCQuarter(d) {\n return 1 + ~~(d.getUTCMonth() / 3);\n }\n\n return {\n format: function(specifier) {\n var f = newFormat(specifier += \"\", formats);\n f.toString = function() { return specifier; };\n return f;\n },\n parse: function(specifier) {\n var p = newParse(specifier += \"\", false);\n p.toString = function() { return specifier; };\n return p;\n },\n utcFormat: function(specifier) {\n var f = newFormat(specifier += \"\", utcFormats);\n f.toString = function() { return specifier; };\n return f;\n },\n utcParse: function(specifier) {\n var p = newParse(specifier += \"\", true);\n p.toString = function() { return specifier; };\n return p;\n }\n };\n}\n\nvar pads = {\"-\": \"\", \"_\": \" \", \"0\": \"0\"},\n numberRe = /^\\s*\\d+/, // note: ignores next directive\n percentRe = /^%/,\n requoteRe = /[\\\\^$*+?|[\\]().{}]/g;\n\nfunction pad(value, fill, width) {\n var sign = value < 0 ? \"-\" : \"\",\n string = (sign ? -value : value) + \"\",\n length = string.length;\n return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);\n}\n\nfunction requote(s) {\n return s.replace(requoteRe, \"\\\\$&\");\n}\n\nfunction formatRe(names) {\n return new RegExp(\"^(?:\" + names.map(requote).join(\"|\") + \")\", \"i\");\n}\n\nfunction formatLookup(names) {\n return new Map(names.map((name, i) => [name.toLowerCase(), i]));\n}\n\nfunction parseWeekdayNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.w = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekdayNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.u = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberSunday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.U = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberISO(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.V = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseWeekNumberMonday(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.W = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseFullYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 4));\n return n ? (d.y = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;\n}\n\nfunction parseZone(d, string, i) {\n var n = /^(Z)|([+-]\\d\\d)(?::?(\\d\\d))?/.exec(string.slice(i, i + 6));\n return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || \"00\")), i + n[0].length) : -1;\n}\n\nfunction parseQuarter(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 1));\n return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;\n}\n\nfunction parseMonthNumber(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.m = n[0] - 1, i + n[0].length) : -1;\n}\n\nfunction parseDayOfMonth(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseDayOfYear(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseHour24(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.H = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMinutes(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.M = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 2));\n return n ? (d.S = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMilliseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 3));\n return n ? (d.L = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseMicroseconds(d, string, i) {\n var n = numberRe.exec(string.slice(i, i + 6));\n return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;\n}\n\nfunction parseLiteralPercent(d, string, i) {\n var n = percentRe.exec(string.slice(i, i + 1));\n return n ? i + n[0].length : -1;\n}\n\nfunction parseUnixTimestamp(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.Q = +n[0], i + n[0].length) : -1;\n}\n\nfunction parseUnixTimestampSeconds(d, string, i) {\n var n = numberRe.exec(string.slice(i));\n return n ? (d.s = +n[0], i + n[0].length) : -1;\n}\n\nfunction formatDayOfMonth(d, p) {\n return pad(d.getDate(), p, 2);\n}\n\nfunction formatHour24(d, p) {\n return pad(d.getHours(), p, 2);\n}\n\nfunction formatHour12(d, p) {\n return pad(d.getHours() % 12 || 12, p, 2);\n}\n\nfunction formatDayOfYear(d, p) {\n return pad(1 + timeDay.count(timeYear(d), d), p, 3);\n}\n\nfunction formatMilliseconds(d, p) {\n return pad(d.getMilliseconds(), p, 3);\n}\n\nfunction formatMicroseconds(d, p) {\n return formatMilliseconds(d, p) + \"000\";\n}\n\nfunction formatMonthNumber(d, p) {\n return pad(d.getMonth() + 1, p, 2);\n}\n\nfunction formatMinutes(d, p) {\n return pad(d.getMinutes(), p, 2);\n}\n\nfunction formatSeconds(d, p) {\n return pad(d.getSeconds(), p, 2);\n}\n\nfunction formatWeekdayNumberMonday(d) {\n var day = d.getDay();\n return day === 0 ? 7 : day;\n}\n\nfunction formatWeekNumberSunday(d, p) {\n return pad(timeSunday.count(timeYear(d) - 1, d), p, 2);\n}\n\nfunction dISO(d) {\n var day = d.getDay();\n return (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n}\n\nfunction formatWeekNumberISO(d, p) {\n d = dISO(d);\n return pad(timeThursday.count(timeYear(d), d) + (timeYear(d).getDay() === 4), p, 2);\n}\n\nfunction formatWeekdayNumberSunday(d) {\n return d.getDay();\n}\n\nfunction formatWeekNumberMonday(d, p) {\n return pad(timeMonday.count(timeYear(d) - 1, d), p, 2);\n}\n\nfunction formatYear(d, p) {\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatYearISO(d, p) {\n d = dISO(d);\n return pad(d.getFullYear() % 100, p, 2);\n}\n\nfunction formatFullYear(d, p) {\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatFullYearISO(d, p) {\n var day = d.getDay();\n d = (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);\n return pad(d.getFullYear() % 10000, p, 4);\n}\n\nfunction formatZone(d) {\n var z = d.getTimezoneOffset();\n return (z > 0 ? \"-\" : (z *= -1, \"+\"))\n + pad(z / 60 | 0, \"0\", 2)\n + pad(z % 60, \"0\", 2);\n}\n\nfunction formatUTCDayOfMonth(d, p) {\n return pad(d.getUTCDate(), p, 2);\n}\n\nfunction formatUTCHour24(d, p) {\n return pad(d.getUTCHours(), p, 2);\n}\n\nfunction formatUTCHour12(d, p) {\n return pad(d.getUTCHours() % 12 || 12, p, 2);\n}\n\nfunction formatUTCDayOfYear(d, p) {\n return pad(1 + utcDay.count(utcYear(d), d), p, 3);\n}\n\nfunction formatUTCMilliseconds(d, p) {\n return pad(d.getUTCMilliseconds(), p, 3);\n}\n\nfunction formatUTCMicroseconds(d, p) {\n return formatUTCMilliseconds(d, p) + \"000\";\n}\n\nfunction formatUTCMonthNumber(d, p) {\n return pad(d.getUTCMonth() + 1, p, 2);\n}\n\nfunction formatUTCMinutes(d, p) {\n return pad(d.getUTCMinutes(), p, 2);\n}\n\nfunction formatUTCSeconds(d, p) {\n return pad(d.getUTCSeconds(), p, 2);\n}\n\nfunction formatUTCWeekdayNumberMonday(d) {\n var dow = d.getUTCDay();\n return dow === 0 ? 7 : dow;\n}\n\nfunction formatUTCWeekNumberSunday(d, p) {\n return pad(utcSunday.count(utcYear(d) - 1, d), p, 2);\n}\n\nfunction UTCdISO(d) {\n var day = d.getUTCDay();\n return (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n}\n\nfunction formatUTCWeekNumberISO(d, p) {\n d = UTCdISO(d);\n return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);\n}\n\nfunction formatUTCWeekdayNumberSunday(d) {\n return d.getUTCDay();\n}\n\nfunction formatUTCWeekNumberMonday(d, p) {\n return pad(utcMonday.count(utcYear(d) - 1, d), p, 2);\n}\n\nfunction formatUTCYear(d, p) {\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCYearISO(d, p) {\n d = UTCdISO(d);\n return pad(d.getUTCFullYear() % 100, p, 2);\n}\n\nfunction formatUTCFullYear(d, p) {\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCFullYearISO(d, p) {\n var day = d.getUTCDay();\n d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);\n return pad(d.getUTCFullYear() % 10000, p, 4);\n}\n\nfunction formatUTCZone() {\n return \"+0000\";\n}\n\nfunction formatLiteralPercent() {\n return \"%\";\n}\n\nfunction formatUnixTimestamp(d) {\n return +d;\n}\n\nfunction formatUnixTimestampSeconds(d) {\n return Math.floor(+d / 1000);\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var timeFormat;\nexport var timeParse;\nexport var utcFormat;\nexport var utcParse;\n\ndefaultLocale({\n dateTime: \"%x, %X\",\n date: \"%-m/%-d/%Y\",\n time: \"%-I:%M:%S %p\",\n periods: [\"AM\", \"PM\"],\n days: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n shortDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n months: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n shortMonths: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n timeFormat = locale.format;\n timeParse = locale.parse;\n utcFormat = locale.utcFormat;\n utcParse = locale.utcParse;\n return locale;\n}\n","export var xhtml = \"http://www.w3.org/1999/xhtml\";\n\nexport default {\n svg: \"http://www.w3.org/2000/svg\",\n xhtml: xhtml,\n xlink: \"http://www.w3.org/1999/xlink\",\n xml: \"http://www.w3.org/XML/1998/namespace\",\n xmlns: \"http://www.w3.org/2000/xmlns/\"\n};\n","import namespaces from \"./namespaces.js\";\n\nexport default function(name) {\n var prefix = name += \"\", i = prefix.indexOf(\":\");\n if (i >= 0 && (prefix = name.slice(0, i)) !== \"xmlns\") name = name.slice(i + 1);\n return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; // eslint-disable-line no-prototype-builtins\n}\n","import namespace from \"./namespace.js\";\nimport {xhtml} from \"./namespaces.js\";\n\nfunction creatorInherit(name) {\n return function() {\n var document = this.ownerDocument,\n uri = this.namespaceURI;\n return uri === xhtml && document.documentElement.namespaceURI === xhtml\n ? document.createElement(name)\n : document.createElementNS(uri, name);\n };\n}\n\nfunction creatorFixed(fullname) {\n return function() {\n return this.ownerDocument.createElementNS(fullname.space, fullname.local);\n };\n}\n\nexport default function(name) {\n var fullname = namespace(name);\n return (fullname.local\n ? creatorFixed\n : creatorInherit)(fullname);\n}\n","function none() {}\n\nexport default function(selector) {\n return selector == null ? none : function() {\n return this.querySelector(selector);\n };\n}\n","import {Selection} from \"./index.js\";\nimport selector from \"../selector.js\";\n\nexport default function(select) {\n if (typeof select !== \"function\") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if (\"__data__\" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n","// Given something array like (or null), returns something that is strictly an\n// array. This is used to ensure that array-like objects passed to d3.selectAll\n// or selection.selectAll are converted into proper arrays when creating a\n// selection; we don’t ever want to create a selection backed by a live\n// HTMLCollection or NodeList. However, note that selection.selectAll will use a\n// static NodeList as a group, since it safely derived from querySelectorAll.\nexport default function array(x) {\n return x == null ? [] : Array.isArray(x) ? x : Array.from(x);\n}\n","function empty() {\n return [];\n}\n\nexport default function(selector) {\n return selector == null ? empty : function() {\n return this.querySelectorAll(selector);\n };\n}\n","import {Selection} from \"./index.js\";\nimport array from \"../array.js\";\nimport selectorAll from \"../selectorAll.js\";\n\nfunction arrayAll(select) {\n return function() {\n return array(select.apply(this, arguments));\n };\n}\n\nexport default function(select) {\n if (typeof select === \"function\") select = arrayAll(select);\n else select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n subgroups.push(select.call(node, node.__data__, i, group));\n parents.push(node);\n }\n }\n }\n\n return new Selection(subgroups, parents);\n}\n","export default function(selector) {\n return function() {\n return this.matches(selector);\n };\n}\n\nexport function childMatcher(selector) {\n return function(node) {\n return node.matches(selector);\n };\n}\n\n","import {childMatcher} from \"../matcher.js\";\n\nvar find = Array.prototype.find;\n\nfunction childFind(match) {\n return function() {\n return find.call(this.children, match);\n };\n}\n\nfunction childFirst() {\n return this.firstElementChild;\n}\n\nexport default function(match) {\n return this.select(match == null ? childFirst\n : childFind(typeof match === \"function\" ? match : childMatcher(match)));\n}\n","import {childMatcher} from \"../matcher.js\";\n\nvar filter = Array.prototype.filter;\n\nfunction children() {\n return Array.from(this.children);\n}\n\nfunction childrenFilter(match) {\n return function() {\n return filter.call(this.children, match);\n };\n}\n\nexport default function(match) {\n return this.selectAll(match == null ? children\n : childrenFilter(typeof match === \"function\" ? match : childMatcher(match)));\n}\n","import {Selection} from \"./index.js\";\nimport matcher from \"../matcher.js\";\n\nexport default function(match) {\n if (typeof match !== \"function\") match = matcher(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n","export default function(update) {\n return new Array(update.length);\n}\n","import sparse from \"./sparse.js\";\nimport {Selection} from \"./index.js\";\n\nexport default function() {\n return new Selection(this._enter || this._groups.map(sparse), this._parents);\n}\n\nexport function EnterNode(parent, datum) {\n this.ownerDocument = parent.ownerDocument;\n this.namespaceURI = parent.namespaceURI;\n this._next = null;\n this._parent = parent;\n this.__data__ = datum;\n}\n\nEnterNode.prototype = {\n constructor: EnterNode,\n appendChild: function(child) { return this._parent.insertBefore(child, this._next); },\n insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },\n querySelector: function(selector) { return this._parent.querySelector(selector); },\n querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }\n};\n","export default function(x) {\n return function() {\n return x;\n };\n}\n","import {Selection} from \"./index.js\";\nimport {EnterNode} from \"./enter.js\";\nimport constant from \"../constant.js\";\n\nfunction bindIndex(parent, group, enter, update, exit, data) {\n var i = 0,\n node,\n groupLength = group.length,\n dataLength = data.length;\n\n // Put any non-null nodes that fit into update.\n // Put any null nodes into enter.\n // Put any remaining data into enter.\n for (; i < dataLength; ++i) {\n if (node = group[i]) {\n node.__data__ = data[i];\n update[i] = node;\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n }\n\n // Put any non-null nodes that don’t fit into exit.\n for (; i < groupLength; ++i) {\n if (node = group[i]) {\n exit[i] = node;\n }\n }\n}\n\nfunction bindKey(parent, group, enter, update, exit, data, key) {\n var i,\n node,\n nodeByKeyValue = new Map,\n groupLength = group.length,\n dataLength = data.length,\n keyValues = new Array(groupLength),\n keyValue;\n\n // Compute the key for each node.\n // If multiple nodes have the same key, the duplicates are added to exit.\n for (i = 0; i < groupLength; ++i) {\n if (node = group[i]) {\n keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + \"\";\n if (nodeByKeyValue.has(keyValue)) {\n exit[i] = node;\n } else {\n nodeByKeyValue.set(keyValue, node);\n }\n }\n }\n\n // Compute the key for each datum.\n // If there a node associated with this key, join and add it to update.\n // If there is not (or the key is a duplicate), add it to enter.\n for (i = 0; i < dataLength; ++i) {\n keyValue = key.call(parent, data[i], i, data) + \"\";\n if (node = nodeByKeyValue.get(keyValue)) {\n update[i] = node;\n node.__data__ = data[i];\n nodeByKeyValue.delete(keyValue);\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n }\n\n // Add any remaining nodes that were not bound to data to exit.\n for (i = 0; i < groupLength; ++i) {\n if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) {\n exit[i] = node;\n }\n }\n}\n\nfunction datum(node) {\n return node.__data__;\n}\n\nexport default function(value, key) {\n if (!arguments.length) return Array.from(this, datum);\n\n var bind = key ? bindKey : bindIndex,\n parents = this._parents,\n groups = this._groups;\n\n if (typeof value !== \"function\") value = constant(value);\n\n for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {\n var parent = parents[j],\n group = groups[j],\n groupLength = group.length,\n data = arraylike(value.call(parent, parent && parent.__data__, j, parents)),\n dataLength = data.length,\n enterGroup = enter[j] = new Array(dataLength),\n updateGroup = update[j] = new Array(dataLength),\n exitGroup = exit[j] = new Array(groupLength);\n\n bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);\n\n // Now connect the enter nodes to their following update node, such that\n // appendChild can insert the materialized enter node before this node,\n // rather than at the end of the parent node.\n for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {\n if (previous = enterGroup[i0]) {\n if (i0 >= i1) i1 = i0 + 1;\n while (!(next = updateGroup[i1]) && ++i1 < dataLength);\n previous._next = next || null;\n }\n }\n }\n\n update = new Selection(update, parents);\n update._enter = enter;\n update._exit = exit;\n return update;\n}\n\n// Given some data, this returns an array-like view of it: an object that\n// exposes a length property and allows numeric indexing. Note that unlike\n// selectAll, this isn’t worried about “live” collections because the resulting\n// array will only be used briefly while data is being bound. (It is possible to\n// cause the data to change while iterating by using a key function, but please\n// don’t; we’d rather avoid a gratuitous copy.)\nfunction arraylike(data) {\n return typeof data === \"object\" && \"length\" in data\n ? data // Array, TypedArray, NodeList, array-like\n : Array.from(data); // Map, Set, iterable, string, or anything else\n}\n","import sparse from \"./sparse.js\";\nimport {Selection} from \"./index.js\";\n\nexport default function() {\n return new Selection(this._exit || this._groups.map(sparse), this._parents);\n}\n","export default function(onenter, onupdate, onexit) {\n var enter = this.enter(), update = this, exit = this.exit();\n if (typeof onenter === \"function\") {\n enter = onenter(enter);\n if (enter) enter = enter.selection();\n } else {\n enter = enter.append(onenter + \"\");\n }\n if (onupdate != null) {\n update = onupdate(update);\n if (update) update = update.selection();\n }\n if (onexit == null) exit.remove(); else onexit(exit);\n return enter && update ? enter.merge(update).order() : update;\n}\n","import {Selection} from \"./index.js\";\n\nexport default function(context) {\n var selection = context.selection ? context.selection() : context;\n\n for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Selection(merges, this._parents);\n}\n","export default function() {\n\n for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {\n for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {\n if (node = group[i]) {\n if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);\n next = node;\n }\n }\n }\n\n return this;\n}\n","import {Selection} from \"./index.js\";\n\nexport default function(compare) {\n if (!compare) compare = ascending;\n\n function compareNode(a, b) {\n return a && b ? compare(a.__data__, b.__data__) : !a - !b;\n }\n\n for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n sortgroup[i] = node;\n }\n }\n sortgroup.sort(compareNode);\n }\n\n return new Selection(sortgroups, this._parents).order();\n}\n\nfunction ascending(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n","export default function() {\n var callback = arguments[0];\n arguments[0] = this;\n callback.apply(null, arguments);\n return this;\n}\n","export default function() {\n return Array.from(this);\n}\n","export default function() {\n\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {\n var node = group[i];\n if (node) return node;\n }\n }\n\n return null;\n}\n","export default function() {\n let size = 0;\n for (const node of this) ++size; // eslint-disable-line no-unused-vars\n return size;\n}\n","export default function() {\n return !this.node();\n}\n","export default function(callback) {\n\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n if (node = group[i]) callback.call(node, node.__data__, i, group);\n }\n }\n\n return this;\n}\n","import namespace from \"../namespace.js\";\n\nfunction attrRemove(name) {\n return function() {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS(fullname) {\n return function() {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant(name, value) {\n return function() {\n this.setAttribute(name, value);\n };\n}\n\nfunction attrConstantNS(fullname, value) {\n return function() {\n this.setAttributeNS(fullname.space, fullname.local, value);\n };\n}\n\nfunction attrFunction(name, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttribute(name);\n else this.setAttribute(name, v);\n };\n}\n\nfunction attrFunctionNS(fullname, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttributeNS(fullname.space, fullname.local);\n else this.setAttributeNS(fullname.space, fullname.local, v);\n };\n}\n\nexport default function(name, value) {\n var fullname = namespace(name);\n\n if (arguments.length < 2) {\n var node = this.node();\n return fullname.local\n ? node.getAttributeNS(fullname.space, fullname.local)\n : node.getAttribute(fullname);\n }\n\n return this.each((value == null\n ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === \"function\"\n ? (fullname.local ? attrFunctionNS : attrFunction)\n : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));\n}\n","export default function(node) {\n return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node\n || (node.document && node) // node is a Window\n || node.defaultView; // node is a Document\n}\n","import defaultView from \"../window.js\";\n\nfunction styleRemove(name) {\n return function() {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant(name, value, priority) {\n return function() {\n this.style.setProperty(name, value, priority);\n };\n}\n\nfunction styleFunction(name, value, priority) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) this.style.removeProperty(name);\n else this.style.setProperty(name, v, priority);\n };\n}\n\nexport default function(name, value, priority) {\n return arguments.length > 1\n ? this.each((value == null\n ? styleRemove : typeof value === \"function\"\n ? styleFunction\n : styleConstant)(name, value, priority == null ? \"\" : priority))\n : styleValue(this.node(), name);\n}\n\nexport function styleValue(node, name) {\n return node.style.getPropertyValue(name)\n || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);\n}\n","function propertyRemove(name) {\n return function() {\n delete this[name];\n };\n}\n\nfunction propertyConstant(name, value) {\n return function() {\n this[name] = value;\n };\n}\n\nfunction propertyFunction(name, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (v == null) delete this[name];\n else this[name] = v;\n };\n}\n\nexport default function(name, value) {\n return arguments.length > 1\n ? this.each((value == null\n ? propertyRemove : typeof value === \"function\"\n ? propertyFunction\n : propertyConstant)(name, value))\n : this.node()[name];\n}\n","function classArray(string) {\n return string.trim().split(/^|\\s+/);\n}\n\nfunction classList(node) {\n return node.classList || new ClassList(node);\n}\n\nfunction ClassList(node) {\n this._node = node;\n this._names = classArray(node.getAttribute(\"class\") || \"\");\n}\n\nClassList.prototype = {\n add: function(name) {\n var i = this._names.indexOf(name);\n if (i < 0) {\n this._names.push(name);\n this._node.setAttribute(\"class\", this._names.join(\" \"));\n }\n },\n remove: function(name) {\n var i = this._names.indexOf(name);\n if (i >= 0) {\n this._names.splice(i, 1);\n this._node.setAttribute(\"class\", this._names.join(\" \"));\n }\n },\n contains: function(name) {\n return this._names.indexOf(name) >= 0;\n }\n};\n\nfunction classedAdd(node, names) {\n var list = classList(node), i = -1, n = names.length;\n while (++i < n) list.add(names[i]);\n}\n\nfunction classedRemove(node, names) {\n var list = classList(node), i = -1, n = names.length;\n while (++i < n) list.remove(names[i]);\n}\n\nfunction classedTrue(names) {\n return function() {\n classedAdd(this, names);\n };\n}\n\nfunction classedFalse(names) {\n return function() {\n classedRemove(this, names);\n };\n}\n\nfunction classedFunction(names, value) {\n return function() {\n (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);\n };\n}\n\nexport default function(name, value) {\n var names = classArray(name + \"\");\n\n if (arguments.length < 2) {\n var list = classList(this.node()), i = -1, n = names.length;\n while (++i < n) if (!list.contains(names[i])) return false;\n return true;\n }\n\n return this.each((typeof value === \"function\"\n ? classedFunction : value\n ? classedTrue\n : classedFalse)(names, value));\n}\n","function textRemove() {\n this.textContent = \"\";\n}\n\nfunction textConstant(value) {\n return function() {\n this.textContent = value;\n };\n}\n\nfunction textFunction(value) {\n return function() {\n var v = value.apply(this, arguments);\n this.textContent = v == null ? \"\" : v;\n };\n}\n\nexport default function(value) {\n return arguments.length\n ? this.each(value == null\n ? textRemove : (typeof value === \"function\"\n ? textFunction\n : textConstant)(value))\n : this.node().textContent;\n}\n","function htmlRemove() {\n this.innerHTML = \"\";\n}\n\nfunction htmlConstant(value) {\n return function() {\n this.innerHTML = value;\n };\n}\n\nfunction htmlFunction(value) {\n return function() {\n var v = value.apply(this, arguments);\n this.innerHTML = v == null ? \"\" : v;\n };\n}\n\nexport default function(value) {\n return arguments.length\n ? this.each(value == null\n ? htmlRemove : (typeof value === \"function\"\n ? htmlFunction\n : htmlConstant)(value))\n : this.node().innerHTML;\n}\n","function raise() {\n if (this.nextSibling) this.parentNode.appendChild(this);\n}\n\nexport default function() {\n return this.each(raise);\n}\n","function lower() {\n if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);\n}\n\nexport default function() {\n return this.each(lower);\n}\n","import creator from \"../creator.js\";\n\nexport default function(name) {\n var create = typeof name === \"function\" ? name : creator(name);\n return this.select(function() {\n return this.appendChild(create.apply(this, arguments));\n });\n}\n","import creator from \"../creator.js\";\nimport selector from \"../selector.js\";\n\nfunction constantNull() {\n return null;\n}\n\nexport default function(name, before) {\n var create = typeof name === \"function\" ? name : creator(name),\n select = before == null ? constantNull : typeof before === \"function\" ? before : selector(before);\n return this.select(function() {\n return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);\n });\n}\n","function remove() {\n var parent = this.parentNode;\n if (parent) parent.removeChild(this);\n}\n\nexport default function() {\n return this.each(remove);\n}\n","function selection_cloneShallow() {\n var clone = this.cloneNode(false), parent = this.parentNode;\n return parent ? parent.insertBefore(clone, this.nextSibling) : clone;\n}\n\nfunction selection_cloneDeep() {\n var clone = this.cloneNode(true), parent = this.parentNode;\n return parent ? parent.insertBefore(clone, this.nextSibling) : clone;\n}\n\nexport default function(deep) {\n return this.select(deep ? selection_cloneDeep : selection_cloneShallow);\n}\n","export default function(value) {\n return arguments.length\n ? this.property(\"__data__\", value)\n : this.node().__data__;\n}\n","function contextListener(listener) {\n return function(event) {\n listener.call(this, event, this.__data__);\n };\n}\n\nfunction parseTypenames(typenames) {\n return typenames.trim().split(/^|\\s+/).map(function(t) {\n var name = \"\", i = t.indexOf(\".\");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n return {type: t, name: name};\n });\n}\n\nfunction onRemove(typename) {\n return function() {\n var on = this.__on;\n if (!on) return;\n for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {\n if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {\n this.removeEventListener(o.type, o.listener, o.options);\n } else {\n on[++i] = o;\n }\n }\n if (++i) on.length = i;\n else delete this.__on;\n };\n}\n\nfunction onAdd(typename, value, options) {\n return function() {\n var on = this.__on, o, listener = contextListener(value);\n if (on) for (var j = 0, m = on.length; j < m; ++j) {\n if ((o = on[j]).type === typename.type && o.name === typename.name) {\n this.removeEventListener(o.type, o.listener, o.options);\n this.addEventListener(o.type, o.listener = listener, o.options = options);\n o.value = value;\n return;\n }\n }\n this.addEventListener(typename.type, listener, options);\n o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options};\n if (!on) this.__on = [o];\n else on.push(o);\n };\n}\n\nexport default function(typename, value, options) {\n var typenames = parseTypenames(typename + \"\"), i, n = typenames.length, t;\n\n if (arguments.length < 2) {\n var on = this.node().__on;\n if (on) for (var j = 0, m = on.length, o; j < m; ++j) {\n for (i = 0, o = on[j]; i < n; ++i) {\n if ((t = typenames[i]).type === o.type && t.name === o.name) {\n return o.value;\n }\n }\n }\n return;\n }\n\n on = value ? onAdd : onRemove;\n for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options));\n return this;\n}\n","import defaultView from \"../window.js\";\n\nfunction dispatchEvent(node, type, params) {\n var window = defaultView(node),\n event = window.CustomEvent;\n\n if (typeof event === \"function\") {\n event = new event(type, params);\n } else {\n event = window.document.createEvent(\"Event\");\n if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;\n else event.initEvent(type, false, false);\n }\n\n node.dispatchEvent(event);\n}\n\nfunction dispatchConstant(type, params) {\n return function() {\n return dispatchEvent(this, type, params);\n };\n}\n\nfunction dispatchFunction(type, params) {\n return function() {\n return dispatchEvent(this, type, params.apply(this, arguments));\n };\n}\n\nexport default function(type, params) {\n return this.each((typeof params === \"function\"\n ? dispatchFunction\n : dispatchConstant)(type, params));\n}\n","export default function*() {\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n if (node = group[i]) yield node;\n }\n }\n}\n","import selection_select from \"./select.js\";\nimport selection_selectAll from \"./selectAll.js\";\nimport selection_selectChild from \"./selectChild.js\";\nimport selection_selectChildren from \"./selectChildren.js\";\nimport selection_filter from \"./filter.js\";\nimport selection_data from \"./data.js\";\nimport selection_enter from \"./enter.js\";\nimport selection_exit from \"./exit.js\";\nimport selection_join from \"./join.js\";\nimport selection_merge from \"./merge.js\";\nimport selection_order from \"./order.js\";\nimport selection_sort from \"./sort.js\";\nimport selection_call from \"./call.js\";\nimport selection_nodes from \"./nodes.js\";\nimport selection_node from \"./node.js\";\nimport selection_size from \"./size.js\";\nimport selection_empty from \"./empty.js\";\nimport selection_each from \"./each.js\";\nimport selection_attr from \"./attr.js\";\nimport selection_style from \"./style.js\";\nimport selection_property from \"./property.js\";\nimport selection_classed from \"./classed.js\";\nimport selection_text from \"./text.js\";\nimport selection_html from \"./html.js\";\nimport selection_raise from \"./raise.js\";\nimport selection_lower from \"./lower.js\";\nimport selection_append from \"./append.js\";\nimport selection_insert from \"./insert.js\";\nimport selection_remove from \"./remove.js\";\nimport selection_clone from \"./clone.js\";\nimport selection_datum from \"./datum.js\";\nimport selection_on from \"./on.js\";\nimport selection_dispatch from \"./dispatch.js\";\nimport selection_iterator from \"./iterator.js\";\n\nexport var root = [null];\n\nexport function Selection(groups, parents) {\n this._groups = groups;\n this._parents = parents;\n}\n\nfunction selection() {\n return new Selection([[document.documentElement]], root);\n}\n\nfunction selection_selection() {\n return this;\n}\n\nSelection.prototype = selection.prototype = {\n constructor: Selection,\n select: selection_select,\n selectAll: selection_selectAll,\n selectChild: selection_selectChild,\n selectChildren: selection_selectChildren,\n filter: selection_filter,\n data: selection_data,\n enter: selection_enter,\n exit: selection_exit,\n join: selection_join,\n merge: selection_merge,\n selection: selection_selection,\n order: selection_order,\n sort: selection_sort,\n call: selection_call,\n nodes: selection_nodes,\n node: selection_node,\n size: selection_size,\n empty: selection_empty,\n each: selection_each,\n attr: selection_attr,\n style: selection_style,\n property: selection_property,\n classed: selection_classed,\n text: selection_text,\n html: selection_html,\n raise: selection_raise,\n lower: selection_lower,\n append: selection_append,\n insert: selection_insert,\n remove: selection_remove,\n clone: selection_clone,\n datum: selection_datum,\n on: selection_on,\n dispatch: selection_dispatch,\n [Symbol.iterator]: selection_iterator\n};\n\nexport default selection;\n","import {Selection, root} from \"./selection/index.js\";\n\nexport default function(selector) {\n return typeof selector === \"string\"\n ? new Selection([[document.querySelector(selector)]], [document.documentElement])\n : new Selection([[selector]], root);\n}\n","export default function(event) {\n let sourceEvent;\n while (sourceEvent = event.sourceEvent) event = sourceEvent;\n return event;\n}\n","import sourceEvent from \"./sourceEvent.js\";\n\nexport default function(event, node) {\n event = sourceEvent(event);\n if (node === undefined) node = event.currentTarget;\n if (node) {\n var svg = node.ownerSVGElement || node;\n if (svg.createSVGPoint) {\n var point = svg.createSVGPoint();\n point.x = event.clientX, point.y = event.clientY;\n point = point.matrixTransform(node.getScreenCTM().inverse());\n return [point.x, point.y];\n }\n if (node.getBoundingClientRect) {\n var rect = node.getBoundingClientRect();\n return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];\n }\n }\n return [event.pageX, event.pageY];\n}\n","import array from \"./array.js\";\nimport {Selection, root} from \"./selection/index.js\";\n\nexport default function(selector) {\n return typeof selector === \"string\"\n ? new Selection([document.querySelectorAll(selector)], [document.documentElement])\n : new Selection([array(selector)], root);\n}\n","var noop = {value: () => {}};\n\nfunction dispatch() {\n for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {\n if (!(t = arguments[i] + \"\") || (t in _) || /[\\s.]/.test(t)) throw new Error(\"illegal type: \" + t);\n _[t] = [];\n }\n return new Dispatch(_);\n}\n\nfunction Dispatch(_) {\n this._ = _;\n}\n\nfunction parseTypenames(typenames, types) {\n return typenames.trim().split(/^|\\s+/).map(function(t) {\n var name = \"\", i = t.indexOf(\".\");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n if (t && !types.hasOwnProperty(t)) throw new Error(\"unknown type: \" + t);\n return {type: t, name: name};\n });\n}\n\nDispatch.prototype = dispatch.prototype = {\n constructor: Dispatch,\n on: function(typename, callback) {\n var _ = this._,\n T = parseTypenames(typename + \"\", _),\n t,\n i = -1,\n n = T.length;\n\n // If no callback was specified, return the callback of the given type and name.\n if (arguments.length < 2) {\n while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;\n return;\n }\n\n // If a type was specified, set the callback for the given type and name.\n // Otherwise, if a null callback was specified, remove callbacks of the given name.\n if (callback != null && typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n while (++i < n) {\n if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);\n else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);\n }\n\n return this;\n },\n copy: function() {\n var copy = {}, _ = this._;\n for (var t in _) copy[t] = _[t].slice();\n return new Dispatch(copy);\n },\n call: function(type, that) {\n if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];\n if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n },\n apply: function(type, that, args) {\n if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n }\n};\n\nfunction get(type, name) {\n for (var i = 0, n = type.length, c; i < n; ++i) {\n if ((c = type[i]).name === name) {\n return c.value;\n }\n }\n}\n\nfunction set(type, name, callback) {\n for (var i = 0, n = type.length; i < n; ++i) {\n if (type[i].name === name) {\n type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));\n break;\n }\n }\n if (callback != null) type.push({name: name, value: callback});\n return type;\n}\n\nexport default dispatch;\n","// These are typically used in conjunction with noevent to ensure that we can\n// preventDefault on the event.\nexport const nonpassive = {passive: false};\nexport const nonpassivecapture = {capture: true, passive: false};\n\nexport function nopropagation(event) {\n event.stopImmediatePropagation();\n}\n\nexport default function(event) {\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n","import {select} from \"d3-selection\";\nimport noevent, {nonpassivecapture} from \"./noevent.js\";\n\nexport default function(view) {\n var root = view.document.documentElement,\n selection = select(view).on(\"dragstart.drag\", noevent, nonpassivecapture);\n if (\"onselectstart\" in root) {\n selection.on(\"selectstart.drag\", noevent, nonpassivecapture);\n } else {\n root.__noselect = root.style.MozUserSelect;\n root.style.MozUserSelect = \"none\";\n }\n}\n\nexport function yesdrag(view, noclick) {\n var root = view.document.documentElement,\n selection = select(view).on(\"dragstart.drag\", null);\n if (noclick) {\n selection.on(\"click.drag\", noevent, nonpassivecapture);\n setTimeout(function() { selection.on(\"click.drag\", null); }, 0);\n }\n if (\"onselectstart\" in root) {\n selection.on(\"selectstart.drag\", null);\n } else {\n root.style.MozUserSelect = root.__noselect;\n delete root.__noselect;\n }\n}\n","export default x => () => x;\n","export default function DragEvent(type, {\n sourceEvent,\n subject,\n target,\n identifier,\n active,\n x, y, dx, dy,\n dispatch\n}) {\n Object.defineProperties(this, {\n type: {value: type, enumerable: true, configurable: true},\n sourceEvent: {value: sourceEvent, enumerable: true, configurable: true},\n subject: {value: subject, enumerable: true, configurable: true},\n target: {value: target, enumerable: true, configurable: true},\n identifier: {value: identifier, enumerable: true, configurable: true},\n active: {value: active, enumerable: true, configurable: true},\n x: {value: x, enumerable: true, configurable: true},\n y: {value: y, enumerable: true, configurable: true},\n dx: {value: dx, enumerable: true, configurable: true},\n dy: {value: dy, enumerable: true, configurable: true},\n _: {value: dispatch}\n });\n}\n\nDragEvent.prototype.on = function() {\n var value = this._.on.apply(this._, arguments);\n return value === this._ ? this : value;\n};\n","import {dispatch} from \"d3-dispatch\";\nimport {select, pointer} from \"d3-selection\";\nimport nodrag, {yesdrag} from \"./nodrag.js\";\nimport noevent, {nonpassive, nonpassivecapture, nopropagation} from \"./noevent.js\";\nimport constant from \"./constant.js\";\nimport DragEvent from \"./event.js\";\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter(event) {\n return !event.ctrlKey && !event.button;\n}\n\nfunction defaultContainer() {\n return this.parentNode;\n}\n\nfunction defaultSubject(event, d) {\n return d == null ? {x: event.x, y: event.y} : d;\n}\n\nfunction defaultTouchable() {\n return navigator.maxTouchPoints || (\"ontouchstart\" in this);\n}\n\nexport default function() {\n var filter = defaultFilter,\n container = defaultContainer,\n subject = defaultSubject,\n touchable = defaultTouchable,\n gestures = {},\n listeners = dispatch(\"start\", \"drag\", \"end\"),\n active = 0,\n mousedownx,\n mousedowny,\n mousemoving,\n touchending,\n clickDistance2 = 0;\n\n function drag(selection) {\n selection\n .on(\"mousedown.drag\", mousedowned)\n .filter(touchable)\n .on(\"touchstart.drag\", touchstarted)\n .on(\"touchmove.drag\", touchmoved, nonpassive)\n .on(\"touchend.drag touchcancel.drag\", touchended)\n .style(\"touch-action\", \"none\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n }\n\n function mousedowned(event, d) {\n if (touchending || !filter.call(this, event, d)) return;\n var gesture = beforestart(this, container.call(this, event, d), event, d, \"mouse\");\n if (!gesture) return;\n select(event.view)\n .on(\"mousemove.drag\", mousemoved, nonpassivecapture)\n .on(\"mouseup.drag\", mouseupped, nonpassivecapture);\n nodrag(event.view);\n nopropagation(event);\n mousemoving = false;\n mousedownx = event.clientX;\n mousedowny = event.clientY;\n gesture(\"start\", event);\n }\n\n function mousemoved(event) {\n noevent(event);\n if (!mousemoving) {\n var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;\n mousemoving = dx * dx + dy * dy > clickDistance2;\n }\n gestures.mouse(\"drag\", event);\n }\n\n function mouseupped(event) {\n select(event.view).on(\"mousemove.drag mouseup.drag\", null);\n yesdrag(event.view, mousemoving);\n noevent(event);\n gestures.mouse(\"end\", event);\n }\n\n function touchstarted(event, d) {\n if (!filter.call(this, event, d)) return;\n var touches = event.changedTouches,\n c = container.call(this, event, d),\n n = touches.length, i, gesture;\n\n for (i = 0; i < n; ++i) {\n if (gesture = beforestart(this, c, event, d, touches[i].identifier, touches[i])) {\n nopropagation(event);\n gesture(\"start\", event, touches[i]);\n }\n }\n }\n\n function touchmoved(event) {\n var touches = event.changedTouches,\n n = touches.length, i, gesture;\n\n for (i = 0; i < n; ++i) {\n if (gesture = gestures[touches[i].identifier]) {\n noevent(event);\n gesture(\"drag\", event, touches[i]);\n }\n }\n }\n\n function touchended(event) {\n var touches = event.changedTouches,\n n = touches.length, i, gesture;\n\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n for (i = 0; i < n; ++i) {\n if (gesture = gestures[touches[i].identifier]) {\n nopropagation(event);\n gesture(\"end\", event, touches[i]);\n }\n }\n }\n\n function beforestart(that, container, event, d, identifier, touch) {\n var dispatch = listeners.copy(),\n p = pointer(touch || event, container), dx, dy,\n s;\n\n if ((s = subject.call(that, new DragEvent(\"beforestart\", {\n sourceEvent: event,\n target: drag,\n identifier,\n active,\n x: p[0],\n y: p[1],\n dx: 0,\n dy: 0,\n dispatch\n }), d)) == null) return;\n\n dx = s.x - p[0] || 0;\n dy = s.y - p[1] || 0;\n\n return function gesture(type, event, touch) {\n var p0 = p, n;\n switch (type) {\n case \"start\": gestures[identifier] = gesture, n = active++; break;\n case \"end\": delete gestures[identifier], --active; // falls through\n case \"drag\": p = pointer(touch || event, container), n = active; break;\n }\n dispatch.call(\n type,\n that,\n new DragEvent(type, {\n sourceEvent: event,\n subject: s,\n target: drag,\n identifier,\n active: n,\n x: p[0] + dx,\n y: p[1] + dy,\n dx: p[0] - p0[0],\n dy: p[1] - p0[1],\n dispatch\n }),\n d\n );\n };\n }\n\n drag.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant(!!_), drag) : filter;\n };\n\n drag.container = function(_) {\n return arguments.length ? (container = typeof _ === \"function\" ? _ : constant(_), drag) : container;\n };\n\n drag.subject = function(_) {\n return arguments.length ? (subject = typeof _ === \"function\" ? _ : constant(_), drag) : subject;\n };\n\n drag.touchable = function(_) {\n return arguments.length ? (touchable = typeof _ === \"function\" ? _ : constant(!!_), drag) : touchable;\n };\n\n drag.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? drag : value;\n };\n\n drag.clickDistance = function(_) {\n return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);\n };\n\n return drag;\n}\n","export default function(constructor, factory, prototype) {\n constructor.prototype = factory.prototype = prototype;\n prototype.constructor = constructor;\n}\n\nexport function extend(parent, definition) {\n var prototype = Object.create(parent.prototype);\n for (var key in definition) prototype[key] = definition[key];\n return prototype;\n}\n","import define, {extend} from \"./define.js\";\n\nexport function Color() {}\n\nexport var darker = 0.7;\nexport var brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\",\n reN = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\",\n reP = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\",\n reHex = /^#([0-9a-f]{3,8})$/,\n reRgbInteger = new RegExp(`^rgb\\\\(${reI},${reI},${reI}\\\\)$`),\n reRgbPercent = new RegExp(`^rgb\\\\(${reP},${reP},${reP}\\\\)$`),\n reRgbaInteger = new RegExp(`^rgba\\\\(${reI},${reI},${reI},${reN}\\\\)$`),\n reRgbaPercent = new RegExp(`^rgba\\\\(${reP},${reP},${reP},${reN}\\\\)$`),\n reHslPercent = new RegExp(`^hsl\\\\(${reN},${reP},${reP}\\\\)$`),\n reHslaPercent = new RegExp(`^hsla\\\\(${reN},${reP},${reP},${reN}\\\\)$`);\n\nvar named = {\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgreen: 0x006400,\n darkgrey: 0xa9a9a9,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n grey: 0x808080,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightgrey: 0xd3d3d3,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n copy(channels) {\n return Object.assign(new this.constructor, this, channels);\n },\n displayable() {\n return this.rgb().displayable();\n },\n hex: color_formatHex, // Deprecated! Use color.formatHex.\n formatHex: color_formatHex,\n formatHex8: color_formatHex8,\n formatHsl: color_formatHsl,\n formatRgb: color_formatRgb,\n toString: color_formatRgb\n});\n\nfunction color_formatHex() {\n return this.rgb().formatHex();\n}\n\nfunction color_formatHex8() {\n return this.rgb().formatHex8();\n}\n\nfunction color_formatHsl() {\n return hslConvert(this).formatHsl();\n}\n\nfunction color_formatRgb() {\n return this.rgb().formatRgb();\n}\n\nexport default function color(format) {\n var m, l;\n format = (format + \"\").trim().toLowerCase();\n return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000\n : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00\n : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000\n : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000\n : null) // invalid hex\n : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins\n : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n : null;\n}\n\nfunction rgbn(n) {\n return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n if (a <= 0) r = g = b = NaN;\n return new Rgb(r, g, b, a);\n}\n\nexport function rgbConvert(o) {\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Rgb;\n o = o.rgb();\n return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nexport function rgb(r, g, b, opacity) {\n return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nexport function Rgb(r, g, b, opacity) {\n this.r = +r;\n this.g = +g;\n this.b = +b;\n this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n brighter(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n darker(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n rgb() {\n return this;\n },\n clamp() {\n return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity));\n },\n displayable() {\n return (-0.5 <= this.r && this.r < 255.5)\n && (-0.5 <= this.g && this.g < 255.5)\n && (-0.5 <= this.b && this.b < 255.5)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n hex: rgb_formatHex, // Deprecated! Use color.formatHex.\n formatHex: rgb_formatHex,\n formatHex8: rgb_formatHex8,\n formatRgb: rgb_formatRgb,\n toString: rgb_formatRgb\n}));\n\nfunction rgb_formatHex() {\n return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`;\n}\n\nfunction rgb_formatHex8() {\n return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`;\n}\n\nfunction rgb_formatRgb() {\n const a = clampa(this.opacity);\n return `${a === 1 ? \"rgb(\" : \"rgba(\"}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? \")\" : `, ${a})`}`;\n}\n\nfunction clampa(opacity) {\n return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity));\n}\n\nfunction clampi(value) {\n return Math.max(0, Math.min(255, Math.round(value) || 0));\n}\n\nfunction hex(value) {\n value = clampi(value);\n return (value < 16 ? \"0\" : \"\") + value.toString(16);\n}\n\nfunction hsla(h, s, l, a) {\n if (a <= 0) h = s = l = NaN;\n else if (l <= 0 || l >= 1) h = s = NaN;\n else if (s <= 0) h = NaN;\n return new Hsl(h, s, l, a);\n}\n\nexport function hslConvert(o) {\n if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Hsl;\n if (o instanceof Hsl) return o;\n o = o.rgb();\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n h = NaN,\n s = max - min,\n l = (max + min) / 2;\n if (s) {\n if (r === max) h = (g - b) / s + (g < b) * 6;\n else if (g === max) h = (b - r) / s + 2;\n else h = (r - g) / s + 4;\n s /= l < 0.5 ? max + min : 2 - max - min;\n h *= 60;\n } else {\n s = l > 0 && l < 1 ? 0 : h;\n }\n return new Hsl(h, s, l, o.opacity);\n}\n\nexport function hsl(h, s, l, opacity) {\n return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n brighter(k) {\n k = k == null ? brighter : Math.pow(brighter, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n darker(k) {\n k = k == null ? darker : Math.pow(darker, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n rgb() {\n var h = this.h % 360 + (this.h < 0) * 360,\n s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n l = this.l,\n m2 = l + (l < 0.5 ? l : 1 - l) * s,\n m1 = 2 * l - m2;\n return new Rgb(\n hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n hsl2rgb(h, m1, m2),\n hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n this.opacity\n );\n },\n clamp() {\n return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity));\n },\n displayable() {\n return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n && (0 <= this.l && this.l <= 1)\n && (0 <= this.opacity && this.opacity <= 1);\n },\n formatHsl() {\n const a = clampa(this.opacity);\n return `${a === 1 ? \"hsl(\" : \"hsla(\"}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? \")\" : `, ${a})`}`;\n }\n}));\n\nfunction clamph(value) {\n value = (value || 0) % 360;\n return value < 0 ? value + 360 : value;\n}\n\nfunction clampt(value) {\n return Math.max(0, Math.min(1, value || 0));\n}\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n return (h < 60 ? m1 + (m2 - m1) * h / 60\n : h < 180 ? m2\n : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n : m1) * 255;\n}\n","export default x => () => x;\n","import constant from \"./constant.js\";\n\nfunction linear(a, d) {\n return function(t) {\n return a + t * d;\n };\n}\n\nfunction exponential(a, b, y) {\n return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {\n return Math.pow(a + t * b, y);\n };\n}\n\nexport function hue(a, b) {\n var d = b - a;\n return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);\n}\n\nexport function gamma(y) {\n return (y = +y) === 1 ? nogamma : function(a, b) {\n return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);\n };\n}\n\nexport default function nogamma(a, b) {\n var d = b - a;\n return d ? linear(a, d) : constant(isNaN(a) ? b : a);\n}\n","import {rgb as colorRgb} from \"d3-color\";\nimport basis from \"./basis.js\";\nimport basisClosed from \"./basisClosed.js\";\nimport nogamma, {gamma} from \"./color.js\";\n\nexport default (function rgbGamma(y) {\n var color = gamma(y);\n\n function rgb(start, end) {\n var r = color((start = colorRgb(start)).r, (end = colorRgb(end)).r),\n g = color(start.g, end.g),\n b = color(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function(t) {\n start.r = r(t);\n start.g = g(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + \"\";\n };\n }\n\n rgb.gamma = rgbGamma;\n\n return rgb;\n})(1);\n\nfunction rgbSpline(spline) {\n return function(colors) {\n var n = colors.length,\n r = new Array(n),\n g = new Array(n),\n b = new Array(n),\n i, color;\n for (i = 0; i < n; ++i) {\n color = colorRgb(colors[i]);\n r[i] = color.r || 0;\n g[i] = color.g || 0;\n b[i] = color.b || 0;\n }\n r = spline(r);\n g = spline(g);\n b = spline(b);\n color.opacity = 1;\n return function(t) {\n color.r = r(t);\n color.g = g(t);\n color.b = b(t);\n return color + \"\";\n };\n };\n}\n\nexport var rgbBasis = rgbSpline(basis);\nexport var rgbBasisClosed = rgbSpline(basisClosed);\n","export default function(a, b) {\n if (!b) b = [];\n var n = a ? Math.min(b.length, a.length) : 0,\n c = b.slice(),\n i;\n return function(t) {\n for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;\n return c;\n };\n}\n\nexport function isNumberArray(x) {\n return ArrayBuffer.isView(x) && !(x instanceof DataView);\n}\n","import value from \"./value.js\";\nimport numberArray, {isNumberArray} from \"./numberArray.js\";\n\nexport default function(a, b) {\n return (isNumberArray(b) ? numberArray : genericArray)(a, b);\n}\n\nexport function genericArray(a, b) {\n var nb = b ? b.length : 0,\n na = a ? Math.min(nb, a.length) : 0,\n x = new Array(na),\n c = new Array(nb),\n i;\n\n for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);\n for (; i < nb; ++i) c[i] = b[i];\n\n return function(t) {\n for (i = 0; i < na; ++i) c[i] = x[i](t);\n return c;\n };\n}\n","export default function(a, b) {\n var d = new Date;\n return a = +a, b = +b, function(t) {\n return d.setTime(a * (1 - t) + b * t), d;\n };\n}\n","export default function(a, b) {\n return a = +a, b = +b, function(t) {\n return a * (1 - t) + b * t;\n };\n}\n","import value from \"./value.js\";\n\nexport default function(a, b) {\n var i = {},\n c = {},\n k;\n\n if (a === null || typeof a !== \"object\") a = {};\n if (b === null || typeof b !== \"object\") b = {};\n\n for (k in b) {\n if (k in a) {\n i[k] = value(a[k], b[k]);\n } else {\n c[k] = b[k];\n }\n }\n\n return function(t) {\n for (k in i) c[k] = i[k](t);\n return c;\n };\n}\n","import number from \"./number.js\";\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,\n reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n return function() {\n return b;\n };\n}\n\nfunction one(b) {\n return function(t) {\n return b(t) + \"\";\n };\n}\n\nexport default function(a, b) {\n var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n am, // current match in a\n bm, // current match in b\n bs, // string preceding current number in b, if any\n i = -1, // index in s\n s = [], // string constants and placeholders\n q = []; // number interpolators\n\n // Coerce inputs to strings.\n a = a + \"\", b = b + \"\";\n\n // Interpolate pairs of numbers in a & b.\n while ((am = reA.exec(a))\n && (bm = reB.exec(b))) {\n if ((bs = bm.index) > bi) { // a string precedes the next number in b\n bs = b.slice(bi, bs);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n if (s[i]) s[i] += bm; // coalesce with previous string\n else s[++i] = bm;\n } else { // interpolate non-matching numbers\n s[++i] = null;\n q.push({i: i, x: number(am, bm)});\n }\n bi = reB.lastIndex;\n }\n\n // Add remains of b.\n if (bi < b.length) {\n bs = b.slice(bi);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n\n // Special optimization for only a single match.\n // Otherwise, interpolate each of the numbers and rejoin the string.\n return s.length < 2 ? (q[0]\n ? one(q[0].x)\n : zero(b))\n : (b = q.length, function(t) {\n for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n });\n}\n","import {color} from \"d3-color\";\nimport rgb from \"./rgb.js\";\nimport {genericArray} from \"./array.js\";\nimport date from \"./date.js\";\nimport number from \"./number.js\";\nimport object from \"./object.js\";\nimport string from \"./string.js\";\nimport constant from \"./constant.js\";\nimport numberArray, {isNumberArray} from \"./numberArray.js\";\n\nexport default function(a, b) {\n var t = typeof b, c;\n return b == null || t === \"boolean\" ? constant(b)\n : (t === \"number\" ? number\n : t === \"string\" ? ((c = color(b)) ? (b = c, rgb) : string)\n : b instanceof color ? rgb\n : b instanceof Date ? date\n : isNumberArray(b) ? numberArray\n : Array.isArray(b) ? genericArray\n : typeof b.valueOf !== \"function\" && typeof b.toString !== \"function\" || isNaN(b) ? object\n : number)(a, b);\n}\n","export default function(a, b) {\n return a = +a, b = +b, function(t) {\n return Math.round(a * (1 - t) + b * t);\n };\n}\n","var degrees = 180 / Math.PI;\n\nexport var identity = {\n translateX: 0,\n translateY: 0,\n rotate: 0,\n skewX: 0,\n scaleX: 1,\n scaleY: 1\n};\n\nexport default function(a, b, c, d, e, f) {\n var scaleX, scaleY, skewX;\n if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;\n if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;\n if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;\n if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;\n return {\n translateX: e,\n translateY: f,\n rotate: Math.atan2(b, a) * degrees,\n skewX: Math.atan(skewX) * degrees,\n scaleX: scaleX,\n scaleY: scaleY\n };\n}\n","import decompose, {identity} from \"./decompose.js\";\n\nvar svgNode;\n\n/* eslint-disable no-undef */\nexport function parseCss(value) {\n const m = new (typeof DOMMatrix === \"function\" ? DOMMatrix : WebKitCSSMatrix)(value + \"\");\n return m.isIdentity ? identity : decompose(m.a, m.b, m.c, m.d, m.e, m.f);\n}\n\nexport function parseSvg(value) {\n if (value == null) return identity;\n if (!svgNode) svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n svgNode.setAttribute(\"transform\", value);\n if (!(value = svgNode.transform.baseVal.consolidate())) return identity;\n value = value.matrix;\n return decompose(value.a, value.b, value.c, value.d, value.e, value.f);\n}\n","import number from \"../number.js\";\nimport {parseCss, parseSvg} from \"./parse.js\";\n\nfunction interpolateTransform(parse, pxComma, pxParen, degParen) {\n\n function pop(s) {\n return s.length ? s.pop() + \" \" : \"\";\n }\n\n function translate(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(\"translate(\", null, pxComma, null, pxParen);\n q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});\n } else if (xb || yb) {\n s.push(\"translate(\" + xb + pxComma + yb + pxParen);\n }\n }\n\n function rotate(a, b, s, q) {\n if (a !== b) {\n if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path\n q.push({i: s.push(pop(s) + \"rotate(\", null, degParen) - 2, x: number(a, b)});\n } else if (b) {\n s.push(pop(s) + \"rotate(\" + b + degParen);\n }\n }\n\n function skewX(a, b, s, q) {\n if (a !== b) {\n q.push({i: s.push(pop(s) + \"skewX(\", null, degParen) - 2, x: number(a, b)});\n } else if (b) {\n s.push(pop(s) + \"skewX(\" + b + degParen);\n }\n }\n\n function scale(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(pop(s) + \"scale(\", null, \",\", null, \")\");\n q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});\n } else if (xb !== 1 || yb !== 1) {\n s.push(pop(s) + \"scale(\" + xb + \",\" + yb + \")\");\n }\n }\n\n return function(a, b) {\n var s = [], // string constants and placeholders\n q = []; // number interpolators\n a = parse(a), b = parse(b);\n translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);\n rotate(a.rotate, b.rotate, s, q);\n skewX(a.skewX, b.skewX, s, q);\n scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);\n a = b = null; // gc\n return function(t) {\n var i = -1, n = q.length, o;\n while (++i < n) s[(o = q[i]).i] = o.x(t);\n return s.join(\"\");\n };\n };\n}\n\nexport var interpolateTransformCss = interpolateTransform(parseCss, \"px, \", \"px)\", \"deg)\");\nexport var interpolateTransformSvg = interpolateTransform(parseSvg, \", \", \")\", \")\");\n","var frame = 0, // is an animation frame pending?\n timeout = 0, // is a timeout pending?\n interval = 0, // are any timers active?\n pokeDelay = 1000, // how frequently we check for clock skew\n taskHead,\n taskTail,\n clockLast = 0,\n clockNow = 0,\n clockSkew = 0,\n clock = typeof performance === \"object\" && performance.now ? performance : Date,\n setFrame = typeof window === \"object\" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };\n\nexport function now() {\n return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);\n}\n\nfunction clearNow() {\n clockNow = 0;\n}\n\nexport function Timer() {\n this._call =\n this._time =\n this._next = null;\n}\n\nTimer.prototype = timer.prototype = {\n constructor: Timer,\n restart: function(callback, delay, time) {\n if (typeof callback !== \"function\") throw new TypeError(\"callback is not a function\");\n time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);\n if (!this._next && taskTail !== this) {\n if (taskTail) taskTail._next = this;\n else taskHead = this;\n taskTail = this;\n }\n this._call = callback;\n this._time = time;\n sleep();\n },\n stop: function() {\n if (this._call) {\n this._call = null;\n this._time = Infinity;\n sleep();\n }\n }\n};\n\nexport function timer(callback, delay, time) {\n var t = new Timer;\n t.restart(callback, delay, time);\n return t;\n}\n\nexport function timerFlush() {\n now(); // Get the current time, if not already set.\n ++frame; // Pretend we’ve set an alarm, if we haven’t already.\n var t = taskHead, e;\n while (t) {\n if ((e = clockNow - t._time) >= 0) t._call.call(undefined, e);\n t = t._next;\n }\n --frame;\n}\n\nfunction wake() {\n clockNow = (clockLast = clock.now()) + clockSkew;\n frame = timeout = 0;\n try {\n timerFlush();\n } finally {\n frame = 0;\n nap();\n clockNow = 0;\n }\n}\n\nfunction poke() {\n var now = clock.now(), delay = now - clockLast;\n if (delay > pokeDelay) clockSkew -= delay, clockLast = now;\n}\n\nfunction nap() {\n var t0, t1 = taskHead, t2, time = Infinity;\n while (t1) {\n if (t1._call) {\n if (time > t1._time) time = t1._time;\n t0 = t1, t1 = t1._next;\n } else {\n t2 = t1._next, t1._next = null;\n t1 = t0 ? t0._next = t2 : taskHead = t2;\n }\n }\n taskTail = t0;\n sleep(time);\n}\n\nfunction sleep(time) {\n if (frame) return; // Soonest alarm already set, or will be.\n if (timeout) timeout = clearTimeout(timeout);\n var delay = time - clockNow; // Strictly less than if we recomputed clockNow.\n if (delay > 24) {\n if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);\n if (interval) interval = clearInterval(interval);\n } else {\n if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);\n frame = 1, setFrame(wake);\n }\n}\n","import {Timer} from \"./timer.js\";\n\nexport default function(callback, delay, time) {\n var t = new Timer;\n delay = delay == null ? 0 : +delay;\n t.restart(elapsed => {\n t.stop();\n callback(elapsed + delay);\n }, delay, time);\n return t;\n}\n","import {dispatch} from \"d3-dispatch\";\nimport {timer, timeout} from \"d3-timer\";\n\nvar emptyOn = dispatch(\"start\", \"end\", \"cancel\", \"interrupt\");\nvar emptyTween = [];\n\nexport var CREATED = 0;\nexport var SCHEDULED = 1;\nexport var STARTING = 2;\nexport var STARTED = 3;\nexport var RUNNING = 4;\nexport var ENDING = 5;\nexport var ENDED = 6;\n\nexport default function(node, name, id, index, group, timing) {\n var schedules = node.__transition;\n if (!schedules) node.__transition = {};\n else if (id in schedules) return;\n create(node, id, {\n name: name,\n index: index, // For context during callback.\n group: group, // For context during callback.\n on: emptyOn,\n tween: emptyTween,\n time: timing.time,\n delay: timing.delay,\n duration: timing.duration,\n ease: timing.ease,\n timer: null,\n state: CREATED\n });\n}\n\nexport function init(node, id) {\n var schedule = get(node, id);\n if (schedule.state > CREATED) throw new Error(\"too late; already scheduled\");\n return schedule;\n}\n\nexport function set(node, id) {\n var schedule = get(node, id);\n if (schedule.state > STARTED) throw new Error(\"too late; already running\");\n return schedule;\n}\n\nexport function get(node, id) {\n var schedule = node.__transition;\n if (!schedule || !(schedule = schedule[id])) throw new Error(\"transition not found\");\n return schedule;\n}\n\nfunction create(node, id, self) {\n var schedules = node.__transition,\n tween;\n\n // Initialize the self timer when the transition is created.\n // Note the actual delay is not known until the first callback!\n schedules[id] = self;\n self.timer = timer(schedule, 0, self.time);\n\n function schedule(elapsed) {\n self.state = SCHEDULED;\n self.timer.restart(start, self.delay, self.time);\n\n // If the elapsed delay is less than our first sleep, start immediately.\n if (self.delay <= elapsed) start(elapsed - self.delay);\n }\n\n function start(elapsed) {\n var i, j, n, o;\n\n // If the state is not SCHEDULED, then we previously errored on start.\n if (self.state !== SCHEDULED) return stop();\n\n for (i in schedules) {\n o = schedules[i];\n if (o.name !== self.name) continue;\n\n // While this element already has a starting transition during this frame,\n // defer starting an interrupting transition until that transition has a\n // chance to tick (and possibly end); see d3/d3-transition#54!\n if (o.state === STARTED) return timeout(start);\n\n // Interrupt the active transition, if any.\n if (o.state === RUNNING) {\n o.state = ENDED;\n o.timer.stop();\n o.on.call(\"interrupt\", node, node.__data__, o.index, o.group);\n delete schedules[i];\n }\n\n // Cancel any pre-empted transitions.\n else if (+i < id) {\n o.state = ENDED;\n o.timer.stop();\n o.on.call(\"cancel\", node, node.__data__, o.index, o.group);\n delete schedules[i];\n }\n }\n\n // Defer the first tick to end of the current frame; see d3/d3#1576.\n // Note the transition may be canceled after start and before the first tick!\n // Note this must be scheduled before the start event; see d3/d3-transition#16!\n // Assuming this is successful, subsequent callbacks go straight to tick.\n timeout(function() {\n if (self.state === STARTED) {\n self.state = RUNNING;\n self.timer.restart(tick, self.delay, self.time);\n tick(elapsed);\n }\n });\n\n // Dispatch the start event.\n // Note this must be done before the tween are initialized.\n self.state = STARTING;\n self.on.call(\"start\", node, node.__data__, self.index, self.group);\n if (self.state !== STARTING) return; // interrupted\n self.state = STARTED;\n\n // Initialize the tween, deleting null tween.\n tween = new Array(n = self.tween.length);\n for (i = 0, j = -1; i < n; ++i) {\n if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {\n tween[++j] = o;\n }\n }\n tween.length = j + 1;\n }\n\n function tick(elapsed) {\n var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),\n i = -1,\n n = tween.length;\n\n while (++i < n) {\n tween[i].call(node, t);\n }\n\n // Dispatch the end event.\n if (self.state === ENDING) {\n self.on.call(\"end\", node, node.__data__, self.index, self.group);\n stop();\n }\n }\n\n function stop() {\n self.state = ENDED;\n self.timer.stop();\n delete schedules[id];\n for (var i in schedules) return; // eslint-disable-line no-unused-vars\n delete node.__transition;\n }\n}\n","import {STARTING, ENDING, ENDED} from \"./transition/schedule.js\";\n\nexport default function(node, name) {\n var schedules = node.__transition,\n schedule,\n active,\n empty = true,\n i;\n\n if (!schedules) return;\n\n name = name == null ? null : name + \"\";\n\n for (i in schedules) {\n if ((schedule = schedules[i]).name !== name) { empty = false; continue; }\n active = schedule.state > STARTING && schedule.state < ENDING;\n schedule.state = ENDED;\n schedule.timer.stop();\n schedule.on.call(active ? \"interrupt\" : \"cancel\", node, node.__data__, schedule.index, schedule.group);\n delete schedules[i];\n }\n\n if (empty) delete node.__transition;\n}\n","import interrupt from \"../interrupt.js\";\n\nexport default function(name) {\n return this.each(function() {\n interrupt(this, name);\n });\n}\n","import {get, set} from \"./schedule.js\";\n\nfunction tweenRemove(id, name) {\n var tween0, tween1;\n return function() {\n var schedule = set(this, id),\n tween = schedule.tween;\n\n // If this node shared tween with the previous node,\n // just assign the updated shared tween and we’re done!\n // Otherwise, copy-on-write.\n if (tween !== tween0) {\n tween1 = tween0 = tween;\n for (var i = 0, n = tween1.length; i < n; ++i) {\n if (tween1[i].name === name) {\n tween1 = tween1.slice();\n tween1.splice(i, 1);\n break;\n }\n }\n }\n\n schedule.tween = tween1;\n };\n}\n\nfunction tweenFunction(id, name, value) {\n var tween0, tween1;\n if (typeof value !== \"function\") throw new Error;\n return function() {\n var schedule = set(this, id),\n tween = schedule.tween;\n\n // If this node shared tween with the previous node,\n // just assign the updated shared tween and we’re done!\n // Otherwise, copy-on-write.\n if (tween !== tween0) {\n tween1 = (tween0 = tween).slice();\n for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {\n if (tween1[i].name === name) {\n tween1[i] = t;\n break;\n }\n }\n if (i === n) tween1.push(t);\n }\n\n schedule.tween = tween1;\n };\n}\n\nexport default function(name, value) {\n var id = this._id;\n\n name += \"\";\n\n if (arguments.length < 2) {\n var tween = get(this.node(), id).tween;\n for (var i = 0, n = tween.length, t; i < n; ++i) {\n if ((t = tween[i]).name === name) {\n return t.value;\n }\n }\n return null;\n }\n\n return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));\n}\n\nexport function tweenValue(transition, name, value) {\n var id = transition._id;\n\n transition.each(function() {\n var schedule = set(this, id);\n (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);\n });\n\n return function(node) {\n return get(node, id).value[name];\n };\n}\n","import {color} from \"d3-color\";\nimport {interpolateNumber, interpolateRgb, interpolateString} from \"d3-interpolate\";\n\nexport default function(a, b) {\n var c;\n return (typeof b === \"number\" ? interpolateNumber\n : b instanceof color ? interpolateRgb\n : (c = color(b)) ? (b = c, interpolateRgb)\n : interpolateString)(a, b);\n}\n","import {interpolateTransformSvg as interpolateTransform} from \"d3-interpolate\";\nimport {namespace} from \"d3-selection\";\nimport {tweenValue} from \"./tween.js\";\nimport interpolate from \"./interpolate.js\";\n\nfunction attrRemove(name) {\n return function() {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS(fullname) {\n return function() {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant(name, interpolate, value1) {\n var string00,\n string1 = value1 + \"\",\n interpolate0;\n return function() {\n var string0 = this.getAttribute(name);\n return string0 === string1 ? null\n : string0 === string00 ? interpolate0\n : interpolate0 = interpolate(string00 = string0, value1);\n };\n}\n\nfunction attrConstantNS(fullname, interpolate, value1) {\n var string00,\n string1 = value1 + \"\",\n interpolate0;\n return function() {\n var string0 = this.getAttributeNS(fullname.space, fullname.local);\n return string0 === string1 ? null\n : string0 === string00 ? interpolate0\n : interpolate0 = interpolate(string00 = string0, value1);\n };\n}\n\nfunction attrFunction(name, interpolate, value) {\n var string00,\n string10,\n interpolate0;\n return function() {\n var string0, value1 = value(this), string1;\n if (value1 == null) return void this.removeAttribute(name);\n string0 = this.getAttribute(name);\n string1 = value1 + \"\";\n return string0 === string1 ? null\n : string0 === string00 && string1 === string10 ? interpolate0\n : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n };\n}\n\nfunction attrFunctionNS(fullname, interpolate, value) {\n var string00,\n string10,\n interpolate0;\n return function() {\n var string0, value1 = value(this), string1;\n if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);\n string0 = this.getAttributeNS(fullname.space, fullname.local);\n string1 = value1 + \"\";\n return string0 === string1 ? null\n : string0 === string00 && string1 === string10 ? interpolate0\n : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n };\n}\n\nexport default function(name, value) {\n var fullname = namespace(name), i = fullname === \"transform\" ? interpolateTransform : interpolate;\n return this.attrTween(name, typeof value === \"function\"\n ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, \"attr.\" + name, value))\n : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname)\n : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value));\n}\n","import {namespace} from \"d3-selection\";\n\nfunction attrInterpolate(name, i) {\n return function(t) {\n this.setAttribute(name, i.call(this, t));\n };\n}\n\nfunction attrInterpolateNS(fullname, i) {\n return function(t) {\n this.setAttributeNS(fullname.space, fullname.local, i.call(this, t));\n };\n}\n\nfunction attrTweenNS(fullname, value) {\n var t0, i0;\n function tween() {\n var i = value.apply(this, arguments);\n if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i);\n return t0;\n }\n tween._value = value;\n return tween;\n}\n\nfunction attrTween(name, value) {\n var t0, i0;\n function tween() {\n var i = value.apply(this, arguments);\n if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i);\n return t0;\n }\n tween._value = value;\n return tween;\n}\n\nexport default function(name, value) {\n var key = \"attr.\" + name;\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n var fullname = namespace(name);\n return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));\n}\n","import {get, init} from \"./schedule.js\";\n\nfunction delayFunction(id, value) {\n return function() {\n init(this, id).delay = +value.apply(this, arguments);\n };\n}\n\nfunction delayConstant(id, value) {\n return value = +value, function() {\n init(this, id).delay = value;\n };\n}\n\nexport default function(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each((typeof value === \"function\"\n ? delayFunction\n : delayConstant)(id, value))\n : get(this.node(), id).delay;\n}\n","import {get, set} from \"./schedule.js\";\n\nfunction durationFunction(id, value) {\n return function() {\n set(this, id).duration = +value.apply(this, arguments);\n };\n}\n\nfunction durationConstant(id, value) {\n return value = +value, function() {\n set(this, id).duration = value;\n };\n}\n\nexport default function(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each((typeof value === \"function\"\n ? durationFunction\n : durationConstant)(id, value))\n : get(this.node(), id).duration;\n}\n","import {get, set} from \"./schedule.js\";\n\nfunction easeConstant(id, value) {\n if (typeof value !== \"function\") throw new Error;\n return function() {\n set(this, id).ease = value;\n };\n}\n\nexport default function(value) {\n var id = this._id;\n\n return arguments.length\n ? this.each(easeConstant(id, value))\n : get(this.node(), id).ease;\n}\n","import {set} from \"./schedule.js\";\n\nfunction easeVarying(id, value) {\n return function() {\n var v = value.apply(this, arguments);\n if (typeof v !== \"function\") throw new Error;\n set(this, id).ease = v;\n };\n}\n\nexport default function(value) {\n if (typeof value !== \"function\") throw new Error;\n return this.each(easeVarying(this._id, value));\n}\n","import {matcher} from \"d3-selection\";\nimport {Transition} from \"./index.js\";\n\nexport default function(match) {\n if (typeof match !== \"function\") match = matcher(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Transition(subgroups, this._parents, this._name, this._id);\n}\n","import {Transition} from \"./index.js\";\n\nexport default function(transition) {\n if (transition._id !== this._id) throw new Error;\n\n for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Transition(merges, this._parents, this._name, this._id);\n}\n","import {get, set, init} from \"./schedule.js\";\n\nfunction start(name) {\n return (name + \"\").trim().split(/^|\\s+/).every(function(t) {\n var i = t.indexOf(\".\");\n if (i >= 0) t = t.slice(0, i);\n return !t || t === \"start\";\n });\n}\n\nfunction onFunction(id, name, listener) {\n var on0, on1, sit = start(name) ? init : set;\n return function() {\n var schedule = sit(this, id),\n on = schedule.on;\n\n // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);\n\n schedule.on = on1;\n };\n}\n\nexport default function(name, listener) {\n var id = this._id;\n\n return arguments.length < 2\n ? get(this.node(), id).on.on(name)\n : this.each(onFunction(id, name, listener));\n}\n","function removeFunction(id) {\n return function() {\n var parent = this.parentNode;\n for (var i in this.__transition) if (+i !== id) return;\n if (parent) parent.removeChild(this);\n };\n}\n\nexport default function() {\n return this.on(\"end.remove\", removeFunction(this._id));\n}\n","import {selector} from \"d3-selection\";\nimport {Transition} from \"./index.js\";\nimport schedule, {get} from \"./schedule.js\";\n\nexport default function(select) {\n var name = this._name,\n id = this._id;\n\n if (typeof select !== \"function\") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if (\"__data__\" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n schedule(subgroup[i], name, id, i, subgroup, get(node, id));\n }\n }\n }\n\n return new Transition(subgroups, this._parents, name, id);\n}\n","import {selectorAll} from \"d3-selection\";\nimport {Transition} from \"./index.js\";\nimport schedule, {get} from \"./schedule.js\";\n\nexport default function(select) {\n var name = this._name,\n id = this._id;\n\n if (typeof select !== \"function\") select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) {\n if (child = children[k]) {\n schedule(child, name, id, k, children, inherit);\n }\n }\n subgroups.push(children);\n parents.push(node);\n }\n }\n }\n\n return new Transition(subgroups, parents, name, id);\n}\n","import {selection} from \"d3-selection\";\n\nvar Selection = selection.prototype.constructor;\n\nexport default function() {\n return new Selection(this._groups, this._parents);\n}\n","import {interpolateTransformCss as interpolateTransform} from \"d3-interpolate\";\nimport {style} from \"d3-selection\";\nimport {set} from \"./schedule.js\";\nimport {tweenValue} from \"./tween.js\";\nimport interpolate from \"./interpolate.js\";\n\nfunction styleNull(name, interpolate) {\n var string00,\n string10,\n interpolate0;\n return function() {\n var string0 = style(this, name),\n string1 = (this.style.removeProperty(name), style(this, name));\n return string0 === string1 ? null\n : string0 === string00 && string1 === string10 ? interpolate0\n : interpolate0 = interpolate(string00 = string0, string10 = string1);\n };\n}\n\nfunction styleRemove(name) {\n return function() {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant(name, interpolate, value1) {\n var string00,\n string1 = value1 + \"\",\n interpolate0;\n return function() {\n var string0 = style(this, name);\n return string0 === string1 ? null\n : string0 === string00 ? interpolate0\n : interpolate0 = interpolate(string00 = string0, value1);\n };\n}\n\nfunction styleFunction(name, interpolate, value) {\n var string00,\n string10,\n interpolate0;\n return function() {\n var string0 = style(this, name),\n value1 = value(this),\n string1 = value1 + \"\";\n if (value1 == null) string1 = value1 = (this.style.removeProperty(name), style(this, name));\n return string0 === string1 ? null\n : string0 === string00 && string1 === string10 ? interpolate0\n : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n };\n}\n\nfunction styleMaybeRemove(id, name) {\n var on0, on1, listener0, key = \"style.\" + name, event = \"end.\" + key, remove;\n return function() {\n var schedule = set(this, id),\n on = schedule.on,\n listener = schedule.value[key] == null ? remove || (remove = styleRemove(name)) : undefined;\n\n // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener);\n\n schedule.on = on1;\n };\n}\n\nexport default function(name, value, priority) {\n var i = (name += \"\") === \"transform\" ? interpolateTransform : interpolate;\n return value == null ? this\n .styleTween(name, styleNull(name, i))\n .on(\"end.style.\" + name, styleRemove(name))\n : typeof value === \"function\" ? this\n .styleTween(name, styleFunction(name, i, tweenValue(this, \"style.\" + name, value)))\n .each(styleMaybeRemove(this._id, name))\n : this\n .styleTween(name, styleConstant(name, i, value), priority)\n .on(\"end.style.\" + name, null);\n}\n","function styleInterpolate(name, i, priority) {\n return function(t) {\n this.style.setProperty(name, i.call(this, t), priority);\n };\n}\n\nfunction styleTween(name, value, priority) {\n var t, i0;\n function tween() {\n var i = value.apply(this, arguments);\n if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority);\n return t;\n }\n tween._value = value;\n return tween;\n}\n\nexport default function(name, value, priority) {\n var key = \"style.\" + (name += \"\");\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n return this.tween(key, styleTween(name, value, priority == null ? \"\" : priority));\n}\n","import {tweenValue} from \"./tween.js\";\n\nfunction textConstant(value) {\n return function() {\n this.textContent = value;\n };\n}\n\nfunction textFunction(value) {\n return function() {\n var value1 = value(this);\n this.textContent = value1 == null ? \"\" : value1;\n };\n}\n\nexport default function(value) {\n return this.tween(\"text\", typeof value === \"function\"\n ? textFunction(tweenValue(this, \"text\", value))\n : textConstant(value == null ? \"\" : value + \"\"));\n}\n","function textInterpolate(i) {\n return function(t) {\n this.textContent = i.call(this, t);\n };\n}\n\nfunction textTween(value) {\n var t0, i0;\n function tween() {\n var i = value.apply(this, arguments);\n if (i !== i0) t0 = (i0 = i) && textInterpolate(i);\n return t0;\n }\n tween._value = value;\n return tween;\n}\n\nexport default function(value) {\n var key = \"text\";\n if (arguments.length < 1) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== \"function\") throw new Error;\n return this.tween(key, textTween(value));\n}\n","import {Transition, newId} from \"./index.js\";\nimport schedule, {get} from \"./schedule.js\";\n\nexport default function() {\n var name = this._name,\n id0 = this._id,\n id1 = newId();\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n var inherit = get(node, id0);\n schedule(node, name, id1, i, group, {\n time: inherit.time + inherit.delay + inherit.duration,\n delay: 0,\n duration: inherit.duration,\n ease: inherit.ease\n });\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id1);\n}\n","import {set} from \"./schedule.js\";\n\nexport default function() {\n var on0, on1, that = this, id = that._id, size = that.size();\n return new Promise(function(resolve, reject) {\n var cancel = {value: reject},\n end = {value: function() { if (--size === 0) resolve(); }};\n\n that.each(function() {\n var schedule = set(this, id),\n on = schedule.on;\n\n // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n if (on !== on0) {\n on1 = (on0 = on).copy();\n on1._.cancel.push(cancel);\n on1._.interrupt.push(cancel);\n on1._.end.push(end);\n }\n\n schedule.on = on1;\n });\n\n // The selection was empty, resolve end immediately\n if (size === 0) resolve();\n });\n}\n","import {selection} from \"d3-selection\";\nimport transition_attr from \"./attr.js\";\nimport transition_attrTween from \"./attrTween.js\";\nimport transition_delay from \"./delay.js\";\nimport transition_duration from \"./duration.js\";\nimport transition_ease from \"./ease.js\";\nimport transition_easeVarying from \"./easeVarying.js\";\nimport transition_filter from \"./filter.js\";\nimport transition_merge from \"./merge.js\";\nimport transition_on from \"./on.js\";\nimport transition_remove from \"./remove.js\";\nimport transition_select from \"./select.js\";\nimport transition_selectAll from \"./selectAll.js\";\nimport transition_selection from \"./selection.js\";\nimport transition_style from \"./style.js\";\nimport transition_styleTween from \"./styleTween.js\";\nimport transition_text from \"./text.js\";\nimport transition_textTween from \"./textTween.js\";\nimport transition_transition from \"./transition.js\";\nimport transition_tween from \"./tween.js\";\nimport transition_end from \"./end.js\";\n\nvar id = 0;\n\nexport function Transition(groups, parents, name, id) {\n this._groups = groups;\n this._parents = parents;\n this._name = name;\n this._id = id;\n}\n\nexport default function transition(name) {\n return selection().transition(name);\n}\n\nexport function newId() {\n return ++id;\n}\n\nvar selection_prototype = selection.prototype;\n\nTransition.prototype = transition.prototype = {\n constructor: Transition,\n select: transition_select,\n selectAll: transition_selectAll,\n selectChild: selection_prototype.selectChild,\n selectChildren: selection_prototype.selectChildren,\n filter: transition_filter,\n merge: transition_merge,\n selection: transition_selection,\n transition: transition_transition,\n call: selection_prototype.call,\n nodes: selection_prototype.nodes,\n node: selection_prototype.node,\n size: selection_prototype.size,\n empty: selection_prototype.empty,\n each: selection_prototype.each,\n on: transition_on,\n attr: transition_attr,\n attrTween: transition_attrTween,\n style: transition_style,\n styleTween: transition_styleTween,\n text: transition_text,\n textTween: transition_textTween,\n remove: transition_remove,\n tween: transition_tween,\n delay: transition_delay,\n duration: transition_duration,\n ease: transition_ease,\n easeVarying: transition_easeVarying,\n end: transition_end,\n [Symbol.iterator]: selection_prototype[Symbol.iterator]\n};\n","export const linear = t => +t;\n","export function cubicIn(t) {\n return t * t * t;\n}\n\nexport function cubicOut(t) {\n return --t * t * t + 1;\n}\n\nexport function cubicInOut(t) {\n return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;\n}\n","import {Transition, newId} from \"../transition/index.js\";\nimport schedule from \"../transition/schedule.js\";\nimport {easeCubicInOut} from \"d3-ease\";\nimport {now} from \"d3-timer\";\n\nvar defaultTiming = {\n time: null, // Set on use.\n delay: 0,\n duration: 250,\n ease: easeCubicInOut\n};\n\nfunction inherit(node, id) {\n var timing;\n while (!(timing = node.__transition) || !(timing = timing[id])) {\n if (!(node = node.parentNode)) {\n throw new Error(`transition ${id} not found`);\n }\n }\n return timing;\n}\n\nexport default function(name) {\n var id,\n timing;\n\n if (name instanceof Transition) {\n id = name._id, name = name._name;\n } else {\n id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + \"\";\n }\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n schedule(node, name, id, i, group, timing || inherit(node, id));\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id);\n}\n","import {selection} from \"d3-selection\";\nimport selection_interrupt from \"./interrupt.js\";\nimport selection_transition from \"./transition.js\";\n\nselection.prototype.interrupt = selection_interrupt;\nselection.prototype.transition = selection_transition;\n","import {dispatch} from \"d3-dispatch\";\nimport {dragDisable, dragEnable} from \"d3-drag\";\nimport {interpolate} from \"d3-interpolate\";\nimport {pointer, select} from \"d3-selection\";\nimport {interrupt} from \"d3-transition\";\nimport constant from \"./constant.js\";\nimport BrushEvent from \"./event.js\";\nimport noevent, {nopropagation} from \"./noevent.js\";\n\nvar MODE_DRAG = {name: \"drag\"},\n MODE_SPACE = {name: \"space\"},\n MODE_HANDLE = {name: \"handle\"},\n MODE_CENTER = {name: \"center\"};\n\nconst {abs, max, min} = Math;\n\nfunction number1(e) {\n return [+e[0], +e[1]];\n}\n\nfunction number2(e) {\n return [number1(e[0]), number1(e[1])];\n}\n\nvar X = {\n name: \"x\",\n handles: [\"w\", \"e\"].map(type),\n input: function(x, e) { return x == null ? null : [[+x[0], e[0][1]], [+x[1], e[1][1]]]; },\n output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }\n};\n\nvar Y = {\n name: \"y\",\n handles: [\"n\", \"s\"].map(type),\n input: function(y, e) { return y == null ? null : [[e[0][0], +y[0]], [e[1][0], +y[1]]]; },\n output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }\n};\n\nvar XY = {\n name: \"xy\",\n handles: [\"n\", \"w\", \"e\", \"s\", \"nw\", \"ne\", \"sw\", \"se\"].map(type),\n input: function(xy) { return xy == null ? null : number2(xy); },\n output: function(xy) { return xy; }\n};\n\nvar cursors = {\n overlay: \"crosshair\",\n selection: \"move\",\n n: \"ns-resize\",\n e: \"ew-resize\",\n s: \"ns-resize\",\n w: \"ew-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n se: \"nwse-resize\",\n sw: \"nesw-resize\"\n};\n\nvar flipX = {\n e: \"w\",\n w: \"e\",\n nw: \"ne\",\n ne: \"nw\",\n se: \"sw\",\n sw: \"se\"\n};\n\nvar flipY = {\n n: \"s\",\n s: \"n\",\n nw: \"sw\",\n ne: \"se\",\n se: \"ne\",\n sw: \"nw\"\n};\n\nvar signsX = {\n overlay: +1,\n selection: +1,\n n: null,\n e: +1,\n s: null,\n w: -1,\n nw: -1,\n ne: +1,\n se: +1,\n sw: -1\n};\n\nvar signsY = {\n overlay: +1,\n selection: +1,\n n: -1,\n e: null,\n s: +1,\n w: null,\n nw: -1,\n ne: -1,\n se: +1,\n sw: +1\n};\n\nfunction type(t) {\n return {type: t};\n}\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter(event) {\n return !event.ctrlKey && !event.button;\n}\n\nfunction defaultExtent() {\n var svg = this.ownerSVGElement || this;\n if (svg.hasAttribute(\"viewBox\")) {\n svg = svg.viewBox.baseVal;\n return [[svg.x, svg.y], [svg.x + svg.width, svg.y + svg.height]];\n }\n return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];\n}\n\nfunction defaultTouchable() {\n return navigator.maxTouchPoints || (\"ontouchstart\" in this);\n}\n\n// Like d3.local, but with the name “__brush” rather than auto-generated.\nfunction local(node) {\n while (!node.__brush) if (!(node = node.parentNode)) return;\n return node.__brush;\n}\n\nfunction empty(extent) {\n return extent[0][0] === extent[1][0]\n || extent[0][1] === extent[1][1];\n}\n\nexport function brushSelection(node) {\n var state = node.__brush;\n return state ? state.dim.output(state.selection) : null;\n}\n\nexport function brushX() {\n return brush(X);\n}\n\nexport function brushY() {\n return brush(Y);\n}\n\nexport default function() {\n return brush(XY);\n}\n\nfunction brush(dim) {\n var extent = defaultExtent,\n filter = defaultFilter,\n touchable = defaultTouchable,\n keys = true,\n listeners = dispatch(\"start\", \"brush\", \"end\"),\n handleSize = 6,\n touchending;\n\n function brush(group) {\n var overlay = group\n .property(\"__brush\", initialize)\n .selectAll(\".overlay\")\n .data([type(\"overlay\")]);\n\n overlay.enter().append(\"rect\")\n .attr(\"class\", \"overlay\")\n .attr(\"pointer-events\", \"all\")\n .attr(\"cursor\", cursors.overlay)\n .merge(overlay)\n .each(function() {\n var extent = local(this).extent;\n select(this)\n .attr(\"x\", extent[0][0])\n .attr(\"y\", extent[0][1])\n .attr(\"width\", extent[1][0] - extent[0][0])\n .attr(\"height\", extent[1][1] - extent[0][1]);\n });\n\n group.selectAll(\".selection\")\n .data([type(\"selection\")])\n .enter().append(\"rect\")\n .attr(\"class\", \"selection\")\n .attr(\"cursor\", cursors.selection)\n .attr(\"fill\", \"#777\")\n .attr(\"fill-opacity\", 0.3)\n .attr(\"stroke\", \"#fff\")\n .attr(\"shape-rendering\", \"crispEdges\");\n\n var handle = group.selectAll(\".handle\")\n .data(dim.handles, function(d) { return d.type; });\n\n handle.exit().remove();\n\n handle.enter().append(\"rect\")\n .attr(\"class\", function(d) { return \"handle handle--\" + d.type; })\n .attr(\"cursor\", function(d) { return cursors[d.type]; });\n\n group\n .each(redraw)\n .attr(\"fill\", \"none\")\n .attr(\"pointer-events\", \"all\")\n .on(\"mousedown.brush\", started)\n .filter(touchable)\n .on(\"touchstart.brush\", started)\n .on(\"touchmove.brush\", touchmoved)\n .on(\"touchend.brush touchcancel.brush\", touchended)\n .style(\"touch-action\", \"none\")\n .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n }\n\n brush.move = function(group, selection, event) {\n if (group.tween) {\n group\n .on(\"start.brush\", function(event) { emitter(this, arguments).beforestart().start(event); })\n .on(\"interrupt.brush end.brush\", function(event) { emitter(this, arguments).end(event); })\n .tween(\"brush\", function() {\n var that = this,\n state = that.__brush,\n emit = emitter(that, arguments),\n selection0 = state.selection,\n selection1 = dim.input(typeof selection === \"function\" ? selection.apply(this, arguments) : selection, state.extent),\n i = interpolate(selection0, selection1);\n\n function tween(t) {\n state.selection = t === 1 && selection1 === null ? null : i(t);\n redraw.call(that);\n emit.brush();\n }\n\n return selection0 !== null && selection1 !== null ? tween : tween(1);\n });\n } else {\n group\n .each(function() {\n var that = this,\n args = arguments,\n state = that.__brush,\n selection1 = dim.input(typeof selection === \"function\" ? selection.apply(that, args) : selection, state.extent),\n emit = emitter(that, args).beforestart();\n\n interrupt(that);\n state.selection = selection1 === null ? null : selection1;\n redraw.call(that);\n emit.start(event).brush(event).end(event);\n });\n }\n };\n\n brush.clear = function(group, event) {\n brush.move(group, null, event);\n };\n\n function redraw() {\n var group = select(this),\n selection = local(this).selection;\n\n if (selection) {\n group.selectAll(\".selection\")\n .style(\"display\", null)\n .attr(\"x\", selection[0][0])\n .attr(\"y\", selection[0][1])\n .attr(\"width\", selection[1][0] - selection[0][0])\n .attr(\"height\", selection[1][1] - selection[0][1]);\n\n group.selectAll(\".handle\")\n .style(\"display\", null)\n .attr(\"x\", function(d) { return d.type[d.type.length - 1] === \"e\" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })\n .attr(\"y\", function(d) { return d.type[0] === \"s\" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })\n .attr(\"width\", function(d) { return d.type === \"n\" || d.type === \"s\" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })\n .attr(\"height\", function(d) { return d.type === \"e\" || d.type === \"w\" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });\n }\n\n else {\n group.selectAll(\".selection,.handle\")\n .style(\"display\", \"none\")\n .attr(\"x\", null)\n .attr(\"y\", null)\n .attr(\"width\", null)\n .attr(\"height\", null);\n }\n }\n\n function emitter(that, args, clean) {\n var emit = that.__brush.emitter;\n return emit && (!clean || !emit.clean) ? emit : new Emitter(that, args, clean);\n }\n\n function Emitter(that, args, clean) {\n this.that = that;\n this.args = args;\n this.state = that.__brush;\n this.active = 0;\n this.clean = clean;\n }\n\n Emitter.prototype = {\n beforestart: function() {\n if (++this.active === 1) this.state.emitter = this, this.starting = true;\n return this;\n },\n start: function(event, mode) {\n if (this.starting) this.starting = false, this.emit(\"start\", event, mode);\n else this.emit(\"brush\", event);\n return this;\n },\n brush: function(event, mode) {\n this.emit(\"brush\", event, mode);\n return this;\n },\n end: function(event, mode) {\n if (--this.active === 0) delete this.state.emitter, this.emit(\"end\", event, mode);\n return this;\n },\n emit: function(type, event, mode) {\n var d = select(this.that).datum();\n listeners.call(\n type,\n this.that,\n new BrushEvent(type, {\n sourceEvent: event,\n target: brush,\n selection: dim.output(this.state.selection),\n mode,\n dispatch: listeners\n }),\n d\n );\n }\n };\n\n function started(event) {\n if (touchending && !event.touches) return;\n if (!filter.apply(this, arguments)) return;\n\n var that = this,\n type = event.target.__data__.type,\n mode = (keys && event.metaKey ? type = \"overlay\" : type) === \"selection\" ? MODE_DRAG : (keys && event.altKey ? MODE_CENTER : MODE_HANDLE),\n signX = dim === Y ? null : signsX[type],\n signY = dim === X ? null : signsY[type],\n state = local(that),\n extent = state.extent,\n selection = state.selection,\n W = extent[0][0], w0, w1,\n N = extent[0][1], n0, n1,\n E = extent[1][0], e0, e1,\n S = extent[1][1], s0, s1,\n dx = 0,\n dy = 0,\n moving,\n shifting = signX && signY && keys && event.shiftKey,\n lockX,\n lockY,\n points = Array.from(event.touches || [event], t => {\n const i = t.identifier;\n t = pointer(t, that);\n t.point0 = t.slice();\n t.identifier = i;\n return t;\n });\n\n interrupt(that);\n var emit = emitter(that, arguments, true).beforestart();\n\n if (type === \"overlay\") {\n if (selection) moving = true;\n const pts = [points[0], points[1] || points[0]];\n state.selection = selection = [[\n w0 = dim === Y ? W : min(pts[0][0], pts[1][0]),\n n0 = dim === X ? N : min(pts[0][1], pts[1][1])\n ], [\n e0 = dim === Y ? E : max(pts[0][0], pts[1][0]),\n s0 = dim === X ? S : max(pts[0][1], pts[1][1])\n ]];\n if (points.length > 1) move(event);\n } else {\n w0 = selection[0][0];\n n0 = selection[0][1];\n e0 = selection[1][0];\n s0 = selection[1][1];\n }\n\n w1 = w0;\n n1 = n0;\n e1 = e0;\n s1 = s0;\n\n var group = select(that)\n .attr(\"pointer-events\", \"none\");\n\n var overlay = group.selectAll(\".overlay\")\n .attr(\"cursor\", cursors[type]);\n\n if (event.touches) {\n emit.moved = moved;\n emit.ended = ended;\n } else {\n var view = select(event.view)\n .on(\"mousemove.brush\", moved, true)\n .on(\"mouseup.brush\", ended, true);\n if (keys) view\n .on(\"keydown.brush\", keydowned, true)\n .on(\"keyup.brush\", keyupped, true)\n\n dragDisable(event.view);\n }\n\n redraw.call(that);\n emit.start(event, mode.name);\n\n function moved(event) {\n for (const p of event.changedTouches || [event]) {\n for (const d of points)\n if (d.identifier === p.identifier) d.cur = pointer(p, that);\n }\n if (shifting && !lockX && !lockY && points.length === 1) {\n const point = points[0];\n if (abs(point.cur[0] - point[0]) > abs(point.cur[1] - point[1]))\n lockY = true;\n else\n lockX = true;\n }\n for (const point of points)\n if (point.cur) point[0] = point.cur[0], point[1] = point.cur[1];\n moving = true;\n noevent(event);\n move(event);\n }\n\n function move(event) {\n const point = points[0], point0 = point.point0;\n var t;\n\n dx = point[0] - point0[0];\n dy = point[1] - point0[1];\n\n switch (mode) {\n case MODE_SPACE:\n case MODE_DRAG: {\n if (signX) dx = max(W - w0, min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;\n if (signY) dy = max(N - n0, min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;\n break;\n }\n case MODE_HANDLE: {\n if (points[1]) {\n if (signX) w1 = max(W, min(E, points[0][0])), e1 = max(W, min(E, points[1][0])), signX = 1;\n if (signY) n1 = max(N, min(S, points[0][1])), s1 = max(N, min(S, points[1][1])), signY = 1;\n } else {\n if (signX < 0) dx = max(W - w0, min(E - w0, dx)), w1 = w0 + dx, e1 = e0;\n else if (signX > 0) dx = max(W - e0, min(E - e0, dx)), w1 = w0, e1 = e0 + dx;\n if (signY < 0) dy = max(N - n0, min(S - n0, dy)), n1 = n0 + dy, s1 = s0;\n else if (signY > 0) dy = max(N - s0, min(S - s0, dy)), n1 = n0, s1 = s0 + dy;\n }\n break;\n }\n case MODE_CENTER: {\n if (signX) w1 = max(W, min(E, w0 - dx * signX)), e1 = max(W, min(E, e0 + dx * signX));\n if (signY) n1 = max(N, min(S, n0 - dy * signY)), s1 = max(N, min(S, s0 + dy * signY));\n break;\n }\n }\n\n if (e1 < w1) {\n signX *= -1;\n t = w0, w0 = e0, e0 = t;\n t = w1, w1 = e1, e1 = t;\n if (type in flipX) overlay.attr(\"cursor\", cursors[type = flipX[type]]);\n }\n\n if (s1 < n1) {\n signY *= -1;\n t = n0, n0 = s0, s0 = t;\n t = n1, n1 = s1, s1 = t;\n if (type in flipY) overlay.attr(\"cursor\", cursors[type = flipY[type]]);\n }\n\n if (state.selection) selection = state.selection; // May be set by brush.move!\n if (lockX) w1 = selection[0][0], e1 = selection[1][0];\n if (lockY) n1 = selection[0][1], s1 = selection[1][1];\n\n if (selection[0][0] !== w1\n || selection[0][1] !== n1\n || selection[1][0] !== e1\n || selection[1][1] !== s1) {\n state.selection = [[w1, n1], [e1, s1]];\n redraw.call(that);\n emit.brush(event, mode.name);\n }\n }\n\n function ended(event) {\n nopropagation(event);\n if (event.touches) {\n if (event.touches.length) return;\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n } else {\n dragEnable(event.view, moving);\n view.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\", null);\n }\n group.attr(\"pointer-events\", \"all\");\n overlay.attr(\"cursor\", cursors.overlay);\n if (state.selection) selection = state.selection; // May be set by brush.move (on start)!\n if (empty(selection)) state.selection = null, redraw.call(that);\n emit.end(event, mode.name);\n }\n\n function keydowned(event) {\n switch (event.keyCode) {\n case 16: { // SHIFT\n shifting = signX && signY;\n break;\n }\n case 18: { // ALT\n if (mode === MODE_HANDLE) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n move(event);\n }\n break;\n }\n case 32: { // SPACE; takes priority over ALT\n if (mode === MODE_HANDLE || mode === MODE_CENTER) {\n if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;\n if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;\n mode = MODE_SPACE;\n overlay.attr(\"cursor\", cursors.selection);\n move(event);\n }\n break;\n }\n default: return;\n }\n noevent(event);\n }\n\n function keyupped(event) {\n switch (event.keyCode) {\n case 16: { // SHIFT\n if (shifting) {\n lockX = lockY = shifting = false;\n move(event);\n }\n break;\n }\n case 18: { // ALT\n if (mode === MODE_CENTER) {\n if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n move(event);\n }\n break;\n }\n case 32: { // SPACE\n if (mode === MODE_SPACE) {\n if (event.altKey) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n } else {\n if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n }\n overlay.attr(\"cursor\", cursors[type]);\n move(event);\n }\n break;\n }\n default: return;\n }\n noevent(event);\n }\n }\n\n function touchmoved(event) {\n emitter(this, arguments).moved(event);\n }\n\n function touchended(event) {\n emitter(this, arguments).ended(event);\n }\n\n function initialize() {\n var state = this.__brush || {selection: null};\n state.extent = number2(extent.apply(this, arguments));\n state.dim = dim;\n return state;\n }\n\n brush.extent = function(_) {\n return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant(number2(_)), brush) : extent;\n };\n\n brush.filter = function(_) {\n return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant(!!_), brush) : filter;\n };\n\n brush.touchable = function(_) {\n return arguments.length ? (touchable = typeof _ === \"function\" ? _ : constant(!!_), brush) : touchable;\n };\n\n brush.handleSize = function(_) {\n return arguments.length ? (handleSize = +_, brush) : handleSize;\n };\n\n brush.keyModifiers = function(_) {\n return arguments.length ? (keys = !!_, brush) : keys;\n };\n\n brush.on = function() {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? brush : value;\n };\n\n return brush;\n}\n","var EOL = {},\n EOF = {},\n QUOTE = 34,\n NEWLINE = 10,\n RETURN = 13;\n\nfunction objectConverter(columns) {\n return new Function(\"d\", \"return {\" + columns.map(function(name, i) {\n return JSON.stringify(name) + \": d[\" + i + \"] || \\\"\\\"\";\n }).join(\",\") + \"}\");\n}\n\nfunction customConverter(columns, f) {\n var object = objectConverter(columns);\n return function(row, i) {\n return f(object(row), i, columns);\n };\n}\n\n// Compute unique columns in order of discovery.\nfunction inferColumns(rows) {\n var columnSet = Object.create(null),\n columns = [];\n\n rows.forEach(function(row) {\n for (var column in row) {\n if (!(column in columnSet)) {\n columns.push(columnSet[column] = column);\n }\n }\n });\n\n return columns;\n}\n\nfunction pad(value, width) {\n var s = value + \"\", length = s.length;\n return length < width ? new Array(width - length + 1).join(0) + s : s;\n}\n\nfunction formatYear(year) {\n return year < 0 ? \"-\" + pad(-year, 6)\n : year > 9999 ? \"+\" + pad(year, 6)\n : pad(year, 4);\n}\n\nfunction formatDate(date) {\n var hours = date.getUTCHours(),\n minutes = date.getUTCMinutes(),\n seconds = date.getUTCSeconds(),\n milliseconds = date.getUTCMilliseconds();\n return isNaN(date) ? \"Invalid Date\"\n : formatYear(date.getUTCFullYear(), 4) + \"-\" + pad(date.getUTCMonth() + 1, 2) + \"-\" + pad(date.getUTCDate(), 2)\n + (milliseconds ? \"T\" + pad(hours, 2) + \":\" + pad(minutes, 2) + \":\" + pad(seconds, 2) + \".\" + pad(milliseconds, 3) + \"Z\"\n : seconds ? \"T\" + pad(hours, 2) + \":\" + pad(minutes, 2) + \":\" + pad(seconds, 2) + \"Z\"\n : minutes || hours ? \"T\" + pad(hours, 2) + \":\" + pad(minutes, 2) + \"Z\"\n : \"\");\n}\n\nexport default function(delimiter) {\n var reFormat = new RegExp(\"[\\\"\" + delimiter + \"\\n\\r]\"),\n DELIMITER = delimiter.charCodeAt(0);\n\n function parse(text, f) {\n var convert, columns, rows = parseRows(text, function(row, i) {\n if (convert) return convert(row, i - 1);\n columns = row, convert = f ? customConverter(row, f) : objectConverter(row);\n });\n rows.columns = columns || [];\n return rows;\n }\n\n function parseRows(text, f) {\n var rows = [], // output rows\n N = text.length,\n I = 0, // current character index\n n = 0, // current line number\n t, // current token\n eof = N <= 0, // current token followed by EOF?\n eol = false; // current token followed by EOL?\n\n // Strip the trailing newline.\n if (text.charCodeAt(N - 1) === NEWLINE) --N;\n if (text.charCodeAt(N - 1) === RETURN) --N;\n\n function token() {\n if (eof) return EOF;\n if (eol) return eol = false, EOL;\n\n // Unescape quotes.\n var i, j = I, c;\n if (text.charCodeAt(j) === QUOTE) {\n while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);\n if ((i = I) >= N) eof = true;\n else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n return text.slice(j + 1, i - 1).replace(/\"\"/g, \"\\\"\");\n }\n\n // Find next delimiter or newline.\n while (I < N) {\n if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;\n else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }\n else if (c !== DELIMITER) continue;\n return text.slice(j, i);\n }\n\n // Return last token before EOF.\n return eof = true, text.slice(j, N);\n }\n\n while ((t = token()) !== EOF) {\n var row = [];\n while (t !== EOL && t !== EOF) row.push(t), t = token();\n if (f && (row = f(row, n++)) == null) continue;\n rows.push(row);\n }\n\n return rows;\n }\n\n function preformatBody(rows, columns) {\n return rows.map(function(row) {\n return columns.map(function(column) {\n return formatValue(row[column]);\n }).join(delimiter);\n });\n }\n\n function format(rows, columns) {\n if (columns == null) columns = inferColumns(rows);\n return [columns.map(formatValue).join(delimiter)].concat(preformatBody(rows, columns)).join(\"\\n\");\n }\n\n function formatBody(rows, columns) {\n if (columns == null) columns = inferColumns(rows);\n return preformatBody(rows, columns).join(\"\\n\");\n }\n\n function formatRows(rows) {\n return rows.map(formatRow).join(\"\\n\");\n }\n\n function formatRow(row) {\n return row.map(formatValue).join(delimiter);\n }\n\n function formatValue(value) {\n return value == null ? \"\"\n : value instanceof Date ? formatDate(value)\n : reFormat.test(value += \"\") ? \"\\\"\" + value.replace(/\"/g, \"\\\"\\\"\") + \"\\\"\"\n : value;\n }\n\n return {\n parse: parse,\n parseRows: parseRows,\n format: format,\n formatBody: formatBody,\n formatRows: formatRows,\n formatRow: formatRow,\n formatValue: formatValue\n };\n}\n","import dsv from \"./dsv.js\";\n\nvar csv = dsv(\",\");\n\nexport var csvParse = csv.parse;\nexport var csvParseRows = csv.parseRows;\nexport var csvFormat = csv.format;\nexport var csvFormatBody = csv.formatBody;\nexport var csvFormatRows = csv.formatRows;\nexport var csvFormatRow = csv.formatRow;\nexport var csvFormatValue = csv.formatValue;\n","import dsv from \"./dsv.js\";\n\nvar tsv = dsv(\"\\t\");\n\nexport var tsvParse = tsv.parse;\nexport var tsvParseRows = tsv.parseRows;\nexport var tsvFormat = tsv.format;\nexport var tsvFormatBody = tsv.formatBody;\nexport var tsvFormatRows = tsv.formatRows;\nexport var tsvFormatRow = tsv.formatRow;\nexport var tsvFormatValue = tsv.formatValue;\n","export function initRange(domain, range) {\n switch (arguments.length) {\n case 0: break;\n case 1: this.range(domain); break;\n default: this.range(range).domain(domain); break;\n }\n return this;\n}\n\nexport function initInterpolator(domain, interpolator) {\n switch (arguments.length) {\n case 0: break;\n case 1: {\n if (typeof domain === \"function\") this.interpolator(domain);\n else this.range(domain);\n break;\n }\n default: {\n this.domain(domain);\n if (typeof interpolator === \"function\") this.interpolator(interpolator);\n else this.range(interpolator);\n break;\n }\n }\n return this;\n}\n","import {InternMap} from \"d3-array\";\nimport {initRange} from \"./init.js\";\n\nexport const implicit = Symbol(\"implicit\");\n\nexport default function ordinal() {\n var index = new InternMap(),\n domain = [],\n range = [],\n unknown = implicit;\n\n function scale(d) {\n let i = index.get(d);\n if (i === undefined) {\n if (unknown !== implicit) return unknown;\n index.set(d, i = domain.push(d) - 1);\n }\n return range[i % range.length];\n }\n\n scale.domain = function(_) {\n if (!arguments.length) return domain.slice();\n domain = [], index = new InternMap();\n for (const value of _) {\n if (index.has(value)) continue;\n index.set(value, domain.push(value) - 1);\n }\n return scale;\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), scale) : range.slice();\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n scale.copy = function() {\n return ordinal(domain, range).unknown(unknown);\n };\n\n initRange.apply(scale, arguments);\n\n return scale;\n}\n","export default function constants(x) {\n return function() {\n return x;\n };\n}\n","export default function number(x) {\n return +x;\n}\n","import {bisect} from \"d3-array\";\nimport {interpolate as interpolateValue, interpolateNumber, interpolateRound} from \"d3-interpolate\";\nimport constant from \"./constant.js\";\nimport number from \"./number.js\";\n\nvar unit = [0, 1];\n\nexport function identity(x) {\n return x;\n}\n\nfunction normalize(a, b) {\n return (b -= (a = +a))\n ? function(x) { return (x - a) / b; }\n : constant(isNaN(b) ? NaN : 0.5);\n}\n\nfunction clamper(a, b) {\n var t;\n if (a > b) t = a, a = b, b = t;\n return function(x) { return Math.max(a, Math.min(b, x)); };\n}\n\n// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].\nfunction bimap(domain, range, interpolate) {\n var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];\n if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);\n else d0 = normalize(d0, d1), r0 = interpolate(r0, r1);\n return function(x) { return r0(d0(x)); };\n}\n\nfunction polymap(domain, range, interpolate) {\n var j = Math.min(domain.length, range.length) - 1,\n d = new Array(j),\n r = new Array(j),\n i = -1;\n\n // Reverse descending domains.\n if (domain[j] < domain[0]) {\n domain = domain.slice().reverse();\n range = range.slice().reverse();\n }\n\n while (++i < j) {\n d[i] = normalize(domain[i], domain[i + 1]);\n r[i] = interpolate(range[i], range[i + 1]);\n }\n\n return function(x) {\n var i = bisect(domain, x, 1, j) - 1;\n return r[i](d[i](x));\n };\n}\n\nexport function copy(source, target) {\n return target\n .domain(source.domain())\n .range(source.range())\n .interpolate(source.interpolate())\n .clamp(source.clamp())\n .unknown(source.unknown());\n}\n\nexport function transformer() {\n var domain = unit,\n range = unit,\n interpolate = interpolateValue,\n transform,\n untransform,\n unknown,\n clamp = identity,\n piecewise,\n output,\n input;\n\n function rescale() {\n var n = Math.min(domain.length, range.length);\n if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]);\n piecewise = n > 2 ? polymap : bimap;\n output = input = null;\n return scale;\n }\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));\n }\n\n scale.invert = function(y) {\n return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)));\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice();\n };\n\n scale.range = function(_) {\n return arguments.length ? (range = Array.from(_), rescale()) : range.slice();\n };\n\n scale.rangeRound = function(_) {\n return range = Array.from(_), interpolate = interpolateRound, rescale();\n };\n\n scale.clamp = function(_) {\n return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity;\n };\n\n scale.interpolate = function(_) {\n return arguments.length ? (interpolate = _, rescale()) : interpolate;\n };\n\n scale.unknown = function(_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n return function(t, u) {\n transform = t, untransform = u;\n return rescale();\n };\n}\n\nexport default function continuous() {\n return transformer()(identity, identity);\n}\n","export default function(x) {\n return Math.abs(x = Math.round(x)) >= 1e21\n ? x.toLocaleString(\"en\").replace(/,/g, \"\")\n : x.toString(10);\n}\n\n// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimalParts(1.23) returns [\"123\", 0].\nexport function formatDecimalParts(x, p) {\n if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\")) < 0) return null; // NaN, ±Infinity\n var i, coefficient = x.slice(0, i);\n\n // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n return [\n coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n +x.slice(i + 1)\n ];\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x) {\n return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;\n}\n","export default function(grouping, thousands) {\n return function(value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n","export default function(numerals) {\n return function(value) {\n return value.replace(/[0-9]/g, function(i) {\n return numerals[+i];\n });\n };\n}\n","// [[fill]align][sign][symbol][0][width][,][.precision][~][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;\n\nexport default function formatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n var match;\n return new FormatSpecifier({\n fill: match[1],\n align: match[2],\n sign: match[3],\n symbol: match[4],\n zero: match[5],\n width: match[6],\n comma: match[7],\n precision: match[8] && match[8].slice(1),\n trim: match[9],\n type: match[10]\n });\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nexport function FormatSpecifier(specifier) {\n this.fill = specifier.fill === undefined ? \" \" : specifier.fill + \"\";\n this.align = specifier.align === undefined ? \">\" : specifier.align + \"\";\n this.sign = specifier.sign === undefined ? \"-\" : specifier.sign + \"\";\n this.symbol = specifier.symbol === undefined ? \"\" : specifier.symbol + \"\";\n this.zero = !!specifier.zero;\n this.width = specifier.width === undefined ? undefined : +specifier.width;\n this.comma = !!specifier.comma;\n this.precision = specifier.precision === undefined ? undefined : +specifier.precision;\n this.trim = !!specifier.trim;\n this.type = specifier.type === undefined ? \"\" : specifier.type + \"\";\n}\n\nFormatSpecifier.prototype.toString = function() {\n return this.fill\n + this.align\n + this.sign\n + this.symbol\n + (this.zero ? \"0\" : \"\")\n + (this.width === undefined ? \"\" : Math.max(1, this.width | 0))\n + (this.comma ? \",\" : \"\")\n + (this.precision === undefined ? \"\" : \".\" + Math.max(0, this.precision | 0))\n + (this.trim ? \"~\" : \"\")\n + this.type;\n};\n","// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.\nexport default function(s) {\n out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (s[i]) {\n case \".\": i0 = i1 = i; break;\n case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break;\n }\n }\n return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport var prefixExponent;\n\nexport default function(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient\n : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return x + \"\";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n","import formatDecimal from \"./formatDecimal.js\";\nimport formatPrefixAuto from \"./formatPrefixAuto.js\";\nimport formatRounded from \"./formatRounded.js\";\n\nexport default {\n \"%\": (x, p) => (x * 100).toFixed(p),\n \"b\": (x) => Math.round(x).toString(2),\n \"c\": (x) => x + \"\",\n \"d\": formatDecimal,\n \"e\": (x, p) => x.toExponential(p),\n \"f\": (x, p) => x.toFixed(p),\n \"g\": (x, p) => x.toPrecision(p),\n \"o\": (x) => Math.round(x).toString(8),\n \"p\": (x, p) => formatRounded(x * 100, p),\n \"r\": formatRounded,\n \"s\": formatPrefixAuto,\n \"X\": (x) => Math.round(x).toString(16).toUpperCase(),\n \"x\": (x) => Math.round(x).toString(16)\n};\n","export default function(x) {\n return x;\n}\n","import exponent from \"./exponent.js\";\nimport formatGroup from \"./formatGroup.js\";\nimport formatNumerals from \"./formatNumerals.js\";\nimport formatSpecifier from \"./formatSpecifier.js\";\nimport formatTrim from \"./formatTrim.js\";\nimport formatTypes from \"./formatTypes.js\";\nimport {prefixExponent} from \"./formatPrefixAuto.js\";\nimport identity from \"./identity.js\";\n\nvar map = Array.prototype.map,\n prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nexport default function(locale) {\n var group = locale.grouping === undefined || locale.thousands === undefined ? identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + \"\"),\n currencyPrefix = locale.currency === undefined ? \"\" : locale.currency[0] + \"\",\n currencySuffix = locale.currency === undefined ? \"\" : locale.currency[1] + \"\",\n decimal = locale.decimal === undefined ? \".\" : locale.decimal + \"\",\n numerals = locale.numerals === undefined ? identity : formatNumerals(map.call(locale.numerals, String)),\n percent = locale.percent === undefined ? \"%\" : locale.percent + \"\",\n minus = locale.minus === undefined ? \"−\" : locale.minus + \"\",\n nan = locale.nan === undefined ? \"NaN\" : locale.nan + \"\";\n\n function newFormat(specifier) {\n specifier = formatSpecifier(specifier);\n\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n trim = specifier.trim,\n type = specifier.type;\n\n // The \"n\" type is an alias for \",g\".\n if (type === \"n\") comma = true, type = \"g\";\n\n // The \"\" type, and any invalid type, is an alias for \".12~g\".\n else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = \"g\";\n\n // If zero fill is specified, padding goes after sign and before digits.\n if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n var prefix = symbol === \"$\" ? currencyPrefix : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\",\n suffix = symbol === \"$\" ? currencySuffix : /[%p]/.test(type) ? percent : \"\";\n\n // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n var formatType = formatTypes[type],\n maybeSuffix = /[defgprs%]/.test(type);\n\n // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n precision = precision === undefined ? 6\n : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i, n, c;\n\n if (type === \"c\") {\n valueSuffix = formatType(value) + valueSuffix;\n value = \"\";\n } else {\n value = +value;\n\n // Determine the sign. -0 is not less than 0, but 1 / -0 is!\n var valueNegative = value < 0 || 1 / value < 0;\n\n // Perform the initial formatting.\n value = isNaN(value) ? nan : formatType(Math.abs(value), precision);\n\n // Trim insignificant zeros.\n if (trim) value = formatTrim(value);\n\n // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.\n if (valueNegative && +value === 0 && sign !== \"+\") valueNegative = false;\n\n // Compute the prefix and suffix.\n valuePrefix = (valueNegative ? (sign === \"(\" ? sign : minus) : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n valueSuffix = (type === \"s\" ? prefixes[8 + prefixExponent / 3] : \"\") + valueSuffix + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n if (maybeSuffix) {\n i = -1, n = value.length;\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n }\n\n // If the fill character is not \"0\", grouping is applied before padding.\n if (comma && !zero) value = group(value, Infinity);\n\n // Compute the padding.\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n // If the fill character is \"0\", grouping is applied after padding.\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n // Reconstruct the final output based on the desired alignment.\n switch (align) {\n case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n default: value = padding + valuePrefix + value + valueSuffix; break;\n }\n\n return numerals(value);\n }\n\n format.toString = function() {\n return specifier + \"\";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier)),\n e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,\n k = Math.pow(10, -e),\n prefix = prefixes[8 + e / 3];\n return function(value) {\n return f(k * value) + prefix;\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var format;\nexport var formatPrefix;\n\ndefaultLocale({\n thousands: \",\",\n grouping: [3],\n currency: [\"$\", \"\"]\n});\n\nexport default function defaultLocale(definition) {\n locale = formatLocale(definition);\n format = locale.format;\n formatPrefix = locale.formatPrefix;\n return locale;\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step) {\n return Math.max(0, -exponent(Math.abs(step)));\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step, value) {\n return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step, max) {\n step = Math.abs(step), max = Math.abs(max) - step;\n return Math.max(0, exponent(max) - exponent(step)) + 1;\n}\n","import {tickStep} from \"d3-array\";\nimport {format, formatPrefix, formatSpecifier, precisionFixed, precisionPrefix, precisionRound} from \"d3-format\";\n\nexport default function tickFormat(start, stop, count, specifier) {\n var step = tickStep(start, stop, count),\n precision;\n specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n switch (specifier.type) {\n case \"s\": {\n var value = Math.max(Math.abs(start), Math.abs(stop));\n if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n return formatPrefix(specifier, value);\n }\n case \"\":\n case \"e\":\n case \"g\":\n case \"p\":\n case \"r\": {\n if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n break;\n }\n case \"f\":\n case \"%\": {\n if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n break;\n }\n }\n return format(specifier);\n}\n","import {ticks, tickIncrement} from \"d3-array\";\nimport continuous, {copy} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\nimport tickFormat from \"./tickFormat.js\";\n\nexport function linearish(scale) {\n var domain = scale.domain;\n\n scale.ticks = function(count) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n };\n\n scale.tickFormat = function(count, specifier) {\n var d = domain();\n return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);\n };\n\n scale.nice = function(count) {\n if (count == null) count = 10;\n\n var d = domain();\n var i0 = 0;\n var i1 = d.length - 1;\n var start = d[i0];\n var stop = d[i1];\n var prestep;\n var step;\n var maxIter = 10;\n\n if (stop < start) {\n step = start, start = stop, stop = step;\n step = i0, i0 = i1, i1 = step;\n }\n \n while (maxIter-- > 0) {\n step = tickIncrement(start, stop, count);\n if (step === prestep) {\n d[i0] = start\n d[i1] = stop\n return domain(d);\n } else if (step > 0) {\n start = Math.floor(start / step) * step;\n stop = Math.ceil(stop / step) * step;\n } else if (step < 0) {\n start = Math.ceil(start * step) / step;\n stop = Math.floor(stop * step) / step;\n } else {\n break;\n }\n prestep = step;\n }\n\n return scale;\n };\n\n return scale;\n}\n\nexport default function linear() {\n var scale = continuous();\n\n scale.copy = function() {\n return copy(scale, linear());\n };\n\n initRange.apply(scale, arguments);\n\n return linearish(scale);\n}\n","export default function nice(domain, interval) {\n domain = domain.slice();\n\n var i0 = 0,\n i1 = domain.length - 1,\n x0 = domain[i0],\n x1 = domain[i1],\n t;\n\n if (x1 < x0) {\n t = i0, i0 = i1, i1 = t;\n t = x0, x0 = x1, x1 = t;\n }\n\n domain[i0] = interval.floor(x0);\n domain[i1] = interval.ceil(x1);\n return domain;\n}\n","import {ticks} from \"d3-array\";\nimport {format, formatSpecifier} from \"d3-format\";\nimport nice from \"./nice.js\";\nimport {copy, transformer} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\n\nfunction transformLog(x) {\n return Math.log(x);\n}\n\nfunction transformExp(x) {\n return Math.exp(x);\n}\n\nfunction transformLogn(x) {\n return -Math.log(-x);\n}\n\nfunction transformExpn(x) {\n return -Math.exp(-x);\n}\n\nfunction pow10(x) {\n return isFinite(x) ? +(\"1e\" + x) : x < 0 ? 0 : x;\n}\n\nfunction powp(base) {\n return base === 10 ? pow10\n : base === Math.E ? Math.exp\n : x => Math.pow(base, x);\n}\n\nfunction logp(base) {\n return base === Math.E ? Math.log\n : base === 10 && Math.log10\n || base === 2 && Math.log2\n || (base = Math.log(base), x => Math.log(x) / base);\n}\n\nfunction reflect(f) {\n return (x, k) => -f(-x, k);\n}\n\nexport function loggish(transform) {\n const scale = transform(transformLog, transformExp);\n const domain = scale.domain;\n let base = 10;\n let logs;\n let pows;\n\n function rescale() {\n logs = logp(base), pows = powp(base);\n if (domain()[0] < 0) {\n logs = reflect(logs), pows = reflect(pows);\n transform(transformLogn, transformExpn);\n } else {\n transform(transformLog, transformExp);\n }\n return scale;\n }\n\n scale.base = function(_) {\n return arguments.length ? (base = +_, rescale()) : base;\n };\n\n scale.domain = function(_) {\n return arguments.length ? (domain(_), rescale()) : domain();\n };\n\n scale.ticks = count => {\n const d = domain();\n let u = d[0];\n let v = d[d.length - 1];\n const r = v < u;\n\n if (r) ([u, v] = [v, u]);\n\n let i = logs(u);\n let j = logs(v);\n let k;\n let t;\n const n = count == null ? 10 : +count;\n let z = [];\n\n if (!(base % 1) && j - i < n) {\n i = Math.floor(i), j = Math.ceil(j);\n if (u > 0) for (; i <= j; ++i) {\n for (k = 1; k < base; ++k) {\n t = i < 0 ? k / pows(-i) : k * pows(i);\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n } else for (; i <= j; ++i) {\n for (k = base - 1; k >= 1; --k) {\n t = i > 0 ? k / pows(-i) : k * pows(i);\n if (t < u) continue;\n if (t > v) break;\n z.push(t);\n }\n }\n if (z.length * 2 < n) z = ticks(u, v, n);\n } else {\n z = ticks(i, j, Math.min(j - i, n)).map(pows);\n }\n return r ? z.reverse() : z;\n };\n\n scale.tickFormat = (count, specifier) => {\n if (count == null) count = 10;\n if (specifier == null) specifier = base === 10 ? \"s\" : \",\";\n if (typeof specifier !== \"function\") {\n if (!(base % 1) && (specifier = formatSpecifier(specifier)).precision == null) specifier.trim = true;\n specifier = format(specifier);\n }\n if (count === Infinity) return specifier;\n const k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?\n return d => {\n let i = d / pows(Math.round(logs(d)));\n if (i * base < base - 0.5) i *= base;\n return i <= k ? specifier(d) : \"\";\n };\n };\n\n scale.nice = () => {\n return domain(nice(domain(), {\n floor: x => pows(Math.floor(logs(x))),\n ceil: x => pows(Math.ceil(logs(x)))\n }));\n };\n\n return scale;\n}\n\nexport default function log() {\n const scale = loggish(transformer()).domain([1, 10]);\n scale.copy = () => copy(scale, log()).base(scale.base());\n initRange.apply(scale, arguments);\n return scale;\n}\n","import {linearish} from \"./linear.js\";\nimport {copy, transformer} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\n\nfunction transformSymlog(c) {\n return function(x) {\n return Math.sign(x) * Math.log1p(Math.abs(x / c));\n };\n}\n\nfunction transformSymexp(c) {\n return function(x) {\n return Math.sign(x) * Math.expm1(Math.abs(x)) * c;\n };\n}\n\nexport function symlogish(transform) {\n var c = 1, scale = transform(transformSymlog(c), transformSymexp(c));\n\n scale.constant = function(_) {\n return arguments.length ? transform(transformSymlog(c = +_), transformSymexp(c)) : c;\n };\n\n return linearish(scale);\n}\n\nexport default function symlog() {\n var scale = symlogish(transformer());\n\n scale.copy = function() {\n return copy(scale, symlog()).constant(scale.constant());\n };\n\n return initRange.apply(scale, arguments);\n}\n","import {timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeTicks, timeTickInterval} from \"d3-time\";\nimport {timeFormat} from \"d3-time-format\";\nimport continuous, {copy} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\nimport nice from \"./nice.js\";\n\nfunction date(t) {\n return new Date(t);\n}\n\nfunction number(t) {\n return t instanceof Date ? +t : +new Date(+t);\n}\n\nexport function calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format) {\n var scale = continuous(),\n invert = scale.invert,\n domain = scale.domain;\n\n var formatMillisecond = format(\".%L\"),\n formatSecond = format(\":%S\"),\n formatMinute = format(\"%I:%M\"),\n formatHour = format(\"%I %p\"),\n formatDay = format(\"%a %d\"),\n formatWeek = format(\"%b %d\"),\n formatMonth = format(\"%B\"),\n formatYear = format(\"%Y\");\n\n function tickFormat(date) {\n return (second(date) < date ? formatMillisecond\n : minute(date) < date ? formatSecond\n : hour(date) < date ? formatMinute\n : day(date) < date ? formatHour\n : month(date) < date ? (week(date) < date ? formatDay : formatWeek)\n : year(date) < date ? formatMonth\n : formatYear)(date);\n }\n\n scale.invert = function(y) {\n return new Date(invert(y));\n };\n\n scale.domain = function(_) {\n return arguments.length ? domain(Array.from(_, number)) : domain().map(date);\n };\n\n scale.ticks = function(interval) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], interval == null ? 10 : interval);\n };\n\n scale.tickFormat = function(count, specifier) {\n return specifier == null ? tickFormat : format(specifier);\n };\n\n scale.nice = function(interval) {\n var d = domain();\n if (!interval || typeof interval.range !== \"function\") interval = tickInterval(d[0], d[d.length - 1], interval == null ? 10 : interval);\n return interval ? domain(nice(d, interval)) : scale;\n };\n\n scale.copy = function() {\n return copy(scale, calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format));\n };\n\n return scale;\n}\n\nexport default function time() {\n return initRange.apply(calendar(timeTicks, timeTickInterval, timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]), arguments);\n}\n","import {utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcTicks, utcTickInterval} from \"d3-time\";\nimport {utcFormat} from \"d3-time-format\";\nimport {calendar} from \"./time.js\";\nimport {initRange} from \"./init.js\";\n\nexport default function utcTime() {\n return initRange.apply(calendar(utcTicks, utcTickInterval, utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]), arguments);\n}\n","export default function(x) {\n return function constant() {\n return x;\n };\n}\n","export const abs = Math.abs;\nexport const atan2 = Math.atan2;\nexport const cos = Math.cos;\nexport const max = Math.max;\nexport const min = Math.min;\nexport const sin = Math.sin;\nexport const sqrt = Math.sqrt;\n\nexport const epsilon = 1e-12;\nexport const pi = Math.PI;\nexport const halfPi = pi / 2;\nexport const tau = 2 * pi;\n\nexport function acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nexport function asin(x) {\n return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);\n}\n","const pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction append(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += arguments[i] + strings[i];\n }\n}\n\nfunction appendRound(digits) {\n let d = Math.floor(digits);\n if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);\n if (d > 15) return append;\n const k = 10 ** d;\n return function(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += Math.round(arguments[i] * k) / k + strings[i];\n }\n };\n}\n\nexport class Path {\n constructor(digits) {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n this._append = digits == null ? append : appendRound(digits);\n }\n moveTo(x, y) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}`;\n }\n closePath() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._append`Z`;\n }\n }\n lineTo(x, y) {\n this._append`L${this._x1 = +x},${this._y1 = +y}`;\n }\n quadraticCurveTo(x1, y1, x, y) {\n this._append`Q${+x1},${+y1},${this._x1 = +x},${this._y1 = +y}`;\n }\n bezierCurveTo(x1, y1, x2, y2, x, y) {\n this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x},${this._y1 = +y}`;\n }\n arcTo(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._append`M${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._append`L${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Otherwise, draw an arc!\n else {\n let x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;\n }\n\n this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;\n }\n }\n arc(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._append`M${x0},${y0}`;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._append`L${x0},${y0}`;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._append`A${r},${r},0,1,${cw},${x - dx},${y - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x + r * Math.cos(a1)},${this._y1 = y + r * Math.sin(a1)}`;\n }\n }\n rect(x, y, w, h) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}h${w = +w}v${+h}h${-w}Z`;\n }\n toString() {\n return this._;\n }\n}\n\nexport function path() {\n return new Path;\n}\n\n// Allow instanceof d3.path\npath.prototype = Path.prototype;\n\nexport function pathRound(digits = 3) {\n return new Path(+digits);\n}\n","import {Path} from \"d3-path\";\n\nexport function withPath(shape) {\n let digits = 3;\n\n shape.digits = function(_) {\n if (!arguments.length) return digits;\n if (_ == null) {\n digits = null;\n } else {\n const d = Math.floor(_);\n if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);\n digits = d;\n }\n return shape;\n };\n\n return () => new Path(digits);\n}\n","export var slice = Array.prototype.slice;\n\nexport default function(x) {\n return typeof x === \"object\" && \"length\" in x\n ? x // Array, TypedArray, NodeList, array-like\n : Array.from(x); // Map, Set, iterable, string, or anything else\n}\n","function Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // falls through\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nexport default function(context) {\n return new Linear(context);\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport curveLinear from \"./curve/linear.js\";\nimport {withPath} from \"./path.js\";\nimport {x as pointX, y as pointY} from \"./point.js\";\n\nexport default function(x, y) {\n var defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null,\n path = withPath(line);\n\n x = typeof x === \"function\" ? x : (x === undefined) ? pointX : constant(x);\n y = typeof y === \"function\" ? y : (y === undefined) ? pointY : constant(y);\n\n function line(data) {\n var i,\n n = (data = array(data)).length,\n d,\n defined0 = false,\n buffer;\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) output.lineStart();\n else output.lineEnd();\n }\n if (defined0) output.point(+x(d, i, data), +y(d, i, data));\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n line.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), line) : x;\n };\n\n line.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), line) : y;\n };\n\n line.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), line) : defined;\n };\n\n line.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;\n };\n\n line.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;\n };\n\n return line;\n}\n","export default function() {}\n","export function point(that, x, y) {\n that._context.bezierCurveTo(\n (2 * that._x0 + that._x1) / 3,\n (2 * that._y0 + that._y1) / 3,\n (that._x0 + 2 * that._x1) / 3,\n (that._y0 + 2 * that._y1) / 3,\n (that._x0 + 4 * that._x1 + x) / 6,\n (that._y0 + 4 * that._y1 + y) / 6\n );\n}\n\nexport function Basis(context) {\n this._context = context;\n}\n\nBasis.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 3: point(this, this._x1, this._y1); // falls through\n case 2: this._context.lineTo(this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // falls through\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new Basis(context);\n}\n","import noop from \"../noop.js\";\nimport {point} from \"./basis.js\";\n\nfunction BasisClosed(context) {\n this._context = context;\n}\n\nBasisClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x2, this._y2);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);\n this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x2, this._y2);\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x2 = x, this._y2 = y; break;\n case 1: this._point = 2; this._x3 = x, this._y3 = y; break;\n case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisClosed(context);\n}\n","import {point} from \"./basis.js\";\n\nfunction BasisOpen(context) {\n this._context = context;\n}\n\nBasisOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;\n case 3: this._point = 4; // falls through\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n }\n};\n\nexport default function(context) {\n return new BasisOpen(context);\n}\n","import {Basis} from \"./basis.js\";\n\nfunction Bundle(context, beta) {\n this._basis = new Basis(context);\n this._beta = beta;\n}\n\nBundle.prototype = {\n lineStart: function() {\n this._x = [];\n this._y = [];\n this._basis.lineStart();\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n j = x.length - 1;\n\n if (j > 0) {\n var x0 = x[0],\n y0 = y[0],\n dx = x[j] - x0,\n dy = y[j] - y0,\n i = -1,\n t;\n\n while (++i <= j) {\n t = i / j;\n this._basis.point(\n this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),\n this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)\n );\n }\n }\n\n this._x = this._y = null;\n this._basis.lineEnd();\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\nexport default (function custom(beta) {\n\n function bundle(context) {\n return beta === 1 ? new Basis(context) : new Bundle(context, beta);\n }\n\n bundle.beta = function(beta) {\n return custom(+beta);\n };\n\n return bundle;\n})(0.85);\n","export function point(that, x, y) {\n that._context.bezierCurveTo(\n that._x1 + that._k * (that._x2 - that._x0),\n that._y1 + that._k * (that._y2 - that._y0),\n that._x2 + that._k * (that._x1 - x),\n that._y2 + that._k * (that._y1 - y),\n that._x2,\n that._y2\n );\n}\n\nexport function Cardinal(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinal.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: point(this, this._x1, this._y1); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; this._x1 = x, this._y1 = y; break;\n case 2: this._point = 3; // falls through\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new Cardinal(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import noop from \"../noop.js\";\nimport {point} from \"./cardinal.js\";\n\nexport function CardinalClosed(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalClosed(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import {point} from \"./cardinal.js\";\n\nexport function CardinalOpen(context, tension) {\n this._context = context;\n this._k = (1 - tension) / 6;\n}\n\nCardinalOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // falls through\n default: point(this, x, y); break;\n }\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(tension) {\n\n function cardinal(context) {\n return new CardinalOpen(context, tension);\n }\n\n cardinal.tension = function(tension) {\n return custom(+tension);\n };\n\n return cardinal;\n})(0);\n","import {epsilon} from \"../math.js\";\nimport {Cardinal} from \"./cardinal.js\";\n\nexport function point(that, x, y) {\n var x1 = that._x1,\n y1 = that._y1,\n x2 = that._x2,\n y2 = that._y2;\n\n if (that._l01_a > epsilon) {\n var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,\n n = 3 * that._l01_a * (that._l01_a + that._l12_a);\n x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;\n y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;\n }\n\n if (that._l23_a > epsilon) {\n var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,\n m = 3 * that._l23_a * (that._l23_a + that._l12_a);\n x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;\n y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;\n }\n\n that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);\n}\n\nfunction CatmullRom(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRom.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x2, this._y2); break;\n case 3: this.point(this._x2, this._y2); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; // falls through\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import {CardinalClosed} from \"./cardinalClosed.js\";\nimport noop from \"../noop.js\";\nimport {point} from \"./catmullRom.js\";\n\nfunction CatmullRomClosed(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =\n this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 1: {\n this._context.moveTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 2: {\n this._context.lineTo(this._x3, this._y3);\n this._context.closePath();\n break;\n }\n case 3: {\n this.point(this._x3, this._y3);\n this.point(this._x4, this._y4);\n this.point(this._x5, this._y5);\n break;\n }\n }\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; this._x3 = x, this._y3 = y; break;\n case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;\n case 2: this._point = 3; this._x5 = x, this._y5 = y; break;\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import {CardinalOpen} from \"./cardinalOpen.js\";\nimport {point} from \"./catmullRom.js\";\n\nfunction CatmullRomOpen(context, alpha) {\n this._context = context;\n this._alpha = alpha;\n}\n\nCatmullRomOpen.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 = this._x2 =\n this._y0 = this._y1 = this._y2 = NaN;\n this._l01_a = this._l12_a = this._l23_a =\n this._l01_2a = this._l12_2a = this._l23_2a =\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n\n if (this._point) {\n var x23 = this._x2 - x,\n y23 = this._y2 - y;\n this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));\n }\n\n switch (this._point) {\n case 0: this._point = 1; break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;\n case 3: this._point = 4; // falls through\n default: point(this, x, y); break;\n }\n\n this._l01_a = this._l12_a, this._l12_a = this._l23_a;\n this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;\n this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;\n this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;\n }\n};\n\nexport default (function custom(alpha) {\n\n function catmullRom(context) {\n return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);\n }\n\n catmullRom.alpha = function(alpha) {\n return custom(+alpha);\n };\n\n return catmullRom;\n})(0.5);\n","import noop from \"../noop.js\";\n\nfunction LinearClosed(context) {\n this._context = context;\n}\n\nLinearClosed.prototype = {\n areaStart: noop,\n areaEnd: noop,\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._point) this._context.closePath();\n },\n point: function(x, y) {\n x = +x, y = +y;\n if (this._point) this._context.lineTo(x, y);\n else this._point = 1, this._context.moveTo(x, y);\n }\n};\n\nexport default function(context) {\n return new LinearClosed(context);\n}\n","function sign(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n}\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nexport function monotoneX(context) {\n return new MonotoneX(context);\n}\n\nexport function monotoneY(context) {\n return new MonotoneY(context);\n}\n","function Natural(context) {\n this._context = context;\n}\n\nNatural.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = [];\n this._y = [];\n },\n lineEnd: function() {\n var x = this._x,\n y = this._y,\n n = x.length;\n\n if (n) {\n this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);\n if (n === 2) {\n this._context.lineTo(x[1], y[1]);\n } else {\n var px = controlPoints(x),\n py = controlPoints(y);\n for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {\n this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);\n }\n }\n }\n\n if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();\n this._line = 1 - this._line;\n this._x = this._y = null;\n },\n point: function(x, y) {\n this._x.push(+x);\n this._y.push(+y);\n }\n};\n\n// See https://www.particleincell.com/2012/bezier-splines/ for derivation.\nfunction controlPoints(x) {\n var i,\n n = x.length - 1,\n m,\n a = new Array(n),\n b = new Array(n),\n r = new Array(n);\n a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];\n for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];\n a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];\n for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];\n a[n - 1] = r[n - 1] / b[n - 1];\n for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];\n b[n - 1] = (x[n] + a[n - 1]) / 2;\n for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];\n return [a, b];\n}\n\nexport default function(context) {\n return new Natural(context);\n}\n","function Step(context, t) {\n this._context = context;\n this._t = t;\n}\n\nStep.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x = this._y = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // falls through\n default: {\n if (this._t <= 0) {\n this._context.lineTo(this._x, y);\n this._context.lineTo(x, y);\n } else {\n var x1 = this._x * (1 - this._t) + x * this._t;\n this._context.lineTo(x1, this._y);\n this._context.lineTo(x1, y);\n }\n break;\n }\n }\n this._x = x, this._y = y;\n }\n};\n\nexport default function(context) {\n return new Step(context, 0.5);\n}\n\nexport function stepBefore(context) {\n return new Step(context, 0);\n}\n\nexport function stepAfter(context) {\n return new Step(context, 1);\n}\n","export default function(x) {\n return x;\n}\n","import identity from \"./identity.js\";\n\nvar top = 1,\n right = 2,\n bottom = 3,\n left = 4,\n epsilon = 1e-6;\n\nfunction translateX(x) {\n return \"translate(\" + x + \",0)\";\n}\n\nfunction translateY(y) {\n return \"translate(0,\" + y + \")\";\n}\n\nfunction number(scale) {\n return d => +scale(d);\n}\n\nfunction center(scale, offset) {\n offset = Math.max(0, scale.bandwidth() - offset * 2) / 2;\n if (scale.round()) offset = Math.round(offset);\n return d => +scale(d) + offset;\n}\n\nfunction entering() {\n return !this.__axis;\n}\n\nfunction axis(orient, scale) {\n var tickArguments = [],\n tickValues = null,\n tickFormat = null,\n tickSizeInner = 6,\n tickSizeOuter = 6,\n tickPadding = 3,\n offset = typeof window !== \"undefined\" && window.devicePixelRatio > 1 ? 0 : 0.5,\n k = orient === top || orient === left ? -1 : 1,\n x = orient === left || orient === right ? \"x\" : \"y\",\n transform = orient === top || orient === bottom ? translateX : translateY;\n\n function axis(context) {\n var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,\n format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity) : tickFormat,\n spacing = Math.max(tickSizeInner, 0) + tickPadding,\n range = scale.range(),\n range0 = +range[0] + offset,\n range1 = +range[range.length - 1] + offset,\n position = (scale.bandwidth ? center : number)(scale.copy(), offset),\n selection = context.selection ? context.selection() : context,\n path = selection.selectAll(\".domain\").data([null]),\n tick = selection.selectAll(\".tick\").data(values, scale).order(),\n tickExit = tick.exit(),\n tickEnter = tick.enter().append(\"g\").attr(\"class\", \"tick\"),\n line = tick.select(\"line\"),\n text = tick.select(\"text\");\n\n path = path.merge(path.enter().insert(\"path\", \".tick\")\n .attr(\"class\", \"domain\")\n .attr(\"stroke\", \"currentColor\"));\n\n tick = tick.merge(tickEnter);\n\n line = line.merge(tickEnter.append(\"line\")\n .attr(\"stroke\", \"currentColor\")\n .attr(x + \"2\", k * tickSizeInner));\n\n text = text.merge(tickEnter.append(\"text\")\n .attr(\"fill\", \"currentColor\")\n .attr(x, k * spacing)\n .attr(\"dy\", orient === top ? \"0em\" : orient === bottom ? \"0.71em\" : \"0.32em\"));\n\n if (context !== selection) {\n path = path.transition(context);\n tick = tick.transition(context);\n line = line.transition(context);\n text = text.transition(context);\n\n tickExit = tickExit.transition(context)\n .attr(\"opacity\", epsilon)\n .attr(\"transform\", function(d) { return isFinite(d = position(d)) ? transform(d + offset) : this.getAttribute(\"transform\"); });\n\n tickEnter\n .attr(\"opacity\", epsilon)\n .attr(\"transform\", function(d) { var p = this.parentNode.__axis; return transform((p && isFinite(p = p(d)) ? p : position(d)) + offset); });\n }\n\n tickExit.remove();\n\n path\n .attr(\"d\", orient === left || orient === right\n ? (tickSizeOuter ? \"M\" + k * tickSizeOuter + \",\" + range0 + \"H\" + offset + \"V\" + range1 + \"H\" + k * tickSizeOuter : \"M\" + offset + \",\" + range0 + \"V\" + range1)\n : (tickSizeOuter ? \"M\" + range0 + \",\" + k * tickSizeOuter + \"V\" + offset + \"H\" + range1 + \"V\" + k * tickSizeOuter : \"M\" + range0 + \",\" + offset + \"H\" + range1));\n\n tick\n .attr(\"opacity\", 1)\n .attr(\"transform\", function(d) { return transform(position(d) + offset); });\n\n line\n .attr(x + \"2\", k * tickSizeInner);\n\n text\n .attr(x, k * spacing)\n .text(format);\n\n selection.filter(entering)\n .attr(\"fill\", \"none\")\n .attr(\"font-size\", 10)\n .attr(\"font-family\", \"sans-serif\")\n .attr(\"text-anchor\", orient === right ? \"start\" : orient === left ? \"end\" : \"middle\");\n\n selection\n .each(function() { this.__axis = position; });\n }\n\n axis.scale = function(_) {\n return arguments.length ? (scale = _, axis) : scale;\n };\n\n axis.ticks = function() {\n return tickArguments = Array.from(arguments), axis;\n };\n\n axis.tickArguments = function(_) {\n return arguments.length ? (tickArguments = _ == null ? [] : Array.from(_), axis) : tickArguments.slice();\n };\n\n axis.tickValues = function(_) {\n return arguments.length ? (tickValues = _ == null ? null : Array.from(_), axis) : tickValues && tickValues.slice();\n };\n\n axis.tickFormat = function(_) {\n return arguments.length ? (tickFormat = _, axis) : tickFormat;\n };\n\n axis.tickSize = function(_) {\n return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;\n };\n\n axis.tickSizeInner = function(_) {\n return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;\n };\n\n axis.tickSizeOuter = function(_) {\n return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;\n };\n\n axis.tickPadding = function(_) {\n return arguments.length ? (tickPadding = +_, axis) : tickPadding;\n };\n\n axis.offset = function(_) {\n return arguments.length ? (offset = +_, axis) : offset;\n };\n\n return axis;\n}\n\nexport function axisTop(scale) {\n return axis(top, scale);\n}\n\nexport function axisRight(scale) {\n return axis(right, scale);\n}\n\nexport function axisBottom(scale) {\n return axis(bottom, scale);\n}\n\nexport function axisLeft(scale) {\n return axis(left, scale);\n}\n","export function Transform(k, x, y) {\n this.k = k;\n this.x = x;\n this.y = y;\n}\n\nTransform.prototype = {\n constructor: Transform,\n scale: function(k) {\n return k === 1 ? this : new Transform(this.k * k, this.x, this.y);\n },\n translate: function(x, y) {\n return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);\n },\n apply: function(point) {\n return [point[0] * this.k + this.x, point[1] * this.k + this.y];\n },\n applyX: function(x) {\n return x * this.k + this.x;\n },\n applyY: function(y) {\n return y * this.k + this.y;\n },\n invert: function(location) {\n return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];\n },\n invertX: function(x) {\n return (x - this.x) / this.k;\n },\n invertY: function(y) {\n return (y - this.y) / this.k;\n },\n rescaleX: function(x) {\n return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));\n },\n rescaleY: function(y) {\n return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));\n },\n toString: function() {\n return \"translate(\" + this.x + \",\" + this.y + \") scale(\" + this.k + \")\";\n }\n};\n\nexport var identity = new Transform(1, 0, 0);\n\ntransform.prototype = Transform.prototype;\n\nexport default function transform(node) {\n while (!node.__zoom) if (!(node = node.parentNode)) return identity;\n return node.__zoom;\n}\n","/*!\n* Copyright (c) 2017 ~ present NAVER Corp.\r\n * billboard.js project is licensed under the MIT license\r\n * \r\n * billboard.js, JavaScript chart library\r\n * https://naver.github.io/billboard.js/\r\n * \r\n * @version 3.7.5\n*/\nimport { timeParse, utcParse, timeFormat, utcFormat } from 'd3-time-format';\nimport { pointer, select, namespaces, selectAll } from 'd3-selection';\nimport { brushSelection, brushY, brushX } from 'd3-brush';\nimport { csvParseRows, csvParse, tsvParseRows, tsvParse } from 'd3-dsv';\nimport { drag as drag$1 } from 'd3-drag';\nimport { scaleOrdinal, scaleLinear, scaleSymlog, scaleLog, scaleTime, scaleUtc } from 'd3-scale';\nimport { transition } from 'd3-transition';\nimport { curveBasis, curveBasisClosed, curveBasisOpen, curveBundle, curveCardinal, curveCardinalClosed, curveCardinalOpen, curveCatmullRom, curveCatmullRomClosed, curveCatmullRomOpen, curveMonotoneX, curveMonotoneY, curveNatural, curveLinearClosed, curveLinear, curveStep, curveStepAfter, curveStepBefore, pie as pie$1, arc, area as area$1, line as line$1 } from 'd3-shape';\nimport { axisLeft, axisBottom, axisTop, axisRight } from 'd3-axis';\nimport { easeLinear } from 'd3-ease';\nimport { interpolate } from 'd3-interpolate';\nimport { treemap as treemap$1, hierarchy, treemapBinary, treemapDice, treemapSlice, treemapSliceDice, treemapSquarify, treemapResquarify } from 'd3-hierarchy';\nimport { zoomIdentity, zoomTransform, zoom as zoom$2 } from 'd3-zoom';\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar win = (function () {\n var root = (typeof globalThis === \"object\" && globalThis !== null && globalThis.Object === Object && globalThis) ||\n (typeof global === \"object\" && global !== null && global.Object === Object && global) ||\n (typeof self === \"object\" && self !== null && self.Object === Object && self);\n return root || Function(\"return this\")();\n})();\n/* eslint-enable no-new-func, no-undef */\n// fallback for non-supported environments\nwin.requestIdleCallback = win.requestIdleCallback || (function (cb) { return setTimeout(cb, 1); });\n// win.cancelIdleCallback = win.cancelIdleCallback || (id => clearTimeout(id));\nwin.requestAnimationFrame = win.requestAnimationFrame || (function (cb) { return setTimeout(cb, 1); });\nvar doc = win === null || win === void 0 ? void 0 : win.document;\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Chart type constant\n * @private\n */\nvar TYPE = {\n AREA: \"area\",\n AREA_LINE_RANGE: \"area-line-range\",\n AREA_SPLINE: \"area-spline\",\n AREA_SPLINE_RANGE: \"area-spline-range\",\n AREA_STEP: \"area-step\",\n BAR: \"bar\",\n BUBBLE: \"bubble\",\n CANDLESTICK: \"candlestick\",\n DONUT: \"donut\",\n GAUGE: \"gauge\",\n LINE: \"line\",\n PIE: \"pie\",\n POLAR: \"polar\",\n RADAR: \"radar\",\n SCATTER: \"scatter\",\n SPLINE: \"spline\",\n STEP: \"step\",\n TREEMAP: \"treemap\"\n};\n/**\n * Chart type module and its method from ChartInternal class, needed to be initialized.\n * @private\n */\nvar TYPE_METHOD_NEEDED = {\n AREA: \"initArea\",\n AREA_LINE_RANGE: \"initArea\",\n AREA_SPLINE: \"initArea\",\n AREA_SPLINE_RANGE: \"initArea\",\n AREA_STEP: \"initArea\",\n BAR: \"initBar\",\n BUBBLE: \"initCircle\",\n CANDLESTICK: \"initCandlestick\",\n DONUT: \"initArc\",\n GAUGE: \"initArc\",\n LINE: \"initLine\",\n PIE: \"initArc\",\n POLAR: \"initPolar\",\n RADAR: \"initCircle\",\n SCATTER: \"initCircle\",\n SPLINE: \"initLine\",\n STEP: \"initLine\",\n TREEMAP: \"initTreemap\"\n};\n/**\n * chart types by category\n * @private\n */\nvar TYPE_BY_CATEGORY = {\n Area: [\n TYPE.AREA,\n TYPE.AREA_SPLINE,\n TYPE.AREA_SPLINE_RANGE,\n TYPE.AREA_LINE_RANGE,\n TYPE.AREA_STEP\n ],\n AreaRange: [\n TYPE.AREA_SPLINE_RANGE,\n TYPE.AREA_LINE_RANGE\n ],\n Arc: [\n TYPE.PIE,\n TYPE.DONUT,\n TYPE.GAUGE,\n TYPE.POLAR,\n TYPE.RADAR\n ],\n Line: [\n TYPE.LINE,\n TYPE.SPLINE,\n TYPE.AREA,\n TYPE.AREA_SPLINE,\n TYPE.AREA_SPLINE_RANGE,\n TYPE.AREA_LINE_RANGE,\n TYPE.STEP,\n TYPE.AREA_STEP\n ],\n Step: [\n TYPE.STEP,\n TYPE.AREA_STEP\n ],\n Spline: [\n TYPE.SPLINE,\n TYPE.AREA_SPLINE,\n TYPE.AREA_SPLINE_RANGE\n ]\n};\n\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\nvar _assign = function __assign() {\n _assign = Object.assign || function (t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n };\n return _assign.apply(this, arguments);\n};\nfunction __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nvar isValue = function (v) { return v || v === 0; };\nvar isFunction = function (v) { return typeof v === \"function\"; };\nvar isString = function (v) { return typeof v === \"string\"; };\nvar isNumber = function (v) { return typeof v === \"number\"; };\nvar isUndefined = function (v) { return typeof v === \"undefined\"; };\nvar isDefined = function (v) { return typeof v !== \"undefined\"; };\nvar isboolean = function (v) { return typeof v === \"boolean\"; };\nvar ceil10 = function (v) { return Math.ceil(v / 10) * 10; };\nvar asHalfPixel = function (n) { return Math.ceil(n) + 0.5; };\nvar diffDomain = function (d) { return d[1] - d[0]; };\nvar isObjectType = function (v) { return typeof v === \"object\"; };\nvar isEmpty = function (o) { return (isUndefined(o) || o === null ||\n (isString(o) && o.length === 0) ||\n (isObjectType(o) && !(o instanceof Date) && Object.keys(o).length === 0) ||\n (isNumber(o) && isNaN(o))); };\nvar notEmpty = function (o) { return !isEmpty(o); };\n/**\n * Check if is array\n * @param {Array} arr Data to be checked\n * @returns {boolean}\n * @private\n */\nvar isArray = function (arr) { return Array.isArray(arr); };\n/**\n * Check if is object\n * @param {object} obj Data to be checked\n * @returns {boolean}\n * @private\n */\nvar isObject = function (obj) { return obj && !(obj === null || obj === void 0 ? void 0 : obj.nodeType) && isObjectType(obj) && !isArray(obj); };\n/**\n * Get specified key value from object\n * If default value is given, will return if given key value not found\n * @param {object} options Source object\n * @param {string} key Key value\n * @param {*} defaultValue Default value\n * @returns {*}\n * @private\n */\nfunction getOption(options, key, defaultValue) {\n return isDefined(options[key]) ? options[key] : defaultValue;\n}\n/**\n * Check if value exist in the given object\n * @param {object} dict Target object to be checked\n * @param {*} value Value to be checked\n * @returns {boolean}\n * @private\n */\nfunction hasValue(dict, value) {\n var found = false;\n Object.keys(dict).forEach(function (key) { return (dict[key] === value) && (found = true); });\n return found;\n}\n/**\n * Call function with arguments\n * @param {Function} fn Function to be called\n * @param {*} thisArg \"this\" value for fn\n * @param {*} args Arguments for fn\n * @returns {boolean} true: fn is function, false: fn is not function\n * @private\n */\nfunction callFn(fn, thisArg) {\n var args = [];\n for (var _i = 2; _i < arguments.length; _i++) {\n args[_i - 2] = arguments[_i];\n }\n var isFn = isFunction(fn);\n isFn && fn.call.apply(fn, __spreadArray([thisArg], args, false));\n return isFn;\n}\n/**\n * Call function after all transitions ends\n * @param {d3.transition} transition Transition\n * @param {Fucntion} cb Callback function\n * @private\n */\nfunction endall(transition, cb) {\n var n = 0;\n var end = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n !--n && cb.apply.apply(cb, __spreadArray([this], args, false));\n };\n // if is transition selection\n if (\"duration\" in transition) {\n transition\n .each(function () { return ++n; })\n .on(\"end\", end);\n }\n else {\n ++n;\n transition.call(end);\n }\n}\n/**\n * Replace tag sign to html entity\n * @param {string} str Target string value\n * @returns {string}\n * @private\n */\nfunction sanitise(str) {\n return isString(str) ?\n str.replace(//g, \">\") : str;\n}\n/**\n * Set text value. If there's multiline add nodes.\n * @param {d3Selection} node Text node\n * @param {string} text Text value string\n * @param {Array} dy dy value for multilined text\n * @param {boolean} toMiddle To be alingned vertically middle\n * @private\n */\nfunction setTextValue(node, text, dy, toMiddle) {\n if (dy === void 0) { dy = [-1, 1]; }\n if (toMiddle === void 0) { toMiddle = false; }\n if (!node || !isString(text)) {\n return;\n }\n if (text.indexOf(\"\\n\") === -1) {\n node.text(text);\n }\n else {\n var diff = [node.text(), text].map(function (v) { return v.replace(/[\\s\\n]/g, \"\"); });\n if (diff[0] !== diff[1]) {\n var multiline = text.split(\"\\n\");\n var len_1 = toMiddle ? multiline.length - 1 : 1;\n // reset possible text\n node.html(\"\");\n multiline.forEach(function (v, i) {\n node.append(\"tspan\")\n .attr(\"x\", 0)\n .attr(\"dy\", \"\".concat(i === 0 ? dy[0] * len_1 : dy[1], \"em\"))\n .text(v);\n });\n }\n }\n}\n/**\n * Substitution of SVGPathSeg API polyfill\n * @param {SVGGraphicsElement} path Target svg element\n * @returns {Array}\n * @private\n */\nfunction getRectSegList(path) {\n /*\n * seg1 ---------- seg2\n * | |\n * | |\n * | |\n * seg0 ---------- seg3\n * */\n var _a = path.getBBox(), x = _a.x, y = _a.y, width = _a.width, height = _a.height;\n return [\n { x: x, y: y + height },\n { x: x, y: y },\n { x: x + width, y: y },\n { x: x + width, y: y + height } // seg3\n ];\n}\n/**\n * Get svg bounding path box dimension\n * @param {SVGGraphicsElement} path Target svg element\n * @returns {object}\n * @private\n */\nfunction getPathBox(path) {\n var _a = path.getBoundingClientRect(), width = _a.width, height = _a.height;\n var items = getRectSegList(path);\n var x = items[0].x;\n var y = Math.min(items[0].y, items[1].y);\n return {\n x: x,\n y: y,\n width: width,\n height: height\n };\n}\n/**\n * Get event's current position coordinates\n * @param {object} event Event object\n * @param {SVGElement|HTMLElement} element Target element\n * @returns {Array} [x, y] Coordinates x, y array\n * @private\n */\nfunction getPointer(event, element) {\n var _a;\n var touches = event && ((_a = (event.touches || (event.sourceEvent && event.sourceEvent.touches))) === null || _a === void 0 ? void 0 : _a[0]);\n var pointer$1 = pointer(touches || event, element);\n return pointer$1.map(function (v) { return (isNaN(v) ? 0 : v); });\n}\n/**\n * Return brush selection array\n * @param {object} ctx Current instance\n * @returns {d3.brushSelection}\n * @private\n */\nfunction getBrushSelection(ctx) {\n var event = ctx.event, $el = ctx.$el;\n var main = $el.subchart.main || $el.main;\n var selection;\n // check from event\n if (event && event.type === \"brush\") {\n selection = event.selection;\n // check from brush area selection\n }\n else if (main && (selection = main.select(\".bb-brush\").node())) {\n selection = brushSelection(selection);\n }\n return selection;\n}\n/**\n * Get boundingClientRect.\n * Cache the evaluated value once it was called.\n * @param {HTMLElement} node Target element\n * @returns {object}\n * @private\n */\nfunction getBoundingRect(node) {\n var needEvaluate = !(\"rect\" in node) || (\"rect\" in node && node.hasAttribute(\"width\") && node.rect.width !== +node.getAttribute(\"width\"));\n return needEvaluate ?\n (node.rect = node.getBoundingClientRect()) : node.rect;\n}\n/**\n * Retrun random number\n * @param {boolean} asStr Convert returned value as string\n * @param {number} min Minimum value\n * @param {number} max Maximum value\n * @returns {number|string}\n * @private\n */\nfunction getRandom(asStr, min, max) {\n if (asStr === void 0) { asStr = true; }\n if (min === void 0) { min = 0; }\n if (max === void 0) { max = 10000; }\n var crpt = win.crypto || win.msCrypto;\n var rand = crpt ?\n min + crpt.getRandomValues(new Uint32Array(1))[0] % (max - min + 1) :\n Math.floor(Math.random() * (max - min) + min);\n return asStr ? String(rand) : rand;\n}\n/**\n * Find index based on binary search\n * @param {Array} arr Data array\n * @param {number} v Target number to find\n * @param {number} start Start index of data array\n * @param {number} end End index of data arr\n * @param {boolean} isRotated Weather is roted axis\n * @returns {number} Index number\n * @private\n */\nfunction findIndex(arr, v, start, end, isRotated) {\n if (start > end) {\n return -1;\n }\n var mid = Math.floor((start + end) / 2);\n var _a = arr[mid], x = _a.x, _b = _a.w, w = _b === void 0 ? 0 : _b;\n if (isRotated) {\n x = arr[mid].y;\n w = arr[mid].h;\n }\n if (v >= x && v <= x + w) {\n return mid;\n }\n return v < x ?\n findIndex(arr, v, start, mid - 1, isRotated) :\n findIndex(arr, v, mid + 1, end, isRotated);\n}\n/**\n * Check if brush is empty\n * @param {object} ctx Bursh context\n * @returns {boolean}\n * @private\n */\nfunction brushEmpty(ctx) {\n var selection = getBrushSelection(ctx);\n if (selection) {\n // brush selected area\n // two-dimensional: [[x0, y0], [x1, y1]]\n // one-dimensional: [x0, x1] or [y0, y1]\n return selection[0] === selection[1];\n }\n return true;\n}\n/**\n * Deep copy object\n * @param {object} objectN Source object\n * @returns {object} Cloned object\n * @private\n */\nfunction deepClone() {\n var objectN = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n objectN[_i] = arguments[_i];\n }\n var clone = function (v) {\n if (isObject(v) && v.constructor) {\n var r = new v.constructor();\n for (var k in v) {\n r[k] = clone(v[k]);\n }\n return r;\n }\n return v;\n };\n return objectN.map(function (v) { return clone(v); })\n .reduce(function (a, c) { return (_assign(_assign({}, a), c)); });\n}\n/**\n * Extend target from source object\n * @param {object} target Target object\n * @param {object|Array} source Source object\n * @returns {object}\n * @private\n */\nfunction extend(target, source) {\n if (target === void 0) { target = {}; }\n if (isArray(source)) {\n source.forEach(function (v) { return extend(target, v); });\n }\n // exclude name with only numbers\n for (var p in source) {\n if (/^\\d+$/.test(p) || p in target) {\n continue;\n }\n target[p] = source[p];\n }\n return target;\n}\n/**\n * Return first letter capitalized\n * @param {string} str Target string\n * @returns {string} capitalized string\n * @private\n */\nvar capitalize = function (str) { return str.charAt(0).toUpperCase() + str.slice(1); };\n/**\n * Camelize from kebob style string\n * @param {string} str Target string\n * @param {string} separator Separator string\n * @returns {string} camelized string\n * @private\n */\nfunction camelize(str, separator) {\n if (separator === void 0) { separator = \"-\"; }\n return str.split(separator)\n .map(function (v, i) { return (i ? v.charAt(0).toUpperCase() + v.slice(1).toLowerCase() : v.toLowerCase()); })\n .join(\"\");\n}\n/**\n * Convert to array\n * @param {object} v Target to be converted\n * @returns {Array}\n * @private\n */\nvar toArray = function (v) { return [].slice.call(v); };\n/**\n * Add CSS rules\n * @param {object} style Style object\n * @param {string} selector Selector string\n * @param {Array} prop Prps arrary\n * @returns {number} Newely added rule index\n * @private\n */\nfunction addCssRules(style, selector, prop) {\n var rootSelctor = style.rootSelctor, sheet = style.sheet;\n var getSelector = function (s) { return s\n .replace(/\\s?(bb-)/g, \".$1\")\n .replace(/\\.+/g, \".\"); };\n var rule = \"\".concat(rootSelctor, \" \").concat(getSelector(selector), \" {\").concat(prop.join(\";\"), \"}\");\n return sheet[sheet.insertRule ? \"insertRule\" : \"addRule\"](rule, sheet.cssRules.length);\n}\n/**\n * Get css rules for specified stylesheets\n * @param {Array} styleSheets The stylesheets to get the rules from\n * @returns {Array}\n * @private\n */\nfunction getCssRules(styleSheets) {\n var rules = [];\n styleSheets.forEach(function (sheet) {\n var _a;\n try {\n if (sheet.cssRules && sheet.cssRules.length) {\n rules = rules.concat(toArray(sheet.cssRules));\n }\n }\n catch (e) {\n (_a = win.console) === null || _a === void 0 ? void 0 : _a.warn(\"Error while reading rules from \".concat(sheet.href, \": \").concat(e.toString()));\n }\n });\n return rules;\n}\n/**\n * Gets the SVGMatrix of an SVGGElement\n * @param {SVGElement} node Node element\n * @returns {SVGMatrix} matrix\n * @private\n */\nfunction getTranslation(node) {\n var transform = node ? node.transform : null;\n var baseVal = transform && transform.baseVal;\n return baseVal && baseVal.numberOfItems ?\n baseVal.getItem(0).matrix :\n { a: 0, b: 0, c: 0, d: 0, e: 0, f: 0 };\n}\n/**\n * Get unique value from array\n * @param {Array} data Source data\n * @returns {Array} Unique array value\n * @private\n */\nfunction getUnique(data) {\n var isDate = data[0] instanceof Date;\n var d = (isDate ? data.map(Number) : data)\n .filter(function (v, i, self) { return self.indexOf(v) === i; });\n return isDate ? d.map(function (v) { return new Date(v); }) : d;\n}\n/**\n * Merge array\n * @param {Array} arr Source array\n * @returns {Array}\n * @private\n */\nfunction mergeArray(arr) {\n return arr && arr.length ? arr.reduce(function (p, c) { return p.concat(c); }) : [];\n}\n/**\n * Merge object returning new object\n * @param {object} target Target object\n * @param {object} objectN Source object\n * @returns {object} merged target object\n * @private\n */\nfunction mergeObj(target) {\n var objectN = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n objectN[_i - 1] = arguments[_i];\n }\n if (!objectN.length || (objectN.length === 1 && !objectN[0])) {\n return target;\n }\n var source = objectN.shift();\n if (isObject(target) && isObject(source)) {\n Object.keys(source).forEach(function (key) {\n var value = source[key];\n if (isObject(value)) {\n !target[key] && (target[key] = {});\n target[key] = mergeObj(target[key], value);\n }\n else {\n target[key] = isArray(value) ?\n value.concat() : value;\n }\n });\n }\n return mergeObj.apply(void 0, __spreadArray([target], objectN, false));\n}\n/**\n * Sort value\n * @param {Array} data value to be sorted\n * @param {boolean} isAsc true: asc, false: desc\n * @returns {number|string|Date} sorted date\n * @private\n */\nfunction sortValue(data, isAsc) {\n if (isAsc === void 0) { isAsc = true; }\n var fn;\n if (data[0] instanceof Date) {\n fn = isAsc ? function (a, b) { return a - b; } : function (a, b) { return b - a; };\n }\n else {\n if (isAsc && !data.every(isNaN)) {\n fn = function (a, b) { return a - b; };\n }\n else if (!isAsc) {\n fn = function (a, b) { return (a > b && -1) || (a < b && 1) || (a === b && 0); };\n }\n }\n return data.concat().sort(fn);\n}\n/**\n * Get min/max value\n * @param {string} type 'min' or 'max'\n * @param {Array} data Array data value\n * @returns {number|Date|undefined}\n * @private\n */\nfunction getMinMax$1(type, data) {\n var res = data.filter(function (v) { return notEmpty(v); });\n if (res.length) {\n if (isNumber(res[0])) {\n res = Math[type].apply(Math, res);\n }\n else if (res[0] instanceof Date) {\n res = sortValue(res, type === \"min\")[0];\n }\n }\n else {\n res = undefined;\n }\n return res;\n}\n/**\n * Get range\n * @param {number} start Start number\n * @param {number} end End number\n * @param {number} step Step number\n * @returns {Array}\n * @private\n */\nvar getRange = function (start, end, step) {\n if (step === void 0) { step = 1; }\n var res = [];\n var n = Math.max(0, Math.ceil((end - start) / step)) | 0;\n for (var i = start; i < n; i++) {\n res.push(start + i * step);\n }\n return res;\n};\n// emulate event\nvar emulateEvent = {\n mouse: (function () {\n var getParams = function () { return ({\n bubbles: false, cancelable: false, screenX: 0, screenY: 0, clientX: 0, clientY: 0\n }); };\n try {\n // eslint-disable-next-line no-new\n new MouseEvent(\"t\");\n return function (el, eventType, params) {\n if (params === void 0) { params = getParams(); }\n el.dispatchEvent(new MouseEvent(eventType, params));\n };\n }\n catch (e) {\n // Polyfills DOM4 MouseEvent\n return function (el, eventType, params) {\n if (params === void 0) { params = getParams(); }\n var mouseEvent = doc.createEvent(\"MouseEvent\");\n // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent\n mouseEvent.initMouseEvent(eventType, params.bubbles, params.cancelable, win, 0, // the event's mouse click count\n params.screenX, params.screenY, params.clientX, params.clientY, false, false, false, false, 0, null);\n el.dispatchEvent(mouseEvent);\n };\n }\n })(),\n touch: function (el, eventType, params) {\n var touchObj = new Touch(mergeObj({\n identifier: Date.now(),\n target: el,\n radiusX: 2.5,\n radiusY: 2.5,\n rotationAngle: 10,\n force: 0.5\n }, params));\n el.dispatchEvent(new TouchEvent(eventType, {\n cancelable: true,\n bubbles: true,\n shiftKey: true,\n touches: [touchObj],\n targetTouches: [],\n changedTouches: [touchObj]\n }));\n }\n};\n/**\n * Process the template & return bound string\n * @param {string} tpl Template string\n * @param {object} data Data value to be replaced\n * @returns {string}\n * @private\n */\nfunction tplProcess(tpl, data) {\n var res = tpl;\n for (var x in data) {\n res = res.replace(new RegExp(\"{=\".concat(x, \"}\"), \"g\"), data[x]);\n }\n return res;\n}\n/**\n * Get parsed date value\n * (It must be called in 'ChartInternal' context)\n * @param {Date|string|number} date Value of date to be parsed\n * @returns {Date}\n * @private\n */\nfunction parseDate(date) {\n var _a;\n var parsedDate;\n if (date instanceof Date) {\n parsedDate = date;\n }\n else if (isString(date)) {\n var _b = this, config = _b.config, format = _b.format;\n // if fails to parse, try by new Date()\n // https://github.com/naver/billboard.js/issues/1714\n parsedDate = (_a = format.dataTime(config.data_xFormat)(date)) !== null && _a !== void 0 ? _a : new Date(date);\n }\n else if (isNumber(date) && !isNaN(date)) {\n parsedDate = new Date(+date);\n }\n if (!parsedDate || isNaN(+parsedDate)) {\n console && console.error &&\n console.error(\"Failed to parse x '\".concat(date, \"' to Date object\"));\n }\n return parsedDate;\n}\n/**\n * Return if the current doc is visible or not\n * @returns {boolean}\n * @private\n */\nfunction isTabVisible() {\n return (doc === null || doc === void 0 ? void 0 : doc.hidden) === false || (doc === null || doc === void 0 ? void 0 : doc.visibilityState) === \"visible\";\n}\n/**\n * Get the current input type\n * @param {boolean} mouse Config value: interaction.inputType.mouse\n * @param {boolean} touch Config value: interaction.inputType.touch\n * @returns {string} \"mouse\" | \"touch\" | null\n * @private\n */\nfunction convertInputType(mouse, touch) {\n var DocumentTouch = win.DocumentTouch, matchMedia = win.matchMedia, navigator = win.navigator;\n var hasTouch = false;\n if (touch) {\n // Some Edge desktop return true: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/20417074/\n if (navigator && \"maxTouchPoints\" in navigator) {\n hasTouch = navigator.maxTouchPoints > 0;\n // Ref: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js\n // On IE11 with IE9 emulation mode, ('ontouchstart' in window) is returning true\n }\n else if (\"ontouchmove\" in win || (DocumentTouch && doc instanceof DocumentTouch)) {\n hasTouch = true;\n }\n else {\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#avoiding_user_agent_detection\n if (matchMedia === null || matchMedia === void 0 ? void 0 : matchMedia(\"(pointer:coarse)\").matches) {\n hasTouch = true;\n }\n else {\n // Only as a last resort, fall back to user agent sniffing\n var UA = navigator.userAgent;\n hasTouch = (/\\b(BlackBerry|webOS|iPhone|IEMobile)\\b/i.test(UA) ||\n /\\b(Android|Windows Phone|iPad|iPod)\\b/i.test(UA));\n }\n }\n }\n // Check if agent has mouse using any-hover, touch devices (e.g iPad) with external mouse will return true as long as mouse is connected\n // https://css-tricks.com/interaction-media-features-and-their-potential-for-incorrect-assumptions/#aa-testing-the-capabilities-of-all-inputs\n // Demo: https://patrickhlauke.github.io/touch/pointer-hover-any-pointer-any-hover/\n var hasMouse = mouse && [\"any-hover:hover\", \"any-pointer:fine\"]\n .some(function (v) { return matchMedia === null || matchMedia === void 0 ? void 0 : matchMedia(\"(\".concat(v, \")\")).matches; });\n // fallback to 'mouse' if no input type is detected.\n return (hasMouse && \"mouse\") || (hasTouch && \"touch\") || \"mouse\";\n}\n/**\n * Run function until given condition function return true\n * @param {Function} fn Function to be executed when condition is true\n * @param {Function} conditionFn Condition function to check if condition is true\n * @private\n */\nfunction runUntil(fn, conditionFn) {\n if (conditionFn() === false) {\n win.requestAnimationFrame(function () { return runUntil(fn, conditionFn); });\n }\n else {\n fn();\n }\n}\n\n/**\n * Check chart type module imports.\n * @param {ChartInternal} ctx Context\n * @private\n */\nfunction checkModuleImport(ctx) {\n var $$ = ctx;\n var config = $$.config;\n var type = \"\";\n if (isEmpty(config.data_type || config.data_types) && !$$[TYPE_METHOD_NEEDED.LINE]) {\n type = \"line\";\n }\n else {\n for (var x in TYPE_METHOD_NEEDED) {\n var t = TYPE[x];\n if ($$.hasType(t) && !$$[TYPE_METHOD_NEEDED[x]]) {\n type = t;\n break;\n }\n }\n }\n type && logError(\"Please, make sure if %c\".concat(camelize(type)), \"module has been imported and specified correctly.\");\n}\n/**\n * Log error and throw error\n * @param {string} head Message header\n * @param {string} tail Message tail\n * @private\n */\nfunction logError(head, tail) {\n var _a;\n var prefix = \"[billboard.js]\";\n var info = \"https://github.com/naver/billboard.js/wiki/CHANGELOG-v2#modularization-by-its-functionality\";\n var hasConsole = (_a = win.console) === null || _a === void 0 ? void 0 : _a.error;\n if (hasConsole) {\n console.error(\"\\u274C \".concat(prefix, \" \").concat(head), \"background:red;color:white;display:block;font-size:15px\", tail);\n console.info(\"%cℹ️\", \"font-size:15px\", info);\n }\n throw Error(\"\".concat(prefix, \" \").concat(head.replace(/\\%c([a-z-]+)/i, \"'$1' \"), \" \").concat(tail));\n}\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * CSS class names definition\n * @private\n */\nvar $COMMON = {\n button: \"bb-button\",\n chart: \"bb-chart\",\n empty: \"bb-empty\",\n main: \"bb-main\",\n target: \"bb-target\",\n EXPANDED: \"_expanded_\"\n};\nvar $ARC = {\n arc: \"bb-arc\",\n arcLabelLine: \"bb-arc-label-line\",\n arcs: \"bb-arcs\",\n chartArc: \"bb-chart-arc\",\n chartArcs: \"bb-chart-arcs\",\n chartArcsBackground: \"bb-chart-arcs-background\",\n chartArcsTitle: \"bb-chart-arcs-title\"\n};\nvar $AREA = {\n area: \"bb-area\",\n areas: \"bb-areas\"\n};\nvar $AXIS = {\n axis: \"bb-axis\",\n axisX: \"bb-axis-x\",\n axisXLabel: \"bb-axis-x-label\",\n axisY: \"bb-axis-y\",\n axisY2: \"bb-axis-y2\",\n axisY2Label: \"bb-axis-y2-label\",\n axisYLabel: \"bb-axis-y-label\"\n};\nvar $BAR = {\n bar: \"bb-bar\",\n bars: \"bb-bars\",\n chartBar: \"bb-chart-bar\",\n chartBars: \"bb-chart-bars\"\n};\nvar $CANDLESTICK = {\n candlestick: \"bb-candlestick\",\n candlesticks: \"bb-candlesticks\",\n chartCandlestick: \"bb-chart-candlestick\",\n chartCandlesticks: \"bb-chart-candlesticks\",\n valueDown: \"bb-value-down\",\n valueUp: \"bb-value-up\"\n};\nvar $CIRCLE = {\n chartCircles: \"bb-chart-circles\",\n circle: \"bb-circle\",\n circles: \"bb-circles\"\n};\nvar $COLOR = {\n colorPattern: \"bb-color-pattern\",\n colorScale: \"bb-colorscale\"\n};\nvar $DRAG = {\n dragarea: \"bb-dragarea\",\n INCLUDED: \"_included_\"\n};\nvar $GAUGE = {\n chartArcsGaugeMax: \"bb-chart-arcs-gauge-max\",\n chartArcsGaugeMin: \"bb-chart-arcs-gauge-min\",\n chartArcsGaugeUnit: \"bb-chart-arcs-gauge-unit\",\n chartArcsGaugeTitle: \"bb-chart-arcs-gauge-title\",\n gaugeValue: \"bb-gauge-value\"\n};\nvar $LEGEND = {\n legend: \"bb-legend\",\n legendBackground: \"bb-legend-background\",\n legendItem: \"bb-legend-item\",\n legendItemEvent: \"bb-legend-item-event\",\n legendItemHidden: \"bb-legend-item-hidden\",\n legendItemPoint: \"bb-legend-item-point\",\n legendItemTile: \"bb-legend-item-tile\"\n};\nvar $LINE = {\n chartLine: \"bb-chart-line\",\n chartLines: \"bb-chart-lines\",\n line: \"bb-line\",\n lines: \"bb-lines\"\n};\nvar $EVENT = {\n eventRect: \"bb-event-rect\",\n eventRects: \"bb-event-rects\",\n eventRectsMultiple: \"bb-event-rects-multiple\",\n eventRectsSingle: \"bb-event-rects-single\"\n};\nvar $FOCUS = {\n focused: \"bb-focused\",\n defocused: \"bb-defocused\",\n legendItemFocused: \"bb-legend-item-focused\",\n xgridFocus: \"bb-xgrid-focus\",\n ygridFocus: \"bb-ygrid-focus\"\n};\nvar $GRID = {\n grid: \"bb-grid\",\n gridLines: \"bb-grid-lines\",\n xgrid: \"bb-xgrid\",\n xgridLine: \"bb-xgrid-line\",\n xgridLines: \"bb-xgrid-lines\",\n xgrids: \"bb-xgrids\",\n ygrid: \"bb-ygrid\",\n ygridLine: \"bb-ygrid-line\",\n ygridLines: \"bb-ygrid-lines\",\n ygrids: \"bb-ygrids\"\n};\nvar $LEVEL = {\n level: \"bb-level\",\n levels: \"bb-levels\"\n};\nvar $RADAR = {\n chartRadar: \"bb-chart-radar\",\n chartRadars: \"bb-chart-radars\"\n};\nvar $REGION = {\n region: \"bb-region\",\n regions: \"bb-regions\"\n};\nvar $SELECT = {\n selectedCircle: \"bb-selected-circle\",\n selectedCircles: \"bb-selected-circles\",\n SELECTED: \"_selected_\"\n};\nvar $SHAPE = {\n shape: \"bb-shape\",\n shapes: \"bb-shapes\"\n};\nvar $SUBCHART = {\n brush: \"bb-brush\",\n subchart: \"bb-subchart\"\n};\nvar $TEXT = {\n chartText: \"bb-chart-text\",\n chartTexts: \"bb-chart-texts\",\n text: \"bb-text\",\n texts: \"bb-texts\",\n title: \"bb-title\",\n TextOverlapping: \"text-overlapping\"\n};\nvar $TOOLTIP = {\n tooltip: \"bb-tooltip\",\n tooltipContainer: \"bb-tooltip-container\",\n tooltipName: \"bb-tooltip-name\"\n};\nvar $TREEMAP = {\n treemap: \"bb-treemap\",\n chartTreemap: \"bb-chart-treemap\",\n chartTreemaps: \"bb-chart-treemaps\"\n};\nvar $ZOOM = {\n buttonZoomReset: \"bb-zoom-reset\",\n zoomBrush: \"bb-zoom-brush\"\n};\nvar CLASS = _assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign(_assign({}, $COMMON), $ARC), $AREA), $AXIS), $BAR), $CANDLESTICK), $CIRCLE), $COLOR), $DRAG), $GAUGE), $LEGEND), $LINE), $EVENT), $FOCUS), $GRID), $RADAR), $REGION), $SELECT), $SHAPE), $SUBCHART), $TEXT), $TOOLTIP), $TREEMAP), $ZOOM);\n\n/**\n * Elements class.\n * @class Elements\n * @ignore\n * @private\n */\nvar Element = /** @class */ (function () {\n function Element() {\n var element = {\n chart: null,\n main: null,\n svg: null,\n axis: {\n x: null,\n y: null,\n y2: null,\n subX: null\n },\n defs: null,\n tooltip: null,\n legend: null,\n title: null,\n subchart: {\n main: null,\n bar: null,\n line: null,\n area: null // $$.contextArea\n },\n arcs: null,\n bar: null,\n candlestick: null,\n line: null,\n area: null,\n circle: null,\n radar: null,\n text: null,\n grid: {\n main: null,\n x: null,\n y: null\n },\n gridLines: {\n main: null,\n x: null,\n y: null\n },\n region: {\n main: null,\n list: null // mainRegion\n },\n eventRect: null,\n zoomResetBtn: null // drag zoom reset button\n };\n return element;\n }\n return Element;\n}());\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * State class.\n * @class State\n * @ignore\n * @private\n */\nvar State = /** @class */ (function () {\n function State() {\n return {\n // chart drawn area dimension, excluding axes\n width: 0,\n width2: 0,\n height: 0,\n height2: 0,\n margin: {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0\n },\n margin2: {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0\n },\n margin3: {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0\n },\n arcWidth: 0,\n arcHeight: 0,\n xAxisHeight: 0,\n hasAxis: false,\n hasRadar: false,\n hasTreemap: false,\n // for data CSS rule index (used when boost.useCssRule is true)\n cssRule: {},\n current: {\n // chart whole dimension\n width: 0,\n height: 0,\n dataMax: 0,\n maxTickWidths: {\n x: { size: 0, ticks: [], clipPath: 0, domain: \"\" },\n y: { size: 0, domain: \"\" },\n y2: { size: 0, domain: \"\" }\n },\n // current used chart type list\n types: []\n },\n // legend\n isLegendRight: false,\n isLegendInset: false,\n isLegendTop: false,\n isLegendLeft: false,\n legendStep: 0,\n legendItemWidth: 0,\n legendItemHeight: 0,\n legendHasRendered: false,\n eventReceiver: {\n currentIdx: -1,\n rect: {},\n data: [],\n coords: [] // coordination value of previous eventRect\n },\n axis: {\n x: {\n padding: { left: 0, right: 0 },\n tickCount: 0\n }\n },\n rotatedPadding: {\n left: 30,\n right: 0,\n top: 5\n },\n withoutFadeIn: {},\n inputType: \"\",\n datetimeId: \"\",\n // clip id string\n clip: {\n id: \"\",\n idXAxis: \"\",\n idYAxis: \"\",\n idXAxisTickTexts: \"\",\n idGrid: \"\",\n idSubchart: \"\",\n path: \"\",\n pathXAxis: \"\",\n pathYAxis: \"\",\n pathXAxisTickTexts: \"\",\n pathGrid: \"\"\n },\n // status\n event: null,\n dragStart: null,\n dragging: false,\n flowing: false,\n cancelClick: false,\n mouseover: false,\n rendered: false,\n transiting: false,\n redrawing: false,\n resizing: false,\n toggling: false,\n zooming: false,\n hasNegativeValue: false,\n hasPositiveValue: true,\n orgAreaOpacity: \"0.2\",\n orgConfig: {},\n // ID strings\n hiddenTargetIds: [],\n hiddenLegendIds: [],\n focusedTargetIds: [],\n defocusedTargetIds: [],\n // value for Arc\n radius: 0,\n innerRadius: 0,\n outerRadius: undefined,\n innerRadiusRatio: 0,\n gaugeArcWidth: 0,\n radiusExpanded: 0,\n // xgrid attribute\n xgridAttr: {\n x1: null,\n x2: null,\n y1: null,\n y2: null\n }\n };\n }\n return State;\n}());\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n// mapping\nvar classes = {\n element: Element,\n state: State\n};\n/**\n * Internal store class.\n * @class Store\n * @ignore\n * @private\n */\nvar Store = /** @class */ (function () {\n function Store() {\n var _this = this;\n Object.keys(classes).forEach(function (v) {\n _this[v] = new classes[v]();\n });\n }\n Store.prototype.getStore = function (name) {\n return this[name];\n };\n return Store;\n}());\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * main config options\n */\nvar main = {\n /**\n * Specify the CSS selector or the element which the chart will be set to. D3 selection object can be specified also.
\n * If other chart is set already, it will be replaced with the new one (only one chart can be set in one element).\n * - **NOTE:** In case of element doesn't exist or not specified, will add a `
` element to the body.\n * @name bindto\n * @memberof Options\n * @property {string|HTMLElement|d3.selection|object} [bindto=\"#chart\"] Specify the element where chart will be drawn.\n * @property {string|HTMLElement|d3.selection} bindto.element=\"#chart\" Specify the element where chart will be drawn.\n * @property {string} [bindto.classname=bb] Specify the class name of bind element.
\n * **NOTE:** When class name isn't `bb`, then you also need to update the default CSS to be rendered correctly.\n * @default #chart\n * @example\n * bindto: \"#myContainer\"\n *\n * // or HTMLElement\n * bindto: document.getElementById(\"myContainer\")\n *\n * // or D3 selection object\n * bindto: d3.select(\"#myContainer\")\n *\n * // or to change default classname\n * bindto: {\n * element: \"#chart\",\n * classname: \"bill-board\" // ex)
\n * }\n */\n bindto: \"#chart\",\n /**\n * Set chart background.\n * @name background\n * @memberof Options\n * @property {object} background background object\n * @property {string} background.class Specify the class name for background element.\n * @property {string} background.color Specify the fill color for background element.
**NOTE:** Will be ignored if `imgUrl` option is set.\n * @property {string} background.imgUrl Specify the image url string for background.\n * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.Background)\n * @example\n * background: {\n * class: \"myClass\",\n * color: \"red\",\n *\n * // Set image url for background.\n * // If specified, 'color' option will be ignored.\n * imgUrl: \"https://naver.github.io/billboard.js/img/logo/billboard.js.svg\",\n * }\n */\n background: {},\n /**\n * Set 'clip-path' attribute for chart element\n * - **NOTE:**\n * > When is false, chart node element is positioned after the axis node in DOM tree hierarchy.\n * > Is to make chart element positioned over axis element.\n * @name clipPath\n * @memberof Options\n * @type {boolean}\n * @default true\n * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.clipPath)\n * @example\n * // don't set 'clip-path' attribute\n * clipPath: false\n */\n clipPath: true,\n /**\n * Set svg element's class name\n * @name svg\n * @memberof Options\n * @type {object}\n * @property {object} [svg] svg object\n * @property {string} [svg.classname] class name for svg element\n * @example\n * svg: {\n * classname: \"test_class\"\n * }\n */\n svg_classname: undefined,\n /**\n * The desired size of the chart element.\n * If value is not specified, the width of the chart will be calculated by the size of the parent element it's appended to.\n * @name size\n * @memberof Options\n * @type {object}\n * @property {object} [size] size object\n * @property {number} [size.width] width of the chart element\n * @property {number} [size.height] height of the chart element\n * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.ChartSize)\n * @example\n * size: {\n * width: 640,\n * height: 480\n * }\n */\n size_width: undefined,\n size_height: undefined,\n /**\n * The padding of the chart element.\n * @name padding\n * @memberof Options\n * @type {object}\n * @property {object|boolean} [padding=true] Set padding of chart, and accepts object or boolean type.\n * - `Object`: Specify each side's padding.\n * - `false`: Remove padding completely and make shape to fully occupy the container element.\n * - In this case, axes and subchart will be hidden.\n * - To adjust some padding from this state, use `axis.[x|y].padding` option.\n * @property {number} [padding.top] padding on the top of chart\n * @property {number} [padding.right] padding on the right of chart\n * @property {number} [padding.bottom] padding on the bottom of chart\n * @property {number} [padding.left] padding on the left of chart\n * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.Padding)\n * @example\n * // remove padding completely.\n * padding: false,\n *\n * // or specify padding value for each side\n * padding: {\n * top: 20,\n * right: 20,\n * bottom: 20,\n * left: 20\n * }\n */\n padding: true,\n padding_left: undefined,\n padding_right: undefined,\n padding_top: undefined,\n padding_bottom: undefined,\n /**\n * Set chart resize options\n * @name resize\n * @memberof Options\n * @type {object}\n * @property {object} [resize] resize object\n * @property {boolean} [resize.auto=true] Set chart resize automatically on viewport changes.\n * @property {boolean|number} [resize.timer=true] Set resize timer option.\n * - **NOTE:**\n * - The resize function will be called using: true - `setTimeout()`, false - `requestIdleCallback()`.\n * - Given number(delay in ms) value, resize function will be triggered using `setTimer()` with given delay.\n * @example\n * resize: {\n * auto: false,\n *\n * // set resize function will be triggered using `setTimer()`\n * timer: true,\n *\n * // set resize function will be triggered using `requestIdleCallback()`\n * timer: false,\n *\n * // set resize function will be triggered using `setTimer()` with a delay of `100ms`.\n * timer: 100\n * }\n */\n resize_auto: true,\n resize_timer: true,\n /**\n * Set a callback to execute when the chart is clicked.\n * @name onclick\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * onclick: function(event) {\n * this; // chart instance itself\n * event; // native event object\n * ...\n * }\n */\n onclick: undefined,\n /**\n * Set a callback to execute when mouse/touch enters the chart.\n * @name onover\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * onover: function(event) {\n * this; // chart instance itself\n * event; // native event object\n * ...\n * }\n */\n onover: undefined,\n /**\n * Set a callback to execute when mouse/touch leaves the chart.\n * @name onout\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * onout: function(event) {\n * this; // chart instance itself\n * event; // native event object\n * ...\n * }\n */\n onout: undefined,\n /**\n * Set a callback to execute when user resizes the screen.\n * @name onresize\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * onresize: function() {\n * this; // chart instance itself\n * ...\n * }\n */\n onresize: undefined,\n /**\n * Set a callback to execute when screen resize finished.\n * @name onresized\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * onresized: function() {\n * this; // chart instance itself\n * ...\n * }\n */\n onresized: undefined,\n /**\n * Set a callback to execute before the chart is initialized\n * @name onbeforeinit\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * onbeforeinit: function() {\n * this; // chart instance itself\n * ...\n * }\n */\n onbeforeinit: undefined,\n /**\n * Set a callback to execute when the chart is initialized.\n * @name oninit\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * oninit: function() {\n * this; // chart instance itself\n * ...\n * }\n */\n oninit: undefined,\n /**\n * Set a callback to execute after the chart is initialized\n * @name onafterinit\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * onafterinit: function() {\n * this; // chart instance itself\n * ...\n * }\n */\n onafterinit: undefined,\n /**\n * Set a callback which is executed when the chart is rendered. Basically, this callback will be called in each time when the chart is redrawed.\n * @name onrendered\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * onrendered: function() {\n * this; // chart instance itself\n * ...\n * }\n */\n onrendered: undefined,\n /**\n * Set duration of transition (in milliseconds) for chart animation.

\n * - **NOTE:** If `0 `or `null` set, transition will be skipped. So, this makes initial rendering faster especially in case you have a lot of data.\n * @name transition\n * @memberof Options\n * @type {object}\n * @property {object} [transition] transition object\n * @property {number} [transition.duration=350] duration in milliseconds\n * @example\n * transition: {\n * duration: 500\n * }\n */\n transition_duration: 250,\n /**\n * Set plugins\n * @name plugins\n * @memberof Options\n * @type {Array}\n * @example\n * plugins: [\n * new bb.plugin.stanford({ ... }),\n * new PluginA(),\n * ...\n * ]\n */\n plugins: [],\n /**\n * Control the render timing\n * @name render\n * @memberof Options\n * @type {object}\n * @property {object} [render] render object\n * @property {boolean} [render.lazy=true] Make to not render at initialization (enabled by default when bind element's visibility is hidden).\n * @property {boolean} [render.observe=true] Observe bind element's visibility(`display` or `visiblity` inline css property or class value) & render when is visible automatically (for IEs, only works IE11+). When set to **false**, call [`.flush()`](./Chart.html#flush) to render.\n * @see [Demo](https://naver.github.io/billboard.js/demo/#ChartOptions.LazyRender)\n * @example\n * render: {\n * lazy: true,\n * observe: true\n * }\n *\n * @example\n *\t// \n * // (a)
\n * // (b) \n *\n * // render.lazy enabled by default when element is hidden\n * var chart = bb.generate({ ... });\n *\n * // chart will be rendered automatically when element's visibility changes\n * // Note: works only for inlined css property or class attribute changes\n * document.getElementById('chart').classList.remove('hide') // (a)\n * document.getElementById('chart').style.display = 'block'; // (b)\n *\n * @example\n *\t// chart won't be rendered and not observing bind element's visiblity changes\n * var chart = bb.generate({\n * render: {\n * lazy: true,\n * observe: false\n * }\n * });\n *\n * // call at any point when you want to render\n * chart.flush();\n */\n render: {},\n /**\n * Show rectangles inside the chart.

\n * This option accepts array including object that has axis, start, end and class.\n * The keys start, end and class are optional.\n * axis must be x, y or y2. start and end should be the value where regions start and end.\n * If not specified, the edge values will be used.\n * If timeseries x axis, date string, Date object and unixtime integer can be used.\n * If class is set, the region element will have it as class.\n * @name regions\n * @memberof Options\n * @type {Array}\n * @default []\n * @example\n * regions: [\n * {\n * axis: \"x\",\n * start: 1,\n * end: 4,\n * class: \"region-1-4\"\n * }\n * ]\n */\n regions: []\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * boost config options\n */\nvar boost = {\n /**\n * Set boost options\n * @name boost\n * @memberof Options\n * @type {object}\n * @property {object} boost boost object\n * @property {boolean} [boost.useCssRule=false] Avoid setting inline styles for each shape elements.\n * - **NOTE:**\n * - Will append <style> to the head tag and will add shpes' CSS rules dynamically.\n * - For now, covers colors related properties (fill, stroke, etc.) only.\n * @property {boolean} [boost.useWorker=false] Use Web Worker as possible for processing.\n * - **NOTE:**\n * - For now, only applies for data conversion at the initial time.\n * - As of Web Worker's async nature, handling chart instance synchrously is not recommended.\n * @example\n * boost: {\n * useCssRule: true,\n * useWorker: false\n * }\n */\n boost_useCssRule: false,\n boost_useWorker: false\n};\n\n/**\n * data config options\n */\nvar data$2 = {\n /**\n * Specify the key of x values in the data.

\n * We can show the data with non-index x values by this option. This option is required when the type of x axis is timeseries. If this option is set on category axis, the values of the data on the key will be used for category names.\n * @name data․x\n * @memberof Options\n * @type {string}\n * @default undefined\n * @example\n * data: {\n * x: \"date\"\n * }\n */\n data_x: undefined,\n /**\n * Converts data id value\n * @name data․idConverter\n * @memberof Options\n * @type {Function}\n * @default function(id) { return id; }\n * @example\n * data: {\n * idConverter: function(id) {\n * // when id is 'data1', converts to be 'data2'\n * // 'data2' should be given as the initial data value\n * if (id === \"data1\") {\n * return \"data2\";\n * } else {\n * return id;\n * }\n * }\n * }\n */\n data_idConverter: function (id) { return id; },\n /**\n * Set custom data name.\n * If a name is set to `null`, the series is omitted from the legend.\n * @name data․names\n * @memberof Options\n * @type {object}\n * @default {}\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataName)\n * @example\n * data: {\n * names: {\n * data1: \"Data Name 1\",\n * data2: \"Data Name 2\"\n * }\n * }\n */\n data_names: {},\n /**\n * Set custom data class.

\n * If this option is specified, the element g for the data has an additional class that has the prefix 'bb-target-' (eg. bb-target-additional-data1-class).\n * @name data․classes\n * @memberof Options\n * @type {object}\n * @default {}\n * @example\n * data: {\n * classes: {\n * data1: \"additional-data1-class\",\n * data2: \"additional-data2-class\"\n * }\n * }\n */\n data_classes: {},\n /**\n * Set chart type at once.

\n * If this option is specified, the type will be applied to every data. This setting can be overwritten by data.types.

\n * **Available Values:**\n * - area\n * - area-line-range\n * - area-spline\n * - area-spline-range\n * - area-step\n * - bar\n * - bubble\n * - candlestick\n * - donut\n * - gauge\n * - line\n * - pie\n * - polar\n * - radar\n * - scatter\n * - spline\n * - step\n * - treemap\n * @name data․type\n * @memberof Options\n * @type {string}\n * @default \"line\"
NOTE: When importing shapes by ESM, `line()` should be specified for type.\n * @example\n * data: {\n * type: \"bar\"\n * }\n * @example\n * // Generate chart by importing ESM\n * // Import types to be used only, where this will make smaller bundle size.\n * import bb, {\n * area,\n * areaLineRange,\n * areaSpline,\n * areaSplineRange,\n * areaStep,\n * bar,\n * bubble,\n * candlestick,\n * donut,\n * gauge,\n * line,\n * pie,\n * polar,\n * radar,\n * scatter,\n * spline,\n * step,\n * treemap\n * }\n *\n * bb.generate({\n * ...,\n * data: {\n * type: bar()\n * }\n * });\n */\n data_type: undefined,\n /**\n * Set chart type for each data.
\n * This setting overwrites data.type setting.\n * - **NOTE:** `radar` and `treemap` type can't be combined with other types.\n * @name data․types\n * @memberof Options\n * @type {object}\n * @default {}\n * @example\n * data: {\n * types: {\n * data1: \"bar\",\n * data2: \"spline\"\n * }\n * }\n * @example\n * // Generate chart by importing ESM\n * // Import types to be used only, where this will make smaller bundle size.\n * import bb, {\n * area,\n * areaLineRange,\n * areaSpline,\n * areaSplineRange,\n * areaStep,\n * bar,\n * bubble,\n * candlestick,\n * donut,\n * gauge,\n * line,\n * pie,\n * polar,\n * radar,\n * scatter,\n * spline,\n * step,\n * treemap\n * }\n *\n * bb.generate({\n * ...,\n * data: {\n * types: {\n * data1: bar(),\n * data1: spline()\n * }\n * }\n * });\n */\n data_types: {},\n /**\n * This option changes the order of stacking data and pieces of pie/donut.\n * - If `null` specified, it will be the order the data loaded.\n * - If function specified, it will be used as [Array.sort compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters)

\n *\n * **Available Values:**\n * - `desc`: In descending order\n * - `asc`: In ascending order\n * - `null`: It keeps the data load order\n * - `function(data1, data2) { ... }`: Array.sort compareFunction\n *\n * **NOTE**: order function, only works for Axis based types & Arc types, except `Radar` type.\n * @name data․order\n * @memberof Options\n * @type {string|Function|null}\n * @default desc\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataOrder)\n * @example\n * data: {\n * // in descending order (default)\n * order: \"desc\"\n *\n * // in ascending order\n * order: \"asc\"\n *\n * // keeps data input order\n * order: null\n *\n * // specifying sort function\n * order: function(a, b) {\n * // param data passed format\n * // {\n * // id: \"data1\", id_org: \"data1\", values: [\n * // {x: 5, value: 250, id: \"data1\", index: 5, name: \"data1\"},\n * // ...\n * // ]\n * // }\n *\n * const reducer = (p, c) => p + Math.abs(c.value);\n * const aSum = a.values.reduce(reducer, 0);\n * const bSum = b.values.reduce(reducer, 0);\n *\n * // ascending order\n * return aSum - bSum;\n *\n * // descending order\n * // return bSum - aSum;\n * }\n * }\n */\n data_order: \"desc\",\n /**\n * Set groups for the data for stacking.\n * @name data․groups\n * @memberof Options\n * @type {Array}\n * @default []\n * @example\n * data: {\n * groups: [\n * [\"data1\", \"data2\"],\n * [\"data3\"]\n * ]\n * }\n */\n data_groups: [],\n /**\n * Set how zero value will be treated on groups.
\n * Possible values:\n * - `zero`: 0 will be positioned at absolute axis zero point.\n * - `positive`: 0 will be positioned at the top of a stack.\n * - `negative`: 0 will be positioned at the bottom of a stack.\n * @name data․groupsZeroAs\n * @memberof Options\n * @type {string}\n * @default \"positive\"\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.Groups)\n * @example\n * data: {\n * groupsZeroAs: \"zero\" // \"positive\" or \"negative\"\n * }\n */\n data_groupsZeroAs: \"positive\",\n /**\n * Set color converter function.

\n * This option should a function and the specified function receives color (e.g. '#ff0000') and d that has data parameters like id, value, index, etc. And it must return a string that represents color (e.g. '#00ff00').\n * @name data․color\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataColor)\n * @example\n * data: {\n * color: function(color, d) { ... }\n * }\n */\n data_color: undefined,\n /**\n * Set color for each data.\n * @name data․colors\n * @memberof Options\n * @type {object}\n * @default {}\n * @example\n * data: {\n * colors: {\n * data1: \"#ff0000\",\n * data2: function(d) {\n * return \"#000\";\n * }\n * ...\n * }\n * }\n */\n data_colors: {},\n /**\n * Set labels options\n * @name data․labels\n * @memberof Options\n * @type {object}\n * @property {object} data Data object\n * @property {boolean} [data.labels=false] Show or hide labels on each data points\n * @property {boolean} [data.labels.centered=false] Centerize labels on `bar` shape. (**NOTE:** works only for 'bar' type)\n * @property {Function} [data.labels.format] Set formatter function for data labels.
\n * The formatter function receives 4 arguments such as v, id, i, j and it **must return a string**(`\\n` character will be used as line break) that will be shown as the label.

\n * The arguments are:
\n * - `v` is the value of the data point where the label is shown.\n * - `id` is the id of the data where the label is shown.\n * - `i` is the index of the data series point where the label is shown.\n * - `texts` is the array of whole corresponding data series' text labels.

\n * Formatter function can be defined for each data by specifying as an object and D3 formatter function can be set (ex. d3.format('$'))\n * @property {string|object} [data.labels.backgroundColors] Set label text background colors.\n * @property {string|object|Function} [data.labels.colors] Set label text colors.\n * @property {object} [data.labels.position] Set each dataset position, relative the original.\n * @property {number} [data.labels.position.x=0] x coordinate position, relative the original.\n * @property {number} [data.labels.position.y=0] y coordinate position, relative the original.\n * @property {object} [data.labels.rotate] Rotate label text. Specify degree value in a range of `0 ~ 360`.\n * - **NOTE:** Depend on rotate value, text position need to be adjusted manually(using `data.labels.position` option) to be shown nicely.\n * @memberof Options\n * @type {object}\n * @default {}\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.DataLabel)\n * @see [Demo: label colors](https://naver.github.io/billboard.js/demo/#Data.DataLabelColors)\n * @see [Demo: label format](https://naver.github.io/billboard.js/demo/#Data.DataLabelFormat)\n * @see [Demo: label multiline](https://naver.github.io/billboard.js/demo/#Data.DataLabelMultiline)\n * @see [Demo: label overlap](https://naver.github.io/billboard.js/demo/#Data.DataLabelOverlap)\n * @see [Demo: label position](https://naver.github.io/billboard.js/demo/#Data.DataLabelPosition)\n * @see [Demo: label rotate](https://naver.github.io/billboard.js/demo/#Data.DataLabelRotate)\n * @example\n * data: {\n * labels: true,\n *\n * // or set specific options\n * labels: {\n * format: function(v, id, i, j) {\n * ...\n * // to multiline, return with '\\n' character\n * return \"Line1\\nLine2\";\n * },\n *\n * // it's possible to set for each data\n * format: {\n * data1: function(v, id, i, texts) { ... },\n * ...\n * },\n *\n * // align text to center of the 'bar' shape (works only for 'bar' type)\n * centered: true,\n *\n * // apply backgound color for label texts\n * backgroundColors: \"red\",\n *\n * // set differenct backround colors per dataset\n * backgroundColors: {\n * data1: \"green\",\n * data2: \"yellow\"\n * }\n *\n * // apply for all label texts\n * colors: \"red\",\n *\n * // set different colors per dataset\n * // for not specified dataset, will have the default color value\n * colors: {\n * data1: \"yellow\",\n * data3: \"green\"\n * },\n *\n * // call back for label text color\n * colors: function(color, d) {\n * // color: the default data label color string\n * // data: ex) {x: 0, value: 200, id: \"data3\", index: 0}\n * ....\n * return d.value > 200 ? \"cyan\" : color;\n * },\n *\n * // set x, y coordinate position\n * position: {\n * x: -10,\n * y: 10\n * },\n *\n * // or set x, y coordinate position by each dataset\n * position: {\n * data1: {x: 5, y: 5},\n * data2: {x: 10, y: -20}\n * },\n *\n *\t // rotate degree for label text\n * rotate: 90\n * }\n * }\n */\n data_labels: {},\n data_labels_backgroundColors: undefined,\n data_labels_colors: undefined,\n data_labels_position: {},\n /**\n * Hide each data when the chart appears.

\n * If true specified, all of data will be hidden. If multiple ids specified as an array, those will be hidden.\n * @name data․hide\n * @memberof Options\n * @type {boolean|Array}\n * @default false\n * @example\n * data: {\n * // all of data will be hidden\n * hide: true\n *\n * // specified data will be hidden\n * hide: [\"data1\", ...]\n * }\n */\n data_hide: false,\n /**\n * Filter values to be shown\n * The data value is the same as the returned by `.data()`.\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter\n * @name data․filter\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * data: {\n * // filter for id value\n * filter: function(v) {\n * // v: [{id: \"data1\", id_org: \"data1\", values: [\n * // {x: 0, value: 130, id: \"data2\", index: 0}, ...]\n * // }, ...]\n * return v.id !== \"data1\";\n * }\n */\n data_filter: undefined,\n /**\n * Set a callback for click event on each data point.

\n * This callback will be called when each data point clicked and will receive `d` and element as the arguments.\n * - `d` is the data clicked and element is the element clicked.\n * - `element` is the current interacting svg element.\n * - In this callback, `this` will be the Chart object.\n * @name data․onclick\n * @memberof Options\n * @type {Function}\n * @default function() {}\n * @example\n * data: {\n * onclick: function(d, element) {\n * // d - ex) {x: 4, value: 150, id: \"data1\", index: 4, name: \"data1\"}\n * // element - \n * ...\n * }\n * }\n */\n data_onclick: function () { },\n /**\n * Set a callback for mouse/touch over event on each data point.

\n * This callback will be called when mouse cursor or via touch moves onto each data point and will receive `d` and `element` as the argument.\n * - `d` is the data where mouse cursor moves onto.\n * - `element` is the current interacting svg element.\n * - In this callback, `this` will be the Chart object.\n * @name data․onover\n * @memberof Options\n * @type {Function}\n * @default function() {}\n * @example\n * data: {\n * onover: function(d, element) {\n * // d - ex) {x: 4, value: 150, id: \"data1\", index: 4}\n * // element - \n * ...\n * }\n * }\n */\n data_onover: function () { },\n /**\n * Set a callback for mouse/touch out event on each data point.

\n * This callback will be called when mouse cursor or via touch moves out each data point and will receive `d` as the argument.\n * - `d` is the data where mouse cursor moves out.\n * - `element` is the current interacting svg element.\n * - In this callback, `this` will be the Chart object.\n * @name data․onout\n * @memberof Options\n * @type {Function}\n * @default function() {}\n * @example\n * data: {\n * onout: function(d, element) {\n * // d - ex) {x: 4, value: 150, id: \"data1\", index: 4}\n * // element - \n * ...\n * }\n * }\n */\n data_onout: function () { },\n /**\n * Set a callback for when data is shown.
\n * The callback will receive shown data ids in array.\n * @name data․onshown\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * data: {\n * onshown: function(ids) {\n * // ids - [\"data1\", \"data2\", ...]\n * ...\n * }\n * }\n */\n data_onshown: undefined,\n /**\n * Set a callback for when data is hidden.
\n * The callback will receive hidden data ids in array.\n * @name data․onhidden\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @example\n * data: {\n * onhidden: function(ids) {\n * // ids - [\"data1\", \"data2\", ...]\n * ...\n * }\n * }\n */\n data_onhidden: undefined,\n /**\n * Set a callback for minimum data\n * - **NOTE:** For 'area-line-range' and 'area-spline-range', `mid` data will be taken for the comparison\n * @name data․onmin\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.OnMinMaxCallback)\n * @example\n * onmin: function(data) {\n * // data - ex) [{x: 3, value: 400, id: \"data1\", index: 3}, ... ]\n * ...\n * }\n */\n data_onmin: undefined,\n /**\n * Set a callback for maximum data\n * - **NOTE:** For 'area-line-range' and 'area-spline-range', `mid` data will be taken for the comparison\n * @name data․onmax\n * @memberof Options\n * @type {Function}\n * @default undefined\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.OnMinMaxCallback)\n * @example\n * onmax: function(data) {\n * // data - ex) [{x: 3, value: 400, id: \"data1\", index: 3}, ... ]\n * ...\n * }\n */\n data_onmax: undefined,\n /**\n * Load a CSV or JSON file from a URL. NOTE that this will not work if loading via the \"file://\" protocol as the most browsers will block XMLHTTPRequests.\n * @name data․url\n * @memberof Options\n * @type {string}\n * @default undefined\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.LoadData)\n * @example\n * data: {\n * url: \"/data/test.csv\"\n * }\n */\n data_url: undefined,\n /**\n * XHR header value\n * - **NOTE:** Should be used with `data.url` option\n * @name data․headers\n * @memberof Options\n * @type {string}\n * @default undefined\n * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader\n * @example\n * data: {\n * url: \"/data/test.csv\",\n * headers: {\n * \"Content-Type\": \"text/xml\",\n * ...\n * }\n * }\n */\n data_headers: undefined,\n /**\n * Parse a JSON object for data. See also data.keys.\n * @name data․json\n * @memberof Options\n * @type {Array}\n * @default undefined\n * @see [data․keys](#.data%25E2%2580%25A4keys)\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.JSONData)\n * @example\n * data: {\n * json: [\n * {name: \"www.site1.com\", upload: 200, download: 200, total: 400},\n * {name: \"www.site2.com\", upload: 100, download: 300, total: 400},\n * {name: \"www.site3.com\", upload: 300, download: 200, total: 500},\n * {name: \"www.site4.com\", upload: 400, download: 100, total: 500}\n * ],\n * keys: {\n * // x: \"name\", // it's possible to specify 'x' when category axis\n * value: [\"upload\", \"download\"]\n * }\n * }\n */\n data_json: undefined,\n /**\n * Load data from a multidimensional array, with the first element containing the data names, the following containing related data in that order.\n * @name data․rows\n * @memberof Options\n * @type {Array}\n * @default undefined\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.RowOrientedData)\n * @example\n * data: {\n * rows: [\n * [\"A\", \"B\", \"C\"],\n * [90, 120, 300],\n * [40, 160, 240],\n * [50, 200, 290],\n * [120, 160, 230],\n * [80, 130, 300],\n * [90, 220, 320]\n * ]\n * }\n *\n * // for 'bar' type, data can contain:\n * // - an array of [start, end] data following the order\n * data: {\n * rows: [\n * [\"data1\", \"data2\"],\n * [[100, 150], 120],\n * [[200, 300], 55],\n * [[-400, 500], 60]\n * ],\n * type: \"bar\"\n * }\n *\n * // for 'range' types('area-line-range' or 'area-spline-range'), data should contain:\n * // - an array of [high, mid, low] data following the order\n * // - or an object with 'high', 'mid' and 'low' key value\n * data: {\n * rows: [\n * [\"data1\", \"data2\"],\n * [\n * // or {high:150, mid: 140, low: 110}, 120\n * [150, 140, 110], 120\n * ],\n * [[155, 130, 115], 55],\n * [[160, 135, 120], 60]\n * ],\n * types: {\n * data1: \"area-line-range\",\n * data2: \"line\"\n * }\n * }\n *\n * // for 'bubble' type, data can contain dimension value:\n * // - an array of [y, z] data following the order\n * // - or an object with 'y' and 'z' key value\n * // 'y' is for y axis coordination and 'z' is the bubble radius value\n * data: {\n * rows: [\n * [\"data1\", \"data2\"],\n * [\n * // or {y:10, z: 140}, 120\n * [10, 140], 120\n * ],\n * [[100, 30], 55],\n * [[50, 100], 60]\n * ],\n * types: {\n * data1: \"bubble\",\n * data2: \"line\"\n * }\n * }\n *\n * // for 'canlestick' type, data should contain:\n * // - an array of [open, high, low, close, volume(optional)] data following the order\n * // - or an object with 'open', 'high', 'low', 'close' and 'value'(optional) key value\n * data: {\n * rows: [\n * [\"data1\", \"data2\"],\n *\t\t[\n *\t\t\t// open, high, low, close, volume (optional)\n *\t\t\t{open: 1300, high: 1369, low: 1200, close: 1339, volume: 100},\n *\t\t\t[1000, 1100, 850, 870]\n *\t\t],\n *\t\t[\n *\t\t\t{open: 1348, high: 1371, low: 1271, close: 1320},\n *\t\t\t[870, 1250, 830, 1200, 50]\n *\t\t]\n * ],\n * type: \"candlestick\"\n * }\n */\n data_rows: undefined,\n /**\n * Load data from a multidimensional array, with each element containing an array consisting of a datum name and associated data values.\n * @name data․columns\n * @memberof Options\n * @type {Array}\n * @default undefined\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Data.ColumnOrientedData)\n * @example\n * data: {\n * columns: [\n * [\"data1\", 30, 20, 50, 40, 60, 50],\n * [\"data2\", 200, 130, 90, 240, 130, 220],\n * [\"data3\", 300, 200, 160, 400, 250, 250]\n * ]\n * }\n *\n * // for 'bar' type, data can contain:\n * // - an array of [start, end] data following the order\n * data: {\n * columns: [\n * [\"data1\", -100, 50, [100, 200], [200, 300]],\n * [\"data2\", -200, 300, [-100, 100], [-50, -30]],\n * ],\n * type: \"bar\"\n * }\n *\n * // for 'range' types('area-line-range' or 'area-spline-range'), data should contain:\n * // - an array of [high, mid, low] data following the order\n * // - or an object with 'high', 'mid' and 'low' key value\n * data: {\n * columns: [\n * [\"data1\",\n * [150, 140, 110], // or {high:150, mid: 140, low: 110}\n * [150, 140, 110],\n * [150, 140, 110]\n * ]\n * ],\n * type: \"area-line-range\"\n * }\n *\n * // for 'bubble' type, data can contain dimension value:\n * // - an array of [y, z] data following the order\n * // - or an object with 'y' and 'z' key value\n * // 'y' is for y axis coordination and 'z' is the bubble radius value\n * data: {\n * columns: [\n * [\"data1\",\n * [10, 140], // or {y:10, z: 140}\n * [100, 30],\n * [50, 100]\n * ]\n * ],\n * type: \"bubble\"\n * }\n *\n * // for 'canlestick' type, data should contain:\n * // - an array of [open, high, low, close, volume(optional)] data following the order\n * // - or an object with 'open', 'high', 'low', 'close' and 'value'(optional) key value\n * data: {\n * columns: [\n * [\"data1\",\n * [1000, 1100, 850, 870, 100], // or {open:1000, high: 1100, low: 870, volume: 100}\n * [870, 1250, 830, 1200] // 'volume' can be omitted\n * ]\n * ],\n * type: \"candlestick\"\n * }\n */\n data_columns: undefined,\n /**\n * Used if loading JSON via data.url.\n * - **Available Values:**\n * - json\n * - csv\n * - tsv\n * @name data․mimeType\n * @memberof Options\n * @type {string}\n * @default csv\n * @example\n * data: {\n * mimeType: \"json\"\n * }\n */\n data_mimeType: \"csv\",\n /**\n * Choose which JSON object keys correspond to desired data.\n * - **NOTE:** Only for JSON object given as array.\n * @name data․keys\n * @memberof Options\n * @type {string}\n * @default undefined\n * @example\n * data: {\n * json: [\n * {name: \"www.site1.com\", upload: 200, download: 200, total: 400},\n * {name: \"www.site2.com\", upload: 100, download: 300, total: 400},\n * {name: \"www.site3.com\", upload: 300, download: 200, total: 500},\n * {name: \"www.site4.com\", upload: 400, download: 100, total: 500}\n * ],\n * keys: {\n * // x: \"name\", // it's possible to specify 'x' when category axis\n * value: [\"upload\", \"download\"]\n * }\n * }\n */\n data_keys: undefined,\n /**\n * Set text label to be displayed when there's no data to show.\n * - ex. Toggling all visible data to not be shown, unloading all current data, etc.\n * @name data․empty․label․text\n * @memberof Options\n * @type {string}\n * @default \"\"\n * @example\n * data: {\n * empty: {\n * label: {\n * text: \"No Data\"\n * }\n * }\n * }\n */\n data_empty_label_text: \"\"\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * color config options\n */\nvar color$1 = {\n /**\n * Set color of the data values\n * @name color\n * @memberof Options\n * @type {object}\n * @property {object} color color object\n * @property {string|object|Function} [color.onover] Set the color value for each data point when mouse/touch onover event occurs.\n * @property {Array|null} [color.pattern=[]] Set custom color pattern. Passing `null` will not set a color for these elements, which requires the usage of custom CSS-based theming to work.\n * @property {Function} [color.tiles] if defined, allows use svg's patterns to fill data area. It should return an array of [SVGPatternElement](https://developer.mozilla.org/en-US/docs/Web/API/SVGPatternElement).\n * - **NOTE:** The pattern element's id will be defined as `bb-colorize-pattern-$COLOR-VALUE`.
\n * ex. When color pattern value is `['red', '#fff']` and defined 2 patterns,then ids for pattern elements are:
\n * - `bb-colorize-pattern-red`\n * - `bb-colorize-pattern-fff`\n * @property {object} [color.threshold] color threshold for gauge and tooltip color\n * @property {string} [color.threshold.unit] If set to `value`, the threshold will be based on the data value. Otherwise it'll be based on equation of the `threshold.max` option value.\n * @property {Array} [color.threshold.values] Threshold values for each steps\n * @property {number} [color.threshold.max=100] The base value to determine threshold step value condition. When the given value is 15 and max 10, then the value for threshold is `15*100/10`.\n * @example\n * color: {\n * pattern: [\"#1f77b4\", \"#aec7e8\", ...],\n *\n * // Set colors' patterns\n * // it should return an array of SVGPatternElement\n * tiles: function() {\n * var pattern = document.createElementNS(\"http://www.w3.org/2000/svg\", \"pattern\");\n * var g = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n * var circle1 = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n *\n * pattern.setAttribute(\"patternUnits\", \"userSpaceOnUse\");\n * pattern.setAttribute(\"width\", \"32\");\n * pattern.setAttribute(\"height\", \"32\");\n *\n * g.style.fill = \"#000\";\n * g.style.opacity = \"0.2\";\n *\n * circle1.setAttribute(\"cx\", \"3\");\n * circle1.setAttribute(\"cy\", \"3\");\n * circle1.setAttribute(\"r\", \"3\");\n *\n * g.appendChild(circle1);\n * pattern.appendChild(g);\n *\n * return [pattern];\n * },\n *\n * // for threshold usage, pattern values should be set for each steps\n * pattern: [\"grey\", \"green\", \"yellow\", \"orange\", \"red\"],\n * threshold: {\n * unit: \"value\",\n *\n * // when value is 20 => 'green', value is 40 => 'orange' will be set.\n * values: [10, 20, 30, 40, 50],\n *\n * // the equation for max:\n * // - unit == 'value': max => 30\n * // - unit != 'value': max => value*100/30\n * max: 30\n * },\n *\n * // set all data to 'red'\n * onover: \"red\",\n *\n * // set different color for data\n * onover: {\n * data1: \"red\",\n * data2: \"yellow\"\n * },\n *\n * // will pass data object to the callback\n * onover: function(d) {\n * return d.id === \"data1\" ? \"red\" : \"green\";\n * }\n * }\n */\n color_pattern: [],\n color_tiles: undefined,\n color_threshold: {},\n color_onover: undefined\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * interaction config options\n */\nvar interaction$1 = {\n /**\n * Interaction options\n * @name interaction\n * @memberof Options\n * @type {object}\n * @property {object} interaction Intersection object\n * @property {boolean} [interaction.enabled=true] Indicate if the chart should have interactions.
\n * If `false` is set, all of interactions (showing/hiding tooltip, selection, mouse events, etc) will be disabled.\n * @property {boolean} [interaction.brighten=true] Make brighter for the selected area (ex. 'pie' type data selected area)\n * @property {boolean} [interaction.inputType.mouse=true] enable or disable mouse interaction\n * @property {boolean} [interaction.inputType.touch=true] enable or disable touch interaction\n * @property {boolean|number} [interaction.inputType.touch.preventDefault=false] enable or disable to call event.preventDefault on touchstart & touchmove event. It's usually used to prevent document scrolling.\n * @see [Demo: touch.preventDefault](https://naver.github.io/billboard.js/demo/#Interaction.PreventScrollOnTouch)\n * @example\n * interaction: {\n * enabled: false,\n * brighten: false,\n * inputType: {\n * mouse: true,\n * touch: false\n *\n * // or declare preventDefault explicitly.\n * // In this case touch inputType is enabled by default\n * touch: {\n * preventDefault: true\n *\n * // or threshold pixel value (pixel moved from touchstart to touchmove)\n * preventDefault: 5\n * }\n * }\n * }\n */\n interaction_enabled: true,\n interaction_brighten: true,\n interaction_inputType_mouse: true,\n interaction_inputType_touch: {}\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * legend config options\n */\nvar legend$2 = {\n /**\n * Legend options\n * @name legend\n * @memberof Options\n * @type {object}\n * @property {object} legend Legend object\n * @property {boolean} [legend.show=true] Show or hide legend.\n * @property {boolean} [legend.hide=false] Hide legend\n * If true given, all legend will be hidden. If string or array given, only the legend that has the id will be hidden.\n * @property {string|HTMLElement} [legend.contents.bindto=undefined] Set CSS selector or element reference to bind legend items.\n * - **NOTE:** Should be used along with `legend.contents.template`.\n * @property {string|Function} [legend.contents.template=\"{=TITLE}\"] Set item's template.
\n * - If set `string` value, within template the 'color' and 'title' can be replaced using template-like syntax string:\n * - {=COLOR}: data color value\n * - {=TITLE}: data title value\n * - If set `function` value, will pass following arguments to the given function:\n * - title {string}: data's id value\n * - color {string}: color string\n * - data {Array}: data array\n * @property {string} [legend.position=bottom] Change the position of legend.
\n * Available values are: `bottom`, `right` and `inset` are supported.\n * @property {object} [legend.inset={anchor: 'top-left',x: 10,y: 0,step: undefined}] Change inset legend attributes.
\n * This option accepts object that has the keys `anchor`, `x`, `y` and `step`.\n * - **anchor** decides the position of the legend:\n * - top-left\n * - top-right\n * - bottom-left\n * - bottom-right\n * - **x** and **y**:\n * - set the position of the legend based on the anchor.\n * - **step**:\n * - defines the max step the legend has (e.g. If 2 set and legend has 3 legend item, the legend 2 columns).\n * @property {boolean} [legend.equally=false] Set to all items have same width size.\n * @property {boolean} [legend.padding=0] Set padding value\n * @property {Function} [legend.item.onclick=undefined] Set click event handler to the legend item.\n * @property {Function} [legend.item.onover=undefined] Set mouse/touch over event handler to the legend item.\n * @property {Function} [legend.item.onout=undefined] Set mouse/touch out event handler to the legend item.\n * @property {number} [legend.item.tile.width=10] Set width for 'rectangle' legend item tile element.\n * @property {number} [legend.item.tile.height=10] ㄹ\n * @property {number} [legend.item.tile.r=5] Set the radius for 'circle' legend item tile type.\n * @property {string} [legend.item.tile.type=\"rectangle\"] Set legend item shape type.
\n * - **Available Values:**\n * - circle\n * - rectangle\n * @property {boolean} [legend.usePoint=false] Whether to use custom points in legend.\n * @see [Demo: item.tile.type](https://naver.github.io/billboard.js/demo/#Legend.LegendItemTileType)\n * @see [Demo: position](https://naver.github.io/billboard.js/demo/#Legend.LegendPosition)\n * @see [Demo: contents.template](https://naver.github.io/billboard.js/demo/#Legend.LegendTemplate1)\n * @see [Demo: usePoint](https://naver.github.io/billboard.js/demo/#Legend.usePoint)\n * @example\n * legend: {\n * show: true,\n * hide: true,\n * //or hide: \"data1\"\n * //or hide: [\"data1\", \"data2\"]\n * contents: {\n * bindto: \"#legend\", //
    \n *\n * // will be as:
  • data1
  • \n * template: \"
  • {=TITLE}
  • \"\n *\n * // or using function\n * template: function(id, color, data) {\n * // if you want omit some legend, return falsy value\n * if (id !== \"data1\") {\n * return \"
  • {=TITLE}\",\n legend_position: \"bottom\",\n legend_inset_anchor: \"top-left\",\n legend_inset_x: 10,\n legend_inset_y: 0,\n legend_inset_step: undefined,\n legend_item_onclick: undefined,\n legend_item_onover: undefined,\n legend_item_onout: undefined,\n legend_equally: false,\n legend_padding: 0,\n legend_item_tile_width: 10,\n legend_item_tile_height: 10,\n legend_item_tile_r: 5,\n legend_item_tile_type: \"rectangle\",\n legend_usePoint: false\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * title config options\n */\nvar title$1 = {\n /**\n * Set title options\n * @name title\n * @memberof Options\n * @type {object}\n * @property {object} title Title object\n * @property {string} [title.text] Title text. If contains `\\n`, it's used as line break allowing multiline title.\n * @property {number} [title.padding.top=0] Top padding value.\n * @property {number} [title.padding.right=0] Right padding value.\n * @property {number} [title.padding.bottom=0] Bottom padding value.\n * @property {number} [title.padding.left=0] Left padding value.\n * @property {string} [title.position=center] Available values are: 'center', 'right' and 'left'.\n * @see [Demo](https://naver.github.io/billboard.js/demo/#Title.MultilinedTitle)\n * @example\n * title: {\n * text: \"Title Text\",\n *\n * // or Multiline title text\n * text: \"Main title text\\nSub title text\",\n *\n * padding: {\n * top: 10,\n * right: 10,\n * bottom: 10,\n * left: 10\n * },\n * position: \"center\"\n * }\n */\n title_text: undefined,\n title_padding: {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n },\n title_position: \"center\"\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * tooltip config options\n */\nvar tooltip$2 = {\n /**\n * Tooltip options\n * @name tooltip\n * @memberof Options\n * @type {object}\n * @property {object} tooltip Tooltip object\n * @property {boolean} [tooltip.show=true] Show or hide tooltip.\n * @property {boolean} [tooltip.doNotHide=false] Make tooltip keep showing not hiding on interaction.\n * @property {boolean} [tooltip.grouped=true] Set if tooltip is grouped or not for the data points.\n * - **NOTE:** The overlapped data points will be displayed as grouped even if set false.\n * @property {boolean} [tooltip.linked=false] Set if tooltips on all visible charts with like x points are shown together when one is shown.\n * @property {string} [tooltip.linked.name=\"\"] Groping name for linked tooltip.
    If specified, linked tooltip will be groped interacting to be worked only with the same name.\n * @property {Function} [tooltip.format.title] Set format for the title of tooltip.
    \n * Specified function receives x of the data point to show.\n * @property {Function} [tooltip.format.name] Set format for the name of each data in tooltip.
    \n * Specified function receives name, ratio, id and index of the data point to show. ratio will be undefined if the chart is not donut/pie/gauge.\n * @property {Function} [tooltip.format.value] Set format for the value of each data in tooltip. If undefined returned, the row of that value will be skipped to be called.\n * - Will pass following arguments to the given function:\n * - `value {string}`: Value of the data point\n * - `ratio {number}`: Ratio of the data point in the `pie/donut/gauge` and `area/bar` when contains grouped data. Otherwise is `undefined`.\n * - `id {string}`: id of the data point\n * - `index {number}`: Index of the data point\n * @property {Function} [tooltip.position] Set custom position function for the tooltip.
    \n * This option can be used to modify the tooltip position by returning object that has top and left.\n * - Will pass following arguments to the given function:\n * - `data {Array}`: Current selected data array object.\n * - `width {number}`: Width of tooltip.\n * - `height {number}`: Height of tooltip.\n * - `element {SVGElement}`: Tooltip event bound element\n * - `pos {object}`: Current position of the tooltip.\n * @property {Function|object} [tooltip.contents] Set custom HTML for the tooltip.
    \n * If tooltip.grouped is true, data includes multiple data points.

    \n * Specified function receives `data` array and `defaultTitleFormat`, `defaultValueFormat` and `color` functions of the data point to show.\n * - **Note:**\n * - defaultTitleFormat:\n * - if `axis.x.tick.format` option will be used if set.\n * - otherwise, will return function based on tick format type(category, timeseries).\n * - defaultValueFormat:\n *\t - for Arc type (except gauge, radar), the function will return value from `(ratio * 100).toFixed(1)`.\n *\t - for Axis based types, will be used `axis.[y|y2].tick.format` option value if is set.\n *\t - otherwise, will parse value and return as number.\n * @property {string|HTMLElement} [tooltip.contents.bindto=undefined] Set CSS selector or element reference to bind tooltip.\n * - **NOTE:** When is specified, will not be updating tooltip's position.\n * @property {string} [tooltip.contents.template=undefined] Set tooltip's template.

    \n * Within template, below syntax will be replaced using template-like syntax string:\n * - **{{ ... }}**: the doubly curly brackets indicate loop block for data rows.\n * - **{=CLASS_TOOLTIP}**: default tooltip class name `bb-tooltip`.\n * - **{=CLASS_TOOLTIP_NAME}**: default tooltip data class name (ex. `bb-tooltip-name-data1`)\n * - **{=TITLE}**: title value.\n * - **{=COLOR}**: data color.\n * - **{=VALUE}**: data value.\n * @property {object} [tooltip.contents.text=undefined] Set additional text content within data loop, using template syntax.\n * - **NOTE:** It should contain `{ key: Array, ... }` value\n * - 'key' name is used as substitution within template as '{=KEY}'\n * - The value array length should match with the data length\n * @property {boolean} [tooltip.init.show=false] Show tooltip at the initialization.\n * @property {number} [tooltip.init.x=0] Set x Axis index(or index for Arc(donut, gauge, pie) types) to be shown at the initialization.\n * @property {object} [tooltip.init.position={top: \"0px\",left: \"50px\"}] Set the position of tooltip at the initialization.\n * @property {Function} [tooltip.onshow] Set a callback that will be invoked before the tooltip is shown.\n * @property {Function} [tooltip.onhide] Set a callback that will be invoked before the tooltip is hidden.\n * @property {Function} [tooltip.onshown] Set a callback that will be invoked after the tooltip is shown\n * @property {Function} [tooltip.onhidden] Set a callback that will be invoked after the tooltip is hidden.\n * @property {string|Function|null} [tooltip.order=null] Set tooltip data display order.

    \n * **Available Values:**\n * - `desc`: In descending data value order\n * - `asc`: In ascending data value order\n * - `null`: It keeps the data display order
    \n * **NOTE:** When `data.groups` is set, the order will follow as the stacked graph order.
    \n * If want to order as data bound, set any value rather than asc, desc or null. (ex. empty string \"\")\n * - `function(data1, data2) { ... }`: [Array.sort compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters)\n * @see [Demo: Hide Tooltip](https://naver.github.io/billboard.js/demo/#Tooltip.HideTooltip)\n * @see [Demo: Tooltip Grouping](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipGrouping)\n * @see [Demo: Tooltip Format](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipFormat)\n * @see [Demo: Linked Tooltip](https://naver.github.io/billboard.js/demo/#Tooltip.LinkedTooltips)\n * @see [Demo: Tooltip Template](https://naver.github.io/billboard.js/demo/#Tooltip.TooltipTemplate)\n * @example\n * tooltip: {\n * show: true,\n * doNotHide: true,\n * grouped: false,\n * format: {\n * title: function(x) { return \"Data \" + x; },\n * name: function(name, ratio, id, index) { return name; },\n * value: function(value, ratio, id, index) { return ratio; }\n * },\n * position: function(data, width, height, element, pos) {\n * // data: [{x, index, id, name, value}, ...]\n * // width: Tooltip width\n * // height: Tooltip height\n * // element: Tooltip event bound element\n * // pos: {\n * // x: Current mouse event x position,\n * // y: Current mouse event y position,\n * // xAxis: Current x Axis position (the value is given for axis based chart type only)\n * // }\n * return {top: 0, left: 0}\n * },\n *\n * contents: function(d, defaultTitleFormat, defaultValueFormat, color) {\n * return ... // formatted html as you want\n * },\n *\n * // specify tooltip contents using template\n * // - example of HTML returned:\n * //
      \n * //
    • 250
      data1
    • \n * //
    • 50
      data2
    • \n * //
    \n * contents: {\n * \tbindto: \"#tooltip\",\n * \ttemplate: '
      {{' +\n * \t\t\t'
    • {=VALUE}
      ' +\n * \t\t\t'{=NAME}
    • ' +\n * \t\t'}}
    '\n * }\n *\n * // with additional text value\n * // - example of HTML returned:\n * //
      \n * //
    • 250
      comment1data1text1
    • \n * //
    • 50
      comment2data2text2
    • \n * //
    \n * contents: {\n * \tbindto: \"#tooltip\",\n * \ttext: {\n * \t\t// a) 'key' name is used as substitution within template as '{=KEY}'\n * \t\t// b) the length should match with the data length\n * \t\tVAR1: [\"text1\", \"text2\"],\n * \t\tVAR2: [\"comment1\", \"comment2\"],\n * \t},\n * \ttemplate: '
      {{' +\n * \t\t\t'
    • {=VALUE}{=VAR2}
      ' +\n * \t\t\t'{=NAME}{=VAR1}
    • ' +\n * \t\t'}}
    '\n * }\n *\n * // sort tooltip data value display in ascending order\n * order: \"asc\",\n *\n * // specifying sort function\n * order: function(a, b) {\n * // param data passed format\n * {x: 5, value: 250, id: \"data1\", index: 5, name: \"data1\"}\n * ...\n * },\n *\n * // show at the initialization\n * init: {\n * show: true,\n * x: 2, // x Axis index(or index for Arc(donut, gauge, pie) types)\n * position: {\n * top: \"150px\",\n * left: \"250px\"\n * }\n * },\n *\n * // fires prior tooltip is shown\n * onshow: function(selectedData) {\n * \t// current dataset selected\n * \t// ==> [{x: 4, value: 150, id: \"data2\", index: 4, name: \"data2\"}, ...]\n * \tselectedData;\n * },\n *\n * // fires prior tooltip is hidden\n * onhide: function(selectedData) {\n * \t// current dataset selected\n * \t// ==> [{x: 4, value: 150, id: \"data2\", index: 4, name: \"data2\"}, ...]\n * \tselectedData;\n * },\n *\n * // fires after tooltip is shown\n * onshown: function(selectedData) {\n * \t// current dataset selected\n * \t// ==> [{x: 4, value: 150, id: \"data2\", index: 4, name: \"data2\"}, ...]\n * \tselectedData;\n * },\n *\n * // fires after tooltip is hidden\n * onhidden: function(selectedData) {\n * \t// current dataset selected\n * \t// ==> [{x: 4, value: 150, id: \"data2\", index: 4, name: \"data2\"}, ...]\n * \tselectedData;\n * },\n *\n * // Link any tooltips when multiple charts are on the screen where same x coordinates are available\n * // Useful for timeseries correlation\n * linked: true,\n *\n * // Specify name to interact those with the same name only.\n * linked: {\n * name: \"some-group\"\n * }\n * }\n */\n tooltip_show: true,\n tooltip_doNotHide: false,\n tooltip_grouped: true,\n tooltip_format_title: undefined,\n tooltip_format_name: undefined,\n tooltip_format_value: undefined,\n tooltip_position: undefined,\n tooltip_contents: {},\n tooltip_init_show: false,\n tooltip_init_x: 0,\n tooltip_init_position: {\n top: \"0px\",\n left: \"50px\"\n },\n tooltip_linked: false,\n tooltip_linked_name: \"\",\n tooltip_onshow: function () { },\n tooltip_onhide: function () { },\n tooltip_onshown: function () { },\n tooltip_onhidden: function () { },\n tooltip_order: null\n};\n\n/**\n * Class to set options on generating chart.\n * - It's instantiated internally, not exposed for public.\n * @class Options\n * @see {@link bb.generate} to use these options on generating the chart\n */\nvar Options = /** @class */ (function () {\n function Options() {\n return deepClone(main, boost, data$2, color$1, interaction$1, legend$2, title$1, tooltip$2, Options.data);\n }\n Options.setOptions = function (options) {\n this.data = options\n .reduce(function (a, c) { return (_assign(_assign({}, a), c)); }, this.data);\n };\n Options.data = {};\n return Options;\n}());\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Constant for cache key\n * - NOTE: Prefixed with '$', will be resetted when .load() is called\n * @private\n */\nvar KEY = {\n bubbleBaseLength: \"$baseLength\",\n colorPattern: \"__colorPattern__\",\n dataMinMax: \"$dataMinMax\",\n dataTotalSum: \"$dataTotalSum\",\n dataTotalPerIndex: \"$totalPerIndex\",\n legendItemTextBox: \"legendItemTextBox\",\n radarPoints: \"$radarPoints\",\n setOverOut: \"setOverOut\",\n callOverOutForTouch: \"callOverOutForTouch\",\n textRect: \"textRect\"\n};\nvar Cache = /** @class */ (function () {\n function Cache() {\n this.cache = {};\n }\n /**\n * Add cache\n * @param {string} key Cache key\n * @param {*} value Value to be stored\n * @param {boolean} isDataType Weather the cache is data typed '{id:'data', id_org: 'data', values: [{x:0, index:0,...}, ...]}'\n * @returns {*} Added data value\n * @private\n */\n Cache.prototype.add = function (key, value, isDataType) {\n if (isDataType === void 0) { isDataType = false; }\n this.cache[key] = isDataType ? this.cloneTarget(value) : value;\n return this.cache[key];\n };\n /**\n * Remove cache\n * @param {string|Array} key Cache key\n * @private\n */\n Cache.prototype.remove = function (key) {\n var _this = this;\n toArray(key).forEach(function (v) { return delete _this.cache[v]; });\n };\n /**\n * Get cahce\n * @param {string|Array} key Cache key\n * @param {boolean} isDataType Weather the cache is data typed '{id:'data', id_org: 'data', values: [{x:0, index:0,...}, ...]}'\n * @returns {*}\n * @private\n */\n Cache.prototype.get = function (key, isDataType) {\n if (isDataType === void 0) { isDataType = false; }\n if (isDataType) {\n var targets = [];\n for (var i = 0, id = void 0; (id = key[i]); i++) {\n if (id in this.cache) {\n targets.push(this.cloneTarget(this.cache[id]));\n }\n }\n return targets;\n }\n else {\n var value = this.cache[key];\n return isValue(value) ? value : null;\n }\n };\n /**\n * Reset cached data\n * @param {boolean} all true: reset all data, false: reset only '$' prefixed key data\n * @private\n */\n Cache.prototype.reset = function (all) {\n var $$ = this;\n for (var x in $$.cache) {\n // reset the prefixed '$' key(which is internal use data) only.\n if (all || /^\\$/.test(x)) {\n $$.cache[x] = null;\n }\n }\n };\n /**\n * Clone data target object\n * @param {object} target Data object\n * @returns {object}\n * @private\n */\n // eslint-disable-next-line camelcase\n Cache.prototype.cloneTarget = function (target) {\n return {\n id: target.id,\n id_org: target.id_org,\n values: target.values.map(function (d) { return ({ x: d.x, value: d.value, id: d.id }); })\n };\n };\n return Cache;\n}());\n\nvar setTimeout$1 = win.setTimeout, clearTimeout$1 = win.clearTimeout;\n/**\n * Generate resize queue function\n * @param {boolean|number} option Resize option\n * @returns {Fucntion}\n * @private\n */\nfunction generateResize(option) {\n var fn = [];\n var timeout;\n var callResizeFn = function () {\n // Delay all resize functions call, to prevent unintended excessive call from resize event\n callResizeFn.clear();\n if (option === false && win.requestIdleCallback) {\n requestIdleCallback(function () {\n fn.forEach(function (f) { return f(); });\n }, { timeout: 200 });\n }\n else {\n timeout = setTimeout$1(function () {\n fn.forEach(function (f) { return f(); });\n }, isNumber(option) ? option : 200);\n }\n };\n callResizeFn.clear = function () {\n if (timeout) {\n clearTimeout$1(timeout);\n timeout = null;\n }\n };\n callResizeFn.add = function (f) { return fn.push(f); };\n callResizeFn.remove = function (f) { return fn.splice(fn.indexOf(f), 1); };\n return callResizeFn;\n}\n/**\n * Generate transition queue function\n * @returns {Function}\n * @private\n */\nfunction generateWait() {\n var transitionsToWait = [];\n // 'f' is called as selection.call(f, ...);\n var f = function (selection, callback) {\n /**\n * Check if transition is complete\n * @returns {boolean} Whether transition is complete\n * @private\n */\n function loop() {\n var _a;\n var done = 0;\n for (var i = 0, t = void 0; (t = transitionsToWait[i]); i++) {\n if (t === true || ((_a = t.empty) === null || _a === void 0 ? void 0 : _a.call(t))) {\n done++;\n continue;\n }\n // when tab isn't visible exit loop\n if (isTabVisible() === false) {\n done = transitionsToWait.length;\n break;\n }\n try {\n t.transition();\n }\n catch (e) {\n done++;\n }\n }\n return done === transitionsToWait.length;\n }\n runUntil(function () {\n callback === null || callback === void 0 ? void 0 : callback();\n }, loop);\n };\n f.add = function (t) {\n isArray(t) ?\n (transitionsToWait = transitionsToWait.concat(t)) :\n transitionsToWait.push(t);\n };\n return f;\n}\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n// Store blob in memory\nvar blob = {};\n/**\n * Get Object URL\n * @param {Function} fn Function to be executed in worker\n * @param {Array} depsFn Dependency functions to run given function(fn).\n * @returns {string}\n * @private\n */\nfunction getObjectURL(fn, depsFn) {\n var _a;\n var fnString = fn.toString();\n var key = fnString.replace(/(function|[\\s\\W\\n])/g, \"\").substring(0, 15);\n if (!(key in blob)) {\n // Web Worker body\n blob[key] = new win.Blob([\n \"\".concat((_a = depsFn === null || depsFn === void 0 ? void 0 : depsFn.map(String).join(\";\")) !== null && _a !== void 0 ? _a : \"\", \"\\n\\n\\t\\t\\tself.onmessage=function({data}) {\\n\\t\\t\\t\\tconst result = (\").concat(fnString, \").apply(null, data);\\n\\t\\t\\t\\tself.postMessage(result);\\n\\t\\t\\t};\")\n ], {\n type: \"text/javascript\"\n });\n }\n return win.URL.createObjectURL(blob[key]);\n}\n/**\n * Create and run on Web Worker\n * @param {boolean} useWorker Use Web Worker\n * @param {Function} fn Function to be executed in worker\n * @param {Function} callback Callback function to receive result from worker\n * @param {Array} depsFn Dependency functions to run given function(fn).\n * @returns {object}\n * @example\n * \tconst worker = runWorker(function(arg) {\n *\t\t // do some tasks...\n *\t\t console.log(\"param:\", A(arg));\n *\n *\t\t return 1234;\n *\t }, function(data) {\n *\t\t // callback after worker is done\n *\t \t console.log(\"result:\", data);\n *\t },\n *\t [function A(){}]\n *\t);\n *\n *\tworker(11111);\n * @private\n */\nfunction runWorker(useWorker, fn, callback, depsFn) {\n if (useWorker === void 0) { useWorker = true; }\n var runFn;\n if (win.Worker && useWorker) {\n var src_1 = getObjectURL(fn, depsFn);\n var worker_1 = new win.Worker(src_1);\n runFn = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n // trigger worker\n worker_1.postMessage(args);\n // listen worker\n worker_1.onmessage = function (e) {\n // release object URL from memory\n win.URL.revokeObjectURL(src_1);\n return callback(e.data);\n };\n // handle error\n worker_1.onerror = function (e) {\n console.error(e);\n };\n // return new Promise((resolve, reject) => {\n // \tworker.onmessage = ({data}) => resolve(data);\n // \tworker.onerror = reject;\n // });\n };\n }\n else {\n runFn = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var res = fn.apply(void 0, args);\n callback(res);\n };\n }\n return runFn;\n}\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/***** Functions to be executed on Web Worker *****\n * NOTE: Don't allowed to use\n * - arrow function syntax\n * - Utils functions\n */\n/**\n * Convert Columns data\n * @param {object} columns\n * @returns {Array}\n * @private\n */\nfunction columns(columns) {\n var newRows = [];\n columns.forEach(function (col, i) {\n var key = col[0];\n col.forEach(function (v, j) {\n if (j > 0) {\n if (typeof newRows[j - 1] === \"undefined\") {\n newRows[j - 1] = {};\n }\n if (typeof v === \"undefined\") {\n throw new Error(\"Source data is missing a component at (\".concat(i, \", \").concat(j, \")!\"));\n }\n newRows[j - 1][key] = v;\n }\n });\n });\n return newRows;\n}\n/**\n * Convert Rows data\n * @param {object} columns\n * @returns {Array}\n * @private\n */\nfunction rows(rows) {\n var keys = rows[0];\n var newRows = [];\n rows.forEach(function (row, i) {\n if (i > 0) {\n var newRow_1 = {};\n row.forEach(function (v, j) {\n if (typeof v === \"undefined\") {\n throw new Error(\"Source data is missing a component at (\".concat(i, \", \").concat(j, \")!\"));\n }\n newRow_1[keys[j]] = v;\n });\n newRows.push(newRow_1);\n }\n });\n return newRows;\n}\n/**\n * Convert JSON data\n * @param {object} columns\n * @returns {Array}\n * @private\n */\nfunction json(json, keysParam) {\n var newRows = [];\n var targetKeys;\n var data;\n if (Array.isArray(json)) {\n var findValueInJson_1 = function (object, path) {\n if (object[path] !== undefined) {\n return object[path];\n }\n var convertedPath = path.replace(/\\[(\\w+)\\]/g, \".$1\"); // convert indexes to properties (replace [] with .)\n var pathArray = convertedPath.replace(/^\\./, \"\").split(\".\"); // strip a leading dot\n var target = object;\n pathArray.some(function (k) {\n return !(target = target && k in target ?\n target[k] : undefined);\n });\n return target;\n };\n if (keysParam.x) {\n targetKeys = keysParam.value.concat(keysParam.x);\n }\n else {\n targetKeys = keysParam.value;\n }\n newRows.push(targetKeys);\n json.forEach(function (o) {\n var newRow = targetKeys.map(function (key) {\n // convert undefined to null because undefined data will be removed in convertDataToTargets()\n var v = findValueInJson_1(o, key);\n if (typeof v === \"undefined\") {\n v = null;\n }\n return v;\n });\n newRows.push(newRow);\n });\n data = rows(newRows);\n }\n else {\n Object.keys(json).forEach(function (key) {\n var _a;\n var tmp = json[key].concat();\n (_a = tmp.unshift) === null || _a === void 0 ? void 0 : _a.call(tmp, key);\n newRows.push(tmp);\n });\n data = columns(newRows);\n }\n return data;\n}\n/***** Functions can't be executed on Web Worker *****/\n/**\n * Convert URL data\n * @param {string} url Remote URL\n * @param {string} mimeType MIME type string: json | csv | tsv\n * @param {object} headers Header object\n * @param {object} keys Key object\n * @param {Function} done Callback function\n * @private\n */\nfunction url(url, mimeType, headers, keys, done) {\n if (mimeType === void 0) { mimeType = \"csv\"; }\n var req = new XMLHttpRequest();\n var converter = { csv: csv, tsv: tsv, json: json };\n req.open(\"GET\", url);\n if (headers) {\n Object.keys(headers).forEach(function (key) {\n req.setRequestHeader(key, headers[key]);\n });\n }\n req.onreadystatechange = function () {\n if (req.readyState === 4) {\n if (req.status === 200) {\n var response = req.responseText;\n response && done.call(this, converter[mimeType](mimeType === \"json\" ? JSON.parse(response) : response, keys));\n }\n else {\n throw new Error(\"\".concat(url, \": Something went wrong loading!\"));\n }\n }\n };\n req.send();\n}\n/**\n * Convert CSV/TSV data\n * @param {object} parser Parser object\n * @param {object} xsv Data\n * @returns {object}\n * @private\n */\nfunction convertCsvTsvToData(parser, xsv) {\n var rows = parser.rows(xsv);\n var d;\n if (rows.length === 1) {\n d = [{}];\n rows[0].forEach(function (id) {\n d[0][id] = null;\n });\n }\n else {\n d = parser.parse(xsv);\n }\n return d;\n}\nfunction csv(xsv) {\n return convertCsvTsvToData({\n rows: csvParseRows,\n parse: csvParse\n }, xsv);\n}\nfunction tsv(tsv) {\n return convertCsvTsvToData({\n rows: tsvParseRows,\n parse: tsvParse\n }, tsv);\n}\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Get data key for JSON\n * @param {string|object} keysParam Key params\n * @param {object} config Config object\n * @returns {string} Data key\n * @private\n */\nfunction getDataKeyForJson(keysParam, config) {\n var keys = keysParam || (config === null || config === void 0 ? void 0 : config.data_keys);\n if (keys === null || keys === void 0 ? void 0 : keys.x) {\n config.data_x = keys.x;\n }\n return keys;\n}\n/**\n * Data convert\n * @memberof ChartInternal\n * @private\n */\nvar dataConvert = {\n /**\n * Convert data according its type\n * @param {object} args data object\n * @param {Function} [callback] callback for url(XHR) type loading\n * @private\n */\n convertData: function (args, callback) {\n var config = this.config;\n var useWorker = config.boost_useWorker;\n var data = args;\n if (args.bindto) {\n data = {};\n [\"url\", \"mimeType\", \"headers\", \"keys\", \"json\", \"keys\", \"rows\", \"columns\"]\n .forEach(function (v) {\n var key = \"data_\".concat(v);\n if (key in args) {\n data[v] = args[key];\n }\n });\n }\n if (data.url && callback) {\n url(data.url, data.mimeType, data.headers, getDataKeyForJson(data.keys, config), callback);\n }\n else if (data.json) {\n runWorker(useWorker, json, callback, [columns, rows])(data.json, getDataKeyForJson(data.keys, config));\n }\n else if (data.rows) {\n runWorker(useWorker, rows, callback)(data.rows);\n }\n else if (data.columns) {\n runWorker(useWorker, columns, callback)(data.columns);\n }\n else if (args.bindto) {\n throw Error(\"url or json or rows or columns is required.\");\n }\n },\n convertDataToTargets: function (data, appendXs) {\n var _this = this;\n var $$ = this;\n var axis = $$.axis, config = $$.config, state = $$.state;\n var isCategorized = false;\n var isTimeSeries = false;\n var isCustomX = false;\n if (axis) {\n isCategorized = axis.isCategorized();\n isTimeSeries = axis.isTimeSeries();\n isCustomX = axis.isCustomX();\n }\n var dataKeys = Object.keys(data[0] || {});\n var ids = dataKeys.length ? dataKeys.filter($$.isNotX, $$) : [];\n var xs = dataKeys.length ? dataKeys.filter($$.isX, $$) : [];\n var xsData;\n // save x for update data by load when custom x and bb.x API\n ids.forEach(function (id) {\n var xKey = _this.getXKey(id);\n if (isCustomX || isTimeSeries) {\n // if included in input data\n if (xs.indexOf(xKey) >= 0) {\n xsData = ((appendXs && $$.data.xs[id]) || [])\n .concat(data.map(function (d) { return d[xKey]; })\n .filter(isValue)\n .map(function (rawX, i) { return $$.generateTargetX(rawX, id, i); }));\n }\n else if (config.data_x) {\n // if not included in input data, find from preloaded data of other id's x\n xsData = _this.getOtherTargetXs();\n }\n else if (notEmpty(config.data_xs)) {\n // if not included in input data, find from preloaded data\n xsData = $$.getXValuesOfXKey(xKey, $$.data.targets);\n }\n // MEMO: if no x included, use same x of current will be used\n }\n else {\n xsData = data.map(function (d, i) { return i; });\n }\n xsData && (_this.data.xs[id] = xsData);\n });\n // check x is defined\n ids.forEach(function (id) {\n if (!_this.data.xs[id]) {\n throw new Error(\"x is not defined for id = \\\"\".concat(id, \"\\\".\"));\n }\n });\n // convert to target\n var targets = ids.map(function (id, index) {\n var convertedId = config.data_idConverter.bind($$.api)(id);\n var xKey = $$.getXKey(id);\n var isCategory = isCustomX && isCategorized;\n var hasCategory = isCategory && data.map(function (v) { return v.x; })\n .every(function (v) { return config.axis_x_categories.indexOf(v) > -1; });\n // when .load() with 'append' option is used for indexed axis\n // @ts-ignore\n var isDataAppend = data.__append__;\n var xIndex = xKey === null && isDataAppend ?\n $$.api.data.values(id).length : 0;\n return {\n id: convertedId,\n id_org: id,\n values: data.map(function (d, i) {\n var rawX = d[xKey];\n var value = d[id];\n var x;\n value = value !== null && !isNaN(value) && !isObject(value) ?\n +value : (isArray(value) || isObject(value) ? value : null);\n // use x as categories if custom x and categorized\n if ((isCategory || state.hasRadar) && index === 0 && !isUndefined(rawX)) {\n if (!hasCategory && index === 0 && i === 0 && !isDataAppend) {\n config.axis_x_categories = [];\n }\n x = config.axis_x_categories.indexOf(rawX);\n if (x === -1) {\n x = config.axis_x_categories.length;\n config.axis_x_categories.push(rawX);\n }\n }\n else {\n x = $$.generateTargetX(rawX, id, xIndex + i);\n }\n // mark as x = undefined if value is undefined and filter to remove after mapped\n if (isUndefined(value) || $$.data.xs[id].length <= i) {\n x = undefined;\n }\n return {\n x: x,\n value: value,\n id: convertedId,\n index: -1\n };\n }).filter(function (v) { return isDefined(v.x); })\n };\n });\n // finish targets\n targets.forEach(function (t) {\n var _a;\n // sort values by its x\n if (config.data_xSort) {\n t.values = t.values.sort(function (v1, v2) {\n var x1 = v1.x || v1.x === 0 ? v1.x : Infinity;\n var x2 = v2.x || v2.x === 0 ? v2.x : Infinity;\n return x1 - x2;\n });\n }\n // indexing each value\n t.values.forEach(function (v, i) { return (v.index = i); });\n // this needs to be sorted because its index and value.index is identical\n (_a = $$.data.xs[t.id]) === null || _a === void 0 ? void 0 : _a.sort(function (v1, v2) { return v1 - v2; });\n });\n // cache information about values\n state.hasNegativeValue = $$.hasNegativeValueInTargets(targets);\n state.hasPositiveValue = $$.hasPositiveValueInTargets(targets);\n // set target types\n if (config.data_type) {\n $$.setTargetType($$.mapToIds(targets)\n .filter(function (id) { return !(id in config.data_types); }), config.data_type);\n }\n // cache as original id keyed\n targets.forEach(function (d) { return $$.cache.add(d.id_org, d, true); });\n return targets;\n }\n};\n\nvar data$1 = {\n isX: function (key) {\n var $$ = this;\n var config = $$.config;\n var dataKey = config.data_x && key === config.data_x;\n var existValue = notEmpty(config.data_xs) && hasValue(config.data_xs, key);\n return dataKey || existValue;\n },\n isNotX: function (key) {\n return !this.isX(key);\n },\n isStackNormalized: function () {\n var config = this.config;\n return !!(config.data_stack_normalize && config.data_groups.length);\n },\n isGrouped: function (id) {\n var groups = this.config.data_groups;\n return id ?\n groups.some(function (v) { return v.indexOf(id) >= 0 && v.length > 1; }) :\n groups.length > 0;\n },\n getXKey: function (id) {\n var $$ = this;\n var config = $$.config;\n return config.data_x ?\n config.data_x : (notEmpty(config.data_xs) ? config.data_xs[id] : null);\n },\n getXValuesOfXKey: function (key, targets) {\n var $$ = this;\n var ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];\n var xValues;\n ids.forEach(function (id) {\n if ($$.getXKey(id) === key) {\n xValues = $$.data.xs[id];\n }\n });\n return xValues;\n },\n /**\n * Get index number based on given x Axis value\n * @param {Date|number|string} x x Axis to be compared\n * @param {Array} basedX x Axis list to be based on\n * @returns {number} index number\n * @private\n */\n getIndexByX: function (x, basedX) {\n var $$ = this;\n return basedX ?\n basedX.indexOf(isString(x) ? x : +x) :\n ($$.filterByX($$.data.targets, x)[0] || { index: null }).index;\n },\n getXValue: function (id, i) {\n var $$ = this;\n return id in $$.data.xs &&\n $$.data.xs[id] &&\n isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;\n },\n getOtherTargetXs: function () {\n var $$ = this;\n var idsForX = Object.keys($$.data.xs);\n return idsForX.length ? $$.data.xs[idsForX[0]] : null;\n },\n getOtherTargetX: function (index) {\n var xs = this.getOtherTargetXs();\n return xs && index < xs.length ? xs[index] : null;\n },\n addXs: function (xs) {\n var $$ = this;\n var config = $$.config;\n Object.keys(xs).forEach(function (id) {\n config.data_xs[id] = xs[id];\n });\n },\n isMultipleX: function () {\n return notEmpty(this.config.data_xs) ||\n this.hasType(\"bubble\") ||\n this.hasType(\"scatter\");\n },\n addName: function (data) {\n var $$ = this;\n var config = $$.config;\n var name;\n if (data) {\n name = config.data_names[data.id];\n data.name = name !== undefined ? name : data.id;\n }\n return data;\n },\n /**\n * Get all values on given index\n * @param {number} index Index\n * @param {boolean} filterNull Filter nullish value\n * @returns {Array}\n * @private\n */\n getAllValuesOnIndex: function (index, filterNull) {\n if (filterNull === void 0) { filterNull = false; }\n var $$ = this;\n var value = $$.filterTargetsToShow($$.data.targets)\n .map(function (t) { return $$.addName($$.getValueOnIndex(t.values, index)); });\n if (filterNull) {\n value = value.filter(function (v) { return v && \"value\" in v && isValue(v.value); });\n }\n return value;\n },\n getValueOnIndex: function (values, index) {\n var valueOnIndex = values.filter(function (v) { return v.index === index; });\n return valueOnIndex.length ? valueOnIndex[0] : null;\n },\n updateTargetX: function (targets, x) {\n var $$ = this;\n targets.forEach(function (t) {\n t.values.forEach(function (v, i) {\n v.x = $$.generateTargetX(x[i], t.id, i);\n });\n $$.data.xs[t.id] = x;\n });\n },\n updateTargetXs: function (targets, xs) {\n var $$ = this;\n targets.forEach(function (t) {\n xs[t.id] && $$.updateTargetX([t], xs[t.id]);\n });\n },\n generateTargetX: function (rawX, id, index) {\n var $$ = this;\n var axis = $$.axis;\n var x = (axis === null || axis === void 0 ? void 0 : axis.isCategorized()) ? index : (rawX || index);\n if (axis === null || axis === void 0 ? void 0 : axis.isTimeSeries()) {\n var fn = parseDate.bind($$);\n x = rawX ? fn(rawX) : fn($$.getXValue(id, index));\n }\n else if ((axis === null || axis === void 0 ? void 0 : axis.isCustomX()) && !(axis === null || axis === void 0 ? void 0 : axis.isCategorized())) {\n x = isValue(rawX) ? +rawX : $$.getXValue(id, index);\n }\n return x;\n },\n updateXs: function (values) {\n if (values.length) {\n this.axis.xs = values.map(function (v) { return v.x; });\n }\n },\n getPrevX: function (i) {\n var x = this.axis.xs[i - 1];\n return isDefined(x) ? x : null;\n },\n getNextX: function (i) {\n var x = this.axis.xs[i + 1];\n return isDefined(x) ? x : null;\n },\n /**\n * Get base value isAreaRangeType\n * @param {object} data Data object\n * @returns {number}\n * @private\n */\n getBaseValue: function (data) {\n var $$ = this;\n var hasAxis = $$.state.hasAxis;\n var value = data.value;\n // In case of area-range, data is given as: [low, mid, high] or {low, mid, high}\n // will take the 'mid' as the base value\n if (value && hasAxis) {\n if ($$.isAreaRangeType(data)) {\n value = $$.getRangedData(data, \"mid\");\n }\n else if ($$.isBubbleZType(data)) {\n value = $$.getBubbleZData(value, \"y\");\n }\n }\n return value;\n },\n /**\n * Get min/max value from the data\n * @private\n * @param {Array} data array data to be evaluated\n * @returns {{min: {number}, max: {number}}}\n */\n getMinMaxValue: function (data) {\n var getBaseValue = this.getBaseValue.bind(this);\n var min;\n var max;\n (data || this.data.targets.map(function (t) { return t.values; }))\n .forEach(function (v, i) {\n var value = v.map(getBaseValue).filter(isNumber);\n min = Math.min.apply(Math, __spreadArray([i ? min : Infinity], value, false));\n max = Math.max.apply(Math, __spreadArray([i ? max : -Infinity], value, false));\n });\n return { min: min, max: max };\n },\n /**\n * Get the min/max data\n * @private\n * @returns {{min: Array, max: Array}}\n */\n getMinMaxData: function () {\n var $$ = this;\n var cacheKey = KEY.dataMinMax;\n var minMaxData = $$.cache.get(cacheKey);\n if (!minMaxData) {\n var data = $$.data.targets.map(function (t) { return t.values; });\n var minMax_1 = $$.getMinMaxValue(data);\n var min_1 = [];\n var max_1 = [];\n data.forEach(function (v) {\n var minData = $$.getFilteredDataByValue(v, minMax_1.min);\n var maxData = $$.getFilteredDataByValue(v, minMax_1.max);\n if (minData.length) {\n min_1 = min_1.concat(minData);\n }\n if (maxData.length) {\n max_1 = max_1.concat(maxData);\n }\n });\n // update the cached data\n $$.cache.add(cacheKey, minMaxData = { min: min_1, max: max_1 });\n }\n return minMaxData;\n },\n /**\n * Get sum of data per index\n * @private\n * @returns {Array}\n */\n getTotalPerIndex: function () {\n var $$ = this;\n var cacheKey = KEY.dataTotalPerIndex;\n var sum = $$.cache.get(cacheKey);\n if (($$.config.data_groups.length || $$.isStackNormalized()) && !sum) {\n sum = [];\n $$.data.targets.forEach(function (row) {\n row.values.forEach(function (v, i) {\n if (!sum[i]) {\n sum[i] = 0;\n }\n sum[i] += isNumber(v.value) ? v.value : 0;\n });\n });\n }\n return sum;\n },\n /**\n * Get total data sum\n * @param {boolean} subtractHidden Subtract hidden data from total\n * @returns {number}\n * @private\n */\n getTotalDataSum: function (subtractHidden) {\n var $$ = this;\n var cacheKey = KEY.dataTotalSum;\n var total = $$.cache.get(cacheKey);\n if (!isNumber(total)) {\n var sum = mergeArray($$.data.targets.map(function (t) { return t.values; }))\n .map(function (v) { return v.value; });\n total = sum.length ? sum.reduce(function (p, c) { return p + c; }) : 0;\n $$.cache.add(cacheKey, total);\n }\n if (subtractHidden) {\n total -= $$.getHiddenTotalDataSum();\n }\n return total;\n },\n /**\n * Get total hidden data sum\n * @returns {number}\n * @private\n */\n getHiddenTotalDataSum: function () {\n var $$ = this;\n var api = $$.api, hiddenTargetIds = $$.state.hiddenTargetIds;\n var total = 0;\n if (hiddenTargetIds.length) {\n total = api.data.values.bind(api)(hiddenTargetIds)\n .reduce(function (p, c) { return p + c; });\n }\n return total;\n },\n /**\n * Get filtered data by value\n * @param {object} data Data\n * @param {number} value Value to be filtered\n * @returns {Array} filtered array data\n * @private\n */\n getFilteredDataByValue: function (data, value) {\n var _this = this;\n return data.filter(function (t) { return _this.getBaseValue(t) === value; });\n },\n /**\n * Return the max length of the data\n * @returns {number} max data length\n * @private\n */\n getMaxDataCount: function () {\n return Math.max.apply(Math, this.data.targets.map(function (t) { return t.values.length; }));\n },\n getMaxDataCountTarget: function () {\n var target = this.filterTargetsToShow() || [];\n var length = target.length;\n if (length > 1) {\n target = target.map(function (t) { return t.values; })\n .reduce(function (a, b) { return a.concat(b); })\n .map(function (v) { return v.x; });\n target = sortValue(getUnique(target))\n .map(function (x, index) { return ({ x: x, index: index }); });\n }\n else if (length) {\n target = target[0].values.concat();\n }\n return target;\n },\n mapToIds: function (targets) {\n return targets.map(function (d) { return d.id; });\n },\n mapToTargetIds: function (ids) {\n var $$ = this;\n return ids ? (isArray(ids) ? ids.concat() : [ids]) : $$.mapToIds($$.data.targets);\n },\n hasTarget: function (targets, id) {\n var ids = this.mapToIds(targets);\n for (var i = 0, val = void 0; (val = ids[i]); i++) {\n if (val === id) {\n return true;\n }\n }\n return false;\n },\n isTargetToShow: function (targetId) {\n return this.state.hiddenTargetIds.indexOf(targetId) < 0;\n },\n isLegendToShow: function (targetId) {\n return this.state.hiddenLegendIds.indexOf(targetId) < 0;\n },\n filterTargetsToShow: function (targets) {\n var $$ = this;\n return (targets || $$.data.targets).filter(function (t) { return $$.isTargetToShow(t.id); });\n },\n mapTargetsToUniqueXs: function (targets) {\n var $$ = this;\n var axis = $$.axis;\n var xs = [];\n if (targets === null || targets === void 0 ? void 0 : targets.length) {\n xs = getUnique(mergeArray(targets.map(function (t) { return t.values.map(function (v) { return +v.x; }); })));\n xs = (axis === null || axis === void 0 ? void 0 : axis.isTimeSeries()) ? xs.map(function (x) { return new Date(+x); }) : xs.map(Number);\n }\n return sortValue(xs);\n },\n /**\n * Add to the state target Ids\n * @param {string} type State's prop name\n * @param {Array|string} targetIds Target ids array\n * @private\n */\n addTargetIds: function (type, targetIds) {\n var state = this.state;\n var ids = (isArray(targetIds) ? targetIds : [targetIds]);\n ids.forEach(function (v) {\n state[type].indexOf(v) < 0 &&\n state[type].push(v);\n });\n },\n /**\n * Remove from the state target Ids\n * @param {string} type State's prop name\n * @param {Array|string} targetIds Target ids array\n * @private\n */\n removeTargetIds: function (type, targetIds) {\n var state = this.state;\n var ids = (isArray(targetIds) ? targetIds : [targetIds]);\n ids.forEach(function (v) {\n var index = state[type].indexOf(v);\n index >= 0 && state[type].splice(index, 1);\n });\n },\n addHiddenTargetIds: function (targetIds) {\n this.addTargetIds(\"hiddenTargetIds\", targetIds);\n },\n removeHiddenTargetIds: function (targetIds) {\n this.removeTargetIds(\"hiddenTargetIds\", targetIds);\n },\n addHiddenLegendIds: function (targetIds) {\n this.addTargetIds(\"hiddenLegendIds\", targetIds);\n },\n removeHiddenLegendIds: function (targetIds) {\n this.removeTargetIds(\"hiddenLegendIds\", targetIds);\n },\n getValuesAsIdKeyed: function (targets) {\n var $$ = this;\n var hasAxis = $$.state.hasAxis;\n var ys = {};\n var isMultipleX = $$.isMultipleX();\n var xs = isMultipleX ? $$.mapTargetsToUniqueXs(targets)\n .map(function (v) { return (isString(v) ? v : +v); }) : null;\n targets.forEach(function (t) {\n var data = [];\n t.values\n .filter(function (_a) {\n var value = _a.value;\n return isValue(value) || value === null;\n })\n .forEach(function (v) {\n var value = v.value;\n // exclude 'volume' value to correct mis domain calculation\n if (value !== null && $$.isCandlestickType(v)) {\n value = isArray(value) ? value.slice(0, 4) : [value.open, value.high, value.low, value.close];\n }\n if (isArray(value)) {\n data.push.apply(data, value);\n }\n else if (isObject(value) && \"high\" in value) {\n data.push.apply(data, Object.values(value));\n }\n else if ($$.isBubbleZType(v)) {\n data.push(hasAxis && $$.getBubbleZData(value, \"y\"));\n }\n else {\n if (isMultipleX) {\n data[$$.getIndexByX(v.x, xs)] = value;\n }\n else {\n data.push(value);\n }\n }\n });\n ys[t.id] = data;\n });\n return ys;\n },\n checkValueInTargets: function (targets, checker) {\n var ids = Object.keys(targets);\n var values;\n for (var i = 0; i < ids.length; i++) {\n values = targets[ids[i]].values;\n for (var j = 0; j < values.length; j++) {\n if (checker(values[j].value)) {\n return true;\n }\n }\n }\n return false;\n },\n hasMultiTargets: function () {\n return this.filterTargetsToShow().length > 1;\n },\n hasNegativeValueInTargets: function (targets) {\n return this.checkValueInTargets(targets, function (v) { return v < 0; });\n },\n hasPositiveValueInTargets: function (targets) {\n return this.checkValueInTargets(targets, function (v) { return v > 0; });\n },\n /**\n * Sort targets data\n * Note: For stacked bar, will sort from the total sum of data series, not for each stacked bar\n * @param {Array} targetsValue Target value\n * @returns {Array}\n * @private\n */\n orderTargets: function (targetsValue) {\n var $$ = this;\n var targets = __spreadArray([], targetsValue, true);\n var fn = $$.getSortCompareFn();\n fn && targets.sort(fn);\n return targets;\n },\n /**\n * Get data.order compare function\n * @param {boolean} isReversed for Arc & Treemap type sort order needs to be reversed\n * @returns {Function} compare function\n * @private\n */\n getSortCompareFn: function (isReversed) {\n if (isReversed === void 0) { isReversed = false; }\n var $$ = this;\n var config = $$.config;\n var order = config.data_order;\n var orderAsc = /asc/i.test(order);\n var orderDesc = /desc/i.test(order);\n var fn;\n if (orderAsc || orderDesc) {\n var reducer_1 = function (p, c) { return p + Math.abs(c.value); };\n fn = function (t1, t2) {\n var t1Sum = \"values\" in t1 ? t1.values.reduce(reducer_1, 0) : t1.value;\n var t2Sum = \"values\" in t2 ? t2.values.reduce(reducer_1, 0) : t2.value;\n return isReversed ?\n (orderAsc ? t1Sum - t2Sum : t2Sum - t1Sum) :\n (orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum);\n };\n }\n else if (isFunction(order)) {\n fn = order.bind($$.api);\n }\n return fn || null;\n },\n filterByX: function (targets, x) {\n return mergeArray(targets.map(function (t) { return t.values; })).filter(function (v) { return v.x - x === 0; });\n },\n filterRemoveNull: function (data) {\n var _this = this;\n return data.filter(function (d) { return isValue(_this.getBaseValue(d)); });\n },\n filterByXDomain: function (targets, xDomain) {\n return targets.map(function (t) { return ({\n id: t.id,\n id_org: t.id_org,\n values: t.values.filter(function (v) { return xDomain[0] <= v.x && v.x <= xDomain[1]; })\n }); });\n },\n hasDataLabel: function () {\n var dataLabels = this.config.data_labels;\n return (isboolean(dataLabels) && dataLabels) ||\n (isObjectType(dataLabels) && notEmpty(dataLabels));\n },\n /**\n * Get data index from the event coodinates\n * @param {Event} event Event object\n * @returns {number}\n */\n getDataIndexFromEvent: function (event) {\n var $$ = this;\n var config = $$.config, _a = $$.state, inputType = _a.inputType, _b = _a.eventReceiver, coords = _b.coords, rect = _b.rect;\n var isRotated = config.axis_rotated;\n // get data based on the mouse coords\n var e = inputType === \"touch\" && event.changedTouches ? event.changedTouches[0] : event;\n var index = findIndex(coords, isRotated ? e.clientY - rect.top : e.clientX - rect.left, 0, coords.length - 1, isRotated);\n return index;\n },\n getDataLabelLength: function (min, max, key) {\n var $$ = this;\n var lengths = [0, 0];\n var paddingCoef = 1.3;\n $$.$el.chart.select(\"svg\").selectAll(\".dummy\")\n .data([min, max])\n .enter()\n .append(\"text\")\n .text(function (d) { return $$.dataLabelFormat(d.id)(d); })\n .each(function (d, i) {\n lengths[i] = this.getBoundingClientRect()[key] * paddingCoef;\n })\n .remove();\n return lengths;\n },\n isNoneArc: function (d) {\n return this.hasTarget(this.data.targets, d.id);\n },\n isArc: function (d) {\n return \"data\" in d && this.hasTarget(this.data.targets, d.data.id);\n },\n findSameXOfValues: function (values, index) {\n var targetX = values[index].x;\n var sames = [];\n var i;\n for (i = index - 1; i >= 0; i--) {\n if (targetX !== values[i].x) {\n break;\n }\n sames.push(values[i]);\n }\n for (i = index; i < values.length; i++) {\n if (targetX !== values[i].x) {\n break;\n }\n sames.push(values[i]);\n }\n return sames;\n },\n findClosestFromTargets: function (targets, pos) {\n var $$ = this;\n var candidates = targets.map(function (target) { return $$.findClosest(target.values, pos); }); // map to array of closest points of each target\n // decide closest point and return\n return $$.findClosest(candidates, pos);\n },\n findClosest: function (values, pos) {\n var $$ = this;\n var config = $$.config, main = $$.$el.main;\n var data = values.filter(function (v) { return v && isValue(v.value); });\n var minDist = config.point_sensitivity;\n var closest;\n // find mouseovering bar/candlestick\n // https://github.com/naver/billboard.js/issues/2434\n data\n .filter(function (v) { return $$.isBarType(v.id) || $$.isCandlestickType(v.id); })\n .forEach(function (v) {\n var selector = $$.isBarType(v.id) ?\n \".\".concat($BAR.chartBar, \".\").concat($COMMON.target).concat($$.getTargetSelectorSuffix(v.id), \" .\").concat($BAR.bar, \"-\").concat(v.index) :\n \".\".concat($CANDLESTICK.chartCandlestick, \".\").concat($COMMON.target).concat($$.getTargetSelectorSuffix(v.id), \" .\").concat($CANDLESTICK.candlestick, \"-\").concat(v.index, \" path\");\n if (!closest && $$.isWithinBar(main.select(selector).node())) {\n closest = v;\n }\n });\n // find closest point from non-bar/candlestick\n data\n .filter(function (v) { return !$$.isBarType(v.id) && !$$.isCandlestickType(v.id); })\n .forEach(function (v) {\n var d = $$.dist(v, pos);\n if (d < minDist) {\n minDist = d;\n closest = v;\n }\n });\n return closest;\n },\n dist: function (data, pos) {\n var $$ = this;\n var isRotated = $$.config.axis_rotated, scale = $$.scale;\n var xIndex = isRotated ? 1 : 0;\n var yIndex = isRotated ? 0 : 1;\n var y = $$.circleY(data, data.index);\n var x = (scale.zoom || scale.x)(data.x);\n return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2));\n },\n /**\n * Convert data for step type\n * @param {Array} values Object data values\n * @returns {Array}\n * @private\n */\n convertValuesToStep: function (values) {\n var $$ = this;\n var axis = $$.axis, config = $$.config;\n var stepType = config.line_step_type;\n var isCategorized = axis ? axis.isCategorized() : false;\n var converted = isArray(values) ? values.concat() : [values];\n if (!(isCategorized || /step\\-(after|before)/.test(stepType))) {\n return values;\n }\n // insert & append cloning first/last value to be fully rendered covering on each gap sides\n var head = converted[0];\n var tail = converted[converted.length - 1];\n var id = head.id;\n var x = head.x;\n // insert head\n converted.unshift({ x: --x, value: head.value, id: id });\n isCategorized && stepType === \"step-after\" &&\n converted.unshift({ x: --x, value: head.value, id: id });\n // append tail\n x = tail.x;\n converted.push({ x: ++x, value: tail.value, id: id });\n isCategorized && stepType === \"step-before\" &&\n converted.push({ x: ++x, value: tail.value, id: id });\n return converted;\n },\n convertValuesToRange: function (values) {\n var converted = isArray(values) ? values.concat() : [values];\n var ranges = [];\n converted.forEach(function (range) {\n var x = range.x, id = range.id;\n ranges.push({\n x: x,\n id: id,\n value: range.value[0]\n });\n ranges.push({\n x: x,\n id: id,\n value: range.value[2]\n });\n });\n return ranges;\n },\n updateDataAttributes: function (name, attrs) {\n var $$ = this;\n var config = $$.config;\n var current = config[\"data_\".concat(name)];\n if (isUndefined(attrs)) {\n return current;\n }\n Object.keys(attrs).forEach(function (id) {\n current[id] = attrs[id];\n });\n $$.redraw({ withLegend: true });\n return current;\n },\n getRangedData: function (d, key, type) {\n if (key === void 0) { key = \"\"; }\n if (type === void 0) { type = \"areaRange\"; }\n var value = d === null || d === void 0 ? void 0 : d.value;\n if (isArray(value)) {\n // @ts-ignore\n var index = {\n areaRange: [\"high\", \"mid\", \"low\"],\n candlestick: [\"open\", \"high\", \"low\", \"close\", \"volume\"]\n }[type].indexOf(key);\n return index >= 0 && value ? value[index] : undefined;\n }\n else if (value) {\n return value[key];\n }\n return value;\n },\n /**\n * Set ratio for grouped data\n * @param {Array} data Data array\n * @private\n */\n setRatioForGroupedData: function (data) {\n var $$ = this;\n var config = $$.config;\n // calculate ratio if grouped data exists\n if (config.data_groups.length && data.some(function (d) { return $$.isGrouped(d.id); })) {\n var setter_1 = function (d) { return $$.getRatio(\"index\", d, true); };\n data.forEach(function (v) {\n \"values\" in v ? v.values.forEach(setter_1) : setter_1(v);\n });\n }\n },\n /**\n * Get ratio value\n * @param {string} type Ratio for given type\n * @param {object} d Data value object\n * @param {boolean} asPercent Convert the return as percent or not\n * @returns {number} Ratio value\n * @private\n */\n getRatio: function (type, d, asPercent) {\n if (asPercent === void 0) { asPercent = false; }\n var $$ = this;\n var config = $$.config, state = $$.state;\n var api = $$.api;\n var ratio = 0;\n if (d && api.data.shown().length) {\n ratio = d.ratio || d.value;\n if (type === \"arc\") {\n // if has padAngle set, calculate rate based on value\n if ($$.pie.padAngle()()) {\n ratio = d.value / $$.getTotalDataSum(true);\n // otherwise, based on the rendered angle value\n }\n else {\n var gaugeArcLength = config.gauge_fullCircle ? $$.getArcLength() : $$.getStartAngle() * -2;\n var arcLength = $$.hasType(\"gauge\") ? gaugeArcLength : Math.PI * 2;\n ratio = (d.endAngle - d.startAngle) / arcLength;\n }\n }\n else if (type === \"index\") {\n var dataValues = api.data.values.bind(api);\n var total = this.getTotalPerIndex();\n if (state.hiddenTargetIds.length) {\n var hiddenSum_1 = dataValues(state.hiddenTargetIds, false);\n if (hiddenSum_1.length) {\n hiddenSum_1 = hiddenSum_1\n .reduce(function (acc, curr) { return acc.map(function (v, i) { return (isNumber(v) ? v : 0) + curr[i]; }); });\n total = total.map(function (v, i) { return v - hiddenSum_1[i]; });\n }\n }\n var divisor = total[d.index];\n d.ratio = isNumber(d.value) && total && divisor ?\n d.value / divisor : 0;\n ratio = d.ratio;\n }\n else if (type === \"radar\") {\n ratio = (parseFloat(String(Math.max(d.value, 0))) / state.current.dataMax) * config.radar_size_ratio;\n }\n else if (type === \"bar\") {\n var yScale = $$.getYScaleById.bind($$)(d.id);\n var max = yScale.domain().reduce(function (a, c) { return c - a; });\n // when all data are 0, return 0\n ratio = max === 0 ? 0 : Math.abs(d.value) / max;\n }\n else if (type === \"treemap\") {\n ratio /= $$.getTotalDataSum(true);\n }\n }\n return asPercent && ratio ? ratio * 100 : ratio;\n },\n /**\n * Sort data index to be aligned with x axis.\n * @param {Array} tickValues Tick array values\n * @private\n */\n updateDataIndexByX: function (tickValues) {\n var $$ = this;\n var tickValueMap = tickValues.reduce(function (out, tick, index) {\n out[Number(tick.x)] = index;\n return out;\n }, {});\n $$.data.targets.forEach(function (t) {\n t.values.forEach(function (value, valueIndex) {\n var index = tickValueMap[Number(value.x)];\n if (index === undefined) {\n index = valueIndex;\n }\n value.index = index;\n });\n });\n },\n /**\n * Determine if bubble has dimension data\n * @param {object|Array} d data value\n * @returns {boolean}\n * @private\n */\n isBubbleZType: function (d) {\n var $$ = this;\n return $$.isBubbleType(d) && ((isObject(d.value) && (\"z\" in d.value || \"y\" in d.value)) ||\n (isArray(d.value) && d.value.length >= 2));\n },\n /**\n * Determine if bar has ranged data\n * @param {Array} d data value\n * @returns {boolean}\n * @private\n */\n isBarRangeType: function (d) {\n var $$ = this;\n var value = d.value;\n return $$.isBarType(d) && isArray(value) && value.length >= 2 && value.every(function (v) { return isNumber(v); });\n },\n /**\n * Get data object by id\n * @param {string} id data id\n * @returns {object}\n * @private\n */\n getDataById: function (id) {\n var _a;\n var d = this.cache.get(id) || this.api.data(id);\n return (_a = d === null || d === void 0 ? void 0 : d[0]) !== null && _a !== void 0 ? _a : d;\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar dataLoad = {\n load: function (rawTargets, args) {\n var _a;\n var $$ = this;\n var append = args.append;\n var targets = rawTargets;\n if (targets) {\n // filter loading targets if needed\n if (args.filter) {\n targets = targets.filter(args.filter);\n }\n // set type if args.types || args.type specified\n if (args.type || args.types) {\n targets.forEach(function (t) {\n var _a;\n var type = ((_a = args.types) === null || _a === void 0 ? void 0 : _a[t.id]) || args.type;\n $$.setTargetType(t.id, type);\n });\n }\n // Update/Add data\n $$.data.targets.forEach(function (d) {\n for (var i = 0; i < targets.length; i++) {\n if (d.id === targets[i].id) {\n d.values = append ?\n d.values.concat(targets[i].values) : targets[i].values;\n targets.splice(i, 1);\n break;\n }\n }\n });\n $$.data.targets = $$.data.targets.concat(targets); // add remained\n }\n // Set targets\n $$.updateTargets($$.data.targets);\n // Redraw with new targets\n $$.redraw({\n withUpdateOrgXDomain: true,\n withUpdateXDomain: true,\n withLegend: true\n });\n // Update current state chart type and elements list after redraw\n $$.updateTypesElements();\n (_a = args.done) === null || _a === void 0 ? void 0 : _a.call($$.api);\n },\n loadFromArgs: function (args) {\n var $$ = this;\n // prevent load when chart is already destroyed\n if (!$$.config) {\n return;\n }\n // reset internally cached data\n $$.cache.reset();\n $$.convertData(args, function (d) {\n var data = args.data || d;\n args.append && (data.__append__ = true);\n data && $$.load($$.convertDataToTargets(data), args);\n });\n },\n unload: function (rawTargetIds, customDoneCb) {\n var $$ = this;\n var state = $$.state, $el = $$.$el, $T = $$.$T;\n var done = customDoneCb;\n var targetIds = rawTargetIds;\n // reset internally cached data\n $$.cache.reset();\n if (!done) {\n done = function () { };\n }\n // filter existing target\n targetIds = targetIds.filter(function (id) { return $$.hasTarget($$.data.targets, id); });\n // If no target, call done and return\n if (!targetIds || targetIds.length === 0) {\n done();\n return;\n }\n var targets = $el.svg.selectAll(targetIds.map(function (id) { return $$.selectorTarget(id); }));\n $T(targets)\n .style(\"opacity\", \"0\")\n .remove()\n .call(endall, done);\n targetIds.forEach(function (id) {\n // Reset fadein for future load\n state.withoutFadeIn[id] = false;\n // Remove target's elements\n if ($el.legend) {\n $el.legend.selectAll(\".\".concat($LEGEND.legendItem).concat($$.getTargetSelectorSuffix(id))).remove();\n }\n // Remove target\n $$.data.targets = $$.data.targets.filter(function (t) { return t.id !== id; });\n });\n // since treemap uses different data types, it needs to be transformed\n state.hasTreemap && $$.updateTargetsForTreemap($$.data.targets);\n // Update current state chart type and elements list after redraw\n $$.updateTypesElements();\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar interaction = {\n selectRectForSingle: function (context, eventRect, index) {\n var _a, _b;\n var $$ = this;\n var config = $$.config, _c = $$.$el, main = _c.main, circle = _c.circle;\n var isSelectionEnabled = config.data_selection_enabled;\n var isSelectionGrouped = config.data_selection_grouped;\n var isSelectable = config.data_selection_isselectable;\n var isTooltipGrouped = config.tooltip_grouped;\n var selectedData = $$.getAllValuesOnIndex(index);\n if (isTooltipGrouped) {\n $$.showTooltip(selectedData, context);\n (_a = $$.showGridFocus) === null || _a === void 0 ? void 0 : _a.call($$, selectedData);\n if (!isSelectionEnabled || isSelectionGrouped) {\n return;\n }\n }\n // remove possible previous focused state\n !circle && main.selectAll(\".\".concat($COMMON.EXPANDED, \":not(.\").concat($SHAPE.shape, \"-\").concat(index, \")\")).classed($COMMON.EXPANDED, false);\n var shapeAtIndex = main.selectAll(\".\".concat($SHAPE.shape, \"-\").concat(index))\n .classed($COMMON.EXPANDED, true)\n .style(\"cursor\", isSelectable ? \"pointer\" : null)\n .filter(function (d) {\n return $$.isWithinShape(this, d);\n });\n if (shapeAtIndex.empty() && !isTooltipGrouped) {\n (_b = $$.hideGridFocus) === null || _b === void 0 ? void 0 : _b.call($$);\n $$.hideTooltip();\n !isSelectionGrouped && $$.setExpand(index);\n }\n shapeAtIndex\n .call(function (selected) {\n var _a, _b;\n var d = selected.data();\n if (isSelectionEnabled &&\n (isSelectionGrouped || (isSelectable === null || isSelectable === void 0 ? void 0 : isSelectable.bind($$.api)(d)))) {\n eventRect.style(\"cursor\", \"pointer\");\n }\n if (!isTooltipGrouped) {\n $$.showTooltip(d, context);\n (_a = $$.showGridFocus) === null || _a === void 0 ? void 0 : _a.call($$, d);\n (_b = $$.unexpandCircles) === null || _b === void 0 ? void 0 : _b.call($$);\n selected.each(function (d) { return $$.setExpand(index, d.id); });\n }\n });\n },\n /**\n * Expand data shape/point\n * @param {number} index Index number\n * @param {string} id Data id\n * @param {boolean} reset Reset expand state\n * @private\n */\n setExpand: function (index, id, reset) {\n var $$ = this;\n var config = $$.config, circle = $$.$el.circle;\n circle && config.point_focus_expand_enabled &&\n $$.expandCircles(index, id, reset);\n // bar, candlestick\n $$.expandBarTypeShapes(true, index, id, reset);\n },\n /**\n * Expand/Unexpand bar type shapes\n * @param {boolean} expand Expand or unexpand\n * @param {number} i Shape index\n * @param {string} id Data id\n * @param {boolean} reset Reset expand style\n * @private\n */\n expandBarTypeShapes: function (expand, i, id, reset) {\n if (expand === void 0) { expand = true; }\n var $$ = this;\n [\"bar\", \"candlestick\"]\n .filter(function (v) { return $$.$el[v]; })\n .forEach(function (v) {\n reset && $$.$el[v].classed($COMMON.EXPANDED, false);\n $$.getShapeByIndex(v, i, id).classed($COMMON.EXPANDED, expand);\n });\n },\n /**\n * Handle data.onover/out callback options\n * @param {boolean} isOver Over or not\n * @param {number|object} d data object\n * @private\n */\n setOverOut: function (isOver, d) {\n var $$ = this;\n var config = $$.config, _a = $$.state, hasRadar = _a.hasRadar, hasTreemap = _a.hasTreemap, main = $$.$el.main;\n var isArcTreemap = isObject(d);\n // Call event handler\n if (isArcTreemap || d !== -1) {\n var callback_1 = config[isOver ? \"data_onover\" : \"data_onout\"].bind($$.api);\n config.color_onover && $$.setOverColor(isOver, d, isArcTreemap);\n if (isArcTreemap && \"id\") {\n var selector = hasTreemap ? $TREEMAP.treemap : $ARC.arc;\n callback_1(d, main.select(\".\".concat(selector).concat($$.getTargetSelectorSuffix(d.id))).node());\n }\n else if (!config.tooltip_grouped) {\n var last_1 = $$.cache.get(KEY.setOverOut) || [];\n // select based on the index\n var shapesAtIndex = main.selectAll(\".\".concat($SHAPE.shape, \"-\").concat(d))\n .filter(function (d) {\n return $$.isWithinShape(this, d);\n });\n // filter if has new selection\n var shape = shapesAtIndex.filter(function () {\n var _this = this;\n return last_1.every(function (v) { return v !== _this; });\n });\n // call onout callback\n if (!isOver || shapesAtIndex.empty() || (last_1.length === shape.size() && shape.nodes().every((function (v, i) { return v !== last_1[i]; })))) {\n while (last_1.length) {\n var target = last_1.pop();\n config.data_onout.bind($$.api)(select(target).datum(), target);\n }\n }\n // call onover callback\n shape.each(function () {\n if (isOver) {\n callback_1(select(this).datum(), this);\n last_1.push(this);\n }\n });\n $$.cache.add(KEY.setOverOut, last_1);\n }\n else {\n if (isOver) {\n config.point_focus_only && hasRadar ?\n $$.showCircleFocus($$.getAllValuesOnIndex(d, true)) :\n $$.setExpand(d, null, true);\n }\n !$$.isMultipleX() && main.selectAll(\".\".concat($SHAPE.shape, \"-\").concat(d))\n .each(function (d) {\n callback_1(d, this);\n });\n }\n }\n },\n /**\n * Call data.onover/out callback for touch event\n * @param {number|object} d target index or data object for Arc type\n * @private\n */\n callOverOutForTouch: function (d) {\n var $$ = this;\n var last = $$.cache.get(KEY.callOverOutForTouch);\n if (isObject(d) && last ? d.id !== last.id : (d !== last)) {\n (last || isNumber(last)) && $$.setOverOut(false, last);\n (d || isNumber(d)) && $$.setOverOut(true, d);\n $$.cache.add(KEY.callOverOutForTouch, d);\n }\n },\n /**\n * Return draggable selection function\n * @returns {Function}\n * @private\n */\n getDraggableSelection: function () {\n var $$ = this;\n var config = $$.config, state = $$.state;\n return config.interaction_enabled && config.data_selection_draggable && $$.drag ?\n drag$1()\n .on(\"drag\", function (event) {\n state.event = event;\n $$.drag(getPointer(event, this));\n })\n .on(\"start\", function (event) {\n state.event = event;\n $$.dragstart(getPointer(event, this));\n })\n .on(\"end\", function (event) {\n state.event = event;\n $$.dragend();\n }) : function () { };\n },\n /**\n * Dispatch a mouse event.\n * @private\n * @param {string} type event type\n * @param {number} index Index of eventRect\n * @param {Array} mouse x and y coordinate value\n */\n dispatchEvent: function (type, index, mouse) {\n var _a;\n var $$ = this;\n var config = $$.config, _b = $$.state, eventReceiver = _b.eventReceiver, hasAxis = _b.hasAxis, hasRadar = _b.hasRadar, hasTreemap = _b.hasTreemap, _c = $$.$el, eventRect = _c.eventRect, arcs = _c.arcs, radar = _c.radar, treemap = _c.treemap;\n var element = (_a = ((hasTreemap && eventReceiver.rect) ||\n (hasRadar && radar.axes.select(\".\".concat($AXIS.axis, \"-\").concat(index, \" text\"))) || (eventRect || (arcs === null || arcs === void 0 ? void 0 : arcs.selectAll(\".\".concat($COMMON.target, \" path\")).filter(function (d, i) { return i === index; }))))) === null || _a === void 0 ? void 0 : _a.node();\n if (element) {\n var isMultipleX = $$.isMultipleX();\n var _d = element.getBoundingClientRect(), width = _d.width, left = _d.left, top_1 = _d.top;\n if (hasAxis && !hasRadar && !isMultipleX) {\n var coords = eventReceiver.coords[index];\n width = coords.w;\n left += coords.x;\n top_1 += coords.y;\n }\n var x = left + (mouse ? mouse[0] : 0) + (isMultipleX || config.axis_rotated ? 0 : (width / 2));\n var y = top_1 + (mouse ? mouse[1] : 0);\n var params = {\n screenX: x,\n screenY: y,\n clientX: x,\n clientY: y\n };\n emulateEvent[/^(mouse|click)/.test(type) ? \"mouse\" : \"touch\"](hasTreemap ? treemap.node() : element, type, params);\n }\n },\n setDragStatus: function (isDragging) {\n this.state.dragging = isDragging;\n },\n /**\n * Unbind zoom events\n * @private\n */\n unbindZoomEvent: function () {\n var $$ = this;\n var _a = $$.$el, eventRect = _a.eventRect, zoomResetBtn = _a.zoomResetBtn;\n eventRect === null || eventRect === void 0 ? void 0 : eventRect.on(\".zoom wheel.zoom .drag\", null);\n zoomResetBtn === null || zoomResetBtn === void 0 ? void 0 : zoomResetBtn.on(\"click\", null).style(\"display\", \"none\");\n },\n /**\n * Unbind all attached events\n * @private\n */\n unbindAllEvents: function () {\n var _a;\n var $$ = this;\n var _b = $$.$el, arcs = _b.arcs, eventRect = _b.eventRect, legend = _b.legend, region = _b.region, svg = _b.svg, treemap = _b.treemap, brush = $$.brush;\n var list = [\n \"wheel\",\n \"click\",\n \"mouseover\",\n \"mousemove\",\n \"mouseout\",\n \"touchstart\",\n \"touchmove\",\n \"touchend\",\n \"touchstart.eventRect\",\n \"touchmove.eventRect\",\n \"touchend.eventRect\",\n \".brush\",\n \".drag\",\n \".zoom\",\n \"wheel.zoom\",\n \"dblclick.zoom\"\n ].join(\" \");\n // detach all possible event types\n [svg, eventRect, region === null || region === void 0 ? void 0 : region.list, brush === null || brush === void 0 ? void 0 : brush.getSelection(), arcs === null || arcs === void 0 ? void 0 : arcs.selectAll(\"path\"), legend === null || legend === void 0 ? void 0 : legend.selectAll(\"g\"), treemap]\n .forEach(function (v) { return v === null || v === void 0 ? void 0 : v.on(list, null); });\n (_a = $$.unbindZoomEvent) === null || _a === void 0 ? void 0 : _a.call($$);\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar classModule = {\n generateClass: function (prefix, targetId) {\n return \" \".concat(prefix, \" \").concat(prefix + this.getTargetSelectorSuffix(targetId));\n },\n /**\n * Get class string\n * @param {string} type Shape type\n * @param {boolean} withShape Get with shape prefix\n * @returns {string} Class string\n * @private\n */\n getClass: function (type, withShape) {\n var _this = this;\n var isPlural = /s$/.test(type);\n var useIdKey = /^(area|arc|line|treemap)s?$/.test(type);\n var key = isPlural ? \"id\" : \"index\";\n return function (d) {\n var data = d.data || d;\n var result = (withShape ? _this.generateClass(CLASS[isPlural ? \"shapes\" : \"shape\"], data[key]) : \"\") + _this.generateClass(CLASS[type], data[useIdKey ? \"id\" : key]);\n return result.trim();\n };\n },\n /**\n * Get chart class string\n * @param {string} type Shape type\n * @returns {string} Class string\n * @private\n */\n getChartClass: function (type) {\n var _this = this;\n return function (d) { return CLASS[\"chart\".concat(type)] + _this.classTarget((d.data ? d.data : d).id); };\n },\n generateExtraLineClass: function () {\n var $$ = this;\n var classes = $$.config.line_classes || [];\n var ids = [];\n return function (d) {\n var _a;\n var id = d.id || ((_a = d.data) === null || _a === void 0 ? void 0 : _a.id) || d;\n if (ids.indexOf(id) < 0) {\n ids.push(id);\n }\n return classes[ids.indexOf(id) % classes.length];\n };\n },\n classRegion: function (d, i) {\n return \"\".concat(this.generateClass(CLASS.region, i), \" \").concat(\"class\" in d ? d[\"class\"] : \"\");\n },\n classTarget: function (id) {\n var additionalClassSuffix = this.config.data_classes[id];\n var additionalClass = \"\";\n if (additionalClassSuffix) {\n additionalClass = \" \".concat(CLASS.target, \"-\").concat(additionalClassSuffix);\n }\n return this.generateClass(CLASS.target, id) + additionalClass;\n },\n classFocus: function (d) {\n return this.classFocused(d) + this.classDefocused(d);\n },\n classFocused: function (d) {\n return \" \".concat(this.state.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : \"\");\n },\n classDefocused: function (d) {\n return \" \".concat(this.state.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : \"\");\n },\n getTargetSelectorSuffix: function (targetId) {\n var targetStr = targetId || targetId === 0 ? \"-\".concat(targetId) : \"\";\n return targetStr.replace(/([\\s?!@#$%^&*()_=+,.<>'\":;\\[\\]\\/|~`{}\\\\])/g, \"-\");\n },\n selectorTarget: function (id, prefix, postfix) {\n if (prefix === void 0) { prefix = \"\"; }\n if (postfix === void 0) { postfix = \"\"; }\n var target = this.getTargetSelectorSuffix(id);\n // select target & circle\n return \"\".concat(prefix, \".\").concat(CLASS.target + target, \" \").concat(postfix, \", \").concat(prefix, \".\").concat(CLASS.circles + target, \" \").concat(postfix);\n },\n selectorTargets: function (idsValue, prefix) {\n var _this = this;\n var ids = idsValue || [];\n return ids.length ?\n ids.map(function (id) { return _this.selectorTarget(id, prefix); }) : null;\n },\n selectorLegend: function (id) {\n return \".\".concat(CLASS.legendItem + this.getTargetSelectorSuffix(id));\n },\n selectorLegends: function (ids) {\n var _this = this;\n return (ids === null || ids === void 0 ? void 0 : ids.length) ?\n ids.map(function (id) { return _this.selectorLegend(id); }) : null;\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar category = {\n /**\n * Category Name\n * @param {number} i Index number\n * @returns {string} category Name\n * @private\n */\n categoryName: function (i) {\n var categories = this.config.axis_x_categories;\n return i < (categories === null || categories === void 0 ? void 0 : categories.length) ? categories[i] : i;\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Set pattern's background color\n * (it adds a element to simulate bg-color)\n * @param {SVGPatternElement} pattern SVG pattern element\n * @param {string} color Color string\n * @param {string} id ID to be set\n * @returns {{id: string, node: SVGPatternElement}}\n * @private\n */\nvar colorizePattern = function (pattern, color, id) {\n var node = select(pattern.cloneNode(true));\n node\n .attr(\"id\", id)\n .insert(\"rect\", \":first-child\")\n .attr(\"width\", node.attr(\"width\"))\n .attr(\"height\", node.attr(\"height\"))\n .style(\"fill\", color);\n return {\n id: id,\n node: node.node()\n };\n};\n/**\n * Get color pattern from CSS file\n * CSS should be defined as: background-image: url(\"#00c73c;#fa7171; ...\");\n * @param {d3Selection} element Chart element\n * @returns {Array}\n * @private\n */\nfunction getColorFromCss(element) {\n var cacheKey = KEY.colorPattern;\n var body = doc.body;\n var pattern = body[cacheKey];\n if (!pattern) {\n var delimiter = \";\";\n var content = element\n .classed($COLOR.colorPattern, true)\n .style(\"background-image\");\n element.classed($COLOR.colorPattern, false);\n if (content.indexOf(delimiter) > -1) {\n pattern = content\n .replace(/url[^#]*|[\"'()]|(\\s|%20)/g, \"\")\n .split(delimiter)\n .map(function (v) { return v.trim().replace(/[\\\"'\\s]/g, \"\"); })\n .filter(Boolean);\n body[cacheKey] = pattern;\n }\n }\n return pattern;\n}\n// Replacement of d3.schemeCategory10.\n// Contained differently depend on d3 version: v4(d3-scale), v5(d3-scale-chromatic)\nvar schemeCategory10 = [\"#1f77b4\", \"#ff7f0e\", \"#2ca02c\", \"#d62728\", \"#9467bd\", \"#8c564b\", \"#e377c2\", \"#7f7f7f\", \"#bcbd22\", \"#17becf\"];\nvar color = {\n generateColor: function () {\n var $$ = this;\n var $el = $$.$el, config = $$.config;\n var colors = config.data_colors;\n var callback = config.data_color;\n var ids = [];\n var pattern = notEmpty(config.color_pattern) ? config.color_pattern :\n scaleOrdinal(getColorFromCss($el.chart) || schemeCategory10).range();\n var originalColorPattern = pattern;\n if (isFunction(config.color_tiles)) {\n var tiles_1 = config.color_tiles.bind($$.api)();\n // Add background color to patterns\n var colorizedPatterns = pattern.map(function (p, index) {\n var color = p.replace(/[#\\(\\)\\s,]/g, \"\");\n var id = \"\".concat($$.state.datetimeId, \"-pattern-\").concat(color, \"-\").concat(index);\n return colorizePattern(tiles_1[index % tiles_1.length], p, id);\n });\n pattern = colorizedPatterns.map(function (p) { return \"url(#\".concat(p.id, \")\"); });\n $$.patterns = colorizedPatterns;\n }\n return function (d) {\n var _a;\n var id = d.id ||\n ((_a = d.data) === null || _a === void 0 ? void 0 : _a.id) ||\n d;\n var isLine = $$.isTypeOf(id, [\"line\", \"spline\", \"step\"]) || !config.data_types[id];\n var color;\n // if callback function is provided\n if (isFunction(colors[id])) {\n color = colors[id].bind($$.api)(d);\n // if specified, choose that color\n }\n else if (colors[id]) {\n color = colors[id];\n // if not specified, choose from pattern\n }\n else {\n if (ids.indexOf(id) < 0) {\n ids.push(id);\n }\n color = isLine ? originalColorPattern[ids.indexOf(id) % originalColorPattern.length] :\n pattern[ids.indexOf(id) % pattern.length];\n colors[id] = color;\n }\n return isFunction(callback) ?\n callback.bind($$.api)(color, d) : color;\n };\n },\n generateLevelColor: function () {\n var $$ = this;\n var config = $$.config;\n var colors = config.color_pattern;\n var threshold = config.color_threshold;\n var asValue = threshold.unit === \"value\";\n var max = threshold.max || 100;\n var values = threshold.values &&\n threshold.values.length ? threshold.values : [];\n return notEmpty(threshold) ? function (value) {\n var v = asValue ? value : (value * 100 / max);\n var color = colors[colors.length - 1];\n for (var i = 0, l = values.length; i < l; i++) {\n if (v <= values[i]) {\n color = colors[i];\n break;\n }\n }\n return color;\n } : null;\n },\n /**\n * Append data backgound color filter definition\n * @param {string} color Color string\n * @private\n */\n generateDataLabelBackgroundColorFilter: function (color) {\n var $$ = this;\n var $el = $$.$el, config = $$.config, state = $$.state;\n var backgroundColors = color || config.data_labels_backgroundColors;\n if (backgroundColors) {\n var ids = [];\n if (isString(backgroundColors)) {\n ids.push(\"\");\n }\n else if (isObject(backgroundColors)) {\n ids = Object.keys(backgroundColors);\n }\n ids.forEach(function (v) {\n var id = \"\".concat(state.datetimeId, \"-labels-bg\").concat($$.getTargetSelectorSuffix(v)).concat(color ? $$.getTargetSelectorSuffix(color) : \"\");\n $el.defs.append(\"filter\")\n .attr(\"x\", \"0\")\n .attr(\"y\", \"0\")\n .attr(\"width\", \"1\")\n .attr(\"height\", \"1\")\n .attr(\"id\", id)\n .html(\"\"));\n });\n }\n },\n /**\n * Get data gradient color url\n * @param {string} id Data id\n * @returns {string}\n * @private\n */\n getGradienColortUrl: function (id) {\n return \"url(#\".concat(this.state.datetimeId, \"-gradient\").concat(this.getTargetSelectorSuffix(id), \")\");\n },\n /**\n * Update linear gradient definition (for area & bar only)\n * @private\n */\n updateLinearGradient: function () {\n var $$ = this;\n var config = $$.config, targets = $$.data.targets, datetimeId = $$.state.datetimeId, defs = $$.$el.defs;\n targets.forEach(function (d) {\n var id = \"\".concat(datetimeId, \"-gradient\").concat($$.getTargetSelectorSuffix(d.id));\n var supportedType = ($$.isAreaType(d) && \"area\") || ($$.isBarType(d) && \"bar\");\n var isRotated = config.axis_rotated;\n if (supportedType && defs.select(\"#\".concat(id)).empty()) {\n var color_1 = $$.color(d);\n var _a = config[\"\".concat(supportedType, \"_linearGradient\")], _b = _a.x, x = _b === void 0 ? isRotated ? [1, 0] : [0, 0] : _b, _c = _a.y, y = _c === void 0 ? isRotated ? [0, 0] : [0, 1] : _c, _d = _a.stops, stops = _d === void 0 ? [[0, color_1, 1], [1, color_1, 0]] : _d;\n var linearGradient_1 = defs.append(\"linearGradient\")\n .attr(\"id\", \"\".concat(id))\n .attr(\"x1\", x[0])\n .attr(\"x2\", x[1])\n .attr(\"y1\", y[0])\n .attr(\"y2\", y[1]);\n stops.forEach(function (v) {\n var stopColor = isFunction(v[1]) ? v[1].bind($$.api)(d.id) : v[1];\n linearGradient_1.append(\"stop\")\n .attr(\"offset\", v[0])\n .attr(\"stop-color\", stopColor || color_1)\n .attr(\"stop-opacity\", v[2]);\n });\n }\n });\n },\n /**\n * Set the data over color.\n * When is out, will restate in its previous color value\n * @param {boolean} isOver true: set overed color, false: restore\n * @param {number|object} d target index or data object for Arc type\n * @private\n */\n setOverColor: function (isOver, d) {\n var $$ = this;\n var config = $$.config, main = $$.$el.main;\n var onover = config.color_onover;\n var color = isOver ? onover : $$.color;\n if (isObject(color)) {\n color = function (_a) {\n var id = _a.id;\n return (id in onover ? onover[id] : $$.color(id));\n };\n }\n else if (isString(color)) {\n color = function () { return onover; };\n }\n else if (isFunction(onover)) {\n color = color.bind($$.api);\n }\n main.selectAll(isObject(d) ?\n // when is Arc type\n \".\".concat($ARC.arc).concat($$.getTargetSelectorSuffix(d.id)) :\n \".\".concat($SHAPE.shape, \"-\").concat(d)).style(\"fill\", color);\n }\n};\n\nvar domain = {\n getYDomainMinMax: function (targets, type) {\n var $$ = this;\n var axis = $$.axis, config = $$.config;\n var isMin = type === \"min\";\n var dataGroups = config.data_groups;\n var ids = $$.mapToIds(targets);\n var ys = $$.getValuesAsIdKeyed(targets);\n if (dataGroups.length > 0) {\n var hasValue_1 = $$[\"has\".concat(isMin ? \"Negative\" : \"Positive\", \"ValueInTargets\")](targets);\n dataGroups.forEach(function (groupIds) {\n // Determine baseId\n var idsInGroup = groupIds\n .filter(function (v) { return ids.indexOf(v) >= 0; });\n if (idsInGroup.length) {\n var baseId_1 = idsInGroup[0];\n var baseAxisId_1 = axis.getId(baseId_1);\n // Initialize base value. Set to 0 if not match with the condition\n if (hasValue_1 && ys[baseId_1]) {\n ys[baseId_1] = ys[baseId_1]\n .map(function (v) { return ((isMin ? v < 0 : v > 0) ? v : 0); });\n }\n idsInGroup\n .filter(function (v, i) { return i > 0; })\n .forEach(function (id) {\n if (ys[id]) {\n var axisId_1 = axis.getId(id);\n ys[id].forEach(function (v, i) {\n var val = +v;\n var meetCondition = isMin ? val > 0 : val < 0;\n if (axisId_1 === baseAxisId_1 && !(hasValue_1 && meetCondition)) {\n ys[baseId_1][i] += val;\n }\n });\n }\n });\n }\n });\n }\n return getMinMax$1(type, Object.keys(ys).map(function (key) { return getMinMax$1(type, ys[key]); }));\n },\n /**\n * Check if hidden targets bound to the given axis id\n * @param {string} id ID to be checked\n * @returns {boolean}\n * @private\n */\n isHiddenTargetWithYDomain: function (id) {\n var $$ = this;\n return $$.state.hiddenTargetIds\n .some(function (v) { return $$.axis.getId(v) === id; });\n },\n getYDomain: function (targets, axisId, xDomain) {\n var $$ = this;\n var axis = $$.axis, config = $$.config, scale = $$.scale;\n var pfx = \"axis_\".concat(axisId);\n if ($$.isStackNormalized()) {\n return [0, 100];\n }\n var isLog = (scale === null || scale === void 0 ? void 0 : scale[axisId]) && scale[axisId].type === \"log\";\n var targetsByAxisId = targets.filter(function (t) { return axis.getId(t.id) === axisId; });\n var yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId;\n if (yTargets.length === 0) { // use domain of the other axis if target of axisId is none\n if ($$.isHiddenTargetWithYDomain(axisId)) {\n return scale[axisId].domain();\n }\n else {\n return axisId === \"y2\" ?\n scale.y.domain() :\n // When all data bounds to y2, y Axis domain is called prior y2.\n // So, it needs to call to get y2 domain here\n $$.getYDomain(targets, \"y2\", xDomain);\n }\n }\n var yMin = config[\"\".concat(pfx, \"_min\")];\n var yMax = config[\"\".concat(pfx, \"_max\")];\n var center = config[\"\".concat(pfx, \"_center\")];\n var isInverted = config[\"\".concat(pfx, \"_inverted\")];\n var showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated;\n var showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;\n var yDomainMin = $$.getYDomainMinMax(yTargets, \"min\");\n var yDomainMax = $$.getYDomainMinMax(yTargets, \"max\");\n var isZeroBased = __spreadArray([TYPE.BAR, TYPE.BUBBLE, TYPE.SCATTER], TYPE_BY_CATEGORY.Line, true).some(function (v) {\n var type = v.indexOf(\"area\") > -1 ? \"area\" : v;\n return $$.hasType(v, yTargets, true) && config[\"\".concat(type, \"_zerobased\")];\n });\n // MEMO: avoid inverting domain unexpectedly\n yDomainMin = isValue(yMin) ? yMin : (isValue(yMax) ? (yDomainMin <= yMax ? yDomainMin : yMax - 10) : yDomainMin);\n yDomainMax = isValue(yMax) ? yMax : (isValue(yMin) ? (yMin <= yDomainMax ? yDomainMax : yMin + 10) : yDomainMax);\n if (isNaN(yDomainMin)) { // set minimum to zero when not number\n yDomainMin = 0;\n }\n if (isNaN(yDomainMax)) { // set maximum to have same value as yDomainMin\n yDomainMax = yDomainMin;\n }\n if (yDomainMin === yDomainMax) {\n yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0;\n }\n var isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;\n var isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;\n // Cancel zerobased if axis_*_min / axis_*_max specified\n if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) {\n isZeroBased = false;\n }\n // Bar/Area chart should be 0-based if all positive|negative\n if (isZeroBased) {\n isAllPositive && (yDomainMin = 0);\n isAllNegative && (yDomainMax = 0);\n }\n var domainLength = Math.abs(yDomainMax - yDomainMin);\n var padding = { top: domainLength * 0.1, bottom: domainLength * 0.1 };\n if (isDefined(center)) {\n var yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));\n yDomainMax = center + yDomainAbs;\n yDomainMin = center - yDomainAbs;\n }\n // add padding for data label\n if (showHorizontalDataLabel) {\n var diff_1 = diffDomain(scale.y.range());\n var ratio_1 = $$.getDataLabelLength(yDomainMin, yDomainMax, \"width\")\n .map(function (v) { return v / diff_1; });\n [\"bottom\", \"top\"].forEach(function (v, i) {\n padding[v] += domainLength * (ratio_1[i] / (1 - ratio_1[0] - ratio_1[1]));\n });\n }\n else if (showVerticalDataLabel) {\n var lengths_1 = $$.getDataLabelLength(yDomainMin, yDomainMax, \"height\");\n [\"bottom\", \"top\"].forEach(function (v, i) {\n padding[v] += $$.convertPixelToScale(\"y\", lengths_1[i], domainLength);\n });\n }\n padding = $$.getResettedPadding(padding);\n // if padding is set, the domain will be updated relative the current domain value\n // ex) $$.height=300, padding.top=150, domainLength=4 --> domain=6\n var p = config[\"\".concat(pfx, \"_padding\")];\n if (notEmpty(p)) {\n [\"bottom\", \"top\"].forEach(function (v) {\n padding[v] = axis.getPadding(p, v, padding[v], domainLength);\n });\n }\n // Bar/Area chart should be 0-based if all positive|negative\n if (isZeroBased) {\n isAllPositive && (padding.bottom = yDomainMin);\n isAllNegative && (padding.top = -yDomainMax);\n }\n var domain = isLog ? [yDomainMin, yDomainMax].map(function (v) { return (v < 0 ? 0 : v); }) :\n [yDomainMin - padding.bottom, yDomainMax + padding.top];\n return isInverted ? domain.reverse() : domain;\n },\n getXDomainMinMax: function (targets, type) {\n var _a;\n var $$ = this;\n var configValue = $$.config[\"axis_x_\".concat(type)];\n var dataValue = getMinMax$1(type, targets.map(function (t) { return getMinMax$1(type, t.values.map(function (v) { return v.x; })); }));\n var value = isObject(configValue) ? configValue.value : configValue;\n value = isDefined(value) && ((_a = $$.axis) === null || _a === void 0 ? void 0 : _a.isTimeSeries()) ? parseDate.bind(this)(value) : value;\n if (isObject(configValue) && configValue.fit && ((type === \"min\" && value < dataValue) || (type === \"max\" && value > dataValue))) {\n value = undefined;\n }\n return isDefined(value) ? value : dataValue;\n },\n /**\n * Get x Axis padding\n * @param {Array} domain x Axis domain\n * @param {number} tickCount Tick count\n * @returns {object} Padding object values with 'left' & 'right' key\n * @private\n */\n getXDomainPadding: function (domain, tickCount) {\n var $$ = this;\n var axis = $$.axis, config = $$.config;\n var padding = config.axis_x_padding;\n var isTimeSeriesTickCount = axis.isTimeSeries() && tickCount;\n var diff = diffDomain(domain);\n var defaultValue;\n // determine default padding value\n if (axis.isCategorized() || isTimeSeriesTickCount) {\n defaultValue = 0;\n }\n else if ($$.hasType(\"bar\")) {\n var maxDataCount = $$.getMaxDataCount();\n defaultValue = maxDataCount > 1 ? (diff / (maxDataCount - 1)) / 2 : 0.5;\n }\n else {\n defaultValue = $$.getResettedPadding(diff * 0.01);\n }\n var _a = isNumber(padding) ?\n { left: padding, right: padding } : padding, _b = _a.left, left = _b === void 0 ? defaultValue : _b, _c = _a.right, right = _c === void 0 ? defaultValue : _c;\n // when the unit is pixel, convert pixels to axis scale value\n if (padding.unit === \"px\") {\n var domainLength = Math.abs(diff + (diff * 0.2));\n left = axis.getPadding(padding, \"left\", defaultValue, domainLength);\n right = axis.getPadding(padding, \"right\", defaultValue, domainLength);\n }\n else {\n var range = diff + left + right;\n if (isTimeSeriesTickCount && range) {\n var relativeTickWidth = (diff / tickCount) / range;\n left = left / range / relativeTickWidth;\n right = right / range / relativeTickWidth;\n }\n }\n return { left: left, right: right };\n },\n /**\n * Get x Axis domain\n * @param {Array} targets targets\n * @returns {Array} x Axis domain\n * @private\n */\n getXDomain: function (targets) {\n var $$ = this;\n var axis = $$.axis, x = $$.scale.x;\n var domain = [\n $$.getXDomainMinMax(targets, \"min\"),\n $$.getXDomainMinMax(targets, \"max\")\n ];\n var _a = domain[0], min = _a === void 0 ? 0 : _a, _b = domain[1], max = _b === void 0 ? 0 : _b;\n if (x.type !== \"log\") {\n var isCategorized = axis.isCategorized();\n var isTimeSeries = axis.isTimeSeries();\n var padding = $$.getXDomainPadding(domain);\n var firstX = domain[0], lastX = domain[1];\n // show center of x domain if min and max are the same\n if ((firstX - lastX) === 0 && !isCategorized) {\n if (isTimeSeries) {\n firstX = new Date(firstX.getTime() * 0.5);\n lastX = new Date(lastX.getTime() * 1.5);\n }\n else {\n firstX = firstX === 0 ? 1 : (firstX * 0.5);\n lastX = lastX === 0 ? -1 : (lastX * 1.5);\n }\n }\n if (firstX || firstX === 0) {\n min = isTimeSeries ? new Date(firstX.getTime() - padding.left) : firstX - padding.left;\n }\n if (lastX || lastX === 0) {\n max = isTimeSeries ? new Date(lastX.getTime() + padding.right) : lastX + padding.right;\n }\n }\n return [min, max];\n },\n updateXDomain: function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {\n var _a;\n var $$ = this;\n var config = $$.config, org = $$.org, _b = $$.scale, x = _b.x, subX = _b.subX;\n var zoomEnabled = config.zoom_enabled;\n if (withUpdateOrgXDomain) {\n x.domain(domain || sortValue($$.getXDomain(targets)));\n org.xDomain = x.domain();\n zoomEnabled && $$.zoom.updateScaleExtent();\n subX.domain(x.domain());\n (_a = $$.brush) === null || _a === void 0 ? void 0 : _a.scale(subX);\n }\n if (withUpdateXDomain) {\n var domainValue = domain || (!$$.brush || brushEmpty($$)) ?\n org.xDomain : getBrushSelection($$).map(subX.invert);\n x.domain(domainValue);\n zoomEnabled && $$.zoom.updateScaleExtent();\n }\n // Trim domain when too big by zoom mousemove event\n withTrim && x.domain($$.trimXDomain(x.orgDomain()));\n return x.domain();\n },\n trimXDomain: function (domain) {\n var zoomDomain = this.getZoomDomain();\n var min = zoomDomain[0], max = zoomDomain[1];\n if (domain[0] <= min) {\n domain[1] = +domain[1] + (min - domain[0]);\n domain[0] = min;\n }\n if (max <= domain[1]) {\n domain[0] = +domain[0] - (domain[1] - max);\n domain[1] = max;\n }\n return domain;\n },\n /**\n * Get zoom domain\n * @returns {Array} zoom domain\n * @private\n */\n getZoomDomain: function () {\n var $$ = this;\n var config = $$.config, org = $$.org;\n var _a = org.xDomain, min = _a[0], max = _a[1];\n if (isDefined(config.zoom_x_min)) {\n min = getMinMax$1(\"min\", [min, config.zoom_x_min]);\n }\n if (isDefined(config.zoom_x_max)) {\n max = getMinMax$1(\"max\", [max, config.zoom_x_max]);\n }\n return [min, max];\n },\n /**\n * Converts pixels to axis' scale values\n * @param {string} type Axis type\n * @param {number} pixels Pixels\n * @param {number} domainLength Domain length\n * @returns {number}\n * @private\n */\n convertPixelToScale: function (type, pixels, domainLength) {\n var $$ = this;\n var config = $$.config, state = $$.state;\n var isRotated = config.axis_rotated;\n var length;\n if (type === \"x\") {\n length = isRotated ? \"height\" : \"width\";\n }\n else {\n length = isRotated ? \"width\" : \"height\";\n }\n return domainLength * (pixels / state[length]);\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Get formatted\n * @param {object} $$ Context\n * @param {string} typeValue Axis type\n * @param {number} v Value to be formatted\n * @returns {number | string}\n * @private\n */\nfunction getFormat($$, typeValue, v) {\n var config = $$.config;\n var type = \"axis_\".concat(typeValue, \"_tick_format\");\n var format = config[type] ?\n config[type] : $$.defaultValueFormat;\n return format.call($$.api, v);\n}\nvar format = {\n yFormat: function (v) {\n return getFormat(this, \"y\", v);\n },\n y2Format: function (v) {\n return getFormat(this, \"y2\", v);\n },\n /**\n * Get default value format function\n * @returns {Function} formatter function\n * @private\n */\n getDefaultValueFormat: function () {\n var $$ = this;\n var defaultArcValueFormat = $$.defaultArcValueFormat, yFormat = $$.yFormat, y2Format = $$.y2Format;\n var hasArc = $$.hasArcType(null, [\"gauge\", \"polar\", \"radar\"]);\n return function (v, ratio, id) {\n var format = hasArc ? defaultArcValueFormat : ($$.axis && $$.axis.getId(id) === \"y2\" ? y2Format : yFormat);\n return format.call($$, v, ratio);\n };\n },\n defaultValueFormat: function (v) {\n return isValue(v) ? +v : \"\";\n },\n defaultArcValueFormat: function (v, ratio) {\n return \"\".concat((ratio * 100).toFixed(1), \"%\");\n },\n defaultPolarValueFormat: function (v) {\n return \"\".concat(v);\n },\n dataLabelFormat: function (targetId) {\n var $$ = this;\n var dataLabels = $$.config.data_labels;\n var defaultFormat = function (v) { return (isValue(v) ? +v : \"\"); };\n var format = defaultFormat;\n // find format according to axis id\n if (isFunction(dataLabels.format)) {\n format = dataLabels.format;\n }\n else if (isObjectType(dataLabels.format)) {\n if (dataLabels.format[targetId]) {\n format = dataLabels.format[targetId] === true ?\n defaultFormat : dataLabels.format[targetId];\n }\n else {\n format = function () { return \"\"; };\n }\n }\n return format.bind($$.api);\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Get color string for given data id\n * @param {string} id Data id\n * @returns {string} Color string\n * @private\n */\nfunction getLegendColor(id) {\n var $$ = this;\n var data = $$.getDataById(id);\n var color = $$.levelColor ?\n $$.levelColor(data.values[0].value) :\n $$.color(data);\n return color;\n}\nvar legend$1 = {\n /**\n * Initialize the legend.\n * @private\n */\n initLegend: function () {\n var $$ = this;\n var config = $$.config, $el = $$.$el;\n $$.legendItemTextBox = {};\n $$.state.legendHasRendered = false;\n if (config.legend_show) {\n if (!config.legend_contents_bindto) {\n $el.legend = $$.$el.svg.append(\"g\")\n .classed($LEGEND.legend, true)\n .attr(\"transform\", $$.getTranslate(\"legend\"));\n }\n // MEMO: call here to update legend box and translate for all\n // MEMO: translate will be updated by this, so transform not needed in updateLegend()\n $$.updateLegend();\n }\n else {\n $$.state.hiddenLegendIds = $$.mapToIds($$.data.targets);\n }\n },\n /**\n * Update legend element\n * @param {Array} targetIds ID's of target\n * @param {object} options withTransform : Whether to use the transform property / withTransitionForTransform: Whether transition is used when using the transform property / withTransition : whether or not to transition.\n * @param {object} transitions Return value of the generateTransitions\n * @private\n */\n updateLegend: function (targetIds, options, transitions) {\n var _a;\n var $$ = this;\n var config = $$.config, state = $$.state, scale = $$.scale, $el = $$.$el;\n var optionz = options || {\n withTransform: false,\n withTransitionForTransform: false,\n withTransition: false\n };\n optionz.withTransition = getOption(optionz, \"withTransition\", true);\n optionz.withTransitionForTransform = getOption(optionz, \"withTransitionForTransform\", true);\n if (config.legend_contents_bindto && config.legend_contents_template) {\n $$.updateLegendTemplate();\n }\n else if (!state.hasTreemap) {\n $$.updateLegendElement(targetIds || $$.mapToIds($$.data.targets), optionz, transitions);\n }\n // toggle legend state\n (_a = $el.legend) === null || _a === void 0 ? void 0 : _a.selectAll(\".\".concat($LEGEND.legendItem)).classed($LEGEND.legendItemHidden, function (id) {\n var hide = !$$.isTargetToShow(id);\n if (hide) {\n this.style.opacity = null;\n }\n return hide;\n });\n // Update size and scale\n $$.updateScales(false, !scale.zoom);\n $$.updateSvgSize();\n // Update g positions\n $$.transformAll(optionz.withTransitionForTransform, transitions);\n state.legendHasRendered = true;\n },\n /**\n * Update legend using template option\n * @private\n */\n updateLegendTemplate: function () {\n var $$ = this;\n var config = $$.config, $el = $$.$el;\n var wrapper = select(config.legend_contents_bindto);\n var template = config.legend_contents_template;\n if (!wrapper.empty()) {\n var targets = $$.mapToIds($$.data.targets);\n var ids_1 = [];\n var html_1 = \"\";\n targets.forEach(function (v) {\n var content = isFunction(template) ?\n template.bind($$.api)(v, $$.color(v), $$.api.data(v)[0].values) :\n tplProcess(template, {\n COLOR: $$.color(v),\n TITLE: v\n });\n if (content) {\n ids_1.push(v);\n html_1 += content;\n }\n });\n var legendItem = wrapper.html(html_1)\n .selectAll(function () { return this.childNodes; })\n .data(ids_1);\n $$.setLegendItem(legendItem);\n $el.legend = wrapper;\n }\n },\n /**\n * Update the size of the legend.\n * @param {Obejct} size Size object\n * @private\n */\n updateSizeForLegend: function (size) {\n var $$ = this;\n var config = $$.config, _a = $$.state, isLegendTop = _a.isLegendTop, isLegendLeft = _a.isLegendLeft, isLegendRight = _a.isLegendRight, isLegendInset = _a.isLegendInset, current = _a.current;\n var width = size.width, height = size.height;\n var insetLegendPosition = {\n top: isLegendTop ?\n $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 :\n current.height - height - $$.getCurrentPaddingBottom() - config.legend_inset_y,\n left: isLegendLeft ?\n $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 :\n current.width - width - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5\n };\n $$.state.margin3 = {\n top: isLegendRight ?\n 0 : isLegendInset ? insetLegendPosition.top : current.height - height,\n right: NaN,\n bottom: 0,\n left: isLegendRight ?\n current.width - width : isLegendInset ? insetLegendPosition.left : 0\n };\n },\n /**\n * Transform Legend\n * @param {boolean} withTransition whether or not to transition.\n * @private\n */\n transformLegend: function (withTransition) {\n var $$ = this;\n var legend = $$.$el.legend, $T = $$.$T;\n $T(legend, withTransition)\n .attr(\"transform\", $$.getTranslate(\"legend\"));\n },\n /**\n * Update the legend step\n * @param {number} step Step value\n * @private\n */\n updateLegendStep: function (step) {\n this.state.legendStep = step;\n },\n /**\n * Update legend item width\n * @param {number} width Width value\n * @private\n */\n updateLegendItemWidth: function (width) {\n this.state.legendItemWidth = width;\n },\n /**\n * Update legend item height\n * @param {number} height Height value\n * @private\n */\n updateLegendItemHeight: function (height) {\n this.state.legendItemHeight = height;\n },\n /**\n * Update legend item color\n * @param {string} id Corresponding data ID value\n * @param {string} color Color value\n * @private\n */\n updateLegendItemColor: function (id, color) {\n var legend = this.$el.legend;\n if (legend) {\n legend.select(\".\".concat($LEGEND.legendItem, \"-\").concat(id, \" line\"))\n .style(\"stroke\", color);\n }\n },\n /**\n * Get the width of the legend\n * @returns {number} width\n * @private\n */\n getLegendWidth: function () {\n var $$ = this;\n var _a = $$.state, width = _a.current.width, isLegendRight = _a.isLegendRight, isLegendInset = _a.isLegendInset, legendItemWidth = _a.legendItemWidth, legendStep = _a.legendStep;\n return $$.config.legend_show ? (isLegendRight || isLegendInset ?\n legendItemWidth * (legendStep + 1) : width) : 0;\n },\n /**\n * Get the height of the legend\n * @returns {number} height\n * @private\n */\n getLegendHeight: function () {\n var $$ = this;\n var _a = $$.state, current = _a.current, isLegendRight = _a.isLegendRight, legendItemHeight = _a.legendItemHeight, legendStep = _a.legendStep;\n return $$.config.legend_show ? (isLegendRight ?\n current.height : Math.max(20, legendItemHeight) * (legendStep + 1)) : 0;\n },\n /**\n * Get the opacity of the legend that is unfocused\n * @param {d3.selection} legendItem Legend item node\n * @returns {string|null} opacity\n * @private\n */\n opacityForUnfocusedLegend: function (legendItem) {\n return legendItem.classed($LEGEND.legendItemHidden) ? null : \"0.3\";\n },\n /**\n * Toggles the focus of the legend\n * @param {Array} targetIds ID's of target\n * @param {boolean} focus whether or not to focus.\n * @private\n */\n toggleFocusLegend: function (targetIds, focus) {\n var $$ = this;\n var legend = $$.$el.legend, $T = $$.$T;\n var targetIdz = $$.mapToTargetIds(targetIds);\n legend && $T(legend.selectAll(\".\".concat($LEGEND.legendItem))\n .filter(function (id) { return targetIdz.indexOf(id) >= 0; })\n .classed($FOCUS.legendItemFocused, focus))\n .style(\"opacity\", function () {\n return focus ? null :\n $$.opacityForUnfocusedLegend.call($$, select(this));\n });\n },\n /**\n * Revert the legend to its default state\n * @private\n */\n revertLegend: function () {\n var $$ = this;\n var legend = $$.$el.legend, $T = $$.$T;\n legend && $T(legend.selectAll(\".\".concat($LEGEND.legendItem))\n .classed($FOCUS.legendItemFocused, false))\n .style(\"opacity\", null);\n },\n /**\n * Shows the legend\n * @param {Array} targetIds ID's of target\n * @private\n */\n showLegend: function (targetIds) {\n var $$ = this;\n var config = $$.config, $el = $$.$el, $T = $$.$T;\n if (!config.legend_show) {\n config.legend_show = true;\n $el.legend ?\n $el.legend.style(\"visibility\", null) :\n $$.initLegend();\n !$$.state.legendHasRendered && $$.updateLegend();\n }\n $$.removeHiddenLegendIds(targetIds);\n $T($el.legend.selectAll($$.selectorLegends(targetIds))\n .style(\"visibility\", null)).style(\"opacity\", null);\n },\n /**\n * Hide the legend\n * @param {Array} targetIds ID's of target\n * @private\n */\n hideLegend: function (targetIds) {\n var $$ = this;\n var config = $$.config, legend = $$.$el.legend;\n if (config.legend_show && isEmpty(targetIds)) {\n config.legend_show = false;\n legend.style(\"visibility\", \"hidden\");\n }\n $$.addHiddenLegendIds(targetIds);\n legend.selectAll($$.selectorLegends(targetIds))\n .style(\"opacity\", \"0\")\n .style(\"visibility\", \"hidden\");\n },\n /**\n * Get legend item textbox dimension\n * @param {string} id Data ID\n * @param {HTMLElement|d3.selection} textElement Text node element\n * @returns {object} Bounding rect\n * @private\n */\n getLegendItemTextBox: function (id, textElement) {\n var $$ = this;\n var cache = $$.cache, state = $$.state;\n var data;\n // do not prefix w/'$', to not be resetted cache in .load() call\n var cacheKey = KEY.legendItemTextBox;\n if (id) {\n data = (!state.redrawing && cache.get(cacheKey)) || {};\n if (!data[id]) {\n data[id] = $$.getTextRect(textElement, $LEGEND.legendItem);\n cache.add(cacheKey, data);\n }\n data = data[id];\n }\n return data;\n },\n /**\n * Set legend item style & bind events\n * @param {d3.selection} item Item node\n * @private\n */\n setLegendItem: function (item) {\n var $$ = this;\n var $el = $$.$el, api = $$.api, config = $$.config, state = $$.state;\n var isTouch = state.inputType === \"touch\";\n var hasGauge = $$.hasType(\"gauge\");\n var useCssRule = config.boost_useCssRule;\n item\n .attr(\"class\", function (id) {\n var node = select(this);\n var itemClass = (!node.empty() && node.attr(\"class\")) || \"\";\n return itemClass + $$.generateClass($LEGEND.legendItem, id);\n })\n .style(\"visibility\", function (id) { return ($$.isLegendToShow(id) ? null : \"hidden\"); });\n if (config.interaction_enabled) {\n if (useCssRule) {\n [\n [\".\".concat($LEGEND.legendItem), \"cursor:pointer\"],\n [\".\".concat($LEGEND.legendItem, \" text\"), \"pointer-events:none\"],\n [\".\".concat($LEGEND.legendItemPoint, \" text\"), \"pointer-events:none\"],\n [\".\".concat($LEGEND.legendItemTile), \"pointer-events:none\"],\n [\".\".concat($LEGEND.legendItemEvent), \"fill-opacity:0\"]\n ].forEach(function (v) {\n var selector = v[0], props = v[1];\n $$.setCssRule(false, selector, [props])($el.legend);\n });\n }\n item\n .style(\"cursor\", $$.getStylePropValue(\"pointer\"))\n .on(\"click\", function (event, id) {\n if (!callFn(config.legend_item_onclick, api, id)) {\n if (event.altKey) {\n api.hide();\n api.show(id);\n }\n else {\n api.toggle(id);\n select(this)\n .classed($FOCUS.legendItemFocused, false);\n }\n }\n isTouch && $$.hideTooltip();\n });\n !isTouch && item\n .on(\"mouseout\", function (event, id) {\n if (!callFn(config.legend_item_onout, api, id)) {\n select(this).classed($FOCUS.legendItemFocused, false);\n if (hasGauge) {\n $$.undoMarkOverlapped($$, \".\".concat($GAUGE.gaugeValue));\n }\n $$.api.revert();\n }\n })\n .on(\"mouseover\", function (event, id) {\n if (!callFn(config.legend_item_onover, api, id)) {\n select(this).classed($FOCUS.legendItemFocused, true);\n if (hasGauge) {\n $$.markOverlapped(id, $$, \".\".concat($GAUGE.gaugeValue));\n }\n if (!state.transiting && $$.isTargetToShow(id)) {\n api.focus(id);\n }\n }\n });\n }\n },\n /**\n * Update the legend\n * @param {Array} targetIds ID's of target\n * @param {object} options withTransform : Whether to use the transform property / withTransitionForTransform: Whether transition is used when using the transform property / withTransition : whether or not to transition.\n * @private\n */\n updateLegendElement: function (targetIds, options) {\n var $$ = this;\n var config = $$.config, state = $$.state, legend = $$.$el.legend, $T = $$.$T;\n var legendType = config.legend_item_tile_type;\n var isRectangle = legendType !== \"circle\";\n var legendItemR = config.legend_item_tile_r;\n var itemTileSize = {\n width: isRectangle ? config.legend_item_tile_width : legendItemR * 2,\n height: isRectangle ? config.legend_item_tile_height : legendItemR * 2\n };\n var dimension = {\n padding: {\n top: 4,\n right: 10\n },\n max: {\n width: 0,\n height: 0\n },\n posMin: 10,\n step: 0,\n tileWidth: itemTileSize.width + 5,\n totalLength: 0\n };\n var sizes = {\n offsets: {},\n widths: {},\n heights: {},\n margins: [0],\n steps: {}\n };\n var xForLegend;\n var yForLegend;\n var background;\n // Skip elements when their name is set to null\n var targetIdz = targetIds\n .filter(function (id) { return !isDefined(config.data_names[id]) || config.data_names[id] !== null; });\n var withTransition = options.withTransition;\n var updatePositions = $$.getUpdateLegendPositions(targetIdz, dimension, sizes);\n if (state.isLegendInset) {\n dimension.step = config.legend_inset_step ? config.legend_inset_step : targetIdz.length;\n $$.updateLegendStep(dimension.step);\n }\n if (state.isLegendRight) {\n xForLegend = function (id) { return dimension.max.width * sizes.steps[id]; };\n yForLegend = function (id) { return sizes.margins[sizes.steps[id]] + sizes.offsets[id]; };\n }\n else if (state.isLegendInset) {\n xForLegend = function (id) { return dimension.max.width * sizes.steps[id] + 10; };\n yForLegend = function (id) { return sizes.margins[sizes.steps[id]] + sizes.offsets[id]; };\n }\n else {\n xForLegend = function (id) { return sizes.margins[sizes.steps[id]] + sizes.offsets[id]; };\n yForLegend = function (id) { return dimension.max.height * sizes.steps[id]; };\n }\n var posFn = {\n xText: function (id, i) { return xForLegend(id, i) + 4 + itemTileSize.width; },\n xRect: function (id, i) { return xForLegend(id, i); },\n x1Tile: function (id, i) { return xForLegend(id, i) - 2; },\n x2Tile: function (id, i) { return xForLegend(id, i) - 2 + itemTileSize.width; },\n yText: function (id, i) { return yForLegend(id, i) + 9; },\n yRect: function (id, i) { return yForLegend(id, i) - 5; },\n yTile: function (id, i) { return yForLegend(id, i) + 4; }\n };\n $$.generateLegendItem(targetIdz, itemTileSize, updatePositions, posFn);\n // Set background for inset legend\n background = legend.select(\".\".concat($LEGEND.legendBackground, \" rect\"));\n if (state.isLegendInset && dimension.max.width > 0 && background.size() === 0) {\n background = legend.insert(\"g\", \".\".concat($LEGEND.legendItem))\n .attr(\"class\", $LEGEND.legendBackground)\n .append(\"rect\");\n }\n var texts = legend.selectAll(\"text\")\n .data(targetIdz)\n .text(function (id) { return (isDefined(config.data_names[id]) ? config.data_names[id] : id); }) // MEMO: needed for update\n .each(function (id, i) {\n updatePositions(this, id, i);\n });\n $T(texts, withTransition)\n .attr(\"x\", posFn.xText)\n .attr(\"y\", posFn.yText);\n var rects = legend.selectAll(\"rect.\".concat($LEGEND.legendItemEvent))\n .data(targetIdz);\n $T(rects, withTransition)\n .attr(\"width\", function (id) { return sizes.widths[id]; })\n .attr(\"height\", function (id) { return sizes.heights[id]; })\n .attr(\"x\", posFn.xRect)\n .attr(\"y\", posFn.yRect);\n // update legend items position\n $$.updateLegendItemPos(targetIdz, withTransition, posFn);\n if (background) {\n $T(background, withTransition)\n .attr(\"height\", $$.getLegendHeight() - 12)\n .attr(\"width\", dimension.max.width * (dimension.step + 1) + 10);\n }\n // Update all to reflect change of legend\n $$.updateLegendItemWidth(dimension.max.width);\n $$.updateLegendItemHeight(dimension.max.height);\n $$.updateLegendStep(dimension.step);\n },\n /**\n * Get position update function\n * @param {Array} targetIdz Data ids\n * @param {object} dimension Dimension object\n * @param {object} sizes Size object\n * @returns {Function} Update position function\n * @private\n */\n getUpdateLegendPositions: function (targetIdz, dimension, sizes) {\n var $$ = this;\n var config = $$.config, state = $$.state;\n var isLegendRightOrInset = state.isLegendRight || state.isLegendInset;\n return function (textElement, id, index) {\n var reset = index === 0;\n var isLast = index === targetIdz.length - 1;\n var box = $$.getLegendItemTextBox(id, textElement);\n var itemWidth = box.width + dimension.tileWidth +\n (isLast && !isLegendRightOrInset ? 0 : dimension.padding.right) + config.legend_padding;\n var itemHeight = box.height + dimension.padding.top;\n var itemLength = isLegendRightOrInset ? itemHeight : itemWidth;\n var areaLength = isLegendRightOrInset ? $$.getLegendHeight() : $$.getLegendWidth();\n var margin;\n // MEMO: care about condifion of step, totalLength\n var updateValues = function (id2, withoutStep) {\n if (!withoutStep) {\n margin = (areaLength - dimension.totalLength - itemLength) / 2;\n if (margin < dimension.posMin) {\n margin = (areaLength - itemLength) / 2;\n dimension.totalLength = 0;\n dimension.step++;\n }\n }\n sizes.steps[id2] = dimension.step;\n sizes.margins[dimension.step] = state.isLegendInset ? 10 : margin;\n sizes.offsets[id2] = dimension.totalLength;\n dimension.totalLength += itemLength;\n };\n if (reset) {\n dimension.totalLength = 0;\n dimension.step = 0;\n dimension.max.width = 0;\n dimension.max.height = 0;\n }\n if (config.legend_show && !$$.isLegendToShow(id)) {\n sizes.widths[id] = 0;\n sizes.heights[id] = 0;\n sizes.steps[id] = 0;\n sizes.offsets[id] = 0;\n return;\n }\n sizes.widths[id] = itemWidth;\n sizes.heights[id] = itemHeight;\n if (!dimension.max.width || itemWidth >= dimension.max.width) {\n dimension.max.width = itemWidth;\n }\n if (!dimension.max.height || itemHeight >= dimension.max.height) {\n dimension.max.height = itemHeight;\n }\n var maxLength = isLegendRightOrInset ? dimension.max.height : dimension.max.width;\n if (config.legend_equally) {\n Object.keys(sizes.widths).forEach(function (id2) { return (sizes.widths[id2] = dimension.max.width); });\n Object.keys(sizes.heights).forEach(function (id2) { return (sizes.heights[id2] = dimension.max.height); });\n margin = (areaLength - maxLength * targetIdz.length) / 2;\n if (margin < dimension.posMin) {\n dimension.totalLength = 0;\n dimension.step = 0;\n targetIdz.forEach(function (id2) { return updateValues(id2); });\n }\n else {\n updateValues(id, true);\n }\n }\n else {\n updateValues(id);\n }\n };\n },\n /**\n * Generate legend item elements\n * @param {Array} targetIdz Data ids\n * @param {object} itemTileSize Item tile size {width, height}\n * @param {Function} updatePositions Update position function\n * @param {object} posFn Position functions\n * @private\n */\n generateLegendItem: function (targetIdz, itemTileSize, updatePositions, posFn) {\n var $$ = this;\n var config = $$.config, state = $$.state, legend = $$.$el.legend;\n var usePoint = config.legend_usePoint;\n var legendItemR = config.legend_item_tile_r;\n var legendType = config.legend_item_tile_type;\n var isRectangle = legendType !== \"circle\";\n var isLegendRightOrInset = state.isLegendRight || state.isLegendInset;\n var pos = -200;\n // Define g for legend area\n var l = legend.selectAll(\".\".concat($LEGEND.legendItem))\n .data(targetIdz)\n .enter()\n .append(\"g\");\n $$.setLegendItem(l);\n l.append(\"text\")\n .text(function (id) { return (isDefined(config.data_names[id]) ? config.data_names[id] : id); })\n .each(function (id, i) {\n updatePositions(this, id, i);\n })\n .style(\"pointer-events\", $$.getStylePropValue(\"none\"))\n .attr(\"x\", isLegendRightOrInset ? posFn.xText : pos)\n .attr(\"y\", isLegendRightOrInset ? pos : posFn.yText);\n l.append(\"rect\")\n .attr(\"class\", $LEGEND.legendItemEvent)\n .style(\"fill-opacity\", $$.getStylePropValue(\"0\"))\n .attr(\"x\", isLegendRightOrInset ? posFn.xRect : pos)\n .attr(\"y\", isLegendRightOrInset ? pos : posFn.yRect);\n if (usePoint) {\n var ids_2 = [];\n l.append(function (d) {\n var pattern = notEmpty(config.point_pattern) ?\n config.point_pattern : [config.point_type];\n ids_2.indexOf(d) === -1 && ids_2.push(d);\n var point = pattern[ids_2.indexOf(d) % pattern.length];\n if (point === \"rectangle\") {\n point = \"rect\";\n }\n return doc.createElementNS(namespaces.svg, (\"hasValidPointType\" in $$) && $$.hasValidPointType(point) ? point : \"use\");\n })\n .attr(\"class\", $LEGEND.legendItemPoint)\n .style(\"fill\", getLegendColor.bind($$))\n .style(\"pointer-events\", $$.getStylePropValue(\"none\"))\n .attr(\"href\", function (data, idx, selection) {\n var node = selection[idx];\n var nodeName = node.nodeName.toLowerCase();\n var id = $$.getTargetSelectorSuffix(data);\n return nodeName === \"use\" ? \"#\".concat(state.datetimeId, \"-point\").concat(id) : undefined;\n });\n }\n else {\n l.append(isRectangle ? \"line\" : legendType)\n .attr(\"class\", $LEGEND.legendItemTile)\n .style(\"stroke\", getLegendColor.bind($$))\n .style(\"pointer-events\", $$.getStylePropValue(\"none\"))\n .call(function (selection) {\n if (legendType === \"circle\") {\n selection\n .attr(\"r\", legendItemR)\n .style(\"fill\", getLegendColor.bind($$))\n .attr(\"cx\", isLegendRightOrInset ? posFn.x2Tile : pos)\n .attr(\"cy\", isLegendRightOrInset ? pos : posFn.yTile);\n }\n else if (isRectangle) {\n selection\n .attr(\"stroke-width\", itemTileSize.height)\n .attr(\"x1\", isLegendRightOrInset ? posFn.x1Tile : pos)\n .attr(\"y1\", isLegendRightOrInset ? pos : posFn.yTile)\n .attr(\"x2\", isLegendRightOrInset ? posFn.x2Tile : pos)\n .attr(\"y2\", isLegendRightOrInset ? pos : posFn.yTile);\n }\n });\n }\n },\n /**\n * Update legend item position\n * @param {Array} targetIdz Data ids\n * @param {boolean} withTransition Whether or not to apply transition\n * @param {object} posFn Position functions\n * @private\n */\n updateLegendItemPos: function (targetIdz, withTransition, posFn) {\n var $$ = this;\n var config = $$.config, legend = $$.$el.legend, $T = $$.$T;\n var usePoint = config.legend_usePoint;\n var legendType = config.legend_item_tile_type;\n var isRectangle = legendType !== \"circle\";\n if (usePoint) {\n var tiles = legend.selectAll(\".\".concat($LEGEND.legendItemPoint))\n .data(targetIdz);\n $T(tiles, withTransition)\n .each(function () {\n var nodeName = this.nodeName.toLowerCase();\n var pointR = config.point_r;\n var x = \"x\";\n var y = \"y\";\n var xOffset = 2;\n var yOffset = 2.5;\n var radius = null;\n var width = null;\n var height = null;\n if (nodeName === \"circle\") {\n var size = pointR * 0.2;\n x = \"cx\";\n y = \"cy\";\n radius = pointR + size;\n xOffset = pointR * 2;\n yOffset = -size;\n }\n else if (nodeName === \"rect\") {\n var size = pointR * 2.5;\n width = size;\n height = size;\n yOffset = 3;\n }\n select(this)\n .attr(x, function (d) { return posFn.x1Tile(d) + xOffset; })\n .attr(y, function (d) { return posFn.yTile(d) - yOffset; })\n .attr(\"r\", radius)\n .attr(\"width\", width)\n .attr(\"height\", height);\n });\n }\n else {\n var tiles = legend.selectAll(\".\".concat($LEGEND.legendItemTile))\n .data(targetIdz);\n $T(tiles, withTransition)\n .style(\"stroke\", getLegendColor.bind($$))\n .call(function (selection) {\n if (legendType === \"circle\") {\n selection\n .attr(\"cx\", function (d) {\n var x2 = posFn.x2Tile(d);\n return x2 - ((x2 - posFn.x1Tile(d)) / 2);\n })\n .attr(\"cy\", posFn.yTile);\n }\n else if (isRectangle) {\n selection\n .attr(\"x1\", posFn.x1Tile)\n .attr(\"y1\", posFn.yTile)\n .attr(\"x2\", posFn.x2Tile)\n .attr(\"y2\", posFn.yTile);\n }\n });\n }\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar redraw = {\n redraw: function (options) {\n var _a, _b, _c;\n if (options === void 0) { options = {}; }\n var $$ = this;\n var config = $$.config, state = $$.state, $el = $$.$el;\n var main = $el.main, treemap = $el.treemap;\n state.redrawing = true;\n var targetsToShow = $$.filterTargetsToShow($$.data.targets);\n var flow = options.flow, initializing = options.initializing;\n var wth = $$.getWithOption(options);\n var duration = wth.Transition ? config.transition_duration : 0;\n var durationForExit = wth.TransitionForExit ? duration : 0;\n var durationForAxis = wth.TransitionForAxis ? duration : 0;\n var transitions = (_a = $$.axis) === null || _a === void 0 ? void 0 : _a.generateTransitions(durationForAxis);\n $$.updateSizes(initializing);\n // update legend and transform each g\n if (wth.Legend && config.legend_show) {\n options.withTransition = !!duration;\n !treemap && $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);\n }\n else if (wth.Dimension) {\n // need to update dimension (e.g. axis.y.tick.values) because y tick values should change\n // no need to update axis in it because they will be updated in redraw()\n $$.updateDimension(true);\n }\n // update circleY based on updated parameters\n if (!treemap && (!$$.hasArcType() || state.hasRadar)) {\n $$.updateCircleY && ($$.circleY = $$.updateCircleY());\n }\n // Data empty label positioning and text.\n config.data_empty_label_text && main.select(\"text.\".concat($TEXT.text, \".\").concat($COMMON.empty))\n .attr(\"x\", state.width / 2)\n .attr(\"y\", state.height / 2)\n .text(config.data_empty_label_text)\n .style(\"display\", targetsToShow.length ? \"none\" : null);\n // update axis\n if (state.hasAxis) {\n // @TODO: Make 'init' state to be accessible everywhere not passing as argument.\n $$.axis.redrawAxis(targetsToShow, wth, transitions, flow, initializing);\n // grid\n $$.hasGrid() && $$.updateGrid();\n // rect for regions\n config.regions.length && $$.updateRegion();\n [\"bar\", \"candlestick\", \"line\", \"area\"].forEach(function (v) {\n var name = capitalize(v);\n if ((/^(line|area)$/.test(v) && $$.hasTypeOf(name)) || $$.hasType(v)) {\n $$[\"update\".concat(name)](wth.TransitionForExit);\n }\n });\n // circles for select\n $el.text && main.selectAll(\".\".concat($SELECT.selectedCircles))\n .filter($$.isBarType.bind($$))\n .selectAll(\"circle\")\n .remove();\n // event rects will redrawn when flow called\n if (config.interaction_enabled && !flow && wth.EventRect) {\n $$.redrawEventRect();\n (_b = $$.bindZoomEvent) === null || _b === void 0 ? void 0 : _b.call($$);\n }\n }\n else {\n // arc\n $el.arcs && $$.redrawArc(duration, durationForExit, wth.Transform);\n // radar\n $el.radar && $$.redrawRadar();\n // polar\n $el.polar && $$.redrawPolar();\n // treemap\n treemap && $$.updateTreemap(durationForExit);\n }\n // @TODO: Axis & Radar type\n if (!state.resizing && !treemap && ($$.hasPointType() || state.hasRadar)) {\n $$.updateCircle();\n }\n // text\n $$.hasDataLabel() && !$$.hasArcType(null, [\"radar\"]) && $$.updateText();\n // title\n (_c = $$.redrawTitle) === null || _c === void 0 ? void 0 : _c.call($$);\n initializing && $$.updateTypesElements();\n $$.generateRedrawList(targetsToShow, flow, duration, wth.Subchart);\n $$.callPluginHook(\"$redraw\", options, duration);\n },\n /**\n * Generate redraw list\n * @param {object} targets targets data to be shown\n * @param {object} flow flow object\n * @param {number} duration duration value\n * @param {boolean} withSubchart whether or not to show subchart\n * @private\n */\n generateRedrawList: function (targets, flow, duration, withSubchart) {\n var $$ = this;\n var config = $$.config, state = $$.state;\n var shape = $$.getDrawShape();\n if (state.hasAxis) {\n // subchart\n config.subchart_show && $$.redrawSubchart(withSubchart, duration, shape);\n }\n // generate flow\n var flowFn = flow && $$.generateFlow({\n targets: targets,\n flow: flow,\n duration: flow.duration,\n shape: shape,\n xv: $$.xv.bind($$)\n });\n var withTransition = (duration || flowFn) && isTabVisible();\n // redraw list\n var redrawList = $$.getRedrawList(shape, flow, flowFn, withTransition);\n // callback function after redraw ends\n var afterRedraw = function () {\n flowFn && flowFn();\n state.redrawing = false;\n callFn(config.onrendered, $$.api);\n };\n if (afterRedraw) {\n // Only use transition when current tab is visible.\n if (withTransition && redrawList.length) {\n // Wait for end of transitions for callback\n var waitForDraw_1 = generateWait();\n // transition should be derived from one transition\n transition().duration(duration)\n .each(function () {\n redrawList\n .reduce(function (acc, t1) { return acc.concat(t1); }, [])\n .forEach(function (t) { return waitForDraw_1.add(t); });\n })\n .call(waitForDraw_1, afterRedraw);\n }\n else if (!state.transiting) {\n afterRedraw();\n }\n }\n // update fadein condition\n $$.mapToIds($$.data.targets).forEach(function (id) {\n state.withoutFadeIn[id] = true;\n });\n },\n getRedrawList: function (shape, flow, flowFn, withTransition) {\n var $$ = this;\n var config = $$.config, _a = $$.state, hasAxis = _a.hasAxis, hasRadar = _a.hasRadar, hasTreemap = _a.hasTreemap, grid = $$.$el.grid;\n var _b = shape.pos, cx = _b.cx, cy = _b.cy, xForText = _b.xForText, yForText = _b.yForText;\n var list = [];\n if (hasAxis) {\n if (config.grid_x_lines.length || config.grid_y_lines.length) {\n list.push($$.redrawGrid(withTransition));\n }\n if (config.regions.length) {\n list.push($$.redrawRegion(withTransition));\n }\n Object.keys(shape.type).forEach(function (v) {\n var name = capitalize(v);\n var drawFn = shape.type[v];\n if ((/^(area|line)$/.test(v) && $$.hasTypeOf(name)) || $$.hasType(v)) {\n list.push($$[\"redraw\".concat(name)](drawFn, withTransition));\n }\n });\n !flow && grid.main && list.push($$.updateGridFocus());\n }\n if (!$$.hasArcType() || hasRadar) {\n notEmpty(config.data_labels) && config.data_labels !== false &&\n list.push($$.redrawText(xForText, yForText, flow, withTransition));\n }\n if (($$.hasPointType() || hasRadar) && !config.point_focus_only) {\n $$.redrawCircle && list.push($$.redrawCircle(cx, cy, withTransition, flowFn));\n }\n if (hasTreemap) {\n list.push($$.redrawTreemap(withTransition));\n }\n return list;\n },\n updateAndRedraw: function (options) {\n if (options === void 0) { options = {}; }\n var $$ = this;\n var config = $$.config, state = $$.state;\n var transitions;\n // same with redraw\n options.withTransition = getOption(options, \"withTransition\", true);\n options.withTransform = getOption(options, \"withTransform\", false);\n options.withLegend = getOption(options, \"withLegend\", false);\n // NOT same with redraw\n options.withUpdateXDomain = true;\n options.withUpdateOrgXDomain = true;\n options.withTransitionForExit = false;\n options.withTransitionForTransform = getOption(options, \"withTransitionForTransform\", options.withTransition);\n // MEMO: called in updateLegend in redraw if withLegend\n if (!(options.withLegend && config.legend_show)) {\n if (state.hasAxis) {\n transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0);\n }\n // Update scales\n $$.updateScales();\n $$.updateSvgSize();\n // Update g positions\n $$.transformAll(options.withTransitionForTransform, transitions);\n }\n // Draw with new sizes & scales\n $$.redraw(options, transitions);\n },\n /**\n * Redraw without rescale\n * @private\n */\n redrawWithoutRescale: function () {\n this.redraw({\n withY: false,\n withDimension: false,\n withLegend: false,\n withSubchart: false,\n withEventRect: false,\n withTransitionForAxis: false\n });\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Get scale\n * @param {string} [type='linear'] Scale type\n * @param {number} [min] Min range\n * @param {number} [max] Max range\n * @returns {d3.scaleLinear|d3.scaleTime} scale\n * @private\n */\nfunction getScale(type, min, max) {\n if (type === void 0) { type = \"linear\"; }\n if (min === void 0) { min = 0; }\n if (max === void 0) { max = 1; }\n var scale = ({\n linear: scaleLinear,\n log: scaleSymlog,\n _log: scaleLog,\n time: scaleTime,\n utc: scaleUtc\n })[type]();\n scale.type = type;\n /_?log/.test(type) && scale.clamp(true);\n return scale.range([min, max]);\n}\nvar scale = {\n /**\n * Get x Axis scale function\n * @param {number} min Min value\n * @param {number} max Max value\n * @param {Array} domain Domain value\n * @param {Function} offset The offset getter to be sum\n * @returns {Function} scale\n * @private\n */\n getXScale: function (min, max, domain, offset) {\n var $$ = this;\n var scale = $$.scale.zoom || getScale($$.axis.getAxisType(\"x\"), min, max);\n return $$.getCustomizedScale(domain ? scale.domain(domain) : scale, offset);\n },\n /**\n * Get y Axis scale function\n * @param {string} id Axis id: 'y' or 'y2'\n * @param {number} min Min value\n * @param {number} max Max value\n * @param {Array} domain Domain value\n * @returns {Function} Scale function\n * @private\n */\n getYScale: function (id, min, max, domain) {\n var $$ = this;\n var scale = getScale($$.axis.getAxisType(id), min, max);\n domain && scale.domain(domain);\n return scale;\n },\n /**\n * Get y Axis scale\n * @param {string} id Axis id\n * @param {boolean} isSub Weather is sub Axis\n * @returns {Function} Scale function\n * @private\n */\n getYScaleById: function (id, isSub) {\n var _a;\n if (isSub === void 0) { isSub = false; }\n var isY2 = ((_a = this.axis) === null || _a === void 0 ? void 0 : _a.getId(id)) === \"y2\";\n var key = isSub ? (isY2 ? \"subY2\" : \"subY\") : (isY2 ? \"y2\" : \"y\");\n return this.scale[key];\n },\n /**\n * Get customized scale\n * @param {d3.scaleLinear|d3.scaleTime} scaleValue Scale function\n * @param {Function} offsetValue Offset getter to be sum\n * @returns {Function} Scale function\n * @private\n */\n getCustomizedScale: function (scaleValue, offsetValue) {\n var $$ = this;\n var offset = offsetValue || (function () { return $$.axis.x.tickOffset(); });\n var scale = function (d, raw) {\n var v = scaleValue(d) + offset();\n return raw ? v : Math.ceil(v);\n };\n // copy original scale methods\n for (var key in scaleValue) {\n scale[key] = scaleValue[key];\n }\n scale.orgDomain = function () { return scaleValue.domain(); };\n scale.orgScale = function () { return scaleValue; };\n // define custom domain() for categorized axis\n if ($$.axis.isCategorized()) {\n scale.domain = function (domainValue) {\n var domain = domainValue;\n if (!arguments.length) {\n domain = this.orgDomain();\n return [domain[0], domain[1] + 1];\n }\n scaleValue.domain(domain);\n return scale;\n };\n }\n return scale;\n },\n /**\n * Update scale\n * @param {boolean} isInit Param is given at the init rendering\n * @param {boolean} updateXDomain If update x domain\n * @private\n */\n updateScales: function (isInit, updateXDomain) {\n var _a, _b;\n if (updateXDomain === void 0) { updateXDomain = true; }\n var $$ = this;\n var axis = $$.axis, config = $$.config, format = $$.format, org = $$.org, scale = $$.scale, _c = $$.state, current = _c.current, width = _c.width, height = _c.height, width2 = _c.width2, height2 = _c.height2, hasAxis = _c.hasAxis, hasTreemap = _c.hasTreemap;\n if (hasAxis) {\n var isRotated = config.axis_rotated;\n var resettedPadding = $$.getResettedPadding(1);\n // update edges\n var min = {\n x: isRotated ? resettedPadding : 0,\n y: isRotated ? 0 : height,\n subX: isRotated ? 1 : 0,\n subY: isRotated ? 0 : height2\n };\n var max = {\n x: isRotated ? height : width,\n y: isRotated ? width : resettedPadding,\n subX: isRotated ? height : width,\n subY: isRotated ? width2 : 1\n };\n // update scales\n // x Axis\n var xDomain = updateXDomain && ((_a = scale.x) === null || _a === void 0 ? void 0 : _a.orgDomain());\n var xSubDomain = updateXDomain && org.xDomain;\n scale.x = $$.getXScale(min.x, max.x, xDomain, function () { return axis.x.tickOffset(); });\n scale.subX = $$.getXScale(min.x, max.x, xSubDomain, function (d) {\n var _a;\n return (d % 1 ? 0 : ((_a = axis.subX) !== null && _a !== void 0 ? _a : axis.x).tickOffset());\n });\n format.xAxisTick = axis.getXAxisTickFormat();\n format.subXAxisTick = axis.getXAxisTickFormat(true);\n axis.setAxis(\"x\", scale.x, config.axis_x_tick_outer, isInit);\n if (config.subchart_show) {\n axis.setAxis(\"subX\", scale.subX, config.axis_x_tick_outer, isInit);\n }\n // y Axis\n scale.y = $$.getYScale(\"y\", min.y, max.y, scale.y ? scale.y.domain() : config.axis_y_default);\n scale.subY = $$.getYScale(\"y\", min.subY, max.subY, scale.subY ? scale.subY.domain() : config.axis_y_default);\n axis.setAxis(\"y\", scale.y, config.axis_y_tick_outer, isInit);\n // y2 Axis\n if (config.axis_y2_show) {\n scale.y2 = $$.getYScale(\"y2\", min.y, max.y, scale.y2 ? scale.y2.domain() : config.axis_y2_default);\n scale.subY2 = $$.getYScale(\"y2\", min.subY, max.subY, scale.subY2 ? scale.subY2.domain() : config.axis_y2_default);\n axis.setAxis(\"y2\", scale.y2, config.axis_y2_tick_outer, isInit);\n }\n }\n else if (hasTreemap) {\n var padding = $$.getCurrentPadding();\n scale.x = scaleLinear().rangeRound([padding.left, current.width - padding.right]);\n scale.y = scaleLinear().rangeRound([padding.top, current.height - padding.bottom]);\n }\n else {\n // update for arc\n (_b = $$.updateArc) === null || _b === void 0 ? void 0 : _b.call($$);\n }\n },\n /**\n * Get the zoom or unzoomed scaled value\n * @param {Date|number|object} d Data value\n * @returns {number|null}\n * @private\n */\n xx: function (d) {\n var $$ = this;\n var config = $$.config, _a = $$.scale, x = _a.x, zoom = _a.zoom;\n var fn = config.zoom_enabled && zoom ? zoom : x;\n return d ? fn(isValue(d.x) ? d.x : d) : null;\n },\n xv: function (d) {\n var $$ = this;\n var axis = $$.axis, config = $$.config, _a = $$.scale, x = _a.x, zoom = _a.zoom;\n var fn = config.zoom_enabled && zoom ? zoom : x;\n var value = $$.getBaseValue(d);\n if (axis.isTimeSeries()) {\n value = parseDate.call($$, value);\n }\n else if (axis.isCategorized() && isString(value)) {\n value = config.axis_x_categories.indexOf(value);\n }\n return Math.ceil(fn(value));\n },\n yv: function (d) {\n var $$ = this;\n var _a = $$.scale, y = _a.y, y2 = _a.y2;\n var yScale = d.axis && d.axis === \"y2\" ? y2 : y;\n return Math.ceil(yScale($$.getBaseValue(d)));\n },\n subxx: function (d) {\n return d ? this.scale.subX(d.x) : null;\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar shape = {\n /**\n * Get the shape draw function\n * @returns {object}\n * @private\n */\n getDrawShape: function () {\n var $$ = this;\n var isRotated = $$.config.axis_rotated;\n var _a = $$.state, hasRadar = _a.hasRadar, hasTreemap = _a.hasTreemap;\n var shape = { type: {}, indices: {}, pos: {} };\n !hasTreemap && [\"bar\", \"candlestick\", \"line\", \"area\"].forEach(function (v) {\n var name = capitalize(/^(bubble|scatter)$/.test(v) ? \"line\" : v);\n if ($$.hasType(v) || $$.hasTypeOf(name) || (v === \"line\" && ($$.hasType(\"bubble\") || $$.hasType(\"scatter\")))) {\n var indices = $$.getShapeIndices($$[\"is\".concat(name, \"Type\")]);\n var drawFn = $$[\"generateDraw\".concat(name)];\n shape.indices[v] = indices;\n shape.type[v] = drawFn ? drawFn.bind($$)(indices, false) : undefined;\n }\n });\n if (!$$.hasArcType() || hasRadar || hasTreemap) {\n var cx = void 0;\n var cy = void 0;\n // generate circle x/y functions depending on updated params\n if (!hasTreemap) {\n cx = hasRadar ? $$.radarCircleX : (isRotated ? $$.circleY : $$.circleX);\n cy = hasRadar ? $$.radarCircleY : (isRotated ? $$.circleX : $$.circleY);\n }\n shape.pos = {\n xForText: $$.generateXYForText(shape.indices, true),\n yForText: $$.generateXYForText(shape.indices, false),\n cx: (cx || function () { }).bind($$),\n cy: (cy || function () { }).bind($$)\n };\n }\n return shape;\n },\n /**\n * Get shape's indices according it's position\n *\n * From the below example, indices will be:\n * ==> {data1: 0, data2: 0, data3: 1, data4: 1, __max__: 1}\n *\n *\tdata1 data3 data1 data3\n *\tdata2 data4 data2 data4\n *\t-------------------------\n *\t\t 0 1\n * @param {Function} typeFilter Chart type filter function\n * @returns {object} Indices object with its position\n */\n getShapeIndices: function (typeFilter) {\n var $$ = this;\n var config = $$.config;\n var xs = config.data_xs;\n var hasXs = notEmpty(xs);\n var indices = {};\n var i = hasXs ? {} : 0;\n if (hasXs) {\n getUnique(Object.keys(xs).map(function (v) { return xs[v]; }))\n .forEach(function (v) {\n i[v] = 0;\n indices[v] = {};\n });\n }\n $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))\n .forEach(function (d) {\n var xKey = d.id in xs ? xs[d.id] : \"\";\n var ind = xKey ? indices[xKey] : indices;\n for (var j = 0, groups = void 0; (groups = config.data_groups[j]); j++) {\n if (groups.indexOf(d.id) < 0) {\n continue;\n }\n for (var k = 0, row = void 0; (row = groups[k]); k++) {\n if (row in ind) {\n ind[d.id] = ind[row];\n break;\n }\n }\n }\n if (isUndefined(ind[d.id])) {\n ind[d.id] = xKey ? i[xKey]++ : i++;\n ind.__max__ = (xKey ? i[xKey] : i) - 1;\n }\n });\n return indices;\n },\n /**\n * Get indices value based on data ID value\n * @param {object} indices Indices object\n * @param {object} d Data row\n * @param {string} caller Caller function name (Used only for 'sparkline' plugin)\n * @returns {object} Indices object\n * @private\n */\n getIndices: function (indices, d, caller) {\n var $$ = this;\n var _a = $$.config, xs = _a.data_xs, removeNull = _a.bar_indices_removeNull;\n var id = d.id, index = d.index;\n if ($$.isBarType(id) && removeNull) {\n var ind_1 = {};\n // redefine bar indices order\n $$.getAllValuesOnIndex(index, true)\n .forEach(function (v, i) {\n ind_1[v.id] = i;\n ind_1.__max__ = i;\n });\n return ind_1;\n }\n return notEmpty(xs) ?\n indices[xs[id]] : indices;\n },\n /**\n * Get indices max number\n * @param {object} indices Indices object\n * @returns {number} Max number\n * @private\n */\n getIndicesMax: function (indices) {\n return notEmpty(this.config.data_xs) ?\n // if is multiple xs, return total sum of xs' __max__ value\n Object.keys(indices)\n .map(function (v) { return indices[v].__max__ || 0; })\n .reduce(function (acc, curr) { return acc + curr; }) : indices.__max__;\n },\n getShapeX: function (offset, indices, isSub) {\n var $$ = this;\n var config = $$.config, scale = $$.scale;\n var currScale = isSub ? scale.subX : (scale.zoom || scale.x);\n var barOverlap = config.bar_overlap;\n var barPadding = config.bar_padding;\n var sum = function (p, c) { return p + c; };\n // total shapes half width\n var halfWidth = isObjectType(offset) && (offset._$total.length ? offset._$total.reduce(sum) / 2 : 0);\n return function (d) {\n var ind = $$.getIndices(indices, d, \"getShapeX\");\n var index = d.id in ind ? ind[d.id] : 0;\n var targetsNum = (ind.__max__ || 0) + 1;\n var x = 0;\n if (notEmpty(d.x)) {\n var xPos = currScale(d.x, true);\n if (halfWidth) {\n var offsetWidth = offset[d.id] || offset._$width;\n x = barOverlap ?\n xPos - offsetWidth / 2 :\n xPos - offsetWidth + offset._$total.slice(0, index + 1).reduce(sum) - halfWidth;\n }\n else {\n x = xPos - (isNumber(offset) ? offset : offset._$width) *\n (targetsNum / 2 - (barOverlap ? 1 : index));\n }\n }\n // adjust x position for bar.padding option\n if (offset && x && targetsNum > 1 && barPadding) {\n if (index) {\n x += barPadding * index;\n }\n if (targetsNum > 2) {\n x -= (targetsNum - 1) * barPadding / 2;\n }\n else if (targetsNum === 2) {\n x -= barPadding / 2;\n }\n }\n return x;\n };\n },\n getShapeY: function (isSub) {\n var $$ = this;\n var isStackNormalized = $$.isStackNormalized();\n return function (d) {\n var value = d.value;\n if (isNumber(d)) {\n value = d;\n }\n else if (isStackNormalized) {\n value = $$.getRatio(\"index\", d, true);\n }\n else if ($$.isBubbleZType(d)) {\n value = $$.getBubbleZData(d.value, \"y\");\n }\n else if ($$.isBarRangeType(d)) {\n // TODO use range.getEnd() like method\n value = value[1];\n }\n return $$.getYScaleById(d.id, isSub)(value);\n };\n },\n /**\n * Get shape based y Axis min value\n * @param {string} id Data id\n * @returns {number}\n * @private\n */\n getShapeYMin: function (id) {\n var $$ = this;\n var axisId = $$.axis.getId(id);\n var scale = $$.scale[axisId];\n var yMin = scale.domain()[0];\n var inverted = $$.config[\"axis_\".concat(axisId, \"_inverted\")];\n return !$$.isGrouped(id) && !inverted && yMin > 0 ? yMin : 0;\n },\n /**\n * Get Shape's offset data\n * @param {Function} typeFilter Type filter function\n * @returns {object}\n * @private\n */\n getShapeOffsetData: function (typeFilter) {\n var $$ = this;\n var targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)));\n var isStackNormalized = $$.isStackNormalized();\n var shapeOffsetTargets = targets.map(function (target) {\n var rowValues = target.values;\n var values = {};\n if ($$.isStepType(target)) {\n rowValues = $$.convertValuesToStep(rowValues);\n }\n var rowValueMapByXValue = rowValues.reduce(function (out, d) {\n var key = Number(d.x);\n out[key] = d;\n values[key] = isStackNormalized ? $$.getRatio(\"index\", d, true) : d.value;\n return out;\n }, {});\n return {\n id: target.id,\n rowValues: rowValues,\n rowValueMapByXValue: rowValueMapByXValue,\n values: values\n };\n });\n var indexMapByTargetId = targets.reduce(function (out, _a, index) {\n var id = _a.id;\n out[id] = index;\n return out;\n }, {});\n return { indexMapByTargetId: indexMapByTargetId, shapeOffsetTargets: shapeOffsetTargets };\n },\n getShapeOffset: function (typeFilter, indices, isSub) {\n var $$ = this;\n var _a = $$.getShapeOffsetData(typeFilter), shapeOffsetTargets = _a.shapeOffsetTargets, indexMapByTargetId = _a.indexMapByTargetId;\n var groupsZeroAs = $$.config.data_groupsZeroAs;\n return function (d, idx) {\n var id = d.id, value = d.value, x = d.x;\n var ind = $$.getIndices(indices, d);\n var scale = $$.getYScaleById(id, isSub);\n if ($$.isBarRangeType(d)) {\n // TODO use range.getStart()\n return scale(value[0]);\n }\n var dataXAsNumber = Number(x);\n var y0 = scale(groupsZeroAs === \"zero\" ? 0 : $$.getShapeYMin(id));\n var offset = y0;\n shapeOffsetTargets\n .filter(function (t) { return t.id !== id && ind[t.id] === ind[id]; })\n .forEach(function (t) {\n var tid = t.id, rowValueMapByXValue = t.rowValueMapByXValue, rowValues = t.rowValues, tvalues = t.values;\n // for same stacked group (ind[tid] === ind[id])\n if (indexMapByTargetId[tid] < indexMapByTargetId[id]) {\n var rValue = tvalues[dataXAsNumber];\n var row = rowValues[idx];\n // check if the x values line up\n if (!row || Number(row.x) !== dataXAsNumber) {\n row = rowValueMapByXValue[dataXAsNumber];\n }\n if ((row === null || row === void 0 ? void 0 : row.value) * value >= 0 && isNumber(rValue)) {\n var addOffset = value === 0 ? ((groupsZeroAs === \"positive\" && rValue > 0) ||\n (groupsZeroAs === \"negative\" && rValue < 0)) : true;\n if (addOffset) {\n offset += scale(rValue) - y0;\n }\n }\n }\n });\n return offset;\n };\n },\n getBarW: function (type, axis, targetsNum) {\n var $$ = this;\n var config = $$.config, org = $$.org, scale = $$.scale;\n var maxDataCount = $$.getMaxDataCount();\n var isGrouped = type === \"bar\" && config.data_groups.length;\n var configName = \"\".concat(type, \"_width\");\n var tickInterval = scale.zoom && !$$.axis.isCategorized() ?\n (org.xDomain.map(function (v) { return scale.zoom(v); })\n .reduce(function (a, c) { return Math.abs(a) + c; }) / maxDataCount) : axis.tickInterval(maxDataCount);\n var getWidth = function (id) {\n var width = id ? config[configName][id] : config[configName];\n var ratio = id ? width.ratio : config[\"\".concat(configName, \"_ratio\")];\n var max = id ? width.max : config[\"\".concat(configName, \"_max\")];\n var w = isNumber(width) ?\n width : targetsNum ? (tickInterval * ratio) / targetsNum : 0;\n return max && w > max ? max : w;\n };\n var result = getWidth();\n if (!isGrouped && isObjectType(config[configName])) {\n result = { _$width: result, _$total: [] };\n $$.filterTargetsToShow($$.data.targets).forEach(function (v) {\n if (config[configName][v.id]) {\n result[v.id] = getWidth(v.id);\n result._$total.push(result[v.id] || result._$width);\n }\n });\n }\n return result;\n },\n /**\n * Get shape element\n * @param {string} shapeName Shape string\n * @param {number} i Index number\n * @param {string} id Data series id\n * @returns {d3Selection}\n * @private\n */\n getShapeByIndex: function (shapeName, i, id) {\n var $$ = this;\n var $el = $$.$el;\n var suffix = (isValue(i) ? \"-\".concat(i) : \"\");\n var shape = $el[shapeName];\n // filter from shape reference if has\n if (shape && !shape.empty()) {\n shape = shape\n .filter(function (d) { return (id ? d.id === id : true); })\n .filter(function (d) { return (isValue(i) ? d.index === i : true); });\n }\n else {\n shape = (id ? $el.main\n .selectAll(\".\".concat(CLASS[\"\".concat(shapeName, \"s\")]).concat($$.getTargetSelectorSuffix(id))) : $el.main)\n .selectAll(\".\".concat(CLASS[shapeName]).concat(suffix));\n }\n return shape;\n },\n isWithinShape: function (that, d) {\n var _a;\n var $$ = this;\n var shape = select(that);\n var isWithin;\n if (!$$.isTargetToShow(d.id)) {\n isWithin = false;\n }\n else if ((_a = $$.hasValidPointType) === null || _a === void 0 ? void 0 : _a.call($$, that.nodeName)) {\n isWithin = $$.isStepType(d) ?\n $$.isWithinStep(that, $$.getYScaleById(d.id)(d.value)) :\n $$.isWithinCircle(that, $$.isBubbleType(d) ? $$.pointSelectR(d) * 1.5 : 0);\n }\n else if (that.nodeName === \"path\") {\n isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar(that) : true;\n }\n return isWithin;\n },\n getInterpolate: function (d) {\n var $$ = this;\n var interpolation = $$.getInterpolateType(d);\n return {\n \"basis\": curveBasis,\n \"basis-closed\": curveBasisClosed,\n \"basis-open\": curveBasisOpen,\n \"bundle\": curveBundle,\n \"cardinal\": curveCardinal,\n \"cardinal-closed\": curveCardinalClosed,\n \"cardinal-open\": curveCardinalOpen,\n \"catmull-rom\": curveCatmullRom,\n \"catmull-rom-closed\": curveCatmullRomClosed,\n \"catmull-rom-open\": curveCatmullRomOpen,\n \"monotone-x\": curveMonotoneX,\n \"monotone-y\": curveMonotoneY,\n \"natural\": curveNatural,\n \"linear-closed\": curveLinearClosed,\n \"linear\": curveLinear,\n \"step\": curveStep,\n \"step-after\": curveStepAfter,\n \"step-before\": curveStepBefore\n }[interpolation];\n },\n getInterpolateType: function (d) {\n var $$ = this;\n var config = $$.config;\n var type = config.spline_interpolation_type;\n var interpolation = $$.isInterpolationType(type) ? type : \"cardinal\";\n return $$.isSplineType(d) ?\n interpolation : ($$.isStepType(d) ?\n config.line_step_type : \"linear\");\n },\n isWithinBar: function (that) {\n var mouse = getPointer(this.state.event, that);\n var list = getRectSegList(that);\n var seg0 = list[0], seg1 = list[1];\n var x = Math.min(seg0.x, seg1.x);\n var y = Math.min(seg0.y, seg1.y);\n var offset = this.config.bar_sensitivity;\n var _a = that.getBBox(), width = _a.width, height = _a.height;\n var sx = x - offset;\n var ex = x + width + offset;\n var sy = y + height + offset;\n var ey = y - offset;\n var isWithin = sx < mouse[0] &&\n mouse[0] < ex &&\n ey < mouse[1] &&\n mouse[1] < sy;\n return isWithin;\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar size = {\n /**\n * Update container size\n * @private\n */\n setContainerSize: function () {\n var $$ = this;\n var state = $$.state;\n state.current.width = $$.getCurrentWidth();\n state.current.height = $$.getCurrentHeight();\n },\n getCurrentWidth: function () {\n var $$ = this;\n return $$.config.size_width || $$.getParentWidth();\n },\n getCurrentHeight: function () {\n var $$ = this;\n var config = $$.config;\n var h = config.size_height || $$.getParentHeight();\n return h > 0 ? h : 320 / ($$.hasType(\"gauge\") && !config.gauge_fullCircle ? 2 : 1);\n },\n getCurrentPaddingTop: function () {\n var $$ = this;\n var config = $$.config, hasAxis = $$.state.hasAxis, $el = $$.$el;\n var axesLen = hasAxis ? config.axis_y2_axes.length : 0;\n var padding = isValue(config.padding_top) ?\n config.padding_top : 0;\n if ($el.title && $el.title.node()) {\n padding += $$.getTitlePadding();\n }\n if (axesLen && config.axis_rotated) {\n padding += $$.getHorizontalAxisHeight(\"y2\") * axesLen;\n }\n return padding;\n },\n getCurrentPaddingBottom: function () {\n var $$ = this;\n var config = $$.config, hasAxis = $$.state.hasAxis;\n var axisId = config.axis_rotated ? \"y\" : \"x\";\n var axesLen = hasAxis ? config[\"axis_\".concat(axisId, \"_axes\")].length : 0;\n var padding = isValue(config.padding_bottom) ?\n config.padding_bottom : 0;\n return padding + (axesLen ? $$.getHorizontalAxisHeight(axisId) * axesLen : 0);\n },\n getCurrentPaddingLeft: function (withoutRecompute) {\n var $$ = this;\n var config = $$.config, hasAxis = $$.state.hasAxis;\n var isRotated = config.axis_rotated;\n var axisId = isRotated ? \"x\" : \"y\";\n var axesLen = hasAxis ? config[\"axis_\".concat(axisId, \"_axes\")].length : 0;\n var axisWidth = hasAxis ? $$.getAxisWidthByAxisId(axisId, withoutRecompute) : 0;\n var padding;\n if (isValue(config.padding_left)) {\n padding = config.padding_left;\n }\n else if (hasAxis && isRotated) {\n padding = !config.axis_x_show ?\n 1 : Math.max(ceil10(axisWidth), 40);\n }\n else if (hasAxis && (!config.axis_y_show || config.axis_y_inner)) { // && !config.axis_rotated\n padding = $$.axis.getAxisLabelPosition(\"y\").isOuter ? 30 : 1;\n }\n else {\n padding = ceil10(axisWidth);\n }\n return padding + (axisWidth * axesLen);\n },\n getCurrentPaddingRight: function (withXAxisTickTextOverflow) {\n if (withXAxisTickTextOverflow === void 0) { withXAxisTickTextOverflow = false; }\n var $$ = this;\n var config = $$.config, hasAxis = $$.state.hasAxis;\n var defaultPadding = 10;\n var legendWidthOnRight = $$.state.isLegendRight ? $$.getLegendWidth() + 20 : 0;\n var axesLen = hasAxis ? config.axis_y2_axes.length : 0;\n var axisWidth = hasAxis ? $$.getAxisWidthByAxisId(\"y2\") : 0;\n var xAxisTickTextOverflow = withXAxisTickTextOverflow ?\n $$.axis.getXAxisTickTextY2Overflow(defaultPadding) : 0;\n var padding;\n if (isValue(config.padding_right)) {\n padding = config.padding_right + (hasAxis ? 1 : 0); // 1 is needed not to hide tick line\n }\n else if ($$.axis && config.axis_rotated) {\n padding = defaultPadding + legendWidthOnRight;\n }\n else if ($$.axis && (!config.axis_y2_show || config.axis_y2_inner)) { // && !config.axis_rotated\n padding = Math.max(2 + legendWidthOnRight + ($$.axis.getAxisLabelPosition(\"y2\").isOuter ? 20 : 0), xAxisTickTextOverflow);\n }\n else {\n padding = Math.max(ceil10(axisWidth) + legendWidthOnRight, xAxisTickTextOverflow);\n }\n return padding + (axisWidth * axesLen);\n },\n /**\n * Get the parent rect element's size\n * @param {string} key property/attribute name\n * @returns {number}\n * @private\n */\n getParentRectValue: function (key) {\n var offsetName = \"offset\".concat(capitalize(key));\n var parent = this.$el.chart.node();\n var v = 0;\n while (v < 30 && parent && parent.tagName !== \"BODY\") {\n try {\n v = parent.getBoundingClientRect()[key];\n }\n catch (e) {\n if (offsetName in parent) {\n // In IE in certain cases getBoundingClientRect\n // will cause an \"unspecified error\"\n v = parent[offsetName];\n }\n }\n parent = parent.parentNode;\n }\n // Sometimes element's dimension value is incorrect(ex. flex container)\n // In this case, use body's offset instead.\n var bodySize = doc.body[offsetName];\n v > bodySize && (v = bodySize);\n return v;\n },\n getParentWidth: function () {\n return this.getParentRectValue(\"width\");\n },\n getParentHeight: function () {\n var h = this.$el.chart.style(\"height\");\n var height = 0;\n if (h) {\n height = /px$/.test(h) ?\n parseInt(h, 10) :\n this.getParentRectValue(\"height\");\n }\n return height;\n },\n getSvgLeft: function (withoutRecompute) {\n var $$ = this;\n var config = $$.config, $el = $$.$el;\n var hasLeftAxisRect = config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner);\n var leftAxisClass = config.axis_rotated ? $AXIS.axisX : $AXIS.axisY;\n var leftAxis = $el.main.select(\".\".concat(leftAxisClass)).node();\n var svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : { right: 0 };\n var chartRect = $el.chart.node().getBoundingClientRect();\n var hasArc = $$.hasArcType();\n var svgLeft = svgRect.right - chartRect.left -\n (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));\n return svgLeft > 0 ? svgLeft : 0;\n },\n updateDimension: function (withoutAxis) {\n var _a;\n var $$ = this;\n var config = $$.config, hasAxis = $$.state.hasAxis, $el = $$.$el;\n if (hasAxis && !withoutAxis && $$.axis.x && config.axis_rotated) {\n (_a = $$.axis.subX) === null || _a === void 0 ? void 0 : _a.create($el.axis.subX);\n }\n // pass 'withoutAxis' param to not animate at the init rendering\n $$.updateScales(withoutAxis);\n $$.updateSvgSize();\n $$.transformAll(false);\n },\n updateSvgSize: function () {\n var $$ = this;\n var _a = $$.state, clip = _a.clip, current = _a.current, hasAxis = _a.hasAxis, width = _a.width, height = _a.height, svg = $$.$el.svg;\n svg\n .attr(\"width\", current.width)\n .attr(\"height\", current.height);\n if (hasAxis) {\n var brush = svg.select(\".\".concat($SUBCHART.brush, \" .overlay\"));\n var brushSize = { width: 0, height: 0 };\n if (brush.size()) {\n brushSize.width = +brush.attr(\"width\");\n brushSize.height = +brush.attr(\"height\");\n }\n svg.selectAll([\"#\".concat(clip.id), \"#\".concat(clip.idGrid)])\n .select(\"rect\")\n .attr(\"width\", width)\n .attr(\"height\", height);\n svg.select(\"#\".concat(clip.idXAxis))\n .select(\"rect\")\n .call($$.setXAxisClipPath.bind($$));\n svg.select(\"#\".concat(clip.idYAxis))\n .select(\"rect\")\n .call($$.setYAxisClipPath.bind($$));\n clip.idSubchart && svg.select(\"#\".concat(clip.idSubchart))\n .select(\"rect\")\n .attr(\"width\", width)\n .attr(\"height\", brushSize.height);\n }\n },\n getCurrentPadding: function () {\n var $$ = this;\n return {\n top: $$.getCurrentPaddingTop(),\n bottom: $$.getCurrentPaddingBottom(),\n left: $$.getCurrentPaddingLeft(),\n right: $$.getCurrentPaddingRight()\n };\n },\n /**\n * Get resetted padding values when 'padding=false' option is set\n * https://github.com/naver/billboard.js/issues/2367\n * @param {number|object} v Padding values to be resetted\n * @returns {number|object} Padding value\n * @private\n */\n getResettedPadding: function (v) {\n var $$ = this;\n var config = $$.config;\n var isNum = isNumber(v);\n var p = isNum ? 0 : {};\n if (config.padding === false) {\n !isNum && Object.keys(v).forEach(function (key) {\n // when data.lables=true, do not reset top padding\n p[key] = (!isEmpty(config.data_labels) &&\n config.data_labels !== false &&\n key === \"top\") ? v[key] : 0;\n });\n }\n else {\n p = v;\n }\n return p;\n },\n /**\n * Update size values\n * @param {boolean} isInit If is called at initialization\n * @private\n */\n updateSizes: function (isInit) {\n var _a, _b;\n var $$ = this;\n var config = $$.config, state = $$.state, legend = $$.$el.legend;\n var isRotated = config.axis_rotated;\n var isNonAxis = $$.hasArcType() || state.hasTreemap;\n !isInit && $$.setContainerSize();\n var currLegend = {\n width: legend ? $$.getLegendWidth() : 0,\n height: legend ? $$.getLegendHeight() : 0\n };\n if (!isNonAxis && config.axis_x_show && config.axis_x_tick_autorotate) {\n $$.updateXAxisTickClip();\n }\n var legendHeightForBottom = state.isLegendRight || state.isLegendInset ? 0 : currLegend.height;\n var xAxisHeight = isRotated || isNonAxis ? 0 : $$.getHorizontalAxisHeight(\"x\");\n var subchartXAxisHeight = config.subchart_axis_x_show && config.subchart_axis_x_tick_text_show ?\n xAxisHeight : 30;\n var subchartHeight = config.subchart_show && !isNonAxis ?\n (config.subchart_size_height + subchartXAxisHeight) : 0;\n var padding = $$.getCurrentPadding();\n // for main\n state.margin = !isNonAxis && isRotated ? {\n top: $$.getHorizontalAxisHeight(\"y2\") + padding.top,\n right: isNonAxis ? 0 : $$.getCurrentPaddingRight(true),\n bottom: $$.getHorizontalAxisHeight(\"y\") + legendHeightForBottom + padding.bottom,\n left: subchartHeight + (isNonAxis ? 0 : padding.left)\n } : {\n top: 4 + padding.top,\n right: isNonAxis ? 0 : $$.getCurrentPaddingRight(true),\n bottom: xAxisHeight + subchartHeight + legendHeightForBottom + padding.bottom,\n left: isNonAxis ? 0 : padding.left\n };\n state.margin = $$.getResettedPadding(state.margin);\n // for subchart\n state.margin2 = isRotated ? {\n top: state.margin.top,\n right: NaN,\n bottom: 20 + legendHeightForBottom,\n left: $$.state.rotatedPadding.left\n } : {\n top: state.current.height - subchartHeight - legendHeightForBottom,\n right: NaN,\n bottom: subchartXAxisHeight + legendHeightForBottom,\n left: state.margin.left\n };\n // for legend\n state.margin3 = {\n top: 0,\n right: NaN,\n bottom: 0,\n left: 0\n };\n (_a = $$.updateSizeForLegend) === null || _a === void 0 ? void 0 : _a.call($$, currLegend);\n state.width = state.current.width - state.margin.left - state.margin.right;\n state.height = state.current.height - state.margin.top - state.margin.bottom;\n if (state.width < 0) {\n state.width = 0;\n }\n if (state.height < 0) {\n state.height = 0;\n }\n state.width2 = isRotated ?\n state.margin.left - state.rotatedPadding.left - state.rotatedPadding.right : state.width;\n state.height2 = isRotated ?\n state.height : state.current.height - state.margin2.top - state.margin2.bottom;\n if (state.width2 < 0) {\n state.width2 = 0;\n }\n if (state.height2 < 0) {\n state.height2 = 0;\n }\n // for arc\n if ($$.hasArcType()) {\n var hasGauge = $$.hasType(\"gauge\");\n var isLegendRight = config.legend_show && state.isLegendRight;\n state.arcWidth = state.width - (isLegendRight ? currLegend.width + 10 : 0);\n state.arcHeight = state.height - (isLegendRight && !hasGauge ? 0 : 10);\n if (hasGauge && !config.gauge_fullCircle) {\n state.arcHeight += state.height - $$.getPaddingBottomForGauge();\n }\n (_b = $$.updateRadius) === null || _b === void 0 ? void 0 : _b.call($$);\n }\n if (state.isLegendRight && isNonAxis) {\n state.margin3.left = state.arcWidth / 2 + state.radiusExpanded * 1.1;\n }\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar style = {\n /**\n * Add props color css rule to given selector\n * @param {boolean} withShape Set shpes' prefix class\n * @param {string} selector CSS selector\n * @param {Array} props CSS props list\n * @param {Function} propsFn Function to retrieve value or determine for props\n * @returns {Function}\n * @private\n */\n setCssRule: function (withShape, selector, props, propsFn) {\n var $$ = this;\n var config = $$.config, _a = $$.state, cssRule = _a.cssRule, style = _a.style;\n return config.boost_useCssRule ? function (selection) {\n selection.each(function (d) {\n var res = propsFn && (propsFn === null || propsFn === void 0 ? void 0 : propsFn.call($$, d));\n var shapeSelector = \"\".concat(withShape ? \".\".concat($SHAPE.shapes + $$.getTargetSelectorSuffix(d.id)) : \"\").concat(selector);\n (selector in cssRule) && style.sheet.deleteRule(cssRule[shapeSelector]);\n $$.state.cssRule[shapeSelector] = addCssRules(style, shapeSelector, props.filter(Boolean).map(function (v) { return (isString(res) && v.indexOf(\":\") === -1 ? \"\".concat(v, \": \").concat(res) : (v || \"\")); }));\n });\n } : function () { };\n },\n /**\n * Get style prop value\n * @param {Function|string} v Value\n * @returns {string|null}\n * @private\n */\n getStylePropValue: function (v) {\n var useCssRule = this.config.boost_useCssRule;\n return useCssRule ? null : isFunction(v) ? v.bind(this) : v;\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Get text-anchor according text.labels.rotate angle\n * @param {number} angle Angle value\n * @returns {string} Anchor string value\n * @private\n */\nfunction getRotateAnchor(angle) {\n var anchor = \"middle\";\n if (angle > 0 && angle <= 170) {\n anchor = \"end\";\n }\n else if (angle > 190 && angle <= 360) {\n anchor = \"start\";\n }\n return anchor;\n}\n/**\n * Set rotated position coordinate according text.labels.rotate angle\n * @param {object} d Data object\n * @param {object} pos Position object\n * @param {object} pos.x x coordinate\n * @param {object} pos.y y coordinate\n * @param {string} anchor string value\n * @param {boolean} isRotated If axis is rotated\n * @param {boolean} isInverted If axis is inverted\n * @returns {object} x, y coordinate\n * @private\n */\nfunction setRotatePos(d, pos, anchor, isRotated, isInverted) {\n var _a;\n var $$ = this;\n var value = d.value;\n var isCandlestickType = $$.isCandlestickType(d);\n var isNegative = (isNumber(value) && value < 0) || (isCandlestickType && !((_a = $$.getCandlestickData(d)) === null || _a === void 0 ? void 0 : _a._isUp));\n var x = pos.x, y = pos.y;\n var gap = 4;\n var doubleGap = gap * 2;\n if (isRotated) {\n if (anchor === \"start\") {\n x += isNegative ? 0 : doubleGap;\n y += gap;\n }\n else if (anchor === \"middle\") {\n x += doubleGap;\n y -= doubleGap;\n }\n else if (anchor === \"end\") {\n isNegative && (x -= doubleGap);\n y += gap;\n }\n }\n else {\n if (anchor === \"start\") {\n x += gap;\n isNegative && (y += doubleGap * 2);\n }\n else if (anchor === \"middle\") {\n y -= doubleGap;\n }\n else if (anchor === \"end\") {\n x -= gap;\n isNegative && (y += doubleGap * 2);\n }\n if (isInverted) {\n y += isNegative ? -17 : (isCandlestickType ? 13 : 7);\n }\n }\n return { x: x, y: y };\n}\nvar text = {\n opacityForText: function (d) {\n var $$ = this;\n return $$.isBarType(d) && !$$.meetsLabelThreshold(Math.abs($$.getRatio(\"bar\", d)), \"bar\") ? \"0\" : ($$.hasDataLabel ? null : \"0\");\n },\n /**\n * Initializes the text\n * @private\n */\n initText: function () {\n var $el = this.$el;\n $el.main.select(\".\".concat($COMMON.chart)).append(\"g\")\n .attr(\"class\", $TEXT.chartTexts)\n .style(\"pointer-events\", $el.treemap ? \"none\" : null);\n },\n /**\n * Update chartText\n * @param {object} targets $$.data.targets\n * @private\n */\n updateTargetsForText: function (targets) {\n var $$ = this;\n var classChartText = $$.getChartClass(\"Text\");\n var classTexts = $$.getClass(\"texts\", \"id\");\n var classFocus = $$.classFocus.bind($$);\n var mainTextUpdate = $$.$el.main.select(\".\".concat($TEXT.chartTexts))\n .selectAll(\".\".concat($TEXT.chartText))\n .data(targets)\n .attr(\"class\", function (d) { return \"\".concat(classChartText(d)).concat(classFocus(d)).trim(); });\n var mainTextEnter = mainTextUpdate.enter().append(\"g\")\n .style(\"opacity\", \"0\")\n .attr(\"class\", classChartText)\n .call($$.setCssRule(true, \" .\".concat($TEXT.text), [\"fill\", \"pointer-events:none\"], $$.updateTextColor));\n mainTextEnter.append(\"g\")\n .attr(\"class\", classTexts);\n },\n /**\n * Update text\n * @private\n */\n updateText: function () {\n var $$ = this;\n var $el = $$.$el, $T = $$.$T, config = $$.config, axis = $$.axis;\n var classText = $$.getClass(\"text\", \"index\");\n var labelsCentered = config.data_labels.centered;\n var text = $el.main.selectAll(\".\".concat($TEXT.texts))\n .selectAll(\".\".concat($TEXT.text))\n .data($$.labelishData.bind($$));\n $T(text.exit())\n .style(\"fill-opacity\", \"0\")\n .remove();\n $el.text = text.enter()\n .append(\"text\")\n .merge(text)\n .attr(\"class\", classText)\n .attr(\"text-anchor\", function (d) {\n var isInverted = config[\"axis_\".concat(axis === null || axis === void 0 ? void 0 : axis.getId(d.id), \"_inverted\")];\n // when value is negative or\n var isEndAnchor = isInverted ? d.value > 0 : d.value < 0;\n if ($$.isCandlestickType(d)) {\n var data = $$.getCandlestickData(d);\n isEndAnchor = !(data === null || data === void 0 ? void 0 : data._isUp);\n }\n else if ($$.isTreemapType(d)) {\n return labelsCentered ? \"middle\" : \"start\";\n }\n return (config.axis_rotated ? (isEndAnchor ? \"end\" : \"start\") : \"middle\");\n })\n .style(\"fill\", $$.getStylePropValue($$.updateTextColor))\n .style(\"fill-opacity\", \"0\")\n .each(function (d, i, texts) {\n var node = select(this);\n var value = d.value;\n if ($$.isBubbleZType(d)) {\n value = $$.getBubbleZData(value, \"z\");\n }\n else if ($$.isCandlestickType(d)) {\n var data = $$.getCandlestickData(d);\n if (data) {\n value = data.close;\n }\n }\n value = $$.isTreemapType(d) ? $$.treemapDataLabelFormat(d)(node) :\n $$.dataLabelFormat(d.id)(value, d.id, i, texts);\n if (isNumber(value)) {\n this.textContent = value;\n }\n else {\n setTextValue(node, value);\n }\n });\n },\n updateTextColor: function (d) {\n var $$ = this;\n var config = $$.config;\n var labelColors = config.data_labels_colors;\n var defaultColor = ($$.isArcType(d) && !$$.isRadarType(d)) || $$.isTreemapType(d) ?\n null : $$.color(d);\n var color;\n if (isString(labelColors)) {\n color = labelColors;\n }\n else if (isObject(labelColors)) {\n var id = (d.data || d).id;\n color = labelColors[id];\n }\n else if (isFunction(labelColors)) {\n color = labelColors.bind($$.api)(defaultColor, d);\n }\n if ($$.isCandlestickType(d) && !isFunction(labelColors)) {\n var value = $$.getCandlestickData(d);\n if (!(value === null || value === void 0 ? void 0 : value._isUp)) {\n var downColor = config.candlestick_color_down;\n color = isObject(downColor) ? downColor[d.id] : downColor;\n }\n }\n return color || defaultColor;\n },\n /**\n * Update data label text background color\n * @param {object} d Data object\n * @returns {string|null}\n * @private\n */\n updateTextBacgroundColor: function (d) {\n var $$ = this;\n var $el = $$.$el, config = $$.config;\n var backgroundColor = config.data_labels_backgroundColors;\n var color = \"\";\n if (isString(backgroundColor) || isObject(backgroundColor)) {\n var id = isString(backgroundColor) ? \"\" : $$.getTargetSelectorSuffix((\"id\" in d ? d.id : d.data.id));\n var filter = $el.defs.select([\"filter[id*='labels-bg\", \"']\"].join(id));\n if (filter.size()) {\n color = \"url(#\".concat(filter.attr(\"id\"), \")\");\n }\n }\n return color || null;\n },\n /**\n * Redraw chartText\n * @param {Function} getX Positioning function for x\n * @param {Function} getY Positioning function for y\n * @param {boolean} forFlow Weather is flow\n * @param {boolean} withTransition transition is enabled\n * @returns {Array}\n * @private\n */\n redrawText: function (getX, getY, forFlow, withTransition) {\n var $$ = this;\n var $T = $$.$T, axis = $$.axis, config = $$.config, hasTreemap = $$.state.hasTreemap;\n var t = getRandom(true);\n var isRotated = config.axis_rotated;\n var angle = config.data_labels.rotate;\n var anchorString = getRotateAnchor(angle);\n var rotateString = angle ? \"rotate(\".concat(angle, \")\") : \"\";\n // $$.meetsLabelThreshold(ratio,\n $$.$el.text\n .style(\"fill\", $$.getStylePropValue($$.updateTextColor))\n .attr(\"filter\", $$.updateTextBacgroundColor.bind($$))\n .style(\"fill-opacity\", forFlow ? 0 : $$.opacityForText.bind($$))\n .each(function (d, i) {\n // do not apply transition for newly added text elements\n var node = $T(hasTreemap && this.childElementCount ? this.parentNode : this, !!(withTransition && this.getAttribute(\"x\")), t);\n var isInverted = config[\"axis_\".concat(axis === null || axis === void 0 ? void 0 : axis.getId(d.id), \"_inverted\")];\n var pos = {\n x: getX.bind(this)(d, i),\n y: getY.bind(this)(d, i)\n };\n if (angle) {\n pos = setRotatePos.bind($$)(d, pos, anchorString, isRotated, isInverted);\n node.attr(\"text-anchor\", anchorString);\n }\n // when is multiline\n if (this.childElementCount || angle) {\n node.attr(\"transform\", \"translate(\".concat(pos.x, \" \").concat(pos.y, \") \").concat(rotateString));\n }\n else {\n node.attr(\"x\", pos.x).attr(\"y\", pos.y);\n }\n });\n // need to return 'true' as of being pushed to the redraw list\n // ref: getRedrawList()\n return true;\n },\n /**\n * Gets the getBoundingClientRect value of the element\n * @param {HTMLElement|d3.selection} element Target element\n * @param {string} className Class name\n * @returns {object} value of element.getBoundingClientRect()\n * @private\n */\n getTextRect: function (element, className) {\n var $$ = this;\n var base = (element.node ? element.node() : element);\n if (!/text/i.test(base.tagName)) {\n base = base.querySelector(\"text\");\n }\n var text = base.textContent;\n var cacheKey = \"\".concat(KEY.textRect, \"-\").concat(text.replace(/\\W/g, \"_\"));\n var rect = $$.cache.get(cacheKey);\n if (!rect) {\n $$.$el.svg.append(\"text\")\n .style(\"visibility\", \"hidden\")\n .style(\"font\", select(base).style(\"font\"))\n .classed(className, true)\n .text(text)\n .call(function (v) {\n rect = getBoundingRect(v.node());\n })\n .remove();\n $$.cache.add(cacheKey, rect);\n }\n return rect;\n },\n /**\n * Gets the x or y coordinate of the text\n * @param {object} indices Indices values\n * @param {boolean} forX whether or not to x\n * @returns {number} coordinates\n * @private\n */\n generateXYForText: function (indices, forX) {\n var $$ = this;\n var _a = $$.state, hasRadar = _a.hasRadar, hasTreemap = _a.hasTreemap;\n var types = Object.keys(indices);\n var points = {};\n var getter = forX ? $$.getXForText : $$.getYForText;\n hasRadar && types.push(\"radar\");\n hasTreemap && types.push(\"treemap\");\n types.forEach(function (v) {\n points[v] = $$[\"generateGet\".concat(capitalize(v), \"Points\")](indices[v], false);\n });\n return function (d, i) {\n var type = ($$.isAreaType(d) && \"area\") ||\n ($$.isBarType(d) && \"bar\") ||\n ($$.isCandlestickType(d) && \"candlestick\") ||\n ($$.isRadarType(d) && \"radar\") ||\n ($$.isTreemapType(d) && \"treemap\") || \"line\";\n return getter.call($$, points[type](d, i), d, this);\n };\n },\n /**\n * Get centerized text position for bar type data.label.text\n * @param {object} d Data object\n * @param {Array} points Data points position\n * @param {HTMLElement} textElement Data label text element\n * @param {string} type 'x' or 'y'\n * @returns {number} Position value\n * @private\n */\n getCenteredTextPos: function (d, points, textElement, type) {\n var $$ = this;\n var config = $$.config;\n var isRotated = config.axis_rotated;\n var isBarType = $$.isBarType(d);\n var isTreemapType = $$.isTreemapType(d);\n if (config.data_labels.centered && (isBarType || isTreemapType)) {\n var rect = getBoundingRect(textElement);\n if (isBarType) {\n var isPositive = d.value >= 0;\n if (isRotated) {\n var w = (isPositive ?\n points[1][1] - points[0][1] :\n points[0][1] - points[1][1]) / 2 + (rect.width / 2);\n return isPositive ? -w - 3 : w + 2;\n }\n else {\n var h = (isPositive ?\n points[0][1] - points[1][1] :\n points[1][1] - points[0][1]) / 2 + (rect.height / 2);\n return isPositive ? h : -h - 2;\n }\n }\n else if (isTreemapType) {\n return type === \"x\" ?\n (points[1][0] - points[0][0]) / 2 :\n (points[1][1] - points[0][1]) / 2 + (rect.height / 2);\n }\n }\n return 0;\n },\n /**\n * Get data.labels.position value\n * @param {string} id Data id value\n * @param {string} type x | y\n * @returns {number} Position value\n * @private\n */\n getTextPos: function (id, type) {\n var pos = this.config.data_labels_position;\n return (id in pos ? pos[id] : pos)[type] || 0;\n },\n /**\n * Gets the x coordinate of the text\n * @param {object} points Data points position\n * @param {object} d Data object\n * @param {HTMLElement} textElement Data label text element\n * @returns {number} x coordinate\n * @private\n */\n getXForText: function (points, d, textElement) {\n var _a;\n var $$ = this;\n var config = $$.config, state = $$.state;\n var isRotated = config.axis_rotated;\n var isTreemapType = $$.isTreemapType(d);\n var xPos = points[0][0];\n if ($$.isCandlestickType(d)) {\n if (isRotated) {\n xPos = ((_a = $$.getCandlestickData(d)) === null || _a === void 0 ? void 0 : _a._isUp) ?\n points[2][2] + 4 : points[2][1] - 4;\n }\n else {\n xPos += (points[1][0] - xPos) / 2;\n }\n }\n else if (isTreemapType) {\n xPos += config.data_labels.centered ? 0 : 5;\n }\n else {\n if (isRotated) {\n var isInverted = config[\"axis_\".concat($$.axis.getId(d.id), \"_inverted\")];\n var padding = $$.isBarType(d) ? 4 : 6;\n var value = d.value;\n xPos = points[2][1];\n if (isInverted) {\n xPos -= padding * (value > 0 ? 1 : -1);\n }\n else {\n xPos += padding * (value < 0 ? -1 : 1);\n }\n }\n else {\n xPos = $$.hasType(\"bar\") ? (points[2][0] + points[0][0]) / 2 : xPos;\n }\n }\n // show labels regardless of the domain if value is null\n if (d.value === null) {\n if (xPos > state.width) {\n var width = getBoundingRect(textElement).width;\n xPos = state.width - width;\n }\n else if (xPos < 0) {\n xPos = 4;\n }\n }\n if (isRotated || isTreemapType) {\n xPos += $$.getCenteredTextPos(d, points, textElement, \"x\");\n }\n return xPos + $$.getTextPos(d.id, \"x\");\n },\n /**\n * Gets the y coordinate of the text\n * @param {object} points Data points position\n * @param {object} d Data object\n * @param {HTMLElement} textElement Data label text element\n * @returns {number} y coordinate\n * @private\n */\n getYForText: function (points, d, textElement) {\n var $$ = this;\n var axis = $$.axis, config = $$.config, state = $$.state;\n var isRotated = config.axis_rotated;\n var isInverted = config[\"axis_\".concat(axis === null || axis === void 0 ? void 0 : axis.getId(d.id), \"_inverted\")];\n var isBarType = $$.isBarType(d);\n var isTreemapType = $$.isTreemapType(d);\n var r = config.point_r;\n var rect = getBoundingRect(textElement);\n var value = d.value;\n var baseY = 3;\n var yPos;\n if ($$.isCandlestickType(d)) {\n value = $$.getCandlestickData(d);\n if (isRotated) {\n yPos = points[0][0];\n yPos += ((points[1][0] - yPos) / 2) + baseY;\n }\n else {\n yPos = value && value._isUp ?\n points[2][2] - baseY :\n points[2][1] + (baseY * 4);\n if (isInverted) {\n yPos += 15 * (value._isUp ? 1 : -1);\n }\n }\n }\n else if (isTreemapType) {\n yPos = points[0][1] + (config.data_labels.centered ? 0 : rect.height + 5);\n }\n else {\n if (isRotated) {\n yPos = (points[0][0] + points[2][0] + rect.height * 0.6) / 2;\n }\n else {\n yPos = points[2][1];\n if (isNumber(r) && r > 5 && ($$.isLineType(d) || $$.isScatterType(d))) {\n baseY += config.point_r / 2.3;\n }\n if (value < 0 || (value === 0 && !state.hasPositiveValue && state.hasNegativeValue)) {\n yPos += isInverted ? (isBarType ? -3 : -5) : (rect.height + (isBarType ? -baseY : baseY));\n }\n else {\n var diff = -baseY * 2;\n if (isBarType) {\n diff = -baseY;\n }\n else if ($$.isBubbleType(d)) {\n diff = baseY;\n }\n if (isInverted) {\n diff = isBarType ? 10 : 15;\n }\n yPos += diff;\n }\n }\n }\n // show labels regardless of the domain if value is null\n if (d.value === null && !isRotated) {\n var boxHeight = rect.height;\n if (yPos < boxHeight) {\n yPos = boxHeight;\n }\n else if (yPos > state.height) {\n yPos = state.height - 4;\n }\n }\n if (!isRotated || isTreemapType) {\n yPos += $$.getCenteredTextPos(d, points, textElement, \"y\");\n }\n return yPos + $$.getTextPos(d.id, \"y\");\n },\n /**\n * Calculate if two or more text nodes are overlapping\n * Mark overlapping text nodes with \"text-overlapping\" class\n * @param {string} id Axis id\n * @param {ChartInternal} $$ ChartInternal context\n * @param {string} selector Selector string\n * @private\n */\n markOverlapped: function (id, $$, selector) {\n var textNodes = $$.$el.arcs.selectAll(selector);\n var filteredTextNodes = textNodes.filter(function (node) { return node.data.id !== id; });\n var textNode = textNodes.filter(function (node) { return node.data.id === id; });\n var translate = getTranslation(textNode.node());\n // Calculates the length of the hypotenuse\n var calcHypo = function (x, y) { return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); };\n textNode.node() && filteredTextNodes.each(function () {\n var coordinate = getTranslation(this);\n var filteredTextNode = select(this);\n var nodeForWidth = calcHypo(translate.e, translate.f) > calcHypo(coordinate.e, coordinate.f) ?\n textNode : filteredTextNode;\n var overlapsX = Math.ceil(Math.abs(translate.e - coordinate.e)) <\n Math.ceil(nodeForWidth.node().getComputedTextLength());\n var overlapsY = Math.ceil(Math.abs(translate.f - coordinate.f)) <\n parseInt(textNode.style(\"font-size\"), 10);\n filteredTextNode.classed($TEXT.TextOverlapping, overlapsX && overlapsY);\n });\n },\n /**\n * Calculate if two or more text nodes are overlapping\n * Remove \"text-overlapping\" class on selected text nodes\n * @param {ChartInternal} $$ ChartInternal context\n * @param {string} selector Selector string\n * @private\n */\n undoMarkOverlapped: function ($$, selector) {\n $$.$el.arcs.selectAll(selector)\n .each(function () {\n selectAll([this, this.previousSibling])\n .classed($TEXT.TextOverlapping, false);\n });\n },\n /**\n * Check if meets the ratio to show data label text\n * @param {number} ratio ratio to meet\n * @param {string} type chart type\n * @returns {boolean}\n * @private\n */\n meetsLabelThreshold: function (ratio, type) {\n if (ratio === void 0) { ratio = 0; }\n var $$ = this;\n var config = $$.config;\n var threshold = config[\"\".concat(type, \"_label_threshold\")] || 0;\n return ratio >= threshold;\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Get the text position\n * @param {string} pos right, left or center\n * @param {number} width chart width\n * @returns {string|number} text-anchor value or position in pixel\n * @private\n */\nfunction getTextPos(pos, width) {\n if (pos === void 0) { pos = \"left\"; }\n var isNum = isNumber(width);\n var position;\n if (pos.indexOf(\"center\") > -1) {\n position = isNum ? width / 2 : \"middle\";\n }\n else if (pos.indexOf(\"right\") > -1) {\n position = isNum ? width : \"end\";\n }\n else {\n position = isNum ? 0 : \"start\";\n }\n return position;\n}\nvar title = {\n /**\n * Initializes the title\n * @private\n */\n initTitle: function () {\n var $$ = this;\n var config = $$.config, $el = $$.$el;\n if (config.title_text) {\n $el.title = $el.svg.append(\"g\");\n var text = $el.title\n .append(\"text\")\n .style(\"text-anchor\", getTextPos(config.title_position))\n .attr(\"class\", $TEXT.title);\n setTextValue(text, config.title_text, [0.3, 1.5]);\n }\n },\n /**\n * Redraw title\n * @private\n */\n redrawTitle: function () {\n var $$ = this;\n var config = $$.config, current = $$.state.current, title = $$.$el.title;\n if (title) {\n var y = $$.yForTitle.call($$);\n if (/g/i.test(title.node().tagName)) {\n title.attr(\"transform\", \"translate(\".concat(getTextPos(config.title_position, current.width), \", \").concat(y, \")\"));\n }\n else {\n title.attr(\"x\", $$.xForTitle.call($$)).attr(\"y\", y);\n }\n }\n },\n /**\n * Returns the x attribute value of the title\n * @returns {number} x attribute value\n * @private\n */\n xForTitle: function () {\n var $$ = this;\n var config = $$.config, current = $$.state.current;\n var position = config.title_position || \"left\";\n var textRectWidth = $$.getTextRect($$.$el.title, $TEXT.title).width;\n var x;\n if (/(right|center)/.test(position)) {\n x = current.width - textRectWidth;\n if (position.indexOf(\"right\") >= 0) {\n x = current.width - textRectWidth - config.title_padding.right;\n }\n else if (position.indexOf(\"center\") >= 0) {\n x = (current.width - textRectWidth) / 2;\n }\n }\n else { // left\n x = (config.title_padding.left || 0);\n }\n return x;\n },\n /**\n * Returns the y attribute value of the title\n * @returns {number} y attribute value\n * @private\n */\n yForTitle: function () {\n var $$ = this;\n return ($$.config.title_padding.top || 0) +\n $$.getTextRect($$.$el.title, $TEXT.title).height;\n },\n /**\n * Get title padding\n * @returns {number} padding value\n * @private\n */\n getTitlePadding: function () {\n var $$ = this;\n return $$.yForTitle() + ($$.config.title_padding.bottom || 0);\n }\n};\n\nvar tooltip$1 = {\n /**\n * Initializes the tooltip\n * @private\n */\n initTooltip: function () {\n var $$ = this;\n var config = $$.config, $el = $$.$el;\n $el.tooltip = select(config.tooltip_contents.bindto);\n if ($el.tooltip.empty()) {\n $el.tooltip = $el.chart\n .append(\"div\")\n .attr(\"class\", $TOOLTIP.tooltipContainer)\n .style(\"position\", \"absolute\")\n .style(\"pointer-events\", \"none\")\n .style(\"display\", \"none\");\n }\n $$.bindTooltipResizePos();\n },\n initShowTooltip: function () {\n var _a, _b;\n var $$ = this;\n var config = $$.config, $el = $$.$el, _c = $$.state, hasAxis = _c.hasAxis, hasRadar = _c.hasRadar;\n // Show tooltip if needed\n if (config.tooltip_init_show) {\n var isArc_1 = !(hasAxis && hasRadar);\n if (((_a = $$.axis) === null || _a === void 0 ? void 0 : _a.isTimeSeries()) && isString(config.tooltip_init_x)) {\n var targets = $$.data.targets[0];\n var i = void 0;\n var val = void 0;\n config.tooltip_init_x = parseDate.call($$, config.tooltip_init_x);\n for (i = 0; (val = targets.values[i]); i++) {\n if ((val.x - config.tooltip_init_x) === 0) {\n break;\n }\n }\n config.tooltip_init_x = i;\n }\n var data = $$.data.targets.map(function (d) {\n var x = isArc_1 ? 0 : config.tooltip_init_x;\n return $$.addName(d.values[x]);\n });\n if (isArc_1) {\n data = [data[config.tooltip_init_x]];\n }\n $el.tooltip.html($$.getTooltipHTML(data, (_b = $$.axis) === null || _b === void 0 ? void 0 : _b.getXAxisTickFormat(), $$.getDefaultValueFormat(), $$.color));\n if (!config.tooltip_contents.bindto) {\n $el.tooltip.style(\"top\", config.tooltip_init_position.top)\n .style(\"left\", config.tooltip_init_position.left)\n .style(\"display\", null);\n }\n }\n },\n /**\n * Get the tooltip HTML string\n * @param {Array} args Arguments\n * @returns {string} Formatted HTML string\n * @private\n */\n getTooltipHTML: function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var $$ = this;\n var api = $$.api, config = $$.config;\n return isFunction(config.tooltip_contents) ? config.tooltip_contents.bind(api).apply(void 0, args) : $$.getTooltipContent.apply($$, args);\n },\n /**\n * Returns the tooltip content(HTML string)\n * @param {object} d data\n * @param {Function} defaultTitleFormat Default title format\n * @param {Function} defaultValueFormat Default format for each data value in the tooltip.\n * @param {Function} color Color function\n * @returns {string} html\n * @private\n */\n getTooltipContent: function (d, defaultTitleFormat, defaultValueFormat, color) {\n var $$ = this;\n var api = $$.api, config = $$.config, state = $$.state, $el = $$.$el;\n var _a = [\"title\", \"name\", \"value\"].map(function (v) {\n var fn = config[\"tooltip_format_\".concat(v)];\n return isFunction(fn) ? fn.bind(api) : fn;\n }), titleFormat = _a[0], nameFormat = _a[1], valueFormat = _a[2];\n titleFormat = titleFormat || defaultTitleFormat;\n nameFormat = nameFormat || (function (name) { return name; });\n valueFormat = valueFormat || (state.hasTreemap || $$.isStackNormalized() ? function (v, ratio) { return \"\".concat((ratio * 100).toFixed(2), \"%\"); } : defaultValueFormat);\n var order = config.tooltip_order;\n var getRowValue = function (row) { return ($$.axis && $$.isBubbleZType(row) ? $$.getBubbleZData(row.value, \"z\") : $$.getBaseValue(row)); };\n var getBgColor = $$.levelColor ? function (row) { return $$.levelColor(row.value); } : function (row) { return color(row); };\n var contents = config.tooltip_contents;\n var tplStr = contents.template;\n var targetIds = $$.mapToTargetIds();\n if (order === null && config.data_groups.length) {\n // for stacked data, order should aligned with the visually displayed data\n var ids_1 = $$.orderTargets($$.data.targets)\n .map(function (i2) { return i2.id; })\n .reverse();\n d.sort(function (a, b) {\n var v1 = a ? a.value : null;\n var v2 = b ? b.value : null;\n if (v1 > 0 && v2 > 0) {\n v1 = a.id ? ids_1.indexOf(a.id) : null;\n v2 = b.id ? ids_1.indexOf(b.id) : null;\n }\n return v1 - v2;\n });\n }\n else if (/^(asc|desc)$/.test(order)) {\n var isAscending_1 = order === \"asc\";\n d.sort(function (a, b) {\n var v1 = a ? getRowValue(a) : null;\n var v2 = b ? getRowValue(b) : null;\n return isAscending_1 ? v1 - v2 : v2 - v1;\n });\n }\n else if (isFunction(order)) {\n d.sort(order.bind(api));\n }\n var tpl = $$.getTooltipContentTemplate(tplStr);\n var len = d.length;\n var text;\n var row;\n var param;\n var value;\n var i;\n var _loop_1 = function () {\n row = d[i];\n if (!row || !(getRowValue(row) || getRowValue(row) === 0)) {\n return \"continue\";\n }\n if (isUndefined(text)) {\n var title = (state.hasAxis || state.hasRadar) &&\n sanitise(titleFormat ? titleFormat(row.x) : row.x);\n text = tplProcess(tpl[0], {\n CLASS_TOOLTIP: $TOOLTIP.tooltip,\n TITLE: isValue(title) ? (tplStr ? title : \"\".concat(title, \"\")) : \"\"\n });\n }\n if (!row.ratio && $el.arcs) {\n param = [\"arc\", $$.$el.arcs.select(\"path.\".concat($ARC.arc, \"-\").concat(row.id)).data()[0]];\n row.ratio = $$.getRatio.apply($$, param);\n }\n param = [row.ratio, row.id, row.index, d];\n value = sanitise(valueFormat.apply(void 0, __spreadArray([getRowValue(row)], param, false)));\n if ($$.isAreaRangeType(row)) {\n var _b = [\"high\", \"low\"].map(function (v) { return sanitise(valueFormat.apply(void 0, __spreadArray([$$.getRangedData(row, v)], param, false))); }), high = _b[0], low = _b[1];\n value = \"Mid: \".concat(value, \" High: \").concat(high, \" Low: \").concat(low);\n }\n else if ($$.isCandlestickType(row)) {\n var _c = [\"open\", \"high\", \"low\", \"close\", \"volume\"].map(function (v) { return sanitise(valueFormat.apply(void 0, __spreadArray([$$.getRangedData(row, v, \"candlestick\")], param, false))); }), open_1 = _c[0], high = _c[1], low = _c[2], close_1 = _c[3], volume = _c[4];\n value = \"Open: \".concat(open_1, \" High: \").concat(high, \" Low: \").concat(low, \" Close: \").concat(close_1).concat(volume ? \" Volume: \".concat(volume) : \"\");\n }\n else if ($$.isBarRangeType(row)) {\n var _d = row.value, start = _d[0], end = _d[1];\n value = \"\".concat(valueFormat(start), \" ~ \").concat(valueFormat(end));\n }\n if (value !== undefined) {\n // Skip elements when their name is set to null\n if (row.name === null) {\n return \"continue\";\n }\n var name_1 = sanitise(nameFormat.apply(void 0, __spreadArray([row.name], param, false)));\n var color_1 = getBgColor(row);\n var contentValue_1 = {\n CLASS_TOOLTIP_NAME: $TOOLTIP.tooltipName + $$.getTargetSelectorSuffix(row.id),\n COLOR: (tplStr || !$$.patterns) ? color_1 : \"\"),\n NAME: name_1,\n VALUE: value\n };\n if (tplStr && isObject(contents.text)) {\n var index_1 = targetIds.indexOf(row.id);\n Object.keys(contents.text).forEach(function (key) {\n contentValue_1[key] = contents.text[key][index_1];\n });\n }\n text += tplProcess(tpl[1], contentValue_1);\n }\n };\n for (i = 0; i < len; i++) {\n _loop_1();\n }\n return \"\".concat(text, \"\");\n },\n /**\n * Get the content template string\n * @param {string} tplStr Tempalte string\n * @returns {Array} Template string\n * @private\n */\n getTooltipContentTemplate: function (tplStr) {\n return (tplStr || \"\\n\\t\\t\\t\\t{=TITLE}\\n\\t\\t\\t\\t{{\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t}}\\n\\t\\t\\t
    \".concat(this.patterns ? \"{=COLOR}\" : \"\", \"{=NAME}{=VALUE}
    \"))\n .replace(/(\\r?\\n|\\t)/g, \"\")\n .split(/{{(.*)}}/);\n },\n /**\n * Returns the position of the tooltip\n * @param {object} dataToShow data\n * @param {string} tWidth Width value of tooltip element\n * @param {string} tHeight Height value of tooltip element\n * @param {HTMLElement} element Tooltip element\n * @returns {object} top, left value\n * @private\n */\n tooltipPosition: function (dataToShow, tWidth, tHeight, element) {\n var $$ = this;\n var config = $$.config, scale = $$.scale, state = $$.state;\n var width = state.width, height = state.height, current = state.current, isLegendRight = state.isLegendRight, inputType = state.inputType, event = state.event;\n var hasGauge = $$.hasType(\"gauge\") && !config.gauge_fullCircle;\n var hasTreemap = state.hasTreemap;\n var svgLeft = $$.getSvgLeft(true);\n var chartRight = svgLeft + current.width - $$.getCurrentPaddingRight();\n var chartLeft = $$.getCurrentPaddingLeft(true);\n var size = 20;\n var _a = getPointer(event, element), x = _a[0], y = _a[1];\n // Determine tooltip position\n if ($$.hasArcType()) {\n var raw = inputType === \"touch\" || $$.hasType(\"radar\");\n if (!raw) {\n y += hasGauge ? height : height / 2;\n x += (width - (isLegendRight ? $$.getLegendWidth() : 0)) / 2;\n }\n }\n else if (!hasTreemap) {\n var dataScale = scale.x(dataToShow[0].x);\n if (config.axis_rotated) {\n y = dataScale + size;\n x += svgLeft + 100;\n chartRight -= svgLeft;\n }\n else {\n y -= 5;\n x = svgLeft + chartLeft + size + (scale.zoom ? x : dataScale);\n }\n }\n // when tooltip left + tWidth > chart's width\n if ((x + tWidth + 15) > chartRight) {\n x -= tWidth + (hasTreemap ? 0 : chartLeft);\n }\n if (y + tHeight > current.height) {\n var gap = hasTreemap ? 0 : 30;\n y -= hasGauge ? tHeight * 3 : tHeight + gap;\n }\n var pos = { top: y, left: x };\n // make sure to not be positioned out of viewport\n Object.keys(pos).forEach(function (v) {\n if (pos[v] < 0) {\n pos[v] = 0;\n }\n });\n return pos;\n },\n /**\n * Show the tooltip\n * @param {object} selectedData Data object\n * @param {SVGElement} eventRect Event element\n * @private\n */\n showTooltip: function (selectedData, eventRect) {\n var _a, _b;\n var $$ = this;\n var config = $$.config, scale = $$.scale, state = $$.state, tooltip = $$.$el.tooltip;\n var bindto = config.tooltip_contents.bindto;\n var dataToShow = selectedData.filter(function (d) { return d && isValue($$.getBaseValue(d)); });\n if (!tooltip || dataToShow.length === 0 || !config.tooltip_show) {\n return;\n }\n var datum = tooltip.datum();\n var _c = datum || {}, _d = _c.width, width = _d === void 0 ? 0 : _d, _e = _c.height, height = _e === void 0 ? 0 : _e;\n var dataStr = JSON.stringify(selectedData);\n if (!datum || datum.current !== dataStr) {\n var index = selectedData.concat().sort()[0].index;\n callFn(config.tooltip_onshow, $$.api, selectedData);\n // set tooltip content\n tooltip\n .html($$.getTooltipHTML(selectedData, // data\n $$.axis ? $$.axis.getXAxisTickFormat() : $$.categoryName.bind($$), // defaultTitleFormat\n $$.getDefaultValueFormat(), // defaultValueFormat\n $$.color // color\n ))\n .style(\"display\", null)\n .style(\"visibility\", null) // for IE9\n .datum(datum = {\n index: index,\n current: dataStr,\n width: width = tooltip.property(\"offsetWidth\"),\n height: height = tooltip.property(\"offsetHeight\")\n });\n callFn(config.tooltip_onshown, $$.api, selectedData);\n $$._handleLinkedCharts(true, index);\n }\n if (!bindto) {\n var fnPos = ((_a = config.tooltip_position) === null || _a === void 0 ? void 0 : _a.bind($$.api)) || $$.tooltipPosition.bind($$);\n var _f = getPointer(state.event, eventRect), x = _f[0], y = _f[1]; // get mouse event position\n var currPos = { x: x, y: y };\n var data = (_b = selectedData.filter(Boolean)) === null || _b === void 0 ? void 0 : _b.shift();\n if (scale.x && data && \"x\" in data) {\n currPos.xAxis = scale.x(data.x);\n }\n // Get tooltip dimensions\n var pos_1 = fnPos(dataToShow, width, height, eventRect, currPos);\n [\"top\", \"left\"].forEach(function (v) {\n var value = pos_1[v];\n tooltip.style(v, \"\".concat(value, \"px\"));\n // Remember left pos in percentage to be used on resize call\n if (v === \"left\" && !datum.xPosInPercent) {\n datum.xPosInPercent = value / state.current.width * 100;\n }\n });\n }\n },\n /**\n * Adjust tooltip position on resize event\n * @private\n */\n bindTooltipResizePos: function () {\n var $$ = this;\n var resizeFunction = $$.resizeFunction, state = $$.state, tooltip = $$.$el.tooltip;\n resizeFunction.add(function () {\n if (tooltip.style(\"display\") === \"block\") {\n var current = state.current;\n var _a = tooltip.datum(), width = _a.width, xPosInPercent = _a.xPosInPercent;\n var value = current.width / 100 * xPosInPercent;\n var diff = current.width - (value + width);\n // if tooltip size overs current viewport size\n if (diff < 0) {\n value += diff;\n }\n tooltip.style(\"left\", \"\".concat(value, \"px\"));\n }\n });\n },\n /**\n * Hide the tooltip\n * @param {boolean} force Force to hide\n * @private\n */\n hideTooltip: function (force) {\n var $$ = this;\n var api = $$.api, config = $$.config, tooltip = $$.$el.tooltip;\n if (tooltip && tooltip.style(\"display\") !== \"none\" && (!config.tooltip_doNotHide || force)) {\n var selectedData = JSON.parse(tooltip.datum().current);\n callFn(config.tooltip_onhide, api, selectedData);\n // hide tooltip\n tooltip\n .style(\"display\", \"none\")\n .style(\"visibility\", \"hidden\") // for IE9\n .datum(null);\n callFn(config.tooltip_onhidden, api, selectedData);\n }\n },\n /**\n * Toggle display for linked chart instances\n * @param {boolean} show true: show, false: hide\n * @param {number} index x Axis index\n * @private\n */\n _handleLinkedCharts: function (show, index) {\n var $$ = this;\n var charts = $$.charts, config = $$.config, event = $$.state.event;\n // Prevent propagation among instances if isn't instantiated from the user's event\n // https://github.com/naver/billboard.js/issues/1979\n if ((event === null || event === void 0 ? void 0 : event.isTrusted) && config.tooltip_linked && charts.length > 1) {\n var linkedName_1 = config.tooltip_linked_name;\n charts\n .filter(function (c) { return c !== $$.api; })\n .forEach(function (c) {\n var _a = c.internal, config = _a.config, $el = _a.$el;\n var isLinked = config.tooltip_linked;\n var name = config.tooltip_linked_name;\n var isInDom = doc.body.contains($el.chart.node());\n if (isLinked && linkedName_1 === name && isInDom) {\n var data = $el.tooltip.data()[0];\n var isNotSameIndex = index !== (data === null || data === void 0 ? void 0 : data.index);\n try {\n c.tooltip[show && isNotSameIndex ? \"show\" : \"hide\"]({ index: index });\n }\n catch (e) { }\n }\n });\n }\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar transform = {\n getTranslate: function (target, index) {\n if (index === void 0) { index = 0; }\n var $$ = this;\n var config = $$.config, state = $$.state;\n var isRotated = config.axis_rotated;\n var padding = 0;\n var x;\n var y;\n if (index && /^(x|y2?)$/.test(target)) {\n padding = $$.getAxisSize(target) * index;\n }\n if (target === \"main\") {\n x = asHalfPixel(state.margin.left);\n y = asHalfPixel(state.margin.top);\n }\n else if (target === \"context\") {\n x = asHalfPixel(state.margin2.left);\n y = asHalfPixel(state.margin2.top);\n }\n else if (target === \"legend\") {\n x = state.margin3.left;\n y = state.margin3.top;\n }\n else if (target === \"x\") {\n x = isRotated ? -padding : 0;\n y = isRotated ? 0 : state.height + padding;\n }\n else if (target === \"y\") {\n x = isRotated ? 0 : -padding;\n y = isRotated ? state.height + padding : 0;\n }\n else if (target === \"y2\") {\n x = isRotated ? 0 : state.width + padding;\n y = isRotated ? 1 - padding : 0;\n }\n else if (target === \"subX\") {\n x = 0;\n y = isRotated ? 0 : state.height2;\n }\n else if (target === \"arc\") {\n x = state.arcWidth / 2;\n y = state.arcHeight / 2;\n }\n else if (target === \"polar\") {\n x = state.arcWidth / 2;\n y = state.arcHeight / 2;\n }\n else if (target === \"radar\") {\n var width = $$.getRadarSize()[0];\n x = state.width / 2 - width;\n y = asHalfPixel(state.margin.top);\n }\n return \"translate(\".concat(x, \", \").concat(y, \")\");\n },\n transformMain: function (withTransition, transitions) {\n var $$ = this;\n var main = $$.$el.main, $T = $$.$T;\n var xAxis = (transitions === null || transitions === void 0 ? void 0 : transitions.axisX) ?\n transitions.axisX :\n $T(main.select(\".\".concat($AXIS.axisX)), withTransition);\n var yAxis = (transitions === null || transitions === void 0 ? void 0 : transitions.axisY) ?\n transitions.axisY :\n $T(main.select(\".\".concat($AXIS.axisY)), withTransition);\n var y2Axis = (transitions === null || transitions === void 0 ? void 0 : transitions.axisY2) ?\n transitions.axisY2 :\n $T(main.select(\".\".concat($AXIS.axisY2)), withTransition);\n $T(main, withTransition)\n .attr(\"transform\", $$.getTranslate(\"main\"));\n xAxis.attr(\"transform\", $$.getTranslate(\"x\"));\n yAxis.attr(\"transform\", $$.getTranslate(\"y\"));\n y2Axis.attr(\"transform\", $$.getTranslate(\"y2\"));\n main.select(\".\".concat($ARC.chartArcs))\n .attr(\"transform\", $$.getTranslate(\"arc\"));\n },\n transformAll: function (withTransition, transitions) {\n var $$ = this;\n var config = $$.config, _a = $$.state, hasAxis = _a.hasAxis, hasTreemap = _a.hasTreemap, $el = $$.$el;\n !hasTreemap && $$.transformMain(withTransition, transitions);\n hasAxis && config.subchart_show &&\n $$.transformContext(withTransition, transitions);\n $el.legend && $$.transformLegend(withTransition);\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar typeInternals = {\n setTargetType: function (targetIds, type) {\n var $$ = this;\n var config = $$.config, withoutFadeIn = $$.state.withoutFadeIn;\n $$.mapToTargetIds(targetIds).forEach(function (id) {\n withoutFadeIn[id] = (type === config.data_types[id]);\n config.data_types[id] = type;\n });\n if (!targetIds) {\n config.data_type = type;\n }\n },\n /**\n * Updte current used chart types\n * @private\n */\n updateTypesElements: function () {\n var $$ = this;\n var current = $$.state.current;\n Object.keys(TYPE).forEach(function (v) {\n var t = TYPE[v];\n var has = $$.hasType(t, null, true);\n var idx = current.types.indexOf(t);\n if (idx === -1 && has) {\n current.types.push(t);\n }\n else if (idx > -1 && !has) {\n current.types.splice(idx, 1);\n }\n });\n // Update current chart elements reference\n $$.setChartElements();\n },\n /**\n * Check if given chart types exists\n * @param {string} type Chart type\n * @param {Array} targetsValue Data array\n * @param {boolean} checkFromData Force to check type cotains from data targets\n * @returns {boolean}\n * @private\n */\n hasType: function (type, targetsValue, checkFromData) {\n var _a;\n if (checkFromData === void 0) { checkFromData = false; }\n var $$ = this;\n var config = $$.config, current = $$.state.current;\n var types = config.data_types;\n var targets = targetsValue || $$.data.targets;\n var has = false;\n if (!checkFromData && ((_a = current.types) === null || _a === void 0 ? void 0 : _a.indexOf(type)) > -1) {\n has = true;\n }\n else if (targets === null || targets === void 0 ? void 0 : targets.length) {\n targets.forEach(function (target) {\n var t = types[target.id];\n if (t === type || (!t && type === \"line\")) {\n has = true;\n }\n });\n }\n else if (Object.keys(types).length) {\n Object.keys(types).forEach(function (id) {\n if (types[id] === type) {\n has = true;\n }\n });\n }\n else {\n has = config.data_type === type;\n }\n return has;\n },\n /**\n * Check if contains given chart types\n * @param {string} type Type key\n * @param {object} targets Target data\n * @param {Array} exclude Excluded types\n * @returns {boolean}\n * @private\n */\n hasTypeOf: function (type, targets, exclude) {\n var _this = this;\n if (exclude === void 0) { exclude = []; }\n if (type in TYPE_BY_CATEGORY) {\n return !TYPE_BY_CATEGORY[type]\n .filter(function (v) { return exclude.indexOf(v) === -1; })\n .every(function (v) { return !_this.hasType(v, targets); });\n }\n return false;\n },\n /**\n * Check if given data is certain chart type\n * @param {object} d Data object\n * @param {string|Array} type chart type\n * @returns {boolean}\n * @private\n */\n isTypeOf: function (d, type) {\n var id = isString(d) ? d : d.id;\n var dataType = this.config.data_types[id] || this.config.data_type;\n return isArray(type) ?\n type.indexOf(dataType) >= 0 : dataType === type;\n },\n hasPointType: function () {\n var $$ = this;\n return $$.hasTypeOf(\"Line\") || $$.hasType(\"bubble\") || $$.hasType(\"scatter\");\n },\n /**\n * Check if contains arc types chart\n * @param {object} targets Target data\n * @param {Array} exclude Excluded types\n * @returns {boolean}\n * @private\n */\n hasArcType: function (targets, exclude) {\n return this.hasTypeOf(\"Arc\", targets, exclude);\n },\n hasMultiArcGauge: function () {\n return this.hasType(\"gauge\") && this.config.gauge_type === \"multi\";\n },\n isLineType: function (d) {\n var id = isString(d) ? d : d.id;\n return !this.config.data_types[id] ||\n this.isTypeOf(id, TYPE_BY_CATEGORY.Line);\n },\n isStepType: function (d) {\n return this.isTypeOf(d, TYPE_BY_CATEGORY.Step);\n },\n isSplineType: function (d) {\n return this.isTypeOf(d, TYPE_BY_CATEGORY.Spline);\n },\n isAreaType: function (d) {\n return this.isTypeOf(d, TYPE_BY_CATEGORY.Area);\n },\n isAreaRangeType: function (d) {\n return this.isTypeOf(d, TYPE_BY_CATEGORY.AreaRange);\n },\n isBarType: function (d) {\n return this.isTypeOf(d, \"bar\");\n },\n isBubbleType: function (d) {\n return this.isTypeOf(d, \"bubble\");\n },\n isCandlestickType: function (d) {\n return this.isTypeOf(d, \"candlestick\");\n },\n isScatterType: function (d) {\n return this.isTypeOf(d, \"scatter\");\n },\n isTreemapType: function (d) {\n return this.isTypeOf(d, \"treemap\");\n },\n isPieType: function (d) {\n return this.isTypeOf(d, \"pie\");\n },\n isGaugeType: function (d) {\n return this.isTypeOf(d, \"gauge\");\n },\n isDonutType: function (d) {\n return this.isTypeOf(d, \"donut\");\n },\n isPolarType: function (d) {\n return this.isTypeOf(d, \"polar\");\n },\n isRadarType: function (d) {\n return this.isTypeOf(d, \"radar\");\n },\n isArcType: function (d) {\n return this.isPieType(d) ||\n this.isDonutType(d) ||\n this.isGaugeType(d) ||\n this.isPolarType(d) ||\n this.isRadarType(d);\n },\n // determine if is 'circle' data point\n isCirclePoint: function (node) {\n var config = this.config;\n var pattern = config.point_pattern;\n var isCircle = false;\n if ((node === null || node === void 0 ? void 0 : node.tagName) === \"circle\") {\n isCircle = true;\n }\n else {\n isCircle = config.point_type === \"circle\" &&\n (!pattern || (isArray(pattern) && pattern.length === 0));\n }\n return isCircle;\n },\n lineData: function (d) {\n return this.isLineType(d) ? [d] : [];\n },\n arcData: function (d) {\n return this.isArcType(d.data) ? [d] : [];\n },\n /**\n * Get data adapt for data label showing\n * @param {object} d Data object\n * @returns {Array}\n * @private\n */\n labelishData: function (d) {\n return this.isBarType(d) ||\n this.isLineType(d) ||\n this.isScatterType(d) ||\n this.isBubbleType(d) ||\n this.isCandlestickType(d) ||\n this.isRadarType(d) ||\n this.isTreemapType(d) ? d.values.filter(function (v) { return isNumber(v.value) || Boolean(v.value); }) : [];\n },\n barLineBubbleData: function (d) {\n return this.isBarType(d) || this.isLineType(d) || this.isBubbleType(d) ?\n d.values : [];\n },\n // https://github.com/d3/d3-shape#curves\n isInterpolationType: function (type) {\n return [\n \"basis\",\n \"basis-closed\",\n \"basis-open\",\n \"bundle\",\n \"cardinal\",\n \"cardinal-closed\",\n \"cardinal-open\",\n \"catmull-rom\",\n \"catmull-rom-closed\",\n \"catmull-rom-open\",\n \"linear\",\n \"linear-closed\",\n \"monotone-x\",\n \"monotone-y\",\n \"natural\"\n ].indexOf(type) >= 0;\n }\n};\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n * @ignore\n */\n/**\n * Internal chart class.\n * - Note: Instantiated internally, not exposed for public.\n * @class ChartInternal\n * @ignore\n * @private\n */\nvar ChartInternal = /** @class */ (function () {\n function ChartInternal(api) {\n // data object\n this.data = {\n xs: {},\n targets: []\n };\n // scales\n this.scale = {\n x: null,\n y: null,\n y2: null,\n subX: null,\n subY: null,\n subY2: null,\n zoom: null\n };\n // original values\n this.org = {\n xScale: null,\n xDomain: null\n };\n // format function\n this.format = {\n extraLineClasses: null,\n xAxisTick: null,\n dataTime: null,\n defaultAxisTime: null,\n axisTime: null // axisTimeFormat\n };\n var $$ = this;\n $$.api = api; // Chart class instance alias\n $$.config = new Options();\n $$.cache = new Cache();\n var store = new Store();\n $$.$el = store.getStore(\"element\");\n $$.state = store.getStore(\"state\");\n $$.$T = $$.$T.bind($$);\n }\n /**\n * Get the selection based on transition config\n * @param {SVGElement|d3Selection} selection Target selection\n * @param {boolean} force Force transition\n * @param {string} name Transition name\n * @returns {d3Selection}\n * @private\n */\n ChartInternal.prototype.$T = function (selection, force, name) {\n var _a = this, config = _a.config, state = _a.state;\n var duration = config.transition_duration;\n var subchart = config.subchart_show;\n var t = selection;\n if (t) {\n // in case of non d3 selection, wrap with d3 selection\n if (\"tagName\" in t) {\n t = select(t);\n }\n // do not transit on:\n // - wheel zoom (state.zooming = true)\n // - when has no subchart\n // - initialization\n // - resizing\n var transit = ((force !== false && duration) || force) &&\n (!state.zooming || state.dragging) &&\n !state.resizing &&\n state.rendered &&\n !subchart;\n t = (transit ? t.transition(name).duration(duration) : t);\n }\n return t;\n };\n ChartInternal.prototype.beforeInit = function () {\n var $$ = this;\n $$.callPluginHook(\"$beforeInit\");\n // can do something\n callFn($$.config.onbeforeinit, $$.api);\n };\n ChartInternal.prototype.afterInit = function () {\n var $$ = this;\n $$.callPluginHook(\"$afterInit\");\n // can do something\n callFn($$.config.onafterinit, $$.api);\n };\n ChartInternal.prototype.init = function () {\n var $$ = this;\n var config = $$.config, state = $$.state, $el = $$.$el;\n var useCssRule = config.boost_useCssRule;\n checkModuleImport($$);\n state.hasRadar = !state.hasAxis && $$.hasType(\"radar\");\n state.hasTreemap = !state.hasAxis && $$.hasType(\"treemap\");\n state.hasAxis = !$$.hasArcType() && !state.hasTreemap;\n // datetime to be used for uniqueness\n state.datetimeId = \"bb-\".concat(+new Date() * getRandom());\n if (useCssRule) {\n // append style element\n var styleEl = doc.createElement(\"style\");\n // styleEl.id = styleId;\n styleEl.type = \"text/css\";\n doc.head.appendChild(styleEl);\n state.style = {\n rootSelctor: \".\".concat(state.datetimeId),\n sheet: styleEl.sheet\n };\n // used on .destroy()\n $el.style = styleEl;\n }\n var bindto = {\n element: config.bindto,\n classname: \"bb\"\n };\n if (isObject(config.bindto)) {\n bindto.element = config.bindto.element || \"#chart\";\n bindto.classname = config.bindto.classname || bindto.classname;\n }\n // select bind element\n $el.chart = isFunction(bindto.element.node) ?\n config.bindto.element : select(bindto.element || []);\n if ($el.chart.empty()) {\n $el.chart = select(doc.body.appendChild(doc.createElement(\"div\")));\n }\n $el.chart.html(\"\")\n .classed(bindto.classname, true)\n .classed(state.datetimeId, useCssRule)\n .style(\"position\", \"relative\");\n $$.initParams();\n $$.initToRender();\n };\n /**\n * Initialize the rendering process\n * @param {boolean} forced Force to render process\n * @private\n */\n ChartInternal.prototype.initToRender = function (forced) {\n var $$ = this;\n var config = $$.config, state = $$.state, chart = $$.$el.chart;\n var isHidden = function () { return chart.style(\"display\") === \"none\" || chart.style(\"visibility\") === \"hidden\"; };\n var isLazy = config.render.lazy || isHidden();\n var MutationObserver = win.MutationObserver;\n if (isLazy && MutationObserver && config.render.observe !== false && !forced) {\n new MutationObserver(function (mutation, observer) {\n if (!isHidden()) {\n observer.disconnect();\n !state.rendered && $$.initToRender(true);\n }\n }).observe(chart.node(), {\n attributes: true,\n attributeFilter: [\"class\", \"style\"]\n });\n }\n if (!isLazy || forced) {\n $$.convertData(config, function (res) {\n $$.initWithData(res);\n $$.afterInit();\n });\n }\n };\n ChartInternal.prototype.initParams = function () {\n var $$ = this;\n var config = $$.config, format = $$.format, state = $$.state;\n var isRotated = config.axis_rotated;\n // color settings\n $$.color = $$.generateColor();\n $$.levelColor = $$.generateLevelColor();\n // when 'padding=false' is set, disable axes and subchart. Because they are useless.\n if (config.padding === false) {\n config.axis_x_show = false;\n config.axis_y_show = false;\n config.axis_y2_show = false;\n config.subchart_show = false;\n }\n if ($$.hasPointType()) {\n $$.point = $$.generatePoint();\n }\n if (state.hasAxis) {\n $$.initClip();\n format.extraLineClasses = $$.generateExtraLineClass();\n format.dataTime = config.data_xLocaltime ? timeParse : utcParse;\n format.axisTime = config.axis_x_localtime ? timeFormat : utcFormat;\n var isDragZoom_1 = $$.config.zoom_enabled && $$.config.zoom_type === \"drag\";\n format.defaultAxisTime = function (d) {\n var _a = $$.scale, x = _a.x, zoom = _a.zoom;\n var isZoomed = isDragZoom_1 ? zoom :\n zoom && x.orgDomain().toString() !== zoom.domain().toString();\n var specifier = (d.getMilliseconds() && \".%L\") ||\n (d.getSeconds() && \".:%S\") ||\n (d.getMinutes() && \"%I:%M\") ||\n (d.getHours() && \"%I %p\") ||\n (d.getDate() !== 1 && \"%b %d\") ||\n (isZoomed && d.getDate() === 1 && \"%b\\'%y\") ||\n (d.getMonth() && \"%-m/%-d\") || \"%Y\";\n return format.axisTime(specifier)(d);\n };\n }\n state.isLegendRight = config.legend_position === \"right\";\n state.isLegendInset = config.legend_position === \"inset\";\n state.isLegendTop = config.legend_inset_anchor === \"top-left\" ||\n config.legend_inset_anchor === \"top-right\";\n state.isLegendLeft = config.legend_inset_anchor === \"top-left\" ||\n config.legend_inset_anchor === \"bottom-left\";\n state.rotatedPadding.top = $$.getResettedPadding(state.rotatedPadding.top);\n state.rotatedPadding.right = isRotated && !config.axis_x_show ? 0 : 30;\n state.inputType = convertInputType(config.interaction_inputType_mouse, config.interaction_inputType_touch);\n };\n ChartInternal.prototype.initWithData = function (data) {\n var _a, _b;\n var $$ = this;\n var config = $$.config, scale = $$.scale, state = $$.state, $el = $$.$el, org = $$.org;\n var hasAxis = state.hasAxis, hasTreemap = state.hasTreemap;\n var hasInteraction = config.interaction_enabled;\n var hasPolar = $$.hasType(\"polar\");\n // for arc type, set axes to not be shown\n // $$.hasArcType() && [\"x\", \"y\", \"y2\"].forEach(id => (config[`axis_${id}_show`] = false));\n if (hasAxis) {\n $$.axis = $$.getAxisInstance();\n config.zoom_enabled && $$.initZoom();\n }\n // Init data as targets\n $$.data.xs = {};\n $$.data.targets = $$.convertDataToTargets(data);\n if (config.data_filter) {\n $$.data.targets = $$.data.targets.filter(config.data_filter.bind($$.api));\n }\n // Set targets to hide if needed\n if (config.data_hide) {\n $$.addHiddenTargetIds(config.data_hide === true ?\n $$.mapToIds($$.data.targets) : config.data_hide);\n }\n if (config.legend_hide) {\n $$.addHiddenLegendIds(config.legend_hide === true ?\n $$.mapToIds($$.data.targets) : config.legend_hide);\n }\n // Init sizes and scales\n $$.updateSizes();\n $$.updateScales(true);\n // retrieve scale after the 'updateScales()' is called\n if (hasAxis) {\n var x = scale.x, y = scale.y, y2 = scale.y2, subX = scale.subX, subY = scale.subY, subY2 = scale.subY2;\n // Set domains for each scale\n if (x) {\n x.domain(sortValue($$.getXDomain($$.data.targets)));\n subX.domain(x.domain());\n // Save original x domain for zoom update\n org.xDomain = x.domain();\n }\n if (y) {\n y.domain($$.getYDomain($$.data.targets, \"y\"));\n subY.domain(y.domain());\n }\n if (y2) {\n y2.domain($$.getYDomain($$.data.targets, \"y2\"));\n subY2 && subY2.domain(y2.domain());\n }\n }\n // -- Basic Elements --\n $el.svg = $el.chart.append(\"svg\")\n .style(\"overflow\", \"hidden\")\n .style(\"display\", \"block\");\n if (hasInteraction && state.inputType) {\n var isTouch = state.inputType === \"touch\";\n var onclick_1 = config.onclick, onover = config.onover, onout = config.onout;\n $el.svg\n .on(\"click\", (onclick_1 === null || onclick_1 === void 0 ? void 0 : onclick_1.bind($$.api)) || null)\n .on(isTouch ? \"touchstart\" : \"mouseenter\", (onover === null || onover === void 0 ? void 0 : onover.bind($$.api)) || null)\n .on(isTouch ? \"touchend\" : \"mouseleave\", (onout === null || onout === void 0 ? void 0 : onout.bind($$.api)) || null);\n }\n config.svg_classname && $el.svg.attr(\"class\", config.svg_classname);\n // Define defs\n var hasColorPatterns = (isFunction(config.color_tiles) && $$.patterns);\n if (hasAxis || hasColorPatterns || hasPolar || hasTreemap ||\n config.data_labels_backgroundColors) {\n $el.defs = $el.svg.append(\"defs\");\n if (hasAxis) {\n [\"id\", \"idXAxis\", \"idYAxis\", \"idGrid\"].forEach(function (v) {\n $$.appendClip($el.defs, state.clip[v]);\n });\n }\n // Append data background color filter definition\n $$.generateDataLabelBackgroundColorFilter();\n // set color patterns\n if (hasColorPatterns) {\n $$.patterns.forEach(function (p) { return $el.defs.append(function () { return p.node; }); });\n }\n }\n $$.updateSvgSize();\n // Bind resize event\n $$.bindResize();\n // Define regions\n var main = $el.svg.append(\"g\")\n .classed($COMMON.main, true)\n .attr(\"transform\", hasTreemap ? null : $$.getTranslate(\"main\"));\n $el.main = main;\n // initialize subchart when subchart show option is set\n config.subchart_show && $$.initSubchart();\n config.tooltip_show && $$.initTooltip();\n config.title_text && $$.initTitle();\n !hasTreemap && config.legend_show && $$.initLegend();\n // -- Main Region --\n // text when empty\n if (config.data_empty_label_text) {\n main.append(\"text\")\n .attr(\"class\", \"\".concat($TEXT.text, \" \").concat($COMMON.empty))\n .attr(\"text-anchor\", \"middle\") // horizontal centering of text at x position in all browsers.\n .attr(\"dominant-baseline\", \"middle\"); // vertical centering of text at y position in all browsers, except IE.\n }\n if (hasAxis) {\n // Regions\n config.regions.length && $$.initRegion();\n // Add Axis here, when clipPath is 'false'\n !config.clipPath && $$.axis.init();\n }\n // Define g for chart area\n main.append(\"g\")\n .classed($COMMON.chart, true)\n .attr(\"clip-path\", hasAxis ? state.clip.path : null);\n $$.callPluginHook(\"$init\");\n if (hasAxis) {\n // Cover whole with rects for events\n hasInteraction && ((_a = $$.initEventRect) === null || _a === void 0 ? void 0 : _a.call($$));\n // Grids\n $$.initGrid();\n // Add Axis here, when clipPath is 'true'\n config.clipPath && ((_b = $$.axis) === null || _b === void 0 ? void 0 : _b.init());\n }\n $$.initChartElements();\n // Set targets\n $$.updateTargets($$.data.targets);\n // Draw with targets\n $$.updateDimension();\n // oninit callback\n callFn(config.oninit, $$.api);\n // Set background\n $$.setBackground();\n $$.redraw({\n withTransition: false,\n withTransform: true,\n withUpdateXDomain: true,\n withUpdateOrgXDomain: true,\n withTransitionForAxis: false,\n initializing: true\n });\n // data.onmin/max callback\n if (config.data_onmin || config.data_onmax) {\n var minMax = $$.getMinMaxData();\n callFn(config.data_onmin, $$.api, minMax.min);\n callFn(config.data_onmax, $$.api, minMax.max);\n }\n config.tooltip_show && $$.initShowTooltip();\n state.rendered = true;\n };\n /**\n * Initialize chart elements\n * @private\n */\n ChartInternal.prototype.initChartElements = function () {\n var $$ = this;\n var _a = $$.state, hasAxis = _a.hasAxis, hasRadar = _a.hasRadar, hasTreemap = _a.hasTreemap;\n var types = [];\n if (hasAxis) {\n [\"bar\", \"bubble\", \"candlestick\", \"line\"].forEach(function (v) {\n var name = capitalize(v);\n if ((v === \"line\" && $$.hasTypeOf(name)) || $$.hasType(v)) {\n types.push(name);\n }\n });\n }\n else if (hasTreemap) {\n types.push(\"Treemap\");\n }\n else {\n var hasPolar = $$.hasType(\"polar\");\n if (!hasRadar) {\n types.push(\"Arc\", \"Pie\");\n }\n if ($$.hasType(\"gauge\")) {\n types.push(\"Gauge\");\n }\n else if (hasRadar) {\n types.push(\"Radar\");\n }\n else if (hasPolar) {\n types.push(\"Polar\");\n }\n }\n types.forEach(function (v) {\n $$[\"init\".concat(v)]();\n });\n notEmpty($$.config.data_labels) && !$$.hasArcType(null, [\"radar\"]) && $$.initText();\n };\n /**\n * Set chart elements\n * @private\n */\n ChartInternal.prototype.setChartElements = function () {\n var $$ = this;\n var _a = $$.$el, chart = _a.chart, svg = _a.svg, defs = _a.defs, main = _a.main, tooltip = _a.tooltip, legend = _a.legend, title = _a.title, grid = _a.grid, arc = _a.arcs, circles = _a.circle, bars = _a.bar, candlestick = _a.candlestick, lines = _a.line, areas = _a.area, texts = _a.text;\n $$.api.$ = {\n chart: chart,\n svg: svg,\n defs: defs,\n main: main,\n tooltip: tooltip,\n legend: legend,\n title: title,\n grid: grid,\n arc: arc,\n circles: circles,\n bar: { bars: bars },\n candlestick: candlestick,\n line: { lines: lines, areas: areas },\n text: { texts: texts }\n };\n };\n /**\n * Set background element/image\n * @private\n */\n ChartInternal.prototype.setBackground = function () {\n var $$ = this;\n var bg = $$.config.background, state = $$.state, svg = $$.$el.svg;\n if (notEmpty(bg)) {\n var element = svg.select(\"g\")\n .insert(bg.imgUrl ? \"image\" : \"rect\", \":first-child\");\n if (bg.imgUrl) {\n element.attr(\"href\", bg.imgUrl);\n }\n else if (bg.color) {\n element\n .style(\"fill\", bg.color)\n .attr(\"clip-path\", state.clip.path);\n }\n element\n .attr(\"class\", bg[\"class\"] || null)\n .attr(\"width\", \"100%\")\n .attr(\"height\", \"100%\");\n }\n };\n /**\n * Update targeted element with given data\n * @param {object} targets Data object formatted as 'target'\n * @private\n */\n ChartInternal.prototype.updateTargets = function (targets) {\n var _a;\n var $$ = this;\n var _b = $$.state, hasAxis = _b.hasAxis, hasRadar = _b.hasRadar, hasTreemap = _b.hasTreemap;\n var helper = function (type) { return $$[\"updateTargetsFor\".concat(type)](targets.filter($$[\"is\".concat(type, \"Type\")].bind($$))); };\n // Text\n $$.updateTargetsForText(targets);\n if (hasAxis) {\n [\"bar\", \"candlestick\", \"line\"].forEach(function (v) {\n var name = capitalize(v);\n if ((v === \"line\" && $$.hasTypeOf(name)) || $$.hasType(v)) {\n helper(name);\n }\n });\n // Sub Chart\n $$.updateTargetsForSubchart &&\n $$.updateTargetsForSubchart(targets);\n // Arc, Polar, Radar\n }\n else if ($$.hasArcType(targets)) {\n var type = \"Arc\";\n if (hasRadar) {\n type = \"Radar\";\n }\n else if ($$.hasType(\"polar\")) {\n type = \"Polar\";\n }\n helper(type);\n // Arc, Polar, Radar\n }\n else if (hasTreemap) {\n helper(\"Treemap\");\n }\n // Point types\n var hasPointType = $$.hasType(\"bubble\") || $$.hasType(\"scatter\");\n if (hasPointType) {\n (_a = $$.updateTargetForCircle) === null || _a === void 0 ? void 0 : _a.call($$);\n }\n // Fade-in each chart\n $$.filterTargetsToShowAtInit(hasPointType);\n };\n /**\n * Display targeted elements at initialization\n * @param {boolean} hasPointType whether has point type(bubble, scatter) or not\n * @private\n */\n ChartInternal.prototype.filterTargetsToShowAtInit = function (hasPointType) {\n if (hasPointType === void 0) { hasPointType = false; }\n var $$ = this;\n var svg = $$.$el.svg, $T = $$.$T;\n var selector = \".\".concat($COMMON.target);\n if (hasPointType) {\n selector += \", .\".concat($CIRCLE.chartCircles, \" > .\").concat($CIRCLE.circles);\n }\n $T(svg.selectAll(selector)\n .filter(function (d) { return $$.isTargetToShow(d.id); })).style(\"opacity\", null);\n };\n ChartInternal.prototype.getWithOption = function (options) {\n var withOptions = {\n Dimension: true,\n EventRect: true,\n Legend: false,\n Subchart: true,\n Transform: false,\n Transition: true,\n TrimXDomain: true,\n UpdateXAxis: \"UpdateXDomain\",\n UpdateXDomain: false,\n UpdateOrgXDomain: false,\n TransitionForExit: \"Transition\",\n TransitionForAxis: \"Transition\",\n Y: true\n };\n Object.keys(withOptions).forEach(function (key) {\n var defVal = withOptions[key];\n if (isString(defVal)) {\n defVal = withOptions[defVal];\n }\n withOptions[key] = getOption(options, \"with\".concat(key), defVal);\n });\n return withOptions;\n };\n ChartInternal.prototype.initialOpacity = function (d) {\n var $$ = this;\n var withoutFadeIn = $$.state.withoutFadeIn;\n var r = $$.getBaseValue(d) !== null &&\n withoutFadeIn[d.id] ? null : \"0\";\n return r;\n };\n ChartInternal.prototype.bindResize = function () {\n var $$ = this;\n var config = $$.config, state = $$.state;\n var resizeFunction = generateResize(config.resize_timer);\n var list = [];\n list.push(function () { return callFn(config.onresize, $$.api); });\n if (config.resize_auto) {\n list.push(function () {\n state.resizing = true;\n // https://github.com/naver/billboard.js/issues/2650\n if (config.legend_show) {\n $$.updateSizes();\n $$.updateLegend();\n }\n $$.api.flush(false);\n });\n }\n list.push(function () {\n callFn(config.onresized, $$.api);\n state.resizing = false;\n });\n // add resize functions\n list.forEach(function (v) { return resizeFunction.add(v); });\n $$.resizeFunction = resizeFunction;\n // attach resize event\n win.addEventListener(\"resize\", $$.resizeFunction = resizeFunction);\n };\n /**\n * Call plugin hook\n * @param {string} phase The lifecycle phase\n * @param {Array} args Arguments\n * @private\n */\n ChartInternal.prototype.callPluginHook = function (phase) {\n var _this = this;\n var args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n args[_i - 1] = arguments[_i];\n }\n this.config.plugins.forEach(function (v) {\n if (phase === \"$beforeInit\") {\n v.$$ = _this;\n _this.api.plugins.push(v);\n }\n v[phase].apply(v, args);\n });\n };\n return ChartInternal;\n}());\nextend(ChartInternal.prototype, [\n // common\n dataConvert,\n data$1,\n dataLoad,\n category,\n classModule,\n color,\n domain,\n interaction,\n format,\n legend$1,\n redraw,\n scale,\n shape,\n size,\n style,\n text,\n title,\n tooltip$1,\n transform,\n typeInternals\n]);\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\n/**\n * Load configuration option\n * @param {object} config User's generation config value\n * @private\n */\nfunction loadConfig(config) {\n var thisConfig = this.config;\n var target;\n var keys;\n var read;\n var find = function () {\n var key = keys.shift();\n if (key && target && isObjectType(target) && key in target) {\n target = target[key];\n return find();\n }\n else if (!key) {\n return target;\n }\n return undefined;\n };\n Object.keys(thisConfig).forEach(function (key) {\n target = config;\n keys = key.split(\"_\");\n read = find();\n if (isDefined(read)) {\n thisConfig[key] = read;\n }\n });\n // only should run in the ChartInternal context\n if (this.api) {\n this.state.orgConfig = config;\n }\n}\n\n/**\n * Copyright (c) 2017 ~ present NAVER Corp.\n * billboard.js project is licensed under the MIT license\n */\nvar apiChart = {\n /**\n * Resize the chart.\n * @function resize\n * @instance\n * @memberof Chart\n * @param {object} size This argument should include width and height in pixels.\n * @param {number} [size.width] width value\n * @param {number} [size.height] height value\n * @example\n * // Resize to 640x480\n * chart.resize({\n * width: 640,\n * height: 480\n * });\n */\n resize: function (size) {\n var $$ = this.internal;\n var config = $$.config, state = $$.state;\n if (state.rendered) {\n config.size_width = size ? size.width : null;\n config.size_height = size ? size.height : null;\n state.resizing = true;\n this.flush(false);\n $$.resizeFunction();\n }\n },\n /**\n * Force to redraw.\n * - **NOTE:** When zoom/subchart is used, the zoomed state will be resetted.\n * @function flush\n * @instance\n * @memberof Chart\n * @param {boolean} [soft] For soft redraw.\n * @example\n * chart.flush();\n *\n * // for soft redraw\n * chart.flush(true);\n */\n flush: function (soft) {\n var _a, _b;\n var $$ = this.internal;\n var state = $$.state, zoomResetBtn = $$.$el.zoomResetBtn;\n if (state.rendered) {\n // reset possible zoom scale when is called from resize event\n // eslint-disable-next-line prefer-rest-params\n if (state.resizing) { // arguments[1] is given when is called from resize\n (_a = $$.brush) === null || _a === void 0 ? void 0 : _a.updateResize();\n }\n else {\n // re-update config info\n (_b = $$.axis) === null || _b === void 0 ? void 0 : _b.setOrient();\n }\n // hide possible reset zoom button\n // https://github.com/naver/billboard.js/issues/2201\n zoomResetBtn === null || zoomResetBtn === void 0 ? void 0 : zoomResetBtn.style(\"display\", \"none\");\n $$.scale.zoom = null;\n soft ? $$.redraw({\n withTransform: true,\n withUpdateXDomain: true,\n withUpdateOrgXDomain: true,\n withLegend: true\n }) : $$.updateAndRedraw({\n withLegend: true,\n withTransition: false,\n withTransitionForTransform: false\n });\n // reset subchart selection & selection state\n if (!state.resizing && $$.brush) {\n $$.brush.getSelection().call($$.brush.move);\n $$.unselectRect();\n }\n }\n else {\n $$.initToRender(true);\n }\n },\n /**\n * Reset the chart object and remove element and events completely.\n * @function destroy\n * @instance\n * @memberof Chart\n * @returns {null}\n * @example\n * chart.destroy();\n */\n destroy: function () {\n var _this = this;\n var $$ = this.internal;\n var _a = $$.$el, chart = _a.chart, style = _a.style, svg = _a.svg;\n if (notEmpty($$)) {\n $$.callPluginHook(\"$willDestroy\");\n $$.charts.splice($$.charts.indexOf(this), 1);\n // detach events\n $$.unbindAllEvents();\n // clear timers && pending transition\n svg.select(\"*\").interrupt();\n $$.resizeFunction.clear();\n win.removeEventListener(\"resize\", $$.resizeFunction);\n chart.classed(\"bb\", false)\n .style(\"position\", null)\n .selectChildren()\n .remove();\n // remove