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.
Files changed (48) hide show
  1. package/README.md +6 -2
  2. package/color-util-helpers-1.0.10.tgz +0 -0
  3. package/esm2022/color-util-helpers.mjs +5 -0
  4. package/esm2022/lib/color-conversion.service.mjs +39 -0
  5. package/esm2022/lib/color-extractor.directive.mjs +37 -0
  6. package/esm2022/lib/color-grab.directive.mjs +185 -0
  7. package/esm2022/lib/color-lighten-darken.service.mjs +79 -0
  8. package/esm2022/lib/color-pallette.service.mjs +172 -0
  9. package/esm2022/lib/color-scheme.service.mjs +113 -0
  10. package/esm2022/lib/color-utilities-demo/color-utilities-demo.component.mjs +41 -0
  11. package/esm2022/lib/color-utils.module.mjs +38 -0
  12. package/esm2022/lib/text-color.service.mjs +79 -0
  13. package/esm2022/public-api.mjs +13 -0
  14. package/fesm2022/color-util-helpers.mjs +767 -0
  15. package/fesm2022/color-util-helpers.mjs.map +1 -0
  16. package/index.d.ts +5 -0
  17. package/lib/color-conversion.service.d.ts +8 -0
  18. package/lib/color-extractor.directive.d.ts +13 -0
  19. package/lib/color-grab.directive.d.ts +31 -0
  20. package/lib/color-lighten-darken.service.d.ts +10 -0
  21. package/lib/color-pallette.service.d.ts +36 -0
  22. package/lib/color-scheme.service.d.ts +45 -0
  23. package/lib/color-utilities-demo/color-utilities-demo.component.d.ts +34 -0
  24. package/lib/color-utils.module.d.ts +12 -0
  25. package/lib/text-color.service.d.ts +18 -0
  26. package/package.json +15 -2
  27. package/{src/public-api.ts → public-api.d.ts} +0 -6
  28. package/ng-package.json +0 -8
  29. package/src/lib/assets/picture.webp +0 -0
  30. package/src/lib/color-conversion.service.spec.ts +0 -54
  31. package/src/lib/color-conversion.service.ts +0 -35
  32. package/src/lib/color-extractor.directive.spec.ts +0 -49
  33. package/src/lib/color-extractor.directive.ts +0 -28
  34. package/src/lib/color-grab.directive.ts +0 -204
  35. package/src/lib/color-lighten-darken.service.spec.ts +0 -61
  36. package/src/lib/color-lighten-darken.service.ts +0 -83
  37. package/src/lib/color-pallette.service.spec.ts +0 -85
  38. package/src/lib/color-pallette.service.ts +0 -191
  39. package/src/lib/color-scheme.service.ts +0 -123
  40. package/src/lib/color-utilities-demo/color-utilities-demo.component.css +0 -12
  41. package/src/lib/color-utilities-demo/color-utilities-demo.component.html +0 -109
  42. package/src/lib/color-utilities-demo/color-utilities-demo.component.ts +0 -57
  43. package/src/lib/color-utils.module.ts +0 -27
  44. package/src/lib/text-color.service.spec.ts +0 -75
  45. package/src/lib/text-color.service.ts +0 -101
  46. package/tsconfig.lib.json +0 -32
  47. package/tsconfig.lib.prod.json +0 -10
  48. package/tsconfig.spec.json +0 -14
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Color Utilities
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 `ColorUtilsModule`
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3ItcGFsbGV0dGUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbG9yLXV0aWwtaGVscGVycy9zcmMvbGliL2NvbG9yLXBhbGxldHRlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUMxQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFBOzs7QUFNdEMsTUFBTSxPQUFPLG9CQUFvQjtJQTJDL0IsWUFDVSxzQkFBOEM7UUFBOUMsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3QjtRQTFDeEQsb0JBQW9CO1FBQ3BCLHlFQUF5RTtRQUV6RSxhQUFhO1FBQ2IsNEVBQTRFO1FBRTVFLGNBQWM7UUFDZCx3Q0FBd0M7UUFDeEMsbUNBQW1DO1FBQ25DLGVBQWU7UUFDZiwwQkFBMEI7UUFDMUIscURBQXFEO1FBQ3JELFlBQVk7UUFDWixnQkFBZ0I7UUFDaEIsaUJBQWlCO1FBQ2pCLGVBQWU7UUFDZiwwQkFBMEI7UUFDMUIsa0VBQWtFO1FBQ2xFLFlBQVk7UUFDWix3QkFBd0I7UUFDeEIsaUJBQWlCO1FBQ2pCLGFBQWE7UUFDYixTQUFTO1FBRVQsTUFBTTtRQUNOLFdBQVc7UUFDWCxvQkFBb0I7UUFDcEIscUJBQXFCO1FBQ3JCLGdDQUFnQztRQUNoQyxvQkFBb0I7UUFDcEIsbUJBQW1CO1FBQ25CLHFCQUFxQjtRQUNyQixxQkFBcUI7UUFDckIsdUJBQXVCO1FBQ3ZCLDZCQUE2QjtRQUM3QiwrQkFBK0I7UUFDL0IsSUFBSTtRQUVJLFlBQU8sR0FBRyxJQUFJLGVBQWUsQ0FBa0QsRUFBRSxDQUFDLENBQUE7UUFDMUYsYUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLENBQUE7SUFJbEMsQ0FBQztJQUVMOzs7Ozs7T0FNRztJQUNILGtCQUFrQixDQUFDLFNBQWlCLEVBQUUsTUFBTSxH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T0FBTyxjQUFjLENBQUE7SUFDdkIsQ0FBQzsrR0FyTFUsb0JBQW9CO21IQUFwQixvQkFBb0IsY0FGbkIsTUFBTTs7NEZBRVAsb0JBQW9CO2tCQUhoQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xyXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJ1xyXG5pbXBvcnQgeyBDb2xvckNvbnZlcnNpb25TZXJ2aWNlIH0gZnJvbSAnLi9jb2xvci1jb252ZXJzaW9uLnNlcnZpY2UnXHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDb2xvclBhbGxldHRlU2VydmljZSB7XHJcblxyXG4gIC8vIGRlZmluZSBpbWFnZSBwYXRoXHJcbiAgLy8gdGhpcy5jb2xvclNlbGVjdGlvblNlcnZpY2UuZ2V0Q29sb3JzRnJvbUltYWdlKCcuLi9hc3NldHMvc2FtcGxlMi5qcGcnKVxyXG5cclxuICAvLyBnZXQgY29sb3JzXHJcbiAgLy8gdGhpcy5jb2xvclNlbGVjdGlvblNlcnZpY2UucGFsZXR0ZS5zdWJzY3JpYmUoZGF0YSA9PiB0aGlzLnBhbGV0dGUgPSBkYXRhKVxyXG5cclxuICAvLyBzYW1wbGUgaHRtbFxyXG4gIC8vICAgPGRpdiAqbmdGb3I9XCJsZXQgY29sb3Igb2YgcGFsZXR0ZVwiPlxyXG4gIC8vICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDtcIj5cclxuICAvLyAgICAgICAgIDxkaXZcclxuICAvLyAgICAgICAgICAgICBjbGFzcz1cImJveFwiXHJcbiAgLy8gICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtY29sb3JdPVwiY29sb3IuY29sb3JcIlxyXG4gIC8vICAgICAgICAgPlxyXG4gIC8vICAgICAgICAgQ29sb3JcclxuICAvLyAgICAgICAgIDwvZGl2PlxyXG4gIC8vICAgICAgICAgPGRpdlxyXG4gIC8vICAgICAgICAgICAgIGNsYXNzPVwiYm94XCJcclxuICAvLyAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1jb2xvcl09XCJjb2xvci5jb21wbGVtZW50YXJ5Q29sb3JcIlxyXG4gIC8vICAgICAgICAgPlxyXG4gIC8vICAgICAgICAgQ29tcGxlbWVudGFyeVxyXG4gIC8vICAgICAgICAgPC9kaXY+XHJcbiAgLy8gICAgIDwvZGl2PlxyXG4gIC8vIDwvZGl2PlxyXG5cclxuICAvLyBDU1NcclxuICAvLyAgIC5ib3gge1xyXG4gIC8vICAgICB3aWR0aDogMTAwcHg7XHJcbiAgLy8gICAgIGhlaWdodDogMTAwcHg7XHJcbiAgLy8gICAgIGJvcmRlcjogc29saWQgdGhpbiBibGFjaztcclxuICAvLyAgICAgY29sb3I6IGJsYWNrO1xyXG4gIC8vICAgICBtYXJnaW46IDRweDtcclxuICAvLyAgICAgcGFkZGluZzogMTZweDtcclxuICAvLyAgICAgZGlzcGxheTogZmxleDtcclxuICAvLyAgICAgZmxleC13cmFwOiB3cmFwO1xyXG4gIC8vICAgICBhbGlnbi1jb250ZW50OiBjZW50ZXI7XHJcbiAgLy8gICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xyXG4gIC8vIH1cclxuXHJcbiAgcHJpdmF0ZSBwYWxldHRlID0gbmV3IEJlaGF2aW9yU3ViamVjdDx7IGNvbG9yOiBzdHJpbmcsIGNvbXBsZW1lbnRhcnlDb2xvcjogc3RyaW5nIH1bXT4oW10pXHJcbiAgcGFsZXR0ZSQgPSB0aGlzLnBhbGV0dGUuYXNPYnNlcnZhYmxlKClcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGNvbG9yQ29udmVyc2lvblNlcnZpY2U6IENvbG9yQ29udmVyc2lvblNlcnZpY2VcclxuICApIHsgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXRyaWV2ZXMgYSBjb2xvciBwYWxldHRlIGZyb20gYW4gaW1hZ2UgYXQgdGhlIHNwZWNpZmllZCBwYXRoLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGltYWdlUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBpbWFnZSB0byBleHRyYWN0IHRoZSBjb2xvciBwYWxldHRlIGZyb20uXHJcbiAgICogQHBhcmFtIGNvbG9ycyAtIFRoZSBudW1iZXIgb2YgY29sb3JzIHRvIGluY2x1ZGUgaW4gdGhlIHBhbGV0dGUgKGRlZmF1bHQgaXMgMykuXHJcbiAgICogQHJldHVybnMgQW4gb2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHRoZSBnZW5lcmF0ZWQgY29sb3IgcGFsZXR0ZS5cclxuICAgKi9cclxuICBnZXRDb2xvcnNGcm9tSW1hZ2UoaW1hZ2VQYXRoOiBzdHJpbmcsIGNvbG9ycyA9IDMpIHtcclxuICAgIGNvbnN0IGltYWdlID0gbmV3IEltYWdlKCk7XHJcbiAgICBpbWFnZS5zcmMgPSBpbWFnZVBhdGg7XHJcblxyXG4gICAgaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5nZW5lcmF0ZUNvbG9yUGFsZXR0ZShpbWFnZSwgY29sb3JzKSB8fCBbXTtcclxuICAgICAgdGhpcy5wYWxldHRlLm5leHQoZGF0YSk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2VuZXJhdGVzIGEgY29sb3IgcGFsZXR0ZSBmcm9tIGFuIGltYWdlLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGltYWdlIC0gVGhlIEhUTUwgaW1hZ2UgZWxlbWVudCB0byBleHRyYWN0IHRoZSBjb2xvciBwYWxldHRlIGZyb20uXHJcbiAgICogQHBhcmFtIGNvbG9yQ291bnQgLSBUaGUgbnVtYmVyIG9mIGNvbG9ycyB0byBpbmNsdWRlIGluIHRoZSBwYWxldHRlIChkZWZhdWx0IGlzIDYpLlxyXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGNvbG9yIG9iamVjdHMsIGVhY2ggd2l0aCBhIGhleCBjb2xvciBhbmQgYSBjb21wbGVtZW50YXJ5IGhleCBjb2xvci5cclxuICAgKi9cclxuICBnZW5lcmF0ZUNvbG9yUGFsZXR0ZShpbWFnZTogSFRNTEltYWdlRWxlbWVudCwgY29sb3JDb3VudCA9IDYpIHtcclxuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XHJcbiAgICBjb25zdCBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcclxuXHJcbiAgICBpZiAoIWNvbnRleHQpIHJldHVybjtcclxuXHJcbiAgICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcclxuICAgIGNhbnZhcy5oZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XHJcbiAgICBjb250ZXh0LmRyYXdJbWFnZShpbWFnZSwgMCwgMCk7XHJcblxyXG4gICAgLy8gR2V0IHRoZSBpbWFnZSBkYXRhXHJcbiAgICBjb25zdCBpbWFnZURhdGEgPSBjb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xyXG4gICAgY29uc3QgcGl4ZWxzID0gaW1hZ2VEYXRhLmRhdGE7XHJcbiAgICBjb25zdCBwaXhlbENvdW50ID0gaW1hZ2VEYXRhLndpZHRoICogaW1hZ2VEYXRhLmhlaWdodDtcclxuXHJcbiAgICAvLyBCdWlsZCBhbiBhcnJheSBvZiBSR0IgY29sb3JzXHJcbiAgICBjb25zdCBjb2xvcnMgPSBbXTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGl4ZWxDb3VudDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IG9mZnNldCA9IGkgKiA0O1xyXG4gICAgICBjb25zdCByID0gcGl4ZWxzW29mZnNldF07XHJcbiAgICAgIGNvbnN0IGcgPSBwaXhlbHNbb2Zmc2V0ICsgMV07XHJcbiAgICAgIGNvbnN0IGIgPSBwaXhlbHNbb2Zmc2V0ICsgMl07XHJcbiAgICAgIGNvbG9ycy5wdXNoKFtyLCBnLCBiXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQXBwbHkgY29sb3IgcXVhbnRpemF0aW9uIHVzaW5nIGstbWVhbnMgY2x1c3RlcmluZ1xyXG4gICAgY29uc3QgcXVhbnRpemVkQ29sb3JzID0gdGhpcy5rTWVhbnNDb2xvclF1YW50aXphdGlvbihjb2xvcnMsIGNvbG9yQ291bnQpO1xyXG5cclxuICAgIC8vIE9yZGVyIGNvbG9ycyBieSBsdW1pbmFuY2VcclxuICAgIHF1YW50aXplZENvbG9ycy5zb3J0KChjb2xvcjEsIGNvbG9yMikgPT4ge1xyXG4gICAgICBjb25zdCBsdW1pbmFuY2UxID0gdGhpcy5nZXRMdW1pbmFuY2UoY29sb3IxKTtcclxuICAgICAgY29uc3QgbHVtaW5hbmNlMiA9IHRoaXMuZ2V0THVtaW5hbmNlKGNvbG9yMik7XHJcbiAgICAgIHJldHVybiBsdW1pbmFuY2UyIC0gbHVtaW5hbmNlMTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IHBhbGV0dGUgPSBxdWFudGl6ZWRDb2xvcnMubWFwKChjb2xvcikgPT4ge1xyXG4gICAgICBjb25zdCBjb21wbGVtZW50YXJ5Q29sb3IgPSBjb2xvci5tYXAoKGNvbXBvbmVudCkgPT4gMjU1IC0gY29tcG9uZW50KTtcclxuICAgICAgY29uc3QgaGV4Q29sb3IgPSB0aGlzLmNvbG9yQ29udmVyc2lvblNlcnZpY2UucmdiVG9IZXgoY29sb3IpO1xyXG4gICAgICBjb25zdCBoZXhDb21wbGVtZW50YXJ5Q29sb3IgPVxyXG4gICAgICAgIHRoaXMuY29sb3JDb252ZXJzaW9uU2VydmljZS5yZ2JUb0hleChjb21wbGVtZW50YXJ5Q29sb3IpO1xyXG4gICAgICByZXR1cm4geyBjb2xvcjogaGV4Q29sb3IsIGNvbXBsZW1lbnRhcnlDb2xvcjogaGV4Q29tcGxlbWVudGFyeUNvbG9yIH07XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcGFsZXR0ZTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0THVtaW5hbmNlKGNvbG9yOiBudW1iZXJbXSkge1xyXG4gICAgY29uc3QgW3IsIGcsIGJdID0gY29sb3JcclxuICAgIHJldHVybiAwLjI5OSAqIHIgKyAwLjU4NyAqIGcgKyAwLjExNCAqIGJcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2FsY3VsYXRlQ29sb3JEaXN0YW5jZShjb2xvcjE6IG51bWJlcltdLCBjb2xvcjI6IG51bWJlcltdKSB7XHJcbiAgICBjb25zdCBbcjEsIGcxLCBiMV0gPSBjb2xvcjFcclxuICAgIGNvbnN0IFtyMiwgZzIsIGIyXSA9IGNvbG9yMlxyXG4gICAgY29uc3QgZHIgPSByMiAtIHIxXHJcbiAgICBjb25zdCBkZyA9IGcyIC0gZzFcclxuICAgIGNvbnN0IGRiID0gYjIgLSBiMVxyXG4gICAgcmV0dXJuIE1hdGguc3FydChkciAqIGRyICsgZGcgKiBkZyArIGRiICogZGIpXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNhbGN1bGF0ZU1lYW5Db2xvcihjb2xvcnM6IG51bWJlcltdW10pIHtcclxuICAgIGxldCBzdW1SID0gMFxyXG4gICAgbGV0IHN1bUcgPSAwXHJcbiAgICBsZXQgc3VtQiA9IDBcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29sb3JzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IFtyLCBnLCBiXSA9IGNvbG9yc1tpXVxyXG4gICAgICBzdW1SICs9IHJcclxuICAgICAgc3VtRyArPSBnXHJcbiAgICAgIHN1bUIgKz0gYlxyXG4gICAgfVxyXG4gICAgY29uc3QgbWVhblIgPSBNYXRoLnJvdW5kKHN1bVIgLyBjb2xvcnMubGVuZ3RoKVxyXG4gICAgY29uc3QgbWVhbkcgPSBNYXRoLnJvdW5kKHN1bUcgLyBjb2xvcnMubGVuZ3RoKVxyXG4gICAgY29uc3QgbWVhbkIgPSBNYXRoLnJvdW5kKHN1bUIgLyBjb2xvcnMubGVuZ3RoKVxyXG4gICAgcmV0dXJuIFttZWFuUiwgbWVhbkcsIG1lYW5CXVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBrTWVhbnNDb2xvclF1YW50aXphdGlvbihjb2xvcnM6IG51bWJlcltdW10sIGs6IG51bWJlcikge1xyXG4gICAgbGV0IGNsdXN0ZXJDZW50ZXJzID0gW11cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgazsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IHJhbmRvbUNvbG9yID0gY29sb3JzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGNvbG9ycy5sZW5ndGgpXVxyXG4gICAgICBjbHVzdGVyQ2VudGVycy5wdXNoKHJhbmRvbUNvbG9yKVxyXG4gICAgfVxyXG5cclxuICAgIGxldCBjbHVzdGVycyA9IFtdXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbG9ycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBjb2xvciA9IGNvbG9yc1tpXVxyXG4gICAgICBsZXQgbWluRGlzdGFuY2UgPSBJbmZpbml0eVxyXG4gICAgICBsZXQgbmVhcmVzdENlbnRlciA9IG51bGxcclxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjbHVzdGVyQ2VudGVycy5sZW5ndGg7IGorKykge1xyXG4gICAgICAgIGNvbnN0IGNlbnRlciA9IGNsdXN0ZXJDZW50ZXJzW2pdXHJcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSB0aGlzLmNhbGN1bGF0ZUNvbG9yRGlzdGFuY2UoY29sb3IsIGNlbnRlcilcclxuICAgICAgICBpZiAoZGlzdGFuY2UgPCBtaW5EaXN0YW5jZSkge1xyXG4gICAgICAgICAgbWluRGlzdGFuY2UgPSBkaXN0YW5jZVxyXG4gICAgICAgICAgbmVhcmVzdENlbnRlciA9IGNlbnRlclxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBjbHVzdGVycy5wdXNoKHsgY29sb3IsIGNlbnRlcjogbmVhcmVzdENlbnRlciB9KVxyXG4gICAgfVxyXG5cclxuICAgIGxldCB1cGRhdGVkQ2VudGVycyA9IFtdXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNsdXN0ZXJDZW50ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IGNlbnRlciA9IGNsdXN0ZXJDZW50ZXJzW2ldXHJcbiAgICAgIGNvbnN0IGNsdXN0ZXJDb2xvcnMgPSBjbHVzdGVycy5maWx0ZXIoYyA9PiBjLmNlbnRlciA9PT0gY2VudGVyKS5tYXAoYyA9PiBjLmNvbG9yKVxyXG4gICAgICBpZiAoY2x1c3RlckNvbG9ycy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgY29uc3QgdXBkYXRlZENlbnRlciA9IHRoaXMuY2FsY3VsYXRlTWVhbkNvbG9yKGNsdXN0ZXJDb2xvcnMpXHJcbiAgICAgICAgdXBkYXRlZENlbnRlcnMucHVzaCh1cGRhdGVkQ2VudGVyKVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHVwZGF0ZWRDZW50ZXJzXHJcbiAgfVxyXG5cclxufVxyXG4iXX0=