@matterdev/credit 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/core/index.ts
21
+ var core_exports = {};
22
+ __export(core_exports, {
23
+ BRAND_NAME: () => BRAND_NAME,
24
+ CREDIT_CSS: () => CREDIT_CSS,
25
+ LOCALES: () => LOCALES,
26
+ LOCALE_CODES: () => LOCALE_CODES,
27
+ MATTER_ORGANIZATION: () => MATTER_ORGANIZATION,
28
+ MATTER_URL: () => MATTER_URL,
29
+ buildCreditUrl: () => buildCreditUrl,
30
+ creatorJsonLd: () => creatorJsonLd,
31
+ creatorJsonLdScript: () => creatorJsonLdScript,
32
+ normalizeSource: () => normalizeSource,
33
+ renderCreditHTML: () => renderCreditHTML,
34
+ renderCreditMarkup: () => renderCreditMarkup,
35
+ resolveCredit: () => resolveCredit,
36
+ serializeJsonLd: () => serializeJsonLd
37
+ });
38
+ module.exports = __toCommonJS(core_exports);
39
+
40
+ // src/core/labels.ts
41
+ var BRAND_NAME = "Matter Development";
42
+ var LOCALES = {
43
+ en: { label: "Developed by", productLabel: "A product of", newTab: "opens in a new tab", opensBrowser: "opens in your browser", dir: "ltr" },
44
+ fr: { label: "D\xE9velopp\xE9 par", productLabel: "Un produit de", newTab: "s\u2019ouvre dans un nouvel onglet", opensBrowser: "s\u2019ouvre dans votre navigateur", dir: "ltr" },
45
+ ar: { label: "\u062A\u0645 \u0627\u0644\u062A\u0637\u0648\u064A\u0631 \u0628\u0648\u0627\u0633\u0637\u0629", productLabel: "\u0623\u062D\u062F \u0645\u0646\u062A\u062C\u0627\u062A", newTab: "\u064A\u0641\u062A\u062D \u0641\u064A \u0639\u0644\u0627\u0645\u0629 \u062A\u0628\u0648\u064A\u0628 \u062C\u062F\u064A\u062F\u0629", opensBrowser: "\u064A\u0641\u062A\u062D \u0641\u064A \u0627\u0644\u0645\u062A\u0635\u0641\u062D", dir: "rtl" },
46
+ es: { label: "Desarrollado por", productLabel: "Un producto de", newTab: "se abre en una pesta\xF1a nueva", opensBrowser: "se abre en tu navegador", dir: "ltr" },
47
+ pt: { label: "Desenvolvido por", productLabel: "Um produto de", newTab: "abre em uma nova aba", opensBrowser: "abre no seu navegador", dir: "ltr" },
48
+ de: { label: "Entwickelt von", productLabel: "Ein Produkt von", newTab: "\xF6ffnet in einem neuen Tab", opensBrowser: "\xF6ffnet im Browser", dir: "ltr" },
49
+ no: { label: "Utviklet av", productLabel: "Et produkt fra", newTab: "\xE5pnes i en ny fane", opensBrowser: "\xE5pnes i nettleseren", dir: "ltr" },
50
+ zh: { label: "\u5F00\u53D1\u8005", productLabel: "\u51FA\u54C1", newTab: "\u5728\u65B0\u6807\u7B7E\u9875\u4E2D\u6253\u5F00", opensBrowser: "\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00", dir: "ltr" },
51
+ ja: { label: "\u958B\u767A", productLabel: "\u63D0\u4F9B", newTab: "\u65B0\u3057\u3044\u30BF\u30D6\u3067\u958B\u304D\u307E\u3059", opensBrowser: "\u30D6\u30E9\u30A6\u30B6\u3067\u958B\u304D\u307E\u3059", dir: "ltr" },
52
+ ko: { label: "\uAC1C\uBC1C", productLabel: "\uC81C\uACF5", newTab: "\uC0C8 \uD0ED\uC5D0\uC11C \uC5F4\uB9BC", opensBrowser: "\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uC5F4\uB9BC", dir: "ltr" }
53
+ };
54
+ var LOCALE_CODES = Object.keys(LOCALES);
55
+ function localeStrings(locale) {
56
+ return LOCALES[locale ?? "en"] ?? LOCALES.en;
57
+ }
58
+
59
+ // src/core/url.ts
60
+ var MATTER_URL = "https://matterdevelopment.com/";
61
+ function normalizeSource(source) {
62
+ return source.trim().toLowerCase().replace(/^www\./, "").replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 100);
63
+ }
64
+ function safeUrl(href) {
65
+ try {
66
+ const url = new URL(href);
67
+ if (url.protocol === "https:" || url.protocol === "http:") return url;
68
+ } catch {
69
+ }
70
+ return new URL(MATTER_URL);
71
+ }
72
+ function buildCreditUrl(options = {}) {
73
+ const { source, utm = {}, variant, defaultMedium = "credit_badge", href = MATTER_URL } = options;
74
+ const { medium, campaign, content, ...extra } = utm;
75
+ const url = safeUrl(href);
76
+ const set = (key, value) => {
77
+ if (value) url.searchParams.set(key, value);
78
+ };
79
+ set("utm_source", source ? normalizeSource(source) : void 0);
80
+ set("utm_medium", medium ?? defaultMedium);
81
+ set("utm_campaign", campaign ?? "developed_by");
82
+ set("utm_content", content ?? variant);
83
+ for (const [key, value] of Object.entries(extra)) set(key, value);
84
+ return url.toString();
85
+ }
86
+
87
+ // src/core/metrics.generated.ts
88
+ var WORDMARK_RATIO = 4.2755;
89
+ var MARK_RATIO = 1.3726;
90
+
91
+ // src/core/model.ts
92
+ var LOGO_HEIGHT = {
93
+ stacked: { sm: 20, md: 28, lg: 36 },
94
+ inline: { sm: 16, md: 20, lg: 26 },
95
+ mark: { sm: 18, md: 24, lg: 32 }
96
+ };
97
+ var LABEL_SIZE = {
98
+ stacked: { sm: 10, md: 11, lg: 13 },
99
+ inline: { sm: 11, md: 12, lg: 14 },
100
+ mark: { sm: 11, md: 12, lg: 14 }
101
+ };
102
+ var round = (n) => Math.round(n * 100) / 100;
103
+ function sizes(variant, size) {
104
+ if (typeof size === "number" && size > 0) {
105
+ return { height: size, label: Math.min(16, Math.max(10, Math.round(size * 0.42))) };
106
+ }
107
+ const key = size === "sm" || size === "lg" ? size : "md";
108
+ return { height: LOGO_HEIGHT[variant][key], label: LABEL_SIZE[variant][key] };
109
+ }
110
+ function resolveCredit(options = {}, platform = "web") {
111
+ const variant = options.variant ?? "stacked";
112
+ const theme = options.theme ?? "inherit";
113
+ const strings = localeStrings(options.locale);
114
+ const label = options.label?.trim() || (options.kind === "product" ? strings.productLabel : strings.label);
115
+ const { height, label: labelSize } = sizes(variant, options.size);
116
+ const ratio = variant === "mark" ? MARK_RATIO : WORDMARK_RATIO;
117
+ return {
118
+ variant,
119
+ theme,
120
+ href: buildCreditUrl({
121
+ source: options.source,
122
+ utm: options.utm,
123
+ variant,
124
+ defaultMedium: platform === "native" ? "app_credit" : "credit_badge",
125
+ href: options.href
126
+ }),
127
+ rel: options.nofollow ? "noopener nofollow" : "noopener",
128
+ dir: strings.dir,
129
+ lang: options.locale && options.locale in LOCALES ? options.locale : "en",
130
+ label: variant === "mark" ? null : label,
131
+ ariaLabel: `${label} ${BRAND_NAME} (${platform === "native" ? strings.opensBrowser : strings.newTab})`,
132
+ title: variant === "mark" ? `${label} ${BRAND_NAME}` : void 0,
133
+ className: [
134
+ "mdc",
135
+ `mdc--${variant}`,
136
+ `mdc--${theme}`,
137
+ options.animate === false ? null : "mdc--animate"
138
+ ].filter(Boolean).join(" "),
139
+ logo: {
140
+ kind: variant === "mark" ? "mark" : "wordmark",
141
+ width: round(height * ratio),
142
+ height
143
+ },
144
+ labelSize,
145
+ iconSize: Math.max(10, Math.round(variant === "stacked" ? height * 0.46 : labelSize))
146
+ };
147
+ }
148
+
149
+ // src/core/assets.generated.ts
150
+ var WORDMARK_MASK = "data:image/webp;base64,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";
151
+ var MARK_MASK = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0ODIuNzIgMzUxLjY4Ij48cGF0aCBkPSJNNzYuNTQsMzQ5LjY3YzIuMzktLjcyLDQuMTUtMS40NSw1Ljg1LTIuMTcsNS4xNC0yLjE2LDEzLjAxLTUuNTQsMjAuMjgtMTIuODMsNC45My00Ljk0LDcuODQtOS45Miw5LjQ3LTEyLjc1LDAsMCwxLjcyLTIuOTksMy4yMS02LjMxLDE0LjAyLTMxLjMyLDExLjQtNzQuNjksMTEuNC03NC42OS0xLjc1LTI0LjUyLTYuNTktNDYuNTQtMTUuOTgtNzIuNTYtNC45My0xMy42Ni00LjctMTMuMTYtMTkuOTYtNDUuMjItNC44OS0xMC4zMS04LjI3LTE3LjYtMTAuNDEtMjIuNjItMS42Ni0zLjg5LTUuNC0xNC4zOS03LjU0LTIxLjE4LS41LTEuNTgtLjk5LTMuMzQtMS40Ni01LjY1LS45Ny00Ljc5LTEuMDMtOC4yNy0xLjA5LTE0LjA0LS4xLTkuMjksLjc0LTEyLjQ1LDEuMjktMTQuMjIsLjE5LS42MSwuNTktMS44NiwxLjI3LTMuMzMsNi4yMS0xMy40OSwxNC44LTE4LjA5LDI5LjIyLTE1LjYsNy44NSwxLjM1LDEyLDMuMTEsMjAuNzMsOC43OCwxMy40Nyw4Ljc3LDMwLjQ5LDI4LjQ1LDQ0Ljk0LDUyLjA1LDIuNzksNC41Niw0Ljc5LDguMDYsNi4xMiwxMC41NywyLjgsNS4yOSw0LjQ2LDkuMTQsNy42MywxNi41NSw0LjU2LDEwLjY1LDYuODQsMTUuOTcsOC4xNiwyMC40NSwuOTIsMy4xMSwyLjI3LDYuOTUsNC45OCwxNC42MiwuMTEsLjMyLC41MywxLjMxLDEuMzgsMy4yOCwxLjA3LDIuNSwxLjMxLDIuOTcsMS44LDMuMTgsMS4yLC41MSwyLjg0LS45Myw0LjM0LTIuMjMsMy4wNi0yLjYzLDYuMzEtNS4wNSw5LjMyLTcuNzMsNS41OC00Ljk3LDYuNDEtNS41Miw2Ljc4LTcuMjEsLjQyLTEuODktLjE4LTMuMTctMS45OC04LjAxLTIuODctNy43Mi0yLjM1LTYuMi0zLjU1LTEwLjAzLTQuNjMtMTQuODctMjIuNDMtNDguOC0zNS4yOS02Ny4zLTYuNS05LjM2LTEzLjgtMTcuODYtMjEuNTEtMjUuMDJDMTM2LjQxLDEwLjI1LDEyNC4wNSwzLjU0LDEwNC44OSwuNzJjLTExLjY3LTEuNzMtMjIuNTMtLjM2LTMzLjM5LDQuMi0xMC4yLDQuMjctMTYuMDgsOS44OS0yMS4yNywyMC4zNC04LjU0LDE3LjI2LTguOCwzNy4xMS0uOCw2MS43OSw0Ljk1LDE1LjMsNi43MSwxOS41OSwxNC4xNiwzNC42NywxMS42MiwyMy41OSwxNS4xMywzMS44MiwyMS4zNyw1MC40MSwyLjYxLDcuNzgsNS4xOSwxNi4yNiw1Ljc0LDE4Ljg1czIuMDYsOS4zNywzLjM1LDE1LjA4YzQuNjksMjAuNjUsNi4zOCwzNS4zNSw2LjI5LDU0LjY1LS4xMiwyNC41Ny0yLjUxLDM2LjU5LTkuNzUsNDkuMTMtMi4xOSwzLjc5LTQuNTEsNi40OS01LjEsNy4xMi00LjU5LDQuOTMtOS4yMiw2LjkzLTEwLjE0LDcuMzItLjU5LC4yNS0yLjU1LDEuMDUtNS4yNSwxLjYxLS43NywuMTYtMy41NywuNjMtNy42NiwuNi04LjczLS4wNS0xMy4wOS0xLjkyLTIwLjAxLTguNjEtOS41NS05LjIzLTEzLjI1LTIxLjUxLTE1Ljc5LTUyLjQ1LTIuMTEtMjUuNTksMy4zNS01OS4zOCwxMy41Ny04My45MSw2LjM1LTE1LjIyLDEyLjM1LTI4LjI5LDE0LjAxLTMwLjQ3LC45Ny0xLjI3LDEuNS0yLjMxLDEuNTctMy40LC4wNy0xLjE3LS4yNi0yLjE5LTMuMDItNi4yMy0yLjU0LTMuNzItMi4xNC0yLjctNS4yNC02Ljk2LTEuNjEtMi4yMS0xLjkyLTIuNzYtMi42OC0yLjg4LTEuODMtLjI4LTMuNjMsMi4zNS01Ljk2LDUuODQtNC45MSw3LjM2LTcuMzcsMTEuMDQtNy4zOCwxMS4wNy0xMC4wMywxNC45MS0xOSwzMi45OC0yMi45OCw0Ni4yNkMxLjY5LDIxNy42MSwuMTgsMjI4LjQ3LDAsMjU1LjQ2Yy0uMTcsMjkuMTksMi40Niw0NC4wMywxMS4xLDYyLjc0LDQuMDYsOC43Nyw4LjgyLDE1LjQ0LDE0Ljg3LDIwLjU1LDcuMTMsNi4wMiwxNC4xMiw4LjQ4LDE3LjcxLDkuNyw0LjAyLDEuMzYsMTcuNjQsNS43OCwzMi44NSwxLjIyWiIvPjxwYXRoIGQ9Ik0yNTcuMjQsMzI2LjU0YzcuMDItMi40NCwxNy40My04LjY1LDIxLjUxLTEyLjg1LDkuNTEtOS43NSwxNi45NS0yNS41MiwxOS44NS00Mi4wNCwyLjQ3LTE0LjIsMS41NC0zNi42My0yLjMtNTQuMjgtNC4yOS0xOS43NC0xMS42Ni0zOS42LTE3LjI5LTM5LjEtLjg1LC4wOC0xLjE2LC41Ny01LjY5LDQuMDEtMy42MiwyLjc0LTYuNjEsNC44NC04LjUsNi4xNC0xLjA2LDEuMDItMi4xMiwyLjA1LTMuMTgsMy4wNywxLjQ3LDQuMDcsMi45NCw4LjE0LDQuNDEsMTIuMjEsMy41NiwxMC43Miw0LjkxLDE1Ljc0LDcuNjYsMjguMjYsLjUyLDIuMzMsLjk5LDEwLjE5LDEuMDQsMTcuNDMsLjA5LDEwLjk2LS4yOCwxNC42My0yLjA4LDIxLjY3LTUuMTUsMTkuOTctMTEuOTEsMjguNTktMjYuMjIsMzMuMzktMTUuNjUsNS4yNy0yOS45NS0uNTUtMzcuMDktMTUuMDgtNi43NC0xMy44LTUuNC00NC43OSwyLjg0LTY0LjQyLDEwLjY0LTI1LjMyLDI3LjQ0LTQ4LjAxLDQ0LjQzLTU5Ljk1LDIuODUtMi4wMSw3LjUyLTUuMzMsMTAuMzgtNy40LDIwLjQ2LTE0Ljg1LDQ4LjQ0LTI0LjE2LDc2LjA3LTI1LjI4LDcuNDItLjI5LDEyLjgxLS45MiwxMy4zMi0xLjU0LC40NS0uNTcsMS4wNC01LjAxLDEuMy05Ljg3LC42Ni0xMS45MywuMjEtMTIuMzYtMTIuMjQtMTIuMzYtOS42MywwLTIyLjksMS4yNi0zMC44NywyLjk0LTguMDIsMS42OC0xMi44MywzLjI1LTMwLjE0LDkuODYtNy41NiwyLjg3LTI0LjI0LDExLjA3LTMzLjkzLDE2LjY3LTIwLjUxLDExLjg1LTM5Ljc5LDMwLjk5LTUzLjg4LDUzLjUyLTQuMDUsNi40My0xMi41NCwyMy43My0xMi41NCwyNS40OSwwLC41NS0uNjIsMi4zMy0xLjM4LDMuOTgtMi41Niw1LjUyLTQuNDMsMTMuNTQtNS40LDIzLjIyLS4yOSwyLjk0LS4zNSw1Ljk2LS40NywxMS45OS0uMDcsMy40NC0uMTMsNi45NSwwLDExLjU3LC4yMiw3LjQ1LC40LDEyLjcyLDIuMDUsMTkuNSwuNTksMi40NCwxLjE2LDQuMjEsMS41OCw1LjQ4LDIuNDEsNy40Miw0LjY0LDE0LjMsMTAuMzYsMjAuNjMsMy45OSw0LjQyLDguMTcsNi45LDEwLjE3LDguMDcsMy43LDIuMTYsNi45OCwzLjM3LDEwLjkxLDQuODEsMy40OSwxLjI5LDYuMjUsMS45Nyw2Ljk2LDIuMTQsLjQzLC4xLC43OSwuMTksMS4wNiwuMjUsNy44OCwxLjc2LDE0LjEzLDEuNTEsMTguMywxLjMyLDYuODktLjMyLDExLjg1LTEuNDYsMTMuMzgtMS44MywwLDAsMi45My0uNjgsNS42My0xLjYyWiIvPjxwYXRoIGQ9Ik00NDEuMzIsMzQ0Ljg3YzEzLjM4LTUuODgsMTguODMtMTAuMjIsMjYuMTUtMjAuOCw1LjU5LTguMDgsOC44Mi0xNC45OSwxMS40NS0yNC41LDQuODEtMTcuNDMsNS4xMi02MC41OSwuNTktODEuMjktNC4wNS0xOC40Ny0xMS45OC0zOS4zMi0yMC40MS01My42Ni0uOTItMS41Ni0zLjM5LTUuODEtNS41Mi05LjQyLTcuNTctMTIuODYtOS4xNC0xNy41OS0xMS44Ni0xNy40My0xLjU1LC4wOS0xLjYxLDEuNjMtNi44MSw4LjQtNC4xMiw1LjM2LTUuMTgsNS44Mi01LjgsOC4wNi0uNjgsMi40OC0uNzMsNS4wMywzLjA4LDExLjcxLDUuNzksMTAuMTcsOS43NSwxOC4wNSwxMS45NywyMy44MywxLjA1LDIuNzUsMi4yOCw1Ljg1LDIuNzEsNi44OCw0LjE1LDkuNzksOC40NywzMS40NCw5LjY1LDQ4LjMzLDIuODIsNDAuMzYtNS42LDY4LjA2LTIyLjk1LDc1LjU5LTYuODEsMi45Ni0xNy4yMiwzLjYtMjIuOTEsMS40NC0zLjU2LTEuMzUtNS45OC0yLjg2LTguMTgtNC4zOS0yLjItMS41My0xMy41NS05LjcyLTE3LjE4LTI0LjgxLS4zNy0xLjUyLS41Ni0yLjk3LS45Ni01Ljg3LTEuMTUtOC40MS0uODYtMTQuNzYtLjg2LTIyLjkxLDAtMjIuMzksLjQ1LTI2LjI5LDUuNjktNDguNTIsMi45NC0xMi40OSw5LjQ2LTMzLjE5LDEzLjUyLTQyLjg3LDEuNjMtMy44OSwzLjMtOC4xMywzLjc1LTkuNDIsLjQzLTEuMywxLjYzLTQuMDUsMi42Ni02LjEyLDcuMzctMTQuOCwxOC40LTQ0LjQxLDE5LjU4LTUyLjU0LC4zMS0yLjIsMS4yNS02LjU1LDIuMDYtOS42NSwyLjIzLTguNTgsMi4wOS00Mi4yMS0uMjEtNDkuOTQtNC44Mi0xNi4yNy0xMi41OS0yNy4xLTI0LjA3LTMzLjYyLTcuODktNC40OC0xMy43Ny01Ljg0LTI1LjQ2LTUuOS0yNC4zMS0uMTQtNDQuMTgsOS4yNS02NC4xNiwzMC4zLTE3LjA3LDE3Ljk4LTI2LjQ0LDMxLjMtMzYuNDIsNTEuNzQtNi45OSwxNC4zLTEwLDIyLjUtOS40OSwyNS45NywuMjQsMS43MywuODYsMi4xNCwzLjEzLDIuMDksNC43Mi0uMTIsMTcuNzMtMy4yMywyMC42OC00Ljk2LDIuNzctMS41OSw5Ljg3LTExLjMzLDE1LjYzLTIxLjM5LDYuMzUtMTEuMSwxNC44Ny0yMi43NywyNC4yNC0zMy4xNyw3LjA0LTcuODIsMjEuMjktMTkuMiwyNy42Ny0yMi4xLDUuMzYtMi40NCwxNC40NC0zLjg3LDIxLjA2LTMuMzQsMi45LC4yMyw1LjM4LC44Nyw3LjYxLDIuMDMsMS45OCwxLjAzLDUuMzksMy4yMSw4LjY5LDguNzksNi40OSwxMC45NSw2LjU0LDI0LjY0LDYuNDksMjguNDYtLjE3LDEzLjE2LTIuOTcsMjIuOTUtNS4zOCwzMS4xNC0zLjUsMTEuOTEtOC40LDIzLjAzLTE4LjMsNDUuMjItMy44Niw4LjY1LTYuNCwxNC45NC0xMS4zNiwyOC4yNy0uNjcsMS44Mi0yLjE2LDYuNDctMy4yOSwxMC4zNi0xLjEyLDMuODctMi42MSw4Ljk4LTMuMzIsMTEuMzEtLjY3LDIuMzItMS45Miw3LjQyLTIuNzMsMTEuMzEtLjgsMy44Ny0xLjg1LDguNTQtMi4zNSwxMC4zNi0uNSwxLjgyLTEuODMsMTAuOTMtMi45NiwyMC4yNS0zLjEsMjUuNjYtMS43OCw0NS4zNiw0LjMyLDY0LjA5LDEuNjIsNC45OCwzLjY1LDkuNDEsMy42NSw5LjQxLC4zNiwuNzMsMS4wOSwyLjEzLDIuMjEsMy45OSwyLjU1LDQuMjEsNy4yMSwxMS45MSwxNS43OSwxOS4xMSwyLjA3LDEuNzQsNS4yMSw0LjMsOS44Nyw2Ljc4LDIuNTIsMS4zNCw1LjE0LDIuNCw4LjQ5LDMuNTUsMy41NywxLjIyLDYuMzUsMS44MSw2Ljg5LDEuOTMsNS41MywxLjE4LDkuNjUsMS4wOSwxNi4yOCwuOTYsOC4xNS0uMTcsMTEuNTQtMS4wMiwxMy42My0xLjY2LDEuNTItLjQ3LDIuNjItLjg4LDMuNzItMS4zNloiLz48L3N2Zz4=";
152
+
153
+ // src/core/css.ts
154
+ var LIGHT_INK = "#1F2A3B";
155
+ var DARK_INK = "#F3F5F7";
156
+ var CREDIT_CSS = `
157
+ .mdc.mdc{color:var(--matter-credit-color);text-decoration:none;font-family:var(--matter-credit-font,ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace)}
158
+ .mdc.mdc--light{color:var(--matter-credit-color,${LIGHT_INK})}
159
+ .mdc.mdc--dark{color:var(--matter-credit-color,${DARK_INK})}
160
+ .mdc.mdc--auto{color:var(--matter-credit-color,${LIGHT_INK})}
161
+ @media (prefers-color-scheme:dark){.mdc.mdc--auto{color:var(--matter-credit-color,${DARK_INK})}}
162
+ .mdc{display:inline-flex;align-items:center;gap:.6em;vertical-align:middle;line-height:1;border-radius:6px;-webkit-tap-highlight-color:transparent}
163
+ .mdc--stacked{flex-direction:column}
164
+ .mdc--mark{gap:.35em}
165
+ .mdc:focus-visible{outline:2px solid currentColor;outline-offset:4px}
166
+ .mdc__label{font-size:var(--mdc-label-size,11px);font-weight:400;letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;opacity:.7;color:var(--matter-credit-label-color)}
167
+ .mdc--stacked .mdc__label{margin-inline-end:-.14em}
168
+ .mdc[dir=rtl] .mdc__label{letter-spacing:0;margin-inline-end:0;text-transform:none;font-family:var(--matter-credit-font-rtl,system-ui,sans-serif)}
169
+ .mdc__row{display:inline-flex;align-items:center;gap:6px}
170
+ .mdc__logo--wordmark{--mdc-logo:url("${WORDMARK_MASK}")}
171
+ .mdc__logo--mark{--mdc-logo:url("${MARK_MASK}")}
172
+ .mdc__logo{display:block;flex:none;background-color:currentColor;opacity:.85;transition:opacity .2s ease;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-mask-image:var(--mdc-logo);mask-image:var(--mdc-logo);-webkit-mask-size:100% 100%;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
173
+ .mdc:hover .mdc__logo,.mdc:focus-visible .mdc__logo{opacity:1}
174
+ .mdc__ext{display:block;flex:none;opacity:.6;transition:transform .25s ease,opacity .2s ease}
175
+ .mdc:hover .mdc__ext{opacity:.9}
176
+ .mdc[dir=rtl] .mdc__ext{transform:scaleX(-1)}
177
+ @media (prefers-reduced-motion:no-preference){
178
+ .mdc--animate .mdc__logo{-webkit-mask-image:var(--mdc-logo),linear-gradient(105deg,#000 40%,rgba(0,0,0,.3) 50%,#000 60%);mask-image:var(--mdc-logo),linear-gradient(105deg,#000 40%,rgba(0,0,0,.3) 50%,#000 60%);-webkit-mask-size:100% 100%,300% 100%;mask-size:100% 100%,300% 100%;-webkit-mask-position:0 0,100% 0;mask-position:0 0,100% 0;-webkit-mask-composite:source-in;mask-composite:intersect}
179
+ .mdc--animate:hover .mdc__logo{-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0;transition:opacity .2s ease,-webkit-mask-position .9s ease,mask-position .9s ease}
180
+ .mdc--animate:hover .mdc__ext{transform:translate(2px,-2px)}
181
+ .mdc--animate[dir=rtl]:hover .mdc__ext{transform:scaleX(-1) translate(2px,-2px)}
182
+ }
183
+ @media (forced-colors:active){.mdc__logo{forced-color-adjust:none;background-color:LinkText}}
184
+ `.trim();
185
+ var EXTERNAL_ICON_PATHS = [
186
+ "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",
187
+ "M15 3h6v6M10 14 21 3"
188
+ ];
189
+
190
+ // src/core/html.ts
191
+ var ESCAPES = {
192
+ "&": "&",
193
+ "<": "&lt;",
194
+ ">": "&gt;",
195
+ '"': "&quot;",
196
+ "'": "&#39;"
197
+ };
198
+ function escapeHtml(value) {
199
+ return value.replace(/[&<>"']/g, (c) => ESCAPES[c]);
200
+ }
201
+ function externalIconSvg(size) {
202
+ const paths = EXTERNAL_ICON_PATHS.map((d) => `<path d="${d}"/>`).join("");
203
+ return `<svg class="mdc__ext" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${paths}</svg>`;
204
+ }
205
+ function renderCreditMarkup(model) {
206
+ const attrs = [
207
+ `class="${model.className}"`,
208
+ `href="${escapeHtml(model.href)}"`,
209
+ `target="_blank"`,
210
+ `rel="${model.rel}"`,
211
+ `dir="${model.dir}"`,
212
+ `lang="${model.lang}"`,
213
+ `aria-label="${escapeHtml(model.ariaLabel)}"`,
214
+ model.title ? `title="${escapeHtml(model.title)}"` : null,
215
+ `style="--mdc-label-size:${model.labelSize}px"`,
216
+ `data-matter-credit=""`
217
+ ].filter(Boolean).join(" ");
218
+ const label = model.label ? `<span class="mdc__label" aria-hidden="true">${escapeHtml(model.label)}</span>` : "";
219
+ const logo = `<span class="mdc__logo mdc__logo--${model.logo.kind}" aria-hidden="true" style="width:${model.logo.width}px;height:${model.logo.height}px"></span>`;
220
+ return `<a ${attrs}>${label}<span class="mdc__row">${logo}${externalIconSvg(model.iconSize)}</span></a>`;
221
+ }
222
+ function renderCreditHTML(options) {
223
+ return `<style data-matter-credit>${CREDIT_CSS}</style>${renderCreditMarkup(resolveCredit(options))}`;
224
+ }
225
+
226
+ // src/core/jsonld.ts
227
+ var MATTER_ORGANIZATION = {
228
+ "@type": "Organization",
229
+ name: BRAND_NAME,
230
+ url: MATTER_URL
231
+ };
232
+ function creatorJsonLd({ name, url, type = "WebSite" }) {
233
+ return {
234
+ "@context": "https://schema.org",
235
+ "@type": type,
236
+ name,
237
+ url,
238
+ creator: MATTER_ORGANIZATION
239
+ };
240
+ }
241
+ function serializeJsonLd(data) {
242
+ return JSON.stringify(data).replace(/</g, "\\u003c").replace(new RegExp("\\u2028", "g"), "\\u2028").replace(new RegExp("\\u2029", "g"), "\\u2029");
243
+ }
244
+ function creatorJsonLdScript(options) {
245
+ return `<script type="application/ld+json">${serializeJsonLd(creatorJsonLd(options))}</script>`;
246
+ }
247
+ // Annotate the CommonJS export names for ESM import in node:
248
+ 0 && (module.exports = {
249
+ BRAND_NAME,
250
+ CREDIT_CSS,
251
+ LOCALES,
252
+ LOCALE_CODES,
253
+ MATTER_ORGANIZATION,
254
+ MATTER_URL,
255
+ buildCreditUrl,
256
+ creatorJsonLd,
257
+ creatorJsonLdScript,
258
+ normalizeSource,
259
+ renderCreditHTML,
260
+ renderCreditMarkup,
261
+ resolveCredit,
262
+ serializeJsonLd
263
+ });
@@ -0,0 +1,102 @@
1
+ import { C as CreditLocale, a as CreditVariant, b as CreditTheme, c as CreditOptions } from './url-lHz60pDq.cjs';
2
+ export { B as BuildCreditUrlOptions, d as CreditKind, e as CreditSize, f as CreditUtm, M as MATTER_URL, g as buildCreditUrl, n as normalizeSource } from './url-lHz60pDq.cjs';
3
+
4
+ declare const BRAND_NAME = "Matter Development";
5
+ interface LocaleStrings {
6
+ label: string;
7
+ /** Label for `kind: "product"`, on Matter's own products. */
8
+ productLabel: string;
9
+ /** Appended to the accessible name: the link opens a new tab. */
10
+ newTab: string;
11
+ /** Same, for apps: the link leaves the app for the browser. */
12
+ opensBrowser: string;
13
+ dir: "ltr" | "rtl";
14
+ }
15
+ /**
16
+ * The label always sits before the logo, so Chinese, Japanese and Korean use a
17
+ * caption-style noun ("Developer:") rather than their name-first "X 开发" order.
18
+ */
19
+ declare const LOCALES: Record<CreditLocale, LocaleStrings>;
20
+ declare const LOCALE_CODES: CreditLocale[];
21
+
22
+ /** Everything a renderer needs, resolved once so React, HTML and the custom element can't drift. */
23
+ interface CreditModel {
24
+ variant: CreditVariant;
25
+ theme: CreditTheme;
26
+ href: string;
27
+ rel: string;
28
+ dir: "ltr" | "rtl";
29
+ /** BCP 47 tag, so browsers pick the right CJK glyphs and screen readers the right voice. */
30
+ lang: CreditLocale;
31
+ /** Visible text; `null` for the `mark` variant, which shows it as a tooltip instead. */
32
+ label: string | null;
33
+ ariaLabel: string;
34
+ title: string | undefined;
35
+ className: string;
36
+ logo: {
37
+ kind: "wordmark" | "mark";
38
+ width: number;
39
+ height: number;
40
+ };
41
+ labelSize: number;
42
+ iconSize: number;
43
+ }
44
+ /** `native` switches the default `utm_medium` to `app_credit` and the a11y hint to "opens in your browser". */
45
+ type CreditPlatform = "web" | "native";
46
+ declare function resolveCredit(options?: CreditOptions, platform?: CreditPlatform): CreditModel;
47
+
48
+ /**
49
+ * One stylesheet for every web renderer. Notes on the less obvious rules:
50
+ *
51
+ * - `.mdc.mdc` doubles specificity so host rules like `.footer a { color }`
52
+ * (0,1,1) don't recolour, underline or re-font the badge.
53
+ * - `color: var(--matter-credit-color)` with no fallback is invalid at
54
+ * computed-value time when unset, which makes `color` inherit — exactly the
55
+ * `inherit` theme, while still beating the UA's blue link colour.
56
+ * - The logo is a mask painted with `currentColor`, so one asset fits any theme.
57
+ * The hover sheen is a second, moving gradient mask intersected with the logo,
58
+ * which dims a band of the logo whatever its ink colour.
59
+ * - Arabic is a joined script: letter-spacing and monospace both break it.
60
+ */
61
+ declare const CREDIT_CSS: string;
62
+
63
+ /** The badge's `<a>` element only — no styles. Pair with `CREDIT_CSS`. */
64
+ declare function renderCreditMarkup(model: CreditModel): string;
65
+ /**
66
+ * The complete badge as an HTML string with its styles: zero JavaScript, made for
67
+ * server rendering. In Astro: `<Fragment set:html={renderCreditHTML({ source: "optimo" })} />`.
68
+ */
69
+ declare function renderCreditHTML(options: CreditOptions & {
70
+ source: string;
71
+ }): string;
72
+
73
+ /** schema.org node for Matter. Add it as `creator` to a JSON-LD block the site already has. */
74
+ declare const MATTER_ORGANIZATION: {
75
+ readonly "@type": "Organization";
76
+ readonly name: "Matter Development";
77
+ readonly url: "https://matterdevelopment.com/";
78
+ };
79
+ interface CreatorJsonLdOptions {
80
+ /** The client site or app name, e.g. "Optimo". */
81
+ name: string;
82
+ /** Its canonical URL. */
83
+ url: string;
84
+ type?: "WebSite" | "WebApplication" | "SoftwareApplication";
85
+ }
86
+ /** A standalone JSON-LD node saying Matter Development built this site. */
87
+ declare function creatorJsonLd({ name, url, type }: CreatorJsonLdOptions): {
88
+ "@context": string;
89
+ "@type": "WebSite" | "WebApplication" | "SoftwareApplication";
90
+ name: string;
91
+ url: string;
92
+ creator: {
93
+ readonly "@type": "Organization";
94
+ readonly name: "Matter Development";
95
+ readonly url: "https://matterdevelopment.com/";
96
+ };
97
+ };
98
+ /** `JSON.stringify` that is safe inside a `<script>`: no `</script>` breakout. */
99
+ declare function serializeJsonLd(data: unknown): string;
100
+ declare function creatorJsonLdScript(options: CreatorJsonLdOptions): string;
101
+
102
+ export { BRAND_NAME, CREDIT_CSS, type CreatorJsonLdOptions, CreditLocale, type CreditModel, CreditOptions, type CreditPlatform, CreditTheme, CreditVariant, LOCALES, LOCALE_CODES, MATTER_ORGANIZATION, creatorJsonLd, creatorJsonLdScript, renderCreditHTML, renderCreditMarkup, resolveCredit, serializeJsonLd };
@@ -0,0 +1,102 @@
1
+ import { C as CreditLocale, a as CreditVariant, b as CreditTheme, c as CreditOptions } from './url-lHz60pDq.js';
2
+ export { B as BuildCreditUrlOptions, d as CreditKind, e as CreditSize, f as CreditUtm, M as MATTER_URL, g as buildCreditUrl, n as normalizeSource } from './url-lHz60pDq.js';
3
+
4
+ declare const BRAND_NAME = "Matter Development";
5
+ interface LocaleStrings {
6
+ label: string;
7
+ /** Label for `kind: "product"`, on Matter's own products. */
8
+ productLabel: string;
9
+ /** Appended to the accessible name: the link opens a new tab. */
10
+ newTab: string;
11
+ /** Same, for apps: the link leaves the app for the browser. */
12
+ opensBrowser: string;
13
+ dir: "ltr" | "rtl";
14
+ }
15
+ /**
16
+ * The label always sits before the logo, so Chinese, Japanese and Korean use a
17
+ * caption-style noun ("Developer:") rather than their name-first "X 开发" order.
18
+ */
19
+ declare const LOCALES: Record<CreditLocale, LocaleStrings>;
20
+ declare const LOCALE_CODES: CreditLocale[];
21
+
22
+ /** Everything a renderer needs, resolved once so React, HTML and the custom element can't drift. */
23
+ interface CreditModel {
24
+ variant: CreditVariant;
25
+ theme: CreditTheme;
26
+ href: string;
27
+ rel: string;
28
+ dir: "ltr" | "rtl";
29
+ /** BCP 47 tag, so browsers pick the right CJK glyphs and screen readers the right voice. */
30
+ lang: CreditLocale;
31
+ /** Visible text; `null` for the `mark` variant, which shows it as a tooltip instead. */
32
+ label: string | null;
33
+ ariaLabel: string;
34
+ title: string | undefined;
35
+ className: string;
36
+ logo: {
37
+ kind: "wordmark" | "mark";
38
+ width: number;
39
+ height: number;
40
+ };
41
+ labelSize: number;
42
+ iconSize: number;
43
+ }
44
+ /** `native` switches the default `utm_medium` to `app_credit` and the a11y hint to "opens in your browser". */
45
+ type CreditPlatform = "web" | "native";
46
+ declare function resolveCredit(options?: CreditOptions, platform?: CreditPlatform): CreditModel;
47
+
48
+ /**
49
+ * One stylesheet for every web renderer. Notes on the less obvious rules:
50
+ *
51
+ * - `.mdc.mdc` doubles specificity so host rules like `.footer a { color }`
52
+ * (0,1,1) don't recolour, underline or re-font the badge.
53
+ * - `color: var(--matter-credit-color)` with no fallback is invalid at
54
+ * computed-value time when unset, which makes `color` inherit — exactly the
55
+ * `inherit` theme, while still beating the UA's blue link colour.
56
+ * - The logo is a mask painted with `currentColor`, so one asset fits any theme.
57
+ * The hover sheen is a second, moving gradient mask intersected with the logo,
58
+ * which dims a band of the logo whatever its ink colour.
59
+ * - Arabic is a joined script: letter-spacing and monospace both break it.
60
+ */
61
+ declare const CREDIT_CSS: string;
62
+
63
+ /** The badge's `<a>` element only — no styles. Pair with `CREDIT_CSS`. */
64
+ declare function renderCreditMarkup(model: CreditModel): string;
65
+ /**
66
+ * The complete badge as an HTML string with its styles: zero JavaScript, made for
67
+ * server rendering. In Astro: `<Fragment set:html={renderCreditHTML({ source: "optimo" })} />`.
68
+ */
69
+ declare function renderCreditHTML(options: CreditOptions & {
70
+ source: string;
71
+ }): string;
72
+
73
+ /** schema.org node for Matter. Add it as `creator` to a JSON-LD block the site already has. */
74
+ declare const MATTER_ORGANIZATION: {
75
+ readonly "@type": "Organization";
76
+ readonly name: "Matter Development";
77
+ readonly url: "https://matterdevelopment.com/";
78
+ };
79
+ interface CreatorJsonLdOptions {
80
+ /** The client site or app name, e.g. "Optimo". */
81
+ name: string;
82
+ /** Its canonical URL. */
83
+ url: string;
84
+ type?: "WebSite" | "WebApplication" | "SoftwareApplication";
85
+ }
86
+ /** A standalone JSON-LD node saying Matter Development built this site. */
87
+ declare function creatorJsonLd({ name, url, type }: CreatorJsonLdOptions): {
88
+ "@context": string;
89
+ "@type": "WebSite" | "WebApplication" | "SoftwareApplication";
90
+ name: string;
91
+ url: string;
92
+ creator: {
93
+ readonly "@type": "Organization";
94
+ readonly name: "Matter Development";
95
+ readonly url: "https://matterdevelopment.com/";
96
+ };
97
+ };
98
+ /** `JSON.stringify` that is safe inside a `<script>`: no `</script>` breakout. */
99
+ declare function serializeJsonLd(data: unknown): string;
100
+ declare function creatorJsonLdScript(options: CreatorJsonLdOptions): string;
101
+
102
+ export { BRAND_NAME, CREDIT_CSS, type CreatorJsonLdOptions, CreditLocale, type CreditModel, CreditOptions, type CreditPlatform, CreditTheme, CreditVariant, LOCALES, LOCALE_CODES, MATTER_ORGANIZATION, creatorJsonLd, creatorJsonLdScript, renderCreditHTML, renderCreditMarkup, resolveCredit, serializeJsonLd };
package/dist/index.js ADDED
@@ -0,0 +1,52 @@
1
+ import {
2
+ CREDIT_CSS,
3
+ renderCreditHTML,
4
+ renderCreditMarkup
5
+ } from "./chunk-E2CTYJ6I.js";
6
+ import {
7
+ BRAND_NAME,
8
+ LOCALES,
9
+ LOCALE_CODES,
10
+ MATTER_URL,
11
+ buildCreditUrl,
12
+ normalizeSource,
13
+ resolveCredit
14
+ } from "./chunk-N6BHBXMD.js";
15
+
16
+ // src/core/jsonld.ts
17
+ var MATTER_ORGANIZATION = {
18
+ "@type": "Organization",
19
+ name: BRAND_NAME,
20
+ url: MATTER_URL
21
+ };
22
+ function creatorJsonLd({ name, url, type = "WebSite" }) {
23
+ return {
24
+ "@context": "https://schema.org",
25
+ "@type": type,
26
+ name,
27
+ url,
28
+ creator: MATTER_ORGANIZATION
29
+ };
30
+ }
31
+ function serializeJsonLd(data) {
32
+ return JSON.stringify(data).replace(/</g, "\\u003c").replace(new RegExp("\\u2028", "g"), "\\u2028").replace(new RegExp("\\u2029", "g"), "\\u2029");
33
+ }
34
+ function creatorJsonLdScript(options) {
35
+ return `<script type="application/ld+json">${serializeJsonLd(creatorJsonLd(options))}</script>`;
36
+ }
37
+ export {
38
+ BRAND_NAME,
39
+ CREDIT_CSS,
40
+ LOCALES,
41
+ LOCALE_CODES,
42
+ MATTER_ORGANIZATION,
43
+ MATTER_URL,
44
+ buildCreditUrl,
45
+ creatorJsonLd,
46
+ creatorJsonLdScript,
47
+ normalizeSource,
48
+ renderCreditHTML,
49
+ renderCreditMarkup,
50
+ resolveCredit,
51
+ serializeJsonLd
52
+ };