### Result {"checks":["placement save requires an applied definition","one authored pointer input connects all three view targets","DOM destinations retain distinct target identities","last input identifies the released target within its group","three independently authored targets move and selection directs keyboard adjustment","placement download is a separate document file","saving neither applies nor discards the unfinished draft","reset returns to authored initial positions","downloaded file restores all states and visible positions","the draft remains separate from the restored executable definition","restored work starts stopped with no replayed inputs or clock","restored selection and bindings remain editable","a fresh browser page reconstructs the saved work without old runtime state","invalid saved state cannot partially replace code, draft or scene","a delayed file read cannot overwrite a newer draft","a delayed restore cannot overwrite placement changes made while reading","saving while time advances requests a stopped document","saving with a held input is refused","editing the shared rule changes the selected amber target","the same single rule edit also changes the blue target","reordering instance declarations preserves every field by qualified name","rebuilt parameter maps still send selection input to blue after reorder","simultaneous touches share code but retain independent field bindings","shared cancel restores each contact to its own start position","a second touch on the same target cannot steal ownership","releasing green keeps blue captured within the same input","the remaining contact keeps moving only its own target","canceling the remaining target preserves the already released position","extra persistence control fits a mobile viewport","no uncaught page errors"],"errors":[],"saved":"output/playwright/pure-routed-layout-saved.json","expected":{"states":{"selected":3,"green.x":150.00000659728084,"green.y":169.9999983506798,"green.ox":9.999986805438311,"green.oy":10.00000164932024,"green.sx":80,"green.sy":120,"green.held":0,"green.id":1,"blue.x":350.00000659728073,"blue.y":209.9999983506798,"blue.ox":9.999980208157467,"blue.oy":10.00000329864045,"blue.sx":280,"blue.sy":160,"blue.held":0,"blue.id":2,"amber.x":509.999947221753,"amber.y":260.0000016493202,"amber.ox":10.000013194561802,"amber.oy":9.999998350679817,"amber.sx":450,"amber.sy":220,"amber.held":0,"amber.id":3},"views":[{"id":"board","type":"box","color":"#233a31","x":20,"y":90,"width":600,"height":240},{"id":"help","type":"text","prefix":"선택한 도형: ","x":25,"y":40,"value":3},{"id":"green_box","type":"box","color":"#c9f08b","x":150.00000659728084,"y":169.9999983506798,"width":56,"height":44},{"id":"blue_box","type":"box","color":"#74c4d4","x":350.00000659728073,"y":209.9999983506798,"width":56,"height":44},{"id":"amber_box","type":"box","color":"#dfb184","x":509.999947221753,"y":260.0000016493202,"width":56,"height":44}]},"source":"# 하나의 포인터 입력과 네 반응을 모든 도형이 공유합니다.\nstate selected = 0\nrecord Tile {\n x = 0; y = 0\n ox = 0; oy = 0\n sx = 0; sy = 0\n held = 0; id = 0\n}\nitem green = Tile(x=80, y=120, sx=80, sy=120, id=1)\nitem blue = Tile(x=280, y=160, sx=280, sy=160, id=2)\nitem amber = Tile(x=450, y=220, sx=450, sy=220, id=3)\ninput left = ArrowLeft\ninput right = ArrowRight\ninput up = ArrowUp\ninput down = ArrowDown\ninput drag = pointer {\n green_box: green\n blue_box: blue\n amber_box: amber\n}\nbox board(20,90,600,240,\"#233a31\")\ntext help(25,40,selected,\"선택한 도형: \")\nbox green_box(green.x,green.y,56,44,\"#c9f08b\")\nbox blue_box(blue.x,blue.y,56,44,\"#74c4d4\")\nbox amber_box(amber.x,amber.y,56,44,\"#dfb184\")\n\nrule grab(t: Tile) {\n selected = t.id\n t.sx = t.x; t.sy = t.y\n t.ox = event_x - t.x; t.oy = event_y - t.y\n t.held = 1\n}\nrule move(t: Tile) {\n t.x = clamp(event_x - t.ox, 20, 564)\n t.y = clamp(event_y - t.oy, 90, 286)\n}\nrule drop(t: Tile) { t.held = 0 }\nrule cancel(t: Tile) { t.x = t.sx; t.y = t.sy; t.held = 0 }\nrule go_left(t: Tile) {\n if selected == t.id && t.held == 0 { t.x = clamp(t.x - 10, 20, 564) }\n}\nrule go_right(t: Tile) {\n if selected == t.id && t.held == 0 { t.x = clamp(t.x + 10, 20, 564) }\n}\nrule go_up(t: Tile) {\n if selected == t.id && t.held == 0 { t.y = clamp(t.y - 10, 90, 286) }\n}\nrule go_down(t: Tile) {\n if selected == t.id && t.held == 0 { t.y = clamp(t.y + 10, 90, 286) }\n}\n\non drag.down use grab(drag.target)\non drag.move use move(drag.target)\non drag.up use drop(drag.target)\non drag.cancel use cancel(drag.target)\n\non left.down use go_left(green)\non right.down use go_right(green)\non up.down use go_up(green)\non down.down use go_down(green)\n\non left.down use go_left(blue)\non right.down use go_right(blue)\non up.down use go_up(blue)\non down.down use go_down(blue)\n\non left.down use go_left(amber)\non right.down use go_right(amber)\non up.down use go_up(amber)\non down.down use go_down(amber)\n","draft":"# 하나의 포인터 입력과 네 반응을 모든 도형이 공유합니다.\nstate selected = 0\nrecord Tile {\n x = 0; y = 0\n ox = 0; oy = 0\n sx = 0; sy = 0\n held = 0; id = 0\n}\nitem green = Tile(x=80, y=120, sx=80, sy=120, id=1)\nitem blue = Tile(x=280, y=160, sx=280, sy=160, id=2)\nitem amber = Tile(x=450, y=220, sx=450, sy=220, id=3)\ninput left = ArrowLeft\ninput right = ArrowRight\ninput up = ArrowUp\ninput down = ArrowDown\ninput drag = pointer {\n green_box: green\n blue_box: blue\n amber_box: amber\n}\nbox board(20,90,600,240,\"#233a31\")\ntext help(25,40,selected,\"선택한 도형: \")\nbox green_box(green.x,green.y,56,44,\"#c9f08b\")\nbox blue_box(blue.x,blue.y,56,44,\"#74c4d4\")\nbox amber_box(amber.x,amber.y,56,44,\"#dfb184\")\n\nrule grab(t: Tile) {\n selected = t.id\n t.sx = t.x; t.sy = t.y\n t.ox = event_x - t.x; t.oy = event_y - t.y\n t.held = 1\n}\nrule move(t: Tile) {\n t.x = clamp(event_x - t.ox, 20, 564)\n t.y = clamp(event_y - t.oy, 90, 286)\n}\nrule drop(t: Tile) { t.held = 0 }\nrule cancel(t: Tile) { t.x = t.sx; t.y = t.sy; t.held = 0 }\nrule go_left(t: Tile) {\n if selected == t.id && t.held == 0 { t.x = clamp(t.x - 10, 20, 564) }\n}\nrule go_right(t: Tile) {\n if selected == t.id && t.held == 0 { t.x = clamp(t.x + 10, 20, 564) }\n}\nrule go_up(t: Tile) {\n if selected == t.id && t.held == 0 { t.y = clamp(t.y - 10, 90, 286) }\n}\nrule go_down(t: Tile) {\n if selected == t.id && t.held == 0 { t.y = clamp(t.y + 10, 90, 286) }\n}\n\non drag.down use grab(drag.target)\non drag.move use move(drag.target)\non drag.up use drop(drag.target)\non drag.cancel use cancel(drag.target)\n\non left.down use go_left(green)\non right.down use go_right(green)\non up.down use go_up(green)\non down.down use go_down(green)\n\non left.down use go_left(blue)\non right.down use go_right(blue)\non up.down use go_up(blue)\non down.down use go_down(blue)\n\non left.down use go_left(amber)\non right.down use go_right(amber)\non up.down use go_up(amber)\non down.down use go_down(amber)\n\nstate unfinished ="} ### Ran Playwright code ```js await (async page => await page.evaluate(() => window.__pureRoutedInputEvidence ?? {pending:true}))(page); ``` ### Page - Page URL: http://127.0.0.1:8766/ - Page Title: Pure · 빈 작업물에서 시작하기 ### Events - Downloading file my-layout.pure.json ... - Downloaded file my-layout.pure.json to ".playwright-cli/my-layout-pure.json"