@jjlmoya/utils-social 1.14.0 → 1.16.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/package.json +4 -2
- package/src/category/i18n/fr.ts +2 -2
- package/src/category/i18n/ru.ts +1 -1
- package/src/category/index.ts +1 -1
- package/src/env.d.ts +5 -0
- package/src/layouts/PreviewLayout.astro +7 -2
- package/src/tests/diacritics_density.test.ts +118 -0
- package/src/tests/inverted_punctuation.test.ts +84 -0
- package/src/tests/no_en_dash.test.ts +70 -0
- package/src/tests/pagespeed_best_practices.test.ts +198 -0
- package/src/tests/script_density.test.ts +94 -0
- package/src/tool/redditFormatter/i18n/fr.ts +2 -2
- package/src/tool/redditFormatter/i18n/pl.ts +4 -4
- package/src/tool/redditFormatter/i18n/ru.ts +2 -2
- package/src/tool/redditFormatter/i18n/zh.ts +1 -1
- package/src/tool/safeZones/component.astro +1 -1
- package/src/tool/safeZones/i18n/de.ts +2 -2
- package/src/tool/safeZones/i18n/en.ts +2 -2
- package/src/tool/safeZones/i18n/fr.ts +11 -11
- package/src/tool/safeZones/i18n/id.ts +2 -2
- package/src/tool/safeZones/i18n/it.ts +6 -6
- package/src/tool/safeZones/i18n/nl.ts +2 -2
- package/src/tool/safeZones/i18n/pl.ts +7 -7
- package/src/tool/safeZones/i18n/pt.ts +2 -2
- package/src/tool/safeZones/i18n/ru.ts +9 -9
- package/src/tool/safeZones/i18n/sv.ts +2 -2
- package/src/tool/safeZones/i18n/zh.ts +4 -4
- package/src/tool/socialImageResizer/component.astro +2 -2
- package/src/tool/socialImageResizer/i18n/de.ts +5 -5
- package/src/tool/socialImageResizer/i18n/en.ts +8 -8
- package/src/tool/socialImageResizer/i18n/es.ts +7 -7
- package/src/tool/socialImageResizer/i18n/fr.ts +11 -11
- package/src/tool/socialImageResizer/i18n/id.ts +8 -8
- package/src/tool/socialImageResizer/i18n/it.ts +16 -16
- package/src/tool/socialImageResizer/i18n/ja.ts +7 -7
- package/src/tool/socialImageResizer/i18n/ko.ts +7 -7
- package/src/tool/socialImageResizer/i18n/nl.ts +8 -8
- package/src/tool/socialImageResizer/i18n/pl.ts +9 -9
- package/src/tool/socialImageResizer/i18n/pt.ts +8 -8
- package/src/tool/socialImageResizer/i18n/ru.ts +14 -14
- package/src/tool/socialImageResizer/i18n/sv.ts +8 -8
- package/src/tool/socialImageResizer/i18n/tr.ts +7 -7
- package/src/tool/socialImageResizer/i18n/zh.ts +7 -7
- package/src/tool/socialValueCalculator/component.astro +1 -2
- package/src/tool/socialValueCalculator/i18n/de.ts +2 -2
- package/src/tool/socialValueCalculator/i18n/en.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/es.ts +2 -2
- package/src/tool/socialValueCalculator/i18n/fr.ts +6 -6
- package/src/tool/socialValueCalculator/i18n/id.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/it.ts +14 -14
- package/src/tool/socialValueCalculator/i18n/ja.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/ko.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/nl.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/pl.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/pt.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/ru.ts +7 -7
- package/src/tool/socialValueCalculator/i18n/sv.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/tr.ts +1 -1
- package/src/tool/socialValueCalculator/i18n/zh.ts +4 -4
- package/src/tool/tinderPhotoOptimizer/component.astro +23 -6
- package/src/tool/tinderPhotoOptimizer/i18n/de.ts +3 -3
- package/src/tool/tinderPhotoOptimizer/i18n/en.ts +1 -1
- package/src/tool/tinderPhotoOptimizer/i18n/es.ts +3 -3
- package/src/tool/tinderPhotoOptimizer/i18n/fr.ts +25 -25
- package/src/tool/tinderPhotoOptimizer/i18n/ru.ts +9 -9
- package/src/tool/tinderPhotoOptimizer/i18n/zh.ts +2 -2
- package/src/tool/youtubeThumbnail/bibliography.ts +1 -1
- package/src/tool/youtubeThumbnail/component.astro +1 -0
- package/src/tool/youtubeThumbnail/i18n/de.ts +3 -3
- package/src/tool/youtubeThumbnail/i18n/en.ts +1 -1
- package/src/tool/youtubeThumbnail/i18n/fr.ts +3 -3
- package/src/tool/youtubeThumbnail/i18n/ru.ts +3 -3
- package/src/tool/youtubeThumbnail/i18n/zh.ts +2 -2
- package/src/tool/youtubeThumbnailPreviewer/i18n/de.ts +8 -8
- package/src/tool/youtubeThumbnailPreviewer/i18n/en.ts +2 -2
- package/src/tool/youtubeThumbnailPreviewer/i18n/fr.ts +9 -9
- package/src/tool/youtubeThumbnailPreviewer/i18n/id.ts +2 -2
- package/src/tool/youtubeThumbnailPreviewer/i18n/it.ts +21 -21
- package/src/tool/youtubeThumbnailPreviewer/i18n/nl.ts +4 -4
- package/src/tool/youtubeThumbnailPreviewer/i18n/pl.ts +7 -7
- package/src/tool/youtubeThumbnailPreviewer/i18n/ru.ts +11 -11
- package/src/tool/youtubeThumbnailPreviewer/i18n/sv.ts +2 -2
- package/src/tool/youtubeThumbnailPreviewer/i18n/zh.ts +10 -10
|
@@ -10,7 +10,7 @@ const description =
|
|
|
10
10
|
|
|
11
11
|
const faqData = [
|
|
12
12
|
{
|
|
13
|
-
question: 'Il calcolatore del valore dell
|
|
13
|
+
question: 'Il calcolatore del valore dell\'account è gratuito?',
|
|
14
14
|
answer:
|
|
15
15
|
'Sì, il nostro strumento è gratuito al 100% e non richiede registrazione né connessione ai tuoi account social. Devi solo inserire le tue metriche pubbliche.',
|
|
16
16
|
},
|
|
@@ -96,7 +96,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
96
96
|
{
|
|
97
97
|
type: 'tip',
|
|
98
98
|
title: 'In questa guida imparerai',
|
|
99
|
-
html: '<ul><li>Il tuo <strong>reale valore di mercato</strong> basato sui dati 2026.</li><li>Come differenziare l
|
|
99
|
+
html: '<ul><li>Il tuo <strong>reale valore di mercato</strong> basato sui dati 2026.</li><li>Come differenziare l\'impatto di <strong>TikTok vs Instagram</strong>.</li><li>Come la tua <strong>nicchia</strong> influisce drasticamente sul tuo CPM.</li><li>Un modello professionale per <strong>negoziare con i brand</strong>.</li></ul>',
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
type: 'title',
|
|
@@ -109,12 +109,12 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
111
|
type: 'title',
|
|
112
|
-
text: 'L
|
|
112
|
+
text: 'L\'ascesa della creator economy',
|
|
113
113
|
level: 3,
|
|
114
114
|
},
|
|
115
115
|
{
|
|
116
116
|
type: 'paragraph',
|
|
117
|
-
html: 'L
|
|
117
|
+
html: 'L\'influencer marketing è maturato e non si tratta più solo di numero di follower. I brand cercano risultati e connessione profonda. Il nostro strumento offre un punto di partenza solido basato su dati reali di mercato.',
|
|
118
118
|
},
|
|
119
119
|
{
|
|
120
120
|
type: 'grid',
|
|
@@ -131,7 +131,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
131
131
|
},
|
|
132
132
|
{
|
|
133
133
|
type: 'card',
|
|
134
|
-
title: '15
|
|
134
|
+
title: '15€ a 50€',
|
|
135
135
|
html: '<p>CPM medio in nicchie di alto valore (stabile)</p>',
|
|
136
136
|
},
|
|
137
137
|
],
|
|
@@ -143,7 +143,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
type: 'paragraph',
|
|
146
|
-
html: 'A differenza di quanto si credesse anni fa, il numero di follower è solo la punta dell
|
|
146
|
+
html: 'A differenza di quanto si credesse anni fa, il numero di follower è solo la punta dell\'iceberg. Ecco le componenti fondamentali:',
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
type: 'title',
|
|
@@ -157,7 +157,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
157
157
|
{
|
|
158
158
|
type: 'tip',
|
|
159
159
|
title: 'Consiglio engagement',
|
|
160
|
-
html: '<p>Prova a rispondere ai commenti nelle prime ore dopo il post per inviare segnali positivi all
|
|
160
|
+
html: '<p>Prova a rispondere ai commenti nelle prime ore dopo il post per inviare segnali positivi all\'algoritmo.</p>',
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
163
|
type: 'title',
|
|
@@ -175,7 +175,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
175
175
|
},
|
|
176
176
|
{
|
|
177
177
|
type: 'paragraph',
|
|
178
|
-
html: 'Non tutte le audience valgono lo stesso. Un creatore tech o finance può chiedere tariffe molto più alte di un creatore di intrattenimento generale, a causa del maggior valore dell
|
|
178
|
+
html: 'Non tutte le audience valgono lo stesso. Un creatore tech o finance può chiedere tariffe molto più alte di un creatore di intrattenimento generale, a causa del maggior valore dell\'utente finale.',
|
|
179
179
|
},
|
|
180
180
|
{
|
|
181
181
|
type: 'title',
|
|
@@ -211,7 +211,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
211
211
|
{
|
|
212
212
|
type: 'card',
|
|
213
213
|
title: 'TikTok',
|
|
214
|
-
html: '<p>La terra della viralità estrema. L
|
|
214
|
+
html: '<p>La terra della viralità estrema. L\'algoritmo regna sui follower. ROI esplosivo a breve termine.</p><ul><li>Valuta portata massiccia</li><li>Potenziale virale assoluto</li><li>Bassi costi di produzione</li><li>Audience molto attiva</li></ul>',
|
|
215
215
|
},
|
|
216
216
|
],
|
|
217
217
|
},
|
|
@@ -222,12 +222,12 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
222
222
|
},
|
|
223
223
|
{
|
|
224
224
|
type: 'paragraph',
|
|
225
|
-
html: 'Ottieni l
|
|
225
|
+
html: 'Ottieni l\'intervallo di prezzo dal nostro strumento e usalo come guida. Presenta le tue metriche con sicurezza usando questo modello:',
|
|
226
226
|
},
|
|
227
227
|
{
|
|
228
228
|
type: 'tip',
|
|
229
229
|
title: 'Modello di negoziazione',
|
|
230
|
-
html: '<p>Ciao [Nome Brand], grazie per il contatto. In base alle mie attuali metriche di portata (media di [X] visualizzazioni) e al mio tasso di engagement del [X]%, la mia tariffa per un
|
|
230
|
+
html: '<p>Ciao [Nome Brand], grazie per il contatto. In base alle mie attuali metriche di portata (media di [X] visualizzazioni) e al mio tasso di engagement del [X]%, la mia tariffa per un\'integrazione in un [Reel/TikTok] è [Prezzo €]. Questo include: scripting e produzione video, 1 link in bio per 24h, 2 Stories di amplificazione, diritti d\'uso per 30 giorni.</p>',
|
|
231
231
|
},
|
|
232
232
|
{
|
|
233
233
|
type: 'title',
|
|
@@ -237,9 +237,9 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
237
237
|
{
|
|
238
238
|
type: 'list',
|
|
239
239
|
items: [
|
|
240
|
-
'<strong>Fomenta l
|
|
241
|
-
'<strong>Alza la qualità:</strong> L
|
|
242
|
-
'<strong>Specializzati:</strong> Essere "l
|
|
240
|
+
'<strong>Fomenta l\'interazione:</strong> Rispondi a ogni commento.',
|
|
241
|
+
'<strong>Alza la qualità:</strong> L\'audio è il 50% di un buon video.',
|
|
242
|
+
'<strong>Specializzati:</strong> Essere "l\'esperto" ti permette di chiedere di più.',
|
|
243
243
|
'<strong>Crea un Media Kit:</strong> Documenta i tuoi successi con i dati.',
|
|
244
244
|
],
|
|
245
245
|
},
|
|
@@ -22,7 +22,7 @@ const faqData = [
|
|
|
22
22
|
{
|
|
23
23
|
question: 'Какой уровень вовлеченности считается хорошим для повышения цены?',
|
|
24
24
|
answer:
|
|
25
|
-
'Как правило, вовлеченность выше 3% считается здоровой. Аккаунты с вовлеченностью более 10% считаются
|
|
25
|
+
'Как правило, вовлеченность выше 3% считается здоровой. Аккаунты с вовлеченностью более 10% считаются \"премиум-профилями\" и могут запрашивать значительную надбавку.',
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
question: 'Ниша действительно так сильно влияет на цену?',
|
|
@@ -34,7 +34,7 @@ const faqData = [
|
|
|
34
34
|
const howToData = [
|
|
35
35
|
{
|
|
36
36
|
name: 'Выберите платформу',
|
|
37
|
-
text: 'Выберите, для какой соцсети вы хотите рассчитать стоимость
|
|
37
|
+
text: 'Выберите, для какой соцсети вы хотите рассчитать стоимость - TikTok или Instagram.',
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
name: 'Введите показатели',
|
|
@@ -131,7 +131,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
131
131
|
},
|
|
132
132
|
{
|
|
133
133
|
type: 'card',
|
|
134
|
-
title: '1500
|
|
134
|
+
title: '1500 до 5000₽',
|
|
135
135
|
html: '<p>Средний CPM в ценных нишах (стабильный)</p>',
|
|
136
136
|
},
|
|
137
137
|
],
|
|
@@ -143,7 +143,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
type: 'paragraph',
|
|
146
|
-
html: 'В отличие от того, что считалось раньше, количество подписчиков
|
|
146
|
+
html: 'В отличие от того, что считалось раньше, количество подписчиков - это лишь верхушка айсберга. Вот основные компоненты:',
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
type: 'title',
|
|
@@ -152,7 +152,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
152
152
|
},
|
|
153
153
|
{
|
|
154
154
|
type: 'paragraph',
|
|
155
|
-
html: 'Это ключевой показатель. Он измеряет, какой процент вашего сообщества активно взаимодействует с вашим контентом. Небольшой аккаунт с высокой активностью гораздо ценнее, чем огромный
|
|
155
|
+
html: 'Это ключевой показатель. Он измеряет, какой процент вашего сообщества активно взаимодействует с вашим контентом. Небольшой аккаунт с высокой активностью гораздо ценнее, чем огромный \"мертвый\" профиль.',
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
type: 'tip',
|
|
@@ -198,7 +198,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
198
198
|
},
|
|
199
199
|
{
|
|
200
200
|
type: 'paragraph',
|
|
201
|
-
html: 'Хотя оба сервиса используют вертикальное видео, их модели монетизации различаются. Instagram
|
|
201
|
+
html: 'Хотя оба сервиса используют вертикальное видео, их модели монетизации различаются. Instagram - это брендинг, TikTok - это чистая эффективность (перформанс).',
|
|
202
202
|
},
|
|
203
203
|
{
|
|
204
204
|
type: 'grid',
|
|
@@ -238,7 +238,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
238
238
|
type: 'list',
|
|
239
239
|
items: [
|
|
240
240
|
'<strong>Стимулируйте активность:</strong> отвечайте на каждый комментарий.',
|
|
241
|
-
'<strong>Повышайте качество:</strong> звук
|
|
241
|
+
'<strong>Повышайте качество:</strong> звук - это 50% успеха хорошего видео.',
|
|
242
242
|
'<strong>Спецциализируйтесь:</strong> статус эксперта позволяет брать больше.',
|
|
243
243
|
'<strong>Создайте медиакит:</strong> фиксируйте свои успехи в цифрах.',
|
|
244
244
|
],
|
|
@@ -22,7 +22,7 @@ const faqData = [
|
|
|
22
22
|
{
|
|
23
23
|
question: '什么样的互动率可以收更高的费用?',
|
|
24
24
|
answer:
|
|
25
|
-
'通常,3% 以上的互动率被认为是健康的。互动率超过 10%
|
|
25
|
+
'通常,3% 以上的互动率被认为是健康的。互动率超过 10% 的账号被视为\"优质账号\",可以收取显著的溢价。',
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
question: '领域(Niche)真的对价格影响那么大吗?',
|
|
@@ -131,7 +131,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
131
131
|
},
|
|
132
132
|
{
|
|
133
133
|
type: 'card',
|
|
134
|
-
title: '¥100
|
|
134
|
+
title: '¥100至¥400',
|
|
135
135
|
html: '<p>高价值领域的平均 CPM(预计)</p>',
|
|
136
136
|
},
|
|
137
137
|
],
|
|
@@ -152,7 +152,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
152
152
|
},
|
|
153
153
|
{
|
|
154
154
|
type: 'paragraph',
|
|
155
|
-
html: '
|
|
155
|
+
html: '这是关键指标。它衡量您的社区中有多大比例的人在积极与您的内容互动。一个互动量高的小账号远比一个毫无反应的\"僵尸\"大号更有价值。',
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
type: 'tip',
|
|
@@ -239,7 +239,7 @@ export const content: ToolLocaleContent<SocialValueCalculatorUI> = {
|
|
|
239
239
|
items: [
|
|
240
240
|
'<strong>鼓励互动:</strong> 回复每一条评论。',
|
|
241
241
|
'<strong>提高质量:</strong> 音频占好视频成功因素的 50%。',
|
|
242
|
-
'<strong>专业化:</strong>
|
|
242
|
+
'<strong>专业化:</strong> 成为\"专家\"能让您收更多钱。',
|
|
243
243
|
'<strong>制作媒体手册 (Media Kit):</strong> 用数据记录您的成功案例。',
|
|
244
244
|
],
|
|
245
245
|
},
|
|
@@ -202,11 +202,11 @@ const t = (ui ?? {}) as TinderPhotoOptimizerUI;
|
|
|
202
202
|
<div class="tfo-panel">
|
|
203
203
|
<h3>{t.panelManual}</h3>
|
|
204
204
|
<div class="tfo-control-group">
|
|
205
|
-
<label>{t.labelZoom} <span>1.0x</span></label>
|
|
205
|
+
<label for="zoom-slider">{t.labelZoom} <span>1.0x</span></label>
|
|
206
206
|
<input type="range" id="zoom-slider" min="1" max="3" step="0.1" value="1" />
|
|
207
207
|
</div>
|
|
208
208
|
<div class="tfo-control-group">
|
|
209
|
-
<label>{t.labelBrightness} <span>100%</span></label>
|
|
209
|
+
<label for="brightness-slider">{t.labelBrightness} <span>100%</span></label>
|
|
210
210
|
<input type="range" id="brightness-slider" min="50" max="150" step="1" value="100" />
|
|
211
211
|
</div>
|
|
212
212
|
</div>
|
|
@@ -310,6 +310,8 @@ const t = (ui ?? {}) as TinderPhotoOptimizerUI;
|
|
|
310
310
|
<script>
|
|
311
311
|
import { TinderOptimizerEngine } from './logic';
|
|
312
312
|
|
|
313
|
+
const getRect = (el: Element) => el.getBoundingClientRect();
|
|
314
|
+
|
|
313
315
|
class TinderOptimizerUI {
|
|
314
316
|
private engine: TinderOptimizerEngine;
|
|
315
317
|
private canvas: HTMLCanvasElement;
|
|
@@ -334,6 +336,10 @@ const t = (ui ?? {}) as TinderPhotoOptimizerUI;
|
|
|
334
336
|
private isSelecting = false;
|
|
335
337
|
private selectionRect = { x: 0, y: 0, w: 0, h: 0 };
|
|
336
338
|
private lastPos = { x: 0, y: 0 };
|
|
339
|
+
private cachedClientWidth = 0;
|
|
340
|
+
private cachedClientHeight = 0;
|
|
341
|
+
private cachedRect = { left: 0, top: 0, width: 1, height: 1 };
|
|
342
|
+
private resizeObserver: ResizeObserver | null = null;
|
|
337
343
|
|
|
338
344
|
constructor() {
|
|
339
345
|
this.canvas = document.getElementById('editor-canvas') as HTMLCanvasElement;
|
|
@@ -422,6 +428,17 @@ const t = (ui ?? {}) as TinderPhotoOptimizerUI;
|
|
|
422
428
|
this.setupSliders();
|
|
423
429
|
this.setupToggles();
|
|
424
430
|
this.setupButtons();
|
|
431
|
+
this.cachedClientWidth = 1;
|
|
432
|
+
this.cachedClientHeight = 1;
|
|
433
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
434
|
+
for (const entry of entries) {
|
|
435
|
+
this.cachedClientWidth = entry.contentRect.width || 1;
|
|
436
|
+
this.cachedClientHeight = entry.contentRect.height || 1;
|
|
437
|
+
const r = getRect(entry.target);
|
|
438
|
+
this.cachedRect = { left: r.left, top: r.top, width: entry.contentRect.width || 1, height: entry.contentRect.height || 1 };
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
this.resizeObserver.observe(this.canvas);
|
|
425
442
|
}
|
|
426
443
|
|
|
427
444
|
private reset() {
|
|
@@ -480,7 +497,7 @@ const t = (ui ?? {}) as TinderPhotoOptimizerUI;
|
|
|
480
497
|
private onStart(e: MouseEvent | TouchEvent) {
|
|
481
498
|
if (e instanceof TouchEvent) e.preventDefault();
|
|
482
499
|
const { x: cx, y: cy } = this.getClientPos(e);
|
|
483
|
-
const rect = this.
|
|
500
|
+
const rect = this.cachedRect;
|
|
484
501
|
const x = (cx - rect.left) * (this.canvas.width / rect.width);
|
|
485
502
|
const y = (cy - rect.top) * (this.canvas.height / rect.height);
|
|
486
503
|
this.initInteraction(x, y, cx, cy);
|
|
@@ -503,15 +520,15 @@ const t = (ui ?? {}) as TinderPhotoOptimizerUI;
|
|
|
503
520
|
}
|
|
504
521
|
|
|
505
522
|
private handleSelectionMove(clientX: number, clientY: number) {
|
|
506
|
-
const rect = this.
|
|
523
|
+
const rect = this.cachedRect;
|
|
507
524
|
this.selectionRect.w = (clientX - rect.left) * (this.canvas.width / rect.width) - this.selectionRect.x;
|
|
508
525
|
this.selectionRect.h = (clientY - rect.top) * (this.canvas.height / rect.height) - this.selectionRect.y;
|
|
509
526
|
this.draw();
|
|
510
527
|
}
|
|
511
528
|
|
|
512
529
|
private handleDragMove(clientX: number, clientY: number) {
|
|
513
|
-
const dx = (clientX - this.lastPos.x) * (this.canvas.width / this.
|
|
514
|
-
const dy = (clientY - this.lastPos.y) * (this.canvas.height / this.
|
|
530
|
+
const dx = (clientX - this.lastPos.x) * (this.canvas.width / this.cachedClientWidth);
|
|
531
|
+
const dy = (clientY - this.lastPos.y) * (this.canvas.height / this.cachedClientHeight);
|
|
515
532
|
const offset = this.engine.offset;
|
|
516
533
|
this.engine.updateState(parseFloat(this.zoomSlider.value), { x: offset.x + dx, y: offset.y + dy }, parseInt(this.brightnessSlider.value));
|
|
517
534
|
this.lastPos = { x: clientX, y: clientY };
|
|
@@ -12,7 +12,7 @@ const faqData = [
|
|
|
12
12
|
{
|
|
13
13
|
question: 'Wie verbessert dieses Tool meine Tinder-Matches?',
|
|
14
14
|
answer:
|
|
15
|
-
'Das Tool analysiert wichtige technische Faktoren: das Verhältnis der Gesichtsgröße (ideal 30
|
|
15
|
+
'Das Tool analysiert wichtige technische Faktoren: das Verhältnis der Gesichtsgröße (ideal 30-50 %), die Position der Augenlinie im Verhältnis zum oberen Drittel, die Abdeckung des Bildausschnitts und die Totzonen der Tinder-Benutzeroberfläche. Durch die Anpassung dieser Parameter projiziert Ihr Foto mehr Vertrauen und überwindet die visuellen Filter des Algorithmus.',
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
question: 'Ist es sicher, meine Fotos hier hochzuladen?',
|
|
@@ -27,7 +27,7 @@ const faqData = [
|
|
|
27
27
|
{
|
|
28
28
|
question: 'Warum wird ein Zoom von 1,2x empfohlen?',
|
|
29
29
|
answer:
|
|
30
|
-
'Frontkameras von Smartphones verwenden Weitwinkeloptiken (24 mm), die das Gesicht durch Tonnenverzerrung verzerren. Ein Zoom von 1,2x simuliert eine Brennweite von 50
|
|
30
|
+
'Frontkameras von Smartphones verwenden Weitwinkeloptiken (24 mm), die das Gesicht durch Tonnenverzerrung verzerren. Ein Zoom von 1,2x simuliert eine Brennweite von 50-85 mm, wodurch die Verzerrung eliminiert wird und natürlichere und attraktivere Gesichtsproportionen entstehen.',
|
|
31
31
|
},
|
|
32
32
|
];
|
|
33
33
|
|
|
@@ -186,7 +186,7 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
186
186
|
{
|
|
187
187
|
type: 'tip',
|
|
188
188
|
title: 'Expertenrat',
|
|
189
|
-
html: '<p>Das erste Foto sollte IMMER ein klares Porträt ab den Schultern aufwärts sein. Heben Sie Ganzkörperfotos oder Aktivitätsfotos für die 3. oder 4. Position auf. Stellen Sie sicher, dass Ihr Blick beim ersten Eindruck frei von Hindernissen ist und Ihr Gesicht die optimale Größe (30
|
|
189
|
+
html: '<p>Das erste Foto sollte IMMER ein klares Porträt ab den Schultern aufwärts sein. Heben Sie Ganzkörperfotos oder Aktivitätsfotos für die 3. oder 4. Position auf. Stellen Sie sicher, dass Ihr Blick beim ersten Eindruck frei von Hindernissen ist und Ihr Gesicht die optimale Größe (30-50 %) hat.</p>',
|
|
190
190
|
},
|
|
191
191
|
{
|
|
192
192
|
type: 'title',
|
|
@@ -130,7 +130,7 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
type: 'paragraph',
|
|
133
|
-
html: '<strong>Barrel Aberration:</strong> At less than one meter distance, a 24mm lens (standard on phones) expands the center of the image. This makes noses look bigger and faces rounder than they really are. Our <strong>1.2x Zoom</strong> recommendation is corrective: by applying a slight digital crop, you simulate a 50mm to 85mm focal length
|
|
133
|
+
html: '<strong>Barrel Aberration:</strong> At less than one meter distance, a 24mm lens (standard on phones) expands the center of the image. This makes noses look bigger and faces rounder than they really are. Our <strong>1.2x Zoom</strong> recommendation is corrective: by applying a slight digital crop, you simulate a 50mm to 85mm focal length - the golden focal length photographers use to slim the face and maintain real proportions.',
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
type: 'title',
|
|
@@ -25,7 +25,7 @@ const faqData = [
|
|
|
25
25
|
'Utiliza face-api.js para detectar 68 puntos de referencia facial, analizar la expresión (sonrisa, expresión seria), evaluar la posición de los ojos y medir la inclinación de la cabeza. Todo el análisis ocurre localmente en tu dispositivo.',
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
|
-
question: '¿Por qué recomienda el zoom al 1
|
|
28
|
+
question: '¿Por qué recomienda el zoom al 1,2x?',
|
|
29
29
|
answer:
|
|
30
30
|
'Las cámaras frontales de smartphone usan ópticas gran angular (24mm) que distorsionan el rostro con la aberración de barril. Un zoom de 1.2x simula una focal de 50-85mm, eliminando la distorsión y proporcionando proporciones faciales más naturales y atractivas.',
|
|
31
31
|
},
|
|
@@ -88,8 +88,8 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
88
88
|
slug,
|
|
89
89
|
title,
|
|
90
90
|
description,
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
faq: faqData,
|
|
92
|
+
bibliography,
|
|
93
93
|
howTo: howToData,
|
|
94
94
|
schemas: [faqSchema, howToSchema, appSchema],
|
|
95
95
|
seo: [
|
|
@@ -4,7 +4,7 @@ import type { ToolLocaleContent } from '../../../types';
|
|
|
4
4
|
import type { TinderPhotoOptimizerUI } from '../ui';
|
|
5
5
|
|
|
6
6
|
const slug = 'optimiseur-photos-tinder';
|
|
7
|
-
const title = "Optimiseur de Photos pour Tinder
|
|
7
|
+
const title = "Optimiseur de Photos pour Tinder: Analyse de Visage et Composition";
|
|
8
8
|
const description =
|
|
9
9
|
"Optimisez vos photos pour Tinder avec une analyse algorithmique du visage. Simule l'interface 2026, analyse le cadrage scientifique et la ligne des yeux, exporte des portraits 9:16 parfaits pour maximiser vos matchs.";
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ const faqData = [
|
|
|
12
12
|
{
|
|
13
13
|
question: "Comment cet outil améliore-t-il mes matchs sur Tinder ?",
|
|
14
14
|
answer:
|
|
15
|
-
"L'outil analyse des facteurs techniques clés
|
|
15
|
+
"L'outil analyse des facteurs techniques clés: le ratio de taille du visage (idéal 30-50%), la position de la ligne des yeux par rapport au tiers supérieur, la couverture du cadre et les zones mortes de l'interface Tinder. En ajustant ces paramètres, votre photo projette plus de confiance et passe les filtres visuels de l'algorithme.",
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
question: "Est-il sûr de télécharger mes photos ici ?",
|
|
@@ -95,16 +95,16 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
95
95
|
seo: [
|
|
96
96
|
{
|
|
97
97
|
type: 'title',
|
|
98
|
-
text: "Optimiseur de Photos pour Tinder
|
|
98
|
+
text: "Optimiseur de Photos pour Tinder: Le Guide Scientifique et Technique Définitif (2026)",
|
|
99
99
|
level: 2,
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
type: 'paragraph',
|
|
103
|
-
html: "Dans l'écosystème des rencontres numériques, votre profil Tinder est traité par deux algorithmes simultanément
|
|
103
|
+
html: "Dans l'écosystème des rencontres numériques, votre profil Tinder est traité par deux algorithmes simultanément: l'algorithme de vision avancée de la plateforme elle-même et le cerveau humain de l'utilisateur qui fait glisser. Notre outil intègre des principes de <strong>psychologie évolutive</strong>, de <strong>biométrie faciale</strong> et de <strong>traitement du signal numérique</strong> pour garantir que votre image projette une valeur sociale et un attrait technique maximum.",
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
type: 'title',
|
|
107
|
-
text: "La Psychologie de la Première Impression
|
|
107
|
+
text: "La Psychologie de la Première Impression: L'Effet des 1,2 Secondes",
|
|
108
108
|
level: 3,
|
|
109
109
|
},
|
|
110
110
|
{
|
|
@@ -121,7 +121,7 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
121
121
|
},
|
|
122
122
|
{
|
|
123
123
|
type: 'title',
|
|
124
|
-
text: "Analyse Technique de l'Objectif
|
|
124
|
+
text: "Analyse Technique de l'Objectif: Le Problème du Grand Angle",
|
|
125
125
|
level: 3,
|
|
126
126
|
},
|
|
127
127
|
{
|
|
@@ -130,11 +130,11 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
type: 'paragraph',
|
|
133
|
-
html: "<strong>L'Aberration en Barillet :</strong> À moins d'un mètre de distance, un objectif de 24mm (standard sur mobile) élargit le centre de l'image. Cela fait paraître les nez plus grands et le visage plus rond que dans la réalité. Notre recommandation de <strong>Zoom 1,2x</strong> est corrective
|
|
133
|
+
html: "<strong>L'Aberration en Barillet :</strong> À moins d'un mètre de distance, un objectif de 24mm (standard sur mobile) élargit le centre de l'image. Cela fait paraître les nez plus grands et le visage plus rond que dans la réalité. Notre recommandation de <strong>Zoom 1,2x</strong> est corrective: en appliquant un léger recadrage numérique, vous simulez une focale de 50mm à 85mm, la focale dorée que les photographes de mode utilisent pour affiner le visage et maintenir les proportions réelles.",
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
type: 'title',
|
|
137
|
-
text: "L'Interface Tinder
|
|
137
|
+
text: "L'Interface Tinder: La Science des Zones Mortes",
|
|
138
138
|
level: 3,
|
|
139
139
|
},
|
|
140
140
|
{
|
|
@@ -151,7 +151,7 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
151
151
|
},
|
|
152
152
|
{
|
|
153
153
|
type: 'title',
|
|
154
|
-
text: "Analyse Visuelle en Temps Réel
|
|
154
|
+
text: "Analyse Visuelle en Temps Réel: Décoder l'Algorithme",
|
|
155
155
|
level: 3,
|
|
156
156
|
},
|
|
157
157
|
{
|
|
@@ -195,7 +195,7 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
195
195
|
},
|
|
196
196
|
{
|
|
197
197
|
type: 'paragraph',
|
|
198
|
-
html: "Nous comprenons que vos photos sont privées. Cet optimiseur utilise la <strong>technologie Client-Side</strong
|
|
198
|
+
html: "Nous comprenons que vos photos sont privées. Cet optimiseur utilise la <strong>technologie Client-Side</strong>: les images sont traitées via un moteur canvas dans votre navigateur local. Aucune donnée ne quitte votre appareil. C'est la façon la plus sûre et la plus rapide d'optimiser votre profil sans compromettre votre vie privée.",
|
|
199
199
|
},
|
|
200
200
|
],
|
|
201
201
|
ui: {
|
|
@@ -244,21 +244,21 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
244
244
|
statusNeutral: 'NEUTRE',
|
|
245
245
|
|
|
246
246
|
alertExcellent: 'Excellente composition technique.',
|
|
247
|
-
alertEmptySpaces: 'ESPACES VIDES
|
|
248
|
-
alertAlmostInvisible: 'PRESQUE INVISIBLE
|
|
249
|
-
alertTooClose: 'TROP PRÈS
|
|
250
|
-
alertPerfectSize: 'TAILLE PARFAITE
|
|
251
|
-
alertImpactfulLook: 'REGARD IMPACTANT
|
|
252
|
-
alertEyeLineMoveUp: 'LIGNE DES YEUX
|
|
253
|
-
alertEyeLineMoveDown: 'LIGNE DES YEUX
|
|
254
|
-
alertTiltedHead: 'TÊTE INCLINÉE
|
|
255
|
-
alertSmileDetected: 'SOURIRE
|
|
256
|
-
alertSevereExpression: 'EXPRESSION SÉVÈRE
|
|
257
|
-
alertObstructedTop: '
|
|
258
|
-
alertObstructedBottom: '
|
|
259
|
-
alertLowLight: 'ÉCLAIRAGE DÉFICIENT
|
|
260
|
-
alertCutOff: '
|
|
261
|
-
alertProTip: 'CONSEIL PRO
|
|
247
|
+
alertEmptySpaces: 'ESPACES VIDES: L\'image ne couvre pas tout le cadre. Ajustez le zoom ou la position.',
|
|
248
|
+
alertAlmostInvisible: 'PRESQUE INVISIBLE: Vous êtes trop loin. Zoomez jusqu\'à ce que votre visage occupe au moins un tiers de l\'écran.',
|
|
249
|
+
alertTooClose: 'TROP PRÈS: Les gros plans extrêmes peuvent paraître agressifs.',
|
|
250
|
+
alertPerfectSize: 'TAILLE PARFAITE: Votre visage a le ratio idéal pour transmettre la confiance.',
|
|
251
|
+
alertImpactfulLook: 'REGARD IMPACTANT: Vos yeux sont sur la ligne d\'attention maximale.',
|
|
252
|
+
alertEyeLineMoveUp: 'LIGNE DES YEUX: Pour un cadrage professionnel, remontez légèrement le visage jusqu\'à la ligne supérieure.',
|
|
253
|
+
alertEyeLineMoveDown: 'LIGNE DES YEUX: Pour un cadrage professionnel, baissez légèrement le visage jusqu\'à la ligne supérieure.',
|
|
254
|
+
alertTiltedHead: 'TÊTE INCLINÉE: Une posture trop inclinée peut transmettre de l\'instabilité.',
|
|
255
|
+
alertSmileDetected: 'SOURIRE DÉTECTÉ: Les sourires augmentent considérablement le taux de match.',
|
|
256
|
+
alertSevereExpression: 'EXPRESSION SÉVÈRE: Essayez d\'utiliser une photo avec un geste plus amical.',
|
|
257
|
+
alertObstructedTop: 'OBSTRUÉ: La barre de progression cache votre visage.',
|
|
258
|
+
alertObstructedBottom: 'OBSTRUÉ: Le bloc d\'information cache votre visage.',
|
|
259
|
+
alertLowLight: 'ÉCLAIRAGE DÉFICIENT: L\'IA a des difficultés à vous voir. Cherchez une photo avec une meilleure lumière.',
|
|
260
|
+
alertCutOff: 'COUPÉ: Le visage sort du cadre vertical.',
|
|
261
|
+
alertProTip: 'CONSEIL PRO: S\'il s\'agit d\'un selfie, utilisez le Zoom (1.2x) pour éviter les distorsions de l\'objectif.',
|
|
262
262
|
|
|
263
263
|
canvasFaceDetected: 'Visage détecté',
|
|
264
264
|
},
|
|
@@ -12,7 +12,7 @@ const faqData = [
|
|
|
12
12
|
{
|
|
13
13
|
question: 'Как этот инструмент улучшает мои совпадения в Tinder?',
|
|
14
14
|
answer:
|
|
15
|
-
'Инструмент анализирует ключевые технические факторы: соотношение размера лица (идеально 30
|
|
15
|
+
'Инструмент анализирует ключевые технические факторы: соотношение размера лица (идеально 30-50%), положение линии глаз относительно верхней трети, охват кадра и \"мертвые зоны\" интерфейса Tinder. Настраивая эти параметры, вы транслируете больше уверенности и обходите визуальные фильтры алгоритма.',
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
question: 'Безопасно ли загружать сюда мои фотографии?',
|
|
@@ -27,7 +27,7 @@ const faqData = [
|
|
|
27
27
|
{
|
|
28
28
|
question: 'Почему рекомендуется зум 1.2x?',
|
|
29
29
|
answer:
|
|
30
|
-
'Фронтальные камеры смартфонов используют широкоугольную оптику (24 мм), которая искажает лицо из-за бочкообразной аберрации. Зум 1.2x симулирует фокусное расстояние 50
|
|
30
|
+
'Фронтальные камеры смартфонов используют широкоугольную оптику (24 мм), которая искажает лицо из-за бочкообразной аберрации. Зум 1.2x симулирует фокусное расстояние 50-85 мм, устраняя искажения и обеспечивая более естественные и привлекательные пропорции лица.',
|
|
31
31
|
},
|
|
32
32
|
];
|
|
33
33
|
|
|
@@ -126,11 +126,11 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
type: 'paragraph',
|
|
129
|
-
html: 'Почти все фото профиля делаются на смартфоны, фронтальные камеры которых являются широкоугольными. Самая частая ошибка
|
|
129
|
+
html: 'Почти все фото профиля делаются на смартфоны, фронтальные камеры которых являются широкоугольными. Самая частая ошибка - подходить слишком близко к устройству.',
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
type: 'paragraph',
|
|
133
|
-
html: '<strong>Бочкообразная аберрация:</strong> На расстоянии менее метра линза 24 мм (стандарт в мобильных телефонах) расширяет центр изображения. Из-за этого нос кажется крупнее, а лицо
|
|
133
|
+
html: '<strong>Бочкообразная аберрация:</strong> На расстоянии менее метра линза 24 мм (стандарт в мобильных телефонах) расширяет центр изображения. Из-за этого нос кажется крупнее, а лицо - круглее, чем на самом деле. Наша рекомендация <strong>Зум 1.2x</strong> является корректирующей: применяя легкое цифровое кадрирование, вы симулируете фокусное расстояние от 50 до 85 мм - \"золотой стандарт\", который используют фэшн-фотографы для визуального сужения лица и сохранения реальных пропорций.',
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
type: 'title',
|
|
@@ -139,12 +139,12 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
139
139
|
},
|
|
140
140
|
{
|
|
141
141
|
type: 'paragraph',
|
|
142
|
-
html: 'Многие отличные фото
|
|
142
|
+
html: 'Многие отличные фото \"проваливаются\" из-за игнорирования программного слоя (UI), который Tinder накладывает сверху. Среднестатистический пользователь видит не ваше чистое фото, а смесь кнопок, градиентов и текста.',
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
type: 'list',
|
|
146
146
|
items: [
|
|
147
|
-
'<strong>Зона заголовков (верхние 15%):</strong> Здесь располагаются индикаторы прогресса и строка состояния. Если ваш лоб или глаза здесь, интерфейс визуально
|
|
147
|
+
'<strong>Зона заголовков (верхние 15%):</strong> Здесь располагаются индикаторы прогресса и строка состояния. Если ваш лоб или глаза здесь, интерфейс визуально \"отрезает\" часть головы.',
|
|
148
148
|
'<strong>Зона действия (кнопки):</strong> Иконки Like, Nope и Boost занимают нижние боковые части. Если ваши руки или элементы стиля находятся там, они будут полностью потеряны.',
|
|
149
149
|
'<strong>Градиент читаемости (нижние 28%):</strong> Tinder применяет черное затемнение, чтобы имя и возраст были читаемы. Если лицо попадает в эту зону, текст наложится на черты лица, портя эстетику профиля.',
|
|
150
150
|
],
|
|
@@ -173,12 +173,12 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
175
|
type: 'paragraph',
|
|
176
|
-
html: 'Знаете ли вы, что
|
|
176
|
+
html: 'Знаете ли вы, что \"вес\" вашего изображения влияет на алгоритм? Приложения для знакомств отдают приоритет контенту, который загружается быстро, чтобы не прерывать флоу пользователя.',
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
179
|
type: 'list',
|
|
180
180
|
items: [
|
|
181
|
-
'<strong>Metadata Stripping (приватность и SEO):</strong> Мы удаляем записи EXIF. Чистое фото дает вам
|
|
181
|
+
'<strong>Metadata Stripping (приватность и SEO):</strong> Мы удаляем записи EXIF. Чистое фото дает вам \"новый холст\" для алгоритма платформы.',
|
|
182
182
|
'<strong>Умное сжатие без потерь:</strong> Мы уменьшаем вес файла JPG, сохраняя цветовое пространство sRGB, нативное для iOS и Android. Ваше фото будет выглядеть сочно даже при плохом сигнале.',
|
|
183
183
|
'<strong>Иммерсивный формат 9:16:</strong> Выдавая ровно 1080x1920 пикселей, мы предотвращаем применение Tinder собственного агрессивного алгоритма сжатия, создающего артефакты изображения.',
|
|
184
184
|
],
|
|
@@ -186,7 +186,7 @@ export const content: ToolLocaleContent<TinderPhotoOptimizerUI> = {
|
|
|
186
186
|
{
|
|
187
187
|
type: 'tip',
|
|
188
188
|
title: 'Совет эксперта',
|
|
189
|
-
html: '<p>Первое фото ВСЕГДА должно быть четким портретом по плечи. Фото в полный рост или за каким-то занятием оставьте для 3-й или 4-й позиции. Убедитесь, что при этом первом впечатлении ваш взгляд ничем не заслонен, а лицо имеет оптимальный размер (30
|
|
189
|
+
html: '<p>Первое фото ВСЕГДА должно быть четким портретом по плечи. Фото в полный рост или за каким-то занятием оставьте для 3-й или 4-й позиции. Убедитесь, что при этом первом впечатлении ваш взгляд ничем не заслонен, а лицо имеет оптимальный размер (30-50%).</p>',
|
|
190
190
|
},
|
|
191
191
|
{
|
|
192
192
|
type: 'title',
|