@fayz-ai/plugin-workforce 0.3.14 → 0.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,177 @@
1
+ import { createPluginContext, createCrudPage, WidgetSlot } from '@fayz-ai/admin';
2
+ export { formatCurrency } from '@fayz-ai/admin';
3
+ import React from 'react';
4
+ import { FileText } from 'lucide-react';
5
+ import { PageSubNav, Skeleton, Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '@fayz-ai/ui';
6
+ import { recordRailFields, RECORD_GROUP, activeFacet } from '@fayz-ai/core';
7
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
8
+
9
+ // src/context.tsx
10
+ var ctx = createPluginContext("WorkforcePage");
11
+ var WorkforceContextProvider = ctx.ContextProvider;
12
+ var useWorkforceConfig = ctx.useConfig;
13
+ var useWorkforceProvider = ctx.useProvider;
14
+ var useWorkforceStore = ctx.useStore;
15
+ var PEOPLE_BASE_PATH = "/workforce/people";
16
+ var DEFAULT_STAFF_ENTITY = {
17
+ name: "Colaborador",
18
+ namePlural: "Pessoas",
19
+ icon: "UserCog",
20
+ layout: "person",
21
+ displayField: "name",
22
+ subtitleField: "documentNumber",
23
+ defaultSort: "name",
24
+ formColumns: 2,
25
+ facets: [activeFacet({ active: "Ativos", inactive: "Inativos", all: "Todos" })],
26
+ fieldGroups: [
27
+ { id: "identity", label: "Dados pessoais", columns: 2 },
28
+ { id: "contact", label: "Contato", columns: 2 },
29
+ { id: "where", label: "Endere\xE7o", columns: 1 },
30
+ {
31
+ id: "work",
32
+ label: "V\xEDnculo",
33
+ columns: 2,
34
+ description: "O que a folha e o fisco esperam desta pessoa."
35
+ },
36
+ {
37
+ id: "banking",
38
+ label: "Dados banc\xE1rios",
39
+ columns: 1,
40
+ description: "Para onde o sal\xE1rio SAI \u2014 n\xE3o \xE9 conta da casa."
41
+ },
42
+ { ...RECORD_GROUP }
43
+ ],
44
+ fields: [
45
+ { key: "name", label: "Nome completo", type: "text", required: true, showInTable: true, searchable: true, group: "identity", span: 2 },
46
+ { key: "documentNumber", label: "CPF", type: "text", showInTable: true, searchable: true, group: "identity" },
47
+ { key: "rg", label: "RG", type: "text", showInTable: false, group: "identity" },
48
+ { key: "dateOfBirth", label: "Data de nascimento", type: "date", showInTable: false, group: "identity" },
49
+ {
50
+ key: "gender",
51
+ label: "Sexo",
52
+ type: "select",
53
+ showInTable: false,
54
+ group: "identity",
55
+ options: [
56
+ { value: "masculino", label: "Masculino" },
57
+ { value: "feminino", label: "Feminino" },
58
+ { value: "outro", label: "Outro" }
59
+ ]
60
+ },
61
+ { key: "phone", label: "Telefone", type: "phone", showInTable: true, searchable: true, group: "contact" },
62
+ { key: "mobile", label: "Celular", type: "phone", showInTable: true, group: "contact" },
63
+ { key: "email", label: "E-mail", type: "email", showInTable: false, searchable: true, group: "contact" },
64
+ { key: "address", label: "Endere\xE7o", type: "address", showInTable: false, showInDetail: false, group: "where" },
65
+ {
66
+ key: "employmentType",
67
+ label: "Tipo de v\xEDnculo",
68
+ type: "select",
69
+ showInTable: true,
70
+ group: "work",
71
+ options: [
72
+ { value: "clt", label: "CLT" },
73
+ { value: "pj", label: "Pessoa jur\xEDdica" },
74
+ { value: "autonomo", label: "Aut\xF4nomo" },
75
+ { value: "estagio", label: "Est\xE1gio" },
76
+ { value: "socio", label: "S\xF3cio" }
77
+ ]
78
+ },
79
+ { key: "jobTitle", label: "Cargo", type: "text", showInTable: true, group: "work" },
80
+ { key: "admissionDate", label: "Admiss\xE3o", type: "date", showInTable: false, group: "work" },
81
+ // O ACESSO ÀS AGENDAS dos profissionais: o V1 pergunta isto no cadastro de
82
+ // funcionário porque a recepção marca para os outros, e quem não marca não
83
+ // precisa ver a semana inteira de ninguém.
84
+ {
85
+ key: "isBookable",
86
+ label: "Aparece na agenda",
87
+ type: "boolean",
88
+ showInTable: false,
89
+ defaultValue: false,
90
+ group: "work",
91
+ hint: "Clientes podem ser marcados com esta pessoa."
92
+ },
93
+ // Para onde o salário SAI — a mesma linha de `payee_accounts` que o
94
+ // fornecedor usa. Quem a casa paga é quem a casa paga.
95
+ { key: "payeeAccount", label: "Conta banc\xE1ria", type: "bank", showInTable: false, showInDetail: false, group: "banking" },
96
+ ...recordRailFields({ tagsTable: "people", activeLabel: "Ativo" })
97
+ ],
98
+ data: {
99
+ table: "people",
100
+ tenantScoped: true,
101
+ archetype: "person",
102
+ archetypeKind: "staff",
103
+ customFields: ["rg", "gender", "mobile", "employmentType", "jobTitle", "admissionDate"],
104
+ searchColumns: ["name", "email", "phone", "document_number"]
105
+ }
106
+ };
107
+ function TeamDocuments() {
108
+ const provider = useWorkforceProvider();
109
+ const [team, setTeam] = React.useState(null);
110
+ const [person, setPerson] = React.useState(null);
111
+ React.useEffect(() => {
112
+ let alive = true;
113
+ provider.getStaff().then((people) => {
114
+ if (alive) setTeam(people);
115
+ }).catch(() => {
116
+ if (alive) setTeam([]);
117
+ });
118
+ return () => {
119
+ alive = false;
120
+ };
121
+ }, [provider]);
122
+ if (!team) return /* @__PURE__ */ jsx(Skeleton, { className: "h-40 w-full" });
123
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
124
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
125
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Documentos de" }),
126
+ /* @__PURE__ */ jsxs(
127
+ Select,
128
+ {
129
+ value: person?.id ?? "",
130
+ onValueChange: (id) => setPerson(team.find((p) => p.id === id) ?? null),
131
+ children: [
132
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-full sm:w-72", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: team.length ? "Escolha algu\xE9m da equipe\u2026" : "Nenhuma pessoa cadastrada" }) }),
133
+ /* @__PURE__ */ jsx(SelectContent, { children: team.map((p) => /* @__PURE__ */ jsx(SelectItem, { value: p.id, children: p.name || "Sem nome" }, p.id)) })
134
+ ]
135
+ }
136
+ )
137
+ ] }),
138
+ person ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
139
+ /* @__PURE__ */ jsx(WidgetSlot, { zone: "person.detail.documents", item: person }),
140
+ /* @__PURE__ */ jsx(WidgetSlot, { zone: "person.detail.files", item: person })
141
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-dashed border-border p-8 text-center", children: [
142
+ /* @__PURE__ */ jsx(FileText, { className: "mx-auto mb-3 h-8 w-8 text-muted-foreground", "aria-hidden": true }),
143
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Documentos, contratos, certificados, RG/CPF, etc. Escolha algu\xE9m da equipe acima." })
144
+ ] })
145
+ ] });
146
+ }
147
+ var cache = /* @__PURE__ */ new Map();
148
+ function PeopleView({ entity, mode }) {
149
+ const def = entity ?? DEFAULT_STAFF_ENTITY;
150
+ const Page = React.useMemo(() => {
151
+ const cached = cache.get(def);
152
+ if (cached) return cached;
153
+ const created = createCrudPage(def);
154
+ created.__crudBasePath = PEOPLE_BASE_PATH;
155
+ cache.set(def, created);
156
+ return created;
157
+ }, [def]);
158
+ const [tab, setTab] = React.useState("people");
159
+ const onList = !mode || mode === "list";
160
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
161
+ onList && /* @__PURE__ */ jsx(
162
+ PageSubNav,
163
+ {
164
+ "aria-label": "Pessoas e Documentos",
165
+ items: [
166
+ { id: "people", label: "Pessoas", icon: "Users" },
167
+ { id: "documents", label: "Documentos", icon: "FileText" }
168
+ ].map((i) => ({ ...i, active: tab === i.id, onClick: () => setTab(i.id) }))
169
+ }
170
+ ),
171
+ onList && tab === "documents" ? /* @__PURE__ */ jsx(TeamDocuments, {}) : /* @__PURE__ */ jsx(Page, {})
172
+ ] });
173
+ }
174
+
175
+ export { DEFAULT_STAFF_ENTITY, PeopleView, WorkforceContextProvider, useWorkforceConfig, useWorkforceProvider, useWorkforceStore };
176
+ //# sourceMappingURL=chunk-6GWD6GQK.js.map
177
+ //# sourceMappingURL=chunk-6GWD6GQK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/context.tsx","../src/views/PeopleView.tsx"],"names":[],"mappings":"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","file":"chunk-6GWD6GQK.js","sourcesContent":["import { createPluginContext, formatCurrency, type CurrencyConfig, type EntityLookup } from '@fayz-ai/admin'\nimport type { WorkforcePluginLabels } from './index'\nimport type { WorkforceDataProvider } from './data/types'\nimport type { WorkforceUIState } from './store'\n\n// ---------------------------------------------------------------------------\n// A configuração RESOLVIDA — nada opcional, tudo já mesclado com o padrão.\n// ---------------------------------------------------------------------------\n\nexport interface WorkforceModules {\n /** Escalas: o calendário mensal e o dia. */\n schedules: boolean\n /** Templates: o molde da escala. */\n templates: boolean\n /** Registros de Ponto: a folha, com ajuste auditado. */\n timeEntries: boolean\n /** Fechamento: a competência mensal. */\n periods: boolean\n /** Pessoas & Documentos: a ficha do colaborador. */\n people: boolean\n /** Encargos e Honorários: o custo de pessoal, lido do Financeiro. */\n payrollCosts: boolean\n /**\n * Ficha de RH: vínculo, férias, afastamentos e pendências.\n *\n * Passa pela permissão `workforce_hr.*`, separada de `workforce.*` — quem vê\n * escala e ponto não vê salário nem CID. É o conserto do V1-069, e o FLOW da\n * Ficha diz que ele tinha de ser resolvido ANTES de portar.\n */\n hr: boolean\n}\n\nexport type WorkforceCurrency = CurrencyConfig\n\nexport interface ResolvedWorkforceConfig {\n modules: WorkforceModules\n labels: WorkforcePluginLabels\n currency: WorkforceCurrency\n /** Ver WorkforcePluginOptions.moduleNav. */\n moduleNav?: 'rail' | 'tabs' | 'sidebar'\n /**\n * O valor da hora, quando o app souber dizer.\n *\n * O SQL da jornada NÃO guarda remuneração em lugar nenhum — nem na batida,\n * nem no turno, nem em `public.people`. Sem isto a coluna \"Valor\" da folha\n * não tem de onde sair, e a tela mostra \"—\" em vez de inventar um número.\n */\n hourlyRate?: number\n /** Busca de pessoa para escalar, quando o app quiser oferecer uma. */\n staffLookup?: EntityLookup\n /** Item de nav → feature de acesso, exatamente como o APP declarou. */\n navFeatureMap: Record<string, string>\n}\n\nconst ctx = createPluginContext<ResolvedWorkforceConfig, WorkforceDataProvider, WorkforceUIState>('WorkforcePage')\n\nexport const WorkforceContextProvider = ctx.ContextProvider\nexport const useWorkforceConfig = ctx.useConfig\nexport const useWorkforceProvider = ctx.useProvider\nexport const useWorkforceStore = ctx.useStore\n\nexport { formatCurrency }\n","import React from 'react'\nimport { FileText } from 'lucide-react'\nimport { createCrudPage, WidgetSlot } from '@fayz-ai/admin'\nimport {\n PageSubNav, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Skeleton,\n} from '@fayz-ai/ui'\nimport type { EntityDef } from '@fayz-ai/core'\nimport { RECORD_GROUP, recordRailFields, activeFacet } from '@fayz-ai/core'\nimport { useWorkforceProvider } from '../context'\nimport type { WorkforcePerson } from '../types'\n\n// ---------------------------------------------------------------------------\n// Pessoas & Documentos — a ficha do colaborador.\n//\n// O cadastro não é refeito aqui, e é de propósito: o colaborador já é\n// `public.people` com papel de equipe, e o arquétipo de pessoa do @fayz-ai/admin\n// já desenha a ficha inteira — acesso, unidades, horário, endereços, registros,\n// arquivos, extrato e atividade — para qualquer entidade com `layout: 'person'`.\n//\n// O que o nome da tela promete são DUAS coisas, e a segunda vive dentro da\n// pessoa. No V1 é igual: Cadastros → Funcionários lista gente, e Documentos é\n// uma vista DA ficha (`docs/v1-guide/rh/ficha-de-rh`) — não há, lá, nenhuma\n// tela que liste o documento de todo mundo junto. Por isso a sub-aba não\n// inventa uma lista nova: ela usa o mesmo gesto que a Ficha de RH já usa neste\n// módulo — escolha a pessoa, a pasta dela abre embaixo.\n// ---------------------------------------------------------------------------\n\n/** Onde esta tela mora. É o que faz a linha da tabela abrir a ficha: sem ele o\n * `createCrudPage` navega a partir da raiz e `/workforce/people` vira\n * `#/<uuid>` — uma rota que não existe, e a ficha (com os Documentos dentro)\n * ficava inalcançável. Casa com o `depthMap` de `WorkforcePage`, que já\n * esperava `people-detail` e `people-edit`. */\nconst PEOPLE_BASE_PATH = '/workforce/people'\n\n/** O recorte de `public.people` que o RH edita. O app pode substituir. */\nexport const DEFAULT_STAFF_ENTITY: EntityDef = {\n name: 'Colaborador',\n namePlural: 'Pessoas',\n icon: 'UserCog',\n layout: 'person',\n displayField: 'name',\n subtitleField: 'documentNumber',\n defaultSort: 'name',\n formColumns: 2,\n facets: [activeFacet({ active: 'Ativos', inactive: 'Inativos', all: 'Todos' })],\n fieldGroups: [\n { id: 'identity', label: 'Dados pessoais', columns: 2 },\n { id: 'contact', label: 'Contato', columns: 2 },\n { id: 'where', label: 'Endereço', columns: 1 },\n {\n id: 'work', label: 'Vínculo', columns: 2,\n description: 'O que a folha e o fisco esperam desta pessoa.',\n },\n {\n id: 'banking', label: 'Dados bancários', columns: 1,\n description: 'Para onde o salário SAI — não é conta da casa.',\n },\n { ...RECORD_GROUP },\n ],\n fields: [\n { key: 'name', label: 'Nome completo', type: 'text', required: true, showInTable: true, searchable: true, group: 'identity', span: 2 },\n { key: 'documentNumber', label: 'CPF', type: 'text', showInTable: true, searchable: true, group: 'identity' },\n { key: 'rg', label: 'RG', type: 'text', showInTable: false, group: 'identity' },\n { key: 'dateOfBirth', label: 'Data de nascimento', type: 'date', showInTable: false, group: 'identity' },\n {\n key: 'gender', label: 'Sexo', type: 'select', showInTable: false, group: 'identity',\n options: [\n { value: 'masculino', label: 'Masculino' },\n { value: 'feminino', label: 'Feminino' },\n { value: 'outro', label: 'Outro' },\n ],\n },\n\n { key: 'phone', label: 'Telefone', type: 'phone', showInTable: true, searchable: true, group: 'contact' },\n { key: 'mobile', label: 'Celular', type: 'phone', showInTable: true, group: 'contact' },\n { key: 'email', label: 'E-mail', type: 'email', showInTable: false, searchable: true, group: 'contact' },\n\n { key: 'address', label: 'Endereço', type: 'address', showInTable: false, showInDetail: false, group: 'where' },\n\n {\n key: 'employmentType', label: 'Tipo de vínculo', type: 'select', showInTable: true, group: 'work',\n options: [\n { value: 'clt', label: 'CLT' },\n { value: 'pj', label: 'Pessoa jurídica' },\n { value: 'autonomo', label: 'Autônomo' },\n { value: 'estagio', label: 'Estágio' },\n { value: 'socio', label: 'Sócio' },\n ],\n },\n { key: 'jobTitle', label: 'Cargo', type: 'text', showInTable: true, group: 'work' },\n { key: 'admissionDate', label: 'Admissão', type: 'date', showInTable: false, group: 'work' },\n // O ACESSO ÀS AGENDAS dos profissionais: o V1 pergunta isto no cadastro de\n // funcionário porque a recepção marca para os outros, e quem não marca não\n // precisa ver a semana inteira de ninguém.\n {\n key: 'isBookable', label: 'Aparece na agenda', type: 'boolean',\n showInTable: false, defaultValue: false, group: 'work',\n hint: 'Clientes podem ser marcados com esta pessoa.',\n },\n\n // Para onde o salário SAI — a mesma linha de `payee_accounts` que o\n // fornecedor usa. Quem a casa paga é quem a casa paga.\n { key: 'payeeAccount', label: 'Conta bancária', type: 'bank', showInTable: false, showInDetail: false, group: 'banking' },\n\n ...recordRailFields({ tagsTable: 'people', activeLabel: 'Ativo' }),\n ],\n data: {\n table: 'people',\n tenantScoped: true,\n archetype: 'person',\n archetypeKind: 'staff',\n customFields: ['rg', 'gender', 'mobile', 'employmentType', 'jobTitle', 'admissionDate'],\n searchColumns: ['name', 'email', 'phone', 'document_number'],\n },\n}\n\n/**\n * A pasta de uma pessoa da equipe.\n *\n * Mesma forma da Ficha de RH: o seletor em cima, sempre, e o conteúdo embaixo.\n * As duas superfícies são as MESMAS da ficha do arquétipo — `WidgetSlot` monta\n * quem estiver registrado nas zonas `person.detail.documents` (o que foi\n * preenchido) e `person.detail.files` (o que foi anexado). Num app sem plugin\n * de documentos nada aparece, que é a resposta honesta.\n */\nfunction TeamDocuments() {\n const provider = useWorkforceProvider()\n const [team, setTeam] = React.useState<WorkforcePerson[] | null>(null)\n const [person, setPerson] = React.useState<WorkforcePerson | null>(null)\n\n React.useEffect(() => {\n let alive = true\n provider.getStaff()\n .then((people) => { if (alive) setTeam(people) })\n .catch(() => { if (alive) setTeam([]) })\n return () => { alive = false }\n }, [provider])\n\n if (!team) return <Skeleton className=\"h-40 w-full\" />\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">Documentos de</span>\n <Select\n value={person?.id ?? ''}\n onValueChange={(id) => setPerson(team.find((p) => p.id === id) ?? null)}\n >\n <SelectTrigger className=\"w-full sm:w-72\">\n <SelectValue placeholder={team.length ? 'Escolha alguém da equipe…' : 'Nenhuma pessoa cadastrada'} />\n </SelectTrigger>\n <SelectContent>\n {team.map((p) => <SelectItem key={p.id} value={p.id}>{p.name || 'Sem nome'}</SelectItem>)}\n </SelectContent>\n </Select>\n </div>\n\n {person ? (\n <div className=\"space-y-4\">\n <WidgetSlot zone=\"person.detail.documents\" item={person} />\n <WidgetSlot zone=\"person.detail.files\" item={person} />\n </div>\n ) : (\n <div className=\"rounded-xl border border-dashed border-border p-8 text-center\">\n <FileText className=\"mx-auto mb-3 h-8 w-8 text-muted-foreground\" aria-hidden />\n {/* A legenda é a do V1, literal (bloco Anexos da ficha). */}\n <p className=\"text-sm text-muted-foreground\">\n Documentos, contratos, certificados, RG/CPF, etc. Escolha alguém da equipe acima.\n </p>\n </div>\n )}\n </div>\n )\n}\n\n/** Memoizado por entidade: `createCrudPage` monta um store, e remontá-lo a cada\n * render zeraria a lista sempre que a aba repintasse. */\nconst cache = new Map<EntityDef, React.ComponentType>()\n\nexport function PeopleView({ entity, mode }: {\n entity?: EntityDef\n /** O modo que a rota pediu. Só a LISTA tem sub-abas: com a ficha aberta, a\n * barra de modos diria \"Pessoas\" em cima da pessoa já escolhida. */\n mode?: 'list' | 'new' | 'edit' | 'detail'\n}) {\n const def = entity ?? DEFAULT_STAFF_ENTITY\n const Page = React.useMemo(() => {\n const cached = cache.get(def)\n if (cached) return cached\n const created = createCrudPage(def as never) as React.ComponentType & { __crudBasePath?: string }\n created.__crudBasePath = PEOPLE_BASE_PATH\n cache.set(def, created)\n return created\n }, [def])\n\n const [tab, setTab] = React.useState<'people' | 'documents'>('people')\n const onList = !mode || mode === 'list'\n\n return (\n <>\n {onList && (\n <PageSubNav\n aria-label=\"Pessoas e Documentos\"\n items={[\n { id: 'people', label: 'Pessoas', icon: 'Users' },\n { id: 'documents', label: 'Documentos', icon: 'FileText' },\n ].map((i) => ({ ...i, active: tab === i.id, onClick: () => setTab(i.id as 'people' | 'documents') }))}\n />\n )}\n {onList && tab === 'documents' ? <TeamDocuments /> : <Page />}\n </>\n )\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIlD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAMzD;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,qBAAqB,CAKnE;AAMD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACvC,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,EAAE,CAAC,EAAE,OAAO,CAAA;QACZ,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,YAAY,CAAC,EAAE,OAAO,CAAA;KACvB,CAAA;IACD,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvC,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IACjC,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;IAEvB,sDAAsD;IACtD,YAAY,CAAC,EAAE,qBAAqB,CAAA;IAEpC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;0EACsE;IACtE,WAAW,CAAC,EAAE,SAAS,CAAA;IAEvB,sEAAsE;IACtE,WAAW,CAAC,EAAE,YAAY,CAAA;IAE1B;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvC;AAoBD;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;CAQQ,CAAA;AA4B3C,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,cAAc,CAiItF;AAMD,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AACxD,YAAY,EACV,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,oBAAoB,EAAE,mBAAmB,EACnF,OAAO,EAAE,eAAe,EACxB,gBAAgB,EAAE,aAAa,EAAE,mBAAmB,EACpD,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,mBAAmB,EACnE,eAAe,EAAE,cAAc,EAAE,gBAAgB,GAClD,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,+BAA+B,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAGlD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAMzD;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,qBAAqB,CAKnE;AAMD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACvC,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,EAAE,CAAC,EAAE,OAAO,CAAA;QACZ,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,YAAY,CAAC,EAAE,OAAO,CAAA;KACvB,CAAA;IACD,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvC,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IACjC,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;IAEvB,sDAAsD;IACtD,YAAY,CAAC,EAAE,qBAAqB,CAAA;IAEpC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;0EACsE;IACtE,WAAW,CAAC,EAAE,SAAS,CAAA;IAEvB,sEAAsE;IACtE,WAAW,CAAC,EAAE,YAAY,CAAA;IAE1B;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvC;AAoBD;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;CAQQ,CAAA;AA4B3C,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,cAAc,CAiItF;AAMD,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AACxD,YAAY,EACV,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,oBAAoB,EAAE,mBAAmB,EACnF,OAAO,EAAE,eAAe,EACxB,gBAAgB,EAAE,aAAa,EAAE,mBAAmB,EACpD,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,mBAAmB,EACnE,eAAe,EAAE,cAAc,EAAE,gBAAgB,GAClD,MAAM,SAAS,CAAA;AAOhB,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,+BAA+B,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA"}