@jjlmoya/utils-tabletop 1.26.0 → 1.28.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.
Files changed (69) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +4 -0
  3. package/src/entries.ts +4 -0
  4. package/src/index.ts +1 -0
  5. package/src/tests/locale_completeness.test.ts +1 -1
  6. package/src/tests/tool_validation.test.ts +1 -1
  7. package/src/tool/mus-scoreboard/bibliography.astro +16 -0
  8. package/src/tool/mus-scoreboard/bibliography.ts +12 -0
  9. package/src/tool/mus-scoreboard/component.astro +169 -0
  10. package/src/tool/mus-scoreboard/controller.ts +178 -0
  11. package/src/tool/mus-scoreboard/dom-views.ts +87 -0
  12. package/src/tool/mus-scoreboard/entry.ts +27 -0
  13. package/src/tool/mus-scoreboard/evaluator.ts +27 -0
  14. package/src/tool/mus-scoreboard/i18n/de.ts +187 -0
  15. package/src/tool/mus-scoreboard/i18n/en.ts +187 -0
  16. package/src/tool/mus-scoreboard/i18n/es.ts +187 -0
  17. package/src/tool/mus-scoreboard/i18n/fr.ts +187 -0
  18. package/src/tool/mus-scoreboard/i18n/id.ts +187 -0
  19. package/src/tool/mus-scoreboard/i18n/it.ts +187 -0
  20. package/src/tool/mus-scoreboard/i18n/ja.ts +187 -0
  21. package/src/tool/mus-scoreboard/i18n/ko.ts +187 -0
  22. package/src/tool/mus-scoreboard/i18n/nl.ts +187 -0
  23. package/src/tool/mus-scoreboard/i18n/pl.ts +187 -0
  24. package/src/tool/mus-scoreboard/i18n/pt.ts +187 -0
  25. package/src/tool/mus-scoreboard/i18n/ru.ts +187 -0
  26. package/src/tool/mus-scoreboard/i18n/sv.ts +187 -0
  27. package/src/tool/mus-scoreboard/i18n/tr.ts +187 -0
  28. package/src/tool/mus-scoreboard/i18n/zh.ts +187 -0
  29. package/src/tool/mus-scoreboard/index.ts +11 -0
  30. package/src/tool/mus-scoreboard/logic.test.ts +82 -0
  31. package/src/tool/mus-scoreboard/logic.ts +122 -0
  32. package/src/tool/mus-scoreboard/online-mus-scoreboard.css +740 -0
  33. package/src/tool/mus-scoreboard/seo.astro +16 -0
  34. package/src/tool/mus-scoreboard/storage.ts +29 -0
  35. package/src/tool/mus-scoreboard/ui.ts +63 -0
  36. package/src/tool/token-stamp-studio/bibliography.astro +16 -0
  37. package/src/tool/token-stamp-studio/bibliography.ts +12 -0
  38. package/src/tool/token-stamp-studio/component.astro +91 -0
  39. package/src/tool/token-stamp-studio/controller.ts +179 -0
  40. package/src/tool/token-stamp-studio/dom-views.ts +266 -0
  41. package/src/tool/token-stamp-studio/entry.ts +27 -0
  42. package/src/tool/token-stamp-studio/evaluator.ts +6 -0
  43. package/src/tool/token-stamp-studio/i18n/de.ts +132 -0
  44. package/src/tool/token-stamp-studio/i18n/en.ts +132 -0
  45. package/src/tool/token-stamp-studio/i18n/es.ts +132 -0
  46. package/src/tool/token-stamp-studio/i18n/fr.ts +132 -0
  47. package/src/tool/token-stamp-studio/i18n/id.ts +132 -0
  48. package/src/tool/token-stamp-studio/i18n/it.ts +132 -0
  49. package/src/tool/token-stamp-studio/i18n/ja.ts +132 -0
  50. package/src/tool/token-stamp-studio/i18n/ko.ts +132 -0
  51. package/src/tool/token-stamp-studio/i18n/nl.ts +132 -0
  52. package/src/tool/token-stamp-studio/i18n/pl.ts +132 -0
  53. package/src/tool/token-stamp-studio/i18n/pt.ts +132 -0
  54. package/src/tool/token-stamp-studio/i18n/ru.ts +132 -0
  55. package/src/tool/token-stamp-studio/i18n/sv.ts +132 -0
  56. package/src/tool/token-stamp-studio/i18n/tr.ts +132 -0
  57. package/src/tool/token-stamp-studio/i18n/zh.ts +132 -0
  58. package/src/tool/token-stamp-studio/index.ts +11 -0
  59. package/src/tool/token-stamp-studio/logic.test.ts +36 -0
  60. package/src/tool/token-stamp-studio/logic.ts +127 -0
  61. package/src/tool/token-stamp-studio/seo.astro +16 -0
  62. package/src/tool/token-stamp-studio/storage.ts +69 -0
  63. package/src/tool/token-stamp-studio/store.ts +139 -0
  64. package/src/tool/token-stamp-studio/token-stamp-studio.css +646 -0
  65. package/src/tool/token-stamp-studio/types.ts +65 -0
  66. package/src/tool/token-stamp-studio/ui.ts +50 -0
  67. package/src/tool/token-stamp-studio/workspace-media.ts +36 -0
  68. package/src/tool/token-stamp-studio/workspace.ts +83 -0
  69. package/src/tools.ts +4 -0
