@nethru/kit 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.esm.js +1083 -1102
  2. package/dist/index.js +1083 -1100
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,1018 +1,234 @@
1
1
  'use strict';
2
2
 
3
3
  var React$1 = require('react');
4
- var Highcharts$1 = require('highcharts');
5
- var HighchartsReact = require('highcharts-react-official');
6
- var highchartsAccessibility = require('highcharts/modules/accessibility');
7
- var highchartsAnnotations = require('highcharts/modules/annotations');
8
- var colors = require('@nethru/ui/base/colors');
9
4
  var material = require('@mui/material');
10
5
  var jsxRuntime = require('react/jsx-runtime');
6
+ var Highcharts = require('highcharts');
7
+ var HighchartsReact = require('highcharts-react-official');
8
+ require('highcharts/modules/pattern-fill.js');
9
+ var highchartsAccessibility = require('highcharts/modules/accessibility.js');
10
+ var highchartsAnnotations = require('highcharts/modules/annotations.js');
11
+ var index_js = require('@nethru/ui/base/colors/index.js');
11
12
  var iconsMaterial = require('@mui/icons-material');
12
13
 
13
- function getDefaultExportFromCjs (x) {
14
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
14
+ let globalConfig = {
15
+ apiUrl: ''
16
+ };
17
+ function configure$1(config) {
18
+ globalConfig = {
19
+ ...globalConfig,
20
+ ...config
21
+ };
15
22
  }
23
+ function getConfig() {
24
+ return globalConfig;
25
+ }
26
+
27
+ function ok$1() {}
16
28
 
17
- var patternFill = {exports: {}};
29
+ function unreachable() {}
18
30
 
19
31
  /**
20
- * Highcharts JS v11.3.0 (2024-01-10)
21
- *
22
- * Module for adding patterns and images as point fills.
32
+ * @typedef Options
33
+ * Configuration for `stringify`.
34
+ * @property {boolean} [padLeft=true]
35
+ * Whether to pad a space before a token.
36
+ * @property {boolean} [padRight=false]
37
+ * Whether to pad a space after a token.
38
+ */
39
+
40
+
41
+ /**
42
+ * Serialize an array of strings or numbers to comma-separated tokens.
23
43
  *
24
- * (c) 2010-2024 Highsoft AS
25
- * Author: Torstein Hønsi, Øystein Moseng
44
+ * @param {Array<string|number>} values
45
+ * List of tokens.
46
+ * @param {Options} [options]
47
+ * Configuration for `stringify` (optional).
48
+ * @returns {string}
49
+ * Comma-separated tokens.
50
+ */
51
+ function stringify$1(values, options) {
52
+ const settings = {};
53
+
54
+ // Ensure the last empty entry is seen.
55
+ const input = values[values.length - 1] === '' ? [...values, ''] : values;
56
+
57
+ return input
58
+ .join(
59
+ (settings.padRight ? ' ' : '') +
60
+ ',' +
61
+ (settings.padLeft === false ? '' : ' ')
62
+ )
63
+ .trim()
64
+ }
65
+
66
+ /**
67
+ * @typedef Options
68
+ * Configuration.
69
+ * @property {boolean | null | undefined} [jsx=false]
70
+ * Support JSX identifiers (default: `false`).
71
+ */
72
+
73
+ const nameRe = /^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u;
74
+ const nameReJsx = /^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u;
75
+
76
+ /** @type {Options} */
77
+ const emptyOptions$2 = {};
78
+
79
+ /**
80
+ * Checks if the given value is a valid identifier name.
26
81
  *
27
- * License: www.highcharts.com/license
82
+ * @param {string} name
83
+ * Identifier to check.
84
+ * @param {Options | null | undefined} [options]
85
+ * Configuration (optional).
86
+ * @returns {boolean}
87
+ * Whether `name` can be an identifier.
88
+ */
89
+ function name(name, options) {
90
+ const settings = emptyOptions$2;
91
+ const re = settings.jsx ? nameReJsx : nameRe;
92
+ return re.test(name)
93
+ }
94
+
95
+ /**
96
+ * @typedef {import('hast').Nodes} Nodes
28
97
  */
29
98
 
30
- var hasRequiredPatternFill;
99
+ // HTML whitespace expression.
100
+ // See <https://infra.spec.whatwg.org/#ascii-whitespace>.
101
+ const re = /[ \t\n\f\r]/g;
31
102
 
32
- function requirePatternFill () {
33
- if (hasRequiredPatternFill) return patternFill.exports;
34
- hasRequiredPatternFill = 1;
35
- (function (module) {
36
- !function(t){module.exports?(t.default=t,module.exports=t):t("undefined"!=typeof Highcharts?Highcharts:void 0);}(function(t){var e=t?t._modules:{};function r(t,e,r,i){t.hasOwnProperty(e)||(t[e]=i.apply(null,r),"function"==typeof CustomEvent&&window.dispatchEvent(new CustomEvent("HighchartsModuleLoaded",{detail:{path:e,module:t[e]}})));}r(e,"Extensions/PatternFill.js",[e["Core/Animation/AnimationUtilities.js"],e["Core/Defaults.js"],e["Core/Globals.js"],e["Core/Utilities.js"]],function(t,e,r,i){let{animObject:a}=t,{getOptions:o}=e,{composed:n}=r,{addEvent:s,defined:h,erase:l,extend:p,merge:c,pick:d,pushUnique:f,removeEvent:u,wrap:g}=i,m=function(){let t=[],e=o().colors,r=0;for(let i of ["M 0 0 L 5 5 M 4.5 -0.5 L 5.5 0.5 M -0.5 4.5 L 0.5 5.5","M 0 5 L 5 0 M -0.5 0.5 L 0.5 -0.5 M 4.5 5.5 L 5.5 4.5","M 2 0 L 2 5 M 4 0 L 4 5","M 0 2 L 5 2 M 0 4 L 5 4","M 0 1.5 L 2.5 1.5 L 2.5 0 M 2.5 5 L 2.5 3.5 L 5 3.5"])t.push({path:i,color:e[r++],width:5,height:5,patternTransform:"scale(1.4 1.4)"});for(let i of(r=5,["M 0 0 L 5 10 L 10 0","M 3 3 L 8 3 L 8 8 L 3 8 Z","M 5 5 m -4 0 a 4 4 0 1 1 8 0 a 4 4 0 1 1 -8 0","M 0 0 L 10 10 M 9 -1 L 11 1 M -1 9 L 1 11","M 0 10 L 10 0 M -1 1 L 1 -1 M 9 11 L 11 9"]))t.push({path:i,color:e[r],width:10,height:10}),r+=5;return t}();function y(t,e){let r=JSON.stringify(t),i=r.length||0,a=0,o=0,n;if(e){n=Math.max(Math.floor(i/500),1);for(let t=0;t<i;t+=n)a+=r.charCodeAt(t);a&=a;}for(;o<i;++o)a=(a<<5)-a+r.charCodeAt(o),a&=a;return a.toString(16).replace("-","1")}function x(){if(this.renderer&&(this.renderer.defIds||[]).filter(t=>t&&t.indexOf&&0===t.indexOf("highcharts-pattern-")).length){for(let t of this.series)if(t.visible)for(let e of t.points){let t=e.options&&e.options.color;t&&t.pattern&&(t.pattern._width="defer",t.pattern._height="defer");}this.redraw(false);}}function w(){let t={},e=this.renderer,r=(e.defIds||[]).filter(t=>t.indexOf&&0===t.indexOf("highcharts-pattern-"));if(r.length)for(let i of([].forEach.call(this.renderTo.querySelectorAll('[color^="url("], [fill^="url("], [stroke^="url("]'),r=>{let i=r.getAttribute("fill")||r.getAttribute("color")||r.getAttribute("stroke");if(i){let r=i.replace(e.url,"").replace("url(#","").replace(")","");t[r]=true;}}),r))!t[i]&&(l(e.defIds,i),e.patternElements[i]&&(e.patternElements[i].destroy(),delete e.patternElements[i]));}function M(){let t=this.options.color;t&&t.pattern&&("string"==typeof t.pattern.path&&(t.pattern.path={d:t.pattern.path}),this.color=this.options.color=c(this.series.options.color,t));}function L(t){let e=t.args[0],r=t.args[1],i=t.args[2],a=this.chartIndex||0,o=e.pattern,n="#333333";if(void 0!==e.patternIndex&&m&&(o=m[e.patternIndex]),!o)return true;if(o.image||"string"==typeof o.path||o.path&&o.path.d){let t=i.parentNode&&i.parentNode.getAttribute("class");t=t&&t.indexOf("highcharts-legend")>-1,("defer"===o._width||"defer"===o._height)&&_.call({graphic:{element:i}},o),(t||!o.id)&&((o=c({},o)).id="highcharts-pattern-"+a+"-"+y(o)+y(o,true)),this.addPattern(o,!this.forExport&&d(o.animation,this.globalAnimation,{duration:100})),n=`url(${this.url}#${o.id+(this.forExport?"-export":"")})`;}else n=o.color||n;return i.setAttribute(r,n),e.toString=function(){return n},false}function b(){let t=this.chart.isResizing;if(this.isDirtyData||t||!this.chart.hasRendered)for(let e of this.points){let r=e.options&&e.options.color;r&&r.pattern&&(t&&!(e.shapeArgs&&e.shapeArgs.width&&e.shapeArgs.height)?(r.pattern._width="defer",r.pattern._height="defer"):e.calculatePatternDimensions(r.pattern));}}function _(t){if(t.width&&t.height)return;let e=this.graphic&&(this.graphic.getBBox&&this.graphic.getBBox(true)||this.graphic.element&&this.graphic.element.getBBox())||{},r=this.shapeArgs;if(r&&(e.width=r.width||e.width,e.height=r.height||e.height,e.x=r.x||e.x,e.y=r.y||e.y),t.image){if(!e.width||!e.height){t._width="defer",t._height="defer";let e=this.series.chart.mapView&&this.series.chart.mapView.getSVGTransform().scaleY;h(e)&&e<0&&(t._inverted=true);return}t.aspectRatio&&(e.aspectRatio=e.width/e.height,t.aspectRatio>e.aspectRatio?e.aspectWidth=e.height*t.aspectRatio:e.aspectHeight=e.width/t.aspectRatio),t._width=t.width||Math.ceil(e.aspectWidth||e.width),t._height=t.height||Math.ceil(e.aspectHeight||e.height);}t.width||(t._x=t.x||0,t._x+=e.x-Math.round(e.aspectWidth?Math.abs(e.aspectWidth-e.width)/2:0)),t.height||(t._y=t.y||0,t._y+=e.y-Math.round(e.aspectHeight?Math.abs(e.aspectHeight-e.height)/2:0));}function A(t,e){let r=d(e,true),o=a(r),n=t.color||"#333333",s=t.height||("number"==typeof t._height?t._height:0)||32,h=t.width||("number"==typeof t._width?t._width:0)||32,l,p=t.id,c;if(!p&&(this.idCounter=this.idCounter||0,p="highcharts-pattern-"+this.idCounter+"-"+(this.chartIndex||0),++this.idCounter),this.forExport&&(p+="-export"),this.defIds=this.defIds||[],this.defIds.indexOf(p)>-1)return;this.defIds.push(p);let f={id:p,patternUnits:"userSpaceOnUse",patternContentUnits:t.patternContentUnits||"userSpaceOnUse",width:h,height:s,x:t._x||t.x||0,y:t._y||t.y||0};t._inverted&&(f.patternTransform="scale(1, -1)",t.patternTransform&&(t.patternTransform+=" scale(1, -1)")),t.patternTransform&&(f.patternTransform=t.patternTransform);let g=this.createElement("pattern").attr(f).add(this.defs);if(g.id=p,t.path){if(c=i.isObject(t.path)?t.path:{d:t.path},t.backgroundColor){var m;m=t.backgroundColor,this.rect(0,0,h,s).attr({fill:m}).add(g);}l={d:c.d},this.styledMode||(l.stroke=c.stroke||n,l["stroke-width"]=d(c.strokeWidth,2),l.fill=c.fill||"none"),c.transform&&(l.transform=c.transform),this.createElement("path").attr(l).add(g),g.color=n;}else t.image&&(r?this.image(t.image,0,0,h,s,function(){this.animate({opacity:d(t.opacity,1)},o),u(this.element,"load");}).attr({opacity:0}).add(g):this.image(t.image,0,0,h,s).add(g));return t.image&&r||void 0===t.opacity||[].forEach.call(g.element.childNodes,e=>{e.setAttribute("opacity",t.opacity);}),this.patternElements=this.patternElements||{},this.patternElements[p]=g,g}function C(t){let e=this.options.color;e&&e.pattern&&!e.pattern.color?(delete this.options.color,t.apply(this,[].slice.call(arguments,1)),e.pattern.color=this.color,this.color=this.options.color=e):t.apply(this,[].slice.call(arguments,1));}function E(){if(!this.chart?.mapView)return;let t=this.chart,e=t.renderer,r=e.patternElements;e.defIds?.length&&r&&this.points.filter(function(t){return !!t.graphic&&(t.graphic.element.hasAttribute("fill")||t.graphic.element.hasAttribute("color")||t.graphic.element.hasAttribute("stroke"))&&!t.options.color?.pattern?.image&&!!t.group?.scaleX&&!!t.group?.scaleY}).map(function(t){let r=(t.graphic?.element.getAttribute("fill")||t.graphic?.element.getAttribute("color")||t.graphic?.element.getAttribute("stroke")||"").replace(e.url,"").replace("url(#","").replace(")","");return [r,{x:t.group?.scaleX||1,y:t.group?.scaleY||1}]}).filter(function([t,e],r,i){return ""!==t&&-1!==t.indexOf("highcharts-pattern-")&&!i.some(function([e,i],a){return e===t&&a<r})}).forEach(function([t,e]){r[t].scaleX=1/e.x,r[t].scaleY=1/e.y,r[t].updateTransform("patternTransform");});}return {compose:function t(e,r,i){let a=r.prototype.pointClass;f(n,t)&&(s(e,"endResize",x),s(e,"redraw",w),p(a.prototype,{calculatePatternDimensions:_}),s(a,"afterInit",M),s(r,"render",b),g(r.prototype,"getColor",C),s(r,"afterRender",E),s(r,"mapZoomComplete",E),p(i.prototype,{addPattern:A}),s(i,"complexColor",L));},patterns:m}}),r(e,"masters/modules/pattern-fill.src.js",[e["Core/Globals.js"],e["Extensions/PatternFill.js"]],function(t,e){t.patterns=e.patterns,e.compose(t.Chart,t.Series,t.SVGRenderer);});});
37
- } (patternFill));
38
- return patternFill.exports;
103
+ /**
104
+ * Check if the given value is *inter-element whitespace*.
105
+ *
106
+ * @param {Nodes | string} thing
107
+ * Thing to check (`Node` or `string`).
108
+ * @returns {boolean}
109
+ * Whether the `value` is inter-element whitespace (`boolean`): consisting of
110
+ * zero or more of space, tab (`\t`), line feed (`\n`), carriage return
111
+ * (`\r`), or form feed (`\f`); if a node is passed it must be a `Text` node,
112
+ * whose `value` field is checked.
113
+ */
114
+ function whitespace(thing) {
115
+ return typeof thing === 'object'
116
+ ? thing.type === 'text'
117
+ ? empty$1(thing.value)
118
+ : false
119
+ : empty$1(thing)
39
120
  }
40
121
 
41
- requirePatternFill();
122
+ /**
123
+ * @param {string} value
124
+ * @returns {boolean}
125
+ */
126
+ function empty$1(value) {
127
+ return value.replace(re, '') === ''
128
+ }
42
129
 
43
- const PieChart = ({
44
- data,
45
- width = 230,
46
- height = 180,
47
- size = '60%',
48
- colors = ['#2652a8', '#b47813', '#aa1a32']
49
- }) => {
50
- const noData = data.metrics.some(m => m.transparent);
51
- const options = React$1.useMemo(() => {
52
- const chartData = data.metrics.filter(metric => metric.transparent || metric.value > 0).map((metric, index) => ({
53
- name: metric.label,
54
- y: metric.value,
55
- color: metric.transparent ? checkerboardPattern() : colors[index % colors.length]
56
- }));
57
- return {
58
- chart: {
59
- type: 'pie',
60
- backgroundColor: 'transparent',
61
- width: width,
62
- height: height,
63
- style: {
64
- fontFamily: fontFamily$1
65
- }
66
- },
67
- title: {
68
- text: undefined
69
- },
70
- tooltip: {
71
- pointFormat: '<span><b>{point.y}</b> ({point.percentage:.1f}%)</span>',
72
- style: {
73
- fontFamily: fontFamily$1,
74
- fontSize: '13px'
75
- },
76
- useHTML: true
77
- },
78
- plotOptions: {
79
- pie: {
80
- size: size,
81
- allowPointSelect: true,
82
- cursor: 'pointer',
83
- dataLabels: {
84
- enabled: true,
85
- format: '{point.name}<br><b>{point.y}</b> ({point.percentage:.1f}%)',
86
- distance: 20,
87
- style: {
88
- fontSize: '13px',
89
- fontWeight: '100',
90
- textOutline: 'none',
91
- fontFamily: fontFamily$1
92
- },
93
- connectorColor: '#666',
94
- connectorWidth: 1,
95
- overflow: 'allow',
96
- crop: false
97
- },
98
- showInLegend: false
99
- }
100
- },
101
- series: [{
102
- type: 'pie',
103
- name: '',
104
- colorByPoint: true,
105
- data: chartData
106
- }],
107
- credits: {
108
- enabled: false
109
- },
110
- accessibility: {
111
- enabled: false
112
- }
113
- };
114
- }, [data, width, height, size, colors]);
115
- return /*#__PURE__*/React$1.createElement("div", {
116
- style: styles$7.chartWrapper
117
- }, /*#__PURE__*/React$1.createElement("div", {
118
- style: {
119
- ...styles$7.chartContainer,
120
- width,
121
- height,
122
- position: 'relative'
123
- }
124
- }, noData && /*#__PURE__*/React$1.createElement(CheckerboardBackground, {
125
- width: width,
126
- height: height
127
- }), /*#__PURE__*/React$1.createElement("div", {
128
- style: {
129
- position: 'relative',
130
- zIndex: 1
130
+ /**
131
+ * @import {Schema as SchemaType, Space} from 'property-information'
132
+ */
133
+
134
+ /** @type {SchemaType} */
135
+ class Schema {
136
+ /**
137
+ * @param {SchemaType['property']} property
138
+ * Property.
139
+ * @param {SchemaType['normal']} normal
140
+ * Normal.
141
+ * @param {Space | undefined} [space]
142
+ * Space.
143
+ * @returns
144
+ * Schema.
145
+ */
146
+ constructor(property, normal, space) {
147
+ this.normal = normal;
148
+ this.property = property;
149
+
150
+ if (space) {
151
+ this.space = space;
131
152
  }
132
- }, /*#__PURE__*/React$1.createElement(HighchartsReact, {
133
- highcharts: Highcharts$1,
134
- options: options
135
- }))), /*#__PURE__*/React$1.createElement("div", {
136
- style: styles$7.agentName
137
- }, data.name));
138
- };
139
- const fontFamily$1 = 'Pretendard, -apple-system, BlinkMacSystemFont, sans-serif';
140
- const styles$7 = {
141
- chartWrapper: {
142
- background: 'transparent',
143
- textAlign: 'center',
144
- display: 'flex',
145
- flexDirection: 'column',
146
- justifyContent: 'center',
147
- alignItems: 'center'
148
- },
149
- chartContainer: {
150
- display: 'flex',
151
- alignItems: 'center',
152
- justifyContent: 'center'
153
- },
154
- agentName: {
155
- fontSize: '12px',
156
- fontWeight: '100',
157
- marginTop: '-30px',
158
- color: '#333'
159
153
  }
160
- };
161
- const CheckerboardBackground = ({
162
- width,
163
- height
164
- }) => {
165
- const circleSize = Math.min(width, height) * 0.47;
166
- return /*#__PURE__*/React$1.createElement("div", {
167
- style: {
168
- position: 'absolute',
169
- width: circleSize,
170
- height: circleSize,
171
- borderRadius: '50%',
172
- backgroundImage: `
173
- linear-gradient(45deg, #e0e0e0 25%, transparent 25%),
174
- linear-gradient(-45deg, #e0e0e0 25%, transparent 25%),
175
- linear-gradient(45deg, transparent 75%, #e0e0e0 75%),
176
- linear-gradient(-45deg, transparent 75%, #e0e0e0 75%)
177
- `,
178
- backgroundSize: '10px 10px',
179
- backgroundPosition: '0 0, 0 5px, 5px -5px, -5px 0px',
180
- backgroundColor: '#ffffff',
181
- zIndex: 0
182
- }
183
- });
184
- };
185
- const checkerboardPattern = () => ({
186
- pattern: {
187
- path: {
188
- d: 'M 0 0 L 5 5 M 4.5 -0.5 L 5.5 0.5 M -0.5 4.5 L 0.5 5.5',
189
- stroke: '#d0d0d0',
190
- strokeWidth: 1
191
- },
192
- width: 5,
193
- height: 5,
194
- backgroundColor: '#ffffff',
195
- opacity: 1
196
- }
197
- });
154
+ }
198
155
 
199
- const ColumnChart = ({
200
- data,
201
- width,
202
- height = 230
203
- }) => {
204
- const series = React$1.useMemo(() => {
205
- return data.series.map((item, sindex) => ({
206
- ...item,
207
- data: item.data.map((value, index) => ({
208
- y: value,
209
- color: data.colors[index % data.colors.length] + alphas[sindex % alphas.length]
210
- }))
211
- }));
212
- }, [data]);
213
- const colors = React$1.useMemo(() => {
214
- return data.series.map((_, index) => data.colors[0] + alphas[index % alphas.length]);
215
- }, [data]);
216
- const options = React$1.useMemo(() => {
217
- return {
218
- chart: {
219
- type: 'column',
220
- backgroundColor: 'transparent',
221
- width: width,
222
- height: height,
223
- style: {
224
- fontFamily: fontFamily
225
- }
226
- },
227
- title: {
228
- text: undefined
229
- },
230
- tooltip: {
231
- pointFormat: '<span><b>{point.y}</b></span>',
232
- style: {
233
- fontFamily: fontFamily,
234
- fontSize: '13px',
235
- fontWeight: '100'
236
- },
237
- useHTML: true
238
- },
239
- plotOptions: {
240
- column: {
241
- //size: size
242
- }
243
- },
244
- xAxis: {
245
- categories: data.categories,
246
- crosshair: true,
247
- labels: {
248
- style: {
249
- color: '#777',
250
- fontFamily: fontFamily,
251
- fontWeight: '400'
252
- }
253
- },
254
- lineColor: '#aaa'
255
- },
256
- yAxis: {
257
- title: {
258
- text: undefined
259
- },
260
- labels: {
261
- style: {
262
- fontFamily: fontFamily,
263
- fontSize: '12px',
264
- fontWeight: '100'
265
- }
266
- },
267
- gridLineColor: '#f9f9f9'
268
- },
269
- legend: {
270
- layout: 'vertical',
271
- itemStyle: {
272
- fontFamily: fontFamily,
273
- fontSize: '12px',
274
- fontWeight: '100'
275
- },
276
- useHTML: true
277
- },
278
- series: series,
279
- colors: colors,
280
- credits: {
281
- enabled: false
282
- },
283
- accessibility: {
284
- enabled: false
285
- }
286
- };
287
- }, [data, width, height, series, colors]);
288
- return /*#__PURE__*/React$1.createElement("div", {
289
- style: styles$6.chartWrapper
290
- }, /*#__PURE__*/React$1.createElement(HighchartsReact, {
291
- highcharts: Highcharts$1,
292
- options: options
293
- }));
294
- };
295
- const fontFamily = 'Pretendard, -apple-system, BlinkMacSystemFont, sans-serif';
296
- const styles$6 = {
297
- chartWrapper: {
298
- background: 'transparent',
299
- textAlign: 'center',
300
- display: 'flex',
301
- flexDirection: 'column',
302
- justifyContent: 'center',
303
- alignItems: 'center'
156
+ Schema.prototype.normal = {};
157
+ Schema.prototype.property = {};
158
+ Schema.prototype.space = undefined;
159
+
160
+ /**
161
+ * @import {Info, Space} from 'property-information'
162
+ */
163
+
164
+
165
+ /**
166
+ * @param {ReadonlyArray<Schema>} definitions
167
+ * Definitions.
168
+ * @param {Space | undefined} [space]
169
+ * Space.
170
+ * @returns {Schema}
171
+ * Schema.
172
+ */
173
+ function merge(definitions, space) {
174
+ /** @type {Record<string, Info>} */
175
+ const property = {};
176
+ /** @type {Record<string, string>} */
177
+ const normal = {};
178
+
179
+ for (const definition of definitions) {
180
+ Object.assign(property, definition.property);
181
+ Object.assign(normal, definition.normal);
304
182
  }
305
- };
306
- const alphas = ['ff', 'bb', '77', '33'];
307
183
 
308
- function _extends() {
309
- return _extends = Object.assign ? Object.assign.bind() : function (n) {
310
- for (var e = 1; e < arguments.length; e++) {
311
- var t = arguments[e];
312
- for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
313
- }
314
- return n;
315
- }, _extends.apply(null, arguments);
184
+ return new Schema(property, normal, space)
316
185
  }
317
186
 
318
- function toValue(value) {
319
- return value && typeof value === 'object' ? value.value : value;
320
- }
321
- function toPercent(value) {
322
- return Math.round(value * 100 * 100) / 100;
323
- }
324
- function formatNumber(value) {
325
- return value !== undefined ? value.toLocaleString() : '-';
326
- }
327
- function formatToPercent(value) {
328
- return formatPercent(toPercent(value));
329
- }
330
- function formatPercent(value) {
331
- return value !== undefined ? `${value.toLocaleString()}%` : '-';
332
- }
333
- function formatDuration(value) {
334
- value = toValue(value);
335
- if (!value) return '-';
336
- let day = Math.floor(value / (60 * 60 * 24));
337
- let hour = Math.floor(value / (60 * 60)) - day * 24;
338
- let minute = Math.floor(value / 60) - (day * 24 + hour) * 60;
339
- let second = Math.round(value % 60);
340
- day = day > 0 ? `${day.toLocaleString()}일 ` : '';
341
- hour = hour > 0 ? `${hour >= 10 ? hour : '0' + hour}시간 ` : '';
342
- minute = `${minute >= 10 ? minute : '0' + minute}분 `;
343
- second = `${second >= 10 ? second : '0' + second}초`;
344
- return `${day}${hour}${minute}${second}`;
345
- }
346
- function formatBytes(value) {
347
- return value !== undefined ? `${value.toLocaleString()} bytes` : '-';
187
+ /**
188
+ * Get the cleaned case insensitive form of an attribute or property.
189
+ *
190
+ * @param {string} value
191
+ * An attribute-like or property-like name.
192
+ * @returns {string}
193
+ * Value that can be used to look up the properly cased property on a
194
+ * `Schema`.
195
+ */
196
+ function normalize$1(value) {
197
+ return value.toLowerCase()
348
198
  }
349
- function format(value, type) {
350
- switch (type) {
351
- case 'TO_PERCENT':
352
- return formatToPercent(value);
353
- case 'DURATION':
354
- return formatDuration(value);
355
- case 'BYTES':
356
- return formatBytes(value);
357
- case 'PERCENT':
358
- return formatPercent(value);
359
- default:
360
- return formatNumber(value);
199
+
200
+ /**
201
+ * @import {Info as InfoType} from 'property-information'
202
+ */
203
+
204
+ /** @type {InfoType} */
205
+ class Info {
206
+ /**
207
+ * @param {string} property
208
+ * Property.
209
+ * @param {string} attribute
210
+ * Attribute.
211
+ * @returns
212
+ * Info.
213
+ */
214
+ constructor(property, attribute) {
215
+ this.attribute = attribute;
216
+ this.property = property;
361
217
  }
362
218
  }
363
219
 
364
- const all$1 = [[colors.blue[500]], [colors.purple[500], '#4168a6', '#81a7e1'], [colors.green[500], '#debb7f', '#ecdbbe'], [colors.yellow[500], '#1b8286', '#4ab3b6'], [colors.red[500]], [colors.orange[500]], [colors.lime[500]], ['#54AAF9'], ['#BB4ECD'], ['#6DDBBA'], ['#FFE81C'], ['#FA7EBA'], ['#F55713'], ['#51B304'], ['#1559B2'], ['#733FAB'], ['#1C7B5F'], ['#D87500'], ['#C91E48'], ['#2F862F']];
365
- [[colors.blue[400], colors.blue[500]], [colors.purple[400], colors.purple[500]], [colors.green[400], colors.green[500]], [colors.yellow[400], colors.yellow[500]], [colors.red[400], colors.red[500]], [colors.orange[400], colors.orange[500]], [colors.lime[400], colors.lime[500]]];
366
- [[material.alpha(colors.blue[500], 0.2), 'transparent', colors.blue[300]], [material.alpha(colors.purple[500], 0.2), 'transparent', colors.purple[500]], [material.alpha(colors.green[500], 0.2), 'transparent', colors.green[500]], [material.alpha(colors.yellow[500], 0.2), 'transparent', colors.yellow[500]], [material.alpha(colors.red[500], 0.2), 'transparent', colors.red[500]], [material.alpha(colors.orange[500], 0.2), 'transparent', colors.orange[500]], [material.alpha(colors.lime[500], 0.2), 'transparent', colors.lime[500]]];
367
- const preset = ['#003f5c', '#a05195', '#665191', '#2f4b7c', '#d45087', '#f95d6a', '#ff7c43', '#ffa600'];
368
- all$1.map(color => color[0]);
369
-
370
- highchartsAccessibility(Highcharts$1);
371
- highchartsAnnotations(Highcharts$1);
372
- function Chart(props) {
373
- const [legendLimitEnabled, setLegendLimitEnabled] = React$1.useState(props.legendLimit > 0);
374
- const [options, setOptions] = React$1.useState(toOptions(props, legendLimitEnabled));
375
- React$1.useEffect(() => {
376
- if (props.delay) setTimeout(() => setOptions(toOptions(props, legendLimitEnabled, handleLegendItemClick)), props.delay);else setOptions(toOptions(props, legendLimitEnabled, handleLegendItemClick));
377
- // eslint-disable-next-line
378
- }, [props]);
379
- const handleLegendItemClick = React$1.useCallback(() => setLegendLimitEnabled(false), []);
380
- return /*#__PURE__*/React.createElement(React.Fragment, null, options && /*#__PURE__*/React.createElement(HighchartsReact, {
381
- highcharts: Highcharts$1,
382
- options: options
383
- }));
384
- }
385
- function toOptions(props, legendLimitEnabled, handleLegendItemClick) {
386
- const {
387
- title = '',
388
- type,
389
- categorize,
390
- stacking,
391
- showLegend = true,
392
- showDataLabel,
393
- xAxisType,
394
- xAxisLabel = true,
395
- xAxisLabelFormat,
396
- xAxisTickInterval,
397
- yAxisLabelEnabled = true,
398
- yAxisLabelFormat,
399
- yAxisTickInterval = null,
400
- yAxisPlotLines = [],
401
- opacity = 1,
402
- innerSize = 0,
403
- colors: customColors,
404
- backgroundColor = undefined,
405
- xPlotIndex,
406
- dimension,
407
- metrics,
408
- records = [],
409
- metas,
410
- height = 200,
411
- legendLimit,
412
- legendAlign = 'center',
413
- tooltip = {},
414
- secondaryXAxis = []
415
- } = props;
416
- const {
417
- outside
418
- } = tooltip;
419
- const pie = type === 'pie';
420
- const centers = pieCenters(metrics.length);
421
- const size = pieSize(metrics.length);
422
- const colors$1 = customColors ? customColors : preset;
423
- const categories = records.map(record => record[dimension]);
424
- const mainXAxis = records.map(r => r.time);
425
- const chartColorHandlers = {
426
- line: (colors, index) => ({
427
- color: colors[index],
428
- mainColor: colors[index]
429
- }),
430
- area: (colors, index) => ({
431
- color: colors[index][0],
432
- mainColor: colors[index][1]
433
- }),
434
- gradient: (colors, index) => ({
435
- color: {
436
- linearGradient: {
437
- x1: 0,
438
- y1: 0,
439
- x2: 0,
440
- y2: 1
441
- },
442
- stops: [[0, `${colors[index][0]}`], [0.95, `${colors[index][1]}`]]
443
- },
444
- mainColor: colors[index][2]
445
- })
446
- };
447
- const series = metrics.map(({
448
- chartType,
449
- metric
450
- }, index) => {
451
- const type = chartType === 'gradient' ? 'area' : chartType;
452
- const {
453
- color,
454
- mainColor
455
- } = chartColorHandlers[chartType](colors$1, index);
456
- const meta = metas[metric];
457
- let option = {
458
- type: type,
459
- name: meta ? meta.name : '',
460
- data: records.map(record => {
461
- const data = record.metric[metric] ?? null;
462
- return pie ? {
463
- name: record[dimension],
464
- y: data
465
- } : data;
466
- }),
467
- custom: {
468
- type: meta ? meta.type : '',
469
- pointerNames: meta?.pointerNames ?? null
470
- },
471
- center: centers[index] || [null, null],
472
- size: size,
473
- point: {
474
- events: {
475
- render: function () {
476
- this.graphic.attr({
477
- zIndex: this.y === 0 ? -1 : ZIndex.COMPARE_CHART_BASE - index
478
- });
479
- }
480
- }
481
- },
482
- showInLegend: pie && index > 0 ? false : true,
483
- color: color,
484
- lineColor: mainColor,
485
- lineWidth: 2,
486
- marker: {
487
- fillColor: mainColor
488
- },
489
- metric: metric
490
- };
491
- if (legendLimitEnabled) option = {
492
- ...option,
493
- visible: index < legendLimit
494
- };
495
- return option;
496
- });
497
- const yPlotLines = yAxisPlotLines.map((line, index) => {
498
- return {
499
- value: line.value,
500
- width: 1,
501
- color: line.color,
502
- dashStyle: "Dash",
503
- zIndex: ZIndex.AVERAGE_LINE_BASE + index,
504
- label: {
505
- text: line.label,
506
- align: line.labelAlign,
507
- style: {
508
- color: line.labelColor,
509
- opacity: 0.7,
510
- fontSize: "12px",
511
- padding: '1px 5px'
512
- },
513
- y: -8,
514
- useHTML: true
515
- }
516
- };
517
- });
518
- const xPlotBands = [{
519
- from: xPlotIndex,
520
- to: categories.length - 1,
521
- color: 'rgba(0, 0, 0, 0.03)',
522
- zIndex: ZIndex.NOW_BAND
523
- }];
524
- const xPlotLines = [{
525
- color: "#aaa",
526
- width: 1,
527
- value: xPlotIndex,
528
- zIndex: ZIndex.NOW_BORDER,
529
- label: {
530
- text: "현재",
531
- rotation: 0,
532
- x: 5,
533
- y: 13,
534
- style: {
535
- fontWeight: 500,
536
- lineHeight: "16.8px",
537
- color: "#333",
538
- fontSize: "12px"
539
- }
540
- }
541
- }];
542
- return {
543
- chart: {
544
- type: type.toLowerCase(),
545
- height: height,
546
- backgroundColor,
547
- events: {
548
- render: secondaryXAxis.length === 0 ? undefined : function () {
549
- const chart = this;
550
- const visibleSeries = chart.series.filter(s => s.visible);
551
- let newCategories = null;
552
- if (visibleSeries.length === 1 && visibleSeries[0].options.metric === 'prev') {
553
- newCategories = secondaryXAxis;
554
- } else {
555
- newCategories = mainXAxis;
556
- }
557
- const isSame = JSON.stringify(chart.xAxis[0].categories) === JSON.stringify(newCategories);
558
- if (!isSame) {
559
- chart.xAxis[0].setCategories(newCategories);
560
- }
561
- }
562
- }
563
- },
564
- title: {
565
- text: ''
566
- },
567
- subtitle: {
568
- text: title
569
- },
570
- colors: colors$1,
571
- xAxis: {
572
- type: xAxisType,
573
- labels: {
574
- enabled: xAxisLabel,
575
- autoRotation: false,
576
- format: xAxisLabelFormat ? `{value:${xAxisLabelFormat}}` : undefined,
577
- style: {
578
- color: colors.grey[600]
579
- }
580
- },
581
- categories: categorize ? categories : undefined,
582
- tickWidth: 1,
583
- tickInterval: xAxisTickInterval ?? (xAxisType === 'datetime' ? records.length / 20 : 1),
584
- lineColor: colors.grey[900],
585
- tickColor: colors.grey[900],
586
- crosshair: true,
587
- startOnTick: true,
588
- plotBands: xPlotIndex !== undefined ? xPlotBands : undefined,
589
- plotLines: xPlotIndex !== undefined ? xPlotLines : undefined
590
- },
591
- yAxis: {
592
- title: {
593
- text: ''
594
- },
595
- labels: {
596
- enabled: yAxisLabelEnabled,
597
- formatter: yAxisLabelFormat,
598
- style: {
599
- color: colors.grey[600]
600
- }
601
- },
602
- tickInterval: yAxisTickInterval,
603
- gridLineColor: '#f8f8f8',
604
- plotLines: yPlotLines
605
- },
606
- plotOptions: {
607
- series: {
608
- opacity: opacity,
609
- stacking: stackingType(stacking),
610
- showInLegend: showLegend,
611
- dataLabels: {
612
- enabled: showDataLabel
613
- },
614
- colorByPoint: pie,
615
- lineWidth: 2,
616
- marker: {
617
- enabled: false,
618
- symbol: 'circle'
619
- },
620
- cursor: 'pointer',
621
- point: {
622
- events: {}
623
- },
624
- events: {
625
- legendItemClick: handleLegendItemClick
626
- }
627
- },
628
- pie: {
629
- allowPointSelect: true,
630
- innerSize: `${innerSize}%`
631
- }
632
- },
633
- legend: {
634
- align: legendAlign,
635
- verticalAlign: 'top',
636
- enabled: showLegend
637
- },
638
- tooltip: {
639
- followPointer: false,
640
- shared: true,
641
- shadow: false,
642
- useHTML: true,
643
- formatter: function () {
644
- return tooltipFormatter(this, tooltip);
645
- },
646
- outside: outside,
647
- style: {
648
- zIndex: 2000
649
- }
650
- },
651
- series: series,
652
- time: {
653
- useUTC: false,
654
- getTimezoneOffset: function () {
655
- return new Date().getTimezoneOffset();
656
- }
657
- },
658
- credits: {
659
- enabled: false
660
- }
661
- };
662
- }
663
- const tooltipFormatter = (_this, props) => {
664
- const {
665
- headerVisible = true,
666
- dateFormat,
667
- headerTime,
668
- legendColors = []
669
- } = props;
670
- let tooltip = '<div style="font-size: 14px;padding: 12px; min-width: 200px;">';
671
- if (headerVisible) {
672
- const xDate = new Date(_this.x);
673
- const date = formatDate(xDate, dateFormat);
674
- tooltip += `<div style="display: flex; justify-content: space-between; font-weight: bold; font-size: 12px;">
675
- <span style="font-size: 12px; color: #333;">${date}</span>`;
676
- if (headerTime) {
677
- const time = formatDate(xDate, '%H:%M');
678
- tooltip += `<span style="font-size: 12px; color: #333;">${time}</span>`;
679
- }
680
- tooltip += '</div>';
681
- }
682
- _this.points.forEach(point => {
683
- const type = point.series.options.custom.type;
684
- const value = type !== 'TO_PERCENT' ? format(point.y, type) : formatToPercent(_this.percentage / 100);
685
- const name = point.series.name;
686
- let color = type !== 'TO_PERCENT' ? point.series.color : point.color;
687
- if (legendColors.length !== 0) {
688
- color = legendColors[point.series.index];
689
- }
690
- tooltip += `<div style="display: flex; flex-direction: column; gap: 8px;">
691
- <div style="display: flex; justify-content: space-between; align-items: center; margin-top: 15px;">
692
- <span style="width: 10px; height: 10px; border-radius: 2px; margin-right: 8px; background-color: ${color}"></span>
693
- <span style="flex-grow: 1; font-size: 14px; padding-right: 20px;">${name}</span>
694
- <span style="font-weight: bold; font-size: 14px;">${value}</span>
695
- </div>
696
- </div>`;
697
- });
698
- tooltip += '</div>';
699
- return tooltip;
700
- };
701
- function formatDate(data, format) {
702
- return Highcharts$1.dateFormat(format, data.getTime() - data.getTimezoneOffset() * 60000);
703
- }
704
- const ZIndex = {
705
- AVERAGE_LINE_BASE: 10,
706
- COMPARE_CHART_BASE: 5,
707
- NOW_BORDER: 2,
708
- NOW_BAND: 1
709
- };
710
- function stackingType(stacking) {
711
- return stacking ? stacking.toLowerCase() : '';
712
- }
713
- function pieCenters(count) {
714
- switch (count) {
715
- case 2:
716
- return [['25%', '50%'], ['75%', '50%']];
717
- case 3:
718
- return [['25%', '25%'], ['75%', '25%'], ['50%', '75%']];
719
- case 4:
720
- return [['25%', '25%'], ['75%', '25%'], ['25%', '75%'], ['75%', '75%']];
721
- default:
722
- return [];
723
- }
724
- }
725
- function pieSize(count) {
726
- switch (count) {
727
- case 3:
728
- return '50%';
729
- case 4:
730
- return '25%';
731
- default:
732
- return null;
733
- }
734
- }
735
-
736
- function TrendChart({
737
- colorIndex = 0,
738
- legendColors,
739
- isDaily,
740
- isRealtime,
741
- ...props
742
- }) {
743
- const colors = React$1.useMemo(() => {
744
- return all$1[colorIndex % all$1.length];
745
- }, [colorIndex]);
746
- const tooltip = React$1.useMemo(() => ({
747
- dateFormat: isRealtime ? '%H:%M' : '%Y-%m-%d',
748
- headerTime: !isDaily && !isRealtime,
749
- outside: props.tooltipOutSide,
750
- legendColors
751
- }), [isRealtime, isDaily, props.tooltipOutSide, legendColors]);
752
- return /*#__PURE__*/React.createElement(Chart, _extends({
753
- type: "areaspline",
754
- categorize: true,
755
- xAxisType: "datetime",
756
- xAxisLabelFormat: isDaily ? '%m-%d' : '%H:%M',
757
- colors: colors,
758
- tooltip: tooltip
759
- }, props));
760
- }
761
-
762
- function StackedAreaTrendChart({
763
- metrics,
764
- records,
765
- isDaily = false,
766
- xPlotIndex,
767
- xAxisTickInterval,
768
- yAxisLabelEnabled = false,
769
- legendLimit = 3,
770
- colors = defaultColors,
771
- ...props
772
- }) {
773
- const _metrics = React$1.useMemo(() => {
774
- return metrics.map(m => ({
775
- metric: m.id,
776
- chartType: 'area'
777
- }));
778
- }, [metrics]);
779
- const metas = React$1.useMemo(() => {
780
- const result = {
781
- time: {
782
- name: "일시",
783
- type: "DATE"
784
- }
785
- };
786
- metrics.forEach(m => {
787
- result[m.id] = {
788
- name: m.name,
789
- type: "NUMBER"
790
- };
791
- });
792
- return result;
793
- }, [metrics]);
794
- return /*#__PURE__*/React.createElement(TrendChart, _extends({
795
- dimension: "time",
796
- stacking: "normal",
797
- metrics: _metrics,
798
- metas: metas,
799
- records: records,
800
- isRealtime: xPlotIndex !== undefined,
801
- isDaily: isDaily,
802
- xPlotIndex: xPlotIndex,
803
- xAxisTickInterval: xAxisTickInterval,
804
- yAxisLabelEnabled: yAxisLabelEnabled,
805
- legendLimit: legendLimit,
806
- colors: colors
807
- }, props));
808
- }
809
- const defaultColors = [["rgba(54,115,237,0.8)", "#3673ed"], ["rgba(149,77,241,0.8)", "#954df1"], ["#4dc391", "#20b476"], ["#fbba3d", "#faa90c"], ["#f2426d", "#ef1348"]];
810
-
811
- function ok$1() {}
812
-
813
- function unreachable() {}
814
-
815
- /**
816
- * @typedef Options
817
- * Configuration for `stringify`.
818
- * @property {boolean} [padLeft=true]
819
- * Whether to pad a space before a token.
820
- * @property {boolean} [padRight=false]
821
- * Whether to pad a space after a token.
822
- */
823
-
824
-
825
- /**
826
- * Serialize an array of strings or numbers to comma-separated tokens.
827
- *
828
- * @param {Array<string|number>} values
829
- * List of tokens.
830
- * @param {Options} [options]
831
- * Configuration for `stringify` (optional).
832
- * @returns {string}
833
- * Comma-separated tokens.
834
- */
835
- function stringify$1(values, options) {
836
- const settings = {};
837
-
838
- // Ensure the last empty entry is seen.
839
- const input = values[values.length - 1] === '' ? [...values, ''] : values;
840
-
841
- return input
842
- .join(
843
- (settings.padRight ? ' ' : '') +
844
- ',' +
845
- (settings.padLeft === false ? '' : ' ')
846
- )
847
- .trim()
848
- }
849
-
850
- /**
851
- * @typedef Options
852
- * Configuration.
853
- * @property {boolean | null | undefined} [jsx=false]
854
- * Support JSX identifiers (default: `false`).
855
- */
856
-
857
- const nameRe = /^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u;
858
- const nameReJsx = /^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u;
859
-
860
- /** @type {Options} */
861
- const emptyOptions$2 = {};
862
-
863
- /**
864
- * Checks if the given value is a valid identifier name.
865
- *
866
- * @param {string} name
867
- * Identifier to check.
868
- * @param {Options | null | undefined} [options]
869
- * Configuration (optional).
870
- * @returns {boolean}
871
- * Whether `name` can be an identifier.
872
- */
873
- function name(name, options) {
874
- const settings = emptyOptions$2;
875
- const re = settings.jsx ? nameReJsx : nameRe;
876
- return re.test(name)
877
- }
878
-
879
- /**
880
- * @typedef {import('hast').Nodes} Nodes
881
- */
882
-
883
- // HTML whitespace expression.
884
- // See <https://infra.spec.whatwg.org/#ascii-whitespace>.
885
- const re = /[ \t\n\f\r]/g;
886
-
887
- /**
888
- * Check if the given value is *inter-element whitespace*.
889
- *
890
- * @param {Nodes | string} thing
891
- * Thing to check (`Node` or `string`).
892
- * @returns {boolean}
893
- * Whether the `value` is inter-element whitespace (`boolean`): consisting of
894
- * zero or more of space, tab (`\t`), line feed (`\n`), carriage return
895
- * (`\r`), or form feed (`\f`); if a node is passed it must be a `Text` node,
896
- * whose `value` field is checked.
897
- */
898
- function whitespace(thing) {
899
- return typeof thing === 'object'
900
- ? thing.type === 'text'
901
- ? empty$1(thing.value)
902
- : false
903
- : empty$1(thing)
904
- }
905
-
906
- /**
907
- * @param {string} value
908
- * @returns {boolean}
909
- */
910
- function empty$1(value) {
911
- return value.replace(re, '') === ''
912
- }
913
-
914
- /**
915
- * @import {Schema as SchemaType, Space} from 'property-information'
916
- */
917
-
918
- /** @type {SchemaType} */
919
- class Schema {
920
- /**
921
- * @param {SchemaType['property']} property
922
- * Property.
923
- * @param {SchemaType['normal']} normal
924
- * Normal.
925
- * @param {Space | undefined} [space]
926
- * Space.
927
- * @returns
928
- * Schema.
929
- */
930
- constructor(property, normal, space) {
931
- this.normal = normal;
932
- this.property = property;
933
-
934
- if (space) {
935
- this.space = space;
936
- }
937
- }
938
- }
939
-
940
- Schema.prototype.normal = {};
941
- Schema.prototype.property = {};
942
- Schema.prototype.space = undefined;
943
-
944
- /**
945
- * @import {Info, Space} from 'property-information'
946
- */
947
-
948
-
949
- /**
950
- * @param {ReadonlyArray<Schema>} definitions
951
- * Definitions.
952
- * @param {Space | undefined} [space]
953
- * Space.
954
- * @returns {Schema}
955
- * Schema.
956
- */
957
- function merge(definitions, space) {
958
- /** @type {Record<string, Info>} */
959
- const property = {};
960
- /** @type {Record<string, string>} */
961
- const normal = {};
962
-
963
- for (const definition of definitions) {
964
- Object.assign(property, definition.property);
965
- Object.assign(normal, definition.normal);
966
- }
967
-
968
- return new Schema(property, normal, space)
969
- }
970
-
971
- /**
972
- * Get the cleaned case insensitive form of an attribute or property.
973
- *
974
- * @param {string} value
975
- * An attribute-like or property-like name.
976
- * @returns {string}
977
- * Value that can be used to look up the properly cased property on a
978
- * `Schema`.
979
- */
980
- function normalize$1(value) {
981
- return value.toLowerCase()
982
- }
983
-
984
- /**
985
- * @import {Info as InfoType} from 'property-information'
986
- */
987
-
988
- /** @type {InfoType} */
989
- class Info {
990
- /**
991
- * @param {string} property
992
- * Property.
993
- * @param {string} attribute
994
- * Attribute.
995
- * @returns
996
- * Info.
997
- */
998
- constructor(property, attribute) {
999
- this.attribute = attribute;
1000
- this.property = property;
1001
- }
1002
- }
1003
-
1004
- Info.prototype.attribute = '';
1005
- Info.prototype.booleanish = false;
1006
- Info.prototype.boolean = false;
1007
- Info.prototype.commaOrSpaceSeparated = false;
1008
- Info.prototype.commaSeparated = false;
1009
- Info.prototype.defined = false;
1010
- Info.prototype.mustUseProperty = false;
1011
- Info.prototype.number = false;
1012
- Info.prototype.overloadedBoolean = false;
1013
- Info.prototype.property = '';
1014
- Info.prototype.spaceSeparated = false;
1015
- Info.prototype.space = undefined;
220
+ Info.prototype.attribute = '';
221
+ Info.prototype.booleanish = false;
222
+ Info.prototype.boolean = false;
223
+ Info.prototype.commaOrSpaceSeparated = false;
224
+ Info.prototype.commaSeparated = false;
225
+ Info.prototype.defined = false;
226
+ Info.prototype.mustUseProperty = false;
227
+ Info.prototype.number = false;
228
+ Info.prototype.overloadedBoolean = false;
229
+ Info.prototype.property = '';
230
+ Info.prototype.spaceSeparated = false;
231
+ Info.prototype.space = undefined;
1016
232
 
1017
233
  let powers = 0;
1018
234
 
@@ -1029,14 +245,14 @@ function increment() {
1029
245
  }
1030
246
 
1031
247
  var types = /*#__PURE__*/Object.freeze({
1032
- __proto__: null,
1033
- boolean: boolean,
1034
- booleanish: booleanish,
1035
- commaOrSpaceSeparated: commaOrSpaceSeparated,
1036
- commaSeparated: commaSeparated,
1037
- number: number,
1038
- overloadedBoolean: overloadedBoolean,
1039
- spaceSeparated: spaceSeparated
248
+ __proto__: null,
249
+ boolean: boolean,
250
+ booleanish: booleanish,
251
+ commaOrSpaceSeparated: commaOrSpaceSeparated,
252
+ commaSeparated: commaSeparated,
253
+ number: number,
254
+ overloadedBoolean: overloadedBoolean,
255
+ spaceSeparated: spaceSeparated
1040
256
  });
1041
257
 
1042
258
  /**
@@ -2276,6 +1492,10 @@ function stringify(values) {
2276
1492
  return values.join(' ').trim()
2277
1493
  }
2278
1494
 
1495
+ function getDefaultExportFromCjs (x) {
1496
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
1497
+ }
1498
+
2279
1499
  var cjs$2 = {};
2280
1500
 
2281
1501
  var cjs$1;
@@ -4040,12 +3260,12 @@ function one(value, includeImageAlt, includeHtml) {
4040
3260
  }
4041
3261
 
4042
3262
  if ('children' in value) {
4043
- return all(value.children, includeImageAlt, includeHtml)
3263
+ return all$1(value.children, includeImageAlt, includeHtml)
4044
3264
  }
4045
3265
  }
4046
3266
 
4047
3267
  if (Array.isArray(value)) {
4048
- return all(value, includeImageAlt, includeHtml)
3268
+ return all$1(value, includeImageAlt, includeHtml)
4049
3269
  }
4050
3270
 
4051
3271
  return ''
@@ -4063,7 +3283,7 @@ function one(value, includeImageAlt, includeHtml) {
4063
3283
  * @returns {string}
4064
3284
  * Serialized nodes.
4065
3285
  */
4066
- function all(values, includeImageAlt, includeHtml) {
3286
+ function all$1(values, includeImageAlt, includeHtml) {
4067
3287
  /** @type {Array<string>} */
4068
3288
  const result = [];
4069
3289
  let index = -1;
@@ -14015,16 +13235,16 @@ const disable = {
14015
13235
  };
14016
13236
 
14017
13237
  var defaultConstructs = /*#__PURE__*/Object.freeze({
14018
- __proto__: null,
14019
- attentionMarkers: attentionMarkers,
14020
- contentInitial: contentInitial,
14021
- disable: disable,
14022
- document: document$1,
14023
- flow: flow,
14024
- flowInitial: flowInitial,
14025
- insideSpan: insideSpan,
14026
- string: string,
14027
- text: text$1
13238
+ __proto__: null,
13239
+ attentionMarkers: attentionMarkers,
13240
+ contentInitial: contentInitial,
13241
+ disable: disable,
13242
+ document: document$1,
13243
+ flow: flow,
13244
+ flowInitial: flowInitial,
13245
+ insideSpan: insideSpan,
13246
+ string: string,
13247
+ text: text$1
14028
13248
  });
14029
13249
 
14030
13250
  /**
@@ -21465,7 +20685,7 @@ function ToolContextProvider({
21465
20685
  const kinds = React$1.useMemo(() => message.kinds ?? [], [message]);
21466
20686
  const tools = React$1.useMemo(() => message.content.filter(c => c.type === 'tool'), [message]);
21467
20687
  const configMap = React$1.useMemo(() => makeTaskConfigs(tools), [tools]);
21468
- return /*#__PURE__*/React.createElement(ToolContext.Provider, {
20688
+ return /*#__PURE__*/React$1.createElement(ToolContext.Provider, {
21469
20689
  value: {
21470
20690
  kinds: kinds,
21471
20691
  tools,
@@ -21586,69 +20806,178 @@ const isToday = (from, to) => {
21586
20806
  const date = new Date(now.toLocaleString('en-US', {
21587
20807
  timeZone: 'Asia/Seoul'
21588
20808
  }));
21589
- const today = date.getFullYear() + String(date.getMonth() + 1).padStart(2, '0') + String(date.getDate()).padStart(2, '0');
21590
- return from === today && to === today;
21591
- };
21592
- const isOneDay = (from, to) => {
21593
- return from === to;
21594
- };
21595
- const formatDateRange = (from, to) => {
21596
- const fromDate = dayjs(from, 'YYYYMMDD');
21597
- const toDate = dayjs(to, 'YYYYMMDD');
21598
- const today = dayjs().startOf('day');
21599
- if (from === to) return formatSingleDate(fromDate, today);
21600
- return formatRange(fromDate, toDate, today);
21601
- };
21602
- const formatSingleDate = (date, today) => {
21603
- const diffDays = today.diff(date, 'day');
21604
- if (diffDays === 0) return '오늘';
21605
- if (diffDays === 1) return '어제';
21606
- if (diffDays === 2) return '그제';
21607
- return date.format('YYYY년 M월 D일');
20809
+ const today = date.getFullYear() + String(date.getMonth() + 1).padStart(2, '0') + String(date.getDate()).padStart(2, '0');
20810
+ return from === today && to === today;
20811
+ };
20812
+ const isOneDay = (from, to) => {
20813
+ return from === to;
20814
+ };
20815
+ const formatDateRange = (from, to) => {
20816
+ const fromDate = dayjs(from, 'YYYYMMDD');
20817
+ const toDate = dayjs(to, 'YYYYMMDD');
20818
+ const today = dayjs().startOf('day');
20819
+ if (from === to) return formatSingleDate(fromDate, today);
20820
+ return formatRange(fromDate, toDate, today);
20821
+ };
20822
+ const formatSingleDate = (date, today) => {
20823
+ const diffDays = today.diff(date, 'day');
20824
+ if (diffDays === 0) return '오늘';
20825
+ if (diffDays === 1) return '어제';
20826
+ if (diffDays === 2) return '그제';
20827
+ return date.format('YYYY년 M월 D일');
20828
+ };
20829
+ const formatRange = (fromDate, toDate, today) => {
20830
+ const thisWeekStart = today.startOf('week'); // 일요일
20831
+ const thisWeekEnd = today.endOf('week'); // 토요일
20832
+
20833
+ if (fromDate.isSame(thisWeekStart, 'day') && (toDate.isSame(today, 'day') || toDate.isSame(thisWeekEnd, 'day'))) {
20834
+ return '이번주';
20835
+ }
20836
+ const lastWeekStart = today.subtract(1, 'week').startOf('week');
20837
+ const lastWeekEnd = today.subtract(1, 'week').endOf('week');
20838
+ if (fromDate.isSame(lastWeekStart, 'day') && toDate.isSame(lastWeekEnd, 'day')) {
20839
+ return '지난주';
20840
+ }
20841
+ const twoWeeksAgoStart = today.subtract(2, 'week').startOf('week');
20842
+ const twoWeeksAgoEnd = today.subtract(2, 'week').endOf('week');
20843
+ if (fromDate.isSame(twoWeeksAgoStart, 'day') && toDate.isSame(twoWeeksAgoEnd, 'day')) {
20844
+ return '지지난주';
20845
+ }
20846
+ const thisMonthStart = today.startOf('month');
20847
+ const thisMonthEnd = today.endOf('month');
20848
+ if (fromDate.isSame(thisMonthStart, 'day') && (toDate.isSame(today, 'day') || toDate.isSame(thisMonthEnd, 'day'))) {
20849
+ return '이번달';
20850
+ }
20851
+ const lastMonthStart = today.subtract(1, 'month').startOf('month');
20852
+ const lastMonthEnd = today.subtract(1, 'month').endOf('month');
20853
+ if (fromDate.isSame(lastMonthStart, 'day') && toDate.isSame(lastMonthEnd, 'day')) {
20854
+ return '지난달';
20855
+ }
20856
+ const twoMonthsAgoStart = today.subtract(2, 'month').startOf('month');
20857
+ const twoMonthsAgoEnd = today.subtract(2, 'month').endOf('month');
20858
+ if (fromDate.isSame(twoMonthsAgoStart, 'day') && toDate.isSame(twoMonthsAgoEnd, 'day')) {
20859
+ return '지지난달';
20860
+ }
20861
+ const fromFormatted = formatDateInRange(fromDate, today);
20862
+ const toFormatted = formatDateInRange(toDate, today);
20863
+ return `${fromFormatted} ~ ${toFormatted}`;
20864
+ };
20865
+ const formatDateInRange = (date, today) => {
20866
+ const diffDays = today.diff(date, 'day');
20867
+ if (diffDays === 0) return '오늘';
20868
+ if (diffDays === 1) return '어제';
20869
+ if (diffDays === 2) return '그제';
20870
+ return date.format('YYYY년 M월 D일');
20871
+ };
20872
+
20873
+ const ColumnChart = ({
20874
+ data,
20875
+ width,
20876
+ height = 230
20877
+ }) => {
20878
+ const series = React$1.useMemo(() => {
20879
+ return data.series.map((item, sindex) => ({
20880
+ ...item,
20881
+ data: item.data.map((value, index) => ({
20882
+ y: value,
20883
+ color: data.colors[index % data.colors.length] + alphas[sindex % alphas.length]
20884
+ }))
20885
+ }));
20886
+ }, [data]);
20887
+ const colors = React$1.useMemo(() => {
20888
+ return data.series.map((_, index) => data.colors[0] + alphas[index % alphas.length]);
20889
+ }, [data]);
20890
+ const options = React$1.useMemo(() => {
20891
+ return {
20892
+ chart: {
20893
+ type: 'column',
20894
+ backgroundColor: 'transparent',
20895
+ width: width,
20896
+ height: height,
20897
+ style: {
20898
+ fontFamily: fontFamily$1
20899
+ }
20900
+ },
20901
+ title: {
20902
+ text: undefined
20903
+ },
20904
+ tooltip: {
20905
+ pointFormat: '<span><b>{point.y}</b></span>',
20906
+ style: {
20907
+ fontFamily: fontFamily$1,
20908
+ fontSize: '13px',
20909
+ fontWeight: '100'
20910
+ },
20911
+ useHTML: true
20912
+ },
20913
+ plotOptions: {
20914
+ column: {
20915
+ //size: size
20916
+ }
20917
+ },
20918
+ xAxis: {
20919
+ categories: data.categories,
20920
+ crosshair: true,
20921
+ labels: {
20922
+ style: {
20923
+ color: '#777',
20924
+ fontFamily: fontFamily$1,
20925
+ fontWeight: '400'
20926
+ }
20927
+ },
20928
+ lineColor: '#aaa'
20929
+ },
20930
+ yAxis: {
20931
+ title: {
20932
+ text: undefined
20933
+ },
20934
+ labels: {
20935
+ style: {
20936
+ fontFamily: fontFamily$1,
20937
+ fontSize: '12px',
20938
+ fontWeight: '100'
20939
+ }
20940
+ },
20941
+ gridLineColor: '#f9f9f9'
20942
+ },
20943
+ legend: {
20944
+ layout: 'vertical',
20945
+ itemStyle: {
20946
+ fontFamily: fontFamily$1,
20947
+ fontSize: '12px',
20948
+ fontWeight: '100'
20949
+ },
20950
+ useHTML: true
20951
+ },
20952
+ series: series,
20953
+ colors: colors,
20954
+ credits: {
20955
+ enabled: false
20956
+ },
20957
+ accessibility: {
20958
+ enabled: false
20959
+ }
20960
+ };
20961
+ }, [data, width, height, series, colors]);
20962
+ return /*#__PURE__*/React$1.createElement("div", {
20963
+ style: styles$7.chartWrapper
20964
+ }, /*#__PURE__*/React$1.createElement(HighchartsReact, {
20965
+ highcharts: Highcharts,
20966
+ options: options
20967
+ }));
21608
20968
  };
21609
- const formatRange = (fromDate, toDate, today) => {
21610
- const thisWeekStart = today.startOf('week'); // 일요일
21611
- const thisWeekEnd = today.endOf('week'); // 토요일
21612
-
21613
- if (fromDate.isSame(thisWeekStart, 'day') && (toDate.isSame(today, 'day') || toDate.isSame(thisWeekEnd, 'day'))) {
21614
- return '이번주';
21615
- }
21616
- const lastWeekStart = today.subtract(1, 'week').startOf('week');
21617
- const lastWeekEnd = today.subtract(1, 'week').endOf('week');
21618
- if (fromDate.isSame(lastWeekStart, 'day') && toDate.isSame(lastWeekEnd, 'day')) {
21619
- return '지난주';
21620
- }
21621
- const twoWeeksAgoStart = today.subtract(2, 'week').startOf('week');
21622
- const twoWeeksAgoEnd = today.subtract(2, 'week').endOf('week');
21623
- if (fromDate.isSame(twoWeeksAgoStart, 'day') && toDate.isSame(twoWeeksAgoEnd, 'day')) {
21624
- return '지지난주';
21625
- }
21626
- const thisMonthStart = today.startOf('month');
21627
- const thisMonthEnd = today.endOf('month');
21628
- if (fromDate.isSame(thisMonthStart, 'day') && (toDate.isSame(today, 'day') || toDate.isSame(thisMonthEnd, 'day'))) {
21629
- return '이번달';
21630
- }
21631
- const lastMonthStart = today.subtract(1, 'month').startOf('month');
21632
- const lastMonthEnd = today.subtract(1, 'month').endOf('month');
21633
- if (fromDate.isSame(lastMonthStart, 'day') && toDate.isSame(lastMonthEnd, 'day')) {
21634
- return '지난달';
21635
- }
21636
- const twoMonthsAgoStart = today.subtract(2, 'month').startOf('month');
21637
- const twoMonthsAgoEnd = today.subtract(2, 'month').endOf('month');
21638
- if (fromDate.isSame(twoMonthsAgoStart, 'day') && toDate.isSame(twoMonthsAgoEnd, 'day')) {
21639
- return '지지난달';
20969
+ const fontFamily$1 = 'Pretendard, -apple-system, BlinkMacSystemFont, sans-serif';
20970
+ const styles$7 = {
20971
+ chartWrapper: {
20972
+ background: 'transparent',
20973
+ textAlign: 'center',
20974
+ display: 'flex',
20975
+ flexDirection: 'column',
20976
+ justifyContent: 'center',
20977
+ alignItems: 'center'
21640
20978
  }
21641
- const fromFormatted = formatDateInRange(fromDate, today);
21642
- const toFormatted = formatDateInRange(toDate, today);
21643
- return `${fromFormatted} ~ ${toFormatted}`;
21644
- };
21645
- const formatDateInRange = (date, today) => {
21646
- const diffDays = today.diff(date, 'day');
21647
- if (diffDays === 0) return '오늘';
21648
- if (diffDays === 1) return '어제';
21649
- if (diffDays === 2) return '그제';
21650
- return date.format('YYYY년 M월 D일');
21651
20979
  };
20980
+ const alphas = ['ff', 'bb', '77', '33'];
21652
20981
 
21653
20982
  const ColumnChartContent = ({
21654
20983
  tools = []
@@ -21679,33 +21008,536 @@ function toData$1(tools, configMap) {
21679
21008
  name: `<b>${configMap.get(taskId)}</b> <span style="font-size:10px">(${formatDateRange(from, to)})</span>`,
21680
21009
  data: []
21681
21010
  };
21682
- const result = reduce(content.result.result);
21683
- item.data.push(result.input);
21684
- item.data.push(result.output);
21685
- if (hasConvert) item.data.push(result.filter);
21686
- item.data.push(result.error);
21687
- items.push(item);
21011
+ const result = reduce(content.result.result);
21012
+ item.data.push(result.input);
21013
+ item.data.push(result.output);
21014
+ if (hasConvert) item.data.push(result.filter);
21015
+ item.data.push(result.error);
21016
+ items.push(item);
21017
+ });
21018
+ return {
21019
+ colors: hasConvert ? ['#333333', '#2652a8', '#b47813', '#aa1a32'] : ['#333333', '#2652a8', '#aa1a32'],
21020
+ categories: hasConvert ? ['입력', '처리', '필터', '에러'] : ['입력', '처리', '에러'],
21021
+ series: items
21022
+ };
21023
+ }
21024
+ function reduce(data) {
21025
+ return data.reduce((acc, item) => {
21026
+ acc.input += item.metric.input;
21027
+ acc.output += item.metric.output;
21028
+ acc.filter += item.metric.filter;
21029
+ acc.error += item.metric.error;
21030
+ return acc;
21031
+ }, {
21032
+ input: 0,
21033
+ output: 0,
21034
+ filter: 0,
21035
+ error: 0
21036
+ });
21037
+ }
21038
+
21039
+ function _extends() {
21040
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
21041
+ for (var e = 1; e < arguments.length; e++) {
21042
+ var t = arguments[e];
21043
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
21044
+ }
21045
+ return n;
21046
+ }, _extends.apply(null, arguments);
21047
+ }
21048
+
21049
+ function toValue(value) {
21050
+ return value && typeof value === 'object' ? value.value : value;
21051
+ }
21052
+ function toPercent(value) {
21053
+ return Math.round(value * 100 * 100) / 100;
21054
+ }
21055
+ function formatNumber(value) {
21056
+ return value !== undefined ? value.toLocaleString() : '-';
21057
+ }
21058
+ function formatToPercent(value) {
21059
+ return formatPercent(toPercent(value));
21060
+ }
21061
+ function formatPercent(value) {
21062
+ return value !== undefined ? `${value.toLocaleString()}%` : '-';
21063
+ }
21064
+ function formatDuration(value) {
21065
+ value = toValue(value);
21066
+ if (!value) return '-';
21067
+ let day = Math.floor(value / (60 * 60 * 24));
21068
+ let hour = Math.floor(value / (60 * 60)) - day * 24;
21069
+ let minute = Math.floor(value / 60) - (day * 24 + hour) * 60;
21070
+ let second = Math.round(value % 60);
21071
+ day = day > 0 ? `${day.toLocaleString()}일 ` : '';
21072
+ hour = hour > 0 ? `${hour >= 10 ? hour : '0' + hour}시간 ` : '';
21073
+ minute = `${minute >= 10 ? minute : '0' + minute}분 `;
21074
+ second = `${second >= 10 ? second : '0' + second}초`;
21075
+ return `${day}${hour}${minute}${second}`;
21076
+ }
21077
+ function formatBytes(value) {
21078
+ return value !== undefined ? `${value.toLocaleString()} bytes` : '-';
21079
+ }
21080
+ function format(value, type) {
21081
+ switch (type) {
21082
+ case 'TO_PERCENT':
21083
+ return formatToPercent(value);
21084
+ case 'DURATION':
21085
+ return formatDuration(value);
21086
+ case 'BYTES':
21087
+ return formatBytes(value);
21088
+ case 'PERCENT':
21089
+ return formatPercent(value);
21090
+ default:
21091
+ return formatNumber(value);
21092
+ }
21093
+ }
21094
+
21095
+ const all = [[index_js.blue[500]], [index_js.purple[500], '#4168a6', '#81a7e1'], [index_js.green[500], '#debb7f', '#ecdbbe'], [index_js.yellow[500], '#1b8286', '#4ab3b6'], [index_js.red[500]], [index_js.orange[500]], [index_js.lime[500]], ['#54AAF9'], ['#BB4ECD'], ['#6DDBBA'], ['#FFE81C'], ['#FA7EBA'], ['#F55713'], ['#51B304'], ['#1559B2'], ['#733FAB'], ['#1C7B5F'], ['#D87500'], ['#C91E48'], ['#2F862F']];
21096
+ [[index_js.blue[400], index_js.blue[500]], [index_js.purple[400], index_js.purple[500]], [index_js.green[400], index_js.green[500]], [index_js.yellow[400], index_js.yellow[500]], [index_js.red[400], index_js.red[500]], [index_js.orange[400], index_js.orange[500]], [index_js.lime[400], index_js.lime[500]]];
21097
+ [[material.alpha(index_js.blue[500], 0.2), 'transparent', index_js.blue[300]], [material.alpha(index_js.purple[500], 0.2), 'transparent', index_js.purple[500]], [material.alpha(index_js.green[500], 0.2), 'transparent', index_js.green[500]], [material.alpha(index_js.yellow[500], 0.2), 'transparent', index_js.yellow[500]], [material.alpha(index_js.red[500], 0.2), 'transparent', index_js.red[500]], [material.alpha(index_js.orange[500], 0.2), 'transparent', index_js.orange[500]], [material.alpha(index_js.lime[500], 0.2), 'transparent', index_js.lime[500]]];
21098
+ const preset = ['#003f5c', '#a05195', '#665191', '#2f4b7c', '#d45087', '#f95d6a', '#ff7c43', '#ffa600'];
21099
+ all.map(color => color[0]);
21100
+
21101
+ highchartsAccessibility(Highcharts);
21102
+ highchartsAnnotations(Highcharts);
21103
+ function Chart(props) {
21104
+ const [legendLimitEnabled, setLegendLimitEnabled] = React$1.useState(props.legendLimit > 0);
21105
+ const [options, setOptions] = React$1.useState(toOptions(props, legendLimitEnabled));
21106
+ React$1.useEffect(() => {
21107
+ if (props.delay) setTimeout(() => setOptions(toOptions(props, legendLimitEnabled, handleLegendItemClick)), props.delay);else setOptions(toOptions(props, legendLimitEnabled, handleLegendItemClick));
21108
+ // eslint-disable-next-line
21109
+ }, [props]);
21110
+ const handleLegendItemClick = React$1.useCallback(() => setLegendLimitEnabled(false), []);
21111
+ return /*#__PURE__*/React$1.createElement(React$1.Fragment, null, options && /*#__PURE__*/React$1.createElement(HighchartsReact, {
21112
+ highcharts: Highcharts,
21113
+ options: options
21114
+ }));
21115
+ }
21116
+ function toOptions(props, legendLimitEnabled, handleLegendItemClick) {
21117
+ const {
21118
+ title = '',
21119
+ type,
21120
+ categorize,
21121
+ stacking,
21122
+ showLegend = true,
21123
+ showDataLabel,
21124
+ xAxisType,
21125
+ xAxisLabel = true,
21126
+ xAxisLabelFormat,
21127
+ xAxisTickInterval,
21128
+ yAxisLabelEnabled = true,
21129
+ yAxisLabelFormat,
21130
+ yAxisTickInterval = null,
21131
+ yAxisPlotLines = [],
21132
+ opacity = 1,
21133
+ innerSize = 0,
21134
+ colors: customColors,
21135
+ backgroundColor = undefined,
21136
+ xPlotIndex,
21137
+ dimension,
21138
+ metrics,
21139
+ records = [],
21140
+ metas,
21141
+ height = 200,
21142
+ legendLimit,
21143
+ legendAlign = 'center',
21144
+ tooltip = {},
21145
+ secondaryXAxis = []
21146
+ } = props;
21147
+ const {
21148
+ outside
21149
+ } = tooltip;
21150
+ const pie = type === 'pie';
21151
+ const centers = pieCenters(metrics.length);
21152
+ const size = pieSize(metrics.length);
21153
+ const colors = customColors ? customColors : preset;
21154
+ const categories = records.map(record => record[dimension]);
21155
+ const mainXAxis = records.map(r => r.time);
21156
+ const chartColorHandlers = {
21157
+ line: (colors, index) => ({
21158
+ color: colors[index],
21159
+ mainColor: colors[index]
21160
+ }),
21161
+ area: (colors, index) => ({
21162
+ color: colors[index][0],
21163
+ mainColor: colors[index][1]
21164
+ }),
21165
+ gradient: (colors, index) => ({
21166
+ color: {
21167
+ linearGradient: {
21168
+ x1: 0,
21169
+ y1: 0,
21170
+ x2: 0,
21171
+ y2: 1
21172
+ },
21173
+ stops: [[0, `${colors[index][0]}`], [0.95, `${colors[index][1]}`]]
21174
+ },
21175
+ mainColor: colors[index][2]
21176
+ })
21177
+ };
21178
+ const series = metrics.map(({
21179
+ chartType,
21180
+ metric
21181
+ }, index) => {
21182
+ const type = chartType === 'gradient' ? 'area' : chartType;
21183
+ const {
21184
+ color,
21185
+ mainColor
21186
+ } = chartColorHandlers[chartType](colors, index);
21187
+ const meta = metas[metric];
21188
+ let option = {
21189
+ type: type,
21190
+ name: meta ? meta.name : '',
21191
+ data: records.map(record => {
21192
+ const data = record.metric[metric] ?? null;
21193
+ return pie ? {
21194
+ name: record[dimension],
21195
+ y: data
21196
+ } : data;
21197
+ }),
21198
+ custom: {
21199
+ type: meta ? meta.type : '',
21200
+ pointerNames: meta?.pointerNames ?? null
21201
+ },
21202
+ center: centers[index] || [null, null],
21203
+ size: size,
21204
+ point: {
21205
+ events: {
21206
+ render: function () {
21207
+ this.graphic.attr({
21208
+ zIndex: this.y === 0 ? -1 : ZIndex.COMPARE_CHART_BASE - index
21209
+ });
21210
+ }
21211
+ }
21212
+ },
21213
+ showInLegend: pie && index > 0 ? false : true,
21214
+ color: color,
21215
+ lineColor: mainColor,
21216
+ lineWidth: 2,
21217
+ marker: {
21218
+ fillColor: mainColor
21219
+ },
21220
+ metric: metric
21221
+ };
21222
+ if (legendLimitEnabled) option = {
21223
+ ...option,
21224
+ visible: index < legendLimit
21225
+ };
21226
+ return option;
21227
+ });
21228
+ const yPlotLines = yAxisPlotLines.map((line, index) => {
21229
+ return {
21230
+ value: line.value,
21231
+ width: 1,
21232
+ color: line.color,
21233
+ dashStyle: "Dash",
21234
+ zIndex: ZIndex.AVERAGE_LINE_BASE + index,
21235
+ label: {
21236
+ text: line.label,
21237
+ align: line.labelAlign,
21238
+ style: {
21239
+ color: line.labelColor,
21240
+ opacity: 0.7,
21241
+ fontSize: "12px",
21242
+ padding: '1px 5px'
21243
+ },
21244
+ y: -8,
21245
+ useHTML: true
21246
+ }
21247
+ };
21688
21248
  });
21249
+ const xPlotBands = [{
21250
+ from: xPlotIndex,
21251
+ to: categories.length - 1,
21252
+ color: 'rgba(0, 0, 0, 0.03)',
21253
+ zIndex: ZIndex.NOW_BAND
21254
+ }];
21255
+ const xPlotLines = [{
21256
+ color: "#aaa",
21257
+ width: 1,
21258
+ value: xPlotIndex,
21259
+ zIndex: ZIndex.NOW_BORDER,
21260
+ label: {
21261
+ text: "현재",
21262
+ rotation: 0,
21263
+ x: 5,
21264
+ y: 13,
21265
+ style: {
21266
+ fontWeight: 500,
21267
+ lineHeight: "16.8px",
21268
+ color: "#333",
21269
+ fontSize: "12px"
21270
+ }
21271
+ }
21272
+ }];
21689
21273
  return {
21690
- colors: hasConvert ? ['#333333', '#2652a8', '#b47813', '#aa1a32'] : ['#333333', '#2652a8', '#aa1a32'],
21691
- categories: hasConvert ? ['입력', '처리', '필터', '에러'] : ['입력', '처리', '에러'],
21692
- series: items
21274
+ chart: {
21275
+ type: type.toLowerCase(),
21276
+ height: height,
21277
+ backgroundColor,
21278
+ events: {
21279
+ render: secondaryXAxis.length === 0 ? undefined : function () {
21280
+ const chart = this;
21281
+ const visibleSeries = chart.series.filter(s => s.visible);
21282
+ let newCategories = null;
21283
+ if (visibleSeries.length === 1 && visibleSeries[0].options.metric === 'prev') {
21284
+ newCategories = secondaryXAxis;
21285
+ } else {
21286
+ newCategories = mainXAxis;
21287
+ }
21288
+ const isSame = JSON.stringify(chart.xAxis[0].categories) === JSON.stringify(newCategories);
21289
+ if (!isSame) {
21290
+ chart.xAxis[0].setCategories(newCategories);
21291
+ }
21292
+ }
21293
+ }
21294
+ },
21295
+ title: {
21296
+ text: ''
21297
+ },
21298
+ subtitle: {
21299
+ text: title
21300
+ },
21301
+ colors: colors,
21302
+ xAxis: {
21303
+ type: xAxisType,
21304
+ labels: {
21305
+ enabled: xAxisLabel,
21306
+ autoRotation: false,
21307
+ format: xAxisLabelFormat ? `{value:${xAxisLabelFormat}}` : undefined,
21308
+ style: {
21309
+ color: index_js.grey[600]
21310
+ }
21311
+ },
21312
+ categories: categorize ? categories : undefined,
21313
+ tickWidth: 1,
21314
+ tickInterval: xAxisTickInterval ?? (xAxisType === 'datetime' ? records.length / 20 : 1),
21315
+ lineColor: index_js.grey[900],
21316
+ tickColor: index_js.grey[900],
21317
+ crosshair: true,
21318
+ startOnTick: true,
21319
+ plotBands: xPlotIndex !== undefined ? xPlotBands : undefined,
21320
+ plotLines: xPlotIndex !== undefined ? xPlotLines : undefined
21321
+ },
21322
+ yAxis: {
21323
+ title: {
21324
+ text: ''
21325
+ },
21326
+ labels: {
21327
+ enabled: yAxisLabelEnabled,
21328
+ formatter: yAxisLabelFormat,
21329
+ style: {
21330
+ color: index_js.grey[600]
21331
+ }
21332
+ },
21333
+ tickInterval: yAxisTickInterval,
21334
+ gridLineColor: '#f8f8f8',
21335
+ plotLines: yPlotLines
21336
+ },
21337
+ plotOptions: {
21338
+ series: {
21339
+ opacity: opacity,
21340
+ stacking: stackingType(stacking),
21341
+ showInLegend: showLegend,
21342
+ dataLabels: {
21343
+ enabled: showDataLabel
21344
+ },
21345
+ colorByPoint: pie,
21346
+ lineWidth: 2,
21347
+ marker: {
21348
+ enabled: false,
21349
+ symbol: 'circle'
21350
+ },
21351
+ cursor: 'pointer',
21352
+ point: {
21353
+ events: {}
21354
+ },
21355
+ events: {
21356
+ legendItemClick: handleLegendItemClick
21357
+ }
21358
+ },
21359
+ pie: {
21360
+ allowPointSelect: true,
21361
+ innerSize: `${innerSize}%`
21362
+ }
21363
+ },
21364
+ legend: {
21365
+ align: legendAlign,
21366
+ verticalAlign: 'top',
21367
+ enabled: showLegend
21368
+ },
21369
+ tooltip: {
21370
+ followPointer: false,
21371
+ shared: true,
21372
+ shadow: false,
21373
+ useHTML: true,
21374
+ formatter: function () {
21375
+ return tooltipFormatter(this, tooltip);
21376
+ },
21377
+ outside: outside,
21378
+ style: {
21379
+ zIndex: 2000
21380
+ }
21381
+ },
21382
+ series: series,
21383
+ time: {
21384
+ useUTC: false,
21385
+ getTimezoneOffset: function () {
21386
+ return new Date().getTimezoneOffset();
21387
+ }
21388
+ },
21389
+ credits: {
21390
+ enabled: false
21391
+ }
21693
21392
  };
21694
21393
  }
21695
- function reduce(data) {
21696
- return data.reduce((acc, item) => {
21697
- acc.input += item.metric.input;
21698
- acc.output += item.metric.output;
21699
- acc.filter += item.metric.filter;
21700
- acc.error += item.metric.error;
21701
- return acc;
21702
- }, {
21703
- input: 0,
21704
- output: 0,
21705
- filter: 0,
21706
- error: 0
21707
- });
21394
+ const tooltipFormatter = (_this, props) => {
21395
+ const {
21396
+ headerVisible = true,
21397
+ dateFormat,
21398
+ headerTime,
21399
+ legendColors = []
21400
+ } = props;
21401
+ let tooltip = '<div style="font-size: 14px;padding: 12px; min-width: 200px;">';
21402
+ if (headerVisible) {
21403
+ const xDate = new Date(_this.x);
21404
+ const date = formatDate(xDate, dateFormat);
21405
+ tooltip += `<div style="display: flex; justify-content: space-between; font-weight: bold; font-size: 12px;">
21406
+ <span style="font-size: 12px; color: #333;">${date}</span>`;
21407
+ if (headerTime) {
21408
+ const time = formatDate(xDate, '%H:%M');
21409
+ tooltip += `<span style="font-size: 12px; color: #333;">${time}</span>`;
21410
+ }
21411
+ tooltip += '</div>';
21412
+ }
21413
+ _this.points.forEach(point => {
21414
+ const type = point.series.options.custom.type;
21415
+ const value = type !== 'TO_PERCENT' ? format(point.y, type) : formatToPercent(_this.percentage / 100);
21416
+ const name = point.series.name;
21417
+ let color = type !== 'TO_PERCENT' ? point.series.color : point.color;
21418
+ if (legendColors.length !== 0) {
21419
+ color = legendColors[point.series.index];
21420
+ }
21421
+ tooltip += `<div style="display: flex; flex-direction: column; gap: 8px;">
21422
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-top: 15px;">
21423
+ <span style="width: 10px; height: 10px; border-radius: 2px; margin-right: 8px; background-color: ${color}"></span>
21424
+ <span style="flex-grow: 1; font-size: 14px; padding-right: 20px;">${name}</span>
21425
+ <span style="font-weight: bold; font-size: 14px;">${value}</span>
21426
+ </div>
21427
+ </div>`;
21428
+ });
21429
+ tooltip += '</div>';
21430
+ return tooltip;
21431
+ };
21432
+ function formatDate(data, format) {
21433
+ return Highcharts.dateFormat(format, data.getTime() - data.getTimezoneOffset() * 60000);
21434
+ }
21435
+ const ZIndex = {
21436
+ AVERAGE_LINE_BASE: 10,
21437
+ COMPARE_CHART_BASE: 5,
21438
+ NOW_BORDER: 2,
21439
+ NOW_BAND: 1
21440
+ };
21441
+ function stackingType(stacking) {
21442
+ return stacking ? stacking.toLowerCase() : '';
21443
+ }
21444
+ function pieCenters(count) {
21445
+ switch (count) {
21446
+ case 2:
21447
+ return [['25%', '50%'], ['75%', '50%']];
21448
+ case 3:
21449
+ return [['25%', '25%'], ['75%', '25%'], ['50%', '75%']];
21450
+ case 4:
21451
+ return [['25%', '25%'], ['75%', '25%'], ['25%', '75%'], ['75%', '75%']];
21452
+ default:
21453
+ return [];
21454
+ }
21455
+ }
21456
+ function pieSize(count) {
21457
+ switch (count) {
21458
+ case 3:
21459
+ return '50%';
21460
+ case 4:
21461
+ return '25%';
21462
+ default:
21463
+ return null;
21464
+ }
21465
+ }
21466
+
21467
+ function TrendChart({
21468
+ colorIndex = 0,
21469
+ legendColors,
21470
+ isDaily,
21471
+ isRealtime,
21472
+ ...props
21473
+ }) {
21474
+ const colors = React$1.useMemo(() => {
21475
+ return all[colorIndex % all.length];
21476
+ }, [colorIndex]);
21477
+ const tooltip = React$1.useMemo(() => ({
21478
+ dateFormat: isRealtime ? '%H:%M' : '%Y-%m-%d',
21479
+ headerTime: !isDaily && !isRealtime,
21480
+ outside: props.tooltipOutSide,
21481
+ legendColors
21482
+ }), [isRealtime, isDaily, props.tooltipOutSide, legendColors]);
21483
+ return /*#__PURE__*/React$1.createElement(Chart, _extends({
21484
+ type: "areaspline",
21485
+ categorize: true,
21486
+ xAxisType: "datetime",
21487
+ xAxisLabelFormat: isDaily ? '%m-%d' : '%H:%M',
21488
+ colors: colors,
21489
+ tooltip: tooltip
21490
+ }, props));
21491
+ }
21492
+
21493
+ function StackedAreaTrendChart({
21494
+ metrics,
21495
+ records,
21496
+ isDaily = false,
21497
+ xPlotIndex,
21498
+ xAxisTickInterval,
21499
+ yAxisLabelEnabled = false,
21500
+ legendLimit = 3,
21501
+ colors = defaultColors,
21502
+ ...props
21503
+ }) {
21504
+ const _metrics = React$1.useMemo(() => {
21505
+ return metrics.map(m => ({
21506
+ metric: m.id,
21507
+ chartType: 'area'
21508
+ }));
21509
+ }, [metrics]);
21510
+ const metas = React$1.useMemo(() => {
21511
+ const result = {
21512
+ time: {
21513
+ name: "일시",
21514
+ type: "DATE"
21515
+ }
21516
+ };
21517
+ metrics.forEach(m => {
21518
+ result[m.id] = {
21519
+ name: m.name,
21520
+ type: "NUMBER"
21521
+ };
21522
+ });
21523
+ return result;
21524
+ }, [metrics]);
21525
+ return /*#__PURE__*/React$1.createElement(TrendChart, _extends({
21526
+ dimension: "time",
21527
+ stacking: "normal",
21528
+ metrics: _metrics,
21529
+ metas: metas,
21530
+ records: records,
21531
+ isRealtime: xPlotIndex !== undefined,
21532
+ isDaily: isDaily,
21533
+ xPlotIndex: xPlotIndex,
21534
+ xAxisTickInterval: xAxisTickInterval,
21535
+ yAxisLabelEnabled: yAxisLabelEnabled,
21536
+ legendLimit: legendLimit,
21537
+ colors: colors
21538
+ }, props));
21708
21539
  }
21540
+ const defaultColors = [["rgba(54,115,237,0.8)", "#3673ed"], ["rgba(149,77,241,0.8)", "#954df1"], ["#4dc391", "#20b476"], ["#fbba3d", "#faa90c"], ["#f2426d", "#ef1348"]];
21709
21541
 
21710
21542
  function StackedAreaChartContent({
21711
21543
  tools
@@ -21799,6 +21631,162 @@ function xPlotIndex(tools) {
21799
21631
  }
21800
21632
  }
21801
21633
 
21634
+ const PieChart = ({
21635
+ data,
21636
+ width = 230,
21637
+ height = 180,
21638
+ size = '60%',
21639
+ colors = ['#2652a8', '#b47813', '#aa1a32']
21640
+ }) => {
21641
+ const noData = data.metrics.some(m => m.transparent);
21642
+ const options = React$1.useMemo(() => {
21643
+ const chartData = data.metrics.filter(metric => metric.transparent || metric.value > 0).map((metric, index) => ({
21644
+ name: metric.label,
21645
+ y: metric.value,
21646
+ color: metric.transparent ? checkerboardPattern() : colors[index % colors.length]
21647
+ }));
21648
+ return {
21649
+ chart: {
21650
+ type: 'pie',
21651
+ backgroundColor: 'transparent',
21652
+ width: width,
21653
+ height: height,
21654
+ style: {
21655
+ fontFamily: fontFamily
21656
+ }
21657
+ },
21658
+ title: {
21659
+ text: undefined
21660
+ },
21661
+ tooltip: {
21662
+ pointFormat: '<span><b>{point.y}</b> ({point.percentage:.1f}%)</span>',
21663
+ style: {
21664
+ fontFamily: fontFamily,
21665
+ fontSize: '13px'
21666
+ },
21667
+ useHTML: true
21668
+ },
21669
+ plotOptions: {
21670
+ pie: {
21671
+ size: size,
21672
+ allowPointSelect: true,
21673
+ cursor: 'pointer',
21674
+ dataLabels: {
21675
+ enabled: true,
21676
+ format: '{point.name}<br><b>{point.y}</b> ({point.percentage:.1f}%)',
21677
+ distance: 20,
21678
+ style: {
21679
+ fontSize: '13px',
21680
+ fontWeight: '100',
21681
+ textOutline: 'none',
21682
+ fontFamily: fontFamily
21683
+ },
21684
+ connectorColor: '#666',
21685
+ connectorWidth: 1,
21686
+ overflow: 'allow',
21687
+ crop: false
21688
+ },
21689
+ showInLegend: false
21690
+ }
21691
+ },
21692
+ series: [{
21693
+ type: 'pie',
21694
+ name: '',
21695
+ colorByPoint: true,
21696
+ data: chartData
21697
+ }],
21698
+ credits: {
21699
+ enabled: false
21700
+ },
21701
+ accessibility: {
21702
+ enabled: false
21703
+ }
21704
+ };
21705
+ }, [data, width, height, size, colors]);
21706
+ return /*#__PURE__*/React$1.createElement("div", {
21707
+ style: styles$6.chartWrapper
21708
+ }, /*#__PURE__*/React$1.createElement("div", {
21709
+ style: {
21710
+ ...styles$6.chartContainer,
21711
+ width,
21712
+ height,
21713
+ position: 'relative'
21714
+ }
21715
+ }, noData && /*#__PURE__*/React$1.createElement(CheckerboardBackground, {
21716
+ width: width,
21717
+ height: height
21718
+ }), /*#__PURE__*/React$1.createElement("div", {
21719
+ style: {
21720
+ position: 'relative',
21721
+ zIndex: 1
21722
+ }
21723
+ }, /*#__PURE__*/React$1.createElement(HighchartsReact, {
21724
+ highcharts: Highcharts,
21725
+ options: options
21726
+ }))), /*#__PURE__*/React$1.createElement("div", {
21727
+ style: styles$6.agentName
21728
+ }, data.name));
21729
+ };
21730
+ const fontFamily = 'Pretendard, -apple-system, BlinkMacSystemFont, sans-serif';
21731
+ const styles$6 = {
21732
+ chartWrapper: {
21733
+ background: 'transparent',
21734
+ textAlign: 'center',
21735
+ display: 'flex',
21736
+ flexDirection: 'column',
21737
+ justifyContent: 'center',
21738
+ alignItems: 'center'
21739
+ },
21740
+ chartContainer: {
21741
+ display: 'flex',
21742
+ alignItems: 'center',
21743
+ justifyContent: 'center'
21744
+ },
21745
+ agentName: {
21746
+ fontSize: '12px',
21747
+ fontWeight: '100',
21748
+ marginTop: '-30px',
21749
+ color: '#333'
21750
+ }
21751
+ };
21752
+ const CheckerboardBackground = ({
21753
+ width,
21754
+ height
21755
+ }) => {
21756
+ const circleSize = Math.min(width, height) * 0.47;
21757
+ return /*#__PURE__*/React$1.createElement("div", {
21758
+ style: {
21759
+ position: 'absolute',
21760
+ width: circleSize,
21761
+ height: circleSize,
21762
+ borderRadius: '50%',
21763
+ backgroundImage: `
21764
+ linear-gradient(45deg, #e0e0e0 25%, transparent 25%),
21765
+ linear-gradient(-45deg, #e0e0e0 25%, transparent 25%),
21766
+ linear-gradient(45deg, transparent 75%, #e0e0e0 75%),
21767
+ linear-gradient(-45deg, transparent 75%, #e0e0e0 75%)
21768
+ `,
21769
+ backgroundSize: '10px 10px',
21770
+ backgroundPosition: '0 0, 0 5px, 5px -5px, -5px 0px',
21771
+ backgroundColor: '#ffffff',
21772
+ zIndex: 0
21773
+ }
21774
+ });
21775
+ };
21776
+ const checkerboardPattern = () => ({
21777
+ pattern: {
21778
+ path: {
21779
+ d: 'M 0 0 L 5 5 M 4.5 -0.5 L 5.5 0.5 M -0.5 4.5 L 0.5 5.5',
21780
+ stroke: '#d0d0d0',
21781
+ strokeWidth: 1
21782
+ },
21783
+ width: 5,
21784
+ height: 5,
21785
+ backgroundColor: '#ffffff',
21786
+ opacity: 1
21787
+ }
21788
+ });
21789
+
21802
21790
  const PieChartContent = ({
21803
21791
  tool
21804
21792
  }) => {
@@ -22198,18 +22186,11 @@ const styles$1 = {
22198
22186
  }
22199
22187
  };
22200
22188
 
22201
- let globalConfig = {
22202
- apiUrl: ''
22203
- };
22204
- function getConfig() {
22205
- return globalConfig;
22206
- }
22207
-
22208
22189
  const {
22209
22190
  apiUrl
22210
22191
  } = getConfig();
22211
22192
  const useChatApi = defaultMessages => {
22212
- const [messages, setMessages] = React$1.useState(defaultMessages ?? []);
22193
+ const [messages, setMessages] = React$1.useState(defaultMessages ? defaultMessages : []);
22213
22194
  const [inputValue, setInputValue] = React$1.useState('');
22214
22195
  const [isLoading, setIsLoading] = React$1.useState(false);
22215
22196
  const [conversationId, setConversationId] = React$1.useState(null);
@@ -22302,16 +22283,16 @@ function AiChat({
22302
22283
  chatContainerRef,
22303
22284
  sendMessage
22304
22285
  } = useChatApi(defaultMessages);
22305
- return /*#__PURE__*/React.createElement(material.Stack, {
22286
+ return /*#__PURE__*/React$1.createElement(material.Stack, {
22306
22287
  sx: {
22307
22288
  ...styles.container,
22308
22289
  ...sx
22309
22290
  }
22310
- }, /*#__PURE__*/React.createElement(ChatMessages, {
22291
+ }, /*#__PURE__*/React$1.createElement(ChatMessages, {
22311
22292
  messages: messages,
22312
22293
  isLoading: isLoading,
22313
22294
  chatContainerRef: chatContainerRef
22314
- }), /*#__PURE__*/React.createElement(ChatInput, {
22295
+ }), /*#__PURE__*/React$1.createElement(ChatInput, {
22315
22296
  inputValue: inputValue,
22316
22297
  setInputValue: setInputValue,
22317
22298
  onSend: sendMessage,
@@ -22333,3 +22314,5 @@ exports.AiChat = AiChat;
22333
22314
  exports.ColumnChart = ColumnChart;
22334
22315
  exports.PieChart = PieChart;
22335
22316
  exports.StackedAreaTrendChart = StackedAreaTrendChart;
22317
+ exports.configure = configure$1;
22318
+ exports.getConfig = getConfig;