ngx-easy-image-drawing 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,84 +1,24 @@
1
- # ngx-easy-image-drawing
1
+ # NgxEasyImageDrawing
2
2
 
3
- **Angular library for easy image drawing on a canvas**
3
+ This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.1.0.
4
4
 
5
- This library provides a simple and efficient way to allow users to draw on images within your Angular applications.
5
+ ## Code scaffolding
6
6
 
7
- ## Installation
7
+ Run `ng generate component component-name --project ngx-easy-image-drawing` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ngx-easy-image-drawing`.
8
+ > Note: Don't forget to add `--project ngx-easy-image-drawing` or else it will be added to the default project in your `angular.json` file.
8
9
 
9
- ```bash
10
- npm install ngx-easy-image-drawing
11
- ```
10
+ ## Build
12
11
 
13
- ## Usage
12
+ Run `ng build ngx-easy-image-drawing` to build the project. The build artifacts will be stored in the `dist/` directory.
14
13
 
15
- 1. Import module
14
+ ## Publishing
16
15
 
17
- ```typescript
18
- import { NgxEasyImageDrawingModule } from 'ngx-easy-image-drawing';
16
+ After building your library with `ng build ngx-easy-image-drawing`, go to the dist folder `cd dist/ngx-easy-image-drawing` and run `npm publish`.
19
17
 
