color-util-helpers 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/ng-package.json +8 -0
  2. package/package.json +2 -15
  3. package/src/lib/assets/picture.webp +0 -0
  4. package/src/lib/color-conversion.service.spec.ts +54 -0
  5. package/src/lib/color-conversion.service.ts +35 -0
  6. package/src/lib/color-extractor.directive.spec.ts +49 -0
  7. package/src/lib/color-extractor.directive.ts +28 -0
  8. package/src/lib/color-grab.directive.ts +204 -0
  9. package/src/lib/color-lighten-darken.service.spec.ts +61 -0
  10. package/src/lib/color-lighten-darken.service.ts +83 -0
  11. package/src/lib/color-pallette.service.spec.ts +85 -0
  12. package/src/lib/color-pallette.service.ts +191 -0
  13. package/src/lib/color-scheme.service.ts +123 -0
  14. package/src/lib/color-utilities-demo/color-utilities-demo.component.css +12 -0
  15. package/src/lib/color-utilities-demo/color-utilities-demo.component.html +109 -0
  16. package/src/lib/color-utilities-demo/color-utilities-demo.component.ts +57 -0
  17. package/src/lib/color-utils.module.ts +27 -0
  18. package/src/lib/text-color.service.spec.ts +75 -0
  19. package/src/lib/text-color.service.ts +101 -0
  20. package/{public-api.d.ts → src/public-api.ts} +6 -0
  21. package/tsconfig.lib.json +32 -0
  22. package/tsconfig.lib.prod.json +10 -0
  23. package/tsconfig.spec.json +14 -0
  24. package/color-util-helpers-1.0.6.tgz +0 -0
  25. package/esm2022/color-util-helpers.mjs +0 -5
  26. package/esm2022/lib/color-conversion.service.mjs +0 -39
  27. package/esm2022/lib/color-extractor.directive.mjs +0 -37
  28. package/esm2022/lib/color-grab.directive.mjs +0 -185
  29. package/esm2022/lib/color-lighten-darken.service.mjs +0 -79
  30. package/esm2022/lib/color-pallette.service.mjs +0 -172
  31. package/esm2022/lib/color-scheme.service.mjs +0 -113
  32. package/esm2022/lib/color-utilities-demo/color-utilities-demo.component.mjs +0 -41
  33. package/esm2022/lib/color-utils.module.mjs +0 -38
  34. package/esm2022/lib/text-color.service.mjs +0 -79
  35. package/esm2022/public-api.mjs +0 -13
  36. package/fesm2022/color-util-helpers.mjs +0 -767
  37. package/fesm2022/color-util-helpers.mjs.map +0 -1
  38. package/index.d.ts +0 -5
  39. package/lib/color-conversion.service.d.ts +0 -8
  40. package/lib/color-extractor.directive.d.ts +0 -13
  41. package/lib/color-grab.directive.d.ts +0 -31
  42. package/lib/color-lighten-darken.service.d.ts +0 -10
  43. package/lib/color-pallette.service.d.ts +0 -36
  44. package/lib/color-scheme.service.d.ts +0 -45
  45. package/lib/color-utilities-demo/color-utilities-demo.component.d.ts +0 -34
  46. package/lib/color-utils.module.d.ts +0 -12
  47. package/lib/text-color.service.d.ts +0 -18
