@webx-ui/module-audit 0.4.7 → 0.5.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.
- package/dist/AuditHostsPage-YFRORYHZ.js +343 -0
- package/dist/AuditHostsPage-YFRORYHZ.js.map +1 -0
- package/dist/AuditIssuesPage-BjTPgAnD.js +693 -0
- package/dist/AuditIssuesPage-BjTPgAnD.js.map +1 -0
- package/dist/AuditLayout.vue_vue_type_script_setup_true_lang-C8H5jlTe.js +66 -0
- package/dist/AuditLayout.vue_vue_type_script_setup_true_lang-C8H5jlTe.js.map +1 -0
- package/dist/AuditOverviewPage-gVpdBOAY.js +432 -0
- package/dist/AuditOverviewPage-gVpdBOAY.js.map +1 -0
- package/dist/AuditPagesPage-DNgZo-K-.js +355 -0
- package/dist/AuditPagesPage-DNgZo-K-.js.map +1 -0
- package/dist/AuditRunsPage-BbWsuATw.js +375 -0
- package/dist/AuditRunsPage-BbWsuATw.js.map +1 -0
- package/dist/AuditSettingsPage-HwfdLU_s.js +88 -0
- package/dist/AuditSettingsPage-HwfdLU_s.js.map +1 -0
- package/dist/index-BFYHJYU_.js +1880 -0
- package/dist/index-BFYHJYU_.js.map +1 -0
- package/dist/index.d.ts +30 -6
- package/dist/index.js +17 -4126
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditOverviewPage-gVpdBOAY.js","sources":["../src/AuditOverviewPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport { useAdmin, useErrorText, useTranslate, WxDate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxButton,\n WxCard,\n WxEmpty,\n WxPopover,\n WxProgress,\n WxSegmented,\n WxSkeleton,\n WxStatistic,\n WxText,\n type ProgressStatus,\n} from '@webx-ui/core'\nimport AuditLayout from './AuditLayout.vue'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditLatest, AuditRun, AuditScope, AuditSeverity } from './types'\n\n/**\n * The last run at a glance (§8): health and what it is made of, the counts by severity and by\n * group, what is new and what got fixed since the run before, and the button that starts the next one. While a run is\n * going the page asks for it every couple of seconds and shows the stage it is in.\n */\nconst props = defineProps<{ base: string }>()\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst POLL_MS = 2000\n\nconst latest = ref<AuditLatest | null>(null)\nconst scope = ref<AuditScope>('quick')\nconst starting = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nconst canRun = context.can('audit.run') || context.can('audit.manage')\n\nconst active = computed(() => latest.value?.active ?? null)\nconst done = computed(() => latest.value?.done ?? null)\nconst counts = computed(() => done.value?.counts ?? null)\n\nconst scopes = computed(() => [\n { value: 'quick', label: t('page.scope-quick') },\n { value: 'full', label: t('page.scope-full') },\n])\n\nconst severities: { key: AuditSeverity; label: string; tone: 'danger' | 'warning' | 'info' }[] = [\n { key: 'error', label: 'page.errors', tone: 'danger' },\n { key: 'warning', label: 'page.warnings', tone: 'warning' },\n { key: 'notice', label: 'page.notices', tone: 'info' },\n]\n\nconst parts = computed(() => counts.value?.health_parts ?? null)\n\nconst healthStatus = computed<ProgressStatus>(() => {\n const health = counts.value?.health ?? 0\n\n if (health >= 90) return 'success'\n if (health >= 60) return 'warning'\n\n return 'danger'\n})\n\n/* The groups this package has words for; a module's own group reads as «Other». */\nconst GROUPS = [\n 'config',\n 'host',\n 'hosts',\n 'indexing',\n 'page',\n 'content',\n 'links',\n 'images',\n 'a11y',\n 'structure',\n]\n\nconst groups = computed(() =>\n Object.entries(counts.value?.groups ?? {}).map(([id, bySeverity]) => ({\n id,\n label: t(`page.group-${GROUPS.includes(id) ? id : 'other'}`),\n bySeverity,\n })),\n)\n\nfunction stageLabel(run: AuditRun): string {\n if (run.status === 'queued') return t('page.status-queued')\n\n return run.progress.stage ? t(`page.stage-${run.progress.stage}`) : t('page.status-running')\n}\n\nasync function load(): Promise<void> {\n try {\n latest.value = await api.latest()\n } catch (error) {\n toast.danger(message(error))\n }\n\n clearTimeout(timer)\n\n if (latest.value?.active) {\n timer = setTimeout(() => void load(), POLL_MS)\n }\n}\n\nasync function start(): Promise<void> {\n starting.value = true\n\n try {\n await api.start(scope.value)\n toast.success(t('page.started'))\n await load()\n } catch (error) {\n toast.danger(message(error))\n } finally {\n starting.value = false\n }\n}\n\nasync function cancel(run: AuditRun): Promise<void> {\n try {\n await api.cancel(run.id)\n await load()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nonMounted(load)\nonBeforeUnmount(() => clearTimeout(timer))\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"overview\" :card=\"false\">\n <div class=\"wx-audit-overview\">\n <wx-card v-if=\"!latest\"><wx-skeleton :rows=\"4\" /></wx-card>\n\n <template v-else>\n <wx-alert v-if=\"latest.queue.sync\" type=\"warning\" :description=\"t('page.sync-queue')\" />\n\n <wx-alert\n v-if=\"latest.last && latest.last.status === 'failed'\"\n type=\"danger\"\n :description=\"t('page.last-failed', { error: latest.last.error ?? '' })\"\n />\n\n <wx-card v-if=\"active\" class=\"wx-audit-overview__active\">\n <div class=\"wx-audit-overview__row\">\n <wx-text weight=\"semibold\">{{ stageLabel(active) }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-overview__url\">{{\n active.base_url\n }}</wx-text>\n <wx-button\n v-if=\"canRun\"\n size=\"sm\"\n class=\"wx-audit-overview__end\"\n @click=\"cancel(active)\"\n >{{ t('page.cancel') }}</wx-button\n >\n </div>\n <wx-progress indeterminate :aria-label=\"stageLabel(active)\" />\n <wx-text v-if=\"active.progress.resources\" size=\"sm\" tone=\"muted\">{{\n t('page.resources-progress', {\n checked: active.progress.resources.checked,\n total: active.progress.resources.total,\n })\n }}</wx-text>\n <wx-text v-else-if=\"active.progress.stage === 'crawl'\" size=\"sm\" tone=\"muted\">{{\n t('page.pages-progress', {\n crawled: active.progress.pages.crawled,\n limit: active.progress.pages.limit,\n })\n }}</wx-text>\n </wx-card>\n\n <wx-card v-else-if=\"canRun && !latest.queue.sync\">\n <div class=\"wx-audit-overview__row\">\n <wx-segmented v-model=\"scope\" :options=\"scopes\" :aria-label=\"t('page.scope')\" />\n <wx-text size=\"sm\" tone=\"muted\">{{\n scope === 'full' ? t('page.scope-full-help') : t('page.scope-quick-help')\n }}</wx-text>\n <wx-button\n type=\"primary\"\n icon=\"refresh\"\n :loading=\"starting\"\n class=\"wx-audit-overview__end\"\n @click=\"start\"\n >{{ t('page.run') }}</wx-button\n >\n </div>\n </wx-card>\n\n <wx-card v-if=\"!done && !active\">\n <wx-empty\n icon=\"check-circle\"\n :title=\"t('page.never')\"\n :description=\"t('page.never-help')\"\n />\n </wx-card>\n\n <template v-if=\"done && counts\">\n <wx-card>\n <div class=\"wx-audit-overview__summary\">\n <div class=\"wx-audit-overview__health\">\n <wx-progress\n type=\"circle\"\n :value=\"counts.health\"\n :status=\"healthStatus\"\n show-value\n :formatter=\"(value: number) => `${value}%`\"\n :aria-label=\"t('page.health')\"\n />\n <div v-if=\"parts\" class=\"wx-audit-overview__parts\">\n <wx-text v-if=\"parts.pages > 0\" size=\"sm\">{{\n t('page.health-pages', { clean: parts.clean, pages: parts.pages })\n }}</wx-text>\n <wx-text v-if=\"parts.site_errors > 0\" size=\"sm\" tone=\"danger\">{{\n t('page.health-site', { count: parts.site_errors })\n }}</wx-text>\n <wx-text v-if=\"parts.warnings > 0\" size=\"sm\" tone=\"warning\">{{\n t('page.health-warnings', { count: parts.warnings })\n }}</wx-text>\n <wx-text size=\"xs\" tone=\"muted\">{{ t('page.health-help') }}</wx-text>\n </div>\n </div>\n <div class=\"wx-audit-overview__stats\">\n <wx-statistic\n v-for=\"severity in severities\"\n :key=\"severity.key\"\n :title=\"t(severity.label)\"\n :value=\"counts.severity[severity.key] ?? 0\"\n :tone=\"(counts.severity[severity.key] ?? 0) > 0 ? severity.tone : 'muted'\"\n />\n <wx-statistic :title=\"t('page.new')\" :value=\"counts.new\" />\n <wx-statistic :title=\"t('page.fixed')\" :value=\"counts.fixed\" tone=\"success\" />\n </div>\n </div>\n <div class=\"wx-audit-overview__meta\">\n <wx-text size=\"sm\" tone=\"muted\">\n {{ t('page.last-run') }} <wx-date :value=\"done.finished_at\" /> ·\n {{ t(`page.scope-${done.scope}`) }} ·\n </wx-text>\n <wx-text size=\"sm\" tone=\"muted\" class=\"wx-audit-overview__url\">{{\n done.base_url\n }}</wx-text>\n </div>\n </wx-card>\n\n <wx-card v-if=\"groups.length\" :title=\"t('page.by-group')\">\n <ul class=\"wx-audit-overview__groups\">\n <li v-for=\"group in groups\" :key=\"group.id\">\n <wx-text size=\"sm\">{{ group.label }}</wx-text>\n <span class=\"wx-audit-overview__badges\">\n <template v-for=\"severity in severities\" :key=\"severity.key\">\n <wx-badge\n v-if=\"(group.bySeverity[severity.key] ?? 0) > 0\"\n :type=\"severity.tone\"\n size=\"sm\"\n >{{ t(severity.label) }} · {{ group.bySeverity[severity.key] }}</wx-badge\n >\n </template>\n </span>\n </li>\n </ul>\n </wx-card>\n\n <wx-card v-else>\n <wx-empty icon=\"check-circle\" :title=\"t('page.clean')\" size=\"sm\" />\n </wx-card>\n\n <wx-card>\n <template #header>\n <span class=\"wx-audit-overview__title\">\n {{ t('page.sources') }}\n <wx-popover :title=\"t('page.sources')\" :width=\"360\" teleport>\n <template #trigger>\n <wx-button\n variant=\"text\"\n size=\"sm\"\n icon=\"question\"\n :aria-label=\"t('page.sources-help-label')\"\n />\n </template>\n <wx-text size=\"sm\">{{ t('page.sources-help') }}</wx-text>\n </wx-popover>\n </span>\n </template>\n <div class=\"wx-audit-overview__badges\">\n <wx-badge v-for=\"source in counts.sources.searched\" :key=\"source\" type=\"success\">{{\n source\n }}</wx-badge>\n </div>\n <div v-if=\"counts.sources.missing.length\" class=\"wx-audit-overview__missing\">\n <wx-text size=\"sm\" tone=\"warning\">{{ t('page.sources-missing') }}</wx-text>\n <wx-badge v-for=\"source in counts.sources.missing\" :key=\"source\" type=\"warning\">{{\n source\n }}</wx-badge>\n </div>\n </wx-card>\n </template>\n </template>\n </div>\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-overview {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n container-type: inline-size;\n}\n\n.wx-audit-overview__row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8) var(--wx-space-12);\n margin-bottom: var(--wx-space-8);\n}\n\n.wx-audit-overview__end {\n margin-left: auto;\n}\n\n.wx-audit-overview__summary {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-24);\n}\n\n.wx-audit-overview__health {\n display: flex;\n flex: 1 1 20rem;\n align-items: center;\n gap: var(--wx-space-16);\n min-width: 0;\n}\n\n/* The help is a sentence; it wraps beside the circle rather than stretching the card. */\n.wx-audit-overview__parts {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n max-width: 36ch;\n min-width: 0;\n}\n\n.wx-audit-overview__stats {\n display: flex;\n flex: 1 1 auto;\n flex-wrap: wrap;\n gap: var(--wx-space-16) var(--wx-space-32);\n}\n\n.wx-audit-overview__meta {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n margin-top: var(--wx-space-16);\n}\n\n/* A long domain breaks rather than pushing the card sideways on a phone. */\n.wx-audit-overview__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-overview__groups {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.wx-audit-overview__groups li {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-overview__badges,\n.wx-audit-overview__missing {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-overview__missing {\n margin-top: var(--wx-space-12);\n}\n\n.wx-audit-overview__title {\n display: inline-flex;\n align-items: center;\n gap: var(--wx-space-4);\n}\n</style>\n"],"names":["POLL_MS","props","__props","context","useAdmin","api","createAuditApi","useAuditMessages","t","useTranslate","message","useErrorText","latest","ref","scope","starting","timer","canRun","active","computed","done","counts","scopes","severities","parts","healthStatus","health","GROUPS","groups","id","bySeverity","stageLabel","run","load","error","toast","start","cancel","onMounted","onBeforeUnmount","_createBlock","AuditLayout","_createElementVNode","_hoisted_1","_createElementBlock","_Fragment","_unref","WxAlert","WxCard","_hoisted_2","_createVNode","WxText","_createTextVNode","_toDisplayString","WxButton","_cache","$event","WxProgress","_hoisted_3","WxSegmented","WxEmpty","_hoisted_4","_hoisted_5","value","_openBlock","_hoisted_6","_hoisted_7","_renderList","severity","WxStatistic","_hoisted_8","WxDate","_hoisted_9","group","_hoisted_10","WxBadge","_hoisted_11","WxPopover","_hoisted_12","source","_hoisted_13","WxSkeleton"],"mappings":";;;;;;;;;;;GAqCMA,KAAU;;;;;;AAThB,UAAMC,IAAQC,GAERC,IAAUC,GAAA,GACVC,IAAMC,GAAeH,CAAO;AAClC,IAAAI,GAAA;AAEA,UAAMC,IAAIC,GAAa,YAAY,GAC7BC,IAAUC,GAAA,GAIVC,IAASC,EAAwB,IAAI,GACrCC,IAAQD,EAAgB,OAAO,GAC/BE,IAAWF,EAAI,EAAK;AAC1B,QAAIG;AAEJ,UAAMC,IAASd,EAAQ,IAAI,WAAW,KAAKA,EAAQ,IAAI,cAAc,GAE/De,IAASC,EAAS,MAAMP,EAAO,OAAO,UAAU,IAAI,GACpDQ,IAAOD,EAAS,MAAMP,EAAO,OAAO,QAAQ,IAAI,GAChDS,IAASF,EAAS,MAAMC,EAAK,OAAO,UAAU,IAAI,GAElDE,IAASH,EAAS,MAAM;AAAA,MAC5B,EAAE,OAAO,SAAS,OAAOX,EAAE,kBAAkB,EAAA;AAAA,MAC7C,EAAE,OAAO,QAAQ,OAAOA,EAAE,iBAAiB,EAAA;AAAA,IAAE,CAC9C,GAEKe,IAA2F;AAAA,MAC/F,EAAE,KAAK,SAAS,OAAO,eAAe,MAAM,SAAA;AAAA,MAC5C,EAAE,KAAK,WAAW,OAAO,iBAAiB,MAAM,UAAA;AAAA,MAChD,EAAE,KAAK,UAAU,OAAO,gBAAgB,MAAM,OAAA;AAAA,IAAO,GAGjDC,IAAQL,EAAS,MAAME,EAAO,OAAO,gBAAgB,IAAI,GAEzDI,IAAeN,EAAyB,MAAM;AAClD,YAAMO,IAASL,EAAO,OAAO,UAAU;AAEvC,aAAIK,KAAU,KAAW,YACrBA,KAAU,KAAW,YAElB;AAAA,IACT,CAAC,GAGKC,IAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,GAGIC,IAAST;AAAA,MAAS,MACtB,OAAO,QAAQE,EAAO,OAAO,UAAU,EAAE,EAAE,IAAI,CAAC,CAACQ,GAAIC,CAAU,OAAO;AAAA,QACpE,IAAAD;AAAA,QACA,OAAOrB,EAAE,cAAcmB,EAAO,SAASE,CAAE,IAAIA,IAAK,OAAO,EAAE;AAAA,QAC3D,YAAAC;AAAA,MAAA,EACA;AAAA,IAAA;AAGJ,aAASC,EAAWC,GAAuB;AACzC,aAAIA,EAAI,WAAW,WAAiBxB,EAAE,oBAAoB,IAEnDwB,EAAI,SAAS,QAAQxB,EAAE,cAAcwB,EAAI,SAAS,KAAK,EAAE,IAAIxB,EAAE,qBAAqB;AAAA,IAC7F;AAEA,mBAAeyB,IAAsB;AACnC,UAAI;AACF,QAAArB,EAAO,QAAQ,MAAMP,EAAI,OAAA;AAAA,MAC3B,SAAS6B,GAAO;AACd,QAAAC,EAAM,OAAOzB,EAAQwB,CAAK,CAAC;AAAA,MAC7B;AAEA,mBAAalB,CAAK,GAEdJ,EAAO,OAAO,WAChBI,IAAQ,WAAW,MAAA;AAAM,QAAKiB,EAAA;AAAA,SAAQjC,EAAO;AAAA,IAEjD;AAEA,mBAAeoC,IAAuB;AACpC,MAAArB,EAAS,QAAQ;AAEjB,UAAI;AACF,cAAMV,EAAI,MAAMS,EAAM,KAAK,GAC3BqB,EAAM,QAAQ3B,EAAE,cAAc,CAAC,GAC/B,MAAMyB,EAAA;AAAA,MACR,SAASC,GAAO;AACd,QAAAC,EAAM,OAAOzB,EAAQwB,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAAnB,EAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,mBAAesB,EAAOL,GAA8B;AAClD,UAAI;AACF,cAAM3B,EAAI,OAAO2B,EAAI,EAAE,GACvB,MAAMC,EAAA;AAAA,MACR,SAASC,GAAO;AACd,QAAAC,EAAM,OAAOzB,EAAQwB,CAAK,CAAC;AAAA,MAC7B;AAAA,IACF;AAEA,WAAAI,EAAUL,CAAI,GACdM,EAAgB,MAAM,aAAavB,CAAK,CAAC,mBAIvCwB,EAyKeC,IAAA;AAAA,MAzKA,MAAMxC,EAAM;AAAA,MAAM,SAAQ;AAAA,MAAY,MAAM;AAAA,IAAA;iBACzD,MAuKM;AAAA,QAvKNyC,EAuKM,OAvKNC,IAuKM;AAAA,UAtKY/B,EAAA,cAEhBgC,EAmKWC,GAAA,EAAA,KAAA,KAAA;AAAA,YAlKOjC,EAAA,MAAO,MAAM,aAA7B4B,EAAwFM,EAAAC,CAAA,GAAA;AAAA;cAArD,MAAK;AAAA,cAAW,aAAaD,EAAAtC,CAAA,EAAC,iBAAA;AAAA,YAAA;YAGzDI,EAAA,MAAO,QAAQA,QAAO,KAAK,WAAM,iBADzC4B,EAIEM,EAAAC,CAAA,GAAA;AAAA;cAFA,MAAK;AAAA,cACJ,aAAaD,EAAAtC,CAAA,EAAC,oBAAA,EAAA,OAA8BI,QAAO,KAAK,SAAK,GAAA,CAAA;AAAA,YAAA;YAGjDM,EAAA,cAAfsB,EA2BUM,EAAAE,CAAA,GAAA;AAAA;cA3Ba,OAAM;AAAA,YAAA;yBAC3B,MAYM;AAAA,gBAZNN,EAYM,OAZNO,IAYM;AAAA,kBAXJC,EAA6DJ,EAAAK,CAAA,GAAA,EAApD,QAAO,cAAU;AAAA,+BAAC,MAAwB;AAAA,sBAArBC,EAAAC,EAAAtB,EAAWb,EAAA,KAAM,CAAA,GAAA,CAAA;AAAA,oBAAA;;;kBAC/CgC,EAEYJ,EAAAK,CAAA,GAAA;AAAA,oBAFH,MAAK;AAAA,oBAAK,MAAK;AAAA,oBAAQ,OAAM;AAAA,kBAAA;+BAAyB,MAE7D;AAAA,sBADAC,EAAAC,EAAAnC,EAAA,MAAO,QAAQ,GAAA,CAAA;AAAA,oBAAA;;;kBAGT4B,EAAA7B,CAAA,UADRuB,EAMCM,EAAAQ,CAAA,GAAA;AAAA;oBAJC,MAAK;AAAA,oBACL,OAAM;AAAA,oBACL,SAAKC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEnB,EAAOnB,EAAA,KAAM;AAAA,kBAAA;+BACpB,MAAsB;AAAA,0BAAnB4B,EAAAtC,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;gBAGT0C,EAA8DJ,EAAAW,CAAA,GAAA;AAAA,kBAAjD,eAAA;AAAA,kBAAe,cAAY1B,EAAWb,EAAA,KAAM;AAAA,gBAAA;gBAC1CA,EAAA,MAAO,SAAS,kBAA/BsB,EAKYM,EAAAK,CAAA,GAAA;AAAA;kBAL8B,MAAK;AAAA,kBAAK,MAAK;AAAA,gBAAA;6BAAQ,MAK/D;AAAA,wBAJAL,EAAAtC,CAAA,EAAC,2BAAA;AAAA,sBAAqD,SAAAU,EAAA,MAAO,SAAS,UAAU;AAAA,sBAA8B,OAAAA,EAAA,MAAO,SAAS,UAAU;AAAA,oBAAA;;;sBAKtHA,EAAA,MAAO,SAAS,UAAK,gBAAzCsB,EAKYM,EAAAK,CAAA,GAAA;AAAA;kBAL2C,MAAK;AAAA,kBAAK,MAAK;AAAA,gBAAA;6BAAQ,MAK5E;AAAA,wBAJAL,EAAAtC,CAAA,EAAC,uBAAA;AAAA,sBAAiD,SAAAU,EAAA,MAAO,SAAS,MAAM;AAAA,sBAA8B,OAAAA,EAAA,MAAO,SAAS,MAAM;AAAA,oBAAA;;;;;;kBAO5G4B,EAAA7B,CAAA,KAAM,CAAKL,EAAA,MAAO,MAAM,aAA5C4B,EAeUM,EAAAE,CAAA,GAAA,EAAA,KAAA,KAAA;AAAA,yBAdR,MAaM;AAAA,gBAbNN,EAaM,OAbNgB,IAaM;AAAA,kBAZJR,EAAgFJ,EAAAa,EAAA,GAAA;AAAA,gCAAzD7C,EAAA;AAAA,kEAAAA,EAAK,QAAA0C;AAAA,oBAAG,SAASlC,EAAA;AAAA,oBAAS,cAAYwB,EAAAtC,CAAA,EAAC,YAAA;AAAA,kBAAA;kBAC9D0C,EAEYJ,EAAAK,CAAA,GAAA;AAAA,oBAFH,MAAK;AAAA,oBAAK,MAAK;AAAA,kBAAA;+BAAQ,MAE9B;AAAA,0BADArC,EAAA,UAAK,SAAcgC,EAAAtC,CAAA,EAAC,sBAAA,IAA2BsC,EAAAtC,CAAA,EAAC,uBAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;kBAElD0C,EAOCJ,EAAAQ,CAAA,GAAA;AAAA,oBANC,MAAK;AAAA,oBACL,MAAK;AAAA,oBACJ,SAASvC,EAAA;AAAA,oBACV,OAAM;AAAA,oBACL,SAAOqB;AAAA,kBAAA;+BACP,MAAmB;AAAA,0BAAhBU,EAAAtC,CAAA,EAAC,UAAA,CAAA,GAAA,CAAA;AAAA,oBAAA;;;;;;;YAKK,CAAAY,EAAA,UAASF,EAAA,cAAzBsB,EAMUM,EAAAE,CAAA,GAAA,EAAA,KAAA,KAAA;AAAA,yBALR,MAIE;AAAA,gBAJFE,EAIEJ,EAAAc,CAAA,GAAA;AAAA,kBAHA,MAAK;AAAA,kBACJ,OAAOd,EAAAtC,CAAA,EAAC,YAAA;AAAA,kBACR,aAAasC,EAAAtC,CAAA,EAAC,iBAAA;AAAA,gBAAA;;;;YAIHY,EAAA,SAAQC,EAAA,cAAxBuB,EAmGWC,GAAA,EAAA,KAAA,KAAA;AAAA,cAlGTK,EA6CUJ,EAAAE,CAAA,GAAA,MAAA;AAAA,2BA5CR,MAkCM;AAAA,kBAlCNN,EAkCM,OAlCNmB,IAkCM;AAAA,oBAjCJnB,EAqBM,OArBNoB,IAqBM;AAAA,sBApBJZ,EAOEJ,EAAAW,CAAA,GAAA;AAAA,wBANA,MAAK;AAAA,wBACJ,OAAOpC,EAAA,MAAO;AAAA,wBACd,QAAQI,EAAA;AAAA,wBACT,cAAA;AAAA,wBACC,WAAS,CAAGsC,MAAa,GAAQA,CAAK;AAAA,wBACtC,cAAYjB,EAAAtC,CAAA,EAAC,aAAA;AAAA,sBAAA;sBAELgB,EAAA,SAAXwC,EAAA,GAAApB,EAWM,OAXNqB,IAWM;AAAA,wBAVWzC,EAAA,MAAM,QAAK,UAA1BgB,EAEYM,EAAAK,CAAA,GAAA;AAAA;0BAFoB,MAAK;AAAA,wBAAA;qCAAK,MAExC;AAAA,4BADAC,EAAAC,EAAAP,EAAAtC,CAAA,gCAAgCgB,EAAA,MAAM,OAAK,OAASA,EAAA,MAAM,OAAK,CAAA,GAAA,CAAA;AAAA,0BAAA;;;wBAElDA,EAAA,MAAM,cAAW,UAAhCgB,EAEYM,EAAAK,CAAA,GAAA;AAAA;0BAF0B,MAAK;AAAA,0BAAK,MAAK;AAAA,wBAAA;qCAAS,MAE5D;AAAA,gCADAL,EAAAtC,CAAA,EAAC,oBAAA,EAAA,OAA8BgB,EAAA,MAAM,YAAA,CAAW,CAAA,GAAA,CAAA;AAAA,0BAAA;;;wBAEnCA,EAAA,MAAM,WAAQ,UAA7BgB,EAEYM,EAAAK,CAAA,GAAA;AAAA;0BAFuB,MAAK;AAAA,0BAAK,MAAK;AAAA,wBAAA;qCAAU,MAE1D;AAAA,gCADAL,EAAAtC,CAAA,EAAC,wBAAA,EAAA,OAAkCgB,EAAA,MAAM,SAAA,CAAQ,CAAA,GAAA,CAAA;AAAA,0BAAA;;;wBAEnD0B,EAAqEJ,EAAAK,CAAA,GAAA;AAAA,0BAA5D,MAAK;AAAA,0BAAK,MAAK;AAAA,wBAAA;qCAAQ,MAA2B;AAAA,gCAAxBL,EAAAtC,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,0BAAA;;;;;oBAGxCkC,EAUM,OAVNwB,IAUM;AAAA,4BATJtB,EAMEC,GAAA,MAAAsB,EALmB5C,GAAU,CAAtB6C,MADTlB,EAMEJ,EAAAuB,CAAA,GAAA;AAAA,wBAJC,KAAKD,EAAS;AAAA,wBACd,OAAOtB,EAAAtC,CAAA,EAAE4D,EAAS,KAAK;AAAA,wBACvB,OAAO/C,EAAA,MAAO,SAAS+C,EAAS,GAAG,KAAA;AAAA,wBACnC,OAAO/C,EAAA,MAAO,SAAS+C,EAAS,GAAG,KAAA,KAAA,IAAcA,EAAS,OAAI;AAAA,sBAAA;sBAEjElB,EAA2DJ,EAAAuB,CAAA,GAAA;AAAA,wBAA5C,OAAOvB,EAAAtC,CAAA,EAAC,UAAA;AAAA,wBAAe,OAAOa,EAAA,MAAO;AAAA,sBAAA;sBACpD6B,EAA8EJ,EAAAuB,CAAA,GAAA;AAAA,wBAA/D,OAAOvB,EAAAtC,CAAA,EAAC,YAAA;AAAA,wBAAiB,OAAOa,EAAA,MAAO;AAAA,wBAAO,MAAK;AAAA,sBAAA;;;kBAGtEqB,EAQM,OARN4B,IAQM;AAAA,oBAPJpB,EAGUJ,EAAAK,CAAA,GAAA;AAAA,sBAHD,MAAK;AAAA,sBAAK,MAAK;AAAA,oBAAA;iCACtB,MAAwB;AAAA,wBAArBC,EAAAC,EAAAP,EAAAtC,CAAA,sBAAqB,KAAC,CAAA;AAAA,wBAAA0C,EAAqCJ,EAAAyB,EAAA,GAAA;AAAA,0BAA3B,OAAOnD,EAAA,MAAK;AAAA,wBAAA;wBAAegC,EAAA,UAC3DN,EAAAtC,CAAA,EAAC,cAAeY,QAAK,KAAK,OAAM,OACrC,CAAA;AAAA,sBAAA;;;oBACA8B,EAEYJ,EAAAK,CAAA,GAAA;AAAA,sBAFH,MAAK;AAAA,sBAAK,MAAK;AAAA,sBAAQ,OAAM;AAAA,oBAAA;iCAAyB,MAE7D;AAAA,wBADAC,EAAAC,EAAAjC,EAAA,MAAK,QAAQ,GAAA,CAAA;AAAA,sBAAA;;;;;;;cAKJQ,EAAA,MAAO,eAAtBY,EAgBUM,EAAAE,CAAA,GAAA;AAAA;gBAhBqB,OAAOF,EAAAtC,CAAA,EAAC,eAAA;AAAA,cAAA;2BACrC,MAcK;AAAA,kBAdLkC,EAcK,MAdL8B,IAcK;AAAA,4BAbH5B,EAYKC,GAAA,MAAAsB,EAZevC,EAAA,OAAM,CAAf6C,YAAX7B,EAYK,MAAA;AAAA,sBAZwB,KAAK6B,EAAM;AAAA,oBAAA;sBACtCvB,EAA8CJ,EAAAK,CAAA,GAAA,EAArC,MAAK,QAAI;AAAA,mCAAC,MAAiB;AAAA,0BAAdC,EAAAC,EAAAoB,EAAM,KAAK,GAAA,CAAA;AAAA,wBAAA;;;sBACjC/B,EASO,QATPgC,IASO;AAAA,8BARL9B,EAOWC,GAAA,MAAAsB,EAPkB5C,GAAU,CAAtB6C;0BAA8B,KAAAA,EAAS;AAAA,wBAAA;2BAE7CK,EAAM,WAAWL,EAAS,GAAG,KAAA,KAAA,UADtC5B,EAKCM,EAAA6B,CAAA,GAAA;AAAA;4BAHE,MAAMP,EAAS;AAAA,4BAChB,MAAK;AAAA,0BAAA;uCACJ,MAAuB;AAAA,8BAApBhB,EAAAC,EAAAP,EAAAtC,CAAA,EAAE4D,EAAS,KAAK,CAAA,IAAI,QAAGf,EAAGoB,EAAM,WAAWL,EAAS,GAAG,CAAA,GAAA,CAAA;AAAA,4BAAA;;;;;;;;;wCAQvE5B,EAEUM,EAAAE,CAAA,GAAA,EAAA,KAAA,KAAA;AAAA,2BADR,MAAmE;AAAA,kBAAnEE,EAAmEJ,EAAAc,CAAA,GAAA;AAAA,oBAAzD,MAAK;AAAA,oBAAgB,OAAOd,EAAAtC,CAAA,EAAC,YAAA;AAAA,oBAAgB,MAAK;AAAA,kBAAA;;;;cAG9D0C,EA4BUJ,EAAAE,CAAA,GAAA,MAAA;AAAA,gBA3BG,UACT,MAaO;AAAA,kBAbPN,EAaO,QAbPkC,IAaO;AAAA,oBAZFxB,EAAAC,EAAAP,EAAAtC,CAAA,qBAAoB,KACvB,CAAA;AAAA,oBAAA0C,EAUaJ,EAAA+B,EAAA,GAAA;AAAA,sBAVA,OAAO/B,EAAAtC,CAAA,EAAC,cAAA;AAAA,sBAAmB,OAAO;AAAA,sBAAK,UAAA;AAAA,oBAAA;sBACvC,WACT,MAKE;AAAA,wBALF0C,EAKEJ,EAAAQ,CAAA,GAAA;AAAA,0BAJA,SAAQ;AAAA,0BACR,MAAK;AAAA,0BACL,MAAK;AAAA,0BACJ,cAAYR,EAAAtC,CAAA,EAAC,yBAAA;AAAA,wBAAA;;iCAGlB,MAAyD;AAAA,wBAAzD0C,EAAyDJ,EAAAK,CAAA,GAAA,EAAhD,MAAK,QAAI;AAAA,qCAAC,MAA4B;AAAA,gCAAzBL,EAAAtC,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,0BAAA;;;;;;;;2BAI7B,MAIM;AAAA,kBAJNkC,EAIM,OAJNoC,IAIM;AAAA,qBAHJd,EAAA,EAAA,GAAApB,EAEaC,WAFcxB,EAAA,MAAO,QAAQ,WAAzB0D,YAAjBvC,EAEaM,EAAA6B,CAAA,GAAA;AAAA,sBAFwC,KAAKI;AAAA,sBAAQ,MAAK;AAAA,oBAAA;iCAAU,MAE/E;AAAA,4BADAA,CAAM,GAAA,CAAA;AAAA,sBAAA;;;;kBAGC1D,EAAA,MAAO,QAAQ,QAAQ,UAAlC2C,KAAApB,EAKM,OALNoC,IAKM;AAAA,oBAJJ9B,EAA2EJ,EAAAK,CAAA,GAAA;AAAA,sBAAlE,MAAK;AAAA,sBAAK,MAAK;AAAA,oBAAA;iCAAU,MAA+B;AAAA,4BAA5BL,EAAAtC,CAAA,EAAC,sBAAA,CAAA,GAAA,CAAA;AAAA,sBAAA;;;qBACtCwD,EAAA,EAAA,GAAApB,EAEaC,WAFcxB,EAAA,MAAO,QAAQ,UAAzB0D,YAAjBvC,EAEaM,EAAA6B,CAAA,GAAA;AAAA,sBAFuC,KAAKI;AAAA,sBAAQ,MAAK;AAAA,oBAAA;iCAAU,MAE9E;AAAA,4BADAA,CAAM,GAAA,CAAA;AAAA,sBAAA;;;;;;;;0BAhKhBvC,EAA2DM,EAAAE,CAAA,GAAA,EAAA,KAAA,KAAA;AAAA,uBAAnC,MAAyB;AAAA,cAAzBE,EAAyBJ,EAAAmC,EAAA,GAAA,EAAX,MAAM,GAAC;AAAA,YAAA;;;;;;;;;"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import { defineComponent as fe, ref as p, watch as G, computed as b, onMounted as be, openBlock as u, createBlock as m, withCtx as i, unref as l, createTextVNode as f, toDisplayString as g, createSlots as xe, createElementVNode as he, createVNode as v, createElementBlock as w, Fragment as T, renderList as J, createCommentVNode as F, normalizeClass as _e } from "vue";
|
|
2
|
+
import { useAdmin as ye, useTranslate as q, useErrorText as we, useDates as Ce } from "@webx-ui/module-admin";
|
|
3
|
+
import { toast as H, WxText as N, WxTable as Se, WxSelect as h, WxInput as ke, WxButton as O, WxPopover as Ve, WxCheckboxGroup as Oe, WxBadge as Ue } from "@webx-ui/core";
|
|
4
|
+
import { _ as Ae } from "./AuditLayout.vue_vue_type_script_setup_true_lang-C8H5jlTe.js";
|
|
5
|
+
import { c as ze, u as Ee, P as r, D as $e, C as K, W as I, S as Pe, b as We, g as Te, O as Q, _ as Fe } from "./index-BFYHJYU_.js";
|
|
6
|
+
const Ne = { class: "wx-audit-pages__filters" }, X = "webx-audit.pages.columns", Ie = /* @__PURE__ */ fe({
|
|
7
|
+
__name: "AuditPagesPage",
|
|
8
|
+
props: {
|
|
9
|
+
base: {}
|
|
10
|
+
},
|
|
11
|
+
setup(Y) {
|
|
12
|
+
const D = Y, C = ze(ye());
|
|
13
|
+
Ee();
|
|
14
|
+
const n = q("webx-audit"), Z = q("webx-admin"), B = we(), ee = Ce(), d = p(null), U = p(!1), L = p(null), A = p(!1), z = p(null), E = p({}), S = p(null), _ = p(null), k = p(null), c = p([]);
|
|
15
|
+
let V = { page: 1, perPage: 50, sort: null, search: "" };
|
|
16
|
+
const y = p(le());
|
|
17
|
+
function le() {
|
|
18
|
+
try {
|
|
19
|
+
const e = JSON.parse(window.localStorage.getItem(X) ?? "null");
|
|
20
|
+
if (Array.isArray(e)) {
|
|
21
|
+
const t = e.filter((a) => a in r);
|
|
22
|
+
if (t.length) return t;
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
return [...$e];
|
|
27
|
+
}
|
|
28
|
+
G(y, (e) => {
|
|
29
|
+
try {
|
|
30
|
+
window.localStorage.setItem(X, JSON.stringify(e));
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const $ = Object.keys(r), ae = b(
|
|
35
|
+
() => $.map((e) => ({ value: e, label: n(`page.field-${e}`) }))
|
|
36
|
+
), te = b(
|
|
37
|
+
() => $.filter((e) => !K.includes(e)).map((e) => ({ value: e, label: n(`page.field-${e}`) }))
|
|
38
|
+
), M = b(
|
|
39
|
+
() => (
|
|
40
|
+
/* The picker keeps the order things were ticked in; the table keeps the card's order. */
|
|
41
|
+
$.filter((e) => y.value.includes(e)).map((e) => ({
|
|
42
|
+
key: e,
|
|
43
|
+
label: n(`page.field-${e}`),
|
|
44
|
+
sortable: !K.includes(e),
|
|
45
|
+
minWidth: r[e] === "url" || r[e] === "text" ? 220 : void 0,
|
|
46
|
+
align: r[e] === "number" ? "right" : void 0
|
|
47
|
+
}))
|
|
48
|
+
)
|
|
49
|
+
), ne = b(() => [
|
|
50
|
+
...["2xx", "3xx", "4xx", "5xx"].map((e) => ({ value: e, label: e })),
|
|
51
|
+
{ value: "none", label: n("page.status-none") }
|
|
52
|
+
]), oe = b(() => [
|
|
53
|
+
{ value: "1", label: n("page.indexable-yes") },
|
|
54
|
+
{ value: "0", label: n("page.indexable-no") }
|
|
55
|
+
]), se = b(
|
|
56
|
+
() => Object.entries(E.value).map(([e, t]) => ({ value: e, label: t }))
|
|
57
|
+
), ue = b(
|
|
58
|
+
() => [S.value, _.value, k.value].filter(Boolean).length + c.value.filter(R).length
|
|
59
|
+
), P = b(() => ({
|
|
60
|
+
status: S.value,
|
|
61
|
+
indexable: _.value === null ? null : _.value === "1",
|
|
62
|
+
check: k.value,
|
|
63
|
+
filters: c.value.filter(R)
|
|
64
|
+
}));
|
|
65
|
+
function R(e) {
|
|
66
|
+
return !I.includes(e.op) || (e.value ?? "").trim() !== "";
|
|
67
|
+
}
|
|
68
|
+
function x(e) {
|
|
69
|
+
return typeof e == "string" && e !== "" ? e : null;
|
|
70
|
+
}
|
|
71
|
+
function ie(e) {
|
|
72
|
+
return Q[r[e]].map((t) => ({ value: t, label: n(`page.op-${t}`) }));
|
|
73
|
+
}
|
|
74
|
+
function re() {
|
|
75
|
+
c.value = [...c.value, { field: "title", op: "empty" }];
|
|
76
|
+
}
|
|
77
|
+
function de(e, t) {
|
|
78
|
+
const a = x(t);
|
|
79
|
+
a && (c.value = c.value.map(
|
|
80
|
+
(o, s) => s === e ? { field: a, op: Q[r[a]][0], value: "" } : o
|
|
81
|
+
));
|
|
82
|
+
}
|
|
83
|
+
function ce(e, t) {
|
|
84
|
+
const a = x(t);
|
|
85
|
+
a && (c.value = c.value.map((o, s) => s === e ? { ...o, op: a } : o));
|
|
86
|
+
}
|
|
87
|
+
function j(e, t) {
|
|
88
|
+
c.value = c.value.map((a, o) => o === e ? { ...a, value: t } : a);
|
|
89
|
+
}
|
|
90
|
+
function pe(e) {
|
|
91
|
+
c.value = c.value.filter((t, a) => a !== e);
|
|
92
|
+
}
|
|
93
|
+
function ve(e) {
|
|
94
|
+
const t = e.filter((a) => String(a) in r);
|
|
95
|
+
y.value = t.length ? t : ["url"];
|
|
96
|
+
}
|
|
97
|
+
function me(e) {
|
|
98
|
+
return e == null || e === "" ? "—" : String(e);
|
|
99
|
+
}
|
|
100
|
+
async function W(e = V) {
|
|
101
|
+
if (V = e, d.value !== null) {
|
|
102
|
+
A.value = !0;
|
|
103
|
+
try {
|
|
104
|
+
L.value = await C.pages(d.value.id, {
|
|
105
|
+
...P.value,
|
|
106
|
+
search: e.search,
|
|
107
|
+
sort: e.sort ? `${e.sort.order === "desc" ? "-" : ""}${e.sort.key}` : null,
|
|
108
|
+
page: e.page,
|
|
109
|
+
per_page: e.perPage
|
|
110
|
+
});
|
|
111
|
+
} catch (t) {
|
|
112
|
+
H.danger(B(t));
|
|
113
|
+
} finally {
|
|
114
|
+
A.value = !1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function ge() {
|
|
119
|
+
d.value !== null && window.location.assign(
|
|
120
|
+
C.pagesFile(
|
|
121
|
+
d.value.id,
|
|
122
|
+
{ ...P.value, search: V.search },
|
|
123
|
+
M.value.map((e) => e.key)
|
|
124
|
+
)
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
return G(P, () => {
|
|
128
|
+
W({ ...V, page: 1 });
|
|
129
|
+
}, { deep: !0 }), be(async () => {
|
|
130
|
+
try {
|
|
131
|
+
if (d.value = (await C.latest()).crawled, d.value !== null) {
|
|
132
|
+
const e = await C.checks(d.value.id);
|
|
133
|
+
E.value = Object.fromEntries(e.map((t) => [t.id, t.title]));
|
|
134
|
+
}
|
|
135
|
+
} catch (e) {
|
|
136
|
+
H.danger(B(e));
|
|
137
|
+
} finally {
|
|
138
|
+
U.value = !0;
|
|
139
|
+
}
|
|
140
|
+
W();
|
|
141
|
+
}), (e, t) => (u(), m(Ae, {
|
|
142
|
+
base: D.base,
|
|
143
|
+
current: "pages"
|
|
144
|
+
}, {
|
|
145
|
+
default: i(() => [
|
|
146
|
+
U.value && d.value === null ? (u(), m(l(N), {
|
|
147
|
+
key: 0,
|
|
148
|
+
tone: "muted",
|
|
149
|
+
class: "wx-audit-pages__none"
|
|
150
|
+
}, {
|
|
151
|
+
default: i(() => [
|
|
152
|
+
f(g(l(n)("page.pages-none")), 1)
|
|
153
|
+
]),
|
|
154
|
+
_: 1
|
|
155
|
+
})) : (u(), m(l(Se), {
|
|
156
|
+
key: 1,
|
|
157
|
+
data: L.value,
|
|
158
|
+
columns: M.value,
|
|
159
|
+
"row-key": "id",
|
|
160
|
+
searchable: "",
|
|
161
|
+
clickable: "",
|
|
162
|
+
hover: "",
|
|
163
|
+
flush: "",
|
|
164
|
+
loading: A.value || !U.value,
|
|
165
|
+
"per-page-options": [50, 100, 200],
|
|
166
|
+
"search-placeholder": l(n)("page.search-url"),
|
|
167
|
+
"filters-count": ue.value,
|
|
168
|
+
"filters-label": l(Z)("filters.title"),
|
|
169
|
+
"filters-width": 420,
|
|
170
|
+
"empty-text": l(n)("page.empty"),
|
|
171
|
+
onStateChange: W,
|
|
172
|
+
onRowClick: t[3] || (t[3] = (a) => z.value = a.id)
|
|
173
|
+
}, xe({
|
|
174
|
+
title: i(() => [
|
|
175
|
+
d.value ? (u(), m(l(N), {
|
|
176
|
+
key: 0,
|
|
177
|
+
size: "sm",
|
|
178
|
+
tone: "muted"
|
|
179
|
+
}, {
|
|
180
|
+
default: i(() => [
|
|
181
|
+
f(g(l(n)("page.pages-run", { date: l(ee).short(d.value.finished_at) })), 1)
|
|
182
|
+
]),
|
|
183
|
+
_: 1
|
|
184
|
+
})) : F("", !0)
|
|
185
|
+
]),
|
|
186
|
+
actions: i(() => [
|
|
187
|
+
v(l(Ve), {
|
|
188
|
+
title: l(n)("page.columns"),
|
|
189
|
+
width: "300"
|
|
190
|
+
}, {
|
|
191
|
+
trigger: i(() => [
|
|
192
|
+
v(l(O), {
|
|
193
|
+
size: "sm",
|
|
194
|
+
variant: "text",
|
|
195
|
+
icon: "sliders"
|
|
196
|
+
}, {
|
|
197
|
+
default: i(() => [
|
|
198
|
+
f(g(l(n)("page.columns")), 1)
|
|
199
|
+
]),
|
|
200
|
+
_: 1
|
|
201
|
+
})
|
|
202
|
+
]),
|
|
203
|
+
default: i(() => [
|
|
204
|
+
v(l(Oe), {
|
|
205
|
+
"model-value": y.value,
|
|
206
|
+
options: ae.value,
|
|
207
|
+
size: "sm",
|
|
208
|
+
class: "wx-audit-pages__picker",
|
|
209
|
+
"onUpdate:modelValue": ve
|
|
210
|
+
}, null, 8, ["model-value", "options"])
|
|
211
|
+
]),
|
|
212
|
+
_: 1
|
|
213
|
+
}, 8, ["title"]),
|
|
214
|
+
v(l(O), {
|
|
215
|
+
size: "sm",
|
|
216
|
+
variant: "text",
|
|
217
|
+
icon: "download",
|
|
218
|
+
disabled: !d.value,
|
|
219
|
+
onClick: ge
|
|
220
|
+
}, {
|
|
221
|
+
default: i(() => [
|
|
222
|
+
f(g(l(n)("page.export")), 1)
|
|
223
|
+
]),
|
|
224
|
+
_: 1
|
|
225
|
+
}, 8, ["disabled"])
|
|
226
|
+
]),
|
|
227
|
+
filters: i(() => [
|
|
228
|
+
he("div", Ne, [
|
|
229
|
+
v(l(h), {
|
|
230
|
+
"model-value": S.value,
|
|
231
|
+
options: ne.value,
|
|
232
|
+
placeholder: l(n)("page.any-status"),
|
|
233
|
+
clearable: "",
|
|
234
|
+
"onUpdate:modelValue": t[0] || (t[0] = (a) => S.value = x(a))
|
|
235
|
+
}, null, 8, ["model-value", "options", "placeholder"]),
|
|
236
|
+
v(l(h), {
|
|
237
|
+
"model-value": _.value,
|
|
238
|
+
options: oe.value,
|
|
239
|
+
placeholder: l(n)("page.any-indexable"),
|
|
240
|
+
clearable: "",
|
|
241
|
+
"onUpdate:modelValue": t[1] || (t[1] = (a) => _.value = x(a))
|
|
242
|
+
}, null, 8, ["model-value", "options", "placeholder"]),
|
|
243
|
+
v(l(h), {
|
|
244
|
+
"model-value": k.value,
|
|
245
|
+
options: se.value,
|
|
246
|
+
placeholder: l(n)("page.any-check"),
|
|
247
|
+
clearable: "",
|
|
248
|
+
filterable: "",
|
|
249
|
+
"onUpdate:modelValue": t[2] || (t[2] = (a) => k.value = x(a))
|
|
250
|
+
}, null, 8, ["model-value", "options", "placeholder"]),
|
|
251
|
+
(u(!0), w(T, null, J(c.value, (a, o) => (u(), w("div", {
|
|
252
|
+
key: o,
|
|
253
|
+
class: "wx-audit-pages__filter"
|
|
254
|
+
}, [
|
|
255
|
+
v(l(h), {
|
|
256
|
+
"model-value": a.field,
|
|
257
|
+
options: te.value,
|
|
258
|
+
filterable: "",
|
|
259
|
+
size: "sm",
|
|
260
|
+
"onUpdate:modelValue": (s) => de(o, s)
|
|
261
|
+
}, null, 8, ["model-value", "options", "onUpdate:modelValue"]),
|
|
262
|
+
v(l(h), {
|
|
263
|
+
"model-value": a.op,
|
|
264
|
+
options: ie(a.field),
|
|
265
|
+
size: "sm",
|
|
266
|
+
"onUpdate:modelValue": (s) => ce(o, s)
|
|
267
|
+
}, null, 8, ["model-value", "options", "onUpdate:modelValue"]),
|
|
268
|
+
l(I).includes(a.op) && l(r)[a.field] === "source" ? (u(), m(l(h), {
|
|
269
|
+
key: 0,
|
|
270
|
+
"model-value": a.value ?? null,
|
|
271
|
+
options: l(Pe).map((s) => ({ value: s, label: l(n)(`page.source-${s}`) })),
|
|
272
|
+
size: "sm",
|
|
273
|
+
"onUpdate:modelValue": (s) => j(o, x(s) ?? "")
|
|
274
|
+
}, null, 8, ["model-value", "options", "onUpdate:modelValue"])) : l(I).includes(a.op) ? (u(), m(l(ke), {
|
|
275
|
+
key: 1,
|
|
276
|
+
"model-value": a.value ?? "",
|
|
277
|
+
placeholder: l(n)("page.value"),
|
|
278
|
+
size: "sm",
|
|
279
|
+
"onUpdate:modelValue": (s) => j(o, String(s ?? ""))
|
|
280
|
+
}, null, 8, ["model-value", "placeholder", "onUpdate:modelValue"])) : F("", !0),
|
|
281
|
+
v(l(O), {
|
|
282
|
+
size: "sm",
|
|
283
|
+
variant: "text",
|
|
284
|
+
icon: "close",
|
|
285
|
+
"aria-label": l(n)("page.remove-filter"),
|
|
286
|
+
onClick: (s) => pe(o)
|
|
287
|
+
}, null, 8, ["aria-label", "onClick"])
|
|
288
|
+
]))), 128)),
|
|
289
|
+
v(l(O), {
|
|
290
|
+
size: "sm",
|
|
291
|
+
variant: "text",
|
|
292
|
+
icon: "plus",
|
|
293
|
+
onClick: re
|
|
294
|
+
}, {
|
|
295
|
+
default: i(() => [
|
|
296
|
+
f(g(l(n)("page.add-filter")), 1)
|
|
297
|
+
]),
|
|
298
|
+
_: 1
|
|
299
|
+
})
|
|
300
|
+
])
|
|
301
|
+
]),
|
|
302
|
+
_: 2
|
|
303
|
+
}, [
|
|
304
|
+
J(y.value, (a) => ({
|
|
305
|
+
name: `cell-${a}`,
|
|
306
|
+
fn: i(({ row: o }) => [
|
|
307
|
+
l(r)[a] === "status" && o[a] !== null ? (u(), m(We, {
|
|
308
|
+
key: 0,
|
|
309
|
+
code: Number(o[a])
|
|
310
|
+
}, null, 8, ["code"])) : l(r)[a] === "status" ? (u(), m(l(N), {
|
|
311
|
+
key: 1,
|
|
312
|
+
size: "sm",
|
|
313
|
+
tone: "danger"
|
|
314
|
+
}, {
|
|
315
|
+
default: i(() => [
|
|
316
|
+
f(g(l(n)("page.status-none")), 1)
|
|
317
|
+
]),
|
|
318
|
+
_: 1
|
|
319
|
+
})) : l(r)[a] === "bool" ? (u(), w(T, { key: 2 }, [
|
|
320
|
+
f(g(o[a] ? l(n)("page.yes") : l(n)("page.no")), 1)
|
|
321
|
+
], 64)) : l(r)[a] === "source" ? (u(), w(T, { key: 3 }, [
|
|
322
|
+
f(g(l(n)(`page.source-${o[a]}`)), 1)
|
|
323
|
+
], 64)) : a === "issues" && o.issues > 0 ? (u(), m(l(Ue), {
|
|
324
|
+
key: 4,
|
|
325
|
+
type: "warning",
|
|
326
|
+
size: "sm"
|
|
327
|
+
}, {
|
|
328
|
+
default: i(() => [
|
|
329
|
+
f(g(o.issues), 1)
|
|
330
|
+
]),
|
|
331
|
+
_: 2
|
|
332
|
+
}, 1024)) : (u(), w("span", {
|
|
333
|
+
key: 5,
|
|
334
|
+
class: _e({ "wx-audit-pages__long": l(r)[a] === "url" })
|
|
335
|
+
}, g(me(o[a])), 3))
|
|
336
|
+
])
|
|
337
|
+
}))
|
|
338
|
+
]), 1032, ["data", "columns", "loading", "search-placeholder", "filters-count", "filters-label", "empty-text"])),
|
|
339
|
+
d.value ? (u(), m(Te, {
|
|
340
|
+
key: 2,
|
|
341
|
+
run: d.value.id,
|
|
342
|
+
base: D.base,
|
|
343
|
+
"page-id": z.value,
|
|
344
|
+
titles: E.value,
|
|
345
|
+
onClose: t[4] || (t[4] = (a) => z.value = null)
|
|
346
|
+
}, null, 8, ["run", "base", "page-id", "titles"])) : F("", !0)
|
|
347
|
+
]),
|
|
348
|
+
_: 1
|
|
349
|
+
}, 8, ["base"]));
|
|
350
|
+
}
|
|
351
|
+
}), je = /* @__PURE__ */ Fe(Ie, [["__scopeId", "data-v-c02a7bc9"]]);
|
|
352
|
+
export {
|
|
353
|
+
je as default
|
|
354
|
+
};
|
|
355
|
+
//# sourceMappingURL=AuditPagesPage-DNgZo-K-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditPagesPage-DNgZo-K-.js","sources":["../src/AuditPagesPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { useAdmin, useDates, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxBadge,\n WxButton,\n WxCheckboxGroup,\n WxInput,\n WxPopover,\n WxSelect,\n WxTable,\n WxText,\n type SelectValue,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditLayout from './AuditLayout.vue'\nimport AuditPageCard from './AuditPageCard.vue'\nimport { createAuditApi } from './api'\nimport {\n COMPUTED_FIELDS,\n DEFAULT_COLUMNS,\n OPERATIONS,\n PAGE_FIELDS,\n SOURCES,\n WITH_VALUE,\n} from './fields'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditFieldFilter,\n AuditFilterOp,\n AuditPage,\n AuditPageField,\n AuditPageQuery,\n AuditPageRow,\n AuditRun,\n} from './types'\n\n/**\n * Every address the last full run crawled (§8, «Pages»): any field of the snapshot as a column,\n * a filter on any of them, the list as CSV, and a row that opens the page's card.\n */\nconst props = defineProps<{ base: string }>()\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst panel = useTranslate('webx-admin')\nconst message = useErrorText()\nconst dates = useDates()\n\nconst STORAGE = 'webx-audit.pages.columns'\n\nconst run = ref<AuditRun | null>(null)\nconst ready = ref(false)\nconst page = ref<AuditPage<AuditPageRow> | null>(null)\nconst loading = ref(false)\nconst opened = ref<number | null>(null)\nconst titles = ref<Record<string, string>>({})\n\nconst status = ref<string | null>(null)\nconst indexable = ref<string | null>(null)\nconst check = ref<string | null>(null)\nconst filters = ref<AuditFieldFilter[]>([])\nlet last: TableState = { page: 1, perPage: 50, sort: null, search: '' }\n\nconst visible = ref<AuditPageField[]>(restore())\n\nfunction restore(): AuditPageField[] {\n try {\n const saved: unknown = JSON.parse(window.localStorage.getItem(STORAGE) ?? 'null')\n\n if (Array.isArray(saved)) {\n const known = saved.filter((key): key is AuditPageField => key in PAGE_FIELDS)\n\n if (known.length) return known\n }\n } catch {\n // A private window or a broken value: the default columns, as for anyone else.\n }\n\n return [...DEFAULT_COLUMNS]\n}\n\nwatch(visible, (keys) => {\n try {\n window.localStorage.setItem(STORAGE, JSON.stringify(keys))\n } catch {\n // Not remembered — still shown.\n }\n})\n\nconst fields = Object.keys(PAGE_FIELDS) as AuditPageField[]\n\nconst columnOptions = computed(() =>\n fields.map((key) => ({ value: key, label: t(`page.field-${key}`) })),\n)\n\nconst filterFields = computed(() =>\n fields\n .filter((key) => !COMPUTED_FIELDS.includes(key))\n .map((key) => ({ value: key, label: t(`page.field-${key}`) })),\n)\n\nconst columns = computed<TableColumn<AuditPageRow>[]>(() =>\n /* The picker keeps the order things were ticked in; the table keeps the card's order. */\n fields\n .filter((key) => visible.value.includes(key))\n .map((key) => ({\n key,\n label: t(`page.field-${key}`),\n sortable: !COMPUTED_FIELDS.includes(key),\n minWidth: PAGE_FIELDS[key] === 'url' || PAGE_FIELDS[key] === 'text' ? 220 : undefined,\n align: PAGE_FIELDS[key] === 'number' ? 'right' : undefined,\n })),\n)\n\nconst statusOptions = computed(() => [\n ...['2xx', '3xx', '4xx', '5xx'].map((value) => ({ value, label: value })),\n { value: 'none', label: t('page.status-none') },\n])\n\nconst indexableOptions = computed(() => [\n { value: '1', label: t('page.indexable-yes') },\n { value: '0', label: t('page.indexable-no') },\n])\n\nconst checkOptions = computed(() =>\n Object.entries(titles.value).map(([value, label]) => ({ value, label })),\n)\n\nconst filtersCount = computed(\n () =>\n [status.value, indexable.value, check.value].filter(Boolean).length +\n filters.value.filter(complete).length,\n)\n\nconst query = computed<AuditPageQuery>(() => ({\n status: status.value,\n indexable: indexable.value === null ? null : indexable.value === '1',\n check: check.value,\n filters: filters.value.filter(complete),\n}))\n\nfunction complete(filter: AuditFieldFilter): boolean {\n return !WITH_VALUE.includes(filter.op) || (filter.value ?? '').trim() !== ''\n}\n\nfunction pick(value: SelectValue | SelectValue[] | null | undefined): string | null {\n return typeof value === 'string' && value !== '' ? value : null\n}\n\nfunction operations(field: AuditPageField) {\n return OPERATIONS[PAGE_FIELDS[field]].map((op) => ({ value: op, label: t(`page.op-${op}`) }))\n}\n\nfunction addFilter(): void {\n filters.value = [...filters.value, { field: 'title', op: 'empty' }]\n}\n\nfunction setField(index: number, value: SelectValue | SelectValue[] | null | undefined): void {\n const field = pick(value) as AuditPageField | null\n\n if (!field) return\n\n filters.value = filters.value.map((filter, at) =>\n at === index ? { field, op: OPERATIONS[PAGE_FIELDS[field]][0]!, value: '' } : filter,\n )\n}\n\nfunction setOp(index: number, value: SelectValue | SelectValue[] | null | undefined): void {\n const op = pick(value) as AuditFilterOp | null\n\n if (op)\n filters.value = filters.value.map((filter, at) => (at === index ? { ...filter, op } : filter))\n}\n\nfunction setValue(index: number, value: string): void {\n filters.value = filters.value.map((filter, at) => (at === index ? { ...filter, value } : filter))\n}\n\nfunction removeFilter(index: number): void {\n filters.value = filters.value.filter((_, at) => at !== index)\n}\n\nfunction setColumns(keys: unknown[]): void {\n const next = keys.filter((key): key is AuditPageField => String(key) in PAGE_FIELDS)\n\n /* A table without columns is a blank card; the address stays at least. */\n visible.value = next.length ? next : ['url']\n}\n\nfunction text(value: unknown): string {\n return value === null || value === undefined || value === '' ? '—' : String(value)\n}\n\nasync function load(state: TableState = last): Promise<void> {\n last = state\n\n if (run.value === null) return\n\n loading.value = true\n\n try {\n page.value = await api.pages(run.value.id, {\n ...query.value,\n search: state.search,\n sort: state.sort ? `${state.sort.order === 'desc' ? '-' : ''}${state.sort.key}` : null,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nfunction download(): void {\n if (run.value === null) return\n\n window.location.assign(\n api.pagesFile(\n run.value.id,\n { ...query.value, search: last.search },\n columns.value.map((column) => column.key),\n ),\n )\n}\n\nwatch(query, () => void load({ ...last, page: 1 }), { deep: true })\n\nonMounted(async () => {\n try {\n run.value = (await api.latest()).crawled\n\n if (run.value !== null) {\n const checks = await api.checks(run.value.id)\n titles.value = Object.fromEntries(checks.map((row) => [row.id, row.title]))\n }\n } catch (error) {\n toast.danger(message(error))\n } finally {\n ready.value = true\n }\n\n void load()\n})\n</script>\n\n<template>\n <audit-layout :base=\"props.base\" current=\"pages\">\n <wx-text v-if=\"ready && run === null\" tone=\"muted\" class=\"wx-audit-pages__none\">{{\n t('page.pages-none')\n }}</wx-text>\n\n <wx-table\n v-else\n :data=\"page\"\n :columns=\"columns\"\n row-key=\"id\"\n searchable\n clickable\n hover\n flush\n :loading=\"loading || !ready\"\n :per-page-options=\"[50, 100, 200]\"\n :search-placeholder=\"t('page.search-url')\"\n :filters-count=\"filtersCount\"\n :filters-label=\"panel('filters.title')\"\n :filters-width=\"420\"\n :empty-text=\"t('page.empty')\"\n @state-change=\"load\"\n @row-click=\"(row) => (opened = row.id)\"\n >\n <template #title>\n <wx-text v-if=\"run\" size=\"sm\" tone=\"muted\">{{\n t('page.pages-run', { date: dates.short(run.finished_at) })\n }}</wx-text>\n </template>\n\n <template #actions>\n <wx-popover :title=\"t('page.columns')\" width=\"300\">\n <template #trigger>\n <wx-button size=\"sm\" variant=\"text\" icon=\"sliders\">{{ t('page.columns') }}</wx-button>\n </template>\n <wx-checkbox-group\n :model-value=\"visible\"\n :options=\"columnOptions\"\n size=\"sm\"\n class=\"wx-audit-pages__picker\"\n @update:model-value=\"setColumns\"\n />\n </wx-popover>\n <wx-button size=\"sm\" variant=\"text\" icon=\"download\" :disabled=\"!run\" @click=\"download\">{{\n t('page.export')\n }}</wx-button>\n </template>\n\n <template #filters>\n <div class=\"wx-audit-pages__filters\">\n <wx-select\n :model-value=\"status\"\n :options=\"statusOptions\"\n :placeholder=\"t('page.any-status')\"\n clearable\n @update:model-value=\"status = pick($event)\"\n />\n <wx-select\n :model-value=\"indexable\"\n :options=\"indexableOptions\"\n :placeholder=\"t('page.any-indexable')\"\n clearable\n @update:model-value=\"indexable = pick($event)\"\n />\n <wx-select\n :model-value=\"check\"\n :options=\"checkOptions\"\n :placeholder=\"t('page.any-check')\"\n clearable\n filterable\n @update:model-value=\"check = pick($event)\"\n />\n\n <div v-for=\"(filter, index) in filters\" :key=\"index\" class=\"wx-audit-pages__filter\">\n <wx-select\n :model-value=\"filter.field\"\n :options=\"filterFields\"\n filterable\n size=\"sm\"\n @update:model-value=\"setField(index, $event)\"\n />\n <wx-select\n :model-value=\"filter.op\"\n :options=\"operations(filter.field)\"\n size=\"sm\"\n @update:model-value=\"setOp(index, $event)\"\n />\n <wx-select\n v-if=\"WITH_VALUE.includes(filter.op) && PAGE_FIELDS[filter.field] === 'source'\"\n :model-value=\"filter.value ?? null\"\n :options=\"SOURCES.map((value) => ({ value, label: t(`page.source-${value}`) }))\"\n size=\"sm\"\n @update:model-value=\"setValue(index, pick($event) ?? '')\"\n />\n <wx-input\n v-else-if=\"WITH_VALUE.includes(filter.op)\"\n :model-value=\"filter.value ?? ''\"\n :placeholder=\"t('page.value')\"\n size=\"sm\"\n @update:model-value=\"setValue(index, String($event ?? ''))\"\n />\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"close\"\n :aria-label=\"t('page.remove-filter')\"\n @click=\"removeFilter(index)\"\n />\n </div>\n\n <wx-button size=\"sm\" variant=\"text\" icon=\"plus\" @click=\"addFilter\">{{\n t('page.add-filter')\n }}</wx-button>\n </div>\n </template>\n\n <template v-for=\"key in visible\" :key=\"key\" #[`cell-${key}`]=\"{ row }\">\n <audit-status\n v-if=\"PAGE_FIELDS[key] === 'status' && row[key] !== null\"\n :code=\"Number(row[key])\"\n />\n <wx-text v-else-if=\"PAGE_FIELDS[key] === 'status'\" size=\"sm\" tone=\"danger\">{{\n t('page.status-none')\n }}</wx-text>\n <template v-else-if=\"PAGE_FIELDS[key] === 'bool'\">{{\n row[key] ? t('page.yes') : t('page.no')\n }}</template>\n <template v-else-if=\"PAGE_FIELDS[key] === 'source'\">{{\n t(`page.source-${row[key]}`)\n }}</template>\n <wx-badge v-else-if=\"key === 'issues' && row.issues > 0\" type=\"warning\" size=\"sm\">{{\n row.issues\n }}</wx-badge>\n <span v-else :class=\"{ 'wx-audit-pages__long': PAGE_FIELDS[key] === 'url' }\">{{\n text(row[key])\n }}</span>\n </template>\n </wx-table>\n\n <audit-page-card\n v-if=\"run\"\n :run=\"run.id\"\n :base=\"props.base\"\n :page-id=\"opened\"\n :titles=\"titles\"\n @close=\"opened = null\"\n />\n </audit-layout>\n</template>\n\n<style scoped>\n.wx-audit-pages__none {\n display: block;\n padding: var(--wx-space-24);\n}\n\n.wx-audit-pages__filters {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-pages__filter {\n display: grid;\n grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr) auto;\n gap: var(--wx-space-4);\n align-items: center;\n}\n\n.wx-audit-pages__picker {\n max-height: 360px;\n overflow-y: auto;\n}\n\n.wx-audit-pages__long {\n overflow-wrap: anywhere;\n}\n</style>\n"],"names":["STORAGE","props","__props","api","createAuditApi","useAdmin","useAuditMessages","t","useTranslate","panel","message","useErrorText","dates","useDates","run","ref","ready","page","loading","opened","titles","status","indexable","check","filters","last","visible","restore","saved","known","key","PAGE_FIELDS","DEFAULT_COLUMNS","watch","keys","fields","columnOptions","computed","filterFields","COMPUTED_FIELDS","columns","statusOptions","value","indexableOptions","checkOptions","label","filtersCount","complete","query","filter","WITH_VALUE","pick","operations","field","OPERATIONS","op","addFilter","setField","index","at","setOp","setValue","removeFilter","_","setColumns","next","text","load","state","error","toast","download","column","onMounted","checks","row","_createBlock","AuditLayout","_unref","WxText","WxTable","_createTextVNode","_toDisplayString","_createVNode","WxPopover","WxButton","WxCheckboxGroup","_createElementVNode","_hoisted_1","WxSelect","_cache","$event","_openBlock","_createElementBlock","_Fragment","_renderList","SOURCES","WxInput","_withCtx","AuditStatus","WxBadge","_normalizeClass","AuditPageCard"],"mappings":";;;;;iDAsDMA,IAAU;;;;;;AAVhB,UAAMC,IAAQC,GAERC,IAAMC,GAAeC,IAAU;AACrC,IAAAC,GAAA;AAEA,UAAMC,IAAIC,EAAa,YAAY,GAC7BC,IAAQD,EAAa,YAAY,GACjCE,IAAUC,GAAA,GACVC,KAAQC,GAAA,GAIRC,IAAMC,EAAqB,IAAI,GAC/BC,IAAQD,EAAI,EAAK,GACjBE,IAAOF,EAAoC,IAAI,GAC/CG,IAAUH,EAAI,EAAK,GACnBI,IAASJ,EAAmB,IAAI,GAChCK,IAASL,EAA4B,EAAE,GAEvCM,IAASN,EAAmB,IAAI,GAChCO,IAAYP,EAAmB,IAAI,GACnCQ,IAAQR,EAAmB,IAAI,GAC/BS,IAAUT,EAAwB,EAAE;AAC1C,QAAIU,IAAmB,EAAE,MAAM,GAAG,SAAS,IAAI,MAAM,MAAM,QAAQ,GAAA;AAEnE,UAAMC,IAAUX,EAAsBY,IAAS;AAE/C,aAASA,KAA4B;AACnC,UAAI;AACF,cAAMC,IAAiB,KAAK,MAAM,OAAO,aAAa,QAAQ5B,CAAO,KAAK,MAAM;AAEhF,YAAI,MAAM,QAAQ4B,CAAK,GAAG;AACxB,gBAAMC,IAAQD,EAAM,OAAO,CAACE,MAA+BA,KAAOC,CAAW;AAE7E,cAAIF,EAAM,OAAQ,QAAOA;AAAA,QAC3B;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,aAAO,CAAC,GAAGG,EAAe;AAAA,IAC5B;AAEA,IAAAC,EAAMP,GAAS,CAACQ,MAAS;AACvB,UAAI;AACF,eAAO,aAAa,QAAQlC,GAAS,KAAK,UAAUkC,CAAI,CAAC;AAAA,MAC3D,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAED,UAAMC,IAAS,OAAO,KAAKJ,CAAW,GAEhCK,KAAgBC;AAAA,MAAS,MAC7BF,EAAO,IAAI,CAACL,OAAS,EAAE,OAAOA,GAAK,OAAOvB,EAAE,cAAcuB,CAAG,EAAE,IAAI;AAAA,IAAA,GAG/DQ,KAAeD;AAAA,MAAS,MAC5BF,EACG,OAAO,CAACL,MAAQ,CAACS,EAAgB,SAAST,CAAG,CAAC,EAC9C,IAAI,CAACA,OAAS,EAAE,OAAOA,GAAK,OAAOvB,EAAE,cAAcuB,CAAG,EAAE,IAAI;AAAA,IAAA,GAG3DU,IAAUH;AAAA,MAAsC;AAAA;AAAA,QAEpDF,EACG,OAAO,CAACL,MAAQJ,EAAQ,MAAM,SAASI,CAAG,CAAC,EAC3C,IAAI,CAACA,OAAS;AAAA,UACb,KAAAA;AAAA,UACA,OAAOvB,EAAE,cAAcuB,CAAG,EAAE;AAAA,UAC5B,UAAU,CAACS,EAAgB,SAAST,CAAG;AAAA,UACvC,UAAUC,EAAYD,CAAG,MAAM,SAASC,EAAYD,CAAG,MAAM,SAAS,MAAM;AAAA,UAC5E,OAAOC,EAAYD,CAAG,MAAM,WAAW,UAAU;AAAA,QAAA,EACjD;AAAA;AAAA,IAAA,GAGAW,KAAgBJ,EAAS,MAAM;AAAA,MACnC,GAAG,CAAC,OAAO,OAAO,OAAO,KAAK,EAAE,IAAI,CAACK,OAAW,EAAE,OAAAA,GAAO,OAAOA,IAAQ;AAAA,MACxE,EAAE,OAAO,QAAQ,OAAOnC,EAAE,kBAAkB,EAAA;AAAA,IAAE,CAC/C,GAEKoC,KAAmBN,EAAS,MAAM;AAAA,MACtC,EAAE,OAAO,KAAK,OAAO9B,EAAE,oBAAoB,EAAA;AAAA,MAC3C,EAAE,OAAO,KAAK,OAAOA,EAAE,mBAAmB,EAAA;AAAA,IAAE,CAC7C,GAEKqC,KAAeP;AAAA,MAAS,MAC5B,OAAO,QAAQjB,EAAO,KAAK,EAAE,IAAI,CAAC,CAACsB,GAAOG,CAAK,OAAO,EAAE,OAAAH,GAAO,OAAAG,IAAQ;AAAA,IAAA,GAGnEC,KAAeT;AAAA,MACnB,MACE,CAAChB,EAAO,OAAOC,EAAU,OAAOC,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,SAC7DC,EAAQ,MAAM,OAAOuB,CAAQ,EAAE;AAAA,IAAA,GAG7BC,IAAQX,EAAyB,OAAO;AAAA,MAC5C,QAAQhB,EAAO;AAAA,MACf,WAAWC,EAAU,UAAU,OAAO,OAAOA,EAAU,UAAU;AAAA,MACjE,OAAOC,EAAM;AAAA,MACb,SAASC,EAAQ,MAAM,OAAOuB,CAAQ;AAAA,IAAA,EACtC;AAEF,aAASA,EAASE,GAAmC;AACnD,aAAO,CAACC,EAAW,SAASD,EAAO,EAAE,MAAMA,EAAO,SAAS,IAAI,KAAA,MAAW;AAAA,IAC5E;AAEA,aAASE,EAAKT,GAAsE;AAClF,aAAO,OAAOA,KAAU,YAAYA,MAAU,KAAKA,IAAQ;AAAA,IAC7D;AAEA,aAASU,GAAWC,GAAuB;AACzC,aAAOC,EAAWvB,EAAYsB,CAAK,CAAC,EAAE,IAAI,CAACE,OAAQ,EAAE,OAAOA,GAAI,OAAOhD,EAAE,WAAWgD,CAAE,EAAE,IAAI;AAAA,IAC9F;AAEA,aAASC,KAAkB;AACzB,MAAAhC,EAAQ,QAAQ,CAAC,GAAGA,EAAQ,OAAO,EAAE,OAAO,SAAS,IAAI,SAAS;AAAA,IACpE;AAEA,aAASiC,GAASC,GAAehB,GAA6D;AAC5F,YAAMW,IAAQF,EAAKT,CAAK;AAExB,MAAKW,MAEL7B,EAAQ,QAAQA,EAAQ,MAAM;AAAA,QAAI,CAACyB,GAAQU,MACzCA,MAAOD,IAAQ,EAAE,OAAAL,GAAO,IAAIC,EAAWvB,EAAYsB,CAAK,CAAC,EAAE,CAAC,GAAI,OAAO,OAAOJ;AAAA,MAAA;AAAA,IAElF;AAEA,aAASW,GAAMF,GAAehB,GAA6D;AACzF,YAAMa,IAAKJ,EAAKT,CAAK;AAErB,MAAIa,MACF/B,EAAQ,QAAQA,EAAQ,MAAM,IAAI,CAACyB,GAAQU,MAAQA,MAAOD,IAAQ,EAAE,GAAGT,GAAQ,IAAAM,EAAA,IAAON,CAAO;AAAA,IACjG;AAEA,aAASY,EAASH,GAAehB,GAAqB;AACpD,MAAAlB,EAAQ,QAAQA,EAAQ,MAAM,IAAI,CAACyB,GAAQU,MAAQA,MAAOD,IAAQ,EAAE,GAAGT,GAAQ,OAAAP,EAAA,IAAUO,CAAO;AAAA,IAClG;AAEA,aAASa,GAAaJ,GAAqB;AACzC,MAAAlC,EAAQ,QAAQA,EAAQ,MAAM,OAAO,CAACuC,GAAGJ,MAAOA,MAAOD,CAAK;AAAA,IAC9D;AAEA,aAASM,GAAW9B,GAAuB;AACzC,YAAM+B,IAAO/B,EAAK,OAAO,CAACJ,MAA+B,OAAOA,CAAG,KAAKC,CAAW;AAGnF,MAAAL,EAAQ,QAAQuC,EAAK,SAASA,IAAO,CAAC,KAAK;AAAA,IAC7C;AAEA,aAASC,GAAKxB,GAAwB;AACpC,aAAOA,KAAU,QAA+BA,MAAU,KAAK,MAAM,OAAOA,CAAK;AAAA,IACnF;AAEA,mBAAeyB,EAAKC,IAAoB3C,GAAqB;AAG3D,UAFAA,IAAO2C,GAEHtD,EAAI,UAAU,MAElB;AAAA,QAAAI,EAAQ,QAAQ;AAEhB,YAAI;AACF,UAAAD,EAAK,QAAQ,MAAMd,EAAI,MAAMW,EAAI,MAAM,IAAI;AAAA,YACzC,GAAGkC,EAAM;AAAA,YACT,QAAQoB,EAAM;AAAA,YACd,MAAMA,EAAM,OAAO,GAAGA,EAAM,KAAK,UAAU,SAAS,MAAM,EAAE,GAAGA,EAAM,KAAK,GAAG,KAAK;AAAA,YAClF,MAAMA,EAAM;AAAA,YACZ,UAAUA,EAAM;AAAA,UAAA,CACjB;AAAA,QACH,SAASC,GAAO;AACd,UAAAC,EAAM,OAAO5D,EAAQ2D,CAAK,CAAC;AAAA,QAC7B,UAAA;AACE,UAAAnD,EAAQ,QAAQ;AAAA,QAClB;AAAA;AAAA,IACF;AAEA,aAASqD,KAAiB;AACxB,MAAIzD,EAAI,UAAU,QAElB,OAAO,SAAS;AAAA,QACdX,EAAI;AAAA,UACFW,EAAI,MAAM;AAAA,UACV,EAAE,GAAGkC,EAAM,OAAO,QAAQvB,EAAK,OAAA;AAAA,UAC/Be,EAAQ,MAAM,IAAI,CAACgC,MAAWA,EAAO,GAAG;AAAA,QAAA;AAAA,MAC1C;AAAA,IAEJ;AAEA,WAAAvC,EAAMe,GAAO;AAAM,MAAKmB,EAAK,EAAE,GAAG1C,GAAM,MAAM,EAAA,CAAG;AAAA,OAAG,EAAE,MAAM,IAAM,GAElEgD,GAAU,YAAY;AACpB,UAAI;AAGF,YAFA3D,EAAI,SAAS,MAAMX,EAAI,OAAA,GAAU,SAE7BW,EAAI,UAAU,MAAM;AACtB,gBAAM4D,IAAS,MAAMvE,EAAI,OAAOW,EAAI,MAAM,EAAE;AAC5C,UAAAM,EAAO,QAAQ,OAAO,YAAYsD,EAAO,IAAI,CAACC,MAAQ,CAACA,EAAI,IAAIA,EAAI,KAAK,CAAC,CAAC;AAAA,QAC5E;AAAA,MACF,SAASN,GAAO;AACd,QAAAC,EAAM,OAAO5D,EAAQ2D,CAAK,CAAC;AAAA,MAC7B,UAAA;AACE,QAAArD,EAAM,QAAQ;AAAA,MAChB;AAEA,MAAKmD,EAAA;AAAA,IACP,CAAC,mBAICS,EAmJeC,IAAA;AAAA,MAnJA,MAAM5E,EAAM;AAAA,MAAM,SAAQ;AAAA,IAAA;iBACvC,MAEY;AAAA,QAFGe,EAAA,SAASF,EAAA,UAAG,aAA3B8D,EAEYE,EAAAC,CAAA,GAAA;AAAA;UAF0B,MAAK;AAAA,UAAQ,OAAM;AAAA,QAAA;qBAAuB,MAE9E;AAAA,gBADAD,EAAAvE,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,UAAA;;oBAGHqE,EAoIWE,EAAAE,EAAA,GAAA;AAAA;UAlIR,MAAM/D,EAAA;AAAA,UACN,SAASuB,EAAA;AAAA,UACV,WAAQ;AAAA,UACR,YAAA;AAAA,UACA,WAAA;AAAA,UACA,OAAA;AAAA,UACA,OAAA;AAAA,UACC,SAAStB,EAAA,SAAO,CAAKF,EAAA;AAAA,UACrB,oBAAkB,CAAA,IAAA,KAAA,GAAA;AAAA,UAClB,sBAAoB8D,EAAAvE,CAAA,EAAC,iBAAA;AAAA,UACrB,iBAAeuC,GAAA;AAAA,UACf,iBAAegC,EAAArE,CAAA,EAAK,eAAA;AAAA,UACpB,iBAAe;AAAA,UACf,cAAYqE,EAAAvE,CAAA,EAAC,YAAA;AAAA,UACb,eAAc4D;AAAA,UACd,6BAAYQ,MAASxD,UAASwD,EAAI;AAAA,QAAA;UAExB,SACT,MAEY;AAAA,YAFG7D,EAAA,cAAf8D,EAEYE,EAAAC,CAAA,GAAA;AAAA;cAFQ,MAAK;AAAA,cAAK,MAAK;AAAA,YAAA;yBAAQ,MAEzC;AAAA,gBADAE,EAAAC,EAAAJ,EAAAvE,CAAA,4BAA4BuE,EAAAlE,EAAA,EAAM,MAAME,EAAA,MAAI,WAAW,GAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;UAIhD,WACT,MAWa;AAAA,YAXbqE,EAWaL,EAAAM,EAAA,GAAA;AAAA,cAXA,OAAON,EAAAvE,CAAA,EAAC,cAAA;AAAA,cAAkB,OAAM;AAAA,YAAA;cAChC,WACT,MAAsF;AAAA,gBAAtF4E,EAAsFL,EAAAO,CAAA,GAAA;AAAA,kBAA3E,MAAK;AAAA,kBAAK,SAAQ;AAAA,kBAAO,MAAK;AAAA,gBAAA;6BAAU,MAAuB;AAAA,wBAApBP,EAAAvE,CAAA,EAAC,cAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;;yBAEzD,MAME;AAAA,gBANF4E,EAMEL,EAAAQ,EAAA,GAAA;AAAA,kBALC,eAAa5D,EAAA;AAAA,kBACb,SAASU,GAAA;AAAA,kBACV,MAAK;AAAA,kBACL,OAAM;AAAA,kBACL,uBAAoB4B;AAAA,gBAAA;;;;YAGzBmB,EAEcL,EAAAO,CAAA,GAAA;AAAA,cAFH,MAAK;AAAA,cAAK,SAAQ;AAAA,cAAO,MAAK;AAAA,cAAY,WAAWvE,EAAA;AAAA,cAAM,SAAOyD;AAAA,YAAA;yBAAU,MAErF;AAAA,oBADAO,EAAAvE,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;UAIM,WACT,MAgEM;AAAA,YAhENgF,GAgEM,OAhENC,IAgEM;AAAA,cA/DJL,EAMEL,EAAAW,CAAA,GAAA;AAAA,gBALC,eAAapE,EAAA;AAAA,gBACb,SAASoB,GAAA;AAAA,gBACT,aAAaqC,EAAAvE,CAAA,EAAC,iBAAA;AAAA,gBACf,WAAA;AAAA,gBACC,uBAAkBmF,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEtE,EAAA,QAAS8B,EAAKwC,CAAM;AAAA,cAAA;cAE3CR,EAMEL,EAAAW,CAAA,GAAA;AAAA,gBALC,eAAanE,EAAA;AAAA,gBACb,SAASqB,GAAA;AAAA,gBACT,aAAamC,EAAAvE,CAAA,EAAC,oBAAA;AAAA,gBACf,WAAA;AAAA,gBACC,uBAAkBmF,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAErE,EAAA,QAAY6B,EAAKwC,CAAM;AAAA,cAAA;cAE9CR,EAOEL,EAAAW,CAAA,GAAA;AAAA,gBANC,eAAalE,EAAA;AAAA,gBACb,SAASqB,GAAA;AAAA,gBACT,aAAakC,EAAAvE,CAAA,EAAC,gBAAA;AAAA,gBACf,WAAA;AAAA,gBACA,YAAA;AAAA,gBACC,uBAAkBmF,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEpE,EAAA,QAAQ4B,EAAKwC,CAAM;AAAA,cAAA;eAG1CC,EAAA,EAAA,GAAAC,EAmCMC,GAAA,MAAAC,EAnCyBvE,EAAA,OAAO,CAAzByB,GAAQS,YAArBmC,EAmCM,OAAA;AAAA,gBAnCmC,KAAKnC;AAAA,gBAAO,OAAM;AAAA,cAAA;gBACzDyB,EAMEL,EAAAW,CAAA,GAAA;AAAA,kBALC,eAAaxC,EAAO;AAAA,kBACpB,SAASX,GAAA;AAAA,kBACV,YAAA;AAAA,kBACA,MAAK;AAAA,kBACJ,uBAAkB,CAAAqD,MAAElC,GAASC,GAAOiC,CAAM;AAAA,gBAAA;gBAE7CR,EAKEL,EAAAW,CAAA,GAAA;AAAA,kBAJC,eAAaxC,EAAO;AAAA,kBACpB,SAASG,GAAWH,EAAO,KAAK;AAAA,kBACjC,MAAK;AAAA,kBACJ,uBAAkB,CAAA0C,MAAE/B,GAAMF,GAAOiC,CAAM;AAAA,gBAAA;gBAGlCb,EAAA5B,CAAA,EAAW,SAASD,EAAO,EAAE,KAAK6B,EAAA/C,CAAA,EAAYkB,EAAO,KAAK,MAAA,iBADlE2B,EAMEE,EAAAW,CAAA,GAAA;AAAA;kBAJC,eAAaxC,EAAO,SAAK;AAAA,kBACzB,SAAS6B,EAAAkB,EAAA,EAAQ,IAAG,CAAEtD,OAAK,EAAQ,OAAAA,GAAK,OAASoC,EAAAvE,CAAA,EAAC,eAAgBmC,CAAK,EAAA,IAAA;AAAA,kBACxE,MAAK;AAAA,kBACJ,8BAAoBmB,EAASH,GAAOP,EAAKwC,CAAM,KAAA,EAAA;AAAA,gBAAA,kEAGrCb,EAAA5B,CAAA,EAAW,SAASD,EAAO,EAAE,UAD1C2B,EAMEE,EAAAmB,EAAA,GAAA;AAAA;kBAJC,eAAahD,EAAO,SAAK;AAAA,kBACzB,aAAa6B,EAAAvE,CAAA,EAAC,YAAA;AAAA,kBACf,MAAK;AAAA,kBACJ,8BAAoBsD,EAASH,GAAO,OAAOiC,KAAM,EAAA,CAAA;AAAA,gBAAA;gBAEpDR,EAMEL,EAAAO,CAAA,GAAA;AAAA,kBALA,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACJ,cAAYP,EAAAvE,CAAA,EAAC,oBAAA;AAAA,kBACb,SAAK,CAAAoF,MAAE7B,GAAaJ,CAAK;AAAA,gBAAA;;cAI9ByB,EAEcL,EAAAO,CAAA,GAAA;AAAA,gBAFH,MAAK;AAAA,gBAAK,SAAQ;AAAA,gBAAO,MAAK;AAAA,gBAAQ,SAAO7B;AAAA,cAAA;2BAAW,MAEjE;AAAA,sBADAsB,EAAAvE,CAAA,EAAC,iBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;;;;;;UAKiBwF,EAAArE,EAAA,QAAPI;0BAAoCA,CAAG;AAAA,YACtD,IAAAoE,EAAA,CAGE,EAJ4D,KAAAvB,QAAG;AAAA,cAEzDG,EAAA/C,CAAA,EAAYD,CAAG,MAAA,YAAkB6C,EAAI7C,CAAG,MAAA,aADhD8C,EAGEuB,IAAA;AAAA;gBADC,MAAM,OAAOxB,EAAI7C,CAAG,CAAA;AAAA,cAAA,yBAEHgD,EAAA/C,CAAA,EAAYD,CAAG,MAAA,iBAAnC8C,EAEYE,EAAAC,CAAA,GAAA;AAAA;gBAFuC,MAAK;AAAA,gBAAK,MAAK;AAAA,cAAA;2BAAS,MAEzE;AAAA,sBADAD,EAAAvE,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,gBAAA;;oBAEkBuE,EAAA/C,CAAA,EAAYD,CAAG,MAAA,eAApC+D,EAEaC,GAAA,EAAA,KAAA,KAAA;AAAA,gBADXb,EAAAC,EAAAP,EAAI7C,CAAG,IAAIgD,EAAAvE,CAAA,gBAAgBuE,EAAAvE,CAAA,EAAC,SAAA,CAAA,GAAA,CAAA;AAAA,cAAA,UAETuE,EAAA/C,CAAA,EAAYD,CAAG,MAAA,iBAApC+D,EAEaC,GAAA,EAAA,KAAA,KAAA;AAAA,oBADXhB,EAAAvE,CAAA,EAAC,eAAgBoE,EAAI7C,CAAG,CAAA,EAAA,CAAA,GAAA,CAAA;AAAA,cAAA,UAELA,MAAG,YAAiB6C,EAAI,SAAM,UAAnDC,EAEaE,EAAAsB,EAAA,GAAA;AAAA;gBAF4C,MAAK;AAAA,gBAAU,MAAK;AAAA,cAAA;2BAAK,MAEhF;AAAA,kBADAnB,EAAAC,EAAAP,EAAI,MAAM,GAAA,CAAA;AAAA,gBAAA;;gCAEZkB,EAES,QAAA;AAAA;gBAFK,OAAKQ,GAAA,EAAA,wBAA4BvB,EAAA/C,CAAA,EAAYD,CAAG,MAAA,MAAA,CAAA;AAAA,cAAA,KAC5DoC,GAAKS,EAAI7C,CAAG,CAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;QAMVhB,EAAA,cADR8D,EAOE0B,IAAA;AAAA;UALC,KAAKxF,EAAA,MAAI;AAAA,UACT,MAAMb,EAAM;AAAA,UACZ,WAASkB,EAAA;AAAA,UACT,QAAQC,EAAA;AAAA,UACR,gCAAOD,EAAA,QAAM;AAAA,QAAA;;;;;;"}
|