2
0

Version 1

This commit is contained in:
MangoPig
2026-06-23 18:50:37 +01:00
commit 55d9772272
133 changed files with 21515 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
FAVICON PACKAGE FOR: Royal-Pop-Accesory
Generated by ConvertICO.com - Favicon Package Generator
============================================================
CONTENTS:
---------
- favicon.ico Multi-size ICO (16x16, 32x32, 48x48)
- favicon-16x16.png Browser tab favicon
- favicon-32x32.png High-DPI browser favicon
- favicon-48x48.png Windows site icon
- apple-touch-icon.png iOS home screen (180x180)
- apple-touch-icon-152x152.png iPad
- apple-touch-icon-120x120.png iPhone
- apple-touch-icon-76x76.png iPad mini
- android-chrome-192x192.png Android home screen
- android-chrome-512x512.png Android splash screen
- mstile-150x150.png Windows tile
- mstile-310x310.png Windows large tile
- site.webmanifest Web app manifest (Android PWA)
- browserconfig.xml Microsoft browser config
INSTALLATION:
-------------
1. Upload all files to your website's /favicon directory.
2. Add this code to your HTML <head> section:
<link rel="icon" type="image/x-icon" href="/favicon/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png">
<link rel="manifest" href="/favicon/site.webmanifest">
<meta name="msapplication-TileColor" content="#e9e9e9">
<meta name="theme-color" content="#e9e9e9">
NOTES:
------
- This project serves all favicon assets from /favicon for cleaner public asset organization
- Modern browsers prefer PNG favicons but ICO provides legacy support
- site.webmanifest enables 'Add to Home Screen' on Android
- browserconfig.xml enables Windows Start menu tiles
Need more sizes or formats? Visit https://convertico.com for more tools!
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/favicon/mstile-150x150.png"/>
<square310x310logo src="/favicon/mstile-310x310.png"/>
<TileColor>#e9e9e9</TileColor>
</tile>
</msapplication>
</browserconfig>
Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

+19
View File
@@ -0,0 +1,19 @@
{
"name": "Royal-Pop-Accesory",
"short_name": "Royal-Pop-Accesory",
"icons": [
{
"src": "/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/favicon/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#e9e9e9",
"background_color": "#ffffff",
"display": "standalone"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

+4
View File
@@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://royal-pop-accessory.com/sitemap.xml
+190
View File
@@ -0,0 +1,190 @@
(function () {
const ROYAL_POP_CART_KEY = "royal-pop-cart";
const ROYAL_POP_BUILDER_KEY = "royal-pop-builder-selection";
const ROYAL_POP_CART_LIMIT = Number.POSITIVE_INFINITY;
const isBrowser = () => typeof window !== "undefined" && typeof window.localStorage !== "undefined";
const readJson = (key, fallback) => {
if (!isBrowser()) return fallback;
try {
const raw = window.localStorage.getItem(key);
if (!raw) return fallback;
return JSON.parse(raw);
} catch {
return fallback;
}
};
const writeJson = (key, value) => {
if (!isBrowser()) return;
try {
window.localStorage.setItem(key, JSON.stringify(value));
} catch {
// Ignore storage write failures.
}
};
const createItemId = () => {
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
return crypto.randomUUID();
}
return `rp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
};
const normalizeSelection = (selection) => ({
style: selection && selection.style === "A" ? "A" : "B",
colorwayId: (selection && selection.colorwayId) || "sorbet-pop-multi-color",
finishId: (selection && selection.finishId) || "silver",
quantity: Math.max(1, Math.round(Number(selection && selection.quantity) || 1)),
});
const loadBuilderSelection = () => {
const selection = readJson(ROYAL_POP_BUILDER_KEY, null);
if (!selection) return null;
return normalizeSelection(selection);
};
const saveBuilderSelection = (selection) => {
writeJson(ROYAL_POP_BUILDER_KEY, normalizeSelection(selection));
};
const loadCart = () => {
const items = readJson(ROYAL_POP_CART_KEY, []);
return items
.filter((item) => item && item.colorwayId && item.finishId)
.map((item) => ({
id: item.id || createItemId(),
style: item.style === "A" ? "A" : "B",
colorwayId: String(item.colorwayId),
finishId: String(item.finishId),
quantity: Math.max(1, Math.round(Number(item.quantity) || 1)),
}))
;
};
const saveCart = (items) => {
writeJson(
ROYAL_POP_CART_KEY,
items.map((item) => ({
...item,
quantity: Math.max(1, Math.round(Number(item.quantity) || 1)),
})),
);
};
const getCartCount = () => loadCart().reduce((sum, item) => sum + Math.max(1, Number(item.quantity) || 1), 0);
const addSelectionToCart = (selection) => {
const normalized = normalizeSelection(selection || {});
const currentCart = loadCart();
const matchingIndex = currentCart.findIndex(
(item) =>
item.style === normalized.style &&
item.colorwayId === normalized.colorwayId &&
item.finishId === normalized.finishId,
);
let nextCart;
if (matchingIndex >= 0) {
nextCart = currentCart.map((item, index) =>
index === matchingIndex
? {
...item,
quantity: Math.max(1, Number(item.quantity) || 1) + normalized.quantity,
}
: item,
);
} else {
nextCart = [
...currentCart,
{
id: createItemId(),
style: normalized.style,
colorwayId: normalized.colorwayId,
finishId: normalized.finishId,
quantity: normalized.quantity,
},
];
}
saveCart(nextCart);
return {
cart: nextCart,
addedCount: normalized.quantity,
isFull: false,
};
};
const removeCartItem = (itemId) => {
const currentCart = loadCart();
const nextCart = currentCart.filter((item) => item.id !== itemId);
saveCart(nextCart);
return nextCart;
};
const getEffectiveCart = () => {
const cart = loadCart();
if (cart.length > 0) return cart;
const selection = loadBuilderSelection();
if (!selection) return [];
return [{
id: createItemId(),
style: selection.style,
colorwayId: selection.colorwayId,
finishId: selection.finishId,
quantity: selection.quantity,
}];
};
const groupCartItems = (items) => {
const groups = new Map();
(items || []).forEach((item) => {
const key = `${item.style}::${item.colorwayId}::${item.finishId}`;
const current = groups.get(key);
const itemQuantity = Math.max(1, Math.round(Number(item.quantity) || 1));
if (current) {
current.quantity += itemQuantity;
return;
}
groups.set(key, {
style: item.style,
colorwayId: item.colorwayId,
finishId: item.finishId,
quantity: itemQuantity,
});
});
return Array.from(groups.values());
};
const clearCart = () => {
if (!isBrowser()) return;
window.localStorage.removeItem(ROYAL_POP_CART_KEY);
};
window.RoyalPopCart = {
ROYAL_POP_CART_KEY,
ROYAL_POP_BUILDER_KEY,
ROYAL_POP_CART_LIMIT,
loadBuilderSelection,
saveBuilderSelection,
loadCart,
saveCart,
getCartCount,
addSelectionToCart,
removeCartItem,
getEffectiveCart,
groupCartItems,
clearCart,
};
})();
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://royal-pop-accessory.com/</loc>
</url>
<url>
<loc>https://royal-pop-accessory.com/buy</loc>
</url>
</urlset>