@medialane/ui 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/asset-markets-tab.cjs +111 -0
- package/dist/components/asset-markets-tab.cjs.map +1 -0
- package/dist/components/asset-markets-tab.d.cts +16 -0
- package/dist/components/asset-markets-tab.d.ts +16 -0
- package/dist/components/asset-markets-tab.js +87 -0
- package/dist/components/asset-markets-tab.js.map +1 -0
- package/dist/components/asset-overview-content.cjs +102 -0
- package/dist/components/asset-overview-content.cjs.map +1 -0
- package/dist/components/asset-overview-content.d.cts +14 -0
- package/dist/components/asset-overview-content.d.ts +14 -0
- package/dist/components/asset-overview-content.js +78 -0
- package/dist/components/asset-overview-content.js.map +1 -0
- package/dist/components/ip-type-display.cjs +201 -0
- package/dist/components/ip-type-display.cjs.map +1 -0
- package/dist/components/ip-type-display.d.cts +12 -0
- package/dist/components/ip-type-display.d.ts +12 -0
- package/dist/components/ip-type-display.js +181 -0
- package/dist/components/ip-type-display.js.map +1 -0
- package/dist/data/ip-templates.cjs +206 -0
- package/dist/data/ip-templates.cjs.map +1 -0
- package/dist/data/ip-templates.d.cts +45 -0
- package/dist/data/ip-templates.d.ts +45 -0
- package/dist/data/ip-templates.js +200 -0
- package/dist/data/ip-templates.js.map +1 -0
- package/dist/data/ip.cjs +163 -0
- package/dist/data/ip.cjs.map +1 -0
- package/dist/data/ip.d.cts +18 -0
- package/dist/data/ip.d.ts +18 -0
- package/dist/data/ip.js +134 -0
- package/dist/data/ip.js.map +1 -0
- package/dist/index.cjs +33 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/time.cjs +15 -2
- package/dist/utils/time.cjs.map +1 -1
- package/dist/utils/time.d.cts +3 -1
- package/dist/utils/time.d.ts +3 -1
- package/dist/utils/time.js +13 -1
- package/dist/utils/time.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var ip_type_display_exports = {};
|
|
21
|
+
__export(ip_type_display_exports, {
|
|
22
|
+
IPTypeDisplay: () => IPTypeDisplay
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(ip_type_display_exports);
|
|
25
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
26
|
+
var import_ip_templates = require("../data/ip-templates.js");
|
|
27
|
+
var import_lucide_react = require("lucide-react");
|
|
28
|
+
function parseYouTubeEmbed(url) {
|
|
29
|
+
try {
|
|
30
|
+
const u = new URL(url);
|
|
31
|
+
let id = null;
|
|
32
|
+
if (u.hostname.includes("youtu.be")) {
|
|
33
|
+
id = u.pathname.slice(1);
|
|
34
|
+
} else if (u.hostname.includes("youtube.com")) {
|
|
35
|
+
id = u.searchParams.get("v");
|
|
36
|
+
}
|
|
37
|
+
if (!id) return null;
|
|
38
|
+
return `https://www.youtube.com/embed/${id}`;
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function parseSpotifyEmbed(url) {
|
|
44
|
+
try {
|
|
45
|
+
const u = new URL(url);
|
|
46
|
+
if (!u.hostname.includes("spotify.com")) return null;
|
|
47
|
+
const match = u.pathname.match(
|
|
48
|
+
/(track|album|playlist|episode|show|artist)\/([A-Za-z0-9]+)/
|
|
49
|
+
);
|
|
50
|
+
if (!match) return null;
|
|
51
|
+
return `https://open.spotify.com/embed/${match[1]}/${match[2]}`;
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function parseSoundCloudEmbed(url) {
|
|
57
|
+
try {
|
|
58
|
+
new URL(url);
|
|
59
|
+
if (!url.includes("soundcloud.com")) return null;
|
|
60
|
+
const encoded = encodeURIComponent(url);
|
|
61
|
+
return `https://w.soundcloud.com/player/?url=${encoded}&color=%23ff5500&auto_play=false&hide_related=true&show_comments=false&show_user=true&show_reposts=false`;
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function parseTikTokEmbed(url) {
|
|
67
|
+
try {
|
|
68
|
+
const u = new URL(url);
|
|
69
|
+
if (!u.hostname.includes("tiktok.com")) return null;
|
|
70
|
+
const match = u.pathname.match(/\/video\/(\d+)/);
|
|
71
|
+
if (!match) return null;
|
|
72
|
+
return `https://www.tiktok.com/embed/v2/${match[1]}`;
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function parseVimeoEmbed(url) {
|
|
78
|
+
try {
|
|
79
|
+
const u = new URL(url);
|
|
80
|
+
if (!u.hostname.includes("vimeo.com")) return null;
|
|
81
|
+
const match = u.pathname.match(/(\d+)/);
|
|
82
|
+
if (!match) return null;
|
|
83
|
+
return `https://player.vimeo.com/video/${match[1]}`;
|
|
84
|
+
} catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function getEmbedSrc(platform, value) {
|
|
89
|
+
switch (platform) {
|
|
90
|
+
case "youtube":
|
|
91
|
+
return parseYouTubeEmbed(value);
|
|
92
|
+
case "spotify":
|
|
93
|
+
return parseSpotifyEmbed(value);
|
|
94
|
+
case "soundcloud":
|
|
95
|
+
return parseSoundCloudEmbed(value);
|
|
96
|
+
case "tiktok":
|
|
97
|
+
return parseTikTokEmbed(value);
|
|
98
|
+
case "vimeo":
|
|
99
|
+
return parseVimeoEmbed(value);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const COMPACT = {
|
|
103
|
+
spotify: true,
|
|
104
|
+
soundcloud: true,
|
|
105
|
+
youtube: false,
|
|
106
|
+
tiktok: false,
|
|
107
|
+
vimeo: false
|
|
108
|
+
};
|
|
109
|
+
function IPTypeDisplay({ attributes }) {
|
|
110
|
+
const attrs = attributes ?? [];
|
|
111
|
+
const ipType = attrs.find(
|
|
112
|
+
(a) => a.trait_type?.toLowerCase() === "ip type"
|
|
113
|
+
)?.value;
|
|
114
|
+
if (!ipType) return null;
|
|
115
|
+
const template = import_ip_templates.IP_TEMPLATES[ipType];
|
|
116
|
+
if (!template) return null;
|
|
117
|
+
const getAttr = (key) => attrs.find((a) => a.trait_type === key)?.value ?? null;
|
|
118
|
+
const embeds = (template.embeds ?? []).flatMap((platform) => {
|
|
119
|
+
const meta = import_ip_templates.EMBED_PLATFORM_META[platform];
|
|
120
|
+
const value = getAttr(meta.traitKey);
|
|
121
|
+
return value ? [{ platform, meta, value }] : [];
|
|
122
|
+
});
|
|
123
|
+
const socials = (template.socials ?? []).flatMap((platform) => {
|
|
124
|
+
const meta = import_ip_templates.SOCIAL_PLATFORM_META[platform];
|
|
125
|
+
const value = getAttr(meta.traitKey);
|
|
126
|
+
return value ? [{ platform, meta, value }] : [];
|
|
127
|
+
});
|
|
128
|
+
if (embeds.length === 0 && socials.length === 0) return null;
|
|
129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-5", children: [
|
|
130
|
+
embeds.map(({ platform, meta, value }) => {
|
|
131
|
+
const src = getEmbedSrc(platform, value);
|
|
132
|
+
if (src) {
|
|
133
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
134
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: meta.label }),
|
|
135
|
+
COMPACT[platform] ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
136
|
+
"iframe",
|
|
137
|
+
{
|
|
138
|
+
src,
|
|
139
|
+
className: "w-full rounded-xl border-0",
|
|
140
|
+
height: 166,
|
|
141
|
+
allow: "autoplay",
|
|
142
|
+
loading: "lazy",
|
|
143
|
+
title: meta.label
|
|
144
|
+
}
|
|
145
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative w-full aspect-video rounded-xl overflow-hidden bg-muted/20", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
146
|
+
"iframe",
|
|
147
|
+
{
|
|
148
|
+
src,
|
|
149
|
+
className: "absolute inset-0 w-full h-full",
|
|
150
|
+
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
151
|
+
allowFullScreen: true,
|
|
152
|
+
loading: "lazy",
|
|
153
|
+
title: meta.label
|
|
154
|
+
}
|
|
155
|
+
) })
|
|
156
|
+
] }, platform);
|
|
157
|
+
}
|
|
158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
159
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1", children: meta.label }),
|
|
160
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
161
|
+
"a",
|
|
162
|
+
{
|
|
163
|
+
href: value,
|
|
164
|
+
target: "_blank",
|
|
165
|
+
rel: "noopener noreferrer",
|
|
166
|
+
className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline",
|
|
167
|
+
children: [
|
|
168
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ExternalLink, { className: "h-3.5 w-3.5" }),
|
|
169
|
+
"Open link"
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
] }, platform);
|
|
174
|
+
}),
|
|
175
|
+
socials.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
|
|
176
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Links" }),
|
|
177
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-wrap gap-2", children: socials.map(({ platform, meta, value }) => {
|
|
178
|
+
const SIcon = meta.icon;
|
|
179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
180
|
+
"a",
|
|
181
|
+
{
|
|
182
|
+
href: value,
|
|
183
|
+
target: "_blank",
|
|
184
|
+
rel: "noopener noreferrer",
|
|
185
|
+
className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-muted/30 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:text-foreground",
|
|
186
|
+
children: [
|
|
187
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SIcon, { className: "h-3.5 w-3.5" }),
|
|
188
|
+
meta.label
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
platform
|
|
192
|
+
);
|
|
193
|
+
}) })
|
|
194
|
+
] })
|
|
195
|
+
] });
|
|
196
|
+
}
|
|
197
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
198
|
+
0 && (module.exports = {
|
|
199
|
+
IPTypeDisplay
|
|
200
|
+
});
|
|
201
|
+
//# sourceMappingURL=ip-type-display.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/ip-type-display.tsx"],"sourcesContent":["\"use client\";\n\nimport type { IPType } from \"../data/ip.js\";\nimport {\n IP_TEMPLATES,\n EMBED_PLATFORM_META,\n SOCIAL_PLATFORM_META,\n type EmbedPlatform,\n} from \"../data/ip-templates.js\";\nimport { ExternalLink } from \"lucide-react\";\n\ninterface Attr {\n trait_type?: string | null;\n value?: string | null;\n}\n\ninterface IPTypeDisplayProps {\n attributes: Attr[] | null | undefined;\n}\n\n// ── Embed URL parsers ────────────────────────────────────────────────────────\n\nfunction parseYouTubeEmbed(url: string): string | null {\n try {\n const u = new URL(url);\n let id: string | null = null;\n if (u.hostname.includes(\"youtu.be\")) {\n id = u.pathname.slice(1);\n } else if (u.hostname.includes(\"youtube.com\")) {\n id = u.searchParams.get(\"v\");\n }\n if (!id) return null;\n return `https://www.youtube.com/embed/${id}`;\n } catch {\n return null;\n }\n}\n\nfunction parseSpotifyEmbed(url: string): string | null {\n try {\n const u = new URL(url);\n if (!u.hostname.includes(\"spotify.com\")) return null;\n // Spotify's embed endpoint only accepts /embed/{type}/{id}. Isolate the\n // resource type + id so locale prefixes (e.g. /intl-pt) and trailing query\n // params don't leak through — `/embed/intl-pt/album/…` 404s on Spotify.\n const match = u.pathname.match(\n /(track|album|playlist|episode|show|artist)\\/([A-Za-z0-9]+)/\n );\n if (!match) return null;\n return `https://open.spotify.com/embed/${match[1]}/${match[2]}`;\n } catch {\n return null;\n }\n}\n\nfunction parseSoundCloudEmbed(url: string): string | null {\n try {\n new URL(url); // validate\n if (!url.includes(\"soundcloud.com\")) return null;\n const encoded = encodeURIComponent(url);\n return `https://w.soundcloud.com/player/?url=${encoded}&color=%23ff5500&auto_play=false&hide_related=true&show_comments=false&show_user=true&show_reposts=false`;\n } catch {\n return null;\n }\n}\n\nfunction parseTikTokEmbed(url: string): string | null {\n try {\n const u = new URL(url);\n if (!u.hostname.includes(\"tiktok.com\")) return null;\n const match = u.pathname.match(/\\/video\\/(\\d+)/);\n if (!match) return null;\n return `https://www.tiktok.com/embed/v2/${match[1]}`;\n } catch {\n return null;\n }\n}\n\nfunction parseVimeoEmbed(url: string): string | null {\n try {\n const u = new URL(url);\n if (!u.hostname.includes(\"vimeo.com\")) return null;\n const match = u.pathname.match(/(\\d+)/);\n if (!match) return null;\n return `https://player.vimeo.com/video/${match[1]}`;\n } catch {\n return null;\n }\n}\n\nfunction getEmbedSrc(platform: EmbedPlatform, value: string): string | null {\n switch (platform) {\n case \"youtube\": return parseYouTubeEmbed(value);\n case \"spotify\": return parseSpotifyEmbed(value);\n case \"soundcloud\": return parseSoundCloudEmbed(value);\n case \"tiktok\": return parseTikTokEmbed(value);\n case \"vimeo\": return parseVimeoEmbed(value);\n }\n}\n\n// Compact iframe (fixed height) vs 16:9 video frame.\nconst COMPACT: Record<EmbedPlatform, boolean> = {\n spotify: true,\n soundcloud: true,\n youtube: false,\n tiktok: false,\n vimeo: false,\n};\n\n// ── Component ─────────────────────────────────────────────────────────────────\n\nexport function IPTypeDisplay({ attributes }: IPTypeDisplayProps) {\n const attrs = attributes ?? [];\n\n const ipType = attrs.find(\n (a) => a.trait_type?.toLowerCase() === \"ip type\"\n )?.value as IPType | undefined;\n if (!ipType) return null;\n\n const template = IP_TEMPLATES[ipType];\n if (!template) return null;\n\n const getAttr = (key: string) =>\n attrs.find((a) => a.trait_type === key)?.value ?? null;\n\n const embeds = (template.embeds ?? []).flatMap((platform) => {\n const meta = EMBED_PLATFORM_META[platform];\n const value = getAttr(meta.traitKey);\n return value ? [{ platform, meta, value }] : [];\n });\n\n const socials = (template.socials ?? []).flatMap((platform) => {\n const meta = SOCIAL_PLATFORM_META[platform];\n const value = getAttr(meta.traitKey);\n return value ? [{ platform, meta, value }] : [];\n });\n\n if (embeds.length === 0 && socials.length === 0) return null;\n\n return (\n <div className=\"space-y-5\">\n {embeds.map(({ platform, meta, value }) => {\n const src = getEmbedSrc(platform, value);\n if (src) {\n return (\n <div key={platform} className=\"space-y-1.5\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n {meta.label}\n </p>\n {COMPACT[platform] ? (\n <iframe\n src={src}\n className=\"w-full rounded-xl border-0\"\n height={166}\n allow=\"autoplay\"\n loading=\"lazy\"\n title={meta.label}\n />\n ) : (\n <div className=\"relative w-full aspect-video rounded-xl overflow-hidden bg-muted/20\">\n <iframe\n src={src}\n className=\"absolute inset-0 w-full h-full\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowFullScreen\n loading=\"lazy\"\n title={meta.label}\n />\n </div>\n )}\n </div>\n );\n }\n // Fallback: plain external link if URL parsing failed\n return (\n <div key={platform}>\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1\">\n {meta.label}\n </p>\n <a\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1.5 text-sm text-primary hover:underline\"\n >\n <ExternalLink className=\"h-3.5 w-3.5\" />\n Open link\n </a>\n </div>\n );\n })}\n\n {socials.length > 0 && (\n <div className=\"space-y-1.5\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Links\n </p>\n <div className=\"flex flex-wrap gap-2\">\n {socials.map(({ platform, meta, value }) => {\n const SIcon = meta.icon;\n return (\n <a\n key={platform}\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-muted/30 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:text-foreground\"\n >\n <SIcon className=\"h-3.5 w-3.5\" />\n {meta.label}\n </a>\n );\n })}\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface Attr {
|
|
4
|
+
trait_type?: string | null;
|
|
5
|
+
value?: string | null;
|
|
6
|
+
}
|
|
7
|
+
interface IPTypeDisplayProps {
|
|
8
|
+
attributes: Attr[] | null | undefined;
|
|
9
|
+
}
|
|
10
|
+
declare function IPTypeDisplay({ attributes }: IPTypeDisplayProps): react_jsx_runtime.JSX.Element | null;
|
|
11
|
+
|
|
12
|
+
export { IPTypeDisplay };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface Attr {
|
|
4
|
+
trait_type?: string | null;
|
|
5
|
+
value?: string | null;
|
|
6
|
+
}
|
|
7
|
+
interface IPTypeDisplayProps {
|
|
8
|
+
attributes: Attr[] | null | undefined;
|
|
9
|
+
}
|
|
10
|
+
declare function IPTypeDisplay({ attributes }: IPTypeDisplayProps): react_jsx_runtime.JSX.Element | null;
|
|
11
|
+
|
|
12
|
+
export { IPTypeDisplay };
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import {
|
|
4
|
+
IP_TEMPLATES,
|
|
5
|
+
EMBED_PLATFORM_META,
|
|
6
|
+
SOCIAL_PLATFORM_META
|
|
7
|
+
} from "../data/ip-templates.js";
|
|
8
|
+
import { ExternalLink } from "lucide-react";
|
|
9
|
+
function parseYouTubeEmbed(url) {
|
|
10
|
+
try {
|
|
11
|
+
const u = new URL(url);
|
|
12
|
+
let id = null;
|
|
13
|
+
if (u.hostname.includes("youtu.be")) {
|
|
14
|
+
id = u.pathname.slice(1);
|
|
15
|
+
} else if (u.hostname.includes("youtube.com")) {
|
|
16
|
+
id = u.searchParams.get("v");
|
|
17
|
+
}
|
|
18
|
+
if (!id) return null;
|
|
19
|
+
return `https://www.youtube.com/embed/${id}`;
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function parseSpotifyEmbed(url) {
|
|
25
|
+
try {
|
|
26
|
+
const u = new URL(url);
|
|
27
|
+
if (!u.hostname.includes("spotify.com")) return null;
|
|
28
|
+
const match = u.pathname.match(
|
|
29
|
+
/(track|album|playlist|episode|show|artist)\/([A-Za-z0-9]+)/
|
|
30
|
+
);
|
|
31
|
+
if (!match) return null;
|
|
32
|
+
return `https://open.spotify.com/embed/${match[1]}/${match[2]}`;
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function parseSoundCloudEmbed(url) {
|
|
38
|
+
try {
|
|
39
|
+
new URL(url);
|
|
40
|
+
if (!url.includes("soundcloud.com")) return null;
|
|
41
|
+
const encoded = encodeURIComponent(url);
|
|
42
|
+
return `https://w.soundcloud.com/player/?url=${encoded}&color=%23ff5500&auto_play=false&hide_related=true&show_comments=false&show_user=true&show_reposts=false`;
|
|
43
|
+
} catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function parseTikTokEmbed(url) {
|
|
48
|
+
try {
|
|
49
|
+
const u = new URL(url);
|
|
50
|
+
if (!u.hostname.includes("tiktok.com")) return null;
|
|
51
|
+
const match = u.pathname.match(/\/video\/(\d+)/);
|
|
52
|
+
if (!match) return null;
|
|
53
|
+
return `https://www.tiktok.com/embed/v2/${match[1]}`;
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function parseVimeoEmbed(url) {
|
|
59
|
+
try {
|
|
60
|
+
const u = new URL(url);
|
|
61
|
+
if (!u.hostname.includes("vimeo.com")) return null;
|
|
62
|
+
const match = u.pathname.match(/(\d+)/);
|
|
63
|
+
if (!match) return null;
|
|
64
|
+
return `https://player.vimeo.com/video/${match[1]}`;
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function getEmbedSrc(platform, value) {
|
|
70
|
+
switch (platform) {
|
|
71
|
+
case "youtube":
|
|
72
|
+
return parseYouTubeEmbed(value);
|
|
73
|
+
case "spotify":
|
|
74
|
+
return parseSpotifyEmbed(value);
|
|
75
|
+
case "soundcloud":
|
|
76
|
+
return parseSoundCloudEmbed(value);
|
|
77
|
+
case "tiktok":
|
|
78
|
+
return parseTikTokEmbed(value);
|
|
79
|
+
case "vimeo":
|
|
80
|
+
return parseVimeoEmbed(value);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const COMPACT = {
|
|
84
|
+
spotify: true,
|
|
85
|
+
soundcloud: true,
|
|
86
|
+
youtube: false,
|
|
87
|
+
tiktok: false,
|
|
88
|
+
vimeo: false
|
|
89
|
+
};
|
|
90
|
+
function IPTypeDisplay({ attributes }) {
|
|
91
|
+
const attrs = attributes ?? [];
|
|
92
|
+
const ipType = attrs.find(
|
|
93
|
+
(a) => a.trait_type?.toLowerCase() === "ip type"
|
|
94
|
+
)?.value;
|
|
95
|
+
if (!ipType) return null;
|
|
96
|
+
const template = IP_TEMPLATES[ipType];
|
|
97
|
+
if (!template) return null;
|
|
98
|
+
const getAttr = (key) => attrs.find((a) => a.trait_type === key)?.value ?? null;
|
|
99
|
+
const embeds = (template.embeds ?? []).flatMap((platform) => {
|
|
100
|
+
const meta = EMBED_PLATFORM_META[platform];
|
|
101
|
+
const value = getAttr(meta.traitKey);
|
|
102
|
+
return value ? [{ platform, meta, value }] : [];
|
|
103
|
+
});
|
|
104
|
+
const socials = (template.socials ?? []).flatMap((platform) => {
|
|
105
|
+
const meta = SOCIAL_PLATFORM_META[platform];
|
|
106
|
+
const value = getAttr(meta.traitKey);
|
|
107
|
+
return value ? [{ platform, meta, value }] : [];
|
|
108
|
+
});
|
|
109
|
+
if (embeds.length === 0 && socials.length === 0) return null;
|
|
110
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
111
|
+
embeds.map(({ platform, meta, value }) => {
|
|
112
|
+
const src = getEmbedSrc(platform, value);
|
|
113
|
+
if (src) {
|
|
114
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
115
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: meta.label }),
|
|
116
|
+
COMPACT[platform] ? /* @__PURE__ */ jsx(
|
|
117
|
+
"iframe",
|
|
118
|
+
{
|
|
119
|
+
src,
|
|
120
|
+
className: "w-full rounded-xl border-0",
|
|
121
|
+
height: 166,
|
|
122
|
+
allow: "autoplay",
|
|
123
|
+
loading: "lazy",
|
|
124
|
+
title: meta.label
|
|
125
|
+
}
|
|
126
|
+
) : /* @__PURE__ */ jsx("div", { className: "relative w-full aspect-video rounded-xl overflow-hidden bg-muted/20", children: /* @__PURE__ */ jsx(
|
|
127
|
+
"iframe",
|
|
128
|
+
{
|
|
129
|
+
src,
|
|
130
|
+
className: "absolute inset-0 w-full h-full",
|
|
131
|
+
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
132
|
+
allowFullScreen: true,
|
|
133
|
+
loading: "lazy",
|
|
134
|
+
title: meta.label
|
|
135
|
+
}
|
|
136
|
+
) })
|
|
137
|
+
] }, platform);
|
|
138
|
+
}
|
|
139
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
140
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1", children: meta.label }),
|
|
141
|
+
/* @__PURE__ */ jsxs(
|
|
142
|
+
"a",
|
|
143
|
+
{
|
|
144
|
+
href: value,
|
|
145
|
+
target: "_blank",
|
|
146
|
+
rel: "noopener noreferrer",
|
|
147
|
+
className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline",
|
|
148
|
+
children: [
|
|
149
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "h-3.5 w-3.5" }),
|
|
150
|
+
"Open link"
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
] }, platform);
|
|
155
|
+
}),
|
|
156
|
+
socials.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
157
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Links" }),
|
|
158
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: socials.map(({ platform, meta, value }) => {
|
|
159
|
+
const SIcon = meta.icon;
|
|
160
|
+
return /* @__PURE__ */ jsxs(
|
|
161
|
+
"a",
|
|
162
|
+
{
|
|
163
|
+
href: value,
|
|
164
|
+
target: "_blank",
|
|
165
|
+
rel: "noopener noreferrer",
|
|
166
|
+
className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-muted/30 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:text-foreground",
|
|
167
|
+
children: [
|
|
168
|
+
/* @__PURE__ */ jsx(SIcon, { className: "h-3.5 w-3.5" }),
|
|
169
|
+
meta.label
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
platform
|
|
173
|
+
);
|
|
174
|
+
}) })
|
|
175
|
+
] })
|
|
176
|
+
] });
|
|
177
|
+
}
|
|
178
|
+
export {
|
|
179
|
+
IPTypeDisplay
|
|
180
|
+
};
|
|
181
|
+
//# sourceMappingURL=ip-type-display.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/ip-type-display.tsx"],"sourcesContent":["\"use client\";\n\nimport type { IPType } from \"../data/ip.js\";\nimport {\n IP_TEMPLATES,\n EMBED_PLATFORM_META,\n SOCIAL_PLATFORM_META,\n type EmbedPlatform,\n} from \"../data/ip-templates.js\";\nimport { ExternalLink } from \"lucide-react\";\n\ninterface Attr {\n trait_type?: string | null;\n value?: string | null;\n}\n\ninterface IPTypeDisplayProps {\n attributes: Attr[] | null | undefined;\n}\n\n// ── Embed URL parsers ────────────────────────────────────────────────────────\n\nfunction parseYouTubeEmbed(url: string): string | null {\n try {\n const u = new URL(url);\n let id: string | null = null;\n if (u.hostname.includes(\"youtu.be\")) {\n id = u.pathname.slice(1);\n } else if (u.hostname.includes(\"youtube.com\")) {\n id = u.searchParams.get(\"v\");\n }\n if (!id) return null;\n return `https://www.youtube.com/embed/${id}`;\n } catch {\n return null;\n }\n}\n\nfunction parseSpotifyEmbed(url: string): string | null {\n try {\n const u = new URL(url);\n if (!u.hostname.includes(\"spotify.com\")) return null;\n // Spotify's embed endpoint only accepts /embed/{type}/{id}. Isolate the\n // resource type + id so locale prefixes (e.g. /intl-pt) and trailing query\n // params don't leak through — `/embed/intl-pt/album/…` 404s on Spotify.\n const match = u.pathname.match(\n /(track|album|playlist|episode|show|artist)\\/([A-Za-z0-9]+)/\n );\n if (!match) return null;\n return `https://open.spotify.com/embed/${match[1]}/${match[2]}`;\n } catch {\n return null;\n }\n}\n\nfunction parseSoundCloudEmbed(url: string): string | null {\n try {\n new URL(url); // validate\n if (!url.includes(\"soundcloud.com\")) return null;\n const encoded = encodeURIComponent(url);\n return `https://w.soundcloud.com/player/?url=${encoded}&color=%23ff5500&auto_play=false&hide_related=true&show_comments=false&show_user=true&show_reposts=false`;\n } catch {\n return null;\n }\n}\n\nfunction parseTikTokEmbed(url: string): string | null {\n try {\n const u = new URL(url);\n if (!u.hostname.includes(\"tiktok.com\")) return null;\n const match = u.pathname.match(/\\/video\\/(\\d+)/);\n if (!match) return null;\n return `https://www.tiktok.com/embed/v2/${match[1]}`;\n } catch {\n return null;\n }\n}\n\nfunction parseVimeoEmbed(url: string): string | null {\n try {\n const u = new URL(url);\n if (!u.hostname.includes(\"vimeo.com\")) return null;\n const match = u.pathname.match(/(\\d+)/);\n if (!match) return null;\n return `https://player.vimeo.com/video/${match[1]}`;\n } catch {\n return null;\n }\n}\n\nfunction getEmbedSrc(platform: EmbedPlatform, value: string): string | null {\n switch (platform) {\n case \"youtube\": return parseYouTubeEmbed(value);\n case \"spotify\": return parseSpotifyEmbed(value);\n case \"soundcloud\": return parseSoundCloudEmbed(value);\n case \"tiktok\": return parseTikTokEmbed(value);\n case \"vimeo\": return parseVimeoEmbed(value);\n }\n}\n\n// Compact iframe (fixed height) vs 16:9 video frame.\nconst COMPACT: Record<EmbedPlatform, boolean> = {\n spotify: true,\n soundcloud: true,\n youtube: false,\n tiktok: false,\n vimeo: false,\n};\n\n// ── Component ─────────────────────────────────────────────────────────────────\n\nexport function IPTypeDisplay({ attributes }: IPTypeDisplayProps) {\n const attrs = attributes ?? [];\n\n const ipType = attrs.find(\n (a) => a.trait_type?.toLowerCase() === \"ip type\"\n )?.value as IPType | undefined;\n if (!ipType) return null;\n\n const template = IP_TEMPLATES[ipType];\n if (!template) return null;\n\n const getAttr = (key: string) =>\n attrs.find((a) => a.trait_type === key)?.value ?? null;\n\n const embeds = (template.embeds ?? []).flatMap((platform) => {\n const meta = EMBED_PLATFORM_META[platform];\n const value = getAttr(meta.traitKey);\n return value ? [{ platform, meta, value }] : [];\n });\n\n const socials = (template.socials ?? []).flatMap((platform) => {\n const meta = SOCIAL_PLATFORM_META[platform];\n const value = getAttr(meta.traitKey);\n return value ? [{ platform, meta, value }] : [];\n });\n\n if (embeds.length === 0 && socials.length === 0) return null;\n\n return (\n <div className=\"space-y-5\">\n {embeds.map(({ platform, meta, value }) => {\n const src = getEmbedSrc(platform, value);\n if (src) {\n return (\n <div key={platform} className=\"space-y-1.5\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n {meta.label}\n </p>\n {COMPACT[platform] ? (\n <iframe\n src={src}\n className=\"w-full rounded-xl border-0\"\n height={166}\n allow=\"autoplay\"\n loading=\"lazy\"\n title={meta.label}\n />\n ) : (\n <div className=\"relative w-full aspect-video rounded-xl overflow-hidden bg-muted/20\">\n <iframe\n src={src}\n className=\"absolute inset-0 w-full h-full\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowFullScreen\n loading=\"lazy\"\n title={meta.label}\n />\n </div>\n )}\n </div>\n );\n }\n // Fallback: plain external link if URL parsing failed\n return (\n <div key={platform}>\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-1\">\n {meta.label}\n </p>\n <a\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1.5 text-sm text-primary hover:underline\"\n >\n <ExternalLink className=\"h-3.5 w-3.5\" />\n Open link\n </a>\n </div>\n );\n })}\n\n {socials.length > 0 && (\n <div className=\"space-y-1.5\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Links\n </p>\n <div className=\"flex flex-wrap gap-2\">\n {socials.map(({ platform, meta, value }) => {\n const SIcon = meta.icon;\n return (\n <a\n key={platform}\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-full border border-border bg-muted/30 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/40 hover:text-foreground\"\n >\n <SIcon className=\"h-3.5 w-3.5\" />\n {meta.label}\n </a>\n );\n })}\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var ip_templates_exports = {};
|
|
20
|
+
__export(ip_templates_exports, {
|
|
21
|
+
EMBED_PLATFORM_META: () => EMBED_PLATFORM_META,
|
|
22
|
+
IP_TEMPLATES: () => IP_TEMPLATES,
|
|
23
|
+
SOCIAL_PLATFORM_META: () => SOCIAL_PLATFORM_META,
|
|
24
|
+
TEMPLATE_TRAIT_TYPES: () => TEMPLATE_TRAIT_TYPES
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(ip_templates_exports);
|
|
27
|
+
var import_lucide_react = require("lucide-react");
|
|
28
|
+
const EMBED_PLATFORM_META = {
|
|
29
|
+
spotify: { label: "Spotify", icon: import_lucide_react.Music2, traitKey: "Spotify URL", placeholder: "https://open.spotify.com/\u2026" },
|
|
30
|
+
soundcloud: { label: "SoundCloud", icon: import_lucide_react.AudioLines, traitKey: "SoundCloud URL", placeholder: "https://soundcloud.com/\u2026" },
|
|
31
|
+
youtube: { label: "YouTube", icon: import_lucide_react.Youtube, traitKey: "YouTube URL", placeholder: "https://youtube.com/watch?v=\u2026" },
|
|
32
|
+
tiktok: { label: "TikTok", icon: import_lucide_react.Video, traitKey: "TikTok URL", placeholder: "https://tiktok.com/@\u2026/video/\u2026" },
|
|
33
|
+
vimeo: { label: "Vimeo", icon: import_lucide_react.Video, traitKey: "Vimeo URL", placeholder: "https://vimeo.com/\u2026" }
|
|
34
|
+
};
|
|
35
|
+
const SOCIAL_PLATFORM_META = {
|
|
36
|
+
x: { label: "X", icon: import_lucide_react.Twitter, traitKey: "X", placeholder: "https://x.com/\u2026" },
|
|
37
|
+
instagram: { label: "Instagram", icon: import_lucide_react.Instagram, traitKey: "Instagram", placeholder: "https://instagram.com/\u2026" },
|
|
38
|
+
facebook: { label: "Facebook", icon: import_lucide_react.Facebook, traitKey: "Facebook", placeholder: "https://facebook.com/\u2026" },
|
|
39
|
+
tiktok: { label: "TikTok", icon: import_lucide_react.Video, traitKey: "TikTok", placeholder: "https://tiktok.com/@\u2026" },
|
|
40
|
+
website: { label: "Website", icon: import_lucide_react.Globe, traitKey: "Website", placeholder: "https://\u2026" }
|
|
41
|
+
};
|
|
42
|
+
const IP_TEMPLATES = {
|
|
43
|
+
Audio: {
|
|
44
|
+
type: "Audio",
|
|
45
|
+
label: "Audio",
|
|
46
|
+
description: "Music, podcasts, sound effects, audio art",
|
|
47
|
+
icon: import_lucide_react.Music,
|
|
48
|
+
color: { bg: "bg-blue-500/10", text: "text-blue-400", border: "border-blue-500/20" },
|
|
49
|
+
embeds: ["spotify", "soundcloud"],
|
|
50
|
+
traitSuggestions: [
|
|
51
|
+
{ key: "Artist" },
|
|
52
|
+
{ key: "Genre", placeholder: "Soundtrack" },
|
|
53
|
+
{ key: "Mood" },
|
|
54
|
+
{ key: "Label" }
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
Video: {
|
|
58
|
+
type: "Video",
|
|
59
|
+
label: "Video",
|
|
60
|
+
description: "Films, animations, short-form video content",
|
|
61
|
+
icon: import_lucide_react.Clapperboard,
|
|
62
|
+
color: { bg: "bg-red-500/10", text: "text-red-400", border: "border-red-500/20" },
|
|
63
|
+
embeds: ["youtube", "tiktok", "vimeo"],
|
|
64
|
+
traitSuggestions: [
|
|
65
|
+
{ key: "Director" },
|
|
66
|
+
{ key: "Genre" },
|
|
67
|
+
{ key: "Cast" },
|
|
68
|
+
{ key: "Studio" }
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
Art: {
|
|
72
|
+
type: "Art",
|
|
73
|
+
label: "Art",
|
|
74
|
+
description: "Digital and physical artwork, illustrations, generative art",
|
|
75
|
+
icon: import_lucide_react.Palette,
|
|
76
|
+
color: { bg: "bg-purple-500/10", text: "text-purple-400", border: "border-purple-500/20" },
|
|
77
|
+
traitSuggestions: [
|
|
78
|
+
{ key: "Medium", placeholder: "Oil on canvas" },
|
|
79
|
+
{ key: "Style", placeholder: "Impressionism" },
|
|
80
|
+
{ key: "Materials" },
|
|
81
|
+
{ key: "Series" }
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
Photography: {
|
|
85
|
+
type: "Photography",
|
|
86
|
+
label: "Photography",
|
|
87
|
+
description: "Photography, photo essays, visual documentation",
|
|
88
|
+
icon: import_lucide_react.Camera,
|
|
89
|
+
color: { bg: "bg-orange-500/10", text: "text-orange-400", border: "border-orange-500/20" },
|
|
90
|
+
traitSuggestions: [
|
|
91
|
+
{ key: "Camera", placeholder: "Sony A7 IV" },
|
|
92
|
+
{ key: "Location" },
|
|
93
|
+
{ key: "Series" },
|
|
94
|
+
{ key: "Edition" }
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
Posts: {
|
|
98
|
+
type: "Posts",
|
|
99
|
+
label: "Posts",
|
|
100
|
+
description: "Articles, blog posts, social media content, essays",
|
|
101
|
+
icon: import_lucide_react.MessageSquare,
|
|
102
|
+
color: { bg: "bg-sky-500/10", text: "text-sky-400", border: "border-sky-500/20" },
|
|
103
|
+
socials: ["x", "instagram", "facebook", "tiktok", "website"],
|
|
104
|
+
traitSuggestions: [
|
|
105
|
+
{ key: "Author" },
|
|
106
|
+
{ key: "Topic" },
|
|
107
|
+
{ key: "Category" }
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
Publications: {
|
|
111
|
+
type: "Publications",
|
|
112
|
+
label: "Publications",
|
|
113
|
+
description: "Books, journals, magazines, academic papers",
|
|
114
|
+
icon: import_lucide_react.BookOpen,
|
|
115
|
+
color: { bg: "bg-indigo-500/10", text: "text-indigo-400", border: "border-indigo-500/20" },
|
|
116
|
+
socials: ["x", "instagram", "website"],
|
|
117
|
+
traitSuggestions: [
|
|
118
|
+
{ key: "Author" },
|
|
119
|
+
{ key: "Publisher" },
|
|
120
|
+
{ key: "Language", placeholder: "English" },
|
|
121
|
+
{ key: "Edition" }
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
Documents: {
|
|
125
|
+
type: "Documents",
|
|
126
|
+
label: "Documents",
|
|
127
|
+
description: "Contracts, reports, whitepapers, legal documents",
|
|
128
|
+
icon: import_lucide_react.FileText,
|
|
129
|
+
color: { bg: "bg-zinc-500/10", text: "text-zinc-400", border: "border-zinc-500/20" },
|
|
130
|
+
traitSuggestions: [
|
|
131
|
+
{ key: "Author" },
|
|
132
|
+
{ key: "Category" },
|
|
133
|
+
{ key: "Language", placeholder: "English" }
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
Patents: {
|
|
137
|
+
type: "Patents",
|
|
138
|
+
label: "Patents",
|
|
139
|
+
description: "Patents, inventions, technical innovations",
|
|
140
|
+
icon: import_lucide_react.Award,
|
|
141
|
+
color: { bg: "bg-amber-500/10", text: "text-amber-400", border: "border-amber-500/20" },
|
|
142
|
+
traitSuggestions: [
|
|
143
|
+
{ key: "Inventor" },
|
|
144
|
+
{ key: "Field" },
|
|
145
|
+
{ key: "Status" }
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
Software: {
|
|
149
|
+
type: "Software",
|
|
150
|
+
label: "Software",
|
|
151
|
+
description: "Applications, scripts, algorithms, code libraries",
|
|
152
|
+
icon: import_lucide_react.Code2,
|
|
153
|
+
color: { bg: "bg-violet-500/10", text: "text-violet-400", border: "border-violet-500/20" },
|
|
154
|
+
socials: ["website"],
|
|
155
|
+
traitSuggestions: [
|
|
156
|
+
{ key: "Language", placeholder: "TypeScript" },
|
|
157
|
+
{ key: "License" },
|
|
158
|
+
{ key: "Platform" }
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
NFT: {
|
|
162
|
+
type: "NFT",
|
|
163
|
+
label: "NFT",
|
|
164
|
+
description: "Blockchain-native digital assets and collectibles",
|
|
165
|
+
icon: import_lucide_react.Hexagon,
|
|
166
|
+
color: { bg: "bg-teal-500/10", text: "text-teal-400", border: "border-teal-500/20" },
|
|
167
|
+
traitSuggestions: [
|
|
168
|
+
{ key: "Collection" },
|
|
169
|
+
{ key: "Edition" },
|
|
170
|
+
{ key: "Rarity", options: ["Common", "Uncommon", "Rare", "Epic", "Legendary"] }
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
RWA: {
|
|
174
|
+
type: "RWA",
|
|
175
|
+
label: "Real World Asset",
|
|
176
|
+
description: "Tokenized physical assets: real estate, commodities, collectibles",
|
|
177
|
+
icon: import_lucide_react.Building2,
|
|
178
|
+
color: { bg: "bg-emerald-500/10", text: "text-emerald-400", border: "border-emerald-500/20" },
|
|
179
|
+
traitSuggestions: [
|
|
180
|
+
{ key: "Asset Type" },
|
|
181
|
+
{ key: "Location" },
|
|
182
|
+
{ key: "Category" }
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
Custom: {
|
|
186
|
+
type: "Custom",
|
|
187
|
+
label: "Custom",
|
|
188
|
+
description: "Custom IP type \u2014 add your own trait pairs for any metadata",
|
|
189
|
+
icon: import_lucide_react.Layers,
|
|
190
|
+
color: { bg: "bg-muted/50", text: "text-muted-foreground", border: "border-border" }
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
const TEMPLATE_TRAIT_TYPES = /* @__PURE__ */ new Set([
|
|
194
|
+
"IP Type",
|
|
195
|
+
...Object.values(EMBED_PLATFORM_META).map((m) => m.traitKey),
|
|
196
|
+
...Object.values(SOCIAL_PLATFORM_META).map((m) => m.traitKey),
|
|
197
|
+
...Object.values(IP_TEMPLATES).flatMap((t) => (t.traitSuggestions ?? []).map((s) => s.key))
|
|
198
|
+
]);
|
|
199
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
200
|
+
0 && (module.exports = {
|
|
201
|
+
EMBED_PLATFORM_META,
|
|
202
|
+
IP_TEMPLATES,
|
|
203
|
+
SOCIAL_PLATFORM_META,
|
|
204
|
+
TEMPLATE_TRAIT_TYPES
|
|
205
|
+
});
|
|
206
|
+
//# sourceMappingURL=ip-templates.cjs.map
|