20
- @NgModule({
21
- imports: [
22
- NgxEasyImageDrawingModule
23
- ]
24
- })
25
- export class AppModule { }
26
- ```
18
+ ## Running unit tests
27
19
 
28
- 2. Use it in your template
20
+ Run `ng test ngx-easy-image-drawing` to execute the unit tests via [Karma](https://karma-runner.github.io).
29
21
 
30
- ```typescript
31
- <app-image-drawing
32
- [height]="canvasHeight"
33
- [width]="canvasWidth"
34
- [src]="uploadImageFilePreview"
35
- [showCancelButton]="false"
36
- forceSizeExport="true"
37
- outputMimeType="uploadImageFile.type"
38
- outputQuality="1"
39
- (savedImage)="onSaveDrawImage($event)"
40
- >
41
- </app-image-drawing>
42
- ```
22
+ ## Further help
43
23
 
44
- ## Options
45
-
46
- ```markdown
47
- | Option | Type | Description |
48
- |---|---|---|
49
- | height | number | The height of the canvas in pixels. |
50
- | width | number | The width of the canvas in pixels. |
51
- | src | string | The image source URL. |
52
- | showCancelButton | boolean | Whether to display a cancel button. |
53
- | forceSizeExport | boolean | Whether to force the exported image size to match the canvas size. |
54
- | outputMimeType | string | The MIME type of the exported image (e.g., 'image/jpeg', 'image/png'). |
55
- | outputQuality | number | The quality of the exported image (0-1). |
56
- | savedImage | EventEmitter<string> | An event emitted when the image is saved. The event payload is a data URL representing the image. |
57
- ```
58
-
59
- ## Example
60
-
61
- ```typescript
62
- import { Component } from '@angular/core';
63
-
64
- @Component({
65
- selector: 'app-my-component',
66
- template: `
67
- <app-image-drawing
68
- [height]="300"
69
- [width]="400"
70
- [src]="imageUrl"
71
- (savedImage)="handleSavedImage($event)"
72
- ></app-image-drawing>
73
- `
74
- })
75
- export class MyComponent {
76
- // You can use uploaded url from input html
77
- imageUrl = 'path/to/your/image.jpg';
78
-
79
- handleSavedImage(imageData: string) {
80
- // Handle the saved image data here
81
- console.log(imageData);
82
- }
83
- }
84
- ```
24
+ To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
@@ -0,0 +1,116 @@
1
+ import { Component, ViewChild, Input, Output, EventEmitter, } from '@angular/core';
2
+ import { MatIconModule } from '@angular/material/icon';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/material/icon";
5
+ export class EasyImageDrawing {
6
+ constructor() {
7
+ this.width = 500;
8
+ this.height = 500;
9
+ this.lineWidth = 7;
10
+ this.lineColor = '#000000';
11
+ this.src = '';
12
+ this.savedImage = new EventEmitter();
13
+ this.previousPosition = { x: 0, y: 0 };
14
+ this.activePath = false;
15
+ this._mousedown = null;
16
+ this._mousemove = null;
17
+ this._mouseup = null;
18
+ }
19
+ ngAfterViewInit() {
20
+ this.canvas.nativeElement.width = this.width;
21
+ this.canvas.nativeElement.height = this.height;
22
+ this.context = this.canvas.nativeElement.getContext('2d');
23
+ this.context.lineWidth = this.lineWidth;
24
+ this.context.strokeStyle = this.lineColor;
25
+ this.context.lineCap = 'round';
26
+ // set src to image
27
+ const image = new Image();
28
+ image.src = this.src;
29
+ image.onload = () => {
30
+ this.context.drawImage(image, 0, 0, this.width, this.height);
31
+ };
32
+ this._mousedown = window.addEventListener('mousedown', (event) => {
33
+ this.activePath = true;
34
+ this.context.beginPath();
35
+ this.previousPosition = this.getMousePosition(event);
36
+ });
37
+ this._mousemove = window.addEventListener('mousemove', (event) => {
38
+ event.preventDefault();
39
+ if (this.activePath) {
40
+ this._drawLine(event);
41
+ }
42
+ });
43
+ this._mouseup = window.addEventListener('mouseup', () => {
44
+ if (this.activePath) {
45
+ this.context.closePath();
46
+ this.activePath = false;
47
+ }
48
+ });
49
+ }
50
+ save() {
51
+ const dataUrl = this.canvas.nativeElement.toDataURL('image/png');
52
+ const blob = this._dataURItoBlob(dataUrl);
53
+ this.savedImage.next(new File([blob], 'image.png'));
54
+ }
55
+ clear() {
56
+ this.context.clearRect(0, 0, this.width, this.height);
57
+ const image = new Image();
58
+ image.src = this.src;
59
+ image.onload = () => {
60
+ this.context.drawImage(image, 0, 0, this.width, this.height);
61
+ };
62
+ }
63
+ _dataURItoBlob(dataUrl) {
64
+ const byteString = atob(dataUrl.split(',')[1]);
65
+ const mimeString = dataUrl.split(',')[0].split(':')[1].split(';')[0];
66
+ const ab = new ArrayBuffer(byteString.length);
67
+ const dw = new DataView(ab);
68
+ for (let i = 0; i < byteString.length; i++) {
69
+ dw.setUint8(i, byteString.charCodeAt(i));
70
+ }
71
+ return new Blob([ab], { type: mimeString });
72
+ }
73
+ _drawLine(event) {
74
+ const currentPosition = this.getMousePosition(event);
75
+ this.context.moveTo(this.previousPosition.x, this.previousPosition.y);
76
+ this.context.lineTo(currentPosition.x, currentPosition.y);
77
+ this.previousPosition = currentPosition;
78
+ this.context.stroke();
79
+ }
80
+ getMousePosition(event) {
81
+ const rect = this.canvas.nativeElement.getBoundingClientRect();
82
+ const scaleX = this.canvas.nativeElement.width / rect.width;
83
+ const scaleY = this.canvas.nativeElement.height / rect.height;
84
+ return {
85
+ x: (event.clientX - rect.left) * scaleX,
86
+ y: (event.clientY - rect.top) * scaleY,
87
+ };
88
+ }
89
+ ngOnDestroy() {
90
+ window.removeEventListener('mousedown', this._mousedown);
91
+ window.removeEventListener('mousemove', this._mousemove);
92
+ window.removeEventListener('mouseup', this._mouseup);
93
+ }
94
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: EasyImageDrawing, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
95
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.3", type: EasyImageDrawing, isStandalone: true, selector: "easy-image-drawing", inputs: { width: "width", height: "height", lineWidth: "lineWidth", lineColor: "lineColor", src: "src" }, outputs: { savedImage: "savedImage" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["drawingCanvas"], descendants: true }], ngImport: i0, template: "<div class=\"bel-remove-image-button-wrapper\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"save()\"\r\n matTooltip=\"Save changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n matTooltip=\"Discard changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>undo</mat-icon>\r\n </button>\r\n</div>\r\n<div class=\"canvas-wrapper\">\r\n <canvas id=\"canvas\" #drawingCanvas></canvas>\r\n</div>\r\n", styles: ["@media only screen and (max-width: 900px){:host{display:flex;flex-direction:column;height:100%}}.bel-remove-image-button-wrapper{display:flex;justify-content:flex-end;margin:0 10px 10px 0}.bel-remove-image-button-wrapper .icon-button{color:var(--primary-color)}#canvas{border:1px solid #ccc;max-width:400px;max-height:700px;cursor:crosshair}.canvas-wrapper{display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
96
+ }
97
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: EasyImageDrawing, decorators: [{
98
+ type: Component,
99
+ args: [{ selector: 'easy-image-drawing', standalone: true, imports: [MatIconModule], template: "<div class=\"bel-remove-image-button-wrapper\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"save()\"\r\n matTooltip=\"Save changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n matTooltip=\"Discard changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>undo</mat-icon>\r\n </button>\r\n</div>\r\n<div class=\"canvas-wrapper\">\r\n <canvas id=\"canvas\" #drawingCanvas></canvas>\r\n</div>\r\n", styles: ["@media only screen and (max-width: 900px){:host{display:flex;flex-direction:column;height:100%}}.bel-remove-image-button-wrapper{display:flex;justify-content:flex-end;margin:0 10px 10px 0}.bel-remove-image-button-wrapper .icon-button{color:var(--primary-color)}#canvas{border:1px solid #ccc;max-width:400px;max-height:700px;cursor:crosshair}.canvas-wrapper{display:flex;align-items:center;justify-content:center}\n"] }]
100
+ }], propDecorators: { width: [{
101
+ type: Input
102
+ }], height: [{
103
+ type: Input
104
+ }], lineWidth: [{
105
+ type: Input
106
+ }], lineColor: [{
107
+ type: Input
108
+ }], src: [{
109
+ type: Input
110
+ }], savedImage: [{
111
+ type: Output
112
+ }], canvas: [{
113
+ type: ViewChild,
114
+ args: ['drawingCanvas']
115
+ }] } });
116
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWFzeS1pbWFnZS1kcmF3aW5nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1lYXN5LWltYWdlLWRyYXdpbmcvc3JjL2xpYi9lYXN5LWltYWdlLWRyYXdpbmcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWVhc3ktaW1hZ2UtZHJhd2luZy9zcmMvbGliL2Vhc3ktaW1hZ2UtZHJhd2luZy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFNBQVMsRUFHVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksR0FFYixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7OztBQVN2RCxNQUFNLE9BQU8sZ0JBQWdCO0lBUDdCO1FBUVcsVUFBSyxHQUFXLEdBQUcsQ0FBQztRQUNwQixXQUFNLEdBQVcsR0FBRyxDQUFDO1FBQ3JCLGNBQVMsR0FBRyxDQUFDLENBQUM7UUFDZCxjQUFTLEdBQUcsU0FBUyxDQUFDO1FBQ3RCLFFBQUcsR0FBRyxFQUFFLENBQUM7UUFDUixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQU14QyxxQkFBZ0IsR0FBNkIsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUM1RCxlQUFVLEdBQUcsS0FBSyxDQUFDO1FBRW5CLGVBQVUsR0FBUSxJQUFJLENBQUM7UUFDdkIsZUFBVSxHQUFRLElBQUksQ0FBQztRQUN2QixhQUFRLEdBQVEsSUFBSSxDQUFDO0tBMkY5QjtJQXpGQyxlQUFlO1FBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDN0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLElB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ZCxLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxHQUFHO3NCQUFYLEtBQUs7Z0JBQ0ksVUFBVTtzQkFBbkIsTUFBTTtnQkFHcUIsTUFBTTtzQkFBakMsU0FBUzt1QkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgVmlld0NoaWxkLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBJbnB1dCxcclxuICBPdXRwdXQsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIE9uRGVzdHJveSxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTWF0SWNvbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdlYXN5LWltYWdlLWRyYXdpbmcnLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW01hdEljb25Nb2R1bGVdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9lYXN5LWltYWdlLWRyYXdpbmcuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2Vhc3ktaW1hZ2UtZHJhd2luZy5jb21wb25lbnQuc2NzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRWFzeUltYWdlRHJhd2luZyBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XHJcbiAgQElucHV0KCkgd2lkdGg6IG51bWJlciA9IDUwMDtcclxuICBASW5wdXQoKSBoZWlnaHQ6IG51bWJlciA9IDUwMDtcclxuICBASW5wdXQoKSBsaW5lV2lkdGggPSA3O1xyXG4gIEBJbnB1dCgpIGxpbmVDb2xvciA9ICcjMDAwMDAwJztcclxuICBASW5wdXQoKSBzcmMgPSAnJztcclxuICBAT3V0cHV0KCkgc2F2ZWRJbWFnZSA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZT4oKTtcclxuXHJcbiAgLy8gaXRzIGltcG9ydGFudCBteUNhbnZhcyBtYXRjaGVzIHRoZSB2YXJpYWJsZSBuYW1lIGluIHRoZSB0ZW1wbGF0ZVxyXG4gIEBWaWV3Q2hpbGQoJ2RyYXdpbmdDYW52YXMnKSBjYW52YXMhOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcclxuXHJcbiAgY29udGV4dCE6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcclxuICBwcml2YXRlIHByZXZpb3VzUG9zaXRpb246IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9IHsgeDogMCwgeTogMCB9O1xyXG4gIHByaXZhdGUgYWN0aXZlUGF0aCA9IGZhbHNlO1xyXG5cclxuICBwcml2YXRlIF9tb3VzZWRvd246IGFueSA9IG51bGw7XHJcbiAgcHJpdmF0ZSBfbW91c2Vtb3ZlOiBhbnkgPSBudWxsO1xyXG4gIHByaXZhdGUgX21vdXNldXA6IGFueSA9IG51bGw7XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2FudmFzLm5hdGl2ZUVsZW1lbnQud2lkdGggPSB0aGlzLndpZHRoO1xyXG4gICAgdGhpcy5jYW52YXMubmF0aXZlRWxlbWVudC5oZWlnaHQgPSB0aGlzLmhlaWdodDtcclxuXHJcbiAgICB0aGlzLmNvbnRleHQgPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50LmdldENvbnRleHQoJzJkJykhO1xyXG4gICAgdGhpcy5jb250ZXh0LmxpbmVXaWR0aCA9IHRoaXMubGluZVdpZHRoO1xyXG4gICAgdGhpcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gdGhpcy5saW5lQ29sb3I7XHJcbiAgICB0aGlzLmNvbnRleHQubGluZUNhcCA9ICdyb3VuZCc7XHJcblxyXG4gICAgLy8gc2V0IHNyYyB0byBpbWFnZVxyXG4gICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcclxuICAgIGltYWdlLnNyYyA9IHRoaXMuc3JjO1xyXG4gICAgaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuX21vdXNlZG93biA9IHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxyXG4gICAgICAnbW91c2Vkb3duJyxcclxuICAgICAgKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgdGhpcy5hY3RpdmVQYXRoID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmNvbnRleHQuYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgdGhpcy5wcmV2aW91c1Bvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcclxuICAgICAgfVxyXG4gICAgKTtcclxuXHJcbiAgICB0aGlzLl9tb3VzZW1vdmUgPSB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGV2ZW50KSA9PiB7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIGlmICh0aGlzLmFjdGl2ZVBhdGgpIHtcclxuICAgICAgICB0aGlzLl9kcmF3TGluZShldmVudCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuX21vdXNldXAgPSB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICgpID0+IHtcclxuICAgICAgaWYgKHRoaXMuYWN0aXZlUGF0aCkge1xyXG4gICAgICAgIHRoaXMuY29udGV4dC5jbG9zZVBhdGgoKTtcclxuICAgICAgICB0aGlzLmFjdGl2ZVBhdGggPSBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2F2ZSgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGRhdGFVcmwgPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50LnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XHJcbiAgICBjb25zdCBibG9iID0gdGhpcy5fZGF0YVVSSXRvQmxvYihkYXRhVXJsKTtcclxuICAgIHRoaXMuc2F2ZWRJbWFnZS5uZXh0KG5ldyBGaWxlKFtibG9iXSwgJ2ltYWdlLnBuZycpKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcclxuICAgIHRoaXMuY29udGV4dC5jbGVhclJlY3QoMCwgMCwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xyXG4gICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcclxuICAgIGltYWdlLnNyYyA9IHRoaXMuc3JjO1xyXG4gICAgaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfZGF0YVVSSXRvQmxvYihkYXRhVXJsOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IGJ5dGVTdHJpbmcgPSBhdG9iKGRhdGFVcmwuc3BsaXQoJywnKVsxXSk7XHJcbiAgICBjb25zdCBtaW1lU3RyaW5nID0gZGF0YVVybC5zcGxpdCgnLCcpWzBdLnNwbGl0KCc6JylbMV0uc3BsaXQoJzsnKVswXTtcclxuICAgIGNvbnN0IGFiID0gbmV3IEFycmF5QnVmZmVyKGJ5dGVTdHJpbmcubGVuZ3RoKTtcclxuICAgIGNvbnN0IGR3ID0gbmV3IERhdGFWaWV3KGFiKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZVN0cmluZy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBkdy5zZXRVaW50OChpLCBieXRlU3RyaW5nLmNoYXJDb2RlQXQoaSkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5ldyBCbG9iKFthYl0sIHsgdHlwZTogbWltZVN0cmluZyB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2RyYXdMaW5lKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICBjb25zdCBjdXJyZW50UG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpO1xyXG4gICAgdGhpcy5jb250ZXh0Lm1vdmVUbyh0aGlzLnByZXZpb3VzUG9zaXRpb24ueCwgdGhpcy5wcmV2aW91c1Bvc2l0aW9uLnkpO1xyXG4gICAgdGhpcy5jb250ZXh0LmxpbmVUbyhjdXJyZW50UG9zaXRpb24ueCwgY3VycmVudFBvc2l0aW9uLnkpO1xyXG4gICAgdGhpcy5wcmV2aW91c1Bvc2l0aW9uID0gY3VycmVudFBvc2l0aW9uO1xyXG4gICAgdGhpcy5jb250ZXh0LnN0cm9rZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRNb3VzZVBvc2l0aW9uKGV2ZW50OiBNb3VzZUV2ZW50KTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcclxuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3Qgc2NhbGVYID0gdGhpcy5jYW52YXMubmF0aXZlRWxlbWVudC53aWR0aCAvIHJlY3Qud2lkdGg7XHJcbiAgICBjb25zdCBzY2FsZVkgPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50LmhlaWdodCAvIHJlY3QuaGVpZ2h0O1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgeDogKGV2ZW50LmNsaWVudFggLSByZWN0LmxlZnQpICogc2NhbGVYLFxyXG4gICAgICB5OiAoZXZlbnQuY2xpZW50WSAtIHJlY3QudG9wKSAqIHNjYWxlWSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLl9tb3VzZWRvd24pO1xyXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuX21vdXNlbW92ZSk7XHJcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuX21vdXNldXApO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiYmVsLXJlbW92ZS1pbWFnZS1idXR0b24td3JhcHBlclwiPlxyXG4gIDxidXR0b25cclxuICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAoY2xpY2spPVwic2F2ZSgpXCJcclxuICAgIG1hdFRvb2x0aXA9XCJTYXZlIGNoYW5nZXNcIlxyXG4gICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWJvdmVcIlxyXG4gICAgY2xhc3M9XCJpY29uLWJ1dHRvblwiXHJcbiAgPlxyXG4gICAgPG1hdC1pY29uPmRvbmU8L21hdC1pY29uPlxyXG4gIDwvYnV0dG9uPlxyXG4gIDxidXR0b25cclxuICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAoY2xpY2spPVwiY2xlYXIoKVwiXHJcbiAgICBtYXRUb29sdGlwPVwiRGlzY2FyZCBjaGFuZ2VzXCJcclxuICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImFib3ZlXCJcclxuICAgIGNsYXNzPVwiaWNvbi1idXR0b25cIlxyXG4gID5cclxuICAgIDxtYXQtaWNvbj51bmRvPC9tYXQtaWNvbj5cclxuICA8L2J1dHRvbj5cclxuPC9kaXY+XHJcbjxkaXYgY2xhc3M9XCJjYW52YXMtd3JhcHBlclwiPlxyXG4gIDxjYW52YXMgaWQ9XCJjYW52YXNcIiAjZHJhd2luZ0NhbnZhcz48L2NhbnZhcz5cclxuPC9kaXY+XHJcbiJdfQ==
@@ -1,5 +1,5 @@
1
1
  /*
2
2
  * Public API Surface of ngx-easy-image-drawing
3
3
  */
4
- export * from './lib/ngx-easy-image-drawing.component';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25neC1lYXN5LWltYWdlLWRyYXdpbmcvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLHdDQUF3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIG5neC1lYXN5LWltYWdlLWRyYXdpbmdcclxuICovXHJcblxyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9uZ3gtZWFzeS1pbWFnZS1kcmF3aW5nLmNvbXBvbmVudCc7XHJcbiJdfQ==
4
+ export * from './lib/easy-image-drawing.component';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25neC1lYXN5LWltYWdlLWRyYXdpbmcvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLG9DQUFvQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIG5neC1lYXN5LWltYWdlLWRyYXdpbmdcclxuICovXHJcblxyXG5leHBvcnQgKiBmcm9tICcuL2xpYi9lYXN5LWltYWdlLWRyYXdpbmcuY29tcG9uZW50JztcclxuIl19
@@ -1,7 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { EventEmitter, Component, Input, Output, ViewChild } from '@angular/core';
3
+ import * as i1 from '@angular/material/icon';
4
+ import { MatIconModule } from '@angular/material/icon';
3
5
 
4
- class NgxEasyImageDrawingComponent {
6
+ class EasyImageDrawing {
5
7
  constructor() {
6
8
  this.width = 500;
7
9
  this.height = 500;
@@ -90,12 +92,12 @@ class NgxEasyImageDrawingComponent {
90
92
  window.removeEventListener('mousemove', this._mousemove);
91
93
  window.removeEventListener('mouseup', this._mouseup);
92
94
  }
93
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: NgxEasyImageDrawingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
94
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.3", type: NgxEasyImageDrawingComponent, isStandalone: true, selector: "lib-ngx-easy-image-drawing", inputs: { width: "width", height: "height", lineWidth: "lineWidth", lineColor: "lineColor", src: "src" }, outputs: { savedImage: "savedImage" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["drawingCanvas"], descendants: true }], ngImport: i0, template: ` <p>ngx-easy-image-drawing works!</p> `, isInline: true, styles: [""] }); }
95
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: EasyImageDrawing, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
96
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.3", type: EasyImageDrawing, isStandalone: true, selector: "easy-image-drawing", inputs: { width: "width", height: "height", lineWidth: "lineWidth", lineColor: "lineColor", src: "src" }, outputs: { savedImage: "savedImage" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["drawingCanvas"], descendants: true }], ngImport: i0, template: "<div class=\"bel-remove-image-button-wrapper\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"save()\"\r\n matTooltip=\"Save changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n matTooltip=\"Discard changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>undo</mat-icon>\r\n </button>\r\n</div>\r\n<div class=\"canvas-wrapper\">\r\n <canvas id=\"canvas\" #drawingCanvas></canvas>\r\n</div>\r\n", styles: ["@media only screen and (max-width: 900px){:host{display:flex;flex-direction:column;height:100%}}.bel-remove-image-button-wrapper{display:flex;justify-content:flex-end;margin:0 10px 10px 0}.bel-remove-image-button-wrapper .icon-button{color:var(--primary-color)}#canvas{border:1px solid #ccc;max-width:400px;max-height:700px;cursor:crosshair}.canvas-wrapper{display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
95
97
  }
96
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: NgxEasyImageDrawingComponent, decorators: [{
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: EasyImageDrawing, decorators: [{
97
99
  type: Component,
98
- args: [{ selector: 'lib-ngx-easy-image-drawing', standalone: true, imports: [], template: ` <p>ngx-easy-image-drawing works!</p> ` }]
100
+ args: [{ selector: 'easy-image-drawing', standalone: true, imports: [MatIconModule], template: "<div class=\"bel-remove-image-button-wrapper\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"save()\"\r\n matTooltip=\"Save changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n matTooltip=\"Discard changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>undo</mat-icon>\r\n </button>\r\n</div>\r\n<div class=\"canvas-wrapper\">\r\n <canvas id=\"canvas\" #drawingCanvas></canvas>\r\n</div>\r\n", styles: ["@media only screen and (max-width: 900px){:host{display:flex;flex-direction:column;height:100%}}.bel-remove-image-button-wrapper{display:flex;justify-content:flex-end;margin:0 10px 10px 0}.bel-remove-image-button-wrapper .icon-button{color:var(--primary-color)}#canvas{border:1px solid #ccc;max-width:400px;max-height:700px;cursor:crosshair}.canvas-wrapper{display:flex;align-items:center;justify-content:center}\n"] }]
99
101
  }], propDecorators: { width: [{
100
102
  type: Input
101
103
  }], height: [{
@@ -121,5 +123,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.3", ngImpor
121
123
  * Generated bundle index. Do not edit.
122
124
  */
123
125
 
124
- export { NgxEasyImageDrawingComponent };
126
+ export { EasyImageDrawing };
125
127
  //# sourceMappingURL=ngx-easy-image-drawing.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-easy-image-drawing.mjs","sources":["../../../projects/ngx-easy-image-drawing/src/lib/ngx-easy-image-drawing.component.ts","../../../projects/ngx-easy-image-drawing/src/public-api.ts","../../../projects/ngx-easy-image-drawing/src/ngx-easy-image-drawing.ts"],"sourcesContent":["import {\r\n Component,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n OnDestroy,\r\n} from '@angular/core';\r\n\r\n@Component({\r\n selector: 'lib-ngx-easy-image-drawing',\r\n standalone: true,\r\n imports: [],\r\n template: ` <p>ngx-easy-image-drawing works!</p> `,\r\n styles: ``,\r\n})\r\nexport class NgxEasyImageDrawingComponent implements AfterViewInit, OnDestroy {\r\n @Input() width: number = 500;\r\n @Input() height: number = 500;\r\n @Input() lineWidth = 7;\r\n @Input() lineColor = '#000000';\r\n @Input() src = '';\r\n @Output() savedImage = new EventEmitter<File>();\r\n\r\n // its important myCanvas matches the variable name in the template\r\n @ViewChild('drawingCanvas') canvas!: ElementRef<HTMLCanvasElement>;\r\n\r\n context!: CanvasRenderingContext2D;\r\n private previousPosition: { x: number; y: number } = { x: 0, y: 0 };\r\n private activePath = false;\r\n\r\n private _mousedown: any = null;\r\n private _mousemove: any = null;\r\n private _mouseup: any = null;\r\n\r\n ngAfterViewInit(): void {\r\n this.canvas.nativeElement.width = this.width;\r\n this.canvas.nativeElement.height = this.height;\r\n\r\n this.context = this.canvas.nativeElement.getContext('2d')!;\r\n this.context.lineWidth = this.lineWidth;\r\n this.context.strokeStyle = this.lineColor;\r\n this.context.lineCap = 'round';\r\n\r\n // set src to image\r\n const image = new Image();\r\n image.src = this.src;\r\n image.onload = () => {\r\n this.context.drawImage(image, 0, 0, this.width, this.height);\r\n };\r\n\r\n this._mousedown = window.addEventListener(\r\n 'mousedown',\r\n (event: MouseEvent) => {\r\n this.activePath = true;\r\n this.context.beginPath();\r\n this.previousPosition = this.getMousePosition(event);\r\n }\r\n );\r\n\r\n this._mousemove = window.addEventListener('mousemove', (event) => {\r\n event.preventDefault();\r\n if (this.activePath) {\r\n this._drawLine(event);\r\n }\r\n });\r\n\r\n this._mouseup = window.addEventListener('mouseup', () => {\r\n if (this.activePath) {\r\n this.context.closePath();\r\n this.activePath = false;\r\n }\r\n });\r\n }\r\n\r\n public save(): void {\r\n const dataUrl = this.canvas.nativeElement.toDataURL('image/png');\r\n const blob = this._dataURItoBlob(dataUrl);\r\n this.savedImage.next(new File([blob], 'image.png'));\r\n }\r\n\r\n public clear(): void {\r\n this.context.clearRect(0, 0, this.width, this.height);\r\n const image = new Image();\r\n image.src = this.src;\r\n image.onload = () => {\r\n this.context.drawImage(image, 0, 0, this.width, this.height);\r\n };\r\n }\r\n\r\n private _dataURItoBlob(dataUrl: string) {\r\n const byteString = atob(dataUrl.split(',')[1]);\r\n const mimeString = dataUrl.split(',')[0].split(':')[1].split(';')[0];\r\n const ab = new ArrayBuffer(byteString.length);\r\n const dw = new DataView(ab);\r\n for (let i = 0; i < byteString.length; i++) {\r\n dw.setUint8(i, byteString.charCodeAt(i));\r\n }\r\n return new Blob([ab], { type: mimeString });\r\n }\r\n\r\n private _drawLine(event: MouseEvent): void {\r\n const currentPosition = this.getMousePosition(event);\r\n this.context.moveTo(this.previousPosition.x, this.previousPosition.y);\r\n this.context.lineTo(currentPosition.x, currentPosition.y);\r\n this.previousPosition = currentPosition;\r\n this.context.stroke();\r\n }\r\n\r\n private getMousePosition(event: MouseEvent): { x: number; y: number } {\r\n const rect = this.canvas.nativeElement.getBoundingClientRect();\r\n const scaleX = this.canvas.nativeElement.width / rect.width;\r\n const scaleY = this.canvas.nativeElement.height / rect.height;\r\n return {\r\n x: (event.clientX - rect.left) * scaleX,\r\n y: (event.clientY - rect.top) * scaleY,\r\n };\r\n }\r\n\r\n ngOnDestroy(): void {\r\n window.removeEventListener('mousedown', this._mousedown);\r\n window.removeEventListener('mousemove', this._mousemove);\r\n window.removeEventListener('mouseup', this._mouseup);\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ngx-easy-image-drawing\r\n */\r\n\r\nexport * from './lib/ngx-easy-image-drawing.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-easy-image-drawing.mjs","sources":["../../../projects/ngx-easy-image-drawing/src/lib/easy-image-drawing.component.ts","../../../projects/ngx-easy-image-drawing/src/lib/easy-image-drawing.component.html","../../../projects/ngx-easy-image-drawing/src/public-api.ts","../../../projects/ngx-easy-image-drawing/src/ngx-easy-image-drawing.ts"],"sourcesContent":["import {\r\n Component,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n OnDestroy,\r\n} from '@angular/core';\r\nimport { MatIconModule } from '@angular/material/icon';\r\n\r\n@Component({\r\n selector: 'easy-image-drawing',\r\n standalone: true,\r\n imports: [MatIconModule],\r\n templateUrl: './easy-image-drawing.component.html',\r\n styleUrls: ['./easy-image-drawing.component.scss'],\r\n})\r\nexport class EasyImageDrawing implements AfterViewInit, OnDestroy {\r\n @Input() width: number = 500;\r\n @Input() height: number = 500;\r\n @Input() lineWidth = 7;\r\n @Input() lineColor = '#000000';\r\n @Input() src = '';\r\n @Output() savedImage = new EventEmitter<File>();\r\n\r\n // its important myCanvas matches the variable name in the template\r\n @ViewChild('drawingCanvas') canvas!: ElementRef<HTMLCanvasElement>;\r\n\r\n context!: CanvasRenderingContext2D;\r\n private previousPosition: { x: number; y: number } = { x: 0, y: 0 };\r\n private activePath = false;\r\n\r\n private _mousedown: any = null;\r\n private _mousemove: any = null;\r\n private _mouseup: any = null;\r\n\r\n ngAfterViewInit(): void {\r\n this.canvas.nativeElement.width = this.width;\r\n this.canvas.nativeElement.height = this.height;\r\n\r\n this.context = this.canvas.nativeElement.getContext('2d')!;\r\n this.context.lineWidth = this.lineWidth;\r\n this.context.strokeStyle = this.lineColor;\r\n this.context.lineCap = 'round';\r\n\r\n // set src to image\r\n const image = new Image();\r\n image.src = this.src;\r\n image.onload = () => {\r\n this.context.drawImage(image, 0, 0, this.width, this.height);\r\n };\r\n\r\n this._mousedown = window.addEventListener(\r\n 'mousedown',\r\n (event: MouseEvent) => {\r\n this.activePath = true;\r\n this.context.beginPath();\r\n this.previousPosition = this.getMousePosition(event);\r\n }\r\n );\r\n\r\n this._mousemove = window.addEventListener('mousemove', (event) => {\r\n event.preventDefault();\r\n if (this.activePath) {\r\n this._drawLine(event);\r\n }\r\n });\r\n\r\n this._mouseup = window.addEventListener('mouseup', () => {\r\n if (this.activePath) {\r\n this.context.closePath();\r\n this.activePath = false;\r\n }\r\n });\r\n }\r\n\r\n public save(): void {\r\n const dataUrl = this.canvas.nativeElement.toDataURL('image/png');\r\n const blob = this._dataURItoBlob(dataUrl);\r\n this.savedImage.next(new File([blob], 'image.png'));\r\n }\r\n\r\n public clear(): void {\r\n this.context.clearRect(0, 0, this.width, this.height);\r\n const image = new Image();\r\n image.src = this.src;\r\n image.onload = () => {\r\n this.context.drawImage(image, 0, 0, this.width, this.height);\r\n };\r\n }\r\n\r\n private _dataURItoBlob(dataUrl: string) {\r\n const byteString = atob(dataUrl.split(',')[1]);\r\n const mimeString = dataUrl.split(',')[0].split(':')[1].split(';')[0];\r\n const ab = new ArrayBuffer(byteString.length);\r\n const dw = new DataView(ab);\r\n for (let i = 0; i < byteString.length; i++) {\r\n dw.setUint8(i, byteString.charCodeAt(i));\r\n }\r\n return new Blob([ab], { type: mimeString });\r\n }\r\n\r\n private _drawLine(event: MouseEvent): void {\r\n const currentPosition = this.getMousePosition(event);\r\n this.context.moveTo(this.previousPosition.x, this.previousPosition.y);\r\n this.context.lineTo(currentPosition.x, currentPosition.y);\r\n this.previousPosition = currentPosition;\r\n this.context.stroke();\r\n }\r\n\r\n private getMousePosition(event: MouseEvent): { x: number; y: number } {\r\n const rect = this.canvas.nativeElement.getBoundingClientRect();\r\n const scaleX = this.canvas.nativeElement.width / rect.width;\r\n const scaleY = this.canvas.nativeElement.height / rect.height;\r\n return {\r\n x: (event.clientX - rect.left) * scaleX,\r\n y: (event.clientY - rect.top) * scaleY,\r\n };\r\n }\r\n\r\n ngOnDestroy(): void {\r\n window.removeEventListener('mousedown', this._mousedown);\r\n window.removeEventListener('mousemove', this._mousemove);\r\n window.removeEventListener('mouseup', this._mouseup);\r\n }\r\n}\r\n","<div class=\"bel-remove-image-button-wrapper\">\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"save()\"\r\n matTooltip=\"Save changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n matTooltip=\"Discard changes\"\r\n matTooltipPosition=\"above\"\r\n class=\"icon-button\"\r\n >\r\n <mat-icon>undo</mat-icon>\r\n </button>\r\n</div>\r\n<div class=\"canvas-wrapper\">\r\n <canvas id=\"canvas\" #drawingCanvas></canvas>\r\n</div>\r\n","/*\r\n * Public API Surface of ngx-easy-image-drawing\r\n */\r\n\r\nexport * from './lib/easy-image-drawing.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { ElementRef, AfterViewInit, EventEmitter, OnDestroy } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
- export declare class NgxEasyImageDrawingComponent implements AfterViewInit, OnDestroy {
3
+ export declare class EasyImageDrawing implements AfterViewInit, OnDestroy {
4
4
  width: number;
5
5
  height: number;
6
6
  lineWidth: number;
@@ -21,6 +21,6 @@ export declare class NgxEasyImageDrawingComponent implements AfterViewInit, OnDe
21
21
  private _drawLine;
22
22
  private getMousePosition;
23
23
  ngOnDestroy(): void;
24
- static ɵfac: i0.ɵɵFactoryDeclaration<NgxEasyImageDrawingComponent, never>;
25
- static ɵcmp: i0.ɵɵComponentDeclaration<NgxEasyImageDrawingComponent, "lib-ngx-easy-image-drawing", never, { "width": { "alias": "width"; "required": false; }; "height": { "alias": "height"; "required": false; }; "lineWidth": { "alias": "lineWidth"; "required": false; }; "lineColor": { "alias": "lineColor"; "required": false; }; "src": { "alias": "src"; "required": false; }; }, { "savedImage": "savedImage"; }, never, never, true, never>;
24
+ static ɵfac: i0.ɵɵFactoryDeclaration<EasyImageDrawing, never>;
25
+ static ɵcmp: i0.ɵɵComponentDeclaration<EasyImageDrawing, "easy-image-drawing", never, { "width": { "alias": "width"; "required": false; }; "height": { "alias": "height"; "required": false; }; "lineWidth": { "alias": "lineWidth"; "required": false; }; "lineColor": { "alias": "lineColor"; "required": false; }; "src": { "alias": "src"; "required": false; }; }, { "savedImage": "savedImage"; }, never, never, true, never>;
26
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-easy-image-drawing",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^18.1.0",
6
6
  "@angular/core": "^18.1.0"
@@ -33,4 +33,4 @@
33
33
  ],
34
34
  "author": "Alex Voronin <alex.varonin@gmail.com>",
35
35
  "license": "ISC"
36
- }
36
+ }
package/public-api.d.ts CHANGED
@@ -1 +1 @@
1
- export * from './lib/ngx-easy-image-drawing.component';
1
+ export * from './lib/easy-image-drawing.component';
@@ -1,114 +0,0 @@
1
- import { Component, ViewChild, Input, Output, EventEmitter, } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- export class NgxEasyImageDrawingComponent {
4
- constructor() {
5
- this.width = 500;
6
- this.height = 500;
7
- this.lineWidth = 7;
8
- this.lineColor = '#000000';
9
- this.src = '';
10
- this.savedImage = new EventEmitter();
11
- this.previousPosition = { x: 0, y: 0 };
12
- this.activePath = false;
13
- this._mousedown = null;
14
- this._mousemove = null;
15
- this._mouseup = null;
16
- }
17
- ngAfterViewInit() {
18
- this.canvas.nativeElement.width = this.width;
19
- this.canvas.nativeElement.height = this.height;
20
- this.context = this.canvas.nativeElement.getContext('2d');
21
- this.context.lineWidth = this.lineWidth;
22
- this.context.strokeStyle = this.lineColor;
23
- this.context.lineCap = 'round';
24
- // set src to image
25
- const image = new Image();
26
- image.src = this.src;
27
- image.onload = () => {
28
- this.context.drawImage(image, 0, 0, this.width, this.height);
29
- };
30
- this._mousedown = window.addEventListener('mousedown', (event) => {
31
- this.activePath = true;
32
- this.context.beginPath();
33
- this.previousPosition = this.getMousePosition(event);
34
- });
35
- this._mousemove = window.addEventListener('mousemove', (event) => {
36
- event.preventDefault();
37
- if (this.activePath) {
38
- this._drawLine(event);
39
- }
40
- });
41
- this._mouseup = window.addEventListener('mouseup', () => {
42
- if (this.activePath) {
43
- this.context.closePath();
44
- this.activePath = false;
45
- }
46
- });
47
- }
48
- save() {
49
- const dataUrl = this.canvas.nativeElement.toDataURL('image/png');
50
- const blob = this._dataURItoBlob(dataUrl);
51
- this.savedImage.next(new File([blob], 'image.png'));
52
- }
53
- clear() {
54
- this.context.clearRect(0, 0, this.width, this.height);
55
- const image = new Image();
56
- image.src = this.src;
57
- image.onload = () => {
58
- this.context.drawImage(image, 0, 0, this.width, this.height);
59
- };
60
- }
61
- _dataURItoBlob(dataUrl) {
62
- const byteString = atob(dataUrl.split(',')[1]);
63
- const mimeString = dataUrl.split(',')[0].split(':')[1].split(';')[0];
64
- const ab = new ArrayBuffer(byteString.length);
65
- const dw = new DataView(ab);
66
- for (let i = 0; i < byteString.length; i++) {
67
- dw.setUint8(i, byteString.charCodeAt(i));
68
- }
69
- return new Blob([ab], { type: mimeString });
70
- }
71
- _drawLine(event) {
72
- const currentPosition = this.getMousePosition(event);
73
- this.context.moveTo(this.previousPosition.x, this.previousPosition.y);
74
- this.context.lineTo(currentPosition.x, currentPosition.y);
75
- this.previousPosition = currentPosition;
76
- this.context.stroke();
77
- }
78
- getMousePosition(event) {
79
- const rect = this.canvas.nativeElement.getBoundingClientRect();
80
- const scaleX = this.canvas.nativeElement.width / rect.width;
81
- const scaleY = this.canvas.nativeElement.height / rect.height;
82
- return {
83
- x: (event.clientX - rect.left) * scaleX,
84
- y: (event.clientY - rect.top) * scaleY,
85
- };
86
- }
87
- ngOnDestroy() {
88
- window.removeEventListener('mousedown', this._mousedown);
89
- window.removeEventListener('mousemove', this._mousemove);
90
- window.removeEventListener('mouseup', this._mouseup);
91
- }
92
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: NgxEasyImageDrawingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
93
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.3", type: NgxEasyImageDrawingComponent, isStandalone: true, selector: "lib-ngx-easy-image-drawing", inputs: { width: "width", height: "height", lineWidth: "lineWidth", lineColor: "lineColor", src: "src" }, outputs: { savedImage: "savedImage" }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["drawingCanvas"], descendants: true }], ngImport: i0, template: ` <p>ngx-easy-image-drawing works!</p> `, isInline: true, styles: [""] }); }
94
- }
95
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: NgxEasyImageDrawingComponent, decorators: [{
96
- type: Component,
97
- args: [{ selector: 'lib-ngx-easy-image-drawing', standalone: true, imports: [], template: ` <p>ngx-easy-image-drawing works!</p> ` }]
98
- }], propDecorators: { width: [{
99
- type: Input
100
- }], height: [{
101
- type: Input
102
- }], lineWidth: [{
103
- type: Input
104
- }], lineColor: [{
105
- type: Input
106
- }], src: [{
107
- type: Input
108
- }], savedImage: [{
109
- type: Output
110
- }], canvas: [{
111
- type: ViewChild,
112
- args: ['drawingCanvas']
113
- }] } });
114
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWVhc3ktaW1hZ2UtZHJhd2luZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWFzeS1pbWFnZS1kcmF3aW5nL3NyYy9saWIvbmd4LWVhc3ktaW1hZ2UtZHJhd2luZy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxTQUFTLEVBR1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEdBRWIsTUFBTSxlQUFlLENBQUM7O0FBU3ZCLE1BQU0sT0FBTyw0QkFBNEI7SUFQekM7UUFRVyxVQUFLLEdBQVcsR0FBRyxDQUFDO1FBQ3BCLFdBQU0sR0FBVyxHQUFHLENBQUM7UUFDckIsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNkLGNBQVMsR0FBRyxTQUFTLENBQUM7UUFDdEIsUUFBRyxHQUFHLEVBQUUsQ0FBQztRQUNSLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBTXhDLHFCQUFnQixHQUE2QixFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQzVELGVBQVUsR0FBRyxLQUFLLENBQUM7UUFFbkIsZUFBVSxHQUFRLElBQUksQ0FBQztRQUN2QixlQUFVLEdBQVEsSUFBSSxDQUFDO1FBQ3ZCLGFBQVEsR0FBUSxJQUFJLENBQUM7S0EyRjlCO0lBekZDLGVBQWU7UUFDYixJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUUvQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUUsQ0FBQztRQUMzRCxJQUFJLENBQUMsT0FBTyxDQUFD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LCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBWaWV3Q2hpbGQsXHJcbiAgRWxlbWVudFJlZixcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIElucHV0LFxyXG4gIE91dHB1dCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgT25EZXN0cm95LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdsaWItbmd4LWVhc3ktaW1hZ2UtZHJhd2luZycsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbXSxcclxuICB0ZW1wbGF0ZTogYCA8cD5uZ3gtZWFzeS1pbWFnZS1kcmF3aW5nIHdvcmtzITwvcD4gYCxcclxuICBzdHlsZXM6IGBgLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmd4RWFzeUltYWdlRHJhd2luZ0NvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XHJcbiAgQElucHV0KCkgd2lkdGg6IG51bWJlciA9IDUwMDtcclxuICBASW5wdXQoKSBoZWlnaHQ6IG51bWJlciA9IDUwMDtcclxuICBASW5wdXQoKSBsaW5lV2lkdGggPSA3O1xyXG4gIEBJbnB1dCgpIGxpbmVDb2xvciA9ICcjMDAwMDAwJztcclxuICBASW5wdXQoKSBzcmMgPSAnJztcclxuICBAT3V0cHV0KCkgc2F2ZWRJbWFnZSA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZT4oKTtcclxuXHJcbiAgLy8gaXRzIGltcG9ydGFudCBteUNhbnZhcyBtYXRjaGVzIHRoZSB2YXJpYWJsZSBuYW1lIGluIHRoZSB0ZW1wbGF0ZVxyXG4gIEBWaWV3Q2hpbGQoJ2RyYXdpbmdDYW52YXMnKSBjYW52YXMhOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcclxuXHJcbiAgY29udGV4dCE6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcclxuICBwcml2YXRlIHByZXZpb3VzUG9zaXRpb246IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9IHsgeDogMCwgeTogMCB9O1xyXG4gIHByaXZhdGUgYWN0aXZlUGF0aCA9IGZhbHNlO1xyXG5cclxuICBwcml2YXRlIF9tb3VzZWRvd246IGFueSA9IG51bGw7XHJcbiAgcHJpdmF0ZSBfbW91c2Vtb3ZlOiBhbnkgPSBudWxsO1xyXG4gIHByaXZhdGUgX21vdXNldXA6IGFueSA9IG51bGw7XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2FudmFzLm5hdGl2ZUVsZW1lbnQud2lkdGggPSB0aGlzLndpZHRoO1xyXG4gICAgdGhpcy5jYW52YXMubmF0aXZlRWxlbWVudC5oZWlnaHQgPSB0aGlzLmhlaWdodDtcclxuXHJcbiAgICB0aGlzLmNvbnRleHQgPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50LmdldENvbnRleHQoJzJkJykhO1xyXG4gICAgdGhpcy5jb250ZXh0LmxpbmVXaWR0aCA9IHRoaXMubGluZVdpZHRoO1xyXG4gICAgdGhpcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gdGhpcy5saW5lQ29sb3I7XHJcbiAgICB0aGlzLmNvbnRleHQubGluZUNhcCA9ICdyb3VuZCc7XHJcblxyXG4gICAgLy8gc2V0IHNyYyB0byBpbWFnZVxyXG4gICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcclxuICAgIGltYWdlLnNyYyA9IHRoaXMuc3JjO1xyXG4gICAgaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuX21vdXNlZG93biA9IHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxyXG4gICAgICAnbW91c2Vkb3duJyxcclxuICAgICAgKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgdGhpcy5hY3RpdmVQYXRoID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmNvbnRleHQuYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgdGhpcy5wcmV2aW91c1Bvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcclxuICAgICAgfVxyXG4gICAgKTtcclxuXHJcbiAgICB0aGlzLl9tb3VzZW1vdmUgPSB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGV2ZW50KSA9PiB7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIGlmICh0aGlzLmFjdGl2ZVBhdGgpIHtcclxuICAgICAgICB0aGlzLl9kcmF3TGluZShldmVudCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuX21vdXNldXAgPSB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICgpID0+IHtcclxuICAgICAgaWYgKHRoaXMuYWN0aXZlUGF0aCkge1xyXG4gICAgICAgIHRoaXMuY29udGV4dC5jbG9zZVBhdGgoKTtcclxuICAgICAgICB0aGlzLmFjdGl2ZVBhdGggPSBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2F2ZSgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGRhdGFVcmwgPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50LnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XHJcbiAgICBjb25zdCBibG9iID0gdGhpcy5fZGF0YVVSSXRvQmxvYihkYXRhVXJsKTtcclxuICAgIHRoaXMuc2F2ZWRJbWFnZS5uZXh0KG5ldyBGaWxlKFtibG9iXSwgJ2ltYWdlLnBuZycpKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcclxuICAgIHRoaXMuY29udGV4dC5jbGVhclJlY3QoMCwgMCwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xyXG4gICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcclxuICAgIGltYWdlLnNyYyA9IHRoaXMuc3JjO1xyXG4gICAgaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICB0aGlzLmNvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfZGF0YVVSSXRvQmxvYihkYXRhVXJsOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IGJ5dGVTdHJpbmcgPSBhdG9iKGRhdGFVcmwuc3BsaXQoJywnKVsxXSk7XHJcbiAgICBjb25zdCBtaW1lU3RyaW5nID0gZGF0YVVybC5zcGxpdCgnLCcpWzBdLnNwbGl0KCc6JylbMV0uc3BsaXQoJzsnKVswXTtcclxuICAgIGNvbnN0IGFiID0gbmV3IEFycmF5QnVmZmVyKGJ5dGVTdHJpbmcubGVuZ3RoKTtcclxuICAgIGNvbnN0IGR3ID0gbmV3IERhdGFWaWV3KGFiKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZVN0cmluZy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBkdy5zZXRVaW50OChpLCBieXRlU3RyaW5nLmNoYXJDb2RlQXQoaSkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5ldyBCbG9iKFthYl0sIHsgdHlwZTogbWltZVN0cmluZyB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2RyYXdMaW5lKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICBjb25zdCBjdXJyZW50UG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpO1xyXG4gICAgdGhpcy5jb250ZXh0Lm1vdmVUbyh0aGlzLnByZXZpb3VzUG9zaXRpb24ueCwgdGhpcy5wcmV2aW91c1Bvc2l0aW9uLnkpO1xyXG4gICAgdGhpcy5jb250ZXh0LmxpbmVUbyhjdXJyZW50UG9zaXRpb24ueCwgY3VycmVudFBvc2l0aW9uLnkpO1xyXG4gICAgdGhpcy5wcmV2aW91c1Bvc2l0aW9uID0gY3VycmVudFBvc2l0aW9uO1xyXG4gICAgdGhpcy5jb250ZXh0LnN0cm9rZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRNb3VzZVBvc2l0aW9uKGV2ZW50OiBNb3VzZUV2ZW50KTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcclxuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3Qgc2NhbGVYID0gdGhpcy5jYW52YXMubmF0aXZlRWxlbWVudC53aWR0aCAvIHJlY3Qud2lkdGg7XHJcbiAgICBjb25zdCBzY2FsZVkgPSB0aGlzLmNhbnZhcy5uYXRpdmVFbGVtZW50LmhlaWdodCAvIHJlY3QuaGVpZ2h0O1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgeDogKGV2ZW50LmNsaWVudFggLSByZWN0LmxlZnQpICogc2NhbGVYLFxyXG4gICAgICB5OiAoZXZlbnQuY2xpZW50WSAtIHJlY3QudG9wKSAqIHNjYWxlWSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLl9tb3VzZWRvd24pO1xyXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuX21vdXNlbW92ZSk7XHJcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuX21vdXNldXApO1xyXG4gIH1cclxufVxyXG4iXX0=