@@ -0,0 +1,101 @@
1
+ import { Injectable } from '@angular/core'
2
+ import { ColorConversionService } from './color-conversion.service'
3
+
4
+ @Injectable({
5
+ providedIn: 'root'
6
+ })
7
+ export class TextColorService {
8
+
9
+ constructor(
10
+ private colorConversionService: ColorConversionService
11
+ ) {}
12
+
13
+ textColorForBgColor(bgColor: string, lightColor: string, darkColor: string) {
14
+
15
+ const UIColors = this.fixColor(bgColor)
16
+
17
+ const r = UIColors[0]
18
+ const g = UIColors[1]
19
+ const b = UIColors[2]
20
+
21
+ return ((r*0.299 + g*0.587 + b*0.114) > 149) ? darkColor : lightColor;
22
+
23
+ }
24
+
25
+ darkerColor(color1: string, color2: string) {
26
+ return this.isColorDarker(color1, color2) ? color1 : color2;
27
+ }
28
+
29
+ isColorDarker(color1: string, color2: string) {
30
+
31
+ const newColor1 = this.fixColor(color1);
32
+ const newColor2 = this.fixColor(color2);
33
+
34
+ const luminance1 = this.calculateLuminance(newColor1[0], newColor1[1], newColor1[2]);
35
+ const luminance2 = this.calculateLuminance(newColor2[0], newColor2[1], newColor2[2]);
36
+
37
+ return luminance1 < luminance2;
38
+ }
39
+
40
+
41
+ lighterColor(color1: string, color2: string): string {
42
+ return (this.isColorLighter(color1,color2)) ? color1 : color2;
43
+ }
44
+
45
+ isColorLighter(color1: string, color2: string) {
46
+
47
+ const newColor1 = this.fixColor(color1);
48
+ const newColor2 = this.fixColor(color2);
49
+
50
+ const luminance1 = this.calculateLuminance(newColor1[0], newColor1[1], newColor1[2]);
51
+ const luminance2 = this.calculateLuminance(newColor2[0], newColor2[1], newColor2[2]);
52
+
53
+ return (luminance1 > luminance2)
54
+
55
+ }
56
+
57
+ calculateLuminance(r: number, g: number, b: number): number {
58
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
59
+ }
60
+
61
+ fixColor(color: string) {
62
+ // Remove leading hash if present
63
+ const sanitizedColor = color.startsWith('#') ? color.slice(1) : color;
64
+
65
+ // Validate if the color is a valid hex (3 or 6 characters)
66
+ if (!this.isValidHex(sanitizedColor)) {
67
+ return this.parseRgb(sanitizedColor); // If not hex, attempt to parse as RGB
68
+ }
69
+
70
+ // Convert hex to RGB
71
+ const rgb = this.hexToRgb(sanitizedColor);
72
+ return rgb;
73
+ }
74
+
75
+ // Helper function to validate if a string is a valid 3 or 6 digit hex code
76
+ isValidHex(color: string): boolean {
77
+ const hexRegex = /^[A-Fa-f0-9]{3}$|^[A-Fa-f0-9]{6}$/i;
78
+ return hexRegex.test(color);
79
+ }
80
+
81
+ // Helper function to convert a 3 or 6 digit hex color to RGB
82
+ hexToRgb(hex: string): number[] {
83
+ if (hex.length === 3) {
84
+ hex = hex.split('').map(c => c + c).join(''); // Expand shorthand hex to full
85
+ }
86
+
87
+ return [
88
+ parseInt(hex.slice(0, 2), 16),
89
+ parseInt(hex.slice(2, 4), 16),
90
+ parseInt(hex.slice(4, 6), 16),
91
+ ];
92
+ }
93
+
94
+ // Helper function to parse an RGB string (e.g., rgb(255, 0, 0)) into an array
95
+ parseRgb(rgb: string): number[] {
96
+ const match = rgb.match(/\d+/g);
97
+ return match ? match.map(num => parseInt(num)) : [];
98
+ }
99
+
100
+
101
+ }
@@ -1,9 +1,15 @@
1
+ /*
2
+ * Public API Surface of color-utils
3
+ */
4
+
1
5
  export * from './lib/color-utils.module';
2
6
  export * from './lib/color-utilities-demo/color-utilities-demo.component';
7
+
3
8
  export * from './lib/color-conversion.service';
4
9
  export * from './lib/color-extractor.directive';
5
10
  export * from './lib/color-grab.directive';
6
11
  export * from './lib/color-pallette.service';
7
12
  export * from './lib/text-color.service';
13
+
8
14
  export * from './lib/color-scheme.service';
9
15
  export * from './lib/color-lighten-darken.service';
