@burdenoff/microfe-botmanor 2026.1014.2 → 2026.1025.2

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.
@@ -33,7 +33,7 @@ function N(e) {
33
33
  CONTENT: e("botlit.policies.typeLabel.CONTENT", "Content Safety"),
34
34
  TOOL: e("botlit.policies.typeLabel.TOOL", "Tool Access"),
35
35
  DATA: e("botlit.policies.typeLabel.DATA", "Data Access"),
36
- RESPONSE: e("botlit.policies.typeLabel.RESPONSE", "Response Format"),
36
+ RESPONSE: e("botlit.policies.typeLabel.RESPONSE", "Response & Models"),
37
37
  BUDGET: e("botlit.policies.typeLabel.BUDGET", "Budget Limits"),
38
38
  RATE_LIMIT: e("botlit.policies.typeLabel.RATE_LIMIT", "Rate Limiting"),
39
39
  RETENTION: e("botlit.policies.typeLabel.RETENTION", "Data Retention")
@@ -1 +1 @@
1
- {"version":3,"file":"PoliciesPage.js","names":[],"sources":["../../../src/botlit/pages/PoliciesPage.tsx"],"sourcesContent":["/**\n * Policies Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Plus,\n Search as SearchIcon,\n Filter,\n Shield,\n Wrench,\n Database,\n MessageSquare,\n DollarSign,\n Clock,\n Trash2,\n AlertTriangle,\n} from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport { usePolicies, type PolicyRecord } from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { PolicyType } from '../types';\n\nconst PolicyTypeIcon: FC<{ type: string; className?: string }> = ({ type, className }) => {\n switch (type) {\n case 'CONTENT':\n return <AlertTriangle className={className} />;\n case 'TOOL':\n return <Wrench className={className} />;\n case 'DATA':\n return <Database className={className} />;\n case 'RESPONSE':\n return <MessageSquare className={className} />;\n case 'BUDGET':\n return <DollarSign className={className} />;\n case 'RATE_LIMIT':\n return <Clock className={className} />;\n case 'RETENTION':\n return <Trash2 className={className} />;\n default:\n return <Shield className={className} />;\n }\n};\n\nfunction usePolicyTypeLabel(t: ReturnType<typeof useTr>): Record<string, string> {\n return {\n CONTENT: t('botlit.policies.typeLabel.CONTENT', 'Content Safety'),\n TOOL: t('botlit.policies.typeLabel.TOOL', 'Tool Access'),\n DATA: t('botlit.policies.typeLabel.DATA', 'Data Access'),\n RESPONSE: t('botlit.policies.typeLabel.RESPONSE', 'Response Format'),\n BUDGET: t('botlit.policies.typeLabel.BUDGET', 'Budget Limits'),\n RATE_LIMIT: t('botlit.policies.typeLabel.RATE_LIMIT', 'Rate Limiting'),\n RETENTION: t('botlit.policies.typeLabel.RETENTION', 'Data Retention'),\n };\n}\n\nexport const PoliciesPage: FC = () => {\n const t = useTr();\n const { getPath } = useBotlit();\n const [search, setSearch] = useState('');\n const [selectedType, setSelectedType] = useState<PolicyType | null>(null);\n const { data: policies, loading, error, refetch } = usePolicies({ search });\n const policyTypeLabel = usePolicyTypeLabel(t);\n\n const filteredPolicies = selectedType\n ? policies.filter((policy) => policy.type === selectedType)\n : policies;\n\n const policyTypes: PolicyType[] = [\n 'CONTENT',\n 'TOOL',\n 'DATA',\n 'RESPONSE',\n 'BUDGET',\n 'RATE_LIMIT',\n 'RETENTION',\n ];\n\n return (\n <PageLayout\n title={t('botlit.policies.title', 'Policies & Guardrails')}\n description={t(\n 'botlit.policies.description',\n 'Configure safety rules, access controls, and operational limits'\n )}\n actions={\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('policies/new')}>\n {t('botlit.policies.actions.createPolicy', 'Create Policy')}\n </Link>\n </Button>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Shield size={18} />}>\n {t(\n 'botlit.policies.purpose',\n 'Policies are the guardrails that keep your agents safe and within budget. Each policy enforces one kind of rule — blocking harmful content or PII, restricting which tools an agent may call, capping token spend, or rate-limiting requests. Define policies here and attach them to agents so every execution stays compliant and predictable.'\n )}\n </PagePurpose>\n\n {/* Policy Type Filters */}\n <div className=\"flex flex-wrap gap-2\">\n <Button\n variant={selectedType === null ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedType(null)}\n >\n {t('botlit.store.filters.all', 'All')}\n </Button>\n {policyTypes.map((type) => (\n <Button\n key={type}\n variant={selectedType === type ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedType(type)}\n leftIcon={<PolicyTypeIcon type={type} className=\"h-4 w-4\" />}\n >\n {policyTypeLabel[type]}\n </Button>\n ))}\n </div>\n\n {/* Search */}\n <div className=\"flex items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <SearchIcon className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={t('botlit.policies.searchPlaceholder', 'Search policies...')}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Button variant=\"outline\" leftIcon={<Filter size={16} />}>\n {t('botlit.policies.actions.moreFilters', 'More Filters')}\n </Button>\n </div>\n\n {/* Policies List */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3, 4, 5, 6].map((i) => (\n <div\n key={i}\n className=\"h-40 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"policies\" error={error} onRetry={() => void refetch()} />\n ) : filteredPolicies.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {filteredPolicies.map((policy: PolicyRecord) => (\n <Link key={policy.id} to={getPath(`policies/${policy.id}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer\">\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div\n className={`p-2 rounded-lg ${\n policy.type === 'CONTENT'\n ? 'bg-status-error-bg-subtle'\n : policy.type === 'TOOL'\n ? 'bg-status-info-bg-subtle'\n : policy.type === 'BUDGET'\n ? 'bg-status-warning-bg-subtle'\n : 'bg-action-primary-bg/10'\n }`}\n >\n <PolicyTypeIcon\n type={policy.type}\n className={`h-5 w-5 ${\n policy.type === 'CONTENT'\n ? 'text-status-error-text'\n : policy.type === 'TOOL'\n ? 'text-status-info-text'\n : policy.type === 'BUDGET'\n ? 'text-status-warning-text'\n : 'text-primary'\n }`}\n />\n </div>\n <div>\n <CardTitle className=\"text-base\">{policy.name}</CardTitle>\n </div>\n </div>\n <StatusBadge status={policy.status} />\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <p className=\"text-sm text-text-secondary line-clamp-2\">\n {policy.description}\n </p>\n\n {/* Type Badge */}\n <div className=\"flex items-center justify-between\">\n <Badge variant=\"outline\" className=\"text-xs\">\n {policyTypeLabel[policy.type]}\n </Badge>\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(policy.createdAt)}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n </Link>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={\n selectedType\n ? t('botlit.policies.empty.titleNoType', 'No {{type}} policies', {\n type: policyTypeLabel[selectedType],\n })\n : t('botlit.policies.empty.title', 'No policies')\n }\n description={t(\n 'botlit.policies.empty.description',\n 'Create policies to enforce safety rules and operational limits across your agents.'\n )}\n action={\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('policies/new')}>\n {t('botlit.policies.actions.createPolicy', 'Create Policy')}\n </Link>\n </Button>\n }\n />\n )}\n\n {/* Policy Types Guide */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.policies.overview.title', 'Policy Types')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'botlit.policies.overview.description',\n 'Different policy types control different aspects of agent behavior'\n )}\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\">\n {[\n {\n type: 'CONTENT' as PolicyType,\n desc: t(\n 'botlit.policies.overview.contentDescription',\n 'Detect and block harmful content, jailbreaks, and PII'\n ),\n },\n {\n type: 'TOOL' as PolicyType,\n desc: t(\n 'botlit.policies.overview.toolDescription',\n 'Control which tools agents can access and use'\n ),\n },\n {\n type: 'BUDGET' as PolicyType,\n desc: t(\n 'botlit.policies.overview.budgetDescription',\n 'Set token limits and cost caps per execution'\n ),\n },\n {\n type: 'RATE_LIMIT' as PolicyType,\n desc: t(\n 'botlit.policies.overview.rateLimitDescription',\n 'Limit request frequency to prevent abuse'\n ),\n },\n ].map((item) => (\n <div key={item.type} className=\"p-4 border border-border-subtle rounded-lg\">\n <div className=\"flex items-center gap-2 mb-2\">\n <PolicyTypeIcon type={item.type} className=\"h-5 w-5 text-primary\" />\n <span className=\"font-medium\">{policyTypeLabel[item.type]}</span>\n </div>\n <p className=\"text-sm text-text-secondary\">{item.desc}</p>\n </div>\n ))}\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PoliciesPage.js","names":[],"sources":["../../../src/botlit/pages/PoliciesPage.tsx"],"sourcesContent":["/**\n * Policies Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Plus,\n Search as SearchIcon,\n Filter,\n Shield,\n Wrench,\n Database,\n MessageSquare,\n DollarSign,\n Clock,\n Trash2,\n AlertTriangle,\n} from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport { usePolicies, type PolicyRecord } from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { PolicyType } from '../types';\n\nconst PolicyTypeIcon: FC<{ type: string; className?: string }> = ({ type, className }) => {\n switch (type) {\n case 'CONTENT':\n return <AlertTriangle className={className} />;\n case 'TOOL':\n return <Wrench className={className} />;\n case 'DATA':\n return <Database className={className} />;\n case 'RESPONSE':\n return <MessageSquare className={className} />;\n case 'BUDGET':\n return <DollarSign className={className} />;\n case 'RATE_LIMIT':\n return <Clock className={className} />;\n case 'RETENTION':\n return <Trash2 className={className} />;\n default:\n return <Shield className={className} />;\n }\n};\n\nfunction usePolicyTypeLabel(t: ReturnType<typeof useTr>): Record<string, string> {\n return {\n CONTENT: t('botlit.policies.typeLabel.CONTENT', 'Content Safety'),\n TOOL: t('botlit.policies.typeLabel.TOOL', 'Tool Access'),\n DATA: t('botlit.policies.typeLabel.DATA', 'Data Access'),\n RESPONSE: t('botlit.policies.typeLabel.RESPONSE', 'Response & Models'),\n BUDGET: t('botlit.policies.typeLabel.BUDGET', 'Budget Limits'),\n RATE_LIMIT: t('botlit.policies.typeLabel.RATE_LIMIT', 'Rate Limiting'),\n RETENTION: t('botlit.policies.typeLabel.RETENTION', 'Data Retention'),\n };\n}\n\nexport const PoliciesPage: FC = () => {\n const t = useTr();\n const { getPath } = useBotlit();\n const [search, setSearch] = useState('');\n const [selectedType, setSelectedType] = useState<PolicyType | null>(null);\n const { data: policies, loading, error, refetch } = usePolicies({ search });\n const policyTypeLabel = usePolicyTypeLabel(t);\n\n const filteredPolicies = selectedType\n ? policies.filter((policy) => policy.type === selectedType)\n : policies;\n\n const policyTypes: PolicyType[] = [\n 'CONTENT',\n 'TOOL',\n 'DATA',\n 'RESPONSE',\n 'BUDGET',\n 'RATE_LIMIT',\n 'RETENTION',\n ];\n\n return (\n <PageLayout\n title={t('botlit.policies.title', 'Policies & Guardrails')}\n description={t(\n 'botlit.policies.description',\n 'Configure safety rules, access controls, and operational limits'\n )}\n actions={\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('policies/new')}>\n {t('botlit.policies.actions.createPolicy', 'Create Policy')}\n </Link>\n </Button>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Shield size={18} />}>\n {t(\n 'botlit.policies.purpose',\n 'Policies are the guardrails that keep your agents safe and within budget. Each policy enforces one kind of rule — blocking harmful content or PII, restricting which tools an agent may call, capping token spend, or rate-limiting requests. Define policies here and attach them to agents so every execution stays compliant and predictable.'\n )}\n </PagePurpose>\n\n {/* Policy Type Filters */}\n <div className=\"flex flex-wrap gap-2\">\n <Button\n variant={selectedType === null ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedType(null)}\n >\n {t('botlit.store.filters.all', 'All')}\n </Button>\n {policyTypes.map((type) => (\n <Button\n key={type}\n variant={selectedType === type ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedType(type)}\n leftIcon={<PolicyTypeIcon type={type} className=\"h-4 w-4\" />}\n >\n {policyTypeLabel[type]}\n </Button>\n ))}\n </div>\n\n {/* Search */}\n <div className=\"flex items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <SearchIcon className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={t('botlit.policies.searchPlaceholder', 'Search policies...')}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Button variant=\"outline\" leftIcon={<Filter size={16} />}>\n {t('botlit.policies.actions.moreFilters', 'More Filters')}\n </Button>\n </div>\n\n {/* Policies List */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3, 4, 5, 6].map((i) => (\n <div\n key={i}\n className=\"h-40 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"policies\" error={error} onRetry={() => void refetch()} />\n ) : filteredPolicies.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {filteredPolicies.map((policy: PolicyRecord) => (\n <Link key={policy.id} to={getPath(`policies/${policy.id}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer\">\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div\n className={`p-2 rounded-lg ${\n policy.type === 'CONTENT'\n ? 'bg-status-error-bg-subtle'\n : policy.type === 'TOOL'\n ? 'bg-status-info-bg-subtle'\n : policy.type === 'BUDGET'\n ? 'bg-status-warning-bg-subtle'\n : 'bg-action-primary-bg/10'\n }`}\n >\n <PolicyTypeIcon\n type={policy.type}\n className={`h-5 w-5 ${\n policy.type === 'CONTENT'\n ? 'text-status-error-text'\n : policy.type === 'TOOL'\n ? 'text-status-info-text'\n : policy.type === 'BUDGET'\n ? 'text-status-warning-text'\n : 'text-primary'\n }`}\n />\n </div>\n <div>\n <CardTitle className=\"text-base\">{policy.name}</CardTitle>\n </div>\n </div>\n <StatusBadge status={policy.status} />\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <p className=\"text-sm text-text-secondary line-clamp-2\">\n {policy.description}\n </p>\n\n {/* Type Badge */}\n <div className=\"flex items-center justify-between\">\n <Badge variant=\"outline\" className=\"text-xs\">\n {policyTypeLabel[policy.type]}\n </Badge>\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(policy.createdAt)}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n </Link>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={\n selectedType\n ? t('botlit.policies.empty.titleNoType', 'No {{type}} policies', {\n type: policyTypeLabel[selectedType],\n })\n : t('botlit.policies.empty.title', 'No policies')\n }\n description={t(\n 'botlit.policies.empty.description',\n 'Create policies to enforce safety rules and operational limits across your agents.'\n )}\n action={\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('policies/new')}>\n {t('botlit.policies.actions.createPolicy', 'Create Policy')}\n </Link>\n </Button>\n }\n />\n )}\n\n {/* Policy Types Guide */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.policies.overview.title', 'Policy Types')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'botlit.policies.overview.description',\n 'Different policy types control different aspects of agent behavior'\n )}\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4\">\n {[\n {\n type: 'CONTENT' as PolicyType,\n desc: t(\n 'botlit.policies.overview.contentDescription',\n 'Detect and block harmful content, jailbreaks, and PII'\n ),\n },\n {\n type: 'TOOL' as PolicyType,\n desc: t(\n 'botlit.policies.overview.toolDescription',\n 'Control which tools agents can access and use'\n ),\n },\n {\n type: 'BUDGET' as PolicyType,\n desc: t(\n 'botlit.policies.overview.budgetDescription',\n 'Set token limits and cost caps per execution'\n ),\n },\n {\n type: 'RATE_LIMIT' as PolicyType,\n desc: t(\n 'botlit.policies.overview.rateLimitDescription',\n 'Limit request frequency to prevent abuse'\n ),\n },\n ].map((item) => (\n <div key={item.type} className=\"p-4 border border-border-subtle rounded-lg\">\n <div className=\"flex items-center gap-2 mb-2\">\n <PolicyTypeIcon type={item.type} className=\"h-5 w-5 text-primary\" />\n <span className=\"font-medium\">{policyTypeLabel[item.type]}</span>\n </div>\n <p className=\"text-sm text-text-secondary\">{item.desc}</p>\n </div>\n ))}\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmCA,IAAM,KAA4D,EAAE,SAAM,mBAAgB;AACxF,SAAQ,GAAR;EACE,KAAK,UACH,QAAO,kBAAC,GAAD,EAA0B,cAAa,CAAA;EAChD,KAAK,OACH,QAAO,kBAAC,GAAD,EAAmB,cAAa,CAAA;EACzC,KAAK,OACH,QAAO,kBAAC,GAAD,EAAqB,cAAa,CAAA;EAC3C,KAAK,WACH,QAAO,kBAAC,GAAD,EAA0B,cAAa,CAAA;EAChD,KAAK,SACH,QAAO,kBAAC,GAAD,EAAuB,cAAa,CAAA;EAC7C,KAAK,aACH,QAAO,kBAAC,GAAD,EAAkB,cAAa,CAAA;EACxC,KAAK,YACH,QAAO,kBAAC,GAAD,EAAmB,cAAa,CAAA;EACzC,QACE,QAAO,kBAAC,GAAD,EAAmB,cAAa,CAAA;;;AAI7C,SAAS,EAAmB,GAAqD;AAC/E,QAAO;EACL,SAAS,EAAE,qCAAqC,iBAAiB;EACjE,MAAM,EAAE,kCAAkC,cAAc;EACxD,MAAM,EAAE,kCAAkC,cAAc;EACxD,UAAU,EAAE,sCAAsC,oBAAoB;EACtE,QAAQ,EAAE,oCAAoC,gBAAgB;EAC9D,YAAY,EAAE,wCAAwC,gBAAgB;EACtE,WAAW,EAAE,uCAAuC,iBAAiB;EACtE;;AAGH,IAAa,UAAyB;CACpC,IAAM,IAAI,GAAO,EACX,EAAE,eAAY,GAAW,EACzB,CAAC,GAAQ,KAAa,EAAS,GAAG,EAClC,CAAC,GAAc,KAAmB,EAA4B,KAAK,EACnE,EAAE,MAAM,GAAU,YAAS,UAAO,eAAY,EAAY,EAAE,WAAQ,CAAC,EACrE,IAAkB,EAAmB,EAAE,EAEvC,IAAmB,IACrB,EAAS,QAAQ,MAAW,EAAO,SAAS,EAAa,GACzD;AAYJ,QACE,kBAAC,GAAD;EACE,OAAO,EAAE,yBAAyB,wBAAwB;EAC1D,aAAa,EACX,+BACA,kEACD;EACD,SACE,kBAAC,GAAD;GAAQ,UAAU,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;aAClC,kBAAC,GAAD;IAAM,IAAI,EAAQ,eAAe;cAC9B,EAAE,wCAAwC,gBAAgB;IACtD,CAAA;GACA,CAAA;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KAAa,MAAM,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;eACpC,EACC,2BACA,mVACD;KACW,CAAA;IAGd,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,SAAS,MAAiB,OAAO,YAAY;MAC7C,MAAK;MACL,eAAe,EAAgB,KAAK;gBAEnC,EAAE,4BAA4B,MAAM;MAC9B,CAAA,EAzCiB;MAChC;MACA;MACA;MACA;MACA;MACA;MACA;MACD,CAkCoB,KAAK,MAChB,kBAAC,GAAD;MAEE,SAAS,MAAiB,IAAO,YAAY;MAC7C,MAAK;MACL,eAAe,EAAgB,EAAK;MACpC,UAAU,kBAAC,GAAD;OAAsB;OAAM,WAAU;OAAY,CAAA;gBAE3D,EAAgB;MACV,EAPF,EAOE,CACT,CACE;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAY,WAAU,wEAAyE,CAAA,EAC/F,kBAAC,GAAD;OACE,aAAa,EAAE,qCAAqC,qBAAqB;OACzE,OAAO;OACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;OAC1C,WAAU;OACV,CAAA,CACE;SACN,kBAAC,GAAD;MAAQ,SAAQ;MAAU,UAAU,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;gBACrD,EAAE,uCAAuC,eAAe;MAClD,CAAA,CACL;;IAGL,IACC,kBAAC,OAAD;KAAK,WAAU;eACZ;MAAC;MAAG;MAAG;MAAG;MAAG;MAAG;MAAE,CAAC,KAAK,MACvB,kBAAC,OAAD,EAEE,WAAU,+DACV,EAFK,EAEL,CACF;KACE,CAAA,GACJ,IACF,kBAAC,GAAD;KAAY,UAAS;KAAkB;KAAO,eAAe,KAAK,GAAS;KAAI,CAAA,GAC7E,EAAiB,SAAS,IAC5B,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAiB,KAAK,MACrB,kBAAC,GAAD;MAAsB,IAAI,EAAQ,YAAY,EAAO,KAAK;gBACxD,kBAAC,GAAD;OAAM,WAAU;iBAAhB,CACE,kBAAC,GAAD;QAAY,WAAU;kBACpB,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WACE,WAAW,kBACT,EAAO,SAAS,YACZ,8BACA,EAAO,SAAS,SACd,6BACA,EAAO,SAAS,WACd,gCACA;qBAGV,kBAAC,GAAD;YACE,MAAM,EAAO;YACb,WAAW,WACT,EAAO,SAAS,YACZ,2BACA,EAAO,SAAS,SACd,0BACA,EAAO,SAAS,WACd,6BACA;YAEV,CAAA;WACE,CAAA,EACN,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD;WAAW,WAAU;qBAAa,EAAO;WAAiB,CAAA,EACtD,CAAA,CACF;aACN,kBAAC,GAAD,EAAa,QAAQ,EAAO,QAAU,CAAA,CAClC;;QACK,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAO;SACN,CAAA,EAGJ,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UAAO,SAAQ;UAAU,WAAU;oBAChC,EAAgB,EAAO;UAClB,CAAA,EACR,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAmB,EAAO,UAAU;UAChC,CAAA,CACH;WACF;WACM,CAAA,CACT;;MACF,EAtDI,EAAO,GAsDX,CACP;KACE,CAAA,GAEN,kBAAC,GAAD;KACE,cAAa;KACb,OACE,IACI,EAAE,qCAAqC,wBAAwB,EAC7D,MAAM,EAAgB,IACvB,CAAC,GACF,EAAE,+BAA+B,cAAc;KAErD,aAAa,EACX,qCACA,qFACD;KACD,QACE,kBAAC,GAAD;MAAQ,UAAU,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;gBAClC,kBAAC,GAAD;OAAM,IAAI,EAAQ,eAAe;iBAC9B,EAAE,wCAAwC,gBAAgB;OACtD,CAAA;MACA,CAAA;KAEX,CAAA;IAIJ,kBAAC,GAAD;KAAW,WAAU;KAAQ,MAAA;KAAK,WAAU;eAA5C,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAE,kCAAkC,eAAe;OACjD,CAAA,EACL,kBAAC,KAAD;OAAG,WAAU;iBACV,EACC,wCACA,qEACD;OACC,CAAA,CACA;SACN,kBAAC,OAAD;MAAK,WAAU;gBACZ;OACC;QACE,MAAM;QACN,MAAM,EACJ,+CACA,wDACD;QACF;OACD;QACE,MAAM;QACN,MAAM,EACJ,4CACA,gDACD;QACF;OACD;QACE,MAAM;QACN,MAAM,EACJ,8CACA,+CACD;QACF;OACD;QACE,MAAM;QACN,MAAM,EACJ,iDACA,2CACD;QACF;OACF,CAAC,KAAK,MACL,kBAAC,OAAD;OAAqB,WAAU;iBAA/B,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAgB,MAAM,EAAK;SAAM,WAAU;SAAyB,CAAA,EACpE,kBAAC,QAAD;SAAM,WAAU;mBAAe,EAAgB,EAAK;SAAa,CAAA,CAC7D;WACN,kBAAC,KAAD;QAAG,WAAU;kBAA+B,EAAK;QAAS,CAAA,CACtD;SANI,EAAK,KAMT,CACN;MACE,CAAA,CACI;;IACR;;EACK,CAAA"}