@libs-ui/components-audio 0.2.189 → 0.2.190
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 +108 -2
- package/audio.component.d.ts +2 -2
- package/demo.component.d.ts +20 -0
- package/esm2022/audio.component.mjs +6 -9
- package/esm2022/demo.component.mjs +128 -0
- package/esm2022/index.mjs +2 -1
- package/fesm2022/libs-ui-components-audio.mjs +131 -9
- package/fesm2022/libs-ui-components-audio.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,3 +1,109 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Component Audio
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Tính năng
|
|
4
|
+
|
|
5
|
+
- Control play/pause âm thanh
|
|
6
|
+
- Control âm lượng với chức năng mute
|
|
7
|
+
- Hiển thị thời gian theo định dạng HH:MM:SS
|
|
8
|
+
- Progress bar với chức năng seek
|
|
9
|
+
- Khả năng download audio với permission control
|
|
10
|
+
- Thiết kế responsive sử dụng Tailwind CSS
|
|
11
|
+
- Source audio có thể cấu hình
|
|
12
|
+
|
|
13
|
+
## Cài đặt
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @libs-ui/components-audio
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Cách sử dụng cơ bản
|
|
20
|
+
|
|
21
|
+
Import component vào module hoặc standalone component của bạn:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { LibsUiComponentsAudioComponent } from '@libs-ui/components-audio';
|
|
25
|
+
|
|
26
|
+
@Component({
|
|
27
|
+
selector: 'your-component',
|
|
28
|
+
standalone: true,
|
|
29
|
+
imports: [LibsUiComponentsAudioComponent],
|
|
30
|
+
template: `
|
|
31
|
+
<libs_ui-components-audio
|
|
32
|
+
fileAudio="https://example.com/audio.mp3"
|
|
33
|
+
[checkPermissionDownloadAudio]="checkDownloadPermission"
|
|
34
|
+
/>
|
|
35
|
+
`
|
|
36
|
+
})
|
|
37
|
+
export class YourComponent {
|
|
38
|
+
checkDownloadPermission(): Promise<boolean> {
|
|
39
|
+
// Your logic to determine if download is allowed
|
|
40
|
+
return Promise.resolve(true);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Inputs
|
|
46
|
+
|
|
47
|
+
| Input | Type | Required | Description |
|
|
48
|
+
|-------|------|----------|-------------|
|
|
49
|
+
| `fileAudio` | `string` | Yes | URL của file audio cần phát |
|
|
50
|
+
| `checkPermissionDownloadAudio` | `() => Promise<boolean>` | Yes | Function trả về promise với kết quả boolean cho biết nếu được phép download |
|
|
51
|
+
|
|
52
|
+
## UI Features
|
|
53
|
+
|
|
54
|
+
### Audio Controls
|
|
55
|
+
- Button play/pause
|
|
56
|
+
- Hiển thị current time và duration (định dạng HH:MM:SS)
|
|
57
|
+
- Progress bar với chức năng seek
|
|
58
|
+
|
|
59
|
+
### Volume Controls
|
|
60
|
+
- Button mute/unmute
|
|
61
|
+
- Volume slider (hiển thị khi hover)
|
|
62
|
+
|
|
63
|
+
### Download
|
|
64
|
+
- Button download cần kiểm tra permission
|
|
65
|
+
|
|
66
|
+
## CSS Classes
|
|
67
|
+
|
|
68
|
+
Component sử dụng các class của Tailwind và các custom icon classes:
|
|
69
|
+
|
|
70
|
+
- `.libs-ui-disable` - Áp dụng cho player bị disabled
|
|
71
|
+
- `.pointer-events-none` - Áp dụng khi player bị disabled
|
|
72
|
+
- `.libs-ui-font-h5r` - Áp dụng cho time display
|
|
73
|
+
- `.libs-ui-icon-play-solid` - Icon play
|
|
74
|
+
- `.libs-ui-icon-pause-solid` - Icon pause
|
|
75
|
+
- `.libs-ui-icon-speaker-on-solid` - Icon speaker (volume on)
|
|
76
|
+
- `.libs-ui-icon-speaker-off-solid` - Icon speaker (volume off/mute)
|
|
77
|
+
- `.libs-ui-icon-download-solid` - Icon download
|
|
78
|
+
|
|
79
|
+
## Dependencies
|
|
80
|
+
|
|
81
|
+
- Angular 16+
|
|
82
|
+
- RxJS
|
|
83
|
+
- @libs-ui/components-inputs-range-slider
|
|
84
|
+
|
|
85
|
+
## Example Implementation
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
@Component({
|
|
89
|
+
selector: 'app-audio-player',
|
|
90
|
+
standalone: true,
|
|
91
|
+
imports: [LibsUiComponentsAudioComponent],
|
|
92
|
+
template: `
|
|
93
|
+
<libs_ui-components-audio
|
|
94
|
+
fileAudio="https://example.com/audio.mp3"
|
|
95
|
+
[checkPermissionDownloadAudio]="checkDownloadPermission"
|
|
96
|
+
/>
|
|
97
|
+
`
|
|
98
|
+
})
|
|
99
|
+
export class AudioPlayerComponent {
|
|
100
|
+
checkDownloadPermission(): Promise<boolean> {
|
|
101
|
+
// Example implementation - can be replaced with actual permission logic
|
|
102
|
+
return new Promise(resolve => {
|
|
103
|
+
// Check user permissions, authentication, or any other business logic
|
|
104
|
+
const isAllowed = true;
|
|
105
|
+
resolve(isAllowed);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
package/audio.component.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare class LibsUiComponentsAudioComponent implements AfterViewInit, On
|
|
|
12
12
|
protected showFullControlVolume: import("@angular/core").WritableSignal<boolean>;
|
|
13
13
|
private onDestroy;
|
|
14
14
|
readonly fileAudio: import("@angular/core").InputSignal<string>;
|
|
15
|
-
checkPermissionDownloadAudio
|
|
15
|
+
readonly checkPermissionDownloadAudio: import("@angular/core").InputSignal<() => Promise<boolean>>;
|
|
16
16
|
readonly audioRef: import("@angular/core").Signal<ElementRef<any>>;
|
|
17
17
|
readonly volumeControlRef: import("@angular/core").Signal<ElementRef<any>>;
|
|
18
18
|
ngAfterViewInit(): void;
|
|
@@ -29,5 +29,5 @@ export declare class LibsUiComponentsAudioComponent implements AfterViewInit, On
|
|
|
29
29
|
protected handlerDownload(e: Event): Promise<void>;
|
|
30
30
|
ngOnDestroy(): void;
|
|
31
31
|
static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiComponentsAudioComponent, never>;
|
|
32
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiComponentsAudioComponent, "libs_ui-components-audio", never, { "fileAudio": { "alias": "fileAudio"; "required": true; "isSignal": true; }; "checkPermissionDownloadAudio": { "alias": "checkPermissionDownloadAudio"; "required": true; }; }, {}, never, never, true, never>;
|
|
32
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiComponentsAudioComponent, "libs_ui-components-audio", never, { "fileAudio": { "alias": "fileAudio"; "required": true; "isSignal": true; }; "checkPermissionDownloadAudio": { "alias": "checkPermissionDownloadAudio"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
33
33
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
/**
|
|
3
|
+
* Demo component hiển thị các ví dụ khác nhau của Audio component
|
|
4
|
+
*/
|
|
5
|
+
export declare class LibsUiComponentsAudioDemoComponent {
|
|
6
|
+
/**
|
|
7
|
+
* Permission function luôn allow download
|
|
8
|
+
*/
|
|
9
|
+
basicPermissionCheck(): Promise<boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* Permission function không cho phép download
|
|
12
|
+
*/
|
|
13
|
+
denyPermissionCheck(): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Permission function có delay để mô phỏng API call
|
|
16
|
+
*/
|
|
17
|
+
delayedPermissionCheck(): Promise<boolean>;
|
|
18
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiComponentsAudioDemoComponent, never>;
|
|
19
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<LibsUiComponentsAudioDemoComponent, "lib-audio-demo", never, {}, {}, never, never, true, never>;
|
|
20
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, input,
|
|
1
|
+
import { ChangeDetectionStrategy, Component, input, signal, viewChild } from '@angular/core';
|
|
2
2
|
import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
|
|
3
3
|
import { fromEvent, merge, Subject, takeUntil, tap } from 'rxjs';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
@@ -16,7 +16,7 @@ export class LibsUiComponentsAudioComponent {
|
|
|
16
16
|
onDestroy = new Subject();
|
|
17
17
|
// #region INPUT
|
|
18
18
|
fileAudio = input.required();
|
|
19
|
-
checkPermissionDownloadAudio;
|
|
19
|
+
checkPermissionDownloadAudio = input.required();
|
|
20
20
|
/* VIEW CHILD */
|
|
21
21
|
audioRef = viewChild.required('audioRef');
|
|
22
22
|
volumeControlRef = viewChild.required('volumeControlRef');
|
|
@@ -111,7 +111,7 @@ export class LibsUiComponentsAudioComponent {
|
|
|
111
111
|
this.isPlay.set(false);
|
|
112
112
|
}
|
|
113
113
|
async handlerDownload(e) {
|
|
114
|
-
if (!this.checkPermissionDownloadAudio || !await this.checkPermissionDownloadAudio()) {
|
|
114
|
+
if (!this.checkPermissionDownloadAudio() || !await this.checkPermissionDownloadAudio()()) {
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
117
|
e.stopPropagation();
|
|
@@ -125,15 +125,12 @@ export class LibsUiComponentsAudioComponent {
|
|
|
125
125
|
this.onDestroy.complete();
|
|
126
126
|
}
|
|
127
127
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
128
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: LibsUiComponentsAudioComponent, isStandalone: true, selector: "libs_ui-components-audio", inputs: { fileAudio: { classPropertyName: "fileAudio", publicName: "fileAudio", isSignal: true, isRequired: true, transformFunction: null }, checkPermissionDownloadAudio: { classPropertyName: "checkPermissionDownloadAudio", publicName: "checkPermissionDownloadAudio", isSignal:
|
|
128
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: LibsUiComponentsAudioComponent, isStandalone: true, selector: "libs_ui-components-audio", inputs: { fileAudio: { classPropertyName: "fileAudio", publicName: "fileAudio", isSignal: true, isRequired: true, transformFunction: null }, checkPermissionDownloadAudio: { classPropertyName: "checkPermissionDownloadAudio", publicName: "checkPermissionDownloadAudio", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "audioRef", first: true, predicate: ["audioRef"], descendants: true, isSignal: true }, { propertyName: "volumeControlRef", first: true, predicate: ["volumeControlRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n", dependencies: [{ kind: "component", type: LibsUiComponentsInputsRangeSliderComponent, selector: "libs_ui-components-inputs-range_slider", inputs: ["mode", "min", "max", "value", "classInclude", "disable", "unit", "step", "hideProgressingValue", "formatNumber"], outputs: ["valueChange", "outChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
129
129
|
}
|
|
130
130
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioComponent, decorators: [{
|
|
131
131
|
type: Component,
|
|
132
132
|
args: [{ selector: 'libs_ui-components-audio', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
133
133
|
LibsUiComponentsInputsRangeSliderComponent
|
|
134
134
|
], template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n" }]
|
|
135
|
-
}]
|
|
136
|
-
type: Input,
|
|
137
|
-
args: [{ required: true }]
|
|
138
|
-
}] } });
|
|
139
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW8uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL2F1ZGlvL3NyYy9hdWRpby5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2F1ZGlvLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsU0FBUyxFQUFjLEtBQUssRUFBRSxLQUFLLEVBQWEsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxSSxPQUFPLEVBQUUsMENBQTBDLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNyRyxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBYyxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUFZN0UsTUFBTSxPQUFPLDhCQUE4QjtJQUN6QyxtQkFBbUI7SUFDVCxlQUFlLEdBQUcsTUFBTSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLGdCQUFnQixHQUFHLE1BQU0sQ0FBUyxHQUFHLENBQUMsQ0FBQztJQUN2QyxNQUFNLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLE1BQU0sR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDaEMsa0JBQWtCLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQzVDLFNBQVMsR0FBRyxNQUFNLENBQVUsSUFBSSxDQUFDLENBQUM7SUFDbEMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFTLE9BQU8sQ0FBQyxDQUFDO0lBQzNDLGlCQUFpQixHQUFHLE1BQU0sQ0FBUyxPQUFPLENBQUMsQ0FBQztJQUM1QyxxQkFBcUIsR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDakQsU0FBUyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFFeEMs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RVMsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFZO1FBQ3ZDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRVMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFRO1FBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsNEJBQTRCLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxFQUFFLENBQUM7WUFDckYsT0FBTztRQUNULENBQUM7UUFDRCxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDO1lBQ3RCLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDNUIsQ0FBQzt3R0FuSlUsOEJBQThCOzRGQUE5Qiw4QkFBOEIsNm9CQ2QzQyxzaEVBb0RBLDRDRHpDSSwwQ0FBMEM7OzRGQUdqQyw4QkFBOEI7a0JBVjFDLFNBQVM7K0JBRUUsMEJBQTBCLGNBRXhCLElBQUksbUJBQ0MsdUJBQXVCLENBQUMsTUFBTSxXQUN0Qzt3QkFDUCwwQ0FBMEM7cUJBQzNDOzhCQWlCMEIsNEJBQTRCO3NCQUF0RCxLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIGlucHV0LCBJbnB1dCwgT25EZXN0cm95LCBzaWduYWwsIHZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0lucHV0c1JhbmdlU2xpZGVyQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1pbnB1dHMtcmFuZ2Utc2xpZGVyJztcbmltcG9ydCB7IGZyb21FdmVudCwgbWVyZ2UsIE9ic2VydmFibGUsIFN1YmplY3QsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcyc7XG5cbkBDb21wb25lbnQoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ2xpYnNfdWktY29tcG9uZW50cy1hdWRpbycsXG4gIHRlbXBsYXRlVXJsOiAnLi9hdWRpby5jb21wb25lbnQuaHRtbCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbXG4gICAgTGlic1VpQ29tcG9uZW50c0lucHV0c1JhbmdlU2xpZGVyQ29tcG9uZW50XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpQ29tcG9uZW50c0F1ZGlvQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLy8gI3JlZ2lvbiBQUk9QRVJUWVxuICBwcm90ZWN0ZWQgYXVkaW9SYXRpb1ZhbHVlID0gc2lnbmFsPG51bWJlcj4oMCk7XG4gIHByb3RlY3RlZCB2b2x1bWVSYXRpb1ZhbHVlID0gc2lnbmFsPG51bWJlcj4oMTAwKTtcbiAgcHJvdGVjdGVkIGlzUGxheSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByb3RlY3RlZCBpc011dGUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcm90ZWN0ZWQgaXNTbGlkZXJBdWRpb1ByZXNzID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJvdGVjdGVkIGlzRGlzYWJsZSA9IHNpZ25hbDxib29sZWFuPih0cnVlKTtcbiAgcHJvdGVjdGVkIGF1ZGlvVGltZUN1cnJlbnQgPSBzaWduYWw8c3RyaW5nPignXzpfOl8nKTtcbiAgcHJvdGVjdGVkIGF1ZGlvVGltZUR1cmF0aW9uID0gc2lnbmFsPHN0cmluZz4oJ186XzpfJyk7XG4gIHByb3RlY3RlZCBzaG93RnVsbENvbnRyb2xWb2x1bWUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIG9uRGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLy8gI3JlZ2lvbiBJTlBVVFxuICByZWFkb25seSBmaWxlQXVkaW8gPSBpbnB1dC5yZXF1aXJlZDxzdHJpbmc+KCk7XG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGNoZWNrUGVybWlzc2lvbkRvd25sb2FkQXVkaW8/OiAoKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xuXG4gIC8qIFZJRVcgQ0hJTEQgKi9cbiAgcmVhZG9ubHkgYXVkaW9SZWYgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ2F1ZGlvUmVmJyk7XG4gIHJlYWRvbmx5IHZvbHVtZUNvbnRyb2xSZWYgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZj4oJ3ZvbHVtZUNvbnRyb2xSZWYnKTtcblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgbWVyZ2UoXG4gICAgICB0aGlzLmluaXRPYnNlcnZhYmxlKHRoaXMudm9sdW1lQ29udHJvbFJlZigpLm5hdGl2ZUVsZW1lbnQsICdtb3VzZWVudGVyJykucGlwZSh0YXAoKCkgPT4gdGhpcy5zaG93RnVsbENvbnRyb2xWb2x1bWUuc2V0KHRydWUpKSksXG4gICAgICB0aGlzLmluaXRPYnNlcnZhYmxlKHRoaXMudm9sdW1lQ29udHJvbFJlZigpLm5hdGl2ZUVsZW1lbnQsICdtb3VzZWxlYXZlJykucGlwZSh0YXAoKCkgPT4gdGhpcy5zaG93RnVsbENvbnRyb2xWb2x1bWUuc2V0KGZhbHNlKSkpXG4gICAgKS5waXBlKHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSkpLnN1YnNjcmliZSgpO1xuICB9XG4gIC8qIEZVTkNUSU9OUyAqL1xuICBwcml2YXRlIGluaXRPYnNlcnZhYmxlKGVsOiBIVE1MRWxlbWVudCwgZXZlbnROYW1lOiBzdHJpbmcpOiBPYnNlcnZhYmxlPE1vdXNlRXZlbnQ+IHtcbiAgICByZXR1cm4gZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KGVsLCBldmVudE5hbWUpLnBpcGUoXG4gICAgICB0YXAoZSA9PiBlLnN0b3BQcm9wYWdhdGlvbigpKSxcbiAgICAgIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSlcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJLZXlQcmVzc0F1ZGlvKCkge1xuICAgIHRoaXMuaXNTbGlkZXJBdWRpb1ByZXNzLnNldCh0cnVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyQXVkaW9NdXRlTXV0ZWQoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50Lm11dGVkID09PSB0cnVlKSB7XG4gICAgICB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5tdXRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5pc011dGUuc2V0KGZhbHNlKTtcbiAgICAgIHRoaXMudm9sdW1lUmF0aW9WYWx1ZS5zZXQoNTApO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudm9sdW1lUmF0aW9WYWx1ZS5zZXQoMCk7XG4gICAgdGhpcy5pc011dGUuc2V0KHRydWUpO1xuICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50Lm11dGVkID0gdHJ1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyQXVkaW9QYXVzZVBsYXkoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgYXVkaW9FbGVtZW50ID0gdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFhdWRpb0VsZW1lbnQucGF1c2VkKSB7XG4gICAgICBhdWRpb0VsZW1lbnQucGF1c2UoKTtcbiAgICAgIHRoaXMuaXNQbGF5LnNldChmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGF1ZGlvRWxlbWVudC5wbGF5KCk7XG4gICAgICB0aGlzLmlzUGxheS5zZXQodHJ1ZSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBsYXlpbmcgYXVkaW86JywgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyTG9hZGVkRGF0YShldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHRoaXMuYXVkaW9UaW1lRHVyYXRpb24uc2V0KGF3YWl0IHRoaXMudG9ISE1NU1MoTWF0aC5mbG9vcih0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5kdXJhdGlvbikpKTtcbiAgICAgIHRoaXMuYXVkaW9UaW1lQ3VycmVudC5zZXQoYXdhaXQgdGhpcy50b0hITU1TUyhNYXRoLmZsb29yKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmN1cnJlbnRUaW1lKSkpO1xuICAgICAgdGhpcy5pc0Rpc2FibGUuc2V0KGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlclRpbWVVcGRhdGUoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKCF0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmF1ZGlvVGltZUR1cmF0aW9uLnNldChhd2FpdCB0aGlzLnRvSEhNTVNTKE1hdGguZmxvb3IodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuZHVyYXRpb24pKSk7XG4gICAgdGhpcy5hdWRpb1RpbWVDdXJyZW50LnNldChhd2FpdCB0aGlzLnRvSEhNTVNTKE1hdGguZmxvb3IodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuY3VycmVudFRpbWUpKSk7XG4gICAgaWYgKHRoaXMuaXNTbGlkZXJBdWRpb1ByZXNzKCkpIHtcbiAgICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmN1cnJlbnRUaW1lID0gdGhpcy5hdWRpb1JhdGlvVmFsdWUoKSAqIE1hdGguZmxvb3IodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuZHVyYXRpb24pIC8gMTAwO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXVkaW9SYXRpb1ZhbHVlLnNldChNYXRoLmZsb29yKCh0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5jdXJyZW50VGltZSAvIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmR1cmF0aW9uKSAqIDEwMCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB0b0hITU1TUyh0aW1lOiBudW1iZXIpIHtcbiAgICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IodGltZSAvIDM2MDApO1xuICAgIGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKCh0aW1lIC0gKGhvdXJzICogMzYwMCkpIC8gNjApO1xuICAgIGNvbnN0IHNlY29uZHMgPSB0aW1lIC0gKGhvdXJzICogMzYwMCkgLSAobWludXRlcyAqIDYwKTtcblxuICAgIGNvbnN0IGdldExhYmVsID0gKCh2YWw6IG51bWJlcikgPT4ge1xuICAgICAgcmV0dXJuIGAke3ZhbCA8IDEwID8gJzAnIDogJyd9JHt2YWx9YDtcbiAgICB9KTtcblxuICAgIHJldHVybiBgJHtnZXRMYWJlbChob3Vycyl9OiR7Z2V0TGFiZWwobWludXRlcyl9OiR7Z2V0TGFiZWwoc2Vjb25kcyl9YDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyQ2hhbmdlQXVkaW8odmFsdWU6IG51bWJlcikge1xuICAgIGlmICh2YWx1ZSA9PT0gdGhpcy5hdWRpb1JhdGlvVmFsdWUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5jdXJyZW50VGltZSA9IHZhbHVlICogdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuZHVyYXRpb24gLyAxMDA7XG4gICAgdGhpcy5hdWRpb1JhdGlvVmFsdWUuc2V0KHZhbHVlKTtcbiAgICB0aGlzLmlzU2xpZGVyQXVkaW9QcmVzcy5zZXQoZmFsc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJDaGFuZ2VWb2x1bWUodmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LnZvbHVtZSA9IHZhbHVlIC8gMTAwO1xuXG4gICAgaWYgKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LnZvbHVtZSkge1xuICAgICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQubXV0ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuaXNNdXRlLnNldChmYWxzZSk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQubXV0ZWQgPSB0cnVlO1xuICAgIHRoaXMuaXNNdXRlLnNldCh0cnVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyRW5kZWQoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5pc1BsYXkuc2V0KGZhbHNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyRG93bmxvYWQoZTogRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuY2hlY2tQZXJtaXNzaW9uRG93bmxvYWRBdWRpbyB8fCAhYXdhaXQgdGhpcy5jaGVja1Blcm1pc3Npb25Eb3dubG9hZEF1ZGlvKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuZmlsZUF1ZGlvKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgd2luZG93Lm9wZW4odGhpcy5maWxlQXVkaW8oKSwgYF9ibGFua2ApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5vbkRlc3Ryb3kubmV4dCgpO1xuICAgIHRoaXMub25EZXN0cm95LmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsIjxhdWRpbyBjb250cm9sc1xuICAjYXVkaW9SZWZcbiAgY2xhc3M9XCJoaWRkZW5cIlxuICAodGltZXVwZGF0ZSk9XCJoYW5kbGVyVGltZVVwZGF0ZSgkZXZlbnQpXCJcbiAgKGxvYWRlZGRhdGEpPVwiaGFuZGxlckxvYWRlZERhdGEoJGV2ZW50KVwiXG4gIChlbmRlZCk9XCJoYW5kbGVyRW5kZWQoJGV2ZW50KVwiPlxuICA8c291cmNlIFtzcmNdPVwiZmlsZUF1ZGlvKClcIlxuICAgIHR5cGU9XCJhdWRpby9tcGVnXCI+XG48L2F1ZGlvPlxuPGRpdiBbY2xhc3MubGlicy11aS1kaXNhYmxlXT1cImlzRGlzYWJsZSgpXCJcbiAgW2NsYXNzLnBvaW50ZXItZXZlbnRzLW5vbmVdPVwiaXNEaXNhYmxlKClcIj5cbiAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3LVs3MCVdIGZsZXggcC0wIGl0ZW1zLWNlbnRlciBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IG1yLVsxNnB4XSBjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgIChjbGljayk9XCJoYW5kbGVyQXVkaW9QYXVzZVBsYXkoJGV2ZW50KVwiPlxuICAgICAgICA8aSBjbGFzcz1cInRleHQtWzE2cHhdXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLXBsYXktc29saWRdPVwiIWlzUGxheSgpXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLXBhdXNlLXNvbGlkXT1cImlzUGxheSgpXCI+XG4gICAgICAgIDwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImxpYnMtdWktZm9udC1oNXIgbXItWzE2cHhdXCI+e3sgYXVkaW9UaW1lQ3VycmVudCgpIH19IC97eyBhdWRpb1RpbWVEdXJhdGlvbigpIH19PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInctWzMwJV0gZmxleCBwLTAgaXRlbXMtY2VudGVyIGp1c3RpZnktZW5kXCI+XG4gICAgICA8ZGl2ICN2b2x1bWVDb250cm9sUmVmXG4gICAgICAgIGNsYXNzPVwiZmxleCBweS1bM3B4XSBpdGVtcy1jZW50ZXIgcm91bmRlZC1bMTJweF0gaC1bMjhweF1cIlxuICAgICAgICBbY2xhc3MuYmctWyNlNmU3ZWFdXT0nc2hvd0Z1bGxDb250cm9sVm9sdW1lKCknXG4gICAgICAgIFtjbGFzcy5weC1bMTJweF1dPSdzaG93RnVsbENvbnRyb2xWb2x1bWUoKSc+XG4gICAgICAgIDxpIGNsYXNzPVwidGV4dC1bMTZweF0gY3Vyc29yLXBvaW50ZXJcIlxuICAgICAgICAgIFtjbGFzcy5saWJzLXVpLWljb24tc3BlYWtlci1vbi1zb2xpZF09XCIhaXNNdXRlKClcIlxuICAgICAgICAgIFtjbGFzcy5saWJzLXVpLWljb24tc3BlYWtlci1vZmYtc29saWRdPVwiaXNNdXRlKClcIlxuICAgICAgICAgIChjbGljayk9XCJoYW5kbGVyQXVkaW9NdXRlTXV0ZWQoJGV2ZW50KVwiPlxuICAgICAgICA8L2k+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXJhbmdlX3NsaWRlciBbY2xhc3MuaGlkZGVuXT1cIiFzaG93RnVsbENvbnRyb2xWb2x1bWUoKVwiXG4gICAgICAgICAgW21vZGVdPVwiJ2F1ZGlvJ1wiXG4gICAgICAgICAgY2xhc3NJbmNsdWRlPVwiZmxleCBpdGVtcy1jZW50ZXIgIXctWzU0cHhdIGN1cnNvci1wb2ludGVyIG1sLVs4cHhdXCJcbiAgICAgICAgICBbdmFsdWVdPVwidm9sdW1lUmF0aW9WYWx1ZSgpXCJcbiAgICAgICAgICAob3V0Q2hhbmdlKT1cImhhbmRsZXJDaGFuZ2VWb2x1bWUoJGV2ZW50KVwiIC8+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGkgY2xhc3M9XCJsaWJzLXVpLWljb24tZG93bmxvYWQtc29saWQgbWwtWzE2cHhdIGN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgKGNsaWNrKT1cImhhbmRsZXJEb3dubG9hZCgkZXZlbnQpXCI+XG4gICAgICA8L2k+XG4gICAgPC9kaXY+XG5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJoLVsyNHB4XVwiPlxuICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXJhbmdlX3NsaWRlciBbbW9kZV09XCInYXVkaW8nXCJcbiAgICAgIFt2YWx1ZV09XCJhdWRpb1JhdGlvVmFsdWUoKVwiXG4gICAgICBbZGlzYWJsZV09J2lzRGlzYWJsZSgpJ1xuICAgICAgKG91dENoYW5nZSk9XCJoYW5kbGVyQ2hhbmdlQXVkaW8oJGV2ZW50KVwiIC8+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
|
|
135
|
+
}] });
|
|
136
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW8uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL2F1ZGlvL3NyYy9hdWRpby5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2F1ZGlvLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsU0FBUyxFQUFjLEtBQUssRUFBYSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25JLE9BQU8sRUFBRSwwQ0FBMEMsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ3JHLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFjLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQVk3RSxNQUFNLE9BQU8sOEJBQThCO0lBQ3pDLG1CQUFtQjtJQUNULGVBQWUsR0FBRyxNQUFNLENBQVMsQ0FBQyxDQUFDLENBQUM7SUFDcEMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDaEMsTUFBTSxHQUFHLE1BQU0sQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUNoQyxrQkFBa0IsR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDNUMsU0FBUyxHQUFHLE1BQU0sQ0FBVSxJQUFJLENBQUMsQ0FBQztJQUNsQyxnQkFBZ0IsR0FBRyxNQUFNLENBQVMsT0FBTyxDQUFDLENBQUM7SUFDM0MsaUJBQWlCLEdBQUcsTUFBTSxDQUFTLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLHFCQUFxQixHQUFHLE1BQU0sQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUNqRCxTQUFTLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztJQUV4QyxnQkFBZ0I7SUFDUCxTQUFTLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBVSxDQUFDO0lBQ3JDLDRCQUE0QixHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQTBCLENBQUM7SUFFakYsZ0JBQWdCO0lBQ1AsUUFBUSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQWEsVUFBVSxDQUFDLENBQUM7SUFDdEQsZ0JBQWdCLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBYSxrQkFBa0IsQ0FBQyxDQUFDO0lBRS9FLGVBQWU7UUFDYixLQUFLLENBQ0gsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDOUgsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FDaEksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ2hELENBQUM7SUFDRCxlQUFlO0lBQ1AsY0FBYyxDQUFDLEVBQWUsRUFBRSxTQUFpQjtRQUN2RCxPQUFPLFNBQVMsQ0FBYSxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUM5QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUMsRUFDN0IsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FDMUIsQ0FBQztJQUNKLENBQUM7SUFFUyxLQUFLLENBQUMsb0JBQW9CO1FBQ2xDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVTLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxLQUFZO1FBQ2hELEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztZQUM1QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRTlCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7SUFDN0MsQ0FBQztJQUVTLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxLQUFZO1FBQ2hELEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDO1FBQ25ELElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDekIsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3ZCLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9DLENBQUM7SUFDSCxDQUFDO0lBRVMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEtBQVk7UUFDNUMsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxLQUFZO1FBQzVDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ25DLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RHLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUU5SCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDbkksQ0FBQztJQUVPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBWTtRQUNqQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQztRQUN0QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDekQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRXZELE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQyxHQUFXLEVBQUUsRUFBRTtZQUNoQyxPQUFPLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztJQUN4RSxDQUFDO0lBRVMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEtBQWE7UUFDOUMsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7WUFDckMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO1FBQ2pHLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVTLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxLQUFhO1FBQy9DLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLEtBQUssR0FBRyxHQUFHLENBQUM7UUFFbkQsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3pDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztZQUM1QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV2QixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUMzQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QixDQUFDO0lBRVMsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFZO1FBQ3ZDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRVMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFRO1FBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLDRCQUE0QixFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQ3pGLE9BQU87UUFDVCxDQUFDO1FBQ0QsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQztZQUN0QixPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzVCLENBQUM7d0dBbkpVLDhCQUE4Qjs0RkFBOUIsOEJBQThCLDRvQkNkM0Msc2hFQW9EQSw0Q0R6Q0ksMENBQTBDOzs0RkFHakMsOEJBQThCO2tCQVYxQyxTQUFTOytCQUVFLDBCQUEwQixjQUV4QixJQUFJLG1CQUNDLHVCQUF1QixDQUFDLE1BQU0sV0FDdEM7d0JBQ1AsMENBQTBDO3FCQUMzQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIGlucHV0LCBPbkRlc3Ryb3ksIHNpZ25hbCwgdmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzSW5wdXRzUmFuZ2VTbGlkZXJDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWlucHV0cy1yYW5nZS1zbGlkZXInO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBtZXJnZSwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzJztcblxuQENvbXBvbmVudCh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnbGlic191aS1jb21wb25lbnRzLWF1ZGlvJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2F1ZGlvLmNvbXBvbmVudC5odG1sJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGltcG9ydHM6IFtcbiAgICBMaWJzVWlDb21wb25lbnRzSW5wdXRzUmFuZ2VTbGlkZXJDb21wb25lbnRcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzQXVkaW9Db21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAvLyAjcmVnaW9uIFBST1BFUlRZXG4gIHByb3RlY3RlZCBhdWRpb1JhdGlvVmFsdWUgPSBzaWduYWw8bnVtYmVyPigwKTtcbiAgcHJvdGVjdGVkIHZvbHVtZVJhdGlvVmFsdWUgPSBzaWduYWw8bnVtYmVyPigxMDApO1xuICBwcm90ZWN0ZWQgaXNQbGF5ID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJvdGVjdGVkIGlzTXV0ZSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByb3RlY3RlZCBpc1NsaWRlckF1ZGlvUHJlc3MgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcm90ZWN0ZWQgaXNEaXNhYmxlID0gc2lnbmFsPGJvb2xlYW4+KHRydWUpO1xuICBwcm90ZWN0ZWQgYXVkaW9UaW1lQ3VycmVudCA9IHNpZ25hbDxzdHJpbmc+KCdfOl86XycpO1xuICBwcm90ZWN0ZWQgYXVkaW9UaW1lRHVyYXRpb24gPSBzaWduYWw8c3RyaW5nPignXzpfOl8nKTtcbiAgcHJvdGVjdGVkIHNob3dGdWxsQ29udHJvbFZvbHVtZSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgb25EZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvLyAjcmVnaW9uIElOUFVUXG4gIHJlYWRvbmx5IGZpbGVBdWRpbyA9IGlucHV0LnJlcXVpcmVkPHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgY2hlY2tQZXJtaXNzaW9uRG93bmxvYWRBdWRpbyA9IGlucHV0LnJlcXVpcmVkPCgpID0+IFByb21pc2U8Ym9vbGVhbj4+KCk7XG5cbiAgLyogVklFVyBDSElMRCAqL1xuICByZWFkb25seSBhdWRpb1JlZiA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPignYXVkaW9SZWYnKTtcbiAgcmVhZG9ubHkgdm9sdW1lQ29udHJvbFJlZiA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPigndm9sdW1lQ29udHJvbFJlZicpO1xuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBtZXJnZShcbiAgICAgIHRoaXMuaW5pdE9ic2VydmFibGUodGhpcy52b2x1bWVDb250cm9sUmVmKCkubmF0aXZlRWxlbWVudCwgJ21vdXNlZW50ZXInKS5waXBlKHRhcCgoKSA9PiB0aGlzLnNob3dGdWxsQ29udHJvbFZvbHVtZS5zZXQodHJ1ZSkpKSxcbiAgICAgIHRoaXMuaW5pdE9ic2VydmFibGUodGhpcy52b2x1bWVDb250cm9sUmVmKCkubmF0aXZlRWxlbWVudCwgJ21vdXNlbGVhdmUnKS5waXBlKHRhcCgoKSA9PiB0aGlzLnNob3dGdWxsQ29udHJvbFZvbHVtZS5zZXQoZmFsc2UpKSlcbiAgICApLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95KSkuc3Vic2NyaWJlKCk7XG4gIH1cbiAgLyogRlVOQ1RJT05TICovXG4gIHByaXZhdGUgaW5pdE9ic2VydmFibGUoZWw6IEhUTUxFbGVtZW50LCBldmVudE5hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8TW91c2VFdmVudD4ge1xuICAgIHJldHVybiBmcm9tRXZlbnQ8TW91c2VFdmVudD4oZWwsIGV2ZW50TmFtZSkucGlwZShcbiAgICAgIHRhcChlID0+IGUuc3RvcFByb3BhZ2F0aW9uKCkpLFxuICAgICAgdGFrZVVudGlsKHRoaXMub25EZXN0cm95KVxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlcktleVByZXNzQXVkaW8oKSB7XG4gICAgdGhpcy5pc1NsaWRlckF1ZGlvUHJlc3Muc2V0KHRydWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJBdWRpb011dGVNdXRlZChldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQubXV0ZWQgPT09IHRydWUpIHtcbiAgICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50Lm11dGVkID0gZmFsc2U7XG4gICAgICB0aGlzLmlzTXV0ZS5zZXQoZmFsc2UpO1xuICAgICAgdGhpcy52b2x1bWVSYXRpb1ZhbHVlLnNldCg1MCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy52b2x1bWVSYXRpb1ZhbHVlLnNldCgwKTtcbiAgICB0aGlzLmlzTXV0ZS5zZXQodHJ1ZSk7XG4gICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQubXV0ZWQgPSB0cnVlO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJBdWRpb1BhdXNlUGxheShldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBhdWRpb0VsZW1lbnQgPSB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWF1ZGlvRWxlbWVudC5wYXVzZWQpIHtcbiAgICAgIGF1ZGlvRWxlbWVudC5wYXVzZSgpO1xuICAgICAgdGhpcy5pc1BsYXkuc2V0KGZhbHNlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgYXVkaW9FbGVtZW50LnBsYXkoKTtcbiAgICAgIHRoaXMuaXNQbGF5LnNldCh0cnVlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcGxheWluZyBhdWRpbzonLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJMb2FkZWREYXRhKGV2ZW50OiBFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICh0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudCkge1xuICAgICAgdGhpcy5hdWRpb1RpbWVEdXJhdGlvbi5zZXQoYXdhaXQgdGhpcy50b0hITU1TUyhNYXRoLmZsb29yKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmR1cmF0aW9uKSkpO1xuICAgICAgdGhpcy5hdWRpb1RpbWVDdXJyZW50LnNldChhd2FpdCB0aGlzLnRvSEhNTVNTKE1hdGguZmxvb3IodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuY3VycmVudFRpbWUpKSk7XG4gICAgICB0aGlzLmlzRGlzYWJsZS5zZXQoZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyVGltZVVwZGF0ZShldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXVkaW9UaW1lRHVyYXRpb24uc2V0KGF3YWl0IHRoaXMudG9ISE1NU1MoTWF0aC5mbG9vcih0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5kdXJhdGlvbikpKTtcbiAgICB0aGlzLmF1ZGlvVGltZUN1cnJlbnQuc2V0KGF3YWl0IHRoaXMudG9ISE1NU1MoTWF0aC5mbG9vcih0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5jdXJyZW50VGltZSkpKTtcbiAgICBpZiAodGhpcy5pc1NsaWRlckF1ZGlvUHJlc3MoKSkge1xuICAgICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuY3VycmVudFRpbWUgPSB0aGlzLmF1ZGlvUmF0aW9WYWx1ZSgpICogTWF0aC5mbG9vcih0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5kdXJhdGlvbikgLyAxMDA7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hdWRpb1JhdGlvVmFsdWUuc2V0KE1hdGguZmxvb3IoKHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmN1cnJlbnRUaW1lIC8gdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQuZHVyYXRpb24pICogMTAwKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHRvSEhNTVNTKHRpbWU6IG51bWJlcikge1xuICAgIGNvbnN0IGhvdXJzID0gTWF0aC5mbG9vcih0aW1lIC8gMzYwMCk7XG4gICAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IoKHRpbWUgLSAoaG91cnMgKiAzNjAwKSkgLyA2MCk7XG4gICAgY29uc3Qgc2Vjb25kcyA9IHRpbWUgLSAoaG91cnMgKiAzNjAwKSAtIChtaW51dGVzICogNjApO1xuXG4gICAgY29uc3QgZ2V0TGFiZWwgPSAoKHZhbDogbnVtYmVyKSA9PiB7XG4gICAgICByZXR1cm4gYCR7dmFsIDwgMTAgPyAnMCcgOiAnJ30ke3ZhbH1gO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGAke2dldExhYmVsKGhvdXJzKX06JHtnZXRMYWJlbChtaW51dGVzKX06JHtnZXRMYWJlbChzZWNvbmRzKX1gO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJDaGFuZ2VBdWRpbyh2YWx1ZTogbnVtYmVyKSB7XG4gICAgaWYgKHZhbHVlID09PSB0aGlzLmF1ZGlvUmF0aW9WYWx1ZSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXVkaW9SZWYoKS5uYXRpdmVFbGVtZW50LmN1cnJlbnRUaW1lID0gdmFsdWUgKiB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5kdXJhdGlvbiAvIDEwMDtcbiAgICB0aGlzLmF1ZGlvUmF0aW9WYWx1ZS5zZXQodmFsdWUpO1xuICAgIHRoaXMuaXNTbGlkZXJBdWRpb1ByZXNzLnNldChmYWxzZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlckNoYW5nZVZvbHVtZSh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQudm9sdW1lID0gdmFsdWUgLyAxMDA7XG5cbiAgICBpZiAodGhpcy5hdWRpb1JlZigpLm5hdGl2ZUVsZW1lbnQudm9sdW1lKSB7XG4gICAgICB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5tdXRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5pc011dGUuc2V0KGZhbHNlKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmF1ZGlvUmVmKCkubmF0aXZlRWxlbWVudC5tdXRlZCA9IHRydWU7XG4gICAgdGhpcy5pc011dGUuc2V0KHRydWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJFbmRlZChldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmlzUGxheS5zZXQoZmFsc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJEb3dubG9hZChlOiBFdmVudCkge1xuICAgIGlmICghdGhpcy5jaGVja1Blcm1pc3Npb25Eb3dubG9hZEF1ZGlvKCkgfHwgIWF3YWl0IHRoaXMuY2hlY2tQZXJtaXNzaW9uRG93bmxvYWRBdWRpbygpKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoIXRoaXMuZmlsZUF1ZGlvKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgd2luZG93Lm9wZW4odGhpcy5maWxlQXVkaW8oKSwgYF9ibGFua2ApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5vbkRlc3Ryb3kubmV4dCgpO1xuICAgIHRoaXMub25EZXN0cm95LmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsIjxhdWRpbyBjb250cm9sc1xuICAjYXVkaW9SZWZcbiAgY2xhc3M9XCJoaWRkZW5cIlxuICAodGltZXVwZGF0ZSk9XCJoYW5kbGVyVGltZVVwZGF0ZSgkZXZlbnQpXCJcbiAgKGxvYWRlZGRhdGEpPVwiaGFuZGxlckxvYWRlZERhdGEoJGV2ZW50KVwiXG4gIChlbmRlZCk9XCJoYW5kbGVyRW5kZWQoJGV2ZW50KVwiPlxuICA8c291cmNlIFtzcmNdPVwiZmlsZUF1ZGlvKClcIlxuICAgIHR5cGU9XCJhdWRpby9tcGVnXCI+XG48L2F1ZGlvPlxuPGRpdiBbY2xhc3MubGlicy11aS1kaXNhYmxlXT1cImlzRGlzYWJsZSgpXCJcbiAgW2NsYXNzLnBvaW50ZXItZXZlbnRzLW5vbmVdPVwiaXNEaXNhYmxlKClcIj5cbiAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJ3LVs3MCVdIGZsZXggcC0wIGl0ZW1zLWNlbnRlciBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IG1yLVsxNnB4XSBjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgIChjbGljayk9XCJoYW5kbGVyQXVkaW9QYXVzZVBsYXkoJGV2ZW50KVwiPlxuICAgICAgICA8aSBjbGFzcz1cInRleHQtWzE2cHhdXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLXBsYXktc29saWRdPVwiIWlzUGxheSgpXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1pY29uLXBhdXNlLXNvbGlkXT1cImlzUGxheSgpXCI+XG4gICAgICAgIDwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImxpYnMtdWktZm9udC1oNXIgbXItWzE2cHhdXCI+e3sgYXVkaW9UaW1lQ3VycmVudCgpIH19IC97eyBhdWRpb1RpbWVEdXJhdGlvbigpIH19PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInctWzMwJV0gZmxleCBwLTAgaXRlbXMtY2VudGVyIGp1c3RpZnktZW5kXCI+XG4gICAgICA8ZGl2ICN2b2x1bWVDb250cm9sUmVmXG4gICAgICAgIGNsYXNzPVwiZmxleCBweS1bM3B4XSBpdGVtcy1jZW50ZXIgcm91bmRlZC1bMTJweF0gaC1bMjhweF1cIlxuICAgICAgICBbY2xhc3MuYmctWyNlNmU3ZWFdXT0nc2hvd0Z1bGxDb250cm9sVm9sdW1lKCknXG4gICAgICAgIFtjbGFzcy5weC1bMTJweF1dPSdzaG93RnVsbENvbnRyb2xWb2x1bWUoKSc+XG4gICAgICAgIDxpIGNsYXNzPVwidGV4dC1bMTZweF0gY3Vyc29yLXBvaW50ZXJcIlxuICAgICAgICAgIFtjbGFzcy5saWJzLXVpLWljb24tc3BlYWtlci1vbi1zb2xpZF09XCIhaXNNdXRlKClcIlxuICAgICAgICAgIFtjbGFzcy5saWJzLXVpLWljb24tc3BlYWtlci1vZmYtc29saWRdPVwiaXNNdXRlKClcIlxuICAgICAgICAgIChjbGljayk9XCJoYW5kbGVyQXVkaW9NdXRlTXV0ZWQoJGV2ZW50KVwiPlxuICAgICAgICA8L2k+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXJhbmdlX3NsaWRlciBbY2xhc3MuaGlkZGVuXT1cIiFzaG93RnVsbENvbnRyb2xWb2x1bWUoKVwiXG4gICAgICAgICAgW21vZGVdPVwiJ2F1ZGlvJ1wiXG4gICAgICAgICAgY2xhc3NJbmNsdWRlPVwiZmxleCBpdGVtcy1jZW50ZXIgIXctWzU0cHhdIGN1cnNvci1wb2ludGVyIG1sLVs4cHhdXCJcbiAgICAgICAgICBbdmFsdWVdPVwidm9sdW1lUmF0aW9WYWx1ZSgpXCJcbiAgICAgICAgICAob3V0Q2hhbmdlKT1cImhhbmRsZXJDaGFuZ2VWb2x1bWUoJGV2ZW50KVwiIC8+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGkgY2xhc3M9XCJsaWJzLXVpLWljb24tZG93bmxvYWQtc29saWQgbWwtWzE2cHhdIGN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgKGNsaWNrKT1cImhhbmRsZXJEb3dubG9hZCgkZXZlbnQpXCI+XG4gICAgICA8L2k+XG4gICAgPC9kaXY+XG5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJoLVsyNHB4XVwiPlxuICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtaW5wdXRzLXJhbmdlX3NsaWRlciBbbW9kZV09XCInYXVkaW8nXCJcbiAgICAgIFt2YWx1ZV09XCJhdWRpb1JhdGlvVmFsdWUoKVwiXG4gICAgICBbZGlzYWJsZV09J2lzRGlzYWJsZSgpJ1xuICAgICAgKG91dENoYW5nZSk9XCJoYW5kbGVyQ2hhbmdlQXVkaW8oJGV2ZW50KVwiIC8+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { LibsUiComponentsAudioComponent } from './audio.component';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Demo component hiển thị các ví dụ khác nhau của Audio component
|
|
7
|
+
*/
|
|
8
|
+
export class LibsUiComponentsAudioDemoComponent {
|
|
9
|
+
/**
|
|
10
|
+
* Permission function luôn allow download
|
|
11
|
+
*/
|
|
12
|
+
basicPermissionCheck() {
|
|
13
|
+
return Promise.resolve(true);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Permission function không cho phép download
|
|
17
|
+
*/
|
|
18
|
+
denyPermissionCheck() {
|
|
19
|
+
return Promise.resolve(false);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Permission function có delay để mô phỏng API call
|
|
23
|
+
*/
|
|
24
|
+
delayedPermissionCheck() {
|
|
25
|
+
return new Promise(resolve => {
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
resolve(true);
|
|
28
|
+
}, 1500);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
32
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LibsUiComponentsAudioDemoComponent, isStandalone: true, selector: "lib-audio-demo", ngImport: i0, template: `
|
|
33
|
+
<div class="p-4">
|
|
34
|
+
<h1 class="text-2xl font-bold mb-4">Audio Component Demo</h1>
|
|
35
|
+
|
|
36
|
+
<p class="mb-4">
|
|
37
|
+
Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause,
|
|
38
|
+
volume control, progress bar và download button.
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<div class="demo-section">
|
|
42
|
+
<div class="demo-title">Basic Usage</div>
|
|
43
|
+
<p class="demo-description">Simple audio player với default settings</p>
|
|
44
|
+
<libs_ui-components-audio
|
|
45
|
+
fileAudio="https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3"
|
|
46
|
+
[checkPermissionDownloadAudio]="basicPermissionCheck"
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div class="demo-section">
|
|
51
|
+
<div class="demo-title">Disabled Download</div>
|
|
52
|
+
<p class="demo-description">Audio player không cho phép download</p>
|
|
53
|
+
<libs_ui-components-audio
|
|
54
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
|
|
55
|
+
[checkPermissionDownloadAudio]="denyPermissionCheck"
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div class="demo-section">
|
|
60
|
+
<div class="demo-title">Long Audio File</div>
|
|
61
|
+
<p class="demo-description">Audio player với track có duration dài hơn</p>
|
|
62
|
+
<libs_ui-components-audio
|
|
63
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
|
|
64
|
+
[checkPermissionDownloadAudio]="basicPermissionCheck"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div class="demo-section">
|
|
69
|
+
<div class="demo-title">Delayed Permission Check</div>
|
|
70
|
+
<p class="demo-description">Mô phỏng permission check có delay, simulate API call</p>
|
|
71
|
+
<libs_ui-components-audio
|
|
72
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"
|
|
73
|
+
[checkPermissionDownloadAudio]="delayedPermissionCheck"
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
`, isInline: true, styles: [".demo-section{margin-bottom:2rem;padding:1rem;border:1px solid #e5e7eb;border-radius:.5rem}.demo-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.demo-description{margin-bottom:1rem;color:#4b5563}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsAudioComponent, selector: "libs_ui-components-audio", inputs: ["fileAudio", "checkPermissionDownloadAudio"] }, { kind: "ngmodule", type: CommonModule }] });
|
|
78
|
+
}
|
|
79
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioDemoComponent, decorators: [{
|
|
80
|
+
type: Component,
|
|
81
|
+
args: [{ selector: 'lib-audio-demo', standalone: true, imports: [LibsUiComponentsAudioComponent, CommonModule], template: `
|
|
82
|
+
<div class="p-4">
|
|
83
|
+
<h1 class="text-2xl font-bold mb-4">Audio Component Demo</h1>
|
|
84
|
+
|
|
85
|
+
<p class="mb-4">
|
|
86
|
+
Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause,
|
|
87
|
+
volume control, progress bar và download button.
|
|
88
|
+
</p>
|
|
89
|
+
|
|
90
|
+
<div class="demo-section">
|
|
91
|
+
<div class="demo-title">Basic Usage</div>
|
|
92
|
+
<p class="demo-description">Simple audio player với default settings</p>
|
|
93
|
+
<libs_ui-components-audio
|
|
94
|
+
fileAudio="https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3"
|
|
95
|
+
[checkPermissionDownloadAudio]="basicPermissionCheck"
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<div class="demo-section">
|
|
100
|
+
<div class="demo-title">Disabled Download</div>
|
|
101
|
+
<p class="demo-description">Audio player không cho phép download</p>
|
|
102
|
+
<libs_ui-components-audio
|
|
103
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
|
|
104
|
+
[checkPermissionDownloadAudio]="denyPermissionCheck"
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div class="demo-section">
|
|
109
|
+
<div class="demo-title">Long Audio File</div>
|
|
110
|
+
<p class="demo-description">Audio player với track có duration dài hơn</p>
|
|
111
|
+
<libs_ui-components-audio
|
|
112
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
|
|
113
|
+
[checkPermissionDownloadAudio]="basicPermissionCheck"
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div class="demo-section">
|
|
118
|
+
<div class="demo-title">Delayed Permission Check</div>
|
|
119
|
+
<p class="demo-description">Mô phỏng permission check có delay, simulate API call</p>
|
|
120
|
+
<libs_ui-components-audio
|
|
121
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"
|
|
122
|
+
[checkPermissionDownloadAudio]="delayedPermissionCheck"
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
`, styles: [".demo-section{margin-bottom:2rem;padding:1rem;border:1px solid #e5e7eb;border-radius:.5rem}.demo-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.demo-description{margin-bottom:1rem;color:#4b5563}\n"] }]
|
|
127
|
+
}] });
|
|
128
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVtby5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2RlbW8uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUMsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDOztBQUUvQzs7R0FFRztBQXVFSCxNQUFNLE9BQU8sa0NBQWtDO0lBQzdDOztPQUVHO0lBQ0gsb0JBQW9CO1FBQ2xCLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxtQkFBbUI7UUFDakIsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7T0FFRztJQUNILHNCQUFzQjtRQUNwQixPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzNCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNYLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzt3R0F4QlUsa0NBQWtDOzRGQUFsQyxrQ0FBa0MsMEVBL0NuQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkNULDJSQWpFUyw4QkFBOEIsMkhBQUUsWUFBWTs7NEZBbUUzQyxrQ0FBa0M7a0JBdEU5QyxTQUFTOytCQUNFLGdCQUFnQixjQUNkLElBQUksV0FDUCxDQUFDLDhCQUE4QixFQUFFLFlBQVksQ0FBQyxZQW9CN0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZDVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c0F1ZGlvQ29tcG9uZW50IH0gZnJvbSAnLi9hdWRpby5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuLyoqXG4gKiBEZW1vIGNvbXBvbmVudCBoaeG7g24gdGjhu4sgY8OhYyB2w60gZOG7pSBraMOhYyBuaGF1IGPhu6dhIEF1ZGlvIGNvbXBvbmVudFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItYXVkaW8tZGVtbycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtMaWJzVWlDb21wb25lbnRzQXVkaW9Db21wb25lbnQsIENvbW1vbk1vZHVsZV0sXG4gIHN0eWxlczogW2BcbiAgICAuZGVtby1zZWN0aW9uIHtcbiAgICAgIG1hcmdpbi1ib3R0b206IDJyZW07XG4gICAgICBwYWRkaW5nOiAxcmVtO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgI2U1ZTdlYjtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDAuNXJlbTtcbiAgICB9XG4gICAgXG4gICAgLmRlbW8tdGl0bGUge1xuICAgICAgZm9udC1zaXplOiAxLjI1cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIG1hcmdpbi1ib3R0b206IDFyZW07XG4gICAgfVxuICAgIFxuICAgIC5kZW1vLWRlc2NyaXB0aW9uIHtcbiAgICAgIG1hcmdpbi1ib3R0b206IDFyZW07XG4gICAgICBjb2xvcjogIzRiNTU2MztcbiAgICB9XG4gIGBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJwLTRcIj5cbiAgICAgIDxoMSBjbGFzcz1cInRleHQtMnhsIGZvbnQtYm9sZCBtYi00XCI+QXVkaW8gQ29tcG9uZW50IERlbW88L2gxPlxuICAgICAgXG4gICAgICA8cCBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgQXVkaW8gQ29tcG9uZW50IGzDoCBt4buZdCB0csOsbmggcGjDoXQgw6JtIHRoYW5oIHTDuXkgY2jhu4luaCB24bubaSBjw6FjIGNvbnRyb2xzIMSR4bqneSDEkeG7pyBuaMawIHBsYXkvcGF1c2UsIFxuICAgICAgICB2b2x1bWUgY29udHJvbCwgcHJvZ3Jlc3MgYmFyIHbDoCBkb3dubG9hZCBidXR0b24uXG4gICAgICA8L3A+XG4gICAgICBcbiAgICAgIDxkaXYgY2xhc3M9XCJkZW1vLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRlbW8tdGl0bGVcIj5CYXNpYyBVc2FnZTwvZGl2PlxuICAgICAgICA8cCBjbGFzcz1cImRlbW8tZGVzY3JpcHRpb25cIj5TaW1wbGUgYXVkaW8gcGxheWVyIHbhu5tpIGRlZmF1bHQgc2V0dGluZ3M8L3A+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYXVkaW9cbiAgICAgICAgICBmaWxlQXVkaW89XCJodHRwczovL25oYWNjaHVvbmcxMjMuY29tL25oYWMtY2h1b25nL2FiY2RlZmdoL25oYWMtY2h1b25nLW5ndW9pLWF5LWRhdS1jby1kYW5nLWFraXJhLXBoYW4tbmd1eWVuLXZhbi1jaHVuZy5tcDNcIlxuICAgICAgICAgIFtjaGVja1Blcm1pc3Npb25Eb3dubG9hZEF1ZGlvXT1cImJhc2ljUGVybWlzc2lvbkNoZWNrXCJcbiAgICAgICAgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgXG4gICAgICA8ZGl2IGNsYXNzPVwiZGVtby1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkZW1vLXRpdGxlXCI+RGlzYWJsZWQgRG93bmxvYWQ8L2Rpdj5cbiAgICAgICAgPHAgY2xhc3M9XCJkZW1vLWRlc2NyaXB0aW9uXCI+QXVkaW8gcGxheWVyIGtow7RuZyBjaG8gcGjDqXAgZG93bmxvYWQ8L3A+XG4gICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtYXVkaW9cbiAgICAgICAgICBmaWxlQXVkaW89XCJodHRwczovL3d3dy5zb3VuZGhlbGl4LmNvbS9leGFtcGxlcy9tcDMvU291bmRIZWxpeC1Tb25nLTEubXAzXCJcbiAgICAgICAgICBbY2hlY2tQZXJtaXNzaW9uRG93bmxvYWRBdWRpb109XCJkZW55UGVybWlzc2lvbkNoZWNrXCJcbiAgICAgICAgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgXG4gICAgICA8ZGl2IGNsYXNzPVwiZGVtby1zZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkZW1vLXRpdGxlXCI+TG9uZyBBdWRpbyBGaWxlPC9kaXY+XG4gICAgICAgIDxwIGNsYXNzPVwiZGVtby1kZXNjcmlwdGlvblwiPkF1ZGlvIHBsYXllciB24bubaSB0cmFjayBjw7MgZHVyYXRpb24gZMOgaSBoxqFuPC9wPlxuICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWF1ZGlvXG4gICAgICAgICAgZmlsZUF1ZGlvPVwiaHR0cHM6Ly93d3cuc291bmRoZWxpeC5jb20vZXhhbXBsZXMvbXAzL1NvdW5kSGVsaXgtU29uZy0yLm1wM1wiXG4gICAgICAgICAgW2NoZWNrUGVybWlzc2lvbkRvd25sb2FkQXVkaW9dPVwiYmFzaWNQZXJtaXNzaW9uQ2hlY2tcIlxuICAgICAgICAvPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJkZW1vLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRlbW8tdGl0bGVcIj5EZWxheWVkIFBlcm1pc3Npb24gQ2hlY2s8L2Rpdj5cbiAgICAgICAgPHAgY2xhc3M9XCJkZW1vLWRlc2NyaXB0aW9uXCI+TcO0IHBo4buPbmcgcGVybWlzc2lvbiBjaGVjayBjw7MgZGVsYXksIHNpbXVsYXRlIEFQSSBjYWxsPC9wPlxuICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWF1ZGlvXG4gICAgICAgICAgZmlsZUF1ZGlvPVwiaHR0cHM6Ly93d3cuc291bmRoZWxpeC5jb20vZXhhbXBsZXMvbXAzL1NvdW5kSGVsaXgtU29uZy0zLm1wM1wiXG4gICAgICAgICAgW2NoZWNrUGVybWlzc2lvbkRvd25sb2FkQXVkaW9dPVwiZGVsYXllZFBlcm1pc3Npb25DaGVja1wiXG4gICAgICAgIC8+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzQXVkaW9EZW1vQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIFBlcm1pc3Npb24gZnVuY3Rpb24gbHXDtG4gYWxsb3cgZG93bmxvYWRcbiAgICovXG4gIGJhc2ljUGVybWlzc2lvbkNoZWNrKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodHJ1ZSk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBQZXJtaXNzaW9uIGZ1bmN0aW9uIGtow7RuZyBjaG8gcGjDqXAgZG93bmxvYWRcbiAgICovXG4gIGRlbnlQZXJtaXNzaW9uQ2hlY2soKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogUGVybWlzc2lvbiBmdW5jdGlvbiBjw7MgZGVsYXkgxJHhu4MgbcO0IHBo4buPbmcgQVBJIGNhbGxcbiAgICovXG4gIGRlbGF5ZWRQZXJtaXNzaW9uQ2hlY2soKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICB9LCAxNTAwKTtcbiAgICB9KTtcbiAgfVxufSAiXX0=
|
package/esm2022/index.mjs
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export * from './audio.component';
|
|
2
|
-
|
|
2
|
+
export * from './demo.component';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvYXVkaW8vc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxrQkFBa0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vYXVkaW8uY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vZGVtby5jb21wb25lbnQnO1xuIl19
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, input, viewChild,
|
|
2
|
+
import { signal, input, viewChild, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';
|
|
4
4
|
import { Subject, merge, tap, takeUntil, fromEvent } from 'rxjs';
|
|
5
|
+
import { CommonModule } from '@angular/common';
|
|
5
6
|
|
|
6
7
|
class LibsUiComponentsAudioComponent {
|
|
7
8
|
// #region PROPERTY
|
|
@@ -17,7 +18,7 @@ class LibsUiComponentsAudioComponent {
|
|
|
17
18
|
onDestroy = new Subject();
|
|
18
19
|
// #region INPUT
|
|
19
20
|
fileAudio = input.required();
|
|
20
|
-
checkPermissionDownloadAudio;
|
|
21
|
+
checkPermissionDownloadAudio = input.required();
|
|
21
22
|
/* VIEW CHILD */
|
|
22
23
|
audioRef = viewChild.required('audioRef');
|
|
23
24
|
volumeControlRef = viewChild.required('volumeControlRef');
|
|
@@ -112,7 +113,7 @@ class LibsUiComponentsAudioComponent {
|
|
|
112
113
|
this.isPlay.set(false);
|
|
113
114
|
}
|
|
114
115
|
async handlerDownload(e) {
|
|
115
|
-
if (!this.checkPermissionDownloadAudio || !await this.checkPermissionDownloadAudio()) {
|
|
116
|
+
if (!this.checkPermissionDownloadAudio() || !await this.checkPermissionDownloadAudio()()) {
|
|
116
117
|
return;
|
|
117
118
|
}
|
|
118
119
|
e.stopPropagation();
|
|
@@ -126,21 +127,142 @@ class LibsUiComponentsAudioComponent {
|
|
|
126
127
|
this.onDestroy.complete();
|
|
127
128
|
}
|
|
128
129
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
129
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: LibsUiComponentsAudioComponent, isStandalone: true, selector: "libs_ui-components-audio", inputs: { fileAudio: { classPropertyName: "fileAudio", publicName: "fileAudio", isSignal: true, isRequired: true, transformFunction: null }, checkPermissionDownloadAudio: { classPropertyName: "checkPermissionDownloadAudio", publicName: "checkPermissionDownloadAudio", isSignal:
|
|
130
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.13", type: LibsUiComponentsAudioComponent, isStandalone: true, selector: "libs_ui-components-audio", inputs: { fileAudio: { classPropertyName: "fileAudio", publicName: "fileAudio", isSignal: true, isRequired: true, transformFunction: null }, checkPermissionDownloadAudio: { classPropertyName: "checkPermissionDownloadAudio", publicName: "checkPermissionDownloadAudio", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "audioRef", first: true, predicate: ["audioRef"], descendants: true, isSignal: true }, { propertyName: "volumeControlRef", first: true, predicate: ["volumeControlRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n", dependencies: [{ kind: "component", type: LibsUiComponentsInputsRangeSliderComponent, selector: "libs_ui-components-inputs-range_slider", inputs: ["mode", "min", "max", "value", "classInclude", "disable", "unit", "step", "hideProgressingValue", "formatNumber"], outputs: ["valueChange", "outChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
130
131
|
}
|
|
131
132
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioComponent, decorators: [{
|
|
132
133
|
type: Component,
|
|
133
134
|
args: [{ selector: 'libs_ui-components-audio', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
134
135
|
LibsUiComponentsInputsRangeSliderComponent
|
|
135
136
|
], template: "<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n" }]
|
|
136
|
-
}]
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
}] });
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Demo component hiển thị các ví dụ khác nhau của Audio component
|
|
141
|
+
*/
|
|
142
|
+
class LibsUiComponentsAudioDemoComponent {
|
|
143
|
+
/**
|
|
144
|
+
* Permission function luôn allow download
|
|
145
|
+
*/
|
|
146
|
+
basicPermissionCheck() {
|
|
147
|
+
return Promise.resolve(true);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Permission function không cho phép download
|
|
151
|
+
*/
|
|
152
|
+
denyPermissionCheck() {
|
|
153
|
+
return Promise.resolve(false);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Permission function có delay để mô phỏng API call
|
|
157
|
+
*/
|
|
158
|
+
delayedPermissionCheck() {
|
|
159
|
+
return new Promise(resolve => {
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
resolve(true);
|
|
162
|
+
}, 1500);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
166
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LibsUiComponentsAudioDemoComponent, isStandalone: true, selector: "lib-audio-demo", ngImport: i0, template: `
|
|
167
|
+
<div class="p-4">
|
|
168
|
+
<h1 class="text-2xl font-bold mb-4">Audio Component Demo</h1>
|
|
169
|
+
|
|
170
|
+
<p class="mb-4">
|
|
171
|
+
Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause,
|
|
172
|
+
volume control, progress bar và download button.
|
|
173
|
+
</p>
|
|
174
|
+
|
|
175
|
+
<div class="demo-section">
|
|
176
|
+
<div class="demo-title">Basic Usage</div>
|
|
177
|
+
<p class="demo-description">Simple audio player với default settings</p>
|
|
178
|
+
<libs_ui-components-audio
|
|
179
|
+
fileAudio="https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3"
|
|
180
|
+
[checkPermissionDownloadAudio]="basicPermissionCheck"
|
|
181
|
+
/>
|
|
182
|
+
</div>
|
|
183
|
+
|
|
184
|
+
<div class="demo-section">
|
|
185
|
+
<div class="demo-title">Disabled Download</div>
|
|
186
|
+
<p class="demo-description">Audio player không cho phép download</p>
|
|
187
|
+
<libs_ui-components-audio
|
|
188
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
|
|
189
|
+
[checkPermissionDownloadAudio]="denyPermissionCheck"
|
|
190
|
+
/>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div class="demo-section">
|
|
194
|
+
<div class="demo-title">Long Audio File</div>
|
|
195
|
+
<p class="demo-description">Audio player với track có duration dài hơn</p>
|
|
196
|
+
<libs_ui-components-audio
|
|
197
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
|
|
198
|
+
[checkPermissionDownloadAudio]="basicPermissionCheck"
|
|
199
|
+
/>
|
|
200
|
+
</div>
|
|
201
|
+
|
|
202
|
+
<div class="demo-section">
|
|
203
|
+
<div class="demo-title">Delayed Permission Check</div>
|
|
204
|
+
<p class="demo-description">Mô phỏng permission check có delay, simulate API call</p>
|
|
205
|
+
<libs_ui-components-audio
|
|
206
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"
|
|
207
|
+
[checkPermissionDownloadAudio]="delayedPermissionCheck"
|
|
208
|
+
/>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
`, isInline: true, styles: [".demo-section{margin-bottom:2rem;padding:1rem;border:1px solid #e5e7eb;border-radius:.5rem}.demo-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.demo-description{margin-bottom:1rem;color:#4b5563}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsAudioComponent, selector: "libs_ui-components-audio", inputs: ["fileAudio", "checkPermissionDownloadAudio"] }, { kind: "ngmodule", type: CommonModule }] });
|
|
212
|
+
}
|
|
213
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsAudioDemoComponent, decorators: [{
|
|
214
|
+
type: Component,
|
|
215
|
+
args: [{ selector: 'lib-audio-demo', standalone: true, imports: [LibsUiComponentsAudioComponent, CommonModule], template: `
|
|
216
|
+
<div class="p-4">
|
|
217
|
+
<h1 class="text-2xl font-bold mb-4">Audio Component Demo</h1>
|
|
218
|
+
|
|
219
|
+
<p class="mb-4">
|
|
220
|
+
Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause,
|
|
221
|
+
volume control, progress bar và download button.
|
|
222
|
+
</p>
|
|
223
|
+
|
|
224
|
+
<div class="demo-section">
|
|
225
|
+
<div class="demo-title">Basic Usage</div>
|
|
226
|
+
<p class="demo-description">Simple audio player với default settings</p>
|
|
227
|
+
<libs_ui-components-audio
|
|
228
|
+
fileAudio="https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3"
|
|
229
|
+
[checkPermissionDownloadAudio]="basicPermissionCheck"
|
|
230
|
+
/>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div class="demo-section">
|
|
234
|
+
<div class="demo-title">Disabled Download</div>
|
|
235
|
+
<p class="demo-description">Audio player không cho phép download</p>
|
|
236
|
+
<libs_ui-components-audio
|
|
237
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
|
|
238
|
+
[checkPermissionDownloadAudio]="denyPermissionCheck"
|
|
239
|
+
/>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
<div class="demo-section">
|
|
243
|
+
<div class="demo-title">Long Audio File</div>
|
|
244
|
+
<p class="demo-description">Audio player với track có duration dài hơn</p>
|
|
245
|
+
<libs_ui-components-audio
|
|
246
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"
|
|
247
|
+
[checkPermissionDownloadAudio]="basicPermissionCheck"
|
|
248
|
+
/>
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
<div class="demo-section">
|
|
252
|
+
<div class="demo-title">Delayed Permission Check</div>
|
|
253
|
+
<p class="demo-description">Mô phỏng permission check có delay, simulate API call</p>
|
|
254
|
+
<libs_ui-components-audio
|
|
255
|
+
fileAudio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3"
|
|
256
|
+
[checkPermissionDownloadAudio]="delayedPermissionCheck"
|
|
257
|
+
/>
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
`, styles: [".demo-section{margin-bottom:2rem;padding:1rem;border:1px solid #e5e7eb;border-radius:.5rem}.demo-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem}.demo-description{margin-bottom:1rem;color:#4b5563}\n"] }]
|
|
261
|
+
}] });
|
|
140
262
|
|
|
141
263
|
/**
|
|
142
264
|
* Generated bundle index. Do not edit.
|
|
143
265
|
*/
|
|
144
266
|
|
|
145
|
-
export { LibsUiComponentsAudioComponent };
|
|
267
|
+
export { LibsUiComponentsAudioComponent, LibsUiComponentsAudioDemoComponent };
|
|
146
268
|
//# sourceMappingURL=libs-ui-components-audio.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs-ui-components-audio.mjs","sources":["../../../../../libs-ui/components/audio/src/audio.component.ts","../../../../../libs-ui/components/audio/src/audio.component.html","../../../../../libs-ui/components/audio/src/libs-ui-components-audio.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, input, Input, OnDestroy, signal, viewChild } from '@angular/core';\nimport { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';\nimport { fromEvent, merge, Observable, Subject, takeUntil, tap } from 'rxjs';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-audio',\n templateUrl: './audio.component.html',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n LibsUiComponentsInputsRangeSliderComponent\n ]\n})\nexport class LibsUiComponentsAudioComponent implements AfterViewInit, OnDestroy {\n // #region PROPERTY\n protected audioRatioValue = signal<number>(0);\n protected volumeRatioValue = signal<number>(100);\n protected isPlay = signal<boolean>(false);\n protected isMute = signal<boolean>(false);\n protected isSliderAudioPress = signal<boolean>(false);\n protected isDisable = signal<boolean>(true);\n protected audioTimeCurrent = signal<string>('_:_:_');\n protected audioTimeDuration = signal<string>('_:_:_');\n protected showFullControlVolume = signal<boolean>(false);\n private onDestroy = new Subject<void>();\n\n // #region INPUT\n readonly fileAudio = input.required<string>();\n @Input({ required: true }) checkPermissionDownloadAudio?: () => Promise<boolean>;\n\n /* VIEW CHILD */\n readonly audioRef = viewChild.required<ElementRef>('audioRef');\n readonly volumeControlRef = viewChild.required<ElementRef>('volumeControlRef');\n\n ngAfterViewInit() {\n merge(\n this.initObservable(this.volumeControlRef().nativeElement, 'mouseenter').pipe(tap(() => this.showFullControlVolume.set(true))),\n this.initObservable(this.volumeControlRef().nativeElement, 'mouseleave').pipe(tap(() => this.showFullControlVolume.set(false)))\n ).pipe(takeUntil(this.onDestroy)).subscribe();\n }\n /* FUNCTIONS */\n private initObservable(el: HTMLElement, eventName: string): Observable<MouseEvent> {\n return fromEvent<MouseEvent>(el, eventName).pipe(\n tap(e => e.stopPropagation()),\n takeUntil(this.onDestroy)\n );\n }\n\n protected async handlerKeyPressAudio() {\n this.isSliderAudioPress.set(true);\n }\n\n protected async handlerAudioMuteMuted(event: Event) {\n event.stopPropagation();\n if (this.audioRef().nativeElement.muted === true) {\n this.audioRef().nativeElement.muted = false;\n this.isMute.set(false);\n this.volumeRatioValue.set(50);\n\n return;\n }\n this.volumeRatioValue.set(0);\n this.isMute.set(true);\n this.audioRef().nativeElement.muted = true;\n }\n\n protected async handlerAudioPausePlay(event: Event) {\n event.stopPropagation();\n const audioElement = this.audioRef().nativeElement;\n if (!audioElement.paused) {\n audioElement.pause();\n this.isPlay.set(false);\n return;\n }\n\n try {\n await audioElement.play();\n this.isPlay.set(true);\n } catch (error) {\n console.error('Error playing audio:', error);\n }\n }\n\n protected async handlerLoadedData(event: Event) {\n event.stopPropagation();\n if (this.audioRef().nativeElement) {\n this.audioTimeDuration.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.duration)));\n this.audioTimeCurrent.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.currentTime)));\n this.isDisable.set(false);\n }\n }\n\n protected async handlerTimeUpdate(event: Event) {\n event.stopPropagation();\n if (!this.audioRef().nativeElement) {\n return;\n }\n this.audioTimeDuration.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.duration)));\n this.audioTimeCurrent.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.currentTime)));\n if (this.isSliderAudioPress()) {\n this.audioRef().nativeElement.currentTime = this.audioRatioValue() * Math.floor(this.audioRef().nativeElement.duration) / 100;\n\n return;\n }\n this.audioRatioValue.set(Math.floor((this.audioRef().nativeElement.currentTime / this.audioRef().nativeElement.duration) * 100));\n }\n\n private async toHHMMSS(time: number) {\n const hours = Math.floor(time / 3600);\n const minutes = Math.floor((time - (hours * 3600)) / 60);\n const seconds = time - (hours * 3600) - (minutes * 60);\n\n const getLabel = ((val: number) => {\n return `${val < 10 ? '0' : ''}${val}`;\n });\n\n return `${getLabel(hours)}:${getLabel(minutes)}:${getLabel(seconds)}`;\n }\n\n protected async handlerChangeAudio(value: number) {\n if (value === this.audioRatioValue()) {\n return;\n }\n this.audioRef().nativeElement.currentTime = value * this.audioRef().nativeElement.duration / 100;\n this.audioRatioValue.set(value);\n this.isSliderAudioPress.set(false);\n }\n\n protected async handlerChangeVolume(value: number) {\n this.audioRef().nativeElement.volume = value / 100;\n\n if (this.audioRef().nativeElement.volume) {\n this.audioRef().nativeElement.muted = false;\n this.isMute.set(false);\n\n return;\n }\n this.audioRef().nativeElement.muted = true;\n this.isMute.set(true);\n }\n\n protected async handlerEnded(event: Event) {\n event.stopPropagation();\n this.isPlay.set(false);\n }\n\n protected async handlerDownload(e: Event) {\n if (!this.checkPermissionDownloadAudio || !await this.checkPermissionDownloadAudio()) {\n return;\n }\n e.stopPropagation();\n if (!this.fileAudio()) {\n return;\n }\n window.open(this.fileAudio(), `_blank`);\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n}\n","<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"libs-ui-components-audio.mjs","sources":["../../../../../libs-ui/components/audio/src/audio.component.ts","../../../../../libs-ui/components/audio/src/audio.component.html","../../../../../libs-ui/components/audio/src/demo.component.ts","../../../../../libs-ui/components/audio/src/libs-ui-components-audio.ts"],"sourcesContent":["import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, input, OnDestroy, signal, viewChild } from '@angular/core';\nimport { LibsUiComponentsInputsRangeSliderComponent } from '@libs-ui/components-inputs-range-slider';\nimport { fromEvent, merge, Observable, Subject, takeUntil, tap } from 'rxjs';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'libs_ui-components-audio',\n templateUrl: './audio.component.html',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n LibsUiComponentsInputsRangeSliderComponent\n ]\n})\nexport class LibsUiComponentsAudioComponent implements AfterViewInit, OnDestroy {\n // #region PROPERTY\n protected audioRatioValue = signal<number>(0);\n protected volumeRatioValue = signal<number>(100);\n protected isPlay = signal<boolean>(false);\n protected isMute = signal<boolean>(false);\n protected isSliderAudioPress = signal<boolean>(false);\n protected isDisable = signal<boolean>(true);\n protected audioTimeCurrent = signal<string>('_:_:_');\n protected audioTimeDuration = signal<string>('_:_:_');\n protected showFullControlVolume = signal<boolean>(false);\n private onDestroy = new Subject<void>();\n\n // #region INPUT\n readonly fileAudio = input.required<string>();\n readonly checkPermissionDownloadAudio = input.required<() => Promise<boolean>>();\n\n /* VIEW CHILD */\n readonly audioRef = viewChild.required<ElementRef>('audioRef');\n readonly volumeControlRef = viewChild.required<ElementRef>('volumeControlRef');\n\n ngAfterViewInit() {\n merge(\n this.initObservable(this.volumeControlRef().nativeElement, 'mouseenter').pipe(tap(() => this.showFullControlVolume.set(true))),\n this.initObservable(this.volumeControlRef().nativeElement, 'mouseleave').pipe(tap(() => this.showFullControlVolume.set(false)))\n ).pipe(takeUntil(this.onDestroy)).subscribe();\n }\n /* FUNCTIONS */\n private initObservable(el: HTMLElement, eventName: string): Observable<MouseEvent> {\n return fromEvent<MouseEvent>(el, eventName).pipe(\n tap(e => e.stopPropagation()),\n takeUntil(this.onDestroy)\n );\n }\n\n protected async handlerKeyPressAudio() {\n this.isSliderAudioPress.set(true);\n }\n\n protected async handlerAudioMuteMuted(event: Event) {\n event.stopPropagation();\n if (this.audioRef().nativeElement.muted === true) {\n this.audioRef().nativeElement.muted = false;\n this.isMute.set(false);\n this.volumeRatioValue.set(50);\n\n return;\n }\n this.volumeRatioValue.set(0);\n this.isMute.set(true);\n this.audioRef().nativeElement.muted = true;\n }\n\n protected async handlerAudioPausePlay(event: Event) {\n event.stopPropagation();\n const audioElement = this.audioRef().nativeElement;\n if (!audioElement.paused) {\n audioElement.pause();\n this.isPlay.set(false);\n return;\n }\n\n try {\n await audioElement.play();\n this.isPlay.set(true);\n } catch (error) {\n console.error('Error playing audio:', error);\n }\n }\n\n protected async handlerLoadedData(event: Event) {\n event.stopPropagation();\n if (this.audioRef().nativeElement) {\n this.audioTimeDuration.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.duration)));\n this.audioTimeCurrent.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.currentTime)));\n this.isDisable.set(false);\n }\n }\n\n protected async handlerTimeUpdate(event: Event) {\n event.stopPropagation();\n if (!this.audioRef().nativeElement) {\n return;\n }\n this.audioTimeDuration.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.duration)));\n this.audioTimeCurrent.set(await this.toHHMMSS(Math.floor(this.audioRef().nativeElement.currentTime)));\n if (this.isSliderAudioPress()) {\n this.audioRef().nativeElement.currentTime = this.audioRatioValue() * Math.floor(this.audioRef().nativeElement.duration) / 100;\n\n return;\n }\n this.audioRatioValue.set(Math.floor((this.audioRef().nativeElement.currentTime / this.audioRef().nativeElement.duration) * 100));\n }\n\n private async toHHMMSS(time: number) {\n const hours = Math.floor(time / 3600);\n const minutes = Math.floor((time - (hours * 3600)) / 60);\n const seconds = time - (hours * 3600) - (minutes * 60);\n\n const getLabel = ((val: number) => {\n return `${val < 10 ? '0' : ''}${val}`;\n });\n\n return `${getLabel(hours)}:${getLabel(minutes)}:${getLabel(seconds)}`;\n }\n\n protected async handlerChangeAudio(value: number) {\n if (value === this.audioRatioValue()) {\n return;\n }\n this.audioRef().nativeElement.currentTime = value * this.audioRef().nativeElement.duration / 100;\n this.audioRatioValue.set(value);\n this.isSliderAudioPress.set(false);\n }\n\n protected async handlerChangeVolume(value: number) {\n this.audioRef().nativeElement.volume = value / 100;\n\n if (this.audioRef().nativeElement.volume) {\n this.audioRef().nativeElement.muted = false;\n this.isMute.set(false);\n\n return;\n }\n this.audioRef().nativeElement.muted = true;\n this.isMute.set(true);\n }\n\n protected async handlerEnded(event: Event) {\n event.stopPropagation();\n this.isPlay.set(false);\n }\n\n protected async handlerDownload(e: Event) {\n if (!this.checkPermissionDownloadAudio() || !await this.checkPermissionDownloadAudio()()) {\n return;\n }\n e.stopPropagation();\n if (!this.fileAudio()) {\n return;\n }\n window.open(this.fileAudio(), `_blank`);\n }\n\n ngOnDestroy(): void {\n this.onDestroy.next();\n this.onDestroy.complete();\n }\n}\n","<audio controls\n #audioRef\n class=\"hidden\"\n (timeupdate)=\"handlerTimeUpdate($event)\"\n (loadeddata)=\"handlerLoadedData($event)\"\n (ended)=\"handlerEnded($event)\">\n <source [src]=\"fileAudio()\"\n type=\"audio/mpeg\">\n</audio>\n<div [class.libs-ui-disable]=\"isDisable()\"\n [class.pointer-events-none]=\"isDisable()\">\n <div class=\"flex justify-between items-center\">\n <div class=\"w-[70%] flex p-0 items-center \">\n <div class=\"flex mr-[16px] cursor-pointer\"\n (click)=\"handlerAudioPausePlay($event)\">\n <i class=\"text-[16px]\"\n [class.libs-ui-icon-play-solid]=\"!isPlay()\"\n [class.libs-ui-icon-pause-solid]=\"isPlay()\">\n </i>\n </div>\n <div class=\"libs-ui-font-h5r mr-[16px]\">{{ audioTimeCurrent() }} /{{ audioTimeDuration() }}</div>\n </div>\n <div class=\"w-[30%] flex p-0 items-center justify-end\">\n <div #volumeControlRef\n class=\"flex py-[3px] items-center rounded-[12px] h-[28px]\"\n [class.bg-[#e6e7ea]]='showFullControlVolume()'\n [class.px-[12px]]='showFullControlVolume()'>\n <i class=\"text-[16px] cursor-pointer\"\n [class.libs-ui-icon-speaker-on-solid]=\"!isMute()\"\n [class.libs-ui-icon-speaker-off-solid]=\"isMute()\"\n (click)=\"handlerAudioMuteMuted($event)\">\n </i>\n <libs_ui-components-inputs-range_slider [class.hidden]=\"!showFullControlVolume()\"\n [mode]=\"'audio'\"\n classInclude=\"flex items-center !w-[54px] cursor-pointer ml-[8px]\"\n [value]=\"volumeRatioValue()\"\n (outChange)=\"handlerChangeVolume($event)\" />\n </div>\n\n <i class=\"libs-ui-icon-download-solid ml-[16px] cursor-pointer\"\n (click)=\"handlerDownload($event)\">\n </i>\n </div>\n\n </div>\n <div class=\"h-[24px]\">\n <libs_ui-components-inputs-range_slider [mode]=\"'audio'\"\n [value]=\"audioRatioValue()\"\n [disable]='isDisable()'\n (outChange)=\"handlerChangeAudio($event)\" />\n </div>\n</div>\n","import { Component } from '@angular/core';\nimport { LibsUiComponentsAudioComponent } from './audio.component';\nimport { CommonModule } from '@angular/common';\n\n/**\n * Demo component hiển thị các ví dụ khác nhau của Audio component\n */\n@Component({\n selector: 'lib-audio-demo',\n standalone: true,\n imports: [LibsUiComponentsAudioComponent, CommonModule],\n styles: [`\n .demo-section {\n margin-bottom: 2rem;\n padding: 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 0.5rem;\n }\n \n .demo-title {\n font-size: 1.25rem;\n font-weight: 600;\n margin-bottom: 1rem;\n }\n \n .demo-description {\n margin-bottom: 1rem;\n color: #4b5563;\n }\n `],\n template: `\n <div class=\"p-4\">\n <h1 class=\"text-2xl font-bold mb-4\">Audio Component Demo</h1>\n \n <p class=\"mb-4\">\n Audio Component là một trình phát âm thanh tùy chỉnh với các controls đầy đủ như play/pause, \n volume control, progress bar và download button.\n </p>\n \n <div class=\"demo-section\">\n <div class=\"demo-title\">Basic Usage</div>\n <p class=\"demo-description\">Simple audio player với default settings</p>\n <libs_ui-components-audio\n fileAudio=\"https://nhacchuong123.com/nhac-chuong/abcdefgh/nhac-chuong-nguoi-ay-dau-co-dang-akira-phan-nguyen-van-chung.mp3\"\n [checkPermissionDownloadAudio]=\"basicPermissionCheck\"\n />\n </div>\n \n <div class=\"demo-section\">\n <div class=\"demo-title\">Disabled Download</div>\n <p class=\"demo-description\">Audio player không cho phép download</p>\n <libs_ui-components-audio\n fileAudio=\"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3\"\n [checkPermissionDownloadAudio]=\"denyPermissionCheck\"\n />\n </div>\n \n <div class=\"demo-section\">\n <div class=\"demo-title\">Long Audio File</div>\n <p class=\"demo-description\">Audio player với track có duration dài hơn</p>\n <libs_ui-components-audio\n fileAudio=\"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3\"\n [checkPermissionDownloadAudio]=\"basicPermissionCheck\"\n />\n </div>\n\n <div class=\"demo-section\">\n <div class=\"demo-title\">Delayed Permission Check</div>\n <p class=\"demo-description\">Mô phỏng permission check có delay, simulate API call</p>\n <libs_ui-components-audio\n fileAudio=\"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3\"\n [checkPermissionDownloadAudio]=\"delayedPermissionCheck\"\n />\n </div>\n </div>\n `\n})\nexport class LibsUiComponentsAudioDemoComponent {\n /**\n * Permission function luôn allow download\n */\n basicPermissionCheck(): Promise<boolean> {\n return Promise.resolve(true);\n }\n \n /**\n * Permission function không cho phép download\n */\n denyPermissionCheck(): Promise<boolean> {\n return Promise.resolve(false);\n }\n\n /**\n * Permission function có delay để mô phỏng API call\n */\n delayedPermissionCheck(): Promise<boolean> {\n return new Promise(resolve => {\n setTimeout(() => {\n resolve(true);\n }, 1500);\n });\n }\n} ","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libs-ui/components-audio",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.190",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/core": "^18.2.0",
|
|
6
|
-
"@libs-ui/components-inputs-range-slider": "^0.2.
|
|
6
|
+
"@libs-ui/components-inputs-range-slider": "^0.2.190",
|
|
7
7
|
"rxjs": "~7.8.0"
|
|
8
8
|
},
|
|
9
9
|
"sideEffects": false,
|