@@ -0,0 +1,32 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "../../tsconfig.json",
4
+ "compilerOptions": {
5
+ "outDir": "../../dist/color-utils",
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "inlineSources": true,
9
+ "types": [],
10
+ "baseUrl": "./",
11
+ "paths": {
12
+ "@angular/*": ["node_modules/@angular/*"],
13
+ "color-utils": ["node_modules/color-utils"],
14
+ },
15
+ "target": "ES2022",
16
+ "lib": [
17
+ "dom",
18
+ "ES2022"
19
+ ]
20
+ },
21
+ "angularCompilerOptions": {
22
+ "skipTemplateCodegen": true,
23
+ "strictMetadataEmit": true,
24
+ "enableResourceInlining": true,
25
+ "strictInjectionParameters": true,
26
+ "strictTemplates": true
27
+ },
28
+ "exclude": [
29
+ "src/test.ts",
30
+ "**/*.spec.ts"
31
+ ]
32
+ }
@@ -0,0 +1,10 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "./tsconfig.lib.json",
4
+ "compilerOptions": {
5
+ "declarationMap": false
6
+ },
7
+ "angularCompilerOptions": {
8
+ "compilationMode": "partial"
9
+ }
10
+ }
@@ -0,0 +1,14 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "../../tsconfig.json",
4
+ "compilerOptions": {
5
+ "outDir": "../../out-tsc/spec",
6
+ "types": [
7
+ "jasmine"
8
+ ]
9
+ },
10
+ "include": [
11
+ "**/*.spec.ts",
12
+ "**/*.d.ts"
13
+ ]
14
+ }
Binary file
@@ -1,5 +0,0 @@
1
- /**
2
- * Generated bundle index. Do not edit.
3
- */
4
- export * from './public-api';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItdXRpbC1oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvY29sb3ItdXRpbHMvc3JjL2NvbG9yLXV0aWwtaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsY0FBYyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHZW5lcmF0ZWQgYnVuZGxlIGluZGV4LiBEbyBub3QgZWRpdC5cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL3B1YmxpYy1hcGknO1xuIl19
@@ -1,39 +0,0 @@
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItY29udmVyc2lvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29sb3ItdXRpbHMvc3JjL2xpYi9jb2xvci1jb252ZXJzaW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFLM0MsTUFBTSxPQUFPLHNCQUFzQjtJQUhuQztRQWVVLG1CQUFjLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtZQUNyQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUM1QyxDQUFDLENBQUE7S0FjRjtJQTNCQyxRQUFRLENBQUMsR0FBb0I7UUFDM0IsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssR0FBRyxHQUFHLENBQUM7WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUUvRixNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDdEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsT0FBTyxHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbEMsQ0FBQztJQU9ELFFBQVEsQ0FBQyxHQUE4QjtRQUNyQyxJQUFJLEdBQUcsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLFNBQVM7WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUVqRCxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDM0MsTUFBTSxNQUFNLEdBQUcsMkNBQTJDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXJFLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNkLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3ZCLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3ZCLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO1NBQ3hCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNULENBQUM7K0dBNUJVLHNCQUFzQjttSEFBdEIsc0JBQXNCLGNBRnJCLE1BQU07OzRGQUVQLHNCQUFzQjtrQkFIbEMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDb2xvckNvbnZlcnNpb25TZXJ2aWNlIHtcclxuXHJcbiAgcmdiVG9IZXgocmdiOiBudW1iZXJbXSB8IG51bGwpOiBzdHJpbmcge1xyXG4gICAgaWYgKHJnYiA9PT0gbnVsbCB8fCByZ2IubGVuZ3RoICE9PSAzIHx8IHJnYi5zb21lKHZhbHVlID0+IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDI1NSkpIHJldHVybiAnJztcclxuXHJcbiAgICBjb25zdCBbciwgZywgYl0gPSByZ2I7XHJcbiAgICBjb25zdCBoZXhSID0gdGhpcy5jb21wb25lbnRUb0hleChyKTtcclxuICAgIGNvbnN0IGhleEcgPSB0aGlzLmNvbXBvbmVudFRvSGV4KGcpO1xyXG4gICAgY29uc3QgaGV4QiA9IHRoaXMuY29tcG9uZW50VG9IZXgoYik7XHJcbiAgICByZXR1cm4gXCIjXCIgKyBoZXhSICsgaGV4RyArIGhleEI7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNvbXBvbmVudFRvSGV4ID0gKGM6IG51bWJlcikgPT4ge1xyXG4gICAgY29uc3QgaGV4ID0gYy50b1N0cmluZygxNik7XHJcbiAgICByZXR1cm4gaGV4Lmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgaGV4IDogaGV4O1xyXG4gIH1cclxuXHJcbiAgaGV4VG9SZ2IoaGV4OiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogbnVtYmVyW10ge1xyXG4gICAgaWYgKGhleCA9PT0gbnVsbCB8fCBoZXggPT09IHVuZGVmaW5lZCkgcmV0dXJuIFtdO1xyXG5cclxuICAgIGhleCA9IChoZXgubGVuZ3RoID09PSAzKSA/IGhleCArIGhleCA6IGhleDtcclxuICAgIGNvbnN0IHJlc3VsdCA9IC9eIz8oW2EtZlxcZF17Mn0pKFthLWZcXGRdezJ9KShbYS1mXFxkXXsyfSkkL2kuZXhlYyhoZXgpO1xyXG5cclxuICAgIHJldHVybiByZXN1bHQgPyBbXHJcbiAgICAgIHBhcnNlSW50KHJlc3VsdFsxXSwgMTYpLFxyXG4gICAgICBwYXJzZUludChyZXN1bHRbMl0sIDE2KSxcclxuICAgICAgcGFyc2VJbnQocmVzdWx0WzNdLCAxNilcclxuICAgIF0gOiBbXTtcclxuICB9XHJcbn1cclxuIl19
@@ -1,37 +0,0 @@
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItZXh0cmFjdG9yLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbG9yLXV0aWxzL3NyYy9saWIvY29sb3ItZXh0cmFjdG9yLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUF5QixZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFLckcsTUFBTSxPQUFPLHVCQUF1QjtJQUlsQyxZQUFvQixVQUFzQixFQUFVLFFBQW1CO1FBQW5ELGVBQVUsR0FBVixVQUFVLENBQVk7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBRjdELGVBQVUsR0FBeUIsSUFBSSxZQUFZLEVBQVUsQ0FBQztJQUVFLENBQUM7SUFFM0UsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUdELFlBQVk7UUFDViw0Q0FBNEM7UUFDNUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUE7SUFDaEYsQ0FBQztJQUdELFlBQVk7UUFDVixpRkFBaUY7UUFDakYsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDL0IsQ0FBQzsrR0FwQlUsdUJBQXVCO21HQUF2Qix1QkFBdUI7OzRGQUF2Qix1QkFBdUI7a0JBSG5DLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLFlBQVk7aUJBQ3ZCO3lIQUdXLFVBQVU7c0JBQW5CLE1BQU07Z0JBU1AsWUFBWTtzQkFEWCxZQUFZO3VCQUFDLFlBQVk7Z0JBTzFCLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBSZW5kZXJlcjIsIEhvc3RMaXN0ZW5lciwgRXZlbnRFbWl0dGVyLCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2dldENvbG9yXSdcbn0pXG5leHBvcnQgY2xhc3MgQ29sb3JFeHRyYWN0b3JEaXJlY3RpdmUge1xuXG4gIEBPdXRwdXQoKSBjb2xvclZhbHVlOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZiwgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyKSB7fVxuXG4gIGdldCBjdXJyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignbW91c2VlbnRlcicpXG4gIG9uTW91c2VFbnRlcigpIHtcbiAgICAvLyBjb25zb2xlLmxvZygnRU5URVInLCB0aGlzLmN1cnJlbnRFbGVtZW50KVxuICAgIHRoaXMuY29sb3JWYWx1ZS5lbWl0KHRoaXMuY3VycmVudEVsZW1lbnQuZ2V0UHJvcGVydHlWYWx1ZSgnYmFja2dyb3VuZC1jb2xvcicpKVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScpXG4gIG9uTW91c2VMZWF2ZSgpIHtcbiAgICAvLyBjb25zb2xlLmxvZygnTEVBVkUnLCB0aGlzLmN1cnJlbnRFbGVtZW50LmdldFByb3BlcnR5VmFsdWUoJ2JhY2tncm91bmQtY29sb3InKSlcbiAgICB0aGlzLmNvbG9yVmFsdWUuZW1pdCgnd2hpdGUnKVxuICB9XG5cbn1cbiJdfQ==
@@ -1,185 +0,0 @@
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItZ3JhYi5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb2xvci11dGlscy9zcmMvbGliL2NvbG9yLWdyYWIuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDOztBQUtyRSxNQUFNLE9BQU8scUJBQXFCO0lBUWhDLFlBQW9CLEVBQWM7UUFBZCxPQUFFLEdBQUYsRUFBRSxDQUFZO0lBQUksQ0FBQztJQUV2QyxRQUFRO1FBRU4sTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRCxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNqQixNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUVsQixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUE2QixDQUFDO1FBRS9ELE1BQU0sR0FBRyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7UUFDeEIsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQztRQUM5QixHQUFHLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVwQyxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRTtZQUNoQixJQUFJLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDckMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxZQUFZLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFckQsSUFBSSxTQUFTLElBQUksU0FBUyxDQUFDLElBQUksRUFB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Z0JBQUUsT0FBTyxHQUFHLEdBQUcsS0FBSyxDQUFBO1lBQ3RDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFFN0MsQ0FBQyxDQUFDLENBQUE7UUFFRixNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUU3RCxPQUFPLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQTtJQUU3QyxDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQThCO1FBRXBDLE1BQU0sR0FBRyxHQUFHLEVBQUUsVUFBVSxFQUFDLENBQUMsRUFBRSxHQUFHLEVBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQTtRQUU3QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDeEMsTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxHQUFHLENBQUMsQ0FBQyxFQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUM5QyxHQUFHLENBQUMsVUFBVSxHQUFHLENBQUMsR0FBRyxJQUFFLEdBQUcsQ0FBQyxDQUFBLENBQUMsQ0FBQSxDQUFDLENBQUEsQ0FBQyxDQUFBLENBQUMsR0FBRyxHQUFDLEdBQUcsR0FBQyxHQUFHLENBQUMsQ0FBQTtRQUUzQyxJQUFJLEdBQUcsQ0FBQyxVQUFVLElBQUksQ0FBQyxFQUFFO1lBQ3ZCLEdBQUcsQ0FB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QUFHLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUVsQyxJQUFJLENBQUMsR0FBRyxHQUFHLEVBQUU7WUFDVCxDQUFDLEdBQUcsR0FBRyxDQUFDO1NBQ1g7YUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDZCxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ1Q7UUFFRCxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRXhFLENBQUM7K0dBcE1VLHFCQUFxQjttR0FBckIscUJBQXFCOzs0RkFBckIscUJBQXFCO2tCQUhqQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxnQkFBZ0I7aUJBQzNCO2lHQUtVLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbY29sb3JHcmFiYmVyXSdcbn0pXG5leHBvcnQgY2xhc3MgQ29sb3JHcmFiYmVyRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0IHtcblxuICBjdHg/OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkRcblxuICBASW5wdXQoKSBpbWFnZVVybD86IHN0cmluZ1xuICBASW5wdXQoKSBsaWdodD86IHN0cmluZ1xuICBASW5wdXQoKSBkYXJrPzogc3RyaW5nXG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbDogRWxlbWVudFJlZikgeyB9XG5cbiAgbmdPbkluaXQoKSB7XG5cbiAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjYW52YXMud2lkdGggPSAxO1xuICAgIGNhbnZhcy5oZWlnaHQgPSAxO1xuXG4gICAgdGhpcy5jdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG5cbiAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICBpbWcuc3JjID0gdGhpcy5pbWFnZVVybCB8fCAnJztcbiAgICBpbWcuc2V0QXR0cmlidXRlKCdjcm9zc09yaWdpbicsICcnKTtcblxuICAgIGltZy5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICB0aGlzLmN0eD8uZHJhd0ltYWdlKGltZywgMCwgMCwgMSwgMSk7XG4gICAgICBjb25zdCBpbWFnZURhdGEgPSB0aGlzLmN0eD8uZ2V0SW1hZ2VEYXRhKDAsIDAsIDEsIDEpO1xuXG4gICAgICBpZiAoaW1hZ2VEYXRhICYmIGltYWdlRGF0YS5kYXRhKSB7XG4gICAgICAgIGNvbnN0IGkgPSBpbWFnZURhdGEuZGF0YTtcblxuICAgICAgICBjb25zdCByZ2JDb2xvciA9IGByZ2JhKCR7aVswXX0sJHtpWzFdfSwke2lbMl19LCR7aVszXX0pYDtcbiAgICAgICAgY29uc3QgaGV4Q29sb3IgPSBcIiNcIiArICgoMSA8PCAyNCkgKyAoaVswXSA8PCAxNikgKyAoaVsxXSA8PCA4KSArIGlbMl0pLnRvU3RyaW5nKDE2KS5zbGljZSgxKTtcblxuICAgICAgICBjb25zdCB0ZXh0Q29sb3IgPSB0aGlzLnRleHRDb2xvckJhc2VkT25CZ0NvbG9yKGhleENvbG9yLCB0aGlzLmxpZ2h0LCB0aGlzLmRhcmspO1xuXG4gICAgICAgIGNvbnN0IGhzdiA9IHRoaXMuUkdCMkhTVih7IHI6IGlbMF0sIGc6IGlbMV0sIGI6IGlbMl0gfSk7XG4gICAgICAgIGhzdi5odWUgPSB0aGlzLkh1ZVNoaWZ0KGhzdi5odWUsIDEzNS4wKTtcblxuICAgICAgICBjb25zdCBzZWNvbmRhcnlDb2xvciA9IHRoaXMuSFNWMlJHQihoc3YpO1xuICAgICAgICBjb25zdCBoaWdobGlnaHRDb2xvciA9IHRoaXMubGlnaHRlbkRhcmtlbkNvbG9yKHNlY29uZGFyeUNvbG9yLmhleCwgNTApO1xuXG4gICAgICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSByZ2JDb2xvcjtcbiAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLmNvbG9yID0gdGV4dENvbG9yO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkZhaWxlZCB0byBnZXQgaW1hZ2UgZGF0YS5cIik7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHRleHRDb2xvckJhc2VkT25CZ0NvbG9yKFxuICAgIGJnQ29sb3I6IHN0cmluZyxcbiAgICBsaWdodENvbG9yOiBzdHJpbmcgPSAnI0ZGRkZGRicsXG4gICAgZGFya0NvbG9yOiBzdHJpbmcgPSAnIzAwMDAwMCdcbiAgICApIHtcblxuICAgIGNvbnN0IGNvbG9yID0gKGJnQ29sb3IuY2hhckF0KDApID09PSAnIycpID8gYmdDb2xvci5zdWJzdHJpbmcoMSwgNykgOiBiZ0NvbG9yXG5cbiAgICBjb25zdCByID0gcGFyc2VJbnQoY29sb3Iuc3Vic3RyaW5nKDAsIDIpLCAxNikgLy8gaGV4VG9SXG4gICAgY29uc3QgZyA9IHBhcnNlSW50KGNvbG9yLnN1YnN0cmluZygyLCA0KSwgMTYpIC8vIGhleFRvR1xuICAgIGNvbnN0IGIgPSBwYXJzZUludChjb2xvci5zdWJzdHJpbmcoNCwgNiksIDE2KSAvLyBoZXhUb0JcblxuICAgIGNvbnN0IHVpY29sb3JzID0gW3IgLyAyNTUsIGcgLyAyNTUsIGIgLyAyNTVdXG5cbiAgICBjb25zdCBjID0gdWljb2xvcnMubWFwKChjb2wpID0+IHtcblxuICAgICAgaWYgKGNvbCA8PSAwLjAzOTI4KSByZXR1cm4gY29sIC8gMTIuOTJcbiAgICAgIHJldHVybiBNYXRoLnBvdygoY29sICsgMC4wNTUpIC8gMS4wNTUsIDIuNClcblxuICAgIH0pXG5cbiAgICBjb25zdCBMID0gKDAuMjEyNiAqIGNbMF0pICsgKDAuNzE1MiAqIGNbMV0pICsgKDAuMDcyMiAqIGNbMl0pXG5cbiAgICByZXR1cm4gKEwgPiAwLjE3OSkgPyBkYXJrQ29sb3IgOiBsaWdodENvbG9yXG5cbiAgfVxuXG4gIFJHQjJIU1YocmdiOiB7IHI6IGFueSwgZzogYW55LCBiOiBhbnl9KSB7XG5cbiAgICBjb25zdCBoc3YgPSB7IHNhdHVyYXRpb246MCwgaHVlOjAsIHZhbHVlOiAwIH1cblxuICAgIGNvbnN0IG1heCA9IHRoaXMubWF4MyhyZ2IucixyZ2IuZyxyZ2IuYilcbiAgICBjb25zdCBkaWYgPSBtYXggLSB0aGlzLm1pbjMocmdiLnIscmdiLmcscmdiLmIpXG4gICAgaHN2LnNhdHVyYXRpb24gPSAobWF4PT0wLjApPzA6KDEwMCpkaWYvbWF4KVxuXG4gICAgaWYgKGhzdi5zYXR1cmF0aW9uID09IDApIHtcbiAgICAgIGhzdi5odWU9MFxuICAgIH0gZWxzZSBpZiAocmdiLnIgPT0gbWF4KSB7XG4gICAgICBoc3YuaHVlPTYwLjAqKHJnYi5nLXJnYi5iKS9kaWZcbiAgICB9IGVsc2UgaWYgKHJnYi5nID09IG1heCkge1xuICAgICAgaHN2Lmh1ZT0xMjAuMCs2MC4wKihyZ2IuYi1yZ2IucikvZGlmXG4gICAgfSBlbHNlIGlmIChyZ2IuYiA9PSBtYXgpIHtcbiAgICAgIGhzdi5odWU9MjQwLjArNjAuMCoocmdiLnItcmdiLmcpL2RpZlxuICAgIH1cblxuICAgIGlmIChoc3YuaHVlPDAuMCkgaHN2Lmh1ZSs9MzYwLjBcblxuICAgIGhzdi52YWx1ZSA9IE1hdGgucm91bmQobWF4KjEwMC8yNTUpXG4gICAgaHN2Lmh1ZSA9IE1hdGgucm91bmQoaHN2Lmh1ZSlcbiAgICBoc3Yuc2F0dXJhdGlvbiA9IE1hdGgucm91bmQoaHN2LnNhdHVyYXRpb24pXG5cbiAgICByZXR1cm4gaHN2XG4gIH1cblxuICBIU1YyUkdCKGhzdjogYW55KSB7XG5cbiAgICBjb25zdCByZ2IgPSB7IHI6IDAsIGc6IDAsIGI6IDB9XG5cbiAgICBpZiAoaHN2LnNhdHVyYXRpb249PTApIHtcbiAgICAgIHJnYi5yID0gcmdiLmcgPSByZ2IuYiA9IE1hdGgucm91bmQoaHN2LnZhbHVlKjIuNTUpXG4gICAgfSBlbHNlIHtcblxuICAgICAgaHN2Lmh1ZS89NjBcbiAgICAgIGhzdi5zYXR1cmF0aW9uLz0xMDBcbiAgICAgIGhzdi52YWx1ZS89MTAwXG4gICAgICBjb25zdCBpID0gTWF0aC5mbG9vcihoc3YuaHVlKVxuICAgICAgY29uc3QgZiA9IGhzdi5odWUtaVxuXG4gICAgICBjb25zdCBwID0gaHN2LnZhbHVlKigxLWhzdi5zYXR1cmF0aW9uKVxuICAgICAgY29uc3QgcSA9IGhzdi52YWx1ZSooMS1oc3Yuc2F0dXJhdGlvbipmKVxuICAgICAgY29uc3QgdCA9IGhzdi52YWx1ZSooMS1oc3Yuc2F0dXJhdGlvbiooMS1mKSlcblxuICAgICAgc3dpdGNoKGkpIHtcblxuICAgICAgY2FzZSAwOiByZ2Iucj1oc3YudmFsdWU7IHJnYi5nPXQ7IHJnYi5iPXA7IGJyZWFrXG4gICAgICBjYXNlIDE6IHJnYi5yPXE7IHJnYi5nPWhzdi52YWx1ZTsgcmdiLmI9cDsgYnJlYWtcbiAgICAgIGNhc2UgMjogcmdiLnI9cDsgcmdiLmc9aHN2LnZhbHVlOyByZ2IuYj10OyBicmVha1xuICAgICAgY2FzZSAzOiByZ2Iucj1wOyByZ2IuZz1xOyByZ2IuYj1oc3YudmFsdWU7IGJyZWFrXG4gICAgICBjYXNlIDQ6IHJnYi5yPXQ7IHJnYi5nPXA7IHJnYi5iPWhzdi52YWx1ZTsgYnJlYWtcblxuICAgICAgZGVmYXVsdDogcmdiLnI9aHN2LnZhbHVlOyByZ2IuZz1wOyByZ2IuYj1xXG5cbiAgICAgIH1cblxuICAgICAgcmdiLnIgPSBNYXRoLnJvdW5kKHJnYi5yKjI1NSlcbiAgICAgIHJnYi5nID0gTWF0aC5yb3VuZChyZ2IuZyoyNTUpXG4gICAgICByZ2IuYiA9IE1hdGgucm91bmQocmdiLmIqMjU1KVxuXG4gICAgfVxuXG4gICAgY29uc3QgcmdiQ29sb3IgPSBgcmdiYSgke3JnYi5yfSwke3JnYi5nfSwke3JnYi5ifSwkezF9KWBcbiAgICBjb25zdCBoZXhDb2xvciA9IFwiI1wiICsgKCgxIDw8IDI0KSArIChyZ2IuciA8PCAxNikgKyAocmdiLmcgPDwgOCkgKyByZ2IuYikudG9TdHJpbmcoMTYpLnNsaWNlKDEpXG5cbiAgICByZXR1cm4geyByZ2I6IHJnYkNvbG9yLCBoZXg6IGhleENvbG9yIH1cbiAgfVxuXG4gIEh1ZVNoaWZ0KGg6IGFueSwgczogYW55KSB7XG4gICAgaCArPSBzXG4gICAgd2hpbGUgKGg+PTM2MC4wKSBoLT0zNjAuMFxuICAgIHdoaWxlIChoPDAuMCkgaCs9MzYwLjBcbiAgICByZXR1cm4gaFxuICB9XG5cbiAgbWluMyhhOiBhbnksIGI6IGFueSwgYzogYW55KSB7XG4gICAgcmV0dXJuIChhPGIpPygoYTxjKT9hOmMpOigoYjxjKT9iOmMpXG4gIH1cblxuICBtYXgzKGE6IGFueSwgYjogYW55LCBjOiBhbnkpIHtcbiAgICByZXR1cm4gKGE+Yik/KChhPmMpP2E6Yyk6KChiPmMpP2I6YylcbiAgfVxuXG4gIGxpZ2h0ZW5EYXJrZW5Db2xvcihjb2xvckNvZGU6IGFueSwgYW1vdW50OiBudW1iZXIpIHtcblxuICAgIHZhciB1c2VQb3VuZCA9IGZhbHNlO1xuXG4gICAgaWYgKGNvbG9yQ29kZVswXSA9PSBcIiNcIikge1xuICAgICAgICBjb2xvckNvZGUgPSBjb2xvckNvZGUuc2xpY2UoMSk7XG4gICAgICAgIHVzZVBvdW5kID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgbnVtID0gcGFyc2VJbnQoY29sb3JDb2RlLCAxNik7XG5cbiAgICB2YXIgciA9IChudW0gPj4gMTYpICsgYW1vdW50O1xuXG4gICAgaWYgKHIgPiAyNTUpIHtcbiAgICAgICAgciA9IDI1NTtcbiAgICB9IGVsc2UgaWYgKHIgPCAwKSB7XG4gICAgICAgIHIgPSAwO1xuICAgIH1cblxuICAgIHZhciBiID0gKChudW0gPj4gOCkgJiAweDAwRkYpICsgYW1vdW50O1xuXG4gICAgaWYgKGIgPiAyNTUpIHtcbiAgICAgICAgYiA9IDI1NTtcbiAgICB9IGVsc2UgaWYgKGIgPCAwKSB7XG4gICAgICAgIGIgPSAwO1xuICAgIH1cblxuICAgIHZhciBnID0gKG51bSAmIDB4MDAwMEZGKSArIGFtb3VudDtcblxuICAgIGlmIChnID4gMjU1KSB7XG4gICAgICAgIGcgPSAyNTU7XG4gICAgfSBlbHNlIGlmIChnIDwgMCkge1xuICAgICAgICBnID0gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gKHVzZVBvdW5kID8gXCIjXCIgOiBcIlwiKSArIChnIHwgKGIgPDwgOCkgfCAociA8PCAxNikpLnRvU3RyaW5nKDE2KVxuXG4gIH1cblxufVxuIl19
@@ -1,79 +0,0 @@
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItbGlnaHRlbi1kYXJrZW4uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbG9yLXV0aWxzL3NyYy9saWIvY29sb3ItbGlnaHRlbi1kYXJrZW4uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7QUFLeEQsTUFBTSxPQUFPLHlCQUF5QjtJQUlwQyx5Q0FBeUM7SUFDekMsMkRBQTJEO0lBQzNELDBEQUEwRDtJQUUxRCwwQ0FBMEM7SUFFNUM7UUFSRSxXQUFNLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUE7SUFRbkIsQ0FBQztJQUVmLE9BQU8sQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUVuQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUN2Qyx1RUFBdUU7UUFFdkUscUJBQXFCO1FBQ3JCLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUN4QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQzNCLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUNQLENBQUMsR0FBRyxDQUFDLEVBQ0wsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV0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S0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7YUFDaEIsUUFBUSxDQUFDLEVBQUUsQ0FBQzthQUNaLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEIsT0FBTyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFhLEVBQUUsTUFBYztRQUNsQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdEMsQ0FBQzsrR0ExRVUseUJBQXlCO21IQUF6Qix5QkFBeUIsY0FGeEIsTUFBTTs7NEZBRVAseUJBQXlCO2tCQUhyQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVGV4dENvbG9yU2VydmljZSB9IGZyb20gJy4vdGV4dC1jb2xvci5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQ29sb3JMaWdodGVuRGFya2VuU2VydmljZSB7XG5cbiAgY29sb3JzID0gaW5qZWN0KFRleHRDb2xvclNlcnZpY2UpXG5cbiAgLy8gY29uc3QgY29sb3IgPSAnIzM0OThkYic7IC8vIFlvdXIgY29sb3JcbiAgLy8gY29uc3QgbGlnaHRlckNvbG9yID0gbGlnaHRlbihjb2xvciwgMC4yKTsgLy8gMjAlIGxpZ2h0ZXJcbiAgLy8gY29uc3QgZGFya2VyQ29sb3IgPSBkYXJrZW4oY29sb3IsIDAuMik7ICAgLy8gMjAlIGRhcmtlclxuXG4gIC8vIGNvbnNvbGUubG9nKGxpZ2h0ZXJDb2xvciwgZGFya2VyQ29sb3IpO1xuXG5jb25zdHJ1Y3RvcigpIHsgfVxuXG4gIGxpZ2h0ZW4oY29sb3I6IHN0cmluZywgYW1vdW50OiBudW1iZXIpIHtcblxuICAgIGNvbnN0IHJnYiA9IHRoaXMuY29sb3JzLmZpeENvbG9yKGNvbG9yKVxuICAgIC8vIGNvbnN0IHJnYiA9IGNvbG9yLm1hdGNoKC9cXHdcXHcvZyk/Lm1hcCgoeCkgPT4gcGFyc2VJbnQoeCwgMTYpKSB8fCBbXTtcblxuICAgIC8vIENvbnZlcnQgUkdCIHRvIEhTTFxuICAgIGxldCBbciwgZywgYl0gPSByZ2IubWFwKChjKSA9PiBjIC8gMjU1KTtcbiAgICBjb25zdCBtYXggPSBNYXRoLm1heChyLCBnLCBiKSxcbiAgICAgIG1pbiA9IE1hdGgubWluKHIsIGcsIGIpO1xuICAgIGxldCBoID0gMCxcbiAgICAgIHMgPSAwLFxuICAgICAgbCA9IChtYXggKyBtaW4pIC8gMjtcblxuICAgIGlmIChtYXggIT09IG1pbikge1xuICAgICAgY29uc3QgZCA9IG1heCAtIG1pbjtcbiAgICAgIHMgPSBsID4gMC41ID8gZCAvICgyIC0gbWF4IC0gbWluKSA6IGQgLyAobWF4ICsgbWluKTtcbiAgICAgIHN3aXRjaCAobWF4KSB7XG4gICAgICAgIGNhc2UgcjpcbiAgICAgICAgICBoID0gKGcgLSBiKSAvIGQgKyAoZyA8IGIgPyA2IDogMCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgZzpcbiAgICAgICAgICBoID0gKGIgLSByKSAvIGQgKyAyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIGI6XG4gICAgICAgICAgaCA9IChyIC0gZykgLyBkICsgNDtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGggLz0gNjtcbiAgICB9XG5cbiAgICAvLyBNb2RpZnkgdGhlIGxpZ2h0bmVzcyBhbmQgY2xhbXAgaXQgdG8gWzAsIDFdXG4gICAgbCA9IE1hdGgubWluKDEsIGwgKyBhbW91bnQpO1xuXG4gICAgLy8gQ29udmVydCBIU0wgYmFjayB0byBSR0JcbiAgICBpZiAocyA9PT0gMCkge1xuICAgICAgciA9IGcgPSBiID0gbDsgLy8gYWNocm9tYXRpY1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBodWUycmdiID0gKHA6IG51bWJlciwgcTogbnVtYmVyLCB0OiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKHQgPCAwKSB0ICs9IDE7XG4gICAgICAgIGlmICh0ID4gMSkgdCAtPSAxO1xuICAgICAgICBpZiAodCA8IDEgLyA2KSByZXR1cm4gcCArIChxIC0gcCkgKiA2ICogdDtcbiAgICAgICAgaWYgKHQgPCAxIC8gMikgcmV0dXJuIHE7XG4gICAgICAgIGlmICh0IDwgMiAvIDMpIHJldHVybiBwICsgKHEgLSBwKSAqICgyIC8gMyAtIHQpICogNjtcbiAgICAgICAgcmV0dXJuIHA7XG4gICAgICB9O1xuICAgICAgY29uc3QgcSA9IGwgPCAwLjUgPyBsICogKDEgKyBzKSA6IGwgKyBzIC0gbCAqIHM7XG4gICAgICBjb25zdCBwID0gMiAqIGwgLSBxO1xuICAgICAgciA9IGh1ZTJyZ2IocCwgcSwgaCArIDEgLyAzKTtcbiAgICAgIGcgPSBodWUycmdiKHAsIHEsIGgpO1xuICAgICAgYiA9IGh1ZTJyZ2IocCwgcSwgaCAtIDEgLyAzKTtcbiAgICB9XG5cbiAgICAvLyBDb252ZXJ0IFJHQiBiYWNrIHRvIGhleGFkZWNpbWFsIGNvbG9yXG4gICAgY29uc3QgdG9IZXggPSAoeDogbnVtYmVyKSA9PlxuICAgICAgTWF0aC5yb3VuZCh4ICogMjU1KVxuICAgICAgICAudG9TdHJpbmcoMTYpXG4gICAgICAgIC5wYWRTdGFydCgyLCAnMCcpO1xuICAgIHJldHVybiBgIyR7dG9IZXgocil9JHt0b0hleChnKX0ke3RvSGV4KGIpfWA7XG4gIH1cblxuICBkYXJrZW4oY29sb3I6IHN0cmluZywgYW1vdW50OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5saWdodGVuKGNvbG9yLCAtYW1vdW50KTtcbiAgfVxuXG59XG4iXX0=