@@ -0,0 +1,132 @@
1
+ import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
2
+ import { bibliography } from '../bibliography';
3
+ import type { TokenStampLocaleContent, TokenStampUI } from '../entry';
4
+
5
+ const ui: TokenStampUI = {
6
+ frameLegend: 'フレームを選択',
7
+ frameHint: '名前を読む前にキャラクターの役割が伝わるシルエットを選びます。',
8
+ randomFrame: 'ランダムフレーム',
9
+ surfaceLegend: 'トリートメント設定',
10
+ backgroundLabel: '背景色',
11
+ borderLabel: 'フレーム色',
12
+ textLabel: '文字色',
13
+ overlayLabel: 'トーン',
14
+ randomColors: 'ランダムカラー',
15
+ borderWidthLabel: 'フレーム幅',
16
+ opacityLabel: 'フレーム不透明度',
17
+ overlayOpacityLabel: 'ポートレート不透明度',
18
+ stageLabel: 'ライブコマ作成スタジオ',
19
+ chooseImage: '画像を選択',
20
+ clearImage: '画像をクリア',
21
+ positionHint: 'コマ上で直接画像やラベルをドラッグして移動できます。',
22
+ markerName: 'マーカー名',
23
+ markerNamePlaceholder: 'マーカーの名前を入力',
24
+ textLegend: '卓で役立つテキストを追加',
25
+ textHint: '名前、レベル、役割、状態などの短いラベルを追加してコマ上に配置します。',
26
+ textPlaceholder: 'キャラクター名や役割',
27
+ addText: 'ラベルを追加',
28
+ removeText: 'ラベルを削除',
29
+ textSizeLabel: '文字サイズ',
30
+ alignmentLabel: 'テキスト揃え',
31
+ alignLeft: '左揃え',
32
+ alignCenter: '中央揃え',
33
+ alignRight: '右揃え',
34
+ imageLegend: 'ポートレートの調整',
35
+ imageZoomLabel: 'ズーム倍率',
36
+ scaleLabel: '出力スケール',
37
+ savedMarkers: '保存済みマーカー',
38
+ noSavedMarkers: '保存されたコマはここに表示され、後から再編集や再利用が可能です。',
39
+ reuseMarker: '再編集するコマを選択してください。',
40
+ deleteMarker: 'コマを削除',
41
+ newMarker: '新規コマ',
42
+ download: 'PNGをダウンロード',
43
+ copy: 'PNGをコピー',
44
+ downloadBatch: '一括ダウンロード',
45
+ batchLabel: '高度な一括エクスポート',
46
+ batchHint: '複数のポートレート画像に同じフレーム設定を適用して一括出力します。',
47
+ chooseBatch: '一括画像を選択',
48
+ batchReady: '{count} 枚の画像が準備完了。',
49
+ noImage: '画像が未読み込みです',
50
+ noText: 'ラベルはまだありません。必要な情報を追加してください。',
51
+ tokenDetails: 'キャラクターコマ操作パネル',
52
+ exportHint: 'フレームの外側は透明PNGとして出力され、ココフォリア等のココフォリアやVTT、印刷シートでそのまま使えます。',
53
+ };
54
+
55
+ const faq = [
56
+ {
57
+ question: '視認性の高いキャラクターコマを作成するコツは?',
58
+ answer: '顔がはっきりと写っているイラストや、フレームとのコントラストが高い画像を選びます。胸から上の切り抜きにすると、オンラインセッション画面で縮小しても見やすくなります。',
59
+ },
60
+ {
61
+ question: 'フレーム内でイラストをうまく配置するには?',
62
+ answer: '画像を読み込んだ後、コマ上で直接ドラッグして位置を調整します。ズーム倍率を変更することで、フレーム枠を変えずに顔の位置を調整できます。',
63
+ },
64
+ {
65
+ question: 'キャラクター名やレベルをコマに印字できますか?',
66
+ answer: 'はい。短いラベルを自由に追加し、サイズや配置を調整してコマ上の読みやすい位置にドラッグして配置できます。',
67
+ },
68
+ {
69
+ question: '出力されるPNG画像の背景は透過されますか?',
70
+ answer: 'はい。選択したフレームの外側は背景透過PNGとして保存されるため、マップの上にそのまま配置できます。',
71
+ },
72
+ {
73
+ question: 'パーティー全員のコマを一括で作成できますか?',
74
+ answer: 'はい。一括エクスポート機能を使用すると、同じフレーム設定を複数の画像に適用して一括で透明PNGを出力できます。',
75
+ },
76
+ {
77
+ question: '作成したコマデータはどこに保存されますか?',
78
+ answer: 'お使いのブラウザのローカルストレージに保存されます。サーバーへ画像がアップロードされることはありません。',
79
+ },
80
+ ];
81
+
82
+ const howTo = [
83
+ { name: 'キャラに合ったフレームを選択', text: 'PC用には円形、エネミーや戦術戦闘用には六角形、ボスには星形など、キャラクターの性質に合わせた枠を選びます。' },
84
+ { name: '画像を読み込んで位置を調整', text: 'イラストを選択またはドラッグ&ドロップし、顔が中央に来るように位置とズームを調整します。' },
85
+ { name: '必要なテキストを追加', text: '名前や役割などの短い文字を追加し、イラストを邪魔しない位置に配置します。' },
86
+ { name: '透過PNGとしてエクスポート', text: '完成したコマをPNGとしてダウンロードし、オンラインセッションツール(VTT)で使用します。' },
87
+ ];
88
+
89
+ const faqSchema: WithContext<FAQPage> = {
90
+ '@context': 'https://schema.org',
91
+ '@type': 'FAQPage',
92
+ mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })),
93
+ };
94
+
95
+ const appSchema: WithContext<SoftwareApplication> = {
96
+ '@context': 'https://schema.org',
97
+ '@type': 'SoftwareApplication',
98
+ name: 'Token Stamp Studio',
99
+ operatingSystem: 'All',
100
+ applicationCategory: 'DesignApplication',
101
+ description: 'TRPGのオンラインセッションで使える見やすいキャラクターコマ(Token)を作成。透過PNG出力、一括作成対応。',
102
+ };
103
+
104
+ const howToSchema: WithContext<HowTo> = {
105
+ '@context': 'https://schema.org',
106
+ '@type': 'HowTo',
107
+ name: 'TRPGキャラクターコマの作り方',
108
+ step: howTo.map((item) => ({ '@type': 'HowToStep', name: item.name, text: item.text })),
109
+ };
110
+
111
+ export const content: TokenStampLocaleContent = {
112
+ slug: 'token-stamp-studio',
113
+ title: 'TRPG用キャラクターコマ作成ツール(透過PNG対応)',
114
+ description: 'TRPGのオンラインセッションで使える見やすいキャラクターコマ(Token)を作成。透過PNG出力、一括作成対応。',
115
+ ui,
116
+ seo: [
117
+ { type: 'title', text: '卓上で一目で判別できるキャラクターコマを作成', level: 2 },
118
+ { type: 'paragraph', html: 'オンラインセッションや卓上ゲームにおいて、コマのシルエットはキャラクターの種別や状態を瞬時に伝える大切な要素です。適切なフレームを選び、縮小表示しても視認性を損なわないコマを作成しましょう。' },
119
+ { type: 'title', text: 'キャラクターの役割に合わせたフレーム選び', level: 2 },
120
+ { type: 'list', items: ['<strong>円形・リング:</strong> プレイヤーキャラクターや味方NPCに最適な王道スタイル。', '<strong>六角形・八角形:</strong> 戦術的なマス目や多数のエネミーの判別に便利。', '<strong>星形:</strong> ボスキャラクターや強調したいユニットに最適。', '<strong>雲型:</strong> 召喚獣や精霊、ファミリアなどの特殊な存在に。'] },
121
+ { type: 'tip', title: '実際のプレイ画面サイズを意識したデザイン', html: 'マップを縮小してコマが小さくなっても、顔の表情やテキストが潰れないか確認しながら作成するのがコツです。' },
122
+ { type: 'title', text: 'プレイ中に役立つ短く簡潔なテキスト配置', level: 2 },
123
+ { type: 'paragraph', html: 'コマ上に載せる情報は名前や簡単な状態(気絶、毒など)に絞ることで、イラストの見やすさを保ちつつ必要な情報を共有できます。' },
124
+ { type: 'title', text: 'パーティー全体のコマを一括で作成', level: 2 },
125
+ { type: 'paragraph', html: '一括作成機能を使えば、統一感のあるデザインでメンバー全員のコマを素早く作成できます。' },
126
+ { type: 'tip', title: 'ローカル自動保存機能', html: '作成途中のコマ設定はブラウザに保存されるため、レベルアップ時などの再編集も簡単です。' },
127
+ ],
128
+ faq,
129
+ bibliography,
130
+ howTo,
131
+ schemas: [faqSchema, appSchema, howToSchema] as unknown as Record<string, unknown>[],
132
+ };
@@ -0,0 +1,132 @@
1
+ import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
2
+ import { bibliography } from '../bibliography';
3
+ import type { TokenStampLocaleContent, TokenStampUI } from '../entry';
4
+
5
+ const ui: TokenStampUI = {
6
+ frameLegend: '프레임 선택',
7
+ frameHint: '이름을 읽기 전에 캐릭터의 역할이 전달되는 실루엣을 선택하세요.',
8
+ randomFrame: '무작위 프레임',
9
+ surfaceLegend: '토큰 색상 설정',
10
+ backgroundLabel: '배경색',
11
+ borderLabel: '테두리색',
12
+ textLabel: '글자색',
13
+ overlayLabel: '톤 덮어씌우기',
14
+ randomColors: '무작위 색상',
15
+ borderWidthLabel: '테두리 두께',
16
+ opacityLabel: '테두리 투명도',
17
+ overlayOpacityLabel: '초상화 투명도',
18
+ stageLabel: '실시간 토큰 제작소',
19
+ chooseImage: '초상화 선택',
20
+ clearImage: '초상화 지우기',
21
+ positionHint: '토큰 위에서 직접 이미지나 라벨을 드래그하여 이동하세요.',
22
+ markerName: '마커 이름',
23
+ markerNamePlaceholder: '마커 이름 입력',
24
+ textLegend: '플레이용 상세 정보 추가',
25
+ textHint: '이름, 레벨, 역할, 상태 등 짧은 라벨을 추가하여 토큰 위에 배치하세요.',
26
+ textPlaceholder: '캐릭터 이름 또는 역할',
27
+ addText: '라벨 추가',
28
+ removeText: '라벨 삭제',
29
+ textSizeLabel: '글자 크기',
30
+ alignmentLabel: '텍스트 정렬',
31
+ alignLeft: '왼쪽 정렬',
32
+ alignCenter: '가운데 정렬',
33
+ alignRight: '오른쪽 정렬',
34
+ imageLegend: '초상화 조절',
35
+ imageZoomLabel: '초상화 확대',
36
+ scaleLabel: '내보내기 크기',
37
+ savedMarkers: '저장된 마커',
38
+ noSavedMarkers: '저장된 마커가 여기에 표시되며 언제든지 다시 열어 수정할 수 있습니다.',
39
+ reuseMarker: '수정할 마커를 선택하세요.',
40
+ deleteMarker: '마커 삭제',
41
+ newMarker: '새 마커',
42
+ download: 'PNG 다운로드',
43
+ copy: 'PNG 복사',
44
+ downloadBatch: '일괄 다운로드',
45
+ batchLabel: '고급 일괄 내보내기',
46
+ batchHint: '여러 초상화 이미지에 현재 프레임 설정을 적용하여 한 번에 내보냅니다.',
47
+ chooseBatch: '일괄 이미지 선택',
48
+ batchReady: '{count}개의 초상화 준비 완료.',
49
+ noImage: '불러온 초상화가 없습니다',
50
+ noText: '라벨이 없습니다. 필요한 정보를 추가하세요.',
51
+ tokenDetails: '캐릭터 토큰 제어판',
52
+ exportHint: '프레임 외곽은 투명 PNG로 저장되어 VTT(온라인 세션) 및 인쇄용으로 바로 사용 가능합니다.',
53
+ };
54
+
55
+ const faq = [
56
+ {
57
+ question: '시인성이 좋은 캐릭터 토큰 초상화 조건은 무엇인가요?',
58
+ answer: '얼굴이 명확히 보이고 테두리와의 대비가 분명한 이미지를 선택하세요. 머리와 어깨 위주의 크롭이 온라인 세션 화면에서 축소되어도 잘 보입니다.',
59
+ },
60
+ {
61
+ question: '프레임 안에서 초상화 위치를 어떻게 맞추나요?',
62
+ answer: '이미지를 불러온 후 토큰 위에서 직접 드래그하여 맞춥니다. 초상화 확대 기능을 사용하면 프레임 형태 변경 없이 얼굴을 맞출 수 있습니다.',
63
+ },
64
+ {
65
+ question: '캐릭터 이름이나 레벨을 토큰에 넣을 수 있나요?',
66
+ answer: '네. 짧은 라벨을 여러 개 추가하고 크기와 정렬을 조절한 후 보기 좋은 위치로 드래그하여 배치할 수 있습니다.',
67
+ },
68
+ {
69
+ question: '저장된 PNG의 배경은 투명하게 유지되나요?',
70
+ answer: '네. 선택한 실루엣 외곽은 배경이 투명한 PNG로 저장되어 지도 위에 자연스럽게 배치됩니다.',
71
+ },
72
+ {
73
+ question: '파티원 전체의 토큰을 한 번에 만들 수 있나요?',
74
+ answer: '네. 일괄 내보내기 기능을 활용하면 일관된 프레임 스타일을 여러 이미지에 적용하여 한 번에 다운로드할 수 있습니다.',
75
+ },
76
+ {
77
+ question: '저장한 마커는 어디에 보관되나요?',
78
+ answer: '마커 데이터는 사용 중인 브라우저의 로컬 저장소에 보관됩니다. 외부 서버로 사진이 업로드되지 않습니다.',
79
+ },
80
+ ];
81
+
82
+ const howTo = [
83
+ { name: '캐릭터에 어울리는 프레임 선택', text: '플레이어 캐릭터는 원형, 전술 전투용은 육각형, 보스는 별 모양 등 캐릭터 성격에 맞는 형태를 선택합니다.' },
84
+ { name: '초상화 등록 및 위치 조절', text: '이미지를 드롭하고 얼굴이 중앙에 오도록 드래그 및 확대율을 조절합니다.' },
85
+ { name: '플레이에 필요한 라벨 추가', text: '이름이나 역할 등 짧은 텍스트를 추가하여 그림을 가리지 않는 위치에 배치합니다.' },
86
+ { name: '투명 PNG로 내보내기', text: '완성된 토큰을 PNG로 저장하여 VTT 프로그램이나 인쇄용 시트에서 사용합니다.' },
87
+ ];
88
+
89
+ const faqSchema: WithContext<FAQPage> = {
90
+ '@context': 'https://schema.org',
91
+ '@type': 'FAQPage',
92
+ mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })),
93
+ };
94
+
95
+ const appSchema: WithContext<SoftwareApplication> = {
96
+ '@context': 'https://schema.org',
97
+ '@type': 'SoftwareApplication',
98
+ name: 'Token Stamp Studio',
99
+ operatingSystem: 'All',
100
+ applicationCategory: 'DesignApplication',
101
+ description: 'TRPG 온라인 세션용 캐릭터 토큰 생성기. 맞춤 프레임, 투명 PNG 다운로드, 일괄 제작 지원.',
102
+ };
103
+
104
+ const howToSchema: WithContext<HowTo> = {
105
+ '@context': 'https://schema.org',
106
+ '@type': 'HowTo',
107
+ name: 'TRPG 캐릭터 토큰 만드는 법',
108
+ step: howTo.map((item) => ({ '@type': 'HowToStep', name: item.name, text: item.text })),
109
+ };
110
+
111
+ export const content: TokenStampLocaleContent = {
112
+ slug: 'token-stamp-studio',
113
+ title: 'TRPG 캐릭터 토큰 만들기 스튜디오 (투명 PNG)',
114
+ description: 'TRPG 온라인 세션용 캐릭터 토큰 생성기. 맞춤 프레임, 투명 PNG 다운로드, 일괄 제작 지원.',
115
+ ui,
116
+ seo: [
117
+ { type: 'title', text: '지도에서 한눈에 구분되는 캐릭터 토큰 제작', level: 2 },
118
+ { type: 'paragraph', html: 'TRPG 및 보드게임 지도에서 토큰의 실루엣은 캐릭터의 형태와 정체를 직관적으로 보여주는 중요한 요소입니다. 캐릭터에 맞는 프레임을 고르고 축소 상태에서도 잘 보이도록 디자인하세요.' },
119
+ { type: 'title', text: '캐릭터 역할에 맞는 프레임 선택', level: 2 },
120
+ { type: 'list', items: ['<strong>원형:</strong> 플레이어 캐릭터 및 동료 NPC에 가장 무난한 디자인.', '<strong>육각형/팔각형:</strong> 많은 단위가 등장하는 전술 전투에서 구분이 용이.', '<strong>별 모양:</strong> 보스 몬스터나 강조가 필요한 캐릭터용.', '<strong>구름형:</strong> 정령, 소환수, 소환물 등 특수 존재용.'] },
121
+ { type: 'tip', title: '실제 게임 플레이 화면 크기를 고려', html: '지도를 축소해 토큰이 작아진 상태에서도 얼굴과 이름이 명확히 구별되는지 확인하며 제작하세요.' },
122
+ { type: 'title', text: '게임에 도움 되는 짧은 라벨 활용', level: 2 },
123
+ { type: 'paragraph', html: '토큰에는 이름이나 짧은 상태 정보만 넣어 일러스트를 가리지 않도록 하는 것이 좋습니다.' },
124
+ { type: 'title', text: '파티 전체 토큰 일괄 생성', level: 2 },
125
+ { type: 'paragraph', html: '일괄 작업 기능을 사용하면 통일된 프레임 디자인으로 파티원 전체의 토큰을 빠르게 완성할 수 있습니다.' },
126
+ { type: 'tip', title: '자동 로컬 저장 기능', html: '작업 중인 토큰은 브라우저에 저장되므로 캐릭터 성장에 맞춰 언제든 수정할 수 있습니다.' },
127
+ ],
128
+ faq,
129
+ bibliography,
130
+ howTo,
131
+ schemas: [faqSchema, appSchema, howToSchema] as unknown as Record<string, unknown>[],
132
+ };
@@ -0,0 +1,132 @@
1
+ import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
2
+ import { bibliography } from '../bibliography';
3
+ import type { TokenStampLocaleContent, TokenStampUI } from '../entry';
4
+
5
+ const ui: TokenStampUI = {
6
+ frameLegend: 'Kies een frame',
7
+ frameHint: 'Kies het silhouet dat de tafel laat zien wie dit karakter is voordat iemand de naam leest.',
8
+ randomFrame: 'Willekeurig frame',
9
+ surfaceLegend: 'Geef kleur aan de token',
10
+ backgroundLabel: 'Achtergrond',
11
+ borderLabel: 'Rand',
12
+ textLabel: 'Tekst',
13
+ overlayLabel: 'Tint',
14
+ randomColors: 'Willekeurige kleuren',
15
+ borderWidthLabel: 'Randdikte',
16
+ opacityLabel: 'Randdekking',
17
+ overlayOpacityLabel: 'Portrettint',
18
+ stageLabel: 'Live token smederij',
19
+ chooseImage: 'Kies portret',
20
+ clearImage: 'Portret wissen',
21
+ positionHint: 'Sleep het portret of de labels rechtstreeks op de token.',
22
+ markerName: 'Markernaam',
23
+ markerNamePlaceholder: 'Geef deze marker een naam',
24
+ textLegend: 'Voeg leesbare details toe',
25
+ textHint: 'Gebruik korte labels zoals naam, niveau, rol of status. Sleep elk label naar de token.',
26
+ textPlaceholder: 'Karakternaam of rol',
27
+ addText: 'Label toevoegen',
28
+ removeText: 'Label verwijderen',
29
+ textSizeLabel: 'Tekstgrootte',
30
+ alignmentLabel: 'Tekstuitlijning',
31
+ alignLeft: 'Links uitlijnen',
32
+ alignCenter: 'Centreren',
33
+ alignRight: 'Rechts uitlijnen',
34
+ imageLegend: 'Pas het portret aan',
35
+ imageZoomLabel: 'Portretzoom',
36
+ scaleLabel: 'Exportschaal',
37
+ savedMarkers: 'Opgeslagen markers',
38
+ noSavedMarkers: 'Opgeslagen markers verschijnen hier om opnieuw te openen en te bewerken.',
39
+ reuseMarker: 'Selecteer een marker om deze opnieuw te openen.',
40
+ deleteMarker: 'Marker verwijderen',
41
+ newMarker: 'Nieuwe marker',
42
+ download: 'PNG downloaden',
43
+ copy: 'PNG kopiëren',
44
+ downloadBatch: 'Batch downloaden',
45
+ batchLabel: 'Geavanceerde batchexport',
46
+ batchHint: 'Optioneel: exporteer meerdere portretten met het huidige frame en de kleurinstellingen.',
47
+ chooseBatch: 'Kies portretten',
48
+ batchReady: '{count} portretten klaar om te smeden.',
49
+ noImage: 'Geen portret geladen',
50
+ noText: 'Nog geen labels. Voeg details toe die je groep nodig heeft.',
51
+ tokenDetails: 'Karaktertoken bediening',
52
+ exportHint: 'De PNG is transparant buiten het gekozen silhouet, klaar voor VTT of afdrukken.',
53
+ };
54
+
55
+ const faq = [
56
+ {
57
+ question: 'Wat maakt een goed portret voor een karaktertoken?',
58
+ answer: 'Kies een afbeelding met een duidelijk gezicht en voldoende contrast met het frame. Een uitsnede van hoofd en schouders blijft goed leesbaar op het virtuele speelbord.',
59
+ },
60
+ {
61
+ question: 'Hoe positioneer ik het portret het beste in het frame?',
62
+ answer: 'Upload de afbeelding en sleep deze op de token om het gezicht te centreren. Gebruik de portretzoom om het gezicht te vergroten zonder het frame aan te passen.',
63
+ },
64
+ {
65
+ question: 'Kan ik een karakternaam en niveau toevoegen?',
66
+ answer: 'Ja. Voeg korte labels toe, pas de tekstgrootte en uitlijning aan, en sleep ze naar een goed leesbare plek op de token.',
67
+ },
68
+ {
69
+ question: 'Blijft het PNG-bestand transparant buiten de token?',
70
+ answer: 'Ja. Het geëxporteerde bestand behoudt een transparante achtergrond buiten het gekozen silhouet, ideaal voor gebruik op digitale kaarten.',
71
+ },
72
+ {
73
+ question: 'Kan ik in één keer tokens voor een hele groep maken?',
74
+ answer: 'Ja. Gebruik de batchexport om meerdere portretten in te laden en voor elk portret een transparante PNG te genereren.',
75
+ },
76
+ {
77
+ question: 'Waar worden mijn opgeslagen markers opgeslagen?',
78
+ answer: 'Markers worden lokaal opgeslagen in je browser. Er worden geen afbeeldingen naar een externe server geüpload.',
79
+ },
80
+ ];
81
+
82
+ const howTo = [
83
+ { name: 'Kies het karaktersilhouet', text: 'Selecteer een frame dat bij de rol past: rond voor een held, zeshoekig voor tactische gevechten of een ster voor een baas.' },
84
+ { name: 'Upload en centreer het portret', text: 'Kies een afbeelding, sleep deze naar de token en pas de zoom aan zodat het gezicht centraal staat.' },
85
+ { name: 'Voeg belangrijke informatie toe', text: 'Plaats een korte naam of status op de token zonder de illustratie te overlappen.' },
86
+ { name: 'Exporteer als transparante PNG', text: 'Download de transparante PNG voor gebruik op je digitale speelbord of printvel.' },
87
+ ];
88
+
89
+ const faqSchema: WithContext<FAQPage> = {
90
+ '@context': 'https://schema.org',
91
+ '@type': 'FAQPage',
92
+ mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })),
93
+ };
94
+
95
+ const appSchema: WithContext<SoftwareApplication> = {
96
+ '@context': 'https://schema.org',
97
+ '@type': 'SoftwareApplication',
98
+ name: 'Token Stamp Studio',
99
+ operatingSystem: 'All',
100
+ applicationCategory: 'DesignApplication',
101
+ description: 'Maak duidelijke karaktertokens voor tafel-RPG\'s met aangepaste frames, labels, transparantie en batchexport.',
102
+ };
103
+
104
+ const howToSchema: WithContext<HowTo> = {
105
+ '@context': 'https://schema.org',
106
+ '@type': 'HowTo',
107
+ name: 'Hoe maak je een karaktertoken voor tafel-RPG\'s',
108
+ step: howTo.map((item) => ({ '@type': 'HowToStep', name: item.name, text: item.text })),
109
+ };
110
+
111
+ export const content: TokenStampLocaleContent = {
112
+ slug: 'karakter-token-maker-rpg-tafel',
113
+ title: 'Karakter Token Maker voor Tafel RPGs',
114
+ description: 'Maak duidelijke karaktertokens voor tafel-RPG\'s met aangepaste frames, labels, transparantie en batchexport.',
115
+ ui,
116
+ seo: [
117
+ { type: 'title', text: 'Ontwerp duidelijke karaktertokens voor elke digitale kaart van je RPG avontuur', level: 2 },
118
+ { type: 'paragraph', html: 'Een token is een essentieel visueel communicatiemiddel op de virtuele speeltafel. Het silhouet laat de groep meteen zien of het om een held, een gevaarlijk monster, een betoveringseffect of een belangrijke bondgenoot gaat voordat iemand inzoomt op de kaart. Kies het juiste frame en zorg dat het gezicht en de tekst goed zichtbaar blijven op de schaal van jouw speelbord.' },
119
+ { type: 'title', text: 'Kies het juiste frame voor elk type karakter in je campagne', level: 2 },
120
+ { type: 'list', items: ['<strong>Rond of ring:</strong> klassiek en betrouwbaar voor spelerskarakters en terugkerende bondgenoten.', '<strong>Zeshoek of achthoek:</strong> ideaal voor tactische gevechten met veel verschillende eenheden.', '<strong>Ster:</strong> perfect voor bazen, kampioenen of karakters die direct de aandacht vragen.', '<strong>Wolk:</strong> een zachte vorm voor geesten, magische wezens en fabeldieren.'] },
121
+ { type: 'tip', title: 'Ontwerp voor het kleinste formaat waarop je daadwerkelijk speelt', html: 'Zoom uit op de digitale kaart totdat de token slechts enkele tientallen pixels groot is. Als gezicht, rand en tekst nog steeds goed te onderscheiden zijn, werkt je token perfect tijdens drukke gevechten.' },
122
+ { type: 'title', text: 'Houd labels kort en functioneel tijdens het spelen', level: 2 },
123
+ { type: 'paragraph', html: 'Een token is geen vervanging voor een volledig karakterblad. Voeg alleen de belangrijkste informatie toe die de tafel voortdurend nodig heeft: een korte naam, een niveau, een rol of een status zoals verdoofd. Te lange zinnen zorgen voor visuele ruis en leiden af van het portret.' },
124
+ { type: 'title', text: 'Maak in één keer tokens voor de hele avonturiersgroep zonder hun identiteit te verliezen', level: 2 },
125
+ { type: 'paragraph', html: 'Met de batchexport geef je de hele avonturiersgroep dezelfde visuele stijl terwijl elk portret zijn eigen unieke uitstraling behoudt. Een consistente framing zorgt voor eenheid in de groep terwijl de gezichten direct herkenbaar blijven.' },
126
+ { type: 'tip', title: 'Automatische lokale opslag op jouw apparaat', html: 'Je actieve marker wordt automatisch opgeslagen in de lokale opslag van je browser zodat je deze later eenvoudig kunt openen en aanpassen wanneer het karakter in niveau stijgt.' },
127
+ ],
128
+ faq,
129
+ bibliography,
130
+ howTo,
131
+ schemas: [faqSchema, appSchema, howToSchema] as unknown as Record<string, unknown>[],
132
+ };
@@ -0,0 +1,132 @@
1
+ import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
2
+ import { bibliography } from '../bibliography';
3
+ import type { TokenStampLocaleContent, TokenStampUI } from '../entry';
4
+
5
+ const ui: TokenStampUI = {
6
+ frameLegend: 'Wybierz ramkę',
7
+ frameHint: 'Wybierz sylwetkę, która informuje graczy, kim jest postać, zanim przeczytają jej imię.',
8
+ randomFrame: 'Losowa ramka',
9
+ surfaceLegend: 'Stylizuj żeton',
10
+ backgroundLabel: 'Tło',
11
+ borderLabel: 'Ramka',
12
+ textLabel: 'Tekst',
13
+ overlayLabel: 'Odcień',
14
+ randomColors: 'Losowe kolory',
15
+ borderWidthLabel: 'Grubość ramki',
16
+ opacityLabel: 'Przezroczystość ramki',
17
+ overlayOpacityLabel: 'Odcień portretu',
18
+ stageLabel: 'Kuźnia żetonów na żywo',
19
+ chooseImage: 'Wybierz portret',
20
+ clearImage: 'Usuń portret',
21
+ positionHint: 'Przeciągnij portret lub etykiety bezpośrednio na żetonie.',
22
+ markerName: 'Nazwa znacznika',
23
+ markerNamePlaceholder: 'Nazwij ten znacznik',
24
+ textLegend: 'Dodaj czytelne detale',
25
+ textHint: 'Używaj krótkich etykiet, takich jak imię, poziom, rola lub status. Przeciągnij każdą na żeton.',
26
+ textPlaceholder: 'Imię postaci lub rola',
27
+ addText: 'Dodaj etykietę',
28
+ removeText: 'Usuń etykietę',
29
+ textSizeLabel: 'Rozmiar czcionki',
30
+ alignmentLabel: 'Wyrównanie etykiety',
31
+ alignLeft: 'Wyrównaj do lewej',
32
+ alignCenter: 'Wyśrodkuj',
33
+ alignRight: 'Wyrównaj do prawej',
34
+ imageLegend: 'Dostosuj portret',
35
+ imageZoomLabel: 'Powiększenie portretu',
36
+ scaleLabel: 'Skala eksportu',
37
+ savedMarkers: 'Zapisane znaczniki',
38
+ noSavedMarkers: 'Zapisane znaczniki pojawią się tutaj, aby móc je ponownie otworzyć i edytować.',
39
+ reuseMarker: 'Wybierz znacznik, aby otworzyć go w kuźni.',
40
+ deleteMarker: 'Usuń znacznik',
41
+ newMarker: 'Nowy znacznik',
42
+ download: 'Pobierz PNG',
43
+ copy: 'Kopiuj PNG',
44
+ downloadBatch: 'Pobierz paczkę',
45
+ batchLabel: 'Zaawansowany eksport seryjny',
46
+ batchHint: 'Opcjonalnie: wyeksportuj kilka portretów z aktualną ramką i kolorami.',
47
+ chooseBatch: 'Wybierz portrety',
48
+ batchReady: '{count} portretów gotowych do wykucia.',
49
+ noImage: 'Brak załadowanego portretu',
50
+ noText: 'Brak etykiet. Dodaj szczegóły potrzebne twojej drużynie.',
51
+ tokenDetails: 'Sterowanie żetonem postaci',
52
+ exportHint: 'Plik PNG jest przezroczysty poza wybraną sylwetką, gotowy do VTT lub druku.',
53
+ };
54
+
55
+ const faq = [
56
+ {
57
+ question: 'Co decyduje o dobrym portrecie na żetonie postaci?',
58
+ answer: 'Wybierz ilustrację z wyraźną twarzą i dobrym kontrastem względem ramki. Kadr od głowy do ramion pozostaje czytelny nawet przy znacznej pomniejszeniu na wirtualnym stole.',
59
+ },
60
+ {
61
+ question: 'Jak najlepiej wykadrować portret w ramce?',
62
+ answer: 'Wgraj obraz i przeciągnij go bezpośrednio na żetonie. Użyj powiększenia portretu, aby przybliżyć twarz bez zmiany kształtu ramki.',
63
+ },
64
+ {
65
+ question: 'Czy mogę dodać imię postaci i poziom?',
66
+ answer: 'Tak. Dodaj krótkie etykiety, dostosuj ich rozmiar i wyrównanie, a następnie przeciągnij je w czytelne miejsce na żetonie.',
67
+ },
68
+ {
69
+ question: 'Czy plik PNG zachowuje przezroczystość poza ramką?',
70
+ answer: 'Tak. Wyeksportowany plik PNG ma przezroczyste tło poza wybraną sylwetką, co ułatwia nakładanie żetonu na mapy.',
71
+ },
72
+ {
73
+ question: 'Czy mogę stworzyć żetony dla całej drużyny jednocześnie?',
74
+ answer: 'Tak. Użyj eksportu seryjnego, aby załadować wiele portretów i wygenerować przezroczysty plik PNG dla każdego z nich.',
75
+ },
76
+ {
77
+ question: 'Gdzie przechowywane są moje zapisane znaczniki?',
78
+ answer: 'Zapisane znaczniki są przechowywane lokalnie w pamięci Twojej przeglądarki. Żadne pliki nie są wysyłane na zewnętrzne serwery.',
79
+ },
80
+ ];
81
+
82
+ const howTo = [
83
+ { name: 'Wybierz sylwetkę postaci', text: 'Zacznij od ramki pasującej do roli: okrągłej dla bohatera, sześciokątnej do walki taktycznej lub gwiazdy dla bossa.' },
84
+ { name: 'Wgraj i dopasuj portret', text: 'Wybierz obraz, przeciągnij go na żeton i dostosuj powiększenie tak, aby twarz była w centrum.' },
85
+ { name: 'Dodaj przydatne etykiety', text: 'Wpisz krótkie imię lub status, nie zasłaniając kluczowych elementów ilustracji.' },
86
+ { name: 'Wyeksportuj jako przezroczysty PNG', text: 'Pobierz plik PNG gotowy do użycia na wirtualnym stole (VTT) lub w druku.' },
87
+ ];
88
+
89
+ const faqSchema: WithContext<FAQPage> = {
90
+ '@context': 'https://schema.org',
91
+ '@type': 'FAQPage',
92
+ mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })),
93
+ };
94
+
95
+ const appSchema: WithContext<SoftwareApplication> = {
96
+ '@context': 'https://schema.org',
97
+ '@type': 'SoftwareApplication',
98
+ name: 'Token Stamp Studio',
99
+ operatingSystem: 'All',
100
+ applicationCategory: 'DesignApplication',
101
+ description: 'Twórz czytelne żetony postaci do gier RPG z własnymi ramkami, etykietami, przezroczystością i eksportem seryjnym PNG.',
102
+ };
103
+
104
+ const howToSchema: WithContext<HowTo> = {
105
+ '@context': 'https://schema.org',
106
+ '@type': 'HowTo',
107
+ name: 'Jak zrobić żeton postaci do RPG',
108
+ step: howTo.map((item) => ({ '@type': 'HowToStep', name: item.name, text: item.text })),
109
+ };
110
+
111
+ export const content: TokenStampLocaleContent = {
112
+ slug: 'kreator-zetonow-postaci-rpg-stolosw',
113
+ title: 'Kreator Żetonów Postaci do Gier RPG (Tokens)',
114
+ description: 'Twórz czytelne żetony postaci do gier RPG z własnymi ramkami, etykietami, przezroczystością i eksportem seryjnym PNG.',
115
+ ui,
116
+ seo: [
117
+ { type: 'title', text: 'Projektuj czytelne żetony postaci na dowolną mapę gry RPG', level: 2 },
118
+ { type: 'paragraph', html: 'Żeton to kluczowy element komunikacji wizualnej na stole gry RPG. Jego sylwetka natychmiast informuje drużynę, czy ma do czynienia z bohaterem, potworem, efektem zaklęcia czy postronnym NPC zanim ktokolwiek przybliży widok mapy. Wybierz odpowiednią ramkę i zadbaj o pełną czytelność ilustracji oraz napisów na wirtualnym stole.' },
119
+ { type: 'title', text: 'Dobierz właściwą ramkę do charakteru i roli postaci', level: 2 },
120
+ { type: 'list', items: ['<strong>Koło lub pierścień:</strong> klasyczny i niezawodny wybór dla postaci graczy oraz stałych sojuszników.', '<strong>Sześciokąt lub ośmiokąt:</strong> świetny do starć taktycznych z wieloma jednostkami na planszy.', '<strong>Gwiazda:</strong> idealna dla bossów, championów i kluczowych celów wymagających natychmiastowej uwagi.', '<strong>Chmura:</strong> miękki kształt dla istot duchowych, chowańców i istot fantastycznych.'] },
121
+ { type: 'tip', title: 'Projektuj z myślą o najmniejszym rozmiarze na mapie taktycznej', html: 'Oddal widok mapy, aż żeton stanie się bardzo mały. Jeśli twarz, ramka i tekst nadal są wyraźnie rozróżnialne, Twój żeton sprawdzi się świetnie podczas dynamicznej rozgrywki.' },
122
+ { type: 'title', text: 'Stosuj krótkie i przydatne etykiety podczas sesji', level: 2 },
123
+ { type: 'paragraph', html: 'Żeton nie zastępuje karty postaci. Dodaj tylko najpotrzebniejsze informacje, takie jak imię, poziom lub aktualny status postaci (np. ogłuszony). Długie zdania tworzą szum wizualny i zasłaniają portret.' },
124
+ { type: 'title', text: 'Przygotuj żetony dla całej drużyny za jednym razem bez utraty ich stylu', level: 2 },
125
+ { type: 'paragraph', html: 'Eksport seryjny pozwala nadać spójny styl graficzny całej drużynie po sesji zero, zachowując indywidualny charakter każdego portretu. Jednolita ramka spaja drużynę wizualnie.' },
126
+ { type: 'tip', title: 'Automatyczne zapisywanie lokalne na Twoim urządzeniu', html: 'Prace nad żetonem są automatycznie zapisywane w pamięci przeglądarki, dzięki czemu możesz łatwo modyfikować go w trakcie trwania całej kampanii.' },
127
+ ],
128
+ faq,
129
+ bibliography,
130
+ howTo,
131
+ schemas: [faqSchema, appSchema, howToSchema] as unknown as Record<string, unknown>[],
132
+ };