{"version":3,"file":"uofx-app-components-pdf.mjs","sources":["../../../projects/uofx-app-pack/pdf/src/api/pdf.model.ts","../../../projects/uofx-app-pack/pdf/src/api/pdf.service.ts","../../../projects/uofx-app-pack/pdf/src/logic/pdf.logic.ts","../../../projects/uofx-app-pack/pdf/src/fullscreen-viewer/fullscreen-viewer.dialog.ts","../../../projects/uofx-app-pack/pdf/src/fullscreen-viewer/fullscreen-viewer.dialog.html","../../../projects/uofx-app-pack/pdf/src/pdf-viewer.component.ts","../../../projects/uofx-app-pack/pdf/src/pdf-viewer.component.html","../../../projects/uofx-app-pack/pdf/src/pdf-viewer.module.ts","../../../projects/uofx-app-pack/pdf/uofx-app-components-pdf.ts"],"sourcesContent":["/** 取得的pdf download url的request model */\r\nexport interface UofxDownloadUrlRequestModel {\r\n  /** 檔案id */\r\n  fileId: string;\r\n  /** 檔案url */\r\n  url: string;\r\n  /** 浮水印設定 */\r\n  watermarkSetting: UofxWatermarkSettingModel;\r\n  /** 是否允許下載檔案 */\r\n  enabledDownloadPdf: boolean;\r\n  /** 取得的pdfUrl不做加密動作 */\r\n  isSimpleView: boolean;\r\n}\r\n\r\n/** 取得pdf相關的url的response model */\r\nexport interface UofxPdfUrlReponseModel {\r\n  /** pdf view url */\r\n  viewUrl: string;\r\n  /** pdf download url */\r\n  pdfUrl: string;\r\n}\r\n\r\n/** 浮水印設定的model */\r\nexport interface UofxWatermarkSettingModel {\r\n  /** 是否要啟用浮水印 */\r\n  enabledWatermark?: boolean;\r\n  /** 文字 */\r\n  text?: string;\r\n  /** 字體 */\r\n  font?: string;\r\n  /** 字體大小 */\r\n  fontSize?: number;\r\n  /** 顏色 */\r\n  color?: Array<number>;\r\n  /** 傾斜角度 */\r\n  rotate?: number;\r\n  /** 透明度 */\r\n  opacity?: number;\r\n}\r\n\r\n/** pdf開啟的狀態 */\r\nexport enum PdfOpenStatus {\r\n  BeforeOpen,\r\n  AfterOpen,\r\n}\r\n\r\n/** 產生pdf viewer時所需的相關設定 */\r\nexport interface UofxPdfViewerSettingInfoModel {\r\n  /** viewer html id */\r\n  viewerHtmlId;\r\n  /** 浮水印設定 */\r\n  watermarkSetting: UofxWatermarkSettingModel;\r\n  /** 是否為全視窗模式 */\r\n  fullscreenMode: boolean;\r\n  /** 是否允許下載pdf */\r\n  enabledDownloadPdf: boolean;\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\n\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { AesModel } from '@uofx/core';\r\n\r\nimport { UofxDownloadUrlRequestModel, UofxPdfUrlReponseModel } from './pdf.model';\r\n\r\n@Injectable()\r\nexport class UofxPdfService {\r\n  constructor(private http: HttpClient) {}\r\n\r\n  /** 取得pdf檔案的密碼AES暗碼 */\r\n  public getPdfDownloadUrl(model: UofxDownloadUrlRequestModel) {\r\n    return this.http.post<UofxPdfUrlReponseModel>(`~/api/app/base/utility/fileviewer/url`, model);\r\n  }\r\n\r\n  /** 取得pdf檔案的密碼AES暗碼 */\r\n  public getPdfAesPwd(fileId: string, model: AesModel) {\r\n    return this.http.post<string>(`~/api/app/base/file/download/lock/pwd/${fileId}`, model);\r\n  }\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { GcPdfViewer } from '@mescius/dspdfviewer';\r\nimport { MCORE_CONFIG } from '@uofx/core/mcore-config';\r\nimport { UofxFileDownloadHelper, UofxFileModel } from '@uofx/app-components/file-helper';\r\nimport { UofxCrypto, UofxI18NService } from '@uofx/core';\r\nimport { forkJoin, Subject } from 'rxjs';\r\nimport {\r\n  PdfOpenStatus,\r\n  UofxDownloadUrlRequestModel,\r\n  UofxPdfUrlReponseModel,\r\n  UofxPdfViewerSettingInfoModel,\r\n  UofxWatermarkSettingModel,\r\n} from './../api/pdf.model';\r\nimport { UofxPdfService } from './../api/pdf.service';\r\n\r\n@Injectable()\r\nexport class UofxPdfLogic {\r\n  /** 用來判斷是否重複開啟一樣的檔案的file id */\r\n  tempFileId = '';\r\n  /** 用來開啟pdf的url */\r\n  viewUrl = '';\r\n  /** 用來下載的pdf url */\r\n  pdfUrl = '';\r\n  /** 開啟pdf的狀態 */\r\n  openPdfStatus$ = new Subject<PdfOpenStatus>();\r\n  /** 當前的file name */\r\n  fileName = '';\r\n  // #region 多語系\r\n  // *UKEY: \"global.pdf-logic.toolbar-zoom-fitwidth\"\r\n  // *UKEY: \"global.pdf-logic.toolbar-zoom-fitpage\"\r\n  // *UKEY: \"global.pdf-logic.context-menu-copy-text\"\r\n  // #endregion\r\n\r\n  // #region private readonly variable\r\n\r\n  /** 開啟檔案所需的AES KEY */\r\n  private readonly AES_KEY = 'uofx@aesk-pdfpwd';\r\n  /** 開啟檔案所需的AES IV */\r\n  private readonly AES_IV = 'uofx@aesi-pdfpwd';\r\n  /** 葡萄城GcPdfViewer授權 */\r\n  private readonly GCPDFVIEWER_LICENSE_KEY =\r\n    'e-Excellence Inc.,362519851819617#B11J8bwk7Q6cnQOt6MZN5SC9EZzIDOmNETyI5VC3USvhVOzkUYNdjcwdTemR7YHZ6RkhFMMJmcVVUONhnSHJkdFdjcDVjTZJkTw9kd7dEW6xGTKFmSwEjbpFDehFUYDR7dZR6TrA7SVdUW89WUhRVMBZTZkhXVxkWNtxmb7Rnaz5UayUnM7BTeCFmYjFDWoZHcvMVYadnM9JlQhlEMwEHdrQ6Z9J7UhtycldkNxhnbY3GaRFld5omS43Wd5okdTZ6N5Vlb98kb6c5UMFmWJ56UJl4b8sERkVUZiojITJCLiQ4MDFUNCZ4NiojIIJCL8MDOzkTOwMzN0IicfJye#4Xfd5nI7IkVLJiOiMkIsISOWBicldXZpZlZkB5QHJiOi8kI1tlOiQmcQJCLiYDN8QTMwAyNwEDM6IDMyIiOiQncDJCLi8yYulEIlNmblxGblNGeF5SZiojIh94QiwiI7EjN9EDOxUDO9ETNyYzMiojIklkI1pjIEJCLi4TPBRUOYVWe9RlM5dUa5IXcSdnQzdFOqJ6cQJlUhhXVzVEStdlbFlDUlpGNnFTUVRGakh4b5VDTuJjc0VjYZdzRHd7TDRWNydmWVdEb65kV6oXOtV5Zxg6c74UWZVXSWxGUwo5cih7RHBjVMpWT9ZFZ9l7Kt56KHlzNJJ5LhVmS';\r\n  /**\r\n   * 沒有浮水印時的上方工具列\r\n   * > reference: https://developer.mescius.com/document-solutions/javascript-pdf-viewer/api/classes/GcPdfViewer.html#toolbarLayout\r\n   */\r\n  private readonly DEFAULT_TOOLBAR = ['rotate', 'zoom', 'text-selection'];\r\n  /** 有浮水印時的上方工具列 (不支援選取文字) */\r\n  private readonly WATERMARK_TOOLBAR = [...this.DEFAULT_TOOLBAR].filter((item) => item !== 'text-selection');\r\n  /**\r\n   * 文件檢視器相關的多語系翻譯\r\n   * > reference: https://developer.mescius.com/document-solutions/javascript-pdf-viewer/demos/ui-customization/localization/purejs\r\n   */\r\n  private readonly TRANSLATION_SETTING;\r\n  /** toolbar的開窗滿版按鈕的key */\r\n  private readonly CUSTOM_FULLSCREEN_KEY = 'custom-fullscreen';\r\n  /** toolbar的下載檔案按鈕的key */\r\n  private readonly CUSTOM_DOWNLOAD_KEY = 'custom-download';\r\n\r\n  // #endregion\r\n\r\n  private mcoreConfig = inject(MCORE_CONFIG);\r\n\r\n  /** smart zoom 事件清除函式列表 */\r\n  private cleanupFns: (() => void)[] = [];\r\n\r\n  constructor(\r\n    private downloadHelper: UofxFileDownloadHelper,\r\n    private pdfService: UofxPdfService,\r\n    private i18nService: UofxI18NService\r\n  ) {\r\n    this.TRANSLATION_SETTING = {\r\n      toolbar: {\r\n        'zoom-fitwidth': this.i18nService.trans('global.pdf-logic.toolbar-zoom-fitwidth'),\r\n        'zoom-fitpage': this.i18nService.trans('global.pdf-logic.toolbar-zoom-fitpage'),\r\n      },\r\n      'context-menu': {\r\n        'copy-text': {\r\n          label: this.i18nService.trans('global.pdf-logic.context-menu-copy-text'),\r\n          title: this.i18nService.trans('global.pdf-logic.context-menu-copy-text'),\r\n        },\r\n      },\r\n    };\r\n  }\r\n\r\n  /** 產生pdf viewer物件 */\r\n  public generateGcPdfViewer(setting: UofxPdfViewerSettingInfoModel): Promise<GcPdfViewer> {\r\n    // 葡萄城viewer授權碼\r\n    GcPdfViewer.LicenseKey = this.GCPDFVIEWER_LICENSE_KEY;\r\n\r\n    // viewer物件\r\n    let resultViewer;\r\n\r\n    // 設定viewer多語系\r\n    return new Promise((resolve) => {\r\n      GcPdfViewer.i18n\r\n        .init({\r\n          resources: { uofxLang: { viewer: this.TRANSLATION_SETTING } },\r\n          defaultNS: 'viewer',\r\n        })\r\n        .then(() => {\r\n          resultViewer = this.newGcPdfViewer(setting);\r\n          resultViewer.addDefaultPanels();\r\n          this.panelAndToolbarSetting(resultViewer, setting);\r\n          this.registerAfterOpen(resultViewer, setting);\r\n          resolve(resultViewer);\r\n        });\r\n    });\r\n  }\r\n\r\n  /** viewer的panel & toolbar設定 */\r\n  private panelAndToolbarSetting(viewer: GcPdfViewer, setting: UofxPdfViewerSettingInfoModel) {\r\n    // 僅顯示有用到的 ToolBar (上方)\r\n    const toolBarSetting =\r\n      setting.watermarkSetting && setting.watermarkSetting.enabledWatermark\r\n        ? this.WATERMARK_TOOLBAR\r\n        : this.DEFAULT_TOOLBAR;\r\n\r\n    if (!setting.fullscreenMode && !toolBarSetting.includes(this.CUSTOM_FULLSCREEN_KEY)) {\r\n      toolBarSetting.push(this.CUSTOM_FULLSCREEN_KEY);\r\n    }\r\n\r\n    if (setting.enabledDownloadPdf && !toolBarSetting.includes(this.CUSTOM_DOWNLOAD_KEY)) {\r\n      toolBarSetting.push(this.CUSTOM_DOWNLOAD_KEY);\r\n      this.addToolbarDownloadItem(viewer);\r\n    }\r\n\r\n    viewer.toolbarLayout.viewer = { default: toolBarSetting, mobile: toolBarSetting };\r\n  }\r\n\r\n  /** new一個新的viewer */\r\n  private newGcPdfViewer(setting: UofxPdfViewerSettingInfoModel) {\r\n    // 產生viewer\r\n    return new GcPdfViewer(`#${setting.viewerHtmlId}`, {\r\n      workerSrc: './assets/gcpdfviewer/dspdfviewer.worker.js',\r\n      cMapUrl: './assets/gcpdfviewer/resources/bcmaps',\r\n      language: 'uofxLang',\r\n      onBeforeOpenContextMenu: (items) => this.contextMenuSetting(items, setting.watermarkSetting),\r\n      zoomByMouseWheel: { always: false, ctrlKey: false, metaKey: false },\r\n    });\r\n  }\r\n\r\n  /** 註冊viewer after open事件 */\r\n  private registerAfterOpen(viewer: GcPdfViewer, setting: UofxPdfViewerSettingInfoModel) {\r\n    viewer.onAfterOpen.register(() => {\r\n      this.afterOpenSetting(viewer, setting);\r\n    });\r\n  }\r\n\r\n  /** 開啟viewer之後要處理的相關設定 */\r\n  private afterOpenSetting(viewer: GcPdfViewer, setting: UofxPdfViewerSettingInfoModel) {\r\n    // 根據是否啟用浮水印設定，來決定預設選取tool bar上面的\"pan\"還是\"text-selection\" (是否可以選取到文字)\r\n    viewer['mouseMode'] = this.enabledWatermark(setting.watermarkSetting) ? 1 : 0;\r\n    // 把左側功能區隱藏 (panel)\r\n    document.querySelector(`#${setting.viewerHtmlId} .gcv-menu`)['style'].display = 'none';\r\n\r\n    // 有時onAfterOpen發出事件了，但事實上還沒開啟完成，所以要等\r\n    setTimeout(() => {\r\n      this.openPdfStatus$.next(PdfOpenStatus.AfterOpen);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * 對內容按右鍵的設定\r\n   * -\r\n   * 1. 是否要顯示選單 (return false代表不顯示選單，反之則顯示)\r\n   * 2. 選單內部顯示列印\r\n   */\r\n  private contextMenuSetting(items, watermarkSetting: UofxWatermarkSettingModel): boolean {\r\n    if (this.enabledWatermark(watermarkSetting)) {\r\n      return false;\r\n    } else {\r\n      items.splice(1, 1);\r\n      return true;\r\n    }\r\n  }\r\n\r\n  /** 開啟pdf之前的判斷邏輯 */\r\n  public beforeOpenPdf(\r\n    viewer: GcPdfViewer,\r\n    file: UofxFileModel,\r\n    watermarkSetting: UofxWatermarkSettingModel,\r\n    enabledDownloadPdf: boolean\r\n  ) {\r\n    // 判斷剛給進來的file id是否已經是現在使用的檔案\r\n    if ((file && this.tempFileId === file.id) || !viewer) return;\r\n    // 如果沒有檔案，則不必執行後續動作\r\n    if (!this.checkHasFile(viewer, file)) return;\r\n    // 開啟pdf前\r\n    this.openPdfStatus$?.next(PdfOpenStatus.BeforeOpen);\r\n    // 執行開啟pdf相關邏輯\r\n    this.getInfoAndOpenPdf(viewer, file, watermarkSetting, enabledDownloadPdf);\r\n  }\r\n\r\n  /**\r\n   * 檢查是否有檔案\r\n   * -\r\n   * 如果沒檔案則直接執行openPdfLogic()\r\n   */\r\n  private checkHasFile(viewer: GcPdfViewer, file: UofxFileModel) {\r\n    if (!this.hasFile(file)) {\r\n      setTimeout(() => {\r\n        this.viewerApply(viewer);\r\n      });\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * 取得pdf所需相關資訊並開啟pdf\r\n   * 1. 取得pdf下載的url\r\n   * 2. 取得打開pdf的密碼：目前機制，我們一律都會對pdf上密碼，需呼叫api取得密碼暗碼再做AES解密取得明碼\r\n   * 3. 開啟pdf\r\n   */\r\n  public getInfoAndOpenPdf(\r\n    viewer: GcPdfViewer,\r\n    file: UofxFileModel,\r\n    watermarkSetting: UofxWatermarkSettingModel,\r\n    enabledDownloadPdf: boolean\r\n  ) {\r\n    forkJoin([\r\n      this.pdfService.getPdfAesPwd(file.id, UofxCrypto.getAesModelWithRsaEncrypt(this.AES_KEY, this.AES_IV)),\r\n      this.pdfService.getPdfDownloadUrl(<UofxDownloadUrlRequestModel>{\r\n        fileId: file.id,\r\n        url: file.url,\r\n        watermarkSetting: watermarkSetting || {},\r\n        enabledDownloadPdf: enabledDownloadPdf,\r\n        isSimpleView: false,\r\n      }),\r\n    ]).subscribe({\r\n      next: (results) => {\r\n        this.handlePwdAndViewUrl(results, viewer);\r\n      },\r\n      complete: () => {\r\n        this.openPdfLogic(viewer, file);\r\n      },\r\n    });\r\n  }\r\n\r\n  /**\r\n   * 處理取得的pdf密碼及觀看url相關邏輯\r\n   * @private\r\n   * @param {[string, UofxPdfUrlReponseModel]} results 兩個api取得的結果\r\n   * @memberof UofxPdfViewerComponent\r\n   */\r\n  private handlePwdAndViewUrl(results: [string, UofxPdfUrlReponseModel], viewer: GcPdfViewer) {\r\n    const filePwd = UofxCrypto.decryptPdfPwd(results[0], this.AES_KEY, this.AES_IV);\r\n    if (filePwd) viewer.options.password = filePwd;\r\n    this.viewUrl = results[1].viewUrl;\r\n    this.pdfUrl = results[1].pdfUrl;\r\n  }\r\n\r\n  /** 打開pdf */\r\n  private openPdfLogic(viewer: GcPdfViewer, file: UofxFileModel) {\r\n    // 非常重要不可拿掉，每次要open新的pdf之前，一定要先apply最新的相關設定\r\n    this.viewerApply(viewer);\r\n\r\n    if (this.hasViewUrl()) {\r\n      const downloadUrl = this.downloadHelper.formatUrl(this.viewUrl);\r\n      viewer.open(downloadUrl);\r\n      this.fileName = file.fileName || '';\r\n      this.tempFileId = file.id;\r\n    } else {\r\n      viewer.open();\r\n      this.tempFileId = '';\r\n    }\r\n  }\r\n\r\n  /** viewer的apply行為 */\r\n  public viewerApply(viewer: GcPdfViewer) {\r\n    viewer.applyOptions();\r\n    viewer.applyToolbarLayout();\r\n  }\r\n\r\n  /** 是否有檔案及url */\r\n  private hasFile(file: UofxFileModel) {\r\n    return file && file.url && file.url !== '';\r\n  }\r\n\r\n  /** 是否有viewUrl */\r\n  private hasViewUrl() {\r\n    return this.viewUrl && this.viewUrl !== '';\r\n  }\r\n\r\n  /** 是否允許浮水印 */\r\n  private enabledWatermark(watermarkSetting: UofxWatermarkSettingModel) {\r\n    return watermarkSetting && watermarkSetting.enabledWatermark;\r\n  }\r\n\r\n  /** 客製的toolbar按鈕onUpdate callback事件 */\r\n  private customOnUpdateCallback(viewer: GcPdfViewer) {\r\n    return () => this.onUpdateCallbackLogic(viewer);\r\n  }\r\n\r\n  /** onUpdate callback邏輯 */\r\n  private onUpdateCallbackLogic(viewer: GcPdfViewer) {\r\n    if (viewer.hasChanges === undefined) return { enabled: false };\r\n    return { enabled: viewer.hasDocument };\r\n  }\r\n\r\n  /** 新增下載檔案的toolbar item */\r\n  private addToolbarDownloadItem(viewer: GcPdfViewer) {\r\n    this.addToolbarItem(viewer, this.CUSTOM_DOWNLOAD_KEY, 'M5 19.998h14v-2H5m14-9h-4v-6H9v6H5l7 7 7-7z', () => {\r\n      this.downloadPdf(true, this.pdfUrl, this.pdfUrl);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * 下載檔案\r\n   * -\r\n   * 1. if: web下載檔案\r\n   * 2. else: app下載檔案\r\n   */\r\n  public downloadPdf(isPdfUrl: boolean, downloadUrl: string, url: string) {\r\n    const isWebMode = this.mcoreConfig.IsMock;\r\n    // downloadUrl 下載url(file:綁token的下載url、img:原始檔案url)\r\n    // url 原始檔案url(24小時內有效)\r\n\r\n    if (isWebMode) {\r\n      const fileName = isPdfUrl ? this.fileName.replace(/\\.[^/.]+$/, '.pdf') : this.fileName;\r\n      this.downloadHelper.webModeDownloadFile(downloadUrl, fileName);\r\n    } else {\r\n      this.downloadHelper.downloadRawFileInAppBrowser(isPdfUrl, downloadUrl, url);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 自行客製新增toolbar item\r\n   * @param {GcPdfViewer} viewer 當前viewer\r\n   * @param {string} title 按鈕的tooltip\r\n   * @param {string} key toolbar key\r\n   * @param {string} svgDrawnStr icon的path d參數\r\n   * @param {*} action\r\n   * @memberof UofxPdfLogic\r\n   */\r\n  public addToolbarItem(viewer: GcPdfViewer, key: string, svgDrawnStr: string, action: any) {\r\n    const react = viewer.getType('React');\r\n    const addObj = {\r\n      key: key,\r\n      icon: {\r\n        type: 'svg',\r\n        content: react.createElement(\r\n          'svg',\r\n          {\r\n            xmlns: 'http://www.w3.org/2000/svg',\r\n            version: '1.1',\r\n            width: '24',\r\n            height: '24',\r\n            viewBox: '0 0 24 24',\r\n            fill: '#205f78',\r\n          },\r\n          react.createElement('path', { d: svgDrawnStr })\r\n        ),\r\n      },\r\n      title: '',\r\n      enabled: false,\r\n      action: action,\r\n      onUpdate: this.customOnUpdateCallback(viewer),\r\n    };\r\n    viewer['toolbar'].addItem(addObj);\r\n  }\r\n\r\n  /** 取得toolbar的開窗滿版按鈕的key */\r\n  public getCustomFullscreenKey() {\r\n    return this.CUSTOM_FULLSCREEN_KEY;\r\n  }\r\n\r\n  /** 取得toolbar的下載檔案按鈕的key */\r\n  public getCustomDownloadKey() {\r\n    return this.CUSTOM_DOWNLOAD_KEY;\r\n  }\r\n\r\n  /** 單純根據已現有的pdfUrl開啟viewer，不需經過加密 */\r\n  public simpleOpen(viewer: GcPdfViewer, file: any) {\r\n    this.viewUrl = file.pdfUrl;\r\n    this.pdfUrl = file.pdfUrl;\r\n    this.openPdfLogic(viewer, file);\r\n  }\r\n\r\n  /** 走simpleOpen(不加密)，但要先取得組好浮水印設定的pdfUrl，再開啟viewer */\r\n  public simpleOpenWithWatermark(\r\n    viewer: GcPdfViewer,\r\n    file: UofxFileModel,\r\n    watermarkSetting: UofxWatermarkSettingModel,\r\n    enabledDownloadPdf: boolean\r\n  ) {\r\n    const reqModel = <UofxDownloadUrlRequestModel>{\r\n      fileId: file.id,\r\n      url: file.pdfUrl,\r\n      watermarkSetting: watermarkSetting || {},\r\n      enabledDownloadPdf: enabledDownloadPdf,\r\n      isSimpleView: true,\r\n    };\r\n    this.pdfService.getPdfDownloadUrl(reqModel).subscribe({\r\n      next: (res) => {\r\n        this.viewUrl = res.viewUrl;\r\n        this.pdfUrl = res.pdfUrl;\r\n      },\r\n      complete: () => {\r\n        this.openPdfLogic(viewer, file);\r\n      },\r\n    });\r\n  }\r\n\r\n  /**\r\n   * 以滑鼠游標位置或兩指中點為錨點縮放\r\n   * -\r\n   * 預設的zoomByMouseWheel是以viewport中心點為錨點縮放，會有游標位置與縮放位置不一致的問題\r\n   */\r\n  public registerZoomAtPoint(viewer: GcPdfViewer): void {\r\n    // scrollView 是 Mescius viewer 內真正負責捲動內容的 DOM 容器。\r\n    const scrollEl = viewer.scrollView as HTMLElement;\r\n    if (!scrollEl) return;\r\n\r\n    /** \r\n     * 名詞解釋\r\n     * 1. scroll 補償：意思就是每次縮放後，都會固定處理scroll位置校正\r\n     */\r\n\r\n    // 防止瀏覽器原生 pinch-zoom 與自訂捏合縮放衝突。\r\n    // 一般閱讀狀態保留 pan；只有真的進入雙指縮放期間才暫時切成 none。\r\n    // 先記住原本的 touchAction，cleanup 時需要完整還原。\r\n    const originalTouchAction = scrollEl.style.touchAction;\r\n    // 這裡的 idle 代表「尚未進入雙指縮放的閱讀狀態」，只允許水平/垂直平移，避免瀏覽器接手原生縮放。\r\n    const idleTouchAction = 'pan-x pan-y';\r\n    // 一進來先把容器切到一般閱讀時的觸控模式。\r\n    scrollEl.style.touchAction = idleTouchAction;\r\n\r\n    // viewer 允許的最小縮放比例。\r\n    const MIN_SCALE = 0.25;\r\n    // viewer 允許的最大縮放比例。\r\n    const MAX_SCALE = 3;\r\n    // wheel 每次滾動對縮放倍率的影響係數。\r\n    const WHEEL_SENSITIVITY = 0.002;\r\n    // pinch 進行中完全交由自訂邏輯處理手勢，不讓瀏覽器做任何 touch 行為。\r\n    const DISABLE_TOUCH_ACTION = 'none';\r\n    // 限制單一次 pinch move 最多只放大/縮小到前一次基準的 1.5 倍，避免快速滑動造成過大的瞬間縮放跳幅。\r\n    const MAX_PINCH_STEP_RATIO = 1.5;\r\n\r\n    // 兩指手勢在當前 viewport 內的即時幾何資訊。\r\n    type TouchMetrics = {\r\n      // 兩指之間的距離，用來換算相對縮放倍率。\r\n      distance: number;\r\n      // 兩指中點在 scroll 容器內的 X 座標。\r\n      viewportMidX: number;\r\n      // 兩指中點在 scroll 容器內的 Y 座標。\r\n      viewportMidY: number;\r\n    };\r\n\r\n    // pinch session 只保存「起始狀態」，後續 move 都以它為基準回推 scroll 補償\r\n    type PinchSession = {\r\n      // 是否已建立一段有效的 pinch session。\r\n      active: boolean;\r\n      // 手勢起始時兩指的距離。\r\n      startDistance: number;\r\n      // 手勢起始時 viewer 的 scale。\r\n      startScale: number;\r\n      // 手勢起始時，中點對應到文件座標的 X。\r\n      startDocFocalX: number;\r\n      // 手勢起始時，中點對應到文件座標的 Y。\r\n      startDocFocalY: number;\r\n    };\r\n\r\n    // 用於保留最後一次待執行的 scroll 補償，避免同一個動作的frame裡面排進多個補償互相覆蓋\r\n    let scheduledScrollRafId: number | null = null;\r\n\r\n    // 用單一物件保存 pinch 起始狀態，避免相關變數分散在 method 各處難以追蹤。\r\n    const pinchSession: PinchSession = {\r\n      active: false,\r\n      startDistance: 0,\r\n      startScale: 1,\r\n      startDocFocalX: 0,\r\n      startDocFocalY: 0,\r\n    };\r\n\r\n    // 用於檢查這個數值能不能安全拿來做縮放計算：必須是有限正數\r\n    const isPositiveFinite = (value: number): boolean => Number.isFinite(value) && value > 0;\r\n\r\n    /** 用於檢查是否有前一次 scroll 補償尚未執行，就先取消，避免操作過快所有補償一起做導致畫面抖動 */\r\n    const cancelScheduledScroll = (): void => {\r\n      if (scheduledScrollRafId !== null) {\r\n        cancelAnimationFrame(scheduledScrollRafId);\r\n        scheduledScrollRafId = null;\r\n      }\r\n    };\r\n\r\n    /** 統一將 scroll 補償延到下一個 frame，等 viewer 吃進新的 zoom 之後再修正 viewport 位置 */\r\n    const scheduleScrollCompensation = (nextScrollLeft: number, nextScrollTop: number): void => {\r\n      // 非法座標不套用，避免把 NaN / Infinity 寫進 DOM scroll 狀態。\r\n      if (!Number.isFinite(nextScrollLeft) || !Number.isFinite(nextScrollTop)) return;\r\n\r\n      cancelScheduledScroll();\r\n      scheduledScrollRafId = requestAnimationFrame(() => {\r\n        scheduledScrollRafId = null;\r\n        // 更新目前 viewport 的目標位置。\r\n        scrollEl.scrollLeft = nextScrollLeft;\r\n        scrollEl.scrollTop = nextScrollTop;\r\n      });\r\n    };\r\n\r\n    /** 將 scale 限制在 viewer 可接受的範圍內 */\r\n    const clampScale = (scale: number): number => Math.min(MAX_SCALE, Math.max(MIN_SCALE, scale));\r\n\r\n    /** 優先取 viewer.currentScale；若 viewer 尚未同步，再退回 zoomValue；最後才給安全預設值 1 */\r\n    const getViewerScale = (): number => {\r\n      const currentScale = Number((viewer as any).currentScale);\r\n      if (isPositiveFinite(currentScale)) return currentScale;\r\n\r\n      const zoomScale = Number(viewer.zoomValue) / 100;\r\n      if (isPositiveFinite(zoomScale)) return zoomScale;\r\n\r\n      return 1;\r\n    };\r\n\r\n    /** 實際把 scale 寫回 viewer，並確認 viewer 沒把數值轉成非法狀態 */\r\n    const applyViewerScale = (scale: number): boolean => {\r\n      const zoomValue = scale * 100;\r\n      if (!Number.isFinite(zoomValue)) return false;\r\n\r\n      viewer.zoomValue = zoomValue;\r\n      return Number.isFinite(Number(viewer.zoomValue));\r\n    };\r\n\r\n    /** 從兩指 touch 資料取得距離與中點，這是 pinch 所需的最基本幾何資訊 */\r\n    const getTouchMetrics = (touches: TouchList | Touch[]): TouchMetrics | null => {\r\n      // 不是雙指就不視為 pinch。\r\n      if (!touches || touches.length !== 2) return null;\r\n\r\n      const firstTouch = touches[0];\r\n      const secondTouch = touches[1];\r\n      // 兩指距離決定相對縮放倍率。\r\n      const distance = Math.hypot(\r\n        secondTouch.clientX - firstTouch.clientX,\r\n        secondTouch.clientY - firstTouch.clientY\r\n      );\r\n      if (!isPositiveFinite(distance)) return null;\r\n\r\n      // 需要容器的位置資訊，才能把視窗座標換算成 scroll 容器內的局部座標。\r\n      const rect = scrollEl.getBoundingClientRect();\r\n      return {\r\n        distance,\r\n        viewportMidX: (firstTouch.clientX + secondTouch.clientX) / 2 - rect.left,\r\n        viewportMidY: (firstTouch.clientY + secondTouch.clientY) / 2 - rect.top,\r\n      };\r\n    };\r\n\r\n    /** 清空 pinch session 的相關狀態 */\r\n    const resetPinchSession = (): void => {\r\n      pinchSession.active = false;\r\n      pinchSession.startDistance = 0;\r\n      pinchSession.startScale = 1;\r\n      pinchSession.startDocFocalX = 0;\r\n      pinchSession.startDocFocalY = 0;\r\n      cancelScheduledScroll();\r\n      scrollEl.style.touchAction = idleTouchAction;\r\n    };\r\n\r\n    /** 建立一段新的 pinch session：手勢起始的距離、scale 與文件焦點座標 */\r\n    const beginPinchSession = (touches: TouchList | Touch[]): boolean => {\r\n      const metrics = getTouchMetrics(touches);\r\n      const startScale = getViewerScale();\r\n      // 只要起始幾何資訊或 scale 有問題，就中止這次 pinch。\r\n      if (!metrics || !isPositiveFinite(startScale)) {\r\n        resetPinchSession();\r\n        return false;\r\n      }\r\n\r\n      pinchSession.active = true;\r\n      // 記住起始時兩指距離，後續 move 以它作為縮放比的分母\r\n      pinchSession.startDistance = metrics.distance;\r\n      // 記住起始時 viewer scale，讓後續縮放一律相對於這個基準計算\r\n      pinchSession.startScale = startScale;\r\n      // 記住起始中點在文件空間的實際位置，後續要維持它仍停留在手勢中點下方\r\n      pinchSession.startDocFocalX = scrollEl.scrollLeft + metrics.viewportMidX;\r\n      pinchSession.startDocFocalY = scrollEl.scrollTop + metrics.viewportMidY;\r\n      // pinch 期間完全關閉瀏覽器 touch 行為，避免和自訂縮放搶控制權\r\n      scrollEl.style.touchAction = DISABLE_TOUCH_ACTION;\r\n      // 新 pinch 開始時，舊的 scroll 補償排程不再有效\r\n      cancelScheduledScroll();\r\n      return true;\r\n    };\r\n\r\n    /** 根據 viewport 內的焦點位置進行縮放，wheel 使用這套補償方式 */\r\n    const zoomAroundViewportPoint = (newScale: number, focalX: number, focalY: number): void => {\r\n      const oldScrollW = scrollEl.scrollWidth;\r\n      const oldScrollH = scrollEl.scrollHeight;\r\n      // 沒有有效的內容尺寸，就不能計算焦點在文件中的相對位置。\r\n      if (!isPositiveFinite(oldScrollW) || !isPositiveFinite(oldScrollH)) return;\r\n\r\n      // 先把目前焦點換算成文件整體的相對比例，縮放後再用這個比例反推新 scroll。\r\n      const ratioX = (scrollEl.scrollLeft + focalX) / oldScrollW;\r\n      const ratioY = (scrollEl.scrollTop + focalY) / oldScrollH;\r\n      if (!Number.isFinite(ratioX) || !Number.isFinite(ratioY)) return;\r\n\r\n      const clampedScale = clampScale(newScale);\r\n      // viewer 如果不接受這次 scale，就不做後續 scroll 補償。\r\n      if (!applyViewerScale(clampedScale)) return;\r\n\r\n      // 讓縮放前的焦點，縮放後仍維持在同一個 viewport 位置。\r\n      scheduleScrollCompensation(ratioX * scrollEl.scrollWidth - focalX, ratioY * scrollEl.scrollHeight - focalY);\r\n    };\r\n\r\n    /** Ctrl/meta + wheel 以游標位置為錨點縮放 */\r\n    const onWheel = (e: WheelEvent): void => {\r\n      // 非縮放型 wheel 事件直接略過，保留原本的普通捲動行為。\r\n      if (!e.ctrlKey && !e.metaKey) return;\r\n\r\n      // 阻止瀏覽器預設的 page zoom 或 scroll，改由 viewer 自己處理。\r\n      e.preventDefault();\r\n      e.stopPropagation();\r\n\r\n      // 取得游標相對於 scroll 容器的位置，作為 wheel 縮放的錨點。\r\n      const rect = scrollEl.getBoundingClientRect();\r\n      const oldScale = getViewerScale();\r\n      zoomAroundViewportPoint(oldScale * (1 + -e.deltaY * WHEEL_SENSITIVITY), e.clientX - rect.left, e.clientY - rect.top);\r\n    };\r\n\r\n    /** 必須用 passive: false 才能在 wheel handler 內呼叫 preventDefault */\r\n    scrollEl.addEventListener('wheel', onWheel, { passive: false });\r\n\r\n    /** \r\n     * touch events 用來接手行動裝置 pinch，避免被外層手勢或瀏覽器原生縮放搶走\r\n     * -\r\n     * 使用 touch events 而非 pointer events：Ionic GestureController 會攔截 pointer events\r\n     */\r\n    const onTouchStart = (e: TouchEvent): void => {\r\n      // 只有雙指開始時才建立 pinch session\r\n      if (e.touches.length !== 2) return;\r\n\r\n      // 阻止瀏覽器原生縮放與外層容器手勢。\r\n      e.preventDefault();\r\n      e.stopPropagation();\r\n\r\n      // 快照這次 pinch 的起始狀態。\r\n      beginPinchSession(e.touches);\r\n    };\r\n\r\n    const onTouchMove = (e: TouchEvent): void => {\r\n      // 不是雙指 move 時，不介入原本其他觸控流程\r\n      if (e.touches.length !== 2) return;\r\n\r\n      // pinch 進行中的 move 一律交給自訂邏輯\r\n      e.preventDefault();\r\n      e.stopPropagation();\r\n\r\n      // 支援第一指先按住、第二指之後才加入的手勢，第一次雙指 move 只建立基準不立刻縮放\r\n      if (!pinchSession.active) {\r\n        beginPinchSession(e.touches);\r\n        return;\r\n      }\r\n\r\n      // 如果起始資料因任何原因失效，就重新建立本次 pinch 基準\r\n      if (!isPositiveFinite(pinchSession.startDistance) || !isPositiveFinite(pinchSession.startScale)) {\r\n        beginPinchSession(e.touches);\r\n        return;\r\n      }\r\n\r\n      // 重新讀取當前兩指距離與中點，作為這一幀的縮放輸入\r\n      const metrics = getTouchMetrics(e.touches);\r\n      if (!metrics) return;\r\n\r\n      // 以「目前距離 / 起始距離」算出本次 move 想要套用的相對縮放倍率\r\n      const requestedStepRatio = metrics.distance / pinchSession.startDistance;\r\n      if (!isPositiveFinite(requestedStepRatio)) return;\r\n\r\n      // 手勢過快時，不讓單一事件把 viewer 瞬間推到過大倍率，避免造成不穩定\r\n      const boundedStepRatio = Math.min(MAX_PINCH_STEP_RATIO, Math.max(1 / MAX_PINCH_STEP_RATIO, requestedStepRatio));\r\n      const nextScale = clampScale(pinchSession.startScale * boundedStepRatio);\r\n      \r\n      // 這個比例後面用來把起始文件焦點換算成縮放後的新位置\r\n      const scaleRatio = nextScale / pinchSession.startScale;\r\n      if (!isPositiveFinite(scaleRatio)) return;\r\n\r\n      // 先把 viewer zoom 更新，再做 scroll 補償\r\n      if (!applyViewerScale(nextScale)) return;\r\n\r\n      const nextDocFocalX = pinchSession.startDocFocalX * scaleRatio;\r\n      const nextDocFocalY = pinchSession.startDocFocalY * scaleRatio;\r\n\r\n      // 讓「手勢起始時中點下方的文件位置」在當前縮放後仍對齊到目前中點\r\n      scheduleScrollCompensation(\r\n        nextDocFocalX - metrics.viewportMidX,\r\n        nextDocFocalY - metrics.viewportMidY\r\n      );\r\n\r\n      /**\r\n       * 這次縮放成功後，把目前的距離、倍率和焦點位置存回去，當成下一次 touchmove 的新起點\r\n       * 如果當次因為滑太快而只先套用一部分縮放設定，剩下還沒追上的差距就留給後面的 move 再補上\r\n       */\r\n      pinchSession.startDistance = pinchSession.startDistance * scaleRatio;\r\n      pinchSession.startScale = nextScale;\r\n      pinchSession.startDocFocalX = nextDocFocalX;\r\n      pinchSession.startDocFocalY = nextDocFocalY;\r\n    };\r\n\r\n    const onTouchEnd = (e: TouchEvent): void => {\r\n      // 還保有雙指時，代表 pinch 尚未結束，不重置狀態\r\n      if (e.touches.length < 2) {\r\n        // 只有在真的有進行 pinch 時，才需要攔截瀏覽器的結束行為\r\n        if (pinchSession.active) {\r\n          e.preventDefault();\r\n          e.stopPropagation();\r\n        }\r\n\r\n        // 手指少於兩根就結束本次 pinch session，回到一般閱讀狀態\r\n        resetPinchSession();\r\n      }\r\n    };\r\n\r\n    // touch 事件同樣必須使用 passive: false，才能阻止瀏覽器原生 gesture\r\n    scrollEl.addEventListener('touchstart', onTouchStart, { passive: false });\r\n    scrollEl.addEventListener('touchmove', onTouchMove, { passive: false });\r\n    scrollEl.addEventListener('touchend', onTouchEnd, { passive: false });\r\n    scrollEl.addEventListener('touchcancel', onTouchEnd, { passive: false });\r\n\r\n    // 用於銷毀時恢復 DOM 與事件狀態，避免殘留 listener 或 touchAction 影響下次開啟\r\n    this.cleanupFns.push(() => {\r\n      // 還原外部原本設定的 touchAction，避免污染 viewer 容器既有樣式\r\n      scrollEl.style.touchAction = originalTouchAction;\r\n      // 取消任何尚未執行的 scroll 補償排程\r\n      cancelScheduledScroll();\r\n      // 移除所有註冊的事件\r\n      scrollEl.removeEventListener('wheel', onWheel);\r\n      scrollEl.removeEventListener('touchstart', onTouchStart);\r\n      scrollEl.removeEventListener('touchmove', onTouchMove);\r\n      scrollEl.removeEventListener('touchend', onTouchEnd);\r\n      scrollEl.removeEventListener('touchcancel', onTouchEnd);\r\n    });\r\n  }\r\n\r\n  /** 清除所有 smart zoom 事件監聽 */\r\n  public cleanupZoom(): void {\r\n    this.cleanupFns.forEach((fn) => fn());\r\n    this.cleanupFns = [];\r\n  }\r\n}\r\n","import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';\r\nimport { ActionSheetController } from '@ionic/angular';\r\nimport { GcPdfViewer } from '@mescius/dspdfviewer';\r\nimport { UofxFileModel } from '@uofx/app-components/file-helper';\r\nimport { UofxI18NService } from '@uofx/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { PdfOpenStatus, UofxPdfViewerSettingInfoModel, UofxWatermarkSettingModel } from '../api/pdf.model';\r\nimport { UofxPdfLogic } from '../logic/pdf.logic';\r\n\r\n@Component({\r\n  selector: 'uofx-fullscreen-viewer-dialog',\r\n  templateUrl: './fullscreen-viewer.dialog.html',\r\n  styleUrls: ['./fullscreen-viewer.dialog.scss'],\r\n  providers: [UofxPdfLogic],\r\n})\r\nexport class UofxFullscreenViewerDialog implements AfterViewInit, OnDestroy {\r\n  /** 檢視器標題(如果未填，會顯示file.fileName) */\r\n  @Input() title: string;\r\n  /** PDF浮水印相關設定 */\r\n  @Input() watermarkSetting: UofxWatermarkSettingModel = null;\r\n  /** 是否允許viewer內點擊下載檔案 */\r\n  @Input() enabledDownloadPdf = false;\r\n  /** 要檢視的PDF檔案 */\r\n  @Input() file: UofxFileModel;\r\n  /** 是否直接將取得的pdf丟進viewer打開，不再需要經過加密動作 */\r\n  @Input() simpleOpen = false;\r\n  /** simpleOpen時，是否套用浮水印設定 */\r\n  @Input() simpleOpenWithWatermark = false;\r\n  /**\r\n   * 下載url(file:綁token的下載url、img:原始檔案url)，\r\n   * 欄位是前端用，未在 UofxFileModel裡，所以另外傳入。\r\n   */\r\n  @Input() downloadUrl: string;\r\n  /** 是否可以編輯，可編輯時才可下載原始檔 */\r\n  @Input() editable = true;\r\n  /** 是否允許下載原始檔 (editable大多是用來給表單相關的判斷，跟allowDownloadFile的使用情境還是有些不同，暫時兩個flag共存) */\r\n  @Input() allowDownloadFile = true;\r\n\r\n  /** 文件檢視器物件 */\r\n  viewer: GcPdfViewer = null;\r\n  /** openPdfStatus$ 的訂閱 */\r\n  private openPdfStatusSub$: Subscription;\r\n  /** pdf是否讀取中 */\r\n  isLoading = true;\r\n  /**\r\n   * 顯示GcPdfViewer的html element id\r\n   * -\r\n   * 產生一個GcPdfViewer只能認一組id，所以不能將此id寫死\r\n   */\r\n  viewerHtmlId = 'viewer_' + uuidv4();\r\n\r\n  constructor(\r\n    private pdfLogic: UofxPdfLogic,\r\n    private actionSheetCtrl: ActionSheetController,\r\n    private i18n: UofxI18NService\r\n  ) {}\r\n\r\n  ngAfterViewInit() {\r\n    this.initOpenPdfStatusSub();\r\n    const setting = <UofxPdfViewerSettingInfoModel>{\r\n      viewerHtmlId: this.viewerHtmlId,\r\n      watermarkSetting: this.watermarkSetting,\r\n      fullscreenMode: true,\r\n      enabledDownloadPdf: this.enabledDownloadPdf,\r\n    };\r\n    this.pdfLogic.generateGcPdfViewer(setting).then((viewer) => {\r\n      // [觀察] 預防性等待一下在讀取檔案 (item 34816)\r\n      setTimeout(() => {\r\n        this.viewer = viewer;\r\n        this.pdfLogic.registerZoomAtPoint(this.viewer);\r\n        this.openViewer();\r\n      });\r\n    });\r\n  }\r\n\r\n  ngOnDestroy() {\r\n    this.openPdfStatusSub$?.unsubscribe();\r\n    this.pdfLogic.cleanupZoom();\r\n    if (this.viewer) this.viewer.dispose();\r\n  }\r\n\r\n  /**\r\n   * 開啟viewer\r\n   * -\r\n   * 有三條路:\r\n   * 1. 正常開啟 (加密、吃浮水印)\r\n   * 2. simpleOpen (不加密、不吃浮水印)\r\n   * 3. simpleOpenWithWatermark (不加密、吃浮水印)\r\n   */\r\n  openViewer() {\r\n    if (!this.simpleOpen) {\r\n      this.pdfLogic.getInfoAndOpenPdf(this.viewer, this.file, this.watermarkSetting, this.enabledDownloadPdf);\r\n      return;\r\n    }\r\n\r\n    if (this.simpleOpenWithWatermark) {\r\n      this.pdfLogic.simpleOpenWithWatermark(this.viewer, this.file, this.watermarkSetting, this.enabledDownloadPdf);\r\n    } else {\r\n      this.pdfLogic.simpleOpen(this.viewer, this.file);\r\n    }\r\n  }\r\n\r\n  /** 點按右上角 [更多] 按鈕 */\r\n  async onMoreBtnClick() {\r\n    const actionSheet = await this.actionSheetCtrl.create({\r\n      buttons: this.setMoreItemButtons(),\r\n    });\r\n    await actionSheet.present();\r\n  }\r\n\r\n  /** 右上角 [更多] 按鈕 */\r\n  setMoreItemButtons() {\r\n    // *UKEY:\"global.pdf-fullscreen-viewer.action-sheet.download\"\r\n\r\n    const button = [];\r\n    // 下載原始檔\r\n    button.push({\r\n      text: this.i18n.trans('global.pdf-fullscreen-viewer.action-sheet.download'),\r\n      handler: () => {\r\n        this.pdfLogic.downloadPdf(false, this.downloadUrl, this.file.url);\r\n      },\r\n    });\r\n    // 取消\r\n    button.push({\r\n      text: this.i18n.trans('global.comm.button.cancel'),\r\n      role: 'cancel',\r\n    });\r\n    return button;\r\n  }\r\n\r\n  /** 開啟pdf狀態的subject訂閱 */\r\n  private initOpenPdfStatusSub() {\r\n    this.openPdfStatusSub$ = this.pdfLogic.openPdfStatus$.subscribe((status) => {\r\n      if (status === PdfOpenStatus.BeforeOpen) {\r\n        this.isLoading = true;\r\n      } else if (status === PdfOpenStatus.AfterOpen) {\r\n        this.isLoading = false;\r\n      }\r\n    });\r\n  }\r\n}\r\n","<uofx-modal-header [title]=\"title ? title : file?.fileName\">\r\n  <ion-button *ngIf=\"editable && allowDownloadFile\" class=\"uofx-btn-icon\" (click)=\"onMoreBtnClick()\">\r\n    <uofx-icon color=\"gb-500\" slot=\"icon-only\" size=\"24\" name=\"ellipsis-horizontal\"></uofx-icon>\r\n  </ion-button>\r\n</uofx-modal-header>\r\n<ion-content fullscreen>\r\n  <div class=\"viewer-wrapper\">\r\n    <div [attr.id]=\"viewerHtmlId\" class=\"viewer-content\" [ngClass]=\"{ 'toolbar-hidden': isLoading }\"></div>\r\n\r\n    <div class=\"viewer-loading-mask\" *ngIf=\"isLoading\">\r\n      <ion-spinner></ion-spinner>\r\n    </div>\r\n  </div>\r\n</ion-content>\r\n","import {\r\n  AfterViewInit,\r\n  Component,\r\n  EventEmitter,\r\n  Input,\r\n  OnChanges,\r\n  OnDestroy,\r\n  Output,\r\n  SimpleChanges,\r\n} from '@angular/core';\r\nimport { ModalController } from '@ionic/angular';\r\nimport { GcPdfViewer } from '@mescius/dspdfviewer';\r\nimport { UofxFileDownloadHelper, UofxFileModel } from '@uofx/app-components/file-helper';\r\nimport { Subject, Subscription } from 'rxjs';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { PdfOpenStatus, UofxPdfViewerSettingInfoModel, UofxWatermarkSettingModel } from './api/pdf.model';\r\nimport { UofxFullscreenViewerDialog } from './fullscreen-viewer/fullscreen-viewer.dialog';\r\nimport { UofxPdfLogic } from './logic/pdf.logic';\r\n\r\n@Component({\r\n  selector: 'uofx-pdf-viewer',\r\n  templateUrl: './pdf-viewer.component.html',\r\n  styleUrls: ['./pdf-viewer.component.scss'],\r\n  providers: [UofxPdfLogic],\r\n})\r\nexport class UofxPdfViewerComponent implements OnChanges, OnDestroy, AfterViewInit {\r\n  /** 要檢視的PDF檔案 */\r\n  @Input() file: UofxFileModel;\r\n  /** viewer的高度 */\r\n  @Input() viewerHeight = null;\r\n  /** PDF浮水印相關設定 */\r\n  @Input() watermarkSetting: UofxWatermarkSettingModel = null;\r\n  /** 是否允許viewer內點擊下載檔案 */\r\n  @Input() enabledDownloadPdf = false;\r\n  /** 是否可以編輯，可編輯時才可下載原始檔 */\r\n  @Input() editable = true;\r\n  /** 要開啟pdf檔案的subject */\r\n  @Input() openPdfSubject: Subject<UofxFileModel> = null;\r\n  /** pdf開啟前事件 */\r\n  @Output() beforeOpenPdf = new EventEmitter();\r\n  /** pdf開啟前事件 */\r\n  @Output() afterOpenPdf = new EventEmitter();\r\n\r\n  /**\r\n   * 顯示GcPdfViewer的html element id\r\n   * -\r\n   * 產生一個GcPdfViewer只能認一組id，所以不能將此id寫死\r\n   */\r\n  viewerHtmlId = 'viewer_' + uuidv4();\r\n  /** 文件檢視器物件 */\r\n  viewer: GcPdfViewer = null;\r\n  /** openPdfSubject 的訂閱 */\r\n  private openPdfSub$: Subscription;\r\n  /** openPdfStatus$ 的訂閱 */\r\n  private openPdfStatusSub$: Subscription;\r\n  /** pdf是否讀取中 */\r\n  isLoading = true;\r\n\r\n  constructor(\r\n    private modalCtrl: ModalController,\r\n    private pdfLogic: UofxPdfLogic,\r\n    private downloadHelper: UofxFileDownloadHelper\r\n  ) {}\r\n\r\n  ngAfterViewInit(): void {\r\n    this.initSubscribe();\r\n    // 產生pdf viewer物件\r\n    const setting = <UofxPdfViewerSettingInfoModel>{\r\n      viewerHtmlId: this.viewerHtmlId,\r\n      watermarkSetting: this.watermarkSetting,\r\n      fullscreenMode: false,\r\n      enabledDownloadPdf: this.enabledDownloadPdf,\r\n    };\r\n    this.pdfLogic.generateGcPdfViewer(setting).then((viewer) => {\r\n      // [觀察] 預防性等待一下在讀取檔案 (item 34816)\r\n      setTimeout(() => {\r\n        this.viewer = viewer;\r\n        this.addToolbarFullscreenItem();\r\n        this.pdfLogic.registerZoomAtPoint(this.viewer);\r\n        this.pdfLogic.beforeOpenPdf(this.viewer, this.file, this.watermarkSetting, this.enabledDownloadPdf);\r\n      });\r\n    });\r\n  }\r\n\r\n  ngOnDestroy() {\r\n    this.openPdfSub$?.unsubscribe();\r\n    this.openPdfStatusSub$?.unsubscribe();\r\n    this.pdfLogic.cleanupZoom();\r\n    if (this.viewer) this.viewer.dispose();\r\n  }\r\n\r\n  ngOnChanges(changes: SimpleChanges) {\r\n    if (changes['file'] && (changes['file'].currentValue === undefined || changes['file'].firstChange)) return;\r\n    this.pdfLogic.beforeOpenPdf(this.viewer, this.file, this.watermarkSetting, this.enabledDownloadPdf);\r\n  }\r\n\r\n  /**\r\n   * 新增開滿版dialog的toolbar item\r\n   * -\r\n   * 開啟fullscreen會在這邊做而不是搬到logic呼叫\r\n   * 是為了防止import cycle的發生\r\n   */\r\n  private addToolbarFullscreenItem() {\r\n    this.pdfLogic.addToolbarItem(\r\n      this.viewer,\r\n      this.pdfLogic.getCustomFullscreenKey(),\r\n      'M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z',\r\n      () => {\r\n        this.openFullscreen();\r\n      }\r\n    );\r\n  }\r\n\r\n  /** 開啟滿版dialog觀看viewer */\r\n  private async openFullscreen() {\r\n    const convertFileUrl = this.downloadHelper.getDownloadUrl(this.file.fileName, this.file.url, this.file.rawUrl);\r\n\r\n    const modal = await this.modalCtrl.create({\r\n      component: UofxFullscreenViewerDialog,\r\n      componentProps: {\r\n        file: this.file,\r\n        watermarkSetting: this.watermarkSetting,\r\n        enabledDownloadPdf: this.enabledDownloadPdf,\r\n        editable: this.editable,\r\n        downloadUrl: convertFileUrl.downloadUrl,\r\n      },\r\n    });\r\n    modal.onWillDismiss().then(() => {\r\n      this.modalDismissLogic();\r\n    });\r\n    await modal.present();\r\n  }\r\n\r\n  /**\r\n   * modal關閉，重新判斷viewer是否有fullscreen的按鈕\r\n   * -\r\n   * fullscreen的viewer不會有'custom-fullscreen'這個key，\r\n   * 當關掉fullscreen後外層的viewer fullscreen key也會一起被拿掉了，\r\n   * 暫時靠dismiss事件來處理這段\r\n   * -\r\n   * 1. if: 沒有fullscreen，並且有download，要放在download前面\r\n   * 2. else: 沒有fullscreen，並且沒有download，直接擺最後面\r\n   */\r\n  private modalDismissLogic() {\r\n    const toolbarItems = this.viewer.toolbarLayout.viewer.mobile;\r\n    const cusFullscreenKey = this.pdfLogic.getCustomFullscreenKey();\r\n    const hasFullscreenItem = toolbarItems.includes(cusFullscreenKey);\r\n\r\n    if (hasFullscreenItem) return;\r\n\r\n    const downloadIndex = toolbarItems.findIndex((item) => item === this.pdfLogic.getCustomDownloadKey());\r\n    if (downloadIndex !== -1) {\r\n      // fullscreen一律放在downlod按鈕前面\r\n      toolbarItems.splice(downloadIndex, 0, cusFullscreenKey);\r\n    } else {\r\n      toolbarItems.push(cusFullscreenKey);\r\n    }\r\n    this.viewer.toolbarLayout.viewer.default = toolbarItems;\r\n    this.viewer.toolbarLayout.viewer.mobile = toolbarItems;\r\n    this.pdfLogic.viewerApply(this.viewer);\r\n  }\r\n\r\n  /** 初始化訂閱 */\r\n  private initSubscribe() {\r\n    if (this.openPdfSubject) this.openPdfSubscribe();\r\n    this.openPdfStatusSub();\r\n  }\r\n\r\n  /** 更換pdf時要open新的pdf的訂閱 */\r\n  private openPdfSubscribe() {\r\n    this.openPdfSub$ = this.openPdfSubject.subscribe((file) => {\r\n      this.file = file;\r\n      this.pdfLogic.beforeOpenPdf(this.viewer, this.file, this.watermarkSetting, this.enabledDownloadPdf);\r\n    });\r\n  }\r\n\r\n  /** 開啟pdf狀態的subject訂閱 */\r\n  private openPdfStatusSub() {\r\n    this.openPdfStatusSub$ = this.pdfLogic.openPdfStatus$.subscribe((status) => {\r\n      if (status === PdfOpenStatus.BeforeOpen) {\r\n        this.isLoading = true;\r\n        this.beforeOpenPdf.emit();\r\n      } else if (status === PdfOpenStatus.AfterOpen) {\r\n        this.isLoading = false;\r\n        this.afterOpenPdf.emit();\r\n      }\r\n    });\r\n  }\r\n}\r\n","<div class=\"viewer-wrapper\" [style.height]=\"viewerHeight || '100%'\">\r\n  <div [attr.id]=\"viewerHtmlId\" class=\"viewer-content\" [ngClass]=\"{ 'toolbar-hidden': isLoading }\"></div>\r\n\r\n  <div *ngIf=\"isLoading\" class=\"viewer-loading-mask\">\r\n    <ion-spinner></ion-spinner>\r\n  </div>\r\n</div>\r\n","import { CommonModule } from '@angular/common';\r\nimport { NgModule } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { IonicModule } from '@ionic/angular';\r\nimport { UofxTranslateModule } from '@uofx/app-components';\r\nimport { UofxIconModule } from '@uofx/app-components/icon';\r\nimport { UofxModalModule } from '@uofx/app-components/modal';\r\n\r\nimport { UofxFullscreenViewerDialog } from './fullscreen-viewer/fullscreen-viewer.dialog';\r\nimport { UofxPdfLogic } from './logic/pdf.logic';\r\nimport { UofxPdfViewerComponent } from './pdf-viewer.component';\r\n\r\nconst COMPONENTS = [UofxPdfViewerComponent, UofxFullscreenViewerDialog];\r\n\r\n@NgModule({\r\n  imports: [CommonModule, FormsModule, IonicModule, UofxIconModule, UofxModalModule, UofxTranslateModule],\r\n  exports: [...COMPONENTS],\r\n  declarations: [...COMPONENTS],\r\n  providers: [UofxPdfLogic],\r\n})\r\nexport class UofxPdfViewerModule {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2.UofxPdfService","uuidv4","i1.UofxPdfLogic","i2.UofxPdfLogic","i3"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwCA;IACY;AAAZ,CAAA,UAAY,aAAa,EAAA;AACvB,IAAA,aAAA,CAAA,aAAA,CAAA,YAAA,CAAA,GAAA,CAAA,CAAA,GAAA,YAAU;AACV,IAAA,aAAA,CAAA,aAAA,CAAA,WAAA,CAAA,GAAA,CAAA,CAAA,GAAA,WAAS;AACX,CAAC,EAHW,aAAa,KAAb,aAAa,GAGxB,EAAA,CAAA,CAAA;;MCnCY,cAAc,CAAA;AACL,IAAA,IAAA;AAApB,IAAA,WAAA,CAAoB,IAAgB,EAAA;QAAhB,IAAI,CAAA,IAAA,GAAJ,IAAI;;;AAGjB,IAAA,iBAAiB,CAAC,KAAkC,EAAA;QACzD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAyB,CAAuC,qCAAA,CAAA,EAAE,KAAK,CAAC;;;IAIxF,YAAY,CAAC,MAAc,EAAE,KAAe,EAAA;AACjD,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAS,CAAyC,sCAAA,EAAA,MAAM,CAAE,CAAA,EAAE,KAAK,CAAC;;wGAV9E,cAAc,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;4GAAd,cAAc,EAAA,CAAA;;4FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B;;;MCQY,YAAY,CAAA;AAmDb,IAAA,cAAA;AACA,IAAA,UAAA;AACA,IAAA,WAAA;;IAnDV,UAAU,GAAG,EAAE;;IAEf,OAAO,GAAG,EAAE;;IAEZ,MAAM,GAAG,EAAE;;AAEX,IAAA,cAAc,GAAG,IAAI,OAAO,EAAiB;;IAE7C,QAAQ,GAAG,EAAE;;;;;;;;IAUI,OAAO,GAAG,kBAAkB;;IAE5B,MAAM,GAAG,kBAAkB;;IAE3B,uBAAuB,GACtC,ssBAAssB;AACxsB;;;AAGG;IACc,eAAe,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC;;AAEtD,IAAA,iBAAiB,GAAG,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,gBAAgB,CAAC;AAC1G;;;AAGG;AACc,IAAA,mBAAmB;;IAEnB,qBAAqB,GAAG,mBAAmB;;IAE3C,mBAAmB,GAAG,iBAAiB;;AAIhD,IAAA,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;;IAGlC,UAAU,GAAmB,EAAE;AAEvC,IAAA,WAAA,CACU,cAAsC,EACtC,UAA0B,EAC1B,WAA4B,EAAA;QAF5B,IAAc,CAAA,cAAA,GAAd,cAAc;QACd,IAAU,CAAA,UAAA,GAAV,UAAU;QACV,IAAW,CAAA,WAAA,GAAX,WAAW;QAEnB,IAAI,CAAC,mBAAmB,GAAG;AACzB,YAAA,OAAO,EAAE;gBACP,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,wCAAwC,CAAC;gBACjF,cAAc,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,uCAAuC,CAAC;AAChF,aAAA;AACD,YAAA,cAAc,EAAE;AACd,gBAAA,WAAW,EAAE;oBACX,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,yCAAyC,CAAC;oBACxE,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,yCAAyC,CAAC;AACzE,iBAAA;AACF,aAAA;SACF;;;AAII,IAAA,mBAAmB,CAAC,OAAsC,EAAA;;AAE/D,QAAA,WAAW,CAAC,UAAU,GAAG,IAAI,CAAC,uBAAuB;;AAGrD,QAAA,IAAI,YAAY;;AAGhB,QAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAI;AAC7B,YAAA,WAAW,CAAC;AACT,iBAAA,IAAI,CAAC;gBACJ,SAAS,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE;AAC7D,gBAAA,SAAS,EAAE,QAAQ;aACpB;iBACA,IAAI,CAAC,MAAK;AACT,gBAAA,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;gBAC3C,YAAY,CAAC,gBAAgB,EAAE;AAC/B,gBAAA,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE,OAAO,CAAC;AAClD,gBAAA,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,OAAO,CAAC;gBAC7C,OAAO,CAAC,YAAY,CAAC;AACvB,aAAC,CAAC;AACN,SAAC,CAAC;;;IAII,sBAAsB,CAAC,MAAmB,EAAE,OAAsC,EAAA;;QAExF,MAAM,cAAc,GAClB,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,CAAC;cACjD,IAAI,CAAC;AACP,cAAE,IAAI,CAAC,eAAe;AAE1B,QAAA,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE;AACnF,YAAA,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC;;AAGjD,QAAA,IAAI,OAAO,CAAC,kBAAkB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE;AACpF,YAAA,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC;AAC7C,YAAA,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC;;AAGrC,QAAA,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE;;;AAI3E,IAAA,cAAc,CAAC,OAAsC,EAAA;;QAE3D,OAAO,IAAI,WAAW,CAAC,CAAA,CAAA,EAAI,OAAO,CAAC,YAAY,EAAE,EAAE;AACjD,YAAA,SAAS,EAAE,4CAA4C;AACvD,YAAA,OAAO,EAAE,uCAAuC;AAChD,YAAA,QAAQ,EAAE,UAAU;AACpB,YAAA,uBAAuB,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC;AAC5F,YAAA,gBAAgB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;AACpE,SAAA,CAAC;;;IAII,iBAAiB,CAAC,MAAmB,EAAE,OAAsC,EAAA;AACnF,QAAA,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAK;AAC/B,YAAA,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC;AACxC,SAAC,CAAC;;;IAII,gBAAgB,CAAC,MAAmB,EAAE,OAAsC,EAAA;;QAElF,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;;AAE7E,QAAA,QAAQ,CAAC,aAAa,CAAC,CAAI,CAAA,EAAA,OAAO,CAAC,YAAY,CAAA,UAAA,CAAY,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,GAAG,MAAM;;QAGtF,UAAU,CAAC,MAAK;YACd,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;AACnD,SAAC,CAAC;;AAGJ;;;;;AAKG;IACK,kBAAkB,CAAC,KAAK,EAAE,gBAA2C,EAAA;AAC3E,QAAA,IAAI,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE;AAC3C,YAAA,OAAO,KAAK;;aACP;AACL,YAAA,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;AAClB,YAAA,OAAO,IAAI;;;;AAKR,IAAA,aAAa,CAClB,MAAmB,EACnB,IAAmB,EACnB,gBAA2C,EAC3C,kBAA2B,EAAA;;AAG3B,QAAA,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM;YAAE;;QAEtD,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC;YAAE;;QAEtC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC;;QAEnD,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,kBAAkB,CAAC;;AAG5E;;;;AAIG;IACK,YAAY,CAAC,MAAmB,EAAE,IAAmB,EAAA;QAC3D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACvB,UAAU,CAAC,MAAK;AACd,gBAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;AAC1B,aAAC,CAAC;AACF,YAAA,OAAO,KAAK;;AAEd,QAAA,OAAO,IAAI;;AAGb;;;;;AAKG;AACI,IAAA,iBAAiB,CACtB,MAAmB,EACnB,IAAmB,EACnB,gBAA2C,EAC3C,kBAA2B,EAAA;AAE3B,QAAA,QAAQ,CAAC;YACP,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,yBAAyB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AACtG,YAAA,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAA8B;gBAC7D,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,gBAAgB,EAAE,gBAAgB,IAAI,EAAE;AACxC,gBAAA,kBAAkB,EAAE,kBAAkB;AACtC,gBAAA,YAAY,EAAE,KAAK;aACpB,CAAC;SACH,CAAC,CAAC,SAAS,CAAC;AACX,YAAA,IAAI,EAAE,CAAC,OAAO,KAAI;AAChB,gBAAA,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC;aAC1C;YACD,QAAQ,EAAE,MAAK;AACb,gBAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC;aAChC;AACF,SAAA,CAAC;;AAGJ;;;;;AAKG;IACK,mBAAmB,CAAC,OAAyC,EAAE,MAAmB,EAAA;AACxF,QAAA,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;AAC/E,QAAA,IAAI,OAAO;AAAE,YAAA,MAAM,CAAC,OAAO,CAAC,QAAQ,GAAG,OAAO;QAC9C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO;QACjC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM;;;IAIzB,YAAY,CAAC,MAAmB,EAAE,IAAmB,EAAA;;AAE3D,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;AAExB,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE;AACrB,YAAA,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;AAC/D,YAAA,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;YACxB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE;AACnC,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE;;aACpB;YACL,MAAM,CAAC,IAAI,EAAE;AACb,YAAA,IAAI,CAAC,UAAU,GAAG,EAAE;;;;AAKjB,IAAA,WAAW,CAAC,MAAmB,EAAA;QACpC,MAAM,CAAC,YAAY,EAAE;QACrB,MAAM,CAAC,kBAAkB,EAAE;;;AAIrB,IAAA,OAAO,CAAC,IAAmB,EAAA;QACjC,OAAO,IAAI,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE;;;IAIpC,UAAU,GAAA;QAChB,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,EAAE;;;AAIpC,IAAA,gBAAgB,CAAC,gBAA2C,EAAA;AAClE,QAAA,OAAO,gBAAgB,IAAI,gBAAgB,CAAC,gBAAgB;;;AAItD,IAAA,sBAAsB,CAAC,MAAmB,EAAA;QAChD,OAAO,MAAM,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC;;;AAIzC,IAAA,qBAAqB,CAAC,MAAmB,EAAA;AAC/C,QAAA,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;AAAE,YAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;AAC9D,QAAA,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE;;;AAIhC,IAAA,sBAAsB,CAAC,MAAmB,EAAA;AAChD,QAAA,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,6CAA6C,EAAE,MAAK;AACxG,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;AAClD,SAAC,CAAC;;AAGJ;;;;;AAKG;AACI,IAAA,WAAW,CAAC,QAAiB,EAAE,WAAmB,EAAE,GAAW,EAAA;AACpE,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM;;;QAIzC,IAAI,SAAS,EAAE;YACb,MAAM,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ;YACtF,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,WAAW,EAAE,QAAQ,CAAC;;aACzD;YACL,IAAI,CAAC,cAAc,CAAC,2BAA2B,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,CAAC;;;AAI/E;;;;;;;;AAQG;AACI,IAAA,cAAc,CAAC,MAAmB,EAAE,GAAW,EAAE,WAAmB,EAAE,MAAW,EAAA;QACtF,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;AACrC,QAAA,MAAM,MAAM,GAAG;AACb,YAAA,GAAG,EAAE,GAAG;AACR,YAAA,IAAI,EAAE;AACJ,gBAAA,IAAI,EAAE,KAAK;AACX,gBAAA,OAAO,EAAE,KAAK,CAAC,aAAa,CAC1B,KAAK,EACL;AACE,oBAAA,KAAK,EAAE,4BAA4B;AACnC,oBAAA,OAAO,EAAE,KAAK;AACd,oBAAA,KAAK,EAAE,IAAI;AACX,oBAAA,MAAM,EAAE,IAAI;AACZ,oBAAA,OAAO,EAAE,WAAW;AACpB,oBAAA,IAAI,EAAE,SAAS;AAChB,iBAAA,EACD,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAChD;AACF,aAAA;AACD,YAAA,KAAK,EAAE,EAAE;AACT,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,QAAQ,EAAE,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC;SAC9C;QACD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;;;IAI5B,sBAAsB,GAAA;QAC3B,OAAO,IAAI,CAAC,qBAAqB;;;IAI5B,oBAAoB,GAAA;QACzB,OAAO,IAAI,CAAC,mBAAmB;;;IAI1B,UAAU,CAAC,MAAmB,EAAE,IAAS,EAAA;AAC9C,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM;AAC1B,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC;;;AAI1B,IAAA,uBAAuB,CAC5B,MAAmB,EACnB,IAAmB,EACnB,gBAA2C,EAC3C,kBAA2B,EAAA;AAE3B,QAAA,MAAM,QAAQ,GAAgC;YAC5C,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,GAAG,EAAE,IAAI,CAAC,MAAM;YAChB,gBAAgB,EAAE,gBAAgB,IAAI,EAAE;AACxC,YAAA,kBAAkB,EAAE,kBAAkB;AACtC,YAAA,YAAY,EAAE,IAAI;SACnB;QACD,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC;AACpD,YAAA,IAAI,EAAE,CAAC,GAAG,KAAI;AACZ,gBAAA,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO;AAC1B,gBAAA,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM;aACzB;YACD,QAAQ,EAAE,MAAK;AACb,gBAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC;aAChC;AACF,SAAA,CAAC;;AAGJ;;;;AAIG;AACI,IAAA,mBAAmB,CAAC,MAAmB,EAAA;;AAE5C,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAyB;AACjD,QAAA,IAAI,CAAC,QAAQ;YAAE;AAEf;;;AAGG;;;;AAKH,QAAA,MAAM,mBAAmB,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW;;QAEtD,MAAM,eAAe,GAAG,aAAa;;AAErC,QAAA,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG,eAAe;;QAG5C,MAAM,SAAS,GAAG,IAAI;;QAEtB,MAAM,SAAS,GAAG,CAAC;;QAEnB,MAAM,iBAAiB,GAAG,KAAK;;QAE/B,MAAM,oBAAoB,GAAG,MAAM;;QAEnC,MAAM,oBAAoB,GAAG,GAAG;;QA2BhC,IAAI,oBAAoB,GAAkB,IAAI;;AAG9C,QAAA,MAAM,YAAY,GAAiB;AACjC,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,aAAa,EAAE,CAAC;AAChB,YAAA,UAAU,EAAE,CAAC;AACb,YAAA,cAAc,EAAE,CAAC;AACjB,YAAA,cAAc,EAAE,CAAC;SAClB;;AAGD,QAAA,MAAM,gBAAgB,GAAG,CAAC,KAAa,KAAc,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;;QAGxF,MAAM,qBAAqB,GAAG,MAAW;AACvC,YAAA,IAAI,oBAAoB,KAAK,IAAI,EAAE;gBACjC,oBAAoB,CAAC,oBAAoB,CAAC;gBAC1C,oBAAoB,GAAG,IAAI;;AAE/B,SAAC;;AAGD,QAAA,MAAM,0BAA0B,GAAG,CAAC,cAAsB,EAAE,aAAqB,KAAU;;AAEzF,YAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAAE;AAEzE,YAAA,qBAAqB,EAAE;AACvB,YAAA,oBAAoB,GAAG,qBAAqB,CAAC,MAAK;gBAChD,oBAAoB,GAAG,IAAI;;AAE3B,gBAAA,QAAQ,CAAC,UAAU,GAAG,cAAc;AACpC,gBAAA,QAAQ,CAAC,SAAS,GAAG,aAAa;AACpC,aAAC,CAAC;AACJ,SAAC;;QAGD,MAAM,UAAU,GAAG,CAAC,KAAa,KAAa,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;;QAG7F,MAAM,cAAc,GAAG,MAAa;YAClC,MAAM,YAAY,GAAG,MAAM,CAAE,MAAc,CAAC,YAAY,CAAC;YACzD,IAAI,gBAAgB,CAAC,YAAY,CAAC;AAAE,gBAAA,OAAO,YAAY;YAEvD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,GAAG;YAChD,IAAI,gBAAgB,CAAC,SAAS,CAAC;AAAE,gBAAA,OAAO,SAAS;AAEjD,YAAA,OAAO,CAAC;AACV,SAAC;;AAGD,QAAA,MAAM,gBAAgB,GAAG,CAAC,KAAa,KAAa;AAClD,YAAA,MAAM,SAAS,GAAG,KAAK,GAAG,GAAG;AAC7B,YAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,gBAAA,OAAO,KAAK;AAE7C,YAAA,MAAM,CAAC,SAAS,GAAG,SAAS;YAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAClD,SAAC;;AAGD,QAAA,MAAM,eAAe,GAAG,CAAC,OAA4B,KAAyB;;AAE5E,YAAA,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;AAAE,gBAAA,OAAO,IAAI;AAEjD,YAAA,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC;AAC7B,YAAA,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;;YAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,WAAW,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,EACxC,WAAW,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CACzC;AACD,YAAA,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AAAE,gBAAA,OAAO,IAAI;;AAG5C,YAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE;YAC7C,OAAO;gBACL,QAAQ;AACR,gBAAA,YAAY,EAAE,CAAC,UAAU,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;AACxE,gBAAA,YAAY,EAAE,CAAC,UAAU,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;aACxE;AACH,SAAC;;QAGD,MAAM,iBAAiB,GAAG,MAAW;AACnC,YAAA,YAAY,CAAC,MAAM,GAAG,KAAK;AAC3B,YAAA,YAAY,CAAC,aAAa,GAAG,CAAC;AAC9B,YAAA,YAAY,CAAC,UAAU,GAAG,CAAC;AAC3B,YAAA,YAAY,CAAC,cAAc,GAAG,CAAC;AAC/B,YAAA,YAAY,CAAC,cAAc,GAAG,CAAC;AAC/B,YAAA,qBAAqB,EAAE;AACvB,YAAA,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG,eAAe;AAC9C,SAAC;;AAGD,QAAA,MAAM,iBAAiB,GAAG,CAAC,OAA4B,KAAa;AAClE,YAAA,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC;AACxC,YAAA,MAAM,UAAU,GAAG,cAAc,EAAE;;YAEnC,IAAI,CAAC,OAAO,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE;AAC7C,gBAAA,iBAAiB,EAAE;AACnB,gBAAA,OAAO,KAAK;;AAGd,YAAA,YAAY,CAAC,MAAM,GAAG,IAAI;;AAE1B,YAAA,YAAY,CAAC,aAAa,GAAG,OAAO,CAAC,QAAQ;;AAE7C,YAAA,YAAY,CAAC,UAAU,GAAG,UAAU;;YAEpC,YAAY,CAAC,cAAc,GAAG,QAAQ,CAAC,UAAU,GAAG,OAAO,CAAC,YAAY;YACxE,YAAY,CAAC,cAAc,GAAG,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,YAAY;;AAEvE,YAAA,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG,oBAAoB;;AAEjD,YAAA,qBAAqB,EAAE;AACvB,YAAA,OAAO,IAAI;AACb,SAAC;;QAGD,MAAM,uBAAuB,GAAG,CAAC,QAAgB,EAAE,MAAc,EAAE,MAAc,KAAU;AACzF,YAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW;AACvC,YAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,YAAY;;YAExC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;gBAAE;;YAGpE,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,UAAU,GAAG,MAAM,IAAI,UAAU;YAC1D,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,SAAS,GAAG,MAAM,IAAI,UAAU;AACzD,YAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE;AAE1D,YAAA,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC;;AAEzC,YAAA,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC;gBAAE;;AAGrC,YAAA,0BAA0B,CAAC,MAAM,GAAG,QAAQ,CAAC,WAAW,GAAG,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,YAAY,GAAG,MAAM,CAAC;AAC7G,SAAC;;AAGD,QAAA,MAAM,OAAO,GAAG,CAAC,CAAa,KAAU;;YAEtC,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO;gBAAE;;YAG9B,CAAC,CAAC,cAAc,EAAE;YAClB,CAAC,CAAC,eAAe,EAAE;;AAGnB,YAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE;AAC7C,YAAA,MAAM,QAAQ,GAAG,cAAc,EAAE;AACjC,YAAA,uBAAuB,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;AACtH,SAAC;;AAGD,QAAA,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAE/D;;;;AAIG;AACH,QAAA,MAAM,YAAY,GAAG,CAAC,CAAa,KAAU;;AAE3C,YAAA,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE;;YAG5B,CAAC,CAAC,cAAc,EAAE;YAClB,CAAC,CAAC,eAAe,EAAE;;AAGnB,YAAA,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9B,SAAC;AAED,QAAA,MAAM,WAAW,GAAG,CAAC,CAAa,KAAU;;AAE1C,YAAA,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE;;YAG5B,CAAC,CAAC,cAAc,EAAE;YAClB,CAAC,CAAC,eAAe,EAAE;;AAGnB,YAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;AACxB,gBAAA,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC;gBAC5B;;;AAIF,YAAA,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE;AAC/F,gBAAA,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC;gBAC5B;;;YAIF,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC;AAC1C,YAAA,IAAI,CAAC,OAAO;gBAAE;;YAGd,MAAM,kBAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,YAAY,CAAC,aAAa;AACxE,YAAA,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,CAAC;gBAAE;;AAG3C,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;YAC/G,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,CAAC,UAAU,GAAG,gBAAgB,CAAC;;AAGxE,YAAA,MAAM,UAAU,GAAG,SAAS,GAAG,YAAY,CAAC,UAAU;AACtD,YAAA,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;gBAAE;;AAGnC,YAAA,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC;gBAAE;AAElC,YAAA,MAAM,aAAa,GAAG,YAAY,CAAC,cAAc,GAAG,UAAU;AAC9D,YAAA,MAAM,aAAa,GAAG,YAAY,CAAC,cAAc,GAAG,UAAU;;AAG9D,YAAA,0BAA0B,CACxB,aAAa,GAAG,OAAO,CAAC,YAAY,EACpC,aAAa,GAAG,OAAO,CAAC,YAAY,CACrC;AAED;;;AAGG;YACH,YAAY,CAAC,aAAa,GAAG,YAAY,CAAC,aAAa,GAAG,UAAU;AACpE,YAAA,YAAY,CAAC,UAAU,GAAG,SAAS;AACnC,YAAA,YAAY,CAAC,cAAc,GAAG,aAAa;AAC3C,YAAA,YAAY,CAAC,cAAc,GAAG,aAAa;AAC7C,SAAC;AAED,QAAA,MAAM,UAAU,GAAG,CAAC,CAAa,KAAU;;YAEzC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;;AAExB,gBAAA,IAAI,YAAY,CAAC,MAAM,EAAE;oBACvB,CAAC,CAAC,cAAc,EAAE;oBAClB,CAAC,CAAC,eAAe,EAAE;;;AAIrB,gBAAA,iBAAiB,EAAE;;AAEvB,SAAC;;AAGD,QAAA,QAAQ,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACzE,QAAA,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACvE,QAAA,QAAQ,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACrE,QAAA,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;;AAGxE,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAK;;AAExB,YAAA,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG,mBAAmB;;AAEhD,YAAA,qBAAqB,EAAE;;AAEvB,YAAA,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;AAC9C,YAAA,QAAQ,CAAC,mBAAmB,CAAC,YAAY,EAAE,YAAY,CAAC;AACxD,YAAA,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC;AACtD,YAAA,QAAQ,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC;AACpD,YAAA,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,UAAU,CAAC;AACzD,SAAC,CAAC;;;IAIG,WAAW,GAAA;AAChB,QAAA,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;AACrC,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;;wGA9sBX,YAAY,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,cAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,eAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;4GAAZ,YAAY,EAAA,CAAA;;4FAAZ,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB;;;MCCY,0BAA0B,CAAA;AAqC3B,IAAA,QAAA;AACA,IAAA,eAAA;AACA,IAAA,IAAA;;AArCD,IAAA,KAAK;;IAEL,gBAAgB,GAA8B,IAAI;;IAElD,kBAAkB,GAAG,KAAK;;AAE1B,IAAA,IAAI;;IAEJ,UAAU,GAAG,KAAK;;IAElB,uBAAuB,GAAG,KAAK;AACxC;;;AAGG;AACM,IAAA,WAAW;;IAEX,QAAQ,GAAG,IAAI;;IAEf,iBAAiB,GAAG,IAAI;;IAGjC,MAAM,GAAgB,IAAI;;AAElB,IAAA,iBAAiB;;IAEzB,SAAS,GAAG,IAAI;AAChB;;;;AAIG;AACH,IAAA,YAAY,GAAG,SAAS,GAAGC,EAAM,EAAE;AAEnC,IAAA,WAAA,CACU,QAAsB,EACtB,eAAsC,EACtC,IAAqB,EAAA;QAFrB,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAe,CAAA,eAAA,GAAf,eAAe;QACf,IAAI,CAAA,IAAA,GAAJ,IAAI;;IAGd,eAAe,GAAA;QACb,IAAI,CAAC,oBAAoB,EAAE;AAC3B,QAAA,MAAM,OAAO,GAAkC;YAC7C,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;AACvC,YAAA,cAAc,EAAE,IAAI;YACpB,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;SAC5C;AACD,QAAA,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAI;;YAEzD,UAAU,CAAC,MAAK;AACd,gBAAA,IAAI,CAAC,MAAM,GAAG,MAAM;gBACpB,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC9C,IAAI,CAAC,UAAU,EAAE;AACnB,aAAC,CAAC;AACJ,SAAC,CAAC;;IAGJ,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,iBAAiB,EAAE,WAAW,EAAE;AACrC,QAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;QAC3B,IAAI,IAAI,CAAC,MAAM;AAAE,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;;AAGxC;;;;;;;AAOG;IACH,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACpB,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,CAAC;YACvG;;AAGF,QAAA,IAAI,IAAI,CAAC,uBAAuB,EAAE;YAChC,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,CAAC;;aACxG;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;;;;AAKpD,IAAA,MAAM,cAAc,GAAA;QAClB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;AACpD,YAAA,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE;AACnC,SAAA,CAAC;AACF,QAAA,MAAM,WAAW,CAAC,OAAO,EAAE;;;IAI7B,kBAAkB,GAAA;;QAGhB,MAAM,MAAM,GAAG,EAAE;;QAEjB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,oDAAoD,CAAC;YAC3E,OAAO,EAAE,MAAK;AACZ,gBAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;aAClE;AACF,SAAA,CAAC;;QAEF,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC;AAClD,YAAA,IAAI,EAAE,QAAQ;AACf,SAAA,CAAC;AACF,QAAA,OAAO,MAAM;;;IAIP,oBAAoB,GAAA;AAC1B,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,MAAM,KAAI;AACzE,YAAA,IAAI,MAAM,KAAK,aAAa,CAAC,UAAU,EAAE;AACvC,gBAAA,IAAI,CAAC,SAAS,GAAG,IAAI;;AAChB,iBAAA,IAAI,MAAM,KAAK,aAAa,CAAC,SAAS,EAAE;AAC7C,gBAAA,IAAI,CAAC,SAAS,GAAG,KAAK;;AAE1B,SAAC,CAAC;;wGA3HO,0BAA0B,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAC,YAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,eAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA1B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,0BAA0B,EAF1B,QAAA,EAAA,+BAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,IAAA,EAAA,MAAA,EAAA,UAAA,EAAA,YAAA,EAAA,uBAAA,EAAA,yBAAA,EAAA,WAAA,EAAA,aAAA,EAAA,QAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,EAAA,SAAA,EAAA,CAAC,YAAY,CAAC,0BCd3B,mpBAcA,EAAA,MAAA,EAAA,CAAA,ytGAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,OAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,oBAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,SAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,wBAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,YAAA,EAAA,QAAA,EAAA,MAAA,EAAA,kBAAA,EAAA,iBAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;4FDEa,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBANtC,SAAS;+BACE,+BAA+B,EAAA,SAAA,EAG9B,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,mpBAAA,EAAA,MAAA,EAAA,CAAA,ytGAAA,CAAA,EAAA;gJAIhB,KAAK,EAAA,CAAA;sBAAb;gBAEQ,gBAAgB,EAAA,CAAA;sBAAxB;gBAEQ,kBAAkB,EAAA,CAAA;sBAA1B;gBAEQ,IAAI,EAAA,CAAA;sBAAZ;gBAEQ,UAAU,EAAA,CAAA;sBAAlB;gBAEQ,uBAAuB,EAAA,CAAA;sBAA/B;gBAKQ,WAAW,EAAA,CAAA;sBAAnB;gBAEQ,QAAQ,EAAA,CAAA;sBAAhB;gBAEQ,iBAAiB,EAAA,CAAA;sBAAzB;;;MEZU,sBAAsB,CAAA;AAkCvB,IAAA,SAAA;AACA,IAAA,QAAA;AACA,IAAA,cAAA;;AAlCD,IAAA,IAAI;;IAEJ,YAAY,GAAG,IAAI;;IAEnB,gBAAgB,GAA8B,IAAI;;IAElD,kBAAkB,GAAG,KAAK;;IAE1B,QAAQ,GAAG,IAAI;;IAEf,cAAc,GAA2B,IAAI;;AAE5C,IAAA,aAAa,GAAG,IAAI,YAAY,EAAE;;AAElC,IAAA,YAAY,GAAG,IAAI,YAAY,EAAE;AAE3C;;;;AAIG;AACH,IAAA,YAAY,GAAG,SAAS,GAAGD,EAAM,EAAE;;IAEnC,MAAM,GAAgB,IAAI;;AAElB,IAAA,WAAW;;AAEX,IAAA,iBAAiB;;IAEzB,SAAS,GAAG,IAAI;AAEhB,IAAA,WAAA,CACU,SAA0B,EAC1B,QAAsB,EACtB,cAAsC,EAAA;QAFtC,IAAS,CAAA,SAAA,GAAT,SAAS;QACT,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAc,CAAA,cAAA,GAAd,cAAc;;IAGxB,eAAe,GAAA;QACb,IAAI,CAAC,aAAa,EAAE;;AAEpB,QAAA,MAAM,OAAO,GAAkC;YAC7C,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;AACvC,YAAA,cAAc,EAAE,KAAK;YACrB,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;SAC5C;AACD,QAAA,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAI;;YAEzD,UAAU,CAAC,MAAK;AACd,gBAAA,IAAI,CAAC,MAAM,GAAG,MAAM;gBACpB,IAAI,CAAC,wBAAwB,EAAE;gBAC/B,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC9C,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,CAAC;AACrG,aAAC,CAAC;AACJ,SAAC,CAAC;;IAGJ,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE;AAC/B,QAAA,IAAI,CAAC,iBAAiB,EAAE,WAAW,EAAE;AACrC,QAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;QAC3B,IAAI,IAAI,CAAC,MAAM;AAAE,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;;AAGxC,IAAA,WAAW,CAAC,OAAsB,EAAA;QAChC,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC;YAAE;QACpG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,CAAC;;AAGrG;;;;;AAKG;IACK,wBAAwB,GAAA;AAC9B,QAAA,IAAI,CAAC,QAAQ,CAAC,cAAc,CAC1B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE,EACtC,wFAAwF,EACxF,MAAK;YACH,IAAI,CAAC,cAAc,EAAE;AACvB,SAAC,CACF;;;AAIK,IAAA,MAAM,cAAc,GAAA;QAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAE9G,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;AACxC,YAAA,SAAS,EAAE,0BAA0B;AACrC,YAAA,cAAc,EAAE;gBACd,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;gBACvC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;gBAC3C,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,WAAW,EAAE,cAAc,CAAC,WAAW;AACxC,aAAA;AACF,SAAA,CAAC;AACF,QAAA,KAAK,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,MAAK;YAC9B,IAAI,CAAC,iBAAiB,EAAE;AAC1B,SAAC,CAAC;AACF,QAAA,MAAM,KAAK,CAAC,OAAO,EAAE;;AAGvB;;;;;;;;;AASG;IACK,iBAAiB,GAAA;QACvB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM;QAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE;QAC/D,MAAM,iBAAiB,GAAG,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AAEjE,QAAA,IAAI,iBAAiB;YAAE;QAEvB,MAAM,aAAa,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;AACrG,QAAA,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE;;YAExB,YAAY,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,EAAE,gBAAgB,CAAC;;aAClD;AACL,YAAA,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC;;QAErC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,GAAG,YAAY;QACvD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,GAAG,YAAY;QACtD,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;;;IAIhC,aAAa,GAAA;QACnB,IAAI,IAAI,CAAC,cAAc;YAAE,IAAI,CAAC,gBAAgB,EAAE;QAChD,IAAI,CAAC,gBAAgB,EAAE;;;IAIjB,gBAAgB,GAAA;AACtB,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,IAAI,KAAI;AACxD,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI;YAChB,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,kBAAkB,CAAC;AACrG,SAAC,CAAC;;;IAII,gBAAgB,GAAA;AACtB,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,MAAM,KAAI;AACzE,YAAA,IAAI,MAAM,KAAK,aAAa,CAAC,UAAU,EAAE;AACvC,gBAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,gBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE;;AACpB,iBAAA,IAAI,MAAM,KAAK,aAAa,CAAC,SAAS,EAAE;AAC7C,gBAAA,IAAI,CAAC,SAAS,GAAG,KAAK;AACtB,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;AAE5B,SAAC,CAAC;;wGAjKO,sBAAsB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAF,EAAA,CAAA,eAAA,EAAA,EAAA,EAAA,KAAA,EAAAI,YAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,IAAA,CAAA,sBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAFtB,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,YAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,EAAA,OAAA,EAAA,EAAA,aAAA,EAAA,eAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,SAAA,EAAA,CAAC,YAAY,CAAC,+CCvB3B,2TAOA,EAAA,MAAA,EAAA,CAAA,6sGAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAL,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;4FDkBa,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBANlC,SAAS;+BACE,iBAAiB,EAAA,SAAA,EAGhB,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,2TAAA,EAAA,MAAA,EAAA,CAAA,6sGAAA,CAAA,EAAA;mJAIhB,IAAI,EAAA,CAAA;sBAAZ;gBAEQ,YAAY,EAAA,CAAA;sBAApB;gBAEQ,gBAAgB,EAAA,CAAA;sBAAxB;gBAEQ,kBAAkB,EAAA,CAAA;sBAA1B;gBAEQ,QAAQ,EAAA,CAAA;sBAAhB;gBAEQ,cAAc,EAAA,CAAA;sBAAtB;gBAES,aAAa,EAAA,CAAA;sBAAtB;gBAES,YAAY,EAAA,CAAA;sBAArB;;;AE7BH,MAAM,UAAU,GAAG,CAAC,sBAAsB,EAAE,0BAA0B,CAAC;MAQ1D,mBAAmB,CAAA;wGAAnB,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,iBARZ,sBAAsB,EAAE,0BAA0B,CAG1D,EAAA,OAAA,EAAA,CAAA,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,mBAAmB,CAHpF,EAAA,OAAA,EAAA,CAAA,sBAAsB,EAAE,0BAA0B,CAAA,EAAA,CAAA;AAQzD,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,EAFnB,SAAA,EAAA,CAAC,YAAY,CAAC,YAHf,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,mBAAmB,CAAA,EAAA,CAAA;;4FAK3F,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAN/B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,OAAO,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,mBAAmB,CAAC;AACvG,oBAAA,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC;AACxB,oBAAA,YAAY,EAAE,CAAC,GAAG,UAAU,CAAC;oBAC7B,SAAS,EAAE,CAAC,YAAY,CAAC;AAC1B,iBAAA;;;ACnBD;;AAEG;;;;"}