osl-base-extended 3.0.1 → 3.0.3

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.
@@ -402,6 +402,29 @@ class Httpbase {
402
402
  return this.handleError(error);
403
403
  }
404
404
  }
405
+ async download(methodName, fileName, params) {
406
+ try {
407
+ const res = await firstValueFrom(this.http
408
+ .get(this.getEndPoint(methodName), {
409
+ observe: 'response',
410
+ headers: this.getHeaders(),
411
+ params: this.buildParams(params || []),
412
+ responseType: 'blob',
413
+ })
414
+ .pipe(timeout(60000)));
415
+ const blob = res.body;
416
+ const url = URL.createObjectURL(blob);
417
+ const anchor = document.createElement('a');
418
+ anchor.href = url;
419
+ anchor.download = fileName;
420
+ anchor.click();
421
+ URL.revokeObjectURL(url);
422
+ return this.handleSuccess(res.status, null, res.headers);
423
+ }
424
+ catch (error) {
425
+ return this.handleError(error);
426
+ }
427
+ }
405
428
  /** Multipart file upload — do NOT pass Content-Type; browser sets the boundary */
406
429
  async upload(methodName, formData, params) {
407
430
  try {
@@ -5384,6 +5407,7 @@ class OslDocumentUploader {
5384
5407
  showUploadButton = false;
5385
5408
  uploadButtonLabel = 'Upload Files';
5386
5409
  savedDocuments = [];
5410
+ savedDocsMaxHeight = '260px';
5387
5411
  skeletonLoading = false;
5388
5412
  skeletonTheme = 'light';
5389
5413
  uploadCallback = new EventEmitter();
@@ -5527,11 +5551,11 @@ class OslDocumentUploader {
5527
5551
  onDelete(doc) { this.deleteCallback.emit(doc); }
5528
5552
  onDownload(doc) { this.downloadCallback.emit(doc); }
5529
5553
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslDocumentUploader, deps: [], target: i0.ɵɵFactoryTarget.Component });
5530
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslDocumentUploader, isStandalone: false, selector: "osl-document-uploader", inputs: { label: "label", required: "required", disabled: "disabled", multiple: "multiple", accept: "accept", maxSize: "maxSize", minFiles: "minFiles", maxFiles: "maxFiles", showUploadButton: "showUploadButton", uploadButtonLabel: "uploadButtonLabel", savedDocuments: "savedDocuments", skeletonLoading: "skeletonLoading", skeletonTheme: "skeletonTheme" }, outputs: { uploadCallback: "uploadCallback", viewCallback: "viewCallback", deleteCallback: "deleteCallback", downloadCallback: "downloadCallback", filesChanged: "filesChanged" }, ngImport: i0, template: "<div class=\"du-container\" [class.du--disabled]=\"disabled\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n\n @if (label) {\n <label class=\"du-label\" [class.du-label--error]=\"isInvalid\">\n <span class=\"du-label__text\" [title]=\"label\">{{ label }}</span>\n @if (required) { <span class=\"du-label__req\">*</span> }\n </label>\n }\n\n <input type=\"file\" [accept]=\"accept\" [multiple]=\"multiple\" [disabled]=\"disabled || maxFilesReached\"\n (change)=\"onFileChange($event)\" #fileInput class=\"du-file-input\">\n\n <!-- \u2500\u2500 Drop Zone \u2500\u2500 -->\n <div class=\"du-dropzone\"\n [class.du-dropzone--over]=\"isDragOver\"\n [class.du-dropzone--error]=\"isInvalid\"\n [class.du-dropzone--disabled]=\"disabled\"\n [class.du-dropzone--maxed]=\"maxFilesReached\"\n (click)=\"triggerInput(fileInput)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n\n <div class=\"du-particles\">\n <span class=\"du-p du-p--1\"></span>\n <span class=\"du-p du-p--2\"></span>\n <span class=\"du-p du-p--3\"></span>\n <span class=\"du-p du-p--4\"></span>\n <span class=\"du-p du-p--5\"></span>\n <span class=\"du-p du-p--6\"></span>\n </div>\n\n <div class=\"du-dropzone__inner\">\n\n @if (maxFilesReached) {\n <!-- Max files reached state -->\n <div class=\"du-maxed-icon\">\n <svg viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"#f0fdf4\" stroke=\"#86efac\" stroke-width=\"2\"/>\n <path d=\"M20 32l8 8 16-16\" stroke=\"#22c55e\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <p class=\"du-dropzone__headline\">\n <span class=\"du-gradient-text du-gradient-text--green\">Limit reached</span>\n </p>\n <p class=\"du-maxed-sub\">{{ maxFiles }} / {{ maxFiles }} files added</p>\n } @else {\n\n <!-- Cloud SVG -->\n <div class=\"du-cloud-wrap\" [class.du-cloud-wrap--over]=\"isDragOver\">\n <svg class=\"du-cloud-svg\" viewBox=\"0 0 90 72\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path class=\"du-cloud-body\"\n d=\"M63 42H27C19.8 42 14 36.2 14 29C14 22.2 19.2 16.7 25.8 16.1C25.9 9.4 31.3 4 38 4C42.8 4 47 6.7 49.2 10.7C50.8 9.6 52.8 9 55 9C61 9 65.9 13.9 65.9 19.9V20.1C72.1 20.9 77 26.3 77 33C77 38.1 70.7 42 63 42Z\"\n stroke=\"#667eea\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <line class=\"du-arrow\" x1=\"45\" y1=\"64\" x2=\"45\" y2=\"46\" stroke=\"#764ba2\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>\n <polyline class=\"du-arrow\" points=\"37,55 45,46 53,55\"\n stroke=\"#764ba2\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <circle class=\"du-cloud-glint\" cx=\"30\" cy=\"26\" r=\"3\" fill=\"#a5b4fc\" opacity=\"0.5\"/>\n </svg>\n </div>\n\n @if (!isDragOver) {\n <p class=\"du-dropzone__headline\">\n <span class=\"du-gradient-text\">Click to browse</span><span class=\"du-or\"> or drag &amp; drop</span>\n </p>\n <div class=\"du-dropzone__meta\">\n @if (multiple) {\n @if (maxFiles > 0 && minFiles > 0) {\n <span class=\"du-chip du-chip--info\">{{ minFiles }}\u2013{{ maxFiles }} files</span>\n } @else if (maxFiles > 0) {\n <span class=\"du-chip du-chip--info\">Max {{ maxFiles }} files</span>\n } @else if (minFiles > 0) {\n <span class=\"du-chip du-chip--info\">Min {{ minFiles }} files</span>\n } @else {\n <span class=\"du-chip du-chip--info\">Multiple files</span>\n }\n } @else {\n <span class=\"du-chip du-chip--info\">Single file</span>\n }\n @if (accept) { <span class=\"du-chip\">{{ accept }}</span> }\n @if (maxSize) { <span class=\"du-chip\">{{ maxSizeLabel }}</span> }\n </div>\n } @else {\n <p class=\"du-dropzone__headline du-dropzone__headline--drop\">\n <span class=\"du-gradient-text\">Release to drop!</span>\n </p>\n }\n\n }\n </div>\n </div>\n\n <!-- \u2500\u2500 Errors \u2500\u2500 -->\n @for (err of sizeErrors; track err) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n {{ err }}\n </div>\n }\n @if (requiredError) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n {{ label || 'File' }} is required!\n </div>\n }\n @if (minFilesError) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n At least {{ minFiles }} files are required ({{ pendingFiles.length }} added).\n </div>\n }\n\n <!-- \u2500\u2500 Pending Files \u2500\u2500 -->\n @if (pendingFiles.length > 0) {\n <div class=\"du-section\">\n <div class=\"du-section__hdr\">\n <span class=\"du-section__title\">Queued Files</span>\n @if (multiple && maxFiles > 0) {\n <span class=\"du-count-label\" [class.du-count-label--full]=\"maxFilesReached\">\n {{ pendingFiles.length }} / {{ maxFiles }}\n </span>\n } @else {\n <span class=\"du-count du-count--purple\">{{ pendingFiles.length }}</span>\n }\n </div>\n <div class=\"du-file-list\">\n @for (file of pendingFiles; track file.name; let i = $index) {\n <div class=\"du-file-card\" [attr.data-ftype]=\"getFileType(file.name)\" [style.animation-delay]=\"i * 40 + 'ms'\">\n\n <div class=\"du-file-icon\">\n @switch (getFileType(file.name)) {\n @case ('pdf') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#FEE2E2\"/>\n <path d=\"M26 4v10h10\" fill=\"#FECACA\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#EF4444\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">PDF</text>\n </svg>\n }\n @case ('word') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#DBEAFE\"/>\n <path d=\"M26 4v10h10\" fill=\"#BFDBFE\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#3B82F6\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">DOC</text>\n </svg>\n }\n @case ('excel') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#DCFCE7\"/>\n <path d=\"M26 4v10h10\" fill=\"#BBF7D0\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#22C55E\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">XLS</text>\n </svg>\n }\n @case ('image') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#FEF9C3\"/>\n <path d=\"M26 4v10h10\" fill=\"#FEF08A\"/>\n <rect x=\"6\" y=\"18\" width=\"28\" height=\"18\" rx=\"2\" fill=\"#FDE047\"/>\n <circle cx=\"13\" cy=\"24\" r=\"3\" fill=\"#CA8A04\"/>\n <path d=\"M6 36l9-9 5 5 4-4 10 8H6Z\" fill=\"#EAB308\" opacity=\"0.8\"/>\n </svg>\n }\n @case ('archive') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#EDE9FE\"/>\n <path d=\"M26 4v10h10\" fill=\"#DDD6FE\"/>\n <rect x=\"14\" y=\"12\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#A78BFA\"/>\n <rect x=\"14\" y=\"18\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#C4B5FD\"/>\n <rect x=\"14\" y=\"24\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#A78BFA\"/>\n <rect x=\"14\" y=\"30\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#C4B5FD\"/>\n <rect x=\"16\" y=\"26\" width=\"8\" height=\"6\" rx=\"1\" fill=\"#7C3AED\"/>\n </svg>\n }\n @default {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#F1F5F9\"/>\n <path d=\"M26 4v10h10\" fill=\"#E2E8F0\"/>\n <line x1=\"10\" y1=\"24\" x2=\"30\" y2=\"24\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <line x1=\"10\" y1=\"30\" x2=\"26\" y2=\"30\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <line x1=\"10\" y1=\"36\" x2=\"22\" y2=\"36\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n }\n }\n </div>\n\n <div class=\"du-file-info\">\n <span class=\"du-file-name\" [title]=\"file.name\">{{ file.name }}</span>\n <span class=\"du-file-size\">{{ getFileSize(file.size) }}</span>\n </div>\n\n <button type=\"button\" class=\"du-remove-btn\" (click)=\"removeFile(i)\" title=\"Remove\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <path d=\"M15 9L9 15M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Upload Button \u2500\u2500 -->\n @if (showUploadButton && pendingFiles.length > 0) {\n <button type=\"button\" class=\"du-upload-btn\" (click)=\"upload()\" [disabled]=\"disabled\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" width=\"17\" height=\"17\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>\n <polyline points=\"17,8 12,3 7,8\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>\n </svg>\n {{ uploadButtonLabel }}\n <span class=\"du-upload-btn__badge\">{{ pendingFiles.length }}</span>\n </button>\n }\n\n <!-- \u2500\u2500 Saved Documents \u2500\u2500 -->\n @if (savedDocuments.length > 0) {\n <div class=\"du-section\">\n <div class=\"du-section__hdr\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" class=\"du-section__icon\">\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\" stroke=\"#10b981\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <polyline points=\"14,2 14,8 20,8\" stroke=\"#10b981\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"du-section__title\">Saved Documents</span>\n <span class=\"du-count du-count--green\">{{ savedDocuments.length }}</span>\n </div>\n <div class=\"du-saved-list\">\n @for (doc of savedDocuments; track doc.id; let i = $index) {\n <div class=\"du-saved-card\" [style.animation-delay]=\"i * 50 + 'ms'\">\n\n <div class=\"du-saved-icon\">\n @switch (getFileType(doc.name)) {\n @case ('pdf') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#FEE2E2\"/>\n <path d=\"M20 3v8h8\" fill=\"#FECACA\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#EF4444\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">PDF</text>\n </svg>\n }\n @case ('word') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#DBEAFE\"/>\n <path d=\"M20 3v8h8\" fill=\"#BFDBFE\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#3B82F6\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">DOC</text>\n </svg>\n }\n @case ('excel') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#DCFCE7\"/>\n <path d=\"M20 3v8h8\" fill=\"#BBF7D0\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#22C55E\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">XLS</text>\n </svg>\n }\n @case ('image') {\n <svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#FEF9C3\"/>\n <rect x=\"4\" y=\"7\" width=\"24\" height=\"18\" rx=\"2\" fill=\"#FDE047\"/>\n <circle cx=\"10\" cy=\"13\" r=\"2.5\" fill=\"#CA8A04\"/>\n <path d=\"M4 25l8-8 5 5 4-4 11 7H4Z\" fill=\"#EAB308\" opacity=\"0.7\"/>\n </svg>\n }\n @case ('archive') {\n <svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#EDE9FE\"/>\n <rect x=\"4\" y=\"8\" width=\"24\" height=\"5\" rx=\"1.5\" fill=\"#A78BFA\"/>\n <rect x=\"4\" y=\"14\" width=\"24\" height=\"14\" rx=\"2\" fill=\"#C4B5FD\"/>\n <rect x=\"11\" y=\"18\" width=\"10\" height=\"6\" rx=\"1.5\" fill=\"#7C3AED\"/>\n <line x1=\"16\" y1=\"18\" x2=\"16\" y2=\"24\" stroke=\"white\" stroke-width=\"1.5\"/>\n </svg>\n }\n @default {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#F1F5F9\"/>\n <path d=\"M20 3v8h8\" fill=\"#E2E8F0\"/>\n <line x1=\"7\" y1=\"20\" x2=\"25\" y2=\"20\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n <line x1=\"7\" y1=\"25\" x2=\"21\" y2=\"25\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n <line x1=\"7\" y1=\"30\" x2=\"17\" y2=\"30\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n </svg>\n }\n }\n </div>\n\n <div class=\"du-saved-info\">\n <span class=\"du-saved-name\" [title]=\"doc.name\">{{ doc.name }}</span>\n @if (doc.addBy || doc.addOn) {\n <span class=\"du-saved-meta\">\n @if (doc.addBy) { <span class=\"du-saved-by\">{{ doc.addBy }}</span> }\n @if (doc.addBy && doc.addOn) { <span class=\"du-saved-sep\">\u00B7</span> }\n @if (doc.addOn) { <span class=\"du-saved-on\">{{ formatDate(doc.addOn) }}</span> }\n </span>\n }\n </div>\n\n <div class=\"du-saved-actions\">\n <button type=\"button\" class=\"du-act du-act--view\" (click)=\"onView(doc)\" title=\"View\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/>\n </svg>\n </button>\n <button type=\"button\" class=\"du-act du-act--download\" (click)=\"onDownload(doc)\" title=\"Download\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <polyline points=\"7,10 12,15 17,10\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n <button type=\"button\" class=\"du-act du-act--delete\" (click)=\"onDelete(doc)\" title=\"Delete\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <polyline points=\"3,6 5,6 21,6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M10 11v6M14 11v6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n\n </div>\n }\n </div>\n </div>\n }\n\n</div>\n", styles: ["@keyframes du-float{0%,to{transform:translateY(0)}50%{transform:translateY(-9px)}}@keyframes du-arrow-bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@keyframes du-particle{0%,to{transform:translate(0) scale(1);opacity:.25}33%{transform:translate(4px,-14px) scale(1.15);opacity:.5}66%{transform:translate(-4px,-7px) scale(.88);opacity:.2}}@keyframes du-slide-in{0%{opacity:0;transform:translate(18px)}to{opacity:1;transform:translate(0)}}@keyframes du-fade-up{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes du-pop-in{0%{opacity:0;transform:scale(.8)}70%{transform:scale(1.06)}to{opacity:1;transform:scale(1)}}@keyframes du-glow-pulse{0%,to{box-shadow:0 0 #667eea59}50%{box-shadow:0 0 0 8px #667eea00}}@keyframes du-btn-pulse{0%,to{box-shadow:0 4px 20px #667eea66}50%{box-shadow:0 6px 30px #764ba299}}@keyframes du-gradient-shift{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes du-ripple{0%{transform:scale(.6);opacity:.7}to{transform:scale(2.2);opacity:0}}@keyframes du-glint{0%,80%,to{opacity:0;transform:scale(.5)}40%{opacity:.7;transform:scale(1.4)}}.du-container{display:flex;flex-direction:column;gap:10px;width:100%}.du-container.du--disabled{opacity:.55;pointer-events:none}.du-label{display:flex;align-items:center;gap:2px;font-size:var(--osl-label-font-size, 13px);font-weight:500;color:#374151;overflow:hidden}.du-label--error{color:var(--osl-error-color, #ef4444)}.du-label__text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.du-label__req{color:var(--osl-error-color, #ef4444);flex-shrink:0;font-weight:700}.du-file-input{display:none}.du-dropzone{position:relative;width:100%;min-height:158px;border-radius:18px;border:2px dashed rgba(102,126,234,.35);background:linear-gradient(145deg,#fafbff,#f5f3ff);cursor:pointer;overflow:hidden;transition:border-color .3s ease,background .3s ease,box-shadow .3s ease,transform .25s ease}.du-dropzone:hover:not(.du-dropzone--disabled){border-color:#667eeab3;background:linear-gradient(145deg,#f5f3ff,#ede9fe);transform:translateY(-2px);box-shadow:0 10px 30px #667eea1f}.du-dropzone--over{border:2px solid #667eea!important;background:linear-gradient(145deg,#ede9fe,#ddd6fe)!important;transform:scale(1.012) translateY(-3px)!important;box-shadow:0 18px 40px #667eea38,inset 0 0 0 1px #667eea4d!important}.du-dropzone--over .du-cloud-body{stroke:#764ba2}.du-dropzone--over .du-cloud-glint{animation:du-glint .6s ease infinite}.du-dropzone--error{border-color:#ef444480;background:linear-gradient(145deg,#fff5f5,#fee2e2);animation:du-glow-pulse 1.8s ease infinite}.du-dropzone--disabled{cursor:not-allowed;background:#f9fafb!important;border-color:#e5e7eb!important;box-shadow:none!important;transform:none!important}.du-particles{position:absolute;inset:0;pointer-events:none;overflow:hidden}.du-p{position:absolute;border-radius:50%;background:radial-gradient(circle,#667eea38,#764ba21f);animation:du-particle var(--dur, 4s) ease-in-out infinite}.du-p--1{width:22px;height:22px;top:12%;left:6%;--dur: 4.2s;animation-delay:0s}.du-p--2{width:14px;height:14px;top:65%;left:88%;--dur: 5.1s;animation-delay:.9s}.du-p--3{width:18px;height:18px;top:18%;left:82%;--dur: 3.8s;animation-delay:1.6s}.du-p--4{width:10px;height:10px;top:75%;left:12%;--dur: 6.3s;animation-delay:.4s}.du-p--5{width:16px;height:16px;top:50%;left:48%;--dur: 4.7s;animation-delay:2.1s}.du-p--6{width:8px;height:8px;top:30%;left:38%;--dur: 5.5s;animation-delay:1.1s}.du-dropzone__inner{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:26px 20px;min-height:158px}.du-cloud-wrap{width:80px;height:64px;animation:du-float 3.2s ease-in-out infinite;filter:drop-shadow(0 4px 10px rgba(102,126,234,.2));transition:filter .3s ease;flex-shrink:0}.du-cloud-wrap--over{animation-duration:1.2s;filter:drop-shadow(0 6px 18px rgba(102,126,234,.45))}.du-cloud-svg{width:100%;height:100%}.du-cloud-body{transition:stroke .3s ease}.du-cloud-glint{transform-origin:center}.du-arrow{animation:du-arrow-bounce 1.6s ease-in-out infinite}.du-dropzone__headline{margin:0;font-size:14px;color:#6b7280;line-height:1.5;text-align:center}.du-dropzone__headline--drop .du-gradient-text{animation:du-glow-pulse .7s ease infinite}.du-gradient-text{background:linear-gradient(135deg,#667eea,#764ba2);background-size:200% 200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;font-weight:700;animation:du-gradient-shift 3s ease infinite}.du-or{color:#9ca3af;font-size:13px}.du-dropzone__meta{display:flex;flex-wrap:wrap;justify-content:center;gap:6px}.du-chip{border-radius:20px;padding:2px 10px;font-size:11px;font-weight:500;background:#667eea14;color:#7c6fcd;border:1px solid rgba(102,126,234,.18);transition:background .2s}.du-chip--info{background:#10b98114;color:#059669;border-color:#10b98133}.du-msg{display:flex;align-items:center;gap:6px;font-size:var(--osl-hint-font-size, 11px);animation:du-fade-up .2s ease}.du-msg svg{flex-shrink:0}.du-msg--error{color:var(--osl-error-color, #ef4444)}.du-section{display:flex;flex-direction:column;gap:8px;animation:du-fade-up .3s ease}.du-section__hdr{display:flex;align-items:center;gap:7px}.du-section__icon{flex-shrink:0}.du-section__title{font-size:11px;font-weight:700;color:#9ca3af;text-transform:uppercase;letter-spacing:.07em}.du-count{width:19px;height:19px;border-radius:50%;font-size:10px;font-weight:800;color:#fff;display:flex;align-items:center;justify-content:center;flex-shrink:0;animation:du-pop-in .3s ease}.du-count--purple{background:linear-gradient(135deg,#667eea,#764ba2)}.du-count--green{background:linear-gradient(135deg,#10b981,#059669)}.du-file-list{display:flex;flex-direction:column;gap:7px}.du-file-card{display:flex;align-items:center;gap:11px;padding:10px 14px 10px 16px;background:#fff;border-radius:13px;border:1px solid #e9ecf1;animation:du-slide-in .28s ease both;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease;position:relative}.du-file-card:before{content:\"\";position:absolute;left:0;top:50%;transform:translateY(-50%);width:4px;height:60%;border-radius:0 4px 4px 0;transition:height .2s ease}.du-file-card[data-ftype=pdf]:before{background:#ef4444}.du-file-card[data-ftype=word]:before{background:#3b82f6}.du-file-card[data-ftype=excel]:before{background:#22c55e}.du-file-card[data-ftype=image]:before{background:#f59e0b}.du-file-card[data-ftype=archive]:before{background:#8b5cf6}.du-file-card[data-ftype=generic]:before{background:#94a3b8}.du-file-card:hover{border-color:#c4b5fd;box-shadow:0 3px 14px #667eea1a;transform:translate(3px)}.du-file-card:hover:before{height:75%}.du-file-icon{width:38px;height:46px;flex-shrink:0}.du-file-icon svg{width:100%;height:100%}.du-file-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.du-file-name{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.du-file-size{font-size:11px;color:#94a3b8;font-weight:500}.du-remove-btn{width:30px;height:30px;flex-shrink:0;border-radius:50%;border:1.5px solid #fecaca;background:#fef2f2;color:#fca5a5;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:6px;transition:all .22s ease}.du-remove-btn svg{width:100%;height:100%}.du-remove-btn:hover{background:#fee2e2;border-color:#ef4444;color:#ef4444;transform:rotate(90deg) scale(1.1);box-shadow:0 3px 10px #ef444440}.du-upload-btn{display:flex;align-items:center;justify-content:center;gap:8px;padding:12px 24px;width:100%;border:none;border-radius:13px;background:linear-gradient(135deg,#667eea,#764ba2);background-size:200% 200%;color:#fff;font-size:14px;font-weight:700;letter-spacing:.03em;cursor:pointer;transition:transform .25s ease,box-shadow .25s ease;animation:du-btn-pulse 2.5s ease-in-out infinite,du-gradient-shift 4s ease infinite}.du-upload-btn svg{flex-shrink:0;transition:transform .25s ease}.du-upload-btn:hover:not([disabled]){transform:translateY(-3px);box-shadow:0 10px 28px #667eea80;animation:du-gradient-shift 1.5s ease infinite}.du-upload-btn:hover:not([disabled]) svg{transform:translateY(-3px)}.du-upload-btn:active:not([disabled]){transform:translateY(-1px)}.du-upload-btn[disabled]{opacity:.45;cursor:not-allowed;animation:none}.du-upload-btn__badge{min-width:22px;height:22px;padding:0 6px;border-radius:11px;background:#ffffff38;font-size:11px;font-weight:800;display:flex;align-items:center;justify-content:center;animation:du-pop-in .3s ease}.du-saved-list{display:flex;flex-direction:column;gap:7px}.du-saved-card{display:flex;align-items:center;gap:11px;padding:10px 12px;background:linear-gradient(135deg,#fff,#f8faff);border-radius:13px;border:1px solid #e9ecf1;opacity:0;animation:du-fade-up .32s ease forwards;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}.du-saved-card:hover{border-color:#a5b4fc;box-shadow:0 4px 18px #667eea1a;transform:translateY(-1px)}.du-saved-icon{width:32px;height:38px;flex-shrink:0}.du-saved-icon svg{width:100%;height:100%}.du-saved-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.du-saved-name{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.du-saved-size{font-size:11px;color:#94a3b8;font-weight:500}.du-saved-actions{display:flex;align-items:center;gap:5px;flex-shrink:0}.du-act{width:32px;height:32px;border-radius:9px;border:1.5px solid transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:7px;transition:all .22s ease;position:relative;overflow:hidden}.du-act svg{width:100%;height:100%;transition:transform .22s ease}.du-act:after{content:\"\";position:absolute;inset:50%;border-radius:50%;transition:all 0s;pointer-events:none}.du-act:active:after{inset:0;border-radius:9px;background:#ffffff59;animation:du-ripple .4s ease}.du-act--view{background:#eff6ff;color:#3b82f6;border-color:#bfdbfe}.du-act--view:hover{background:#dbeafe;border-color:#93c5fd;box-shadow:0 3px 12px #3b82f64d}.du-act--view:hover svg{transform:scale(1.12)}.du-act--download{background:#f0fdf4;color:#22c55e;border-color:#bbf7d0}.du-act--download:hover{background:#dcfce7;border-color:#86efac;box-shadow:0 3px 12px #22c55e4d}.du-act--download:hover svg{transform:translateY(2px) scale(1.08)}.du-act--delete{background:#fef2f2;color:#ef4444;border-color:#fecaca}.du-act--delete:hover{background:#fee2e2;border-color:#fca5a5;box-shadow:0 3px 12px #ef44444d}.du-act--delete:hover svg{transform:scale(1.1) rotate(-5deg)}.du-dropzone--maxed{cursor:default;border-color:#22c55e66!important;background:linear-gradient(145deg,#f0fdf4,#dcfce7)!important;pointer-events:none}.du-dropzone--maxed .du-particles .du-p{background:radial-gradient(circle,#22c55e2e,#10b9811a)}.du-maxed-icon{width:56px;height:56px;animation:du-pop-in .4s cubic-bezier(.34,1.56,.64,1)}.du-maxed-icon svg{width:100%;height:100%}.du-gradient-text--green{background:linear-gradient(135deg,#22c55e,#059669)!important;background-size:200% 200%!important;-webkit-background-clip:text!important;-webkit-text-fill-color:transparent!important;background-clip:text!important}.du-maxed-sub{margin:0;font-size:12px;color:#6b7280;font-weight:500}.du-count-label{font-size:11px;font-weight:700;padding:2px 9px;border-radius:20px;background:#667eea1a;color:#667eea;border:1px solid rgba(102,126,234,.2);transition:all .25s ease;animation:du-pop-in .3s ease}.du-count-label--full{background:#22c55e1a;color:#16a34a;border-color:#22c55e40}.du-saved-meta{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.du-saved-by{font-size:11px;font-weight:600;color:#667eea}.du-saved-sep{font-size:11px;color:#d1d5db}.du-saved-on{font-size:11px;color:#94a3b8}\n"], dependencies: [{ kind: "directive", type: OslSkeletonDirective, selector: "[oslSkeleton]", inputs: ["oslSkeleton", "oslSkeletonType", "oslSkeletonAnimation", "oslSkeletonTheme", "oslSkeletonColor", "oslSkeletonHighlight", "oslSkeletonRadius", "oslSkeletonRows", "oslSkeletonRowGap", "oslSkeletonZIndex", "oslSkeletonDelay", "oslSkeletonDuration", "oslSkeletonMinHeight", "oslSkeletonForceReread", "oslSkeletonCircleSize", "oslSkeletonListItems", "oslSkeletonTableRows", "oslSkeletonTableCols", "oslSkeletonCardLines", "oslSkeletonBgColor"] }] });
5554
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslDocumentUploader, isStandalone: false, selector: "osl-document-uploader", inputs: { label: "label", required: "required", disabled: "disabled", multiple: "multiple", accept: "accept", maxSize: "maxSize", minFiles: "minFiles", maxFiles: "maxFiles", showUploadButton: "showUploadButton", uploadButtonLabel: "uploadButtonLabel", savedDocuments: "savedDocuments", savedDocsMaxHeight: "savedDocsMaxHeight", skeletonLoading: "skeletonLoading", skeletonTheme: "skeletonTheme" }, outputs: { uploadCallback: "uploadCallback", viewCallback: "viewCallback", deleteCallback: "deleteCallback", downloadCallback: "downloadCallback", filesChanged: "filesChanged" }, ngImport: i0, template: "<div class=\"du-container\" [class.du--disabled]=\"disabled\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n\n @if (label) {\n <label class=\"du-label\" [class.du-label--error]=\"isInvalid\">\n <span class=\"du-label__text\" [title]=\"label\">{{ label }}</span>\n @if (required) { <span class=\"du-label__req\">*</span> }\n </label>\n }\n\n <input type=\"file\" [accept]=\"accept\" [multiple]=\"multiple\" [disabled]=\"disabled || maxFilesReached\"\n (change)=\"onFileChange($event)\" #fileInput class=\"du-file-input\">\n\n <!-- \u2500\u2500 Drop Zone \u2500\u2500 -->\n <div class=\"du-dropzone\"\n [class.du-dropzone--over]=\"isDragOver\"\n [class.du-dropzone--error]=\"isInvalid\"\n [class.du-dropzone--disabled]=\"disabled\"\n [class.du-dropzone--maxed]=\"maxFilesReached\"\n (click)=\"triggerInput(fileInput)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n\n <div class=\"du-particles\">\n <span class=\"du-p du-p--1\"></span>\n <span class=\"du-p du-p--2\"></span>\n <span class=\"du-p du-p--3\"></span>\n <span class=\"du-p du-p--4\"></span>\n <span class=\"du-p du-p--5\"></span>\n <span class=\"du-p du-p--6\"></span>\n </div>\n\n <div class=\"du-dropzone__inner\">\n\n @if (maxFilesReached) {\n <!-- Max files reached state -->\n <div class=\"du-maxed-icon\">\n <svg viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"#f0fdf4\" stroke=\"#86efac\" stroke-width=\"2\"/>\n <path d=\"M20 32l8 8 16-16\" stroke=\"#22c55e\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <p class=\"du-dropzone__headline\">\n <span class=\"du-gradient-text du-gradient-text--green\">Limit reached</span>\n </p>\n <p class=\"du-maxed-sub\">{{ maxFiles }} / {{ maxFiles }} files added</p>\n } @else {\n\n <!-- Cloud SVG -->\n <div class=\"du-cloud-wrap\" [class.du-cloud-wrap--over]=\"isDragOver\">\n <svg class=\"du-cloud-svg\" viewBox=\"0 0 90 72\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path class=\"du-cloud-body\"\n d=\"M63 42H27C19.8 42 14 36.2 14 29C14 22.2 19.2 16.7 25.8 16.1C25.9 9.4 31.3 4 38 4C42.8 4 47 6.7 49.2 10.7C50.8 9.6 52.8 9 55 9C61 9 65.9 13.9 65.9 19.9V20.1C72.1 20.9 77 26.3 77 33C77 38.1 70.7 42 63 42Z\"\n stroke=\"#667eea\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <line class=\"du-arrow\" x1=\"45\" y1=\"64\" x2=\"45\" y2=\"46\" stroke=\"#764ba2\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>\n <polyline class=\"du-arrow\" points=\"37,55 45,46 53,55\"\n stroke=\"#764ba2\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <circle class=\"du-cloud-glint\" cx=\"30\" cy=\"26\" r=\"3\" fill=\"#a5b4fc\" opacity=\"0.5\"/>\n </svg>\n </div>\n\n @if (!isDragOver) {\n <p class=\"du-dropzone__headline\">\n <span class=\"du-gradient-text\">Click to browse</span><span class=\"du-or\"> or drag &amp; drop</span>\n </p>\n <div class=\"du-dropzone__meta\">\n @if (multiple) {\n @if (maxFiles > 0 && minFiles > 0) {\n <span class=\"du-chip du-chip--info\">{{ minFiles }}\u2013{{ maxFiles }} files</span>\n } @else if (maxFiles > 0) {\n <span class=\"du-chip du-chip--info\">Max {{ maxFiles }} files</span>\n } @else if (minFiles > 0) {\n <span class=\"du-chip du-chip--info\">Min {{ minFiles }} files</span>\n } @else {\n <span class=\"du-chip du-chip--info\">Multiple files</span>\n }\n } @else {\n <span class=\"du-chip du-chip--info\">Single file</span>\n }\n @if (accept) { <span class=\"du-chip\">{{ accept }}</span> }\n @if (maxSize) { <span class=\"du-chip\">{{ maxSizeLabel }}</span> }\n </div>\n } @else {\n <p class=\"du-dropzone__headline du-dropzone__headline--drop\">\n <span class=\"du-gradient-text\">Release to drop!</span>\n </p>\n }\n\n }\n </div>\n </div>\n\n <!-- \u2500\u2500 Errors \u2500\u2500 -->\n @for (err of sizeErrors; track err) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n {{ err }}\n </div>\n }\n @if (requiredError) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n {{ label || 'File' }} is required!\n </div>\n }\n @if (minFilesError) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n At least {{ minFiles }} files are required ({{ pendingFiles.length }} added).\n </div>\n }\n\n <!-- \u2500\u2500 Pending Files \u2500\u2500 -->\n @if (pendingFiles.length > 0) {\n <div class=\"du-section\">\n <div class=\"du-section__hdr\">\n <span class=\"du-section__title\">Queued Files</span>\n @if (multiple && maxFiles > 0) {\n <span class=\"du-count-label\" [class.du-count-label--full]=\"maxFilesReached\">\n {{ pendingFiles.length }} / {{ maxFiles }}\n </span>\n } @else {\n <span class=\"du-count du-count--purple\">{{ pendingFiles.length }}</span>\n }\n </div>\n <div class=\"du-file-list\">\n @for (file of pendingFiles; track file.name; let i = $index) {\n <div class=\"du-file-card\" [attr.data-ftype]=\"getFileType(file.name)\" [style.animation-delay]=\"i * 40 + 'ms'\">\n\n <div class=\"du-file-icon\">\n @switch (getFileType(file.name)) {\n @case ('pdf') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#FEE2E2\"/>\n <path d=\"M26 4v10h10\" fill=\"#FECACA\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#EF4444\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">PDF</text>\n </svg>\n }\n @case ('word') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#DBEAFE\"/>\n <path d=\"M26 4v10h10\" fill=\"#BFDBFE\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#3B82F6\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">DOC</text>\n </svg>\n }\n @case ('excel') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#DCFCE7\"/>\n <path d=\"M26 4v10h10\" fill=\"#BBF7D0\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#22C55E\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">XLS</text>\n </svg>\n }\n @case ('image') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#FEF9C3\"/>\n <path d=\"M26 4v10h10\" fill=\"#FEF08A\"/>\n <rect x=\"6\" y=\"18\" width=\"28\" height=\"18\" rx=\"2\" fill=\"#FDE047\"/>\n <circle cx=\"13\" cy=\"24\" r=\"3\" fill=\"#CA8A04\"/>\n <path d=\"M6 36l9-9 5 5 4-4 10 8H6Z\" fill=\"#EAB308\" opacity=\"0.8\"/>\n </svg>\n }\n @case ('archive') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#EDE9FE\"/>\n <path d=\"M26 4v10h10\" fill=\"#DDD6FE\"/>\n <rect x=\"14\" y=\"12\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#A78BFA\"/>\n <rect x=\"14\" y=\"18\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#C4B5FD\"/>\n <rect x=\"14\" y=\"24\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#A78BFA\"/>\n <rect x=\"14\" y=\"30\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#C4B5FD\"/>\n <rect x=\"16\" y=\"26\" width=\"8\" height=\"6\" rx=\"1\" fill=\"#7C3AED\"/>\n </svg>\n }\n @default {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#F1F5F9\"/>\n <path d=\"M26 4v10h10\" fill=\"#E2E8F0\"/>\n <line x1=\"10\" y1=\"24\" x2=\"30\" y2=\"24\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <line x1=\"10\" y1=\"30\" x2=\"26\" y2=\"30\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <line x1=\"10\" y1=\"36\" x2=\"22\" y2=\"36\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n }\n }\n </div>\n\n <div class=\"du-file-info\">\n <span class=\"du-file-name\" [title]=\"file.name\">{{ file.name }}</span>\n <span class=\"du-file-size\">{{ getFileSize(file.size) }}</span>\n </div>\n\n <button type=\"button\" class=\"du-remove-btn\" (click)=\"removeFile(i)\" title=\"Remove\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <path d=\"M15 9L9 15M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Upload Button \u2500\u2500 -->\n @if (showUploadButton && pendingFiles.length > 0) {\n <button type=\"button\" class=\"du-upload-btn\" (click)=\"upload()\" [disabled]=\"disabled\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" width=\"17\" height=\"17\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>\n <polyline points=\"17,8 12,3 7,8\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>\n </svg>\n {{ uploadButtonLabel }}\n <span class=\"du-upload-btn__badge\">{{ pendingFiles.length }}</span>\n </button>\n }\n\n <!-- \u2500\u2500 Saved Documents \u2500\u2500 -->\n @if (savedDocuments.length > 0) {\n <div class=\"du-section\">\n <div class=\"du-section__hdr\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" class=\"du-section__icon\">\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\" stroke=\"#10b981\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <polyline points=\"14,2 14,8 20,8\" stroke=\"#10b981\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"du-section__title\">Saved Documents</span>\n <span class=\"du-count du-count--green\">{{ savedDocuments.length }}</span>\n </div>\n <div class=\"du-saved-list\" [style.max-height]=\"savedDocsMaxHeight\">\n @for (doc of savedDocuments; track doc.id; let i = $index) {\n <div class=\"du-saved-card\" [style.animation-delay]=\"i * 50 + 'ms'\">\n\n <div class=\"du-saved-icon\">\n @switch (getFileType(doc.name)) {\n @case ('pdf') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#FEE2E2\"/>\n <path d=\"M20 3v8h8\" fill=\"#FECACA\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#EF4444\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">PDF</text>\n </svg>\n }\n @case ('word') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#DBEAFE\"/>\n <path d=\"M20 3v8h8\" fill=\"#BFDBFE\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#3B82F6\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">DOC</text>\n </svg>\n }\n @case ('excel') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#DCFCE7\"/>\n <path d=\"M20 3v8h8\" fill=\"#BBF7D0\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#22C55E\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">XLS</text>\n </svg>\n }\n @case ('image') {\n <svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#FEF9C3\"/>\n <rect x=\"4\" y=\"7\" width=\"24\" height=\"18\" rx=\"2\" fill=\"#FDE047\"/>\n <circle cx=\"10\" cy=\"13\" r=\"2.5\" fill=\"#CA8A04\"/>\n <path d=\"M4 25l8-8 5 5 4-4 11 7H4Z\" fill=\"#EAB308\" opacity=\"0.7\"/>\n </svg>\n }\n @case ('archive') {\n <svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#EDE9FE\"/>\n <rect x=\"4\" y=\"8\" width=\"24\" height=\"5\" rx=\"1.5\" fill=\"#A78BFA\"/>\n <rect x=\"4\" y=\"14\" width=\"24\" height=\"14\" rx=\"2\" fill=\"#C4B5FD\"/>\n <rect x=\"11\" y=\"18\" width=\"10\" height=\"6\" rx=\"1.5\" fill=\"#7C3AED\"/>\n <line x1=\"16\" y1=\"18\" x2=\"16\" y2=\"24\" stroke=\"white\" stroke-width=\"1.5\"/>\n </svg>\n }\n @default {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#F1F5F9\"/>\n <path d=\"M20 3v8h8\" fill=\"#E2E8F0\"/>\n <line x1=\"7\" y1=\"20\" x2=\"25\" y2=\"20\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n <line x1=\"7\" y1=\"25\" x2=\"21\" y2=\"25\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n <line x1=\"7\" y1=\"30\" x2=\"17\" y2=\"30\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n </svg>\n }\n }\n </div>\n\n <div class=\"du-saved-info\">\n <span class=\"du-saved-name\" [title]=\"doc.name\">{{ doc.name }}</span>\n @if (doc.addBy || doc.addOn) {\n <span class=\"du-saved-meta\">\n @if (doc.addBy) { <span class=\"du-saved-by\">{{ doc.addBy }}</span> }\n @if (doc.addBy && doc.addOn) { <span class=\"du-saved-sep\">\u00B7</span> }\n @if (doc.addOn) { <span class=\"du-saved-on\">{{ formatDate(doc.addOn) }}</span> }\n </span>\n }\n </div>\n\n <div class=\"du-saved-actions\">\n <!-- <button type=\"button\" class=\"du-act du-act--view\" (click)=\"onView(doc)\" title=\"View\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/>\n </svg>\n </button> -->\n <button type=\"button\" class=\"du-act du-act--download\" (click)=\"onDownload(doc)\" title=\"Download\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <polyline points=\"7,10 12,15 17,10\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n <button type=\"button\" class=\"du-act du-act--delete\" (click)=\"onDelete(doc)\" title=\"Delete\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <polyline points=\"3,6 5,6 21,6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M10 11v6M14 11v6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n\n </div>\n }\n </div>\n </div>\n }\n\n</div>\n", styles: ["@keyframes du-float{0%,to{transform:translateY(0)}50%{transform:translateY(-9px)}}@keyframes du-arrow-bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@keyframes du-particle{0%,to{transform:translate(0) scale(1);opacity:.25}33%{transform:translate(4px,-14px) scale(1.15);opacity:.5}66%{transform:translate(-4px,-7px) scale(.88);opacity:.2}}@keyframes du-slide-in{0%{opacity:0;transform:translate(18px)}to{opacity:1;transform:translate(0)}}@keyframes du-fade-up{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes du-pop-in{0%{opacity:0;transform:scale(.8)}70%{transform:scale(1.06)}to{opacity:1;transform:scale(1)}}@keyframes du-glow-pulse{0%,to{box-shadow:0 0 #667eea59}50%{box-shadow:0 0 0 8px #667eea00}}@keyframes du-btn-pulse{0%,to{box-shadow:0 4px 20px #667eea66}50%{box-shadow:0 6px 30px #764ba299}}@keyframes du-gradient-shift{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes du-ripple{0%{transform:scale(.6);opacity:.7}to{transform:scale(2.2);opacity:0}}@keyframes du-glint{0%,80%,to{opacity:0;transform:scale(.5)}40%{opacity:.7;transform:scale(1.4)}}.du-container{display:flex;flex-direction:column;gap:10px;width:100%}.du-container.du--disabled{opacity:.55;pointer-events:none}.du-label{display:flex;align-items:center;gap:2px;font-size:var(--osl-label-font-size, 13px);font-weight:500;color:#374151;overflow:hidden}.du-label--error{color:var(--osl-error-color, #ef4444)}.du-label__text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.du-label__req{color:var(--osl-error-color, #ef4444);flex-shrink:0;font-weight:700}.du-file-input{display:none}.du-dropzone{position:relative;width:100%;min-height:158px;border-radius:18px;border:2px dashed rgba(102,126,234,.35);background:linear-gradient(145deg,#fafbff,#f5f3ff);cursor:pointer;overflow:hidden;transition:border-color .3s ease,background .3s ease,box-shadow .3s ease,transform .25s ease}.du-dropzone:hover:not(.du-dropzone--disabled){border-color:#667eeab3;background:linear-gradient(145deg,#f5f3ff,#ede9fe);transform:translateY(-2px);box-shadow:0 10px 30px #667eea1f}.du-dropzone--over{border:2px solid #667eea!important;background:linear-gradient(145deg,#ede9fe,#ddd6fe)!important;transform:scale(1.012) translateY(-3px)!important;box-shadow:0 18px 40px #667eea38,inset 0 0 0 1px #667eea4d!important}.du-dropzone--over .du-cloud-body{stroke:#764ba2}.du-dropzone--over .du-cloud-glint{animation:du-glint .6s ease infinite}.du-dropzone--error{border-color:#ef444480;background:linear-gradient(145deg,#fff5f5,#fee2e2);animation:du-glow-pulse 1.8s ease infinite}.du-dropzone--disabled{cursor:not-allowed;background:#f9fafb!important;border-color:#e5e7eb!important;box-shadow:none!important;transform:none!important}.du-particles{position:absolute;inset:0;pointer-events:none;overflow:hidden}.du-p{position:absolute;border-radius:50%;background:radial-gradient(circle,#667eea38,#764ba21f);animation:du-particle var(--dur, 4s) ease-in-out infinite}.du-p--1{width:22px;height:22px;top:12%;left:6%;--dur: 4.2s;animation-delay:0s}.du-p--2{width:14px;height:14px;top:65%;left:88%;--dur: 5.1s;animation-delay:.9s}.du-p--3{width:18px;height:18px;top:18%;left:82%;--dur: 3.8s;animation-delay:1.6s}.du-p--4{width:10px;height:10px;top:75%;left:12%;--dur: 6.3s;animation-delay:.4s}.du-p--5{width:16px;height:16px;top:50%;left:48%;--dur: 4.7s;animation-delay:2.1s}.du-p--6{width:8px;height:8px;top:30%;left:38%;--dur: 5.5s;animation-delay:1.1s}.du-dropzone__inner{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:26px 20px;min-height:158px}.du-cloud-wrap{width:80px;height:64px;animation:du-float 3.2s ease-in-out infinite;filter:drop-shadow(0 4px 10px rgba(102,126,234,.2));transition:filter .3s ease;flex-shrink:0}.du-cloud-wrap--over{animation-duration:1.2s;filter:drop-shadow(0 6px 18px rgba(102,126,234,.45))}.du-cloud-svg{width:100%;height:100%}.du-cloud-body{transition:stroke .3s ease}.du-cloud-glint{transform-origin:center}.du-arrow{animation:du-arrow-bounce 1.6s ease-in-out infinite}.du-dropzone__headline{margin:0;font-size:14px;color:#6b7280;line-height:1.5;text-align:center}.du-dropzone__headline--drop .du-gradient-text{animation:du-glow-pulse .7s ease infinite}.du-gradient-text{background:linear-gradient(135deg,#667eea,#764ba2);background-size:200% 200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;font-weight:700;animation:du-gradient-shift 3s ease infinite}.du-or{color:#9ca3af;font-size:13px}.du-dropzone__meta{display:flex;flex-wrap:wrap;justify-content:center;gap:6px}.du-chip{border-radius:20px;padding:2px 10px;font-size:11px;font-weight:500;background:#667eea14;color:#7c6fcd;border:1px solid rgba(102,126,234,.18);transition:background .2s}.du-chip--info{background:#10b98114;color:#059669;border-color:#10b98133}.du-msg{display:flex;align-items:center;gap:6px;font-size:var(--osl-hint-font-size, 11px);animation:du-fade-up .2s ease}.du-msg svg{flex-shrink:0}.du-msg--error{color:var(--osl-error-color, #ef4444)}.du-section{display:flex;flex-direction:column;gap:8px;animation:du-fade-up .3s ease}.du-section__hdr{display:flex;align-items:center;gap:7px}.du-section__icon{flex-shrink:0}.du-section__title{font-size:11px;font-weight:700;color:#9ca3af;text-transform:uppercase;letter-spacing:.07em}.du-count{width:19px;height:19px;border-radius:50%;font-size:10px;font-weight:800;color:#fff;display:flex;align-items:center;justify-content:center;flex-shrink:0;animation:du-pop-in .3s ease}.du-count--purple{background:linear-gradient(135deg,#667eea,#764ba2)}.du-count--green{background:linear-gradient(135deg,#10b981,#059669)}.du-file-list{display:flex;flex-direction:column;gap:7px}.du-file-card{display:flex;align-items:center;gap:11px;padding:10px 14px 10px 16px;background:#fff;border-radius:13px;border:1px solid #e9ecf1;animation:du-slide-in .28s ease both;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease;position:relative}.du-file-card:before{content:\"\";position:absolute;left:0;top:50%;transform:translateY(-50%);width:4px;height:60%;border-radius:0 4px 4px 0;transition:height .2s ease}.du-file-card[data-ftype=pdf]:before{background:#ef4444}.du-file-card[data-ftype=word]:before{background:#3b82f6}.du-file-card[data-ftype=excel]:before{background:#22c55e}.du-file-card[data-ftype=image]:before{background:#f59e0b}.du-file-card[data-ftype=archive]:before{background:#8b5cf6}.du-file-card[data-ftype=generic]:before{background:#94a3b8}.du-file-card:hover{border-color:#c4b5fd;box-shadow:0 3px 14px #667eea1a;transform:translate(3px)}.du-file-card:hover:before{height:75%}.du-file-icon{width:38px;height:46px;flex-shrink:0}.du-file-icon svg{width:100%;height:100%}.du-file-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.du-file-name{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.du-file-size{font-size:11px;color:#94a3b8;font-weight:500}.du-remove-btn{width:30px;height:30px;flex-shrink:0;border-radius:50%;border:1.5px solid #fecaca;background:#fef2f2;color:#fca5a5;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:6px;transition:all .22s ease}.du-remove-btn svg{width:100%;height:100%}.du-remove-btn:hover{background:#fee2e2;border-color:#ef4444;color:#ef4444;transform:rotate(90deg) scale(1.1);box-shadow:0 3px 10px #ef444440}.du-upload-btn{display:flex;align-items:center;justify-content:center;gap:8px;padding:12px 24px;width:100%;border:none;border-radius:13px;background:linear-gradient(135deg,#667eea,#764ba2);background-size:200% 200%;color:#fff;font-size:14px;font-weight:700;letter-spacing:.03em;cursor:pointer;transition:transform .25s ease,box-shadow .25s ease;animation:du-btn-pulse 2.5s ease-in-out infinite,du-gradient-shift 4s ease infinite}.du-upload-btn svg{flex-shrink:0;transition:transform .25s ease}.du-upload-btn:hover:not([disabled]){transform:translateY(-3px);box-shadow:0 10px 28px #667eea80;animation:du-gradient-shift 1.5s ease infinite}.du-upload-btn:hover:not([disabled]) svg{transform:translateY(-3px)}.du-upload-btn:active:not([disabled]){transform:translateY(-1px)}.du-upload-btn[disabled]{opacity:.45;cursor:not-allowed;animation:none}.du-upload-btn__badge{min-width:22px;height:22px;padding:0 6px;border-radius:11px;background:#ffffff38;font-size:11px;font-weight:800;display:flex;align-items:center;justify-content:center;animation:du-pop-in .3s ease}.du-saved-list{display:flex;flex-direction:column;gap:7px;overflow-y:auto;padding-right:2px;scrollbar-width:thin;scrollbar-color:#c4b5fd transparent}.du-saved-list::-webkit-scrollbar{width:5px}.du-saved-list::-webkit-scrollbar-track{background:transparent;border-radius:10px}.du-saved-list::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#a5b4fc,#c4b5fd);border-radius:10px}.du-saved-list::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,#818cf8,#a78bfa)}.du-saved-card{display:flex;align-items:center;gap:11px;padding:10px 12px;background:linear-gradient(135deg,#fff,#f8faff);border-radius:13px;border:1px solid #e9ecf1;opacity:0;animation:du-fade-up .32s ease forwards;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}.du-saved-card:hover{border-color:#a5b4fc;box-shadow:0 4px 18px #667eea1a;transform:translateY(-1px)}.du-saved-icon{width:32px;height:38px;flex-shrink:0}.du-saved-icon svg{width:100%;height:100%}.du-saved-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.du-saved-name{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.du-saved-size{font-size:11px;color:#94a3b8;font-weight:500}.du-saved-actions{display:flex;align-items:center;gap:5px;flex-shrink:0}.du-act{width:32px;height:32px;border-radius:9px;border:1.5px solid transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:7px;transition:all .22s ease;position:relative;overflow:hidden}.du-act svg{width:100%;height:100%;transition:transform .22s ease}.du-act:after{content:\"\";position:absolute;inset:50%;border-radius:50%;transition:all 0s;pointer-events:none}.du-act:active:after{inset:0;border-radius:9px;background:#ffffff59;animation:du-ripple .4s ease}.du-act--view{background:#eff6ff;color:#3b82f6;border-color:#bfdbfe}.du-act--view:hover{background:#dbeafe;border-color:#93c5fd;box-shadow:0 3px 12px #3b82f64d}.du-act--view:hover svg{transform:scale(1.12)}.du-act--download{background:#f0fdf4;color:#22c55e;border-color:#bbf7d0}.du-act--download:hover{background:#dcfce7;border-color:#86efac;box-shadow:0 3px 12px #22c55e4d}.du-act--download:hover svg{transform:translateY(2px) scale(1.08)}.du-act--delete{background:#fef2f2;color:#ef4444;border-color:#fecaca}.du-act--delete:hover{background:#fee2e2;border-color:#fca5a5;box-shadow:0 3px 12px #ef44444d}.du-act--delete:hover svg{transform:scale(1.1) rotate(-5deg)}.du-dropzone--maxed{cursor:default;border-color:#22c55e66!important;background:linear-gradient(145deg,#f0fdf4,#dcfce7)!important;pointer-events:none}.du-dropzone--maxed .du-particles .du-p{background:radial-gradient(circle,#22c55e2e,#10b9811a)}.du-maxed-icon{width:56px;height:56px;animation:du-pop-in .4s cubic-bezier(.34,1.56,.64,1)}.du-maxed-icon svg{width:100%;height:100%}.du-gradient-text--green{background:linear-gradient(135deg,#22c55e,#059669)!important;background-size:200% 200%!important;-webkit-background-clip:text!important;-webkit-text-fill-color:transparent!important;background-clip:text!important}.du-maxed-sub{margin:0;font-size:12px;color:#6b7280;font-weight:500}.du-count-label{font-size:11px;font-weight:700;padding:2px 9px;border-radius:20px;background:#667eea1a;color:#667eea;border:1px solid rgba(102,126,234,.2);transition:all .25s ease;animation:du-pop-in .3s ease}.du-count-label--full{background:#22c55e1a;color:#16a34a;border-color:#22c55e40}.du-saved-meta{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.du-saved-by{font-size:11px;font-weight:600;color:#667eea}.du-saved-sep{font-size:11px;color:#d1d5db}.du-saved-on{font-size:11px;color:#94a3b8}\n"], dependencies: [{ kind: "directive", type: OslSkeletonDirective, selector: "[oslSkeleton]", inputs: ["oslSkeleton", "oslSkeletonType", "oslSkeletonAnimation", "oslSkeletonTheme", "oslSkeletonColor", "oslSkeletonHighlight", "oslSkeletonRadius", "oslSkeletonRows", "oslSkeletonRowGap", "oslSkeletonZIndex", "oslSkeletonDelay", "oslSkeletonDuration", "oslSkeletonMinHeight", "oslSkeletonForceReread", "oslSkeletonCircleSize", "oslSkeletonListItems", "oslSkeletonTableRows", "oslSkeletonTableCols", "oslSkeletonCardLines", "oslSkeletonBgColor"] }] });
5531
5555
  }
5532
5556
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslDocumentUploader, decorators: [{
5533
5557
  type: Component,
5534
- args: [{ selector: 'osl-document-uploader', standalone: false, template: "<div class=\"du-container\" [class.du--disabled]=\"disabled\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n\n @if (label) {\n <label class=\"du-label\" [class.du-label--error]=\"isInvalid\">\n <span class=\"du-label__text\" [title]=\"label\">{{ label }}</span>\n @if (required) { <span class=\"du-label__req\">*</span> }\n </label>\n }\n\n <input type=\"file\" [accept]=\"accept\" [multiple]=\"multiple\" [disabled]=\"disabled || maxFilesReached\"\n (change)=\"onFileChange($event)\" #fileInput class=\"du-file-input\">\n\n <!-- \u2500\u2500 Drop Zone \u2500\u2500 -->\n <div class=\"du-dropzone\"\n [class.du-dropzone--over]=\"isDragOver\"\n [class.du-dropzone--error]=\"isInvalid\"\n [class.du-dropzone--disabled]=\"disabled\"\n [class.du-dropzone--maxed]=\"maxFilesReached\"\n (click)=\"triggerInput(fileInput)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n\n <div class=\"du-particles\">\n <span class=\"du-p du-p--1\"></span>\n <span class=\"du-p du-p--2\"></span>\n <span class=\"du-p du-p--3\"></span>\n <span class=\"du-p du-p--4\"></span>\n <span class=\"du-p du-p--5\"></span>\n <span class=\"du-p du-p--6\"></span>\n </div>\n\n <div class=\"du-dropzone__inner\">\n\n @if (maxFilesReached) {\n <!-- Max files reached state -->\n <div class=\"du-maxed-icon\">\n <svg viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"#f0fdf4\" stroke=\"#86efac\" stroke-width=\"2\"/>\n <path d=\"M20 32l8 8 16-16\" stroke=\"#22c55e\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <p class=\"du-dropzone__headline\">\n <span class=\"du-gradient-text du-gradient-text--green\">Limit reached</span>\n </p>\n <p class=\"du-maxed-sub\">{{ maxFiles }} / {{ maxFiles }} files added</p>\n } @else {\n\n <!-- Cloud SVG -->\n <div class=\"du-cloud-wrap\" [class.du-cloud-wrap--over]=\"isDragOver\">\n <svg class=\"du-cloud-svg\" viewBox=\"0 0 90 72\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path class=\"du-cloud-body\"\n d=\"M63 42H27C19.8 42 14 36.2 14 29C14 22.2 19.2 16.7 25.8 16.1C25.9 9.4 31.3 4 38 4C42.8 4 47 6.7 49.2 10.7C50.8 9.6 52.8 9 55 9C61 9 65.9 13.9 65.9 19.9V20.1C72.1 20.9 77 26.3 77 33C77 38.1 70.7 42 63 42Z\"\n stroke=\"#667eea\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <line class=\"du-arrow\" x1=\"45\" y1=\"64\" x2=\"45\" y2=\"46\" stroke=\"#764ba2\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>\n <polyline class=\"du-arrow\" points=\"37,55 45,46 53,55\"\n stroke=\"#764ba2\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <circle class=\"du-cloud-glint\" cx=\"30\" cy=\"26\" r=\"3\" fill=\"#a5b4fc\" opacity=\"0.5\"/>\n </svg>\n </div>\n\n @if (!isDragOver) {\n <p class=\"du-dropzone__headline\">\n <span class=\"du-gradient-text\">Click to browse</span><span class=\"du-or\"> or drag &amp; drop</span>\n </p>\n <div class=\"du-dropzone__meta\">\n @if (multiple) {\n @if (maxFiles > 0 && minFiles > 0) {\n <span class=\"du-chip du-chip--info\">{{ minFiles }}\u2013{{ maxFiles }} files</span>\n } @else if (maxFiles > 0) {\n <span class=\"du-chip du-chip--info\">Max {{ maxFiles }} files</span>\n } @else if (minFiles > 0) {\n <span class=\"du-chip du-chip--info\">Min {{ minFiles }} files</span>\n } @else {\n <span class=\"du-chip du-chip--info\">Multiple files</span>\n }\n } @else {\n <span class=\"du-chip du-chip--info\">Single file</span>\n }\n @if (accept) { <span class=\"du-chip\">{{ accept }}</span> }\n @if (maxSize) { <span class=\"du-chip\">{{ maxSizeLabel }}</span> }\n </div>\n } @else {\n <p class=\"du-dropzone__headline du-dropzone__headline--drop\">\n <span class=\"du-gradient-text\">Release to drop!</span>\n </p>\n }\n\n }\n </div>\n </div>\n\n <!-- \u2500\u2500 Errors \u2500\u2500 -->\n @for (err of sizeErrors; track err) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n {{ err }}\n </div>\n }\n @if (requiredError) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n {{ label || 'File' }} is required!\n </div>\n }\n @if (minFilesError) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n At least {{ minFiles }} files are required ({{ pendingFiles.length }} added).\n </div>\n }\n\n <!-- \u2500\u2500 Pending Files \u2500\u2500 -->\n @if (pendingFiles.length > 0) {\n <div class=\"du-section\">\n <div class=\"du-section__hdr\">\n <span class=\"du-section__title\">Queued Files</span>\n @if (multiple && maxFiles > 0) {\n <span class=\"du-count-label\" [class.du-count-label--full]=\"maxFilesReached\">\n {{ pendingFiles.length }} / {{ maxFiles }}\n </span>\n } @else {\n <span class=\"du-count du-count--purple\">{{ pendingFiles.length }}</span>\n }\n </div>\n <div class=\"du-file-list\">\n @for (file of pendingFiles; track file.name; let i = $index) {\n <div class=\"du-file-card\" [attr.data-ftype]=\"getFileType(file.name)\" [style.animation-delay]=\"i * 40 + 'ms'\">\n\n <div class=\"du-file-icon\">\n @switch (getFileType(file.name)) {\n @case ('pdf') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#FEE2E2\"/>\n <path d=\"M26 4v10h10\" fill=\"#FECACA\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#EF4444\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">PDF</text>\n </svg>\n }\n @case ('word') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#DBEAFE\"/>\n <path d=\"M26 4v10h10\" fill=\"#BFDBFE\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#3B82F6\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">DOC</text>\n </svg>\n }\n @case ('excel') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#DCFCE7\"/>\n <path d=\"M26 4v10h10\" fill=\"#BBF7D0\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#22C55E\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">XLS</text>\n </svg>\n }\n @case ('image') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#FEF9C3\"/>\n <path d=\"M26 4v10h10\" fill=\"#FEF08A\"/>\n <rect x=\"6\" y=\"18\" width=\"28\" height=\"18\" rx=\"2\" fill=\"#FDE047\"/>\n <circle cx=\"13\" cy=\"24\" r=\"3\" fill=\"#CA8A04\"/>\n <path d=\"M6 36l9-9 5 5 4-4 10 8H6Z\" fill=\"#EAB308\" opacity=\"0.8\"/>\n </svg>\n }\n @case ('archive') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#EDE9FE\"/>\n <path d=\"M26 4v10h10\" fill=\"#DDD6FE\"/>\n <rect x=\"14\" y=\"12\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#A78BFA\"/>\n <rect x=\"14\" y=\"18\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#C4B5FD\"/>\n <rect x=\"14\" y=\"24\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#A78BFA\"/>\n <rect x=\"14\" y=\"30\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#C4B5FD\"/>\n <rect x=\"16\" y=\"26\" width=\"8\" height=\"6\" rx=\"1\" fill=\"#7C3AED\"/>\n </svg>\n }\n @default {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#F1F5F9\"/>\n <path d=\"M26 4v10h10\" fill=\"#E2E8F0\"/>\n <line x1=\"10\" y1=\"24\" x2=\"30\" y2=\"24\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <line x1=\"10\" y1=\"30\" x2=\"26\" y2=\"30\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <line x1=\"10\" y1=\"36\" x2=\"22\" y2=\"36\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n }\n }\n </div>\n\n <div class=\"du-file-info\">\n <span class=\"du-file-name\" [title]=\"file.name\">{{ file.name }}</span>\n <span class=\"du-file-size\">{{ getFileSize(file.size) }}</span>\n </div>\n\n <button type=\"button\" class=\"du-remove-btn\" (click)=\"removeFile(i)\" title=\"Remove\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <path d=\"M15 9L9 15M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Upload Button \u2500\u2500 -->\n @if (showUploadButton && pendingFiles.length > 0) {\n <button type=\"button\" class=\"du-upload-btn\" (click)=\"upload()\" [disabled]=\"disabled\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" width=\"17\" height=\"17\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>\n <polyline points=\"17,8 12,3 7,8\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>\n </svg>\n {{ uploadButtonLabel }}\n <span class=\"du-upload-btn__badge\">{{ pendingFiles.length }}</span>\n </button>\n }\n\n <!-- \u2500\u2500 Saved Documents \u2500\u2500 -->\n @if (savedDocuments.length > 0) {\n <div class=\"du-section\">\n <div class=\"du-section__hdr\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" class=\"du-section__icon\">\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\" stroke=\"#10b981\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <polyline points=\"14,2 14,8 20,8\" stroke=\"#10b981\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"du-section__title\">Saved Documents</span>\n <span class=\"du-count du-count--green\">{{ savedDocuments.length }}</span>\n </div>\n <div class=\"du-saved-list\">\n @for (doc of savedDocuments; track doc.id; let i = $index) {\n <div class=\"du-saved-card\" [style.animation-delay]=\"i * 50 + 'ms'\">\n\n <div class=\"du-saved-icon\">\n @switch (getFileType(doc.name)) {\n @case ('pdf') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#FEE2E2\"/>\n <path d=\"M20 3v8h8\" fill=\"#FECACA\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#EF4444\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">PDF</text>\n </svg>\n }\n @case ('word') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#DBEAFE\"/>\n <path d=\"M20 3v8h8\" fill=\"#BFDBFE\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#3B82F6\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">DOC</text>\n </svg>\n }\n @case ('excel') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#DCFCE7\"/>\n <path d=\"M20 3v8h8\" fill=\"#BBF7D0\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#22C55E\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">XLS</text>\n </svg>\n }\n @case ('image') {\n <svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#FEF9C3\"/>\n <rect x=\"4\" y=\"7\" width=\"24\" height=\"18\" rx=\"2\" fill=\"#FDE047\"/>\n <circle cx=\"10\" cy=\"13\" r=\"2.5\" fill=\"#CA8A04\"/>\n <path d=\"M4 25l8-8 5 5 4-4 11 7H4Z\" fill=\"#EAB308\" opacity=\"0.7\"/>\n </svg>\n }\n @case ('archive') {\n <svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#EDE9FE\"/>\n <rect x=\"4\" y=\"8\" width=\"24\" height=\"5\" rx=\"1.5\" fill=\"#A78BFA\"/>\n <rect x=\"4\" y=\"14\" width=\"24\" height=\"14\" rx=\"2\" fill=\"#C4B5FD\"/>\n <rect x=\"11\" y=\"18\" width=\"10\" height=\"6\" rx=\"1.5\" fill=\"#7C3AED\"/>\n <line x1=\"16\" y1=\"18\" x2=\"16\" y2=\"24\" stroke=\"white\" stroke-width=\"1.5\"/>\n </svg>\n }\n @default {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#F1F5F9\"/>\n <path d=\"M20 3v8h8\" fill=\"#E2E8F0\"/>\n <line x1=\"7\" y1=\"20\" x2=\"25\" y2=\"20\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n <line x1=\"7\" y1=\"25\" x2=\"21\" y2=\"25\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n <line x1=\"7\" y1=\"30\" x2=\"17\" y2=\"30\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n </svg>\n }\n }\n </div>\n\n <div class=\"du-saved-info\">\n <span class=\"du-saved-name\" [title]=\"doc.name\">{{ doc.name }}</span>\n @if (doc.addBy || doc.addOn) {\n <span class=\"du-saved-meta\">\n @if (doc.addBy) { <span class=\"du-saved-by\">{{ doc.addBy }}</span> }\n @if (doc.addBy && doc.addOn) { <span class=\"du-saved-sep\">\u00B7</span> }\n @if (doc.addOn) { <span class=\"du-saved-on\">{{ formatDate(doc.addOn) }}</span> }\n </span>\n }\n </div>\n\n <div class=\"du-saved-actions\">\n <button type=\"button\" class=\"du-act du-act--view\" (click)=\"onView(doc)\" title=\"View\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/>\n </svg>\n </button>\n <button type=\"button\" class=\"du-act du-act--download\" (click)=\"onDownload(doc)\" title=\"Download\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <polyline points=\"7,10 12,15 17,10\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n <button type=\"button\" class=\"du-act du-act--delete\" (click)=\"onDelete(doc)\" title=\"Delete\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <polyline points=\"3,6 5,6 21,6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M10 11v6M14 11v6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n\n </div>\n }\n </div>\n </div>\n }\n\n</div>\n", styles: ["@keyframes du-float{0%,to{transform:translateY(0)}50%{transform:translateY(-9px)}}@keyframes du-arrow-bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@keyframes du-particle{0%,to{transform:translate(0) scale(1);opacity:.25}33%{transform:translate(4px,-14px) scale(1.15);opacity:.5}66%{transform:translate(-4px,-7px) scale(.88);opacity:.2}}@keyframes du-slide-in{0%{opacity:0;transform:translate(18px)}to{opacity:1;transform:translate(0)}}@keyframes du-fade-up{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes du-pop-in{0%{opacity:0;transform:scale(.8)}70%{transform:scale(1.06)}to{opacity:1;transform:scale(1)}}@keyframes du-glow-pulse{0%,to{box-shadow:0 0 #667eea59}50%{box-shadow:0 0 0 8px #667eea00}}@keyframes du-btn-pulse{0%,to{box-shadow:0 4px 20px #667eea66}50%{box-shadow:0 6px 30px #764ba299}}@keyframes du-gradient-shift{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes du-ripple{0%{transform:scale(.6);opacity:.7}to{transform:scale(2.2);opacity:0}}@keyframes du-glint{0%,80%,to{opacity:0;transform:scale(.5)}40%{opacity:.7;transform:scale(1.4)}}.du-container{display:flex;flex-direction:column;gap:10px;width:100%}.du-container.du--disabled{opacity:.55;pointer-events:none}.du-label{display:flex;align-items:center;gap:2px;font-size:var(--osl-label-font-size, 13px);font-weight:500;color:#374151;overflow:hidden}.du-label--error{color:var(--osl-error-color, #ef4444)}.du-label__text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.du-label__req{color:var(--osl-error-color, #ef4444);flex-shrink:0;font-weight:700}.du-file-input{display:none}.du-dropzone{position:relative;width:100%;min-height:158px;border-radius:18px;border:2px dashed rgba(102,126,234,.35);background:linear-gradient(145deg,#fafbff,#f5f3ff);cursor:pointer;overflow:hidden;transition:border-color .3s ease,background .3s ease,box-shadow .3s ease,transform .25s ease}.du-dropzone:hover:not(.du-dropzone--disabled){border-color:#667eeab3;background:linear-gradient(145deg,#f5f3ff,#ede9fe);transform:translateY(-2px);box-shadow:0 10px 30px #667eea1f}.du-dropzone--over{border:2px solid #667eea!important;background:linear-gradient(145deg,#ede9fe,#ddd6fe)!important;transform:scale(1.012) translateY(-3px)!important;box-shadow:0 18px 40px #667eea38,inset 0 0 0 1px #667eea4d!important}.du-dropzone--over .du-cloud-body{stroke:#764ba2}.du-dropzone--over .du-cloud-glint{animation:du-glint .6s ease infinite}.du-dropzone--error{border-color:#ef444480;background:linear-gradient(145deg,#fff5f5,#fee2e2);animation:du-glow-pulse 1.8s ease infinite}.du-dropzone--disabled{cursor:not-allowed;background:#f9fafb!important;border-color:#e5e7eb!important;box-shadow:none!important;transform:none!important}.du-particles{position:absolute;inset:0;pointer-events:none;overflow:hidden}.du-p{position:absolute;border-radius:50%;background:radial-gradient(circle,#667eea38,#764ba21f);animation:du-particle var(--dur, 4s) ease-in-out infinite}.du-p--1{width:22px;height:22px;top:12%;left:6%;--dur: 4.2s;animation-delay:0s}.du-p--2{width:14px;height:14px;top:65%;left:88%;--dur: 5.1s;animation-delay:.9s}.du-p--3{width:18px;height:18px;top:18%;left:82%;--dur: 3.8s;animation-delay:1.6s}.du-p--4{width:10px;height:10px;top:75%;left:12%;--dur: 6.3s;animation-delay:.4s}.du-p--5{width:16px;height:16px;top:50%;left:48%;--dur: 4.7s;animation-delay:2.1s}.du-p--6{width:8px;height:8px;top:30%;left:38%;--dur: 5.5s;animation-delay:1.1s}.du-dropzone__inner{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:26px 20px;min-height:158px}.du-cloud-wrap{width:80px;height:64px;animation:du-float 3.2s ease-in-out infinite;filter:drop-shadow(0 4px 10px rgba(102,126,234,.2));transition:filter .3s ease;flex-shrink:0}.du-cloud-wrap--over{animation-duration:1.2s;filter:drop-shadow(0 6px 18px rgba(102,126,234,.45))}.du-cloud-svg{width:100%;height:100%}.du-cloud-body{transition:stroke .3s ease}.du-cloud-glint{transform-origin:center}.du-arrow{animation:du-arrow-bounce 1.6s ease-in-out infinite}.du-dropzone__headline{margin:0;font-size:14px;color:#6b7280;line-height:1.5;text-align:center}.du-dropzone__headline--drop .du-gradient-text{animation:du-glow-pulse .7s ease infinite}.du-gradient-text{background:linear-gradient(135deg,#667eea,#764ba2);background-size:200% 200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;font-weight:700;animation:du-gradient-shift 3s ease infinite}.du-or{color:#9ca3af;font-size:13px}.du-dropzone__meta{display:flex;flex-wrap:wrap;justify-content:center;gap:6px}.du-chip{border-radius:20px;padding:2px 10px;font-size:11px;font-weight:500;background:#667eea14;color:#7c6fcd;border:1px solid rgba(102,126,234,.18);transition:background .2s}.du-chip--info{background:#10b98114;color:#059669;border-color:#10b98133}.du-msg{display:flex;align-items:center;gap:6px;font-size:var(--osl-hint-font-size, 11px);animation:du-fade-up .2s ease}.du-msg svg{flex-shrink:0}.du-msg--error{color:var(--osl-error-color, #ef4444)}.du-section{display:flex;flex-direction:column;gap:8px;animation:du-fade-up .3s ease}.du-section__hdr{display:flex;align-items:center;gap:7px}.du-section__icon{flex-shrink:0}.du-section__title{font-size:11px;font-weight:700;color:#9ca3af;text-transform:uppercase;letter-spacing:.07em}.du-count{width:19px;height:19px;border-radius:50%;font-size:10px;font-weight:800;color:#fff;display:flex;align-items:center;justify-content:center;flex-shrink:0;animation:du-pop-in .3s ease}.du-count--purple{background:linear-gradient(135deg,#667eea,#764ba2)}.du-count--green{background:linear-gradient(135deg,#10b981,#059669)}.du-file-list{display:flex;flex-direction:column;gap:7px}.du-file-card{display:flex;align-items:center;gap:11px;padding:10px 14px 10px 16px;background:#fff;border-radius:13px;border:1px solid #e9ecf1;animation:du-slide-in .28s ease both;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease;position:relative}.du-file-card:before{content:\"\";position:absolute;left:0;top:50%;transform:translateY(-50%);width:4px;height:60%;border-radius:0 4px 4px 0;transition:height .2s ease}.du-file-card[data-ftype=pdf]:before{background:#ef4444}.du-file-card[data-ftype=word]:before{background:#3b82f6}.du-file-card[data-ftype=excel]:before{background:#22c55e}.du-file-card[data-ftype=image]:before{background:#f59e0b}.du-file-card[data-ftype=archive]:before{background:#8b5cf6}.du-file-card[data-ftype=generic]:before{background:#94a3b8}.du-file-card:hover{border-color:#c4b5fd;box-shadow:0 3px 14px #667eea1a;transform:translate(3px)}.du-file-card:hover:before{height:75%}.du-file-icon{width:38px;height:46px;flex-shrink:0}.du-file-icon svg{width:100%;height:100%}.du-file-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.du-file-name{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.du-file-size{font-size:11px;color:#94a3b8;font-weight:500}.du-remove-btn{width:30px;height:30px;flex-shrink:0;border-radius:50%;border:1.5px solid #fecaca;background:#fef2f2;color:#fca5a5;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:6px;transition:all .22s ease}.du-remove-btn svg{width:100%;height:100%}.du-remove-btn:hover{background:#fee2e2;border-color:#ef4444;color:#ef4444;transform:rotate(90deg) scale(1.1);box-shadow:0 3px 10px #ef444440}.du-upload-btn{display:flex;align-items:center;justify-content:center;gap:8px;padding:12px 24px;width:100%;border:none;border-radius:13px;background:linear-gradient(135deg,#667eea,#764ba2);background-size:200% 200%;color:#fff;font-size:14px;font-weight:700;letter-spacing:.03em;cursor:pointer;transition:transform .25s ease,box-shadow .25s ease;animation:du-btn-pulse 2.5s ease-in-out infinite,du-gradient-shift 4s ease infinite}.du-upload-btn svg{flex-shrink:0;transition:transform .25s ease}.du-upload-btn:hover:not([disabled]){transform:translateY(-3px);box-shadow:0 10px 28px #667eea80;animation:du-gradient-shift 1.5s ease infinite}.du-upload-btn:hover:not([disabled]) svg{transform:translateY(-3px)}.du-upload-btn:active:not([disabled]){transform:translateY(-1px)}.du-upload-btn[disabled]{opacity:.45;cursor:not-allowed;animation:none}.du-upload-btn__badge{min-width:22px;height:22px;padding:0 6px;border-radius:11px;background:#ffffff38;font-size:11px;font-weight:800;display:flex;align-items:center;justify-content:center;animation:du-pop-in .3s ease}.du-saved-list{display:flex;flex-direction:column;gap:7px}.du-saved-card{display:flex;align-items:center;gap:11px;padding:10px 12px;background:linear-gradient(135deg,#fff,#f8faff);border-radius:13px;border:1px solid #e9ecf1;opacity:0;animation:du-fade-up .32s ease forwards;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}.du-saved-card:hover{border-color:#a5b4fc;box-shadow:0 4px 18px #667eea1a;transform:translateY(-1px)}.du-saved-icon{width:32px;height:38px;flex-shrink:0}.du-saved-icon svg{width:100%;height:100%}.du-saved-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.du-saved-name{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.du-saved-size{font-size:11px;color:#94a3b8;font-weight:500}.du-saved-actions{display:flex;align-items:center;gap:5px;flex-shrink:0}.du-act{width:32px;height:32px;border-radius:9px;border:1.5px solid transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:7px;transition:all .22s ease;position:relative;overflow:hidden}.du-act svg{width:100%;height:100%;transition:transform .22s ease}.du-act:after{content:\"\";position:absolute;inset:50%;border-radius:50%;transition:all 0s;pointer-events:none}.du-act:active:after{inset:0;border-radius:9px;background:#ffffff59;animation:du-ripple .4s ease}.du-act--view{background:#eff6ff;color:#3b82f6;border-color:#bfdbfe}.du-act--view:hover{background:#dbeafe;border-color:#93c5fd;box-shadow:0 3px 12px #3b82f64d}.du-act--view:hover svg{transform:scale(1.12)}.du-act--download{background:#f0fdf4;color:#22c55e;border-color:#bbf7d0}.du-act--download:hover{background:#dcfce7;border-color:#86efac;box-shadow:0 3px 12px #22c55e4d}.du-act--download:hover svg{transform:translateY(2px) scale(1.08)}.du-act--delete{background:#fef2f2;color:#ef4444;border-color:#fecaca}.du-act--delete:hover{background:#fee2e2;border-color:#fca5a5;box-shadow:0 3px 12px #ef44444d}.du-act--delete:hover svg{transform:scale(1.1) rotate(-5deg)}.du-dropzone--maxed{cursor:default;border-color:#22c55e66!important;background:linear-gradient(145deg,#f0fdf4,#dcfce7)!important;pointer-events:none}.du-dropzone--maxed .du-particles .du-p{background:radial-gradient(circle,#22c55e2e,#10b9811a)}.du-maxed-icon{width:56px;height:56px;animation:du-pop-in .4s cubic-bezier(.34,1.56,.64,1)}.du-maxed-icon svg{width:100%;height:100%}.du-gradient-text--green{background:linear-gradient(135deg,#22c55e,#059669)!important;background-size:200% 200%!important;-webkit-background-clip:text!important;-webkit-text-fill-color:transparent!important;background-clip:text!important}.du-maxed-sub{margin:0;font-size:12px;color:#6b7280;font-weight:500}.du-count-label{font-size:11px;font-weight:700;padding:2px 9px;border-radius:20px;background:#667eea1a;color:#667eea;border:1px solid rgba(102,126,234,.2);transition:all .25s ease;animation:du-pop-in .3s ease}.du-count-label--full{background:#22c55e1a;color:#16a34a;border-color:#22c55e40}.du-saved-meta{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.du-saved-by{font-size:11px;font-weight:600;color:#667eea}.du-saved-sep{font-size:11px;color:#d1d5db}.du-saved-on{font-size:11px;color:#94a3b8}\n"] }]
5558
+ args: [{ selector: 'osl-document-uploader', standalone: false, template: "<div class=\"du-container\" [class.du--disabled]=\"disabled\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n\n @if (label) {\n <label class=\"du-label\" [class.du-label--error]=\"isInvalid\">\n <span class=\"du-label__text\" [title]=\"label\">{{ label }}</span>\n @if (required) { <span class=\"du-label__req\">*</span> }\n </label>\n }\n\n <input type=\"file\" [accept]=\"accept\" [multiple]=\"multiple\" [disabled]=\"disabled || maxFilesReached\"\n (change)=\"onFileChange($event)\" #fileInput class=\"du-file-input\">\n\n <!-- \u2500\u2500 Drop Zone \u2500\u2500 -->\n <div class=\"du-dropzone\"\n [class.du-dropzone--over]=\"isDragOver\"\n [class.du-dropzone--error]=\"isInvalid\"\n [class.du-dropzone--disabled]=\"disabled\"\n [class.du-dropzone--maxed]=\"maxFilesReached\"\n (click)=\"triggerInput(fileInput)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n\n <div class=\"du-particles\">\n <span class=\"du-p du-p--1\"></span>\n <span class=\"du-p du-p--2\"></span>\n <span class=\"du-p du-p--3\"></span>\n <span class=\"du-p du-p--4\"></span>\n <span class=\"du-p du-p--5\"></span>\n <span class=\"du-p du-p--6\"></span>\n </div>\n\n <div class=\"du-dropzone__inner\">\n\n @if (maxFilesReached) {\n <!-- Max files reached state -->\n <div class=\"du-maxed-icon\">\n <svg viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"#f0fdf4\" stroke=\"#86efac\" stroke-width=\"2\"/>\n <path d=\"M20 32l8 8 16-16\" stroke=\"#22c55e\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <p class=\"du-dropzone__headline\">\n <span class=\"du-gradient-text du-gradient-text--green\">Limit reached</span>\n </p>\n <p class=\"du-maxed-sub\">{{ maxFiles }} / {{ maxFiles }} files added</p>\n } @else {\n\n <!-- Cloud SVG -->\n <div class=\"du-cloud-wrap\" [class.du-cloud-wrap--over]=\"isDragOver\">\n <svg class=\"du-cloud-svg\" viewBox=\"0 0 90 72\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path class=\"du-cloud-body\"\n d=\"M63 42H27C19.8 42 14 36.2 14 29C14 22.2 19.2 16.7 25.8 16.1C25.9 9.4 31.3 4 38 4C42.8 4 47 6.7 49.2 10.7C50.8 9.6 52.8 9 55 9C61 9 65.9 13.9 65.9 19.9V20.1C72.1 20.9 77 26.3 77 33C77 38.1 70.7 42 63 42Z\"\n stroke=\"#667eea\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <line class=\"du-arrow\" x1=\"45\" y1=\"64\" x2=\"45\" y2=\"46\" stroke=\"#764ba2\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>\n <polyline class=\"du-arrow\" points=\"37,55 45,46 53,55\"\n stroke=\"#764ba2\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <circle class=\"du-cloud-glint\" cx=\"30\" cy=\"26\" r=\"3\" fill=\"#a5b4fc\" opacity=\"0.5\"/>\n </svg>\n </div>\n\n @if (!isDragOver) {\n <p class=\"du-dropzone__headline\">\n <span class=\"du-gradient-text\">Click to browse</span><span class=\"du-or\"> or drag &amp; drop</span>\n </p>\n <div class=\"du-dropzone__meta\">\n @if (multiple) {\n @if (maxFiles > 0 && minFiles > 0) {\n <span class=\"du-chip du-chip--info\">{{ minFiles }}\u2013{{ maxFiles }} files</span>\n } @else if (maxFiles > 0) {\n <span class=\"du-chip du-chip--info\">Max {{ maxFiles }} files</span>\n } @else if (minFiles > 0) {\n <span class=\"du-chip du-chip--info\">Min {{ minFiles }} files</span>\n } @else {\n <span class=\"du-chip du-chip--info\">Multiple files</span>\n }\n } @else {\n <span class=\"du-chip du-chip--info\">Single file</span>\n }\n @if (accept) { <span class=\"du-chip\">{{ accept }}</span> }\n @if (maxSize) { <span class=\"du-chip\">{{ maxSizeLabel }}</span> }\n </div>\n } @else {\n <p class=\"du-dropzone__headline du-dropzone__headline--drop\">\n <span class=\"du-gradient-text\">Release to drop!</span>\n </p>\n }\n\n }\n </div>\n </div>\n\n <!-- \u2500\u2500 Errors \u2500\u2500 -->\n @for (err of sizeErrors; track err) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n {{ err }}\n </div>\n }\n @if (requiredError) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n {{ label || 'File' }} is required!\n </div>\n }\n @if (minFilesError) {\n <div class=\"du-msg du-msg--error\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"17\" r=\"1.2\" fill=\"currentColor\"/>\n </svg>\n At least {{ minFiles }} files are required ({{ pendingFiles.length }} added).\n </div>\n }\n\n <!-- \u2500\u2500 Pending Files \u2500\u2500 -->\n @if (pendingFiles.length > 0) {\n <div class=\"du-section\">\n <div class=\"du-section__hdr\">\n <span class=\"du-section__title\">Queued Files</span>\n @if (multiple && maxFiles > 0) {\n <span class=\"du-count-label\" [class.du-count-label--full]=\"maxFilesReached\">\n {{ pendingFiles.length }} / {{ maxFiles }}\n </span>\n } @else {\n <span class=\"du-count du-count--purple\">{{ pendingFiles.length }}</span>\n }\n </div>\n <div class=\"du-file-list\">\n @for (file of pendingFiles; track file.name; let i = $index) {\n <div class=\"du-file-card\" [attr.data-ftype]=\"getFileType(file.name)\" [style.animation-delay]=\"i * 40 + 'ms'\">\n\n <div class=\"du-file-icon\">\n @switch (getFileType(file.name)) {\n @case ('pdf') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#FEE2E2\"/>\n <path d=\"M26 4v10h10\" fill=\"#FECACA\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#EF4444\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">PDF</text>\n </svg>\n }\n @case ('word') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#DBEAFE\"/>\n <path d=\"M26 4v10h10\" fill=\"#BFDBFE\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#3B82F6\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">DOC</text>\n </svg>\n }\n @case ('excel') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#DCFCE7\"/>\n <path d=\"M26 4v10h10\" fill=\"#BBF7D0\"/>\n <rect x=\"4\" y=\"28\" width=\"32\" height=\"12\" rx=\"2\" fill=\"#22C55E\"/>\n <text x=\"20\" y=\"38\" text-anchor=\"middle\" fill=\"white\" font-size=\"7\" font-weight=\"800\" font-family=\"sans-serif\">XLS</text>\n </svg>\n }\n @case ('image') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#FEF9C3\"/>\n <path d=\"M26 4v10h10\" fill=\"#FEF08A\"/>\n <rect x=\"6\" y=\"18\" width=\"28\" height=\"18\" rx=\"2\" fill=\"#FDE047\"/>\n <circle cx=\"13\" cy=\"24\" r=\"3\" fill=\"#CA8A04\"/>\n <path d=\"M6 36l9-9 5 5 4-4 10 8H6Z\" fill=\"#EAB308\" opacity=\"0.8\"/>\n </svg>\n }\n @case ('archive') {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#EDE9FE\"/>\n <path d=\"M26 4v10h10\" fill=\"#DDD6FE\"/>\n <rect x=\"14\" y=\"12\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#A78BFA\"/>\n <rect x=\"14\" y=\"18\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#C4B5FD\"/>\n <rect x=\"14\" y=\"24\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#A78BFA\"/>\n <rect x=\"14\" y=\"30\" width=\"12\" height=\"4\" rx=\"1\" fill=\"#C4B5FD\"/>\n <rect x=\"16\" y=\"26\" width=\"8\" height=\"6\" rx=\"1\" fill=\"#7C3AED\"/>\n </svg>\n }\n @default {\n <svg viewBox=\"0 0 40 48\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4h20l10 10v30a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2z\" fill=\"#F1F5F9\"/>\n <path d=\"M26 4v10h10\" fill=\"#E2E8F0\"/>\n <line x1=\"10\" y1=\"24\" x2=\"30\" y2=\"24\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <line x1=\"10\" y1=\"30\" x2=\"26\" y2=\"30\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <line x1=\"10\" y1=\"36\" x2=\"22\" y2=\"36\" stroke=\"#94A3B8\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n }\n }\n </div>\n\n <div class=\"du-file-info\">\n <span class=\"du-file-name\" [title]=\"file.name\">{{ file.name }}</span>\n <span class=\"du-file-size\">{{ getFileSize(file.size) }}</span>\n </div>\n\n <button type=\"button\" class=\"du-remove-btn\" (click)=\"removeFile(i)\" title=\"Remove\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\"/>\n <path d=\"M15 9L9 15M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Upload Button \u2500\u2500 -->\n @if (showUploadButton && pendingFiles.length > 0) {\n <button type=\"button\" class=\"du-upload-btn\" (click)=\"upload()\" [disabled]=\"disabled\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" width=\"17\" height=\"17\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>\n <polyline points=\"17,8 12,3 7,8\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"/>\n </svg>\n {{ uploadButtonLabel }}\n <span class=\"du-upload-btn__badge\">{{ pendingFiles.length }}</span>\n </button>\n }\n\n <!-- \u2500\u2500 Saved Documents \u2500\u2500 -->\n @if (savedDocuments.length > 0) {\n <div class=\"du-section\">\n <div class=\"du-section__hdr\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" class=\"du-section__icon\">\n <path d=\"M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z\" stroke=\"#10b981\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <polyline points=\"14,2 14,8 20,8\" stroke=\"#10b981\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"du-section__title\">Saved Documents</span>\n <span class=\"du-count du-count--green\">{{ savedDocuments.length }}</span>\n </div>\n <div class=\"du-saved-list\" [style.max-height]=\"savedDocsMaxHeight\">\n @for (doc of savedDocuments; track doc.id; let i = $index) {\n <div class=\"du-saved-card\" [style.animation-delay]=\"i * 50 + 'ms'\">\n\n <div class=\"du-saved-icon\">\n @switch (getFileType(doc.name)) {\n @case ('pdf') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#FEE2E2\"/>\n <path d=\"M20 3v8h8\" fill=\"#FECACA\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#EF4444\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">PDF</text>\n </svg>\n }\n @case ('word') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#DBEAFE\"/>\n <path d=\"M20 3v8h8\" fill=\"#BFDBFE\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#3B82F6\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">DOC</text>\n </svg>\n }\n @case ('excel') {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#DCFCE7\"/>\n <path d=\"M20 3v8h8\" fill=\"#BBF7D0\"/>\n <rect x=\"2\" y=\"22\" width=\"28\" height=\"10\" rx=\"2\" fill=\"#22C55E\"/>\n <text x=\"16\" y=\"30\" text-anchor=\"middle\" fill=\"white\" font-size=\"6\" font-weight=\"800\" font-family=\"sans-serif\">XLS</text>\n </svg>\n }\n @case ('image') {\n <svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#FEF9C3\"/>\n <rect x=\"4\" y=\"7\" width=\"24\" height=\"18\" rx=\"2\" fill=\"#FDE047\"/>\n <circle cx=\"10\" cy=\"13\" r=\"2.5\" fill=\"#CA8A04\"/>\n <path d=\"M4 25l8-8 5 5 4-4 11 7H4Z\" fill=\"#EAB308\" opacity=\"0.7\"/>\n </svg>\n }\n @case ('archive') {\n <svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#EDE9FE\"/>\n <rect x=\"4\" y=\"8\" width=\"24\" height=\"5\" rx=\"1.5\" fill=\"#A78BFA\"/>\n <rect x=\"4\" y=\"14\" width=\"24\" height=\"14\" rx=\"2\" fill=\"#C4B5FD\"/>\n <rect x=\"11\" y=\"18\" width=\"10\" height=\"6\" rx=\"1.5\" fill=\"#7C3AED\"/>\n <line x1=\"16\" y1=\"18\" x2=\"16\" y2=\"24\" stroke=\"white\" stroke-width=\"1.5\"/>\n </svg>\n }\n @default {\n <svg viewBox=\"0 0 32 38\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 3h16l8 8v24a1.5 1.5 0 01-1.5 1.5H4A1.5 1.5 0 012.5 35V4.5A1.5 1.5 0 014 3z\" fill=\"#F1F5F9\"/>\n <path d=\"M20 3v8h8\" fill=\"#E2E8F0\"/>\n <line x1=\"7\" y1=\"20\" x2=\"25\" y2=\"20\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n <line x1=\"7\" y1=\"25\" x2=\"21\" y2=\"25\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n <line x1=\"7\" y1=\"30\" x2=\"17\" y2=\"30\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"/>\n </svg>\n }\n }\n </div>\n\n <div class=\"du-saved-info\">\n <span class=\"du-saved-name\" [title]=\"doc.name\">{{ doc.name }}</span>\n @if (doc.addBy || doc.addOn) {\n <span class=\"du-saved-meta\">\n @if (doc.addBy) { <span class=\"du-saved-by\">{{ doc.addBy }}</span> }\n @if (doc.addBy && doc.addOn) { <span class=\"du-saved-sep\">\u00B7</span> }\n @if (doc.addOn) { <span class=\"du-saved-on\">{{ formatDate(doc.addOn) }}</span> }\n </span>\n }\n </div>\n\n <div class=\"du-saved-actions\">\n <!-- <button type=\"button\" class=\"du-act du-act--view\" (click)=\"onView(doc)\" title=\"View\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"2\"/>\n </svg>\n </button> -->\n <button type=\"button\" class=\"du-act du-act--download\" (click)=\"onDownload(doc)\" title=\"Download\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <polyline points=\"7,10 12,15 17,10\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/>\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n <button type=\"button\" class=\"du-act du-act--delete\" (click)=\"onDelete(doc)\" title=\"Delete\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <polyline points=\"3,6 5,6 21,6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M10 11v6M14 11v6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n <path d=\"M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n </button>\n </div>\n\n </div>\n }\n </div>\n </div>\n }\n\n</div>\n", styles: ["@keyframes du-float{0%,to{transform:translateY(0)}50%{transform:translateY(-9px)}}@keyframes du-arrow-bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@keyframes du-particle{0%,to{transform:translate(0) scale(1);opacity:.25}33%{transform:translate(4px,-14px) scale(1.15);opacity:.5}66%{transform:translate(-4px,-7px) scale(.88);opacity:.2}}@keyframes du-slide-in{0%{opacity:0;transform:translate(18px)}to{opacity:1;transform:translate(0)}}@keyframes du-fade-up{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes du-pop-in{0%{opacity:0;transform:scale(.8)}70%{transform:scale(1.06)}to{opacity:1;transform:scale(1)}}@keyframes du-glow-pulse{0%,to{box-shadow:0 0 #667eea59}50%{box-shadow:0 0 0 8px #667eea00}}@keyframes du-btn-pulse{0%,to{box-shadow:0 4px 20px #667eea66}50%{box-shadow:0 6px 30px #764ba299}}@keyframes du-gradient-shift{0%{background-position:0% 50%}50%{background-position:100% 50%}to{background-position:0% 50%}}@keyframes du-ripple{0%{transform:scale(.6);opacity:.7}to{transform:scale(2.2);opacity:0}}@keyframes du-glint{0%,80%,to{opacity:0;transform:scale(.5)}40%{opacity:.7;transform:scale(1.4)}}.du-container{display:flex;flex-direction:column;gap:10px;width:100%}.du-container.du--disabled{opacity:.55;pointer-events:none}.du-label{display:flex;align-items:center;gap:2px;font-size:var(--osl-label-font-size, 13px);font-weight:500;color:#374151;overflow:hidden}.du-label--error{color:var(--osl-error-color, #ef4444)}.du-label__text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.du-label__req{color:var(--osl-error-color, #ef4444);flex-shrink:0;font-weight:700}.du-file-input{display:none}.du-dropzone{position:relative;width:100%;min-height:158px;border-radius:18px;border:2px dashed rgba(102,126,234,.35);background:linear-gradient(145deg,#fafbff,#f5f3ff);cursor:pointer;overflow:hidden;transition:border-color .3s ease,background .3s ease,box-shadow .3s ease,transform .25s ease}.du-dropzone:hover:not(.du-dropzone--disabled){border-color:#667eeab3;background:linear-gradient(145deg,#f5f3ff,#ede9fe);transform:translateY(-2px);box-shadow:0 10px 30px #667eea1f}.du-dropzone--over{border:2px solid #667eea!important;background:linear-gradient(145deg,#ede9fe,#ddd6fe)!important;transform:scale(1.012) translateY(-3px)!important;box-shadow:0 18px 40px #667eea38,inset 0 0 0 1px #667eea4d!important}.du-dropzone--over .du-cloud-body{stroke:#764ba2}.du-dropzone--over .du-cloud-glint{animation:du-glint .6s ease infinite}.du-dropzone--error{border-color:#ef444480;background:linear-gradient(145deg,#fff5f5,#fee2e2);animation:du-glow-pulse 1.8s ease infinite}.du-dropzone--disabled{cursor:not-allowed;background:#f9fafb!important;border-color:#e5e7eb!important;box-shadow:none!important;transform:none!important}.du-particles{position:absolute;inset:0;pointer-events:none;overflow:hidden}.du-p{position:absolute;border-radius:50%;background:radial-gradient(circle,#667eea38,#764ba21f);animation:du-particle var(--dur, 4s) ease-in-out infinite}.du-p--1{width:22px;height:22px;top:12%;left:6%;--dur: 4.2s;animation-delay:0s}.du-p--2{width:14px;height:14px;top:65%;left:88%;--dur: 5.1s;animation-delay:.9s}.du-p--3{width:18px;height:18px;top:18%;left:82%;--dur: 3.8s;animation-delay:1.6s}.du-p--4{width:10px;height:10px;top:75%;left:12%;--dur: 6.3s;animation-delay:.4s}.du-p--5{width:16px;height:16px;top:50%;left:48%;--dur: 4.7s;animation-delay:2.1s}.du-p--6{width:8px;height:8px;top:30%;left:38%;--dur: 5.5s;animation-delay:1.1s}.du-dropzone__inner{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:26px 20px;min-height:158px}.du-cloud-wrap{width:80px;height:64px;animation:du-float 3.2s ease-in-out infinite;filter:drop-shadow(0 4px 10px rgba(102,126,234,.2));transition:filter .3s ease;flex-shrink:0}.du-cloud-wrap--over{animation-duration:1.2s;filter:drop-shadow(0 6px 18px rgba(102,126,234,.45))}.du-cloud-svg{width:100%;height:100%}.du-cloud-body{transition:stroke .3s ease}.du-cloud-glint{transform-origin:center}.du-arrow{animation:du-arrow-bounce 1.6s ease-in-out infinite}.du-dropzone__headline{margin:0;font-size:14px;color:#6b7280;line-height:1.5;text-align:center}.du-dropzone__headline--drop .du-gradient-text{animation:du-glow-pulse .7s ease infinite}.du-gradient-text{background:linear-gradient(135deg,#667eea,#764ba2);background-size:200% 200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;font-weight:700;animation:du-gradient-shift 3s ease infinite}.du-or{color:#9ca3af;font-size:13px}.du-dropzone__meta{display:flex;flex-wrap:wrap;justify-content:center;gap:6px}.du-chip{border-radius:20px;padding:2px 10px;font-size:11px;font-weight:500;background:#667eea14;color:#7c6fcd;border:1px solid rgba(102,126,234,.18);transition:background .2s}.du-chip--info{background:#10b98114;color:#059669;border-color:#10b98133}.du-msg{display:flex;align-items:center;gap:6px;font-size:var(--osl-hint-font-size, 11px);animation:du-fade-up .2s ease}.du-msg svg{flex-shrink:0}.du-msg--error{color:var(--osl-error-color, #ef4444)}.du-section{display:flex;flex-direction:column;gap:8px;animation:du-fade-up .3s ease}.du-section__hdr{display:flex;align-items:center;gap:7px}.du-section__icon{flex-shrink:0}.du-section__title{font-size:11px;font-weight:700;color:#9ca3af;text-transform:uppercase;letter-spacing:.07em}.du-count{width:19px;height:19px;border-radius:50%;font-size:10px;font-weight:800;color:#fff;display:flex;align-items:center;justify-content:center;flex-shrink:0;animation:du-pop-in .3s ease}.du-count--purple{background:linear-gradient(135deg,#667eea,#764ba2)}.du-count--green{background:linear-gradient(135deg,#10b981,#059669)}.du-file-list{display:flex;flex-direction:column;gap:7px}.du-file-card{display:flex;align-items:center;gap:11px;padding:10px 14px 10px 16px;background:#fff;border-radius:13px;border:1px solid #e9ecf1;animation:du-slide-in .28s ease both;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease;position:relative}.du-file-card:before{content:\"\";position:absolute;left:0;top:50%;transform:translateY(-50%);width:4px;height:60%;border-radius:0 4px 4px 0;transition:height .2s ease}.du-file-card[data-ftype=pdf]:before{background:#ef4444}.du-file-card[data-ftype=word]:before{background:#3b82f6}.du-file-card[data-ftype=excel]:before{background:#22c55e}.du-file-card[data-ftype=image]:before{background:#f59e0b}.du-file-card[data-ftype=archive]:before{background:#8b5cf6}.du-file-card[data-ftype=generic]:before{background:#94a3b8}.du-file-card:hover{border-color:#c4b5fd;box-shadow:0 3px 14px #667eea1a;transform:translate(3px)}.du-file-card:hover:before{height:75%}.du-file-icon{width:38px;height:46px;flex-shrink:0}.du-file-icon svg{width:100%;height:100%}.du-file-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.du-file-name{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.du-file-size{font-size:11px;color:#94a3b8;font-weight:500}.du-remove-btn{width:30px;height:30px;flex-shrink:0;border-radius:50%;border:1.5px solid #fecaca;background:#fef2f2;color:#fca5a5;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:6px;transition:all .22s ease}.du-remove-btn svg{width:100%;height:100%}.du-remove-btn:hover{background:#fee2e2;border-color:#ef4444;color:#ef4444;transform:rotate(90deg) scale(1.1);box-shadow:0 3px 10px #ef444440}.du-upload-btn{display:flex;align-items:center;justify-content:center;gap:8px;padding:12px 24px;width:100%;border:none;border-radius:13px;background:linear-gradient(135deg,#667eea,#764ba2);background-size:200% 200%;color:#fff;font-size:14px;font-weight:700;letter-spacing:.03em;cursor:pointer;transition:transform .25s ease,box-shadow .25s ease;animation:du-btn-pulse 2.5s ease-in-out infinite,du-gradient-shift 4s ease infinite}.du-upload-btn svg{flex-shrink:0;transition:transform .25s ease}.du-upload-btn:hover:not([disabled]){transform:translateY(-3px);box-shadow:0 10px 28px #667eea80;animation:du-gradient-shift 1.5s ease infinite}.du-upload-btn:hover:not([disabled]) svg{transform:translateY(-3px)}.du-upload-btn:active:not([disabled]){transform:translateY(-1px)}.du-upload-btn[disabled]{opacity:.45;cursor:not-allowed;animation:none}.du-upload-btn__badge{min-width:22px;height:22px;padding:0 6px;border-radius:11px;background:#ffffff38;font-size:11px;font-weight:800;display:flex;align-items:center;justify-content:center;animation:du-pop-in .3s ease}.du-saved-list{display:flex;flex-direction:column;gap:7px;overflow-y:auto;padding-right:2px;scrollbar-width:thin;scrollbar-color:#c4b5fd transparent}.du-saved-list::-webkit-scrollbar{width:5px}.du-saved-list::-webkit-scrollbar-track{background:transparent;border-radius:10px}.du-saved-list::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#a5b4fc,#c4b5fd);border-radius:10px}.du-saved-list::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,#818cf8,#a78bfa)}.du-saved-card{display:flex;align-items:center;gap:11px;padding:10px 12px;background:linear-gradient(135deg,#fff,#f8faff);border-radius:13px;border:1px solid #e9ecf1;opacity:0;animation:du-fade-up .32s ease forwards;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}.du-saved-card:hover{border-color:#a5b4fc;box-shadow:0 4px 18px #667eea1a;transform:translateY(-1px)}.du-saved-icon{width:32px;height:38px;flex-shrink:0}.du-saved-icon svg{width:100%;height:100%}.du-saved-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.du-saved-name{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.du-saved-size{font-size:11px;color:#94a3b8;font-weight:500}.du-saved-actions{display:flex;align-items:center;gap:5px;flex-shrink:0}.du-act{width:32px;height:32px;border-radius:9px;border:1.5px solid transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:7px;transition:all .22s ease;position:relative;overflow:hidden}.du-act svg{width:100%;height:100%;transition:transform .22s ease}.du-act:after{content:\"\";position:absolute;inset:50%;border-radius:50%;transition:all 0s;pointer-events:none}.du-act:active:after{inset:0;border-radius:9px;background:#ffffff59;animation:du-ripple .4s ease}.du-act--view{background:#eff6ff;color:#3b82f6;border-color:#bfdbfe}.du-act--view:hover{background:#dbeafe;border-color:#93c5fd;box-shadow:0 3px 12px #3b82f64d}.du-act--view:hover svg{transform:scale(1.12)}.du-act--download{background:#f0fdf4;color:#22c55e;border-color:#bbf7d0}.du-act--download:hover{background:#dcfce7;border-color:#86efac;box-shadow:0 3px 12px #22c55e4d}.du-act--download:hover svg{transform:translateY(2px) scale(1.08)}.du-act--delete{background:#fef2f2;color:#ef4444;border-color:#fecaca}.du-act--delete:hover{background:#fee2e2;border-color:#fca5a5;box-shadow:0 3px 12px #ef44444d}.du-act--delete:hover svg{transform:scale(1.1) rotate(-5deg)}.du-dropzone--maxed{cursor:default;border-color:#22c55e66!important;background:linear-gradient(145deg,#f0fdf4,#dcfce7)!important;pointer-events:none}.du-dropzone--maxed .du-particles .du-p{background:radial-gradient(circle,#22c55e2e,#10b9811a)}.du-maxed-icon{width:56px;height:56px;animation:du-pop-in .4s cubic-bezier(.34,1.56,.64,1)}.du-maxed-icon svg{width:100%;height:100%}.du-gradient-text--green{background:linear-gradient(135deg,#22c55e,#059669)!important;background-size:200% 200%!important;-webkit-background-clip:text!important;-webkit-text-fill-color:transparent!important;background-clip:text!important}.du-maxed-sub{margin:0;font-size:12px;color:#6b7280;font-weight:500}.du-count-label{font-size:11px;font-weight:700;padding:2px 9px;border-radius:20px;background:#667eea1a;color:#667eea;border:1px solid rgba(102,126,234,.2);transition:all .25s ease;animation:du-pop-in .3s ease}.du-count-label--full{background:#22c55e1a;color:#16a34a;border-color:#22c55e40}.du-saved-meta{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.du-saved-by{font-size:11px;font-weight:600;color:#667eea}.du-saved-sep{font-size:11px;color:#d1d5db}.du-saved-on{font-size:11px;color:#94a3b8}\n"] }]
5535
5559
  }], propDecorators: { label: [{
5536
5560
  type: Input,
5537
5561
  args: ['label']
@@ -5565,6 +5589,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
5565
5589
  }], savedDocuments: [{
5566
5590
  type: Input,
5567
5591
  args: ['savedDocuments']
5592
+ }], savedDocsMaxHeight: [{
5593
+ type: Input,
5594
+ args: ['savedDocsMaxHeight']
5568
5595
  }], skeletonLoading: [{
5569
5596
  type: Input,
5570
5597
  args: ['skeletonLoading']