@hasna/contacts 0.6.32 → 0.6.34
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/THIRD_PARTY_NOTICES.md +5 -0
- package/dist/cli/index.js +22033 -5522
- package/dist/index.js +3 -0
- package/dist/mcp/index.js +27401 -11286
- package/dist/server/cloud-index.js +9187 -0
- package/dist/server/index.js +198 -60
- package/migrations/0013_remote_delete_tombstones.sql +15 -0
- package/migrations/0014_contact_tag_filter_index.sql +9 -0
- package/package.json +9 -4
- package/vendor/fast-uri/LICENSE +30 -0
- package/dashboard/dist/assets/index-0l6aQb1t.css +0 -1
- package/dashboard/dist/assets/index-opnZdkVD.js +0 -229
- package/dashboard/dist/index.html +0 -13
- package/dist/cli/commands/advanced.d.ts +0 -3
- package/dist/cli/commands/advanced.d.ts.map +0 -1
- package/dist/cli/commands/audience.d.ts +0 -18
- package/dist/cli/commands/audience.d.ts.map +0 -1
- package/dist/cli/commands/core.d.ts +0 -3
- package/dist/cli/commands/core.d.ts.map +0 -1
- package/dist/cli/commands/crm.d.ts +0 -3
- package/dist/cli/commands/crm.d.ts.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/storage.d.ts +0 -3
- package/dist/cli/storage.d.ts.map +0 -1
- package/dist/cli/utils.d.ts +0 -10
- package/dist/cli/utils.d.ts.map +0 -1
- package/dist/cloud/http-storage.d.ts +0 -88
- package/dist/cloud/http-storage.d.ts.map +0 -1
- package/dist/db/activity.d.ts +0 -15
- package/dist/db/activity.d.ts.map +0 -1
- package/dist/db/applications.d.ts +0 -10
- package/dist/db/applications.d.ts.map +0 -1
- package/dist/db/audiences.d.ts +0 -51
- package/dist/db/audiences.d.ts.map +0 -1
- package/dist/db/companies.d.ts +0 -19
- package/dist/db/companies.d.ts.map +0 -1
- package/dist/db/contact-tasks.d.ts +0 -19
- package/dist/db/contact-tasks.d.ts.map +0 -1
- package/dist/db/contacts.d.ts +0 -30
- package/dist/db/contacts.d.ts.map +0 -1
- package/dist/db/coordination.d.ts +0 -30
- package/dist/db/coordination.d.ts.map +0 -1
- package/dist/db/database.d.ts +0 -8
- package/dist/db/database.d.ts.map +0 -1
- package/dist/db/deals.d.ts +0 -14
- package/dist/db/deals.d.ts.map +0 -1
- package/dist/db/documents.d.ts +0 -38
- package/dist/db/documents.d.ts.map +0 -1
- package/dist/db/events.d.ts +0 -14
- package/dist/db/events.d.ts.map +0 -1
- package/dist/db/field-history.d.ts +0 -17
- package/dist/db/field-history.d.ts.map +0 -1
- package/dist/db/freshness.d.ts +0 -24
- package/dist/db/freshness.d.ts.map +0 -1
- package/dist/db/graph.d.ts +0 -21
- package/dist/db/graph.d.ts.map +0 -1
- package/dist/db/groups.d.ts +0 -22
- package/dist/db/groups.d.ts.map +0 -1
- package/dist/db/health.d.ts +0 -40
- package/dist/db/health.d.ts.map +0 -1
- package/dist/db/identity.d.ts +0 -32
- package/dist/db/identity.d.ts.map +0 -1
- package/dist/db/job-history.d.ts +0 -29
- package/dist/db/job-history.d.ts.map +0 -1
- package/dist/db/learnings.d.ts +0 -43
- package/dist/db/learnings.d.ts.map +0 -1
- package/dist/db/notes.d.ts +0 -8
- package/dist/db/notes.d.ts.map +0 -1
- package/dist/db/org-chart.d.ts +0 -37
- package/dist/db/org-chart.d.ts.map +0 -1
- package/dist/db/org-members.d.ts +0 -9
- package/dist/db/org-members.d.ts.map +0 -1
- package/dist/db/paths.d.ts +0 -3
- package/dist/db/paths.d.ts.map +0 -1
- package/dist/db/pg-migrations.d.ts +0 -8
- package/dist/db/pg-migrations.d.ts.map +0 -1
- package/dist/db/relationships.d.ts +0 -30
- package/dist/db/relationships.d.ts.map +0 -1
- package/dist/db/signals.d.ts +0 -18
- package/dist/db/signals.d.ts.map +0 -1
- package/dist/db/sqlite-adapter.d.ts +0 -15
- package/dist/db/sqlite-adapter.d.ts.map +0 -1
- package/dist/db/storage.d.ts +0 -15
- package/dist/db/storage.d.ts.map +0 -1
- package/dist/db/tags.d.ts +0 -14
- package/dist/db/tags.d.ts.map +0 -1
- package/dist/db/tombstones.d.ts +0 -19
- package/dist/db/tombstones.d.ts.map +0 -1
- package/dist/db/vendor-comms.d.ts +0 -15
- package/dist/db/vendor-comms.d.ts.map +0 -1
- package/dist/generated/storage-kit/health.d.ts +0 -20
- package/dist/generated/storage-kit/health.d.ts.map +0 -1
- package/dist/generated/storage-kit/index.d.ts +0 -8
- package/dist/generated/storage-kit/index.d.ts.map +0 -1
- package/dist/generated/storage-kit/migrations.d.ts +0 -48
- package/dist/generated/storage-kit/migrations.d.ts.map +0 -1
- package/dist/generated/storage-kit/mode.d.ts +0 -48
- package/dist/generated/storage-kit/mode.d.ts.map +0 -1
- package/dist/generated/storage-kit/pool.d.ts +0 -34
- package/dist/generated/storage-kit/pool.d.ts.map +0 -1
- package/dist/generated/storage-kit/query.d.ts +0 -36
- package/dist/generated/storage-kit/query.d.ts.map +0 -1
- package/dist/generated/storage-kit/tls.d.ts +0 -26
- package/dist/generated/storage-kit/tls.d.ts.map +0 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/apple-contacts.d.ts +0 -3
- package/dist/lib/apple-contacts.d.ts.map +0 -1
- package/dist/lib/audience-contract.d.ts +0 -215
- package/dist/lib/audience-contract.d.ts.map +0 -1
- package/dist/lib/audit.d.ts +0 -12
- package/dist/lib/audit.d.ts.map +0 -1
- package/dist/lib/brief.d.ts +0 -3
- package/dist/lib/brief.d.ts.map +0 -1
- package/dist/lib/config.d.ts +0 -7
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/connector.d.ts +0 -44
- package/dist/lib/connector.d.ts.map +0 -1
- package/dist/lib/context.d.ts +0 -5
- package/dist/lib/context.d.ts.map +0 -1
- package/dist/lib/dedup.d.ts +0 -10
- package/dist/lib/dedup.d.ts.map +0 -1
- package/dist/lib/document-scanner.d.ts +0 -8
- package/dist/lib/document-scanner.d.ts.map +0 -1
- package/dist/lib/embeddings.d.ts +0 -9
- package/dist/lib/embeddings.d.ts.map +0 -1
- package/dist/lib/export.d.ts +0 -8
- package/dist/lib/export.d.ts.map +0 -1
- package/dist/lib/freshness.d.ts +0 -19
- package/dist/lib/freshness.d.ts.map +0 -1
- package/dist/lib/gmail-import.d.ts +0 -51
- package/dist/lib/gmail-import.d.ts.map +0 -1
- package/dist/lib/google-contacts.d.ts +0 -115
- package/dist/lib/google-contacts.d.ts.map +0 -1
- package/dist/lib/images.d.ts +0 -30
- package/dist/lib/images.d.ts.map +0 -1
- package/dist/lib/import.d.ts +0 -10
- package/dist/lib/import.d.ts.map +0 -1
- package/dist/lib/learning-maintenance.d.ts +0 -8
- package/dist/lib/learning-maintenance.d.ts.map +0 -1
- package/dist/lib/mailery-sync.d.ts +0 -46
- package/dist/lib/mailery-sync.d.ts.map +0 -1
- package/dist/lib/meeting-capture.d.ts +0 -15
- package/dist/lib/meeting-capture.d.ts.map +0 -1
- package/dist/lib/package-version.d.ts +0 -6
- package/dist/lib/package-version.d.ts.map +0 -1
- package/dist/lib/signals.d.ts +0 -9
- package/dist/lib/signals.d.ts.map +0 -1
- package/dist/lib/signature-parser.d.ts +0 -36
- package/dist/lib/signature-parser.d.ts.map +0 -1
- package/dist/lib/stats.d.ts +0 -24
- package/dist/lib/stats.d.ts.map +0 -1
- package/dist/lib/timeline.d.ts +0 -11
- package/dist/lib/timeline.d.ts.map +0 -1
- package/dist/lib/upcoming.d.ts +0 -14
- package/dist/lib/upcoming.d.ts.map +0 -1
- package/dist/lib/vault.d.ts +0 -24
- package/dist/lib/vault.d.ts.map +0 -1
- package/dist/mcp/handlers/advanced.d.ts +0 -14
- package/dist/mcp/handlers/advanced.d.ts.map +0 -1
- package/dist/mcp/handlers/audience.d.ts +0 -9
- package/dist/mcp/handlers/audience.d.ts.map +0 -1
- package/dist/mcp/handlers/core.d.ts +0 -10
- package/dist/mcp/handlers/core.d.ts.map +0 -1
- package/dist/mcp/handlers/crm.d.ts +0 -14
- package/dist/mcp/handlers/crm.d.ts.map +0 -1
- package/dist/mcp/handlers/index.d.ts +0 -4
- package/dist/mcp/handlers/index.d.ts.map +0 -1
- package/dist/mcp/handlers/types.d.ts +0 -10
- package/dist/mcp/handlers/types.d.ts.map +0 -1
- package/dist/mcp/http.d.ts +0 -17
- package/dist/mcp/http.d.ts.map +0 -1
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/register-tools.d.ts +0 -3
- package/dist/mcp/register-tools.d.ts.map +0 -1
- package/dist/mcp/schema.d.ts +0 -3
- package/dist/mcp/schema.d.ts.map +0 -1
- package/dist/mcp/storage-tools.d.ts +0 -3
- package/dist/mcp/storage-tools.d.ts.map +0 -1
- package/dist/mcp/tools.d.ts +0 -3799
- package/dist/mcp/tools.d.ts.map +0 -1
- package/dist/sdk/index.d.ts +0 -16
- package/dist/sdk/index.d.ts.map +0 -1
- package/dist/sdk/v1.generated.d.ts +0 -203
- package/dist/sdk/v1.generated.d.ts.map +0 -1
- package/dist/server/cloud.d.ts +0 -51
- package/dist/server/cloud.d.ts.map +0 -1
- package/dist/server/index.d.ts +0 -3
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/openapi.d.ts +0 -765
- package/dist/server/openapi.d.ts.map +0 -1
- package/dist/server/pg-store.d.ts +0 -861
- package/dist/server/pg-store.d.ts.map +0 -1
- package/dist/server/security.d.ts +0 -24
- package/dist/server/security.d.ts.map +0 -1
- package/dist/server/serve.d.ts +0 -9
- package/dist/server/serve.d.ts.map +0 -1
- package/dist/server/v1.d.ts +0 -6
- package/dist/server/v1.d.ts.map +0 -1
- package/dist/store/index.d.ts +0 -383
- package/dist/store/index.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -856
- package/dist/types/index.d.ts.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -4513,10 +4513,13 @@ var require_data = __commonJS((exports, module) => {
|
|
|
4513
4513
|
};
|
|
4514
4514
|
});
|
|
4515
4515
|
|
|
4516
|
-
//
|
|
4516
|
+
// vendor/fast-uri/lib/utils.js
|
|
4517
4517
|
var require_utils = __commonJS((exports, module) => {
|
|
4518
4518
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
4519
4519
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
4520
|
+
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
4521
|
+
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
4522
|
+
var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
|
|
4520
4523
|
function stringArrayToHexStripped(input) {
|
|
4521
4524
|
let acc = "";
|
|
4522
4525
|
let code = 0;
|
|
@@ -4710,27 +4713,77 @@ var require_utils = __commonJS((exports, module) => {
|
|
|
4710
4713
|
}
|
|
4711
4714
|
return output.join("");
|
|
4712
4715
|
}
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4716
|
+
var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
|
|
4717
|
+
var HOST_DELIM_RE = /[@/?#:]/g;
|
|
4718
|
+
var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
|
|
4719
|
+
function reescapeHostDelimiters(host, isIP) {
|
|
4720
|
+
const re = isIP ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
|
|
4721
|
+
re.lastIndex = 0;
|
|
4722
|
+
return host.replace(re, (ch) => HOST_DELIMS[ch]);
|
|
4723
|
+
}
|
|
4724
|
+
function normalizePercentEncoding(input, decodeUnreserved = false) {
|
|
4725
|
+
if (input.indexOf("%") === -1) {
|
|
4726
|
+
return input;
|
|
4723
4727
|
}
|
|
4724
|
-
|
|
4725
|
-
|
|
4728
|
+
let output = "";
|
|
4729
|
+
for (let i = 0;i < input.length; i++) {
|
|
4730
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
4731
|
+
const hex = input.slice(i + 1, i + 3);
|
|
4732
|
+
if (isHexPair(hex)) {
|
|
4733
|
+
const normalizedHex = hex.toUpperCase();
|
|
4734
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
4735
|
+
if (decodeUnreserved && isUnreserved(decoded)) {
|
|
4736
|
+
output += decoded;
|
|
4737
|
+
} else {
|
|
4738
|
+
output += "%" + normalizedHex;
|
|
4739
|
+
}
|
|
4740
|
+
i += 2;
|
|
4741
|
+
continue;
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
output += input[i];
|
|
4726
4745
|
}
|
|
4727
|
-
|
|
4728
|
-
|
|
4746
|
+
return output;
|
|
4747
|
+
}
|
|
4748
|
+
function normalizePathEncoding(input) {
|
|
4749
|
+
let output = "";
|
|
4750
|
+
for (let i = 0;i < input.length; i++) {
|
|
4751
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
4752
|
+
const hex = input.slice(i + 1, i + 3);
|
|
4753
|
+
if (isHexPair(hex)) {
|
|
4754
|
+
const normalizedHex = hex.toUpperCase();
|
|
4755
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
4756
|
+
if (decoded !== "." && isUnreserved(decoded)) {
|
|
4757
|
+
output += decoded;
|
|
4758
|
+
} else {
|
|
4759
|
+
output += "%" + normalizedHex;
|
|
4760
|
+
}
|
|
4761
|
+
i += 2;
|
|
4762
|
+
continue;
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
if (isPathCharacter(input[i])) {
|
|
4766
|
+
output += input[i];
|
|
4767
|
+
} else {
|
|
4768
|
+
output += escape(input[i]);
|
|
4769
|
+
}
|
|
4729
4770
|
}
|
|
4730
|
-
|
|
4731
|
-
|
|
4771
|
+
return output;
|
|
4772
|
+
}
|
|
4773
|
+
function escapePreservingEscapes(input) {
|
|
4774
|
+
let output = "";
|
|
4775
|
+
for (let i = 0;i < input.length; i++) {
|
|
4776
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
4777
|
+
const hex = input.slice(i + 1, i + 3);
|
|
4778
|
+
if (isHexPair(hex)) {
|
|
4779
|
+
output += "%" + hex.toUpperCase();
|
|
4780
|
+
i += 2;
|
|
4781
|
+
continue;
|
|
4782
|
+
}
|
|
4783
|
+
}
|
|
4784
|
+
output += escape(input[i]);
|
|
4732
4785
|
}
|
|
4733
|
-
return
|
|
4786
|
+
return output;
|
|
4734
4787
|
}
|
|
4735
4788
|
function recomposeAuthority(component) {
|
|
4736
4789
|
const uriTokens = [];
|
|
@@ -4745,7 +4798,7 @@ var require_utils = __commonJS((exports, module) => {
|
|
|
4745
4798
|
if (ipV6res.isIPV6 === true) {
|
|
4746
4799
|
host = `[${ipV6res.escapedHost}]`;
|
|
4747
4800
|
} else {
|
|
4748
|
-
host =
|
|
4801
|
+
host = reescapeHostDelimiters(host, false);
|
|
4749
4802
|
}
|
|
4750
4803
|
}
|
|
4751
4804
|
uriTokens.push(host);
|
|
@@ -4759,7 +4812,10 @@ var require_utils = __commonJS((exports, module) => {
|
|
|
4759
4812
|
module.exports = {
|
|
4760
4813
|
nonSimpleDomain,
|
|
4761
4814
|
recomposeAuthority,
|
|
4762
|
-
|
|
4815
|
+
reescapeHostDelimiters,
|
|
4816
|
+
normalizePercentEncoding,
|
|
4817
|
+
normalizePathEncoding,
|
|
4818
|
+
escapePreservingEscapes,
|
|
4763
4819
|
removeDotSegments,
|
|
4764
4820
|
isIPv4,
|
|
4765
4821
|
isUUID,
|
|
@@ -4768,7 +4824,7 @@ var require_utils = __commonJS((exports, module) => {
|
|
|
4768
4824
|
};
|
|
4769
4825
|
});
|
|
4770
4826
|
|
|
4771
|
-
//
|
|
4827
|
+
// vendor/fast-uri/lib/schemes.js
|
|
4772
4828
|
var require_schemes = __commonJS((exports, module) => {
|
|
4773
4829
|
var { isUUID } = require_utils();
|
|
4774
4830
|
var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
|
|
@@ -4942,13 +4998,13 @@ var require_schemes = __commonJS((exports, module) => {
|
|
|
4942
4998
|
};
|
|
4943
4999
|
});
|
|
4944
5000
|
|
|
4945
|
-
//
|
|
5001
|
+
// vendor/fast-uri/index.js
|
|
4946
5002
|
var require_fast_uri = __commonJS((exports, module) => {
|
|
4947
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority,
|
|
5003
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
4948
5004
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
4949
5005
|
function normalize(uri, options) {
|
|
4950
5006
|
if (typeof uri === "string") {
|
|
4951
|
-
uri =
|
|
5007
|
+
uri = normalizeString(uri, options);
|
|
4952
5008
|
} else if (typeof uri === "object") {
|
|
4953
5009
|
uri = parse6(serialize(uri, options), options);
|
|
4954
5010
|
}
|
|
@@ -5014,19 +5070,9 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5014
5070
|
return target;
|
|
5015
5071
|
}
|
|
5016
5072
|
function equal(uriA, uriB, options) {
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
} else if (typeof uriA === "object") {
|
|
5021
|
-
uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
|
|
5022
|
-
}
|
|
5023
|
-
if (typeof uriB === "string") {
|
|
5024
|
-
uriB = unescape(uriB);
|
|
5025
|
-
uriB = serialize(normalizeComponentEncoding(parse6(uriB, options), true), { ...options, skipEscape: true });
|
|
5026
|
-
} else if (typeof uriB === "object") {
|
|
5027
|
-
uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
|
|
5028
|
-
}
|
|
5029
|
-
return uriA.toLowerCase() === uriB.toLowerCase();
|
|
5073
|
+
const normalizedA = normalizeComparableURI(uriA, options);
|
|
5074
|
+
const normalizedB = normalizeComparableURI(uriB, options);
|
|
5075
|
+
return normalizedA !== undefined && normalizedB !== undefined && normalizedA.toLowerCase() === normalizedB.toLowerCase();
|
|
5030
5076
|
}
|
|
5031
5077
|
function serialize(cmpts, opts) {
|
|
5032
5078
|
const component = {
|
|
@@ -5052,12 +5098,12 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5052
5098
|
schemeHandler.serialize(component, options);
|
|
5053
5099
|
if (component.path !== undefined) {
|
|
5054
5100
|
if (!options.skipEscape) {
|
|
5055
|
-
component.path =
|
|
5101
|
+
component.path = escapePreservingEscapes(component.path);
|
|
5056
5102
|
if (component.scheme !== undefined) {
|
|
5057
5103
|
component.path = component.path.split("%3A").join(":");
|
|
5058
5104
|
}
|
|
5059
5105
|
} else {
|
|
5060
|
-
component.path =
|
|
5106
|
+
component.path = normalizePercentEncoding(component.path);
|
|
5061
5107
|
}
|
|
5062
5108
|
}
|
|
5063
5109
|
if (options.reference !== "suffix" && component.scheme) {
|
|
@@ -5092,7 +5138,17 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5092
5138
|
return uriTokens.join("");
|
|
5093
5139
|
}
|
|
5094
5140
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
5095
|
-
|
|
5141
|
+
var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
|
|
5142
|
+
function getParseError(parsed, matches) {
|
|
5143
|
+
if (matches[2] !== undefined && parsed.path && parsed.path[0] !== "/") {
|
|
5144
|
+
return 'URI path must start with "/" when authority is present.';
|
|
5145
|
+
}
|
|
5146
|
+
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
|
|
5147
|
+
return "URI port is malformed.";
|
|
5148
|
+
}
|
|
5149
|
+
return;
|
|
5150
|
+
}
|
|
5151
|
+
function parseWithStatus(uri, opts) {
|
|
5096
5152
|
const options = Object.assign({}, opts);
|
|
5097
5153
|
const parsed = {
|
|
5098
5154
|
scheme: undefined,
|
|
@@ -5103,6 +5159,7 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5103
5159
|
query: undefined,
|
|
5104
5160
|
fragment: undefined
|
|
5105
5161
|
};
|
|
5162
|
+
let malformedAuthorityOrPort = false;
|
|
5106
5163
|
let isIP = false;
|
|
5107
5164
|
if (options.reference === "suffix") {
|
|
5108
5165
|
if (options.scheme) {
|
|
@@ -5111,6 +5168,11 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5111
5168
|
uri = "//" + uri;
|
|
5112
5169
|
}
|
|
5113
5170
|
}
|
|
5171
|
+
const authorityMatch = uri.match(AUTHORITY_PREFIX);
|
|
5172
|
+
if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
|
|
5173
|
+
parsed.error = "URI authority must not contain a literal backslash.";
|
|
5174
|
+
malformedAuthorityOrPort = true;
|
|
5175
|
+
}
|
|
5114
5176
|
const matches = uri.match(URI_PARSE);
|
|
5115
5177
|
if (matches) {
|
|
5116
5178
|
parsed.scheme = matches[1];
|
|
@@ -5123,6 +5185,11 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5123
5185
|
if (isNaN(parsed.port)) {
|
|
5124
5186
|
parsed.port = matches[5];
|
|
5125
5187
|
}
|
|
5188
|
+
const parseError = getParseError(parsed, matches);
|
|
5189
|
+
if (parseError !== undefined) {
|
|
5190
|
+
parsed.error = parsed.error || parseError;
|
|
5191
|
+
malformedAuthorityOrPort = true;
|
|
5192
|
+
}
|
|
5126
5193
|
if (parsed.host) {
|
|
5127
5194
|
const ipv4result = isIPv4(parsed.host);
|
|
5128
5195
|
if (ipv4result === false) {
|
|
@@ -5149,7 +5216,7 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5149
5216
|
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
|
|
5150
5217
|
if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
5151
5218
|
try {
|
|
5152
|
-
parsed.host = URL
|
|
5219
|
+
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
5153
5220
|
} catch (e) {
|
|
5154
5221
|
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
5155
5222
|
}
|
|
@@ -5161,14 +5228,18 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5161
5228
|
parsed.scheme = unescape(parsed.scheme);
|
|
5162
5229
|
}
|
|
5163
5230
|
if (parsed.host !== undefined) {
|
|
5164
|
-
parsed.host = unescape(parsed.host);
|
|
5231
|
+
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
|
|
5165
5232
|
}
|
|
5166
5233
|
}
|
|
5167
5234
|
if (parsed.path) {
|
|
5168
|
-
parsed.path =
|
|
5235
|
+
parsed.path = normalizePathEncoding(parsed.path);
|
|
5169
5236
|
}
|
|
5170
5237
|
if (parsed.fragment) {
|
|
5171
|
-
|
|
5238
|
+
try {
|
|
5239
|
+
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
5240
|
+
} catch {
|
|
5241
|
+
parsed.error = parsed.error || "URI malformed";
|
|
5242
|
+
}
|
|
5172
5243
|
}
|
|
5173
5244
|
}
|
|
5174
5245
|
if (schemeHandler && schemeHandler.parse) {
|
|
@@ -5177,7 +5248,29 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
5177
5248
|
} else {
|
|
5178
5249
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
5179
5250
|
}
|
|
5180
|
-
return parsed;
|
|
5251
|
+
return { parsed, malformedAuthorityOrPort };
|
|
5252
|
+
}
|
|
5253
|
+
function parse6(uri, opts) {
|
|
5254
|
+
return parseWithStatus(uri, opts).parsed;
|
|
5255
|
+
}
|
|
5256
|
+
function normalizeString(uri, opts) {
|
|
5257
|
+
return normalizeStringWithStatus(uri, opts).normalized;
|
|
5258
|
+
}
|
|
5259
|
+
function normalizeStringWithStatus(uri, opts) {
|
|
5260
|
+
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
5261
|
+
return {
|
|
5262
|
+
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
5263
|
+
malformedAuthorityOrPort
|
|
5264
|
+
};
|
|
5265
|
+
}
|
|
5266
|
+
function normalizeComparableURI(uri, opts) {
|
|
5267
|
+
if (typeof uri === "string") {
|
|
5268
|
+
const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
|
|
5269
|
+
return malformedAuthorityOrPort ? undefined : normalized;
|
|
5270
|
+
}
|
|
5271
|
+
if (typeof uri === "object") {
|
|
5272
|
+
return serialize(uri, opts);
|
|
5273
|
+
}
|
|
5181
5274
|
}
|
|
5182
5275
|
var fastUri = {
|
|
5183
5276
|
SCHEMES,
|
|
@@ -8923,6 +9016,14 @@ var init_pg_migrations = __esm(() => {
|
|
|
8923
9016
|
CREATE INDEX IF NOT EXISTS idx_contacts_tombstones_deleted_at ON _contacts_tombstones(deleted_at);
|
|
8924
9017
|
|
|
8925
9018
|
INSERT INTO _migrations (version) VALUES (12) ON CONFLICT DO NOTHING;
|
|
9019
|
+
`,
|
|
9020
|
+
`
|
|
9021
|
+
-- The contact_tags primary key is (contact_id, tag_id), which does not
|
|
9022
|
+
-- support the public tag_id filter efficiently. Keep this forward-only and
|
|
9023
|
+
-- idempotent for populated cloud deployments.
|
|
9024
|
+
CREATE INDEX IF NOT EXISTS idx_contact_tags_tag_contact ON contact_tags(tag_id, contact_id);
|
|
9025
|
+
|
|
9026
|
+
INSERT INTO _migrations (version) VALUES (13) ON CONFLICT DO NOTHING;
|
|
8926
9027
|
`
|
|
8927
9028
|
];
|
|
8928
9029
|
});
|
|
@@ -8950,7 +9051,8 @@ function resolveSigningSecret(env = process.env) {
|
|
|
8950
9051
|
return env.HASNA_CONTACTS_API_SIGNING_KEY || env.HASNA_API_SIGNING_KEY || env.API_KEY_SIGNING_SECRET || undefined;
|
|
8951
9052
|
}
|
|
8952
9053
|
function isCloudModeEnabled(env = process.env) {
|
|
8953
|
-
|
|
9054
|
+
const mode = env.HASNA_CONTACTS_STORAGE_MODE || env.CONTACTS_STORAGE_MODE;
|
|
9055
|
+
return Boolean(resolveCloudDatabaseUrl(env)) || mode === "cloud" || mode === "self_hosted";
|
|
8954
9056
|
}
|
|
8955
9057
|
function getCloudClient() {
|
|
8956
9058
|
if (cachedClient)
|
|
@@ -31019,8 +31121,13 @@ async function main() {
|
|
|
31019
31121
|
await buildServer().connect(transport);
|
|
31020
31122
|
console.error("Contacts MCP server running on stdio");
|
|
31021
31123
|
}
|
|
31022
|
-
|
|
31023
|
-
if (
|
|
31124
|
+
function isDirectMcpEntry(entry = process.argv[1]) {
|
|
31125
|
+
if (!entry)
|
|
31126
|
+
return false;
|
|
31127
|
+
const normalized = entry.replaceAll("\\", "/");
|
|
31128
|
+
return normalized.endsWith("/mcp/index.ts") || normalized.endsWith("/mcp/index.js");
|
|
31129
|
+
}
|
|
31130
|
+
if (isDirectMcpEntry()) {
|
|
31024
31131
|
main().catch((err2) => {
|
|
31025
31132
|
console.error("Fatal error:", err2);
|
|
31026
31133
|
process.exit(1);
|
|
@@ -31252,6 +31359,19 @@ class ContactsPgStore {
|
|
|
31252
31359
|
constructor(client) {
|
|
31253
31360
|
this.client = client;
|
|
31254
31361
|
}
|
|
31362
|
+
async attachTags(contacts) {
|
|
31363
|
+
const tagsByContactId = new Map(contacts.map((contact) => [contact.id, []]));
|
|
31364
|
+
if (contacts.length === 0)
|
|
31365
|
+
return [];
|
|
31366
|
+
const rows = await this.client.many(`SELECT ct.contact_id, t.*
|
|
31367
|
+
FROM contact_tags ct
|
|
31368
|
+
JOIN tags t ON t.id = ct.tag_id
|
|
31369
|
+
WHERE ct.contact_id = ANY($1::text[])
|
|
31370
|
+
ORDER BY t.name ASC`, [contacts.map((contact) => contact.id)]);
|
|
31371
|
+
for (const row of rows)
|
|
31372
|
+
tagsByContactId.get(row.contact_id)?.push(mapTag(row));
|
|
31373
|
+
return contacts.map((contact) => ({ ...contact, tags: tagsByContactId.get(contact.id) ?? [] }));
|
|
31374
|
+
}
|
|
31255
31375
|
async listContacts(filter = {}) {
|
|
31256
31376
|
const limit = Math.min(Math.max(filter.limit ?? 50, 1), 500);
|
|
31257
31377
|
const offset = Math.max(filter.offset ?? 0, 0);
|
|
@@ -31265,6 +31385,10 @@ class ContactsPgStore {
|
|
|
31265
31385
|
params.push(filter.status);
|
|
31266
31386
|
where.push(`status = $${params.length}`);
|
|
31267
31387
|
}
|
|
31388
|
+
if (filter.tag_id) {
|
|
31389
|
+
params.push(filter.tag_id);
|
|
31390
|
+
where.push(`EXISTS (SELECT 1 FROM contact_tags ct WHERE ct.contact_id = contacts.id AND ct.tag_id = $${params.length})`);
|
|
31391
|
+
}
|
|
31268
31392
|
if (filter.q) {
|
|
31269
31393
|
params.push(filter.q);
|
|
31270
31394
|
where.push(`search_vector @@ plainto_tsquery('simple', $${params.length})`);
|
|
@@ -31273,11 +31397,13 @@ class ContactsPgStore {
|
|
|
31273
31397
|
const countRow = await this.client.get(`SELECT COUNT(*)::text AS count FROM contacts ${whereSql}`, params);
|
|
31274
31398
|
params.push(limit, offset);
|
|
31275
31399
|
const rows = await this.client.many(`SELECT * FROM contacts ${whereSql} ORDER BY display_name ASC LIMIT $${params.length - 1} OFFSET $${params.length}`, params);
|
|
31276
|
-
return { contacts: rows.map(mapContact), count: Number(countRow?.count ?? rows.length) };
|
|
31400
|
+
return { contacts: await this.attachTags(rows.map(mapContact)), count: Number(countRow?.count ?? rows.length) };
|
|
31277
31401
|
}
|
|
31278
31402
|
async getContact(id) {
|
|
31279
31403
|
const row = await this.client.get(`SELECT * FROM contacts WHERE id = $1`, [id]);
|
|
31280
|
-
|
|
31404
|
+
if (!row)
|
|
31405
|
+
return null;
|
|
31406
|
+
return (await this.attachTags([mapContact(row)]))[0];
|
|
31281
31407
|
}
|
|
31282
31408
|
async createContact(input) {
|
|
31283
31409
|
const id = uuid3();
|
|
@@ -31313,7 +31439,7 @@ class ContactsPgStore {
|
|
|
31313
31439
|
input.priority ?? 3,
|
|
31314
31440
|
input.timezone ?? null
|
|
31315
31441
|
]);
|
|
31316
|
-
return mapContact(row);
|
|
31442
|
+
return (await this.attachTags([mapContact(row)]))[0];
|
|
31317
31443
|
}
|
|
31318
31444
|
async updateContact(id, input) {
|
|
31319
31445
|
const allowed = {};
|
|
@@ -31353,7 +31479,7 @@ class ContactsPgStore {
|
|
|
31353
31479
|
const sets = keys.map((k, i) => `${k} = $${i + 2}`);
|
|
31354
31480
|
sets.push(`updated_at = NOW()`);
|
|
31355
31481
|
const row = await this.client.get(`UPDATE contacts SET ${sets.join(", ")} WHERE id = $1 RETURNING *`, [id, ...keys.map((k) => allowed[k])]);
|
|
31356
|
-
return row ? mapContact(row) : null;
|
|
31482
|
+
return row ? (await this.attachTags([mapContact(row)]))[0] : null;
|
|
31357
31483
|
}
|
|
31358
31484
|
async deleteContact(id) {
|
|
31359
31485
|
const result = await this.client.query(`DELETE FROM contacts WHERE id = $1`, [id]);
|
|
@@ -32815,6 +32941,16 @@ async function readJson(req) {
|
|
|
32815
32941
|
return null;
|
|
32816
32942
|
}
|
|
32817
32943
|
}
|
|
32944
|
+
function contactListFilterFromUrl(url) {
|
|
32945
|
+
return {
|
|
32946
|
+
...url.searchParams.get("company_id") ? { company_id: url.searchParams.get("company_id") } : {},
|
|
32947
|
+
...url.searchParams.get("status") ? { status: url.searchParams.get("status") } : {},
|
|
32948
|
+
...url.searchParams.get("tag_id") ? { tag_id: url.searchParams.get("tag_id") } : {},
|
|
32949
|
+
...url.searchParams.get("q") ? { q: url.searchParams.get("q") } : {},
|
|
32950
|
+
...url.searchParams.get("limit") ? { limit: Number(url.searchParams.get("limit")) } : {},
|
|
32951
|
+
...url.searchParams.get("offset") ? { offset: Number(url.searchParams.get("offset")) } : {}
|
|
32952
|
+
};
|
|
32953
|
+
}
|
|
32818
32954
|
async function handleV1Request(req, url) {
|
|
32819
32955
|
const path = url.pathname;
|
|
32820
32956
|
if (path !== "/v1" && !path.startsWith("/v1/"))
|
|
@@ -32834,7 +32970,12 @@ async function handleV1Request(req, url) {
|
|
|
32834
32970
|
}
|
|
32835
32971
|
await ensureCloudSchemaBestEffort();
|
|
32836
32972
|
const store = getContactsPgStore(getCloudClient());
|
|
32837
|
-
|
|
32973
|
+
let segments;
|
|
32974
|
+
try {
|
|
32975
|
+
segments = path.split("/").filter(Boolean).map((segment) => decodeURIComponent(segment));
|
|
32976
|
+
} catch {
|
|
32977
|
+
return error2(400, "invalid URL path encoding");
|
|
32978
|
+
}
|
|
32838
32979
|
const resource = segments[1];
|
|
32839
32980
|
const id = segments[2];
|
|
32840
32981
|
const sub = segments[3];
|
|
@@ -32923,13 +33064,7 @@ async function handleV1Request(req, url) {
|
|
|
32923
33064
|
if (resource === "contacts") {
|
|
32924
33065
|
if (!id) {
|
|
32925
33066
|
if (method === "GET") {
|
|
32926
|
-
const result = await store.listContacts(
|
|
32927
|
-
...url.searchParams.get("company_id") ? { company_id: url.searchParams.get("company_id") } : {},
|
|
32928
|
-
...url.searchParams.get("status") ? { status: url.searchParams.get("status") } : {},
|
|
32929
|
-
...url.searchParams.get("q") ? { q: url.searchParams.get("q") } : {},
|
|
32930
|
-
...url.searchParams.get("limit") ? { limit: Number(url.searchParams.get("limit")) } : {},
|
|
32931
|
-
...url.searchParams.get("offset") ? { offset: Number(url.searchParams.get("offset")) } : {}
|
|
32932
|
-
});
|
|
33067
|
+
const result = await store.listContacts(contactListFilterFromUrl(url));
|
|
32933
33068
|
return json5(result);
|
|
32934
33069
|
}
|
|
32935
33070
|
if (method === "POST") {
|
|
@@ -33589,6 +33724,7 @@ function getPackageVersion() {
|
|
|
33589
33724
|
// src/server/openapi.ts
|
|
33590
33725
|
var contactSchema = {
|
|
33591
33726
|
type: "object",
|
|
33727
|
+
required: ["tags"],
|
|
33592
33728
|
properties: {
|
|
33593
33729
|
id: { type: "string" },
|
|
33594
33730
|
first_name: { type: "string" },
|
|
@@ -33603,6 +33739,7 @@ var contactSchema = {
|
|
|
33603
33739
|
sensitivity: { type: "string" },
|
|
33604
33740
|
archived: { type: "boolean" },
|
|
33605
33741
|
priority: { type: "number" },
|
|
33742
|
+
tags: { type: "array", items: { $ref: "#/components/schemas/Tag" } },
|
|
33606
33743
|
created_at: { type: "string" },
|
|
33607
33744
|
updated_at: { type: "string" }
|
|
33608
33745
|
}
|
|
@@ -33735,6 +33872,7 @@ function buildV1OpenApiDocument(version2 = getPackageVersion()) {
|
|
|
33735
33872
|
{ name: "q", in: "query", schema: { type: "string" } },
|
|
33736
33873
|
{ name: "company_id", in: "query", schema: { type: "string" } },
|
|
33737
33874
|
{ name: "status", in: "query", schema: { type: "string" } },
|
|
33875
|
+
{ name: "tag_id", in: "query", schema: { type: "string" } },
|
|
33738
33876
|
{ name: "limit", in: "query", schema: { type: "number" } },
|
|
33739
33877
|
{ name: "offset", in: "query", schema: { type: "number" } }
|
|
33740
33878
|
],
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- @hasna/contacts cloud schema (A1 pure-remote) — generated from src/db/pg-migrations.ts
|
|
2
|
+
-- Idempotent and forward-only: retains deletion metadata for remote sync.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS _contacts_tombstones (
|
|
5
|
+
table_name TEXT NOT NULL CHECK(table_name IN ('contacts','companies','tags')),
|
|
6
|
+
row_id TEXT NOT NULL,
|
|
7
|
+
deleted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
8
|
+
actor TEXT,
|
|
9
|
+
reason TEXT,
|
|
10
|
+
PRIMARY KEY (table_name, row_id)
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
CREATE INDEX IF NOT EXISTS idx_contacts_tombstones_deleted_at ON _contacts_tombstones(deleted_at);
|
|
14
|
+
|
|
15
|
+
INSERT INTO _migrations (version) VALUES (12) ON CONFLICT DO NOTHING;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- @hasna/contacts cloud schema (A1 pure-remote) — generated from src/db/pg-migrations.ts
|
|
2
|
+
-- Idempotent and forward-only: supports GET /v1/contacts?tag_id=... filters.
|
|
3
|
+
|
|
4
|
+
-- The contact_tags primary key is (contact_id, tag_id), which does not
|
|
5
|
+
-- support the public tag_id filter efficiently. Keep this forward-only and
|
|
6
|
+
-- idempotent for populated cloud deployments.
|
|
7
|
+
CREATE INDEX IF NOT EXISTS idx_contact_tags_tag_contact ON contact_tags(tag_id, contact_id);
|
|
8
|
+
|
|
9
|
+
INSERT INTO _migrations (version) VALUES (13) ON CONFLICT DO NOTHING;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/contacts",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.34",
|
|
4
4
|
"description": "Contact management for AI coding agents — CLI + MCP + Web",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
"migrations",
|
|
27
27
|
"hasna.contract.json",
|
|
28
28
|
"LICENSE",
|
|
29
|
+
"THIRD_PARTY_NOTICES.md",
|
|
30
|
+
"vendor/fast-uri/LICENSE",
|
|
29
31
|
"README.md"
|
|
30
32
|
],
|
|
31
33
|
"scripts": {
|
|
@@ -33,8 +35,8 @@
|
|
|
33
35
|
"clean:core": "rm -rf dist",
|
|
34
36
|
"build": "bun run clean && cd dashboard && bun run build && cd .. && bun run build:bundles && tsc -p tsconfig.build.json --emitDeclarationOnly --outDir dist",
|
|
35
37
|
"build:core": "bun run clean:core && bun run build:bundles && tsc -p tsconfig.build.json --emitDeclarationOnly --outDir dist",
|
|
36
|
-
"build:bundles": "bun
|
|
37
|
-
"build:server": "rm -rf dist/server dist/sdk && bun
|
|
38
|
+
"build:bundles": "bun run scripts/build-bundles.ts",
|
|
39
|
+
"build:server": "rm -rf dist/server dist/sdk && bun run scripts/build-bundles.ts --server-only",
|
|
38
40
|
"generate:sdk": "bun run scripts/generate-sdk.ts",
|
|
39
41
|
"migrate": "bun run scripts/migrate.ts",
|
|
40
42
|
"typecheck": "tsc --noEmit",
|
|
@@ -75,7 +77,6 @@
|
|
|
75
77
|
"dependencies": {
|
|
76
78
|
"@hasna/contracts": "^0.5.1",
|
|
77
79
|
"@hasna/events": "^0.1.6",
|
|
78
|
-
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
79
80
|
"chalk": "^5.4.1",
|
|
80
81
|
"commander": "^13.1.0",
|
|
81
82
|
"ink": "^5.2.0",
|
|
@@ -87,6 +88,10 @@
|
|
|
87
88
|
"@types/bun": "^1.2.4",
|
|
88
89
|
"@types/pg": "^8.11.11",
|
|
89
90
|
"@types/react": "^18.3.18",
|
|
91
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
90
92
|
"typescript": "^5.7.3"
|
|
93
|
+
},
|
|
94
|
+
"overrides": {
|
|
95
|
+
"fast-uri": "3.1.3"
|
|
91
96
|
}
|
|
92
97
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Copyright (c) 2011-2021, Gary Court until https://github.com/garycourt/uri-js/commit/a1acf730b4bba3f1097c9f52e7d9d3aba8cdcaae
|
|
2
|
+
Copyright (c) 2021-present The Fastify team <https://github.com/fastify/fastify#team>
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
* Redistributions of source code must retain the above copyright
|
|
8
|
+
notice, this list of conditions and the following disclaimer.
|
|
9
|
+
* Redistributions in binary form must reproduce the above copyright
|
|
10
|
+
notice, this list of conditions and the following disclaimer in the
|
|
11
|
+
documentation and/or other materials provided with the distribution.
|
|
12
|
+
* The names of any contributors may not be used to endorse or promote
|
|
13
|
+
products derived from this software without specific prior written
|
|
14
|
+
permission.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
17
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
18
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
|
|
20
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
21
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
22
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
23
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
24
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
25
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
|
|
27
|
+
* * *
|
|
28
|
+
|
|
29
|
+
The complete list of contributors can be found at:
|
|
30
|
+
- https://github.com/garycourt/uri-js/graphs/contributors
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-duration:initial;--tw-space-x-reverse:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-200:oklch(94.5% .129 101.54);--color-yellow-800:oklch(47.6% .114 61.907);--color-yellow-950:oklch(28.6% .066 53.813);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-800:oklch(44.8% .119 151.328);--color-green-900:oklch(39.3% .095 152.535);--color-green-950:oklch(26.6% .065 152.934);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:221.2 83.2% 53.3%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:221.2 83.2% 53.3%;--radius:.5rem}.dark{--background:222.2 84% 4.9%;--foreground:210 40% 98%;--card:222.2 84% 4.9%;--card-foreground:210 40% 98%;--popover:222.2 84% 4.9%;--popover-foreground:210 40% 98%;--primary:217.2 91.2% 59.8%;--primary-foreground:222.2 47.4% 11.2%;--secondary:217.2 32.6% 17.5%;--secondary-foreground:210 40% 98%;--muted:217.2 32.6% 17.5%;--muted-foreground:215 20.2% 65.1%;--accent:217.2 32.6% 17.5%;--accent-foreground:210 40% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:210 40% 98%;--border:217.2 32.6% 17.5%;--input:217.2 32.6% 17.5%;--ring:224.3 76.3% 48%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));min-height:100vh;margin:0;font-family:system-ui,-apple-system,sans-serif}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.end{inset-inline-end:var(--spacing)}.top-4{top:calc(var(--spacing) * 4)}.top-\[50\%\]{top:50%}.right-1{right:calc(var(--spacing) * 1)}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.right-6{right:calc(var(--spacing) * 6)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-2{left:calc(var(--spacing) * 2)}.left-3{left:calc(var(--spacing) * 3)}.left-\[50\%\]{left:50%}.z-50{z-index:50}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-2{margin-left:calc(var(--spacing) * 2)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-14{height:calc(var(--spacing) * 14)}.h-\[calc\(100vh-56px\)\]{height:calc(100vh - 56px)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-full{height:100%}.h-px{height:1px}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[90vh\]{max-height:90vh}.min-h-screen{min-height:100vh}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-9{width:calc(var(--spacing) * 9)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.max-w-7xl{max-width:var(--container-7xl)}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-1{--tw-translate-y:calc(var(--spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-110{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.rotate-0{rotate:0deg}.rotate-90{rotate:90deg}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-green-200{border-color:var(--color-green-200)}.border-red-200{border-color:var(--color-red-200)}.border-transparent{border-color:#0000}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-green-50{background-color:var(--color-green-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-transparent{background-color:#0000}.bg-yellow-50{background-color:var(--color-yellow-50)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pr-9{padding-right:calc(var(--spacing) * 9)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-8{padding-left:calc(var(--spacing) * 8)}.pl-9{padding-left:calc(var(--spacing) * 9)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-green-800{color:var(--color-green-800)}.text-red-800{color:var(--color-red-800)}.text-white{color:var(--color-white)}.text-yellow-800{color:var(--color-yellow-800)}.capitalize{text-transform:capitalize}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-30{opacity:.3}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}@media(hover:hover){.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-100:hover{opacity:1}}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}@media(min-width:40rem){.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}:where(.sm\:space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 2) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius-lg)}.sm\:text-left{text-align:left}}@media(min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media(prefers-color-scheme:dark){.dark\:scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:-rotate-90{rotate:-90deg}.dark\:rotate-0{rotate:0deg}.dark\:border-green-900{border-color:var(--color-green-900)}.dark\:border-red-900{border-color:var(--color-red-900)}.dark\:bg-green-950{background-color:var(--color-green-950)}.dark\:bg-red-950{background-color:var(--color-red-950)}.dark\:bg-yellow-950{background-color:var(--color-yellow-950)}.dark\:text-green-200{color:var(--color-green-200)}.dark\:text-red-200{color:var(--color-red-200)}.dark\:text-yellow-200{color:var(--color-yellow-200)}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing) * 0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-duration{syntax:"*";inherits:false}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}
|