UNPKG

ng-circle-progress

Version:
1 lines 60.9 kB
{"version":3,"file":"ng-circle-progress.mjs","sources":["../../../projects/ng-circle-progress/src/lib/ng-circle-progress.component.ts","../../../projects/ng-circle-progress/src/lib/ng-circle-progress.module.ts","../../../projects/ng-circle-progress/src/public-api.ts","../../../projects/ng-circle-progress/src/ng-circle-progress.ts"],"sourcesContent":["import { Component, EventEmitter, Input, OnChanges, Output, OnInit, OnDestroy, ElementRef, SimpleChanges, NgZone, Injector } from '@angular/core';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { Subscription, timer } from 'rxjs';\r\n\r\nexport interface CircleProgressOptionsInterface {\r\n class?: string;\r\n backgroundGradient?: boolean;\r\n backgroundColor?: string;\r\n backgroundGradientStopColor?: string;\r\n backgroundOpacity?: number;\r\n backgroundStroke?: string;\r\n backgroundStrokeWidth?: number;\r\n backgroundPadding?: number;\r\n percent?: number;\r\n radius?: number;\r\n space?: number;\r\n toFixed?: number;\r\n maxPercent?: number;\r\n renderOnClick?: boolean;\r\n units?: string;\r\n unitsFontSize?: string;\r\n unitsFontWeight?: string;\r\n unitsColor?: string;\r\n outerStrokeGradient?: boolean;\r\n outerStrokeWidth?: number;\r\n outerStrokeColor?: string;\r\n outerStrokeGradientStopColor?: string;\r\n outerStrokeLinecap?: string;\r\n innerStrokeColor?: string;\r\n innerStrokeWidth?: number;\r\n titleFormat?: Function;\r\n title?: string | Array<String>;\r\n titleColor?: string;\r\n titleFontSize?: string;\r\n titleFontWeight?: string;\r\n subtitleFormat?: Function;\r\n subtitle?: string | Array<String>;\r\n subtitleColor?: string;\r\n subtitleFontSize?: string;\r\n subtitleFontWeight?: string;\r\n imageSrc?: string;\r\n imageHeight?: number;\r\n imageWidth?: number;\r\n animation?: boolean;\r\n animateTitle?: boolean;\r\n animateSubtitle?: boolean;\r\n animationDuration?: number;\r\n showTitle?: boolean;\r\n showSubtitle?: boolean;\r\n showUnits?: boolean;\r\n showImage?: boolean;\r\n showBackground?: boolean;\r\n showInnerStroke?: boolean;\r\n clockwise?: boolean;\r\n responsive?: boolean;\r\n startFromZero?: boolean;\r\n showZeroOuterStroke?: boolean;\r\n lazy?: boolean;\r\n}\r\n\r\nexport class CircleProgressOptions implements CircleProgressOptionsInterface {\r\n class = '';\r\n backgroundGradient = false;\r\n backgroundColor = 'transparent';\r\n backgroundGradientStopColor = 'transparent';\r\n backgroundOpacity = 1;\r\n backgroundStroke = 'transparent';\r\n backgroundStrokeWidth = 0;\r\n backgroundPadding = 5;\r\n percent = 0;\r\n radius = 90;\r\n space = 4;\r\n toFixed = 0;\r\n maxPercent = 1000;\r\n renderOnClick = true;\r\n units = '%';\r\n unitsFontSize = '10';\r\n unitsFontWeight = 'normal';\r\n unitsColor = '#444444';\r\n outerStrokeGradient = false;\r\n outerStrokeWidth = 8;\r\n outerStrokeColor = '#78C000';\r\n outerStrokeGradientStopColor = 'transparent';\r\n outerStrokeLinecap = 'round';\r\n innerStrokeColor = '#C7E596';\r\n innerStrokeWidth = 4;\r\n titleFormat = undefined;\r\n title: string | Array<String> = 'auto';\r\n titleColor = '#444444';\r\n titleFontSize = '20';\r\n titleFontWeight = 'normal';\r\n subtitleFormat = undefined;\r\n subtitle: string | Array<String> = 'progress';\r\n subtitleColor = '#A9A9A9';\r\n subtitleFontSize = '10';\r\n subtitleFontWeight = 'normal';\r\n imageSrc = undefined;\r\n imageHeight = 0;\r\n imageWidth = 0;\r\n animation = true;\r\n animateTitle = true;\r\n animateSubtitle = false;\r\n animationDuration = 500;\r\n showTitle = true;\r\n showSubtitle = true;\r\n showUnits = true;\r\n showImage = false;\r\n showBackground = true;\r\n showInnerStroke = true;\r\n clockwise = true;\r\n responsive = false;\r\n startFromZero = true;\r\n showZeroOuterStroke = true;\r\n lazy = false;\r\n}\r\n\r\n@Component({\r\n selector: 'circle-progress',\r\n template: `\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" *ngIf=\"svg\"\r\n [attr.viewBox]=\"svg.viewBox\" preserveAspectRatio=\"xMidYMid meet\"\r\n [attr.height]=\"svg.height\" [attr.width]=\"svg.width\" (click)=\"emitClickEvent($event)\" [attr.class]=\"options.class\">\r\n <defs>\r\n <linearGradient *ngIf=\"options.outerStrokeGradient\" [attr.id]=\"svg.outerLinearGradient.id\">\r\n <stop offset=\"5%\" [attr.stop-color]=\"svg.outerLinearGradient.colorStop1\" [attr.stop-opacity]=\"1\"/>\r\n <stop offset=\"95%\" [attr.stop-color]=\"svg.outerLinearGradient.colorStop2\" [attr.stop-opacity]=\"1\"/>\r\n </linearGradient>\r\n <radialGradient *ngIf=\"options.backgroundGradient\" [attr.id]=\"svg.radialGradient.id\">\r\n <stop offset=\"5%\" [attr.stop-color]=\"svg.radialGradient.colorStop1\" [attr.stop-opacity]=\"1\"/>\r\n <stop offset=\"95%\" [attr.stop-color]=\"svg.radialGradient.colorStop2\" [attr.stop-opacity]=\"1\"/>\r\n </radialGradient>\r\n </defs>\r\n <ng-container *ngIf=\"options.showBackground\">\r\n <circle *ngIf=\"!options.backgroundGradient\"\r\n [attr.cx]=\"svg.backgroundCircle.cx\"\r\n [attr.cy]=\"svg.backgroundCircle.cy\"\r\n [attr.r]=\"svg.backgroundCircle.r\"\r\n [attr.fill]=\"svg.backgroundCircle.fill\"\r\n [attr.fill-opacity]=\"svg.backgroundCircle.fillOpacity\"\r\n [attr.stroke]=\"svg.backgroundCircle.stroke\"\r\n [attr.stroke-width]=\"svg.backgroundCircle.strokeWidth\"/>\r\n <circle *ngIf=\"options.backgroundGradient\"\r\n [attr.cx]=\"svg.backgroundCircle.cx\"\r\n [attr.cy]=\"svg.backgroundCircle.cy\"\r\n [attr.r]=\"svg.backgroundCircle.r\"\r\n attr.fill=\"url({{window.location.href}}#{{svg.radialGradient.id}})\"\r\n [attr.fill-opacity]=\"svg.backgroundCircle.fillOpacity\"\r\n [attr.stroke]=\"svg.backgroundCircle.stroke\"\r\n [attr.stroke-width]=\"svg.backgroundCircle.strokeWidth\"/>\r\n </ng-container> \r\n <circle *ngIf=\"options.showInnerStroke\"\r\n [attr.cx]=\"svg.circle.cx\"\r\n [attr.cy]=\"svg.circle.cy\"\r\n [attr.r]=\"svg.circle.r\"\r\n [attr.fill]=\"svg.circle.fill\"\r\n [attr.stroke]=\"svg.circle.stroke\"\r\n [attr.stroke-width]=\"svg.circle.strokeWidth\"/>\r\n <ng-container *ngIf=\"+options.percent!==0 || options.showZeroOuterStroke\">\r\n <path *ngIf=\"!options.outerStrokeGradient\"\r\n [attr.d]=\"svg.path.d\"\r\n [attr.stroke]=\"svg.path.stroke\"\r\n [attr.stroke-width]=\"svg.path.strokeWidth\"\r\n [attr.stroke-linecap]=\"svg.path.strokeLinecap\"\r\n [attr.fill]=\"svg.path.fill\"/>\r\n <path *ngIf=\"options.outerStrokeGradient\"\r\n [attr.d]=\"svg.path.d\"\r\n attr.stroke=\"url({{window.location.href}}#{{svg.outerLinearGradient.id}})\"\r\n [attr.stroke-width]=\"svg.path.strokeWidth\"\r\n [attr.stroke-linecap]=\"svg.path.strokeLinecap\"\r\n [attr.fill]=\"svg.path.fill\"/>\r\n </ng-container>\r\n <text *ngIf=\"!options.showImage && (options.showTitle || options.showUnits || options.showSubtitle)\"\r\n alignment-baseline=\"baseline\"\r\n [attr.x]=\"svg.circle.cx\"\r\n [attr.y]=\"svg.circle.cy\"\r\n [attr.text-anchor]=\"svg.title.textAnchor\">\r\n <ng-container *ngIf=\"options.showTitle\">\r\n <tspan *ngFor=\"let tspan of svg.title.tspans\"\r\n [attr.x]=\"svg.title.x\"\r\n [attr.y]=\"svg.title.y\"\r\n [attr.dy]=\"tspan.dy\"\r\n [attr.font-size]=\"svg.title.fontSize\"\r\n [attr.font-weight]=\"svg.title.fontWeight\"\r\n [attr.fill]=\"svg.title.color\">{{tspan.span}}</tspan>\r\n </ng-container>\r\n <tspan *ngIf=\"options.showUnits\"\r\n [attr.font-size]=\"svg.units.fontSize\"\r\n [attr.font-weight]=\"svg.units.fontWeight\"\r\n [attr.fill]=\"svg.units.color\">{{svg.units.text}}</tspan>\r\n <ng-container *ngIf=\"options.showSubtitle\">\r\n <tspan *ngFor=\"let tspan of svg.subtitle.tspans\"\r\n [attr.x]=\"svg.subtitle.x\"\r\n [attr.y]=\"svg.subtitle.y\"\r\n [attr.dy]=\"tspan.dy\"\r\n [attr.font-size]=\"svg.subtitle.fontSize\"\r\n [attr.font-weight]=\"svg.subtitle.fontWeight\"\r\n [attr.fill]=\"svg.subtitle.color\">{{tspan.span}}</tspan>\r\n </ng-container>\r\n </text>\r\n <image *ngIf=\"options.showImage\" preserveAspectRatio=\"none\" \r\n [attr.height]=\"svg.image.height\"\r\n [attr.width]=\"svg.image.width\"\r\n [attr.xlink:href]=\"svg.image.src\"\r\n [attr.x]=\"svg.image.x\"\r\n [attr.y]=\"svg.image.y\"\r\n />\r\n </svg>\r\n `\r\n})\r\nexport class CircleProgressComponent implements OnChanges, OnInit, OnDestroy {\r\n\r\n @Output() onClick = new EventEmitter<MouseEvent>();\r\n\r\n @Input() name: string;\r\n @Input() class: string;\r\n @Input() backgroundGradient: boolean;\r\n @Input() backgroundColor: string;\r\n @Input() backgroundGradientStopColor: String;\r\n @Input() backgroundOpacity: number;\r\n @Input() backgroundStroke: string;\r\n @Input() backgroundStrokeWidth: number;\r\n @Input() backgroundPadding: number;\r\n\r\n @Input() radius: number;\r\n @Input() space: number;\r\n @Input() percent: number;\r\n @Input() toFixed: number;\r\n @Input() maxPercent: number;\r\n @Input() renderOnClick: boolean;\r\n\r\n @Input() units: string;\r\n @Input() unitsFontSize: string;\r\n @Input() unitsFontWeight: string;\r\n @Input() unitsColor: string;\r\n\r\n @Input() outerStrokeGradient: boolean;\r\n @Input() outerStrokeWidth: number;\r\n @Input() outerStrokeColor: string;\r\n @Input() outerStrokeGradientStopColor: String;\r\n @Input() outerStrokeLinecap: string;\r\n\r\n @Input() innerStrokeColor: string;\r\n @Input() innerStrokeWidth: string | number;\r\n\r\n @Input() titleFormat: Function;\r\n @Input() title: string | Array<String>;\r\n @Input() titleColor: string;\r\n @Input() titleFontSize: string;\r\n @Input() titleFontWeight: string;\r\n\r\n @Input() subtitleFormat: Function;\r\n @Input() subtitle: string | string[];\r\n @Input() subtitleColor: string;\r\n @Input() subtitleFontSize: string;\r\n @Input() subtitleFontWeight: string;\r\n\r\n @Input() imageSrc: string;\r\n @Input() imageHeight: number;\r\n @Input() imageWidth: number;\r\n\r\n @Input() animation: boolean;\r\n @Input() animateTitle: boolean;\r\n @Input() animateSubtitle: boolean;\r\n @Input() animationDuration: number;\r\n\r\n @Input() showTitle: boolean;\r\n @Input() showSubtitle: boolean;\r\n @Input() showUnits: boolean;\r\n @Input() showImage: boolean;\r\n @Input() showBackground: boolean;\r\n @Input() showInnerStroke: boolean;\r\n @Input() clockwise: boolean;\r\n @Input() responsive: boolean;\r\n @Input() startFromZero: boolean;\r\n @Input() showZeroOuterStroke: boolean;\r\n\r\n @Input() lazy: boolean;\r\n\r\n @Input('options') templateOptions: CircleProgressOptions;\r\n\r\n // <svg> of component\r\n svgElement: HTMLElement = null;\r\n // whether <svg> is in viewport\r\n isInViewport: Boolean = false;\r\n // event for notifying viewport change caused by scrolling or resizing\r\n onViewportChanged: EventEmitter<{ oldValue: Boolean, newValue: Boolean }> = new EventEmitter();\r\n window: Window;\r\n _viewportChangedSubscriber: Subscription = null;\r\n\r\n svg: any;\r\n\r\n options: CircleProgressOptions = new CircleProgressOptions();\r\n defaultOptions: CircleProgressOptions = new CircleProgressOptions();\r\n _lastPercent: number = 0;\r\n _gradientUUID: string = null;\r\n render = () => {\r\n\r\n this.applyOptions();\r\n\r\n if (this.options.lazy) {\r\n // Draw svg if it doesn't exist\r\n this.svgElement === null && this.draw(this._lastPercent);\r\n // Draw it only when it's in the viewport\r\n if (this.isInViewport) {\r\n // Draw it at the latest position when I am in.\r\n if (this.options.animation && this.options.animationDuration > 0) {\r\n this.animate(this._lastPercent, this.options.percent);\r\n } else {\r\n this.draw(this.options.percent);\r\n }\r\n this._lastPercent = this.options.percent;\r\n }\r\n } else {\r\n if (this.options.animation && this.options.animationDuration > 0) {\r\n this.animate(this._lastPercent, this.options.percent);\r\n } else {\r\n this.draw(this.options.percent);\r\n }\r\n this._lastPercent = this.options.percent;\r\n }\r\n };\r\n polarToCartesian = (centerX: number, centerY: number, radius: number, angleInDegrees: number) => {\r\n let angleInRadius = angleInDegrees * Math.PI / 180;\r\n let x = centerX + Math.sin(angleInRadius) * radius;\r\n let y = centerY - Math.cos(angleInRadius) * radius;\r\n return { x: x, y: y };\r\n };\r\n draw = (percent: number) => {\r\n // make percent reasonable\r\n percent = (percent === undefined) ? this.options.percent : Math.abs(percent);\r\n // circle percent shouldn't be greater than 100%.\r\n let circlePercent = (percent > 100) ? 100 : percent;\r\n // determine box size\r\n let boxSize = this.options.radius * 2 + this.options.outerStrokeWidth * 2;\r\n if (this.options.showBackground) {\r\n boxSize += (this.options.backgroundStrokeWidth * 2 + this.max(0, this.options.backgroundPadding * 2));\r\n }\r\n // the centre of the circle\r\n let centre = { x: boxSize / 2, y: boxSize / 2 };\r\n // the start point of the arc\r\n let startPoint = { x: centre.x, y: centre.y - this.options.radius };\r\n // get the end point of the arc\r\n let endPoint = this.polarToCartesian(centre.x, centre.y, this.options.radius, 360 * (this.options.clockwise ?\r\n circlePercent :\r\n (100 - circlePercent)) / 100); // ####################\r\n // We'll get an end point with the same [x, y] as the start point when percent is 100%, so move x a little bit.\r\n if (circlePercent === 100) {\r\n endPoint.x = endPoint.x + (this.options.clockwise ? -0.01 : +0.01);\r\n }\r\n // largeArcFlag and sweepFlag\r\n let largeArcFlag: any, sweepFlag: any;\r\n if (circlePercent > 50) {\r\n [largeArcFlag, sweepFlag] = this.options.clockwise ? [1, 1] : [1, 0];\r\n } else {\r\n [largeArcFlag, sweepFlag] = this.options.clockwise ? [0, 1] : [0, 0];\r\n }\r\n // percent may not equal the actual percent\r\n let titlePercent = this.options.animateTitle ? percent : this.options.percent;\r\n let titleTextPercent = titlePercent > this.options.maxPercent ?\r\n `${this.options.maxPercent.toFixed(this.options.toFixed)}+` : titlePercent.toFixed(this.options.toFixed);\r\n let subtitlePercent = this.options.animateSubtitle ? percent : this.options.percent;\r\n // get title object\r\n let title = {\r\n x: centre.x,\r\n y: centre.y,\r\n textAnchor: 'middle',\r\n color: this.options.titleColor,\r\n fontSize: this.options.titleFontSize,\r\n fontWeight: this.options.titleFontWeight,\r\n texts: [],\r\n tspans: []\r\n };\r\n // from v0.9.9, both title and titleFormat(...) may be an array of string.\r\n if (this.options.titleFormat !== undefined && this.options.titleFormat.constructor.name === 'Function') {\r\n let formatted = this.options.titleFormat(titlePercent);\r\n if (formatted instanceof Array) {\r\n title.texts = [...formatted];\r\n } else {\r\n title.texts.push(formatted.toString());\r\n }\r\n } else {\r\n if (this.options.title === 'auto') {\r\n title.texts.push(titleTextPercent);\r\n } else {\r\n if (this.options.title instanceof Array) {\r\n title.texts = [...this.options.title]\r\n } else {\r\n title.texts.push(this.options.title.toString());\r\n }\r\n }\r\n }\r\n // get subtitle object\r\n let subtitle = {\r\n x: centre.x,\r\n y: centre.y,\r\n textAnchor: 'middle',\r\n color: this.options.subtitleColor,\r\n fontSize: this.options.subtitleFontSize,\r\n fontWeight: this.options.subtitleFontWeight,\r\n texts: [],\r\n tspans: []\r\n }\r\n // from v0.9.9, both subtitle and subtitleFormat(...) may be an array of string.\r\n if (this.options.subtitleFormat !== undefined && this.options.subtitleFormat.constructor.name === 'Function') {\r\n let formatted = this.options.subtitleFormat(subtitlePercent);\r\n if (formatted instanceof Array) {\r\n subtitle.texts = [...formatted];\r\n } else {\r\n subtitle.texts.push(formatted.toString());\r\n }\r\n } else {\r\n if (this.options.subtitle instanceof Array) {\r\n subtitle.texts = [...this.options.subtitle]\r\n } else {\r\n subtitle.texts.push(this.options.subtitle.toString());\r\n }\r\n }\r\n // get units object\r\n let units = {\r\n text: `${this.options.units}`,\r\n fontSize: this.options.unitsFontSize,\r\n fontWeight: this.options.unitsFontWeight,\r\n color: this.options.unitsColor\r\n };\r\n // get total count of text lines to be shown\r\n let rowCount = 0, rowNum = 1;\r\n this.options.showTitle && (rowCount += title.texts.length);\r\n this.options.showSubtitle && (rowCount += subtitle.texts.length);\r\n // calc dy for each tspan for title\r\n if (this.options.showTitle) {\r\n for (let span of title.texts) {\r\n title.tspans.push({ span: span, dy: this.getRelativeY(rowNum, rowCount) });\r\n rowNum++;\r\n }\r\n }\r\n // calc dy for each tspan for subtitle\r\n if (this.options.showSubtitle) {\r\n for (let span of subtitle.texts) {\r\n subtitle.tspans.push({ span: span, dy: this.getRelativeY(rowNum, rowCount) })\r\n rowNum++;\r\n }\r\n }\r\n // create ID for gradient element\r\n if (null === this._gradientUUID) {\r\n this._gradientUUID = this.uuid();\r\n }\r\n // Bring it all together\r\n this.svg = {\r\n viewBox: `0 0 ${boxSize} ${boxSize}`,\r\n // Set both width and height to '100%' if it's responsive\r\n width: this.options.responsive ? '100%' : boxSize,\r\n height: this.options.responsive ? '100%' : boxSize,\r\n backgroundCircle: {\r\n cx: centre.x,\r\n cy: centre.y,\r\n r: this.options.radius + this.options.outerStrokeWidth / 2 + this.options.backgroundPadding,\r\n fill: this.options.backgroundColor,\r\n fillOpacity: this.options.backgroundOpacity,\r\n stroke: this.options.backgroundStroke,\r\n strokeWidth: this.options.backgroundStrokeWidth,\r\n },\r\n path: {\r\n // A rx ry x-axis-rotation large-arc-flag sweep-flag x y (https://developer.mozilla.org/en/docs/Web/SVG/Tutorial/Paths#Arcs)\r\n d: `M ${startPoint.x} ${startPoint.y}\r\n A ${this.options.radius} ${this.options.radius} 0 ${largeArcFlag} ${sweepFlag} ${endPoint.x} ${endPoint.y}`,\r\n stroke: this.options.outerStrokeColor,\r\n strokeWidth: this.options.outerStrokeWidth,\r\n strokeLinecap: this.options.outerStrokeLinecap,\r\n fill: 'none'\r\n },\r\n circle: {\r\n cx: centre.x,\r\n cy: centre.y,\r\n r: this.options.radius - this.options.space - this.options.outerStrokeWidth / 2 - this.options.innerStrokeWidth / 2,\r\n fill: 'none',\r\n stroke: this.options.innerStrokeColor,\r\n strokeWidth: this.options.innerStrokeWidth,\r\n },\r\n title: title,\r\n units: units,\r\n subtitle: subtitle,\r\n image: {\r\n x: centre.x - this.options.imageWidth / 2,\r\n y: centre.y - this.options.imageHeight / 2,\r\n src: this.options.imageSrc,\r\n width: this.options.imageWidth,\r\n height: this.options.imageHeight,\r\n },\r\n outerLinearGradient: {\r\n id: 'outer-linear-' + this._gradientUUID,\r\n colorStop1: this.options.outerStrokeColor,\r\n colorStop2: this.options.outerStrokeGradientStopColor === 'transparent' ? '#FFF' : this.options.outerStrokeGradientStopColor,\r\n },\r\n radialGradient: {\r\n id: 'radial-' + this._gradientUUID,\r\n colorStop1: this.options.backgroundColor,\r\n colorStop2: this.options.backgroundGradientStopColor === 'transparent' ? '#FFF' : this.options.backgroundGradientStopColor,\r\n }\r\n };\r\n };\r\n getAnimationParameters = (previousPercent: number, currentPercent: number) => {\r\n const MIN_INTERVAL = 10;\r\n let times: number, step: number, interval: number;\r\n let fromPercent = this.options.startFromZero ? 0 : (previousPercent < 0 ? 0 : previousPercent);\r\n let toPercent = currentPercent < 0 ? 0 : this.min(currentPercent, this.options.maxPercent);\r\n let delta = Math.abs(Math.round(toPercent - fromPercent));\r\n\r\n if (delta >= 100) {\r\n // we will finish animation in 100 times\r\n times = 100;\r\n if (!this.options.animateTitle && !this.options.animateSubtitle) {\r\n step = 1;\r\n } else {\r\n // show title or subtitle animation even if the arc is full, we also need to finish it in 100 times.\r\n step = Math.round(delta / times);\r\n }\r\n } else {\r\n // we will finish in as many times as the number of percent.\r\n times = delta;\r\n step = 1;\r\n }\r\n // Get the interval of timer\r\n interval = Math.round(this.options.animationDuration / times);\r\n // Readjust all values if the interval of timer is extremely small.\r\n if (interval < MIN_INTERVAL) {\r\n interval = MIN_INTERVAL;\r\n times = this.options.animationDuration / interval;\r\n if (!this.options.animateTitle && !this.options.animateSubtitle && delta > 100) {\r\n step = Math.round(100 / times);\r\n } else {\r\n step = Math.round(delta / times);\r\n }\r\n }\r\n // step must be greater than 0.\r\n if (step < 1) {\r\n step = 1;\r\n }\r\n return { times: times, step: step, interval: interval };\r\n };\r\n animate = (previousPercent: number, currentPercent: number) => {\r\n if (this._timerSubscription && !this._timerSubscription.closed) {\r\n this._timerSubscription.unsubscribe();\r\n }\r\n let fromPercent = this.options.startFromZero ? 0 : previousPercent;\r\n let toPercent = currentPercent;\r\n let { step: step, interval: interval } = this.getAnimationParameters(fromPercent, toPercent);\r\n let count = fromPercent;\r\n if (fromPercent < toPercent) {\r\n this._timerSubscription = timer(0, interval).subscribe(() => {\r\n count += step;\r\n if (count <= toPercent) {\r\n if (!this.options.animateTitle && !this.options.animateSubtitle && count >= 100) {\r\n this.draw(toPercent);\r\n this._timerSubscription.unsubscribe();\r\n } else {\r\n this.draw(count);\r\n }\r\n } else {\r\n this.draw(toPercent);\r\n this._timerSubscription.unsubscribe();\r\n }\r\n });\r\n } else {\r\n this._timerSubscription = timer(0, interval).subscribe(() => {\r\n count -= step;\r\n if (count >= toPercent) {\r\n if (!this.options.animateTitle && !this.options.animateSubtitle && toPercent >= 100) {\r\n this.draw(toPercent);\r\n this._timerSubscription.unsubscribe();\r\n } else {\r\n this.draw(count);\r\n }\r\n } else {\r\n this.draw(toPercent);\r\n this._timerSubscription.unsubscribe();\r\n }\r\n });\r\n }\r\n };\r\n emitClickEvent(event: MouseEvent): void {\r\n if (this.options.renderOnClick) {\r\n this.animate(0, this.options.percent);\r\n }\r\n if (this.onClick.observers.length > 0) {\r\n this.onClick.emit(event);\r\n }\r\n }\r\n private _timerSubscription: Subscription;\r\n private applyOptions = () => {\r\n // the options of <circle-progress> may change already\r\n for (let name of Object.keys(this.options)) {\r\n if (this.hasOwnProperty(name) && this[name] !== undefined) {\r\n this.options[name] = this[name];\r\n } else if (this.templateOptions && this.templateOptions[name] !== undefined) {\r\n this.options[name] = this.templateOptions[name];\r\n }\r\n }\r\n // make sure key options valid\r\n this.options.radius = Math.abs(+this.options.radius);\r\n this.options.space = +this.options.space;\r\n this.options.percent = +this.options.percent > 0 ? +this.options.percent : 0;\r\n this.options.maxPercent = Math.abs(+this.options.maxPercent);\r\n this.options.animationDuration = Math.abs(this.options.animationDuration);\r\n this.options.outerStrokeWidth = Math.abs(+this.options.outerStrokeWidth);\r\n this.options.innerStrokeWidth = Math.abs(+this.options.innerStrokeWidth);\r\n this.options.backgroundPadding = +this.options.backgroundPadding;\r\n };\r\n private getRelativeY = (rowNum: number, rowCount: number): string => {\r\n // why '-0.18em'? It's a magic number when property 'alignment-baseline' equals 'baseline'. :)\r\n let initialOffset = -0.18, offset = 1;\r\n return (initialOffset + offset * (rowNum - rowCount / 2)).toFixed(2) + 'em';\r\n };\r\n\r\n private min = (a: number, b: number) => {\r\n return a < b ? a : b;\r\n };\r\n\r\n private max = (a: number, b: number) => {\r\n return a > b ? a : b;\r\n };\r\n\r\n private uuid = () => {\r\n // https://www.w3resource.com/javascript-exercises/javascript-math-exercise-23.php\r\n var dt = new Date().getTime();\r\n var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n var r = (dt + Math.random() * 16) % 16 | 0;\r\n dt = Math.floor(dt / 16);\r\n return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);\r\n });\r\n return uuid;\r\n }\r\n\r\n public isDrawing(): boolean {\r\n return (this._timerSubscription && !this._timerSubscription.closed);\r\n }\r\n\r\n public findSvgElement(): void {\r\n if (this.svgElement === null) {\r\n let tags = this.elRef.nativeElement.getElementsByTagName('svg');\r\n if (tags.length > 0) {\r\n this.svgElement = tags[0];\r\n }\r\n }\r\n }\r\n\r\n private isElementInViewport(el): Boolean {\r\n // Return false if el has not been created in page.\r\n if (el === null || el === undefined) return false;\r\n // Check if the element is out of view due to a container scrolling\r\n let rect = el.getBoundingClientRect(), parent = el.parentNode, parentRect;\r\n do {\r\n parentRect = parent.getBoundingClientRect();\r\n if (rect.top >= parentRect.bottom) return false;\r\n if (rect.bottom <= parentRect.top) return false;\r\n if (rect.left >= parentRect.right) return false;\r\n if (rect.right <= parentRect.left) return false;\r\n parent = parent.parentNode;\r\n } while (parent != this.document.body);\r\n // Check its within the document viewport\r\n if (rect.top >= (this.window.innerHeight || this.document.documentElement.clientHeight)) return false;\r\n if (rect.bottom <= 0) return false;\r\n if (rect.left >= (this.window.innerWidth || this.document.documentElement.clientWidth)) return false;\r\n if (rect.right <= 0) return false;\r\n return true;\r\n }\r\n\r\n checkViewport = () => {\r\n this.findSvgElement();\r\n let previousValue = this.isInViewport;\r\n this.isInViewport = this.isElementInViewport(this.svgElement);\r\n if (previousValue !== this.isInViewport && this.onViewportChanged.observers.length > 0) {\r\n this.ngZone.run(() => {\r\n this.onViewportChanged.emit({ oldValue: previousValue, newValue: this.isInViewport });\r\n });\r\n }\r\n }\r\n\r\n onScroll = (event: Event) => {\r\n this.checkViewport();\r\n }\r\n\r\n loadEventsForLazyMode = () => {\r\n if (this.options.lazy) {\r\n this.ngZone.runOutsideAngular(() => {\r\n this.document.addEventListener('scroll', this.onScroll, true);\r\n this.window.addEventListener('resize', this.onScroll, true);\r\n });\r\n if (this._viewportChangedSubscriber === null) {\r\n this._viewportChangedSubscriber = this.onViewportChanged.subscribe(({ oldValue, newValue }) => {\r\n newValue ? this.render() : null;\r\n });\r\n }\r\n // svgElement must be created in DOM before being checked.\r\n // Is there a better way to check the existence of svgElemnt?\r\n let _timer = timer(0, 50).subscribe(() => {\r\n this.svgElement === null ? this.checkViewport() : _timer.unsubscribe();\r\n })\r\n }\r\n }\r\n\r\n unloadEventsForLazyMode = () => {\r\n // Remove event listeners\r\n this.document.removeEventListener('scroll', this.onScroll, true);\r\n this.window.removeEventListener('resize', this.onScroll, true);\r\n // Unsubscribe onViewportChanged\r\n if (this._viewportChangedSubscriber !== null) {\r\n this._viewportChangedSubscriber.unsubscribe();\r\n this._viewportChangedSubscriber = null;\r\n }\r\n }\r\n\r\n ngOnInit() {\r\n this.loadEventsForLazyMode();\r\n }\r\n\r\n ngOnDestroy() {\r\n this.unloadEventsForLazyMode();\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges) {\r\n\r\n this.render();\r\n\r\n if ('lazy' in changes) {\r\n changes.lazy.currentValue ? this.loadEventsForLazyMode() : this.unloadEventsForLazyMode();\r\n }\r\n\r\n }\r\n\r\n private document: Document;\r\n\r\n constructor(\r\n defaultOptions: CircleProgressOptions,\r\n private ngZone: NgZone,\r\n private elRef: ElementRef,\r\n injector: Injector,\r\n ) {\r\n this.document = injector.get(DOCUMENT);\r\n this.window = this.document.defaultView;\r\n Object.assign(this.options, defaultOptions);\r\n Object.assign(this.defaultOptions, defaultOptions);\r\n }\r\n\r\n}\r\n","import { NgModule, ModuleWithProviders } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { CircleProgressComponent, CircleProgressOptionsInterface, CircleProgressOptions } from './ng-circle-progress.component';\n\n\n@NgModule({\n declarations: [CircleProgressComponent],\n imports: [\n CommonModule\n ],\n exports: [CircleProgressComponent]\n})\nexport class NgCircleProgressModule {\n static forRoot(options: CircleProgressOptionsInterface = {}): ModuleWithProviders<NgCircleProgressModule> {\n return {\n ngModule: NgCircleProgressModule,\n providers: [\n { provide: CircleProgressOptions, useValue: options }\n ]\n };\n }\n}\n","/*\n * Public API Surface of ng-circle-progress\n */\n\nexport * from './lib/ng-circle-progress.component';\nexport * from './lib/ng-circle-progress.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;MA4Da,qBAAqB,CAAA;AAAlC,IAAA,WAAA,GAAA;AACI,QAAA,IAAK,CAAA,KAAA,GAAG,EAAE,CAAC;AACX,QAAA,IAAkB,CAAA,kBAAA,GAAG,KAAK,CAAC;AAC3B,QAAA,IAAe,CAAA,eAAA,GAAG,aAAa,CAAC;AAChC,QAAA,IAA2B,CAAA,2BAAA,GAAG,aAAa,CAAC;AAC5C,QAAA,IAAiB,CAAA,iBAAA,GAAG,CAAC,CAAC;AACtB,QAAA,IAAgB,CAAA,gBAAA,GAAG,aAAa,CAAC;AACjC,QAAA,IAAqB,CAAA,qBAAA,GAAG,CAAC,CAAC;AAC1B,QAAA,IAAiB,CAAA,iBAAA,GAAG,CAAC,CAAC;AACtB,QAAA,IAAO,CAAA,OAAA,GAAG,CAAC,CAAC;AACZ,QAAA,IAAM,CAAA,MAAA,GAAG,EAAE,CAAC;AACZ,QAAA,IAAK,CAAA,KAAA,GAAG,CAAC,CAAC;AACV,QAAA,IAAO,CAAA,OAAA,GAAG,CAAC,CAAC;AACZ,QAAA,IAAU,CAAA,UAAA,GAAG,IAAI,CAAC;AAClB,QAAA,IAAa,CAAA,aAAA,GAAG,IAAI,CAAC;AACrB,QAAA,IAAK,CAAA,KAAA,GAAG,GAAG,CAAC;AACZ,QAAA,IAAa,CAAA,aAAA,GAAG,IAAI,CAAC;AACrB,QAAA,IAAe,CAAA,eAAA,GAAG,QAAQ,CAAC;AAC3B,QAAA,IAAU,CAAA,UAAA,GAAG,SAAS,CAAC;AACvB,QAAA,IAAmB,CAAA,mBAAA,GAAG,KAAK,CAAC;AAC5B,QAAA,IAAgB,CAAA,gBAAA,GAAG,CAAC,CAAC;AACrB,QAAA,IAAgB,CAAA,gBAAA,GAAG,SAAS,CAAC;AAC7B,QAAA,IAA4B,CAAA,4BAAA,GAAG,aAAa,CAAC;AAC7C,QAAA,IAAkB,CAAA,kBAAA,GAAG,OAAO,CAAC;AAC7B,QAAA,IAAgB,CAAA,gBAAA,GAAG,SAAS,CAAC;AAC7B,QAAA,IAAgB,CAAA,gBAAA,GAAG,CAAC,CAAC;AACrB,QAAA,IAAW,CAAA,WAAA,GAAG,SAAS,CAAC;AACxB,QAAA,IAAK,CAAA,KAAA,GAA2B,MAAM,CAAC;AACvC,QAAA,IAAU,CAAA,UAAA,GAAG,SAAS,CAAC;AACvB,QAAA,IAAa,CAAA,aAAA,GAAG,IAAI,CAAC;AACrB,QAAA,IAAe,CAAA,eAAA,GAAG,QAAQ,CAAC;AAC3B,QAAA,IAAc,CAAA,cAAA,GAAG,SAAS,CAAC;AAC3B,QAAA,IAAQ,CAAA,QAAA,GAA2B,UAAU,CAAC;AAC9C,QAAA,IAAa,CAAA,aAAA,GAAG,SAAS,CAAC;AAC1B,QAAA,IAAgB,CAAA,gBAAA,GAAG,IAAI,CAAC;AACxB,QAAA,IAAkB,CAAA,kBAAA,GAAG,QAAQ,CAAC;AAC9B,QAAA,IAAQ,CAAA,QAAA,GAAG,SAAS,CAAC;AACrB,QAAA,IAAW,CAAA,WAAA,GAAG,CAAC,CAAC;AAChB,QAAA,IAAU,CAAA,UAAA,GAAG,CAAC,CAAC;AACf,QAAA,IAAS,CAAA,SAAA,GAAG,IAAI,CAAC;AACjB,QAAA,IAAY,CAAA,YAAA,GAAG,IAAI,CAAC;AACpB,QAAA,IAAe,CAAA,eAAA,GAAG,KAAK,CAAC;AACxB,QAAA,IAAiB,CAAA,iBAAA,GAAG,GAAG,CAAC;AACxB,QAAA,IAAS,CAAA,SAAA,GAAG,IAAI,CAAC;AACjB,QAAA,IAAY,CAAA,YAAA,GAAG,IAAI,CAAC;AACpB,QAAA,IAAS,CAAA,SAAA,GAAG,IAAI,CAAC;AACjB,QAAA,IAAS,CAAA,SAAA,GAAG,KAAK,CAAC;AAClB,QAAA,IAAc,CAAA,cAAA,GAAG,IAAI,CAAC;AACtB,QAAA,IAAe,CAAA,eAAA,GAAG,IAAI,CAAC;AACvB,QAAA,IAAS,CAAA,SAAA,GAAG,IAAI,CAAC;AACjB,QAAA,IAAU,CAAA,UAAA,GAAG,KAAK,CAAC;AACnB,QAAA,IAAa,CAAA,aAAA,GAAG,IAAI,CAAC;AACrB,QAAA,IAAmB,CAAA,mBAAA,GAAG,IAAI,CAAC;AAC3B,QAAA,IAAI,CAAA,IAAA,GAAG,KAAK,CAAC;KAChB;AAAA,CAAA;MA+FY,uBAAuB,CAAA;AA0gBhC,IAAA,WAAA,CACE,cAAqC,EAC7B,MAAc,EACd,KAAiB,EACzB,QAAkB,EAAA;AAFV,QAAA,IAAM,CAAA,MAAA,GAAN,MAAM,CAAQ;AACd,QAAA,IAAK,CAAA,KAAA,GAAL,KAAK,CAAY;AA3gBjB,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,YAAY,EAAc,CAAC;;AAsEnD,QAAA,IAAU,CAAA,UAAA,GAAgB,IAAI,CAAC;;AAE/B,QAAA,IAAY,CAAA,YAAA,GAAY,KAAK,CAAC;;AAE9B,QAAA,IAAA,CAAA,iBAAiB,GAA2D,IAAI,YAAY,EAAE,CAAC;AAE/F,QAAA,IAA0B,CAAA,0BAAA,GAAiB,IAAI,CAAC;AAIhD,QAAA,IAAA,CAAA,OAAO,GAA0B,IAAI,qBAAqB,EAAE,CAAC;AAC7D,QAAA,IAAA,CAAA,cAAc,GAA0B,IAAI,qBAAqB,EAAE,CAAC;AACpE,QAAA,IAAY,CAAA,YAAA,GAAW,CAAC,CAAC;AACzB,QAAA,IAAa,CAAA,aAAA,GAAW,IAAI,CAAC;AAC7B,QAAA,IAAM,CAAA,MAAA,GAAG,MAAK;YAEV,IAAI,CAAC,YAAY,EAAE,CAAC;AAEpB,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;;AAEnB,gBAAA,IAAI,CAAC,UAAU,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;;gBAEzD,IAAI,IAAI,CAAC,YAAY,EAAE;;AAEnB,oBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,CAAC,EAAE;AAC9D,wBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACzD,qBAAA;AAAM,yBAAA;wBACH,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACnC,qBAAA;oBACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AAC5C,iBAAA;AACJ,aAAA;AAAM,iBAAA;AACH,gBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,CAAC,EAAE;AAC9D,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACzD,iBAAA;AAAM,qBAAA;oBACH,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACnC,iBAAA;gBACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AAC5C,aAAA;AACL,SAAC,CAAC;AACF,QAAA,IAAgB,CAAA,gBAAA,GAAG,CAAC,OAAe,EAAE,OAAe,EAAE,MAAc,EAAE,cAAsB,KAAI;YAC5F,IAAI,aAAa,GAAG,cAAc,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC;AACnD,YAAA,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC;AACnD,YAAA,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC;YACnD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1B,SAAC,CAAC;AACF,QAAA,IAAA,CAAA,IAAI,GAAG,CAAC,OAAe,KAAI;;YAEvB,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;;AAE7E,YAAA,IAAI,aAAa,GAAG,CAAC,OAAO,GAAG,GAAG,IAAI,GAAG,GAAG,OAAO,CAAC;;AAEpD,YAAA,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,CAAC,CAAC;AAC1E,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE;gBAC7B,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,qBAAqB,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC;AACzG,aAAA;;AAED,YAAA,IAAI,MAAM,GAAG,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,CAAC;;YAEhD,IAAI,UAAU,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;;AAEpE,YAAA,IAAI,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS;AACvG,gBAAA,aAAa;iBACZ,GAAG,GAAG,aAAa,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;;YAElC,IAAI,aAAa,KAAK,GAAG,EAAE;gBACvB,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;AACtE,aAAA;;YAED,IAAI,YAAiB,EAAE,SAAc,CAAC;YACtC,IAAI,aAAa,GAAG,EAAE,EAAE;gBACpB,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxE,aAAA;AAAM,iBAAA;gBACH,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxE,aAAA;;AAED,YAAA,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YAC9E,IAAI,gBAAgB,GAAG,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU;AACzD,gBAAA,CAAA,EAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAG,CAAA,CAAA,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAC7G,YAAA,IAAI,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,GAAG,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;;AAEpF,YAAA,IAAI,KAAK,GAAG;gBACR,CAAC,EAAE,MAAM,CAAC,CAAC;gBACX,CAAC,EAAE,MAAM,CAAC,CAAC;AACX,gBAAA,UAAU,EAAE,QAAQ;AACpB,gBAAA,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;AAC9B,gBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;AACpC,gBAAA,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe;AACxC,gBAAA,KAAK,EAAE,EAAE;AACT,gBAAA,MAAM,EAAE,EAAE;aACb,CAAC;;AAEF,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,KAAK,UAAU,EAAE;gBACpG,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;gBACvD,IAAI,SAAS,YAAY,KAAK,EAAE;AAC5B,oBAAA,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;AAChC,iBAAA;AAAM,qBAAA;oBACH,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC1C,iBAAA;AACJ,aAAA;AAAM,iBAAA;AACH,gBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,MAAM,EAAE;AAC/B,oBAAA,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AACtC,iBAAA;AAAM,qBAAA;AACH,oBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,YAAY,KAAK,EAAE;wBACrC,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AACxC,qBAAA;AAAM,yBAAA;AACH,wBAAA,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AACnD,qBAAA;AACJ,iBAAA;AACJ,aAAA;;AAED,YAAA,IAAI,QAAQ,GAAG;gBACX,CAAC,EAAE,MAAM,CAAC,CAAC;gBACX,CAAC,EAAE,MAAM,CAAC,CAAC;AACX,gBAAA,UAAU,EAAE,QAAQ;AACpB,gBAAA,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;AACjC,gBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;AACvC,gBAAA,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB;AAC3C,gBAAA,KAAK,EAAE,EAAE;AACT,gBAAA,MAAM,EAAE,EAAE;aACb,CAAA;;AAED,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,KAAK,UAAU,EAAE;gBAC1G,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;gBAC7D,IAAI,SAAS,YAAY,KAAK,EAAE;AAC5B,oBAAA,QAAQ,CAAC,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;AACnC,iBAAA;AAAM,qBAAA;oBACH,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC7C,iBAAA;AACJ,aAAA;AAAM,iBAAA;AACH,gBAAA,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,YAAY,KAAK,EAAE;oBACxC,QAAQ,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAC9C,iBAAA;AAAM,qBAAA;AACH,oBAAA,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;AACzD,iBAAA;AACJ,aAAA;;AAED,YAAA,IAAI,KAAK,GAAG;AACR,gBAAA,IAAI,EAAE,CAAG,EAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAE,CAAA;AAC7B,gBAAA,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;AACpC,gBAAA,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe;AACxC,gBAAA,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;aACjC,CAAC;;AAEF,YAAA,IAAI,QAAQ,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;AAC7B,YAAA,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC3D,YAAA,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;;AAEjE,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;AACxB,gBAAA,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE;oBAC1B,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3E,oBAAA,MAAM,EAAE,CAAC;AACZ,iBAAA;AACJ,aAAA;;AAED,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE;AAC3B,gBAAA,KAAK,IAAI,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE;oBAC7B,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAA;AAC7E,oBAAA,MAAM,EAAE,CAAC;AACZ,iBAAA;AACJ,aAAA;;AAED,YAAA,IAAI,IAAI,KAAK,IAAI,CAAC,aAAa,EAAE;AAC7B,gBAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;AACpC,aAAA;;YAED,IAAI,CAAC,GAAG,GAAG;AACP,gBAAA,OAAO,EAAE,CAAA,IAAA,EAAO,OAAO,CAAA,CAAA,EAAI,OAAO,CAAE,CAAA;;AAEpC,gBAAA,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,MAAM,GAAG,OAAO;AACjD,gBAAA,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,MAAM,GAAG,OAAO;AAClD,gBAAA,gBAAgB,EAAE;oBACd,EAAE,EAAE,MAAM,CAAC,CAAC;oBACZ,EAAE,EAAE,MAAM,CAAC,CAAC;AACZ,oBAAA,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB;AAC3F,oBAAA,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe;AAClC,oBAAA,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB;AAC3C,oBAAA,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;AACrC,oBAAA,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB;AAClD,iBAAA;AACD,gBAAA,IAAI,EAAE;;oBAEF,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,CAAI,CAAA,EAAA,UAAU,CAAC,CAAC,CAAA;YACxC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA,GAAA,EAAM,YAAY,CAAI,CAAA,EAAA,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAI,CAAA,EAAA,QAAQ,CAAC,CAAC,CAAE,CAAA;AACnG,oBAAA,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;AACrC,oBAAA,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;AAC1C,oBAAA,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB;AAC9C,oBAAA,IAAI,EAAE,MAAM;AACf,iBAAA;AACD,gBAAA,MAAM,EAAE;oBACJ,EAAE,EAAE,MAAM,CAAC,CAAC;oBACZ,EAAE,EAAE,MAAM,CAAC,CAAC;oBACZ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,CAAC;AACnH,oBAAA,IAAI,EAAE,MAAM;AACZ,oBAAA,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;AACrC,oBAAA,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;AAC7C,iBAAA;AACD,gBAAA,KAAK,EAAE,KAAK;AACZ,gBAAA,KAAK,EAAE,KAAK;AACZ,gBAAA,QAAQ,EAAE,QAAQ;AAClB,gBAAA,KAAK,EAAE;oBACH,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC;oBACzC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,CAAC;AAC1C,oBAAA,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;AAC1B,oBAAA,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;AAC9B,oBAAA,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;AACnC,iBAAA;AACD,gBAAA,mBAAmB,EAAE;AACjB,oBAAA,EAAE,EAAE,eAAe,GAAG,IAAI,CAAC,aAAa;AACxC,oBAAA,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;AACzC,oBAAA,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,4BAA4B,KAAK,aAAa,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,4BAA4B;AAC/H,iBAAA;AACD,gBAAA,cAAc,EAAE;AACZ,oBAAA,EAAE,EAAE,SAAS,GAAG,IAAI,CAAC,aAAa;AAClC,oBAAA,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe;AACxC,oBAAA,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,2BAA2B,KAAK,aAAa,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,2BAA2B;AAC7H,iBAAA;aACJ,CAAC;AACN,SAAC,CAAC;QACF,IAAA,CAAA,sBAAsB,GAAG,CAAC,eAAuB,EAAE,cAAsB,KAAI;YACzE,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,YAAA,IAAI,KAAa,EAAE,IAAY,EAAE,QAAgB,CAAC;YAClD,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG,CAAC,IAAI,eAAe,GAAG,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC;YAC/F,IAAI,SAAS,GAAG,cAAc,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAC3F,YAAA,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;YAE1D,IAAI,KAAK,IAAI,GAAG,EAAE;;gBAEd,KAAK,GAAG,GAAG,CAAC;AACZ,gBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;oBAC7D,IAAI,GAAG,CAAC,CAAC;AACZ,iBAAA;AAAM,qBAAA;;oBAEH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;AACpC,iBAAA;AACJ,aAAA;AAAM,iBAAA;;gBAEH,KAAK,GAAG,KAAK,CAAC;gBACd,IAAI,GAAG,CAAC,CAAC;AACZ,aAAA;;AAED,YAAA,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC;;YAE9D,IAAI,QAAQ,GAAG,YAAY,EAAE;gBACzB,QAAQ,GAAG,YAAY,CAAC;gBACxB,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,QAAQ,CAAC;AAClD,gBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,KAAK,GAAG,GAAG,EAAE;oBAC5E,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;AAClC,iBAAA;AAAM,qBAAA;oBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;AACpC,iBAAA;AACJ,aAAA;;YAED,IAAI,IAAI,GAAG,CAAC,EAAE;gBACV,IAAI,GAAG,CAAC,CAAC;AACZ,aAAA;AACD,YAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC5D,SAAC,CAAC;QACF,IAAA,CAAA,OAAO,GAAG,CAAC,eAAuB,EAAE,cAAsB,KAAI;YAC1D,IAAI,IAAI,CAAC,kBAAkB,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE;AAC5D,gBAAA,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC;AACzC,aAAA;AACD,YAAA,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG,CAAC,GAAG,eAAe,CAAC;YACnE,IAAI,SAAS,GAAG,cAAc,CAAC;AAC/B,YAAA,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAC7F,IAAI,KAAK,GAAG,WAAW,CAAC;YACxB,IAAI,WAAW,GAAG,SAAS,EAAE;AACzB,gBAAA,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAK;oBACxD,KAAK,IAAI,IAAI,CAAC;oBACd,IAAI,KAAK,IAAI,SAAS,EAAE;AACpB,wBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,KAAK,IAAI,GAAG,EAAE;AAC7E,4BAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACrB,4BAAA,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC;AACzC,yBAAA;AAAM,6BAAA;AACH,4BAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACpB,yBAAA;AACJ,qBAAA;AAAM,yBAAA;AACH,wBAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACrB,wBAAA,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC;AACzC,qBAAA;AACL,iBAAC,CAAC,CAAC;AACN,aAAA;AAAM,iBAAA;AACH,gBAAA,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAK;oBACxD,KAAK,IAAI,IAAI,CAAC;oBACd,IAAI,KAAK,IAAI,SAAS,EAAE;AACpB,wBAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,SAAS,IAAI,GAAG,EAAE;AACjF,4BAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACrB,4BAAA,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC;AACzC,yBAAA;AAAM,6BAAA;AACH,4BAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACpB,yBAAA;AACJ,qBAAA;AAAM,yBAAA;AACH,wBAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACrB,wBAAA,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC;AACzC,qBAAA;AACL,iBAAC,CAAC,CAAC;AACN,aAAA;AACL,SAAC,CAAC;AAUM,QAAA,IAAY,CAAA,YAAA,GAAG,MAAK;;YAExB,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;AACxC,gBAAA,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE;oBACvD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;AACnC,iBAAA;AAAM,qBAAA,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE;AACzE,oBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AACnD,iBAAA;AACJ,aAAA;;AAED,YAAA,IAAI,CAAC,OAA