diff --git a/README.md b/README.md
index 7c335e7..375df09 100644
--- a/README.md
+++ b/README.md
@@ -134,7 +134,7 @@ renders an image, including templates that contain only text.
使用流程:选择模板 → 编辑数据 → 生成预览 → 显示到画框。生成预览只创建本地图片;
保存默认数据只保存配置,两者都不会更新设备。自动化模板任务每次运行重新生成图片。
-- **照片与文字 / Photo + Text**:所选照片铺满画面,底部叠加文字。
+- **照片与文字 / Photo + Text**:标题、中央照片区域、下方正文;与照片数据源任务的底部水印布局不同。
- **家庭早报 / Daily Dashboard**:日期、天气、事项、一句话与所选照片区域。
- **天气 / Weather**:当前天气与三天预报;天气 JSON 留空时使用配置的 Provider。
- **日历、每日诗词、一句话、系统告警**:将相应信息排版为图片,不自动选择图库照片。
diff --git a/pigway_frame_flow/web/app.js b/pigway_frame_flow/web/app.js
index f3381fa..b689a3d 100644
--- a/pigway_frame_flow/web/app.js
+++ b/pigway_frame_flow/web/app.js
@@ -67,9 +67,10 @@ async function templateEditor(selected){
const raw=$('#template-data');const assets=await api('/api/v1/assets?source=uploaded&limit=200');let values=JSON.parse(raw.value);
const panel=document.createElement('div');panel.id='template-fields';raw.before(panel);
const labels={title:state.lang==='zh'?'标题':'Title',message:state.lang==='zh'?'正文':'Message',quote:state.lang==='zh'?'一句话':'Quote',author:state.lang==='zh'?'作者':'Author',events:t('eventsHelp'),date:t('date'),weekday:state.lang==='zh'?'星期(留空自动)':'Weekday (blank for automatic)',weather:state.lang==='zh'?'天气数据(JSON,可留空使用 Provider)':'Weather JSON (blank uses provider)'};
+ const fieldHelp={title:'helpTitle',message:'helpMessage',quote:'helpQuote',author:'helpAuthor',events:'helpEvents',date:'helpDate',weekday:'helpWeekday',weather:'helpWeather',poem_title:'helpPoemTitle',poem_author:'helpPoemAuthor',poem_lines:'helpPoemLines'};
const fields=[...new Set(['title',...selected.fields.filter(k=>Object.hasOwn(selected.defaults,k)),...(['daily-dashboard','calendar'].includes(selected.id)?['events','date','weekday']:selected.id==='daily-poetry'?['date']:[]),...(selected.id==='weather'||selected.id==='daily-dashboard'?['weather']:[]),...(['photo-text','daily-dashboard'].includes(selected.id)?['photo_id']:[])])];
- function invalidate(){state.templatePreview=null;$('#display-template').disabled=true;$('#template-preview').className='empty';$('#template-preview').textContent=t('previewHint');}
- function build(){panel.innerHTML=`
${t('formEditor')} `+fields.map(k=>k==='photo_id'?`${t('photo')} ${t('noPhoto')} ${values.photo_id&&!assets.some(a=>a.asset_id===values.photo_id)?`${state.lang==='zh'?'已有选择不在上传照片列表中,请重新选择':'Previous selection is outside uploaded photos; choose again'} `:''}${assets.map(a=>`${esc(a.name)} `).join('')}${state.lang==='zh'?'只列出上传的图片,不包含模板生成图。没有照片时,请使用下方文件选择器上传。':'Uploaded images only; generated templates are excluded. Upload a photo below if needed.'}
`:`${esc(labels[k]||t(k))}
`).join('');panel.querySelectorAll('[data-field]').forEach(el=>el.oninput=()=>{try{const k=el.dataset.field;let v=el.value;if(k==='events')v=v.split('\n').filter(x=>x.trim());if(['weather','forecast'].includes(k))v=v.trim()?JSON.parse(v):null;if(v===null||v==='')delete values[k];else values[k]=v;raw.value=JSON.stringify(values,null,2);el.setCustomValidity('');invalidate();}catch{el.setCustomValidity(t('INVALID_REQUEST'));el.reportValidity();}});}
+ function invalidate(){state.templatePreview=null;$('#display-template').disabled=true;$('#template-preview').className='empty';$('#template-preview').textContent=t('templatePreviewHint');}
+ function build(){panel.innerHTML=`${t('formEditor')} ${t('templateEditHelp')}
`+fields.map(k=>k==='photo_id'?`${t('photo')} ${t('noPhoto')} ${values.photo_id&&!assets.some(a=>a.asset_id===values.photo_id)?`${state.lang==='zh'?'已有选择不在上传照片列表中,请重新选择':'Previous selection is outside uploaded photos; choose again'} `:''}${assets.map(a=>`${esc(a.name)} `).join('')}${state.lang==='zh'?'只列出上传的图片,不包含模板生成图。没有照片时,请使用下方文件选择器上传。':'Uploaded images only; generated templates are excluded. Upload a photo below if needed.'}
`:`${esc(labels[k]||t(k))} ${fieldHelp[k]?`
${t(fieldHelp[k])}
`:''}
`).join('');panel.querySelectorAll('[data-field]').forEach(el=>el.oninput=()=>{try{const k=el.dataset.field;let v=el.value;if(k==='events')v=v.split('\n').filter(x=>x.trim());if(['weather','forecast'].includes(k))v=v.trim()?JSON.parse(v):null;if(v===null||v==='')delete values[k];else values[k]=v;raw.value=JSON.stringify(values,null,2);el.setCustomValidity('');invalidate();}catch{el.setCustomValidity(t('INVALID_REQUEST'));el.reportValidity();}});}
build();const advanced=document.createElement('details');advanced.innerHTML=`${t('advanced')} `;raw.before(advanced);advanced.append(raw);raw.oninput=()=>{invalidate();try{values=JSON.parse(raw.value);if(!values||typeof values!=='object'||Array.isArray(values))throw Error();raw.setCustomValidity('');build();}catch{raw.setCustomValidity(t('INVALID_REQUEST'));}};
const reset=document.createElement('button');reset.id='reset-template';reset.textContent=t('resetTemplate');$('#save-template').after(reset);bind('reset-template',()=>confirmDialog(t('resetConfirm'),async()=>{await api('/api/v1/templates/'+selected.id+'/config',{method:'DELETE'});await navigate();}));
const save=$('#save-template');const oldSave=save.onclick;save.onclick=async e=>{if([...panel.querySelectorAll('textarea'),raw].some(x=>!x.checkValidity())){toast(t('INVALID_REQUEST'));return;}await oldSave(e);};
@@ -80,7 +81,7 @@ const views={
async dashboard(epoch){const d=await api('/api/v1/devices/'+state.device);if(epoch!==state.epoch)return;const s=d.slideshow;$('#main').innerHTML=notice()+`${d.power.battery_percent!==null&&d.power.battery_percent<20?`${t('lowBattery')}
`:''}● ${t(d.status).toUpperCase()} ${esc(d.name)} ${esc(d.model)} · ${esc(d.model_code)} · ${d.display.width} × ${d.display.height}
${buttons('go-upload','upload',true)}${buttons('restore','restore')}${buttons('refresh-device','refresh')}
${t('refreshInterval')}
${[['battery',d.power.battery_percent===null?'—':d.power.battery_percent+'%'],['current',d.current_content.id??'—'],['sync',t(d.current_content.synced?'synced':'syncing')],['firmware',d.firmware]].map(([l,v])=>`
`).join('')}
${t('device')} ${detail('heartbeat',fmt(d.last_seen_at))}${detail('rotation',d.display.rotation+'°')}${detail('timezone',d.timezone)}${detail('coverId',d.current_content.cover_id??'—')}${detail('storage',d.storage_used_bytes===null?'—':(d.storage_used_bytes/1024/1024).toFixed(1)+' MiB')}${detail('model',t(d.model_verified?'modelVerified':'modelConfigured'))}
${t('cloudRotation')} ${detail('mode',s.mode?t(s.mode):'—')}${detail('interval',s.interval_minutes==null?'—':s.interval_minutes+' '+t('minutes'))}
${t('rotationNotice')}
${t('playlists')} → `;bind('go-upload',()=>navigate('upload'));bind('refresh-device',async()=>{await api('/api/v1/devices/'+state.device+'?refresh=true');await navigate();});$('#restore').disabled=!d.can_restore;bind('restore',()=>accepted('/api/v1/devices/'+state.device+'/restore',{}));$('#go-playlists').onclick=e=>{e.preventDefault();navigate('playlists');};},
async gallery(epoch){let items=state.tab==='cloud'?await api('/api/v1/devices/'+state.device+'/images'):await api('/api/v1/assets?limit=200&offset='+(state.assetOffset||0)+'&origin='+encodeURIComponent(state.assetOrigin||'all')+(state.assetJob?'&job_id='+encodeURIComponent(state.assetJob):''));if(epoch!==state.epoch)return;state.gallery=items;$('#main').innerHTML=notice()+`${t('cloud')} ${t('local')}
${buttons('gallery-refresh','refresh')}${state.tab==='cloud'?buttons('show-name','displayByName'):''}${buttons('gallery-upload','upload',true)}
${state.tab==='local'?`${t('uploadNotice')}
`:''}${items.length?`${items.map((x,i)=>`
${esc(x.name)} ${state.tab==='cloud'?'#'+x.image_id:'LOCAL'} · ${esc(fmt(x.created_at))} ${t(x.current?'current':'display')} ${t('original')} ${t('delete')}
`).join('')}
`:`${t('noImages')} ${t('emptyHint')}
`}`;bind('cloud-tab',()=>{state.tab='cloud';return navigate();});bind('local-tab',()=>{state.tab='local';return navigate();});bind('gallery-refresh',()=>navigate());bind('gallery-upload',()=>navigate('upload'));bind('show-name',()=>{showModal(`${t('displayByName')} ${t('name')}
${buttons('modal-cancel','cancel')}${buttons('show-name-confirm','display',true)}
`);bind('show-name-confirm',async()=>{const name=$('#image-name').value;$('#modal').close();displayDialog({type:'image',image_name:name});});});hydrateImages();document.querySelectorAll('[data-show]').forEach(b=>b.onclick=busy(()=>{const x=items[b.dataset.show];if(x.current)return;return displayDialog(state.tab==='cloud'?{type:'image',image_id:x.image_id}:{type:'image',asset_id:x.asset_id});}));document.querySelectorAll('[data-original]').forEach(b=>b.onclick=busy(async()=>{const x=items[b.dataset.original];showModal(`${esc(x.name)} ${buttons('modal-cancel','cancel')}
`);await blobImage($('#original-image'),x.url);}));document.querySelectorAll('[data-delete]').forEach(b=>b.onclick=()=>{const x=items[b.dataset.delete];confirmDialog(x.current?t('deleteCurrent'):t('deleteConfirm'),async()=>{if(state.tab==='local'){await api('/api/v1/assets/'+x.asset_id,{method:'DELETE'});}else{const result=await api(`/api/v1/devices/${state.device}/images/${x.image_id}?confirm_current=${x.current}`,{method:'DELETE',headers:{'Idempotency-Key':'web-'+clientUUID()}});await waitOperation(result.operation_id);}await navigate();});});},
async upload(){state.preview=null;$('#main').innerHTML=notice()+`${t('uploadNotice')}
${t('upload')} ${buttons('make-preview','preview',true)}${t('previewHint')}
${t('preview')} ${t('previewHint')}
${t('staging')} ${t('display')}
`;bind('make-preview',async()=>{const file=$('#file').files[0];if(!file)throw new Error(t('selectFile'));const form=new FormData();form.append('file',file);form.append('fit',$('#fit').value);form.append('profile',$('#profile').value);state.preview=await api('/api/v1/preview',{method:'POST',body:form});$('#preview-box').className='';$('#preview-box').innerHTML=' ';await blobImage($('#upload-preview'),state.preview.url);$('#save-local').disabled=false;$('#display-upload').disabled=!liveWriteAllowed();});for(const id of ['file','fit','profile'])$('#'+id).onchange=()=>{state.preview=null;$('#save-local').disabled=true;$('#display-upload').disabled=true;};bind('save-local',async()=>{const id=await accepted('/api/v1/devices/'+state.device+'/upload',{type:'image',asset_id:state.preview.asset_id});await waitOperation(id);state.tab='local';return navigate('gallery');});bind('display-upload',()=>displayDialog({type:'image',asset_id:state.preview.asset_id}));},
- async templates(){state.templates=await api('/api/v1/templates');const selected=state.templates.find(x=>x.id===state.selectedTemplate)||state.templates[0];state.selectedTemplate=selected.id;if(state.pendingTemplateData?.template===selected.id){selected.defaults=state.pendingTemplateData.data;state.initialProfile=state.pendingTemplateData.profile;state.pendingTemplateData=null;}state.templatePreview=null;$('#main').innerHTML=notice()+`${t('templateHint')}
${t('templateSteps')}
${state.templates.map((x,i)=>`
${{'daily-poetry':'詩','calendar':'▦','daily-dashboard':'☀','photo-text':'▣','quote':'❝','system-alert':'◒','weather':'☁'}[x.id]||'▦'}
${esc(x.name.split(' / ')[state.lang==='zh'?1:0]||x.name)} 1200 × 1600 · ${esc(x.id)} `).join('')}
${t('templateData')} ${t(['photo-text','daily-dashboard'].includes(selected.id)?'templatePhotoHelp':'templateContentHelp')}
${['weather','daily-dashboard'].includes(selected.id)?`${t('templateWeatherHelp')}
`:''}${t('profile')} ${t('color')} ${t('grayscale')}
${buttons('render-template','render',true)}${buttons('save-template','saveTemplate')}
${t('preview')} ${t('previewHint')}
${t('display')} `;document.querySelectorAll('[data-template]').forEach(b=>{b.onclick=()=>{state.selectedTemplate=b.dataset.template;navigate();};b.onkeydown=e=>{if(e.key==='Enter')b.click();};});bind('render-template',async()=>{const content={type:'template',template:selected.id,data:JSON.parse($('#template-data').value),profile:$('#template-profile').value};if([...document.querySelectorAll('#template-fields textarea'),$('#template-data')].some(x=>!x.checkValidity())){toast(t('INVALID_REQUEST'));return;}const id=await accepted('/api/v1/render',content);$('#template-preview').textContent=t('previewLoading');const op=await waitOperation(id);state.templatePreview=op.result.asset_id;$('#template-preview').className='';$('#template-preview').innerHTML=' ';await blobImage($('#template-image'),op.result.url);$('#display-template').disabled=!liveWriteAllowed();});bind('save-template',async()=>{await api('/api/v1/templates/'+selected.id+'/config',{method:'PUT',body:{data:JSON.parse($('#template-data').value)}});toast(t('done'));});$('#template-data').oninput=()=>$('#display-template').disabled=true;$('#template-profile').onchange=()=>$('#display-template').disabled=true;bind('display-template',()=>displayDialog({type:'image',asset_id:state.templatePreview}));await templateEditor(selected);if(state.initialProfile){$('#template-profile').value=state.initialProfile;state.initialProfile=null;}},
+ async templates(){state.templates=await api('/api/v1/templates');const selected=state.templates.find(x=>x.id===state.selectedTemplate)||state.templates[0];state.selectedTemplate=selected.id;if(state.pendingTemplateData?.template===selected.id){selected.defaults=state.pendingTemplateData.data;state.initialProfile=state.pendingTemplateData.profile;state.pendingTemplateData=null;}state.templatePreview=null;$('#main').innerHTML=notice()+`${t('templateHint')}
${t('templateSteps')}
${state.templates.map((x,i)=>`
${{'daily-poetry':'詩','calendar':'▦','daily-dashboard':'☀','photo-text':'▣','quote':'❝','system-alert':'◒','weather':'☁'}[x.id]||'▦'}
${esc(x.name.split(' / ')[state.lang==='zh'?1:0]||x.name)} 1200 × 1600 · ${esc(x.id)} `).join('')}
${t('templateData')} ${t('templateGuideTitle')}
${t({'photo-text':'guidePhotoText','daily-dashboard':'guideDashboard',weather:'guideWeather',calendar:'guideCalendar',quote:'guideQuote','daily-poetry':'guidePoetry','system-alert':'guideAlert'}[selected.id]||'templateContentHelp')}
${['weather','daily-dashboard'].includes(selected.id)?`${t('templateWeatherHelp')}
`:''}${t('profile')} ${t('color')} ${t('grayscale')} ${t('helpProfile')}
${t('templateActionHelp')}
${t('templateAutomationHelp')}
${buttons('render-template','render',true)}${buttons('save-template','saveTemplate')}
${t('preview')} ${t('templatePreviewHint')}
${t('display')} `;document.querySelectorAll('[data-template]').forEach(b=>{b.onclick=()=>{state.selectedTemplate=b.dataset.template;navigate();};b.onkeydown=e=>{if(e.key==='Enter')b.click();};});bind('render-template',async()=>{const content={type:'template',template:selected.id,data:JSON.parse($('#template-data').value),profile:$('#template-profile').value};if([...document.querySelectorAll('#template-fields textarea'),$('#template-data')].some(x=>!x.checkValidity())){toast(t('INVALID_REQUEST'));return;}const id=await accepted('/api/v1/render',content);$('#template-preview').textContent=t('previewLoading');const op=await waitOperation(id);state.templatePreview=op.result.asset_id;$('#template-preview').className='';$('#template-preview').innerHTML=' ';await blobImage($('#template-image'),op.result.url);$('#display-template').disabled=!liveWriteAllowed();});bind('save-template',async()=>{await api('/api/v1/templates/'+selected.id+'/config',{method:'PUT',body:{data:JSON.parse($('#template-data').value)}});toast(t('done'));});$('#template-data').oninput=()=>$('#display-template').disabled=true;$('#template-profile').onchange=()=>$('#display-template').disabled=true;bind('display-template',()=>displayDialog({type:'image',asset_id:state.templatePreview}));await templateEditor(selected);if(state.initialProfile){$('#template-profile').value=state.initialProfile;state.initialProfile=null;}},
async automation(epoch){const jobs=await api('/api/v1/jobs');if(epoch!==state.epoch)return;$('#main').innerHTML=notice()+`Asia/Shanghai · ${t('automation')}
${buttons('new-job','newJob',true)}
${jobs.length?`
${['name','schedule','status','nextRun','lastRun','result','action'].map(x=>`${t(x)} `).join('')} ${jobs.map((j,i)=>`${esc(j.name)} ${esc(j.device_id)} ${t(j.schedule.type)} ${esc(j.schedule.time||j.schedule.cron||fmt(j.schedule.at))} ${t(j.enabled?'enabled':'disabled')} ${fmt(j.next_run)} ${fmt(j.last_run)} ${esc(j.last_result)}${t('edit')} ${t(j.enabled?'disabled':'enabled')} ${t('remove')}
`).join('')}
`:`
${t('noTasks')}
`}
`;bind('new-job',()=>jobEditor());document.querySelectorAll('[data-job-edit]').forEach(b=>b.onclick=()=>jobEditor(jobs[b.dataset.jobEdit]));document.querySelectorAll('[data-job-toggle]').forEach(b=>b.onclick=busy(async()=>{const j=jobs[b.dataset.jobToggle];await api('/api/v1/jobs/'+j.id,{method:'PUT',body:jobPayload(j,{enabled:!j.enabled})});await navigate();}));document.querySelectorAll('[data-job-delete]').forEach(b=>b.onclick=()=>confirmDialog(t('removeConfirm'),async()=>{await api('/api/v1/jobs/'+jobs[b.dataset.jobDelete].id,{method:'DELETE'});await navigate();}));},
async playlists(epoch){const playlists=await api('/api/v1/playlists');if(epoch!==state.epoch)return;$('#main').innerHTML=notice()+`${t('playlistNotice')}
${t('playlists')} ${buttons('new-playlist','newPlaylist',true)}${playlists.map((p,i)=>`
${t(p.enabled?'enabled':'disabled')} ${esc(p.name)} ${p.image_ids.length} ${t('count')} · ${p.interval_minutes} ${t('minutes')} · ${t(p.mode)}
${esc(p.image_ids.join(' → '))}
${t('lastScheduled')}: ${p.position>=0?esc(p.image_ids[p.position]):'—'} ${t('edit')} ${t('remove')}
`).join('')||`
${t('noTasks')}
`}
`;bind('new-playlist',()=>playlistEditor());document.querySelectorAll('[data-pl-edit]').forEach(b=>b.onclick=()=>playlistEditor(playlists[b.dataset.plEdit]));document.querySelectorAll('[data-pl-delete]').forEach(b=>b.onclick=()=>confirmDialog(t('removeConfirm'),async()=>{await api('/api/v1/playlists/'+playlists[b.dataset.plDelete].id,{method:'DELETE'});await navigate();}));},
async history(epoch){const ops=await api('/api/v1/operations');if(epoch!==state.epoch)return;$('#main').innerHTML=`
${t('history')} ${buttons('history-refresh','refresh')}${ops.some(x=>x.status==='UNKNOWN')?`${t('unknown')}
`:''}${ops.length?`
${['created','action','status','result','client','requestId'].map(x=>`${t(x)} `).join('')} ${ops.map((o,i)=>`${fmt(o.created_at)} ${esc(o.action)}${esc(o.device_id)} ${t(o.status)} ${o.status==='UNKNOWN'?`${t('reconcile')}
`:''}${esc(o.result?.image_id||o.result?.asset_id||o.error?.code||'—')} ${esc(o.client_id)} ${esc(o.request_id)} ${esc(o.operation_id)} `).join('')}
`:`
${t('noHistory')}
`}
`;bind('history-refresh',()=>navigate());document.querySelectorAll('[data-reconcile]').forEach(b=>b.onclick=busy(async()=>{const o=ops[b.dataset.reconcile];const r=await api('/api/v1/operations/'+o.operation_id+'/reconcile',{method:'POST',body:{acknowledge:false}});showModal(`${t('reconcile')} ${t('current')}: ${esc(r.current_image_id)}
${t('result')}: ${esc(r.expected_image_id)}
${t('unknown')}
${buttons('modal-cancel','cancel')}${r.resolved?'':buttons('acknowledge','acknowledge')}
`);bind('acknowledge',async()=>{await api('/api/v1/operations/'+o.operation_id+'/reconcile',{method:'POST',body:{acknowledge:true}});$('#modal').close();await navigate();});}));},
diff --git a/pigway_frame_flow/web/i18n.js b/pigway_frame_flow/web/i18n.js
index 9ebeef8..b70f2ce 100644
--- a/pigway_frame_flow/web/i18n.js
+++ b/pigway_frame_flow/web/i18n.js
@@ -58,3 +58,59 @@ Object.assign(window.MESSAGES.en,{
templateContentHelp:'This template displays formatted information and does not automatically choose gallery photos. Weather and dates update when rendering; the displayed image stays static until rendered and displayed again.',
templateWeatherHelp:'Leave weather blank to use Settings → Weather source automatically. Enter JSON only to override it manually.'
});
+
+Object.assign(window.MESSAGES.zh,{
+ templateData:'画面内容',formEditor:'填写要出现在图片上的内容',
+ templateEditHelp:'这里编辑的是生成图片上的文字和照片,不是设备设置,也不会修改原照片。输入框内现有文字是默认内容,可以直接替换。',
+ templateGuideTitle:'这个模板会显示什么?',
+ guidePhotoText:'标题显示在顶部,所选照片显示在中间的大图区,正文显示在照片下方。它与照片数据源任务的底部水印布局不同。',
+ guideDashboard:'显示标题、日期、星期、天气、今日事项、一句话和底部照片区域。事项由你填写;不会自动读取私人日历。',
+ guideWeather:'显示标题、日期、当前天气和三天预报。默认从设置中的天气来源自动获取,不需要手填气温。',
+ guideCalendar:'显示标题、日期对应月份的日历和你填写的事项。它不是已经连接的外部日历。',
+ guideQuote:'显示标题、一句话和署名。现有句子是默认示例,可换成你想展示的文字。',
+ guidePoetry:'显示标题、诗名、作者、诗词正文和日期。可在上方选择每日自动选诗,或选择一首诗;填写诗词正文后使用自定义内容。',
+ guideAlert:'显示告警标题和正文。这里手动填写消息,不会自动检测 NAS 故障;自动告警需外部服务调用。',
+ helpTitle:'图片顶部标题,例如「我们的周末」。不是文件名。',
+ helpMessage:'你想显示的说明文字,例如「第一次一起去海边」。可换行。',
+ helpQuote:'图片中要展示的一句话,例如「把平凡的日子过成喜欢的样子」。',
+ helpAuthor:'这句话的作者或署名,例如「爸爸」。',
+ helpEvents:'每行一件事,例如「09:00 看牙医」。这是手动内容,不会自动同步日历。',
+ helpDate:'留空自动使用生成时的上海日期;指定日期请填 YYYY-MM-DD,例如 2026-10-08。',
+ helpWeekday:'留空使用生成时的上海星期;只有需要自定义文字时才填写。',
+ helpWeather:'留空自动获取已配置的天气。一般无需编辑;JSON 仅供高级用户覆盖数据。',
+ helpPoemTitle:'自定义诗词的诗名;未填写正文时,会由所选诗词自动提供。',
+ helpPoemAuthor:'自定义诗词的作者;未填写正文时,会由所选诗词自动提供。',
+ helpPoemLines:'自定义诗词正文,每行一句。留空时自动读取上方所选诗词。',
+ poem_title:'诗名',poem_author:'诗人',poem_lines:'诗词正文',
+ templateActionHelp:'生成预览:仅生成本地图片。保存默认数据:下次打开沿用这些内容,不会更新画框或已有任务。显示到画框:上传已预览的图片并切换显示。',
+ templateAutomationHelp:'需要每天更新?去「自动化」新建任务,内容类型选「模板」,选择同一模板。任务有自己的内容配置;自动日期和天气会在每次运行时读取。',
+ templatePreviewHint:'填写左侧内容后点击「生成预览」。这里会展示最终图片,确认后再点击「显示到画框」。',
+ helpProfile:'彩色保留颜色;灰度生成黑白灰图片。不会改变设备硬件模式。'
+});
+Object.assign(window.MESSAGES.en,{
+ templateData:'Image content',formEditor:'Content that appears in the generated image',
+ templateEditHelp:'Edit the text and photo used to create the image, rather than device settings. The original photo stays intact. Existing text is a default you can replace.',
+ templateGuideTitle:'What does this template display?',
+ guidePhotoText:'A title at the top, a large photo in the middle, and your message below. This differs from the bottom watermark used by photo-source jobs.',
+ guideDashboard:'Title, date, weekday, weather, your events, a quote and a lower photo area. Events are entered manually; private calendars are not connected automatically.',
+ guideWeather:'Title, date, current weather and a three-day forecast. Weather comes from the source configured in Settings; no manual temperature entry is needed.',
+ guideCalendar:'Title, a month grid for the selected date, and your events. This is not an already-connected external calendar.',
+ guideQuote:'Title, a quote and its author. Replace the default example with your own text.',
+ guidePoetry:'Title, poem title, author, verses and date. Choose daily automatic selection or a poem above. Enter verses to use custom content.',
+ guideAlert:'An alert title and message you enter. This does not automatically monitor NAS faults; automated alerts require an external caller.',
+ helpTitle:'The heading at the top of the image, such as Our weekend. This is not a filename.',
+ helpMessage:'Your message, such as Our first trip to the seaside. Line breaks are supported.',
+ helpQuote:'The sentence you want to display.',helpAuthor:'The author or signature, such as Dad.',
+ helpEvents:'One event per line, such as 09:00 Dentist. These are manual entries, not synchronized calendar events.',
+ helpDate:'Leave blank for the Shanghai date at render time, or use YYYY-MM-DD, such as 2026-10-08.',
+ helpWeekday:'Leave blank for the Shanghai weekday at render time; enter text only for a custom label.',
+ helpWeather:'Leave blank for configured weather. Usually no editing is needed; JSON is an advanced override.',
+ helpPoemTitle:'Custom poem title. The selected poem supplies this when verses are blank.',
+ helpPoemAuthor:'Custom poem author. The selected poem supplies this when verses are blank.',
+ helpPoemLines:'Custom verses, one per line. Leave blank to use the poem selected above.',
+ poem_title:'Poem title',poem_author:'Poet',poem_lines:'Verses',
+ templateActionHelp:'Generate preview: create a local image only. Save defaults: reuse this content next time, without updating the frame or existing jobs. Display on frame: upload and activate the previewed image.',
+ templateAutomationHelp:'For daily updates, create an Automation job with content type Template and select this template. Jobs have their own content settings; automatic dates and weather resolve on each run.',
+ templatePreviewHint:'Enter content on the left and select Generate preview. Inspect the final image here before selecting Display on frame.',
+ helpProfile:'Color preserves colors; grayscale creates a grayscale image. This does not change device hardware settings.'
+});