perf(site): inline small classic icons and favicon as base64
- New src/lib/site-icons.ts: base64 data URIs for the 13 tiny classic icons actually referenced in markup (100–2000 bytes), replacing extra requests with inline payloads. home.png, dynamic flags and currency sets stay on the filesystem. - Default favicon is now served server-side as a base64 SVG data URI (memoized), while a DB-configured custom favicon still takes priority. - Icons render through <Image unoptimized>, so data URIs pass through untouched on all affected pages (home, login, register, settings, navigation, auth top bar, client loading).
This commit is contained in:
1 parent
97012a78f6
commit
e5e17d75ae
10 files changed
+128
-64
No files matched your search
@@ -12,6 +12,7 @@ import { db, User } from "@/lib/db";
|
||||
import { resolveHotelName } from "@/lib/hotel-name";
|
||||
import { captchaConfig } from "@/lib/services/captcha";
|
||||
import { siteSettings } from "@/lib/services/site-settings";
|
||||
import { ICON_FRIENDS, ICON_NAV_GOODY, ICON_NAV_ME } from "@/lib/site-icons";
|
||||
|
||||
export default async function LoginPage() {
|
||||
const t = await getTranslations("pages.login");
|
||||
@@ -117,7 +118,7 @@ export default async function LoginPage() {
|
||||
{recentUsers.length > 0 && (
|
||||
<SurfaceCard
|
||||
title={th("online", { count: online, hotel: "" }).trim()}
|
||||
icon="/assets/images/icons/navigation/goody.png"
|
||||
icon={ICON_NAV_GOODY}
|
||||
bodyClassName="p-4"
|
||||
className="card-glow"
|
||||
>
|
||||
@@ -154,7 +155,7 @@ export default async function LoginPage() {
|
||||
{latestUsers.length > 0 && (
|
||||
<SurfaceCard
|
||||
title="Newest citizens"
|
||||
icon="/assets/images/icons/friends.png"
|
||||
icon={ICON_FRIENDS}
|
||||
bodyClassName="p-4"
|
||||
className="card-glow"
|
||||
>
|
||||
@@ -193,7 +194,7 @@ export default async function LoginPage() {
|
||||
<div className="flex-1">
|
||||
<SurfaceCard
|
||||
title={t("title")}
|
||||
icon="/assets/images/icons/navigation/me.png"
|
||||
icon={ICON_NAV_ME}
|
||||
bodyClassName="p-6 sm:p-7"
|
||||
>
|
||||
<p
|
||||
|
||||
+21
-15
@@ -6,6 +6,15 @@ import { redirect } from "next/navigation";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { PublicLoadError } from "@/components/public/load-error";
|
||||
import { publicReadFailure } from "@/lib/services/public-read";
|
||||
import {
|
||||
ICON_ARTICLE,
|
||||
ICON_CAMERA,
|
||||
ICON_CATALOG,
|
||||
ICON_FRIENDS,
|
||||
ICON_LIGHTHOUSE,
|
||||
ICON_NAV_GOODY,
|
||||
ICON_NAV_ME,
|
||||
} from "@/lib/site-icons";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Home",
|
||||
@@ -124,17 +133,17 @@ export default async function Home() {
|
||||
{
|
||||
title: tp("featuresAvatar"),
|
||||
desc: tp("featuresAvatarDesc"),
|
||||
icon: "/assets/images/icons/friends.png",
|
||||
icon: ICON_FRIENDS,
|
||||
},
|
||||
{
|
||||
title: tp("featuresFurniture"),
|
||||
desc: tp("featuresFurnitureDesc"),
|
||||
icon: "/assets/images/icons/catalog.png",
|
||||
icon: ICON_CATALOG,
|
||||
},
|
||||
{
|
||||
title: tp("featuresCommunity"),
|
||||
desc: tp("featuresCommunityDesc"),
|
||||
icon: "/assets/images/icons/navigation/goody.png",
|
||||
icon: ICON_NAV_GOODY,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -168,7 +177,7 @@ export default async function Home() {
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
src="/assets/images/icons/lighthouse.png"
|
||||
src={ICON_LIGHTHOUSE}
|
||||
alt={hotelName}
|
||||
width={28}
|
||||
height={28}
|
||||
@@ -393,25 +402,25 @@ export default async function Home() {
|
||||
{
|
||||
value: users,
|
||||
label: tp("statsCitizens"),
|
||||
icon: "/assets/images/icons/friends.png",
|
||||
icon: ICON_FRIENDS,
|
||||
live: false,
|
||||
},
|
||||
{
|
||||
value: rooms,
|
||||
label: tp("statsRooms"),
|
||||
icon: "/assets/images/icons/catalog.png",
|
||||
icon: ICON_CATALOG,
|
||||
live: false,
|
||||
},
|
||||
{
|
||||
value: online,
|
||||
label: tp("statsOnline"),
|
||||
icon: "/assets/images/icons/navigation/me.png",
|
||||
icon: ICON_NAV_ME,
|
||||
live: true,
|
||||
},
|
||||
{
|
||||
value: articles?.length ?? null,
|
||||
label: tp("statsArticles"),
|
||||
icon: "/assets/images/icons/article.gif",
|
||||
icon: ICON_ARTICLE,
|
||||
live: false,
|
||||
},
|
||||
].map((s) => (
|
||||
@@ -458,7 +467,7 @@ export default async function Home() {
|
||||
<Reveal className="flex w-full flex-col gap-4 md:w-1/3 md:flex-shrink-0">
|
||||
<SurfaceCard
|
||||
title={th("login")}
|
||||
icon="/assets/images/icons/navigation/me.png"
|
||||
icon={ICON_NAV_ME}
|
||||
bodyClassName="p-3.5 sm:p-4"
|
||||
>
|
||||
<HomeLoginForm
|
||||
@@ -479,7 +488,7 @@ export default async function Home() {
|
||||
recentUsers.length > 0 && (
|
||||
<SurfaceCard
|
||||
title={tp("recentUsers")}
|
||||
icon="/assets/images/icons/navigation/goody.png"
|
||||
icon={ICON_NAV_GOODY}
|
||||
actionHref="/community"
|
||||
actionLabel={tp("allUsers")}
|
||||
bodyClassName="p-3.5 sm:p-4"
|
||||
@@ -514,7 +523,7 @@ export default async function Home() {
|
||||
<Reveal delay={0.15} className="flex w-full flex-col gap-4 md:w-2/3">
|
||||
<SurfaceCard
|
||||
title={tp("latestNews")}
|
||||
icon="/assets/images/icons/article.gif"
|
||||
icon={ICON_ARTICLE}
|
||||
actionHref="/news"
|
||||
actionLabel={tp("allNews")}
|
||||
>
|
||||
@@ -588,10 +597,7 @@ export default async function Home() {
|
||||
) : (
|
||||
recentPhotos.length > 0 && (
|
||||
<Reveal>
|
||||
<SurfaceCard
|
||||
title={tp("recentPhotos")}
|
||||
icon="/assets/images/icons/camera.png"
|
||||
>
|
||||
<SurfaceCard title={tp("recentPhotos")} icon={ICON_CAMERA}>
|
||||
<div className="mx-auto grid max-w-md grid-cols-4 gap-2">
|
||||
{recentPhotos.slice(0, 4).map((p) => (
|
||||
<Link
|
||||
|
||||
@@ -12,6 +12,7 @@ import { db, User } from "@/lib/db";
|
||||
import { resolveHotelName } from "@/lib/hotel-name";
|
||||
import { captchaConfig } from "@/lib/services/captcha";
|
||||
import { siteSettings } from "@/lib/services/site-settings";
|
||||
import { ICON_FRIENDS, ICON_NAV_GOODY, ICON_NAV_ME } from "@/lib/site-icons";
|
||||
|
||||
export default async function RegisterPage() {
|
||||
const tpr = await getTranslations("pages.register");
|
||||
@@ -126,7 +127,7 @@ export default async function RegisterPage() {
|
||||
{recentUsers.length > 0 && (
|
||||
<SurfaceCard
|
||||
title={tpr("whoIsOnline")}
|
||||
icon="/assets/images/icons/navigation/goody.png"
|
||||
icon={ICON_NAV_GOODY}
|
||||
bodyClassName="p-4"
|
||||
className="card-glow"
|
||||
>
|
||||
@@ -163,7 +164,7 @@ export default async function RegisterPage() {
|
||||
{latestUsers.length > 0 && (
|
||||
<SurfaceCard
|
||||
title="Newest citizens"
|
||||
icon="/assets/images/icons/friends.png"
|
||||
icon={ICON_FRIENDS}
|
||||
bodyClassName="p-4"
|
||||
className="card-glow"
|
||||
>
|
||||
@@ -202,7 +203,7 @@ export default async function RegisterPage() {
|
||||
<div className="flex-1 lg:sticky lg:top-6">
|
||||
<SurfaceCard
|
||||
title={tpr("title")}
|
||||
icon="/assets/images/icons/navigation/me.png"
|
||||
icon={ICON_NAV_ME}
|
||||
bodyClassName="p-6 sm:p-7"
|
||||
>
|
||||
<p
|
||||
|
||||
@@ -9,7 +9,12 @@ import { SurfaceCard } from "@/components/surface-card";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { db, User } from "@/lib/db";
|
||||
import { avatarImageUrl } from "@/lib/format";
|
||||
|
||||
import {
|
||||
ICON_NAV_COMMUNITY,
|
||||
ICON_NAV_GOODY,
|
||||
ICON_NAV_ME,
|
||||
ICON_STAR,
|
||||
} from "@/lib/site-icons";
|
||||
import ProfilePrivacySettings from "./ProfilePrivacySettings";
|
||||
export default async function SettingsPage({
|
||||
searchParams,
|
||||
@@ -74,7 +79,7 @@ export default async function SettingsPage({
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/me.png"
|
||||
src={ICON_NAV_ME}
|
||||
alt=""
|
||||
width={22}
|
||||
height={22}
|
||||
@@ -106,7 +111,7 @@ export default async function SettingsPage({
|
||||
<Reveal delay={0.05}>
|
||||
<SurfaceCard
|
||||
title={t("publicProfile")}
|
||||
icon="/assets/images/icons/navigation/me.png"
|
||||
icon={ICON_NAV_ME}
|
||||
bodyClassName="p-5 flex flex-col sm:flex-row items-center sm:items-center gap-5"
|
||||
>
|
||||
<div className="shrink-0">
|
||||
@@ -161,7 +166,7 @@ export default async function SettingsPage({
|
||||
<Reveal delay={0.1}>
|
||||
<SurfaceCard
|
||||
title={t("changeMotto")}
|
||||
icon="/assets/images/icons/star.gif"
|
||||
icon={ICON_STAR}
|
||||
bodyClassName="p-5"
|
||||
>
|
||||
<p
|
||||
@@ -211,7 +216,7 @@ export default async function SettingsPage({
|
||||
<Reveal delay={0.15}>
|
||||
<SurfaceCard
|
||||
title={t("securityTitle")}
|
||||
icon="/assets/images/icons/navigation/goody.png"
|
||||
icon={ICON_NAV_GOODY}
|
||||
bodyClassName="p-5"
|
||||
>
|
||||
<p
|
||||
@@ -253,7 +258,7 @@ export default async function SettingsPage({
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/community.png"
|
||||
src={ICON_NAV_COMMUNITY}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Image from "next/image";
|
||||
import { ICON_LIGHTHOUSE } from "@/lib/site-icons";
|
||||
|
||||
export default function ClientLoading() {
|
||||
return (
|
||||
@@ -27,7 +28,7 @@ export default function ClientLoading() {
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src="/assets/images/icons/lighthouse.png"
|
||||
src={ICON_LIGHTHOUSE}
|
||||
alt=""
|
||||
width={44}
|
||||
height={44}
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ import { ScopedThemeVars } from "@/components/scoped-theme-vars";
|
||||
import { ThemeScopeDetector } from "@/components/theme-scope-detector";
|
||||
import { ThemeVars } from "@/components/theme-vars";
|
||||
import { enforceSiteAccess } from "@/lib/access-guard";
|
||||
import { getDefaultFaviconDataUri } from "@/lib/default-favicon";
|
||||
import { resolveHotelName } from "@/lib/hotel-name";
|
||||
import { siteSettings } from "@/lib/services/site-settings";
|
||||
import "./globals.css";
|
||||
@@ -40,7 +41,7 @@ export async function generateMetadata(): Promise<Metadata> {
|
||||
const appUrl = process.env.APP_URL ?? "http://localhost:3000";
|
||||
const hotel = await resolveHotelName();
|
||||
const customFavicon = await siteSettings.get("cms_favicon");
|
||||
const faviconUrl = customFavicon ?? "/favicon.svg";
|
||||
const faviconUrl = customFavicon ?? getDefaultFaviconDataUri();
|
||||
const icons = [
|
||||
{ rel: "icon", url: faviconUrl },
|
||||
{ rel: "shortcut icon", url: faviconUrl },
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Clock } from "@/components/clock";
|
||||
import { LanguageSwitcher } from "@/components/language-switcher";
|
||||
import { Reveal } from "@/components/motion-reveal";
|
||||
import { ThemeSwitcher } from "@/components/theme-switcher";
|
||||
import { ICON_LIGHTHOUSE } from "@/lib/site-icons";
|
||||
|
||||
/**
|
||||
* Shared frosted-glass top bar for the public auth pages (login, register,
|
||||
@@ -47,7 +48,7 @@ export function AuthTopBar({
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
src="/assets/images/icons/lighthouse.png"
|
||||
src={ICON_LIGHTHOUSE}
|
||||
alt={hotelName}
|
||||
width={28}
|
||||
height={28}
|
||||
|
||||
@@ -12,6 +12,15 @@ import { db, MessengerFriendrequests, MessengerOffline } from "@/lib/db";
|
||||
import { resolveHotelName } from "@/lib/hotel-name";
|
||||
import { canAccess, getApiAdminContext, PERMS } from "@/lib/permissions";
|
||||
import { logServerError } from "@/lib/server-log";
|
||||
import {
|
||||
ICON_NAV_BB,
|
||||
ICON_NAV_COMMUNITY,
|
||||
ICON_NAV_GOODY,
|
||||
ICON_NAV_LEADERBOARDS,
|
||||
ICON_NAV_ME,
|
||||
ICON_NAV_RULES,
|
||||
ICON_NAV_SHOP,
|
||||
} from "@/lib/site-icons";
|
||||
|
||||
export async function Navigation({ session }: { session: Session | null }) {
|
||||
const t = await getTranslations("nav");
|
||||
@@ -81,7 +90,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
<div className="hidden md:flex items-center gap-x-1">
|
||||
<Link href="/" className="nav-item shrink-0">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/me.png"
|
||||
src={ICON_NAV_ME}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -93,10 +102,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
|
||||
{/* Desktop: nav items */}
|
||||
<div className="hidden md:flex items-center gap-x-1">
|
||||
<NavDropdown
|
||||
label={t("community")}
|
||||
icon="/assets/images/icons/navigation/community.png"
|
||||
>
|
||||
<NavDropdown label={t("community")} icon={ICON_NAV_COMMUNITY}>
|
||||
<Link href="/news" className="dropdown-item" role="menuitem">
|
||||
{t("articles")}
|
||||
</Link>
|
||||
@@ -120,10 +126,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
</Link>
|
||||
</NavDropdown>
|
||||
|
||||
<NavDropdown
|
||||
label={t("shop")}
|
||||
icon="/assets/images/icons/navigation/shop.png"
|
||||
>
|
||||
<NavDropdown label={t("shop")} icon={ICON_NAV_SHOP}>
|
||||
<Link href="/shop" className="dropdown-item" role="menuitem">
|
||||
{t("shop")}
|
||||
</Link>
|
||||
@@ -137,7 +140,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
|
||||
<Link href="/leaderboard" className="nav-item">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/leaderboards.png"
|
||||
src={ICON_NAV_LEADERBOARDS}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -148,7 +151,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
|
||||
<Link href="/radio" className="nav-item">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/bb.png"
|
||||
src={ICON_NAV_BB}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -157,10 +160,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
{t("radio")}
|
||||
</Link>
|
||||
|
||||
<NavDropdown
|
||||
label={t("assistance")}
|
||||
icon="/assets/images/icons/navigation/rules.gif"
|
||||
>
|
||||
<NavDropdown label={t("assistance")} icon={ICON_NAV_RULES}>
|
||||
<Link href="/help" className="dropdown-item" role="menuitem">
|
||||
{t("helpCenter")}
|
||||
</Link>
|
||||
@@ -185,7 +185,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
<>
|
||||
<Link href="/friends" className="nav-item relative">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/goody.png"
|
||||
src={ICON_NAV_GOODY}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -195,7 +195,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
</Link>
|
||||
<Link href="/messages" className="nav-item relative">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/bb.png"
|
||||
src={ICON_NAV_BB}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -292,7 +292,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
>
|
||||
<Link href="/" className="nav-item">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/me.png"
|
||||
src={ICON_NAV_ME}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -301,10 +301,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
{t("home")}
|
||||
</Link>
|
||||
|
||||
<NavDropdown
|
||||
label={t("community")}
|
||||
icon="/assets/images/icons/navigation/community.png"
|
||||
>
|
||||
<NavDropdown label={t("community")} icon={ICON_NAV_COMMUNITY}>
|
||||
<Link href="/news" className="dropdown-item" role="menuitem">
|
||||
{t("articles")}
|
||||
</Link>
|
||||
@@ -328,10 +325,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
</Link>
|
||||
</NavDropdown>
|
||||
|
||||
<NavDropdown
|
||||
label={t("shop")}
|
||||
icon="/assets/images/icons/navigation/shop.png"
|
||||
>
|
||||
<NavDropdown label={t("shop")} icon={ICON_NAV_SHOP}>
|
||||
<Link href="/shop" className="dropdown-item" role="menuitem">
|
||||
{t("shop")}
|
||||
</Link>
|
||||
@@ -345,7 +339,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
|
||||
<Link href="/leaderboard" className="nav-item">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/leaderboards.png"
|
||||
src={ICON_NAV_LEADERBOARDS}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -356,7 +350,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
|
||||
<Link href="/radio" className="nav-item">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/bb.png"
|
||||
src={ICON_NAV_BB}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -365,10 +359,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
{t("radio")}
|
||||
</Link>
|
||||
|
||||
<NavDropdown
|
||||
label={t("assistance")}
|
||||
icon="/assets/images/icons/navigation/rules.gif"
|
||||
>
|
||||
<NavDropdown label={t("assistance")} icon={ICON_NAV_RULES}>
|
||||
<Link href="/help" className="dropdown-item" role="menuitem">
|
||||
{t("helpCenter")}
|
||||
</Link>
|
||||
@@ -393,7 +384,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
<>
|
||||
<Link href="/friends" className="nav-item">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/goody.png"
|
||||
src={ICON_NAV_GOODY}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
@@ -403,7 +394,7 @@ export async function Navigation({ session }: { session: Session | null }) {
|
||||
</Link>
|
||||
<Link href="/messages" className="nav-item">
|
||||
<Image
|
||||
src="/assets/images/icons/navigation/bb.png"
|
||||
src={ICON_NAV_BB}
|
||||
alt=""
|
||||
width={20}
|
||||
height={20}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
let cached: string | null = null;
|
||||
|
||||
/**
|
||||
* The bundled default favicon (public/favicon.svg) as a base64 data URI.
|
||||
* Read once and memoized; only used when no custom favicon is configured.
|
||||
*/
|
||||
export function getDefaultFaviconDataUri(): string {
|
||||
if (cached) return cached;
|
||||
const raw = readFileSync(join(process.cwd(), "public", "favicon.svg"));
|
||||
cached = `data:image/svg+xml;base64,${raw.toString("base64")}`;
|
||||
return cached;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Base64 data URIs for the small classic icons, generated from public/assets/images/icons.
|
||||
// Inlining avoids extra font-icon requests for tiny assets. home.png and the
|
||||
// dynamic flags/currency icon sets stay on the filesystem.
|
||||
|
||||
export const ICON_FRIENDS =
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAA1BAMAAADBmLQbAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAC1QTFRFAAAAAAAAAAAAyINZ1rNvpVpJdCg1LnmERZunn1NvxG+OLGFphkdebDZKIkNHE9pz0wAAAA90Uk5TADP/////////////////DbIXmAAAAcNJREFUeJyN071KxEAQAODkDW72DXZOCOGwSbwX0LyCTyD4AGn24MDCJlun23A212W5a2xSBCyuU2JjFzGNjYXgMzibv/PWExxICB87uzPDxnGGAICJYwUAcltdwDDgYC1kZ1EUWEthGkXRBT9At8eDfJeFlB4GNpr4D8LUILdxHs5HdKk90yILr68C891VjfSJiJRP707BkxxQxNP55WXgK2ybIkS2kDK+CENf67zdFrxk4Ukpk5PoPMvyLG1xJpMBVzrbpCafMBaULuLIf93qvOYDmiBsaqV+IdkevYevr+LExpvyQUxDv36r6hFRfH7EVGZ91+xXlp4Q1CeiUima6oEtlmJZlkLcP6qGzt9RocAKIRMhpPR1Tge1jQLMCChun6hzpbXeAc2TFR1mGxK90alBOqrDrcGtQcpnv9EdcW32XOtueGbGNOVsXVWratehy7qB/IGrR1WlNlLtysZnKj2/ezpAVWdUkqoPEFWLKe+xLMsi9k3jVOqI759FrHoc0pd8Rnv2Me7JPdrztHnBpsE+fZFwT8bg65RlNOP/4+QITpwfB4GvUqbUgMdW0o2nm8/bB7v73f4fP+NvdCx0jsc3C18noSuk+DIAAAAASUVORK5CYII=";
|
||||
|
||||
export const ICON_LIGHTHOUSE =
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAeCAYAAABNChwpAAAABHNCSVQICAgIfAhkiAAAAZRJREFUSInVVrttwzAQfQ4SILW4gusUKiJu4sYDpPICtisqC6RwMkAazXALyClUZI9THSDFpZAo6B+SkRH4AYIp3+Hx8fR45ArhkN77KoTkJnRyIoKIQERARGOCLgZJjRFmFgtmltQYCRHhWwEhIiRaDwKJ1hevRGfVU2Bmr0r4GKdDulOqE3xhDuL2da587avBXfrUCXwf3gAA989+vKG7YDG4Km3K/1H/Puy7CZ/VyvHoye8sgFvfOIoiAEBZlqPvAKAqj/zKf+soAK+nUzMe24YAcM5zVzp/AYnWiOMYRVEgjuNm1RZ29TbHFddnwqX5vftAasysBw7HoxevswcsrBemPOCLq/EAAMhOKWzrfhBtNp1gmWUAgHel7LngxP3vFfASsB2eeEE5wQIs+uWf+m9JAdI//+dQ5y56MxIiEmaevRXZOBE534quy4QABg3INTYFl706u//78O0Hf/oE6yzDup4wFGMCpPc4r76d0+oHA742+uWR1BgA07cei3OeNznt8Vw+gMFpORAwy7Icmnl/AOPK9CFW1E7aAAAAAElFTkSuQmCC";
|
||||
|
||||
export const ICON_CAMERA =
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAWCAYAAADTlvzyAAAABHNCSVQICAgIfAhkiAAAAF96VFh0UmF3IHByb2ZpbGUgdHlwZSBBUFAxAAAImeNKT81LLcpMVigoyk/LzEnlUgADYxMuE0sTS6NEAwMDCwMIMDQwMDYEkkZAtjlUKNEABZiYm6UBoblZspkpiM8FAE+6FWgbLdiMAAAB8klEQVRIib2WsWvbQBSHv1O8Jg5ZMkkEXHuo63roFJpCaZcSyJB0i8Hdjf3XJGSvwd6aDIXQpaVQh8xpCIQ0hSAtKQHHsuf0Opi7SKc71y3BPxCS7km/T+/dk04CADzJTPRbCPCklHczwQkxR06dRFH0YMZBEKTOwzDE932Ae+BDwh4/W+X52hoAR70eQRAgpfw/YLlSzYydnZ5kxo56Pev9UwMVaHdvxxk7Oz0hDENrSf8JWK5U2d3bob5ds8br2zXa3Q7lSlVDXcrBuHtcms/nNWxhccl53XDQ1w83STmA9c0ta/DwYD8Fe7r60mm0sLikoc1GixevXlv9BHhyfXOLb18+s+yv8Cu60vtRHCPlXQr2duNNxujDx08AfD/+ynDQ15VI+pWKBQ4P9vHUTTbY+047ZWyD2cZVYyX9lHTTJIPL/gqjONvqZkaTHsJMIgM0M/wbaNKYLYlSsQBwX1IzQ1O3N9fc3lxbjV0xm59zDh89qdJstJzmyc1Us9FyVsyZoWqcdrfDcNAnujy3ZqcUXZ4zHPRpdztWPyXnHI4vuuJdrQ6QanebFExVxfRTc6iBpWJBDyb3Fz9+ahP1YtukYOqdM32UBHhyPp+fVK2UbB9v21zbNIpj9Io/7QI87fJkyvd9hJhj5r8YYnw4u5+oP1nbI5NSaqxTAAAAAElFTkSuQmCC";
|
||||
|
||||
export const ICON_STAR =
|
||||
"data:image/gif;base64,R0lGODlhDwAPAKIAAPz8neq/B96IBgAAAP///wAAAAAAAAAAACH5BAEAAAQALAAAAAAPAA8AAANASLo0/GwAB5+kVckwswYcpg3kFoQlCazgebLd4M4zJgt4LgRiE+i7ng/Ig9x2uGIEsOOdBJ2FjOcgnUQlC0mRAAA7";
|
||||
|
||||
export const ICON_ARTICLE =
|
||||
"data:image/gif;base64,R0lGODlhFgAkAKIAAP///6+or5mZmf8A/8wAAGZmZgAAAAAAACH5BAkIAAMALAAAAAAWACQAAAPJOKpm+zA2EFq8Y4ZSqMUMAGic52CGKJJddUJpp7ImLJZzurVfpgKyHKXk8nFkuJWOOLkBVcHRUvp0In8joOsW7Xhlhg0VGsSVYlsAgQythjtN9S/5RMfXhDX39x6r81hAYFpNgHqCbX0TAiqHR0F2KQACjHKCjyNiiyKUZJiRnJWdj2eaKaKVnnCEkp2TjK6lcKehWK5ZBWmunbuMipK1P7eggcGdihnAgcOEC3HGvpowyq8zzRLUM9Io2XYgDMphPd/JSuQX4wMJADs=";
|
||||
|
||||
export const ICON_CATALOG =
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAiCAMAAACUYSJFAAAAMFBMVEXx8fHv7++srKz/AP+neK2QYJbioGX/b2+0cjLMPDxmZmZ7TR9PLw87OzsAAAAAAACHEQfKAAAABHRSTlP///8AQCqp9AAAAAlwSFlzAAALEwAACxMBAJqcGAAABhtpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDkuMC1jMDAwIDc5LjE3MWMyN2YsIDIwMjIvMDgvMTYtMTg6MDI6NDMgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyNC4wIChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjMtMDQtMzBUMjM6MjE6MjArMDI6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIzLTA0LTMwVDIzOjQ5OjIyKzAyOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIzLTA0LTMwVDIzOjQ5OjIyKzAyOjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3YjJjNDU3MS0wM2Q0LTZiNDktODlkMC03MzAxZTYyNDhlYTUiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDpkMzEyYjdlMS01MmM3LTM0NGYtYWEzYi03ODJjNDIzZGRiZmYiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3Mjc5ODljOS05NTdmLWFkNDAtODNkNC01ZDQ4MWIyODNjZTAiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjcyNzk4OWM5LTk1N2YtYWQ0MC04M2Q0LTVkNDgxYjI4M2NlMCIgc3RFdnQ6d2hlbj0iMjAyMy0wNC0zMFQyMzoyMToyMCswMjowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDI0LjAgKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjb252ZXJ0ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImZyb20gaW1hZ2UvZ2lmIHRvIGltYWdlL3BuZyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6N2IyYzQ1NzEtMDNkNC02YjQ5LTg5ZDAtNzMwMWU2MjQ4ZWE1IiBzdEV2dDp3aGVuPSIyMDIzLTA0LTMwVDIzOjQ5OjIyKzAyOjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjQuMCAoV2luZG93cykiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+nGm8igAAARBJREFUKJF1ktuqxCAMRZcxDDOkZ/7/P1uhOGrPg7W1t8AGySI7Juo8GIQ7gQBMD6p0wZarAMEMR3JXmSE2jQzMNxonc9+Rx/hTFsebgqwC4oYFeM8lylyizDMxElFV9QAKS3nJu4oIEV0AfAYFtzthhBXiai3aWLKEEfAtoXUbW5QoRmhYTkOIlJgsP1AQKRu+0j53R/fQ/ZixR5oxUjl5NZqNVIAj1wZTWTM93/uuD4Rw2hWAJ9dHREm6VbTGThURVMPtRAEj9ey4DR/wXdOORo116v28O/vfbyvqzq1v7+frx/gcbgXEV/PMkBkOtPcHhqD0H6f3ZwgojuQ4xyczhOuvA+qdhgC476WuRgD4B7yWfZeQ9k0CAAAAAElFTkSuQmCC";
|
||||
|
||||
export const ICON_NAV_ME =
|
||||
"data:image/png;base64,R0lGODlhFwAWAMQAAP///+jo6KOegZ6env8A/wZ0/P6/fcuRXlRTRS0rJSYmJiQkJBkZGRwaFhMSEA0NDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkIAAQALAAAAAAXABYAAAWWIEFApGieKAoJbJm+YoLMcgLBL5TU5I2rNojBcPD9TD3IweA6IoVCpvMUHRanzyHDOEp6bxDGgqH1QQDotBpAUii2EIUZUKjb7ey42+063/95cnt9a4VtenJzX2xoh3xCImeFal4BAYRfPWwERQMBA0aSk40jlhCgSHmMJGlgpqiRo62llxANc7KbEA8ODQ5cmUlPXFghADs=";
|
||||
|
||||
export const ICON_NAV_COMMUNITY =
|
||||
"data:image/png;base64,R0lGODlhDwAPAKIAAPz8neq/B96IBgAAAP///wAAAAAAAAAAACH5BAEAAAQALAAAAAAPAA8AAANASLo0/GwAB5+kVckwswYcpg3kFoQlCazgebLd4M4zJgt4LgRiE+i7ng/Ig9x2uGIEsOOdBJ2FjOcgnUQlC0mRAAA7";
|
||||
|
||||
export const ICON_NAV_GOODY =
|
||||
"data:image/png;base64,R0lGODlhEQAPAPcAAP/nyv/js/vau//asffVsuvTuerQtf/Yqf/Xp//Wpv/VpPzRp/DOqffNo+/Pqf/Qn//NnP8A/+mlaNKZZNGXZc6bbuCSSsmRXtCOUcGOX8SHUMOHU8GDUMuHSMmCRM+EQcmCQsOBR8SAQbiMZbmLZ7qLYbeNZ7eMYq2LaKqHaaeDYb2NXbyGWLSFW7yHVbaBVbKDV7CAUKyGX62GXaiFX76GTb6ARcR/SMN9QbV/ULJ/UqJ/X6B5WKt+VKR+V6d6UbJ+Trl8Q7l4QLd4RbR4RLd6QbR5QbF1Qa98T6p3Sq93Rq91R6duQYBgSc1/PcN+PbhyNrVzNrNxNK5xO7drL6tmLYBcPINfO4BeO5hbJZVcJ4xeLYlYLY1aK4VSJ5NWH51TFoxTHI9SG4BGGI1PFItKEptOCJZPDZZJA3lWQHRZPH9ZNXRTMnJNMmNKNGBKNXtQLmtCImVEI3lGEWY7GW0+FGY6F2I7FHQ+D3Q8DWA2DGU0C2s3BWYyAmMrAFs4GFswDV8vCVwqAFoqAFUrAVMpA1ElAFQhAEoiAEoVAEUSAEQMAEEPADQTADwKADMOADoFADwAADcDADYAADIAADAAAC4PAC4MAC4JACUKACcIAC0HAC4BAC4AAC0AACsAACoAACkAACgAACQGACQAACMAACIAACAAAB4JABoJAB0HAB8AABwAABsAABoAABkAABgAABMEABYAABUAABIAABEBABEAAA8AAA0BAA0AAAwAAAsAAAoAAAgAAAUEAAcCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkIABEALAAAAAARAA8AAAj+ACMIHDgpEqVOswYqHKhq1RQJXyrseJVwYYRPJErkoDDhQoYkLE4t7HSDCRcdLr4E0XJEyAtbA20NAeOl0CAjIJ4s6pMFT4pUAltxKIOIAAIyaM4EaHCoywlYEVbxqGOoAIBQGMx0GCCLASFBJnaRGrFJjgFWoGyIKEJqlAM9iXrkCvWjEZsFBxIAibECwgMFWyTN2AUJhiYsREIoEbXKlAYpNeYwkqGrEhJLa3A42UBKgCkPFqKEUeSDl6cWmf5UobLEziVAUD6I4eOIxi5OKlC52TMmUBxMdPL4uXOlFApes97gqvWqTZNTaR7BsWLr1is1vSL4+iWQV69YtGYHucrVfVeEgAA7";
|
||||
|
||||
export const ICON_NAV_BB =
|
||||
"data:image/png;base64,R0lGODlhDgARAMQAAAAAAP////zTY/unAPqlAPqmAPqnAPmlAPmnAPikAPilAPimAPieANBFANpcHkocBv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAOABEAAAVoIAQ9j2iOpfgwTKqy6SO050qPTkvujOM+jhyr56sdGIJk8jY6HJRDASL2VM4UyNKjUFVyB4IDidvlGljih5NAcBYKiWO6QY4vDoZ8QesgHxIGC30xQYWFB3smQIYOiC4qQE5pJzU7lCEAOw==";
|
||||
|
||||
export const ICON_NAV_RULES =
|
||||
"data:image/gif;base64,R0lGODlhDwAQAPMAAP/3wvyn/9+P4nCn8f8A/7ZruVB32iRDkP/rPv+YAKpXBHk1fAAAAAAAAAAAAAAAACH5BAkIAAQALAAAAAAPABAAAARTUMlJFblEoc25OuChdZ0ynGKirquJjuSmLIshxp6wDDeOKDoejNMq7HqdhCyIJP6ARw1gCngCmRWKYBudbb/gBeiyEATO6IBuTKC53zRMGw6/RAAAOw==";
|
||||
|
||||
export const ICON_NAV_SHOP =
|
||||
"data:image/png;base64,R0lGODlhEAAOAKIAAP//nP8A/9uPUu7RDqVfJlotCAAAAAAAACH5BAkIAAEALAAAAAAQAA4AAAM5GKrVvRCWUUCJyxUx9WXCAIzkOHAgoa4sGhRsvH6wHF+1fef6zPeEBpAlJAiOyKQKZ0w6gxmPVJEAADs=";
|
||||
|
||||
export const ICON_NAV_LEADERBOARDS =
|
||||
"data:image/png;base64,R0lGODlhDwANALMAAAAAAP///zY+OP/5l//iJv6gALZwFcZ6GB0XFD09Pf///wAAAAAAAAAAAAAAAAAAACH5BAEAAAoALAAAAAAPAA0AAARDUAkhp6VTFiLKIEQhCuFEIN0XjggncYMqFiSlVNs62vfdzbSe0NfJDIcJ11FIAvGOk5lxKDhYr4enz8DtGrSVi6UXAQA7";
|
||||
Reference in new issue
Block a user