irisa-minio 20.0.0

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.
@@ -0,0 +1,824 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Inject, Injectable, forwardRef, booleanAttribute, ViewChild, Input, Component, ContentChild, NgModule } from '@angular/core';
3
+ import { of, Observable } from 'rxjs';
4
+ import { switchMap, map } from 'rxjs/operators';
5
+ import * as i1 from '@angular/common/http';
6
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormsModule } from '@angular/forms';
7
+ import { ObservableState, recordState } from 'irisa-helpers';
8
+ import { saveAs } from 'file-saver';
9
+ import * as i2 from 'irisa-toasts';
10
+ import * as i3 from '@ngx-translate/core';
11
+ import { TranslateModule } from '@ngx-translate/core';
12
+ import * as i4 from '@angular/common';
13
+ import { CommonModule } from '@angular/common';
14
+ import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
15
+
16
+ function getFileIcon(extension) {
17
+ if (extension)
18
+ return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(getFileIconContent(extension.toLowerCase()))}`;
19
+ return '';
20
+ }
21
+ function getFileSize(bytes, decimals = 2) {
22
+ if (bytes === 0) {
23
+ return '0 Bytes';
24
+ }
25
+ const k = 1024;
26
+ const dm = decimals <= 0 ? 0 : decimals || 2;
27
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
28
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
29
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
30
+ }
31
+ const svgs = {
32
+ doc: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M18.536 2.323v2.545c3.4.019 7.12-.035 10.521.019a.783.783 0 01.912.861c.054 6.266-.013 12.89.032 19.157-.02.4.009 1.118-.053 1.517-.079.509-.306.607-.817.676-.286.039-.764.034-1.045.047-2.792-.014-5.582-.011-8.374-.01h-1.175v2.547L2 27.133V4.873l16.536-2.551" fill="#283c82"/><path d="M18.536 5.822h10.5V26.18h-10.5v-2.545h8.27v-1.272h-8.27v-1.59h8.27V19.5h-8.27v-1.59h8.27v-1.273h-8.27v-1.59h8.27v-1.273h-8.27v-1.59h8.27v-1.273h-8.27v-1.59h8.27V8.048h-8.27V5.822M8.573 11.443c.6-.035 1.209-.06 1.813-.092.423 2.147.856 4.291 1.314 6.429.359-2.208.757-4.409 1.142-6.613a57.415 57.415 0 001.905-.1c-.719 3.082-1.349 6.19-2.134 9.254-.531.277-1.326-.013-1.956.032-.423-2.106-.916-4.2-1.295-6.314-.372 2.061-.856 4.094-1.282 6.136q-.916-.048-1.839-.111c-.528-2.8-1.148-5.579-1.641-8.385.544-.025 1.091-.048 1.635-.067.328 2.026.7 4.043.986 6.072.448-2.08.907-4.161 1.352-6.241" fill="#fff"/></svg>',
33
+ xls: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M28.781 4.405h-10.13V2.018L2 4.588v22.527l16.651 2.868v-3.538h10.13A1.162 1.162 0 0030 25.349V5.5a1.162 1.162 0 00-1.219-1.095zm.16 21.126H18.617l-.017-1.889h2.487v-2.2h-2.506l-.012-1.3h2.518v-2.2H18.55l-.012-1.3h2.549v-2.2H18.53v-1.3h2.557v-2.2H18.53v-1.3h2.557v-2.2H18.53v-2h10.411z" fill="#20744a" fill-rule="evenodd"/><path fill="#20744a" d="M22.487 7.439h4.323v2.2h-4.323zM22.487 10.94h4.323v2.2h-4.323zM22.487 14.441h4.323v2.2h-4.323zM22.487 17.942h4.323v2.2h-4.323zM22.487 21.443h4.323v2.2h-4.323z"/><path fill="#fff" fill-rule="evenodd" d="M6.347 10.673l2.146-.123 1.349 3.709 1.594-3.862 2.146-.123-2.606 5.266 2.606 5.279-2.269-.153-1.532-4.024-1.533 3.871-2.085-.184 2.422-4.663-2.238-4.993z"/></svg>',
34
+ ppt: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M18.536 2.321v2.863c3.4.019 7.357-.035 10.754.016.642 0 .67.568.678 1.064.054 5.942-.013 12.055.032 18-.012.234-.006 1.1-.013 1.346-.022.823-.434.859-1.257.884-.132 0-.52.006-.648.012-3.181-.016-6.362-.009-9.546-.009v3.182L2 27.134V4.873l16.536-2.551" fill="#d33922"/><path d="M18.536 6.138h10.5v19.4h-10.5V23h7.634v-1.275h-7.634v-1.59h7.634v-1.272h-7.631c0-.624 0-1.247-.006-1.87a4.467 4.467 0 003.82-.375 4.352 4.352 0 001.959-3.474c-1.4-.01-2.793-.006-4.186-.006 0-1.384.016-2.767-.029-4.148-.522.1-1.043.21-1.562.321V6.139" fill="#fff"/><path d="M20.766 8.324a4.476 4.476 0 014.186 4.167c-1.4.016-2.793.01-4.189.01V8.324" fill="#d33922"/><path d="M7.1 10.726c1.727.083 3.82-.684 5.252.611 1.371 1.664 1.008 4.724-1.024 5.719A4.7 4.7 0 019 17.348c0 1.244-.006 2.488 0 3.731-.63-.054-1.263-.108-1.893-.159-.029-3.4-.035-6.8 0-10.2" fill="#fff"/><path d="M8.993 12.446c.627-.029 1.4-.143 1.826.445a2.308 2.308 0 01.041 2.087c-.363.655-1.183.592-1.816.668-.067-1.066-.06-2.131-.051-3.2" fill="#d33922"/></svg>',
35
+ png: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30 5.851v20.298H2V5.851h28" fill="#2dcc9f"/><path d="M24.232 8.541a2.2 2.2 0 101.127.623 2.212 2.212 0 00-1.127-.623M18.111 20.1q-2.724-3.788-5.45-7.575L4.579 23.766h10.9q1.316-1.832 2.634-3.663M22.057 16q-2.793 3.882-5.584 7.765h11.169Q24.851 19.882 22.057 16z" fill="#fff"/></svg>',
36
+ zip: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32"><defs><linearGradient id="a" x1="-414.07" y1="-323.688" x2="-413.475" y2="-323.688" gradientTransform="rotate(-2.754 55095.274 -73583.23) scale(8.352)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#3dc2f3"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="d" x1="-466.763" y1="-351.799" x2="-466.168" y2="-351.799" gradientTransform="rotate(176.688 -1581.368 -1116.272) scale(6.683)" xlink:href="#a"/><linearGradient id="e" x1="-515.182" y1="-375.873" x2="-514.587" y2="-375.873" gradientTransform="rotate(180 -662.65 -481.324) scale(2.607)" xlink:href="#a"/><linearGradient id="b" x1="-413.465" y1="-322.372" x2="-412.869" y2="-322.372" gradientTransform="rotate(-1.63 93678.305 -123744.426) scale(8.403)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0995dd"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="f" x1="-515.182" y1="-373.034" x2="-514.587" y2="-373.034" gradientTransform="rotate(180 -662.625 -472.184) scale(2.607)" xlink:href="#a"/><linearGradient id="g" x1="-415.664" y1="-321.968" x2="-415.069" y2="-321.968" gradientTransform="rotate(-7.749 19166.393 -28309.74) scale(8.752)" xlink:href="#b"/><linearGradient id="i" x1="-397.199" y1="-317.443" x2="-396.604" y2="-317.443" gradientTransform="rotate(.719 -126538.107 155625.572) scale(4.876)" xlink:href="#a"/><radialGradient id="c" cx="-428.363" cy="-337.616" r=".076" gradientTransform="matrix(22.426 -.918 .944 23.053 9940.275 7417.533)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#41c3f3"/></radialGradient><radialGradient id="h" cx="-435.908" cy="-337.858" r=".076" gradientTransform="matrix(22.426 -.918 .944 23.053 10123.552 7416.068)" xlink:href="#c"/></defs><path d="M9.832 2l7.415.053a2 2 0 012.054.936l.67.819h5.672c.5.032.8.175.949.446a2.8 2.8 0 01.092 1.046l.019.913c.008 1.534-.388 1.533-1.009 1.523l-1.31.017v11.741a8.05 8.05 0 01.846.019c.621.011 1.19.005 1.191 1.366-.009.224-.017.45-.01.621a2.2 2.2 0 000 .569c-.032.5-.07.83-.3 1.047-.18.231-.487.312-.988.28-.277-.024-.516.021-.741.012l-.016 2.207c.105.031.225.007.33.039.156.045.329.04.419.121a1.43 1.43 0 011.124 1.4l1.952.113a.587.587 0 01.227-.388.754.754 0 01.524-.245l.053.015a.9.9 0 01.79.8l-.015.053.012.741a.942.942 0 01-.286.6 1.194 1.194 0 01-.577.229.753.753 0 01-.546-.271.425.425 0 01-.148-.271l-2.082.134a1.6 1.6 0 01-.452.777 2.156 2.156 0 01-1.513.525l-2.9.011a2.421 2.421 0 01-1.585-.4 1.483 1.483 0 01-.482-.877l-3.2-.133a.518.518 0 01-.211.335.866.866 0 01-.577.23.745.745 0 01-.56-.219.868.868 0 01-.23-.577v-.794a.754.754 0 01.271-.545.6.6 0 01.577-.23.745.745 0 01.56.219.428.428 0 01.149.27l3.2-.264a1.928 1.928 0 01.6-.9 2.406 2.406 0 011.274-.48l.016-2.208c-.292.028-.568 0-.913.019l-1.247 1.169a2.482 2.482 0 01-2.158.793c-1.19-.005-2.5.012-3.809.029-1.243-.02-2.484-.04-3.847-.038a2.971 2.971 0 01-1.144-.162 3.342 3.342 0 01-1.052-.872 5.746 5.746 0 01-.469-.533c-.127-.15-.253-.3-.469-.533a.763.763 0 01-.164-.218.467.467 0 01.106-.367c.067-.037.15-.126.218-.163.172-.007.359-.066.532-.073 1.415.013 3.053.035 4.639.041s3.173.013 4.812.035a2.273 2.273 0 001-.333 5.376 5.376 0 00.833-.722c.88-.88 2.044-1.96 2.837-1.957a.5.5 0 01.277.023l.033-11.848h-.4a1.545 1.545 0 01-1.4-.634l-1.377-1.7c-.633-.75-.633-.75-1.546-.732L7.55 4.572c-.517.02-1.429.04-.805-.744l.827-.9a3.127 3.127 0 011.088-.813A5.06 5.06 0 019.828 2" fill="#2e2a2b"/><path d="M15.366 27.055l-.005.018-.041.007-.041.007-.018-.007-.082.015-.018-.007-.128.04-.028.03-.041.007-.016.054-.046.025-.018-.007-.016.054-.016.054-.016.054-.016.054-.016.054-.016.054-.016.054.022.123-.005.018-.01.035.022.123-.016.054.012.158-.016.054-.016.054.031.028.008.041-.016.054-.016.054.048.033-.01.035.038.069.043.051-.005.018.054.015.038.069.054.015c.028.051.092.068.173.07h.077l.082-.015a.45.45 0 00.164-.03l.051-.044.018.007.016-.054.085-.092.016-.054.016-.054.016-.054.016-.054.016-.054.01-.035-.038-.069.031-.107-.017-.141.026-.089-.022-.123.016-.054.016-.054-.038-.069.016-.054.01-.035-.031-.028-.008-.041-.013-.023-.025-.046-.038-.069-.02-.064-.054-.015-.145-.1-.089-.026z" fill="url(#c)"/><path fill="url(#a)" d="M19.234 27.352l-.123.023-.053-.015-.123.022-.159.012-.053-.015-.123.023-.123.022-.122.023-.108-.032-.117.004-.105.028-.053-.015-.123.022-.177.008-.053-.016-.123.023-.123.022-.053-.015-.159.012-.122.023-.054-.016-.123.023-.122.022-.108-.031-.122.022-.105.028-.006.018-.063.02-.054-.015-.176.007-.021.672.069-.039.09.026.122-.022.054.015.053.015.177-.007.053.015.054.016.123-.023.053.016.089.026.123-.023.054.015.176-.007.054.016.053.015.123-.023.054.016.107.031.105-.028.053.016.123-.023.107.031.054.016.122-.023.054.016.053.015.159-.012.054.015.053.015.117-.004.108.031.122-.022.054.015.054.015.122-.022.007-1.024-.054-.016.001.002z"/><path d="M24.59 26.043a.777.777 0 01-.176.007c-.1-.03-.162-.047-.23-.007l-.054-.015-.054-.015-.335.019-.176.007-.176.007-.158.012-.337-.039-.353.014-.158.012-.176.007-.176.007-.367-.068-.354.009-.123.022-.054-.015-.064.02h-.059a1.327 1.327 0 00-.3.088 1.161 1.161 0 00-.174.066l-.087.033a.406.406 0 00-.156.071l-.074.056-.11.045-.016.054c-.053-.015-.071.038-.138.076l-.044.084-.033.048-.09.11-.01.035a.967.967 0 00-.124.429l-.018 1.2A1.128 1.128 0 0019.8 29l.007.041c.037.067.06.134.165.164l.079.061.084.044a.551.551 0 00.15.082l.031.028.071.021.089.026c.1.03.215.006.319.034s.234.007.391.055l.005-.018.018.007.1-.009.054.015.158-.012.176-.007.176-.007.337.039.158-.012.176-.007.176-.007.171.011.158-.012.176-.007.337.039.335-.019.036.011h.194c.067-.037 0 0 .054.015l.1-.028c.106-.012.209 0 .317-.024a.942.942 0 00.174-.066.936.936 0 00.325-.119l.005-.018a.588.588 0 00.143-.094l.005-.018.05-.009.023-.012.074-.056a1.072 1.072 0 00.162-.224.881.881 0 00.227-.515.344.344 0 00.009-.23v-1.006l-.01-.1a.681.681 0 00-.108-.361.562.562 0 00-.229-.279 1.075 1.075 0 00-.183-.169L25 26.166l-.107-.031-.25-.073-.054-.015z" fill="url(#d)"/><path d="M23.876 7.715l-.335.019-.337-.04-.335.019-.176.007-.176.007-.278-.042-.281.035-.176.007-.23-.009-.028 2.432.006 5.85.009.235v2.654l-.01.636h.077l.1-.009a.531.531 0 00.235-.01 1.656 1.656 0 01.26.037l.1-.009h.077a.811.811 0 01.176-.007c.12-.023.215 0 .335-.019.052.015.055.016.123-.022l.089.026a.824.824 0 00.276-.017l.041-.007a2.009 2.009 0 01.266.019 1.4 1.4 0 01.141-.018l.036.011c.052.015.054.015.069-.038l.019-2.2-.014-2.889.007-2.961-.007-.176-.007-2.713v-.794h-.059l.005-.018z" fill="url(#e)"/><path d="M25.9 4.263a2.521 2.521 0 01-.283-.024l-.276.017-.572-.03h-.736l-.741.017-.687.033H21.48l-.78-.049-.759.012-.051.043-.2-.116-.076-.138-.674-.815a2.164 2.164 0 00-.313-.323 1.118 1.118 0 00-.471-.311 2.133 2.133 0 00-.763-.105l-.123.022-.266-.019-.353.014-.779-.052h-.736l-.741.017h-.406l-.741.017h-.388l-.72-.054h-.253l-.153-.006-.734.026h-.388l-.353.014-.442-.012c-.119.022-.226-.025-.294.012h-.388a1.279 1.279 0 00-.315.083l-.069.038a1.308 1.308 0 00-.2.078 1.45 1.45 0 00-.19.119l-.028.031a1.919 1.919 0 00-.385.392l-.848.942a2.047 2.047 0 01.4.02l1.179-.006.353-.014h1.142l.741-.017.779.052.335-.019h1.936l.335-.019h.406l.725.036h.194l.207.021.565-.011c.07 0 .115-.007.176-.007a3.12 3.12 0 01.388 0 1.219 1.219 0 01.686.238 3.355 3.355 0 01.381.42 1.089 1.089 0 01.209.215l.485.664.712.884.183.169a1.878 1.878 0 00.209.215l.018.005a1.451 1.451 0 00.326.211 1.558 1.558 0 00.391.055.173.173 0 00.158-.012l.225.026h.406l.725.036.335-.019.353-.014H24.293l.353-.014h.794l.266.019.054.016.1-.01a.319.319 0 00.325-.254 3.266 3.266 0 00.052-.779l.045-.955c0-.068-.005-.114-.007-.176-.013-.345 0-.562-.084-.644-.022-.12-.133-.155-.29-.2zM23.874 7.7l.055.81v-.794l-.055-.016z" fill="url(#b)"/><path d="M23.876 23.365l-.005.018h-.117l-.054-.015h-.117l-.054-.015-.069.038-.161-.047-.005.018-.064.02-.089-.026-.069.038-.161-.047-.051.044-.018-.007-.107-.031-.069.038-.107-.031-.123.022-.036-.011-.123.022-.071-.021-.158.012-.054-.015c-.068.037-.071.038-.123.022h-.077a.258.258 0 01-.153 0l-.036-.011-.005.02-.041.007-.023.012-.023.613.021 1.129v.406l.054.015.054.015.158-.012.054.015.123-.022.054.015.176-.007.054.015.123-.022.054.015.158-.012.054.015.123-.022.054.015.173-.003.054.015h.117l.054.015.158-.012.054.015.123-.022.054.015.176-.007.054.015.005-.018.064-.02v-.929l.021-1.272-.054-.015z" fill="url(#f)"/><path d="M25.542 19.973a1.57 1.57 0 00-.237-.049l-.069.038a.5.5 0 00-.171-.011 2.583 2.583 0 00-.623.013c-.142 0-.276.008-.388 0a3.98 3.98 0 01-.46-.02 3.534 3.534 0 01-.388 0l-.1.009h-.194c-.1.009-.219.011-.353.014a3.682 3.682 0 00-.618 0 3.69 3.69 0 01-.388 0c-.113 0-.233-.007-.347 0l-.112-.014c-.068.037-.16.012-.228.05a.2.2 0 00-.176.007l-.146.035-.082.015-.151.053-.005.018a8.1 8.1 0 00-.763.5c-.117.108-.223.219-.346.326l-.046.025-.056.061c-.093.077-.192.15-.3.224-.083.089-.168.2-.259.293l-.08.074a1.176 1.176 0 01-.223.168c-.083.089-.1.127-.164.165l-.005.018a2.265 2.265 0 01-.672.58l-.016.054a5.191 5.191 0 01-.765.3 1.5 1.5 0 01-.2.037l-.041.007a.84.84 0 01-.171-.011l-.046.025-.023.012c-.1-.031-.216-.007-.373-.05a4.353 4.353 0 01-.593.041 4.292 4.292 0 00-.524 0c-.106 0-.215-.019-.324-.016-.219-.007-.439 0-.654-.014-.277-.024-.517.025-.794 0l-.041.007h-.059c-.12 0-.241-.017-.36-.027-.293.029-.572.011-.863.04a.406.406 0 00-.23-.007c-.052-.015-.086-.043-.153 0-.14 0-.281-.008-.406 0a4.247 4.247 0 01-.442-.013c-.136 0-.273.01-.406 0a4.249 4.249 0 01-.442-.013c-.059.011-.131 0-.194 0H9.06c-.292.028-.566-.007-.858.022a4.549 4.549 0 00-.848-.014c-.167 0-.333 0-.5-.009-.057 0-.114-.009-.171-.011l-.123.022c-.078.014-.15.036-.228.05l-.016.054a1.663 1.663 0 01.387.4l.081.12a1.712 1.712 0 01.188.152l.148.159.013.023a.3.3 0 00.183.169 1.572 1.572 0 00.29.336l.013.023.048.033a1.675 1.675 0 00.407.331l.107.031.357.1h.618l.094.009h.135c.277.024.566.008.843.032l.141-.017c.088.009.178.011.266.019.278-.027.546-.01.822-.033l.041-.007a4.606 4.606 0 00.848.014c.224.007.442.03.666.038.172-.006.34-.019.565-.01.146-.015.294-.008.429-.011.269-.022.53 0 .8-.02.057 0 .114.011.171.011a3.859 3.859 0 00.7.008c.136 0 .273-.01.406 0s.253 0 .388 0c.12-.022.233.007.353-.014l.107.031c.292-.029.532-.081.772-.125l.023-.012.018.007c.084-.021.141-.033.21-.055a1.435 1.435 0 00.156-.071l.046-.025a2.2 2.2 0 00.241-.162l.1-.069.005-.018c.052-.047.108-.092.159-.148l.169-.183.182-.16.192-.2.387-.333.4-.387.174-.066.094.009.082-.015c.133.011.27 0 .406 0 .277.024.571-.01.848.014.239-.024.466 0 .7-.01l.158-.012a.17.17 0 00.158-.012l.112.014h.523c.277.024.571-.009.848.014.292-.029.572-.011.863-.04.07 0 .137.019.207.022a1.918 1.918 0 00.6-.059l.085-.092a1.285 1.285 0 00.151-.741 2.921 2.921 0 01-.011-.565 2.092 2.092 0 01.01-.636c-.008-.107-.02-.2-.035-.281a1.147 1.147 0 00-.063-.251l-.058-.133-.025-.046-.079-.061-.008-.041-.071-.021-.12-.054z" fill="url(#g)"/><path d="M28.993 27h-.176l-.028.03-.041.007-.01.035h-.059l-.016.054-.051.043-.01.035-.016.054-.016.054-.016.054-.016.054-.016.054-.016.054v.118l-.005.018-.005.018.004.018.008.041.015.082-.031.107.028.1-.016.054-.016.054.038.069-.016.054-.016.054.031.028.008.041.013.023.01.1.054.015.038.069.054.015.038.069.107.031.143.041c.058-.031.151-.063.22-.091l.041-.007.051-.043.033-.048.069-.038.005-.018.01-.035.016-.054.016-.054.016-.054.016-.054.01-.035-.038-.069.016-.054.016-.054-.007-.176.016-.054-.007-.176-.022-.123.016-.054.01-.035-.013-.023-.013-.023-.013-.023.016-.054-.018-.007-.02-.064-.018-.007-.056-.074a.055.055 0 01-.038-.069l-.107-.031-.054-.015a1.383 1.383 0 00-.161-.047z" fill="url(#h)"/><path d="M4.416 5.513h12.705a.2.2 0 01.142.1l.074.135.012 13.449-.061.209-1 .9-1 .9-.068.037-.067.037-12.69-.053c-.1-.031-.247-.129-.216-.234L2.219 7.6l.015-.053a.168.168 0 01.082-.089L4.225 5.57a.29.29 0 01.188-.059" fill="#b3272c"/><path fill="#f46d22" d="M16.556 5.989L4.488 5.947 2.992 7.386l12.003.078 1.562-1.475M16.854 6.287l-1.511 1.491.012 8.17-.027 4.588.632-.612.916-.812-.022-12.824"/><path fill="#f6e216" d="M14.89 20.807l.008-12.932-12.24-.035-.009 12.932 12.241.035"/><path d="M12.807 15.689l.662-.716-.018 4.363-9.242-.016.646-.664 7.944-.019v-2.948zM6.973 11.16l3.57.014.027.689L7 11.849l-.027-.689zm5.819-1.091l.032 3.015-7.932-.032-.7.649 9.3.031V9.421l-.7.649zm-5.8 6.713l-.026.674 3.569.015.025-.674-3.569-.015" fill="#2e2a2b"/><path d="M12.807 10.036L4.875 10l.032 3.016-.7.649V9.354l9.3.031-.7.649zm.014 5.62l.662-.716-9.3-.031.034 4.377.646-.664.02-3 7.932.033" fill="#ec771d"/><path fill="url(#i)" d="M27.982 27.59l-.006.018-.064.02-.053-.015-.107-.031-.105.027-.054-.015-.053-.015-.123.022-.054-.015-.107-.031-.005.017-.064.02-.054-.015-.107-.031-.117.004-.054-.015-.089-.026-.005.018-.064.02-.054-.016-.107-.031-.069.038-.054-.015-.053-.015-.054-.015-.005.017-.064.02-.021.672.01.1-.002.076.053.016.123-.023.054.016.123-.023.035.011.123-.023.118-.004.053.015.123-.022.053.015.123-.022.054.015.122-.022.054.015.051-.043.054.015.123-.022.053.015.123-.022.053.015.006-.018.064-.02.053.016.054.015.005-.018.064-.02.053.015.005-.618-.053-.015-.054-.016-.107-.031z"/><path d="M12.807 10.036L4.875 10l.032 3.016-.7.649V9.354l9.3.031-.7.649zm.014 5.62l.662-.716-9.3-.031.034 4.377.646-.664.02-3 7.932.033" fill="#ec771d"/><path d="M20.9 9.083l3.385-.719.1.03a.746.746 0 01.591.115.975.975 0 01.317.491l-.015.052a.329.329 0 01-.009.224c-.015.052.022.12-.046.157a.855.855 0 01-.683.6l-3.438.7-.052-.015a.773.773 0 01-.591-.115.965.965 0 01-.313-.488l-.038-.067a.329.329 0 00.009-.224l.046-.157a.9.9 0 01.736-.58zm-.177 8.23l3.475-.637.068-.038a1.1 1.1 0 01.575.167.529.529 0 01.312.488l.037.067.007.173-.061.209a.984.984 0 01-.736.58l-3.422.652c-.067.037-.067.037-.12.021a.633.633 0 01-.523-.152.791.791 0 01-.38-.45l.03-.1a.2.2 0 01-.007-.172l.046-.157a1.013 1.013 0 01.7-.648zm.128-5.522a1.013 1.013 0 00-.7.649l-.046.157a.411.411 0 00-.008.225l-.015.052a.864.864 0 00.365.5.666.666 0 00.538.1l.052.015 3.438-.705a.983.983 0 00.736-.581l.046-.157c.03-.1-.007-.172.009-.224l-.037-.067a.624.624 0 00-.312-.488.787.787 0 00-.59-.114l-.053-.015-3.422.652zm-.063 2.761a1.07 1.07 0 00-.751.633l-.046.157a.2.2 0 01.006.172l-.015.052.038.068a1.473 1.473 0 00.313.487.773.773 0 00.591.114l.052.015 3.49-.689a.921.921 0 00.683-.6l.061-.209a.2.2 0 00-.007-.172l.015-.052a.727.727 0 00-.312-.488 1.122 1.122 0 00-.576-.167c-.067.037-.067.037-.119.022l-3.422.652" fill="#2e2a2b"/></svg>',
37
+ mp3: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M17.229 4a.9.9 0 00-.569.232l-7.6 6.32a1.158 1.158 0 01-.955.328H3.208A1.2 1.2 0 002 12.088v7.826a1.2 1.2 0 001.208 1.206H8.1a1.158 1.158 0 01.955.328l7.6 6.32c.521.433 1.081.224 1.081-.289V4.522A.494.494 0 0017.229 4zM27 6.3l-1.791 1.793a14.708 14.708 0 010 15.844l1.785 1.776A17.19 17.19 0 0027 6.3zm-4.333 4.323L20.905 12.4a6.035 6.035 0 010 7.237l1.756 1.756a8.554 8.554 0 00.01-10.769z" fill="#00007f"/></svg>',
38
+ mp4: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M4.5 2.375A2.562 2.562 0 015.861 2h20.366a2.545 2.545 0 012.423 1.951 3.37 3.37 0 01.072.862v11.176h-1.573a1.814 1.814 0 00-.22.022 5.236 5.236 0 00-.581-.011c-.3.007-.61-.014-.914.014a2.275 2.275 0 00-.4-.02h-4.739c-.2 0-.392.008-.587-.01l.1-.065-6.353-3.813v3.889c-2.213-.005-4.427 0-6.64 0a2.274 2.274 0 00-.251.021c-.212-.032-.427-.016-.642-.016-.284.006-.57-.015-.853.015a2.052 2.052 0 00-.253-.022H3.275c.006-3.635 0-7.27 0-10.9a4.786 4.786 0 01.071-1.131A2.541 2.541 0 014.5 2.375zm.54 2.188a.639.639 0 00-.489.606v1.316a.639.639 0 00.627.6h1.309a.638.638 0 00.6-.608c.005-.426 0-.853 0-1.279a.644.644 0 00-.329-.575.708.708 0 00-.358-.078H5.264a1.081 1.081 0 00-.224.018zm20.341 0a.639.639 0 00-.474.607v1.306a.638.638 0 00.6.608c.436.005.872 0 1.308 0a.639.639 0 00.627-.606c.006-.438 0-.876 0-1.314a.638.638 0 00-.594-.621c-.348-.009-.7 0-1.045 0a1.98 1.98 0 00-.422.024zM5.042 8.38a.637.637 0 00-.452.4 1.078 1.078 0 00-.041.386v1.135a.637.637 0 00.6.6c.4.008.795 0 1.192 0a.826.826 0 00.395-.065.641.641 0 00.36-.574V8.983a.638.638 0 00-.6-.624c-.338-.008-.677 0-1.016 0a2.385 2.385 0 00-.438.021zm20.338 0a.637.637 0 00-.433.4 1.072 1.072 0 00-.041.387v1.131a.638.638 0 00.608.607c.406.006.812 0 1.218 0a.739.739 0 00.38-.078.64.64 0 00.335-.558V8.985a.637.637 0 00-.593-.622c-.349-.009-.7 0-1.047 0a1.928 1.928 0 00-.428.022zM5.041 12.2a.639.639 0 00-.491.608c0 .438-.005.877 0 1.315a.638.638 0 00.627.6h1.3a.638.638 0 00.608-.607v-1.307a.638.638 0 00-.605-.626c-.348-.007-.7 0-1.045 0a2.12 2.12 0 00-.394.017zm20.335.006a.635.635 0 00-.43.394 1.06 1.06 0 00-.041.386v1.131a.638.638 0 00.607.608c.435.005.87 0 1.306 0a.639.639 0 00.628-.605c.006-.438 0-.876 0-1.313a.637.637 0 00-.592-.622c-.349-.01-.7 0-1.046 0a1.908 1.908 0 00-.431.015z" fill="#e75749"/><path d="M13.458 12.1q3.176 1.908 6.353 3.813l-.1.065q-3.127 1.872-6.251 3.748V15.99c-.001-1.295-.004-2.59-.002-3.89z" fill="#fff"/><path d="M3.275 15.988h1.541a2.052 2.052 0 01.253.022.645.645 0 00-.409.273.883.883 0 00-.111.518v1.045a.686.686 0 00.685.689h1.192a.68.68 0 00.657-.569c.008-.447 0-.9 0-1.343a.632.632 0 00-.521-.613 2.274 2.274 0 01.251-.021h6.64v3.736q3.127-1.871 6.251-3.748c.2.018.391.007.587.01h4.741a2.275 2.275 0 01.4.02.637.637 0 00-.475.385.983.983 0 00-.045.407v1.014a.677.677 0 00.691.719h1.16a.684.684 0 00.686-.658v-.984a1.074 1.074 0 00-.1-.589.642.642 0 00-.42-.292 1.814 1.814 0 01.22-.022h1.573c.011 1.721 0 3.443 0 5.165v6.293a2.567 2.567 0 01-.612 1.651 2.539 2.539 0 01-1.563.868 7.534 7.534 0 01-.981.033H6.724a9.27 9.27 0 01-1.368-.048 2.557 2.557 0 01-2-1.846 2.825 2.825 0 01-.09-.746V16.891c.007-.3-.002-.602.009-.903zm1.795 3.843a.613.613 0 00-.386.234.761.761 0 00-.134.464v1.162a.685.685 0 00.686.658h1.283a.687.687 0 00.568-.716v-1.191a.617.617 0 00-.2-.458.712.712 0 00-.487-.17H5.264a1.039 1.039 0 00-.194.017zm20.366 0a.62.62 0 00-.522.58v1.222a.676.676 0 00.69.718c.428 0 .857.005 1.285 0a.7.7 0 00.562-.684v-1.013a.9.9 0 00-.123-.568.661.661 0 00-.532-.267h-.954a2.246 2.246 0 00-.406.011zM5.071 23.648a.609.609 0 00-.4.249.766.766 0 00-.124.448v1.132a.7.7 0 00.6.688h1.376a.687.687 0 00.567-.717v-1.189a.617.617 0 00-.2-.459.71.71 0 00-.484-.17H5.265a1.028 1.028 0 00-.194.018zm20.362 0a.616.616 0 00-.492.427.99.99 0 00-.029.33V25.6a.681.681 0 00.656.567h1.193a.689.689 0 00.686-.719v-1.164a.657.657 0 00-.286-.545 1.461 1.461 0 00-.787-.11c-.312.01-.629-.02-.94.018z" fill="#c0392b"/></svg>',
39
+ exe: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M20.929 2h-16.4v28h23.3V9zm5.114 26.35H6.409V3.65h13.406l6.333 6.333V28.35zM11.477 15.393c1.584 0 2.563-1.463 2.563-3.663 0-2.145-.8-3.443-2.4-3.443S9.068 9.75 9.068 11.95c0 2.15.803 3.443 2.409 3.443zm-1.243-3.663c0-1.562.429-2.453 1.32-2.453.649 0 1.045.55 1.221 1.474l-2.53 1.309a3.2 3.2 0 01-.011-.33zm1.331 2.67c-.638 0-1.045-.528-1.221-1.43l2.53-1.309v.286c0 1.565-.418 2.453-1.309 2.453zm10.27.847l.1-1.023h-1.65V8.21l-1.177.1v.8l-1.694.176.022.891 1.672-.044v4.092h-1.849v1.025zm-7.85 9.5l.1-1.023h-1.65V17.71l-1.177.1v.8l-1.694.176.022.891 1.672-.044v4.092H9.409v1.025zm5.442.143c1.584 0 2.563-1.463 2.563-3.663 0-2.145-.8-3.443-2.4-3.443s-2.574 1.463-2.574 3.663c.002 2.148.805 3.446 2.411 3.446zm-1.243-3.66c0-1.562.429-2.453 1.32-2.453.649 0 1.045.55 1.221 1.474l-2.53 1.309a3.2 3.2 0 01-.011-.33zm1.331 2.67c-.638 0-1.045-.528-1.221-1.43l2.53-1.309v.286c0 1.565-.418 2.453-1.309 2.453z" fill="#9f4246"/></svg>',
40
+ txt: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M22.038 2H6.375a1.755 1.755 0 00-1.75 1.75v24.5A1.755 1.755 0 006.375 30h19.25a1.755 1.755 0 001.75-1.75V6.856zm.525 2.844l1.663 1.531h-1.663zM6.375 28.25V3.75h14.438v4.375h4.813V28.25z" fill="#c2c2c2"/><path fill="#829ec2" d="M8.125 15.097h13.076v1.75H8.125zM8.125 24.439h9.762v1.75H8.125zM8.125 19.763h15.75v1.75H8.125zM8.125 10.23h15.75v1.75H8.125z"/></svg>',
41
+ svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M7.674 14.488a2.218 2.218 0 100 3.137h16.652a2.218 2.218 0 100-3.137z" fill="#ffb13b" stroke="#000" stroke-width="3.73"/><path d="M11.222 9.06A2.218 2.218 0 109 11.278l11.778 11.774A2.218 2.218 0 1023 20.834z" fill="#ffb13b" stroke="#000" stroke-width="3.73"/><path d="M17.568 7.73a2.218 2.218 0 10-3.137 0v16.652a2.218 2.218 0 103.137 0z" fill="#ffb13b" stroke="#000" stroke-width="3.73"/><path d="M23 11.278a2.218 2.218 0 10-2.222-2.218L9 20.834a2.218 2.218 0 102.218 2.218z" fill="#ffb13b" stroke="#000" stroke-width="3.73"/><path d="M7.674 14.488a2.218 2.218 0 100 3.137h16.652a2.218 2.218 0 100-3.137z" fill="#ffb13b"/><path d="M11.222 9.06A2.218 2.218 0 109 11.278l11.778 11.774A2.218 2.218 0 1023 20.834z" fill="#ffb13b"/><path d="M17.568 7.73a2.218 2.218 0 10-3.137 0v16.652a2.218 2.218 0 103.137 0z" fill="#ffb13b"/><path d="M23 11.278a2.218 2.218 0 10-2.222-2.218L9 20.834a2.218 2.218 0 102.218 2.218z" fill="#ffb13b"/><path d="M2 16.056h28v9.894a4.035 4.035 0 01-4.106 4.106H6.106A4.035 4.035 0 012 25.95z"/><path d="M6.2 23.045a3.628 3.628 0 116.2-2.565h-2.13a1.5 1.5 0 10-2.57 1.061 1.6 1.6 0 001.062.441 4.118 4.118 0 012.566 1.063 3.628 3.628 0 11-6.194 2.565h2.13a1.5 1.5 0 102.566-1.06 1.948 1.948 0 00-1.063-.44A4.465 4.465 0 016.2 23.045zM19.651 16.852L17.085 29.24H14.96L12.4 16.852h2.12l1.5 7.255 1.5-7.255zM23.28 21.983h3.628v3.628a3.628 3.628 0 11-7.257 0V20.48a3.628 3.628 0 017.257 0h-2.125a1.5 1.5 0 10-3.005 0v5.13a1.5 1.5 0 003.005 0v-1.5h-1.5v-2.127z" fill="#fff"/></svg>',
42
+ ai: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M24.037 2.072l5.564 5.8v22.056H8.814V30H29.67V7.945l-5.633-5.873" fill="#909090"/><path d="M23.965 2H8.742v27.928H29.6V7.873L23.965 2" fill="#231612"/><path d="M23.893 2.072v5.874h5.633l-5.633-5.874" fill="#4c4442"/><path d="M23.965 2v5.873H29.6L23.965 2z" fill="#f36617"/><path d="M2.384 10.264h6.359V3.432H2.384v6.832z" fill="#909090"/><path d="M8.743 10.264h13.718V3.432H8.743v6.832z" fill="#4c4442"/><path d="M22.407 10.211H2.33V3.379h20.077v6.832" fill="#f36617"/><path d="M18.1 20.619c-.275-1.07-.948-3.226-1.223-4.344h-.014c-.206 1.054-.769 2.859-1.181 4.344H18.1zm-2.775 1.566l-.838 2.779c-.014.1-.055.128-.137.128h-1.4c-.1 0-.124-.048-.1-.16a858.912 858.912 0 012.871-9.279 3.686 3.686 0 00.11-.878.086.086 0 01.082-.1h1.9c.069 0 .082.016.11.08 1.016 3.274 2.129 6.884 3.173 10.19q.041.144-.082.144h-1.542c-.069 0-.1-.032-.124-.1l-.879-2.811h-3.146M22.29 17.547c0-.1.027-.128.094-.128h1.431c.081 0 .108.016.108.128v7.506c0 .08-.027.128-.108.128h-1.4c-.081 0-.121-.032-.121-.144v-7.49zm-.09-2.173a.918.918 0 01.918-.99.884.884 0 01.891.99.908.908 0 11-1.809 0" fill="#f46c25"/><path d="M11.238 5.279h-.013L10.9 7.352h.652zM9.5 9.3l1.06-4.86h1.355l1.033 4.86H11.81l-.15-1.133h-.882L10.634 9.3H9.5M13.438 9.3V4.44h1.086V9.3h-1.086" fill="#231612"/></svg>',
43
+ eps: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32"><defs><linearGradient id="b" x1="-403.546" y1="-337.031" x2="-403.376" y2="-337.031" gradientTransform="scale(180.004 -180.004) rotate(57.433 -509.183 199.746)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#e6e6e6"/></linearGradient><linearGradient id="a" x1="-403.546" y1="-337.033" x2="-403.376" y2="-337.033" gradientTransform="scale(180.004 -180.004) rotate(57.433 -509.183 199.746)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#949494"/><stop offset="1" stop-color="#8c8c8c"/></linearGradient><linearGradient id="c" x1="-403.546" y1="-336.987" x2="-403.376" y2="-336.987" xlink:href="#a"/><linearGradient id="d" x1="-405.673" y1="-336.64" x2="-405.503" y2="-336.64" gradientTransform="scale(-78.102 78.102) rotate(-45.304 200.718 -653.812)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#b3b3b3"/><stop offset="1" stop-color="#f2f2f2"/></linearGradient></defs><path fill="#949494" d="M24.037 2.072h-.003l5.564 5.801v22.055H8.814V30H29.67V7.945l-5.633-5.873"/><path d="M23.893 7.945V2.072l5.633 5.873h-5.633M23.965 2H8.742v1.432h13.719v6.832H8.742v19.664H29.6V7.873l-5.564-5.8L23.965 2" fill="url(#b)"/><path fill="url(#a)" d="M23.893 2.072v5.873h5.633l-5.633-5.873"/><path fill="#fff" d="M23.965 2v5.873h5.633L23.965 2z"/><path fill="#949494" d="M8.742 3.432H2.384v6.832h6.358V3.432"/><path fill="url(#c)" d="M22.461 3.432H8.742v6.832h13.719V3.432"/><path fill="#030100" d="M2.33 3.378h20.077v6.832H2.33z"/><path fill="#fe7814" d="M10.003 7.309H8.779v.834h1.371v.995H7.863V4.605h2.216v.989h-1.3v.733h1.224v.982zM11.163 4.666a5.451 5.451 0 011.129-.094 1.432 1.432 0 011.078.356 1.557 1.557 0 01.39 1.1 1.767 1.767 0 01-.329 1.116 1.422 1.422 0 01-1.139.471 1.893 1.893 0 01-.223-.014v1.54h-.906zm.906 2a1.463 1.463 0 00.207.014.564.564 0 00.582-.632.5.5 0 00-.516-.565 1.06 1.06 0 00-.273.027zM14.777 7.928a1.676 1.676 0 00.886.283c.314 0 .466-.141.466-.37s-.152-.35-.536-.525a1.448 1.448 0 01-.957-1.365A1.321 1.321 0 0116 4.531a1.748 1.748 0 01.926.235l-.192.968a1.431 1.431 0 00-.744-.215c-.278 0-.43.135-.43.336 0 .229.182.323.612.538a1.4 1.4 0 01.891 1.365 1.357 1.357 0 01-1.458 1.453 1.924 1.924 0 01-1-.283z"/><path d="M12.608 17.582s5.392-4.282 9.559-.15.18 9.739.18 9.739z" fill="url(#d)"/><path d="M22.42 27.223l-.147-.1c.039-.055 3.892-5.59-.17-9.623s-9.387.114-9.44.156l-.112-.141c.055-.043 5.5-4.287 9.678-.143s.231 9.795.191 9.851z" fill="#666"/><path fill="#999" d="M17.863 13.255l.127-.127 8.406 8.375-.127.127z"/><path fill="#fff" d="M21.792 17.058h.749v.749h-.749z"/><path d="M22.692 17.958h-1.051v-1.051h1.051zm-.749-.3h.447v-.447h-.447z" fill="gray"/><path fill="#fff" d="M12.233 17.208h.749v.749h-.749z"/><path d="M13.133 18.108h-1.051v-1.051h1.051zm-.749-.3h.447v-.447h-.447z" fill="gray"/><path fill="#fff" d="M21.972 26.797h.749v.749h-.749z"/><path d="M22.872 27.7h-1.051v-1.054h1.051zm-.749-.3h.447v-.447h-.447z" fill="gray"/><path fill="#999" d="M17.552 12.818h.749v.749h-.749zM25.958 21.193h.749v.749h-.749z"/></svg>',
44
+ webp: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32"><defs><linearGradient id="a" x1="596.629" y1="-820.523" x2="599.481" y2="-826.534" gradientTransform="matrix(.366 0 0 -.366 -210.44 -292.295)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#8ae234"/><stop offset="1" stop-color="#4e9a06"/></linearGradient><linearGradient id="c" x1="599.996" y1="-815.078" x2="631.107" y2="-868.963" xlink:href="#a"/><linearGradient id="d" x1="648.158" y1="-1013.946" x2="677.021" y2="-1071.027" gradientTransform="matrix(.347 0 0 -.339 -214.765 -336.913)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff" stop-opacity=".549"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><radialGradient id="e" cx="572.646" cy="-769.85" r="14.375" gradientTransform="matrix(.358 0 0 -.358 -181.98 -268.597)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".5" stop-color="#fff520" stop-opacity=".891"/><stop offset="1" stop-color="#fff300" stop-opacity="0"/></radialGradient><filter id="b"><feGaussianBlur stdDeviation="1.275"/></filter></defs><g filter="url(#b)"><path d="M4.646 8h22.707a1.976 1.976 0 011.981 1.971V25.96a1.977 1.977 0 01-1.972 1.981H4.646a1.976 1.976 0 01-1.98-1.972V9.978A1.976 1.976 0 014.637 8z" fill-rule="evenodd"/><path d="M4.646 8h22.707a1.976 1.976 0 011.981 1.971V25.96a1.977 1.977 0 01-1.972 1.981H4.646a1.976 1.976 0 01-1.98-1.972V9.978A1.976 1.976 0 014.637 8z" fill="none" stroke="#000" stroke-width="2.051"/></g><path d="M6.2 6.374h3.281v3.3H6.2z" stroke="#366a04" stroke-width="2.902" fill-rule="evenodd" fill="url(#a)"/><path d="M4.646 8h22.707a1.977 1.977 0 011.981 1.972v15.989a1.977 1.977 0 01-1.972 1.98H4.646a1.976 1.976 0 01-1.98-1.972V9.978A1.976 1.976 0 014.638 8h.008z" stroke="#366a04" stroke-width="3.605" fill-rule="evenodd" fill="url(#c)"/><path d="M20.877 17.969A4.878 4.878 0 1116 13.092a4.877 4.877 0 014.877 4.877z" fill="#fff" stroke="#366a04" stroke-width="3.605"/><path d="M5.185 8.7h21.54c1.406 0 1.879.59 1.879 1.835V25.34c0 1.245-.518 1.834-1.879 1.834H5.185c-1.407 0-1.879-.544-1.879-1.834V10.534c0-1.382.609-1.834 1.879-1.834z" fill="none" stroke-linejoin="round" stroke-width="3.38" stroke="url(#d)"/><circle cx="23.184" cy="7.22" r="5.15" fill="url(#e)"/></svg>',
45
+ pdf: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M24.1 2.072l5.564 5.8v22.056H8.879V30h20.856V7.945L24.1 2.072" fill="#909090"/><path d="M24.031 2H8.808v27.928h20.856V7.873L24.03 2" fill="#f4f4f4"/><path d="M8.655 3.5h-6.39v6.827h20.1V3.5H8.655" fill="#7a7b7c"/><path d="M22.472 10.211H2.395V3.379h20.077v6.832" fill="#dd2025"/><path d="M9.052 4.534H7.745v4.8h1.028V7.715L9 7.728a2.042 2.042 0 00.647-.117 1.427 1.427 0 00.493-.291 1.224 1.224 0 00.335-.454 2.13 2.13 0 00.105-.908 2.237 2.237 0 00-.114-.644 1.173 1.173 0 00-.687-.65 2.149 2.149 0 00-.409-.104 2.232 2.232 0 00-.319-.026m-.189 2.294h-.089v-1.48h.193a.57.57 0 01.459.181.92.92 0 01.183.558c0 .246 0 .469-.222.626a.942.942 0 01-.524.114M12.533 4.521c-.111 0-.219.008-.295.011L12 4.538h-.78v4.8h.918a2.677 2.677 0 001.028-.175 1.71 1.71 0 00.68-.491 1.939 1.939 0 00.373-.749 3.728 3.728 0 00.114-.949 4.416 4.416 0 00-.087-1.127 1.777 1.777 0 00-.4-.733 1.63 1.63 0 00-.535-.4 2.413 2.413 0 00-.549-.178 1.282 1.282 0 00-.228-.017m-.182 3.937h-.1V5.392h.013a1.062 1.062 0 01.6.107 1.2 1.2 0 01.324.4 1.3 1.3 0 01.142.526c.009.22 0 .4 0 .549a2.926 2.926 0 01-.033.513 1.756 1.756 0 01-.169.5 1.13 1.13 0 01-.363.36.673.673 0 01-.416.106M17.43 4.538H15v4.8h1.028V7.434h1.3v-.892h-1.3V5.43h1.4v-.892" fill="#464648"/><path d="M21.781 20.255s3.188-.578 3.188.511-1.975.646-3.188-.511zm-2.357.083a7.543 7.543 0 00-1.473.489l.4-.9c.4-.9.815-2.127.815-2.127a14.216 14.216 0 001.658 2.252 13.033 13.033 0 00-1.4.288zm-1.262-6.5c0-.949.307-1.208.546-1.208s.508.115.517.939a10.787 10.787 0 01-.517 2.434 4.426 4.426 0 01-.547-2.162zm-4.649 10.516c-.978-.585 2.051-2.386 2.6-2.444-.003.001-1.576 3.056-2.6 2.444zM25.9 20.895c-.01-.1-.1-1.207-2.07-1.16a14.228 14.228 0 00-2.453.173 12.542 12.542 0 01-2.012-2.655 11.76 11.76 0 00.623-3.1c-.029-1.2-.316-1.888-1.236-1.878s-1.054.815-.933 2.013a9.309 9.309 0 00.665 2.338s-.425 1.323-.987 2.639-.946 2.006-.946 2.006a9.622 9.622 0 00-2.725 1.4c-.824.767-1.159 1.356-.725 1.945.374.508 1.683.623 2.853-.91a22.549 22.549 0 001.7-2.492s1.784-.489 2.339-.623 1.226-.24 1.226-.24 1.629 1.639 3.2 1.581 1.495-.939 1.485-1.035" fill="#dd2025"/><path d="M23.954 2.077V7.95h5.633l-5.633-5.873z" fill="#909090"/><path d="M24.031 2v5.873h5.633L24.031 2z" fill="#f4f4f4"/><path d="M8.975 4.457H7.668v4.8H8.7V7.639l.228.013a2.042 2.042 0 00.647-.117 1.428 1.428 0 00.493-.291 1.224 1.224 0 00.332-.454 2.13 2.13 0 00.105-.908 2.237 2.237 0 00-.114-.644 1.173 1.173 0 00-.687-.65 2.149 2.149 0 00-.411-.105 2.232 2.232 0 00-.319-.026m-.189 2.294h-.089v-1.48h.194a.57.57 0 01.459.181.92.92 0 01.183.558c0 .246 0 .469-.222.626a.942.942 0 01-.524.114M12.456 4.444c-.111 0-.219.008-.295.011l-.235.006h-.78v4.8h.918a2.677 2.677 0 001.028-.175 1.71 1.71 0 00.68-.491 1.939 1.939 0 00.373-.749 3.728 3.728 0 00.114-.949 4.416 4.416 0 00-.087-1.127 1.777 1.777 0 00-.4-.733 1.63 1.63 0 00-.535-.4 2.413 2.413 0 00-.549-.178 1.282 1.282 0 00-.228-.017m-.182 3.937h-.1V5.315h.013a1.062 1.062 0 01.6.107 1.2 1.2 0 01.324.4 1.3 1.3 0 01.142.526c.009.22 0 .4 0 .549a2.926 2.926 0 01-.033.513 1.756 1.756 0 01-.169.5 1.13 1.13 0 01-.363.36.673.673 0 01-.416.106M17.353 4.461h-2.43v4.8h1.028V7.357h1.3v-.892h-1.3V5.353h1.4v-.892" fill="#fff"/></svg>',
46
+ psd: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#070444" d="M24.099 2H8.837v28h20.91V7.888l-5.579-5.816L24.099 2"/><path fill="#5bc3f6" d="M2.253 3.493H22.56v7.844H2.253zM24.099 2v5.888h5.648L24.099 2z"/><path d="M7.1 4.987a6 6 0 011.242-.1 1.576 1.576 0 011.187.392 1.714 1.714 0 01.429 1.207A1.946 1.946 0 019.6 7.712a1.565 1.565 0 01-1.254.518 2.084 2.084 0 01-.246-.015v1.7h-1zm1 2.206a1.61 1.61 0 00.228.015.621.621 0 00.641-.7.546.546 0 00-.569-.618 1.166 1.166 0 00-.3.03zM11.083 8.578a1.845 1.845 0 00.975.311c.345 0 .513-.156.513-.407S12.4 8.1 11.98 7.9a1.594 1.594 0 01-1.053-1.5 1.454 1.454 0 011.5-1.562 1.925 1.925 0 011.02.259l-.207 1.067a1.576 1.576 0 00-.819-.237c-.306 0-.474.148-.474.37 0 .252.2.355.674.592a1.543 1.543 0 01.981 1.5 1.494 1.494 0 01-1.6 1.6 2.117 2.117 0 01-1.1-.311zM15.62 8.98h-.1V5.755h.014a1.117 1.117 0 01.629.113 1.262 1.262 0 01.341.422 1.369 1.369 0 01.149.553c.01.231 0 .417 0 .578a3.079 3.079 0 01-.035.539 1.846 1.846 0 01-.178.529 1.187 1.187 0 01-.382.379.707.707 0 01-.437.111m.192-4.141c-.117 0-.23.009-.31.012l-.247.007h-.82v5.054h.964a2.815 2.815 0 001.082-.184 1.8 1.8 0 00.718-.517 2.04 2.04 0 00.392-.788 3.921 3.921 0 00.12-1 4.644 4.644 0 00-.092-1.186 1.868 1.868 0 00-.425-.771 1.712 1.712 0 00-.563-.422 2.537 2.537 0 00-.577-.188 1.349 1.349 0 00-.24-.018" fill="#070444"/><path d="M16 19.651a7.218 7.218 0 01-.9-.031v-3.49c.111-.016.5-.031 1.04-.031 1.3 0 1.873.546 1.873 1.791 0 1.556-.916 1.761-2.012 1.761m.139-5.031c-1.054 0-2.095.016-2.622.031-.069 0-.083.031-.083.109v9.93c0 .078.028.109.1.109H15c.069 0 .1-.031.1-.125V21.13h.86c2.039 0 3.718-.658 3.718-3.132-.014-1.805-.818-3.378-3.538-3.378M23.075 17.218a2.266 2.266 0 00-2.539 2.257c0 1.136.5 1.743 1.928 2.4 1 .451 1.249.685 1.249 1.089 0 .342-.222.7-.86.7a4.067 4.067 0 01-2.247-.841.056.056 0 00-.034-.012c-.033 0-.063.032-.063.09v1.432a.159.159 0 00.083.156 3.942 3.942 0 002.15.607 2.317 2.317 0 002.594-2.4c0-1.121-.61-1.7-2.039-2.35-1.04-.467-1.221-.669-1.221-1.043 0-.3.18-.654.86-.654a3.8 3.8 0 011.928.591.094.094 0 00.052.018c.043 0 .073-.043.073-.112v-1.274a.224.224 0 00-.083-.2 3.365 3.365 0 00-1.831-.451" fill="#5bc3f6"/></svg>',
47
+ html: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#e44f26" d="M5.902 27.201L3.655 2h24.69l-2.25 25.197L15.985 30 5.902 27.201z"/><path fill="#f1662a" d="M16 27.858l8.17-2.265 1.922-21.532H16v23.797z"/><path fill="#ebebeb" d="M16 13.407h-4.09l-.282-3.165H16V7.151H8.25l.074.83.759 8.517H16v-3.091zM16 21.434l-.014.004-3.442-.929-.22-2.465H9.221l.433 4.852 6.332 1.758.014-.004v-3.216z"/><path fill="#fff" d="M15.989 13.407v3.091h3.806l-.358 4.009-3.448.93v3.216l6.337-1.757.046-.522.726-8.137.076-.83H15.989zM15.989 7.151V10.242h7.466l.062-.694.141-1.567.074-.83h-7.743z"/></svg>',
48
+ css: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#1572b6" d="M5.902 27.201L3.656 2h24.688l-2.249 25.197L15.985 30 5.902 27.201z"/><path fill="#33a9dc" d="M16 27.858l8.17-2.265 1.922-21.532H16v23.797z"/><path fill="#fff" d="M16 13.191h4.09l.282-3.165H16V6.935h7.75l-.074.829-.759 8.518H16v-3.091z"/><path fill="#ebebeb" d="M16.019 21.218l-.014.004-3.442-.93-.22-2.465H9.24l.433 4.853 6.331 1.758.015-.004v-3.216z"/><path fill="#fff" d="M19.827 16.151l-.372 4.139-3.447.93v3.216l6.336-1.756.047-.522.537-6.007h-3.101z"/><path fill="#ebebeb" d="M16.011 6.935v3.091H8.545l-.062-.695-.141-1.567-.074-.829h7.743zM16 13.191v3.091H12.601l-.062-.695-.14-1.567-.074-.829H16z"/></svg>',
49
+ json: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32"><defs><linearGradient id="a" x1="-679.793" y1="-637.805" x2="-668.005" y2="-649.595" gradientTransform="matrix(.999 0 0 -.999 688.969 -626.71)" gradientUnits="userSpaceOnUse"><stop offset="0"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="b" x1="-667.471" y1="-649.062" x2="-679.26" y2="-637.272" xlink:href="#a"/></defs><path d="M3.015 14.891a2.72 2.72 0 001.7-.561 2.575 2.575 0 00.873-1.468 16.533 16.533 0 00.23-3.193q.01-2.259.082-2.976a5.672 5.672 0 01.453-1.826 3.277 3.277 0 01.818-1.1 3.3 3.3 0 011.245-.629A7.325 7.325 0 0110.09 3h.758v2.124h-.419a2.532 2.532 0 00-1.867.507A3.689 3.689 0 008.1 7.9a39.059 39.059 0 01-.149 4.478 5.129 5.129 0 01-.832 2.232A4.948 4.948 0 015.274 16a4.126 4.126 0 012.158 1.9 9.6 9.6 0 01.67 4.187q0 2.638.054 3.138a1.9 1.9 0 00.544 1.286 2.859 2.859 0 001.725.365h.419V29h-.754a6.126 6.126 0 01-1.921-.216 3.217 3.217 0 01-1.434-1.008A3.632 3.632 0 016 26.01a26.19 26.19 0 01-.183-3.5 17.842 17.842 0 00-.23-3.368 2.608 2.608 0 00-.873-1.475 2.7 2.7 0 00-1.7-.568zM28.985 17.1a2.7 2.7 0 00-1.7.568 2.608 2.608 0 00-.873 1.475 17.842 17.842 0 00-.23 3.368A26.19 26.19 0 0126 26.01a3.632 3.632 0 01-.737 1.765 3.217 3.217 0 01-1.434 1.008A6.126 6.126 0 0121.91 29h-.758v-2.124h.419a2.859 2.859 0 001.725-.365 1.9 1.9 0 00.548-1.285q.054-.5.054-3.138a9.6 9.6 0 01.67-4.187A4.126 4.126 0 0126.726 16a4.948 4.948 0 01-1.847-1.393 5.129 5.129 0 01-.832-2.232A39.059 39.059 0 0123.9 7.9a3.689 3.689 0 00-.46-2.266 2.532 2.532 0 00-1.867-.507h-.419V3h.758a7.325 7.325 0 011.677.135 3.3 3.3 0 011.245.629 3.277 3.277 0 01.818 1.1 5.672 5.672 0 01.448 1.829q.068.717.081 2.976a16.533 16.533 0 00.23 3.193 2.575 2.575 0 00.873 1.468 2.72 2.72 0 001.7.561z" fill="#f5de19"/><path d="M15.986 20.085c3.7 5.041 7.317-1.407 7.311-5.285-.006-4.585-4.653-7.147-7.314-7.147a8.352 8.352 0 000 16.7c-.832-.12-3.6-.714-3.642-7.1-.025-4.319 1.409-6.045 3.636-5.286a4.242 4.242 0 012.456 4.069 4.257 4.257 0 01-2.447 4.049z" fill="url(#a)"/><path d="M15.982 11.968c-2.443-.842-5.437 1.172-5.437 5.205 0 6.586 4.881 7.184 5.472 7.184a8.352 8.352 0 000-16.7c1.018-.141 5.489 1.1 5.489 7.212 0 3.984-3.338 6.153-5.509 5.227a4.242 4.242 0 01-2.456-4.069 4.28 4.28 0 012.441-4.059z" fill="url(#b)"/></svg>',
50
+ js: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#f5de19" d="M2 2h28v28H2z"/><path d="M20.809 23.875a2.866 2.866 0 002.6 1.6c1.09 0 1.787-.545 1.787-1.3 0-.9-.716-1.222-1.916-1.747l-.658-.282c-1.9-.809-3.16-1.822-3.16-3.964 0-1.973 1.5-3.476 3.853-3.476a3.889 3.889 0 013.742 2.107L25 18.128A1.789 1.789 0 0023.311 17a1.145 1.145 0 00-1.259 1.128c0 .789.489 1.109 1.618 1.6l.658.282c2.236.959 3.5 1.936 3.5 4.133 0 2.369-1.861 3.667-4.36 3.667a5.055 5.055 0 01-4.795-2.691zm-9.295.228c.413.733.789 1.353 1.693 1.353.864 0 1.41-.338 1.41-1.653v-8.947h2.631v8.982c0 2.724-1.6 3.964-3.929 3.964a4.085 4.085 0 01-3.947-2.4z"/></svg>',
51
+ md: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="none" stroke="#755838" d="M2.5 7.955h27v16.091h-27z"/><path fill="#755838" d="M5.909 20.636v-9.272h2.727l2.728 3.409 2.727-3.409h2.727v9.272h-2.727v-5.318l-2.727 3.409-2.728-3.409v5.318H5.909zM22.955 20.636l-4.091-4.5h2.727v-4.772h2.727v4.772h2.727l-4.09 4.5z"/></svg>',
52
+ tex: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M11.333 13.122c-.128-1.562-.241-2.756-2.287-2.756H7.91v8.4h2.145v.611l-3.083-.029-3.082.029v-.611h2.144v-8.4h-1.15c-2.046 0-2.159 1.208-2.287 2.756H2l.284-3.367h9.362l.284 3.367h-.6z" fill="#cfcfcf"/><path d="M19.289 22.53H10.41v-.61h1.506v-8.453H10.41v-.611h8.637l.412 3.367h-.6c-.213-1.833-.682-2.756-2.855-2.756h-2.213V17.2h.838c1.364 0 1.505-.6 1.505-1.662h.6v3.935h-.6c0-1.08-.142-1.662-1.505-1.662h-.838v4.106h2.216c2.472 0 3-1.108 3.3-3.225h.6z" fill="#cfcfcf"/><path d="M27.727 19.186c-.54 0-1.96 0-2.415.029V18.6h1.179l-2.557-3.552-2.529 3.381a4.1 4.1 0 001.295.171v.611c-.355-.029-1.576-.029-2.017-.029-.4 0-1.548 0-1.875.029V18.6h.383a7.459 7.459 0 00.824-.043c.5-.043.54-.085.667-.256l2.854-3.801-3.153-4.418H19V9.47c.384.028 1.79.028 2.273.028.582 0 1.918 0 2.429-.028v.611h-1.174l2.117 2.955 2.074-2.784a4.1 4.1 0 00-1.293-.17V9.47c.356.028 1.591.028 2.032.028.4 0 1.534 0 1.861-.028v.611h-.369a5.264 5.264 0 00-.838.043c-.469.043-.526.071-.667.256l-2.4 3.21 3.591 5.01H30v.611c-.355-.025-1.818-.025-2.273-.025z" fill="#cfcfcf"/></svg>',
53
+ xml: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M20.42 21.157l2.211 2.211L30 16l-7.369-7.369-2.211 2.212L25.58 16zM11.58 10.843L9.369 8.631 2 16l7.369 7.369 2.211-2.211L6.42 16zM17.411 7.677l1.6.437-4.42 16.209-1.6-.437 4.42-16.209z" fill="#f1662a"/></svg>',
54
+ default: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M20.414 2H5v28h22V8.586zM7 28V4h12v6h6v18z" fill="#c5c5c5"/></svg>'
55
+ };
56
+ function getFileIconContent(extension) {
57
+ switch (extension) {
58
+ case 'doc':
59
+ case 'docx':
60
+ return svgs.doc;
61
+ case 'xls':
62
+ case 'xlsx':
63
+ case 'ods':
64
+ return svgs.xls;
65
+ case 'ppt':
66
+ case 'pptx':
67
+ return svgs.ppt;
68
+ case 'png':
69
+ case 'jpg':
70
+ case 'jpeg':
71
+ case 'bmp':
72
+ case 'gif':
73
+ case 'ico':
74
+ return svgs.png;
75
+ case 'zip':
76
+ case 'rar':
77
+ case '7z':
78
+ case 'tar':
79
+ case 'gz':
80
+ case 'bz2':
81
+ case 'xz':
82
+ case 'tgz':
83
+ case 'zipx':
84
+ return svgs.zip;
85
+ case 'mp3':
86
+ case 'raw':
87
+ case 'wav':
88
+ case 'flac':
89
+ case 'aac':
90
+ case 'ogg':
91
+ case 'wma':
92
+ case 'm4a':
93
+ case 'opus':
94
+ return svgs.mp3;
95
+ case 'mp4':
96
+ case 'avi':
97
+ case 'mkv':
98
+ case 'mov':
99
+ case 'wmv':
100
+ case 'flv':
101
+ case 'webm':
102
+ case '3gp':
103
+ case 'm4v':
104
+ case 'vob':
105
+ case 'ogv':
106
+ return svgs.mp4;
107
+ case 'exe':
108
+ case 'dll':
109
+ return svgs.exe;
110
+ case 'txt':
111
+ case 'csv':
112
+ return svgs.txt;
113
+ case 'svg':
114
+ return svgs.svg;
115
+ case 'ai':
116
+ return svgs.ai;
117
+ case 'eps':
118
+ return svgs.eps;
119
+ case 'webp':
120
+ return svgs.webp;
121
+ case 'pdf':
122
+ return svgs.pdf;
123
+ case 'psd':
124
+ return svgs.psd;
125
+ case 'html':
126
+ return svgs.html;
127
+ case 'css':
128
+ return svgs.css;
129
+ case 'json':
130
+ return svgs.json;
131
+ case 'js':
132
+ return svgs.js;
133
+ case 'md':
134
+ return svgs.md;
135
+ case 'tex':
136
+ return svgs.tex;
137
+ case 'xml':
138
+ return svgs.xml;
139
+ default:
140
+ return svgs.default;
141
+ }
142
+ }
143
+ function getFileExtension(fileName) {
144
+ if (!fileName) {
145
+ return '';
146
+ }
147
+ const lastDotIndex = fileName.lastIndexOf('.');
148
+ if (lastDotIndex === -1 || lastDotIndex === fileName.length - 1) {
149
+ return '';
150
+ }
151
+ return fileName.substring(lastDotIndex + 1).toLowerCase();
152
+ }
153
+ function getContentTypeFromExtension(extension) {
154
+ const ext = extension.toLowerCase().replace('.', '');
155
+ const contentTypeMap = {
156
+ 'jpg': 'image/jpeg',
157
+ 'jpeg': 'image/jpeg',
158
+ 'png': 'image/png',
159
+ 'gif': 'image/gif',
160
+ 'bmp': 'image/bmp',
161
+ 'webp': 'image/webp',
162
+ 'svg': 'image/svg+xml',
163
+ 'pdf': 'application/pdf',
164
+ 'doc': 'application/msword',
165
+ 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
166
+ 'xls': 'application/vnd.ms-excel',
167
+ 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
168
+ 'ppt': 'application/vnd.ms-powerpoint',
169
+ 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
170
+ 'txt': 'text/plain',
171
+ 'csv': 'text/csv',
172
+ 'zip': 'application/zip',
173
+ 'rar': 'application/x-rar-compressed',
174
+ '7z': 'application/x-7z-compressed',
175
+ 'mp4': 'video/mp4',
176
+ 'webm': 'video/webm',
177
+ 'mov': 'video/quicktime',
178
+ 'mp3': 'audio/mpeg',
179
+ 'wav': 'audio/wav',
180
+ 'ogg': 'audio/ogg'
181
+ };
182
+ return contentTypeMap[ext] || 'application/octet-stream';
183
+ }
184
+ function getExtensionFromContentType(contentType) {
185
+ const type = contentType.toLowerCase().split(';')[0].trim(); // Handle content types with charset/parameters
186
+ const extensionMap = {
187
+ 'image/jpeg': 'jpg',
188
+ 'image/png': 'png',
189
+ 'image/gif': 'gif',
190
+ 'image/bmp': 'bmp',
191
+ 'image/webp': 'webp',
192
+ 'image/svg+xml': 'svg',
193
+ 'application/pdf': 'pdf',
194
+ 'application/msword': 'doc',
195
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',
196
+ 'application/vnd.ms-excel': 'xls',
197
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',
198
+ 'application/vnd.ms-powerpoint': 'ppt',
199
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'pptx',
200
+ 'text/plain': 'txt',
201
+ 'text/csv': 'csv',
202
+ 'application/zip': 'zip',
203
+ 'application/x-rar-compressed': 'rar',
204
+ 'application/x-7z-compressed': '7z',
205
+ 'video/mp4': 'mp4',
206
+ 'video/webm': 'webm',
207
+ 'video/quicktime': 'mov',
208
+ 'audio/mpeg': 'mp3',
209
+ 'audio/wav': 'wav',
210
+ 'audio/ogg': 'ogg',
211
+ 'application/octet-stream': 'bin'
212
+ };
213
+ return extensionMap[type] || 'bin';
214
+ }
215
+ function convertToBytes(value, unit) {
216
+ switch (unit) {
217
+ case 'KB':
218
+ return value * 1024;
219
+ case 'MB':
220
+ return value * 1024 * 1024;
221
+ case 'GB':
222
+ return value * 1024 * 1024 * 1024;
223
+ default:
224
+ return value;
225
+ }
226
+ }
227
+ function base64ToFile(base64, filename) {
228
+ const arr = base64.split(',');
229
+ const mime = arr[0].match(/:(.*?);/)?.[1] || 'image/png';
230
+ const bstr = atob(arr[1]); // decode base64
231
+ let n = bstr.length;
232
+ const u8arr = new Uint8Array(n);
233
+ while (n--) {
234
+ u8arr[n] = bstr.charCodeAt(n);
235
+ }
236
+ return new File([u8arr], filename, { type: mime });
237
+ }
238
+
239
+ class MinIOService {
240
+ constructor(http, baseUrl) {
241
+ this.http = http;
242
+ this.baseUrl = baseUrl;
243
+ }
244
+ uploadFileWithSignedUrl(file, onProgress) {
245
+ return this.computeFileChecksum(file).pipe(switchMap(checksum => {
246
+ return this.getUploadUrl(file.name, file.type, getFileExtension(file.name), file.size, checksum);
247
+ }), switchMap(response => {
248
+ if (response.isDuplicate) {
249
+ return of({
250
+ fileName: response.fileName,
251
+ fileKey: response.fileKey,
252
+ fileSize: response.fileSizeBytes,
253
+ fileExtension: response.fileExtension,
254
+ fileContentType: response.fileContentType,
255
+ reservationId: response.reservationId
256
+ });
257
+ }
258
+ return this.uploadToSignedUrl(file, response.uploadUrl, onProgress).pipe(switchMap(() => {
259
+ return this.confirmUpload(response.fileKey, response.reservationId).pipe(map(() => ({
260
+ fileName: response.fileName,
261
+ fileKey: response.fileKey,
262
+ fileSize: response.fileSizeBytes,
263
+ fileExtension: response.fileExtension,
264
+ fileContentType: response.fileContentType
265
+ })));
266
+ }));
267
+ }));
268
+ }
269
+ getUploadUrl(fileName, contentType, extension, fileSizeBytes, checksumSha256) {
270
+ return this.http.get(this.baseUrl + 'api/Files/GetUploadUrl', {
271
+ params: {
272
+ fileName,
273
+ contentType,
274
+ extension,
275
+ fileSizeBytes: fileSizeBytes.toString(),
276
+ ...(checksumSha256 ? { checksumSha256 } : {})
277
+ }
278
+ });
279
+ }
280
+ computeFileChecksum(file) {
281
+ return new Observable(observer => {
282
+ const reader = new FileReader();
283
+ reader.onload = () => {
284
+ const arrayBuffer = reader.result;
285
+ crypto.subtle.digest('SHA-256', arrayBuffer).then(hashBuffer => {
286
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
287
+ const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
288
+ observer.next(hashHex);
289
+ observer.complete();
290
+ }).catch(error => {
291
+ observer.error(error);
292
+ });
293
+ };
294
+ reader.onerror = () => {
295
+ observer.error(new Error('Failed to read file for checksum computation'));
296
+ };
297
+ reader.readAsArrayBuffer(file);
298
+ });
299
+ }
300
+ uploadToSignedUrl(file, signedUrl, onProgress) {
301
+ return new Observable(observer => {
302
+ const xhr = new XMLHttpRequest();
303
+ xhr.upload.addEventListener('progress', (event) => {
304
+ if (event.lengthComputable && onProgress) {
305
+ onProgress({
306
+ loaded: event.loaded,
307
+ total: event.total,
308
+ percentage: Math.round((event.loaded / event.total) * 100)
309
+ });
310
+ }
311
+ });
312
+ xhr.addEventListener('load', () => {
313
+ if (xhr.status >= 200 && xhr.status < 300) {
314
+ observer.next();
315
+ observer.complete();
316
+ }
317
+ else {
318
+ console.error('MinIO PUT error:', xhr.status, xhr.responseText);
319
+ observer.error(new Error(`Upload failed with status ${xhr.status}`));
320
+ }
321
+ });
322
+ xhr.addEventListener('error', () => {
323
+ observer.error(new Error('Upload failed'));
324
+ });
325
+ xhr.open('PUT', signedUrl);
326
+ xhr.send(file);
327
+ });
328
+ }
329
+ confirmUpload(fileKey, reservationId) {
330
+ return this.http.post(this.baseUrl + 'api/Files/ConfirmUpload', { fileKey, reservationId });
331
+ }
332
+ download(fileKey) {
333
+ return this.http.get(this.baseUrl + 'api/Files/GetDownloadUrl', { params: { fileKey } })
334
+ .pipe(switchMap(response => {
335
+ return this.http.get(response.downloadUrl, {
336
+ observe: 'response',
337
+ responseType: 'blob'
338
+ });
339
+ }));
340
+ }
341
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinIOService, deps: [{ token: i1.HttpClient }, { token: 'BASE_URL' }], target: i0.ɵɵFactoryTarget.Injectable }); }
342
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinIOService, providedIn: 'root' }); }
343
+ }
344
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinIOService, decorators: [{
345
+ type: Injectable,
346
+ args: [{
347
+ providedIn: 'root'
348
+ }]
349
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
350
+ type: Inject,
351
+ args: ['BASE_URL']
352
+ }] }] });
353
+
354
+ class MinioFileUploadComponent {
355
+ registerOnChange(fn) {
356
+ this.onChange = fn;
357
+ }
358
+ registerOnTouched(fn) {
359
+ this.onTouched = fn;
360
+ }
361
+ registerOnValidatorChange(fn) {
362
+ this.onValidatorChange = fn;
363
+ }
364
+ constructor(service, toastsService, translateService) {
365
+ this.service = service;
366
+ this.toastsService = toastsService;
367
+ this.translateService = translateService;
368
+ this.maxSize = 10;
369
+ this.sizeUnit = 'MB';
370
+ this.accept = ['image/jpeg', 'image/jpg', 'image/png', 'application/pdf'];
371
+ this.multiple = false;
372
+ this.buttonOnly = false;
373
+ this.required = false;
374
+ this.readOnly = false;
375
+ this.disabled = false;
376
+ this.acceptExtension = '';
377
+ this.maxBytes = 0;
378
+ this.files = [];
379
+ this.tempFiles = [];
380
+ this.onChange = (_) => { };
381
+ this.onTouched = () => { };
382
+ this.onValidatorChange = () => { };
383
+ }
384
+ ngOnInit() {
385
+ this.maxBytes = convertToBytes(this.maxSize, this.sizeUnit);
386
+ this.acceptExtension = this.accept.map(x => getExtensionFromContentType(x).toUpperCase()).join(', ');
387
+ if (!this.multiple) {
388
+ this.limit = 1;
389
+ }
390
+ }
391
+ validate(control) {
392
+ return null;
393
+ }
394
+ writeValue(value) {
395
+ if (value && value.length) {
396
+ value.forEach(file => file.downloadState = new ObservableState());
397
+ this.files = value;
398
+ }
399
+ else
400
+ this.files = [];
401
+ }
402
+ onUploadClick() {
403
+ if (this.disabled)
404
+ return;
405
+ this.fileInput.nativeElement.click();
406
+ this.onTouched();
407
+ }
408
+ onFileDropped(event) {
409
+ if (this.disabled)
410
+ return;
411
+ this.onTouched();
412
+ event.preventDefault();
413
+ const files = event.dataTransfer?.files;
414
+ if (files && files.length) {
415
+ this.handleFile(files);
416
+ }
417
+ }
418
+ allowDrop(event) {
419
+ event.preventDefault();
420
+ }
421
+ onFileSelected(event) {
422
+ if (this.disabled)
423
+ return;
424
+ const files = this.fileInput.nativeElement.files;
425
+ if (files && files.length) {
426
+ this.handleFile(files);
427
+ }
428
+ this.fileInput.nativeElement.value = '';
429
+ }
430
+ handleFile(selectedFiles) {
431
+ if (this.multiple) {
432
+ if ((this.tempFiles.length + this.files.length + selectedFiles.length) > this.limit) {
433
+ this.toastsService.showErrorToast(this.translateService.instant('MinioLabels.MaxFilesAllowedError', { limit: this.limit }));
434
+ return;
435
+ }
436
+ }
437
+ else {
438
+ if ((this.tempFiles.length + this.files.length + selectedFiles.length) > 1) {
439
+ this.toastsService.showErrorToast(this.translateService.instant('MinioLabels.MaxFilesAllowedError', { limit: this.limit }));
440
+ return;
441
+ }
442
+ }
443
+ for (let selectedFile of selectedFiles) {
444
+ if (!this.accept.includes(selectedFile.type)) {
445
+ this.toastsService.showErrorToast(this.translateService.instant('MinioLabels.ExtensionError', { fileName: selectedFile.name, allowed: this.acceptExtension }));
446
+ continue;
447
+ }
448
+ if (selectedFile.size > this.maxBytes) {
449
+ this.toastsService.showErrorToast(this.translateService.instant('MinioLabels.MaxSizeError', { fileName: selectedFile.name, max: `${this.maxSize}${this.sizeUnit}` }));
450
+ continue;
451
+ }
452
+ if (this.tempFiles.some(tempFile => tempFile.file.size === selectedFile.size && tempFile.file.name === selectedFile.name) ||
453
+ this.files.some(file => file.fileSize === selectedFile.size && file.fileName === selectedFile.name)) {
454
+ this.toastsService.showErrorToast(this.translateService.instant('MinioLabels.DuplicateFile', { fileName: selectedFile.name }));
455
+ continue;
456
+ }
457
+ this.tempFiles.push({
458
+ file: selectedFile,
459
+ progress: 0,
460
+ isUploading: false
461
+ });
462
+ }
463
+ this.tempFiles
464
+ .filter(tempFile => !tempFile.isUploading)
465
+ .forEach(tempFile => this.uploadToMinIO(tempFile));
466
+ }
467
+ uploadToMinIO(tempFile) {
468
+ tempFile.isUploading = true;
469
+ this.service.uploadFileWithSignedUrl(tempFile.file, progress => tempFile.progress = progress.percentage)
470
+ .subscribe({
471
+ next: result => {
472
+ result.downloadState = new ObservableState();
473
+ this.files.push(result);
474
+ this.removeFromTempFiles(tempFile);
475
+ this.onChange(this.files);
476
+ this.onValidatorChange();
477
+ },
478
+ error: () => {
479
+ this.removeFromTempFiles(tempFile);
480
+ }
481
+ });
482
+ }
483
+ removeFromTempFiles(file) {
484
+ const index = this.tempFiles.findIndex(tempFile => tempFile === file);
485
+ if (index > -1) {
486
+ this.tempFiles.splice(index, 1);
487
+ }
488
+ }
489
+ onRemoveFileClick(index) {
490
+ this.files.splice(index, 1);
491
+ this.onChange(this.files);
492
+ this.onValidatorChange();
493
+ }
494
+ getTempFileIcon(tempFile) {
495
+ return getFileIcon(getFileExtension(tempFile.file?.name));
496
+ }
497
+ getFileIcon(extension) {
498
+ return getFileIcon(extension);
499
+ }
500
+ getSize(size) {
501
+ return getFileSize(size);
502
+ }
503
+ onDownloadFile(file) {
504
+ if (!file.fileKey)
505
+ return;
506
+ file.downloadState.Wait();
507
+ this.service.download(file.fileKey)
508
+ .pipe(recordState(file.downloadState))
509
+ .subscribe({
510
+ next: response => {
511
+ saveAs(response.body, `${file.fileName}`);
512
+ }
513
+ });
514
+ }
515
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinioFileUploadComponent, deps: [{ token: MinIOService }, { token: i2.ToastsService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
516
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.2", type: MinioFileUploadComponent, isStandalone: false, selector: "minio-file-upload", inputs: { maxSize: "maxSize", sizeUnit: "sizeUnit", accept: "accept", multiple: "multiple", limit: "limit", buttonOnly: "buttonOnly", required: ["required", "required", booleanAttribute], readOnly: ["readOnly", "readOnly", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute] }, providers: [
517
+ {
518
+ provide: NG_VALUE_ACCESSOR,
519
+ useExisting: forwardRef(() => MinioFileUploadComponent),
520
+ multi: true,
521
+ },
522
+ {
523
+ provide: NG_VALIDATORS,
524
+ useExisting: forwardRef(() => MinioFileUploadComponent),
525
+ multi: true,
526
+ }
527
+ ], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<input type=\"file\"\r\n hidden\r\n [multiple]=\"multiple\"\r\n (change)=\"onFileSelected($event)\"\r\n [accept]=\"accept.join(',')\"\r\n #fileInput />\r\n\r\n@if(buttonOnly){\r\n<button class=\"btn btn-text p-0 text-primary\"\r\n [disabled]=\"tempFiles.length || disabled || readOnly\"\r\n (click)=\"onUploadClick()\">\r\n @if(tempFiles.length){\r\n <span class=\"spinner-grow spinner-grow-sm\"></span>\r\n }\r\n @else {\r\n <span [innerText]=\"'MinioLabels.UploadFile' | translate\"></span>\r\n }\r\n</button>\r\n}\r\n@else{\r\n\r\n@if(!readOnly){\r\n<div class=\"border radius-8 px-6px py-12px\"\r\n [ngClass]=\"disabled ? 'opacity-50 cursor-default' : 'cursor-pointer'\"\r\n (drop)=\"onFileDropped($event)\"\r\n (dragover)=\"allowDrop($event)\"\r\n (click)=\"onUploadClick()\">\r\n <div class=\"flex-center\">\r\n <div class=\"flex-center\">\r\n <div class=\"flex-center bg-gray-100 border radius-8 wh-40 me-8px\">\r\n <i class=\"fs-20 text-gray-400 ri-file-line\"></i>\r\n </div>\r\n <div class=\"flex-center flex-column\">\r\n <div>\r\n <span class=\"font-regular text-primary me-1\"\r\n [innerText]=\"'MinioLabels.Click' | translate\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"'MinioLabels.Drag' | translate\"></span>\r\n </div>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"'MinioLabels.FileRules' | translate: {acceptExtension: acceptExtension, maxSize: maxSize, sizeUnit: sizeUnit}\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n}\r\n\r\n@for (tempFile of tempFiles; track $index) {\r\n<div class=\"d-flex flex-column justify-content-start align-items-start border radius-8 bg-white p-8px mt-8px\">\r\n <div class=\"d-flex align-items-center\">\r\n <div class=\"flex-center border border-gray-100 radius-8 wh-40\">\r\n <div class=\"flex-center border border-gray-200 radius-8 wh-34\">\r\n <div class=\"flex-center border border-gray-300 radius-8 wh-28\">\r\n <img [src]=\"getTempFileIcon(tempFile)\"\r\n height=\"20\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex flex-column ms-8px\">\r\n <span class=\"text-gray-800\"\r\n [innerText]=\"tempFile.file?.name\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"getSize(tempFile.file.size)\"></span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center ps-48px pe-16px w-100\">\r\n <div class=\"loading-wrapper bg-gray-200 radius-16 w-100\">\r\n <div class=\"loading bg-primary radius-16 h-100\"\r\n [style.width.%]=\"tempFile.progress\"></div>\r\n </div>\r\n <span class=\"ms-32px\"\r\n [innerText]=\"tempFile.progress + '%'\"></span>\r\n </div>\r\n</div>\r\n}\r\n\r\n@for (file of files; track $index; let index = $index) {\r\n<div class=\"d-flex justify-content-between align-items-start border radius-8 bg-white p-8px mt-8px\">\r\n <div class=\"d-flex align-items-center\">\r\n <div class=\"flex-center border border-gray-100 radius-8 wh-40\">\r\n <div class=\"flex-center border border-gray-200 radius-8 wh-34\">\r\n <div class=\"flex-center border border-gray-300 radius-8 wh-28\">\r\n <img [src]=\"getFileIcon(file.fileExtension)\"\r\n height=\"20\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex flex-column ms-8px\">\r\n <span class=\"text-gray-800\"\r\n [innerText]=\"file.fileName\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"getSize(file.fileSize)\"></span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center\">\r\n <button class=\"btn btn-text text-gray-500 py-0 px-2\"\r\n [disabled]=\"file.downloadState.IsWait\"\r\n (click)=\"onDownloadFile(file)\">\r\n @if(file.downloadState.IsWait)\r\n {\r\n <span class=\"spinner-grow spinner-grow-sm\"></span>\r\n }\r\n @else {\r\n <i class=\"fs-18 ri-download-2-line\"></i>\r\n }\r\n </button>\r\n <button class=\"btn btn-text text-gray-500 py-0 px-2\"\r\n (click)=\"onRemoveFileClick(index)\">\r\n <i class=\"fs-18 ri-delete-bin-7-line\"></i>\r\n </button>\r\n </div>\r\n</div>\r\n}\r\n\r\n@if(!buttonOnly && readOnly && !files.length && !tempFiles.length){\r\n<div class=\"d-flex justify-content-center align-items-center border radius-8 bg-white mt-8px p-3\">\r\n <i class=\"fs-20 text-gray-400 ri-attachment-line me-3\"></i>\r\n <span class=\"font-semibold text-gray-400\"\r\n [innerText]=\"'MinioLabels.NoAttachment' | translate\"></span>\r\n</div>\r\n}\r\n}", styles: [".loading-wrapper{position:relative;height:8px}.loading{position:absolute;left:0}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] }); }
528
+ }
529
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinioFileUploadComponent, decorators: [{
530
+ type: Component,
531
+ args: [{ selector: 'minio-file-upload', providers: [
532
+ {
533
+ provide: NG_VALUE_ACCESSOR,
534
+ useExisting: forwardRef(() => MinioFileUploadComponent),
535
+ multi: true,
536
+ },
537
+ {
538
+ provide: NG_VALIDATORS,
539
+ useExisting: forwardRef(() => MinioFileUploadComponent),
540
+ multi: true,
541
+ }
542
+ ], standalone: false, template: "<input type=\"file\"\r\n hidden\r\n [multiple]=\"multiple\"\r\n (change)=\"onFileSelected($event)\"\r\n [accept]=\"accept.join(',')\"\r\n #fileInput />\r\n\r\n@if(buttonOnly){\r\n<button class=\"btn btn-text p-0 text-primary\"\r\n [disabled]=\"tempFiles.length || disabled || readOnly\"\r\n (click)=\"onUploadClick()\">\r\n @if(tempFiles.length){\r\n <span class=\"spinner-grow spinner-grow-sm\"></span>\r\n }\r\n @else {\r\n <span [innerText]=\"'MinioLabels.UploadFile' | translate\"></span>\r\n }\r\n</button>\r\n}\r\n@else{\r\n\r\n@if(!readOnly){\r\n<div class=\"border radius-8 px-6px py-12px\"\r\n [ngClass]=\"disabled ? 'opacity-50 cursor-default' : 'cursor-pointer'\"\r\n (drop)=\"onFileDropped($event)\"\r\n (dragover)=\"allowDrop($event)\"\r\n (click)=\"onUploadClick()\">\r\n <div class=\"flex-center\">\r\n <div class=\"flex-center\">\r\n <div class=\"flex-center bg-gray-100 border radius-8 wh-40 me-8px\">\r\n <i class=\"fs-20 text-gray-400 ri-file-line\"></i>\r\n </div>\r\n <div class=\"flex-center flex-column\">\r\n <div>\r\n <span class=\"font-regular text-primary me-1\"\r\n [innerText]=\"'MinioLabels.Click' | translate\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"'MinioLabels.Drag' | translate\"></span>\r\n </div>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"'MinioLabels.FileRules' | translate: {acceptExtension: acceptExtension, maxSize: maxSize, sizeUnit: sizeUnit}\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n}\r\n\r\n@for (tempFile of tempFiles; track $index) {\r\n<div class=\"d-flex flex-column justify-content-start align-items-start border radius-8 bg-white p-8px mt-8px\">\r\n <div class=\"d-flex align-items-center\">\r\n <div class=\"flex-center border border-gray-100 radius-8 wh-40\">\r\n <div class=\"flex-center border border-gray-200 radius-8 wh-34\">\r\n <div class=\"flex-center border border-gray-300 radius-8 wh-28\">\r\n <img [src]=\"getTempFileIcon(tempFile)\"\r\n height=\"20\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex flex-column ms-8px\">\r\n <span class=\"text-gray-800\"\r\n [innerText]=\"tempFile.file?.name\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"getSize(tempFile.file.size)\"></span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center ps-48px pe-16px w-100\">\r\n <div class=\"loading-wrapper bg-gray-200 radius-16 w-100\">\r\n <div class=\"loading bg-primary radius-16 h-100\"\r\n [style.width.%]=\"tempFile.progress\"></div>\r\n </div>\r\n <span class=\"ms-32px\"\r\n [innerText]=\"tempFile.progress + '%'\"></span>\r\n </div>\r\n</div>\r\n}\r\n\r\n@for (file of files; track $index; let index = $index) {\r\n<div class=\"d-flex justify-content-between align-items-start border radius-8 bg-white p-8px mt-8px\">\r\n <div class=\"d-flex align-items-center\">\r\n <div class=\"flex-center border border-gray-100 radius-8 wh-40\">\r\n <div class=\"flex-center border border-gray-200 radius-8 wh-34\">\r\n <div class=\"flex-center border border-gray-300 radius-8 wh-28\">\r\n <img [src]=\"getFileIcon(file.fileExtension)\"\r\n height=\"20\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex flex-column ms-8px\">\r\n <span class=\"text-gray-800\"\r\n [innerText]=\"file.fileName\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"getSize(file.fileSize)\"></span>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center\">\r\n <button class=\"btn btn-text text-gray-500 py-0 px-2\"\r\n [disabled]=\"file.downloadState.IsWait\"\r\n (click)=\"onDownloadFile(file)\">\r\n @if(file.downloadState.IsWait)\r\n {\r\n <span class=\"spinner-grow spinner-grow-sm\"></span>\r\n }\r\n @else {\r\n <i class=\"fs-18 ri-download-2-line\"></i>\r\n }\r\n </button>\r\n <button class=\"btn btn-text text-gray-500 py-0 px-2\"\r\n (click)=\"onRemoveFileClick(index)\">\r\n <i class=\"fs-18 ri-delete-bin-7-line\"></i>\r\n </button>\r\n </div>\r\n</div>\r\n}\r\n\r\n@if(!buttonOnly && readOnly && !files.length && !tempFiles.length){\r\n<div class=\"d-flex justify-content-center align-items-center border radius-8 bg-white mt-8px p-3\">\r\n <i class=\"fs-20 text-gray-400 ri-attachment-line me-3\"></i>\r\n <span class=\"font-semibold text-gray-400\"\r\n [innerText]=\"'MinioLabels.NoAttachment' | translate\"></span>\r\n</div>\r\n}\r\n}", styles: [".loading-wrapper{position:relative;height:8px}.loading{position:absolute;left:0}\n"] }]
543
+ }], ctorParameters: () => [{ type: MinIOService }, { type: i2.ToastsService }, { type: i3.TranslateService }], propDecorators: { maxSize: [{
544
+ type: Input
545
+ }], sizeUnit: [{
546
+ type: Input
547
+ }], accept: [{
548
+ type: Input
549
+ }], multiple: [{
550
+ type: Input
551
+ }], limit: [{
552
+ type: Input
553
+ }], buttonOnly: [{
554
+ type: Input
555
+ }], required: [{
556
+ type: Input,
557
+ args: [{ transform: booleanAttribute }]
558
+ }], readOnly: [{
559
+ type: Input,
560
+ args: [{ transform: booleanAttribute }]
561
+ }], disabled: [{
562
+ type: Input,
563
+ args: [{ transform: booleanAttribute }]
564
+ }], fileInput: [{
565
+ type: ViewChild,
566
+ args: ['fileInput']
567
+ }] } });
568
+
569
+ class MinioImageComponent {
570
+ registerOnChange(fn) {
571
+ this.onChange = fn;
572
+ }
573
+ registerOnTouched(fn) {
574
+ this.onTouched = fn;
575
+ }
576
+ registerOnValidatorChange(fn) {
577
+ this.onValidatorChange = fn;
578
+ }
579
+ constructor(service, toastsService, translateService) {
580
+ this.service = service;
581
+ this.toastsService = toastsService;
582
+ this.translateService = translateService;
583
+ this.maxHeight = 400;
584
+ this.maxWidth = 700;
585
+ this.maxSize = 10;
586
+ this.sizeUnit = 'MB';
587
+ this.accept = ['image/jpeg', 'image/jpg', 'image/png'];
588
+ this.required = false;
589
+ this.readOnly = false;
590
+ this.disabled = false;
591
+ this.hasDefaultLoading = true;
592
+ this.previewLoadingClass = '';
593
+ this.tempPreview = null;
594
+ this.preview = null;
595
+ this.acceptExtension = '';
596
+ this.maxBytes = 0;
597
+ this.file = { downloadState: new ObservableState() };
598
+ this.tempFile = {};
599
+ this.onChange = (_) => { };
600
+ this.onTouched = () => { };
601
+ this.onValidatorChange = () => { };
602
+ }
603
+ ngOnInit() {
604
+ this.maxBytes = convertToBytes(this.maxSize, this.sizeUnit);
605
+ this.acceptExtension = this.accept.map(x => getExtensionFromContentType(x).toUpperCase()).join(', ');
606
+ }
607
+ validate(control) {
608
+ return null;
609
+ }
610
+ writeValue(value) {
611
+ if (value) {
612
+ value.downloadState = new ObservableState();
613
+ this.file = value;
614
+ this.onDownloadFile(this.file);
615
+ }
616
+ else {
617
+ this.file = { downloadState: new ObservableState() };
618
+ }
619
+ }
620
+ onUploadClick() {
621
+ if (this.disabled || this.readOnly)
622
+ return;
623
+ this.fileInput.nativeElement.click();
624
+ this.onTouched();
625
+ }
626
+ onFileDropped(event) {
627
+ if (this.disabled || this.readOnly)
628
+ return;
629
+ this.onTouched();
630
+ event.preventDefault();
631
+ const file = event.dataTransfer?.files[0];
632
+ if (file) {
633
+ this.handleFile(file);
634
+ }
635
+ }
636
+ allowDrop(event) {
637
+ event.preventDefault();
638
+ }
639
+ onFileSelected(event) {
640
+ if (this.disabled || this.tempFile.isUploading)
641
+ return;
642
+ const file = this.fileInput.nativeElement.files[0];
643
+ if (file) {
644
+ this.handleFile(file);
645
+ }
646
+ this.fileInput.nativeElement.value = '';
647
+ }
648
+ handleFile(selectedFile) {
649
+ if (!this.accept.includes(selectedFile.type)) {
650
+ this.toastsService.showErrorToast(this.translateService.instant('MinioLabels.ExtensionError', { fileName: selectedFile.name, allowed: this.acceptExtension }));
651
+ return;
652
+ }
653
+ if (selectedFile.size > this.maxBytes) {
654
+ this.toastsService.showErrorToast(this.translateService.instant('MinioLabels.MaxSizeError', { fileName: selectedFile.name, max: `${this.maxSize}${this.sizeUnit}` }));
655
+ return;
656
+ }
657
+ this.tempFile = {
658
+ file: selectedFile,
659
+ progress: 0,
660
+ isUploading: false
661
+ };
662
+ this.getTempFilePreview();
663
+ this.uploadToMinIO(this.tempFile);
664
+ }
665
+ uploadToMinIO(tempFile) {
666
+ tempFile.isUploading = true;
667
+ this.service.uploadFileWithSignedUrl(tempFile.file, progress => tempFile.progress = progress.percentage)
668
+ .subscribe({
669
+ next: result => {
670
+ result.downloadState = new ObservableState();
671
+ this.file = result;
672
+ this.preview = this.tempPreview;
673
+ this.tempFile = {};
674
+ this.tempPreview = null;
675
+ this.onChange(this.file);
676
+ this.onValidatorChange();
677
+ },
678
+ error: () => {
679
+ this.tempFile = {};
680
+ this.tempPreview = null;
681
+ }
682
+ });
683
+ }
684
+ onRemoveFileClick() {
685
+ this.file = { downloadState: new ObservableState() };
686
+ this.preview = null;
687
+ this.onChange({});
688
+ this.onValidatorChange();
689
+ }
690
+ getTempFilePreview() {
691
+ const reader = new FileReader();
692
+ reader.onload = (e) => {
693
+ this.tempPreview = e.target.result;
694
+ };
695
+ reader.readAsDataURL(this.tempFile.file);
696
+ }
697
+ generatePreview(file) {
698
+ const reader = new FileReader();
699
+ reader.onload = (e) => {
700
+ this.preview = e.target.result;
701
+ };
702
+ reader.readAsDataURL(file);
703
+ }
704
+ getSize(size) {
705
+ return getFileSize(size);
706
+ }
707
+ onDownloadFile(file) {
708
+ if (!file.fileKey)
709
+ return;
710
+ file.downloadState.Wait();
711
+ this.service.download(file.fileKey)
712
+ .pipe(recordState(file.downloadState))
713
+ .subscribe({
714
+ next: response => {
715
+ this.generatePreview(response.body);
716
+ }
717
+ });
718
+ }
719
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinioImageComponent, deps: [{ token: MinIOService }, { token: i2.ToastsService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
720
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.2", type: MinioImageComponent, isStandalone: false, selector: "minio-image", inputs: { maxHeight: "maxHeight", maxWidth: "maxWidth", maxSize: "maxSize", sizeUnit: "sizeUnit", accept: "accept", required: ["required", "required", booleanAttribute], readOnly: ["readOnly", "readOnly", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], hasDefaultLoading: "hasDefaultLoading", previewLoadingClass: "previewLoadingClass" }, providers: [
721
+ {
722
+ provide: NG_VALUE_ACCESSOR,
723
+ useExisting: forwardRef(() => MinioImageComponent),
724
+ multi: true,
725
+ },
726
+ {
727
+ provide: NG_VALIDATORS,
728
+ useExisting: forwardRef(() => MinioImageComponent),
729
+ multi: true,
730
+ }
731
+ ], queries: [{ propertyName: "previewTemplate", first: true, predicate: ["preview"], descendants: true, static: true }, { propertyName: "uploadTemplate", first: true, predicate: ["upload"], descendants: true, static: true }], viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "@if(!!previewTemplate){\r\n@if(hasDefaultLoading && file.downloadState.IsWait){\r\n<span [ngClass]=\"previewLoadingClass\"\r\n class=\"spinner-grow spinner-grow-sm\"></span>\r\n}\r\n@else {\r\n<ng-container *ngTemplateOutlet=\"previewTemplate; context: { preview: preview, downloadStateIsWait: file.downloadState.IsWait }\"></ng-container>\r\n}\r\n}\r\n@else {\r\n<input type=\"file\"\r\n hidden\r\n (change)=\"onFileSelected($event)\"\r\n [accept]=\"accept.join(',')\"\r\n #fileInput />\r\n@if(!!uploadTemplate){\r\n<ng-container *ngTemplateOutlet=\"\r\n uploadTemplate; \r\n context: { \r\n preview: preview, \r\n uploadStateIsWait: tempFile.isUploading, \r\n downloadStateIsWait: file.downloadState.IsWait,\r\n upload: onUploadClick.bind(this)\r\n }\">\r\n</ng-container>\r\n}\r\n@else{\r\n@if(!readOnly && !file.fileKey && !tempPreview && !preview){\r\n<div class=\"border radius-8 px-6px py-12px\"\r\n [ngClass]=\"disabled ? 'opacity-50 cursor-default' : 'cursor-pointer'\"\r\n (drop)=\"onFileDropped($event)\"\r\n (dragover)=\"allowDrop($event)\"\r\n (click)=\"onUploadClick()\">\r\n <div class=\"flex-center\">\r\n <div class=\"flex-center\">\r\n <div class=\"flex-center bg-gray-100 border radius-8 wh-40 me-8px\">\r\n <i class=\"fs-20 text-gray-400 ri-image-line\"></i>\r\n </div>\r\n <div class=\"flex-center flex-column\">\r\n <div>\r\n <span class=\"font-regular text-primary me-1\"\r\n [innerText]=\"'MinioLabels.Click' | translate\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"'MinioLabels.Drag' | translate\"></span>\r\n </div>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"'MinioLabels.ImageRules' | translate: {acceptExtension: acceptExtension, maxSize: maxSize, sizeUnit: sizeUnit, maxWidth: maxWidth, maxHeight: maxHeight}\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n}\r\n\r\n@if (tempFile.file) {\r\n<div class=\"d-flex flex-column justify-content-start align-items-start border radius-8 bg-white p-8px mt-8px\">\r\n <div class=\"d-flex align-items-center w-100\">\r\n <img [src]=\"tempPreview\"\r\n height=\"60\"\r\n class=\"border radius-8\">\r\n <div class=\"d-flex flex-column justify-content-end ms-12px w-100\">\r\n <span class=\"text-gray-800\"\r\n [innerText]=\"tempFile.file.name\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"getSize(tempFile.file.size)\"></span>\r\n <div class=\"d-flex align-items-center pe-16px\">\r\n <div class=\"loading-wrapper bg-gray-200 radius-16 w-100\">\r\n <div class=\"loading bg-primary radius-16 h-100\"\r\n [style.width.%]=\"tempFile.progress\"></div>\r\n </div>\r\n <span class=\"ms-32px\"\r\n [innerText]=\"tempFile.progress + '%'\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n}\r\n\r\n@if(file.fileKey && !tempFile.file){\r\n<div class=\"d-flex justify-content-center align-items-center position-relative min-h-80px\"\r\n [style.max-height.px]=\"maxHeight\"\r\n [ngClass]=\"(disabled || readOnly) ? 'cursor-default' : 'cursor-pointer'\"\r\n (click)=\"onUploadClick()\">\r\n @if(file.downloadState.IsWait){\r\n <span class=\"spinner-grow spinner-grow-sm\"></span>\r\n }\r\n @else{\r\n <img [src]=\"preview\"\r\n class=\"border radius-8 w-100\"\r\n [style.max-height.px]=\"maxHeight\">\r\n @if(!required && !readOnly){\r\n <button class=\"btn btn-danger remove-image\"\r\n (click)=\"onRemoveFileClick()\">\r\n <i class=\"ri-delete-bin-7-line\"></i>\r\n </button>\r\n }\r\n }\r\n</div>\r\n}\r\n\r\n}\r\n}", styles: [".loading-wrapper{position:relative;height:8px}.loading{position:absolute;left:0}.remove-image{position:absolute;right:10px;top:10px}.min-h-80px{min-height:80px}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] }); }
732
+ }
733
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinioImageComponent, decorators: [{
734
+ type: Component,
735
+ args: [{ selector: 'minio-image', providers: [
736
+ {
737
+ provide: NG_VALUE_ACCESSOR,
738
+ useExisting: forwardRef(() => MinioImageComponent),
739
+ multi: true,
740
+ },
741
+ {
742
+ provide: NG_VALIDATORS,
743
+ useExisting: forwardRef(() => MinioImageComponent),
744
+ multi: true,
745
+ }
746
+ ], standalone: false, template: "@if(!!previewTemplate){\r\n@if(hasDefaultLoading && file.downloadState.IsWait){\r\n<span [ngClass]=\"previewLoadingClass\"\r\n class=\"spinner-grow spinner-grow-sm\"></span>\r\n}\r\n@else {\r\n<ng-container *ngTemplateOutlet=\"previewTemplate; context: { preview: preview, downloadStateIsWait: file.downloadState.IsWait }\"></ng-container>\r\n}\r\n}\r\n@else {\r\n<input type=\"file\"\r\n hidden\r\n (change)=\"onFileSelected($event)\"\r\n [accept]=\"accept.join(',')\"\r\n #fileInput />\r\n@if(!!uploadTemplate){\r\n<ng-container *ngTemplateOutlet=\"\r\n uploadTemplate; \r\n context: { \r\n preview: preview, \r\n uploadStateIsWait: tempFile.isUploading, \r\n downloadStateIsWait: file.downloadState.IsWait,\r\n upload: onUploadClick.bind(this)\r\n }\">\r\n</ng-container>\r\n}\r\n@else{\r\n@if(!readOnly && !file.fileKey && !tempPreview && !preview){\r\n<div class=\"border radius-8 px-6px py-12px\"\r\n [ngClass]=\"disabled ? 'opacity-50 cursor-default' : 'cursor-pointer'\"\r\n (drop)=\"onFileDropped($event)\"\r\n (dragover)=\"allowDrop($event)\"\r\n (click)=\"onUploadClick()\">\r\n <div class=\"flex-center\">\r\n <div class=\"flex-center\">\r\n <div class=\"flex-center bg-gray-100 border radius-8 wh-40 me-8px\">\r\n <i class=\"fs-20 text-gray-400 ri-image-line\"></i>\r\n </div>\r\n <div class=\"flex-center flex-column\">\r\n <div>\r\n <span class=\"font-regular text-primary me-1\"\r\n [innerText]=\"'MinioLabels.Click' | translate\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"'MinioLabels.Drag' | translate\"></span>\r\n </div>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"'MinioLabels.ImageRules' | translate: {acceptExtension: acceptExtension, maxSize: maxSize, sizeUnit: sizeUnit, maxWidth: maxWidth, maxHeight: maxHeight}\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n}\r\n\r\n@if (tempFile.file) {\r\n<div class=\"d-flex flex-column justify-content-start align-items-start border radius-8 bg-white p-8px mt-8px\">\r\n <div class=\"d-flex align-items-center w-100\">\r\n <img [src]=\"tempPreview\"\r\n height=\"60\"\r\n class=\"border radius-8\">\r\n <div class=\"d-flex flex-column justify-content-end ms-12px w-100\">\r\n <span class=\"text-gray-800\"\r\n [innerText]=\"tempFile.file.name\"></span>\r\n <span class=\"font-regular text-gray-500\"\r\n [innerText]=\"getSize(tempFile.file.size)\"></span>\r\n <div class=\"d-flex align-items-center pe-16px\">\r\n <div class=\"loading-wrapper bg-gray-200 radius-16 w-100\">\r\n <div class=\"loading bg-primary radius-16 h-100\"\r\n [style.width.%]=\"tempFile.progress\"></div>\r\n </div>\r\n <span class=\"ms-32px\"\r\n [innerText]=\"tempFile.progress + '%'\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n}\r\n\r\n@if(file.fileKey && !tempFile.file){\r\n<div class=\"d-flex justify-content-center align-items-center position-relative min-h-80px\"\r\n [style.max-height.px]=\"maxHeight\"\r\n [ngClass]=\"(disabled || readOnly) ? 'cursor-default' : 'cursor-pointer'\"\r\n (click)=\"onUploadClick()\">\r\n @if(file.downloadState.IsWait){\r\n <span class=\"spinner-grow spinner-grow-sm\"></span>\r\n }\r\n @else{\r\n <img [src]=\"preview\"\r\n class=\"border radius-8 w-100\"\r\n [style.max-height.px]=\"maxHeight\">\r\n @if(!required && !readOnly){\r\n <button class=\"btn btn-danger remove-image\"\r\n (click)=\"onRemoveFileClick()\">\r\n <i class=\"ri-delete-bin-7-line\"></i>\r\n </button>\r\n }\r\n }\r\n</div>\r\n}\r\n\r\n}\r\n}", styles: [".loading-wrapper{position:relative;height:8px}.loading{position:absolute;left:0}.remove-image{position:absolute;right:10px;top:10px}.min-h-80px{min-height:80px}\n"] }]
747
+ }], ctorParameters: () => [{ type: MinIOService }, { type: i2.ToastsService }, { type: i3.TranslateService }], propDecorators: { maxHeight: [{
748
+ type: Input
749
+ }], maxWidth: [{
750
+ type: Input
751
+ }], maxSize: [{
752
+ type: Input
753
+ }], sizeUnit: [{
754
+ type: Input
755
+ }], accept: [{
756
+ type: Input
757
+ }], required: [{
758
+ type: Input,
759
+ args: [{ transform: booleanAttribute }]
760
+ }], readOnly: [{
761
+ type: Input,
762
+ args: [{ transform: booleanAttribute }]
763
+ }], disabled: [{
764
+ type: Input,
765
+ args: [{ transform: booleanAttribute }]
766
+ }], hasDefaultLoading: [{
767
+ type: Input
768
+ }], previewLoadingClass: [{
769
+ type: Input
770
+ }], previewTemplate: [{
771
+ type: ContentChild,
772
+ args: ['preview', { static: true }]
773
+ }], uploadTemplate: [{
774
+ type: ContentChild,
775
+ args: ['upload', { static: true }]
776
+ }], fileInput: [{
777
+ type: ViewChild,
778
+ args: ['fileInput']
779
+ }] } });
780
+
781
+ class MinioModule {
782
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinioModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
783
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.2", ngImport: i0, type: MinioModule, declarations: [MinioFileUploadComponent,
784
+ MinioImageComponent], imports: [FormsModule,
785
+ CommonModule,
786
+ NgbPopoverModule,
787
+ TranslateModule], exports: [MinioFileUploadComponent,
788
+ MinioImageComponent] }); }
789
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinioModule, imports: [FormsModule,
790
+ CommonModule,
791
+ NgbPopoverModule,
792
+ TranslateModule] }); }
793
+ }
794
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: MinioModule, decorators: [{
795
+ type: NgModule,
796
+ args: [{
797
+ declarations: [
798
+ MinioFileUploadComponent,
799
+ MinioImageComponent
800
+ ],
801
+ imports: [
802
+ FormsModule,
803
+ CommonModule,
804
+ NgbPopoverModule,
805
+ TranslateModule
806
+ ],
807
+ exports: [
808
+ MinioFileUploadComponent,
809
+ MinioImageComponent
810
+ ],
811
+ providers: []
812
+ }]
813
+ }] });
814
+
815
+ /*
816
+ * Public API Surface of minio-file-upload
817
+ */
818
+
819
+ /**
820
+ * Generated bundle index. Do not edit.
821
+ */
822
+
823
+ export { MinIOService, MinioFileUploadComponent, MinioImageComponent, MinioModule };
824
+ //# sourceMappingURL=irisa-minio.mjs.map