'use strict';
/*
* PetSprite — единый источник модели питомца для /pet и /dashboard.
* Канонические PET_PALETTES + shadeColor + renderPetSVG. pet.html и
* dashboard.html используют window.PetSprite.render(...) — без дублей.
*/
(function () {
const PET_PALETTES = {
purple:'#9B5DE5', cyan:'#06D6E0', gold:'#F9C74F',
red:'#F94144', green:'#38D95A', blue:'#4A90D9',
};
function shadeColor(hex, pct) {
const n = parseInt(hex.slice(1), 16);
const r = Math.min(255,Math.max(0,(n>>16)+pct));
const g = Math.min(255,Math.max(0,((n>>8)&0xff)+pct));
const b = Math.min(255,Math.max(0,(n&0xff)+pct));
return `rgb(${r},${g},${b})`;
}
function renderPetSVG(level, mood, accessories = [], colorKey = 'purple', streak = 0) {
const col = PET_PALETTES[colorKey] || '#9B5DE5';
const dark = shadeColor(col, -45);
const light = shadeColor(col, 52);
const uid = `pg${level}${mood[0]}${colorKey[0]}`;
const bodyPath = 'M55,22 C70,22 86,37 87,56 C89,75 78,94 55,97 C32,94 21,75 23,56 C24,37 40,22 55,22 Z';
const eyeY = 52, eyeX1 = 40, eyeX2 = 70;
/* ── Eyebrows ── */
let eyebrows = '';
if (mood !== 'sleeping') {
if (mood === 'ecstatic') {
eyebrows = `
`;
} else if (mood === 'sad' || mood === 'hungry') {
eyebrows = `
`;
} else {
eyebrows = `
`;
}
}
/* ── Eyes ── */
let eyeGroups = '', cheeks = '', extras = '';
if (mood === 'sleeping') {
eyeGroups = `
`;
} else {
const ry1 = mood === 'ecstatic' ? 13 : mood === 'happy' ? 12 : 10.5;
const prx = mood === 'ecstatic' ? 7 : mood === 'happy' ? 6.5 : 5.5;
const pry = mood === 'ecstatic' ? 8 : mood === 'happy' ? 7.5 : 6.5;
const pOff = (mood === 'sad' || mood === 'hungry') ? 3 : 2;
eyeGroups = `
`;
}
/* ── Nose ── */
const nose = mood !== 'sleeping'
? `` : '';
/* ── Mouth + cheeks ── */
let mouth = '';
if (mood === 'sleeping') {
mouth = ``;
} else if (mood === 'ecstatic') {
mouth = ``;
cheeks = `
`;
} else if (mood === 'happy') {
mouth = ``;
cheeks = `
`;
} else if (mood === 'sad' || mood === 'hungry') {
mouth = ``;
if (mood === 'hungry')
extras = ``;
} else {
mouth = ``;
}
/* ── Animated tail (all levels) ── */
const tail = `
`;
/* ── Ears (level 2+) ── */
let ears = '';
if (level >= 2) {
ears = `
`;
}
/* ── Antennae (level 3+) ── */
let antennae = '';
if (level >= 3) {
antennae = `
`;
}
/* ── Wings with flutter (level 4+) ── */
let wings = '';
if (level >= 4) {
wings = `
`;
}
/* ── Paws with fingers ── */
const paws = `
`;
/* ── Accessories ── */
let accSvg = '';
if (accessories.includes('hat')) {
accSvg += `
`;
}
if (accessories.includes('glasses')) {
accSvg += `
`;
}
if (accessories.includes('crown') || level >= 5) {
accSvg += `
`;
}
if (accessories.includes('star') && level < 5) {
accSvg += ``;
}
/* ── Aura ring (level 4+) ── */
let aura = '';
if (level >= 4) {
aura = `
`;
}
/* ── B3 Rainbow collar (streak ≥ 7) ── */
let rainbowCollar = '';
if (streak >= 7) {
rainbowCollar = `
`;
}
/* ── Orbital particles (level 5+) ── */
let orbitals = '';
if (level >= 5) {
const oData = [
{ start: 0, dur: 2.8, r: 46, size: 4, fill: col, op: .85 },
{ start: 120, dur: 3.6, r: 43, size: 3, fill: light, op: .7 },
{ start: 240, dur: 2.2, r: 48, size: 3.5, fill: 'white', op: .6 },
];
// Extra orbitals for level 6+
if (level >= 6) {
oData.push(
{ start: 60, dur: 1.9, r: 51, size: 2.5, fill: light, op: .65 },
{ start: 180, dur: 4.1, r: 40, size: 2, fill: col, op: .55 },
{ start: 300, dur: 3.0, r: 54, size: 3, fill: 'white', op: .5 },
);
}
// Even more for level 8
if (level >= 8) {
oData.push(
{ start: 45, dur: 1.5, r: 56, size: 3.5, fill: '#FFD700', op: .9 },
{ start: 225, dur: 2.4, r: 38, size: 2.5, fill: '#FFD700', op: .75 },
);
}
orbitals = oData.map(o => `
`).join('\n');
}
/* ── Second aura ring (level 6+) ── */
if (level >= 6) {
aura += `
`;
}
/* ── Crystal halo (level 7+) ── */
let halo = '';
if (level >= 7) {
halo = `
`;
}
/* ── Second wing pair (level 7+) ── */
if (level >= 7) {
wings += `
`;
}
/* ── Third aura + body shimmer (level 8) ── */
let shimmer = '';
if (level >= 8) {
aura += `
`;
shimmer = ``;
}
return ``;
}
var MOOD_RU = {
ecstatic: 'в восторге', happy: 'в духе', neutral: 'бодр',
sad: 'скучает', hungry: 'голоден', sleeping: 'спит',
};
window.PetSprite = {
PALETTES: PET_PALETTES,
shade: shadeColor,
render: renderPetSVG,
moodLabel: function (m) { return MOOD_RU[m] || 'бодр'; },
};
})();