line.includes('aria-label="Current family outputs"'))
+ const render=new Function('Vue',compile('
',{mode:'function'}).code)(Vue)
+ const state={selected:{id:'a',kind:'still'},hideOutput:true,xaigen:true,family:[{id:'a',kind:'still'}],form:{hideInput:true},previewHidden,stillUrl:id=>'/image/'+id,selectOutput(){}}
+ const hidden=await renderToString(Vue.createSSRApp({render,data:()=>state}));assert.doesNotMatch(hidden,/
![]()
({...state,xaigen:false})}));assert.match(visible,/
![]()
{
+ const cache={image:['Klein/portrait.safetensors'],video:['motion.safetensors']};let queried=0
+ const opts={read:()=>cache,write:()=>assert.fail('Do not erase cache'),live:async()=>{queried++;throw Error('Comfy asleep')}}
+ assert.deepEqual(await cachedLoras(opts),cache);assert.equal(queried,0);assert.deepEqual(await cachedLoras({...opts,fresh:true}),cache);assert.equal(queried,1)
+})
+test('source/hero actions are independent and full input restores structured settings',()=>{
+ const form={identityStillId:'hero',imageAId:'source',promptSections:{action:'old'},settings:{}}
+ assert.equal(useAsHero(form,{id:'new'}).imageAId,'source');assert.equal(useAsSource(form,{id:'new'}).identityStillId,'hero')
+ const saved={mode:'edit',identityStillId:'h',imageAId:'s',imageStyles:{positive:['Comic'],negative:['Skin pores']},promptSections:{action:'New',cameraBeats:[{moves:['hold']}]},settings:{steps:24,loraStack:[{name:'a',strengthModel:.4,strengthClip:.6}]}}
+ const restored=restoreAll(form,{id:'result',studio2:saved});assert.equal(restored.imageAId,'s');assert.equal(restored.identityStillId,'h');assert.deepEqual(restored.settings.loraStack,saved.settings.loraStack);assert.deepEqual(restored.imageStyles,saved.imageStyles);assert.equal(restored.promptSections.action,'New')
+})
+test('image chips compile positive and negative independently; video chips do not leak',()=>{
+ let styles=toggleStyle({},'Comic');styles=toggleStyle(styles,'Skin pores',true);styles=toggleStyle(styles,'Comic',true);assert.equal(stylePrompt(styles),'');assert.match(stylePrompt(styles,true),/Comic/)
+ styles=toggleStyle(styles,'Photorealistic');const q=validateRequest({mode:'edit',engine:'flux',folderId:'f',imageAId:'s',imageStyles:styles,promptSections:{action:'Restaurant',cameraBeats:[{moves:['hold']}],locks:'VIDEO ONLY'}})
+ assert.match(q.compiledPrompt,/Photorealistic/);assert.doesNotMatch(q.compiledPrompt,/Comic|pores|tripod|hold|VIDEO ONLY/i);assert.deepEqual(q.imageStyles,styles)
+ assert.doesNotMatch(compilePrompt(q.promptSections,false,q),/Picture 1/)
+ assert.deepEqual(parseBatch('A wrapped\nsentence\n\nSecond shot\r\n\r\nThird'),['A wrapped\nsentence','Second shot','Third'])
+})