@medialane/ui 0.13.1 → 0.14.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.
@@ -24,6 +24,7 @@ __export(ip_type_display_exports, {
24
24
  module.exports = __toCommonJS(ip_type_display_exports);
25
25
  var import_jsx_runtime = require("react/jsx-runtime");
26
26
  var import_ip_templates = require("../data/ip-templates.js");
27
+ var import_ipfs = require("../utils/ipfs.js");
27
28
  var import_lucide_react = require("lucide-react");
28
29
  function parseYouTubeEmbed(url) {
29
30
  try {
@@ -125,8 +126,32 @@ function IPTypeDisplay({ attributes }) {
125
126
  const value = getAttr(meta.traitKey);
126
127
  return value ? [{ platform, meta, value }] : [];
127
128
  });
128
- if (embeds.length === 0 && socials.length === 0) return null;
129
+ const docUri = template.docUpload ? getAttr(template.docUpload.traitType) : null;
130
+ if (embeds.length === 0 && socials.length === 0 && !docUri) return null;
129
131
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-5", children: [
132
+ docUri && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5", children: [
133
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Document" }),
134
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
135
+ "a",
136
+ {
137
+ href: docUri.startsWith("ipfs://") ? (0, import_ipfs.ipfsToHttp)(docUri) : docUri,
138
+ target: "_blank",
139
+ rel: "noopener noreferrer",
140
+ className: "flex items-center gap-3 rounded-xl border border-border bg-muted/20 px-4 py-3 transition-colors hover:border-primary/40 group",
141
+ children: [
142
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.FileText, { className: "h-5 w-5 text-primary shrink-0" }),
143
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0 flex-1", children: [
144
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold group-hover:text-primary transition-colors", children: "View document" }),
145
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-muted-foreground flex items-center gap-1 mt-0.5", children: [
146
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShieldCheck, { className: "h-3 w-3 shrink-0" }),
147
+ "Stored on IPFS \u2014 immutable, timestamped copy of the original"
148
+ ] })
149
+ ] }),
150
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ExternalLink, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" })
151
+ ]
152
+ }
153
+ )
154
+ ] }),
130
155
  embeds.map(({ platform, meta, value }) => {
131
156
  const src = getEmbedSrc(platform, value);
132
157
  if (src) {
@@ -1 +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":[]}
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 { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { ExternalLink, FileText, ShieldCheck } 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 const docUri = template.docUpload ? getAttr(template.docUpload.traitType) : null;\n\n if (embeds.length === 0 && socials.length === 0 && !docUri) return null;\n\n return (\n <div className=\"space-y-5\">\n {/* Document pinned to IPFS — immutable, timestamped copy of the work */}\n {docUri && (\n <div className=\"space-y-1.5\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Document\n </p>\n <a\n href={docUri.startsWith(\"ipfs://\") ? ipfsToHttp(docUri) : docUri}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-3 rounded-xl border border-border bg-muted/20 px-4 py-3 transition-colors hover:border-primary/40 group\"\n >\n <FileText className=\"h-5 w-5 text-primary shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold group-hover:text-primary transition-colors\">\n View document\n </p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1 mt-0.5\">\n <ShieldCheck className=\"h-3 w-3 shrink-0\" />\n Stored on IPFS — immutable, timestamped copy of the original\n </p>\n </div>\n <ExternalLink className=\"h-3.5 w-3.5 text-muted-foreground shrink-0\" />\n </a>\n </div>\n )}\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":[]}
@@ -5,7 +5,8 @@ import {
5
5
  EMBED_PLATFORM_META,
6
6
  SOCIAL_PLATFORM_META
7
7
  } from "../data/ip-templates.js";
8
- import { ExternalLink } from "lucide-react";
8
+ import { ipfsToHttp } from "../utils/ipfs.js";
9
+ import { ExternalLink, FileText, ShieldCheck } from "lucide-react";
9
10
  function parseYouTubeEmbed(url) {
10
11
  try {
11
12
  const u = new URL(url);
@@ -106,8 +107,32 @@ function IPTypeDisplay({ attributes }) {
106
107
  const value = getAttr(meta.traitKey);
107
108
  return value ? [{ platform, meta, value }] : [];
108
109
  });
109
- if (embeds.length === 0 && socials.length === 0) return null;
110
+ const docUri = template.docUpload ? getAttr(template.docUpload.traitType) : null;
111
+ if (embeds.length === 0 && socials.length === 0 && !docUri) return null;
110
112
  return /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
113
+ docUri && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
114
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Document" }),
115
+ /* @__PURE__ */ jsxs(
116
+ "a",
117
+ {
118
+ href: docUri.startsWith("ipfs://") ? ipfsToHttp(docUri) : docUri,
119
+ target: "_blank",
120
+ rel: "noopener noreferrer",
121
+ className: "flex items-center gap-3 rounded-xl border border-border bg-muted/20 px-4 py-3 transition-colors hover:border-primary/40 group",
122
+ children: [
123
+ /* @__PURE__ */ jsx(FileText, { className: "h-5 w-5 text-primary shrink-0" }),
124
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
125
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold group-hover:text-primary transition-colors", children: "View document" }),
126
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground flex items-center gap-1 mt-0.5", children: [
127
+ /* @__PURE__ */ jsx(ShieldCheck, { className: "h-3 w-3 shrink-0" }),
128
+ "Stored on IPFS \u2014 immutable, timestamped copy of the original"
129
+ ] })
130
+ ] }),
131
+ /* @__PURE__ */ jsx(ExternalLink, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" })
132
+ ]
133
+ }
134
+ )
135
+ ] }),
111
136
  embeds.map(({ platform, meta, value }) => {
112
137
  const src = getEmbedSrc(platform, value);
113
138
  if (src) {
@@ -1 +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":[]}
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 { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { ExternalLink, FileText, ShieldCheck } 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 const docUri = template.docUpload ? getAttr(template.docUpload.traitType) : null;\n\n if (embeds.length === 0 && socials.length === 0 && !docUri) return null;\n\n return (\n <div className=\"space-y-5\">\n {/* Document pinned to IPFS — immutable, timestamped copy of the work */}\n {docUri && (\n <div className=\"space-y-1.5\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Document\n </p>\n <a\n href={docUri.startsWith(\"ipfs://\") ? ipfsToHttp(docUri) : docUri}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-3 rounded-xl border border-border bg-muted/20 px-4 py-3 transition-colors hover:border-primary/40 group\"\n >\n <FileText className=\"h-5 w-5 text-primary shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold group-hover:text-primary transition-colors\">\n View document\n </p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1 mt-0.5\">\n <ShieldCheck className=\"h-3 w-3 shrink-0\" />\n Stored on IPFS — immutable, timestamped copy of the original\n </p>\n </div>\n <ExternalLink className=\"h-3.5 w-3.5 text-muted-foreground shrink-0\" />\n </a>\n </div>\n )}\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":[]}
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var ip_templates_exports = {};
20
20
  __export(ip_templates_exports, {
21
+ DOC_UPLOAD: () => DOC_UPLOAD,
21
22
  EMBED_PLATFORM_META: () => EMBED_PLATFORM_META,
22
23
  IP_TEMPLATES: () => IP_TEMPLATES,
23
24
  SOCIAL_PLATFORM_META: () => SOCIAL_PLATFORM_META,
@@ -39,6 +40,12 @@ const SOCIAL_PLATFORM_META = {
39
40
  tiktok: { label: "TikTok", icon: import_lucide_react.Video, traitKey: "TikTok", placeholder: "https://tiktok.com/@\u2026" },
40
41
  website: { label: "Website", icon: import_lucide_react.Globe, traitKey: "Website", placeholder: "https://\u2026" }
41
42
  };
43
+ const DOC_UPLOAD = {
44
+ traitType: "Document File",
45
+ accept: ".pdf,.doc,.docx,.txt,.md,.rtf,.odt",
46
+ maxMb: 20,
47
+ hint: "Stored permanently on IPFS \u2014 an immutable, timestamped copy of your work (proof of authorship under the Berne Convention)."
48
+ };
42
49
  const IP_TEMPLATES = {
43
50
  Audio: {
44
51
  type: "Audio",
@@ -113,6 +120,7 @@ const IP_TEMPLATES = {
113
120
  description: "Books, journals, magazines, academic papers",
114
121
  icon: import_lucide_react.BookOpen,
115
122
  color: { bg: "bg-indigo-500/10", text: "text-indigo-400", border: "border-indigo-500/20" },
123
+ docUpload: DOC_UPLOAD,
116
124
  socials: ["x", "instagram", "website"],
117
125
  traitSuggestions: [
118
126
  { key: "Author" },
@@ -127,6 +135,7 @@ const IP_TEMPLATES = {
127
135
  description: "Contracts, reports, whitepapers, legal documents",
128
136
  icon: import_lucide_react.FileText,
129
137
  color: { bg: "bg-zinc-500/10", text: "text-zinc-400", border: "border-zinc-500/20" },
138
+ docUpload: DOC_UPLOAD,
130
139
  traitSuggestions: [
131
140
  { key: "Author" },
132
141
  { key: "Category" },
@@ -139,6 +148,7 @@ const IP_TEMPLATES = {
139
148
  description: "Patents, inventions, technical innovations",
140
149
  icon: import_lucide_react.Award,
141
150
  color: { bg: "bg-amber-500/10", text: "text-amber-400", border: "border-amber-500/20" },
151
+ docUpload: DOC_UPLOAD,
142
152
  traitSuggestions: [
143
153
  { key: "Inventor" },
144
154
  { key: "Field" },
@@ -151,6 +161,7 @@ const IP_TEMPLATES = {
151
161
  description: "Applications, scripts, algorithms, code libraries",
152
162
  icon: import_lucide_react.Code2,
153
163
  color: { bg: "bg-violet-500/10", text: "text-violet-400", border: "border-violet-500/20" },
164
+ docUpload: DOC_UPLOAD,
154
165
  socials: ["website"],
155
166
  traitSuggestions: [
156
167
  { key: "Language", placeholder: "TypeScript" },
@@ -192,12 +203,14 @@ const IP_TEMPLATES = {
192
203
  };
193
204
  const TEMPLATE_TRAIT_TYPES = /* @__PURE__ */ new Set([
194
205
  "IP Type",
206
+ DOC_UPLOAD.traitType,
195
207
  ...Object.values(EMBED_PLATFORM_META).map((m) => m.traitKey),
196
208
  ...Object.values(SOCIAL_PLATFORM_META).map((m) => m.traitKey),
197
209
  ...Object.values(IP_TEMPLATES).flatMap((t) => (t.traitSuggestions ?? []).map((s) => s.key))
198
210
  ]);
199
211
  // Annotate the CommonJS export names for ESM import in node:
200
212
  0 && (module.exports = {
213
+ DOC_UPLOAD,
201
214
  EMBED_PLATFORM_META,
202
215
  IP_TEMPLATES,
203
216
  SOCIAL_PLATFORM_META,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data/ip-templates.ts"],"sourcesContent":["import {\n Music, Palette, FileText, Hexagon, Clapperboard, Camera,\n Award, MessageSquare, BookOpen, Building2, Code2, Layers,\n Music2, AudioLines, Youtube, Video, Twitter, Instagram, Facebook, Globe,\n type LucideIcon,\n} from \"lucide-react\";\nimport type { IPType } from \"./ip.js\";\n\n// ── Embeds (inline iframe players) ──────────────────────────────────────────\n// Only platforms with clean iframe embeds. Each maps to a stored trait_type key\n// so the asset page can render the player from metadata attributes.\nexport type EmbedPlatform = \"spotify\" | \"soundcloud\" | \"youtube\" | \"tiktok\" | \"vimeo\";\n\nexport const EMBED_PLATFORM_META: Record<\n EmbedPlatform,\n { label: string; icon: LucideIcon; traitKey: string; placeholder: string }\n> = {\n spotify: { label: \"Spotify\", icon: Music2, traitKey: \"Spotify URL\", placeholder: \"https://open.spotify.com/…\" },\n soundcloud: { label: \"SoundCloud\", icon: AudioLines, traitKey: \"SoundCloud URL\", placeholder: \"https://soundcloud.com/…\" },\n youtube: { label: \"YouTube\", icon: Youtube, traitKey: \"YouTube URL\", placeholder: \"https://youtube.com/watch?v=…\" },\n tiktok: { label: \"TikTok\", icon: Video, traitKey: \"TikTok URL\", placeholder: \"https://tiktok.com/@…/video/…\" },\n vimeo: { label: \"Vimeo\", icon: Video, traitKey: \"Vimeo URL\", placeholder: \"https://vimeo.com/…\" },\n};\n\n// ── Socials (icon-chip links — open in a new tab, never iframed) ────────────\n// X / Instagram / Facebook need fragile JS SDKs and sites block iframing, so\n// these render as clickable platform chips on the asset page, not players.\nexport type SocialPlatform = \"x\" | \"instagram\" | \"facebook\" | \"tiktok\" | \"website\";\n\nexport const SOCIAL_PLATFORM_META: Record<\n SocialPlatform,\n { label: string; icon: LucideIcon; traitKey: string; placeholder: string }\n> = {\n x: { label: \"X\", icon: Twitter, traitKey: \"X\", placeholder: \"https://x.com/…\" },\n instagram: { label: \"Instagram\", icon: Instagram, traitKey: \"Instagram\", placeholder: \"https://instagram.com/…\" },\n facebook: { label: \"Facebook\", icon: Facebook, traitKey: \"Facebook\", placeholder: \"https://facebook.com/…\" },\n tiktok: { label: \"TikTok\", icon: Video, traitKey: \"TikTok\", placeholder: \"https://tiktok.com/@…\" },\n website: { label: \"Website\", icon: Globe, traitKey: \"Website\", placeholder: \"https://…\" },\n};\n\n// ── Trait suggestions (friendly, no dates / no technical fields) ────────────\n// Tapping a suggestion pre-fills a trait row. Optional `options` renders the\n// value as a select (e.g. Rarity).\nexport interface TraitSuggestion {\n key: string;\n placeholder?: string;\n options?: string[];\n}\n\nexport interface IPTemplate {\n type: IPType;\n label: string;\n description: string;\n icon: LucideIcon;\n color: { bg: string; text: string; border: string };\n embeds?: EmbedPlatform[];\n socials?: SocialPlatform[];\n traitSuggestions?: TraitSuggestion[];\n}\n\nexport const IP_TEMPLATES: Record<IPType, IPTemplate> = {\n Audio: {\n type: \"Audio\",\n label: \"Audio\",\n description: \"Music, podcasts, sound effects, audio art\",\n icon: Music,\n color: { bg: \"bg-blue-500/10\", text: \"text-blue-400\", border: \"border-blue-500/20\" },\n embeds: [\"spotify\", \"soundcloud\"],\n traitSuggestions: [\n { key: \"Artist\" }, { key: \"Genre\", placeholder: \"Soundtrack\" }, { key: \"Mood\" }, { key: \"Label\" },\n ],\n },\n Video: {\n type: \"Video\",\n label: \"Video\",\n description: \"Films, animations, short-form video content\",\n icon: Clapperboard,\n color: { bg: \"bg-red-500/10\", text: \"text-red-400\", border: \"border-red-500/20\" },\n embeds: [\"youtube\", \"tiktok\", \"vimeo\"],\n traitSuggestions: [\n { key: \"Director\" }, { key: \"Genre\" }, { key: \"Cast\" }, { key: \"Studio\" },\n ],\n },\n Art: {\n type: \"Art\",\n label: \"Art\",\n description: \"Digital and physical artwork, illustrations, generative art\",\n icon: Palette,\n color: { bg: \"bg-purple-500/10\", text: \"text-purple-400\", border: \"border-purple-500/20\" },\n traitSuggestions: [\n { key: \"Medium\", placeholder: \"Oil on canvas\" },\n { key: \"Style\", placeholder: \"Impressionism\" },\n { key: \"Materials\" },\n { key: \"Series\" },\n ],\n },\n Photography: {\n type: \"Photography\",\n label: \"Photography\",\n description: \"Photography, photo essays, visual documentation\",\n icon: Camera,\n color: { bg: \"bg-orange-500/10\", text: \"text-orange-400\", border: \"border-orange-500/20\" },\n traitSuggestions: [\n { key: \"Camera\", placeholder: \"Sony A7 IV\" },\n { key: \"Location\" },\n { key: \"Series\" },\n { key: \"Edition\" },\n ],\n },\n Posts: {\n type: \"Posts\",\n label: \"Posts\",\n description: \"Articles, blog posts, social media content, essays\",\n icon: MessageSquare,\n color: { bg: \"bg-sky-500/10\", text: \"text-sky-400\", border: \"border-sky-500/20\" },\n socials: [\"x\", \"instagram\", \"facebook\", \"tiktok\", \"website\"],\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Topic\" }, { key: \"Category\" },\n ],\n },\n Publications: {\n type: \"Publications\",\n label: \"Publications\",\n description: \"Books, journals, magazines, academic papers\",\n icon: BookOpen,\n color: { bg: \"bg-indigo-500/10\", text: \"text-indigo-400\", border: \"border-indigo-500/20\" },\n socials: [\"x\", \"instagram\", \"website\"],\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Publisher\" }, { key: \"Language\", placeholder: \"English\" }, { key: \"Edition\" },\n ],\n },\n Documents: {\n type: \"Documents\",\n label: \"Documents\",\n description: \"Contracts, reports, whitepapers, legal documents\",\n icon: FileText,\n color: { bg: \"bg-zinc-500/10\", text: \"text-zinc-400\", border: \"border-zinc-500/20\" },\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Category\" }, { key: \"Language\", placeholder: \"English\" },\n ],\n },\n Patents: {\n type: \"Patents\",\n label: \"Patents\",\n description: \"Patents, inventions, technical innovations\",\n icon: Award,\n color: { bg: \"bg-amber-500/10\", text: \"text-amber-400\", border: \"border-amber-500/20\" },\n traitSuggestions: [\n { key: \"Inventor\" }, { key: \"Field\" }, { key: \"Status\" },\n ],\n },\n Software: {\n type: \"Software\",\n label: \"Software\",\n description: \"Applications, scripts, algorithms, code libraries\",\n icon: Code2,\n color: { bg: \"bg-violet-500/10\", text: \"text-violet-400\", border: \"border-violet-500/20\" },\n socials: [\"website\"],\n traitSuggestions: [\n { key: \"Language\", placeholder: \"TypeScript\" }, { key: \"License\" }, { key: \"Platform\" },\n ],\n },\n NFT: {\n type: \"NFT\",\n label: \"NFT\",\n description: \"Blockchain-native digital assets and collectibles\",\n icon: Hexagon,\n color: { bg: \"bg-teal-500/10\", text: \"text-teal-400\", border: \"border-teal-500/20\" },\n traitSuggestions: [\n { key: \"Collection\" },\n { key: \"Edition\" },\n { key: \"Rarity\", options: [\"Common\", \"Uncommon\", \"Rare\", \"Epic\", \"Legendary\"] },\n ],\n },\n RWA: {\n type: \"RWA\",\n label: \"Real World Asset\",\n description: \"Tokenized physical assets: real estate, commodities, collectibles\",\n icon: Building2,\n color: { bg: \"bg-emerald-500/10\", text: \"text-emerald-400\", border: \"border-emerald-500/20\" },\n traitSuggestions: [\n { key: \"Asset Type\" }, { key: \"Location\" }, { key: \"Category\" },\n ],\n },\n Custom: {\n type: \"Custom\",\n label: \"Custom\",\n description: \"Custom IP type — add your own trait pairs for any metadata\",\n icon: Layers,\n color: { bg: \"bg-muted/50\", text: \"text-muted-foreground\", border: \"border-border\" },\n },\n};\n\n/**\n * All trait_type keys owned by templates (embeds + socials + suggestions), plus\n * \"IP Type\" itself. Used to filter template-managed attributes out of other\n * attribute grids so they aren't duplicated.\n */\nexport const TEMPLATE_TRAIT_TYPES = new Set<string>([\n \"IP Type\",\n ...Object.values(EMBED_PLATFORM_META).map((m) => m.traitKey),\n ...Object.values(SOCIAL_PLATFORM_META).map((m) => m.traitKey),\n ...Object.values(IP_TEMPLATES).flatMap((t) => (t.traitSuggestions ?? []).map((s) => s.key)),\n]);\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/data/ip-templates.ts"],"sourcesContent":["import {\n Music, Palette, FileText, Hexagon, Clapperboard, Camera,\n Award, MessageSquare, BookOpen, Building2, Code2, Layers,\n Music2, AudioLines, Youtube, Video, Twitter, Instagram, Facebook, Globe,\n type LucideIcon,\n} from \"lucide-react\";\nimport type { IPType } from \"./ip.js\";\n\n// ── Embeds (inline iframe players) ──────────────────────────────────────────\n// Only platforms with clean iframe embeds. Each maps to a stored trait_type key\n// so the asset page can render the player from metadata attributes.\nexport type EmbedPlatform = \"spotify\" | \"soundcloud\" | \"youtube\" | \"tiktok\" | \"vimeo\";\n\nexport const EMBED_PLATFORM_META: Record<\n EmbedPlatform,\n { label: string; icon: LucideIcon; traitKey: string; placeholder: string }\n> = {\n spotify: { label: \"Spotify\", icon: Music2, traitKey: \"Spotify URL\", placeholder: \"https://open.spotify.com/…\" },\n soundcloud: { label: \"SoundCloud\", icon: AudioLines, traitKey: \"SoundCloud URL\", placeholder: \"https://soundcloud.com/…\" },\n youtube: { label: \"YouTube\", icon: Youtube, traitKey: \"YouTube URL\", placeholder: \"https://youtube.com/watch?v=…\" },\n tiktok: { label: \"TikTok\", icon: Video, traitKey: \"TikTok URL\", placeholder: \"https://tiktok.com/@…/video/…\" },\n vimeo: { label: \"Vimeo\", icon: Video, traitKey: \"Vimeo URL\", placeholder: \"https://vimeo.com/…\" },\n};\n\n// ── Socials (icon-chip links — open in a new tab, never iframed) ────────────\n// X / Instagram / Facebook need fragile JS SDKs and sites block iframing, so\n// these render as clickable platform chips on the asset page, not players.\nexport type SocialPlatform = \"x\" | \"instagram\" | \"facebook\" | \"tiktok\" | \"website\";\n\nexport const SOCIAL_PLATFORM_META: Record<\n SocialPlatform,\n { label: string; icon: LucideIcon; traitKey: string; placeholder: string }\n> = {\n x: { label: \"X\", icon: Twitter, traitKey: \"X\", placeholder: \"https://x.com/…\" },\n instagram: { label: \"Instagram\", icon: Instagram, traitKey: \"Instagram\", placeholder: \"https://instagram.com/…\" },\n facebook: { label: \"Facebook\", icon: Facebook, traitKey: \"Facebook\", placeholder: \"https://facebook.com/…\" },\n tiktok: { label: \"TikTok\", icon: Video, traitKey: \"TikTok\", placeholder: \"https://tiktok.com/@…\" },\n website: { label: \"Website\", icon: Globe, traitKey: \"Website\", placeholder: \"https://…\" },\n};\n\n// ── Trait suggestions (friendly, no dates / no technical fields) ────────────\n// Tapping a suggestion pre-fills a trait row. Optional `options` renders the\n// value as a select (e.g. Rarity).\nexport interface TraitSuggestion {\n key: string;\n placeholder?: string;\n options?: string[];\n}\n\nexport interface DocUploadConfig {\n /** Stored trait_type carrying the ipfs:// URI of the uploaded document */\n traitType: string;\n /** File-input accept list */\n accept: string;\n maxMb: number;\n /** Creator-facing explanation shown under the upload field */\n hint: string;\n}\n\nexport interface IPTemplate {\n type: IPType;\n label: string;\n description: string;\n icon: LucideIcon;\n color: { bg: string; text: string; border: string };\n embeds?: EmbedPlatform[];\n socials?: SocialPlatform[];\n traitSuggestions?: TraitSuggestion[];\n /** Document/PDF upload to IPFS (Documents, Patents, Publications, Software) */\n docUpload?: DocUploadConfig;\n}\n\n/** The document itself, pinned to immutable IPFS — a timestamped copy of the\n * work that stands as proof of authorship (Berne Convention: protection\n * exists from fixation; an immutable dated copy is the evidence). */\nexport const DOC_UPLOAD: DocUploadConfig = {\n traitType: \"Document File\",\n accept: \".pdf,.doc,.docx,.txt,.md,.rtf,.odt\",\n maxMb: 20,\n hint: \"Stored permanently on IPFS — an immutable, timestamped copy of your work (proof of authorship under the Berne Convention).\",\n};\n\nexport const IP_TEMPLATES: Record<IPType, IPTemplate> = {\n Audio: {\n type: \"Audio\",\n label: \"Audio\",\n description: \"Music, podcasts, sound effects, audio art\",\n icon: Music,\n color: { bg: \"bg-blue-500/10\", text: \"text-blue-400\", border: \"border-blue-500/20\" },\n embeds: [\"spotify\", \"soundcloud\"],\n traitSuggestions: [\n { key: \"Artist\" }, { key: \"Genre\", placeholder: \"Soundtrack\" }, { key: \"Mood\" }, { key: \"Label\" },\n ],\n },\n Video: {\n type: \"Video\",\n label: \"Video\",\n description: \"Films, animations, short-form video content\",\n icon: Clapperboard,\n color: { bg: \"bg-red-500/10\", text: \"text-red-400\", border: \"border-red-500/20\" },\n embeds: [\"youtube\", \"tiktok\", \"vimeo\"],\n traitSuggestions: [\n { key: \"Director\" }, { key: \"Genre\" }, { key: \"Cast\" }, { key: \"Studio\" },\n ],\n },\n Art: {\n type: \"Art\",\n label: \"Art\",\n description: \"Digital and physical artwork, illustrations, generative art\",\n icon: Palette,\n color: { bg: \"bg-purple-500/10\", text: \"text-purple-400\", border: \"border-purple-500/20\" },\n traitSuggestions: [\n { key: \"Medium\", placeholder: \"Oil on canvas\" },\n { key: \"Style\", placeholder: \"Impressionism\" },\n { key: \"Materials\" },\n { key: \"Series\" },\n ],\n },\n Photography: {\n type: \"Photography\",\n label: \"Photography\",\n description: \"Photography, photo essays, visual documentation\",\n icon: Camera,\n color: { bg: \"bg-orange-500/10\", text: \"text-orange-400\", border: \"border-orange-500/20\" },\n traitSuggestions: [\n { key: \"Camera\", placeholder: \"Sony A7 IV\" },\n { key: \"Location\" },\n { key: \"Series\" },\n { key: \"Edition\" },\n ],\n },\n Posts: {\n type: \"Posts\",\n label: \"Posts\",\n description: \"Articles, blog posts, social media content, essays\",\n icon: MessageSquare,\n color: { bg: \"bg-sky-500/10\", text: \"text-sky-400\", border: \"border-sky-500/20\" },\n socials: [\"x\", \"instagram\", \"facebook\", \"tiktok\", \"website\"],\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Topic\" }, { key: \"Category\" },\n ],\n },\n Publications: {\n type: \"Publications\",\n label: \"Publications\",\n description: \"Books, journals, magazines, academic papers\",\n icon: BookOpen,\n color: { bg: \"bg-indigo-500/10\", text: \"text-indigo-400\", border: \"border-indigo-500/20\" },\n docUpload: DOC_UPLOAD,\n socials: [\"x\", \"instagram\", \"website\"],\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Publisher\" }, { key: \"Language\", placeholder: \"English\" }, { key: \"Edition\" },\n ],\n },\n Documents: {\n type: \"Documents\",\n label: \"Documents\",\n description: \"Contracts, reports, whitepapers, legal documents\",\n icon: FileText,\n color: { bg: \"bg-zinc-500/10\", text: \"text-zinc-400\", border: \"border-zinc-500/20\" },\n docUpload: DOC_UPLOAD,\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Category\" }, { key: \"Language\", placeholder: \"English\" },\n ],\n },\n Patents: {\n type: \"Patents\",\n label: \"Patents\",\n description: \"Patents, inventions, technical innovations\",\n icon: Award,\n color: { bg: \"bg-amber-500/10\", text: \"text-amber-400\", border: \"border-amber-500/20\" },\n docUpload: DOC_UPLOAD,\n traitSuggestions: [\n { key: \"Inventor\" }, { key: \"Field\" }, { key: \"Status\" },\n ],\n },\n Software: {\n type: \"Software\",\n label: \"Software\",\n description: \"Applications, scripts, algorithms, code libraries\",\n icon: Code2,\n color: { bg: \"bg-violet-500/10\", text: \"text-violet-400\", border: \"border-violet-500/20\" },\n docUpload: DOC_UPLOAD,\n socials: [\"website\"],\n traitSuggestions: [\n { key: \"Language\", placeholder: \"TypeScript\" }, { key: \"License\" }, { key: \"Platform\" },\n ],\n },\n NFT: {\n type: \"NFT\",\n label: \"NFT\",\n description: \"Blockchain-native digital assets and collectibles\",\n icon: Hexagon,\n color: { bg: \"bg-teal-500/10\", text: \"text-teal-400\", border: \"border-teal-500/20\" },\n traitSuggestions: [\n { key: \"Collection\" },\n { key: \"Edition\" },\n { key: \"Rarity\", options: [\"Common\", \"Uncommon\", \"Rare\", \"Epic\", \"Legendary\"] },\n ],\n },\n RWA: {\n type: \"RWA\",\n label: \"Real World Asset\",\n description: \"Tokenized physical assets: real estate, commodities, collectibles\",\n icon: Building2,\n color: { bg: \"bg-emerald-500/10\", text: \"text-emerald-400\", border: \"border-emerald-500/20\" },\n traitSuggestions: [\n { key: \"Asset Type\" }, { key: \"Location\" }, { key: \"Category\" },\n ],\n },\n Custom: {\n type: \"Custom\",\n label: \"Custom\",\n description: \"Custom IP type — add your own trait pairs for any metadata\",\n icon: Layers,\n color: { bg: \"bg-muted/50\", text: \"text-muted-foreground\", border: \"border-border\" },\n },\n};\n\n/**\n * All trait_type keys owned by templates (embeds + socials + suggestions), plus\n * \"IP Type\" itself. Used to filter template-managed attributes out of other\n * attribute grids so they aren't duplicated.\n */\nexport const TEMPLATE_TRAIT_TYPES = new Set<string>([\n \"IP Type\",\n DOC_UPLOAD.traitType,\n ...Object.values(EMBED_PLATFORM_META).map((m) => m.traitKey),\n ...Object.values(SOCIAL_PLATFORM_META).map((m) => m.traitKey),\n ...Object.values(IP_TEMPLATES).flatMap((t) => (t.traitSuggestions ?? []).map((s) => s.key)),\n]);\n"],"mappings":"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","names":[]}
@@ -20,6 +20,15 @@ interface TraitSuggestion {
20
20
  placeholder?: string;
21
21
  options?: string[];
22
22
  }
23
+ interface DocUploadConfig {
24
+ /** Stored trait_type carrying the ipfs:// URI of the uploaded document */
25
+ traitType: string;
26
+ /** File-input accept list */
27
+ accept: string;
28
+ maxMb: number;
29
+ /** Creator-facing explanation shown under the upload field */
30
+ hint: string;
31
+ }
23
32
  interface IPTemplate {
24
33
  type: IPType;
25
34
  label: string;
@@ -33,7 +42,13 @@ interface IPTemplate {
33
42
  embeds?: EmbedPlatform[];
34
43
  socials?: SocialPlatform[];
35
44
  traitSuggestions?: TraitSuggestion[];
45
+ /** Document/PDF upload to IPFS (Documents, Patents, Publications, Software) */
46
+ docUpload?: DocUploadConfig;
36
47
  }
48
+ /** The document itself, pinned to immutable IPFS — a timestamped copy of the
49
+ * work that stands as proof of authorship (Berne Convention: protection
50
+ * exists from fixation; an immutable dated copy is the evidence). */
51
+ declare const DOC_UPLOAD: DocUploadConfig;
37
52
  declare const IP_TEMPLATES: Record<IPType, IPTemplate>;
38
53
  /**
39
54
  * All trait_type keys owned by templates (embeds + socials + suggestions), plus
@@ -42,4 +57,4 @@ declare const IP_TEMPLATES: Record<IPType, IPTemplate>;
42
57
  */
43
58
  declare const TEMPLATE_TRAIT_TYPES: Set<string>;
44
59
 
45
- export { EMBED_PLATFORM_META, type EmbedPlatform, type IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, type SocialPlatform, TEMPLATE_TRAIT_TYPES, type TraitSuggestion };
60
+ export { DOC_UPLOAD, type DocUploadConfig, EMBED_PLATFORM_META, type EmbedPlatform, type IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, type SocialPlatform, TEMPLATE_TRAIT_TYPES, type TraitSuggestion };
@@ -20,6 +20,15 @@ interface TraitSuggestion {
20
20
  placeholder?: string;
21
21
  options?: string[];
22
22
  }
23
+ interface DocUploadConfig {
24
+ /** Stored trait_type carrying the ipfs:// URI of the uploaded document */
25
+ traitType: string;
26
+ /** File-input accept list */
27
+ accept: string;
28
+ maxMb: number;
29
+ /** Creator-facing explanation shown under the upload field */
30
+ hint: string;
31
+ }
23
32
  interface IPTemplate {
24
33
  type: IPType;
25
34
  label: string;
@@ -33,7 +42,13 @@ interface IPTemplate {
33
42
  embeds?: EmbedPlatform[];
34
43
  socials?: SocialPlatform[];
35
44
  traitSuggestions?: TraitSuggestion[];
45
+ /** Document/PDF upload to IPFS (Documents, Patents, Publications, Software) */
46
+ docUpload?: DocUploadConfig;
36
47
  }
48
+ /** The document itself, pinned to immutable IPFS — a timestamped copy of the
49
+ * work that stands as proof of authorship (Berne Convention: protection
50
+ * exists from fixation; an immutable dated copy is the evidence). */
51
+ declare const DOC_UPLOAD: DocUploadConfig;
37
52
  declare const IP_TEMPLATES: Record<IPType, IPTemplate>;
38
53
  /**
39
54
  * All trait_type keys owned by templates (embeds + socials + suggestions), plus
@@ -42,4 +57,4 @@ declare const IP_TEMPLATES: Record<IPType, IPTemplate>;
42
57
  */
43
58
  declare const TEMPLATE_TRAIT_TYPES: Set<string>;
44
59
 
45
- export { EMBED_PLATFORM_META, type EmbedPlatform, type IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, type SocialPlatform, TEMPLATE_TRAIT_TYPES, type TraitSuggestion };
60
+ export { DOC_UPLOAD, type DocUploadConfig, EMBED_PLATFORM_META, type EmbedPlatform, type IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, type SocialPlatform, TEMPLATE_TRAIT_TYPES, type TraitSuggestion };
@@ -34,6 +34,12 @@ const SOCIAL_PLATFORM_META = {
34
34
  tiktok: { label: "TikTok", icon: Video, traitKey: "TikTok", placeholder: "https://tiktok.com/@\u2026" },
35
35
  website: { label: "Website", icon: Globe, traitKey: "Website", placeholder: "https://\u2026" }
36
36
  };
37
+ const DOC_UPLOAD = {
38
+ traitType: "Document File",
39
+ accept: ".pdf,.doc,.docx,.txt,.md,.rtf,.odt",
40
+ maxMb: 20,
41
+ hint: "Stored permanently on IPFS \u2014 an immutable, timestamped copy of your work (proof of authorship under the Berne Convention)."
42
+ };
37
43
  const IP_TEMPLATES = {
38
44
  Audio: {
39
45
  type: "Audio",
@@ -108,6 +114,7 @@ const IP_TEMPLATES = {
108
114
  description: "Books, journals, magazines, academic papers",
109
115
  icon: BookOpen,
110
116
  color: { bg: "bg-indigo-500/10", text: "text-indigo-400", border: "border-indigo-500/20" },
117
+ docUpload: DOC_UPLOAD,
111
118
  socials: ["x", "instagram", "website"],
112
119
  traitSuggestions: [
113
120
  { key: "Author" },
@@ -122,6 +129,7 @@ const IP_TEMPLATES = {
122
129
  description: "Contracts, reports, whitepapers, legal documents",
123
130
  icon: FileText,
124
131
  color: { bg: "bg-zinc-500/10", text: "text-zinc-400", border: "border-zinc-500/20" },
132
+ docUpload: DOC_UPLOAD,
125
133
  traitSuggestions: [
126
134
  { key: "Author" },
127
135
  { key: "Category" },
@@ -134,6 +142,7 @@ const IP_TEMPLATES = {
134
142
  description: "Patents, inventions, technical innovations",
135
143
  icon: Award,
136
144
  color: { bg: "bg-amber-500/10", text: "text-amber-400", border: "border-amber-500/20" },
145
+ docUpload: DOC_UPLOAD,
137
146
  traitSuggestions: [
138
147
  { key: "Inventor" },
139
148
  { key: "Field" },
@@ -146,6 +155,7 @@ const IP_TEMPLATES = {
146
155
  description: "Applications, scripts, algorithms, code libraries",
147
156
  icon: Code2,
148
157
  color: { bg: "bg-violet-500/10", text: "text-violet-400", border: "border-violet-500/20" },
158
+ docUpload: DOC_UPLOAD,
149
159
  socials: ["website"],
150
160
  traitSuggestions: [
151
161
  { key: "Language", placeholder: "TypeScript" },
@@ -187,11 +197,13 @@ const IP_TEMPLATES = {
187
197
  };
188
198
  const TEMPLATE_TRAIT_TYPES = /* @__PURE__ */ new Set([
189
199
  "IP Type",
200
+ DOC_UPLOAD.traitType,
190
201
  ...Object.values(EMBED_PLATFORM_META).map((m) => m.traitKey),
191
202
  ...Object.values(SOCIAL_PLATFORM_META).map((m) => m.traitKey),
192
203
  ...Object.values(IP_TEMPLATES).flatMap((t) => (t.traitSuggestions ?? []).map((s) => s.key))
193
204
  ]);
194
205
  export {
206
+ DOC_UPLOAD,
195
207
  EMBED_PLATFORM_META,
196
208
  IP_TEMPLATES,
197
209
  SOCIAL_PLATFORM_META,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data/ip-templates.ts"],"sourcesContent":["import {\n Music, Palette, FileText, Hexagon, Clapperboard, Camera,\n Award, MessageSquare, BookOpen, Building2, Code2, Layers,\n Music2, AudioLines, Youtube, Video, Twitter, Instagram, Facebook, Globe,\n type LucideIcon,\n} from \"lucide-react\";\nimport type { IPType } from \"./ip.js\";\n\n// ── Embeds (inline iframe players) ──────────────────────────────────────────\n// Only platforms with clean iframe embeds. Each maps to a stored trait_type key\n// so the asset page can render the player from metadata attributes.\nexport type EmbedPlatform = \"spotify\" | \"soundcloud\" | \"youtube\" | \"tiktok\" | \"vimeo\";\n\nexport const EMBED_PLATFORM_META: Record<\n EmbedPlatform,\n { label: string; icon: LucideIcon; traitKey: string; placeholder: string }\n> = {\n spotify: { label: \"Spotify\", icon: Music2, traitKey: \"Spotify URL\", placeholder: \"https://open.spotify.com/…\" },\n soundcloud: { label: \"SoundCloud\", icon: AudioLines, traitKey: \"SoundCloud URL\", placeholder: \"https://soundcloud.com/…\" },\n youtube: { label: \"YouTube\", icon: Youtube, traitKey: \"YouTube URL\", placeholder: \"https://youtube.com/watch?v=…\" },\n tiktok: { label: \"TikTok\", icon: Video, traitKey: \"TikTok URL\", placeholder: \"https://tiktok.com/@…/video/…\" },\n vimeo: { label: \"Vimeo\", icon: Video, traitKey: \"Vimeo URL\", placeholder: \"https://vimeo.com/…\" },\n};\n\n// ── Socials (icon-chip links — open in a new tab, never iframed) ────────────\n// X / Instagram / Facebook need fragile JS SDKs and sites block iframing, so\n// these render as clickable platform chips on the asset page, not players.\nexport type SocialPlatform = \"x\" | \"instagram\" | \"facebook\" | \"tiktok\" | \"website\";\n\nexport const SOCIAL_PLATFORM_META: Record<\n SocialPlatform,\n { label: string; icon: LucideIcon; traitKey: string; placeholder: string }\n> = {\n x: { label: \"X\", icon: Twitter, traitKey: \"X\", placeholder: \"https://x.com/…\" },\n instagram: { label: \"Instagram\", icon: Instagram, traitKey: \"Instagram\", placeholder: \"https://instagram.com/…\" },\n facebook: { label: \"Facebook\", icon: Facebook, traitKey: \"Facebook\", placeholder: \"https://facebook.com/…\" },\n tiktok: { label: \"TikTok\", icon: Video, traitKey: \"TikTok\", placeholder: \"https://tiktok.com/@…\" },\n website: { label: \"Website\", icon: Globe, traitKey: \"Website\", placeholder: \"https://…\" },\n};\n\n// ── Trait suggestions (friendly, no dates / no technical fields) ────────────\n// Tapping a suggestion pre-fills a trait row. Optional `options` renders the\n// value as a select (e.g. Rarity).\nexport interface TraitSuggestion {\n key: string;\n placeholder?: string;\n options?: string[];\n}\n\nexport interface IPTemplate {\n type: IPType;\n label: string;\n description: string;\n icon: LucideIcon;\n color: { bg: string; text: string; border: string };\n embeds?: EmbedPlatform[];\n socials?: SocialPlatform[];\n traitSuggestions?: TraitSuggestion[];\n}\n\nexport const IP_TEMPLATES: Record<IPType, IPTemplate> = {\n Audio: {\n type: \"Audio\",\n label: \"Audio\",\n description: \"Music, podcasts, sound effects, audio art\",\n icon: Music,\n color: { bg: \"bg-blue-500/10\", text: \"text-blue-400\", border: \"border-blue-500/20\" },\n embeds: [\"spotify\", \"soundcloud\"],\n traitSuggestions: [\n { key: \"Artist\" }, { key: \"Genre\", placeholder: \"Soundtrack\" }, { key: \"Mood\" }, { key: \"Label\" },\n ],\n },\n Video: {\n type: \"Video\",\n label: \"Video\",\n description: \"Films, animations, short-form video content\",\n icon: Clapperboard,\n color: { bg: \"bg-red-500/10\", text: \"text-red-400\", border: \"border-red-500/20\" },\n embeds: [\"youtube\", \"tiktok\", \"vimeo\"],\n traitSuggestions: [\n { key: \"Director\" }, { key: \"Genre\" }, { key: \"Cast\" }, { key: \"Studio\" },\n ],\n },\n Art: {\n type: \"Art\",\n label: \"Art\",\n description: \"Digital and physical artwork, illustrations, generative art\",\n icon: Palette,\n color: { bg: \"bg-purple-500/10\", text: \"text-purple-400\", border: \"border-purple-500/20\" },\n traitSuggestions: [\n { key: \"Medium\", placeholder: \"Oil on canvas\" },\n { key: \"Style\", placeholder: \"Impressionism\" },\n { key: \"Materials\" },\n { key: \"Series\" },\n ],\n },\n Photography: {\n type: \"Photography\",\n label: \"Photography\",\n description: \"Photography, photo essays, visual documentation\",\n icon: Camera,\n color: { bg: \"bg-orange-500/10\", text: \"text-orange-400\", border: \"border-orange-500/20\" },\n traitSuggestions: [\n { key: \"Camera\", placeholder: \"Sony A7 IV\" },\n { key: \"Location\" },\n { key: \"Series\" },\n { key: \"Edition\" },\n ],\n },\n Posts: {\n type: \"Posts\",\n label: \"Posts\",\n description: \"Articles, blog posts, social media content, essays\",\n icon: MessageSquare,\n color: { bg: \"bg-sky-500/10\", text: \"text-sky-400\", border: \"border-sky-500/20\" },\n socials: [\"x\", \"instagram\", \"facebook\", \"tiktok\", \"website\"],\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Topic\" }, { key: \"Category\" },\n ],\n },\n Publications: {\n type: \"Publications\",\n label: \"Publications\",\n description: \"Books, journals, magazines, academic papers\",\n icon: BookOpen,\n color: { bg: \"bg-indigo-500/10\", text: \"text-indigo-400\", border: \"border-indigo-500/20\" },\n socials: [\"x\", \"instagram\", \"website\"],\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Publisher\" }, { key: \"Language\", placeholder: \"English\" }, { key: \"Edition\" },\n ],\n },\n Documents: {\n type: \"Documents\",\n label: \"Documents\",\n description: \"Contracts, reports, whitepapers, legal documents\",\n icon: FileText,\n color: { bg: \"bg-zinc-500/10\", text: \"text-zinc-400\", border: \"border-zinc-500/20\" },\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Category\" }, { key: \"Language\", placeholder: \"English\" },\n ],\n },\n Patents: {\n type: \"Patents\",\n label: \"Patents\",\n description: \"Patents, inventions, technical innovations\",\n icon: Award,\n color: { bg: \"bg-amber-500/10\", text: \"text-amber-400\", border: \"border-amber-500/20\" },\n traitSuggestions: [\n { key: \"Inventor\" }, { key: \"Field\" }, { key: \"Status\" },\n ],\n },\n Software: {\n type: \"Software\",\n label: \"Software\",\n description: \"Applications, scripts, algorithms, code libraries\",\n icon: Code2,\n color: { bg: \"bg-violet-500/10\", text: \"text-violet-400\", border: \"border-violet-500/20\" },\n socials: [\"website\"],\n traitSuggestions: [\n { key: \"Language\", placeholder: \"TypeScript\" }, { key: \"License\" }, { key: \"Platform\" },\n ],\n },\n NFT: {\n type: \"NFT\",\n label: \"NFT\",\n description: \"Blockchain-native digital assets and collectibles\",\n icon: Hexagon,\n color: { bg: \"bg-teal-500/10\", text: \"text-teal-400\", border: \"border-teal-500/20\" },\n traitSuggestions: [\n { key: \"Collection\" },\n { key: \"Edition\" },\n { key: \"Rarity\", options: [\"Common\", \"Uncommon\", \"Rare\", \"Epic\", \"Legendary\"] },\n ],\n },\n RWA: {\n type: \"RWA\",\n label: \"Real World Asset\",\n description: \"Tokenized physical assets: real estate, commodities, collectibles\",\n icon: Building2,\n color: { bg: \"bg-emerald-500/10\", text: \"text-emerald-400\", border: \"border-emerald-500/20\" },\n traitSuggestions: [\n { key: \"Asset Type\" }, { key: \"Location\" }, { key: \"Category\" },\n ],\n },\n Custom: {\n type: \"Custom\",\n label: \"Custom\",\n description: \"Custom IP type — add your own trait pairs for any metadata\",\n icon: Layers,\n color: { bg: \"bg-muted/50\", text: \"text-muted-foreground\", border: \"border-border\" },\n },\n};\n\n/**\n * All trait_type keys owned by templates (embeds + socials + suggestions), plus\n * \"IP Type\" itself. Used to filter template-managed attributes out of other\n * attribute grids so they aren't duplicated.\n */\nexport const TEMPLATE_TRAIT_TYPES = new Set<string>([\n \"IP Type\",\n ...Object.values(EMBED_PLATFORM_META).map((m) => m.traitKey),\n ...Object.values(SOCIAL_PLATFORM_META).map((m) => m.traitKey),\n ...Object.values(IP_TEMPLATES).flatMap((t) => (t.traitSuggestions ?? []).map((s) => s.key)),\n]);\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EAAO;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAc;AAAA,EACjD;AAAA,EAAO;AAAA,EAAe;AAAA,EAAU;AAAA,EAAW;AAAA,EAAO;AAAA,EAClD;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAS;AAAA,EAAO;AAAA,EAAS;AAAA,EAAW;AAAA,EAAU;AAAA,OAE7D;AAQA,MAAM,sBAGT;AAAA,EACF,SAAY,EAAE,OAAO,WAAc,MAAM,QAAY,UAAU,eAAkB,aAAa,kCAA6B;AAAA,EAC3H,YAAY,EAAE,OAAO,cAAc,MAAM,YAAY,UAAU,kBAAkB,aAAa,gCAA2B;AAAA,EACzH,SAAY,EAAE,OAAO,WAAc,MAAM,SAAY,UAAU,eAAkB,aAAa,qCAAgC;AAAA,EAC9H,QAAY,EAAE,OAAO,UAAc,MAAM,OAAY,UAAU,cAAkB,aAAa,0CAAgC;AAAA,EAC9H,OAAY,EAAE,OAAO,SAAc,MAAM,OAAY,UAAU,aAAkB,aAAa,2BAAsB;AACtH;AAOO,MAAM,uBAGT;AAAA,EACF,GAAW,EAAE,OAAO,KAAa,MAAM,SAAW,UAAU,KAAa,aAAa,uBAAkB;AAAA,EACxG,WAAW,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,aAAa,aAAa,+BAA0B;AAAA,EAChH,UAAW,EAAE,OAAO,YAAa,MAAM,UAAW,UAAU,YAAa,aAAa,8BAAyB;AAAA,EAC/G,QAAW,EAAE,OAAO,UAAa,MAAM,OAAW,UAAU,UAAa,aAAa,6BAAwB;AAAA,EAC9G,SAAW,EAAE,OAAO,WAAa,MAAM,OAAW,UAAU,WAAa,aAAa,iBAAY;AACpG;AAsBO,MAAM,eAA2C;AAAA,EACtD,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,kBAAkB,MAAM,iBAAiB,QAAQ,qBAAqB;AAAA,IACnF,QAAQ,CAAC,WAAW,YAAY;AAAA,IAChC,kBAAkB;AAAA,MAChB,EAAE,KAAK,SAAS;AAAA,MAAG,EAAE,KAAK,SAAS,aAAa,aAAa;AAAA,MAAG,EAAE,KAAK,OAAO;AAAA,MAAG,EAAE,KAAK,QAAQ;AAAA,IAClG;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,iBAAiB,MAAM,gBAAgB,QAAQ,oBAAoB;AAAA,IAChF,QAAQ,CAAC,WAAW,UAAU,OAAO;AAAA,IACrC,kBAAkB;AAAA,MAChB,EAAE,KAAK,WAAW;AAAA,MAAG,EAAE,KAAK,QAAQ;AAAA,MAAG,EAAE,KAAK,OAAO;AAAA,MAAG,EAAE,KAAK,SAAS;AAAA,IAC1E;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,oBAAoB,MAAM,mBAAmB,QAAQ,uBAAuB;AAAA,IACzF,kBAAkB;AAAA,MAChB,EAAE,KAAK,UAAU,aAAa,gBAAgB;AAAA,MAC9C,EAAE,KAAK,SAAS,aAAa,gBAAgB;AAAA,MAC7C,EAAE,KAAK,YAAY;AAAA,MACnB,EAAE,KAAK,SAAS;AAAA,IAClB;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,oBAAoB,MAAM,mBAAmB,QAAQ,uBAAuB;AAAA,IACzF,kBAAkB;AAAA,MAChB,EAAE,KAAK,UAAU,aAAa,aAAa;AAAA,MAC3C,EAAE,KAAK,WAAW;AAAA,MAClB,EAAE,KAAK,SAAS;AAAA,MAChB,EAAE,KAAK,UAAU;AAAA,IACnB;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,iBAAiB,MAAM,gBAAgB,QAAQ,oBAAoB;AAAA,IAChF,SAAS,CAAC,KAAK,aAAa,YAAY,UAAU,SAAS;AAAA,IAC3D,kBAAkB;AAAA,MAChB,EAAE,KAAK,SAAS;AAAA,MAAG,EAAE,KAAK,QAAQ;AAAA,MAAG,EAAE,KAAK,WAAW;AAAA,IACzD;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,oBAAoB,MAAM,mBAAmB,QAAQ,uBAAuB;AAAA,IACzF,SAAS,CAAC,KAAK,aAAa,SAAS;AAAA,IACrC,kBAAkB;AAAA,MAChB,EAAE,KAAK,SAAS;AAAA,MAAG,EAAE,KAAK,YAAY;AAAA,MAAG,EAAE,KAAK,YAAY,aAAa,UAAU;AAAA,MAAG,EAAE,KAAK,UAAU;AAAA,IACzG;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,kBAAkB,MAAM,iBAAiB,QAAQ,qBAAqB;AAAA,IACnF,kBAAkB;AAAA,MAChB,EAAE,KAAK,SAAS;AAAA,MAAG,EAAE,KAAK,WAAW;AAAA,MAAG,EAAE,KAAK,YAAY,aAAa,UAAU;AAAA,IACpF;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,mBAAmB,MAAM,kBAAkB,QAAQ,sBAAsB;AAAA,IACtF,kBAAkB;AAAA,MAChB,EAAE,KAAK,WAAW;AAAA,MAAG,EAAE,KAAK,QAAQ;AAAA,MAAG,EAAE,KAAK,SAAS;AAAA,IACzD;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,oBAAoB,MAAM,mBAAmB,QAAQ,uBAAuB;AAAA,IACzF,SAAS,CAAC,SAAS;AAAA,IACnB,kBAAkB;AAAA,MAChB,EAAE,KAAK,YAAY,aAAa,aAAa;AAAA,MAAG,EAAE,KAAK,UAAU;AAAA,MAAG,EAAE,KAAK,WAAW;AAAA,IACxF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,kBAAkB,MAAM,iBAAiB,QAAQ,qBAAqB;AAAA,IACnF,kBAAkB;AAAA,MAChB,EAAE,KAAK,aAAa;AAAA,MACpB,EAAE,KAAK,UAAU;AAAA,MACjB,EAAE,KAAK,UAAU,SAAS,CAAC,UAAU,YAAY,QAAQ,QAAQ,WAAW,EAAE;AAAA,IAChF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,qBAAqB,MAAM,oBAAoB,QAAQ,wBAAwB;AAAA,IAC5F,kBAAkB;AAAA,MAChB,EAAE,KAAK,aAAa;AAAA,MAAG,EAAE,KAAK,WAAW;AAAA,MAAG,EAAE,KAAK,WAAW;AAAA,IAChE;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,eAAe,MAAM,yBAAyB,QAAQ,gBAAgB;AAAA,EACrF;AACF;AAOO,MAAM,uBAAuB,oBAAI,IAAY;AAAA,EAClD;AAAA,EACA,GAAG,OAAO,OAAO,mBAAmB,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ;AAAA,EAC3D,GAAG,OAAO,OAAO,oBAAoB,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ;AAAA,EAC5D,GAAG,OAAO,OAAO,YAAY,EAAE,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAC5F,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/data/ip-templates.ts"],"sourcesContent":["import {\n Music, Palette, FileText, Hexagon, Clapperboard, Camera,\n Award, MessageSquare, BookOpen, Building2, Code2, Layers,\n Music2, AudioLines, Youtube, Video, Twitter, Instagram, Facebook, Globe,\n type LucideIcon,\n} from \"lucide-react\";\nimport type { IPType } from \"./ip.js\";\n\n// ── Embeds (inline iframe players) ──────────────────────────────────────────\n// Only platforms with clean iframe embeds. Each maps to a stored trait_type key\n// so the asset page can render the player from metadata attributes.\nexport type EmbedPlatform = \"spotify\" | \"soundcloud\" | \"youtube\" | \"tiktok\" | \"vimeo\";\n\nexport const EMBED_PLATFORM_META: Record<\n EmbedPlatform,\n { label: string; icon: LucideIcon; traitKey: string; placeholder: string }\n> = {\n spotify: { label: \"Spotify\", icon: Music2, traitKey: \"Spotify URL\", placeholder: \"https://open.spotify.com/…\" },\n soundcloud: { label: \"SoundCloud\", icon: AudioLines, traitKey: \"SoundCloud URL\", placeholder: \"https://soundcloud.com/…\" },\n youtube: { label: \"YouTube\", icon: Youtube, traitKey: \"YouTube URL\", placeholder: \"https://youtube.com/watch?v=…\" },\n tiktok: { label: \"TikTok\", icon: Video, traitKey: \"TikTok URL\", placeholder: \"https://tiktok.com/@…/video/…\" },\n vimeo: { label: \"Vimeo\", icon: Video, traitKey: \"Vimeo URL\", placeholder: \"https://vimeo.com/…\" },\n};\n\n// ── Socials (icon-chip links — open in a new tab, never iframed) ────────────\n// X / Instagram / Facebook need fragile JS SDKs and sites block iframing, so\n// these render as clickable platform chips on the asset page, not players.\nexport type SocialPlatform = \"x\" | \"instagram\" | \"facebook\" | \"tiktok\" | \"website\";\n\nexport const SOCIAL_PLATFORM_META: Record<\n SocialPlatform,\n { label: string; icon: LucideIcon; traitKey: string; placeholder: string }\n> = {\n x: { label: \"X\", icon: Twitter, traitKey: \"X\", placeholder: \"https://x.com/…\" },\n instagram: { label: \"Instagram\", icon: Instagram, traitKey: \"Instagram\", placeholder: \"https://instagram.com/…\" },\n facebook: { label: \"Facebook\", icon: Facebook, traitKey: \"Facebook\", placeholder: \"https://facebook.com/…\" },\n tiktok: { label: \"TikTok\", icon: Video, traitKey: \"TikTok\", placeholder: \"https://tiktok.com/@…\" },\n website: { label: \"Website\", icon: Globe, traitKey: \"Website\", placeholder: \"https://…\" },\n};\n\n// ── Trait suggestions (friendly, no dates / no technical fields) ────────────\n// Tapping a suggestion pre-fills a trait row. Optional `options` renders the\n// value as a select (e.g. Rarity).\nexport interface TraitSuggestion {\n key: string;\n placeholder?: string;\n options?: string[];\n}\n\nexport interface DocUploadConfig {\n /** Stored trait_type carrying the ipfs:// URI of the uploaded document */\n traitType: string;\n /** File-input accept list */\n accept: string;\n maxMb: number;\n /** Creator-facing explanation shown under the upload field */\n hint: string;\n}\n\nexport interface IPTemplate {\n type: IPType;\n label: string;\n description: string;\n icon: LucideIcon;\n color: { bg: string; text: string; border: string };\n embeds?: EmbedPlatform[];\n socials?: SocialPlatform[];\n traitSuggestions?: TraitSuggestion[];\n /** Document/PDF upload to IPFS (Documents, Patents, Publications, Software) */\n docUpload?: DocUploadConfig;\n}\n\n/** The document itself, pinned to immutable IPFS — a timestamped copy of the\n * work that stands as proof of authorship (Berne Convention: protection\n * exists from fixation; an immutable dated copy is the evidence). */\nexport const DOC_UPLOAD: DocUploadConfig = {\n traitType: \"Document File\",\n accept: \".pdf,.doc,.docx,.txt,.md,.rtf,.odt\",\n maxMb: 20,\n hint: \"Stored permanently on IPFS — an immutable, timestamped copy of your work (proof of authorship under the Berne Convention).\",\n};\n\nexport const IP_TEMPLATES: Record<IPType, IPTemplate> = {\n Audio: {\n type: \"Audio\",\n label: \"Audio\",\n description: \"Music, podcasts, sound effects, audio art\",\n icon: Music,\n color: { bg: \"bg-blue-500/10\", text: \"text-blue-400\", border: \"border-blue-500/20\" },\n embeds: [\"spotify\", \"soundcloud\"],\n traitSuggestions: [\n { key: \"Artist\" }, { key: \"Genre\", placeholder: \"Soundtrack\" }, { key: \"Mood\" }, { key: \"Label\" },\n ],\n },\n Video: {\n type: \"Video\",\n label: \"Video\",\n description: \"Films, animations, short-form video content\",\n icon: Clapperboard,\n color: { bg: \"bg-red-500/10\", text: \"text-red-400\", border: \"border-red-500/20\" },\n embeds: [\"youtube\", \"tiktok\", \"vimeo\"],\n traitSuggestions: [\n { key: \"Director\" }, { key: \"Genre\" }, { key: \"Cast\" }, { key: \"Studio\" },\n ],\n },\n Art: {\n type: \"Art\",\n label: \"Art\",\n description: \"Digital and physical artwork, illustrations, generative art\",\n icon: Palette,\n color: { bg: \"bg-purple-500/10\", text: \"text-purple-400\", border: \"border-purple-500/20\" },\n traitSuggestions: [\n { key: \"Medium\", placeholder: \"Oil on canvas\" },\n { key: \"Style\", placeholder: \"Impressionism\" },\n { key: \"Materials\" },\n { key: \"Series\" },\n ],\n },\n Photography: {\n type: \"Photography\",\n label: \"Photography\",\n description: \"Photography, photo essays, visual documentation\",\n icon: Camera,\n color: { bg: \"bg-orange-500/10\", text: \"text-orange-400\", border: \"border-orange-500/20\" },\n traitSuggestions: [\n { key: \"Camera\", placeholder: \"Sony A7 IV\" },\n { key: \"Location\" },\n { key: \"Series\" },\n { key: \"Edition\" },\n ],\n },\n Posts: {\n type: \"Posts\",\n label: \"Posts\",\n description: \"Articles, blog posts, social media content, essays\",\n icon: MessageSquare,\n color: { bg: \"bg-sky-500/10\", text: \"text-sky-400\", border: \"border-sky-500/20\" },\n socials: [\"x\", \"instagram\", \"facebook\", \"tiktok\", \"website\"],\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Topic\" }, { key: \"Category\" },\n ],\n },\n Publications: {\n type: \"Publications\",\n label: \"Publications\",\n description: \"Books, journals, magazines, academic papers\",\n icon: BookOpen,\n color: { bg: \"bg-indigo-500/10\", text: \"text-indigo-400\", border: \"border-indigo-500/20\" },\n docUpload: DOC_UPLOAD,\n socials: [\"x\", \"instagram\", \"website\"],\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Publisher\" }, { key: \"Language\", placeholder: \"English\" }, { key: \"Edition\" },\n ],\n },\n Documents: {\n type: \"Documents\",\n label: \"Documents\",\n description: \"Contracts, reports, whitepapers, legal documents\",\n icon: FileText,\n color: { bg: \"bg-zinc-500/10\", text: \"text-zinc-400\", border: \"border-zinc-500/20\" },\n docUpload: DOC_UPLOAD,\n traitSuggestions: [\n { key: \"Author\" }, { key: \"Category\" }, { key: \"Language\", placeholder: \"English\" },\n ],\n },\n Patents: {\n type: \"Patents\",\n label: \"Patents\",\n description: \"Patents, inventions, technical innovations\",\n icon: Award,\n color: { bg: \"bg-amber-500/10\", text: \"text-amber-400\", border: \"border-amber-500/20\" },\n docUpload: DOC_UPLOAD,\n traitSuggestions: [\n { key: \"Inventor\" }, { key: \"Field\" }, { key: \"Status\" },\n ],\n },\n Software: {\n type: \"Software\",\n label: \"Software\",\n description: \"Applications, scripts, algorithms, code libraries\",\n icon: Code2,\n color: { bg: \"bg-violet-500/10\", text: \"text-violet-400\", border: \"border-violet-500/20\" },\n docUpload: DOC_UPLOAD,\n socials: [\"website\"],\n traitSuggestions: [\n { key: \"Language\", placeholder: \"TypeScript\" }, { key: \"License\" }, { key: \"Platform\" },\n ],\n },\n NFT: {\n type: \"NFT\",\n label: \"NFT\",\n description: \"Blockchain-native digital assets and collectibles\",\n icon: Hexagon,\n color: { bg: \"bg-teal-500/10\", text: \"text-teal-400\", border: \"border-teal-500/20\" },\n traitSuggestions: [\n { key: \"Collection\" },\n { key: \"Edition\" },\n { key: \"Rarity\", options: [\"Common\", \"Uncommon\", \"Rare\", \"Epic\", \"Legendary\"] },\n ],\n },\n RWA: {\n type: \"RWA\",\n label: \"Real World Asset\",\n description: \"Tokenized physical assets: real estate, commodities, collectibles\",\n icon: Building2,\n color: { bg: \"bg-emerald-500/10\", text: \"text-emerald-400\", border: \"border-emerald-500/20\" },\n traitSuggestions: [\n { key: \"Asset Type\" }, { key: \"Location\" }, { key: \"Category\" },\n ],\n },\n Custom: {\n type: \"Custom\",\n label: \"Custom\",\n description: \"Custom IP type — add your own trait pairs for any metadata\",\n icon: Layers,\n color: { bg: \"bg-muted/50\", text: \"text-muted-foreground\", border: \"border-border\" },\n },\n};\n\n/**\n * All trait_type keys owned by templates (embeds + socials + suggestions), plus\n * \"IP Type\" itself. Used to filter template-managed attributes out of other\n * attribute grids so they aren't duplicated.\n */\nexport const TEMPLATE_TRAIT_TYPES = new Set<string>([\n \"IP Type\",\n DOC_UPLOAD.traitType,\n ...Object.values(EMBED_PLATFORM_META).map((m) => m.traitKey),\n ...Object.values(SOCIAL_PLATFORM_META).map((m) => m.traitKey),\n ...Object.values(IP_TEMPLATES).flatMap((t) => (t.traitSuggestions ?? []).map((s) => s.key)),\n]);\n"],"mappings":"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","names":[]}
package/dist/index.cjs CHANGED
@@ -38,6 +38,7 @@ __export(index_exports, {
38
38
  CurrencyAmount: () => import_currency_icon.CurrencyAmount,
39
39
  CurrencyIcon: () => import_currency_icon.CurrencyIcon,
40
40
  DERIVATIVES_OPTIONS: () => import_ip.DERIVATIVES_OPTIONS,
41
+ DOC_UPLOAD: () => import_ip_templates.DOC_UPLOAD,
41
42
  DiscoverCollectionsStrip: () => import_discover_collections_strip.DiscoverCollectionsStrip,
42
43
  DiscoverCreatorsStrip: () => import_discover_creators_strip.DiscoverCreatorsStrip,
43
44
  DiscoverFeedSection: () => import_discover_feed_section.DiscoverFeedSection,
@@ -163,6 +164,7 @@ var import_portfolio_counts = require("./utils/portfolio-counts.js");
163
164
  CurrencyAmount,
164
165
  CurrencyIcon,
165
166
  DERIVATIVES_OPTIONS,
167
+ DOC_UPLOAD,
166
168
  DiscoverCollectionsStrip,
167
169
  DiscoverCreatorsStrip,
168
170
  DiscoverFeedSection,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// ── Utils ─────────────────────────────────────────────────────────────────────\nexport { cn } from \"./utils/cn.js\";\nexport { formatDisplayPrice } from \"./utils/format.js\";\nexport { shortenAddress } from \"./utils/address.js\";\nexport { ipfsToHttp } from \"./utils/ipfs.js\";\n\n// ── Data (server-safe — no React, safe in Server Components) ──────────────────\nexport { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from \"./data/ip-types.js\";\nexport type { IpTypeData } from \"./data/ip-types.js\";\nexport {\n IP_TYPES, LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES,\n DERIVATIVES_OPTIONS, LICENSE_TRAIT_TYPES,\n} from \"./data/ip.js\";\nexport type { IPType, LicenseType } from \"./data/ip.js\";\nexport {\n IP_TEMPLATES, EMBED_PLATFORM_META, SOCIAL_PLATFORM_META, TEMPLATE_TRAIT_TYPES,\n} from \"./data/ip-templates.js\";\nexport type { EmbedPlatform, SocialPlatform, TraitSuggestion, IPTemplate } from \"./data/ip-templates.js\";\nexport { IPTypeDisplay } from \"./components/ip-type-display.js\";\nexport { AssetOverviewContent } from \"./components/asset-overview-content.js\";\nexport { AssetMarketsTab } from \"./components/asset-markets-tab.js\";\nexport { ParentAttributionBanner } from \"./components/parent-attribution-banner.js\";\nexport type { ParentBannerProps } from \"./components/parent-attribution-banner.js\";\nexport { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from \"./components/asset-top-sections.js\";\nexport { BRAND } from \"./data/brand.js\";\n\n// ── Components (client-only — all have \"use client\") ─────────────────────────\nexport { CurrencyIcon, CurrencyAmount } from \"./components/currency-icon.js\";\nexport type { CurrencyIconProps, CurrencyAmountProps } from \"./components/currency-icon.js\";\n\nexport { IpTypeBadge, IP_TYPE_CONFIG, IP_TYPE_MAP } from \"./components/ip-type-badge.js\";\nexport type { IpTypeBadgeProps, IpTypeConfig } from \"./components/ip-type-badge.js\";\n\nexport { AddressDisplay } from \"./components/address-display.js\";\nexport type { AddressDisplayProps } from \"./components/address-display.js\";\n\nexport { MedialaneIcon } from \"./components/brand-icon.js\";\nexport type { MedialaneIconProps } from \"./components/brand-icon.js\";\nexport { MedialaneLogoFull } from \"./components/brand-logo.js\";\nexport type { MedialaneLogoFullProps } from \"./components/brand-logo.js\";\n\n// ── v0.2 additions ────────────────────────────────────────────────────────────\nexport { MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT } from \"./components/motion-primitives.js\";\nexport { PageContainer } from \"./components/page-container.js\";\nexport type { PageContainerProps } from \"./components/page-container.js\";\nexport { ScrollSection } from \"./components/scroll-section.js\";\nexport type { ScrollSectionProps } from \"./components/scroll-section.js\";\nexport { ShareButton } from \"./components/share-button.js\";\nexport type { ShareButtonProps } from \"./components/share-button.js\";\nexport { CollectionCard, CollectionCardSkeleton } from \"./components/collection-card.js\";\nexport type { CollectionCardProps } from \"./components/collection-card.js\";\nexport { TokenCard, TokenCardSkeleton } from \"./components/token-card.js\";\nexport type { TokenCardProps, RarityTier } from \"./components/token-card.js\";\n\n// ── v0.3 additions ────────────────────────────────────────────────────────────\nexport { timeAgo, timeUntil } from \"./utils/time.js\";\nexport { ACTIVITY_TYPE_CONFIG, TYPE_FILTERS } from \"./data/activity.js\";\nexport type { ActivityTypeConfig } from \"./data/activity.js\";\nexport { HeroSlider, HeroSliderSkeleton } from \"./components/hero-slider.js\";\nexport type { HeroSliderProps } from \"./components/hero-slider.js\";\nexport { ActivityTicker } from \"./components/activity-ticker.js\";\nexport type { ActivityTickerProps } from \"./components/activity-ticker.js\";\nexport { ListingCard, ListingCardSkeleton } from \"./components/listing-card.js\";\nexport type { ListingCardProps } from \"./components/listing-card.js\";\nexport { ActivityRow } from \"./components/activity-row.js\";\nexport type { ActivityRowProps } from \"./components/activity-row.js\";\nexport { ActivityFeedShell } from \"./components/activity-feed-shell.js\";\nexport type { ActivityFeedShellProps } from \"./components/activity-feed-shell.js\";\nexport { CtaCardGrid } from \"./components/cta-card-grid.js\";\nexport type { CtaCardGridProps, CtaCardItem } from \"./components/cta-card-grid.js\";\n\n// ── v0.3.2 additions ─────────────────────────────────────────────────────────\nexport { DiscoverHero } from \"./components/discover-hero.js\";\nexport type { DiscoverHeroProps } from \"./components/discover-hero.js\";\nexport { FeaturedCarousel, FeaturedCarouselSkeleton } from \"./components/featured-carousel.js\";\nexport type { FeaturedCarouselProps } from \"./components/featured-carousel.js\";\nexport { DiscoverCollectionsStrip } from \"./components/discover-collections-strip.js\";\nexport type { DiscoverCollectionsStripProps } from \"./components/discover-collections-strip.js\";\nexport { DiscoverCreatorsStrip } from \"./components/discover-creators-strip.js\";\nexport type { DiscoverCreatorsStripProps } from \"./components/discover-creators-strip.js\";\nexport { DiscoverFeedSection } from \"./components/discover-feed-section.js\";\nexport type { DiscoverFeedSectionProps } from \"./components/discover-feed-section.js\";\nexport { ActivityCard, ActivityCardSkeleton, ACTIVITY_MESSAGES } from \"./components/activity-card.js\";\nexport type { ActivityCardProps } from \"./components/activity-card.js\";\n\n// ── Launchpad (grouped sections — single page-UI source since 0.8.0) ─────────\nexport { LaunchpadGroupedSections, LaunchpadServiceCard, SERVICE_HUES } from \"./components/launchpad-services.js\";\nexport { LaunchpadStrip } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadStripProps } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadGroupedSectionsProps, LaunchpadServiceCardProps, ServiceOverride, ServiceOverrides } from \"./components/launchpad-services.js\";\nexport { LAUNCHPAD_SERVICE_DEFINITIONS, LAUNCHPAD_SERVICE_GROUPS } from \"./data/launchpad-services.js\";\nexport type { ServiceDefinition, ServiceStatus, ServiceCategory, ServiceGroup, ServiceGroupDefinition } from \"./data/launchpad-services.js\";\n\n// ── v0.5.0 additions ─────────────────────────────────────────────────────────\nexport { NavCommandMenu, useNavCommandMenu } from \"./components/nav-command-menu.js\";\nexport type { NavCommand, NavCommandGroup, NavCommandMenuProps } from \"./components/nav-command-menu.js\";\n\n// ── v0.6.0 additions — portfolio subnav + counts ────────────────────────────\nexport { PortfolioSubnav } from \"./components/portfolio-subnav.js\";\nexport type {\n PortfolioSubnavProps,\n PortfolioNavItem,\n PortfolioNavGroup,\n PortfolioBadgeVariant,\n} from \"./components/portfolio-subnav.js\";\nexport { derivePortfolioCounts } from \"./utils/portfolio-counts.js\";\nexport type { PortfolioCounts, CountableOrder } from \"./utils/portfolio-counts.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,gBAAmB;AACnB,oBAAmC;AACnC,qBAA+B;AAC/B,kBAA2B;AAG3B,sBAA+C;AAE/C,gBAGO;AAEP,0BAEO;AAEP,6BAA8B;AAC9B,oCAAqC;AACrC,+BAAgC;AAChC,uCAAwC;AAExC,gCAAsE;AACtE,mBAAsB;AAGtB,2BAA6C;AAG7C,2BAAyD;AAGzD,6BAA+B;AAG/B,wBAA8B;AAE9B,wBAAkC;AAIlC,+BAAyF;AACzF,4BAA8B;AAE9B,4BAA8B;AAE9B,0BAA4B;AAE5B,6BAAuD;AAEvD,wBAA6C;AAI7C,kBAAmC;AACnC,sBAAmD;AAEnD,yBAA+C;AAE/C,6BAA+B;AAE/B,0BAAiD;AAEjD,0BAA4B;AAE5B,iCAAkC;AAElC,2BAA4B;AAI5B,2BAA6B;AAE7B,+BAA2D;AAE3D,wCAAyC;AAEzC,qCAAsC;AAEtC,mCAAoC;AAEpC,2BAAsE;AAItE,gCAA6E;AAC7E,6BAA+B;AAG/B,IAAAA,6BAAwE;AAIxE,8BAAkD;AAIlD,8BAAgC;AAOhC,8BAAsC;","names":["import_launchpad_services"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// ── Utils ─────────────────────────────────────────────────────────────────────\nexport { cn } from \"./utils/cn.js\";\nexport { formatDisplayPrice } from \"./utils/format.js\";\nexport { shortenAddress } from \"./utils/address.js\";\nexport { ipfsToHttp } from \"./utils/ipfs.js\";\n\n// ── Data (server-safe — no React, safe in Server Components) ──────────────────\nexport { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from \"./data/ip-types.js\";\nexport type { IpTypeData } from \"./data/ip-types.js\";\nexport {\n IP_TYPES, LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES,\n DERIVATIVES_OPTIONS, LICENSE_TRAIT_TYPES,\n} from \"./data/ip.js\";\nexport type { IPType, LicenseType } from \"./data/ip.js\";\nexport {\n IP_TEMPLATES, EMBED_PLATFORM_META, SOCIAL_PLATFORM_META, TEMPLATE_TRAIT_TYPES, DOC_UPLOAD,\n} from \"./data/ip-templates.js\";\nexport type { EmbedPlatform, SocialPlatform, TraitSuggestion, IPTemplate, DocUploadConfig } from \"./data/ip-templates.js\";\nexport { IPTypeDisplay } from \"./components/ip-type-display.js\";\nexport { AssetOverviewContent } from \"./components/asset-overview-content.js\";\nexport { AssetMarketsTab } from \"./components/asset-markets-tab.js\";\nexport { ParentAttributionBanner } from \"./components/parent-attribution-banner.js\";\nexport type { ParentBannerProps } from \"./components/parent-attribution-banner.js\";\nexport { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from \"./components/asset-top-sections.js\";\nexport { BRAND } from \"./data/brand.js\";\n\n// ── Components (client-only — all have \"use client\") ─────────────────────────\nexport { CurrencyIcon, CurrencyAmount } from \"./components/currency-icon.js\";\nexport type { CurrencyIconProps, CurrencyAmountProps } from \"./components/currency-icon.js\";\n\nexport { IpTypeBadge, IP_TYPE_CONFIG, IP_TYPE_MAP } from \"./components/ip-type-badge.js\";\nexport type { IpTypeBadgeProps, IpTypeConfig } from \"./components/ip-type-badge.js\";\n\nexport { AddressDisplay } from \"./components/address-display.js\";\nexport type { AddressDisplayProps } from \"./components/address-display.js\";\n\nexport { MedialaneIcon } from \"./components/brand-icon.js\";\nexport type { MedialaneIconProps } from \"./components/brand-icon.js\";\nexport { MedialaneLogoFull } from \"./components/brand-logo.js\";\nexport type { MedialaneLogoFullProps } from \"./components/brand-logo.js\";\n\n// ── v0.2 additions ────────────────────────────────────────────────────────────\nexport { MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT } from \"./components/motion-primitives.js\";\nexport { PageContainer } from \"./components/page-container.js\";\nexport type { PageContainerProps } from \"./components/page-container.js\";\nexport { ScrollSection } from \"./components/scroll-section.js\";\nexport type { ScrollSectionProps } from \"./components/scroll-section.js\";\nexport { ShareButton } from \"./components/share-button.js\";\nexport type { ShareButtonProps } from \"./components/share-button.js\";\nexport { CollectionCard, CollectionCardSkeleton } from \"./components/collection-card.js\";\nexport type { CollectionCardProps } from \"./components/collection-card.js\";\nexport { TokenCard, TokenCardSkeleton } from \"./components/token-card.js\";\nexport type { TokenCardProps, RarityTier } from \"./components/token-card.js\";\n\n// ── v0.3 additions ────────────────────────────────────────────────────────────\nexport { timeAgo, timeUntil } from \"./utils/time.js\";\nexport { ACTIVITY_TYPE_CONFIG, TYPE_FILTERS } from \"./data/activity.js\";\nexport type { ActivityTypeConfig } from \"./data/activity.js\";\nexport { HeroSlider, HeroSliderSkeleton } from \"./components/hero-slider.js\";\nexport type { HeroSliderProps } from \"./components/hero-slider.js\";\nexport { ActivityTicker } from \"./components/activity-ticker.js\";\nexport type { ActivityTickerProps } from \"./components/activity-ticker.js\";\nexport { ListingCard, ListingCardSkeleton } from \"./components/listing-card.js\";\nexport type { ListingCardProps } from \"./components/listing-card.js\";\nexport { ActivityRow } from \"./components/activity-row.js\";\nexport type { ActivityRowProps } from \"./components/activity-row.js\";\nexport { ActivityFeedShell } from \"./components/activity-feed-shell.js\";\nexport type { ActivityFeedShellProps } from \"./components/activity-feed-shell.js\";\nexport { CtaCardGrid } from \"./components/cta-card-grid.js\";\nexport type { CtaCardGridProps, CtaCardItem } from \"./components/cta-card-grid.js\";\n\n// ── v0.3.2 additions ─────────────────────────────────────────────────────────\nexport { DiscoverHero } from \"./components/discover-hero.js\";\nexport type { DiscoverHeroProps } from \"./components/discover-hero.js\";\nexport { FeaturedCarousel, FeaturedCarouselSkeleton } from \"./components/featured-carousel.js\";\nexport type { FeaturedCarouselProps } from \"./components/featured-carousel.js\";\nexport { DiscoverCollectionsStrip } from \"./components/discover-collections-strip.js\";\nexport type { DiscoverCollectionsStripProps } from \"./components/discover-collections-strip.js\";\nexport { DiscoverCreatorsStrip } from \"./components/discover-creators-strip.js\";\nexport type { DiscoverCreatorsStripProps } from \"./components/discover-creators-strip.js\";\nexport { DiscoverFeedSection } from \"./components/discover-feed-section.js\";\nexport type { DiscoverFeedSectionProps } from \"./components/discover-feed-section.js\";\nexport { ActivityCard, ActivityCardSkeleton, ACTIVITY_MESSAGES } from \"./components/activity-card.js\";\nexport type { ActivityCardProps } from \"./components/activity-card.js\";\n\n// ── Launchpad (grouped sections — single page-UI source since 0.8.0) ─────────\nexport { LaunchpadGroupedSections, LaunchpadServiceCard, SERVICE_HUES } from \"./components/launchpad-services.js\";\nexport { LaunchpadStrip } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadStripProps } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadGroupedSectionsProps, LaunchpadServiceCardProps, ServiceOverride, ServiceOverrides } from \"./components/launchpad-services.js\";\nexport { LAUNCHPAD_SERVICE_DEFINITIONS, LAUNCHPAD_SERVICE_GROUPS } from \"./data/launchpad-services.js\";\nexport type { ServiceDefinition, ServiceStatus, ServiceCategory, ServiceGroup, ServiceGroupDefinition } from \"./data/launchpad-services.js\";\n\n// ── v0.5.0 additions ─────────────────────────────────────────────────────────\nexport { NavCommandMenu, useNavCommandMenu } from \"./components/nav-command-menu.js\";\nexport type { NavCommand, NavCommandGroup, NavCommandMenuProps } from \"./components/nav-command-menu.js\";\n\n// ── v0.6.0 additions — portfolio subnav + counts ────────────────────────────\nexport { PortfolioSubnav } from \"./components/portfolio-subnav.js\";\nexport type {\n PortfolioSubnavProps,\n PortfolioNavItem,\n PortfolioNavGroup,\n PortfolioBadgeVariant,\n} from \"./components/portfolio-subnav.js\";\nexport { derivePortfolioCounts } from \"./utils/portfolio-counts.js\";\nexport type { PortfolioCounts, CountableOrder } from \"./utils/portfolio-counts.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,gBAAmB;AACnB,oBAAmC;AACnC,qBAA+B;AAC/B,kBAA2B;AAG3B,sBAA+C;AAE/C,gBAGO;AAEP,0BAEO;AAEP,6BAA8B;AAC9B,oCAAqC;AACrC,+BAAgC;AAChC,uCAAwC;AAExC,gCAAsE;AACtE,mBAAsB;AAGtB,2BAA6C;AAG7C,2BAAyD;AAGzD,6BAA+B;AAG/B,wBAA8B;AAE9B,wBAAkC;AAIlC,+BAAyF;AACzF,4BAA8B;AAE9B,4BAA8B;AAE9B,0BAA4B;AAE5B,6BAAuD;AAEvD,wBAA6C;AAI7C,kBAAmC;AACnC,sBAAmD;AAEnD,yBAA+C;AAE/C,6BAA+B;AAE/B,0BAAiD;AAEjD,0BAA4B;AAE5B,iCAAkC;AAElC,2BAA4B;AAI5B,2BAA6B;AAE7B,+BAA2D;AAE3D,wCAAyC;AAEzC,qCAAsC;AAEtC,mCAAoC;AAEpC,2BAAsE;AAItE,gCAA6E;AAC7E,6BAA+B;AAG/B,IAAAA,6BAAwE;AAIxE,8BAAkD;AAIlD,8BAAgC;AAOhC,8BAAsC;","names":["import_launchpad_services"]}
package/dist/index.d.cts CHANGED
@@ -4,7 +4,7 @@ export { shortenAddress } from './utils/address.cjs';
4
4
  export { ipfsToHttp } from './utils/ipfs.cjs';
5
5
  export { IP_TYPE_DATA, IP_TYPE_DATA_MAP, IpTypeData } from './data/ip-types.cjs';
6
6
  export { AI_POLICIES, DERIVATIVES_OPTIONS, GEOGRAPHIC_SCOPES, IPType, IP_TYPES, LICENSE_TRAIT_TYPES, LICENSE_TYPES, LicenseType } from './data/ip.cjs';
7
- export { EMBED_PLATFORM_META, EmbedPlatform, IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, SocialPlatform, TEMPLATE_TRAIT_TYPES, TraitSuggestion } from './data/ip-templates.cjs';
7
+ export { DOC_UPLOAD, DocUploadConfig, EMBED_PLATFORM_META, EmbedPlatform, IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, SocialPlatform, TEMPLATE_TRAIT_TYPES, TraitSuggestion } from './data/ip-templates.cjs';
8
8
  export { IPTypeDisplay } from './components/ip-type-display.cjs';
9
9
  export { AssetOverviewContent } from './components/asset-overview-content.cjs';
10
10
  export { AssetMarketsTab } from './components/asset-markets-tab.cjs';
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { shortenAddress } from './utils/address.js';
4
4
  export { ipfsToHttp } from './utils/ipfs.js';
5
5
  export { IP_TYPE_DATA, IP_TYPE_DATA_MAP, IpTypeData } from './data/ip-types.js';
6
6
  export { AI_POLICIES, DERIVATIVES_OPTIONS, GEOGRAPHIC_SCOPES, IPType, IP_TYPES, LICENSE_TRAIT_TYPES, LICENSE_TYPES, LicenseType } from './data/ip.js';
7
- export { EMBED_PLATFORM_META, EmbedPlatform, IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, SocialPlatform, TEMPLATE_TRAIT_TYPES, TraitSuggestion } from './data/ip-templates.js';
7
+ export { DOC_UPLOAD, DocUploadConfig, EMBED_PLATFORM_META, EmbedPlatform, IPTemplate, IP_TEMPLATES, SOCIAL_PLATFORM_META, SocialPlatform, TEMPLATE_TRAIT_TYPES, TraitSuggestion } from './data/ip-templates.js';
8
8
  export { IPTypeDisplay } from './components/ip-type-display.js';
9
9
  export { AssetOverviewContent } from './components/asset-overview-content.js';
10
10
  export { AssetMarketsTab } from './components/asset-markets-tab.js';
package/dist/index.js CHANGED
@@ -15,7 +15,8 @@ import {
15
15
  IP_TEMPLATES,
16
16
  EMBED_PLATFORM_META,
17
17
  SOCIAL_PLATFORM_META,
18
- TEMPLATE_TRAIT_TYPES
18
+ TEMPLATE_TRAIT_TYPES,
19
+ DOC_UPLOAD
19
20
  } from "./data/ip-templates.js";
20
21
  import { IPTypeDisplay } from "./components/ip-type-display.js";
21
22
  import { AssetOverviewContent } from "./components/asset-overview-content.js";
@@ -75,6 +76,7 @@ export {
75
76
  CurrencyAmount,
76
77
  CurrencyIcon,
77
78
  DERIVATIVES_OPTIONS,
79
+ DOC_UPLOAD,
78
80
  DiscoverCollectionsStrip,
79
81
  DiscoverCreatorsStrip,
80
82
  DiscoverFeedSection,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// ── Utils ─────────────────────────────────────────────────────────────────────\nexport { cn } from \"./utils/cn.js\";\nexport { formatDisplayPrice } from \"./utils/format.js\";\nexport { shortenAddress } from \"./utils/address.js\";\nexport { ipfsToHttp } from \"./utils/ipfs.js\";\n\n// ── Data (server-safe — no React, safe in Server Components) ──────────────────\nexport { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from \"./data/ip-types.js\";\nexport type { IpTypeData } from \"./data/ip-types.js\";\nexport {\n IP_TYPES, LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES,\n DERIVATIVES_OPTIONS, LICENSE_TRAIT_TYPES,\n} from \"./data/ip.js\";\nexport type { IPType, LicenseType } from \"./data/ip.js\";\nexport {\n IP_TEMPLATES, EMBED_PLATFORM_META, SOCIAL_PLATFORM_META, TEMPLATE_TRAIT_TYPES,\n} from \"./data/ip-templates.js\";\nexport type { EmbedPlatform, SocialPlatform, TraitSuggestion, IPTemplate } from \"./data/ip-templates.js\";\nexport { IPTypeDisplay } from \"./components/ip-type-display.js\";\nexport { AssetOverviewContent } from \"./components/asset-overview-content.js\";\nexport { AssetMarketsTab } from \"./components/asset-markets-tab.js\";\nexport { ParentAttributionBanner } from \"./components/parent-attribution-banner.js\";\nexport type { ParentBannerProps } from \"./components/parent-attribution-banner.js\";\nexport { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from \"./components/asset-top-sections.js\";\nexport { BRAND } from \"./data/brand.js\";\n\n// ── Components (client-only — all have \"use client\") ─────────────────────────\nexport { CurrencyIcon, CurrencyAmount } from \"./components/currency-icon.js\";\nexport type { CurrencyIconProps, CurrencyAmountProps } from \"./components/currency-icon.js\";\n\nexport { IpTypeBadge, IP_TYPE_CONFIG, IP_TYPE_MAP } from \"./components/ip-type-badge.js\";\nexport type { IpTypeBadgeProps, IpTypeConfig } from \"./components/ip-type-badge.js\";\n\nexport { AddressDisplay } from \"./components/address-display.js\";\nexport type { AddressDisplayProps } from \"./components/address-display.js\";\n\nexport { MedialaneIcon } from \"./components/brand-icon.js\";\nexport type { MedialaneIconProps } from \"./components/brand-icon.js\";\nexport { MedialaneLogoFull } from \"./components/brand-logo.js\";\nexport type { MedialaneLogoFullProps } from \"./components/brand-logo.js\";\n\n// ── v0.2 additions ────────────────────────────────────────────────────────────\nexport { MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT } from \"./components/motion-primitives.js\";\nexport { PageContainer } from \"./components/page-container.js\";\nexport type { PageContainerProps } from \"./components/page-container.js\";\nexport { ScrollSection } from \"./components/scroll-section.js\";\nexport type { ScrollSectionProps } from \"./components/scroll-section.js\";\nexport { ShareButton } from \"./components/share-button.js\";\nexport type { ShareButtonProps } from \"./components/share-button.js\";\nexport { CollectionCard, CollectionCardSkeleton } from \"./components/collection-card.js\";\nexport type { CollectionCardProps } from \"./components/collection-card.js\";\nexport { TokenCard, TokenCardSkeleton } from \"./components/token-card.js\";\nexport type { TokenCardProps, RarityTier } from \"./components/token-card.js\";\n\n// ── v0.3 additions ────────────────────────────────────────────────────────────\nexport { timeAgo, timeUntil } from \"./utils/time.js\";\nexport { ACTIVITY_TYPE_CONFIG, TYPE_FILTERS } from \"./data/activity.js\";\nexport type { ActivityTypeConfig } from \"./data/activity.js\";\nexport { HeroSlider, HeroSliderSkeleton } from \"./components/hero-slider.js\";\nexport type { HeroSliderProps } from \"./components/hero-slider.js\";\nexport { ActivityTicker } from \"./components/activity-ticker.js\";\nexport type { ActivityTickerProps } from \"./components/activity-ticker.js\";\nexport { ListingCard, ListingCardSkeleton } from \"./components/listing-card.js\";\nexport type { ListingCardProps } from \"./components/listing-card.js\";\nexport { ActivityRow } from \"./components/activity-row.js\";\nexport type { ActivityRowProps } from \"./components/activity-row.js\";\nexport { ActivityFeedShell } from \"./components/activity-feed-shell.js\";\nexport type { ActivityFeedShellProps } from \"./components/activity-feed-shell.js\";\nexport { CtaCardGrid } from \"./components/cta-card-grid.js\";\nexport type { CtaCardGridProps, CtaCardItem } from \"./components/cta-card-grid.js\";\n\n// ── v0.3.2 additions ─────────────────────────────────────────────────────────\nexport { DiscoverHero } from \"./components/discover-hero.js\";\nexport type { DiscoverHeroProps } from \"./components/discover-hero.js\";\nexport { FeaturedCarousel, FeaturedCarouselSkeleton } from \"./components/featured-carousel.js\";\nexport type { FeaturedCarouselProps } from \"./components/featured-carousel.js\";\nexport { DiscoverCollectionsStrip } from \"./components/discover-collections-strip.js\";\nexport type { DiscoverCollectionsStripProps } from \"./components/discover-collections-strip.js\";\nexport { DiscoverCreatorsStrip } from \"./components/discover-creators-strip.js\";\nexport type { DiscoverCreatorsStripProps } from \"./components/discover-creators-strip.js\";\nexport { DiscoverFeedSection } from \"./components/discover-feed-section.js\";\nexport type { DiscoverFeedSectionProps } from \"./components/discover-feed-section.js\";\nexport { ActivityCard, ActivityCardSkeleton, ACTIVITY_MESSAGES } from \"./components/activity-card.js\";\nexport type { ActivityCardProps } from \"./components/activity-card.js\";\n\n// ── Launchpad (grouped sections — single page-UI source since 0.8.0) ─────────\nexport { LaunchpadGroupedSections, LaunchpadServiceCard, SERVICE_HUES } from \"./components/launchpad-services.js\";\nexport { LaunchpadStrip } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadStripProps } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadGroupedSectionsProps, LaunchpadServiceCardProps, ServiceOverride, ServiceOverrides } from \"./components/launchpad-services.js\";\nexport { LAUNCHPAD_SERVICE_DEFINITIONS, LAUNCHPAD_SERVICE_GROUPS } from \"./data/launchpad-services.js\";\nexport type { ServiceDefinition, ServiceStatus, ServiceCategory, ServiceGroup, ServiceGroupDefinition } from \"./data/launchpad-services.js\";\n\n// ── v0.5.0 additions ─────────────────────────────────────────────────────────\nexport { NavCommandMenu, useNavCommandMenu } from \"./components/nav-command-menu.js\";\nexport type { NavCommand, NavCommandGroup, NavCommandMenuProps } from \"./components/nav-command-menu.js\";\n\n// ── v0.6.0 additions — portfolio subnav + counts ────────────────────────────\nexport { PortfolioSubnav } from \"./components/portfolio-subnav.js\";\nexport type {\n PortfolioSubnavProps,\n PortfolioNavItem,\n PortfolioNavGroup,\n PortfolioBadgeVariant,\n} from \"./components/portfolio-subnav.js\";\nexport { derivePortfolioCounts } from \"./utils/portfolio-counts.js\";\nexport type { PortfolioCounts, CountableOrder } from \"./utils/portfolio-counts.js\";\n"],"mappings":"AACA,SAAS,UAAU;AACnB,SAAS,0BAA0B;AACnC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAG3B,SAAS,cAAc,wBAAwB;AAE/C;AAAA,EACE;AAAA,EAAU;AAAA,EAAe;AAAA,EAAmB;AAAA,EAC5C;AAAA,EAAqB;AAAA,OAChB;AAEP;AAAA,EACE;AAAA,EAAc;AAAA,EAAqB;AAAA,EAAsB;AAAA,OACpD;AAEP,SAAS,qBAAqB;AAC9B,SAAS,4BAA4B;AACrC,SAAS,uBAAuB;AAChC,SAAS,+BAA+B;AAExC,SAAS,kBAAkB,kBAAkB,yBAAyB;AACtE,SAAS,aAAa;AAGtB,SAAS,cAAc,sBAAsB;AAG7C,SAAS,aAAa,gBAAgB,mBAAmB;AAGzD,SAAS,sBAAsB;AAG/B,SAAS,qBAAqB;AAE9B,SAAS,yBAAyB;AAIlC,SAAS,YAAY,QAAQ,SAAS,aAAa,cAAc,QAAQ,gBAAgB;AACzF,SAAS,qBAAqB;AAE9B,SAAS,qBAAqB;AAE9B,SAAS,mBAAmB;AAE5B,SAAS,gBAAgB,8BAA8B;AAEvD,SAAS,WAAW,yBAAyB;AAI7C,SAAS,SAAS,iBAAiB;AACnC,SAAS,sBAAsB,oBAAoB;AAEnD,SAAS,YAAY,0BAA0B;AAE/C,SAAS,sBAAsB;AAE/B,SAAS,aAAa,2BAA2B;AAEjD,SAAS,mBAAmB;AAE5B,SAAS,yBAAyB;AAElC,SAAS,mBAAmB;AAI5B,SAAS,oBAAoB;AAE7B,SAAS,kBAAkB,gCAAgC;AAE3D,SAAS,gCAAgC;AAEzC,SAAS,6BAA6B;AAEtC,SAAS,2BAA2B;AAEpC,SAAS,cAAc,sBAAsB,yBAAyB;AAItE,SAAS,0BAA0B,sBAAsB,oBAAoB;AAC7E,SAAS,sBAAsB;AAG/B,SAAS,+BAA+B,gCAAgC;AAIxE,SAAS,gBAAgB,yBAAyB;AAIlD,SAAS,uBAAuB;AAOhC,SAAS,6BAA6B;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// ── Utils ─────────────────────────────────────────────────────────────────────\nexport { cn } from \"./utils/cn.js\";\nexport { formatDisplayPrice } from \"./utils/format.js\";\nexport { shortenAddress } from \"./utils/address.js\";\nexport { ipfsToHttp } from \"./utils/ipfs.js\";\n\n// ── Data (server-safe — no React, safe in Server Components) ──────────────────\nexport { IP_TYPE_DATA, IP_TYPE_DATA_MAP } from \"./data/ip-types.js\";\nexport type { IpTypeData } from \"./data/ip-types.js\";\nexport {\n IP_TYPES, LICENSE_TYPES, GEOGRAPHIC_SCOPES, AI_POLICIES,\n DERIVATIVES_OPTIONS, LICENSE_TRAIT_TYPES,\n} from \"./data/ip.js\";\nexport type { IPType, LicenseType } from \"./data/ip.js\";\nexport {\n IP_TEMPLATES, EMBED_PLATFORM_META, SOCIAL_PLATFORM_META, TEMPLATE_TRAIT_TYPES, DOC_UPLOAD,\n} from \"./data/ip-templates.js\";\nexport type { EmbedPlatform, SocialPlatform, TraitSuggestion, IPTemplate, DocUploadConfig } from \"./data/ip-templates.js\";\nexport { IPTypeDisplay } from \"./components/ip-type-display.js\";\nexport { AssetOverviewContent } from \"./components/asset-overview-content.js\";\nexport { AssetMarketsTab } from \"./components/asset-markets-tab.js\";\nexport { ParentAttributionBanner } from \"./components/parent-attribution-banner.js\";\nexport type { ParentBannerProps } from \"./components/parent-attribution-banner.js\";\nexport { AssetMediaColumn, AssetHeaderBlock, buildEditionStats } from \"./components/asset-top-sections.js\";\nexport { BRAND } from \"./data/brand.js\";\n\n// ── Components (client-only — all have \"use client\") ─────────────────────────\nexport { CurrencyIcon, CurrencyAmount } from \"./components/currency-icon.js\";\nexport type { CurrencyIconProps, CurrencyAmountProps } from \"./components/currency-icon.js\";\n\nexport { IpTypeBadge, IP_TYPE_CONFIG, IP_TYPE_MAP } from \"./components/ip-type-badge.js\";\nexport type { IpTypeBadgeProps, IpTypeConfig } from \"./components/ip-type-badge.js\";\n\nexport { AddressDisplay } from \"./components/address-display.js\";\nexport type { AddressDisplayProps } from \"./components/address-display.js\";\n\nexport { MedialaneIcon } from \"./components/brand-icon.js\";\nexport type { MedialaneIconProps } from \"./components/brand-icon.js\";\nexport { MedialaneLogoFull } from \"./components/brand-logo.js\";\nexport type { MedialaneLogoFullProps } from \"./components/brand-logo.js\";\n\n// ── v0.2 additions ────────────────────────────────────────────────────────────\nexport { MotionCard, FadeIn, Stagger, StaggerItem, KineticWords, SPRING, EASE_OUT } from \"./components/motion-primitives.js\";\nexport { PageContainer } from \"./components/page-container.js\";\nexport type { PageContainerProps } from \"./components/page-container.js\";\nexport { ScrollSection } from \"./components/scroll-section.js\";\nexport type { ScrollSectionProps } from \"./components/scroll-section.js\";\nexport { ShareButton } from \"./components/share-button.js\";\nexport type { ShareButtonProps } from \"./components/share-button.js\";\nexport { CollectionCard, CollectionCardSkeleton } from \"./components/collection-card.js\";\nexport type { CollectionCardProps } from \"./components/collection-card.js\";\nexport { TokenCard, TokenCardSkeleton } from \"./components/token-card.js\";\nexport type { TokenCardProps, RarityTier } from \"./components/token-card.js\";\n\n// ── v0.3 additions ────────────────────────────────────────────────────────────\nexport { timeAgo, timeUntil } from \"./utils/time.js\";\nexport { ACTIVITY_TYPE_CONFIG, TYPE_FILTERS } from \"./data/activity.js\";\nexport type { ActivityTypeConfig } from \"./data/activity.js\";\nexport { HeroSlider, HeroSliderSkeleton } from \"./components/hero-slider.js\";\nexport type { HeroSliderProps } from \"./components/hero-slider.js\";\nexport { ActivityTicker } from \"./components/activity-ticker.js\";\nexport type { ActivityTickerProps } from \"./components/activity-ticker.js\";\nexport { ListingCard, ListingCardSkeleton } from \"./components/listing-card.js\";\nexport type { ListingCardProps } from \"./components/listing-card.js\";\nexport { ActivityRow } from \"./components/activity-row.js\";\nexport type { ActivityRowProps } from \"./components/activity-row.js\";\nexport { ActivityFeedShell } from \"./components/activity-feed-shell.js\";\nexport type { ActivityFeedShellProps } from \"./components/activity-feed-shell.js\";\nexport { CtaCardGrid } from \"./components/cta-card-grid.js\";\nexport type { CtaCardGridProps, CtaCardItem } from \"./components/cta-card-grid.js\";\n\n// ── v0.3.2 additions ─────────────────────────────────────────────────────────\nexport { DiscoverHero } from \"./components/discover-hero.js\";\nexport type { DiscoverHeroProps } from \"./components/discover-hero.js\";\nexport { FeaturedCarousel, FeaturedCarouselSkeleton } from \"./components/featured-carousel.js\";\nexport type { FeaturedCarouselProps } from \"./components/featured-carousel.js\";\nexport { DiscoverCollectionsStrip } from \"./components/discover-collections-strip.js\";\nexport type { DiscoverCollectionsStripProps } from \"./components/discover-collections-strip.js\";\nexport { DiscoverCreatorsStrip } from \"./components/discover-creators-strip.js\";\nexport type { DiscoverCreatorsStripProps } from \"./components/discover-creators-strip.js\";\nexport { DiscoverFeedSection } from \"./components/discover-feed-section.js\";\nexport type { DiscoverFeedSectionProps } from \"./components/discover-feed-section.js\";\nexport { ActivityCard, ActivityCardSkeleton, ACTIVITY_MESSAGES } from \"./components/activity-card.js\";\nexport type { ActivityCardProps } from \"./components/activity-card.js\";\n\n// ── Launchpad (grouped sections — single page-UI source since 0.8.0) ─────────\nexport { LaunchpadGroupedSections, LaunchpadServiceCard, SERVICE_HUES } from \"./components/launchpad-services.js\";\nexport { LaunchpadStrip } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadStripProps } from \"./components/launchpad-strip.js\";\nexport type { LaunchpadGroupedSectionsProps, LaunchpadServiceCardProps, ServiceOverride, ServiceOverrides } from \"./components/launchpad-services.js\";\nexport { LAUNCHPAD_SERVICE_DEFINITIONS, LAUNCHPAD_SERVICE_GROUPS } from \"./data/launchpad-services.js\";\nexport type { ServiceDefinition, ServiceStatus, ServiceCategory, ServiceGroup, ServiceGroupDefinition } from \"./data/launchpad-services.js\";\n\n// ── v0.5.0 additions ─────────────────────────────────────────────────────────\nexport { NavCommandMenu, useNavCommandMenu } from \"./components/nav-command-menu.js\";\nexport type { NavCommand, NavCommandGroup, NavCommandMenuProps } from \"./components/nav-command-menu.js\";\n\n// ── v0.6.0 additions — portfolio subnav + counts ────────────────────────────\nexport { PortfolioSubnav } from \"./components/portfolio-subnav.js\";\nexport type {\n PortfolioSubnavProps,\n PortfolioNavItem,\n PortfolioNavGroup,\n PortfolioBadgeVariant,\n} from \"./components/portfolio-subnav.js\";\nexport { derivePortfolioCounts } from \"./utils/portfolio-counts.js\";\nexport type { PortfolioCounts, CountableOrder } from \"./utils/portfolio-counts.js\";\n"],"mappings":"AACA,SAAS,UAAU;AACnB,SAAS,0BAA0B;AACnC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAG3B,SAAS,cAAc,wBAAwB;AAE/C;AAAA,EACE;AAAA,EAAU;AAAA,EAAe;AAAA,EAAmB;AAAA,EAC5C;AAAA,EAAqB;AAAA,OAChB;AAEP;AAAA,EACE;AAAA,EAAc;AAAA,EAAqB;AAAA,EAAsB;AAAA,EAAsB;AAAA,OAC1E;AAEP,SAAS,qBAAqB;AAC9B,SAAS,4BAA4B;AACrC,SAAS,uBAAuB;AAChC,SAAS,+BAA+B;AAExC,SAAS,kBAAkB,kBAAkB,yBAAyB;AACtE,SAAS,aAAa;AAGtB,SAAS,cAAc,sBAAsB;AAG7C,SAAS,aAAa,gBAAgB,mBAAmB;AAGzD,SAAS,sBAAsB;AAG/B,SAAS,qBAAqB;AAE9B,SAAS,yBAAyB;AAIlC,SAAS,YAAY,QAAQ,SAAS,aAAa,cAAc,QAAQ,gBAAgB;AACzF,SAAS,qBAAqB;AAE9B,SAAS,qBAAqB;AAE9B,SAAS,mBAAmB;AAE5B,SAAS,gBAAgB,8BAA8B;AAEvD,SAAS,WAAW,yBAAyB;AAI7C,SAAS,SAAS,iBAAiB;AACnC,SAAS,sBAAsB,oBAAoB;AAEnD,SAAS,YAAY,0BAA0B;AAE/C,SAAS,sBAAsB;AAE/B,SAAS,aAAa,2BAA2B;AAEjD,SAAS,mBAAmB;AAE5B,SAAS,yBAAyB;AAElC,SAAS,mBAAmB;AAI5B,SAAS,oBAAoB;AAE7B,SAAS,kBAAkB,gCAAgC;AAE3D,SAAS,gCAAgC;AAEzC,SAAS,6BAA6B;AAEtC,SAAS,2BAA2B;AAEpC,SAAS,cAAc,sBAAsB,yBAAyB;AAItE,SAAS,0BAA0B,sBAAsB,oBAAoB;AAC7E,SAAS,sBAAsB;AAG/B,SAAS,+BAA+B,gCAAgC;AAIxE,SAAS,gBAAgB,yBAAyB;AAIlD,SAAS,uBAAuB;AAOhC,SAAS,6BAA6B;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",