PageSourceSearch

https://agiscorecard.com/foresight-assets/planner-ui.mjs?v=20261003-select1

js agiscorecard.com collected 2026-10-08 03:57:45 UTC 4,047 bytes, 46 lines download raw bytes

1import {scenarios,actions,counters,reviewChoices,reviewDate,makePlan,defaultChoices} from './planner.mjs?v=20261003-select1';
2export function initPlanner({root=document,lang,onGoal=()=>{},onChange=()=>{}}){
3 const $=id=>root.querySelector('#'+id),t=(en,zh)=>lang==='zh'?zh:en;
4 let legacy={},fixedReview='',goal='work';
5 function options(id,rows,value,retained){
6  const select=$(id);select.replaceChildren();
7  for(const r of rows){const o=document.createElement('option');o.value=r.id;o.textContent=r.label[lang];select.append(o);}
8  if(retained!==undefined){const o=document.createElement('option');o.value='saved';o.textContent=retained;select.prepend(o);}
9  select.value=value;
10 }
11 function populate(note={}){
12  legacy={};const base=defaultChoices(goal);
13  for(const [field,rows]of [['task',scenarios[goal]],['action',actions[goal]],['counter',counters[goal]]]){
14   const retained=typeof note[field]==='string';if(retained)legacy[field]=note[field];
15   const label=note[field]===''?t('Not chosen yet','尚未选择'):field==='task'?t('Saved: ','已存:')+note[field]:field==='action'?t('Keep my saved action','保留已保存的行动'):t('Keep my saved condition','保留已保存的调整条件');
16   options('note-'+field,rows,retained?'saved':base[field],retained?label:undefined);
17  }
18  // Resolve relative choices once, using the visitor's local calendar. Restoring
19  // an absolute date never silently moves a review into the future.
20  const dated=typeof note.review==='string'&&note.review.length>0,restored=Object.hasOwn(note,'review');
21  options('note-review',reviewChoices.map(([id,en,zh])=>({id,label:{en,zh}})),dated?'saved':restored?'none':'7',dated?t('Saved: ','已存:')+note.review:undefined);
22  fixedReview=dated?note.review:reviewDate(restored?'none':'7');$('note-done').value=note.done?'tried':'planned';preview();
23 }
24 function read(){
25  const defaults=defaultChoices(goal),choice={goal,done:$('note-done').value==='tried',review:'none'};
26  for(const k of ['task','action','counter'])choice[k]=$('note-'+k).value==='saved'?defaults[k]:$('note-'+k).value;
27  const note=makePlan(choice,lang);for(const k of ['task','action','counter'])if($('note-'+k).value==='saved')note[k]=legacy[k];
28  if($('note-task').value==='saved'&&legacy.task&&$('note-action').value!=='saved'){
29   const scenario=scenarios[goal].find(s=>s.label.en===legacy.task||s.label.zh===legacy.task)||{input:{en:legacy.task,zh:legacy.task},output:{en:'a result you can check',zh:'一份可核对的结果'}};
30   note.action=actions[goal].find(a=>a.id===choice.action).make(scenario)[lang];
31  }
32  note.review=fixedReview;return note;
33 }
34 function preview(){const note=read();for(const k of ['task','action','counter','review'])root.querySelector('[data-plan-output='+k+']').textContent=note[k]||(k==='review'?t('No review date set','暂未安排复查'):t('Not chosen yet','尚未选择'));}
35 function changed(){preview();onChange();}
36 $('plan-goal').addEventListener('change',()=>{goal=$('plan-goal').value;populate();onGoal(goal);changed();});
37 $('note-task').addEventListener('change',()=>{
38  // A new scenario gets a matching action; a saved action is retained until the
39  // reader actively chooses another scenario or direction.
40  if($('note-task').value!=='saved'){const id=$('note-action').value;options('note-action',actions[goal],actions[goal].some(a=>a.id===id)?id:actions[goal][0].id);delete legacy.action;}$('note-done').value='planned';changed();
41 });
42 $('note-action').addEventListener('change',()=>{if($('note-action').value!=='saved'&&$('note-task').value==='saved'&&!legacy.task)$('note-task').value=defaultChoices(goal).task;$('note-done').value='planned';changed();});
43 for(const k of ['counter','done'])$('note-'+k).addEventListener('change',changed);
44 $('note-review').addEventListener('change',()=>{fixedReview=$('note-review').value==='saved'?legacy.review:reviewDate($('note-review').value);changed();});
45 return {read,load(nextGoal,note){goal=nextGoal;$('plan-goal').value=goal;populate(note);legacy.review=note?.review||'';}};
46}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.