UNPKG

ng-smart-on-fhir

Version:

[![SRDC](https://www.srdc.com.tr/wp-content/uploads/2014/12/srdc-wp.png)](https://srdc.com.tr/en)

127 lines 18.9 kB
import { Component, ViewChild } from '@angular/core'; import jsQR from 'jsqr'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; /** * QR reader & parser component */ export class QrReaderComponent { constructor(router) { this.router = router; this.scanning = false; this.qrResult = null; } ngOnInit() { window['jsqr'] = jsQR; this.startCamera(); } async startCamera() { try { this.videoStream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } }); const video = this.videoElement.nativeElement; video.srcObject = this.videoStream; video.onloadedmetadata = () => { video.play(); this.scanning = true; this.scanQRCode(); }; } catch (error) { console.error('Error accessing camera:', error); } } scanQRCode() { if (!this.scanning) return; const video = this.videoElement.nativeElement; const canvas = this.canvasElement.nativeElement; const ctx = canvas.getContext('2d'); if (!ctx) return; const scan = () => { if (!this.scanning) return; // Ensure video dimensions are available if (video.videoWidth === 0 || video.videoHeight === 0) { requestAnimationFrame(scan); return; } canvas.width = video.videoWidth; canvas.height = video.videoHeight; ctx.drawImage(video, 0, 0, canvas.width, canvas.height); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const code = jsQR(imageData.data, imageData.width, imageData.height); if (code) { this.checkCode(code); } else { requestAnimationFrame(scan); } }; scan(); } scanFile(event) { const input = event.target; if (input.files && input.files[0]) { const file = input.files[0]; const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.src = e.target?.result; img.onload = () => { const canvas = this.fileCanvasElement.nativeElement; const ctx = canvas.getContext('2d'); if (ctx) { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0, img.width, img.height); const imageData = ctx.getImageData(0, 0, img.width, img.height); const code = jsQR(imageData.data, imageData.width, imageData.height); if (code) { this.checkCode(code); } else { this.error = 'The file does not contain a valid QR.'; } } }; }; reader.readAsDataURL(file); } } stopCamera() { if (this.videoStream) { this.videoStream.getTracks().forEach(track => track.stop()); } this.scanning = false; } ngOnDestroy() { this.stopCamera(); } checkCode(code) { this.qrResult = code.data; if (!(this.qrResult.startsWith('shc:/') || this.qrResult.startsWith('shlink:/'))) { this.error = 'QR doesn\' contain a SMART Health Card or Link'; } else { this.router.navigate([!this.qrResult.startsWith('shc:/') ? '/shc' : '/shl'], { fragment: this.qrResult }); this.stopCamera(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: QrReaderComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: QrReaderComponent, selector: "sof-qr-reader", viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["video"], descendants: true, static: true }, { propertyName: "canvasElement", first: true, predicate: ["canvas"], descendants: true, static: true }, { propertyName: "fileCanvasElement", first: true, predicate: ["fileCanvas"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"scanner-container\">\r\n <h2>QR Scanner</h2>\r\n\r\n <!-- Live Camera Scanner -->\r\n <video #video class=\"qr-video\"></video>\r\n <canvas #canvas class=\"qr-canvas\"></canvas>\r\n\r\n <hr>\r\n\r\n <!-- File Upload Scanner -->\r\n <input type=\"file\" accept=\"image/*\" (change)=\"scanFile($event)\">\r\n <canvas #fileCanvas class=\"qr-file-canvas\"></canvas>\r\n\r\n @if (qrResult) {\r\n <p>Scanned QR Code: {{ qrResult }}</p>\r\n }\r\n</div>\r\n", styles: [".scanner-container{text-align:center;width:100%;max-width:500px;margin:auto}.qr-video{width:100%;height:auto;border:2px solid #000}.qr-canvas,.qr-file-canvas{display:none}input[type=file]{margin:10px 0}\n"] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: QrReaderComponent, decorators: [{ type: Component, args: [{ selector: 'sof-qr-reader', template: "<div class=\"scanner-container\">\r\n <h2>QR Scanner</h2>\r\n\r\n <!-- Live Camera Scanner -->\r\n <video #video class=\"qr-video\"></video>\r\n <canvas #canvas class=\"qr-canvas\"></canvas>\r\n\r\n <hr>\r\n\r\n <!-- File Upload Scanner -->\r\n <input type=\"file\" accept=\"image/*\" (change)=\"scanFile($event)\">\r\n <canvas #fileCanvas class=\"qr-file-canvas\"></canvas>\r\n\r\n @if (qrResult) {\r\n <p>Scanned QR Code: {{ qrResult }}</p>\r\n }\r\n</div>\r\n", styles: [".scanner-container{text-align:center;width:100%;max-width:500px;margin:auto}.qr-video{width:100%;height:auto;border:2px solid #000}.qr-canvas,.qr-file-canvas{display:none}input[type=file]{margin:10px 0}\n"] }] }], ctorParameters: () => [{ type: i1.Router }], propDecorators: { videoElement: [{ type: ViewChild, args: ['video', { static: true }] }], canvasElement: [{ type: ViewChild, args: ['canvas', { static: true }] }], fileCanvasElement: [{ type: ViewChild, args: ['fileCanvas', { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXItcmVhZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LW9uLWZoaXIvc3JjL2xpYi9jb21wb25lbnRzL3FyLXJlYWRlci9xci1yZWFkZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtb24tZmhpci9zcmMvbGliL2NvbXBvbmVudHMvcXItcmVhZGVyL3FyLXJlYWRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFzQixTQUFTLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDcEYsT0FBTyxJQUFjLE1BQU0sTUFBTSxDQUFDOzs7QUFHbEM7O0dBRUc7QUFNSCxNQUFNLE9BQU8saUJBQWlCO0lBVTVCLFlBQW9CLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBSmxDLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFDMUIsYUFBUSxHQUFrQixJQUFJLENBQUM7SUFJL0IsQ0FBQztJQUVELFFBQVE7UUFDQSxNQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBQ0QsS0FBSyxDQUFDLFdBQVc7UUFDZixJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sU0FBUyxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZHLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDO1lBQzlDLEtBQUssQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUVuQyxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsR0FBRyxFQUFFO2dCQUM1QixLQUFL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Q0FBQyxJQUFZO1FBQzVCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDakYsSUFBSSxDQUFDLEtBQUssR0FBRyxnREFBZ0QsQ0FBQztRQUNoRSxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQTtZQUN6RyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDcEIsQ0FBQztJQUNILENBQUM7K0dBekhVLGlCQUFpQjttR0FBakIsaUJBQWlCLGtZQ1o5Qiw2ZEFpQkE7OzRGRExhLGlCQUFpQjtrQkFMN0IsU0FBUzsrQkFDRSxlQUFlOzJFQUthLFlBQVk7c0JBQWpELFNBQVM7dUJBQUMsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFDRyxhQUFhO3NCQUFuRCxTQUFTO3VCQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ00saUJBQWlCO3NCQUEzRCxTQUFTO3VCQUFDLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIE9uSW5pdCwgVmlld0NoaWxkLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IGpzUVIsIHtRUkNvZGV9IGZyb20gJ2pzcXInO1xyXG5pbXBvcnQge1JvdXRlcn0gZnJvbSBcIkBhbmd1bGFyL3JvdXRlclwiO1xyXG5cclxuLyoqXHJcbiAqIFFSIHJlYWRlciAmIHBhcnNlciBjb21wb25lbnRcclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnc29mLXFyLXJlYWRlcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3FyLXJlYWRlci5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vcXItcmVhZGVyLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFFyUmVhZGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBWaWV3Q2hpbGQoJ3ZpZGVvJywgeyBzdGF0aWM6IHRydWUgfSkgdmlkZW9FbGVtZW50ITogRWxlbWVudFJlZjxIVE1MVmlkZW9FbGVtZW50PjtcclxuICBAVmlld0NoaWxkKCdjYW52YXMnLCB7IHN0YXRpYzogdHJ1ZSB9KSBjYW52YXNFbGVtZW50ITogRWxlbWVudFJlZjxIVE1MQ2FudmFzRWxlbWVudD47XHJcbiAgQFZpZXdDaGlsZCgnZmlsZUNhbnZhcycsIHsgc3RhdGljOiB0cnVlIH0pIGZpbGVDYW52YXNFbGVtZW50ITogRWxlbWVudFJlZjxIVE1MQ2FudmFzRWxlbWVudD47XHJcblxyXG4gIHZpZGVvU3RyZWFtITogTWVkaWFTdHJlYW07XHJcbiAgc2Nhbm5pbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBxclJlc3VsdDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XHJcbiAgZXJyb3I6IHN0cmluZ3x1bmRlZmluZWQ7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcm91dGVyOiBSb3V0ZXIpIHtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgKDxhbnk+d2luZG93KVsnanNxciddID0ganNRUjtcclxuICAgIHRoaXMuc3RhcnRDYW1lcmEoKTtcclxuICB9XHJcbiAgYXN5bmMgc3RhcnRDYW1lcmEoKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLnZpZGVvU3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoeyB2aWRlbzogeyBmYWNpbmdNb2RlOiAnZW52aXJvbm1lbnQnIH0gfSk7XHJcbiAgICAgIGNvbnN0IHZpZGVvID0gdGhpcy52aWRlb0VsZW1lbnQubmF0aXZlRWxlbWVudDtcclxuICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy52aWRlb1N0cmVhbTtcclxuXHJcbiAgICAgIHZpZGVvLm9ubG9hZGVkbWV0YWRhdGEgPSAoKSA9PiB7XHJcbiAgICAgICAgdmlkZW8ucGxheSgpO1xyXG4gICAgICAgIHRoaXMuc2Nhbm5pbmcgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuc2NhblFSQ29kZSgpO1xyXG4gICAgICB9O1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgYWNjZXNzaW5nIGNhbWVyYTonLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzY2FuUVJDb2RlKCkge1xyXG4gICAgaWYgKCF0aGlzLnNjYW5uaW5nKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgdmlkZW8gPSB0aGlzLnZpZGVvRWxlbWVudC5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5jYW52YXNFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuXHJcbiAgICBpZiAoIWN0eCkgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IHNjYW4gPSAoKSA9PiB7XHJcbiAgICAgIGlmICghdGhpcy5zY2FubmluZykgcmV0dXJuO1xyXG5cclxuICAgICAgLy8gRW5zdXJlIHZpZGVvIGRpbWVuc2lvbnMgYXJlIGF2YWlsYWJsZVxyXG4gICAgICBpZiAodmlkZW8udmlkZW9XaWR0aCA9PT0gMCB8fCB2aWRlby52aWRlb0hlaWdodCA9PT0gMCkge1xyXG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShzY2FuKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNhbnZhcy53aWR0aCA9IHZpZGVvLnZpZGVvV2lkdGg7XHJcbiAgICAgIGNhbnZhcy5oZWlnaHQgPSB2aWRlby52aWRlb0hlaWdodDtcclxuXHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XHJcbiAgICAgIGNvbnN0IGltYWdlRGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcclxuICAgICAgY29uc3QgY29kZSA9IGpzUVIoaW1hZ2VEYXRhLmRhdGEsIGltYWdlRGF0YS53aWR0aCwgaW1hZ2VEYXRhLmhlaWdodCk7XHJcblxyXG4gICAgICBpZiAoY29kZSkge1xyXG4gICAgICAgIHRoaXMuY2hlY2tDb2RlKGNvZGUpXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHNjYW4pO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHNjYW4oKTtcclxuICB9XHJcblxyXG4gIHNjYW5GaWxlKGV2ZW50OiBFdmVudCkge1xyXG4gICAgY29uc3QgaW5wdXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcclxuICAgIGlmIChpbnB1dC5maWxlcyAmJiBpbnB1dC5maWxlc1swXSkge1xyXG4gICAgICBjb25zdCBmaWxlID0gaW5wdXQuZmlsZXNbMF07XHJcbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcblxyXG4gICAgICByZWFkZXIub25sb2FkID0gKGUpID0+IHtcclxuICAgICAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcclxuICAgICAgICBpbWcuc3JjID0gZS50YXJnZXQ/LnJlc3VsdCBhcyBzdHJpbmc7XHJcbiAgICAgICAgaW1nLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuZmlsZUNhbnZhc0VsZW1lbnQubmF0aXZlRWxlbWVudDtcclxuICAgICAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xyXG5cclxuICAgICAgICAgIGlmIChjdHgpIHtcclxuICAgICAgICAgICAgY2FudmFzLndpZHRoID0gaW1nLndpZHRoO1xyXG4gICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaW1nLmhlaWdodDtcclxuICAgICAgICAgICAgY3R4LmRyYXdJbWFnZShpbWcsIDAsIDAsIGltZy53aWR0aCwgaW1nLmhlaWdodCk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBpbWFnZURhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIGltZy53aWR0aCwgaW1nLmhlaWdodCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvZGUgPSBqc1FSKGltYWdlRGF0YS5kYXRhLCBpbWFnZURhdGEud2lkdGgsIGltYWdlRGF0YS5oZWlnaHQpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvZGUpIHtcclxuICAgICAgICAgICAgICB0aGlzLmNoZWNrQ29kZShjb2RlKVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSAnVGhlIGZpbGUgZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIFFSLidcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgIH07XHJcblxyXG4gICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHN0b3BDYW1lcmEoKSB7XHJcbiAgICBpZiAodGhpcy52aWRlb1N0cmVhbSkge1xyXG4gICAgICB0aGlzLnZpZGVvU3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2godHJhY2sgPT4gdHJhY2suc3RvcCgpKTtcclxuICAgIH1cclxuICAgIHRoaXMuc2Nhbm5pbmcgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5zdG9wQ2FtZXJhKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNoZWNrQ29kZShjb2RlOiBRUkNvZGUpIHtcclxuICAgIHRoaXMucXJSZXN1bHQgPSBjb2RlLmRhdGE7XHJcbiAgICBpZiAoISh0aGlzLnFyUmVzdWx0LnN0YXJ0c1dpdGgoJ3NoYzovJykgfHwgdGhpcy5xclJlc3VsdC5zdGFydHNXaXRoKCdzaGxpbms6LycpKSkge1xyXG4gICAgICB0aGlzLmVycm9yID0gJ1FSIGRvZXNuXFwnIGNvbnRhaW4gYSBTTUFSVCBIZWFsdGggQ2FyZCBvciBMaW5rJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFshdGhpcy5xclJlc3VsdC5zdGFydHNXaXRoKCdzaGM6LycpID8gJy9zaGMnIDogJy9zaGwnXSwgeyBmcmFnbWVudDogdGhpcy5xclJlc3VsdCB9KVxyXG4gICAgICB0aGlzLnN0b3BDYW1lcmEoKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cInNjYW5uZXItY29udGFpbmVyXCI+XHJcbiAgPGgyPlFSIFNjYW5uZXI8L2gyPlxyXG5cclxuICA8IS0tIExpdmUgQ2FtZXJhIFNjYW5uZXIgLS0+XHJcbiAgPHZpZGVvICN2aWRlbyBjbGFzcz1cInFyLXZpZGVvXCI+PC92aWRlbz5cclxuICA8Y2FudmFzICNjYW52YXMgY2xhc3M9XCJxci1jYW52YXNcIj48L2NhbnZhcz5cclxuXHJcbiAgPGhyPlxyXG5cclxuICA8IS0tIEZpbGUgVXBsb2FkIFNjYW5uZXIgLS0+XHJcbiAgPGlucHV0IHR5cGU9XCJmaWxlXCIgYWNjZXB0PVwiaW1hZ2UvKlwiIChjaGFuZ2UpPVwic2NhbkZpbGUoJGV2ZW50KVwiPlxyXG4gIDxjYW52YXMgI2ZpbGVDYW52YXMgY2xhc3M9XCJxci1maWxlLWNhbnZhc1wiPjwvY2FudmFzPlxyXG5cclxuICBAaWYgKHFyUmVzdWx0KSB7XHJcbiAgICA8cD5TY2FubmVkIFFSIENvZGU6IHt7IHFyUmVzdWx0IH19PC9wPlxyXG4gIH1cclxuPC9kaXY+XHJcbiJdfQ==