color-util-helpers 1.0.7 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/color-util-helpers-1.0.10.tgz +0 -0
- package/esm2022/color-util-helpers.mjs +5 -0
- package/esm2022/lib/color-conversion.service.mjs +39 -0
- package/esm2022/lib/color-extractor.directive.mjs +37 -0
- package/esm2022/lib/color-grab.directive.mjs +185 -0
- package/esm2022/lib/color-lighten-darken.service.mjs +79 -0
- package/esm2022/lib/color-pallette.service.mjs +172 -0
- package/esm2022/lib/color-scheme.service.mjs +113 -0
- package/esm2022/lib/color-utilities-demo/color-utilities-demo.component.mjs +41 -0
- package/esm2022/lib/color-utils.module.mjs +38 -0
- package/esm2022/lib/text-color.service.mjs +79 -0
- package/esm2022/public-api.mjs +13 -0
- package/fesm2022/color-util-helpers.mjs +767 -0
- package/fesm2022/color-util-helpers.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/color-conversion.service.d.ts +8 -0
- package/lib/color-extractor.directive.d.ts +13 -0
- package/lib/color-grab.directive.d.ts +31 -0
- package/lib/color-lighten-darken.service.d.ts +10 -0
- package/lib/color-pallette.service.d.ts +36 -0
- package/lib/color-scheme.service.d.ts +45 -0
- package/lib/color-utilities-demo/color-utilities-demo.component.d.ts +34 -0
- package/lib/color-utils.module.d.ts +12 -0
- package/lib/text-color.service.d.ts +18 -0
- package/package.json +15 -2
- package/{src/public-api.ts → public-api.d.ts} +0 -6
- package/ng-package.json +0 -8
- package/src/lib/assets/picture.webp +0 -0
- package/src/lib/color-conversion.service.spec.ts +0 -54
- package/src/lib/color-conversion.service.ts +0 -35
- package/src/lib/color-extractor.directive.spec.ts +0 -49
- package/src/lib/color-extractor.directive.ts +0 -28
- package/src/lib/color-grab.directive.ts +0 -204
- package/src/lib/color-lighten-darken.service.spec.ts +0 -61
- package/src/lib/color-lighten-darken.service.ts +0 -83
- package/src/lib/color-pallette.service.spec.ts +0 -85
- package/src/lib/color-pallette.service.ts +0 -191
- package/src/lib/color-scheme.service.ts +0 -123
- package/src/lib/color-utilities-demo/color-utilities-demo.component.css +0 -12
- package/src/lib/color-utilities-demo/color-utilities-demo.component.html +0 -109
- package/src/lib/color-utilities-demo/color-utilities-demo.component.ts +0 -57
- package/src/lib/color-utils.module.ts +0 -27
- package/src/lib/text-color.service.spec.ts +0 -75
- package/src/lib/text-color.service.ts +0 -101
- package/tsconfig.lib.json +0 -32
- package/tsconfig.lib.prod.json +0 -10
- package/tsconfig.spec.json +0 -14
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Color
|
|
1
|
+
# Color Util Helpers
|
|
2
2
|
|
|
3
3
|
This lib contains a variety of very useful color utils
|
|
4
4
|
|
|
@@ -10,9 +10,13 @@ This lib contains a variety of very useful color utils
|
|
|
10
10
|
- Generate Random Color - This function generates a random hue value between 0 and 360 degrees, and random saturation and lightness values between 50% and 100%.
|
|
11
11
|
- Color Grabber - Directive when applied to a div will get the average color of the provided url of an image and then change the background color.
|
|
12
12
|
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
`npm install color-util-helpers`
|
|
16
|
+
|
|
13
17
|
## Demo
|
|
14
18
|
|
|
15
|
-
Import the `
|
|
19
|
+
Import the `ColorUtilHelpersModule`
|
|
16
20
|
|
|
17
21
|
add the selector `<app-color-utilities-demo></app-color-utilities-demo>`
|
|
18
22
|
|
|
Binary file
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItdXRpbC1oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvY29sb3ItdXRpbC1oZWxwZXJzL3NyYy9jb2xvci11dGlsLWhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class ColorConversionService {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.componentToHex = (c) => {
|
|
6
|
+
const hex = c.toString(16);
|
|
7
|
+
return hex.length === 1 ? "0" + hex : hex;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
rgbToHex(rgb) {
|
|
11
|
+
if (rgb === null || rgb.length !== 3 || rgb.some(value => value < 0 || value > 255))
|
|
12
|
+
return '';
|
|
13
|
+
const [r, g, b] = rgb;
|
|
14
|
+
const hexR = this.componentToHex(r);
|
|
15
|
+
const hexG = this.componentToHex(g);
|
|
16
|
+
const hexB = this.componentToHex(b);
|
|
17
|
+
return "#" + hexR + hexG + hexB;
|
|
18
|
+
}
|
|
19
|
+
hexToRgb(hex) {
|
|
20
|
+
if (hex === null || hex === undefined)
|
|
21
|
+
return [];
|
|
22
|
+
hex = (hex.length === 3) ? hex + hex : hex;
|
|
23
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
24
|
+
return result ? [
|
|
25
|
+
parseInt(result[1], 16),
|
|
26
|
+
parseInt(result[2], 16),
|
|
27
|
+
parseInt(result[3], 16)
|
|
28
|
+
] : [];
|
|
29
|
+
}
|
|
30
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
31
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorConversionService, providedIn: 'root' }); }
|
|
32
|
+
}
|
|
33
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorConversionService, decorators: [{
|
|
34
|
+
type: Injectable,
|
|
35
|
+
args: [{
|
|
36
|
+
providedIn: 'root'
|
|
37
|
+
}]
|
|
38
|
+
}] });
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItY29udmVyc2lvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29sb3ItdXRpbC1oZWxwZXJzL3NyYy9saWIvY29sb3ItY29udmVyc2lvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBSzNDLE1BQU0sT0FBTyxzQkFBc0I7SUFIbkM7UUFlVSxtQkFBYyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7WUFDckMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMzQixPQUFPLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDNUMsQ0FBQyxDQUFBO0tBY0Y7SUEzQkMsUUFBUSxDQUFDLEdBQW9CO1FBQzNCLElBQUksR0FBRyxLQUFLLElBQUksSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxLQUFLLEdBQUcsR0FBRyxDQUFDO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFFL0YsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBQ3RCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sR0FBRyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2xDLENBQUM7SUFPRCxRQUFRLENBQUMsR0FBOEI7UUFDckMsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFFakQsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQzNDLE1BQU0sTUFBTSxHQUFHLDJDQUEyQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVyRSxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDZCxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN2QixRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN2QixRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztTQUN4QixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDVCxDQUFDOytHQTVCVSxzQkFBc0I7bUhBQXRCLHNCQUFzQixjQUZyQixNQUFNOzs0RkFFUCxzQkFBc0I7a0JBSGxDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQ29sb3JDb252ZXJzaW9uU2VydmljZSB7XHJcblxyXG4gIHJnYlRvSGV4KHJnYjogbnVtYmVyW10gfCBudWxsKTogc3RyaW5nIHtcclxuICAgIGlmIChyZ2IgPT09IG51bGwgfHwgcmdiLmxlbmd0aCAhPT0gMyB8fCByZ2Iuc29tZSh2YWx1ZSA9PiB2YWx1ZSA8IDAgfHwgdmFsdWUgPiAyNTUpKSByZXR1cm4gJyc7XHJcblxyXG4gICAgY29uc3QgW3IsIGcsIGJdID0gcmdiO1xyXG4gICAgY29uc3QgaGV4UiA9IHRoaXMuY29tcG9uZW50VG9IZXgocik7XHJcbiAgICBjb25zdCBoZXhHID0gdGhpcy5jb21wb25lbnRUb0hleChnKTtcclxuICAgIGNvbnN0IGhleEIgPSB0aGlzLmNvbXBvbmVudFRvSGV4KGIpO1xyXG4gICAgcmV0dXJuIFwiI1wiICsgaGV4UiArIGhleEcgKyBoZXhCO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wb25lbnRUb0hleCA9IChjOiBudW1iZXIpID0+IHtcclxuICAgIGNvbnN0IGhleCA9IGMudG9TdHJpbmcoMTYpO1xyXG4gICAgcmV0dXJuIGhleC5sZW5ndGggPT09IDEgPyBcIjBcIiArIGhleCA6IGhleDtcclxuICB9XHJcblxyXG4gIGhleFRvUmdiKGhleDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG51bWJlcltdIHtcclxuICAgIGlmIChoZXggPT09IG51bGwgfHwgaGV4ID09PSB1bmRlZmluZWQpIHJldHVybiBbXTtcclxuXHJcbiAgICBoZXggPSAoaGV4Lmxlbmd0aCA9PT0gMykgPyBoZXggKyBoZXggOiBoZXg7XHJcbiAgICBjb25zdCByZXN1bHQgPSAvXiM/KFthLWZcXGRdezJ9KShbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pJC9pLmV4ZWMoaGV4KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0ID8gW1xyXG4gICAgICBwYXJzZUludChyZXN1bHRbMV0sIDE2KSxcclxuICAgICAgcGFyc2VJbnQocmVzdWx0WzJdLCAxNiksXHJcbiAgICAgIHBhcnNlSW50KHJlc3VsdFszXSwgMTYpXHJcbiAgICBdIDogW107XHJcbiAgfVxyXG59XHJcbiJdfQ==
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Directive, HostListener, EventEmitter, Output } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class ColorExtractorDirective {
|
|
4
|
+
constructor(elementRef, renderer) {
|
|
5
|
+
this.elementRef = elementRef;
|
|
6
|
+
this.renderer = renderer;
|
|
7
|
+
this.colorValue = new EventEmitter();
|
|
8
|
+
}
|
|
9
|
+
get currentElement() {
|
|
10
|
+
return window.getComputedStyle(this.elementRef.nativeElement);
|
|
11
|
+
}
|
|
12
|
+
onMouseEnter() {
|
|
13
|
+
// console.log('ENTER', this.currentElement)
|
|
14
|
+
this.colorValue.emit(this.currentElement.getPropertyValue('background-color'));
|
|
15
|
+
}
|
|
16
|
+
onMouseLeave() {
|
|
17
|
+
// console.log('LEAVE', this.currentElement.getPropertyValue('background-color'))
|
|
18
|
+
this.colorValue.emit('white');
|
|
19
|
+
}
|
|
20
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorExtractorDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
21
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColorExtractorDirective, selector: "[getColor]", outputs: { colorValue: "colorValue" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, ngImport: i0 }); }
|
|
22
|
+
}
|
|
23
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorExtractorDirective, decorators: [{
|
|
24
|
+
type: Directive,
|
|
25
|
+
args: [{
|
|
26
|
+
selector: '[getColor]'
|
|
27
|
+
}]
|
|
28
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { colorValue: [{
|
|
29
|
+
type: Output
|
|
30
|
+
}], onMouseEnter: [{
|
|
31
|
+
type: HostListener,
|
|
32
|
+
args: ['mouseenter']
|
|
33
|
+
}], onMouseLeave: [{
|
|
34
|
+
type: HostListener,
|
|
35
|
+
args: ['mouseleave']
|
|
36
|
+
}] } });
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItZXh0cmFjdG9yLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbG9yLXV0aWwtaGVscGVycy9zcmMvbGliL2NvbG9yLWV4dHJhY3Rvci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBeUIsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBS3JHLE1BQU0sT0FBTyx1QkFBdUI7SUFJbEMsWUFBb0IsVUFBc0IsRUFBVSxRQUFtQjtRQUFuRCxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUY3RCxlQUFVLEdBQXlCLElBQUksWUFBWSxFQUFVLENBQUM7SUFFRSxDQUFDO0lBRTNFLElBQUksY0FBYztRQUNoQixPQUFPLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFHRCxZQUFZO1FBQ1YsNENBQTRDO1FBQzVDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFBO0lBQ2hGLENBQUM7SUFHRCxZQUFZO1FBQ1YsaUZBQWlGO1FBQ2pGLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQy9CLENBQUM7K0dBcEJVLHVCQUF1QjttR0FBdkIsdUJBQXVCOzs0RkFBdkIsdUJBQXVCO2tCQUhuQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxZQUFZO2lCQUN2Qjt5SEFHVyxVQUFVO3NCQUFuQixNQUFNO2dCQVNQLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxZQUFZO2dCQU8xQixZQUFZO3NCQURYLFlBQVk7dUJBQUMsWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgUmVuZGVyZXIyLCBIb3N0TGlzdGVuZXIsIEV2ZW50RW1pdHRlciwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tnZXRDb2xvcl0nXG59KVxuZXhwb3J0IGNsYXNzIENvbG9yRXh0cmFjdG9yRGlyZWN0aXZlIHtcblxuICBAT3V0cHV0KCkgY29sb3JWYWx1ZTogRXZlbnRFbWl0dGVyPHN0cmluZz4gPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMikge31cblxuICBnZXQgY3VycmVudEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlZW50ZXInKVxuICBvbk1vdXNlRW50ZXIoKSB7XG4gICAgLy8gY29uc29sZS5sb2coJ0VOVEVSJywgdGhpcy5jdXJyZW50RWxlbWVudClcbiAgICB0aGlzLmNvbG9yVmFsdWUuZW1pdCh0aGlzLmN1cnJlbnRFbGVtZW50LmdldFByb3BlcnR5VmFsdWUoJ2JhY2tncm91bmQtY29sb3InKSlcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnKVxuICBvbk1vdXNlTGVhdmUoKSB7XG4gICAgLy8gY29uc29sZS5sb2coJ0xFQVZFJywgdGhpcy5jdXJyZW50RWxlbWVudC5nZXRQcm9wZXJ0eVZhbHVlKCdiYWNrZ3JvdW5kLWNvbG9yJykpXG4gICAgdGhpcy5jb2xvclZhbHVlLmVtaXQoJ3doaXRlJylcbiAgfVxuXG59XG4iXX0=
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { Directive, Input } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class ColorGrabberDirective {
|
|
4
|
+
constructor(el) {
|
|
5
|
+
this.el = el;
|
|
6
|
+
}
|
|
7
|
+
ngOnInit() {
|
|
8
|
+
const canvas = document.createElement('canvas');
|
|
9
|
+
canvas.width = 1;
|
|
10
|
+
canvas.height = 1;
|
|
11
|
+
this.ctx = canvas.getContext('2d');
|
|
12
|
+
const img = new Image();
|
|
13
|
+
img.src = this.imageUrl || '';
|
|
14
|
+
img.setAttribute('crossOrigin', '');
|
|
15
|
+
img.onload = () => {
|
|
16
|
+
this.ctx?.drawImage(img, 0, 0, 1, 1);
|
|
17
|
+
const imageData = this.ctx?.getImageData(0, 0, 1, 1);
|
|
18
|
+
if (imageData && imageData.data) {
|
|
19
|
+
const i = imageData.data;
|
|
20
|
+
const rgbColor = `rgba(${i[0]},${i[1]},${i[2]},${i[3]})`;
|
|
21
|
+
const hexColor = "#" + ((1 << 24) + (i[0] << 16) + (i[1] << 8) + i[2]).toString(16).slice(1);
|
|
22
|
+
const textColor = this.textColorBasedOnBgColor(hexColor, this.light, this.dark);
|
|
23
|
+
const hsv = this.RGB2HSV({ r: i[0], g: i[1], b: i[2] });
|
|
24
|
+
hsv.hue = this.HueShift(hsv.hue, 135.0);
|
|
25
|
+
const secondaryColor = this.HSV2RGB(hsv);
|
|
26
|
+
const highlightColor = this.lightenDarkenColor(secondaryColor.hex, 50);
|
|
27
|
+
this.el.nativeElement.style.backgroundColor = rgbColor;
|
|
28
|
+
this.el.nativeElement.style.color = textColor;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.error("Failed to get image data.");
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
textColorBasedOnBgColor(bgColor, lightColor = '#FFFFFF', darkColor = '#000000') {
|
|
36
|
+
const color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
|
|
37
|
+
const r = parseInt(color.substring(0, 2), 16); // hexToR
|
|
38
|
+
const g = parseInt(color.substring(2, 4), 16); // hexToG
|
|
39
|
+
const b = parseInt(color.substring(4, 6), 16); // hexToB
|
|
40
|
+
const uicolors = [r / 255, g / 255, b / 255];
|
|
41
|
+
const c = uicolors.map((col) => {
|
|
42
|
+
if (col <= 0.03928)
|
|
43
|
+
return col / 12.92;
|
|
44
|
+
return Math.pow((col + 0.055) / 1.055, 2.4);
|
|
45
|
+
});
|
|
46
|
+
const L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
|
|
47
|
+
return (L > 0.179) ? darkColor : lightColor;
|
|
48
|
+
}
|
|
49
|
+
RGB2HSV(rgb) {
|
|
50
|
+
const hsv = { saturation: 0, hue: 0, value: 0 };
|
|
51
|
+
const max = this.max3(rgb.r, rgb.g, rgb.b);
|
|
52
|
+
const dif = max - this.min3(rgb.r, rgb.g, rgb.b);
|
|
53
|
+
hsv.saturation = (max == 0.0) ? 0 : (100 * dif / max);
|
|
54
|
+
if (hsv.saturation == 0) {
|
|
55
|
+
hsv.hue = 0;
|
|
56
|
+
}
|
|
57
|
+
else if (rgb.r == max) {
|
|
58
|
+
hsv.hue = 60.0 * (rgb.g - rgb.b) / dif;
|
|
59
|
+
}
|
|
60
|
+
else if (rgb.g == max) {
|
|
61
|
+
hsv.hue = 120.0 + 60.0 * (rgb.b - rgb.r) / dif;
|
|
62
|
+
}
|
|
63
|
+
else if (rgb.b == max) {
|
|
64
|
+
hsv.hue = 240.0 + 60.0 * (rgb.r - rgb.g) / dif;
|
|
65
|
+
}
|
|
66
|
+
if (hsv.hue < 0.0)
|
|
67
|
+
hsv.hue += 360.0;
|
|
68
|
+
hsv.value = Math.round(max * 100 / 255);
|
|
69
|
+
hsv.hue = Math.round(hsv.hue);
|
|
70
|
+
hsv.saturation = Math.round(hsv.saturation);
|
|
71
|
+
return hsv;
|
|
72
|
+
}
|
|
73
|
+
HSV2RGB(hsv) {
|
|
74
|
+
const rgb = { r: 0, g: 0, b: 0 };
|
|
75
|
+
if (hsv.saturation == 0) {
|
|
76
|
+
rgb.r = rgb.g = rgb.b = Math.round(hsv.value * 2.55);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
hsv.hue /= 60;
|
|
80
|
+
hsv.saturation /= 100;
|
|
81
|
+
hsv.value /= 100;
|
|
82
|
+
const i = Math.floor(hsv.hue);
|
|
83
|
+
const f = hsv.hue - i;
|
|
84
|
+
const p = hsv.value * (1 - hsv.saturation);
|
|
85
|
+
const q = hsv.value * (1 - hsv.saturation * f);
|
|
86
|
+
const t = hsv.value * (1 - hsv.saturation * (1 - f));
|
|
87
|
+
switch (i) {
|
|
88
|
+
case 0:
|
|
89
|
+
rgb.r = hsv.value;
|
|
90
|
+
rgb.g = t;
|
|
91
|
+
rgb.b = p;
|
|
92
|
+
break;
|
|
93
|
+
case 1:
|
|
94
|
+
rgb.r = q;
|
|
95
|
+
rgb.g = hsv.value;
|
|
96
|
+
rgb.b = p;
|
|
97
|
+
break;
|
|
98
|
+
case 2:
|
|
99
|
+
rgb.r = p;
|
|
100
|
+
rgb.g = hsv.value;
|
|
101
|
+
rgb.b = t;
|
|
102
|
+
break;
|
|
103
|
+
case 3:
|
|
104
|
+
rgb.r = p;
|
|
105
|
+
rgb.g = q;
|
|
106
|
+
rgb.b = hsv.value;
|
|
107
|
+
break;
|
|
108
|
+
case 4:
|
|
109
|
+
rgb.r = t;
|
|
110
|
+
rgb.g = p;
|
|
111
|
+
rgb.b = hsv.value;
|
|
112
|
+
break;
|
|
113
|
+
default:
|
|
114
|
+
rgb.r = hsv.value;
|
|
115
|
+
rgb.g = p;
|
|
116
|
+
rgb.b = q;
|
|
117
|
+
}
|
|
118
|
+
rgb.r = Math.round(rgb.r * 255);
|
|
119
|
+
rgb.g = Math.round(rgb.g * 255);
|
|
120
|
+
rgb.b = Math.round(rgb.b * 255);
|
|
121
|
+
}
|
|
122
|
+
const rgbColor = `rgba(${rgb.r},${rgb.g},${rgb.b},${1})`;
|
|
123
|
+
const hexColor = "#" + ((1 << 24) + (rgb.r << 16) + (rgb.g << 8) + rgb.b).toString(16).slice(1);
|
|
124
|
+
return { rgb: rgbColor, hex: hexColor };
|
|
125
|
+
}
|
|
126
|
+
HueShift(h, s) {
|
|
127
|
+
h += s;
|
|
128
|
+
while (h >= 360.0)
|
|
129
|
+
h -= 360.0;
|
|
130
|
+
while (h < 0.0)
|
|
131
|
+
h += 360.0;
|
|
132
|
+
return h;
|
|
133
|
+
}
|
|
134
|
+
min3(a, b, c) {
|
|
135
|
+
return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
|
|
136
|
+
}
|
|
137
|
+
max3(a, b, c) {
|
|
138
|
+
return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
|
|
139
|
+
}
|
|
140
|
+
lightenDarkenColor(colorCode, amount) {
|
|
141
|
+
var usePound = false;
|
|
142
|
+
if (colorCode[0] == "#") {
|
|
143
|
+
colorCode = colorCode.slice(1);
|
|
144
|
+
usePound = true;
|
|
145
|
+
}
|
|
146
|
+
var num = parseInt(colorCode, 16);
|
|
147
|
+
var r = (num >> 16) + amount;
|
|
148
|
+
if (r > 255) {
|
|
149
|
+
r = 255;
|
|
150
|
+
}
|
|
151
|
+
else if (r < 0) {
|
|
152
|
+
r = 0;
|
|
153
|
+
}
|
|
154
|
+
var b = ((num >> 8) & 0x00FF) + amount;
|
|
155
|
+
if (b > 255) {
|
|
156
|
+
b = 255;
|
|
157
|
+
}
|
|
158
|
+
else if (b < 0) {
|
|
159
|
+
b = 0;
|
|
160
|
+
}
|
|
161
|
+
var g = (num & 0x0000FF) + amount;
|
|
162
|
+
if (g > 255) {
|
|
163
|
+
g = 255;
|
|
164
|
+
}
|
|
165
|
+
else if (g < 0) {
|
|
166
|
+
g = 0;
|
|
167
|
+
}
|
|
168
|
+
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16);
|
|
169
|
+
}
|
|
170
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorGrabberDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
171
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColorGrabberDirective, selector: "[colorGrabber]", inputs: { imageUrl: "imageUrl", light: "light", dark: "dark" }, ngImport: i0 }); }
|
|
172
|
+
}
|
|
173
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorGrabberDirective, decorators: [{
|
|
174
|
+
type: Directive,
|
|
175
|
+
args: [{
|
|
176
|
+
selector: '[colorGrabber]'
|
|
177
|
+
}]
|
|
178
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { imageUrl: [{
|
|
179
|
+
type: Input
|
|
180
|
+
}], light: [{
|
|
181
|
+
type: Input
|
|
182
|
+
}], dark: [{
|
|
183
|
+
type: Input
|
|
184
|
+
}] } });
|
|
185
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItZ3JhYi5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb2xvci11dGlsLWhlbHBlcnMvc3JjL2xpYi9jb2xvci1ncmFiLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLEtBQUssRUFBVSxNQUFNLGVBQWUsQ0FBQzs7QUFLckUsTUFBTSxPQUFPLHFCQUFxQjtJQVFoQyxZQUFvQixFQUFjO1FBQWQsT0FBRSxHQUFGLEVBQUUsQ0FBWTtJQUFJLENBQUM7SUFFdkMsUUFBUTtRQUVOLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEQsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDakIsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFFbEIsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBNkIsQ0FBQztRQUUvRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3hCLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7UUFDOUIsR0FBRyxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFcEMsR0FBRyxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUU7WUFDaEIsSUFBSSxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBRXJELElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxJ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R0FBRyxDQUFDLENBQUE7U0FFOUI7UUFFRCxNQUFNLFFBQVEsR0FBRyxRQUFRLEdBQUcsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFBO1FBQ3hELE1BQU0sUUFBUSxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFL0YsT0FBTyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxDQUFBO0lBQ3pDLENBQUM7SUFFRCxRQUFRLENBQUMsQ0FBTSxFQUFFLENBQU07UUFDckIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNOLE9BQU8sQ0FBQyxJQUFFLEtBQUs7WUFBRSxDQUFDLElBQUUsS0FBSyxDQUFBO1FBQ3pCLE9BQU8sQ0FBQyxHQUFDLEdBQUc7WUFBRSxDQUFDLElBQUUsS0FBSyxDQUFBO1FBQ3RCLE9BQU8sQ0FBQyxDQUFBO0lBQ1YsQ0FBQztJQUVELElBQUksQ0FBQyxDQUFNLEVBQUUsQ0FBTSxFQUFFLENBQU07UUFDekIsT0FBTyxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQSxDQUFDLENBQUEsQ0FBQyxDQUFBLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQSxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQSxDQUFDLENBQUEsQ0FBQyxDQUFBLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQTtJQUN0QyxDQUFDO0lBRUQsSUFBSSxDQUFDLENBQU0sRUFBRSxDQUFNLEVBQUUsQ0FBTTtRQUN6QixPQUFPLENBQUMsQ0FBQyxHQUFDLENBQUMsQ0FBQyxDQUFBLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQyxHQUFDLENBQUMsQ0FBQyxDQUFBLENBQUMsQ0FBQSxDQUFDLENBQUEsQ0FBQyxDQUFBLENBQUMsQ0FBQyxDQUFBLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQyxHQUFDLENBQUMsQ0FBQyxDQUFBLENBQUMsQ0FBQSxDQUFDLENBQUEsQ0FBQyxDQUFBLENBQUMsQ0FBQyxDQUFBO0lBQ3RDLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxTQUFjLEVBQUUsTUFBYztRQUUvQyxJQUFJLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFFckIsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxFQUFFO1lBQ3JCLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLFFBQVEsR0FBRyxJQUFJLENBQUM7U0FDbkI7UUFFRCxJQUFJLEdBQUcsR0FBRyxRQUFRLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWxDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUU3QixJQUFJLENBQUMsR0FBRyxHQUFHLEVBQUU7WUFDVCxDQUFDLEdBQUcsR0FBRyxDQUFDO1NBQ1g7YUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDZCxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ1Q7UUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUV2QyxJQUFJLENBQUMsR0FBRyxHQUFHLEVBQUU7WUFDVCxDQUFDLEdBQUcsR0FBRyxDQUFDO1NBQ1g7YUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDZCxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ1Q7UUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUM7UUFFbEMsSUFBSSxDQUFDLEdBQUcsR0FBRyxFQUFFO1lBQ1QsQ0FBQyxHQUFHLEdBQUcsQ0FBQztTQUNYO2FBQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ2QsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNUO1FBRUQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUV4RSxDQUFDOytHQXBNVSxxQkFBcUI7bUdBQXJCLHFCQUFxQjs7NEZBQXJCLHFCQUFxQjtrQkFIakMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsZ0JBQWdCO2lCQUMzQjtpR0FLVSxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2NvbG9yR3JhYmJlcl0nXG59KVxuZXhwb3J0IGNsYXNzIENvbG9yR3JhYmJlckRpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgY3R4PzogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEXG5cbiAgQElucHV0KCkgaW1hZ2VVcmw/OiBzdHJpbmdcbiAgQElucHV0KCkgbGlnaHQ/OiBzdHJpbmdcbiAgQElucHV0KCkgZGFyaz86IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWw6IEVsZW1lbnRSZWYpIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuXG4gICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgY2FudmFzLndpZHRoID0gMTtcbiAgICBjYW52YXMuaGVpZ2h0ID0gMTtcblxuICAgIHRoaXMuY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJykgYXMgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEO1xuXG4gICAgY29uc3QgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgaW1nLnNyYyA9IHRoaXMuaW1hZ2VVcmwgfHwgJyc7XG4gICAgaW1nLnNldEF0dHJpYnV0ZSgnY3Jvc3NPcmlnaW4nLCAnJyk7XG5cbiAgICBpbWcub25sb2FkID0gKCkgPT4ge1xuICAgICAgdGhpcy5jdHg/LmRyYXdJbWFnZShpbWcsIDAsIDAsIDEsIDEpO1xuICAgICAgY29uc3QgaW1hZ2VEYXRhID0gdGhpcy5jdHg/LmdldEltYWdlRGF0YSgwLCAwLCAxLCAxKTtcblxuICAgICAgaWYgKGltYWdlRGF0YSAmJiBpbWFnZURhdGEuZGF0YSkge1xuICAgICAgICBjb25zdCBpID0gaW1hZ2VEYXRhLmRhdGE7XG5cbiAgICAgICAgY29uc3QgcmdiQ29sb3IgPSBgcmdiYSgke2lbMF19LCR7aVsxXX0sJHtpWzJdfSwke2lbM119KWA7XG4gICAgICAgIGNvbnN0IGhleENvbG9yID0gXCIjXCIgKyAoKDEgPDwgMjQpICsgKGlbMF0gPDwgMTYpICsgKGlbMV0gPDwgOCkgKyBpWzJdKS50b1N0cmluZygxNikuc2xpY2UoMSk7XG5cbiAgICAgICAgY29uc3QgdGV4dENvbG9yID0gdGhpcy50ZXh0Q29sb3JCYXNlZE9uQmdDb2xvcihoZXhDb2xvciwgdGhpcy5saWdodCwgdGhpcy5kYXJrKTtcblxuICAgICAgICBjb25zdCBoc3YgPSB0aGlzLlJHQjJIU1YoeyByOiBpWzBdLCBnOiBpWzFdLCBiOiBpWzJdIH0pO1xuICAgICAgICBoc3YuaHVlID0gdGhpcy5IdWVTaGlmdChoc3YuaHVlLCAxMzUuMCk7XG5cbiAgICAgICAgY29uc3Qgc2Vjb25kYXJ5Q29sb3IgPSB0aGlzLkhTVjJSR0IoaHN2KTtcbiAgICAgICAgY29uc3QgaGlnaGxpZ2h0Q29sb3IgPSB0aGlzLmxpZ2h0ZW5EYXJrZW5Db2xvcihzZWNvbmRhcnlDb2xvci5oZXgsIDUwKTtcblxuICAgICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gcmdiQ29sb3I7XG4gICAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5zdHlsZS5jb2xvciA9IHRleHRDb2xvcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJGYWlsZWQgdG8gZ2V0IGltYWdlIGRhdGEuXCIpO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICB0ZXh0Q29sb3JCYXNlZE9uQmdDb2xvcihcbiAgICBiZ0NvbG9yOiBzdHJpbmcsXG4gICAgbGlnaHRDb2xvcjogc3RyaW5nID0gJyNGRkZGRkYnLFxuICAgIGRhcmtDb2xvcjogc3RyaW5nID0gJyMwMDAwMDAnXG4gICAgKSB7XG5cbiAgICBjb25zdCBjb2xvciA9IChiZ0NvbG9yLmNoYXJBdCgwKSA9PT0gJyMnKSA/IGJnQ29sb3Iuc3Vic3RyaW5nKDEsIDcpIDogYmdDb2xvclxuXG4gICAgY29uc3QgciA9IHBhcnNlSW50KGNvbG9yLnN1YnN0cmluZygwLCAyKSwgMTYpIC8vIGhleFRvUlxuICAgIGNvbnN0IGcgPSBwYXJzZUludChjb2xvci5zdWJzdHJpbmcoMiwgNCksIDE2KSAvLyBoZXhUb0dcbiAgICBjb25zdCBiID0gcGFyc2VJbnQoY29sb3Iuc3Vic3RyaW5nKDQsIDYpLCAxNikgLy8gaGV4VG9CXG5cbiAgICBjb25zdCB1aWNvbG9ycyA9IFtyIC8gMjU1LCBnIC8gMjU1LCBiIC8gMjU1XVxuXG4gICAgY29uc3QgYyA9IHVpY29sb3JzLm1hcCgoY29sKSA9PiB7XG5cbiAgICAgIGlmIChjb2wgPD0gMC4wMzkyOCkgcmV0dXJuIGNvbCAvIDEyLjkyXG4gICAgICByZXR1cm4gTWF0aC5wb3coKGNvbCArIDAuMDU1KSAvIDEuMDU1LCAyLjQpXG5cbiAgICB9KVxuXG4gICAgY29uc3QgTCA9ICgwLjIxMjYgKiBjWzBdKSArICgwLjcxNTIgKiBjWzFdKSArICgwLjA3MjIgKiBjWzJdKVxuXG4gICAgcmV0dXJuIChMID4gMC4xNzkpID8gZGFya0NvbG9yIDogbGlnaHRDb2xvclxuXG4gIH1cblxuICBSR0IySFNWKHJnYjogeyByOiBhbnksIGc6IGFueSwgYjogYW55fSkge1xuXG4gICAgY29uc3QgaHN2ID0geyBzYXR1cmF0aW9uOjAsIGh1ZTowLCB2YWx1ZTogMCB9XG5cbiAgICBjb25zdCBtYXggPSB0aGlzLm1heDMocmdiLnIscmdiLmcscmdiLmIpXG4gICAgY29uc3QgZGlmID0gbWF4IC0gdGhpcy5taW4zKHJnYi5yLHJnYi5nLHJnYi5iKVxuICAgIGhzdi5zYXR1cmF0aW9uID0gKG1heD09MC4wKT8wOigxMDAqZGlmL21heClcblxuICAgIGlmIChoc3Yuc2F0dXJhdGlvbiA9PSAwKSB7XG4gICAgICBoc3YuaHVlPTBcbiAgICB9IGVsc2UgaWYgKHJnYi5yID09IG1heCkge1xuICAgICAgaHN2Lmh1ZT02MC4wKihyZ2IuZy1yZ2IuYikvZGlmXG4gICAgfSBlbHNlIGlmIChyZ2IuZyA9PSBtYXgpIHtcbiAgICAgIGhzdi5odWU9MTIwLjArNjAuMCoocmdiLmItcmdiLnIpL2RpZlxuICAgIH0gZWxzZSBpZiAocmdiLmIgPT0gbWF4KSB7XG4gICAgICBoc3YuaHVlPTI0MC4wKzYwLjAqKHJnYi5yLXJnYi5nKS9kaWZcbiAgICB9XG5cbiAgICBpZiAoaHN2Lmh1ZTwwLjApIGhzdi5odWUrPTM2MC4wXG5cbiAgICBoc3YudmFsdWUgPSBNYXRoLnJvdW5kKG1heCoxMDAvMjU1KVxuICAgIGhzdi5odWUgPSBNYXRoLnJvdW5kKGhzdi5odWUpXG4gICAgaHN2LnNhdHVyYXRpb24gPSBNYXRoLnJvdW5kKGhzdi5zYXR1cmF0aW9uKVxuXG4gICAgcmV0dXJuIGhzdlxuICB9XG5cbiAgSFNWMlJHQihoc3Y6IGFueSkge1xuXG4gICAgY29uc3QgcmdiID0geyByOiAwLCBnOiAwLCBiOiAwfVxuXG4gICAgaWYgKGhzdi5zYXR1cmF0aW9uPT0wKSB7XG4gICAgICByZ2IuciA9IHJnYi5nID0gcmdiLmIgPSBNYXRoLnJvdW5kKGhzdi52YWx1ZSoyLjU1KVxuICAgIH0gZWxzZSB7XG5cbiAgICAgIGhzdi5odWUvPTYwXG4gICAgICBoc3Yuc2F0dXJhdGlvbi89MTAwXG4gICAgICBoc3YudmFsdWUvPTEwMFxuICAgICAgY29uc3QgaSA9IE1hdGguZmxvb3IoaHN2Lmh1ZSlcbiAgICAgIGNvbnN0IGYgPSBoc3YuaHVlLWlcblxuICAgICAgY29uc3QgcCA9IGhzdi52YWx1ZSooMS1oc3Yuc2F0dXJhdGlvbilcbiAgICAgIGNvbnN0IHEgPSBoc3YudmFsdWUqKDEtaHN2LnNhdHVyYXRpb24qZilcbiAgICAgIGNvbnN0IHQgPSBoc3YudmFsdWUqKDEtaHN2LnNhdHVyYXRpb24qKDEtZikpXG5cbiAgICAgIHN3aXRjaChpKSB7XG5cbiAgICAgIGNhc2UgMDogcmdiLnI9aHN2LnZhbHVlOyByZ2IuZz10OyByZ2IuYj1wOyBicmVha1xuICAgICAgY2FzZSAxOiByZ2Iucj1xOyByZ2IuZz1oc3YudmFsdWU7IHJnYi5iPXA7IGJyZWFrXG4gICAgICBjYXNlIDI6IHJnYi5yPXA7IHJnYi5nPWhzdi52YWx1ZTsgcmdiLmI9dDsgYnJlYWtcbiAgICAgIGNhc2UgMzogcmdiLnI9cDsgcmdiLmc9cTsgcmdiLmI9aHN2LnZhbHVlOyBicmVha1xuICAgICAgY2FzZSA0OiByZ2Iucj10OyByZ2IuZz1wOyByZ2IuYj1oc3YudmFsdWU7IGJyZWFrXG5cbiAgICAgIGRlZmF1bHQ6IHJnYi5yPWhzdi52YWx1ZTsgcmdiLmc9cDsgcmdiLmI9cVxuXG4gICAgICB9XG5cbiAgICAgIHJnYi5yID0gTWF0aC5yb3VuZChyZ2IucioyNTUpXG4gICAgICByZ2IuZyA9IE1hdGgucm91bmQocmdiLmcqMjU1KVxuICAgICAgcmdiLmIgPSBNYXRoLnJvdW5kKHJnYi5iKjI1NSlcblxuICAgIH1cblxuICAgIGNvbnN0IHJnYkNvbG9yID0gYHJnYmEoJHtyZ2Iucn0sJHtyZ2IuZ30sJHtyZ2IuYn0sJHsxfSlgXG4gICAgY29uc3QgaGV4Q29sb3IgPSBcIiNcIiArICgoMSA8PCAyNCkgKyAocmdiLnIgPDwgMTYpICsgKHJnYi5nIDw8IDgpICsgcmdiLmIpLnRvU3RyaW5nKDE2KS5zbGljZSgxKVxuXG4gICAgcmV0dXJuIHsgcmdiOiByZ2JDb2xvciwgaGV4OiBoZXhDb2xvciB9XG4gIH1cblxuICBIdWVTaGlmdChoOiBhbnksIHM6IGFueSkge1xuICAgIGggKz0gc1xuICAgIHdoaWxlIChoPj0zNjAuMCkgaC09MzYwLjBcbiAgICB3aGlsZSAoaDwwLjApIGgrPTM2MC4wXG4gICAgcmV0dXJuIGhcbiAgfVxuXG4gIG1pbjMoYTogYW55LCBiOiBhbnksIGM6IGFueSkge1xuICAgIHJldHVybiAoYTxiKT8oKGE8Yyk/YTpjKTooKGI8Yyk/YjpjKVxuICB9XG5cbiAgbWF4MyhhOiBhbnksIGI6IGFueSwgYzogYW55KSB7XG4gICAgcmV0dXJuIChhPmIpPygoYT5jKT9hOmMpOigoYj5jKT9iOmMpXG4gIH1cblxuICBsaWdodGVuRGFya2VuQ29sb3IoY29sb3JDb2RlOiBhbnksIGFtb3VudDogbnVtYmVyKSB7XG5cbiAgICB2YXIgdXNlUG91bmQgPSBmYWxzZTtcblxuICAgIGlmIChjb2xvckNvZGVbMF0gPT0gXCIjXCIpIHtcbiAgICAgICAgY29sb3JDb2RlID0gY29sb3JDb2RlLnNsaWNlKDEpO1xuICAgICAgICB1c2VQb3VuZCA9IHRydWU7XG4gICAgfVxuXG4gICAgdmFyIG51bSA9IHBhcnNlSW50KGNvbG9yQ29kZSwgMTYpO1xuXG4gICAgdmFyIHIgPSAobnVtID4+IDE2KSArIGFtb3VudDtcblxuICAgIGlmIChyID4gMjU1KSB7XG4gICAgICAgIHIgPSAyNTU7XG4gICAgfSBlbHNlIGlmIChyIDwgMCkge1xuICAgICAgICByID0gMDtcbiAgICB9XG5cbiAgICB2YXIgYiA9ICgobnVtID4+IDgpICYgMHgwMEZGKSArIGFtb3VudDtcblxuICAgIGlmIChiID4gMjU1KSB7XG4gICAgICAgIGIgPSAyNTU7XG4gICAgfSBlbHNlIGlmIChiIDwgMCkge1xuICAgICAgICBiID0gMDtcbiAgICB9XG5cbiAgICB2YXIgZyA9IChudW0gJiAweDAwMDBGRikgKyBhbW91bnQ7XG5cbiAgICBpZiAoZyA+IDI1NSkge1xuICAgICAgICBnID0gMjU1O1xuICAgIH0gZWxzZSBpZiAoZyA8IDApIHtcbiAgICAgICAgZyA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuICh1c2VQb3VuZCA/IFwiI1wiIDogXCJcIikgKyAoZyB8IChiIDw8IDgpIHwgKHIgPDwgMTYpKS50b1N0cmluZygxNilcblxuICB9XG5cbn1cbiJdfQ==
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Injectable, inject } from '@angular/core';
|
|
2
|
+
import { TextColorService } from './text-color.service';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class ColorLightenDarkenService {
|
|
5
|
+
// const color = '#3498db'; // Your color
|
|
6
|
+
// const lighterColor = lighten(color, 0.2); // 20% lighter
|
|
7
|
+
// const darkerColor = darken(color, 0.2); // 20% darker
|
|
8
|
+
// console.log(lighterColor, darkerColor);
|
|
9
|
+
constructor() {
|
|
10
|
+
this.colors = inject(TextColorService);
|
|
11
|
+
}
|
|
12
|
+
lighten(color, amount) {
|
|
13
|
+
const rgb = this.colors.fixColor(color);
|
|
14
|
+
// const rgb = color.match(/\w\w/g)?.map((x) => parseInt(x, 16)) || [];
|
|
15
|
+
// Convert RGB to HSL
|
|
16
|
+
let [r, g, b] = rgb.map((c) => c / 255);
|
|
17
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b);
|
|
18
|
+
let h = 0, s = 0, l = (max + min) / 2;
|
|
19
|
+
if (max !== min) {
|
|
20
|
+
const d = max - min;
|
|
21
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
22
|
+
switch (max) {
|
|
23
|
+
case r:
|
|
24
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
25
|
+
break;
|
|
26
|
+
case g:
|
|
27
|
+
h = (b - r) / d + 2;
|
|
28
|
+
break;
|
|
29
|
+
case b:
|
|
30
|
+
h = (r - g) / d + 4;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
h /= 6;
|
|
34
|
+
}
|
|
35
|
+
// Modify the lightness and clamp it to [0, 1]
|
|
36
|
+
l = Math.min(1, l + amount);
|
|
37
|
+
// Convert HSL back to RGB
|
|
38
|
+
if (s === 0) {
|
|
39
|
+
r = g = b = l; // achromatic
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const hue2rgb = (p, q, t) => {
|
|
43
|
+
if (t < 0)
|
|
44
|
+
t += 1;
|
|
45
|
+
if (t > 1)
|
|
46
|
+
t -= 1;
|
|
47
|
+
if (t < 1 / 6)
|
|
48
|
+
return p + (q - p) * 6 * t;
|
|
49
|
+
if (t < 1 / 2)
|
|
50
|
+
return q;
|
|
51
|
+
if (t < 2 / 3)
|
|
52
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
53
|
+
return p;
|
|
54
|
+
};
|
|
55
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
56
|
+
const p = 2 * l - q;
|
|
57
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
58
|
+
g = hue2rgb(p, q, h);
|
|
59
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
60
|
+
}
|
|
61
|
+
// Convert RGB back to hexadecimal color
|
|
62
|
+
const toHex = (x) => Math.round(x * 255)
|
|
63
|
+
.toString(16)
|
|
64
|
+
.padStart(2, '0');
|
|
65
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
66
|
+
}
|
|
67
|
+
darken(color, amount) {
|
|
68
|
+
return this.lighten(color, -amount);
|
|
69
|
+
}
|
|
70
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorLightenDarkenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
71
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorLightenDarkenService, providedIn: 'root' }); }
|
|
72
|
+
}
|
|
73
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorLightenDarkenService, decorators: [{
|
|
74
|
+
type: Injectable,
|
|
75
|
+
args: [{
|
|
76
|
+
providedIn: 'root'
|
|
77
|
+
}]
|
|
78
|
+
}], ctorParameters: function () { return []; } });
|
|
79
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItbGlnaHRlbi1kYXJrZW4uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbG9yLXV0aWwtaGVscGVycy9zcmMvbGliL2NvbG9yLWxpZ2h0ZW4tZGFya2VuLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7O0FBS3hELE1BQU0sT0FBTyx5QkFBeUI7SUFJcEMseUNBQXlDO0lBQ3pDLDJEQUEyRDtJQUMzRCwwREFBMEQ7SUFFMUQsMENBQTBDO0lBRTVDO1FBUkUsV0FBTSxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0lBUW5CLENBQUM7SUFFZixPQUFPLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFFbkMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDdkMsdUVBQXVFO1FBRXZFLHFCQUFxQjtRQUNyQixJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDeEMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUMzQixHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxHQUFHLENBQUMsRUFDUCxDQUFDLEdBQUcsQ0FBQyxFQUNMLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENB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SSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO2FBQ2hCLFFBQVEsQ0FBQyxFQUFFLENBQUM7YUFDWixRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLE9BQU8sSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUM7SUFFRCxNQUFNLENBQUMsS0FBYSxFQUFFLE1BQWM7UUFDbEMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RDLENBQUM7K0dBMUVVLHlCQUF5QjttSEFBekIseUJBQXlCLGNBRnhCLE1BQU07OzRGQUVQLHlCQUF5QjtrQkFIckMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRleHRDb2xvclNlcnZpY2UgfSBmcm9tICcuL3RleHQtY29sb3Iuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIENvbG9yTGlnaHRlbkRhcmtlblNlcnZpY2Uge1xuXG4gIGNvbG9ycyA9IGluamVjdChUZXh0Q29sb3JTZXJ2aWNlKVxuXG4gIC8vIGNvbnN0IGNvbG9yID0gJyMzNDk4ZGInOyAvLyBZb3VyIGNvbG9yXG4gIC8vIGNvbnN0IGxpZ2h0ZXJDb2xvciA9IGxpZ2h0ZW4oY29sb3IsIDAuMik7IC8vIDIwJSBsaWdodGVyXG4gIC8vIGNvbnN0IGRhcmtlckNvbG9yID0gZGFya2VuKGNvbG9yLCAwLjIpOyAgIC8vIDIwJSBkYXJrZXJcblxuICAvLyBjb25zb2xlLmxvZyhsaWdodGVyQ29sb3IsIGRhcmtlckNvbG9yKTtcblxuY29uc3RydWN0b3IoKSB7IH1cblxuICBsaWdodGVuKGNvbG9yOiBzdHJpbmcsIGFtb3VudDogbnVtYmVyKSB7XG5cbiAgICBjb25zdCByZ2IgPSB0aGlzLmNvbG9ycy5maXhDb2xvcihjb2xvcilcbiAgICAvLyBjb25zdCByZ2IgPSBjb2xvci5tYXRjaCgvXFx3XFx3L2cpPy5tYXAoKHgpID0+IHBhcnNlSW50KHgsIDE2KSkgfHwgW107XG5cbiAgICAvLyBDb252ZXJ0IFJHQiB0byBIU0xcbiAgICBsZXQgW3IsIGcsIGJdID0gcmdiLm1hcCgoYykgPT4gYyAvIDI1NSk7XG4gICAgY29uc3QgbWF4ID0gTWF0aC5tYXgociwgZywgYiksXG4gICAgICBtaW4gPSBNYXRoLm1pbihyLCBnLCBiKTtcbiAgICBsZXQgaCA9IDAsXG4gICAgICBzID0gMCxcbiAgICAgIGwgPSAobWF4ICsgbWluKSAvIDI7XG5cbiAgICBpZiAobWF4ICE9PSBtaW4pIHtcbiAgICAgIGNvbnN0IGQgPSBtYXggLSBtaW47XG4gICAgICBzID0gbCA+IDAuNSA/IGQgLyAoMiAtIG1heCAtIG1pbikgOiBkIC8gKG1heCArIG1pbik7XG4gICAgICBzd2l0Y2ggKG1heCkge1xuICAgICAgICBjYXNlIHI6XG4gICAgICAgICAgaCA9IChnIC0gYikgLyBkICsgKGcgPCBiID8gNiA6IDApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGc6XG4gICAgICAgICAgaCA9IChiIC0gcikgLyBkICsgMjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBiOlxuICAgICAgICAgIGggPSAociAtIGcpIC8gZCArIDQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBoIC89IDY7XG4gICAgfVxuXG4gICAgLy8gTW9kaWZ5IHRoZSBsaWdodG5lc3MgYW5kIGNsYW1wIGl0IHRvIFswLCAxXVxuICAgIGwgPSBNYXRoLm1pbigxLCBsICsgYW1vdW50KTtcblxuICAgIC8vIENvbnZlcnQgSFNMIGJhY2sgdG8gUkdCXG4gICAgaWYgKHMgPT09IDApIHtcbiAgICAgIHIgPSBnID0gYiA9IGw7IC8vIGFjaHJvbWF0aWNcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaHVlMnJnYiA9IChwOiBudW1iZXIsIHE6IG51bWJlciwgdDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGlmICh0IDwgMCkgdCArPSAxO1xuICAgICAgICBpZiAodCA+IDEpIHQgLT0gMTtcbiAgICAgICAgaWYgKHQgPCAxIC8gNikgcmV0dXJuIHAgKyAocSAtIHApICogNiAqIHQ7XG4gICAgICAgIGlmICh0IDwgMSAvIDIpIHJldHVybiBxO1xuICAgICAgICBpZiAodCA8IDIgLyAzKSByZXR1cm4gcCArIChxIC0gcCkgKiAoMiAvIDMgLSB0KSAqIDY7XG4gICAgICAgIHJldHVybiBwO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IHEgPSBsIDwgMC41ID8gbCAqICgxICsgcykgOiBsICsgcyAtIGwgKiBzO1xuICAgICAgY29uc3QgcCA9IDIgKiBsIC0gcTtcbiAgICAgIHIgPSBodWUycmdiKHAsIHEsIGggKyAxIC8gMyk7XG4gICAgICBnID0gaHVlMnJnYihwLCBxLCBoKTtcbiAgICAgIGIgPSBodWUycmdiKHAsIHEsIGggLSAxIC8gMyk7XG4gICAgfVxuXG4gICAgLy8gQ29udmVydCBSR0IgYmFjayB0byBoZXhhZGVjaW1hbCBjb2xvclxuICAgIGNvbnN0IHRvSGV4ID0gKHg6IG51bWJlcikgPT5cbiAgICAgIE1hdGgucm91bmQoeCAqIDI1NSlcbiAgICAgICAgLnRvU3RyaW5nKDE2KVxuICAgICAgICAucGFkU3RhcnQoMiwgJzAnKTtcbiAgICByZXR1cm4gYCMke3RvSGV4KHIpfSR7dG9IZXgoZyl9JHt0b0hleChiKX1gO1xuICB9XG5cbiAgZGFya2VuKGNvbG9yOiBzdHJpbmcsIGFtb3VudDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMubGlnaHRlbihjb2xvciwgLWFtb3VudCk7XG4gIH1cblxufVxuIl19
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "./color-conversion.service";
|
|
5
|
+
export class ColorPalletteService {
|
|
6
|
+
constructor(colorConversionService) {
|
|
7
|
+
this.colorConversionService = colorConversionService;
|
|
8
|
+
// define image path
|
|
9
|
+
// this.colorSelectionService.getColorsFromImage('../assets/sample2.jpg')
|
|
10
|
+
// get colors
|
|
11
|
+
// this.colorSelectionService.palette.subscribe(data => this.palette = data)
|
|
12
|
+
// sample html
|
|
13
|
+
// <div *ngFor="let color of palette">
|
|
14
|
+
// <div style="display: flex;">
|
|
15
|
+
// <div
|
|
16
|
+
// class="box"
|
|
17
|
+
// [style.background-color]="color.color"
|
|
18
|
+
// >
|
|
19
|
+
// Color
|
|
20
|
+
// </div>
|
|
21
|
+
// <div
|
|
22
|
+
// class="box"
|
|
23
|
+
// [style.background-color]="color.complementaryColor"
|
|
24
|
+
// >
|
|
25
|
+
// Complementary
|
|
26
|
+
// </div>
|
|
27
|
+
// </div>
|
|
28
|
+
// </div>
|
|
29
|
+
// CSS
|
|
30
|
+
// .box {
|
|
31
|
+
// width: 100px;
|
|
32
|
+
// height: 100px;
|
|
33
|
+
// border: solid thin black;
|
|
34
|
+
// color: black;
|
|
35
|
+
// margin: 4px;
|
|
36
|
+
// padding: 16px;
|
|
37
|
+
// display: flex;
|
|
38
|
+
// flex-wrap: wrap;
|
|
39
|
+
// align-content: center;
|
|
40
|
+
// justify-content: center;
|
|
41
|
+
// }
|
|
42
|
+
this.palette = new BehaviorSubject([]);
|
|
43
|
+
this.palette$ = this.palette.asObservable();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Retrieves a color palette from an image at the specified path.
|
|
47
|
+
*
|
|
48
|
+
* @param imagePath - The path to the image to extract the color palette from.
|
|
49
|
+
* @param colors - The number of colors to include in the palette (default is 3).
|
|
50
|
+
* @returns An observable that emits the generated color palette.
|
|
51
|
+
*/
|
|
52
|
+
getColorsFromImage(imagePath, colors = 3) {
|
|
53
|
+
const image = new Image();
|
|
54
|
+
image.src = imagePath;
|
|
55
|
+
image.onload = () => {
|
|
56
|
+
const data = this.generateColorPalette(image, colors) || [];
|
|
57
|
+
this.palette.next(data);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generates a color palette from an image.
|
|
62
|
+
*
|
|
63
|
+
* @param image - The HTML image element to extract the color palette from.
|
|
64
|
+
* @param colorCount - The number of colors to include in the palette (default is 6).
|
|
65
|
+
* @returns An array of color objects, each with a hex color and a complementary hex color.
|
|
66
|
+
*/
|
|
67
|
+
generateColorPalette(image, colorCount = 6) {
|
|
68
|
+
const canvas = document.createElement("canvas");
|
|
69
|
+
const context = canvas.getContext("2d");
|
|
70
|
+
if (!context)
|
|
71
|
+
return;
|
|
72
|
+
canvas.width = image.width;
|
|
73
|
+
canvas.height = image.height;
|
|
74
|
+
context.drawImage(image, 0, 0);
|
|
75
|
+
// Get the image data
|
|
76
|
+
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
|
77
|
+
const pixels = imageData.data;
|
|
78
|
+
const pixelCount = imageData.width * imageData.height;
|
|
79
|
+
// Build an array of RGB colors
|
|
80
|
+
const colors = [];
|
|
81
|
+
for (let i = 0; i < pixelCount; i++) {
|
|
82
|
+
const offset = i * 4;
|
|
83
|
+
const r = pixels[offset];
|
|
84
|
+
const g = pixels[offset + 1];
|
|
85
|
+
const b = pixels[offset + 2];
|
|
86
|
+
colors.push([r, g, b]);
|
|
87
|
+
}
|
|
88
|
+
// Apply color quantization using k-means clustering
|
|
89
|
+
const quantizedColors = this.kMeansColorQuantization(colors, colorCount);
|
|
90
|
+
// Order colors by luminance
|
|
91
|
+
quantizedColors.sort((color1, color2) => {
|
|
92
|
+
const luminance1 = this.getLuminance(color1);
|
|
93
|
+
const luminance2 = this.getLuminance(color2);
|
|
94
|
+
return luminance2 - luminance1;
|
|
95
|
+
});
|
|
96
|
+
const palette = quantizedColors.map((color) => {
|
|
97
|
+
const complementaryColor = color.map((component) => 255 - component);
|
|
98
|
+
const hexColor = this.colorConversionService.rgbToHex(color);
|
|
99
|
+
const hexComplementaryColor = this.colorConversionService.rgbToHex(complementaryColor);
|
|
100
|
+
return { color: hexColor, complementaryColor: hexComplementaryColor };
|
|
101
|
+
});
|
|
102
|
+
return palette;
|
|
103
|
+
}
|
|
104
|
+
getLuminance(color) {
|
|
105
|
+
const [r, g, b] = color;
|
|
106
|
+
return 0.299 * r + 0.587 * g + 0.114 * b;
|
|
107
|
+
}
|
|
108
|
+
calculateColorDistance(color1, color2) {
|
|
109
|
+
const [r1, g1, b1] = color1;
|
|
110
|
+
const [r2, g2, b2] = color2;
|
|
111
|
+
const dr = r2 - r1;
|
|
112
|
+
const dg = g2 - g1;
|
|
113
|
+
const db = b2 - b1;
|
|
114
|
+
return Math.sqrt(dr * dr + dg * dg + db * db);
|
|
115
|
+
}
|
|
116
|
+
calculateMeanColor(colors) {
|
|
117
|
+
let sumR = 0;
|
|
118
|
+
let sumG = 0;
|
|
119
|
+
let sumB = 0;
|
|
120
|
+
for (let i = 0; i < colors.length; i++) {
|
|
121
|
+
const [r, g, b] = colors[i];
|
|
122
|
+
sumR += r;
|
|
123
|
+
sumG += g;
|
|
124
|
+
sumB += b;
|
|
125
|
+
}
|
|
126
|
+
const meanR = Math.round(sumR / colors.length);
|
|
127
|
+
const meanG = Math.round(sumG / colors.length);
|
|
128
|
+
const meanB = Math.round(sumB / colors.length);
|
|
129
|
+
return [meanR, meanG, meanB];
|
|
130
|
+
}
|
|
131
|
+
kMeansColorQuantization(colors, k) {
|
|
132
|
+
let clusterCenters = [];
|
|
133
|
+
for (let i = 0; i < k; i++) {
|
|
134
|
+
const randomColor = colors[Math.floor(Math.random() * colors.length)];
|
|
135
|
+
clusterCenters.push(randomColor);
|
|
136
|
+
}
|
|
137
|
+
let clusters = [];
|
|
138
|
+
for (let i = 0; i < colors.length; i++) {
|
|
139
|
+
const color = colors[i];
|
|
140
|
+
let minDistance = Infinity;
|
|
141
|
+
let nearestCenter = null;
|
|
142
|
+
for (let j = 0; j < clusterCenters.length; j++) {
|
|
143
|
+
const center = clusterCenters[j];
|
|
144
|
+
const distance = this.calculateColorDistance(color, center);
|
|
145
|
+
if (distance < minDistance) {
|
|
146
|
+
minDistance = distance;
|
|
147
|
+
nearestCenter = center;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
clusters.push({ color, center: nearestCenter });
|
|
151
|
+
}
|
|
152
|
+
let updatedCenters = [];
|
|
153
|
+
for (let i = 0; i < clusterCenters.length; i++) {
|
|
154
|
+
const center = clusterCenters[i];
|
|
155
|
+
const clusterColors = clusters.filter(c => c.center === center).map(c => c.color);
|
|
156
|
+
if (clusterColors.length > 0) {
|
|
157
|
+
const updatedCenter = this.calculateMeanColor(clusterColors);
|
|
158
|
+
updatedCenters.push(updatedCenter);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return updatedCenters;
|
|
162
|
+
}
|
|
163
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorPalletteService, deps: [{ token: i1.ColorConversionService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
164
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorPalletteService, providedIn: 'root' }); }
|
|
165
|
+
}
|
|
166
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColorPalletteService, decorators: [{
|
|
167
|
+
type: Injectable,
|
|
168
|
+
args: [{
|
|
169
|
+
providedIn: 'root'
|
|
170
|
+
}]
|
|
171
|
+
}], ctorParameters: function () { return [{ type: i1.ColorConversionService }]; } });
|
|
172
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItcGFsbGV0dGUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbG9yLXV0aWwtaGVscGVycy9zcmMvbGliL2NvbG9yLXBhbGxldHRlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUMxQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFBOzs7QUFNdEMsTUFBTSxPQUFPLG9CQUFvQjtJQTJDL0IsWUFDVSxzQkFBOEM7UUFBOUMsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3QjtRQTFDeEQsb0JBQW9CO1FBQ3BCLHlFQUF5RTtRQUV6RSxhQUFhO1FBQ2IsNEVBQTRFO1FBRTVFLGNBQWM7UUFDZCx3Q0FBd0M7UUFDeEMsbUNBQW1DO1FBQ25DLGVBQWU7UUFDZiwwQkFBMEI7UUFDMUIscURBQXFEO1FBQ3JELFlBQVk7UUFDWixnQkFBZ0I7UUFDaEIsaUJBQWlCO1FBQ2pCLGVBQWU7UUFDZiwwQkFBMEI7UUFDMUIsa0VBQWtFO1FBQ2xFLFlBQVk7UUFDWix3QkFBd0I7UUFDeEIsaUJBQWlCO1FBQ2pCLGFBQWE7UUFDYixTQUFTO1FBRVQsTUFBTTtRQUNOLFdBQVc7UUFDWCxvQkFBb0I7UUFDcEIscUJBQXFCO1FBQ3JCLGdDQUFnQztRQUNoQyxvQkFBb0I7UUFDcEIsbUJBQW1CO1FBQ25CLHFCQUFxQjtRQUNyQixxQkFBcUI7UUFDckIsdUJBQXVCO1FBQ3ZCLDZCQUE2QjtRQUM3QiwrQkFBK0I7UUFDL0IsSUFBSTtRQUVJLFlBQU8sR0FBRyxJQUFJLGVBQWUsQ0FBa0QsRUFBRSxDQUFDLENBQUE7UUFDMUYsYUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLENBQUE7SUFJbEMsQ0FBQztJQUVMOzs7Ozs7T0FNRztJQUNILGtCQUFrQixDQUFDLFNBQWlCLEVBQUUsTUFBTSxHQUFHLENBQUM7UUFDOUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxQixLQUFLLENBQUMsR0FBRyxHQUFHLFNBQVMsQ0FBQztRQUV0QixLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRTtZQUNsQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM1RCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQixDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsb0JBQW9CLENBQUMsS0FBdUIsRUFBRSxVQUFVLEdBQUcsQ0FBQztRQUMxRCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEMsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRXJCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUMzQixNQUFNLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDN0IsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRS9CLHFCQUFxQjtRQUNyQixNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUUsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztRQUM5QixNQUFNLFVBQVUsR0FBRyxTQUFTLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFFdEQsK0JBQStCO1FBQy9CLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNsQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ25DLE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDN0IsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztZQUM3QixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ3hCO1FBRUQsb0RBQW9EO1FBQ3BELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFekUsNEJBQTRCO1FBQzVCLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDdEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzdDLE9BQU8sVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUNqQyxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUM1QyxNQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxTQUFTLENBQUMsQ0FBQztZQUNyRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzdELE1BQU0scUJBQXFCLEdBQ3pCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUMzRCxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVPLFlBQVksQ0FBQyxLQUFlO1FBQ2xDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQTtRQUN2QixPQUFPLEtBQUssR0FBRyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFBO0lBQzFDLENBQUM7SUFFTyxzQkFBc0IsQ0FBQyxNQUFnQixFQUFFLE1BQWdCO1FBQy9ELE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQTtRQUMzQixNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUE7UUFDM0IsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQTtRQUNsQixNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFBO1FBQ2xCLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUE7UUFDbEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUE7SUFDL0MsQ0FBQztJQUVPLGtCQUFrQixDQUFDLE1BQWtCO1FBQzNDLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQTtRQUNaLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQTtRQUNaLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQTtRQUNaLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3RDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUMzQixJQUFJLElBQUksQ0FBQyxDQUFBO1lBQ1QsSUFBSSxJQUFJLENBQUMsQ0FBQTtZQUNULElBQUksSUFBSSxDQUFDLENBQUE7U0FDVjtRQUNELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUM5QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDOUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQzlDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQzlCLENBQUM7SUFFTyx1QkFBdUIsQ0FBQyxNQUFrQixFQUFFLENBQVM7UUFDM0QsSUFBSSxjQUFjLEdBQUcsRUFBRSxDQUFBO1FBQ3ZCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDMUIsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO1lBQ3JFLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7U0FDakM7UUFFRCxJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUE7UUFDakIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDdEMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQ3ZCLElBQUksV0FBVyxHQUFHLFFBQVEsQ0FBQTtZQUMxQixJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUE7WUFDeEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQzlDLE1BQU0sTUFBTSxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtnQkFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQTtnQkFDM0QsSUFBSSxRQUFRLEdBQUcsV0FBVyxFQUFFO29CQUMxQixXQUFXLEdBQUcsUUFBUSxDQUFBO29CQUN0QixhQUFhLEdBQUcsTUFBTSxDQUFBO2lCQUN2QjthQUNGO1lBQ0QsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQTtTQUNoRDtRQUVELElBQUksY0FBYyxHQUFHLEVBQUUsQ0FBQTtRQUN2QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUM5QyxNQUFNLE1BQU0sR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUE7WUFDaEMsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ2pGLElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQzVCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLENBQUMsQ0FBQTtnQkFDNUQsY0FBYyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTthQUNuQztTQUNGO1FBRUQsT0FBTyxjQUFjLENBQUE7SUFDdkIsQ0FBQzsrR0FyTFUsb0JBQW9CO21IQUFwQixvQkFBb0IsY0FGbkIsTUFBTTs7NEZBRVAsb0JBQW9CO2tCQUhoQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xyXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJ1xyXG5pbXBvcnQgeyBDb2xvckNvbnZlcnNpb25TZXJ2aWNlIH0gZnJvbSAnLi9jb2xvci1jb252ZXJzaW9uLnNlcnZpY2UnXHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDb2xvclBhbGxldHRlU2VydmljZSB7XHJcblxyXG4gIC8vIGRlZmluZSBpbWFnZSBwYXRoXHJcbiAgLy8gdGhpcy5jb2xvclNlbGVjdGlvblNlcnZpY2UuZ2V0Q29sb3JzRnJvbUltYWdlKCcuLi9hc3NldHMvc2FtcGxlMi5qcGcnKVxyXG5cclxuICAvLyBnZXQgY29sb3JzXHJcbiAgLy8gdGhpcy5jb2xvclNlbGVjdGlvblNlcnZpY2UucGFsZXR0ZS5zdWJzY3JpYmUoZGF0YSA9PiB0aGlzLnBhbGV0dGUgPSBkYXRhKVxyXG5cclxuICAvLyBzYW1wbGUgaHRtbFxyXG4gIC8vICAgPGRpdiAqbmdGb3I9XCJsZXQgY29sb3Igb2YgcGFsZXR0ZVwiPlxyXG4gIC8vICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDtcIj5cclxuICAvLyAgICAgICAgIDxkaXZcclxuICAvLyAgICAgICAgICAgICBjbGFzcz1cImJveFwiXHJcbiAgLy8gICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtY29sb3JdPVwiY29sb3IuY29sb3JcIlxyXG4gIC8vICAgICAgICAgPlxyXG4gIC8vICAgICAgICAgQ29sb3JcclxuICAvLyAgICAgICAgIDwvZGl2PlxyXG4gIC8vICAgICAgICAgPGRpdlxyXG4gIC8vICAgICAgICAgICAgIGNsYXNzPVwiYm94XCJcclxuICAvLyAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1jb2xvcl09XCJjb2xvci5jb21wbGVtZW50YXJ5Q29sb3JcIlxyXG4gIC8vICAgICAgICAgPlxyXG4gIC8vICAgICAgICAgQ29tcGxlbWVudGFyeVxyXG4gIC8vICAgICAgICAgPC9kaXY+XHJcbiAgLy8gICAgIDwvZGl2PlxyXG4gIC8vIDwvZGl2PlxyXG5cclxuICAvLyBDU1NcclxuICAvLyAgIC5ib3gge1xyXG4gIC8vICAgICB3aWR0aDogMTAwcHg7XHJcbiAgLy8gICAgIGhlaWdodDogMTAwcHg7XHJcbiAgLy8gICAgIGJvcmRlcjogc29saWQgdGhpbiBibGFjaztcclxuICAvLyAgICAgY29sb3I6IGJsYWNrO1xyXG4gIC8vICAgICBtYXJnaW46IDRweDtcclxuICAvLyAgICAgcGFkZGluZzogMTZweDtcclxuICAvLyAgICAgZGlzcGxheTogZmxleDtcclxuICAvLyAgICAgZmxleC13cmFwOiB3cmFwO1xyXG4gIC8vICAgICBhbGlnbi1jb250ZW50OiBjZW50ZXI7XHJcbiAgLy8gICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xyXG4gIC8vIH1cclxuXHJcbiAgcHJpdmF0ZSBwYWxldHRlID0gbmV3IEJlaGF2aW9yU3ViamVjdDx7IGNvbG9yOiBzdHJpbmcsIGNvbXBsZW1lbnRhcnlDb2xvcjogc3RyaW5nIH1bXT4oW10pXHJcbiAgcGFsZXR0ZSQgPSB0aGlzLnBhbGV0dGUuYXNPYnNlcnZhYmxlKClcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGNvbG9yQ29udmVyc2lvblNlcnZpY2U6IENvbG9yQ29udmVyc2lvblNlcnZpY2VcclxuICApIHsgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXRyaWV2ZXMgYSBjb2xvciBwYWxldHRlIGZyb20gYW4gaW1hZ2UgYXQgdGhlIHNwZWNpZmllZCBwYXRoLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGltYWdlUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBpbWFnZSB0byBleHRyYWN0IHRoZSBjb2xvciBwYWxldHRlIGZyb20uXHJcbiAgICogQHBhcmFtIGNvbG9ycyAtIFRoZSBudW1iZXIgb2YgY29sb3JzIHRvIGluY2x1ZGUgaW4gdGhlIHBhbGV0dGUgKGRlZmF1bHQgaXMgMykuXHJcbiAgICogQHJldHVybnMgQW4gb2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHRoZSBnZW5lcmF0ZWQgY29sb3IgcGFsZXR0ZS5cclxuICAgKi9cclxuICBnZXRDb2xvcnNGcm9tSW1hZ2UoaW1hZ2VQYXRoOiBzdHJpbmcsIGNvbG9ycyA9IDMpIHtcclxuICAgIGNvbnN0IGltYWdlID0gbmV3IEltYWdlKCk7XHJcbiAgICBpbWFnZS5zcmMgPSBpbWFnZVBhdGg7XHJcblxyXG4gICAgaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5nZW5lcmF0ZUNvbG9yUGFsZXR0ZShpbWFnZSwgY29sb3JzKSB8fCBbXTtcclxuICAgICAgdGhpcy5wYWxldHRlLm5leHQoZGF0YSk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2VuZXJhdGVzIGEgY29sb3IgcGFsZXR0ZSBmcm9tIGFuIGltYWdlLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGltYWdlIC0gVGhlIEhUTUwgaW1hZ2UgZWxlbWVudCB0byBleHRyYWN0IHRoZSBjb2xvciBwYWxldHRlIGZyb20uXHJcbiAgICogQHBhcmFtIGNvbG9yQ291bnQgLSBUaGUgbnVtYmVyIG9mIGNvbG9ycyB0byBpbmNsdWRlIGluIHRoZSBwYWxldHRlIChkZWZhdWx0IGlzIDYpLlxyXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGNvbG9yIG9iamVjdHMsIGVhY2ggd2l0aCBhIGhleCBjb2xvciBhbmQgYSBjb21wbGVtZW50YXJ5IGhleCBjb2xvci5cclxuICAgKi9cclxuICBnZW5lcmF0ZUNvbG9yUGFsZXR0ZShpbWFnZTogSFRNTEltYWdlRWxlbWVudCwgY29sb3JDb3VudCA9IDYpIHtcclxuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XHJcbiAgICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuXHJcbiAgICBpZiAoIWNvbnRleHQpIHJldHVybjtcclxuXHJcbiAgICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcclxuICAgIGNhbnZhcy5oZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XHJcbiAgICBjb250ZXh0LmRyYXdJbWFnZShpbWFnZSwgMCwgMCk7XHJcblxyXG4gICAgLy8gR2V0IHRoZSBpbWFnZSBkYXRhXHJcbiAgICBjb25zdCBpbWFnZURhdGEgPSBjb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xyXG4gICAgY29uc3QgcGl4ZWxzID0gaW1hZ2VEYXRhLmRhdGE7XHJcbiAgICBjb25zdCBwaXhlbENvdW50ID0gaW1hZ2VEYXRhLndpZHRoICogaW1hZ2VEYXRhLmhlaWdodDtcclxuXHJcbiAgICAvLyBCdWlsZCBhbiBhcnJheSBvZiBSR0IgY29sb3JzXHJcbiAgICBjb25zdCBjb2xvcnMgPSBbXTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGl4ZWxDb3VudDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IG9mZnNldCA9IGkgKiA0O1xyXG4gICAgICBjb25zdCByID0gcGl4ZWxzW29mZnNldF07XHJcbiAgICAgIGNvbnN0IGcgPSBwaXhlbHNbb2Zmc2V0ICsgMV07XHJcbiAgICAgIGNvbnN0IGIgPSBwaXhlbHNbb2Zmc2V0ICsgMl07XHJcbiAgICAgIGNvbG9ycy5wdXNoKFtyLCBnLCBiXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQXBwbHkgY29sb3IgcXVhbnRpemF0aW9uIHVzaW5nIGstbWVhbnMgY2x1c3RlcmluZ1xyXG4gICAgY29uc3QgcXVhbnRpemVkQ29sb3JzID0gdGhpcy5rTWVhbnNDb2xvclF1YW50aXphdGlvbihjb2xvcnMsIGNvbG9yQ291bnQpO1xyXG5cclxuICAgIC8vIE9yZGVyIGNvbG9ycyBieSBsdW1pbmFuY2VcclxuICAgIHF1YW50aXplZENvbG9ycy5zb3J0KChjb2xvcjEsIGNvbG9yMikgPT4ge1xyXG4gICAgICBjb25zdCBsdW1pbmFuY2UxID0gdGhpcy5nZXRMdW1pbmFuY2UoY29sb3IxKTtcclxuICAgICAgY29uc3QgbHVtaW5hbmNlMiA9IHRoaXMuZ2V0THVtaW5hbmNlKGNvbG9yMik7XHJcbiAgICAgIHJldHVybiBsdW1pbmFuY2UyIC0gbHVtaW5hbmNlMTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IHBhbGV0dGUgPSBxdWFudGl6ZWRDb2xvcnMubWFwKChjb2xvcikgPT4ge1xyXG4gICAgICBjb25zdCBjb21wbGVtZW50YXJ5Q29sb3IgPSBjb2xvci5tYXAoKGNvbXBvbmVudCkgPT4gMjU1IC0gY29tcG9uZW50KTtcclxuICAgICAgY29uc3QgaGV4Q29sb3IgPSB0aGlzLmNvbG9yQ29udmVyc2lvblNlcnZpY2UucmdiVG9IZXgoY29sb3IpO1xyXG4gICAgICBjb25zdCBoZXhDb21wbGVtZW50YXJ5Q29sb3IgPVxyXG4gICAgICAgIHRoaXMuY29sb3JDb252ZXJzaW9uU2VydmljZS5yZ2JUb0hleChjb21wbGVtZW50YXJ5Q29sb3IpO1xyXG4gICAgICByZXR1cm4geyBjb2xvcjogaGV4Q29sb3IsIGNvbXBsZW1lbnRhcnlDb2xvcjogaGV4Q29tcGxlbWVudGFyeUNvbG9yIH07XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcGFsZXR0ZTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0THVtaW5hbmNlKGNvbG9yOiBudW1iZXJbXSkge1xyXG4gICAgY29uc3QgW3IsIGcsIGJdID0gY29sb3JcclxuICAgIHJldHVybiAwLjI5OSAqIHIgKyAwLjU4NyAqIGcgKyAwLjExNCAqIGJcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2FsY3VsYXRlQ29sb3JEaXN0YW5jZShjb2xvcjE6IG51bWJlcltdLCBjb2xvcjI6IG51bWJlcltdKSB7XHJcbiAgICBjb25zdCBbcjEsIGcxLCBiMV0gPSBjb2xvcjFcclxuICAgIGNvbnN0IFtyMiwgZzIsIGIyXSA9IGNvbG9yMlxyXG4gICAgY29uc3QgZHIgPSByMiAtIHIxXHJcbiAgICBjb25zdCBkZyA9IGcyIC0gZzFcclxuICAgIGNvbnN0IGRiID0gYjIgLSBiMVxyXG4gICAgcmV0dXJuIE1hdGguc3FydChkciAqIGRyICsgZGcgKiBkZyArIGRiICogZGIpXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNhbGN1bGF0ZU1lYW5Db2xvcihjb2xvcnM6IG51bWJlcltdW10pIHtcclxuICAgIGxldCBzdW1SID0gMFxyXG4gICAgbGV0IHN1bUcgPSAwXHJcbiAgICBsZXQgc3VtQiA9IDBcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29sb3JzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IFtyLCBnLCBiXSA9IGNvbG9yc1tpXVxyXG4gICAgICBzdW1SICs9IHJcclxuICAgICAgc3VtRyArPSBnXHJcbiAgICAgIHN1bUIgKz0gYlxyXG4gICAgfVxyXG4gICAgY29uc3QgbWVhblIgPSBNYXRoLnJvdW5kKHN1bVIgLyBjb2xvcnMubGVuZ3RoKVxyXG4gICAgY29uc3QgbWVhbkcgPSBNYXRoLnJvdW5kKHN1bUcgLyBjb2xvcnMubGVuZ3RoKVxyXG4gICAgY29uc3QgbWVhbkIgPSBNYXRoLnJvdW5kKHN1bUIgLyBjb2xvcnMubGVuZ3RoKVxyXG4gICAgcmV0dXJuIFttZWFuUiwgbWVhbkcsIG1lYW5CXVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBrTWVhbnNDb2xvclF1YW50aXphdGlvbihjb2xvcnM6IG51bWJlcltdW10sIGs6IG51bWJlcikge1xyXG4gICAgbGV0IGNsdXN0ZXJDZW50ZXJzID0gW11cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgazsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IHJhbmRvbUNvbG9yID0gY29sb3JzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGNvbG9ycy5sZW5ndGgpXVxyXG4gICAgICBjbHVzdGVyQ2VudGVycy5wdXNoKHJhbmRvbUNvbG9yKVxyXG4gICAgfVxyXG5cclxuICAgIGxldCBjbHVzdGVycyA9IFtdXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbG9ycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBjb2xvciA9IGNvbG9yc1tpXVxyXG4gICAgICBsZXQgbWluRGlzdGFuY2UgPSBJbmZpbml0eVxyXG4gICAgICBsZXQgbmVhcmVzdENlbnRlciA9IG51bGxcclxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjbHVzdGVyQ2VudGVycy5sZW5ndGg7IGorKykge1xyXG4gICAgICAgIGNvbnN0IGNlbnRlciA9IGNsdXN0ZXJDZW50ZXJzW2pdXHJcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSB0aGlzLmNhbGN1bGF0ZUNvbG9yRGlzdGFuY2UoY29sb3IsIGNlbnRlcilcclxuICAgICAgICBpZiAoZGlzdGFuY2UgPCBtaW5EaXN0YW5jZSkge1xyXG4gICAgICAgICAgbWluRGlzdGFuY2UgPSBkaXN0YW5jZVxyXG4gICAgICAgICAgbmVhcmVzdENlbnRlciA9IGNlbnRlclxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBjbHVzdGVycy5wdXNoKHsgY29sb3IsIGNlbnRlcjogbmVhcmVzdENlbnRlciB9KVxyXG4gICAgfVxyXG5cclxuICAgIGxldCB1cGRhdGVkQ2VudGVycyA9IFtdXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNsdXN0ZXJDZW50ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IGNlbnRlciA9IGNsdXN0ZXJDZW50ZXJzW2ldXHJcbiAgICAgIGNvbnN0IGNsdXN0ZXJDb2xvcnMgPSBjbHVzdGVycy5maWx0ZXIoYyA9PiBjLmNlbnRlciA9PT0gY2VudGVyKS5tYXAoYyA9PiBjLmNvbG9yKVxyXG4gICAgICBpZiAoY2x1c3RlckNvbG9ycy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgY29uc3QgdXBkYXRlZENlbnRlciA9IHRoaXMuY2FsY3VsYXRlTWVhbkNvbG9yKGNsdXN0ZXJDb2xvcnMpXHJcbiAgICAgICAgdXBkYXRlZENlbnRlcnMucHVzaCh1cGRhdGVkQ2VudGVyKVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHVwZGF0ZWRDZW50ZXJzXHJcbiAgfVxyXG5cclxufVxyXG4iXX0=
|